[Freeswitch-svn] [commit] r3693 - in freeswitch/trunk/libs/js: . nsprpub nsprpub/CVS nsprpub/admin nsprpub/admin/CVS nsprpub/build nsprpub/build/CVS nsprpub/build/autoconf nsprpub/build/autoconf/CVS nsprpub/config nsprpub/config/CVS nsprpub/include nsprpub/include/CVS nsprpub/lib nsprpub/lib/CVS nsprpub/lib/ds nsprpub/lib/ds/CVS nsprpub/lib/libc nsprpub/lib/libc/CVS nsprpub/lib/libc/include nsprpub/lib/libc/include/CVS nsprpub/lib/libc/src nsprpub/lib/libc/src/CVS nsprpub/lib/msgc nsprpub/lib/msgc/CVS nsprpub/lib/msgc/include nsprpub/lib/msgc/include/CVS nsprpub/lib/msgc/src nsprpub/lib/msgc/src/CVS nsprpub/lib/msgc/tests nsprpub/lib/msgc/tests/CVS nsprpub/lib/prstreams nsprpub/lib/prstreams/CVS nsprpub/lib/prstreams/tests nsprpub/lib/prstreams/tests/CVS nsprpub/lib/prstreams/tests/testprstrm nsprpub/lib/prstreams/tests/testprstrm/CVS nsprpub/lib/tests nsprpub/lib/tests/CVS nsprpub/lib/tests/windows nsprpub/lib/tests/windows/CVS nsprpub/macbuild nsprpub/macbuild/CVS nsprpub/pkg nsprpub/pkg/CVS nsprpub/pkg/linux nsprpub/pkg/linux/CVS nsprpub/pkg/solaris nsprpub/pkg/solaris/CVS nsprpub/pkg/solaris/SUNWnspr nsprpub/pkg/solaris/SUNWnspr/CVS nsprpub/pkg/solaris/SUNWnsprx nsprpub/pkg/solaris/SUNWnsprx/CVS nsprpub/pkg/solaris/SUNWpr nsprpub/pkg/solaris/SUNWpr-devl nsprpub/pkg/solaris/SUNWpr-devl/CVS nsprpub/pkg/solaris/SUNWpr/CVS nsprpub/pkg/solaris/SUNWprd nsprpub/pkg/solaris/SUNWprd/CVS nsprpub/pkg/solaris/SUNWprdx nsprpub/pkg/solaris/SUNWprdx/CVS nsprpub/pkg/solaris/SUNWprx nsprpub/pkg/solaris/SUNWprx-devl nsprpub/pkg/solaris/SUNWprx-devl/CVS nsprpub/pkg/solaris/SUNWprx/CVS nsprpub/pkg/solaris/common_files nsprpub/pkg/solaris/common_files/CVS nsprpub/pr nsprpub/pr/CVS nsprpub/pr/include nsprpub/pr/include/CVS nsprpub/pr/include/md nsprpub/pr/include/md/CVS nsprpub/pr/include/obsolete nsprpub/pr/include/obsolete/CVS nsprpub/pr/include/private nsprpub/pr/include/private/CVS nsprpub/pr/src nsprpub/pr/src/CVS nsprpub/pr/src/bthreads nsprpub/pr/src/bthreads/CVS nsprpub/pr/src/cplus nsprpub/pr/src/cplus/CVS nsprpub/pr/src/cplus/tests nsprpub/pr/src/cplus/tests/CVS nsprpub/pr/src/cthreads nsprpub/pr/src/cthreads/CVS nsprpub/pr/src/io nsprpub/pr/src/io/CVS nsprpub/pr/src/linking nsprpub/pr/src/linking/CVS nsprpub/pr/src/malloc nsprpub/pr/src/malloc/CVS nsprpub/pr/src/md nsprpub/pr/src/md/CVS nsprpub/pr/src/md/beos nsprpub/pr/src/md/beos/CVS nsprpub/pr/src/md/mac nsprpub/pr/src/md/mac/CVS nsprpub/pr/src/md/os2 nsprpub/pr/src/md/os2/CVS nsprpub/pr/src/md/unix nsprpub/pr/src/md/unix/CVS nsprpub/pr/src/md/windows nsprpub/pr/src/md/windows/CVS nsprpub/pr/src/memory nsprpub/pr/src/memory/CVS nsprpub/pr/src/misc nsprpub/pr/src/misc/CVS nsprpub/pr/src/pthreads nsprpub/pr/src/pthreads/CVS nsprpub/pr/src/threads nsprpub/pr/src/threads/CVS nsprpub/pr/src/threads/combined nsprpub/pr/src/threads/combined/CVS nsprpub/pr/tests nsprpub/pr/tests/CVS nsprpub/pr/tests/dll nsprpub/pr/tests/dll/CVS nsprpub/pr/tests/macbuild nsprpub/pr/tests/macbuild/CVS nsprpub/pr/tests/w16gui nsprpub/pr/tests/w16gui/CVS nsprpub/tools nsprpub/tools/CVS src src/fdlibm src/perlconnect

Freeswitch SVN brian at freeswitch.org
Mon Dec 18 10:55:04 EST 2006


Author: brian
Date: Mon Dec 18 10:53:47 2006
New Revision: 3693

Added:
   freeswitch/trunk/libs/js/
   freeswitch/trunk/libs/js/AUTHORS
   freeswitch/trunk/libs/js/ChangeLog
   freeswitch/trunk/libs/js/LINKS
   freeswitch/trunk/libs/js/Makefile.in
   freeswitch/trunk/libs/js/README
   freeswitch/trunk/libs/js/THANKS
   freeswitch/trunk/libs/js/TODO
   freeswitch/trunk/libs/js/VERSION
   freeswitch/trunk/libs/js/aclocal.m4
   freeswitch/trunk/libs/js/config.guess   (contents, props changed)
   freeswitch/trunk/libs/js/config.h.in
   freeswitch/trunk/libs/js/config.sub   (contents, props changed)
   freeswitch/trunk/libs/js/configure   (contents, props changed)
   freeswitch/trunk/libs/js/configure.ac
   freeswitch/trunk/libs/js/js-config.1
   freeswitch/trunk/libs/js/js-config.sh.in
   freeswitch/trunk/libs/js/js.1
   freeswitch/trunk/libs/js/js.3
   freeswitch/trunk/libs/js/js.pc.in
   freeswitch/trunk/libs/js/jslint.js
   freeswitch/trunk/libs/js/libtool.m4
   freeswitch/trunk/libs/js/ltmain.sh
   freeswitch/trunk/libs/js/nsprpub/
   freeswitch/trunk/libs/js/nsprpub/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/CVS/
   freeswitch/trunk/libs/js/nsprpub/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/admin/
   freeswitch/trunk/libs/js/nsprpub/admin/CVS/
   freeswitch/trunk/libs/js/nsprpub/admin/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/admin/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/admin/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/admin/explode.pl
   freeswitch/trunk/libs/js/nsprpub/admin/makeTargetDirs.sh
   freeswitch/trunk/libs/js/nsprpub/admin/repackage.sh   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/admin/symlinks.sh
   freeswitch/trunk/libs/js/nsprpub/build/
   freeswitch/trunk/libs/js/nsprpub/build/CVS/
   freeswitch/trunk/libs/js/nsprpub/build/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/build/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/build/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/build/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/build/autoconf/
   freeswitch/trunk/libs/js/nsprpub/build/autoconf/CVS/
   freeswitch/trunk/libs/js/nsprpub/build/autoconf/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/build/autoconf/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/build/autoconf/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/build/autoconf/config.guess   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/build/autoconf/config.sub   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/build/autoconf/install-sh   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/build/cygwin-wrapper   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/config/
   freeswitch/trunk/libs/js/nsprpub/config/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/config/CVS/
   freeswitch/trunk/libs/js/nsprpub/config/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/config/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/config/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/config/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/config/autoconf.mk.in
   freeswitch/trunk/libs/js/nsprpub/config/config.mk
   freeswitch/trunk/libs/js/nsprpub/config/gcc_hidden.h
   freeswitch/trunk/libs/js/nsprpub/config/libc_r.h
   freeswitch/trunk/libs/js/nsprpub/config/make-system-wrappers.pl
   freeswitch/trunk/libs/js/nsprpub/config/nfspwd.pl
   freeswitch/trunk/libs/js/nsprpub/config/now.c
   freeswitch/trunk/libs/js/nsprpub/config/nsinstall.c
   freeswitch/trunk/libs/js/nsprpub/config/nspr-config.in   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/config/nspr.m4
   freeswitch/trunk/libs/js/nsprpub/config/nsprincl.mk.in
   freeswitch/trunk/libs/js/nsprpub/config/nsprincl.sh.in
   freeswitch/trunk/libs/js/nsprpub/config/pathsub.h
   freeswitch/trunk/libs/js/nsprpub/config/prdepend.h
   freeswitch/trunk/libs/js/nsprpub/config/prmkdir.bat   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/config/rules.mk
   freeswitch/trunk/libs/js/nsprpub/config/system-headers
   freeswitch/trunk/libs/js/nsprpub/configure   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/configure.in
   freeswitch/trunk/libs/js/nsprpub/include/
   freeswitch/trunk/libs/js/nsprpub/include/CVS/
   freeswitch/trunk/libs/js/nsprpub/include/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/include/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/include/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/
   freeswitch/trunk/libs/js/nsprpub/lib/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/lib/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/ds/
   freeswitch/trunk/libs/js/nsprpub/lib/ds/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/ds/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/ds/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/ds/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/ds/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/ds/MANIFEST
   freeswitch/trunk/libs/js/nsprpub/lib/ds/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/ds/plarena.c
   freeswitch/trunk/libs/js/nsprpub/lib/ds/plarena.h
   freeswitch/trunk/libs/js/nsprpub/lib/ds/plarenas.h
   freeswitch/trunk/libs/js/nsprpub/lib/ds/plds.def
   freeswitch/trunk/libs/js/nsprpub/lib/ds/plds.rc
   freeswitch/trunk/libs/js/nsprpub/lib/ds/plds_symvec.opt
   freeswitch/trunk/libs/js/nsprpub/lib/ds/plhash.c
   freeswitch/trunk/libs/js/nsprpub/lib/ds/plhash.h
   freeswitch/trunk/libs/js/nsprpub/lib/ds/plvrsion.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/
   freeswitch/trunk/libs/js/nsprpub/lib/libc/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/libc/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/libc/README
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/MANIFEST
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/README
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plbase64.h
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plerror.h
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plgetopt.h
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plresolv.h
   freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plstr.h
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/README
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/base64.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plc.def
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plc.rc
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plc_symvec.opt
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plerror.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plgetopt.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plvrsion.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcat.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strccmp.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strchr.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcmp.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcpy.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcstr.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strdup.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strlen.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strpbrk.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strstr.c
   freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strtok.c
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/MANIFEST
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/gcint.h
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/prgc.h
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/macgc.c
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/os2gc.c
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/prgcapi.c
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/prmsgc.c
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/unixgc.c
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/win16gc.c
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/win32gc.c
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/gc1.c
   freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/thrashgc.c
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/plvrsion.c
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/prstrms.cpp
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/prstrms.h
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/prstrms.rc
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp
   freeswitch/trunk/libs/js/nsprpub/lib/tests/
   freeswitch/trunk/libs/js/nsprpub/lib/tests/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/tests/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/lib/tests/arena.c
   freeswitch/trunk/libs/js/nsprpub/lib/tests/base64t.c
   freeswitch/trunk/libs/js/nsprpub/lib/tests/string.c
   freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/
   freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/CVS/
   freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/makefile
   freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/readme.1st
   freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/winevent.c
   freeswitch/trunk/libs/js/nsprpub/macbuild/
   freeswitch/trunk/libs/js/nsprpub/macbuild/CVS/
   freeswitch/trunk/libs/js/nsprpub/macbuild/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/macbuild/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/macbuild/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/
   freeswitch/trunk/libs/js/nsprpub/pkg/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pkg/linux/
   freeswitch/trunk/libs/js/nsprpub/pkg/linux/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/linux/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/linux/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/linux/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/linux/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pkg/linux/sun-nspr.spec
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile-devl.com   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile-devl.targ   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile.com
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile.targ
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnspr/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnspr/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnspr/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnspr/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnspr/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnsprx/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnsprx/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnsprx/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnsprx/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnsprx/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr-devl/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr-devl/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr-devl/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr-devl/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr-devl/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/depend
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/prototype_com
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/prototype_i386
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/prototype_sparc
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/Makefile.in   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/depend   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/pkginfo.tmpl   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/prototype   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprdx/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprdx/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprdx/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprdx/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprdx/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx-devl/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx-devl/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx-devl/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx-devl/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx-devl/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/CVS/
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/copyright
   freeswitch/trunk/libs/js/nsprpub/pkg/solaris/proto64.mk
   freeswitch/trunk/libs/js/nsprpub/pr/
   freeswitch/trunk/libs/js/nsprpub/pr/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/pr/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/include/
   freeswitch/trunk/libs/js/nsprpub/pr/include/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/include/MANIFEST
   freeswitch/trunk/libs/js/nsprpub/pr/include/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/include/gencfg.c
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_aix.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_aix32.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_aix64.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_beos.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_beos.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_bsdi.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_bsdi.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_darwin.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_darwin.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_dgux.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_dgux.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_freebsd.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_freebsd.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_hpux.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_hpux32.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_hpux64.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_irix.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_irix32.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_irix64.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_linux.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_linux.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_macos.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_ncr.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_ncr.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nec.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nec.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_netbsd.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_netbsd.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nextstep.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nextstep.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nspr_pthread.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nto.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nto.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openbsd.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openbsd.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openvms.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openvms.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_os2.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_os2.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_os2_errors.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_osf1.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_osf1.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_pcos.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_pth.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_qnx.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_qnx.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_reliantunix.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_reliantunix.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_rhapsody.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_rhapsody.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_riscos.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_riscos.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_scoos.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_scoos.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_solaris.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_solaris.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sony.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sony.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sunos4.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sunos4.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unix_errors.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixos.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixware.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixware.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixware7.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win16.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win16.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win32_errors.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win95.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win95.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_winnt.cfg
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/_winnt.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/prosdep.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/md/sunos4.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/nspr.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/
   freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/pralarm.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/probslet.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/protypes.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/prsem.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/pratom.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prbit.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prclist.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prcmon.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prcountr.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prcvar.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prdtoa.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prenv.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prerr.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prerror.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prinet.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prinit.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prinrval.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prio.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/pripcsem.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/pprio.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/pprmwait.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/pprthred.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/primpl.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/private/prpriv.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prlink.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prlock.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prlog.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prlong.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prmem.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prmon.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prmwait.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prnetdb.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prolock.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prpdce.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prprf.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prproces.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prrng.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prrwlock.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prshm.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prshma.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prsystem.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prthread.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prtime.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prtpool.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prtrace.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prtypes.h
   freeswitch/trunk/libs/js/nsprpub/pr/include/prvrsion.h   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pr/include/prwin16.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/
   freeswitch/trunk/libs/js/nsprpub/pr/src/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/bsrcs.mk
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btcvar.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btlocks.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btmisc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btmon.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btsem.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btthread.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/objs.mk
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcascii.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcbase.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcbase.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rccv.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rccv.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcfileio.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcfileio.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcinrval.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcinrval.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcio.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcio.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rclock.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rclock.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcmon.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetdb.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetdb.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetio.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetio.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcthread.cpp   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcthread.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rctime.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rctime.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/fileio.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/interval.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/ranfile.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/switch.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/thread.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/time.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/tpd.cpp
   freeswitch/trunk/libs/js/nsprpub/pr/src/cthreads/
   freeswitch/trunk/libs/js/nsprpub/pr/src/cthreads/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/cthreads/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/cthreads/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/cthreads/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prdir.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prfdcach.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prfile.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prio.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/priometh.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/pripv6.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prlayer.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prlog.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prmapopt.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prmmap.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prmwait.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prpolevt.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prprf.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prscanf.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prsocket.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/io/prstdio.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/linking/
   freeswitch/trunk/libs/js/nsprpub/pr/src/linking/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/linking/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/linking/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/linking/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/linking/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/linking/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/linking/prlink.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/
   freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/prmalloc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/prmem.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bcpu.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/beos.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/beos_errors.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bfile.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bmemory.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bmisc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bmmap.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bnet.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bproc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/brng.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bseg.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bsrcs.mk
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/btime.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/objs.mk
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/MANIFEST
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/MacErrorHandling.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macdll.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macdll.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macio.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macio.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macrng.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macsocket.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macsockotpt.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macthr.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mactime.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mactime.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdcriticalregion.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdcriticalregion.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdmac.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdmac.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/prcpucfg.h
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/objs.mk
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2_errors.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2cv.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2emx.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2gc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2inrval.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2io.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2misc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2poll.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2rng.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2sem.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2sock.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2thred.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2vaclegacy.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2vacpp.asm
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/prosdep.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/aix.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/aixwrap.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/bsdi.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/darwin.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/dgux.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/freebsd.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/hpux.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/irix.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/linux.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/ncr.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/nec.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/netbsd.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/nextstep.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/nto.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/objs.mk
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/openbsd.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/openvms.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_AIX.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_BSD_386_2.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Darwin_ppc.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Darwin_x86.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_HPUX.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_HPUX_ia64.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Irix.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Linux_ia64.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86_64.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_ReliantUNIX.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_sparcv9.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/osf1.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/pthreads_user.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/qnx.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/reliantunix.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/rhapsody.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/riscos.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/scoos.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/solaris.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/sony.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/sunos4.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/unix.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/unix_errors.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/unixware.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxpoll.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxproces.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxrng.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxshm.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxwrap.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntdllmn.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntgc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntinrval.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntio.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntmisc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntsec.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntsem.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntthread.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/objs.mk
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16callb.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16error.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16fmem.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16gc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16io.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16mem.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16null.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16proc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16sock.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16stdio.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16thred.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32ipcsem.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32poll.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32rng.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32shm.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95cv.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95dllmain.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95io.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95sock.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95thred.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/win32_errors.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/memory/
   freeswitch/trunk/libs/js/nsprpub/pr/src/memory/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/memory/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/memory/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/memory/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/memory/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/memory/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prgcleak.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prseg.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prshm.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prshma.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/compile-et.pl
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pralarm.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pratom.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prcountr.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prdtoa.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prenv.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerr.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerr.et
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerr.properties
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerror.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerrortable.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prinit.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prinrval.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pripc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pripcsem.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prlog2.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prlong.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prnetdb.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prolock.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prrng.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prsystem.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prthinfo.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prtime.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prtpool.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prtrace.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/nspr.def
   freeswitch/trunk/libs/js/nsprpub/pr/src/nspr.rc
   freeswitch/trunk/libs/js/nsprpub/pr/src/nspr_symvec.opt
   freeswitch/trunk/libs/js/nsprpub/pr/src/os2extra.def
   freeswitch/trunk/libs/js/nsprpub/pr/src/prvrsion.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/
   freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptio.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptmisc.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptsynch.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptthread.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/README
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prucpu.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prucv.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prulock.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prustack.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/pruthr.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prcmon.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prcthr.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prdump.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prmon.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prrwlock.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prsem.c
   freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prtpd.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/
   freeswitch/trunk/libs/js/nsprpub/pr/tests/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Entries.Log
   freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/tests/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/tests/README.TXT
   freeswitch/trunk/libs/js/nsprpub/pr/tests/accept.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/acceptread.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/acceptreademu.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/addrstr.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/affinity.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/alarm.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/anonfm.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/append.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/atomic.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/attach.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/bigfile.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/bigfile2.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/bigfile3.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/bug1test.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/cleanup.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/cltsrv.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/concur.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/cvar.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/cvar2.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dbmalloc.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dbmalloc1.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dceemu.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/depend.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/my.def
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/mygetval.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/mysetval.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dlltest.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/dtoa.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/env.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/errcodes.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/errset.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/exit.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/fdcach.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/fileio.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/foreign.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/forktest.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/formattm.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/freeif.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/fsync.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/getai.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/gethost.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/getproto.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/i2l.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/initclk.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/inrval.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/instrumt.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/intrio.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/intrupt.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/io_timeout.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/io_timeoutk.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/io_timeoutu.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/ioconthr.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/ipv6.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/join.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/joinkk.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/joinku.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/joinuk.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/joinuu.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/layer.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/lazyinit.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/libfilename.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/lltest.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/lock.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/lockfile.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/logger.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/macbuild/
   freeswitch/trunk/libs/js/nsprpub/pr/tests/macbuild/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/tests/macbuild/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/tests/macbuild/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/tests/macbuild/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/tests/makedir.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/many_cv.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/mbcs.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/multiacc.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/multiwait.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/nameshm1.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/nbconn.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/nblayer.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/nonblock.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/ntioto.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/ntoh.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/obsints.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/op_2long.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/op_excl.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/op_filnf.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/op_filok.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/op_noacc.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/op_nofil.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/openfile.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/parent.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/peek.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/perf.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/pipeping.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/pipeping2.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/pipepong.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/pipepong2.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/pipeself.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/poll_er.c   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pr/tests/poll_nm.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/poll_to.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/pollable.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/prftest.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/prftest1.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/prftest2.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/primblok.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/priotest.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/provider.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/prpoll.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/prpollml.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/prselect.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/prttools.h
   freeswitch/trunk/libs/js/nsprpub/pr/tests/randseed.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/ranfile.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/rmdir.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/runtests.ksh   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pr/tests/runtests.sh   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pr/tests/runy2ktests.ksh
   freeswitch/trunk/libs/js/nsprpub/pr/tests/rwlocktest.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sel_spd.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/selct_er.c   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pr/tests/selct_nm.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/selct_to.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/select2.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/selintr.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sem.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sema.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/semaerr.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/semaerr1.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/semaping.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/semapong.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sendzlf.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/server_test.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_kk.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_ku.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_uk.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_uu.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/short_thread.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sigpipe.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sleep.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/socket.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sockopt.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sockping.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sockpong.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sprintf.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sproc_ch.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/sproc_p.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/stack.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/stat.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/stdio.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/str2addr.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/strod.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/suspend.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/switch.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/system.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/testbit.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/testfile.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/threads.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/thrpool_client.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/thrpool_server.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/thruput.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/time.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/timemac.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/timetest.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/tmoacc.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/tmocon.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/tpd.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/udpsrv.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/ut_ttools.h
   freeswitch/trunk/libs/js/nsprpub/pr/tests/vercheck.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/version.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/CVS/
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popfile.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popfind.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popfont.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/poppad.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/poppad.h
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/poppad.ico   (contents, props changed)
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/poppad.rc
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popprnt0.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/readme.1st
   freeswitch/trunk/libs/js/nsprpub/pr/tests/writev.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/xnotify.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/y2k.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/y2ktmo.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/yield.c
   freeswitch/trunk/libs/js/nsprpub/pr/tests/zerolen.c
   freeswitch/trunk/libs/js/nsprpub/tools/
   freeswitch/trunk/libs/js/nsprpub/tools/.cvsignore
   freeswitch/trunk/libs/js/nsprpub/tools/CVS/
   freeswitch/trunk/libs/js/nsprpub/tools/CVS/Entries
   freeswitch/trunk/libs/js/nsprpub/tools/CVS/Repository
   freeswitch/trunk/libs/js/nsprpub/tools/CVS/Root
   freeswitch/trunk/libs/js/nsprpub/tools/Makefile.in
   freeswitch/trunk/libs/js/nsprpub/tools/httpget.c
   freeswitch/trunk/libs/js/nsprpub/tools/tail.c
   freeswitch/trunk/libs/js/shtool   (contents, props changed)
   freeswitch/trunk/libs/js/src/
   freeswitch/trunk/libs/js/src/fdlibm/
   freeswitch/trunk/libs/js/src/fdlibm/e_acos.c
   freeswitch/trunk/libs/js/src/fdlibm/e_acosh.c
   freeswitch/trunk/libs/js/src/fdlibm/e_asin.c
   freeswitch/trunk/libs/js/src/fdlibm/e_atan2.c
   freeswitch/trunk/libs/js/src/fdlibm/e_atanh.c
   freeswitch/trunk/libs/js/src/fdlibm/e_cosh.c
   freeswitch/trunk/libs/js/src/fdlibm/e_exp.c
   freeswitch/trunk/libs/js/src/fdlibm/e_fmod.c
   freeswitch/trunk/libs/js/src/fdlibm/e_gamma.c
   freeswitch/trunk/libs/js/src/fdlibm/e_gamma_r.c
   freeswitch/trunk/libs/js/src/fdlibm/e_hypot.c
   freeswitch/trunk/libs/js/src/fdlibm/e_j0.c
   freeswitch/trunk/libs/js/src/fdlibm/e_j1.c
   freeswitch/trunk/libs/js/src/fdlibm/e_jn.c
   freeswitch/trunk/libs/js/src/fdlibm/e_lgamma.c
   freeswitch/trunk/libs/js/src/fdlibm/e_lgamma_r.c
   freeswitch/trunk/libs/js/src/fdlibm/e_log.c
   freeswitch/trunk/libs/js/src/fdlibm/e_log10.c
   freeswitch/trunk/libs/js/src/fdlibm/e_pow.c
   freeswitch/trunk/libs/js/src/fdlibm/e_rem_pio2.c
   freeswitch/trunk/libs/js/src/fdlibm/e_remainder.c
   freeswitch/trunk/libs/js/src/fdlibm/e_scalb.c
   freeswitch/trunk/libs/js/src/fdlibm/e_sinh.c
   freeswitch/trunk/libs/js/src/fdlibm/e_sqrt.c
   freeswitch/trunk/libs/js/src/fdlibm/fdlibm.h
   freeswitch/trunk/libs/js/src/fdlibm/k_cos.c
   freeswitch/trunk/libs/js/src/fdlibm/k_rem_pio2.c
   freeswitch/trunk/libs/js/src/fdlibm/k_sin.c
   freeswitch/trunk/libs/js/src/fdlibm/k_standard.c
   freeswitch/trunk/libs/js/src/fdlibm/k_tan.c
   freeswitch/trunk/libs/js/src/fdlibm/s_asinh.c
   freeswitch/trunk/libs/js/src/fdlibm/s_atan.c
   freeswitch/trunk/libs/js/src/fdlibm/s_cbrt.c
   freeswitch/trunk/libs/js/src/fdlibm/s_ceil.c
   freeswitch/trunk/libs/js/src/fdlibm/s_copysign.c
   freeswitch/trunk/libs/js/src/fdlibm/s_cos.c
   freeswitch/trunk/libs/js/src/fdlibm/s_erf.c
   freeswitch/trunk/libs/js/src/fdlibm/s_expm1.c
   freeswitch/trunk/libs/js/src/fdlibm/s_fabs.c
   freeswitch/trunk/libs/js/src/fdlibm/s_finite.c
   freeswitch/trunk/libs/js/src/fdlibm/s_floor.c
   freeswitch/trunk/libs/js/src/fdlibm/s_frexp.c
   freeswitch/trunk/libs/js/src/fdlibm/s_ilogb.c
   freeswitch/trunk/libs/js/src/fdlibm/s_isnan.c
   freeswitch/trunk/libs/js/src/fdlibm/s_ldexp.c
   freeswitch/trunk/libs/js/src/fdlibm/s_lib_version.c
   freeswitch/trunk/libs/js/src/fdlibm/s_log1p.c
   freeswitch/trunk/libs/js/src/fdlibm/s_logb.c
   freeswitch/trunk/libs/js/src/fdlibm/s_matherr.c
   freeswitch/trunk/libs/js/src/fdlibm/s_modf.c
   freeswitch/trunk/libs/js/src/fdlibm/s_nextafter.c
   freeswitch/trunk/libs/js/src/fdlibm/s_rint.c
   freeswitch/trunk/libs/js/src/fdlibm/s_scalbn.c
   freeswitch/trunk/libs/js/src/fdlibm/s_signgam.c
   freeswitch/trunk/libs/js/src/fdlibm/s_significand.c
   freeswitch/trunk/libs/js/src/fdlibm/s_sin.c
   freeswitch/trunk/libs/js/src/fdlibm/s_tan.c
   freeswitch/trunk/libs/js/src/fdlibm/s_tanh.c
   freeswitch/trunk/libs/js/src/fdlibm/w_acos.c
   freeswitch/trunk/libs/js/src/fdlibm/w_acosh.c
   freeswitch/trunk/libs/js/src/fdlibm/w_asin.c
   freeswitch/trunk/libs/js/src/fdlibm/w_atan2.c
   freeswitch/trunk/libs/js/src/fdlibm/w_atanh.c
   freeswitch/trunk/libs/js/src/fdlibm/w_cosh.c
   freeswitch/trunk/libs/js/src/fdlibm/w_exp.c
   freeswitch/trunk/libs/js/src/fdlibm/w_fmod.c
   freeswitch/trunk/libs/js/src/fdlibm/w_gamma.c
   freeswitch/trunk/libs/js/src/fdlibm/w_gamma_r.c
   freeswitch/trunk/libs/js/src/fdlibm/w_hypot.c
   freeswitch/trunk/libs/js/src/fdlibm/w_j0.c
   freeswitch/trunk/libs/js/src/fdlibm/w_j1.c
   freeswitch/trunk/libs/js/src/fdlibm/w_jn.c
   freeswitch/trunk/libs/js/src/fdlibm/w_lgamma.c
   freeswitch/trunk/libs/js/src/fdlibm/w_lgamma_r.c
   freeswitch/trunk/libs/js/src/fdlibm/w_log.c
   freeswitch/trunk/libs/js/src/fdlibm/w_log10.c
   freeswitch/trunk/libs/js/src/fdlibm/w_pow.c
   freeswitch/trunk/libs/js/src/fdlibm/w_remainder.c
   freeswitch/trunk/libs/js/src/fdlibm/w_scalb.c
   freeswitch/trunk/libs/js/src/fdlibm/w_sinh.c
   freeswitch/trunk/libs/js/src/fdlibm/w_sqrt.c
   freeswitch/trunk/libs/js/src/js.c
   freeswitch/trunk/libs/js/src/js.msg
   freeswitch/trunk/libs/js/src/jsapi.c
   freeswitch/trunk/libs/js/src/jsapi.h
   freeswitch/trunk/libs/js/src/jsarena.c
   freeswitch/trunk/libs/js/src/jsarena.h
   freeswitch/trunk/libs/js/src/jsarray.c
   freeswitch/trunk/libs/js/src/jsarray.h
   freeswitch/trunk/libs/js/src/jsatom.c
   freeswitch/trunk/libs/js/src/jsatom.h
   freeswitch/trunk/libs/js/src/jsautocfg.h
   freeswitch/trunk/libs/js/src/jsbit.h
   freeswitch/trunk/libs/js/src/jsbool.c
   freeswitch/trunk/libs/js/src/jsbool.h
   freeswitch/trunk/libs/js/src/jsclist.h
   freeswitch/trunk/libs/js/src/jscntxt.c
   freeswitch/trunk/libs/js/src/jscntxt.h
   freeswitch/trunk/libs/js/src/jscompat.h
   freeswitch/trunk/libs/js/src/jsconfig.h
   freeswitch/trunk/libs/js/src/jscpucfg.c
   freeswitch/trunk/libs/js/src/jscpucfg.h
   freeswitch/trunk/libs/js/src/jsdate.c
   freeswitch/trunk/libs/js/src/jsdate.h
   freeswitch/trunk/libs/js/src/jsdbgapi.c
   freeswitch/trunk/libs/js/src/jsdbgapi.h
   freeswitch/trunk/libs/js/src/jsdhash.c
   freeswitch/trunk/libs/js/src/jsdhash.h
   freeswitch/trunk/libs/js/src/jsdso.c
   freeswitch/trunk/libs/js/src/jsdso.h
   freeswitch/trunk/libs/js/src/jsdtoa.c
   freeswitch/trunk/libs/js/src/jsdtoa.h
   freeswitch/trunk/libs/js/src/jsemit.c
   freeswitch/trunk/libs/js/src/jsemit.h
   freeswitch/trunk/libs/js/src/jsexn.c
   freeswitch/trunk/libs/js/src/jsexn.h
   freeswitch/trunk/libs/js/src/jsfile.c
   freeswitch/trunk/libs/js/src/jsfile.h
   freeswitch/trunk/libs/js/src/jsfile.msg
   freeswitch/trunk/libs/js/src/jsfun.c
   freeswitch/trunk/libs/js/src/jsfun.h
   freeswitch/trunk/libs/js/src/jsgc.c
   freeswitch/trunk/libs/js/src/jsgc.h
   freeswitch/trunk/libs/js/src/jshash.c
   freeswitch/trunk/libs/js/src/jshash.h
   freeswitch/trunk/libs/js/src/jsinterp.c
   freeswitch/trunk/libs/js/src/jsinterp.h
   freeswitch/trunk/libs/js/src/jslibmath.h
   freeswitch/trunk/libs/js/src/jslock.c
   freeswitch/trunk/libs/js/src/jslock.h
   freeswitch/trunk/libs/js/src/jslog2.c
   freeswitch/trunk/libs/js/src/jslong.c
   freeswitch/trunk/libs/js/src/jslong.h
   freeswitch/trunk/libs/js/src/jsmath.c
   freeswitch/trunk/libs/js/src/jsmath.h
   freeswitch/trunk/libs/js/src/jsnum.c
   freeswitch/trunk/libs/js/src/jsnum.h
   freeswitch/trunk/libs/js/src/jsobj.c
   freeswitch/trunk/libs/js/src/jsobj.h
   freeswitch/trunk/libs/js/src/jsopcode.c
   freeswitch/trunk/libs/js/src/jsopcode.h
   freeswitch/trunk/libs/js/src/jsopcode.tbl
   freeswitch/trunk/libs/js/src/jsosdep.h
   freeswitch/trunk/libs/js/src/jsotypes.h
   freeswitch/trunk/libs/js/src/jsparse.c
   freeswitch/trunk/libs/js/src/jsparse.h
   freeswitch/trunk/libs/js/src/jsprf.c
   freeswitch/trunk/libs/js/src/jsprf.h
   freeswitch/trunk/libs/js/src/jsprvtd.h
   freeswitch/trunk/libs/js/src/jspubtd.h
   freeswitch/trunk/libs/js/src/jsregexp.c
   freeswitch/trunk/libs/js/src/jsregexp.h
   freeswitch/trunk/libs/js/src/jsscan.c
   freeswitch/trunk/libs/js/src/jsscan.h
   freeswitch/trunk/libs/js/src/jsscope.c
   freeswitch/trunk/libs/js/src/jsscope.h
   freeswitch/trunk/libs/js/src/jsscript.c
   freeswitch/trunk/libs/js/src/jsscript.h
   freeswitch/trunk/libs/js/src/jsshell.msg
   freeswitch/trunk/libs/js/src/jsstddef.h
   freeswitch/trunk/libs/js/src/jsstr.c
   freeswitch/trunk/libs/js/src/jsstr.h
   freeswitch/trunk/libs/js/src/jstypes.h
   freeswitch/trunk/libs/js/src/jsutil.c
   freeswitch/trunk/libs/js/src/jsutil.h
   freeswitch/trunk/libs/js/src/jsxdrapi.c
   freeswitch/trunk/libs/js/src/jsxdrapi.h
   freeswitch/trunk/libs/js/src/jsxml.c
   freeswitch/trunk/libs/js/src/jsxml.h
   freeswitch/trunk/libs/js/src/perlconnect/
   freeswitch/trunk/libs/js/src/perlconnect/JS.pm
   freeswitch/trunk/libs/js/src/perlconnect/JS.xs
   freeswitch/trunk/libs/js/src/perlconnect/MANIFEST
   freeswitch/trunk/libs/js/src/perlconnect/Makefile.PL.in
   freeswitch/trunk/libs/js/src/perlconnect/PerlConnect.pm
   freeswitch/trunk/libs/js/src/perlconnect/jsperl.c
   freeswitch/trunk/libs/js/src/perlconnect/jsperl.h
   freeswitch/trunk/libs/js/src/perlconnect/jsperlpvt.h
   freeswitch/trunk/libs/js/src/perlconnect/typemap
   freeswitch/trunk/libs/js/src/prmjtime.c
   freeswitch/trunk/libs/js/src/prmjtime.h

Log:
add js to tree

Added: freeswitch/trunk/libs/js/AUTHORS
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/AUTHORS	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,17 @@
+   _        ___  ____ ____  ____     _      
+  |_|_ _   / _ \/ ___/ ___||  _ \   (_)___  
+  _|_||_| | | | \___ \___ \| |_) |  | / __| 
+ |_||_|_| | |_| |___) |__) |  __/   | \__ \ 
+  |_|_|_|  \___/|____/____/|_|     _/ |___/ 
+                                  |__/      
+
+  OSSP js - Mozilla JavaScript Engine
+
+  LINKS
+
+  Brendan Eich <brendan at mozilla.org> et al
+      - Mozilla JavaScript implementation
+
+  Ralf S. Engelschall <rse at engelschall.com>
+      - OSSP js distribution of Mozilla JavaScript
+

Added: freeswitch/trunk/libs/js/ChangeLog
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/ChangeLog	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,165 @@
+   _        ___  ____ ____  ____     _      
+  |_|_ _   / _ \/ ___/ ___||  _ \   (_)___  
+  _|_||_| | | | \___ \___ \| |_) |  | / __| 
+ |_||_|_| | |_| |___) |__) |  __/   | \__ \ 
+  |_|_|_|  \___/|____/____/|_|     _/ |___/ 
+                                  |__/      
+
+  OSSP js - Mozilla JavaScript Engine
+
+  CHANGELOG
+
+  This is a list of all changes to OSSP js.
+
+  Changes between 1.6.20060803 and 1.6.20060820 (2006-08-03 to 2006-08-20)
+
+   o Add support for UTF-8 C strings in the API and internally by
+     adding a --with-utf8 build-time options which builds the code
+     with JS_C_STRINGS_ARE_UTF8.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Upgrade to upstream sources as of 2006-08-20.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+  Changes between 1.6.20060731 and 1.6.20060803 (2006-07-31 to 2006-08-03)
+
+   o Add optional Dynamic Shared Object (DSO) support (see src/jsdso.[ch]).
+     This comes in two flavors:
+
+     1. Provide two public C API functions...
+        JSBool JS_DSOLoad   (JSContext *cx, int *id, const char *filename);
+        JSBool JS_DSOUnload (JSContext *cx, int  id);
+        ...as an ultra-thin wrapper around the POSIX dlopen(3) API. It
+        especially mimics the BSD RTLD behaviour of calling pre-defined
+        functions (mandatory "js_DSO_load" and optional "js_DSO_unload")
+        inside the DSO after/before the dlopen/dlclose calls. This
+        allows the DSOs to perform their init/shutdown actions.
+
+     2. Provide a small JavaScript global object "DSO" which binds
+        the two public DSO C API functions into the JavaScript language
+        as "DSO.load" and "DSO.unload". The "DSO" object can be created
+        by the friend C API function js_InitDSOClass(). This function is
+        used by the command-linne interface "js" by default.
+
+     As a result the OSSP Mozilla JavaScript engine is now able to
+     dynamically load C extensions similar to what other programming
+     languages provide since a longer time.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Be more clean and replace weak "#if JS_HAS_FILE_OBJECT" constructs
+     with the stronger "#if defined(JS_HAS_FILE_OBJECT) && (JS_HAS_FILE_OBJECT - 0)"
+     as the JS_HAS_FILE_OBJECT can be not defined at all (in contrast to
+     other JS_HAS_XXXX defines which are all listed in src/jsconfig.h)
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Fix a bunch of compiler warnings.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Change from -O2 to -O0 and without -Wshadow under --enable-debug.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+  Changes between 1.6.20060730 and 1.6.20060731 (2006-07-30 to 2006-07-31)
+
+   o Fix "make distclean": src/perlconnect/Makefile.PL is always generated
+     and hence has to be always deleted.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Fix "devtool dist" command: "make man" does not exist.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Fix "make install": the executable "js" was not installed via GNU
+     libtool and this way under --enable-shared the wrapper script was
+     installed only.
+     [Alfred Reibenschuh <alfred.reibenschuh at it-austria.com>]
+
+   o Add a src/perlconnect/MANIFEST file to make ExtUtils::MakeMaker more happy.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Fix "make install": js-config.1 was not installed.
+     [Alfred Reibenschuh <alfred.reibenschuh at it-austria.com>]
+
+   o Use Autoconf macros AC_CANONICAL_BUILD and AC_CANONICAL_HOST to
+     make sure that the host identification is really available.
+     [Alfred Reibenschuh <alfred.reibenschuh at it-austria.com>]
+
+   o Upgrade to upstream sources as of 2006-07-31.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+  Changes between 1.6.20060729 and 1.6.20060730 (2006-07-29 to 2006-07-30)
+
+   o Add support for Windows CygWin and MinGW environments.
+     [Ralf S. Engelschall <rse at engelschall.com>,
+      Andrew Vajoczki <vajoczki at yahoo.com>]
+
+   o Upgrade to upstream sources as of 2006-07-30.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+  Changes between 1.6.20060724 and 1.6.20060729 (2006-07-24 to 2006-07-29)
+
+   o Upgrade to upstream sources as of 2006-07-29.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Changed GNU libtool shared library versioning from 0:0 to 1:6.
+     [Ralf S. Engelschall <rse at engelschall.com>,
+      Alfred Reibenschuh <alfred.reibenschuh at it-austria.com>]
+
+   o Increase portability by gracefully downgrading the stat(2) use of
+     st_birthtime to st_birthtimensec or even st_ctime.
+     [Ralf S. Engelschall <rse at engelschall.com>,
+      Andrew Vajoczki <vajoczki at yahoo.com>]
+
+   o Apply a few more upstream fixes to jsfile.c.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+  Changes between 1.6.20060722 and 1.6.20060724 (2006-07-22 to 2006-07-24)
+
+   o Apply multiple code cleanups and bugfixes.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Move definitions of XP_UNIX and EXPORT_JS_API back from jstypes.h
+     to configure.ac (and this way the command-line) to not break the
+     use of jstypes.h as a regular API header in JS based applications.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Consistently mark all OSSP bugfixes with a "/* BUGFIX */" tag on
+     the "#ifdef OSSP" line. This way one can more easily see what
+     are specific OSSP specific changes what should be taken over by
+     upstream vendor.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Fix an incorrect argument type bug in jsfile.c related to a call to
+     js_InflateString(). A "size_t *" has to be passed, not a "size_t".
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Upgrade from (the Mozilla Firefox 1.5 pinned version) SpiderMonkey
+     1.6.20060722 to the (SPIDERMONKEY_1_6_0_BRANCH based) 1.6.20060724
+     upstream version.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Added jslint (see http://www.jslint.com/) together with some
+     home-brewn option parser. The result is installed as
+     a stand-alone "jslint" program.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Install all src/js*.h headers during "make install" to allow
+     applications to at least optionally poke around in the internals.
+     This also allows an application to call js_InitFileClass() from
+     <jsfile.h> without us having to really call this function in the
+     standard API function JS_InitStandardClasses().
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+   o Change the default of the --with-file/--without from --without-file
+     to --with-file (enable the File object by default), but activate
+     it only in the CLI (where it doesn't hurt and where it is actually
+     really required to get something useful running there in practice)
+     but explicitly _NOT_ in JS_InitStandardClasses() (as this is
+     what would hurt the security in applications which assume that
+     JS_InitStandardClasses() initialized only really the standard
+     classes).
+     [Ralf S. Engelschall <rse at engelschall.com>]
+
+  Changes between *GENESIS* and 1.6.20060722 (2006-06-XX to 2006-07-22)
+   
+   o Initial OSSP js distribution of Mozilla JavaScript 1.6 as of 2006-07-22.
+     [Ralf S. Engelschall <rse at engelschall.com>]
+

Added: freeswitch/trunk/libs/js/LINKS
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/LINKS	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,28 @@
+   _        ___  ____ ____  ____     _      
+  |_|_ _   / _ \/ ___/ ___||  _ \   (_)___  
+  _|_||_| | | | \___ \___ \| |_) |  | / __| 
+ |_||_|_| | |_| |___) |__) |  __/   | \__ \ 
+  |_|_|_|  \___/|____/____/|_|     _/ |___/ 
+                                  |__/      
+
+  OSSP js - Mozilla JavaScript Engine
+
+  LINKS
+
+  o http://www.mozilla.org/js/
+  o http://www.mozilla.org/js/language/
+  o http://www.mozilla.org/js/spidermonkey/
+  o http://www.ecma-international.org/publications/standards/Ecma-262.htm
+  o http://developer.mozilla.org/en/docs/JavaScript_C_Engine_Embedder's_Guide
+  o http://developer.mozilla.org/en/docs/JSAPI_Reference
+  o http://lxr.mozilla.org/mozilla/source/js/src
+  o http://lxr.mozilla.org/mozilla/source/js/src/README.html
+  o http://www.jibbering.com/faq/
+  o http://www.faqts.com/knowledge_base/index.phtml/fid/53/
+  o http://users.skynet.be/saw/SpiderMonkey.htm
+  o http://groups.google.com/group/mozilla.dev.tech.js-engine
+  o http://groups.google.com/group/netscape.public.mozilla.jseng
+  o http://groups.google.com/group/comp.lang.javascript
+  o http://burstproject.org/build/doc/shells.html
+  o http://developer.mozilla.org/es4/
+

Added: freeswitch/trunk/libs/js/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,228 @@
+##
+##  OSSP js - JavaScript Engine
+##  Copyright (c) 1998-2006 Mozilla <http://www.mozilla.org/>
+##
+##  This file is part of OSSP js, a distribution of the Mozilla JavaScript
+##  reference implementation, which can found at http://www.ossp.org/pkg/lib/js/
+##
+##  Permission to use, copy, modify, and distribute this software for
+##  any purpose with or without fee is hereby granted, provided that
+##  the above copyright notice and this permission notice appear in all
+##  copies.
+##
+##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+##  SUCH DAMAGE.
+##
+##  Makefile.in: make(1) build procedure
+##
+
+ at SET_MAKE@
+
+VPATH        = @srcdir@
+srcdir       = @srcdir@
+top_srcdir   = @top_srcdir@
+
+DESTDIR      =
+prefix       = @prefix@
+exec_prefix  = @exec_prefix@
+datarootdir  = @datarootdir@
+bindir       = @bindir@
+libdir       = @libdir@
+includedir   = @includedir@
+mandir       = @mandir@
+
+CC           = @CC@
+CPPFLAGS     = @CPPFLAGS@ @DEFS@ -Isrc
+CFLAGS       = @CFLAGS@
+LDFLAGS      = @LDFLAGS@
+LIBS         = @LIBS@
+
+CLI_CFLAGS   = @CLI_CFLAGS@
+CLI_CPPFLAGS = @CLI_CPPFLAGS@
+CLI_LDFLAGS  = @CLI_LDFLAGS@
+CLI_LIBS     = @CLI_LIBS@
+
+RM           = rm -f
+CP           = cp
+RMDIR        = rmdir
+SHTOOL       = ./shtool
+LIBTOOL      = ./libtool
+PERL         = @PERL@
+TRUE         = true
+
+LIB_OBJS     = src/jsapi.lo                \
+               src/jsarena.lo              \
+               src/jsarray.lo              \
+               src/jsatom.lo               \
+               src/jsbool.lo               \
+               src/jscntxt.lo              \
+               src/jsdate.lo               \
+               src/jsdbgapi.lo             \
+               src/jsdhash.lo              \
+               src/jsdtoa.lo               \
+               src/jsemit.lo               \
+               src/jsexn.lo                \
+               src/jsfile.lo               \
+               src/jsfun.lo                \
+               src/jsgc.lo                 \
+               src/jshash.lo               \
+               src/jsinterp.lo             \
+               src/jslock.lo               \
+               src/jslog2.lo               \
+               src/jslong.lo               \
+               src/jsmath.lo               \
+               src/jsnum.lo                \
+               src/jsobj.lo                \
+               src/jsopcode.lo             \
+               src/jsparse.lo              \
+               src/jsprf.lo                \
+               src/jsregexp.lo             \
+               src/jsscan.lo               \
+               src/jsscope.lo              \
+               src/jsscript.lo             \
+               src/jsstr.lo                \
+               src/jsutil.lo               \
+               src/jsxdrapi.lo             \
+               src/jsxml.lo                \
+               src/prmjtime.lo             \
+               src/jsdso.lo                \
+               src/fdlibm/e_acos.lo        \
+               src/fdlibm/e_asin.lo        \
+               src/fdlibm/e_atan2.lo       \
+               src/fdlibm/e_exp.lo         \
+               src/fdlibm/e_fmod.lo        \
+               src/fdlibm/e_log.lo         \
+               src/fdlibm/e_pow.lo         \
+               src/fdlibm/e_rem_pio2.lo    \
+               src/fdlibm/s_scalbn.lo      \
+               src/fdlibm/e_sqrt.lo        \
+               src/fdlibm/k_cos.lo         \
+               src/fdlibm/k_sin.lo         \
+               src/fdlibm/k_rem_pio2.lo    \
+               src/fdlibm/k_tan.lo         \
+               src/fdlibm/s_atan.lo        \
+               src/fdlibm/s_ceil.lo        \
+               src/fdlibm/s_copysign.lo    \
+               src/fdlibm/s_cos.lo         \
+               src/fdlibm/s_fabs.lo        \
+               src/fdlibm/s_finite.lo      \
+               src/fdlibm/s_floor.lo       \
+               src/fdlibm/s_isnan.lo       \
+               src/fdlibm/s_lib_version.lo \
+               src/fdlibm/s_sin.lo         \
+               src/fdlibm/s_tan.lo         \
+               src/fdlibm/w_acos.lo        \
+               src/fdlibm/w_asin.lo        \
+               src/fdlibm/w_atan2.lo       \
+               src/fdlibm/w_exp.lo         \
+               src/fdlibm/w_fmod.lo        \
+               src/fdlibm/w_log.lo         \
+               src/fdlibm/w_pow.lo         \
+               src/fdlibm/w_sqrt.lo
+LIB_NAME     = libjs.la
+
+CLI_OBJS     = src/js.o @CLI_OBJS@
+CLI_NAME     = js
+
+WITH_PERL    = @WITH_PERL@
+
+TARGETS      = $(LIB_NAME) $(CLI_NAME)
+
+.SUFFIXES:
+.SUFFIXES: .c .o .lo
+
+all: $(TARGETS) subdirs
+
+subdirs:
+	@if [ ".$(WITH_PERL)" = ".yes" ]; then \
+	    (cd src/perlconnect; $(PERL) Makefile.PL; $(MAKE) $(MFLAGS)); \
+	fi
+
+.c.o:
+	$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
+
+.c.lo:
+	@$(LIBTOOL) --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
+
+$(LIB_NAME): $(LIB_OBJS)
+	@$(LIBTOOL) --mode=link $(CC) -o $(LIB_NAME) $(LIB_OBJS) -rpath $(libdir) -version-info 1:6
+
+$(CLI_NAME): $(CLI_OBJS) $(LIB_NAME)
+	@$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(CLI_LDFLAGS) -o $(CLI_NAME) $(CLI_OBJS) $(LIB_NAME) $(LIBS) $(CLI_LIBS)
+src/js.o: src/js.c
+	$(CC) $(CPPFLAGS) $(CLI_CPPFLAGS) $(CFLAGS) $(CLI_CFLAGS) -o $@ -c $<
+src/perlconnect/jsperl.o: src/perlconnect/jsperl.c
+	$(CC) $(CPPFLAGS) $(CLI_CPPFLAGS) $(CFLAGS) $(CLI_CFLAGS) -o $@ -c $<
+
+$(LIB_OBJS): src/jsautocfg.h
+src/jsautocfg.h: jscpucfg
+	-rm -f $@ src/jsautocfg.h
+	$(LIBTOOL) --mode=execute ./jscpucfg >src/jsautocfg.h
+jscpucfg.o: src/jscpucfg.c
+	$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
+jscpucfg: jscpucfg.o
+	@$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o jscpucfg jscpucfg.o $(LIBS)
+src/jsopcode.h src/jsopcode.c: src/jsopcode.tbl
+
+.PHONY: install
+install: all
+	$(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(prefix)
+	$(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(bindir)
+	$(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(mandir)/man1
+	$(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(mandir)/man3
+	$(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(includedir)/js
+	$(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(libdir)/pkgconfig
+	$(SHTOOL) install -c -m 644 js.1 $(DESTDIR)$(mandir)/man1/
+	$(SHTOOL) install -c -m 644 js-config.1 $(DESTDIR)$(mandir)/man1/
+	$(SHTOOL) install -c -m 644 js.3 $(DESTDIR)$(mandir)/man3/
+	$(SHTOOL) install -c -m 644 src/js*.h $(DESTDIR)$(includedir)/js/
+	@$(LIBTOOL) --mode=install $(SHTOOL) install -c -m 644 $(LIB_NAME) $(DESTDIR)$(libdir)/
+	$(SHTOOL) install -c -m 644 js.pc $(DESTDIR)$(libdir)/pkgconfig/
+	$(SHTOOL) install -c -m 755 js-config.sh $(DESTDIR)$(bindir)/js-config
+	@$(LIBTOOL) --mode=install $(SHTOOL) install -c -m 755 js $(DESTDIR)$(bindir)/
+	$(SHTOOL) install -e 's;#!\./js;#!$(bindir)/js;' -c -m 755 jslint.js $(DESTDIR)$(bindir)/jslint
+	@if [ ".$(WITH_PERL)" = ".yes" ]; then \
+	    (cd src/perlconnect; $(MAKE) $(MFLAGS) install DESTDIR=$(DESTDIR)); \
+	fi
+
+.PHONY: clean
+clean:
+	-$(RM) jscpucfg $(LIB_NAME) $(LIB_OBJS)
+	-$(RM) js src/js.o
+	-$(RM) -r .libs >/dev/null 2>&1 || $(TRUE)
+	-$(RM) -r src/.libs src/fdlibm/.libs >/dev/null 2>&1 || $(TRUE)
+	-$(RM) *.o *.lo
+	@if [ ".$(WITH_PERL)" = ".yes" ]; then \
+	    ( cd src/perlconnect; \
+	      if [ -f Makefile ]; then $(MAKE) $(MFLAGS) clean || $(TRUE); fi; \
+	      if [ -f Makefile.old ]; then mv Makefile.old Makefile; fi; \
+	    ); \
+	fi
+
+distclean: clean
+	-$(RM) config.log config.status config.cache
+	-$(RM) Makefile config.h js.pc js-config.sh
+	-$(RM) libtool
+	-$(RM) src/perlconnect/Makefile.PL
+	@if [ ".$(WITH_PERL)" = ".yes" ]; then \
+	    ( cd src/perlconnect; \
+	      if [ -f Makefile ]; then $(MAKE) $(MFLAGS) distclean || $(TRUE); fi; \
+	      $(RM) -f Makefile Makefile.old || $(TRUE); \
+	    ); \
+	fi
+
+realclean: distclean
+	-$(RM) configure config.h.in config.h.in~
+	-$(RM) shtool
+	-$(RM) ltmain.sh libtool.m4 config.guess config.sub
+

Added: freeswitch/trunk/libs/js/README
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/README	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,73 @@
+   _        ___  ____ ____  ____     _      
+  |_|_ _   / _ \/ ___/ ___||  _ \   (_)___  
+  _|_||_| | | | \___ \___ \| |_) |  | / __| 
+ |_||_|_| | |_| |___) |__) |  __/   | \__ \ 
+  |_|_|_|  \___/|____/____/|_|     _/ |___/ 
+                                  |__/      
+
+  OSSP js - Mozilla JavaScript Engine
+  Version 1.6.20060820 (20-Aug-2006)
+
+  ABSTRACT
+
+  OSSP js is a stand-alone distribution of the JavaScript (JS)
+  programming language reference implementation from Mozilla -- aka
+  "JSRef" or "SpiderMonkey". This distribution provides a smart,
+  stand-alone and portable distribution of Mozilla JavaScript through a
+  build environment based on GNU autoconf, GNU libtool and GNU shtool,
+  including support for easy JavaScript build-time feature set selection
+  (ECMA-3, JS-1.5, JS-1.6), optional CLI line editing support, optional
+  "stdio" based File object support and JS/Perl bindings. Additionally,
+  the C API in "libjs" contains both the JavaScript engine and the
+  required Sun math library ("fdlibm") and with all internal symbols
+  carefully protected under the "js" namespace. Finally, a js-config(1)
+  utility and a pkg-config(1) specification is provided to allow
+  applications to easily build with the JavaScript C API.
+
+  JUSTIFICATION
+
+  OSSP js was created because for OSSP and similar pedantic C coding
+  projects a smart, stand-alone, portable, clean, powerful and
+  robust scripting language engine is required. JavaScript is a
+  great programming language and Mozilla JavaScript "SpiderMonkey"
+  definitely is an acceptable clean, powerful and robust implementation.
+  Unfortunately there is just a stand-alone distribution released from
+  time to time by Mozilla and it is far away from really being smart,
+  stand-alone and portable. At least for OSSP it was not acceptable
+  having to tell the community that for small and stand-alone C
+  components like the OSSP components they either have to install the
+  great but large Mozilla Firefox application (where Mozilla JavaScript
+  is included) or have to fiddle around theirself with an older
+  stand-alone JavaScript distribution and its weak build environment.
+  OSSP js combines the best from two worlds: the 1:1 repackaged
+  JavaScript code base from Mozilla and the usual amount of GNU
+  autoconf, GNU libtool and GNU shtool wrappers as always used by OSSP.
+  Additionally, stand-alone ("stdio" instead of NSPR based) File object
+  support was required.
+
+  VERSIONING
+
+  The version of OSSP js is M.N.YYYYMMDD where M.N is the JavaScript
+  branch and YYYYMMDD is the date where the JavaScript code was
+  extracted from the Mozilla CVS repository.
+
+  COPYRIGHT AND LICENSE
+
+  Copyright (c) 1998-2006 Mozilla <http://www.mozilla.org/>
+
+  This file is part of OSSP js, a repackaging of the Mozilla JavaScript
+  reference implementation, which can found at http://www.ossp.org/pkg/lib/js/
+
+  The content of this distribution is licensed under the Mozilla
+  Public License (MPL) 1.1 (see http://www.mozilla.org/MPL/) or
+  alternatively the GNU General Public License (GPL) 2.0 (see
+  http://www.gnu.org/licenses/gpl.html) or the GNU Lesser General Public
+  License (LGPL) 2.1 (see http://www.gnu.org/licenses/lgpl.html).
+
+  HOME
+
+  The latest release can be found on
+
+  o http://www.ossp.org/pkg/lib/js/
+  o  ftp://ftp.ossp.org/pkg/lib/js/
+

Added: freeswitch/trunk/libs/js/THANKS
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/THANKS	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,18 @@
+   _        ___  ____ ____  ____     _      
+  |_|_ _   / _ \/ ___/ ___||  _ \   (_)___  
+  _|_||_| | | | \___ \___ \| |_) |  | / __| 
+ |_||_|_| | |_| |___) |__) |  __/   | \__ \ 
+  |_|_|_|  \___/|____/____/|_|     _/ |___/ 
+                                  |__/      
+
+  OSSP js - Mozilla JavaScript Engine
+
+  THANKS
+
+  Credit has to be given to the following people who contributed ideas,
+  bugfixes, hints, gave platform feedback, etc. (in alphabetical order):
+
+    o  Thomas Lotterer             <thomas at lotterer.net>
+    o  Alfred Reibenschuh          <alfred.reibenschuh at it-austria.com>
+    o  Andrew Vajoczki             <vajoczki at yahoo.com>
+

Added: freeswitch/trunk/libs/js/TODO
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/TODO	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,17 @@
+   _        ___  ____ ____  ____     _      
+  |_|_ _   / _ \/ ___/ ___||  _ \   (_)___  
+  _|_||_| | | | \___ \___ \| |_) |  | / __| 
+ |_||_|_| | |_| |___) |__) |  __/   | \__ \ 
+  |_|_|_|  \___/|____/____/|_|     _/ |___/ 
+                                  |__/      
+
+  OSSP js - Mozilla JavaScript Engine
+
+  TODO
+
+  - nothing known at this point.
+
+  CANDO
+
+  - nothing known at this point.
+

Added: freeswitch/trunk/libs/js/VERSION
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/VERSION	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,6 @@
+
+  VERSION -- Version Information for OSSP js (syntax: Text)
+  [automatically generated and maintained by GNU shtool]
+
+  This is OSSP js, Version 1.6.20060820 (20-Aug-2006)
+

Added: freeswitch/trunk/libs/js/aclocal.m4
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/aclocal.m4	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,226 @@
+dnl ##
+dnl ##  SA - OSSP Socket Abstraction Library
+dnl ##  Copyright (c) 2001-2003 Ralf S. Engelschall <rse at engelschall.com>
+dnl ##  Copyright (c) 2001-2003 The OSSP Project <http://www.ossp.org/>
+dnl ##  Copyright (c) 2001-2003 Cable & Wireless Deutschland <http://www.cw.com/de/>
+dnl ##
+dnl ##  This file is part of OSSP SA, a socket abstraction library which
+dnl ##  can be found at http://www.ossp.org/pkg/sa/.
+dnl ##
+dnl ##  Permission to use, copy, modify, and distribute this software for
+dnl ##  any purpose with or without fee is hereby granted, provided that
+dnl ##  the above copyright notice and this permission notice appear in all
+dnl ##  copies.
+dnl ##
+dnl ##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+dnl ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+dnl ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+dnl ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+dnl ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+dnl ##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+dnl ##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+dnl ##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+dnl ##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+dnl ##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+dnl ##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+dnl ##  SUCH DAMAGE.
+dnl ##
+dnl ##  aclocal.m4: GNU Autoconf local macro definitions
+dnl ##
+
+dnl ##
+dnl ##  Check whether compiler option works
+dnl ##
+dnl ##  configure.in:
+dnl ##    AC_COMPILER_OPTION(<name>, <display>, <option>,
+dnl ##                       <action-success>, <action-failure>)
+dnl ##
+
+AC_DEFUN(AC_COMPILER_OPTION,[dnl
+AC_MSG_CHECKING(whether compiler option(s) $2 work)
+AC_CACHE_VAL(ac_cv_compiler_option_$1,[
+SAVE_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $3"
+AC_TRY_COMPILE([],[], ac_cv_compiler_option_$1=yes, ac_cv_compiler_option_$1=no)
+CFLAGS="$SAVE_CFLAGS"
+])dnl
+if test ".$ac_cv_compiler_option_$1" = .yes; then
+    ifelse([$4], , :, [$4])
+else
+    ifelse([$5], , :, [$5])
+fi
+AC_MSG_RESULT([$ac_cv_compiler_option_$1])
+])dnl
+
+dnl ##
+dnl ##  Debugging Support
+dnl ##
+dnl ##  configure.in:
+dnl ##    AC_CHECK_DEBUGGING
+dnl ##
+
+AC_DEFUN(AC_CHECK_DEBUGGING,[dnl
+AC_ARG_ENABLE(debug,dnl
+[  --enable-debug          build for debugging (default=no)],
+[dnl
+if test ".$ac_cv_prog_gcc" = ".yes"; then
+    case "$CFLAGS" in
+        *-O* ) ;;
+           * ) CFLAGS="$CFLAGS -O0" ;;
+    esac
+    case "$CFLAGS" in
+        *-g* ) ;;
+           * ) CFLAGS="$CFLAGS -g" ;;
+    esac
+    case "$CFLAGS" in
+        *-pipe* ) ;;
+              * ) AC_COMPILER_OPTION(pipe, -pipe, -pipe, CFLAGS="$CFLAGS -pipe") ;;
+    esac
+    AC_COMPILER_OPTION(defdbg, -DDEBUG, -DDEBUG, CFLAGS="$CFLAGS -DDEBUG")
+    CFLAGS="$CFLAGS -pedantic"
+    CFLAGS="$CFLAGS -Wall"
+    WMORE="-Wpointer-arith -Wcast-align -Winline"
+    WMORE="$WMORE -Wmissing-prototypes -Wmissing-declarations -Wnested-externs"
+    AC_COMPILER_OPTION(wmore, -W<xxx>, $WMORE, CFLAGS="$CFLAGS $WMORE")
+    AC_COMPILER_OPTION(wnolonglong, -Wno-long-long, -Wno-long-long, CFLAGS="$CFLAGS -Wno-long-long")
+else
+    case "$CFLAGS" in
+        *-g* ) ;;
+           * ) CFLAGS="$CFLAGS -g" ;;
+    esac
+fi
+msg="enabled"
+],[
+AC_COMPILER_OPTION(defnodbg, -DNDEBUG, -DNDEBUG, CFLAGS="$CFLAGS -DNDEBUG")
+if test ".$ac_cv_prog_gcc" = ".yes"; then
+case "$CFLAGS" in
+    *-pipe* ) ;;
+          * ) AC_COMPILER_OPTION(pipe, -pipe, -pipe, CFLAGS="$CFLAGS -pipe") ;;
+esac
+fi
+case "$CFLAGS" in
+    *-g* ) CFLAGS=`echo "$CFLAGS" |\
+                   sed -e 's/ -g / /g' -e 's/ -g$//' -e 's/^-g //g' -e 's/^-g$//'` ;;
+esac
+case "$CXXFLAGS" in
+    *-g* ) CXXFLAGS=`echo "$CXXFLAGS" |\
+                     sed -e 's/ -g / /g' -e 's/ -g$//' -e 's/^-g //g' -e 's/^-g$//'` ;;
+esac
+msg=disabled
+])dnl
+AC_MSG_CHECKING(for compilation debug mode)
+AC_MSG_RESULT([$msg])
+if test ".$msg" = .enabled; then
+    enable_shared=no
+fi
+])
+
+dnl ##
+dnl ##  Check for C99 va_copy() implementation
+dnl ##  (and provide fallback implementation if neccessary)
+dnl ##
+dnl ##  configure.in:
+dnl ##    AC_CHECK_VA_COPY
+dnl ##  foo.c:
+dnl ##    #include "config.h"
+dnl ##    [...]
+dnl ##    va_copy(d,s)
+dnl ##
+dnl ##  This check is rather complex: first because we really have to
+dnl ##  try various possible implementations in sequence and second, we
+dnl ##  cannot define a macro in config.h with parameters directly.
+dnl ##
+
+dnl #   test program for va_copy() implementation
+changequote(<<,>>)
+m4_define(__va_copy_test, <<[
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define DO_VA_COPY(d, s) $1
+void test(char *str, ...)
+{
+    va_list ap, ap2;
+    int i;
+    va_start(ap, str);
+    DO_VA_COPY(ap2, ap);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    DO_VA_COPY(ap, ap2);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    va_end(ap);
+}
+int main(int argc, char *argv[])
+{
+    test("test", 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    exit(0);
+}
+]>>)
+changequote([,])
+
+dnl #   test driver for va_copy() implementation
+m4_define(__va_copy_check, [
+    AH_VERBATIM($1,
+[/* Predefined possible va_copy() implementation (id: $1) */
+#define __VA_COPY_USE_$1(d, s) $2])
+    if test ".$ac_cv_va_copy" = .; then
+        AC_TRY_RUN(__va_copy_test($2), [ac_cv_va_copy="$1"])
+    fi
+])
+
+dnl #   Autoconf check for va_copy() implementation checking
+AC_DEFUN(AC_CHECK_VA_COPY,[
+  dnl #   provide Autoconf display check message
+  AC_MSG_CHECKING(for va_copy() function)
+  dnl #   check for various implementations in priorized sequence   
+  AC_CACHE_VAL(ac_cv_va_copy, [
+    ac_cv_va_copy=""
+    dnl #   1. check for standardized C99 macro
+    __va_copy_check(C99, [va_copy((d), (s))])
+    dnl #   2. check for alternative/deprecated GCC macro
+    __va_copy_check(GCM, [VA_COPY((d), (s))])
+    dnl #   3. check for internal GCC macro (high-level define)
+    __va_copy_check(GCH, [__va_copy((d), (s))])
+    dnl #   4. check for internal GCC macro (built-in function)
+    __va_copy_check(GCB, [__builtin_va_copy((d), (s))])
+    dnl #   5. check for assignment approach (assuming va_list is a struct)
+    __va_copy_check(ASS, [do { (d) = (s); } while (0)])
+    dnl #   6. check for assignment approach (assuming va_list is a pointer)
+    __va_copy_check(ASP, [do { *(d) = *(s); } while (0)])
+    dnl #   7. check for memory copying approach (assuming va_list is a struct)
+    __va_copy_check(CPS, [memcpy((void *)&(d), (void *)&(s)), sizeof((s))])
+    dnl #   8. check for memory copying approach (assuming va_list is a pointer)
+    __va_copy_check(CPP, [memcpy((void *)(d), (void *)(s)), sizeof(*(s))])
+    if test ".$ac_cv_va_copy" = .; then
+        AC_ERROR([no working implementation found])
+    fi
+  ])
+  dnl #   optionally activate the fallback implementation
+  if test ".$ac_cv_va_copy" = ".C99"; then
+      AC_DEFINE(HAVE_VA_COPY, 1, [Define if va_copy() macro exists (and no fallback implementation is required)])
+  fi
+  dnl #   declare which fallback implementation to actually use
+  AC_DEFINE_UNQUOTED([__VA_COPY_USE], [__VA_COPY_USE_$ac_cv_va_copy],
+      [Define to id of used va_copy() implementation])
+  dnl #   provide activation hook for fallback implementation
+  AH_VERBATIM([__VA_COPY_ACTIVATION],
+[/* Optional va_copy() implementation activation */
+#ifndef HAVE_VA_COPY
+#define va_copy(d, s) __VA_COPY_USE(d, s)
+#endif
+])
+  dnl #   provide Autoconf display result message
+  if test ".$ac_cv_va_copy" = ".C99"; then
+      AC_MSG_RESULT([yes])
+  else
+      AC_MSG_RESULT([no (using fallback implementation)])
+  fi
+])
+

Added: freeswitch/trunk/libs/js/config.guess
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/config.guess	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1471 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-12-13'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per at bothner.com>.
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    x86:Interix*:[345]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^CPU/{s: ::g;p;}'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^CPU/{s: ::g;p;}'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#if defined(__INTEL_COMPILER) || defined(__PGI)
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '/^LIBC/{s: ::g;p;}'`"
+	test x"${LIBC}" != x && {
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+		exit
+	}
+	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:

Added: freeswitch/trunk/libs/js/config.h.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/config.h.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,113 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Predefined possible va_copy() implementation (id: ASP) */
+#define __VA_COPY_USE_ASP(d, s) do { *(d) = *(s); } while (0)
+
+/* Predefined possible va_copy() implementation (id: ASS) */
+#define __VA_COPY_USE_ASS(d, s) do { (d) = (s); } while (0)
+
+/* Predefined possible va_copy() implementation (id: C99) */
+#define __VA_COPY_USE_C99(d, s) va_copy((d), (s))
+
+/* Predefined possible va_copy() implementation (id: CPP) */
+#define __VA_COPY_USE_CPP(d, s) memcpy((void *)(d), (void *)(s)), sizeof(*(s))
+
+/* Predefined possible va_copy() implementation (id: CPS) */
+#define __VA_COPY_USE_CPS(d, s) memcpy((void *)&(d), (void *)&(s)), sizeof((s))
+
+/* Predefined possible va_copy() implementation (id: GCB) */
+#define __VA_COPY_USE_GCB(d, s) __builtin_va_copy((d), (s))
+
+/* Predefined possible va_copy() implementation (id: GCH) */
+#define __VA_COPY_USE_GCH(d, s) __va_copy((d), (s))
+
+/* Predefined possible va_copy() implementation (id: GCM) */
+#define __VA_COPY_USE_GCM(d, s) VA_COPY((d), (s))
+
+/* Define to 1 if you have the `dlclose' function. */
+#undef HAVE_DLCLOSE
+
+/* Define to 1 if you have the `dlerror' function. */
+#undef HAVE_DLERROR
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `dlopen' function. */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if `st_birthtime' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BIRTHTIME
+
+/* Define to 1 if `st_birthtimensec' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if va_copy() macro exists (and no fallback implementation is
+   required) */
+#undef HAVE_VA_COPY
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Optional va_copy() implementation activation */
+#ifndef HAVE_VA_COPY
+#define va_copy(d, s) __VA_COPY_USE(d, s)
+#endif
+
+
+/* Define to id of used va_copy() implementation */
+#undef __VA_COPY_USE

Added: freeswitch/trunk/libs/js/config.sub
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/config.sub	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1599 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-12-11'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| mt \
+	| msp430 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m32c)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	m32c-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:

Added: freeswitch/trunk/libs/js/configure
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/configure	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,23259 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.60 (OpenPKG-CURRENT).
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+if test "x$CONFIG_SHELL" = x; then
+  if (eval ":") 2>/dev/null; then
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+
+  if test $as_have_required = yes && 	 (eval ":
+(as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0) || { (exit 1); exit 1; }
+
+(
+  as_lineno_1=\$LINENO
+  as_lineno_2=\$LINENO
+  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
+  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
+") 2> /dev/null; then
+  :
+else
+  as_candidate_shells=
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  case $as_dir in
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+	   done;;
+       esac
+done
+IFS=$as_save_IFS
+
+
+      for as_shell in $as_candidate_shells $SHELL; do
+	 # Try only shells that exist, to save several forks.
+	 if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		{ ("$as_shell") 2> /dev/null <<\_ASEOF
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+:
+_ASEOF
+}; then
+  CONFIG_SHELL=$as_shell
+	       as_have_required=yes
+	       if { "$as_shell" 2> /dev/null <<\_ASEOF
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+:
+(as_func_return () {
+  (exit $1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = "$1" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test $exitcode = 0) || { (exit 1); exit 1; }
+
+(
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
+
+_ASEOF
+}; then
+  break
+fi
+
+fi
+
+      done
+
+      if test "x$CONFIG_SHELL" != x; then
+  for as_var in BASH_ENV ENV
+        do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+        done
+        export CONFIG_SHELL
+        exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+
+    if test $as_have_required = no; then
+  echo This script requires a shell more modern than all the
+      echo shells that I found on your system.  Please install a
+      echo modern shell, or manually run the script under such a
+      echo shell if you do have one.
+      { (exit 1); exit 1; }
+fi
+
+
+fi
+
+fi
+
+
+
+(eval "as_func_return () {
+  (exit \$1)
+}
+as_func_success () {
+  as_func_return 0
+}
+as_func_failure () {
+  as_func_return 1
+}
+as_func_ret_success () {
+  return 0
+}
+as_func_ret_failure () {
+  return 1
+}
+
+exitcode=0
+if as_func_success; then
+  :
+else
+  exitcode=1
+  echo as_func_success failed.
+fi
+
+if as_func_failure; then
+  exitcode=1
+  echo as_func_failure succeeded.
+fi
+
+if as_func_ret_success; then
+  :
+else
+  exitcode=1
+  echo as_func_ret_success failed.
+fi
+
+if as_func_ret_failure; then
+  exitcode=1
+  echo as_func_ret_failure succeeded.
+fi
+
+if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
+  :
+else
+  exitcode=1
+  echo positional parameters were not saved.
+fi
+
+test \$exitcode = 0") || {
+  echo No shell found that supports shell functions.
+  echo Please tell autoconf at gnu.org about your system,
+  echo including any error possibly output before this
+  echo message
+}
+
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+    as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+# Find out whether ``test -x'' works.  Don't use a zero-byte file, as
+# systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+  as_executable_p="test -x"
+else
+  as_executable_p=:
+fi
+rm -f conf$$.file
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string=`eval $cmd`) 2>/dev/null &&
+       echo_test_string=`eval $cmd` &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    IFS="$lt_save_ifs"
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+	 test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+	 echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+	 test "X$echo_testing_string" = "X$echo_test_string"; then
+	# Cool, printf works
+	:
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	export CONFIG_SHELL
+	SHELL="$CONFIG_SHELL"
+	export SHELL
+	echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+	# maybe with a smaller string...
+	prev=:
+
+	for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+	  if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+	  then
+	    break
+	  fi
+	  prev="$cmd"
+	done
+
+	if test "$prev" != 'sed 50q "$0"'; then
+	  echo_test_string=`eval $prev`
+	  export echo_test_string
+	  exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+	else
+	  # Oops.  We lost completely, so just stick with echo.
+	  echo=echo
+	fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+
+tagnames=${tagnames+${tagnames},}CXX
+
+tagnames=${tagnames+${tagnames},}F77
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL
+PATH_SEPARATOR
+PACKAGE_NAME
+PACKAGE_TARNAME
+PACKAGE_VERSION
+PACKAGE_STRING
+PACKAGE_BUGREPORT
+exec_prefix
+prefix
+program_transform_name
+bindir
+sbindir
+libexecdir
+datarootdir
+datadir
+sysconfdir
+sharedstatedir
+localstatedir
+includedir
+oldincludedir
+docdir
+infodir
+htmldir
+dvidir
+pdfdir
+psdir
+libdir
+localedir
+mandir
+DEFS
+ECHO_C
+ECHO_N
+ECHO_T
+LIBS
+build_alias
+host_alias
+target_alias
+JS_VERSION
+build
+build_cpu
+build_vendor
+build_os
+host
+host_cpu
+host_vendor
+host_os
+SET_MAKE
+CC
+CFLAGS
+LDFLAGS
+CPPFLAGS
+ac_ct_CC
+EXEEXT
+OBJEXT
+WITH_PERL
+PERL
+CPP
+GREP
+EGREP
+CLI_CFLAGS
+CLI_CPPFLAGS
+CLI_LDFLAGS
+CLI_LIBS
+CLI_OBJS
+LN_S
+ECHO
+AR
+RANLIB
+STRIP
+CXX
+CXXFLAGS
+ac_ct_CXX
+CXXCPP
+F77
+FFLAGS
+ac_ct_F77
+LIBTOOL
+LIBOBJS
+LTLIBOBJS'
+ac_subst_files=''
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+CPPFLAGS
+CPP
+CXX
+CXXFLAGS
+CCC
+CXXCPP
+F77
+FFLAGS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)	ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval enable_$ac_feature=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval enable_$ac_feature=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval with_$ac_package=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval with_$ac_package=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute directory names.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; }
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  { echo "$as_me: error: Working directory cannot be determined" >&2
+   { (exit 1); exit 1; }; }
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  { echo "$as_me: error: pwd does not report name of working directory" >&2
+   { (exit 1); exit 1; }; }
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$0" ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
+   { (exit 1); exit 1; }; }
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR          info documentation [DATAROOTDIR/info]
+  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR           man documentation [DATAROOTDIR/man]
+  --docdir=DIR           documentation root [DATAROOTDIR/doc/PACKAGE]
+  --htmldir=DIR          html documentation [DOCDIR]
+  --dvidir=DIR           dvi documentation [DOCDIR]
+  --pdfdir=DIR           pdf documentation [DOCDIR]
+  --psdir=DIR            ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-debug          build for debugging (default=no)
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-version          build the run-time engine with JavaScript features
+                          only. Available versions are: ECMA-3, JS-1.5, JS-1.6
+                          (default)
+  --with-editline         build command line interface with line editing
+                          support via editline, libedit or GNU readline
+  --with-perl             build Perl-to-JS and JS-to-Perl bindings
+  --without-file          build without File object (grants access to the
+                          filesystem)
+  --with-dso              build without DSO object (allows run-time process
+                          extending)
+  --with-utf8             build with exclusive UTF-8 C strings (uses Unicode
+                          UTF-8 encoded C strings only)
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-pic              try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-tags[=TAGS]      include additional configurations [automatic]
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CXXCPP      C++ preprocessor
+  F77         Fortran 77 compiler command
+  FFLAGS      Fortran 77 compiler flags
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" || continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.60 (OpenPKG-CURRENT)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.60 (OpenPKG-CURRENT).  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args '$ac_arg'"
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -n "$CONFIG_SITE"; then
+  set x "$CONFIG_SITE"
+elif test "x$prefix" != xNONE; then
+  set x "$prefix/share/config.site" "$prefix/etc/config.site"
+else
+  set x "$ac_default_prefix/share/config.site" \
+	"$ac_default_prefix/etc/config.site"
+fi
+shift
+for ac_site_file
+do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+JS_VERSION=`./shtool version -l txt -d short VERSION`
+$ac_confdir/shtool echo -e \
+    "Configuring %BOSSP js%b (Mozilla JavaScript Engine), version %B${JS_VERSION}%b"
+
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
+echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+{ echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6; }
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5
+echo "$as_me: error: invalid value of canonical build" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6; }
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5
+echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5
+echo "$as_me: error: invalid value of canonical host" >&2;}
+   { (exit 1); exit 1; }; };;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; }
+set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+  SET_MAKE=
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+#
+# List of possible output files, starting from the most likely.
+# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
+# only as a last resort.  b.out is created by i960 compilers.
+ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
+#
+# The IRIX 6 linker writes into existing files which may not be
+# executable, retaining their permissions.  Remove them first so a
+# subsequent execution test works.
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { (ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+        if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+{ echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6; }
+
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+{ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6; }
+
+{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	CFLAGS=""
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
+echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_c89=$ac_arg
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6; } ;;
+  xno)
+    { echo "$as_me:$LINENO: result: unsupported" >&5
+echo "${ECHO_T}unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then
+  enableval=$enable_debug; if test ".$ac_cv_c_compiler_gnu" = ".yes"; then
+    case "$CFLAGS" in
+        *-O* ) ;;
+           * ) CFLAGS="$CFLAGS -O0" ;;
+    esac
+    case "$CFLAGS" in
+        *-g* ) ;;
+           * ) CFLAGS="$CFLAGS -g" ;;
+    esac
+    case "$CFLAGS" in
+        *-pipe* ) ;;
+              * ) { echo "$as_me:$LINENO: checking whether compiler option(s) -pipe work" >&5
+echo $ECHO_N "checking whether compiler option(s) -pipe work... $ECHO_C" >&6; }
+if test "${ac_cv_compiler_option_pipe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+SAVE_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -pipe"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_compiler_option_pipe=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_compiler_option_pipe=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+CFLAGS="$SAVE_CFLAGS"
+
+fi
+if test ".$ac_cv_compiler_option_pipe" = .yes; then
+    CFLAGS="$CFLAGS -pipe"
+else
+    :
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_compiler_option_pipe" >&5
+echo "${ECHO_T}$ac_cv_compiler_option_pipe" >&6; }
+ ;;
+    esac
+    { echo "$as_me:$LINENO: checking whether compiler option(s) -DDEBUG work" >&5
+echo $ECHO_N "checking whether compiler option(s) -DDEBUG work... $ECHO_C" >&6; }
+if test "${ac_cv_compiler_option_defdbg+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+SAVE_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -DDEBUG"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_compiler_option_defdbg=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_compiler_option_defdbg=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+CFLAGS="$SAVE_CFLAGS"
+
+fi
+if test ".$ac_cv_compiler_option_defdbg" = .yes; then
+    CFLAGS="$CFLAGS -DDEBUG"
+else
+    :
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_compiler_option_defdbg" >&5
+echo "${ECHO_T}$ac_cv_compiler_option_defdbg" >&6; }
+
+    CFLAGS="$CFLAGS -pedantic"
+    CFLAGS="$CFLAGS -Wall"
+    WMORE="-Wpointer-arith -Wcast-align -Winline"
+    WMORE="$WMORE -Wmissing-prototypes -Wmissing-declarations -Wnested-externs"
+    { echo "$as_me:$LINENO: checking whether compiler option(s) -W<xxx> work" >&5
+echo $ECHO_N "checking whether compiler option(s) -W<xxx> work... $ECHO_C" >&6; }
+if test "${ac_cv_compiler_option_wmore+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+SAVE_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $WMORE"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_compiler_option_wmore=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_compiler_option_wmore=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+CFLAGS="$SAVE_CFLAGS"
+
+fi
+if test ".$ac_cv_compiler_option_wmore" = .yes; then
+    CFLAGS="$CFLAGS $WMORE"
+else
+    :
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_compiler_option_wmore" >&5
+echo "${ECHO_T}$ac_cv_compiler_option_wmore" >&6; }
+
+    { echo "$as_me:$LINENO: checking whether compiler option(s) -Wno-long-long work" >&5
+echo $ECHO_N "checking whether compiler option(s) -Wno-long-long work... $ECHO_C" >&6; }
+if test "${ac_cv_compiler_option_wnolonglong+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+SAVE_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Wno-long-long"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_compiler_option_wnolonglong=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_compiler_option_wnolonglong=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+CFLAGS="$SAVE_CFLAGS"
+
+fi
+if test ".$ac_cv_compiler_option_wnolonglong" = .yes; then
+    CFLAGS="$CFLAGS -Wno-long-long"
+else
+    :
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_compiler_option_wnolonglong" >&5
+echo "${ECHO_T}$ac_cv_compiler_option_wnolonglong" >&6; }
+
+else
+    case "$CFLAGS" in
+        *-g* ) ;;
+           * ) CFLAGS="$CFLAGS -g" ;;
+    esac
+fi
+msg="enabled"
+
+else
+
+{ echo "$as_me:$LINENO: checking whether compiler option(s) -DNDEBUG work" >&5
+echo $ECHO_N "checking whether compiler option(s) -DNDEBUG work... $ECHO_C" >&6; }
+if test "${ac_cv_compiler_option_defnodbg+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+SAVE_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -DNDEBUG"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_compiler_option_defnodbg=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_compiler_option_defnodbg=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+CFLAGS="$SAVE_CFLAGS"
+
+fi
+if test ".$ac_cv_compiler_option_defnodbg" = .yes; then
+    CFLAGS="$CFLAGS -DNDEBUG"
+else
+    :
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_compiler_option_defnodbg" >&5
+echo "${ECHO_T}$ac_cv_compiler_option_defnodbg" >&6; }
+
+if test ".$ac_cv_c_compiler_gnu" = ".yes"; then
+case "$CFLAGS" in
+    *-pipe* ) ;;
+          * ) { echo "$as_me:$LINENO: checking whether compiler option(s) -pipe work" >&5
+echo $ECHO_N "checking whether compiler option(s) -pipe work... $ECHO_C" >&6; }
+if test "${ac_cv_compiler_option_pipe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+SAVE_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -pipe"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_compiler_option_pipe=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_compiler_option_pipe=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+CFLAGS="$SAVE_CFLAGS"
+
+fi
+if test ".$ac_cv_compiler_option_pipe" = .yes; then
+    CFLAGS="$CFLAGS -pipe"
+else
+    :
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_compiler_option_pipe" >&5
+echo "${ECHO_T}$ac_cv_compiler_option_pipe" >&6; }
+ ;;
+esac
+fi
+case "$CFLAGS" in
+    *-g* ) CFLAGS=`echo "$CFLAGS" |\
+                   sed -e 's/ -g / /g' -e 's/ -g$//' -e 's/^-g //g' -e 's/^-g$//'` ;;
+esac
+case "$CXXFLAGS" in
+    *-g* ) CXXFLAGS=`echo "$CXXFLAGS" |\
+                     sed -e 's/ -g / /g' -e 's/ -g$//' -e 's/^-g //g' -e 's/^-g$//'` ;;
+esac
+msg=disabled
+
+fi
+{ echo "$as_me:$LINENO: checking for compilation debug mode" >&5
+echo $ECHO_N "checking for compilation debug mode... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $msg" >&5
+echo "${ECHO_T}$msg" >&6; }
+if test ".$msg" = .enabled; then
+    enable_shared=no
+fi
+
+
+    { echo "$as_me:$LINENO: checking for va_copy() function" >&5
+echo $ECHO_N "checking for va_copy() function... $ECHO_C" >&6; }
+    if test "${ac_cv_va_copy+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    ac_cv_va_copy=""
+
+
+
+    if test ".$ac_cv_va_copy" = .; then
+        if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define DO_VA_COPY(d, s) va_copy((d), (s))
+void test(char *str, ...)
+{
+    va_list ap, ap2;
+    int i;
+    va_start(ap, str);
+    DO_VA_COPY(ap2, ap);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    DO_VA_COPY(ap, ap2);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    va_end(ap);
+}
+int main(int argc, char *argv[])
+{
+    test("test", 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    exit(0);
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_va_copy="C99"
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+    fi
+
+
+
+
+    if test ".$ac_cv_va_copy" = .; then
+        if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define DO_VA_COPY(d, s) VA_COPY((d), (s))
+void test(char *str, ...)
+{
+    va_list ap, ap2;
+    int i;
+    va_start(ap, str);
+    DO_VA_COPY(ap2, ap);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    DO_VA_COPY(ap, ap2);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    va_end(ap);
+}
+int main(int argc, char *argv[])
+{
+    test("test", 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    exit(0);
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_va_copy="GCM"
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+    fi
+
+
+
+
+    if test ".$ac_cv_va_copy" = .; then
+        if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define DO_VA_COPY(d, s) __va_copy((d), (s))
+void test(char *str, ...)
+{
+    va_list ap, ap2;
+    int i;
+    va_start(ap, str);
+    DO_VA_COPY(ap2, ap);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    DO_VA_COPY(ap, ap2);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    va_end(ap);
+}
+int main(int argc, char *argv[])
+{
+    test("test", 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    exit(0);
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_va_copy="GCH"
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+    fi
+
+
+
+
+    if test ".$ac_cv_va_copy" = .; then
+        if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define DO_VA_COPY(d, s) __builtin_va_copy((d), (s))
+void test(char *str, ...)
+{
+    va_list ap, ap2;
+    int i;
+    va_start(ap, str);
+    DO_VA_COPY(ap2, ap);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    DO_VA_COPY(ap, ap2);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    va_end(ap);
+}
+int main(int argc, char *argv[])
+{
+    test("test", 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    exit(0);
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_va_copy="GCB"
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+    fi
+
+
+
+
+    if test ".$ac_cv_va_copy" = .; then
+        if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define DO_VA_COPY(d, s) do { (d) = (s); } while (0)
+void test(char *str, ...)
+{
+    va_list ap, ap2;
+    int i;
+    va_start(ap, str);
+    DO_VA_COPY(ap2, ap);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    DO_VA_COPY(ap, ap2);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    va_end(ap);
+}
+int main(int argc, char *argv[])
+{
+    test("test", 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    exit(0);
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_va_copy="ASS"
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+    fi
+
+
+
+
+    if test ".$ac_cv_va_copy" = .; then
+        if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define DO_VA_COPY(d, s) do { *(d) = *(s); } while (0)
+void test(char *str, ...)
+{
+    va_list ap, ap2;
+    int i;
+    va_start(ap, str);
+    DO_VA_COPY(ap2, ap);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    DO_VA_COPY(ap, ap2);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    va_end(ap);
+}
+int main(int argc, char *argv[])
+{
+    test("test", 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    exit(0);
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_va_copy="ASP"
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+    fi
+
+
+
+
+    if test ".$ac_cv_va_copy" = .; then
+        if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define DO_VA_COPY(d, s) memcpy((void *)&(d), (void *)&(s))
+void test(char *str, ...)
+{
+    va_list ap, ap2;
+    int i;
+    va_start(ap, str);
+    DO_VA_COPY(ap2, ap);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    DO_VA_COPY(ap, ap2);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    va_end(ap);
+}
+int main(int argc, char *argv[])
+{
+    test("test", 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    exit(0);
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_va_copy="CPS"
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+    fi
+
+
+
+
+    if test ".$ac_cv_va_copy" = .; then
+        if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define DO_VA_COPY(d, s) memcpy((void *)(d), (void *)(s))
+void test(char *str, ...)
+{
+    va_list ap, ap2;
+    int i;
+    va_start(ap, str);
+    DO_VA_COPY(ap2, ap);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    DO_VA_COPY(ap, ap2);
+    for (i = 1; i <= 9; i++) {
+        int k = (int)va_arg(ap, int);
+        if (k != i)
+            abort();
+    }
+    va_end(ap);
+}
+int main(int argc, char *argv[])
+{
+    test("test", 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    exit(0);
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_va_copy="CPP"
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+    fi
+
+    if test ".$ac_cv_va_copy" = .; then
+        { { echo "$as_me:$LINENO: error: no working implementation found" >&5
+echo "$as_me: error: no working implementation found" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+fi
+
+    if test ".$ac_cv_va_copy" = ".C99"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_VA_COPY 1
+_ACEOF
+
+  fi
+
+cat >>confdefs.h <<_ACEOF
+#define __VA_COPY_USE __VA_COPY_USE_$ac_cv_va_copy
+_ACEOF
+
+
+
+    if test ".$ac_cv_va_copy" = ".C99"; then
+      { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+  else
+      { echo "$as_me:$LINENO: result: no (using fallback implementation)" >&5
+echo "${ECHO_T}no (using fallback implementation)" >&6; }
+  fi
+
+
+
+{ echo "$as_me:$LINENO: checking for gethostname in -lnsl" >&5
+echo $ECHO_N "checking for gethostname in -lnsl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_nsl_gethostname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostname ();
+int
+main ()
+{
+return gethostname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_gethostname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_nsl_gethostname=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostname" >&6; }
+if test $ac_cv_lib_nsl_gethostname = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNSL 1
+_ACEOF
+
+  LIBS="-lnsl $LIBS"
+
+fi
+
+if test ".`echo $LIBS | grep nsl`" = .; then
+
+{ echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_nsl_gethostbyname=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNSL 1
+_ACEOF
+
+  LIBS="-lnsl $LIBS"
+
+fi
+
+fi
+
+{ echo "$as_me:$LINENO: checking for accept in -lsocket" >&5
+echo $ECHO_N "checking for accept in -lsocket... $ECHO_C" >&6; }
+if test "${ac_cv_lib_socket_accept+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char accept ();
+int
+main ()
+{
+return accept ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_accept=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_socket_accept=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_socket_accept" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_accept" >&6; }
+if test $ac_cv_lib_socket_accept = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSOCKET 1
+_ACEOF
+
+  LIBS="-lsocket $LIBS"
+
+fi
+
+
+{ echo "$as_me:$LINENO: checking for floor in -lm" >&5
+echo $ECHO_N "checking for floor in -lm... $ECHO_C" >&6; }
+if test "${ac_cv_lib_m_floor+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char floor ();
+int
+main ()
+{
+return floor ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_floor=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_m_floor=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_floor" >&5
+echo "${ECHO_T}$ac_cv_lib_m_floor" >&6; }
+if test $ac_cv_lib_m_floor = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+fi
+
+
+{ echo "$as_me:$LINENO: checking for struct stat.st_birthtime" >&5
+echo $ECHO_N "checking for struct stat.st_birthtime... $ECHO_C" >&6; }
+if test "${ac_cv_member_struct_stat_st_birthtime+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+
+int
+main ()
+{
+static struct stat ac_aggr;
+if (ac_aggr.st_birthtime)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_birthtime=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+
+int
+main ()
+{
+static struct stat ac_aggr;
+if (sizeof ac_aggr.st_birthtime)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_birthtime=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_member_struct_stat_st_birthtime=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_birthtime" >&5
+echo "${ECHO_T}$ac_cv_member_struct_stat_st_birthtime" >&6; }
+if test $ac_cv_member_struct_stat_st_birthtime = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
+_ACEOF
+
+
+fi
+{ echo "$as_me:$LINENO: checking for struct stat.st_birthtimensec" >&5
+echo $ECHO_N "checking for struct stat.st_birthtimensec... $ECHO_C" >&6; }
+if test "${ac_cv_member_struct_stat_st_birthtimensec+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+
+int
+main ()
+{
+static struct stat ac_aggr;
+if (ac_aggr.st_birthtimensec)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_birthtimensec=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+
+int
+main ()
+{
+static struct stat ac_aggr;
+if (sizeof ac_aggr.st_birthtimensec)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_birthtimensec=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_member_struct_stat_st_birthtimensec=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_birthtimensec" >&5
+echo "${ECHO_T}$ac_cv_member_struct_stat_st_birthtimensec" >&6; }
+if test $ac_cv_member_struct_stat_st_birthtimensec = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC 1
+_ACEOF
+
+
+fi
+
+
+CPPFLAGS="$CPPFLAGS -DOSSP"
+case "${host}" in
+    *mingw* | *windows* | *winnt* ) CPPFLAGS="$CPPFLAGS -DXP_WIN"  ;;
+    *                             ) CPPFLAGS="$CPPFLAGS -DXP_UNIX" ;;
+esac
+CPPFLAGS="$CPPFLAGS -DEXPORT_JS_API"
+
+
+# Check whether --with-version was given.
+if test "${with_version+set}" = set; then
+  withval=$with_version; ac_cv_with_version=$withval
+else
+  ac_cv_with_version=no
+fi
+
+{ echo "$as_me:$LINENO: checking whether to build the run-time engine with JavaScript features only" >&5
+echo $ECHO_N "checking whether to build the run-time engine with JavaScript features only... $ECHO_C" >&6; }
+if test "${ac_cv_with_version+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_with_version=no
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_with_version" >&5
+echo "${ECHO_T}$ac_cv_with_version" >&6; }
+case "$ac_cv_with_version" in
+                        ECMA-3 ) CPPFLAGS="$CPPFLAGS -DJS_VERSION=148" ;;
+    JS-1.5 ) CPPFLAGS="$CPPFLAGS -DJS_VERSION=150" ;;
+    JS-1.6 ) CPPFLAGS="$CPPFLAGS -DJS_VERSION=160" ;;
+esac
+
+CLI_CPPFLAGS=""
+CLI_CFLAGS=""
+CLI_LDFLAGS=""
+CLI_LIBS=""
+CLI_OBJS=""
+
+
+# Check whether --with-editline was given.
+if test "${with_editline+set}" = set; then
+  withval=$with_editline; ac_cv_with_editline=$withval
+else
+  ac_cv_with_editline=no
+fi
+
+{ echo "$as_me:$LINENO: checking whether to build command line interface with line editing support" >&5
+echo $ECHO_N "checking whether to build command line interface with line editing support... $ECHO_C" >&6; }
+if test "${ac_cv_with_editline+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_with_editline=no
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_with_editline" >&5
+echo "${ECHO_T}$ac_cv_with_editline" >&6; }
+if test ".$ac_cv_with_editline" != ".no"; then
+    CLI_CPPFLAGS="$CLI_CPPFLAGS -DEDITLINE"
+    case "$ac_cv_with_editline" in
+        /* ) CLI_LDFLAGS="-L$ac_cv_with_editline" ;;
+    esac
+    OLD_LDFLAGS="$LDFLAGS";
+    OLD_LIBS="$LIBS";
+    LDFLAGS="$LDFLAGS $CLI_LDFLAGS"
+    LIBS=""
+    { echo "$as_me:$LINENO: checking for library containing tcgetattr" >&5
+echo $ECHO_N "checking for library containing tcgetattr... $ECHO_C" >&6; }
+if test "${ac_cv_search_tcgetattr+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tcgetattr ();
+int
+main ()
+{
+return tcgetattr ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' termcap termlib curses ncurses; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_tcgetattr=$ac_res
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext
+  if test "${ac_cv_search_tcgetattr+set}" = set; then
+  break
+fi
+done
+if test "${ac_cv_search_tcgetattr+set}" = set; then
+  :
+else
+  ac_cv_search_tcgetattr=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_search_tcgetattr" >&5
+echo "${ECHO_T}$ac_cv_search_tcgetattr" >&6; }
+ac_res=$ac_cv_search_tcgetattr
+if test "$ac_res" != no; then
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+    { echo "$as_me:$LINENO: checking for library containing tputs" >&5
+echo $ECHO_N "checking for library containing tputs... $ECHO_C" >&6; }
+if test "${ac_cv_search_tputs+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tputs ();
+int
+main ()
+{
+return tputs ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' termcap termlib curses ncurses; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_tputs=$ac_res
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext
+  if test "${ac_cv_search_tputs+set}" = set; then
+  break
+fi
+done
+if test "${ac_cv_search_tputs+set}" = set; then
+  :
+else
+  ac_cv_search_tputs=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_search_tputs" >&5
+echo "${ECHO_T}$ac_cv_search_tputs" >&6; }
+ac_res=$ac_cv_search_tputs
+if test "$ac_res" != no; then
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+    TERM_LIBS="$LIBS"
+    { echo "$as_me:$LINENO: checking for library containing readline" >&5
+echo $ECHO_N "checking for library containing readline... $ECHO_C" >&6; }
+if test "${ac_cv_search_readline+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char readline ();
+int
+main ()
+{
+return readline ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' editline edit readline; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib $TERM_LIBS $ac_func_search_save_LIBS"
+  fi
+  rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_readline=$ac_res
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext
+  if test "${ac_cv_search_readline+set}" = set; then
+  break
+fi
+done
+if test "${ac_cv_search_readline+set}" = set; then
+  :
+else
+  ac_cv_search_readline=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_search_readline" >&5
+echo "${ECHO_T}$ac_cv_search_readline" >&6; }
+ac_res=$ac_cv_search_readline
+if test "$ac_res" != no; then
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+    CLI_LIBS="$LIBS"
+    LDFLAGS="$OLD_LDFLAGS"
+    LIBS="$OLD_LIBS"
+fi
+
+
+# Check whether --with-perl was given.
+if test "${with_perl+set}" = set; then
+  withval=$with_perl; ac_cv_with_perl=$withval
+else
+  ac_cv_with_perl=no
+fi
+
+{ echo "$as_me:$LINENO: checking whether to build Perl-to-JS and JS-to-Perl bindings" >&5
+echo $ECHO_N "checking whether to build Perl-to-JS and JS-to-Perl bindings... $ECHO_C" >&6; }
+if test "${ac_cv_with_perl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_with_perl=no
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_with_perl" >&5
+echo "${ECHO_T}$ac_cv_with_perl" >&6; }
+if test ".$ac_cv_with_perl" != ".no"; then
+	WITH_PERL="yes"
+	CLI_OBJS="$CLI_OBJS src/perlconnect/jsperl.o"
+	CLI_CPPFLAGS="$CLI_CPPFLAGS -DPERLCONNECT"
+else
+	WITH_PERL="no"
+fi
+
+case "$ac_cv_with_perl" in
+    /* ) PERL="$ac_cv_with_perl" ;;
+esac
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_PERL+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $PERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="NA"
+  ;;
+esac
+fi
+PERL=$ac_cv_path_PERL
+if test -n "$PERL"; then
+  { echo "$as_me:$LINENO: result: $PERL" >&5
+echo "${ECHO_T}$PERL" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+if test ".$ac_cv_with_perl" = ".yes" -a ".$PERL" = ".NA"; then
+	{ { echo "$as_me:$LINENO: error: required Perl interpreter not found in \$PATH" >&5
+echo "$as_me: error: required Perl interpreter not found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test ".$ac_cv_with_perl" != ".no"; then
+    CLI_CFLAGS="$CLI_CFLAGS `$PERL -MExtUtils::Embed -e ccopts`"
+    CLI_LIBS="$CLI_LIBS `$PERL -MExtUtils::Embed -e ldopts`"
+fi
+
+
+# Check whether --with-file was given.
+if test "${with_file+set}" = set; then
+  withval=$with_file; ac_cv_with_file=$withval
+else
+  ac_cv_with_file=yes
+fi
+
+{ echo "$as_me:$LINENO: checking whether to build with the File object" >&5
+echo $ECHO_N "checking whether to build with the File object... $ECHO_C" >&6; }
+if test "${ac_cv_with_file+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_with_file=yes
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_with_file" >&5
+echo "${ECHO_T}$ac_cv_with_file" >&6; }
+if test ".$ac_cv_with_file" = ".yes"; then
+    CPPFLAGS="$CPPFLAGS -DJS_HAS_FILE_OBJECT"
+fi
+
+
+# Check whether --with-dso was given.
+if test "${with_dso+set}" = set; then
+  withval=$with_dso; ac_cv_with_dso=$withval
+else
+  ac_cv_with_dso=no
+fi
+
+{ echo "$as_me:$LINENO: checking whether to build with the DSO object" >&5
+echo $ECHO_N "checking whether to build with the DSO object... $ECHO_C" >&6; }
+if test "${ac_cv_with_dso+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_with_dso=no
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_with_dso" >&5
+echo "${ECHO_T}$ac_cv_with_dso" >&6; }
+if test ".$ac_cv_with_dso" = ".yes"; then
+
+{ echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_dl_dlopen=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; }
+if test $ac_cv_lib_dl_dlopen = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDL 1
+_ACEOF
+
+  LIBS="-ldl $LIBS"
+
+fi
+
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
+echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Extract the first word of "grep ggrep" to use in msg output
+if test -z "$GREP"; then
+set dummy grep ggrep; ac_prog_name=$2
+if test "${ac_cv_path_GREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_GREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in grep ggrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue
+    # Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_GREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+GREP="$ac_cv_path_GREP"
+if test -z "$GREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
+echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     # Extract the first word of "egrep" to use in msg output
+if test -z "$EGREP"; then
+set dummy egrep; ac_prog_name=$2
+if test "${ac_cv_path_EGREP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_path_EGREP_found=false
+# Loop through the user's path and test for each of PROGNAME-LIST
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_prog in egrep; do
+  for ac_exec_ext in '' $ac_executable_extensions; do
+    ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+    { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue
+    # Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    ac_count=`expr $ac_count + 1`
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+
+    $ac_path_EGREP_found && break 3
+  done
+done
+
+done
+IFS=$as_save_IFS
+
+
+fi
+
+EGREP="$ac_cv_path_EGREP"
+if test -z "$EGREP"; then
+  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
+echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+
+   fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
+echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_header_stdc=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_Header=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking dlfcn.h usability" >&5
+echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <dlfcn.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking dlfcn.h presence" >&5
+echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <dlfcn.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: dlfcn.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: dlfcn.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for dlfcn.h" >&5
+echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_dlfcn_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_dlfcn_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
+echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6; }
+
+fi
+if test $ac_cv_header_dlfcn_h = yes; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: dlopen(3) header <dlfcn.h> required" >&5
+echo "$as_me: error: dlopen(3) header <dlfcn.h> required" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+
+
+
+for ac_func in dlopen dlclose dlerror
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  { { echo "$as_me:$LINENO: error: dlopen(3) API functions dlopen/dlclose/dlerror required" >&5
+echo "$as_me: error: dlopen(3) API functions dlopen/dlclose/dlerror required" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+done
+
+    CPPFLAGS="$CPPFLAGS -DJS_HAS_DSO_OBJECT"
+    CLI_LDFLAGS="$CLI_LDFLAGS -export-dynamic"
+fi
+
+
+# Check whether --with-utf8 was given.
+if test "${with_utf8+set}" = set; then
+  withval=$with_utf8; ac_cv_with_utf8=$withval
+else
+  ac_cv_with_utf8=no
+fi
+
+{ echo "$as_me:$LINENO: checking whether to build with exclusive UTF-8 C string" >&5
+echo $ECHO_N "checking whether to build with exclusive UTF-8 C string... $ECHO_C" >&6; }
+if test "${ac_cv_with_utf8+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_with_utf8=no
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_with_utf8" >&5
+echo "${ECHO_T}$ac_cv_with_utf8" >&6; }
+if test ".$ac_cv_with_utf8" = ".yes"; then
+    CPPFLAGS="$CPPFLAGS -DJS_C_STRINGS_ARE_UTF8"
+fi
+
+
+
+
+
+
+
+with_tags=""
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
+## Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+##
+## This file is free software; the Free Software Foundation gives
+## unlimited permission to copy and/or distribute it, with or without
+## modifications, as long as this notice is preserved.
+
+# serial 48 AC_PROG_LIBTOOL
+
+
+# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
+# -----------------------------------------------------------
+# If this macro is not defined by Autoconf, define it here.
+
+
+
+# AC_PROG_LIBTOOL
+# ---------------
+# AC_PROG_LIBTOOL
+
+
+# _AC_PROG_LIBTOOL
+# ----------------
+# _AC_PROG_LIBTOOL
+
+
+# AC_LIBTOOL_SETUP
+# ----------------
+# AC_LIBTOOL_SETUP
+
+
+# _LT_AC_SYS_COMPILER
+# -------------------
+# _LT_AC_SYS_COMPILER
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+# _LT_LINKER_BOILERPLATE
+
+
+# _LT_AC_SYS_LIBPATH_AIX
+# ----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# _LT_AC_SYS_LIBPATH_AIX
+
+
+# _LT_AC_SHELL_INIT(ARG)
+# ----------------------
+# _LT_AC_SHELL_INIT
+
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+# _LT_AC_PROG_ECHO_BACKSLASH
+
+
+# _LT_AC_LOCK
+# -----------
+# _LT_AC_LOCK
+
+
+# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+# AC_LIBTOOL_COMPILER_OPTION
+
+
+# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                          [ACTION-SUCCESS], [ACTION-FAILURE])
+# ------------------------------------------------------------
+# Check whether the given compiler option works
+# AC_LIBTOOL_LINKER_OPTION
+
+
+# AC_LIBTOOL_SYS_MAX_CMD_LEN
+# --------------------------
+# AC_LIBTOOL_SYS_MAX_CMD_LEN
+
+
+# _LT_AC_CHECK_DLFCN
+# ------------------
+# _LT_AC_CHECK_DLFCN
+
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                           ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ---------------------------------------------------------------------
+# _LT_AC_TRY_DLOPEN_SELF
+
+
+# AC_LIBTOOL_DLOPEN_SELF
+# ----------------------
+# AC_LIBTOOL_DLOPEN_SELF
+
+
+# AC_LIBTOOL_PROG_CC_C_O([TAGNAME])
+# ---------------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler
+# AC_LIBTOOL_PROG_CC_C_O
+
+
+# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME])
+# -----------------------------------------
+# Check to see if we can do hard links to lock some files if needed
+# AC_LIBTOOL_SYS_HARD_LINK_LOCKS
+
+
+# AC_LIBTOOL_OBJDIR
+# -----------------
+# AC_LIBTOOL_OBJDIR
+
+
+# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME])
+# ----------------------------------------------
+# Check hardcoding attributes.
+# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH
+
+
+# AC_LIBTOOL_SYS_LIB_STRIP
+# ------------------------
+# AC_LIBTOOL_SYS_LIB_STRIP
+
+
+# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+
+
+# _LT_AC_TAGCONFIG
+# ----------------
+# _LT_AC_TAGCONFIG
+
+
+# AC_LIBTOOL_DLOPEN
+# -----------------
+# enable checks for dlopen support
+# AC_LIBTOOL_DLOPEN
+
+
+# AC_LIBTOOL_WIN32_DLL
+# --------------------
+# declare package support for building win32 DLLs
+# AC_LIBTOOL_WIN32_DLL
+
+
+# AC_ENABLE_SHARED([DEFAULT])
+# ---------------------------
+# implement the --enable-shared flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+# AC_ENABLE_SHARED
+
+
+# AC_DISABLE_SHARED
+# -----------------
+# set the default shared flag to --disable-shared
+# AC_DISABLE_SHARED
+
+
+# AC_ENABLE_STATIC([DEFAULT])
+# ---------------------------
+# implement the --enable-static flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+# AC_ENABLE_STATIC
+
+
+# AC_DISABLE_STATIC
+# -----------------
+# set the default static flag to --disable-static
+# AC_DISABLE_STATIC
+
+
+# AC_ENABLE_FAST_INSTALL([DEFAULT])
+# ---------------------------------
+# implement the --enable-fast-install flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+# AC_ENABLE_FAST_INSTALL
+
+
+# AC_DISABLE_FAST_INSTALL
+# -----------------------
+# set the default to --disable-fast-install
+# AC_DISABLE_FAST_INSTALL
+
+
+# AC_LIBTOOL_PICMODE([MODE])
+# --------------------------
+# implement the --with-pic flag
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+# AC_LIBTOOL_PICMODE
+
+
+# AC_PROG_EGREP
+# -------------
+# This is predefined starting with Autoconf 2.54, so this conditional
+# definition can be removed once we require Autoconf 2.54 or later.
+
+
+
+# AC_PATH_TOOL_PREFIX
+# -------------------
+# find a file program which can recognise shared library
+# AC_PATH_TOOL_PREFIX
+
+
+# AC_PATH_MAGIC
+# -------------
+# find a file program which can recognise a shared library
+# AC_PATH_MAGIC
+
+
+# AC_PROG_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+# AC_PROG_LD
+
+
+# AC_PROG_LD_GNU
+# --------------
+# AC_PROG_LD_GNU
+
+
+# AC_PROG_LD_RELOAD_FLAG
+# ----------------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+# AC_PROG_LD_RELOAD_FLAG
+
+
+# AC_DEPLIBS_CHECK_METHOD
+# -----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+# AC_DEPLIBS_CHECK_METHOD
+
+
+# AC_PROG_NM
+# ----------
+# find the pathname to a BSD-compatible name lister
+# AC_PROG_NM
+
+
+# AC_CHECK_LIBM
+# -------------
+# check for math library
+# AC_CHECK_LIBM
+
+
+# AC_LIBLTDL_CONVENIENCE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl convenience library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-convenience to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
+# it is assumed to be `libltdl'.  LIBLTDL will be prefixed with
+# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/'
+# (note the single quotes!).  If your package is not flat and you're not
+# using automake, define top_builddir and top_srcdir appropriately in
+# the Makefiles.
+# AC_LIBLTDL_CONVENIENCE
+
+
+# AC_LIBLTDL_INSTALLABLE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl installable library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-install to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
+# and an installed libltdl is not found, it is assumed to be `libltdl'.
+# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and top_srcdir
+# appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+# AC_LIBLTDL_INSTALLABLE
+
+
+# AC_LIBTOOL_CXX
+# --------------
+# enable support for C++ libraries
+# AC_LIBTOOL_CXX
+
+
+# _LT_AC_LANG_CXX
+# ---------------
+# _LT_AC_LANG_CXX
+
+# _LT_AC_PROG_CXXCPP
+# ------------------
+# _LT_AC_PROG_CXXCPP
+
+# AC_LIBTOOL_F77
+# --------------
+# enable support for Fortran 77 libraries
+# AC_LIBTOOL_F77
+
+
+# _LT_AC_LANG_F77
+# ---------------
+# _LT_AC_LANG_F77
+
+
+# AC_LIBTOOL_GCJ
+# --------------
+# enable support for GCJ libraries
+# AC_LIBTOOL_GCJ
+
+
+# _LT_AC_LANG_GCJ
+# ---------------
+# _LT_AC_LANG_GCJ
+
+
+# AC_LIBTOOL_RC
+# -------------
+# enable support for Windows resource files
+# AC_LIBTOOL_RC
+
+
+# AC_LIBTOOL_LANG_C_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+
+# AC_LIBTOOL_LANG_C_CONFIG
+
+
+# AC_LIBTOOL_LANG_CXX_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+
+# AC_LIBTOOL_LANG_CXX_CONFIG
+
+# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
+# ------------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+# AC_LIBTOOL_POSTDEP_PREDEP
+
+# AC_LIBTOOL_LANG_F77_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+
+# AC_LIBTOOL_LANG_F77_CONFIG
+
+
+# AC_LIBTOOL_LANG_GCJ_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+
+# AC_LIBTOOL_LANG_GCJ_CONFIG
+
+
+# AC_LIBTOOL_LANG_RC_CONFIG
+# -------------------------
+# Ensure that the configuration vars for the Windows resource compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+
+# AC_LIBTOOL_LANG_RC_CONFIG
+
+
+# AC_LIBTOOL_CONFIG([TAGNAME])
+# ----------------------------
+# If TAGNAME is not passed, then create an initial libtool script
+# with a default configuration from the untagged config vars.  Otherwise
+# add code to config.status for appending the configuration named by
+# TAGNAME from the matching tagged config vars.
+# AC_LIBTOOL_CONFIG
+
+
+# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------------------
+# AC_LIBTOOL_PROG_COMPILER_NO_RTTI
+
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+ # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+
+# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME])
+# ---------------------------------------
+
+
+
+# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME])
+# ------------------------------------
+# See if the linker supports building shared libraries.
+# AC_LIBTOOL_PROG_LD_SHLIBS
+
+
+# _LT_AC_FILE_LTDLL_C
+# -------------------
+# Be careful that the start marker always follows a newline.
+# _LT_AC_FILE_LTDLL_C
+
+
+# _LT_AC_TAGVAR(VARNAME, [TAGNAME])
+# ---------------------------------
+
+
+
+# old names
+
+
+
+
+
+
+
+
+# This is just to silence aclocal about the macro not being used
+
+
+
+
+
+
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+# LT_AC_PROG_SED
+# --------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+
+
+# Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+# Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi
+
+
+# Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+{ echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
+echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6; }
+if test "${lt_cv_path_SED+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+
+fi
+
+SED=$lt_cv_path_SED
+{ echo "$as_me:$LINENO: result: $SED" >&5
+echo "${ECHO_T}$SED" >&6; }
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
+else
+  { echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+{ echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
+echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6; }
+if test "${lt_cv_ld_reload_flag+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
+echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+{ echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
+echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6; }
+if test "${lt_cv_path_NM+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5
+echo "${ECHO_T}$lt_cv_path_NM" >&6; }
+NM="$lt_cv_path_NM"
+
+{ echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5
+echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6; }
+if test "${lt_cv_deplibs_check_method+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | kfreebsd*-gnu | dragonfly*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix3*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+nto-qnx*)
+  lt_cv_deplibs_check_method=unknown
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
+echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6; }
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *ELF-32*)
+      HPUX_IA64_MODE="32"
+      ;;
+    *ELF-64*)
+      HPUX_IA64_MODE="64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 7452 "configure"' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+   if test "$lt_cv_prog_gnu_ld" = yes; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -melf32bsmip"
+      ;;
+    *N32*)
+      LD="${LD-ld} -melf32bmipn32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -melf64bmip"
+      ;;
+    esac
+   else
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+   fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    case `/usr/bin/file conftest.o` in
+    *32-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
+        ppc64-*linux*|powerpc64-*linux*)
+          LD="${LD-ld} -m elf32ppclinux"
+          ;;
+        s390x-*linux*)
+          LD="${LD-ld} -m elf_s390"
+          ;;
+        sparc64-*linux*)
+          LD="${LD-ld} -m elf32_sparc"
+          ;;
+      esac
+      ;;
+    *64-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        ppc*-*linux*|powerpc*-*linux*)
+          LD="${LD-ld} -m elf64ppc"
+          ;;
+        s390*-*linux*)
+          LD="${LD-ld} -m elf64_s390"
+          ;;
+        sparc*-*linux*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  { echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
+echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6; }
+if test "${lt_cv_cc_needs_belf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  lt_cv_cc_needs_belf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	lt_cv_cc_needs_belf=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
+echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6; }
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)    LD="${LD-ld} -64" ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+
+for ac_header in dlfcn.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; }
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	CXXFLAGS=""
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
+echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6; }
+if test -z "$CXXCPP"; then
+  if test "${ac_cv_prog_CXXCPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ echo "$as_me:$LINENO: result: $CXXCPP" >&5
+echo "${ECHO_T}$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+fi
+
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in g77 f77 xlf frt pgf77 cf77 fort77 fl32 af77 f90 xlf90 pgf90 pghpf epcf90 gfortran g95 f95 fort xlf95 ifort ifc efc pgf95 lf95 ftn
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$F77"; then
+  ac_cv_prog_F77="$F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+F77=$ac_cv_prog_F77
+if test -n "$F77"; then
+  { echo "$as_me:$LINENO: result: $F77" >&5
+echo "${ECHO_T}$F77" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+    test -n "$F77" && break
+  done
+fi
+if test -z "$F77"; then
+  ac_ct_F77=$F77
+  for ac_prog in g77 f77 xlf frt pgf77 cf77 fort77 fl32 af77 f90 xlf90 pgf90 pghpf epcf90 gfortran g95 f95 fort xlf95 ifort ifc efc pgf95 lf95 ftn
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_F77"; then
+  ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_F77="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_F77=$ac_cv_prog_ac_ct_F77
+if test -n "$ac_ct_F77"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_F77" >&5
+echo "${ECHO_T}$ac_ct_F77" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+  test -n "$ac_ct_F77" && break
+done
+
+  if test "x$ac_ct_F77" = x; then
+    F77=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    F77=$ac_ct_F77
+  fi
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO: checking for Fortran 77 compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (ac_try="$ac_compiler --version >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler --version >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -v >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -v >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (ac_try="$ac_compiler -V >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compiler -V >&5") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file.  (Note that this only needs to work for GNU compilers.)
+ac_save_ext=$ac_ext
+ac_ext=F
+{ echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6; }
+if test "${ac_cv_f77_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+      program main
+#ifndef __GNUC__
+       choke me
+#endif
+
+      end
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_compiler_gnu=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_f77_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6; }
+ac_ext=$ac_save_ext
+ac_test_FFLAGS=${FFLAGS+set}
+ac_save_FFLAGS=$FFLAGS
+FFLAGS=
+{ echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5
+echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6; }
+if test "${ac_cv_prog_f77_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  FFLAGS=-g
+cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_f77_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_prog_f77_g=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5
+echo "${ECHO_T}$ac_cv_prog_f77_g" >&6; }
+if test "$ac_test_FFLAGS" = set; then
+  FFLAGS=$ac_save_FFLAGS
+elif test $ac_cv_prog_f77_g = yes; then
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-g -O2"
+  else
+    FFLAGS="-g"
+  fi
+else
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-O2"
+  else
+    FFLAGS=
+  fi
+fi
+
+G77=`test $ac_compiler_gnu = yes && echo yes`
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+
+# find the maximum length of command line arguments
+{ echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5
+echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6; }
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ 	]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    # If test is not a shell built-in, we'll probably end up computing a
+    # maximum length that is only half of the actual maximum length, but
+    # we can't tell.
+    SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+    while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \
+	       = "XX$teststring") >/dev/null 2>&1 &&
+	    new_result=`expr "X$teststring" : ".*" 2>&1` &&
+	    lt_cv_sys_max_cmd_len=$new_result &&
+	    test $i != 17 # 1/2 MB should be enough
+    do
+      i=`expr $i + 1`
+      teststring=$teststring$teststring
+    done
+    teststring=
+    # Add a significant safety factor because C++ compilers can tack on massive
+    # amounts of additional arguments before passing them to the linker.
+    # It appears as though 1/2 is a usable value.
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  { echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5
+echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6; }
+fi
+
+
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5
+echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6; }
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+linux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDGIRSTW]'
+    lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+    lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ 	]\($symcode$symcode*\)[ 	][ 	]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5
+  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if grep ' nm_test_var$' "$nlist" >/dev/null; then
+	if grep ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
+
+	  cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
+	  cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_save_LIBS="$LIBS"
+	  lt_save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$lt_save_LIBS"
+	  CFLAGS="$lt_save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { echo "$as_me:$LINENO: result: failed" >&5
+echo "${ECHO_T}failed" >&6; }
+else
+  { echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6; }
+fi
+
+{ echo "$as_me:$LINENO: checking for objdir" >&5
+echo $ECHO_N "checking for objdir... $ECHO_C" >&6; }
+if test "${lt_cv_objdir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5
+echo "${ECHO_T}$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AR="${ac_tool_prefix}ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+echo "${ECHO_T}$ac_ct_AR" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&5
+echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
+whose name does not start with the host triplet.  If you think this
+configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$SED" && SED=sed
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
+echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { echo "$as_me:$LINENO: checking for file" >&5
+echo $ECHO_N "checking for file... $ECHO_C" >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+enable_dlopen=no
+enable_win32_dll=no
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then
+  withval=$with_pic; pic_mode="$withval"
+else
+  pic_mode=default
+fi
+
+test -z "$pic_mode" && pic_mode=default
+
+# Use C for the default configuration in the libtool script
+tagname=
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}\n'
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+
+
+{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; }
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:9770: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:9774: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+      darwin*)
+        # PIC is the default on this platform
+        # Common symbols not allowed in MH_DYLIB files
+       case $cc_basename in
+         xlc*)
+         lt_prog_compiler_pic='-qnocommon'
+         lt_prog_compiler_wl='-Wl,'
+         ;;
+       esac
+       ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    linux*)
+      case $cc_basename in
+      icc* | ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fpic'
+	lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic" >&6; }
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+
+{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_pic_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:10038: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:10042: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_prog_compiler_pic_works=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_static_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works=yes
+       fi
+     else
+       lt_prog_compiler_static_works=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works" >&6; }
+
+if test x"$lt_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:10142: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:10146: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6; }
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  enable_shared_with_static_runtimes=no
+  archive_cmds=
+  archive_expsym_cmds=
+  old_archive_From_new_cmds=
+  old_archive_from_expsyms_cmds=
+  export_dynamic_flag_spec=
+  whole_archive_flag_spec=
+  thread_safe_flag_spec=
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_flag_spec_ld=
+  hardcode_libdir_separator=
+  hardcode_direct=no
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  link_all_deplibs=unknown
+  hardcode_automatic=no
+  module_cmds=
+  module_expsym_cmds=
+  always_export_symbols=no
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+  # Just being paranoid about ensuring that cc_basename is set.
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+	whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+  	whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>/dev/null` in
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs=no
+	cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+
+      # Samuel A. Falvo II <kc5tja at dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    interix3*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    linux*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	tmp_addflag=
+	case $cc_basename,$host_cpu in
+	pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)		# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	esac
+	archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+	if test $supports_anon_versioning = yes; then
+	  archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
+  cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+  $echo "local: *; };" >> $output_objdir/$libname.ver~
+	  $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	fi
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+	  for ld_flag in $LDFLAGS; do
+  	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+  	    aix_use_runtimelinking=yes
+  	    break
+  	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" && \
+  	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	  then
+  	  # We have reworked collect2
+  	  hardcode_direct=yes
+	  else
+  	  # We have old collect2
+  	  hardcode_direct=unsupported
+  	  # It fails to find uninstalled libraries when the uninstalled
+  	  # path is not listed in the libpath.  Setting hardcode_minus_L
+  	  # to unsupported forces relinking
+  	  hardcode_minus_L=yes
+  	  hardcode_libdir_flag_spec='-L$libdir'
+  	  hardcode_libdir_separator=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+  	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+  	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an empty executable.
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  whole_archive_flag_spec='$convenience'
+	  archive_cmds_need_lc=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs=no
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec=' '
+      allow_undefined_flag=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    darwin* | rhapsody*)
+      case $host_os in
+        rhapsody* | darwin1.[012])
+         allow_undefined_flag='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[012])
+               allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+      esac
+      archive_cmds_need_lc=no
+      hardcode_direct=no
+      hardcode_automatic=yes
+      hardcode_shlibpath_var=unsupported
+      whole_archive_flag_spec=''
+      link_all_deplibs=yes
+    if test "$GCC" = yes ; then
+    	output_verbose_link_cmd='echo'
+        archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+      archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      module_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+         archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          module_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         ld_shlibs=no
+          ;;
+      esac
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu | dragonfly*)
+      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	hardcode_direct=yes
+	export_dynamic_flag_spec='${wl}-E'
+
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_libdir_flag_spec_ld='+b $libdir'
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	*)
+	  hardcode_direct=yes
+	  export_dynamic_flag_spec='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec_ld='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      link_all_deplibs=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    openbsd*)
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec='${wl}-E'
+      else
+       case $host_os in
+	 openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	   archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	   hardcode_libdir_flag_spec='-R$libdir'
+	   ;;
+	 *)
+	   archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	   hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	   ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+	$LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z text'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+	wlarc=''
+	archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  	$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+ 	# The compiler driver will combine linker options so we
+ 	# cannot just pass the convience library names through
+ 	# without $wl, iff we do not link with $LD.
+ 	# Luckily, gcc supports the same syntax we need for Sun Studio.
+ 	# Supported since Solaris 2.6 (maybe 2.5.1?)
+ 	case $wlarc in
+ 	'')
+ 	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+ 	*)
+ 	  whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+ 	esac ;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+  fi
+
+{ echo "$as_me:$LINENO: result: $ld_shlibs" >&5
+echo "${ECHO_T}$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl
+	pic_flag=$lt_prog_compiler_pic
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag
+        allow_undefined_flag=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+	  archive_cmds_need_lc=no
+        else
+	  archive_cmds_need_lc=yes
+        fi
+        allow_undefined_flag=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      { echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5
+echo "${ECHO_T}$archive_cmds_need_lc" >&6; }
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  freebsd*) # from 4.6 on
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix3*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var" || \
+   test "X$hardcode_automatic" = "Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ echo "$as_me:$LINENO: result: $hardcode_action" >&5
+echo "${ECHO_T}$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+striplib=
+old_striplib=
+{ echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+       else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+       ;;
+   *)
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+    ;;
+  esac
+fi
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_dl_dlopen=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; }
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+   ;;
+
+  *)
+    { echo "$as_me:$LINENO: checking for shl_load" >&5
+echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; }
+if test "${ac_cv_func_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shl_load innocuous_shl_load
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef shl_load
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_shl_load || defined __stub___shl_load
+choke me
+#endif
+
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_func_shl_load=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+echo "${ECHO_T}$ac_cv_func_shl_load" >&6; }
+if test $ac_cv_func_shl_load = yes; then
+  lt_cv_dlopen="shl_load"
+else
+  { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_dld_shl_load=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; }
+if test $ac_cv_lib_dld_shl_load = yes; then
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+  { echo "$as_me:$LINENO: checking for dlopen" >&5
+echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; }
+if test "${ac_cv_func_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define dlopen innocuous_dlopen
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef dlopen
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_dlopen || defined __stub___dlopen
+choke me
+#endif
+
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_func_dlopen=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+echo "${ECHO_T}$ac_cv_func_dlopen" >&6; }
+if test $ac_cv_func_dlopen = yes; then
+  lt_cv_dlopen="dlopen"
+else
+  { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_dl_dlopen=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; }
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; }
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_svld_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_svld_dlopen=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; }
+if test $ac_cv_lib_svld_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; }
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_dld_link=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_dld_dld_link=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; }
+if test $ac_cv_lib_dld_dld_link = yes; then
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6; }
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 12594 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+    exit (status);
+}
+EOF
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self" >&6; }
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; }
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 12694 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+    exit (status);
+}
+EOF
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+# Report which library types will actually be built
+{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6; }
+
+{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; }
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case $host_os in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+    ;;
+esac
+{ echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6; }
+
+{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; }
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+{ echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6; }
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler \
+    CC \
+    LD \
+    lt_prog_compiler_wl \
+    lt_prog_compiler_pic \
+    lt_prog_compiler_static \
+    lt_prog_compiler_no_builtin_flag \
+    export_dynamic_flag_spec \
+    thread_safe_flag_spec \
+    whole_archive_flag_spec \
+    enable_shared_with_static_runtimes \
+    old_archive_cmds \
+    old_archive_from_new_cmds \
+    predep_objects \
+    postdep_objects \
+    predeps \
+    postdeps \
+    compiler_lib_search_path \
+    archive_cmds \
+    archive_expsym_cmds \
+    postinstall_cmds \
+    postuninstall_cmds \
+    old_archive_from_expsyms_cmds \
+    allow_undefined_flag \
+    no_undefined_flag \
+    export_symbols_cmds \
+    hardcode_libdir_flag_spec \
+    hardcode_libdir_flag_spec_ld \
+    hardcode_libdir_separator \
+    hardcode_automatic \
+    module_cmds \
+    module_expsym_cmds \
+    lt_cv_prog_compiler_c_o \
+    exclude_expsyms \
+    include_expsyms; do
+
+    case $var in
+    old_archive_cmds | \
+    old_archive_from_new_cmds | \
+    archive_cmds | \
+    archive_expsym_cmds | \
+    module_cmds | \
+    module_expsym_cmds | \
+    old_archive_from_expsyms_cmds | \
+    export_symbols_cmds | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="${ofile}T"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  $rm -f "$cfgfile"
+  { echo "$as_me:$LINENO: creating $ofile" >&5
+echo "$as_me: creating $ofile" >&6;}
+
+  cat <<__EOF__ >> "$cfgfile"
+#! $SHELL
+
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e 1s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# The names of the tagged configurations supported by this script.
+available_tags=
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "$cfgfile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" || \
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+# Check whether --with-tags was given.
+if test "${with_tags+set}" = set; then
+  withval=$with_tags; tagnames="$withval"
+fi
+
+
+if test -f "$ltmain" && test -n "$tagnames"; then
+  if test ! -f "${ofile}"; then
+    { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5
+echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;}
+  fi
+
+  if test -z "$LTCC"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+    if test -z "$LTCC"; then
+      { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5
+echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;}
+    else
+      { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5
+echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;}
+    fi
+  fi
+  if test -z "$LTCFLAGS"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
+  fi
+
+  # Extract list of available tagged configurations in $ofile.
+  # Note that this assumes the entire list is on one line.
+  available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
+
+  lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+  for tagname in $tagnames; do
+    IFS="$lt_save_ifs"
+    # Check whether tagname contains only valid characters
+    case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in
+    "") ;;
+    *)  { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5
+echo "$as_me: error: invalid tag name: $tagname" >&2;}
+   { (exit 1); exit 1; }; }
+	;;
+    esac
+
+    if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
+    then
+      { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5
+echo "$as_me: error: tag name \"$tagname\" already exists" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+    # Update the list of available tags.
+    if test -n "$tagname"; then
+      echo appending configuration tag \"$tagname\" to $ofile
+
+      case $tagname in
+      CXX)
+	if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+	    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+	    (test "X$CXX" != "Xg++"))) ; then
+	  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_flag_spec_ld_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_LD=$LD
+lt_save_GCC=$GCC
+GCC=$GXX
+lt_save_with_gnu_ld=$with_gnu_ld
+lt_save_path_LD=$lt_cv_path_LD
+if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+  lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+else
+  $as_unset lt_cv_prog_gnu_ld
+fi
+if test -n "${lt_cv_path_LDCXX+set}"; then
+  lt_cv_path_LD=$lt_cv_path_LDCXX
+else
+  $as_unset lt_cv_path_LD
+fi
+test -z "${LDCXX+set}" || LD=$LDCXX
+CC=${CXX-"c++"}
+compiler=$CC
+compiler_CXX=$CC
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# We don't want -fno-exception wen compiling C++ code, so set the
+# no_builtin_flag separately
+if test "$GXX" = yes; then
+  lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+else
+  lt_prog_compiler_no_builtin_flag_CXX=
+fi
+
+if test "$GXX" = yes; then
+  # Set up default GNU C++ configuration
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
+else
+  { echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+{ echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+  # Check if GNU C++ uses GNU ld as the underlying linker, since the
+  # archiving commands below assume that GNU ld is being used.
+  if test "$with_gnu_ld" = yes; then
+    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+    #     investigate it a little bit more. (MM)
+    wlarc='${wl}'
+
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
+	grep 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec_CXX=
+    fi
+  else
+    with_gnu_ld=no
+    wlarc=
+
+    # A generic and very simple default shared library creation
+    # command for GNU C++ for the case where it uses the native
+    # linker, instead of GNU ld.  If possible, this setting should
+    # overridden to take advantage of the native linker features on
+    # the platform it is being used on.
+    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+  fi
+
+  # Commands to make compiler produce verbose output that lists
+  # what "hidden" libraries, object files and flags are used when
+  # linking a shared library.
+  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+else
+  GXX=no
+  with_gnu_ld=no
+  wlarc=
+fi
+
+# PORTME: fill in a description of your system's C++ link characteristics
+{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
+ld_shlibs_CXX=yes
+case $host_os in
+  aix3*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+	for ld_flag in $LDFLAGS; do
+	  case $ld_flag in
+	  *-brtl*)
+	    aix_use_runtimelinking=yes
+	    break
+	    ;;
+	  esac
+	done
+	;;
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    archive_cmds_CXX=''
+    hardcode_direct_CXX=yes
+    hardcode_libdir_separator_CXX=':'
+    link_all_deplibs_CXX=yes
+
+    if test "$GXX" = yes; then
+      case $host_os in aix4.[012]|aix4.[012].*)
+      # We only want to do this on AIX 4.2 and lower, the check
+      # below for broken collect2 doesn't work under 4.3+
+	collect2name=`${CC} -print-prog-name=collect2`
+	if test -f "$collect2name" && \
+	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	then
+	  # We have reworked collect2
+	  hardcode_direct_CXX=yes
+	else
+	  # We have old collect2
+	  hardcode_direct_CXX=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L_CXX=yes
+	  hardcode_libdir_flag_spec_CXX='-L$libdir'
+	  hardcode_libdir_separator_CXX=
+	fi
+	;;
+      esac
+      shared_flag='-shared'
+      if test "$aix_use_runtimelinking" = yes; then
+	shared_flag="$shared_flag "'${wl}-G'
+      fi
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	shared_flag='-G'
+      else
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag='${wl}-G'
+	else
+	  shared_flag='${wl}-bM:SRE'
+	fi
+      fi
+    fi
+
+    # It seems that -bexpall does not export symbols beginning with
+    # underscore (_), so it is better to generate a list of symbols to export.
+    always_export_symbols_CXX=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      allow_undefined_flag_CXX='-berok'
+      # Determine the default libpath from the value encoded in an empty executable.
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+      hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+      archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+     else
+      if test "$host_cpu" = ia64; then
+	hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+	allow_undefined_flag_CXX="-z nodefs"
+	archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+      else
+	# Determine the default libpath from the value encoded in an empty executable.
+	cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+	# Warning - without using the other run time loading flags,
+	# -berok will link without error, but may produce a broken library.
+	no_undefined_flag_CXX=' ${wl}-bernotok'
+	allow_undefined_flag_CXX=' ${wl}-berok'
+	# Exported symbols can be pulled into shared objects from archives
+	whole_archive_flag_spec_CXX='$convenience'
+	archive_cmds_need_lc_CXX=yes
+	# This is similar to how AIX traditionally builds its shared libraries.
+	archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+      fi
+    fi
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag_CXX=unsupported
+      # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs_CXX=no
+    fi
+    ;;
+
+  chorus*)
+    case $cc_basename in
+      *)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+    esac
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+    # as there is no search path for DLLs.
+    hardcode_libdir_flag_spec_CXX='-L$libdir'
+    allow_undefined_flag_CXX=unsupported
+    always_export_symbols_CXX=no
+    enable_shared_with_static_runtimes_CXX=yes
+
+    if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+      archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      # If the export-symbols file already is a .def file (1st line
+      # is EXPORTS), use it as is; otherwise, prepend...
+      archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	cp $export_symbols $output_objdir/$soname.def;
+      else
+	echo EXPORTS > $output_objdir/$soname.def;
+	cat $export_symbols >> $output_objdir/$soname.def;
+      fi~
+      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+    else
+      ld_shlibs_CXX=no
+    fi
+  ;;
+      darwin* | rhapsody*)
+        case $host_os in
+        rhapsody* | darwin1.[012])
+         allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[012])
+               allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+        esac
+      archive_cmds_need_lc_CXX=no
+      hardcode_direct_CXX=no
+      hardcode_automatic_CXX=yes
+      hardcode_shlibpath_var_CXX=unsupported
+      whole_archive_flag_spec_CXX=''
+      link_all_deplibs_CXX=yes
+
+    if test "$GXX" = yes ; then
+      lt_int_apple_cc_single_mod=no
+      output_verbose_link_cmd='echo'
+      if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then
+       lt_int_apple_cc_single_mod=yes
+      fi
+      if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+       archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      else
+          archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+        fi
+        module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+        # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+          if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+            archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          else
+            archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          fi
+            module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+          archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+          module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+          archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         ld_shlibs_CXX=no
+          ;;
+      esac
+      fi
+        ;;
+
+  dgux*)
+    case $cc_basename in
+      ec++*)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      ghcx*)
+	# Green Hills C++ Compiler
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+    esac
+    ;;
+  freebsd[12]*)
+    # C++ shared libraries reported to be fairly broken before switch to ELF
+    ld_shlibs_CXX=no
+    ;;
+  freebsd-elf*)
+    archive_cmds_need_lc_CXX=no
+    ;;
+  freebsd* | kfreebsd*-gnu | dragonfly*)
+    # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+    # conventions
+    ld_shlibs_CXX=yes
+    ;;
+  gnu*)
+    ;;
+  hpux9*)
+    hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator_CXX=:
+    export_dynamic_flag_spec_CXX='${wl}-E'
+    hardcode_direct_CXX=yes
+    hardcode_minus_L_CXX=yes # Not in the search PATH,
+				# but as the default
+				# location of the library.
+
+    case $cc_basename in
+    CC*)
+      # FIXME: insert proper C++ library support
+      ld_shlibs_CXX=no
+      ;;
+    aCC*)
+      archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      #
+      # There doesn't appear to be a way to prevent this compiler from
+      # explicitly linking system object files so we need to strip them
+      # from the output so that they don't get included in the library
+      # dependencies.
+      output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+      ;;
+    *)
+      if test "$GXX" = yes; then
+        archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+      fi
+      ;;
+    esac
+    ;;
+  hpux10*|hpux11*)
+    if test $with_gnu_ld = no; then
+      hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_CXX=:
+
+      case $host_cpu in
+      hppa*64*|ia64*)
+	hardcode_libdir_flag_spec_ld_CXX='+b $libdir'
+        ;;
+      *)
+	export_dynamic_flag_spec_CXX='${wl}-E'
+        ;;
+      esac
+    fi
+    case $host_cpu in
+    hppa*64*|ia64*)
+      hardcode_direct_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      ;;
+    *)
+      hardcode_direct_CXX=yes
+      hardcode_minus_L_CXX=yes # Not in the search PATH,
+					      # but as the default
+					      # location of the library.
+      ;;
+    esac
+
+    case $cc_basename in
+      CC*)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      aCC*)
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  ;;
+	esac
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes; then
+	  if test $with_gnu_ld = no; then
+	    case $host_cpu in
+	    hppa*64*)
+	      archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      ;;
+	    ia64*)
+	      archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      ;;
+	    *)
+	      archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      ;;
+	    esac
+	  fi
+	else
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	fi
+	;;
+    esac
+    ;;
+  interix3*)
+    hardcode_direct_CXX=no
+    hardcode_shlibpath_var_CXX=no
+    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+    export_dynamic_flag_spec_CXX='${wl}-E'
+    # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+    # Instead, shared libraries are loaded at an image base (0x10000000 by
+    # default) and relocated if they conflict, which is a slow very memory
+    # consuming and fragmenting process.  To avoid this, we pick a random,
+    # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+    # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+    archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    ;;
+  irix5* | irix6*)
+    case $cc_basename in
+      CC*)
+	# SGI C++
+	archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	# Archives containing C++ object files must be created using
+	# "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	# necessary to make sure instantiated templates are included
+	# in the archive.
+	old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	;;
+      *)
+	if test "$GXX" = yes; then
+	  if test "$with_gnu_ld" = no; then
+	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	  else
+	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+	  fi
+	fi
+	link_all_deplibs_CXX=yes
+	;;
+    esac
+    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator_CXX=:
+    ;;
+  linux*)
+    case $cc_basename in
+      KCC*)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+	hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+	# Archives containing C++ object files must be created using
+	# "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+	;;
+      icpc*)
+	# Intel C++
+	with_gnu_ld=yes
+	# version 8.0 and above of icpc choke on multiply defined symbols
+	# if we add $predep_objects and $postdep_objects, however 7.1 and
+	# earlier do not add the objects themselves.
+	case `$CC -V 2>&1` in
+	*"Version 7."*)
+  	  archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+  	  archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  ;;
+	*)  # Version 8.0 or newer
+	  tmp_idyn=
+	  case $host_cpu in
+	    ia64*) tmp_idyn=' -i_dynamic';;
+	  esac
+  	  archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	  archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  ;;
+	esac
+	archive_cmds_need_lc_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	;;
+      pgCC*)
+        # Portland Group C++ compiler
+	archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+  	archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+
+	hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+        ;;
+      cxx*)
+	# Compaq C++
+	archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	runpath_var=LD_RUN_PATH
+	hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	hardcode_libdir_separator_CXX=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+    esac
+    ;;
+  lynxos*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  m88k*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  mvs*)
+    case $cc_basename in
+      cxx*)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+    esac
+    ;;
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+      wlarc=
+      hardcode_libdir_flag_spec_CXX='-R$libdir'
+      hardcode_direct_CXX=yes
+      hardcode_shlibpath_var_CXX=no
+    fi
+    # Workaround some broken pre-1.5 toolchains
+    output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+    ;;
+  openbsd2*)
+    # C++ shared libraries are fairly broken
+    ld_shlibs_CXX=no
+    ;;
+  openbsd*)
+    hardcode_direct_CXX=yes
+    hardcode_shlibpath_var_CXX=no
+    archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+    if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+      export_dynamic_flag_spec_CXX='${wl}-E'
+      whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    fi
+    output_verbose_link_cmd='echo'
+    ;;
+  osf3*)
+    case $cc_basename in
+      KCC*)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	hardcode_libdir_separator_CXX=:
+
+	# Archives containing C++ object files must be created using
+	# "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+
+	;;
+      RCC*)
+	# Rational C++ 2.4.1
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      cxx*)
+	allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	hardcode_libdir_separator_CXX=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	  archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+	  # Commands to make compiler produce verbose output that lists
+	  # what "hidden" libraries, object files and flags are used when
+	  # linking a shared library.
+	  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+	else
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	fi
+	;;
+    esac
+    ;;
+  osf4* | osf5*)
+    case $cc_basename in
+      KCC*)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	hardcode_libdir_separator_CXX=:
+
+	# Archives containing C++ object files must be created using
+	# the KAI C++ compiler.
+	old_archive_cmds_CXX='$CC -o $oldlib $oldobjs'
+	;;
+      RCC*)
+	# Rational C++ 2.4.1
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      cxx*)
+	allow_undefined_flag_CXX=' -expect_unresolved \*'
+	archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	  echo "-hidden">> $lib.exp~
+	  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp  `test -n "$verstring" && echo -set_version	$verstring` -update_registry ${output_objdir}/so_locations -o $lib~
+	  $rm $lib.exp'
+
+	hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	hardcode_libdir_separator_CXX=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	 archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+	  # Commands to make compiler produce verbose output that lists
+	  # what "hidden" libraries, object files and flags are used when
+	  # linking a shared library.
+	  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+	else
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	fi
+	;;
+    esac
+    ;;
+  psos*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  sunos4*)
+    case $cc_basename in
+      CC*)
+	# Sun C++ 4.x
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      lcc*)
+	# Lucid
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+    esac
+    ;;
+  solaris*)
+    case $cc_basename in
+      CC*)
+	# Sun C++ 4.2, 5.x and Centerline C++
+        archive_cmds_need_lc_CXX=yes
+	no_undefined_flag_CXX=' -zdefs'
+	archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	$CC -G${allow_undefined_flag}  ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	hardcode_libdir_flag_spec_CXX='-R$libdir'
+	hardcode_shlibpath_var_CXX=no
+	case $host_os in
+	  solaris2.[0-5] | solaris2.[0-5].*) ;;
+	  *)
+	    # The C++ compiler is used as linker so we must use $wl
+	    # flag to pass the commands to the underlying system
+	    # linker. We must also pass each convience library through
+	    # to the system linker between allextract/defaultextract.
+	    # The C++ compiler will combine linker options so we
+	    # cannot just pass the convience library names through
+	    # without $wl.
+	    # Supported since Solaris 2.6 (maybe 2.5.1?)
+	    whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract'
+	    ;;
+	esac
+	link_all_deplibs_CXX=yes
+
+	output_verbose_link_cmd='echo'
+
+	# Archives containing C++ object files must be created using
+	# "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	# necessary to make sure instantiated templates are included
+	# in the archive.
+	old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	;;
+      gcx*)
+	# Green Hills C++ Compiler
+	archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	# The C++ compiler must be used to create the archive.
+	old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	;;
+      *)
+	# GNU C++ compiler with Solaris linker
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+	  if $CC --version | grep -v '^2\.7' > /dev/null; then
+	    archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+	  else
+	    # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	    # platform.
+	    archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+	  fi
+
+	  hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	fi
+	;;
+    esac
+    ;;
+  sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+    no_undefined_flag_CXX='${wl}-z,text'
+    archive_cmds_need_lc_CXX=no
+    hardcode_shlibpath_var_CXX=no
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+	archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      *)
+	archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+    esac
+    ;;
+  sysv5* | sco3.2v5* | sco5v6*)
+    # Note: We can NOT use -z defs as we might desire, because we do not
+    # link with -lc, and that would cause any symbols used from libc to
+    # always be unresolved, which means just about no library would
+    # ever link correctly.  If we're not using GNU ld we use -z text
+    # though, which does catch some bad symbols but isn't as heavy-handed
+    # as -z defs.
+    # For security reasons, it is highly recommended that you always
+    # use absolute paths for naming shared libraries, and exclude the
+    # DT_RUNPATH tag from executables and libraries.  But doing so
+    # requires that you compile everything twice, which is a pain.
+    # So that behaviour is only enabled if SCOABSPATH is set to a
+    # non-empty value in the environment.  Most likely only useful for
+    # creating official distributions of packages.
+    # This is a hack until libtool officially supports absolute path
+    # names for shared libraries.
+    no_undefined_flag_CXX='${wl}-z,text'
+    allow_undefined_flag_CXX='${wl}-z,nodefs'
+    archive_cmds_need_lc_CXX=no
+    hardcode_shlibpath_var_CXX=no
+    hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+    hardcode_libdir_separator_CXX=':'
+    link_all_deplibs_CXX=yes
+    export_dynamic_flag_spec_CXX='${wl}-Bexport'
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+	archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      *)
+	archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+    esac
+    ;;
+  tandem*)
+    case $cc_basename in
+      NCC*)
+	# NonStop-UX NCC 3.20
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+    esac
+    ;;
+  vxworks*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  *)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+esac
+{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+echo "${ECHO_T}$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+GCC_CXX="$GXX"
+LD_CXX="$LD"
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+
+cat > conftest.$ac_ext <<EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+EOF
+
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  # The `*' in the case matches for architectures that use `case' in
+  # $output_verbose_cmd can trigger glob expansion during the loop
+  # eval without this substitution.
+  output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
+
+  for p in `eval $output_verbose_link_cmd`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" \
+	  || test $p = "-R"; then
+	 prev=$p
+	 continue
+       else
+	 prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 case $p in
+	 -L* | -R*)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$compiler_lib_search_path_CXX"; then
+	     compiler_lib_search_path_CXX="${prev}${p}"
+	   else
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$postdeps_CXX"; then
+	   postdeps_CXX="${prev}${p}"
+	 else
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+	 fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$predep_objects_CXX"; then
+	   predep_objects_CXX="$p"
+	 else
+	   predep_objects_CXX="$predep_objects_CXX $p"
+	 fi
+       else
+	 if test -z "$postdep_objects_CXX"; then
+	   postdep_objects_CXX="$p"
+	 else
+	   postdep_objects_CXX="$postdep_objects_CXX $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$rm -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix3*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    postdeps_CXX='-lCstd -lCrun'
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+
+lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_CXX='-Bstatic'
+      fi
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | os2* | pw32*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic_CXX=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	;;
+      *)
+	lt_prog_compiler_pic_CXX='-fPIC'
+	;;
+      esac
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix4* | aix5*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  lt_prog_compiler_static_CXX='-Bstatic'
+	else
+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+       darwin*)
+         # PIC is the default on this platform
+         # Common symbols not allowed in MH_DYLIB files
+         case $cc_basename in
+           xlc*)
+           lt_prog_compiler_pic_CXX='-qnocommon'
+           lt_prog_compiler_wl_CXX='-Wl,'
+           ;;
+         esac
+       ;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | kfreebsd*-gnu | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      lt_prog_compiler_pic_CXX='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      lt_prog_compiler_pic_CXX='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux*)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  icpc* | ecpc*)
+	    # Intel C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  pgCC*)
+	    # Portland Group C++ compiler.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fpic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    lt_prog_compiler_pic_CXX='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    lt_prog_compiler_wl_CXX='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    lt_prog_compiler_pic_CXX='-pic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	lt_prog_compiler_can_build_shared_CXX=no
+	;;
+    esac
+  fi
+
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6; }
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+
+{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_CXX=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:15066: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:15070: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_prog_compiler_pic_works_CXX=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_static_works_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works_CXX=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works_CXX=yes
+       fi
+     else
+       lt_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+fi
+
+
+{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:15170: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:15174: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix4* | aix5*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+  ;;
+  cygwin* | mingw*)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+
+{ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+echo "${ECHO_T}$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_CXX
+	pic_flag=$lt_prog_compiler_pic_CXX
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+        allow_undefined_flag_CXX=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+	  archive_cmds_need_lc_CXX=no
+        else
+	  archive_cmds_need_lc_CXX=yes
+        fi
+        allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6; }
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  freebsd*) # from 4.6 on
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix3*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" || \
+   test -n "$runpath_var_CXX" || \
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_CXX" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+{ echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5
+echo "${ECHO_T}$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_CXX \
+    CC_CXX \
+    LD_CXX \
+    lt_prog_compiler_wl_CXX \
+    lt_prog_compiler_pic_CXX \
+    lt_prog_compiler_static_CXX \
+    lt_prog_compiler_no_builtin_flag_CXX \
+    export_dynamic_flag_spec_CXX \
+    thread_safe_flag_spec_CXX \
+    whole_archive_flag_spec_CXX \
+    enable_shared_with_static_runtimes_CXX \
+    old_archive_cmds_CXX \
+    old_archive_from_new_cmds_CXX \
+    predep_objects_CXX \
+    postdep_objects_CXX \
+    predeps_CXX \
+    postdeps_CXX \
+    compiler_lib_search_path_CXX \
+    archive_cmds_CXX \
+    archive_expsym_cmds_CXX \
+    postinstall_cmds_CXX \
+    postuninstall_cmds_CXX \
+    old_archive_from_expsyms_cmds_CXX \
+    allow_undefined_flag_CXX \
+    no_undefined_flag_CXX \
+    export_symbols_cmds_CXX \
+    hardcode_libdir_flag_spec_CXX \
+    hardcode_libdir_flag_spec_ld_CXX \
+    hardcode_libdir_separator_CXX \
+    hardcode_automatic_CXX \
+    module_cmds_CXX \
+    module_expsym_cmds_CXX \
+    lt_cv_prog_compiler_c_o_CXX \
+    exclude_expsyms_CXX \
+    include_expsyms_CXX; do
+
+    case $var in
+    old_archive_cmds_CXX | \
+    old_archive_from_new_cmds_CXX | \
+    archive_cmds_CXX | \
+    archive_expsym_cmds_CXX | \
+    module_cmds_CXX | \
+    module_expsym_cmds_CXX | \
+    old_archive_from_expsyms_cmds_CXX | \
+    export_symbols_cmds_CXX | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_CXX
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_CXX
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_CXX
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_CXX
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_CXX
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_CXX"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC=$lt_save_CC
+LDCXX=$LD
+LD=$lt_save_LD
+GCC=$lt_save_GCC
+with_gnu_ldcxx=$with_gnu_ld
+with_gnu_ld=$lt_save_with_gnu_ld
+lt_cv_path_LDCXX=$lt_cv_path_LD
+lt_cv_path_LD=$lt_save_path_LD
+lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+
+	else
+	  tagname=""
+	fi
+	;;
+
+      F77)
+	if test -n "$F77" && test "X$F77" != "Xno"; then
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+
+archive_cmds_need_lc_F77=no
+allow_undefined_flag_F77=
+always_export_symbols_F77=no
+archive_expsym_cmds_F77=
+export_dynamic_flag_spec_F77=
+hardcode_direct_F77=no
+hardcode_libdir_flag_spec_F77=
+hardcode_libdir_flag_spec_ld_F77=
+hardcode_libdir_separator_F77=
+hardcode_minus_L_F77=no
+hardcode_automatic_F77=no
+module_cmds_F77=
+module_expsym_cmds_F77=
+link_all_deplibs_F77=unknown
+old_archive_cmds_F77=$old_archive_cmds
+no_undefined_flag_F77=
+whole_archive_flag_spec_F77=
+enable_shared_with_static_runtimes_F77=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+objext_F77=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="      subroutine t\n      return\n      end\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="      program t\n      end\n"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${F77-"f77"}
+compiler=$CC
+compiler_F77=$CC
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+{ echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6; }
+
+{ echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6; }
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case $host_os in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+esac
+{ echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6; }
+
+{ echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6; }
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+{ echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6; }
+
+GCC_F77="$G77"
+LD_F77="$LD"
+
+lt_prog_compiler_wl_F77=
+lt_prog_compiler_pic_F77=
+lt_prog_compiler_static_F77=
+
+{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl_F77='-Wl,'
+    lt_prog_compiler_static_F77='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_F77='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_F77='-fno-common'
+      ;;
+
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared_F77=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic_F77=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic_F77='-fPIC'
+	;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic_F77='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_F77='-Bstatic'
+      else
+	lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+      darwin*)
+        # PIC is the default on this platform
+        # Common symbols not allowed in MH_DYLIB files
+       case $cc_basename in
+         xlc*)
+         lt_prog_compiler_pic_F77='-qnocommon'
+         lt_prog_compiler_wl_F77='-Wl,'
+         ;;
+       esac
+       ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic_F77='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static_F77='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static_F77='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    linux*)
+      case $cc_basename in
+      icc* | ecc*)
+	lt_prog_compiler_wl_F77='-Wl,'
+	lt_prog_compiler_pic_F77='-KPIC'
+	lt_prog_compiler_static_F77='-static'
+        ;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl_F77='-Wl,'
+	lt_prog_compiler_pic_F77='-fpic'
+	lt_prog_compiler_static_F77='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl_F77='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static_F77='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static_F77='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	lt_prog_compiler_wl_F77='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl_F77='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl_F77='-Qoption ld '
+      lt_prog_compiler_pic_F77='-PIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic_F77='-Kconform_pic'
+	lt_prog_compiler_static_F77='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_can_build_shared_F77=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic_F77='-pic'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared_F77=no
+      ;;
+    esac
+  fi
+
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6; }
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_F77"; then
+
+{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_pic_works_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_F77=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_F77"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:16740: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:16744: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_prog_compiler_pic_works_F77=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6; }
+
+if test x"$lt_prog_compiler_pic_works_F77" = xyes; then
+    case $lt_prog_compiler_pic_F77 in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;;
+     esac
+else
+    lt_prog_compiler_pic_F77=
+     lt_prog_compiler_can_build_shared_F77=no
+fi
+
+fi
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_F77=
+    ;;
+  *)
+    lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77"
+    ;;
+esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\"
+{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_static_works_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works_F77=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works_F77=yes
+       fi
+     else
+       lt_prog_compiler_static_works_F77=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6; }
+
+if test x"$lt_prog_compiler_static_works_F77" = xyes; then
+    :
+else
+    lt_prog_compiler_static_F77=
+fi
+
+
+{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
+if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_F77=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:16844: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:16848: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_F77=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6; }
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
+
+  runpath_var=
+  allow_undefined_flag_F77=
+  enable_shared_with_static_runtimes_F77=no
+  archive_cmds_F77=
+  archive_expsym_cmds_F77=
+  old_archive_From_new_cmds_F77=
+  old_archive_from_expsyms_cmds_F77=
+  export_dynamic_flag_spec_F77=
+  whole_archive_flag_spec_F77=
+  thread_safe_flag_spec_F77=
+  hardcode_libdir_flag_spec_F77=
+  hardcode_libdir_flag_spec_ld_F77=
+  hardcode_libdir_separator_F77=
+  hardcode_direct_F77=no
+  hardcode_minus_L_F77=no
+  hardcode_shlibpath_var_F77=unsupported
+  link_all_deplibs_F77=unknown
+  hardcode_automatic_F77=no
+  module_cmds_F77=
+  module_expsym_cmds_F77=
+  always_export_symbols_F77=no
+  export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms_F77=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+  # Just being paranoid about ensuring that cc_basename is set.
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs_F77=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec_F77='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+	whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+  	whole_archive_flag_spec_F77=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>/dev/null` in
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs_F77=no
+	cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+
+      # Samuel A. Falvo II <kc5tja at dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs_F77=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag_F77=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      allow_undefined_flag_F77=unsupported
+      always_export_symbols_F77=no
+      enable_shared_with_static_runtimes_F77=yes
+      export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+
+    interix3*)
+      hardcode_direct_F77=no
+      hardcode_shlibpath_var_F77=no
+      hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec_F77='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    linux*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	tmp_addflag=
+	case $cc_basename,$host_cpu in
+	pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)		# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	esac
+	archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+	if test $supports_anon_versioning = yes; then
+	  archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~
+  cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+  $echo "local: *; };" >> $output_objdir/$libname.ver~
+	  $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	fi
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+	ld_shlibs_F77=no
+	cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs_F77=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+	    archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+	    archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+	  else
+	    ld_shlibs_F77=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs_F77" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec_F77=
+      export_dynamic_flag_spec_F77=
+      whole_archive_flag_spec_F77=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag_F77=unsupported
+      always_export_symbols_F77=yes
+      archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L_F77=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct_F77=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+	  export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+	  for ld_flag in $LDFLAGS; do
+  	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+  	    aix_use_runtimelinking=yes
+  	    break
+  	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds_F77=''
+      hardcode_direct_F77=yes
+      hardcode_libdir_separator_F77=':'
+      link_all_deplibs_F77=yes
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" && \
+  	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	  then
+  	  # We have reworked collect2
+  	  hardcode_direct_F77=yes
+	  else
+  	  # We have old collect2
+  	  hardcode_direct_F77=unsupported
+  	  # It fails to find uninstalled libraries when the uninstalled
+  	  # path is not listed in the libpath.  Setting hardcode_minus_L
+  	  # to unsupported forces relinking
+  	  hardcode_minus_L_F77=yes
+  	  hardcode_libdir_flag_spec_F77='-L$libdir'
+  	  hardcode_libdir_separator_F77=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+  	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+  	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols_F77=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag_F77='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+	archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag_F77="-z nodefs"
+	  archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an empty executable.
+	 cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	 hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag_F77=' ${wl}-bernotok'
+	  allow_undefined_flag_F77=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  whole_archive_flag_spec_F77='$convenience'
+	  archive_cmds_need_lc_F77=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs_F77=no
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec_F77=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec_F77=' '
+      allow_undefined_flag_F77=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds_F77='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path_F77='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes_F77=yes
+      ;;
+
+    darwin* | rhapsody*)
+      case $host_os in
+        rhapsody* | darwin1.[012])
+         allow_undefined_flag_F77='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[012])
+               allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+      esac
+      archive_cmds_need_lc_F77=no
+      hardcode_direct_F77=no
+      hardcode_automatic_F77=yes
+      hardcode_shlibpath_var_F77=unsupported
+      whole_archive_flag_spec_F77=''
+      link_all_deplibs_F77=yes
+    if test "$GCC" = yes ; then
+    	output_verbose_link_cmd='echo'
+        archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+      archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+         archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         ld_shlibs_F77=no
+          ;;
+      esac
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs_F77=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu | dragonfly*)
+      archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      hardcode_direct_F77=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L_F77=yes
+      export_dynamic_flag_spec_F77='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator_F77=:
+
+	hardcode_direct_F77=yes
+	export_dynamic_flag_spec_F77='${wl}-E'
+
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L_F77=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator_F77=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_libdir_flag_spec_ld_F77='+b $libdir'
+	  hardcode_direct_F77=no
+	  hardcode_shlibpath_var_F77=no
+	  ;;
+	*)
+	  hardcode_direct_F77=yes
+	  export_dynamic_flag_spec_F77='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L_F77=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec_ld_F77='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      link_all_deplibs_F77=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    newsos6)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    openbsd*)
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_F77='${wl}-E'
+      else
+       case $host_os in
+	 openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	   archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	   hardcode_libdir_flag_spec_F77='-R$libdir'
+	   ;;
+	 *)
+	   archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	   hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+	   ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+      allow_undefined_flag_F77=unsupported
+      archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag_F77=' -expect_unresolved \*'
+	archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag_F77=' -expect_unresolved \*'
+	archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+	$LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec_F77='-rpath $libdir'
+      fi
+      hardcode_libdir_separator_F77=:
+      ;;
+
+    solaris*)
+      no_undefined_flag_F77=' -z text'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+	wlarc=''
+	archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  	$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_shlibpath_var_F77=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+ 	# The compiler driver will combine linker options so we
+ 	# cannot just pass the convience library names through
+ 	# without $wl, iff we do not link with $LD.
+ 	# Luckily, gcc supports the same syntax we need for Sun Studio.
+ 	# Supported since Solaris 2.6 (maybe 2.5.1?)
+ 	case $wlarc in
+ 	'')
+ 	  whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;;
+ 	*)
+ 	  whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+ 	esac ;;
+      esac
+      link_all_deplibs_F77=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct_F77=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds_F77='$CC -r -o $output$reload_objs'
+	  hardcode_direct_F77=no
+        ;;
+	motorola)
+	  archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_F77=no
+      export_dynamic_flag_spec_F77='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var_F77=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs_F77=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
+      no_undefined_flag_F77='${wl}-z,text'
+      archive_cmds_need_lc_F77=no
+      hardcode_shlibpath_var_F77=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag_F77='${wl}-z,text'
+      allow_undefined_flag_F77='${wl}-z,nodefs'
+      archive_cmds_need_lc_F77=no
+      hardcode_shlibpath_var_F77=no
+      hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator_F77=':'
+      link_all_deplibs_F77=yes
+      export_dynamic_flag_spec_F77='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    *)
+      ld_shlibs_F77=no
+      ;;
+    esac
+  fi
+
+{ echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5
+echo "${ECHO_T}$ld_shlibs_F77" >&6; }
+test "$ld_shlibs_F77" = no && can_build_shared=no
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_F77" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_F77=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_F77 in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_F77
+	pic_flag=$lt_prog_compiler_pic_F77
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_F77
+        allow_undefined_flag_F77=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+	  archive_cmds_need_lc_F77=no
+        else
+	  archive_cmds_need_lc_F77=yes
+        fi
+        allow_undefined_flag_F77=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6; }
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  freebsd*) # from 4.6 on
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix3*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
+hardcode_action_F77=
+if test -n "$hardcode_libdir_flag_spec_F77" || \
+   test -n "$runpath_var_F77" || \
+   test "X$hardcode_automatic_F77" = "Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_F77" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no &&
+     test "$hardcode_minus_L_F77" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_F77=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_F77=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_F77=unsupported
+fi
+{ echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5
+echo "${ECHO_T}$hardcode_action_F77" >&6; }
+
+if test "$hardcode_action_F77" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_F77 \
+    CC_F77 \
+    LD_F77 \
+    lt_prog_compiler_wl_F77 \
+    lt_prog_compiler_pic_F77 \
+    lt_prog_compiler_static_F77 \
+    lt_prog_compiler_no_builtin_flag_F77 \
+    export_dynamic_flag_spec_F77 \
+    thread_safe_flag_spec_F77 \
+    whole_archive_flag_spec_F77 \
+    enable_shared_with_static_runtimes_F77 \
+    old_archive_cmds_F77 \
+    old_archive_from_new_cmds_F77 \
+    predep_objects_F77 \
+    postdep_objects_F77 \
+    predeps_F77 \
+    postdeps_F77 \
+    compiler_lib_search_path_F77 \
+    archive_cmds_F77 \
+    archive_expsym_cmds_F77 \
+    postinstall_cmds_F77 \
+    postuninstall_cmds_F77 \
+    old_archive_from_expsyms_cmds_F77 \
+    allow_undefined_flag_F77 \
+    no_undefined_flag_F77 \
+    export_symbols_cmds_F77 \
+    hardcode_libdir_flag_spec_F77 \
+    hardcode_libdir_flag_spec_ld_F77 \
+    hardcode_libdir_separator_F77 \
+    hardcode_automatic_F77 \
+    module_cmds_F77 \
+    module_expsym_cmds_F77 \
+    lt_cv_prog_compiler_c_o_F77 \
+    exclude_expsyms_F77 \
+    include_expsyms_F77; do
+
+    case $var in
+    old_archive_cmds_F77 | \
+    old_archive_from_new_cmds_F77 | \
+    archive_cmds_F77 | \
+    archive_expsym_cmds_F77 | \
+    module_cmds_F77 | \
+    module_expsym_cmds_F77 | \
+    old_archive_from_expsyms_cmds_F77 | \
+    export_symbols_cmds_F77 | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_F77
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_compiler_F77
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_F77
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_F77
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_F77
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_F77
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_F77
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_F77
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_F77
+archive_expsym_cmds=$lt_archive_expsym_cmds_F77
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_F77
+module_expsym_cmds=$lt_module_expsym_cmds_F77
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_F77
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_F77
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_F77
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_F77
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_F77
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_F77
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_F77
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_F77
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_F77
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_F77
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_F77
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_F77
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_F77
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_F77"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_F77
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_F77
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_F77
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_F77
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+	else
+	  tagname=""
+	fi
+	;;
+
+      GCJ)
+	if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+objext_GCJ=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${GCJ-"gcj"}
+compiler=$CC
+compiler_GCJ=$CC
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+archive_cmds_need_lc_GCJ=no
+
+old_archive_cmds_GCJ=$old_archive_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+
+lt_prog_compiler_no_builtin_flag_GCJ=
+
+if test "$GCC" = yes; then
+  lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin'
+
+
+{ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6; }
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:19078: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:19082: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+lt_prog_compiler_wl_GCJ=
+lt_prog_compiler_pic_GCJ=
+lt_prog_compiler_static_GCJ=
+
+{ echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; }
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl_GCJ='-Wl,'
+    lt_prog_compiler_static_GCJ='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_GCJ='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_GCJ='-fno-common'
+      ;;
+
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared_GCJ=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic_GCJ=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic_GCJ='-fPIC'
+	;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic_GCJ='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_GCJ='-Bstatic'
+      else
+	lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+      darwin*)
+        # PIC is the default on this platform
+        # Common symbols not allowed in MH_DYLIB files
+       case $cc_basename in
+         xlc*)
+         lt_prog_compiler_pic_GCJ='-qnocommon'
+         lt_prog_compiler_wl_GCJ='-Wl,'
+         ;;
+       esac
+       ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic_GCJ='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static_GCJ='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    linux*)
+      case $cc_basename in
+      icc* | ecc*)
+	lt_prog_compiler_wl_GCJ='-Wl,'
+	lt_prog_compiler_pic_GCJ='-KPIC'
+	lt_prog_compiler_static_GCJ='-static'
+        ;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl_GCJ='-Wl,'
+	lt_prog_compiler_pic_GCJ='-fpic'
+	lt_prog_compiler_static_GCJ='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl_GCJ='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static_GCJ='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static_GCJ='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	lt_prog_compiler_wl_GCJ='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl_GCJ='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl_GCJ='-Qoption ld '
+      lt_prog_compiler_pic_GCJ='-PIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic_GCJ='-Kconform_pic'
+	lt_prog_compiler_static_GCJ='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      lt_prog_compiler_can_build_shared_GCJ=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic_GCJ='-pic'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared_GCJ=no
+      ;;
+    esac
+  fi
+
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6; }
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_GCJ"; then
+
+{ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_GCJ=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_GCJ"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:19346: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:19350: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_prog_compiler_pic_works_GCJ=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6; }
+
+if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then
+    case $lt_prog_compiler_pic_GCJ in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;;
+     esac
+else
+    lt_prog_compiler_pic_GCJ=
+     lt_prog_compiler_can_build_shared_GCJ=no
+fi
+
+fi
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_GCJ=
+    ;;
+  *)
+    lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ"
+    ;;
+esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\"
+{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; }
+if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works_GCJ=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works_GCJ=yes
+       fi
+     else
+       lt_prog_compiler_static_works_GCJ=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6; }
+
+if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then
+    :
+else
+    lt_prog_compiler_static_GCJ=
+fi
+
+
+{ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; }
+if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_GCJ=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:19450: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:19454: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_GCJ=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6; }
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6; }
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+{ echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6; }
+
+  runpath_var=
+  allow_undefined_flag_GCJ=
+  enable_shared_with_static_runtimes_GCJ=no
+  archive_cmds_GCJ=
+  archive_expsym_cmds_GCJ=
+  old_archive_From_new_cmds_GCJ=
+  old_archive_from_expsyms_cmds_GCJ=
+  export_dynamic_flag_spec_GCJ=
+  whole_archive_flag_spec_GCJ=
+  thread_safe_flag_spec_GCJ=
+  hardcode_libdir_flag_spec_GCJ=
+  hardcode_libdir_flag_spec_ld_GCJ=
+  hardcode_libdir_separator_GCJ=
+  hardcode_direct_GCJ=no
+  hardcode_minus_L_GCJ=no
+  hardcode_shlibpath_var_GCJ=unsupported
+  link_all_deplibs_GCJ=unknown
+  hardcode_automatic_GCJ=no
+  module_cmds_GCJ=
+  module_expsym_cmds_GCJ=
+  always_export_symbols_GCJ=no
+  export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms_GCJ=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+  # Just being paranoid about ensuring that cc_basename is set.
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs_GCJ=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec_GCJ='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+	whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+  	whole_archive_flag_spec_GCJ=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>/dev/null` in
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs_GCJ=no
+	cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+
+      # Samuel A. Falvo II <kc5tja at dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs_GCJ=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag_GCJ=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      allow_undefined_flag_GCJ=unsupported
+      always_export_symbols_GCJ=no
+      enable_shared_with_static_runtimes_GCJ=yes
+      export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    interix3*)
+      hardcode_direct_GCJ=no
+      hardcode_shlibpath_var_GCJ=no
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec_GCJ='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    linux*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	tmp_addflag=
+	case $cc_basename,$host_cpu in
+	pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)		# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	esac
+	archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+	if test $supports_anon_versioning = yes; then
+	  archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~
+  cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+  $echo "local: *; };" >> $output_objdir/$libname.ver~
+	  $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	fi
+      else
+	ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+	ld_shlibs_GCJ=no
+	cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs_GCJ=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+	    archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+	    archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+	  else
+	    ld_shlibs_GCJ=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs_GCJ=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs_GCJ" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec_GCJ=
+      export_dynamic_flag_spec_GCJ=
+      whole_archive_flag_spec_GCJ=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag_GCJ=unsupported
+      always_export_symbols_GCJ=yes
+      archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L_GCJ=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct_GCJ=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+	  export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+	  for ld_flag in $LDFLAGS; do
+  	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+  	    aix_use_runtimelinking=yes
+  	    break
+  	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds_GCJ=''
+      hardcode_direct_GCJ=yes
+      hardcode_libdir_separator_GCJ=':'
+      link_all_deplibs_GCJ=yes
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" && \
+  	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	  then
+  	  # We have reworked collect2
+  	  hardcode_direct_GCJ=yes
+	  else
+  	  # We have old collect2
+  	  hardcode_direct_GCJ=unsupported
+  	  # It fails to find uninstalled libraries when the uninstalled
+  	  # path is not listed in the libpath.  Setting hardcode_minus_L
+  	  # to unsupported forces relinking
+  	  hardcode_minus_L_GCJ=yes
+  	  hardcode_libdir_flag_spec_GCJ='-L$libdir'
+  	  hardcode_libdir_separator_GCJ=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+  	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+  	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols_GCJ=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag_GCJ='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
+	archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag_GCJ="-z nodefs"
+	  archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an empty executable.
+	 cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	 hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag_GCJ=' ${wl}-bernotok'
+	  allow_undefined_flag_GCJ=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  whole_archive_flag_spec_GCJ='$convenience'
+	  archive_cmds_need_lc_GCJ=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs_GCJ=no
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec_GCJ=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec_GCJ=' '
+      allow_undefined_flag_GCJ=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds_GCJ='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes_GCJ=yes
+      ;;
+
+    darwin* | rhapsody*)
+      case $host_os in
+        rhapsody* | darwin1.[012])
+         allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[012])
+               allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+      esac
+      archive_cmds_need_lc_GCJ=no
+      hardcode_direct_GCJ=no
+      hardcode_automatic_GCJ=yes
+      hardcode_shlibpath_var_GCJ=unsupported
+      whole_archive_flag_spec_GCJ=''
+      link_all_deplibs_GCJ=yes
+    if test "$GCC" = yes ; then
+    	output_verbose_link_cmd='echo'
+        archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+      archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+         archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         ld_shlibs_GCJ=no
+          ;;
+      esac
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs_GCJ=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_GCJ=yes
+      hardcode_minus_L_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu | dragonfly*)
+      archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      hardcode_direct_GCJ=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L_GCJ=yes
+      export_dynamic_flag_spec_GCJ='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator_GCJ=:
+
+	hardcode_direct_GCJ=yes
+	export_dynamic_flag_spec_GCJ='${wl}-E'
+
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L_GCJ=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator_GCJ=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_libdir_flag_spec_ld_GCJ='+b $libdir'
+	  hardcode_direct_GCJ=no
+	  hardcode_shlibpath_var_GCJ=no
+	  ;;
+	*)
+	  hardcode_direct_GCJ=yes
+	  export_dynamic_flag_spec_GCJ='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L_GCJ=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      link_all_deplibs_GCJ=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    newsos6)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_GCJ=yes
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    openbsd*)
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_GCJ='${wl}-E'
+      else
+       case $host_os in
+	 openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	   archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	   hardcode_libdir_flag_spec_GCJ='-R$libdir'
+	   ;;
+	 *)
+	   archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	   hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+	   ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+      allow_undefined_flag_GCJ=unsupported
+      archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag_GCJ=' -expect_unresolved \*'
+	archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag_GCJ=' -expect_unresolved \*'
+	archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+	$LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec_GCJ='-rpath $libdir'
+      fi
+      hardcode_libdir_separator_GCJ=:
+      ;;
+
+    solaris*)
+      no_undefined_flag_GCJ=' -z text'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+	wlarc=''
+	archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  	$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+ 	# The compiler driver will combine linker options so we
+ 	# cannot just pass the convience library names through
+ 	# without $wl, iff we do not link with $LD.
+ 	# Luckily, gcc supports the same syntax we need for Sun Studio.
+ 	# Supported since Solaris 2.6 (maybe 2.5.1?)
+ 	case $wlarc in
+ 	'')
+ 	  whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;;
+ 	*)
+ 	  whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+ 	esac ;;
+      esac
+      link_all_deplibs_GCJ=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_minus_L_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct_GCJ=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds_GCJ='$CC -r -o $output$reload_objs'
+	  hardcode_direct_GCJ=no
+        ;;
+	motorola)
+	  archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_GCJ=no
+      export_dynamic_flag_spec_GCJ='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var_GCJ=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs_GCJ=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
+      no_undefined_flag_GCJ='${wl}-z,text'
+      archive_cmds_need_lc_GCJ=no
+      hardcode_shlibpath_var_GCJ=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag_GCJ='${wl}-z,text'
+      allow_undefined_flag_GCJ='${wl}-z,nodefs'
+      archive_cmds_need_lc_GCJ=no
+      hardcode_shlibpath_var_GCJ=no
+      hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator_GCJ=':'
+      link_all_deplibs_GCJ=yes
+      export_dynamic_flag_spec_GCJ='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    *)
+      ld_shlibs_GCJ=no
+      ;;
+    esac
+  fi
+
+{ echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5
+echo "${ECHO_T}$ld_shlibs_GCJ" >&6; }
+test "$ld_shlibs_GCJ" = no && can_build_shared=no
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_GCJ" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_GCJ=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_GCJ in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; }
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_GCJ
+	pic_flag=$lt_prog_compiler_pic_GCJ
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ
+        allow_undefined_flag_GCJ=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+	  archive_cmds_need_lc_GCJ=no
+        else
+	  archive_cmds_need_lc_GCJ=yes
+        fi
+        allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      { echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6; }
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+{ echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6; }
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  freebsd*) # from 4.6 on
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix3*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+{ echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; }
+hardcode_action_GCJ=
+if test -n "$hardcode_libdir_flag_spec_GCJ" || \
+   test -n "$runpath_var_GCJ" || \
+   test "X$hardcode_automatic_GCJ" = "Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_GCJ" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no &&
+     test "$hardcode_minus_L_GCJ" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_GCJ=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_GCJ=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_GCJ=unsupported
+fi
+{ echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5
+echo "${ECHO_T}$hardcode_action_GCJ" >&6; }
+
+if test "$hardcode_action_GCJ" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_GCJ \
+    CC_GCJ \
+    LD_GCJ \
+    lt_prog_compiler_wl_GCJ \
+    lt_prog_compiler_pic_GCJ \
+    lt_prog_compiler_static_GCJ \
+    lt_prog_compiler_no_builtin_flag_GCJ \
+    export_dynamic_flag_spec_GCJ \
+    thread_safe_flag_spec_GCJ \
+    whole_archive_flag_spec_GCJ \
+    enable_shared_with_static_runtimes_GCJ \
+    old_archive_cmds_GCJ \
+    old_archive_from_new_cmds_GCJ \
+    predep_objects_GCJ \
+    postdep_objects_GCJ \
+    predeps_GCJ \
+    postdeps_GCJ \
+    compiler_lib_search_path_GCJ \
+    archive_cmds_GCJ \
+    archive_expsym_cmds_GCJ \
+    postinstall_cmds_GCJ \
+    postuninstall_cmds_GCJ \
+    old_archive_from_expsyms_cmds_GCJ \
+    allow_undefined_flag_GCJ \
+    no_undefined_flag_GCJ \
+    export_symbols_cmds_GCJ \
+    hardcode_libdir_flag_spec_GCJ \
+    hardcode_libdir_flag_spec_ld_GCJ \
+    hardcode_libdir_separator_GCJ \
+    hardcode_automatic_GCJ \
+    module_cmds_GCJ \
+    module_expsym_cmds_GCJ \
+    lt_cv_prog_compiler_c_o_GCJ \
+    exclude_expsyms_GCJ \
+    include_expsyms_GCJ; do
+
+    case $var in
+    old_archive_cmds_GCJ | \
+    old_archive_from_new_cmds_GCJ | \
+    archive_cmds_GCJ | \
+    archive_expsym_cmds_GCJ | \
+    module_cmds_GCJ | \
+    module_expsym_cmds_GCJ | \
+    old_archive_from_expsyms_cmds_GCJ | \
+    export_symbols_cmds_GCJ | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_GCJ
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_compiler_GCJ
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_GCJ
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_GCJ
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_GCJ
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_GCJ
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_GCJ
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_GCJ
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_GCJ
+archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_GCJ
+module_expsym_cmds=$lt_module_expsym_cmds_GCJ
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_GCJ
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_GCJ
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_GCJ
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_GCJ
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_GCJ
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_GCJ
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_GCJ
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_GCJ
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_GCJ
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_GCJ
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_GCJ
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_GCJ"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_GCJ
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_GCJ
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_GCJ
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_GCJ
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+	else
+	  tagname=""
+	fi
+	;;
+
+      RC)
+
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+objext_RC=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${RC-"windres"}
+compiler=$CC
+compiler_RC=$CC
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+lt_cv_prog_compiler_c_o_RC=yes
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_RC \
+    CC_RC \
+    LD_RC \
+    lt_prog_compiler_wl_RC \
+    lt_prog_compiler_pic_RC \
+    lt_prog_compiler_static_RC \
+    lt_prog_compiler_no_builtin_flag_RC \
+    export_dynamic_flag_spec_RC \
+    thread_safe_flag_spec_RC \
+    whole_archive_flag_spec_RC \
+    enable_shared_with_static_runtimes_RC \
+    old_archive_cmds_RC \
+    old_archive_from_new_cmds_RC \
+    predep_objects_RC \
+    postdep_objects_RC \
+    predeps_RC \
+    postdeps_RC \
+    compiler_lib_search_path_RC \
+    archive_cmds_RC \
+    archive_expsym_cmds_RC \
+    postinstall_cmds_RC \
+    postuninstall_cmds_RC \
+    old_archive_from_expsyms_cmds_RC \
+    allow_undefined_flag_RC \
+    no_undefined_flag_RC \
+    export_symbols_cmds_RC \
+    hardcode_libdir_flag_spec_RC \
+    hardcode_libdir_flag_spec_ld_RC \
+    hardcode_libdir_separator_RC \
+    hardcode_automatic_RC \
+    module_cmds_RC \
+    module_expsym_cmds_RC \
+    lt_cv_prog_compiler_c_o_RC \
+    exclude_expsyms_RC \
+    include_expsyms_RC; do
+
+    case $var in
+    old_archive_cmds_RC | \
+    old_archive_from_new_cmds_RC | \
+    archive_cmds_RC | \
+    archive_expsym_cmds_RC | \
+    module_cmds_RC | \
+    module_expsym_cmds_RC | \
+    old_archive_from_expsyms_cmds_RC | \
+    export_symbols_cmds_RC | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_RC
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_compiler_RC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_RC
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_RC
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_RC
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_RC
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_RC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_RC
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_RC
+archive_expsym_cmds=$lt_archive_expsym_cmds_RC
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_RC
+module_expsym_cmds=$lt_module_expsym_cmds_RC
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_RC
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_RC
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_RC
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_RC
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_RC
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_RC
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_RC
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_RC
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_RC
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_RC
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_RC
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_RC
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_RC
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_RC"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_RC
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_RC
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_RC
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_RC
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+	;;
+
+      *)
+	{ { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5
+echo "$as_me: error: Unsupported tag name: $tagname" >&2;}
+   { (exit 1); exit 1; }; }
+	;;
+      esac
+
+      # Append the new tag name to the list of available tags.
+      if test -n "$tagname" ; then
+      available_tags="$available_tags $tagname"
+    fi
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  # Now substitute the updated list of available tags.
+  if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
+    mv "${ofile}T" "$ofile"
+    chmod +x "$ofile"
+  else
+    rm -f "${ofile}T"
+    { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5
+echo "$as_me: error: unable to update list of available tagged configurations." >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+fi
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Prevent multiple expansion
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+ac_config_files="$ac_config_files Makefile js.pc js-config.sh src/perlconnect/Makefile.PL"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
+echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      *) $as_unset $ac_var ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    test "x$cache_file" != "x/dev/null" &&
+      { echo "$as_me:$LINENO: updating cache $cache_file" >&5
+echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
+echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+
+# PATH needs CR
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+as_nl='
+'
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+case $0 in
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  { (exit 1); exit 1; }
+fi
+
+# Work around bugs in pre-3.0 UWIN ksh.
+for as_var in ENV MAIL MAILPATH
+do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line after each line using $LINENO; the second 'sed'
+  # does the real work.  The second script uses 'N' to pair each
+  # line-number line with the line containing $LINENO, and appends
+  # trailing '-' during substitution so that $LINENO is not a special
+  # case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # scripts with optimization help from Paolo Bonzini.  Blame Lee
+  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in
+-n*)
+  case `echo 'x\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  *)   ECHO_C='\c';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir
+fi
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s='ln -s'
+  # ... but there are two gotchas:
+  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+  # In both cases, we have to default to `cp -p'.
+  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+    as_ln_s='cp -p'
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+# Find out whether ``test -x'' works.  Don't use a zero-byte file, as
+# systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+  as_executable_p="test -x"
+else
+  as_executable_p=:
+fi
+rm -f conf$$.file
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+
+# Save the log message, to keep $[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.60 (OpenPKG-CURRENT).  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf at gnu.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.60 (OpenPKG-CURRENT),
+  with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2006 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    echo "$ac_cs_version"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    { echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  CONFIG_SHELL=$SHELL
+  export CONFIG_SHELL
+  exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "js.pc") CONFIG_FILES="$CONFIG_FILES js.pc" ;;
+    "js-config.sh") CONFIG_FILES="$CONFIG_FILES js-config.sh" ;;
+    "src/perlconnect/Makefile.PL") CONFIG_FILES="$CONFIG_FILES src/perlconnect/Makefile.PL" ;;
+
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+#
+# Set up the sed scripts for CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+
+_ACEOF
+
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  cat >conf$$subs.sed <<_ACEOF
+SHELL!$SHELL$ac_delim
+PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
+PACKAGE_NAME!$PACKAGE_NAME$ac_delim
+PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
+PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
+PACKAGE_STRING!$PACKAGE_STRING$ac_delim
+PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
+exec_prefix!$exec_prefix$ac_delim
+prefix!$prefix$ac_delim
+program_transform_name!$program_transform_name$ac_delim
+bindir!$bindir$ac_delim
+sbindir!$sbindir$ac_delim
+libexecdir!$libexecdir$ac_delim
+datarootdir!$datarootdir$ac_delim
+datadir!$datadir$ac_delim
+sysconfdir!$sysconfdir$ac_delim
+sharedstatedir!$sharedstatedir$ac_delim
+localstatedir!$localstatedir$ac_delim
+includedir!$includedir$ac_delim
+oldincludedir!$oldincludedir$ac_delim
+docdir!$docdir$ac_delim
+infodir!$infodir$ac_delim
+htmldir!$htmldir$ac_delim
+dvidir!$dvidir$ac_delim
+pdfdir!$pdfdir$ac_delim
+psdir!$psdir$ac_delim
+libdir!$libdir$ac_delim
+localedir!$localedir$ac_delim
+mandir!$mandir$ac_delim
+DEFS!$DEFS$ac_delim
+ECHO_C!$ECHO_C$ac_delim
+ECHO_N!$ECHO_N$ac_delim
+ECHO_T!$ECHO_T$ac_delim
+LIBS!$LIBS$ac_delim
+build_alias!$build_alias$ac_delim
+host_alias!$host_alias$ac_delim
+target_alias!$target_alias$ac_delim
+JS_VERSION!$JS_VERSION$ac_delim
+build!$build$ac_delim
+build_cpu!$build_cpu$ac_delim
+build_vendor!$build_vendor$ac_delim
+build_os!$build_os$ac_delim
+host!$host$ac_delim
+host_cpu!$host_cpu$ac_delim
+host_vendor!$host_vendor$ac_delim
+host_os!$host_os$ac_delim
+SET_MAKE!$SET_MAKE$ac_delim
+CC!$CC$ac_delim
+CFLAGS!$CFLAGS$ac_delim
+LDFLAGS!$LDFLAGS$ac_delim
+CPPFLAGS!$CPPFLAGS$ac_delim
+ac_ct_CC!$ac_ct_CC$ac_delim
+EXEEXT!$EXEEXT$ac_delim
+OBJEXT!$OBJEXT$ac_delim
+WITH_PERL!$WITH_PERL$ac_delim
+PERL!$PERL$ac_delim
+CPP!$CPP$ac_delim
+GREP!$GREP$ac_delim
+EGREP!$EGREP$ac_delim
+CLI_CFLAGS!$CLI_CFLAGS$ac_delim
+CLI_CPPFLAGS!$CLI_CPPFLAGS$ac_delim
+CLI_LDFLAGS!$CLI_LDFLAGS$ac_delim
+CLI_LIBS!$CLI_LIBS$ac_delim
+CLI_OBJS!$CLI_OBJS$ac_delim
+LN_S!$LN_S$ac_delim
+ECHO!$ECHO$ac_delim
+AR!$AR$ac_delim
+RANLIB!$RANLIB$ac_delim
+STRIP!$STRIP$ac_delim
+CXX!$CXX$ac_delim
+CXXFLAGS!$CXXFLAGS$ac_delim
+ac_ct_CXX!$ac_ct_CXX$ac_delim
+CXXCPP!$CXXCPP$ac_delim
+F77!$F77$ac_delim
+FFLAGS!$FFLAGS$ac_delim
+ac_ct_F77!$ac_ct_F77$ac_delim
+LIBTOOL!$LIBTOOL$ac_delim
+LIBOBJS!$LIBOBJS$ac_delim
+LTLIBOBJS!$LTLIBOBJS$ac_delim
+_ACEOF
+
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 79; then
+    break
+  elif $ac_last_try; then
+    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+   { (exit 1); exit 1; }; }
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+  ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+:end
+s/|#_!!_#|//g
+CEOF$ac_eof
+_ACEOF
+
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[	 ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+fi # test -n "$CONFIG_FILES"
+
+
+for ac_tag in  :F $CONFIG_FILES  :H $CONFIG_HEADERS
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
+echo "$as_me: error: Invalid tag $ac_tag." >&2;}
+   { (exit 1); exit 1; }; };;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
+echo "$as_me: error: cannot find input file: $ac_f" >&2;}
+   { (exit 1); exit 1; }; };;
+      esac
+      ac_file_inputs="$ac_file_inputs $ac_f"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input="Generated from "`IFS=:
+	  echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    fi
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin";;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  { as_dir="$ac_dir"
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
+echo "$as_me: error: cannot create directory $as_dir" >&2;}
+   { (exit 1); exit 1; }; }; }
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+
+case `sed -n '/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p
+' $ac_file_inputs` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+    s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s&@configure_input@&$configure_input&;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out"; rm -f "$tmp/out";;
+  *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
+  esac
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+_ACEOF
+
+# Transform confdefs.h into a sed script `conftest.defines', that
+# substitutes the proper values into config.h.in to produce config.h.
+rm -f conftest.defines conftest.tail
+# First, append a space to every undef/define line, to ease matching.
+echo 's/$/ /' >conftest.defines
+# Then, protect against being on the right side of a sed subst, or in
+# an unquoted here document, in config.status.  If some macros were
+# called several times there might be several #defines for the same
+# symbol, which is useless.  But do not sort them, since the last
+# AC_DEFINE must be honored.
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where
+# NAME is the cpp macro being defined, VALUE is the value it is being given.
+# PARAMS is the parameter list in the macro definition--in most cases, it's
+# just an empty string.
+ac_dA='s,^\\([	 #]*\\)[^	 ]*\\([	 ]*'
+ac_dB='\\)[	 (].*,\\1define\\2'
+ac_dC=' '
+ac_dD=' ,'
+
+uniq confdefs.h |
+  sed -n '
+	t rset
+	:rset
+	s/^[	 ]*#[	 ]*define[	 ][	 ]*//
+	t ok
+	d
+	:ok
+	s/[\\&,]/\\&/g
+	s/^\('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p
+	s/^\('"$ac_word_re"'\)[	 ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p
+  ' >>conftest.defines
+
+# Remove the space that was appended to ease matching.
+# Then replace #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+# (The regexp can be short, since the line contains either #define or #undef.)
+echo 's/ $//
+s,^[	 #]*u.*,/* & */,' >>conftest.defines
+
+# Break up conftest.defines:
+ac_max_sed_lines=50
+
+# First sed command is:	 sed -f defines.sed $ac_file_inputs >"$tmp/out1"
+# Second one is:	 sed -f defines.sed "$tmp/out1" >"$tmp/out2"
+# Third one will be:	 sed -f defines.sed "$tmp/out2" >"$tmp/out1"
+# et cetera.
+ac_in='$ac_file_inputs'
+ac_out='"$tmp/out1"'
+ac_nxt='"$tmp/out2"'
+
+while :
+do
+  # Write a here document:
+    cat >>$CONFIG_STATUS <<_ACEOF
+    # First, check the format of the line:
+    cat >"\$tmp/defines.sed" <<\\CEOF
+/^[	 ]*#[	 ]*undef[	 ][	 ]*$ac_word_re[	 ]*\$/b def
+/^[	 ]*#[	 ]*define[	 ][	 ]*$ac_word_re[(	 ]/b def
+b
+:def
+_ACEOF
+  sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+    sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS
+  ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in
+  sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail
+  grep . conftest.tail >/dev/null || break
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines conftest.tail
+
+echo "ac_result=$ac_in" >>$CONFIG_STATUS
+cat >>$CONFIG_STATUS <<\_ACEOF
+  if test x"$ac_file" != x-; then
+    echo "/* $configure_input  */" >"$tmp/config.h"
+    cat "$ac_result" >>"$tmp/config.h"
+    if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f $ac_file
+      mv "$tmp/config.h" $ac_file
+    fi
+  else
+    echo "/* $configure_input  */"
+    cat "$ac_result"
+  fi
+  rm -f "$tmp/out12"
+ ;;
+
+
+  esac
+
+done # for ac_tag
+
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+

Added: freeswitch/trunk/libs/js/configure.ac
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/configure.ac	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,176 @@
+dnl ##
+dnl ##  OSSP js - JavaScript Engine
+dnl ##  Copyright (c) 1998-2006 Mozilla <http://www.mozilla.org/>
+dnl ##
+dnl ##  This file is part of OSSP js, a distribution of the Mozilla JavaScript
+dnl ##  reference implementation, which can found at http://www.ossp.org/pkg/lib/js/
+dnl ##
+dnl ##  Permission to use, copy, modify, and distribute this software for
+dnl ##  any purpose with or without fee is hereby granted, provided that
+dnl ##  the above copyright notice and this permission notice appear in all
+dnl ##  copies.
+dnl ##
+dnl ##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+dnl ##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+dnl ##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+dnl ##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+dnl ##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+dnl ##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+dnl ##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+dnl ##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+dnl ##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+dnl ##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+dnl ##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+dnl ##  SUCH DAMAGE.
+dnl ##
+dnl ##  configure.ac: GNU Autoconf source script
+dnl ##
+
+AC_PREREQ(2.60)
+AC_INIT
+JS_VERSION=`./shtool version -l txt -d short VERSION`
+$ac_confdir/shtool echo -e \
+    "Configuring %BOSSP js%b (Mozilla JavaScript Engine), version %B${JS_VERSION}%b"
+AC_SUBST(JS_VERSION)
+
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+
+AC_PROG_MAKE_SET
+AC_PROG_CC
+AC_CHECK_DEBUGGING
+AC_CHECK_VA_COPY
+
+AC_CHECK_LIB(nsl, gethostname)
+if test ".`echo $LIBS | grep nsl`" = .; then
+    AC_CHECK_LIB(nsl, gethostbyname)
+fi
+AC_CHECK_LIB(socket, accept)
+AC_CHECK_LIB(m, floor)
+
+AC_CHECK_MEMBERS([struct stat.st_birthtime, struct stat.st_birthtimensec],,, [#include <sys/stat.h>])
+
+CPPFLAGS="$CPPFLAGS -DOSSP"
+case "${host}" in
+    *mingw* | *windows* | *winnt* ) CPPFLAGS="$CPPFLAGS -DXP_WIN"  ;;
+    *                             ) CPPFLAGS="$CPPFLAGS -DXP_UNIX" ;;
+esac
+CPPFLAGS="$CPPFLAGS -DEXPORT_JS_API"
+
+dnl #   configure option --with-version
+AC_ARG_WITH([version],
+    AC_HELP_STRING([--with-version], [build the run-time engine with JavaScript features only. Available versions are: ECMA-3, JS-1.5, JS-1.6 (default)]),
+    [ac_cv_with_version=$withval], [ac_cv_with_version=no])
+AC_CACHE_CHECK([whether to build the run-time engine with JavaScript features only],
+    [ac_cv_with_version], [ac_cv_with_version=no])
+case "$ac_cv_with_version" in
+    dnl JS-1.0 ) CPPFLAGS="$CPPFLAGS -DJS_VERSION=100" ;;
+    dnl JS-1.1 ) CPPFLAGS="$CPPFLAGS -DJS_VERSION=110" ;;
+    dnl JS-1.2 ) CPPFLAGS="$CPPFLAGS -DJS_VERSION=120" ;;
+    dnl JS-1.3 ) CPPFLAGS="$CPPFLAGS -DJS_VERSION=130" ;;
+    dnl JS-1.4 ) CPPFLAGS="$CPPFLAGS -DJS_VERSION=140" ;;
+    ECMA-3 ) CPPFLAGS="$CPPFLAGS -DJS_VERSION=148" ;;
+    JS-1.5 ) CPPFLAGS="$CPPFLAGS -DJS_VERSION=150" ;;
+    JS-1.6 ) CPPFLAGS="$CPPFLAGS -DJS_VERSION=160" ;;
+esac
+
+CLI_CPPFLAGS=""
+CLI_CFLAGS=""
+CLI_LDFLAGS=""
+CLI_LIBS=""
+CLI_OBJS=""
+
+dnl #   configure option --with-editline[=path]
+AC_ARG_WITH([editline],
+    AC_HELP_STRING([--with-editline], [build command line interface with line editing support via editline, libedit or GNU readline]),
+    [ac_cv_with_editline=$withval], [ac_cv_with_editline=no])
+AC_CACHE_CHECK([whether to build command line interface with line editing support],
+    [ac_cv_with_editline], [ac_cv_with_editline=no])
+if test ".$ac_cv_with_editline" != ".no"; then
+    CLI_CPPFLAGS="$CLI_CPPFLAGS -DEDITLINE"
+    case "$ac_cv_with_editline" in
+        /* ) CLI_LDFLAGS="-L$ac_cv_with_editline" ;;
+    esac
+    OLD_LDFLAGS="$LDFLAGS";
+    OLD_LIBS="$LIBS";
+    LDFLAGS="$LDFLAGS $CLI_LDFLAGS"
+    LIBS=""
+    AC_SEARCH_LIBS(tcgetattr, termcap termlib curses ncurses)
+    AC_SEARCH_LIBS(tputs, termcap termlib curses ncurses)
+    TERM_LIBS="$LIBS"
+    AC_SEARCH_LIBS(readline, editline edit readline,,, [$TERM_LIBS])
+    CLI_LIBS="$LIBS"
+    LDFLAGS="$OLD_LDFLAGS"
+    LIBS="$OLD_LIBS"
+fi
+
+dnl #   configure option --with-perl
+AC_ARG_WITH([perl],
+	AS_HELP_STRING([--with-perl], [build Perl-to-JS and JS-to-Perl bindings]),
+	[ac_cv_with_perl=$withval], [ac_cv_with_perl=no])
+AC_CACHE_CHECK([whether to build Perl-to-JS and JS-to-Perl bindings], [ac_cv_with_perl], [ac_cv_with_perl=no])
+if test ".$ac_cv_with_perl" != ".no"; then
+	WITH_PERL="yes"
+	CLI_OBJS="$CLI_OBJS src/perlconnect/jsperl.o"
+	CLI_CPPFLAGS="$CLI_CPPFLAGS -DPERLCONNECT"
+else
+	WITH_PERL="no"
+fi
+AC_SUBST(WITH_PERL)
+case "$ac_cv_with_perl" in
+    /* ) PERL="$ac_cv_with_perl" ;;
+esac
+AC_PATH_PROG(PERL, perl, NA)
+if test ".$ac_cv_with_perl" = ".yes" -a ".$PERL" = ".NA"; then
+	AC_ERROR([required Perl interpreter not found in \$PATH])
+fi
+if test ".$ac_cv_with_perl" != ".no"; then
+    CLI_CFLAGS="$CLI_CFLAGS `$PERL -MExtUtils::Embed -e ccopts`"
+    CLI_LIBS="$CLI_LIBS `$PERL -MExtUtils::Embed -e ldopts`"
+fi
+
+dnl #   configure option --without-file
+AC_ARG_WITH([file],
+	AS_HELP_STRING([--without-file], [build without File object (grants access to the filesystem)]),
+	[ac_cv_with_file=$withval], [ac_cv_with_file=yes])
+AC_CACHE_CHECK([whether to build with the File object], [ac_cv_with_file], [ac_cv_with_file=yes])
+if test ".$ac_cv_with_file" = ".yes"; then
+    CPPFLAGS="$CPPFLAGS -DJS_HAS_FILE_OBJECT"
+fi
+
+dnl #   configure option --with-dso
+AC_ARG_WITH([dso],
+	AS_HELP_STRING([--with-dso], [build without DSO object (allows run-time process extending)]),
+	[ac_cv_with_dso=$withval], [ac_cv_with_dso=no])
+AC_CACHE_CHECK([whether to build with the DSO object], [ac_cv_with_dso], [ac_cv_with_dso=no])
+if test ".$ac_cv_with_dso" = ".yes"; then
+    AC_CHECK_LIB(dl, dlopen)
+    AC_CHECK_HEADER(dlfcn.h, , AC_ERROR([dlopen(3) header <dlfcn.h> required]))
+    AC_CHECK_FUNCS(dlopen dlclose dlerror, , AC_ERROR([dlopen(3) API functions dlopen/dlclose/dlerror required]))
+    CPPFLAGS="$CPPFLAGS -DJS_HAS_DSO_OBJECT"
+    CLI_LDFLAGS="$CLI_LDFLAGS -export-dynamic"
+fi
+
+dnl #   configure option --with-utf8
+AC_ARG_WITH([utf8],
+	AS_HELP_STRING([--with-utf8], [build with exclusive UTF-8 C strings (uses Unicode UTF-8 encoded C strings only)]),
+	[ac_cv_with_utf8=$withval], [ac_cv_with_utf8=no])
+AC_CACHE_CHECK([whether to build with exclusive UTF-8 C string], [ac_cv_with_utf8], [ac_cv_with_utf8=no])
+if test ".$ac_cv_with_utf8" = ".yes"; then
+    CPPFLAGS="$CPPFLAGS -DJS_C_STRINGS_ARE_UTF8"
+fi
+
+AC_SUBST(CLI_CFLAGS)
+AC_SUBST(CLI_CPPFLAGS)
+AC_SUBST(CLI_LDFLAGS)
+AC_SUBST(CLI_LIBS)
+AC_SUBST(CLI_OBJS)
+
+with_tags=""
+sinclude(libtool.m4)
+AC_PROG_LIBTOOL
+
+AC_CONFIG_HEADERS(config.h)
+AC_CONFIG_FILES([Makefile js.pc js-config.sh src/perlconnect/Makefile.PL])
+AC_OUTPUT
+

Added: freeswitch/trunk/libs/js/js-config.1
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/js-config.1	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,67 @@
+.TH JS-CONFIG 1 "22 July 2006"
+.SH NAME
+.BR js-config " - Mozilla JavaScript C API Configuration Query Utility"
+.SH SYNOPSIS
+.B js-config
+.RB [ --help ]
+.RB [ --version ]
+.RB [ --prefix ]
+.RB [ --exec-prefix ]
+.RB [ --bindir ]
+.RB [ --libdir ]
+.RB [ --includedir ]
+.RB [ --mandir ]
+.RB [ --datadir ]
+.RB [ --acdir ]
+.RB [ --cppflags ]
+.RB [ --cflags ]
+.RB [ --ldflags ]
+.RB [ --libs ]
+.SH DESCRIPTION
+The Mozilla JavaScript C API Configuration Query Utility
+.B js-config
+is a command line utility
+for querying various build-time parameters when
+linking the
+.B Mozilla JavaScript
+language engine ("SpiderMonkey"),
+as provided by the
+.B OSSP js
+distribution, into own applications.
+.PP
+For platforms where
+.BR pkg-config ( 1 )
+is available one can use this as an alternative, too.
+The advantage of
+.BR js-config ( 1 )
+is that it is a stand-alone shell script without
+any dependencies and already ships with the
+.B OSSP js
+distribution.
+.SH EXAMPLES
+.RS 0
+cc `js-config --cppflags` -o foo foo.c `js-config --ldflags --libs`
+.RE
+.SH SEE ALSO
+.BR js ( 1 ),
+.BR js ( 3 )
+.PP
+.RS 0
+http://www.mozilla.org/js/spidermonkey/
+.RE
+.RS 0
+http://www.ossp.org/pkg/lib/js/
+.RE
+.SH AUTHOR
+The author of the 
+.B Mozilla JavaScript
+language implementation ("SpiderMonkey") is
+.I Brendan Eich
+from the 
+.IR "Mozilla Foundation" .
+This manual page was written by 
+.I Ralf S. Engelschall
+for the 
+.B OSSP js
+distribution of 
+.BR "Mozilla JavaScript" .

Added: freeswitch/trunk/libs/js/js-config.sh.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/js-config.sh.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,138 @@
+#!/bin/sh
+##
+##  OSSP js - JavaScript Engine
+##  Copyright (c) 1998-2006 Mozilla <http://www.mozilla.org/>
+##
+##  This file is part of OSSP js, a distribution of the Mozilla JavaScript
+##  reference implementation, which can found at http://www.ossp.org/pkg/lib/js/
+##
+##  Permission to use, copy, modify, and distribute this software for
+##  any purpose with or without fee is hereby granted, provided that
+##  the above copyright notice and this permission notice appear in all
+##  copies.
+##
+##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+##  SUCH DAMAGE.
+##
+##  js-config.in: library build utility
+##
+
+DIFS=' 
+'
+
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+
+js_prefix="$prefix"
+js_exec_prefix="$exec_prefix"
+js_datarootdir="@datarootdir@"
+js_bindir="@bindir@"
+js_libdir="@libdir@"
+js_includedir="@includedir@"
+js_mandir="@mandir@"
+js_datadir="@datadir@"
+js_acdir="@datadir@/aclocal"
+js_libs="@LIBS@"
+js_version="@JS_VERSION@"
+
+help=no
+version=no
+
+usage="js-config"
+usage="$usage [--help] [--version]"
+usage="$usage [--prefix] [--exec-prefix] [--bindir] [--libdir] [--includedir] [--mandir] [--datadir] [--acdir]"
+usage="$usage [--cppflags] [--cflags] [--ldflags] [--libs]"
+if [ $# -eq 0 ]; then
+    echo "js-config:Error: Invalid option" 1>&2
+    echo "js-config:Usage: $usage" 1>&2
+    exit 1
+fi
+output=''
+all=no
+prev=''
+OIFS="$IFS" IFS="$DIFS"
+for option
+do
+    if [ ".$prev" != . ]; then
+        eval "$prev=\$option"
+        prev=''
+        continue
+    fi
+    case "$option" in
+        -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+           *) optarg='' ;;
+    esac
+    case "$option" in
+        --help|-h)
+            echo "Usage: $usage"
+            exit 0
+            ;;
+        --version|-v)
+            echo "OSSP js $js_version"
+            exit 0
+            ;;
+        --all)
+            all=yes
+            ;;
+        --prefix)
+            output="$output $js_prefix"
+            ;;
+        --exec-prefix)
+            output="$output $js_exec_prefix"
+            ;;
+        --bindir)
+            output="$output $js_bindir"
+            ;;
+        --libdir)
+            output="$output $js_libdir"
+            ;;
+        --includedir)
+            output="$output $js_includedir"
+            ;;
+        --mandir)
+            output="$output $js_mandir"
+            ;;
+        --datadir)
+            output="$output $js_datadir"
+            ;;
+        --acdir)
+            output="$output $js_acdir"
+            ;;
+        --cppflags)
+            output="$output -DOSSP -DXP_UNIX -I$js_includedir/js"
+            ;;
+        --cflags)
+            : # none
+            ;;
+        --ldflags)
+            output="$output -L$js_libdir"
+            ;;
+        --libs)
+            output="$output -ljs $js_libs"
+            ;;
+        * )
+            echo "js-config:Error: Invalid option" 1>&2
+            echo "js-config:Usage: $usage" 1>&2
+            exit 1;
+            ;;
+    esac
+done
+IFS="$OIFS"
+if [ ".$prev" != . ]; then
+    echo "js-config:Error: missing argument to --`echo $prev | sed 's/_/-/g'`" 1>&2
+    exit 1
+fi
+if [ ".$output" != . ]; then
+    echo $output
+fi
+

Added: freeswitch/trunk/libs/js/js.1
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/js.1	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,167 @@
+.TH JS 1 "22 July 2006"
+.SH NAME
+.BR js " - Mozilla JavaScript Shell"
+.SH SYNOPSIS
+.B js
+.RB [ -w ]
+.RB [ -W ]
+.RB [ -S ]
+.RB [ -x ]
+.RB [ -C ]
+.RB [ -c
+.IR stackchunksize ]
+.RB [ -S
+.IR maxstacksize ]
+.RB [ -b
+.IR maxbranches ]
+.RB [ -P ]
+.RB [ -v
+.IR version ]
+.RB [ -e
+.IR script ]
+.RB [ -f
+.IR scriptfile ]
+.RI [ scriptfile ]
+.RI [ scriptarg " ..." "" ]
+.SH DESCRIPTION
+The Mozilla JavaScript Shell
+.B js
+is a command line interface to the 
+.B Mozilla JavaScript
+language engine ("SpiderMonkey"),
+as provided by the
+.B OSSP js
+distribution.
+The
+.B js
+program provides a test vehicle for easily evaluating JavaScript scripts, calling JavaScript functions,
+trying out debugger primitives, etc.
+.SH OPTIONS
+.SS Compile-Time Options
+.TP 8
+.B -w
+Disable the printing of warnings.
+.TP 8
+.B -W
+Enable the printing of warnings.
+.TP 8
+.B -s
+Enable strict language parsing during compile-time.
+This will print warnings on dubious JavaScript programming practices. 
+.TP 8
+.B -x
+Enable ECMAScript for XML (E4X) support during compile-time.
+.TP 8
+.B -C
+Compile only. This compiles the script but does not
+execute it.
+.SS Run-Time Options
+.TP 8
+.BI -c " stackchunksize"
+Set the stack chunk size to
+.I stackchunksize
+bytes. The default is
+.BR 8192 .
+.TP 8
+.BI -S " maxstacksize"
+Set a maximum stack size limit to
+.I maxstacksize
+bytes in order to restruct script resource consumption.
+The default is a stack of unlimited size.
+.TP 8
+.BI -b " maxbranches"
+Set a maximum branch number limit to
+.I maxbranches
+in order to restrict script resource consumption. The default is an
+unlimited number of branches.
+.TP 8
+.B -P
+In case the prototype object of the (potentially changed) global object
+is no longer connected to the global class, create a new global object
+(which is again connected to the global class) and set its prototype
+object to the old global object.
+.TP 8
+.BI -v " version"
+override the numerical JavaScript version number, which the JavaScript
+.B version()
+function returns, with the value
+.IR version .
+The argument
+.I version
+usually is one of the following integer values:
+.B 0
+(default),
+.B 100
+(JS 1.0),
+.B 110
+(JS 1.1),
+.B 120
+(JS 1.2),
+.B 130
+(JS 1.3),
+.B 140
+(JS 1.4),
+.B 148
+(ECMA-3),
+.B 150
+(JS 1.5),
+.B 160
+(JS 1.6).
+.SS Script Execution
+.TP 8
+.BI -e " script"
+Command-line passed JavaScript script to execute.
+This is executed immediately during command
+line parsing, so specify it after
+.B "Compile-Time Options"
+and
+.BR "Run-Time Options" .
+.TP 7
+.BI -f " scriptfile"
+Externally passed JavaScript script to execute.
+This is executed immediately during command
+line parsing, so specify it after
+.B "Compile-Time Options"
+and
+.BR "Run-Time Options" .
+.SH ARGUMENTS
+.TP 8
+.RI scriptfile
+Externally passed JavaScript script to execute.
+This is executed after command line parsing
+(and this way after scripts of options
+.BR -e " and " -f
+were executed.
+This additional way of executing an external JavaScript
+script exists to especially support Unix "shebang"
+style scripts.
+.TP 8
+.IR scriptarg
+Zero or more arguments which are passed to the executed
+.IR scriptfile .
+They are available in the script through the global
+array object
+.BR arguments .
+.SH SEE ALSO
+.BR js ( 3 ),
+.BR js-config ( 1 )
+.PP
+.RS 0
+http://www.mozilla.org/js/spidermonkey/
+.RE
+.RS 0
+http://www.ossp.org/pkg/lib/js/
+.RE
+.SH AUTHOR
+The author of the 
+.B Mozilla JavaScript
+language implementation ("SpiderMonkey") is
+.I Brendan Eich
+from the 
+.IR "Mozilla Foundation" .
+This manual page was written by 
+.I Ralf S. Engelschall
+for the 
+.B OSSP js
+distribution of 
+.BR "Mozilla JavaScript" .

Added: freeswitch/trunk/libs/js/js.3
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/js.3	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,46 @@
+.TH JS 3 "22 July 2006"
+.SH NAME
+.BR libjs " - Mozilla JavaScript C API"
+.SH SYNOPSIS
+.RS 0
+.B cc `js-config --cppflags` -o foo foo.c `js-config --ldflags --libs`
+.RE
+.RS 0
+.B cc `pkg-config --cflags js` -o foo foo.c `pkg-config --libs js`
+.RE
+.SH DESCRIPTION
+The Mozilla JavaScript C API
+is the programmatic interface to the 
+.B Mozilla JavaScript
+language engine ("SpiderMonkey").
+For the complete reference documentation of the Mozilla JavaScript C API please see
+the following online documents:
+.TP 8
+.I JS Embedder's Guide
+http://www.mozilla.org/js/spidermonkey/apidoc/jsguide.html
+.TP 8
+.I JS Embedder's Reference
+http://www.mozilla.org/js/spidermonkey/apidoc/complete-frameset.html
+.SH SEE ALSO
+.BR js-config ( 1 ),
+.BR js ( 1 )
+.PP
+.RS 0
+http://www.mozilla.org/js/spidermonkey/
+.RE
+.RS 0
+http://www.ossp.org/pkg/lib/js/
+.RE
+.SH AUTHOR
+The author of the 
+.B Mozilla JavaScript
+language implementation ("SpiderMonkey") is
+.I Brendan Eich
+from the 
+.IR "Mozilla Foundation" .
+This manual page was written by 
+.I Ralf S. Engelschall
+for the 
+.B OSSP js
+distribution of 
+.BR "Mozilla JavaScript" .

Added: freeswitch/trunk/libs/js/js.pc.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/js.pc.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: OSSP js
+Description: Mozilla JavaScript Engine
+Version: @JS_VERSION@
+Libs: -L${libdir} -ljs @LIBS@
+Cflags: -DOSSP -DXP_UNIX -I${includedir}/js

Added: freeswitch/trunk/libs/js/jslint.js
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/jslint.js	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2542 @@
+#!./js
+
+/* ============================================================== */
+
+// jslint.js
+// 2006-06-12
+/*
+Copyright (c) 2002 Douglas Crockford  (www.JSLint.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+The Software shall be used for Good, not Evil.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+
+/*
+    jslint is a function. It takes two parameters.
+
+        var myResult = jslint(source, option);
+
+    The first parameter is either a string or an array of strings. If it is a
+    string, it will be split on '\n' or '\r'. If it is an array of strings, it
+    is assumed that each string represents one line. The source can be a
+    JavaScript text, or HTML text, or a Konfabulator text.
+
+    The second parameter is an optional object of options which control the
+    operation of jslint. All of the options are booleans. All are optional and
+    have a default value of false.
+
+    {
+        browser    : true if the standard browser globals should be predefined
+        cap        : true if upper case HTML should be allowed
+        debug      : true if debugger statements should be allowed
+        evil       : true if eval should be allowed
+        jscript    : true if jscript deviations should be allowed
+        laxLineEnd : true if line breaks should not be checked
+        passfail   : true if the scan should stop on first error
+        plusplus   : true if post increment should not be allowed
+        undef      : true if undefined variables are errors
+    }
+
+    If it checks out, jslint returns true. Otherwise, it returns false.
+
+    If false, you can inspect jslint.errors to find out the problems.
+    jslint.errors is an array of objects containing these members:
+
+    {
+        line      : The line (relative to 0) at which the lint was found
+        character : The character (relative to 0) at which the lint was found
+        reason    : The problem
+        evidence  : The text line in which the problem occurred
+    }
+
+    If a fatal error was found, a null will be the last element of the
+    jslint.errors array.
+
+    You can request a Function Report, which shows all of the functions
+    and the parameters and vars that they use. This can be used to find
+    implied global variables and other problems. The report is in HTML and
+    can be inserted in a <body>.
+
+        var myReport = jslint.report(option);
+
+    If the option is true, then the report will be limited to only errors.
+*/
+
+String.prototype.entityify = function () {
+    return this.
+        replace(/&/g, '&amp;').
+        replace(/</g, '&lt;').
+        replace(/>/g, '&gt;');
+};
+
+String.prototype.isAlpha = function () {
+    return (this >= 'a' && this <= 'z\uffff') ||
+        (this >= 'A' && this <= 'Z\uffff');
+};
+
+
+String.prototype.isDigit = function () {
+    return (this >= '0' && this <= '9');
+};
+
+
+// We build the application inside a function so that we produce only a single
+// global variable. The function will be invoked, its return value is the JSLint
+// function itself.
+
+var jslint;
+jslint = function () {
+
+    var anonname,
+
+// browser contains a set of global names which are commonly provided by a
+// web browser environment.
+
+        browser = {
+            alert: true,
+            blur: true,
+            clearInterval: true,
+            clearTimeout: true,
+            close: true,
+            closed: true,
+            confirm: true,
+            defaultStatus: true,
+            document: true,
+            event: true,
+            focus: true,
+            frames: true,
+            history: true,
+            Image: true,
+            length: true,
+            location: true,
+            moveBy: true,
+            moveTo: true,
+            name: true,
+            navigator: true,
+            onblur: true,
+            onerror: true,
+            onfocus: true,
+            onload: true,
+            onresize: true,
+            onunload: true,
+            open: true,
+            opener: true,
+            parent: true,
+            print: true,
+            prompt: true,
+            resizeBy: true,
+            resizeTo: true,
+            screen: true,
+            scroll: true,
+            scrollBy: true,
+            scrollTo: true,
+            self: true,
+            setInterval: true,
+            setTimeout: true,
+            status: true,
+            top: true,
+            window: true,
+            XMLHttpRequest: true
+        },
+        funlab, funstack, functions, globals,
+
+// konfab contains the global names which are provided to a Konfabulator widget.
+
+        konfab = {
+            alert: true,
+            animator: true,
+            appleScript: true,
+            beep: true,
+            bytesToUIString: true,
+            chooseColor: true,
+            chooseFile: true,
+            chooseFolder: true,
+            convertPathToHFS: true,
+            convertPathToPlatform: true,
+            closeWidget: true,
+            CustomAnimation: true,
+            escape: true,
+            FadeAnimation: true,
+            focusWidget: true,
+            form: true,
+            include: true,
+            isApplicationRunning: true,
+            iTunes: true,
+            konfabulatorVersion: true,
+            log: true,
+            MoveAnimation: true,
+            openURL: true,
+            play: true,
+            popupMenu: true,
+            print: true,
+            prompt: true,
+            reloadWidget: true,
+            resolvePath: true,
+            resumeUpdates: true,
+            RotateAnimation: true,
+            runCommand: true,
+            runCommandInBg: true,
+            saveAs: true,
+            savePreferences: true,
+            showWidgetPreferences: true,
+            sleep: true,
+            speak: true,
+            suppressUpdates: true,
+            tellWidget: true,
+            unescape: true,
+            updateNow: true,
+            yahooCheckLogin: true,
+            yahooLogin: true,
+            yahooLogout: true,
+            COM: true,
+            filesystem: true,
+            preferenceGroups: true,
+            preferences: true,
+            screen: true,
+            system: true,
+            URL: true,
+            XMLDOM: true,
+            XMLHttpRequest: true
+        },
+        lines, lookahead, member, noreach, option, prevtoken, stack,
+
+// standard contains the global names that are provided by standard JavaScript.
+
+        standard = {
+            Array: true,
+            Boolean: true,
+            Date: true,
+            decodeURI: true,
+            decodeURIComponent: true,
+            encodeURI: true,
+            encodeURIComponent: true,
+            Error: true,
+            escape: true,
+            eval: true,
+            EvalError: true,
+            Function: true,
+            isFinite: true,
+            isNaN: true,
+            Math: true,
+            Number: true,
+            Object: true,
+            parseInt: true,
+            parseFloat: true,
+            RangeError: true,
+            ReferenceError: true,
+            RegExp: true,
+            String: true,
+            SyntaxError: true,
+            TypeError: true,
+            unescape: true,
+            URIError: true
+        },
+        syntax = {}, token, verb,
+/*
+    xmode is used to adapt to the exceptions in XML parsing. It can have these
+    states:
+        false   .js script file
+        "       A " attribute
+        '       A ' attribute
+        content The content of a script tag
+        CDATA   A CDATA block
+*/
+        xmode,
+/*
+    xtype identifies the type of document being analyzed. It can have these
+    states:
+        false   .js script file
+        html    .html file
+        widget  .kon Konfabulator file
+*/
+        xtype,
+// token
+        tx = /^([(){}[.,:;'"~]|\](\]>)?|\?>?|==?=?|\/(\*(global|extern)*|=|)|\*[\/=]?|\+[+=]?|-[-=]?|%[=>]?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=%\?]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+-]?[0-9]+)?)/,
+// string ending in single quote
+        sx = /^((\\[^\x00-\x1f]|[^\x00-\x1f'\\])*)'/,
+        sxx = /^(([^\x00-\x1f'])*)'/,
+// string ending in double quote
+        qx = /^((\\[^\x00-\x1f]|[^\x00-\x1f"\\])*)"/,
+        qxx = /^(([^\x00-\x1f"])*)"/,
+// regular expression
+        rx = /^(\\[^\x00-\x1f]|\[(\\[^\x00-\x1f]|[^\x00-\x1f\\\/])*\]|[^\x00-\x1f\\\/\[])+\/[gim]*/,
+// star slash
+        lx = /\*\/|\/\*/,
+// global identifier
+        gx = /^([a-zA-Z_$][a-zA-Z0-9_$]*)/,
+// identifier
+        ix = /^([a-zA-Z_$][a-zA-Z0-9_$]*$)/,
+// global separators
+        hx = /^[\x00-\x20,]*(\*\/)?/,
+// whitespace
+        wx = /^\s*(\/\/.*\r*$)?/;
+
+// Make a new object that inherits from an existing object.
+
+    function object(o) {
+        function f() {}
+        f.prototype = o;
+        return new f();
+    }
+
+// Produce an error warning.
+
+    function warning(m, x, y) {
+        var l, c, t = typeof x === 'object' ? x : token;
+        if (typeof x === 'number') {
+            l = x;
+            c = y || 0;
+        } else {
+            if (t.id === '(end)') {
+                t = prevtoken;
+            }
+            l = t.line || 0;
+            c = t.from || 0;
+        }
+        jslint.errors.push({
+            id: '(error)',
+            reason: m,
+            evidence: lines[l] || '',
+            line: l,
+            character: c
+        });
+        if (option.passfail) {
+            jslint.errors.push(null);
+            throw null;
+        }
+    }
+
+    function error(m, x, y) {
+        warning(m, x, y);
+        jslint.errors.push(null);
+        throw null;
+    }
+
+
+// lexical analysis
+
+    var lex = function () {
+        var character, from, line, s;
+
+// Private lex methods
+
+        function nextLine() {
+            line += 1;
+            if (line >= lines.length) {
+                return false;
+            }
+            character = 0;
+            s = lines[line];
+            return true;
+        }
+
+// Produce a token object.  The token inherits from a syntax symbol.
+
+        function it(type, value) {
+            var t;
+            if (type === '(punctuator)') {
+                t = syntax[value];
+            } else if (type === '(identifier)') {
+                t = syntax[value];
+                if (!t || typeof t != 'object') {
+                    t = syntax[type];
+                }
+            } else {
+                t = syntax[type];
+            }
+            if (!t || typeof t != 'object') {
+                error("Unrecognized symbol: '" + value + "' " + type);
+            }
+            t = object(t);
+            if (value || type === '(string)') {
+                t.value = value;
+            }
+            t.line = line;
+            t.character = character;
+            t.from = from;
+            return t;
+        }
+
+// Public lex methods
+
+        return {
+            init: function (source) {
+                if (typeof source === 'string') {
+                    lines = source.split('\n');
+                    if (lines.length == 1) {
+                        lines = lines[0].split('\r');
+                    }
+                } else {
+                    lines = source;
+                }
+                line = 0;
+                character = 0;
+                from = 0;
+                s = lines[0];
+            },
+
+// token -- this is called by advance to get the next token.
+
+            token: function () {
+                var c, i, l, r, t;
+
+                function string(x) {
+                    r = x.exec(s);
+                    if (r) {
+                        t = r[1];
+                        l = r[0].length;
+                        s = s.substr(l);
+                        character += l;
+                        if (xmode == 'script') {
+                            if (t.indexOf('<\/') >= 0) {
+                                warning(
+    'Expected "...<\\/..." and instead saw "...<\/...".', token);
+                            }
+                        }
+                        return it('(string)', r[1]);
+                    } else {
+                        for (var j = 0; j < s.length; j += 1) {
+                            var c = s.charAt(j);
+                            if (c < ' ') {
+                                if (c === '\n' || c === '\r') {
+                                    break;
+                                }
+                                error("Control character in string: " +
+                                    s.substring(0, j), line, character + j);
+                            }
+                        }
+                        error("Unclosed string: " + s, line, character);
+                    }
+                }
+
+                for (;;) {
+                    if (!s) {
+                        return it(nextLine() ? '(endline)' : '(end)', '');
+                    }
+                    r = wx.exec(s);
+                    if (!r || !r[0]) {
+                        break;
+                    }
+                    l = r[0].length;
+                    s = s.substr(l);
+                    character += l;
+                    if (s) {
+                        break;
+                    }
+                }
+                from = character;
+                r = tx.exec(s);
+                if (r) {
+                    t = r[0];
+                    l = t.length;
+                    s = s.substr(l);
+                    character += l;
+                    c = t.substr(0, 1);
+
+//      identifier
+
+                    if (c.isAlpha() || c === '_' || c === '$') {
+                        return it('(identifier)', t);
+                    }
+
+//      number
+
+                    if (c.isDigit()) {
+                        if (token.id === '.') {
+                            warning(
+            "A decimal fraction should have a zero before the decimal point.",
+                                token);
+                        }
+                        if (!isFinite(Number(t))) {
+                            warning("Bad number: '" + t + "'.",
+                                line, character);
+                        }
+                        if (s.substr(0, 1).isAlpha()) {
+                            error("Space is required after a number: '" +
+                                t + "'.", line, character);
+                        }
+                        if (c === '0' && t.substr(1,1).isDigit()) {
+                            warning("Don't use extra leading zeros: '" +
+                                t + "'.", line, character);
+                        }
+                        if (t.substr(t.length - 1) === '.') {
+                            warning(
+    "A trailing decimal point can be confused with a dot: '" + t + "'.",
+                                line, character);
+                        }
+                        return it('(number)', t);
+                    }
+
+//      string
+
+                    if (t === '"') {
+                        return (xmode === '"' ||  xmode === 'string') ?
+                            it('(punctuator)', t) :
+                            string(xmode === 'xml' ? qxx : qx);
+                    }
+                    if (t === "'") {
+                        return (xmode === "'" ||  xmode === 'string') ?
+                            it('(punctuator)', t) :
+                            string(xmode === 'xml' ? sxx : sx);
+                    }
+
+//      unbegun comment
+
+                    if (t === '/*') {
+                        for (;;) {
+                            i = s.search(lx);
+                            if (i >= 0) {
+                                break;
+                            }
+                            if (!nextLine()) {
+                                error("Unclosed comment.", token);
+                            }
+                        }
+                        character += i + 2;
+                        if (s.substr(i, 1) === '/') {
+                            error("Nested comment.");
+                        }
+                        s = s.substr(i + 2);
+                        return this.token();
+                    }
+
+//      /*extern
+
+                    if (t === '/*extern' || t === '/*global') {
+                        for (;;) {
+                            r = hx.exec(s);
+                            if (r) {
+                                l = r[0].length;
+                                s = s.substr(l);
+                                character += l;
+                                if (r[1] === '*/') {
+                                    return this.token();
+                                }
+                            }
+                            if (s) {
+                                r = gx.exec(s);
+                                if (r) {
+                                    l = r[0].length;
+                                    s = s.substr(l);
+                                    character += l;
+                                    globals[r[1]] = true;
+                                } else {
+                                    error("Bad extern identifier: '" +
+                                        s + "'.", line, character);
+                                }
+                             } else if (!nextLine()) {
+                                error("Unclosed comment.");
+                            }
+                        }
+                    }
+
+//      punctuator
+
+                    return it('(punctuator)', t);
+                }
+                error("Unexpected token: " + (t || s.substr(0, 1)),
+                    line, character);
+            },
+
+// skip -- skip past the next occurrence of a particular string.
+// If the argument is empty, skip to just before the next '<' character.
+// This is used to ignore HTML content. Return false if it isn't found.
+
+            skip: function (to) {
+                if (token.id) {
+                    if (!to) {
+                        to = '';
+                        if (token.id.substr(0, 1) === '<') {
+                            lookahead.push(token);
+                            return true;
+                        }
+                    } else if (token.id.indexOf(to) >= 0) {
+                        return true;
+                    }
+                }
+                prevtoken = token;
+                token = syntax['(error)'];
+                for (;;) {
+                    var i = s.indexOf(to || '<');
+                    if (i >= 0) {
+                        character += i + to.length;
+                        s = s.substr(i + to.length);
+                        return true;
+                    }
+                    if (!nextLine()) {
+                        break;
+                    }
+                }
+                return false;
+            },
+
+// regex -- this is called by parse when it sees '/' being used as a prefix.
+
+            regex: function () {
+                var l, r = rx.exec(s), x;
+                if (r) {
+                    l = r[0].length;
+                    character += l;
+                    s = s.substr(l);
+                    x = r[1];
+                    return it('(regex)', x);
+                }
+                error("Bad regular expression: " + s);
+            }
+        };
+    }();
+
+    function builtin(name) {
+        return standard[name] === true ||
+               globals[name] === true ||
+               (xtype === 'widget' && konfab[name] === true) ||
+               ((xtype === 'html' || option.browser) && browser[name] === true);
+    }
+
+    function addlabel(t, type) {
+        if (t) {
+            if (typeof funlab[t] === 'string') {
+                switch (funlab[t]) {
+                case 'var':
+                case 'var*':
+                    if (type === 'global') {
+                        funlab[t] = 'var*';
+                        return;
+                    }
+                    break;
+                case 'global':
+                    if (type === 'var') {
+                        warning('Var ' + t +
+                            ' was used before it was declared.', prevtoken);
+                    }
+                    if (type === 'var*' || type === 'global') {
+                        return;
+                    }
+                    break;
+                case 'function':
+                case 'parameter':
+                    if (type === 'global') {
+                        return;
+                    }
+                    break;
+                }
+                warning("Identifier '" + t + "' already declared as " +
+                    funlab[t], prevtoken);
+            }
+            funlab[t] = type;
+        }
+    }
+
+
+// We need a peek function. If it has an argument, it peeks that much farther
+// ahead. It is used to distinguish
+//     for ( var i in ...
+// from
+//     for ( var i = ...
+
+    function peek(i) {
+        var j = 0, t;
+        if (token == syntax['(error)']) {
+            return token;
+        }
+        if (typeof i === 'undefined') {
+            i = 0;
+        }
+        while (j <= i) {
+            t = lookahead[j];
+            if (!t) {
+                t = lookahead[j] = lex.token();
+            }
+            j += 1;
+        }
+        return t;
+    }
+
+
+    var badbreak = {')': true, ']': true, '++': true, '--': true};
+
+// Produce the next token. It looks for programming errors.
+
+    function advance(id, t) {
+        var l;
+        switch (prevtoken.id) {
+        case '(number)':
+            if (token.id === '.') {
+                warning(
+"A dot following a number can be confused with a decimal point.", prevtoken);
+            }
+            break;
+        case '-':
+            if (token.id === '-' || token.id === '--') {
+                warning("Confusing minusses.");
+            }
+            break;
+        case '+':
+            if (token.id === '+' || token.id === '++') {
+                warning("Confusing plusses.");
+            }
+            break;
+        }
+        if (prevtoken.type === '(string)' || prevtoken.identifier) {
+            anonname = prevtoken.value;
+        }
+
+        if (id && token.value != id) {
+            if (t) {
+                if (token.id === '(end)') {
+                    warning("Unmatched '" + t.id + "'.", t);
+                } else {
+                    warning("Expected '" + id + "' to match '" +
+                        t.id + "' from line " + (t.line + 1) +
+                        " and instead saw '" + token.value + "'.");
+                }
+            } else {
+                warning("Expected '" + id + "' and instead saw '" +
+                    token.value + "'.");
+            }
+        }
+        prevtoken = token;
+        for (;;) {
+            token = lookahead.shift() || lex.token();
+            if (token.id === '<![') {
+                if (xtype === 'html') {
+                    error("Unexpected token '<!['");
+                }
+                if (xmode === 'script') {
+                    token = lex.token();
+                    if (token.value !== 'CDATA') {
+                        error("Expected 'CDATA'");
+                    }
+                    token = lex.token();
+                    if (token.id !== '[') {
+                        error("Expected '['");
+                    }
+                    xmode = 'CDATA';
+                } else if (xmode === 'xml') {
+                    lex.skip(']]>');
+                } else {
+                    error("Unexpected token '<!['");
+                }
+            } else if (token.id === ']]>') {
+                if (xmode === 'CDATA') {
+                    xmode = 'script';
+                } else {
+                    error("Unexpected token ']]>");
+                }
+            } else if (token.id !== '(endline)') {
+                break;
+            }
+            if (xmode === '"' || xmode === "'") {
+                error("Missing '" + xmode + "'.", prevtoken);
+            }
+            l = !xmode && !option.laxLineEnd &&
+                (prevtoken.type == '(string)' || prevtoken.type == '(number)' ||
+                prevtoken.type == '(identifier)' || badbreak[prevtoken.id]);
+        }
+        if (l && token.id != '{' && token.id != '}' && token.id != ']') {
+            warning(
+                "Strict line ending error: '" +
+                prevtoken.value + "'.", prevtoken);
+        }
+        if (xtype === 'widget' && xmode === 'script' && token.id) {
+            l = token.id.charAt(0);
+            if (l === '<' || l === '&') {
+                token.nud = token.led = null;
+                token.lbp = 0;
+                token.reach = true;
+            }
+        }
+    }
+
+
+    function advanceregex() {
+        token = lex.regex();
+    }
+
+
+    function beginfunction(i) {
+        var f = {'(name)': i, '(line)': token.line + 1, '(context)': funlab};
+        funstack.push(funlab);
+        funlab = f;
+        functions.push(funlab);
+    }
+
+
+    function endfunction() {
+        funlab = funstack.pop();
+    }
+
+
+// This is the heart of JSLint, the Pratt parser. In addition to parsing, it
+// is looking for ad hoc lint patterns. We add to Pratt's model .fud, which is
+// like nud except that it is only used on the first token of a statement.
+// Having .fud makes it much easier to define JavaScript. I retained Pratt's
+// nomenclature, even though it isn't very descriptive.
+
+// .nud     Null denotation
+// .fud     First null denotation
+// .led     Left denotation
+//  lbp     Left binding power
+//  rbp     Right binding power
+
+// They are key to the parsing method called Top Down Operator Precedence.
+
+    function parse(rbp, initial) {
+        var l, left, o;
+        if (token.id && token.id === '/') {
+            if (prevtoken.id != '(' && prevtoken.id != '=' &&
+                    prevtoken.id != ':' && prevtoken.id != ',' &&
+                    prevtoken.id != '=') {
+                warning(
+"Expected to see a '(' or '=' or ':' or ',' preceding a regular expression literal, and instead saw '" +
+                    prevtoken.value + "'.", prevtoken);
+            }
+            advanceregex();
+        }
+        if (token.id === '(end)') {
+            warning("Unexpected early end of program", prevtoken);
+        }
+        advance();
+        if (initial) {
+            anonname = 'anonymous';
+            verb = prevtoken.value;
+        }
+        if (initial && prevtoken.fud) {
+            prevtoken.fud();
+        } else {
+            if (prevtoken.nud) {
+                o = prevtoken.exps;
+                left = prevtoken.nud();
+            } else {
+                if (token.type === '(number)' && prevtoken.id === '.') {
+                    warning(
+"A leading decimal point can be confused with a dot: ." + token.value,
+                        prevtoken);
+                }
+                error("Expected an identifier and instead saw '" +
+                    prevtoken.id + "'.", prevtoken);
+            }
+            while (rbp < token.lbp) {
+                o = token.exps;
+                advance();
+                if (prevtoken.led) {
+                    left = prevtoken.led(left);
+                } else {
+                    error("Expected an operator and instead saw '" +
+                        prevtoken.id + "'.");
+                }
+            }
+            if (initial && !o) {
+                warning(
+"Expected an assignment or function call and instead saw an expression.",
+                    prevtoken);
+            }
+        }
+        if (l) {
+            funlab[l] = 'label';
+        }
+        return left;
+    }
+
+
+// Parasitic constructors for making the symbols that will be inherited by
+// tokens.
+
+    function symbol(s, p) {
+        return syntax[s] || (syntax[s] = {id: s, lbp: p, value: s});
+    }
+
+
+    function delim(s) {
+        return symbol(s, 0);
+    }
+
+
+    function stmt(s, f) {
+        var x = delim(s);
+        x.identifier = x.reserved = true;
+        x.fud = f;
+        return x;
+    }
+
+
+    function blockstmt(s, f) {
+        var x = stmt(s, f);
+        x.block = true;
+        return x;
+    }
+
+
+    function prefix(s, f) {
+        var x = symbol(s, 150);
+        x.nud = (typeof f === 'function') ? f : function () {
+            parse(150);
+            return this;
+        };
+        return x;
+    }
+
+
+    function prefixname(s, f) {
+        var x = prefix(s, f);
+        x.identifier = x.reserved = true;
+        return x;
+    }
+
+
+    function type(s, f) {
+        var x = delim(s);
+        x.type = s;
+        x.nud = f;
+        return x;
+    }
+
+
+    function reserve(s, f) {
+        var x = type(s, f);
+        x.identifier = x.reserved = true;
+        return x;
+    }
+
+
+    function reservevar(s) {
+        return reserve(s, function () {
+            return this;
+        });
+    }
+
+
+    function infix(s, f, p) {
+        var x = symbol(s, p);
+        x.led = (typeof f === 'function') ? f : function (left) {
+            return [f, left, parse(p)];
+        };
+        return x;
+    }
+
+
+    function assignop(s, f) {
+        symbol(s, 20).exps = true;
+        return infix(s, function (left) {
+            if (left) {
+                if (left.id === '.' || left.id === '[' ||
+                        (left.identifier && !left.reserved)) {
+                    parse(19);
+                    return left;
+                }
+                if (left == syntax['function']) {
+                    if (option.jscript) {
+                        parse(19);
+                        return left;
+                    } else {
+                        warning(
+"Expected an identifier in an assignment, and instead saw a function invocation.",
+                            prevtoken);
+                    }
+                }
+            }
+            error("Bad assignment.", this);
+        }, 20);
+    }
+
+
+    function suffix(s, f) {
+        var x = symbol(s, 150);
+        x.led = function (left) {
+            if (option.plusplus) {
+                warning(this.id + " is considered harmful.", this);
+            }
+            return [f, left];
+        };
+        return x;
+    }
+
+
+    function optionalidentifier() {
+        if (token.reserved) {
+            warning("Expected an identifier and instead saw '" +
+                token.id + "' (a reserved word).");
+        }
+        if (token.identifier) {
+            advance();
+            return prevtoken.value;
+        }
+    }
+
+
+    function identifier() {
+        var i = optionalidentifier();
+        if (i) {
+            return i;
+        }
+        if (prevtoken.id === 'function' && token.id === '(') {
+            warning("Missing name in function statement.");
+        } else {
+            error("Expected an identifier and instead saw '" +
+                    token.value + "'.", token);
+        }
+    }
+
+
+    function reachable(s) {
+        var i = 0, t;
+        if (token.id != ';' || noreach) {
+            return;
+        }
+        for (;;) {
+            t = peek(i);
+            if (t.reach) {
+                return;
+            }
+            if (t.id != '(endline)') {
+                if (t.id === 'function') {
+                    warning(
+"Inner functions should be listed at the top of the outer function.", t);
+                    break;
+                }
+                warning("Unreachable '" + t.value + "' after '" + s +
+                    "'.", t);
+                break;
+            }
+            i += 1;
+        }
+    }
+
+
+    function statement() {
+        var t = token;
+        while (t.id === ';') {
+            warning("Unnecessary semicolon", t);
+            advance(';');
+            t = token;
+            if (t.id === '}') {
+                return;
+            }
+        }
+        if (t.identifier && !t.reserved && peek().id === ':') {
+            advance();
+            advance(':');
+            addlabel(t.value, 'live*');
+            if (!token.labelled) {
+                warning("Label '" + t.value +
+                    "' on unlabelable statement '" + token.value + "'.",
+                    token);
+            }
+            if (t.value.toLowerCase() == 'javascript') {
+                warning("Label '" + t.value +
+                    "' looks like a javascript url.",
+                    token);
+            }
+            token.label = t.value;
+            t = token;
+        }
+        parse(0, true);
+        if (!t.block) {
+            if (token.id != ';') {
+                warning("Missing ';'", prevtoken.line,
+                    prevtoken.from + prevtoken.value.length);
+            } else {
+                advance(';');
+            }
+        }
+    }
+
+
+    function statements() {
+        while (!token.reach) {
+            statement();
+        }
+    }
+
+
+    function block() {
+        var t = token;
+        if (token.id === '{') {
+            advance('{');
+            statements();
+            advance('}', t);
+        } else {
+            warning("Missing '{' before '" + token.value + "'.");
+            noreach = true;
+            statement();
+            noreach = false;
+        }
+        verb = null;
+    }
+
+
+// An identity function, used by string and number tokens.
+
+    function idValue() {
+        return this;
+    }
+
+
+    function countMember(m) {
+        if (typeof member[m] === 'number') {
+            member[m] += 1;
+        } else {
+            member[m] = 1;
+        }
+    }
+
+
+// Common HTML attributes that carry scripts.
+
+    var scriptstring = {
+        onblur:      true,
+        onchange:    true,
+        onclick:     true,
+        ondblclick:  true,
+        onfocus:     true,
+        onkeydown:   true,
+        onkeypress:  true,
+        onkeyup:     true,
+        onload:      true,
+        onmousedown: true,
+        onmousemove: true,
+        onmouseout:  true,
+        onmouseover: true,
+        onmouseup:   true,
+        onreset:     true,
+        onselect:    true,
+        onsubmit:    true,
+        onunload:    true
+    };
+
+
+// XML types. Currently we support html and widget.
+
+    var xmltype = {
+        HTML: {
+            doBegin: function (n) {
+                if (!option.cap) {
+                    warning("HTML case error.");
+                }
+                xmltype.html.doBegin();
+            }
+        },
+        html: {
+            doBegin: function (n) {
+                xtype = 'html';
+                xmltype.html.script = false;
+            },
+            doTagName: function (n, p) {
+                var i, t = xmltype.html.tag[n], x;
+                if (!t) {
+                    error('Unrecognized tag: <' + n + '>. ' +
+                        (n === n.toLowerCase() ?
+                        'Did you mean <' + n.toLowerCase() + '>?' : ''));
+                }
+                x = t.parent;
+                if (x) {
+                    if (x.indexOf(' ' + p + ' ') < 0) {
+                        error('A <' + n + '> must be within <' + x + '>',
+                            prevtoken);
+                    }
+                } else {
+                    i = stack.length;
+                    do {
+                        if (i <= 0) {
+                            error('A <' + n + '> must be within the body',
+                                prevtoken);
+                        }
+                        i -= 1;
+                    } while (stack[i].name !== 'body');
+                }
+                xmltype.html.script = n === 'script';
+                return t.simple;
+            },
+            doAttribute: function (n, a) {
+                if (n === 'script') {
+                    if (a === 'src') {
+                        xmltype.html.script = false;
+                        return 'string';
+                    } else if (a === 'language') {
+                        warning("The 'language' attribute is deprecated",
+                            prevtoken);
+                        return false;
+                    }
+                }
+                return scriptstring[a] && 'script';
+            },
+            doIt: function (n) {
+                return xmltype.html.script ? 'script' :
+                    n !== 'html' && xmltype.html.tag[n].special && 'special';
+            },
+            tag: {
+                a:        {},
+                abbr:     {},
+                acronym:  {},
+                address:  {},
+                applet:   {},
+                area:     {simple: true, parent: ' map '},
+                b:        {},
+                base:     {simple: true, parent: ' head '},
+                bdo:      {},
+                big:      {},
+                blockquote: {},
+                body:     {parent: ' html noframes '},
+                br:       {simple: true},
+                button:   {},
+                caption:  {parent: ' table '},
+                center:   {},
+                cite:     {},
+                code:     {},
+                col:      {simple: true, parent: ' table colgroup '},
+                colgroup: {parent: ' table '},
+                dd:       {parent: ' dl '},
+                del:      {},
+                dfn:      {},
+                dir:      {},
+                div:      {},
+                dl:       {},
+                dt:       {parent: ' dl '},
+                em:       {},
+                embed:    {},
+                fieldset: {},
+                font:     {},
+                form:     {},
+                frame:    {simple: true, parent: ' frameset '},
+                frameset: {parent: ' html frameset '},
+                h1:       {},
+                h2:       {},
+                h3:       {},
+                h4:       {},
+                h5:       {},
+                h6:       {},
+                head:     {parent: ' html '},
+                html:     {},
+                hr:       {simple: true},
+                i:        {},
+                iframe:   {},
+                img:      {simple: true},
+                input:    {simple: true},
+                ins:      {},
+                kbd:      {},
+                label:    {},
+                legend:   {parent: ' fieldset '},
+                li:       {parent: ' dir menu ol ul '},
+                link:     {simple: true, parent: ' head '},
+                map:      {},
+                menu:     {},
+                meta:     {simple: true, parent: ' head noscript '},
+                noframes: {parent: ' html body '},
+                noscript: {parent: ' html head body frameset '},
+                object:   {},
+                ol:       {},
+                optgroup: {parent: ' select '},
+                option:   {parent: ' optgroup select '},
+                p:        {},
+                param:    {simple: true, parent: ' applet object '},
+                pre:      {},
+                q:        {},
+                samp:     {},
+                script:   {parent:
+' head body p div span abbr acronym address bdo blockquote cite code del dfn em ins kbd pre samp strong th td var '},
+                select:   {},
+                small:    {},
+                span:     {},
+                strong:   {},
+                style:    {parent: ' head ', special: true},
+                sub:      {},
+                sup:      {},
+                table:    {},
+                tbody:    {parent: ' table '},
+                td:       {parent: ' tr '},
+                textarea: {},
+                tfoot:    {parent: ' table '},
+                th:       {parent: ' tr '},
+                thead:    {parent: ' table '},
+                title:    {parent: ' head '},
+                tr:       {parent: ' table tbody thead tfoot '},
+                tt:       {},
+                u:        {},
+                ul:       {},
+                'var':    {}
+            }
+        },
+        widget: {
+            doBegin: function (n) {
+                xtype = 'widget';
+            },
+            doTagName: function (n, p) {
+                var t = xmltype.widget.tag[n];
+                if (!t) {
+                    error('Unrecognized tag: <' + n + '>. ');
+                }
+                var x = t.parent;
+                if (x.indexOf(' ' + p + ' ') < 0) {
+                    error('A <' + n + '> must be within <' + x + '>', prevtoken);
+                }
+            },
+            doAttribute: function (n, a) {
+                var t = xmltype.widget.tag[a];
+                if (!t) {
+                    error('Unrecognized attribute: <' + n + ' ' + a + '>. ');
+                }
+                var x = t.parent;
+                if (x.indexOf(' ' + n + ' ') < 0) {
+                    error('Attribute ' + a + ' does not belong in <' +
+                        n + '>');
+                }
+                return t.script ? 'script' : a === 'name' ? 'define' : 'string';
+            },
+            doIt: function (n) {
+                var x = xmltype.widget.tag[n];
+                return x && x.script && 'script';
+            },
+            tag: {
+                "about-box": {parent: ' widget '},
+                "about-image": {parent: ' about-box '},
+                "about-text": {parent: ' about-box '},
+                "about-version": {parent: ' about-box '},
+                action: {parent: ' widget ', script: true},
+                alignment: {parent: ' image text textarea window '},
+                author: {parent: ' widget '},
+                autoHide: {parent: ' scrollbar '},
+                bgColor: {parent: ' text textarea '},
+                bgOpacity: {parent: ' text textarea '},
+                checked: {parent: ' image '},
+                clipRect: {parent: ' image '},
+                color: {parent: ' about-text about-version shadow text textarea '},
+                contextMenuItems: {parent: ' frame image text textarea window '},
+                colorize: {parent: ' image '},
+                columns: {parent: ' textarea '},
+                company: {parent: ' widget '},
+                copyright: {parent: ' widget '},
+                data: {parent: ' about-text about-version text textarea '},
+                debug: {parent: ' widget '},
+                defaultValue: {parent: ' preference '},
+                defaultTracking: {parent: ' widget '},
+                description: {parent: ' preference '},
+                directory: {parent: ' preference '},
+                editable: {parent: ' textarea '},
+                enabled: {parent: ' menuItem '},
+                extension: {parent: ' preference '},
+                file: {parent: ' action preference '},
+                fillMode: {parent: ' image '},
+                font: {parent: ' about-text about-version text textarea '},
+                frame: {parent: ' frame window '},
+                group: {parent: ' preference '},
+                hAlign: {parent: ' frame image scrollbar text textarea '},
+                height: {parent: ' frame image scrollbar text textarea window '},
+                hidden: {parent: ' preference '},
+                hLineSize: {parent: ' frame '},
+                hOffset: {parent: ' about-text about-version frame image scrollbar shadow text textarea window '},
+                hotkey: {parent: ' widget '},
+                hRegistrationPoint: {parent: ' image '},
+                hslAdjustment: {parent: ' image '},
+                hslTinting: {parent: ' image '},
+                hScrollBar: {parent: ' frame '},
+                icon: {parent: ' preferenceGroup '},
+                image: {parent: ' about-box frame window widget '},
+                interval: {parent: ' action timer '},
+                key: {parent: ' hotkey '},
+                kind: {parent: ' preference '},
+                level: {parent: ' window '},
+                lines: {parent: ' textarea '},
+                loadingSrc: {parent: ' image '},
+                max: {parent: ' scrollbar '},
+                maxLength: {parent: ' preference '},
+                menuItem: {parent: ' contextMenuItems '},
+                min: {parent: ' scrollbar '},
+                minimumVersion: {parent: ' widget '},
+                minLength: {parent: ' preference '},
+                missingSrc: {parent: ' image '},
+                modifier: {parent: ' hotkey '},
+                name: {parent: ' hotkey image preference preferenceGroup text textarea timer window '},
+                notSaved: {parent: ' preference '},
+                onContextMenu: {parent: ' frame image text textarea window ', script: true},
+                onDragDrop: {parent: ' frame image text textarea ', script: true},
+                onDragEnter: {parent: ' frame image text textarea ', script: true},
+                onDragExit: {parent: ' frame image text textarea ', script: true},
+                onFirstDisplay: {parent: ' window ', script: true},
+                onGainFocus: {parent: ' textarea window ', script: true},
+                onKeyDown: {parent: ' hotkey text textarea ', script: true},
+                onKeyPress: {parent: ' textarea ', script: true},
+                onKeyUp: {parent: ' hotkey text textarea ', script: true},
+                onImageLoaded: {parent: ' image ', script: true},
+                onLoseFocus: {parent: ' textarea window ', script: true},
+                onMouseDown: {parent: ' frame image text textarea ', script: true},
+                onMouseEnter: {parent: ' frame image text textarea ', script: true},
+                onMouseExit: {parent: ' frame image text textarea ', script: true},
+                onMouseMove: {parent: ' frame image text ', script: true},
+                onMouseUp: {parent: ' frame image text textarea ', script: true},
+                onMouseWheel: {parent: ' frame ', script: true},
+                onMultiClick: {parent: ' frame image text textarea window ', script: true},
+                onSelect: {parent: ' menuItem ', script: true},
+                onTimerFired: {parent: ' timer ', script: true},
+                onValueChanged: {parent: ' scrollbar ', script: true},
+                opacity: {parent: ' frame image scrollbar shadow text textarea window '},
+                option: {parent: ' preference widget '},
+                optionValue: {parent: ' preference '},
+                order: {parent: ' preferenceGroup '},
+                orientation: {parent: ' scrollbar '},
+                pageSize: {parent: ' scrollbar '},
+                preference: {parent: ' widget '},
+                preferenceGroup: {parent: ' widget '},
+                remoteAsync: {parent: ' image '},
+                requiredPlatform: {parent: ' widget '},
+                rotation: {parent: ' image '},
+                scrollX: {parent: ' frame '},
+                scrollY: {parent: ' frame '},
+                secure: {parent: ' preference textarea '},
+                scrollbar: {parent: ' text textarea '},
+                shadow: {parent: ' about-text text window '},
+                size: {parent: ' about-text about-version text textarea '},
+                spellcheck: {parent: ' textarea '},
+                src: {parent: ' image '},
+                srcHeight: {parent: ' image '},
+                srcWidth: {parent: ' image '},
+                style: {parent: ' about-text about-version preference text textarea '},
+                text: {parent: ' frame window '},
+                textarea: {parent: ' frame window '},
+                timer: {parent: ' widget '},
+                thumbColor: {parent: ' scrollbar '},
+                ticking: {parent: ' timer '},
+                ticks: {parent: ' preference '},
+                tickLabel: {parent: ' preference '},
+                tileOrigin: {parent: ' image '},
+                title: {parent: ' menuItem preference preferenceGroup window '},
+                tooltip: {parent: ' image text textarea '},
+                truncation: {parent: ' text '},
+                tracking: {parent: ' image '},
+                trigger: {parent: ' action '},
+                truncation: {parent: ' text textarea '},
+                type: {parent: ' preference '},
+                useFileIcon: {parent: ' image '},
+                vAlign: {parent: ' frame image scrollbar text textarea '},
+                value: {parent: ' preference scrollbar '},
+                version: {parent: ' widget '},
+                visible: {parent: ' frame image scrollbar text textarea window '},
+                vLineSize: {parent: ' frame '},
+                vOffset: {parent: ' about-text about-version frame image scrollbar shadow text textarea window '},
+                vRegistrationPoint: {parent: ' image '},
+                vScrollBar: {parent: ' frame '},
+                width: {parent: ' frame image scrollbar text textarea window '},
+                window: {parent: ' widget '},
+                zOrder: {parent: ' frame image scrollbar text textarea '}
+            }
+        }
+    };
+
+    function xmlword(tag) {
+        var w = token.value;
+        if (!token.identifier) {
+            if (token.id === '<') {
+                error(tag ? "Expected &lt; and saw '<'" : "Missing '>'",
+                    prevtoken);
+            } else {
+                warning("Missing quotes", prevtoken);
+            }
+        }
+        advance();
+        while (token.id === '-' || token.id === ':') {
+            w += token.id;
+            advance();
+            if (!token.identifier) {
+                error('Bad name: ' + w + token.value);
+            }
+            w += token.value;
+            advance();
+        }
+        return w;
+    }
+
+    function xml() {
+        var a, e, n, q, t;
+        xmode = 'xml';
+        stack = [];
+        for (;;) {
+            switch (token.value) {
+            case '<':
+                advance('<');
+                t = token;
+                n = xmlword(true);
+                t.name = n;
+                if (!xtype) {
+                    if (xmltype[n]) {
+                        xmltype[n].doBegin();
+                        n = xtype;
+                        e = false;
+                    } else {
+                        error("Unrecognized <" + n + ">");
+                    }
+                } else {
+                    if (option.cap && xtype === 'html') {
+                        n = n.toLowerCase();
+                    }
+                    e = xmltype[xtype].doTagName(n, stack[stack.length - 1].type);
+                }
+                t.type = n;
+                for (;;) {
+                    if (token.id === '/') {
+                        advance('/');
+                        e = true;
+                        break;
+                    }
+                    if (token.id && token.id.substr(0, 1) === '>') {
+                        break;
+                    }
+                    a = xmlword();
+                    switch (xmltype[xtype].doAttribute(n, a)) {
+                    case 'script':
+                        xmode = 'string';
+                        advance('=');
+                        q = token.id;
+                        if (q !== '"' && q !== "'") {
+                            error('Missing quote.');
+                        }
+                        xmode = q;
+                        advance(q);
+                        statements();
+                        if (token.id !== q) {
+                            error(
+                              'Missing close quote on script attribute');
+                        }
+                        xmode = 'xml';
+                        advance(q);
+                        break;
+                    case 'value':
+                        advance('=');
+                        if (!token.identifier &&
+                                token.type != '(string)' &&
+                                token.type != '(number)') {
+                            error('Bad value: ' + token.value);
+                        }
+                        advance();
+                        break;
+                    case 'string':
+                        advance('=');
+                        if (token.type !== '(string)') {
+                            error('Bad value: ' + token.value);
+                        }
+                        advance();
+                        break;
+                    case 'define':
+                        advance('=');
+                        if (token.type !== '(string)') {
+                            error('Bad value: ' + token.value);
+                        }
+                        addlabel(token.value, 'global');
+                        advance();
+                        break;
+                    default:
+                        if (token.id === '=') {
+                            advance('=');
+                            if (!token.identifier &&
+                                    token.type != '(string)' &&
+                                    token.type != '(number)') {
+                            }
+                            advance();
+                        }
+                    }
+                }
+                switch (xmltype[xtype].doIt(n)) {
+                case 'script':
+                    xmode = 'script';
+                    advance('>');
+                    statements();
+                    xmode = 'xml';
+                    break;
+                case 'special':
+                    e = true;
+                    n = '</' + t.name + '>';
+                    if (!lex.skip(n)) {
+                        error("Missing " + n, t);
+                    }
+                    break;
+                default:
+                    lex.skip('>');
+                }
+                if (!e) {
+                    stack.push(t);
+                }
+                break;
+            case '</':
+                advance('</');
+                n = xmlword(true);
+                t = stack.pop();
+                if (!t) {
+                    error('Unexpected close tag: </' + n + '>');
+                }
+                if (t.name != n) {
+                    error('Expected </' + t.name +
+                        '> and instead saw </' + n + '>');
+                }
+                if (token.id !== '>') {
+                    error("Expected '>'");
+                }
+                lex.skip('>');
+                break;
+            case '<!':
+                for (;;) {
+                    advance();
+                    if (token.id === '>') {
+                        break;
+                    }
+                    if (token.id === '<' || token.id === '(end)') {
+                        error("Missing '>'.", prevtoken);
+                    }
+                }
+                lex.skip('>');
+                break;
+            case '<!--':
+                lex.skip('-->');
+                break;
+            case '<%':
+                lex.skip('%>');
+                break;
+            case '<?':
+                for (;;) {
+                    advance();
+                    if (token.id === '?>') {
+                        break;
+                    }
+                    if (token.id === '<?' || token.id === '<' ||
+                            token.id === '>' || token.id === '(end)') {
+                        error("Missing '?>'.", prevtoken);
+                    }
+                }
+                lex.skip('?>');
+                break;
+            case '<=':
+            case '<<':
+            case '<<=':
+                error("Expected '&lt;'.");
+                break;
+            case '(end)':
+                return;
+            }
+            if (!lex.skip('')) {
+                if (stack.length) {
+                    t = stack.pop();
+                    error('Missing </' + t.name + '>', t);
+                }
+                return;
+            }
+            advance();
+        }
+    }
+
+
+// Build the syntax table by declaring the syntactic elements of the language.
+
+    type('(number)', idValue);
+    type('(string)', idValue);
+
+    syntax['(identifier)'] = {
+        type: '(identifier)',
+        lbp: 0,
+        identifier: true,
+        nud: function () {
+            if (option.undef && !builtin(this.value) &&
+                    xmode !== '"' && xmode !== "'") {
+                var c = funlab;
+                while (!c[this.value]) {
+                    c = c['(context)'];
+                    if (!c) {
+                        warning("Undefined variable: " + this.value,
+                            prevtoken);
+                        break;
+                    }
+                }
+            }
+            addlabel(this.value, 'global');
+            return this;
+        },
+        led: function () {
+            error("Expected an operator and instead saw '" +
+                token.value + "'.");
+        }
+    };
+
+    type('(regex)', function () {
+        return [this.id, this.value, this.flags];
+    });
+
+    delim('(endline)');
+    delim('(begin)');
+    delim('(end)').reach = true;
+    delim('</').reach = true;
+    delim('<![').reach = true;
+    delim('<%');
+    delim('<?');
+    delim('<!');
+    delim('<!--');
+    delim('%>');
+    delim('?>');
+    delim('(error)').reach = true;
+    delim('}').reach = true;
+    delim(')');
+    delim(']');
+    delim(']]>').reach = true;
+    delim('"').reach = true;
+    delim("'").reach = true;
+    delim(';');
+    delim(':').reach = true;
+    delim(',');
+    reserve('else');
+    reserve('case').reach = true;
+    reserve('default').reach = true;
+    reserve('catch');
+    reserve('finally');
+    reservevar('arguments');
+    reservevar('false');
+    reservevar('Infinity');
+    reservevar('NaN');
+    reservevar('null');
+    reservevar('this');
+    reservevar('true');
+    reservevar('undefined');
+    assignop('=', 'assign', 20);
+    assignop('+=', 'assignadd', 20);
+    assignop('-=', 'assignsub', 20);
+    assignop('*=', 'assignmult', 20);
+    assignop('/=', 'assigndiv', 20).nud = function () {
+        warning(
+            "A regular expression literal can be confused with '/='.");
+    };
+    assignop('%=', 'assignmod', 20);
+    assignop('&=', 'assignbitand', 20);
+    assignop('|=', 'assignbitor', 20);
+    assignop('^=', 'assignbitxor', 20);
+    assignop('<<=', 'assignshiftleft', 20);
+    assignop('>>=', 'assignshiftright', 20);
+    assignop('>>>=', 'assignshiftrightunsigned', 20);
+    infix('?', function (left) {
+        parse(10);
+        advance(':');
+        parse(10);
+    }, 30);
+
+    infix('||', 'or', 40);
+    infix('&&', 'and', 50);
+    infix('|', 'bitor', 70);
+    infix('^', 'bitxor', 80);
+    infix('&', 'bitand', 90);
+    infix('==', function (left) {
+        var t = token;
+        if (    (t.type === '(number)' && !+t.value) ||
+                (t.type === '(string)' && !t.value) ||
+                t.type === 'true' || t.type === 'false' ||
+                t.type === 'undefined' || t.type === 'null') {
+            warning("Use '===' to compare with '" + t.value + "'.", t);
+        }
+        return ['==', left, parse(100)];
+    }, 100);
+    infix('===', 'equalexact', 100);
+    infix('!=', function (left) {
+        var t = token;
+        if (    (t.type === '(number)' && !+t.value) ||
+                (t.type === '(string)' && !t.value) ||
+                t.type === 'true' || t.type === 'false' ||
+                t.type === 'undefined' || t.type === 'null') {
+            warning("Use '!==' to compare with '" + t.value + "'.", t);
+        }
+        return ['!=', left, parse(100)];
+    }, 100);
+    infix('!==', 'notequalexact', 100);
+    infix('<', 'less', 110);
+    infix('>', 'greater', 110);
+    infix('<=', 'lessequal', 110);
+    infix('>=', 'greaterequal', 110);
+    infix('<<', 'shiftleft', 120);
+    infix('>>', 'shiftright', 120);
+    infix('>>>', 'shiftrightunsigned', 120);
+    infix('in', 'in', 120);
+    infix('instanceof', 'instanceof', 120);
+    infix('+', 'addconcat', 130);
+    prefix('+', 'num');
+    infix('-', 'sub', 130);
+    prefix('-', 'neg');
+    infix('*', 'mult', 140);
+    infix('/', 'div', 140);
+    infix('%', 'mod', 140);
+
+    suffix('++', 'postinc');
+    prefix('++', 'preinc');
+    syntax['++'].exps = true;
+
+    suffix('--', 'postdec');
+    prefix('--', 'predec');
+    syntax['--'].exps = true;
+    prefixname('delete', function () {
+        parse(0);
+    }).exps = true;
+
+
+    prefix('~', 'bitnot');
+    prefix('!', 'not');
+    prefixname('typeof', 'typeof');
+    prefixname('new', function () {
+        var c = parse(155);
+        if (c) {
+            if (c.identifier) {
+                switch (c.value) {
+                case 'Object':
+                    warning('Use the object literal notation {}.', prevtoken);
+                    break;
+                case 'Array':
+                    warning('Use the array literal notation [].', prevtoken);
+                    break;
+                case 'Number':
+                case 'String':
+                case 'Boolean':
+                    warning("Do not use the " + c.value +
+                        " function as a constructor.", prevtoken);
+                    break;
+                case 'Function':
+                    if (!option.evil) {
+                        warning('The Function constructor is eval.');
+                    }
+                }
+            } else {
+                if (c.id !== '.' && c.id !== '[' && c.id !== '(') {
+                    warning('Bad constructor', prevtoken);
+                }
+            }
+        } else {
+            warning('Weird construction.', this);
+        }
+        if (token.id === '(') {
+            advance('(');
+            if (token.id !== ')') {
+                for (;;) {
+                    parse(10);
+                    if (token.id !== ',') {
+                        break;
+                    }
+                    advance(',');
+                }
+            }
+            advance(')');
+        } else {
+            warning("Missing '()' invoking a constructor.");
+        }
+        return syntax['function'];
+    });
+    syntax['new'].exps = true;
+
+    infix('.', function (left) {
+        var m = identifier();
+        if (typeof m === 'string') {
+            countMember(m);
+        }
+        if (!option.evil && left && left.value === 'document' &&
+                (m === 'write' || m === 'writeln')) {
+            warning("document.write can be a form of eval.", left);
+        }
+        this.left = left;
+        this.right = m;
+        return this;
+    }, 160);
+
+    infix('(', function (left) {
+        var n = 0, p = [];
+        if (token.id !== ')') {
+            for (;;) {
+                p[p.length] = parse(10);
+                n += 1;
+                if (token.id !== ',') {
+                    break;
+                }
+                advance(',');
+            }
+        }
+        advance(')');
+        if (typeof left === 'object') {
+            if (left.value == 'parseInt' && n == 1) {
+                warning("Missing radix parameter", left);
+            }
+            if (!option.evil) {
+                if (left.value == 'eval' || left.value == 'Function') {
+                    warning("eval is evil", left);
+                } else if (p[0] && p[0].id === '(string)' &&
+                       (left.value === 'setTimeout' ||
+                        left.value === 'setInterval')) {
+                    warning(
+    "Implied eval is evil. Use a function argument instead of a string", left);
+                }
+            }
+            if (!left.identifier && left.id !== '.' &&
+                    left.id !== '[' && left.id !== '(') {
+                warning('Bad invocation.', left);
+            }
+
+        }
+        return syntax['function'];
+    }, 155).exps = true;
+
+    prefix('(', function () {
+        parse(0);
+        advance(')', this);
+    });
+
+    infix('[', function (left) {
+        var e = parse(0);
+        if (e && e.type === '(string)') {
+            countMember(e.value);
+            if (ix.test(e.value)) {
+                var s = syntax[e.value];
+                if (!s || !s.reserved) {
+                    warning("This is better written in dot notation.", e);
+                }
+            }
+        }
+        advance(']', this);
+        this.left = left;
+        this.right = e;
+        return this;
+    }, 160);
+
+    prefix('[', function () {
+        if (token.id === ']') {
+            advance(']');
+            return;
+        }
+        for (;;) {
+            parse(10);
+            if (token.id === ',') {
+                advance(',');
+                if (token.id === ']' || token.id === ',') {
+                    warning('Extra comma.', prevtoken);
+                }
+            } else {
+                advance(']', this);
+                return;
+            }
+        }
+    }, 160);
+
+    (function (x) {
+        x.nud = function () {
+            var i;
+            if (token.id === '}') {
+                advance('}');
+                return;
+            }
+            for (;;) {
+                i = optionalidentifier(true);
+                if (!i && (token.id === '(string)' || token.id === '(number)')) {
+                    i = token.id;
+                    advance();
+                }
+                if (!i) {
+                    error("Expected an identifier and instead saw '" +
+                        token.value + "'.");
+                }
+                if (typeof i.value === 'string') {
+                    countMember(i.value);
+                }
+                advance(':');
+                parse(10);
+                if (token.id === ',') {
+                    advance(',');
+                    if (token.id === ',' || token.id === '}') {
+                        warning("Extra comma.");
+                    }
+                } else {
+                    advance('}', this);
+                    return;
+                }
+            }
+        };
+        x.fud = function () {
+            error(
+                "Expected to see a statement and instead saw a block.");
+        };
+    })(delim('{'));
+
+
+    function varstatement() {
+        for (;;) {
+            addlabel(identifier(), 'var');
+            if (token.id === '=') {
+                advance('=');
+                parse(20);
+            }
+            if (token.id === ',') {
+                advance(',');
+            } else {
+                return;
+            }
+        }
+    }
+
+
+    stmt('var', varstatement);
+
+
+    function functionparams() {
+        var t = token;
+        advance('(');
+        if (token.id === ')') {
+            advance(')');
+            return;
+        }
+        for (;;) {
+            addlabel(identifier(), 'parameter');
+            if (token.id === ',') {
+                advance(',');
+            } else {
+                advance(')', t);
+                return;
+            }
+        }
+    }
+
+
+    blockstmt('function', function () {
+        var i = identifier();
+        addlabel(i, 'var*');
+        beginfunction(i);
+        addlabel(i, 'function');
+        functionparams();
+        block();
+        endfunction();
+    });
+
+    prefixname('function', function () {
+        var i = optionalidentifier() || ('"' + anonname + '"');
+        beginfunction(i);
+        addlabel(i, 'function');
+        functionparams();
+        block();
+        endfunction();
+    });
+
+    blockstmt('if', function () {
+        var t = token;
+        advance('(');
+        parse(20);
+        advance(')', t);
+        block();
+        if (token.id === 'else') {
+            advance('else');
+            if (token.id === 'if' || token.id === 'switch') {
+                statement();
+            } else {
+                block();
+            }
+        }
+    });
+
+    blockstmt('try', function () {
+        var b;
+        block();
+        if (token.id === 'catch') {
+            advance('catch');
+            beginfunction('"catch"');
+            functionparams();
+            block();
+            endfunction();
+            b = true;
+        }
+        if (token.id === 'finally') {
+            advance('finally');
+            beginfunction('"finally"');
+            block();
+            endfunction();
+            return;
+        } else if (!b) {
+            error("Expected 'catch' or 'finally' and instead saw '" +
+                token.value + "'.");
+        }
+    });
+
+    blockstmt('while', function () {
+        var t= token;
+        advance('(');
+        parse(20);
+        advance(')', t);
+        block();
+    }).labelled = true;
+
+    reserve('with');
+
+    blockstmt('switch', function () {
+        var t = token;
+        advance('(');
+        var g = false;
+        parse(20);
+        advance(')', t);
+        t = token;
+        advance('{');
+        for (;;) {
+            switch (token.id) {
+            case 'case':
+                switch (verb) {
+                case 'break':
+                case 'case':
+                case 'continue':
+                case 'return':
+                case 'switch':
+                case 'throw':
+                    break;
+                default:
+                    warning(
+                        "Expected a 'break' statement before 'case'.",
+                        prevtoken);
+                }
+                advance('case');
+                parse(20);
+                g = true;
+                advance(':');
+                verb = 'case';
+                break;
+            case 'default':
+                switch (verb) {
+                case 'break':
+                case 'continue':
+                case 'return':
+                case 'throw':
+                    break;
+                default:
+                    warning(
+                        "Expected a 'break' statement before 'default'.",
+                        prevtoken);
+                }
+                advance('default');
+                g = true;
+                advance(':');
+                break;
+            case '}':
+                advance('}', t);
+                return;
+            default:
+                if (g) {
+                    statements();
+                } else {
+                    error("Expected to see 'case' and instead saw '" +
+                        token.value + "'.");
+                }
+            }
+        }
+    }).labelled = true;
+
+    stmt('debugger', function () {
+        if (!option.debug) {
+            warning("All debugger statements should be removed.");
+        }
+    });
+
+    stmt('do', function () {
+        block();
+        advance('while');
+        var t = token;
+        advance('(');
+        parse(20);
+        advance(')', t);
+    }).labelled = true;
+
+    blockstmt('for', function () {
+        var t = token;
+        advance('(');
+        if (peek(token.id === 'var' ? 1 : 0).id === 'in') {
+            if (token.id === 'var') {
+                advance('var');
+                addlabel(identifier(), 'var');
+            } else {
+                advance();
+            }
+            advance('in');
+            parse(20);
+            advance(')', t);
+            block();
+            return;
+        } else {
+            if (token.id != ';') {
+                if (token.id === 'var') {
+                    advance('var');
+                    varstatement();
+                } else {
+                    for (;;) {
+                        parse(0);
+                        if (token.id !== ',') {
+                            break;
+                        }
+                        advance(',');
+                    }
+                }
+            }
+            advance(';');
+            if (token.id != ';') {
+                parse(20);
+            }
+            advance(';');
+            if (token.id === ';') {
+                error("Expected to see ')' and instead saw ';'");
+            }
+            if (token.id != ')') {
+                for (;;) {
+                    parse(0);
+                    if (token.id !== ',') {
+                        break;
+                    }
+                    advance(',');
+                }
+            }
+            advance(')', t);
+            block();
+        }
+    }).labelled = true;
+
+
+    function nolinebreak(t) {
+        if (t.line !== token.line) {
+            warning("Statement broken badly.", t);
+        }
+    }
+
+
+    stmt('break', function () {
+        nolinebreak(this);
+        if (funlab[token.value] === 'live*') {
+            advance();
+        }
+        reachable('break');
+    });
+
+
+    stmt('continue', function () {
+        nolinebreak(this);
+        if (funlab[token.id] === 'live*') {
+            advance();
+        }
+        reachable('continue');
+    });
+
+
+    stmt('return', function () {
+        nolinebreak(this);
+        if (token.id != ';' && !token.reach) {
+            parse(20);
+        }
+        reachable('return');
+    });
+
+
+    stmt('throw', function () {
+        nolinebreak(this);
+        parse(20);
+        reachable('throw');
+    });
+
+
+//  Superfluous reserved words
+
+    reserve('abstract');
+    reserve('boolean');
+    reserve('byte');
+    reserve('char');
+    reserve('class');
+    reserve('const');
+    reserve('double');
+    reserve('enum');
+    reserve('export');
+    reserve('extends');
+    reserve('final');
+    reserve('float');
+    reserve('goto');
+    reserve('implements');
+    reserve('import');
+    reserve('int');
+    reserve('interface');
+    reserve('long');
+    reserve('native');
+    reserve('package');
+    reserve('private');
+    reserve('protected');
+    reserve('public');
+    reserve('short');
+    reserve('static');
+    reserve('super');
+    reserve('synchronized');
+    reserve('throws');
+    reserve('transient');
+    reserve('void');
+    reserve('volatile');
+
+
+// The actual jslint function itself.
+
+    var j = function (s, o) {
+        option = o;
+        if (!o) {
+            option = {};
+        }
+        jslint.errors = [];
+        globals = {};
+        functions = [];
+        xmode = false;
+        xtype = '';
+        stack = null;
+        funlab = {};
+        member = {};
+        funstack = [];
+        lookahead = [];
+        lex.init(s);
+
+        prevtoken = token = syntax['(begin)'];
+        try {
+            advance();
+            if (token.value.charAt(0) === '<') {
+                xml();
+            } else {
+                statements();
+                advance('(end)');
+            }
+        } catch (e) {
+            if (e) {
+                jslint.errors.push({
+                    reason: "JSLint error: " + e.description,
+                    line: token.line,
+                    character: token.from,
+                    evidence: token.value
+                });
+            }
+        }
+        return jslint.errors.length === 0;
+    };
+
+
+// Report generator.
+
+    j.report = function (option) {
+        var a = [], c, cc, f, i, k, o = [], s;
+
+        function detail(h) {
+            if (s.length) {
+                o.push('<div>' + h + ':&nbsp; ' + s.sort().join(', ') +
+                    '</div>');
+            }
+        }
+
+        k = jslint.errors.length;
+        if (k) {
+            o.push(
+                '<div style="background-color: mistyrose;">Error:<blockquote>');
+            for (i = 0; i < k; i += 1) {
+                c = jslint.errors[i];
+                if (c) {
+                    o.push('<p>Problem at line ' + (c.line + 1) +
+                        ' character ' + (c.character + 1) +
+                        ': ' + c.reason.entityify() +
+                        '</p><p><tt>' + c.evidence.entityify() +
+                        '</tt></p>');
+                }
+            }
+            o.push('</blockquote></div>');
+            if (!c) {
+                return o.join('');
+            }
+        }
+
+        if (!option) {
+            for (k in member) {
+                a.push(k);
+            }
+            if (a.length) {
+                a = a.sort();
+                o.push(
+                 '<table><tbody><tr><th>Members</th><th>Occurrences</th></tr>');
+                for (i = 0; i < a.length; i += 1) {
+                    o.push('<tr><td><tt>', a[i], '</tt></td><td>', member[a[i]],
+                        '</td></tr>');
+                }
+                o.push('</tbody></table>');
+            }
+            for (i = 0; i < functions.length; ++i) {
+                f = functions[i];
+                for (k in f) {
+                    if (f[k] === 'global') {
+                        c = f['(context)'];
+                        for (;;) {
+                            cc = c['(context)'];
+                            if (!cc) {
+                                if ((!funlab[k] || funlab[k] === 'var?') &&
+                                        !builtin(k)) {
+                                    funlab[k] = 'var?';
+                                    f[k] = 'global?';
+                                }
+                                break;
+                            }
+                            if (c[k] === 'parameter!' || c[k] === 'var!') {
+                                f[k] = 'var.';
+                                break;
+                            }
+                            if (c[k] === 'var' || c[k] === 'var*' ||
+                                    c[k] === 'var!') {
+                                f[k] = 'var.';
+                                c[k] = 'var!';
+                                break;
+                            }
+                            if (c[k] === 'parameter') {
+                                f[k] = 'var.';
+                                c[k] = 'parameter!';
+                                break;
+                            }
+                            c = cc;
+                        }
+                    }
+                }
+            }
+            s = [];
+            for (k in funlab) {
+                c = funlab[k];
+                if (typeof c === 'string' && c.substr(0, 3) === 'var') {
+                    if (c === 'var?') {
+                        s.push('<tt>' + k + '</tt><small>&nbsp;(?)</small>');
+                    } else {
+                        s.push('<tt>' + k + '</tt>');
+                    }
+                }
+            }
+            detail('Global');
+            if (functions.length) {
+                o.push('<br>Function:<ol style="padding-left:0.5in">');
+            }
+            for (i = 0; i < functions.length; i += 1) {
+                f = functions[i];
+                o.push('<li value=' +
+                    f['(line)'] + '><tt>' + (f['(name)'] || '') + '</tt>');
+                s = [];
+                for (k in f) {
+                    if (k.charAt(0) != '(') {
+                        switch (f[k]) {
+                        case 'parameter':
+                            s.push('<tt>' + k + '</tt>');
+                            break;
+                        case 'parameter!':
+                            s.push('<tt>' + k +
+                                '</tt><small>&nbsp;(closure)</small>');
+                            break;
+                        }
+                    }
+                }
+                detail('Parameter');
+                s = [];
+                for (k in f) {
+                    if (k.charAt(0) != '(') {
+                        switch(f[k]) {
+                        case 'var':
+                            s.push('<tt>' + k +
+                                '</tt><small>&nbsp;(unused)</small>');
+                            break;
+                        case 'var*':
+                            s.push('<tt>' + k + '</tt>');
+                            break;
+                        case 'var!':
+                            s.push('<tt>' + k +
+                                '</tt><small>&nbsp;(closure)</small>');
+                            break;
+                        case 'var.':
+                            s.push('<tt>' + k +
+                                '</tt><small>&nbsp;(outer)</small>');
+                            break;
+                        }
+                    }
+                }
+                detail('Var');
+                s = [];
+                c = f['(context)'];
+                for (k in f) {
+                    if (k.charAt(0) != '(' && f[k].substr(0, 6) === 'global') {
+                        if (f[k] === 'global?') {
+                            s.push('<tt>' + k + '</tt><small>&nbsp;(?)</small>');
+                        } else {
+                            s.push('<tt>' + k + '</tt>');
+                        }
+                    }
+                }
+                detail('Global');
+                s = [];
+                for (k in f) {
+                    if (k.charAt(0) != '(' && f[k] === 'label') {
+                       s.push(k);
+                    }
+                }
+                detail('Label');
+                o.push('</li>');
+            }
+            if (functions.length) {
+                o.push('</ol>');
+            }
+        }
+        return o.join('');
+    };
+
+    return j;
+
+}();
+
+/* ============================================================== */
+
+var options = {
+    "browser"    : false,
+    "cap"        : false,
+    "debug"      : false,
+    "evil"       : false,
+    "jscript"    : false,
+    "laxLineEnd" : false,
+    "passfail"   : false,
+    "plusplus"   : false,
+    "undef"      : false
+};
+
+function die(str) {
+    print("jslint:ERROR: " + str);
+    quit();
+}
+
+function usage() {
+    print("jslint:USAGE: jslint file.js");
+    quit();
+}
+
+var i;
+for (i = 0; i < arguments.length; i++) {
+    if (   arguments[i].substring(0, 1) != '-'
+        && arguments[i].substring(0, 1) != '+')
+        break;
+    if (options[arguments[i].substring(1)] == undefined)
+        die("invalid command line option \"" + arguments[i] + "\"");
+    options[arguments[i].substring(1)] =
+        (arguments[i].substring(0, 1) == "-" ? true : false);
+}
+if (arguments[i] == undefined) {
+    usage()
+}
+
+var file = new File(arguments[i]);
+file.open("read");
+var script = file.readAll();
+file.close();
+
+if (!jslint(script, { passfail: true })) {
+    var e = jslint.errors[0];
+    print('jslint: line ' + (e.line + 1) + ' character ' + (e.character + 1) + ': ' + e.reason);
+    print((e.evidence || ''). replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1"));
+    quit();
+}
+

Added: freeswitch/trunk/libs/js/libtool.m4
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/libtool.m4	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,6397 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
+## Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+##
+## This file is free software; the Free Software Foundation gives
+## unlimited permission to copy and/or distribute it, with or without
+## modifications, as long as this notice is preserved.
+
+# serial 48 AC_PROG_LIBTOOL
+
+
+# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
+# -----------------------------------------------------------
+# If this macro is not defined by Autoconf, define it here.
+m4_ifdef([AC_PROVIDE_IFELSE],
+         [],
+         [m4_define([AC_PROVIDE_IFELSE],
+	         [m4_ifdef([AC_PROVIDE_$1],
+		           [$2], [$3])])])
+
+
+# AC_PROG_LIBTOOL
+# ---------------
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl
+dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX
+dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX.
+  AC_PROVIDE_IFELSE([AC_PROG_CXX],
+    [AC_LIBTOOL_CXX],
+    [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX
+  ])])
+dnl And a similar setup for Fortran 77 support
+  AC_PROVIDE_IFELSE([AC_PROG_F77],
+    [AC_LIBTOOL_F77],
+    [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77
+])])
+
+dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly.
+dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run
+dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both.
+  AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+    [AC_LIBTOOL_GCJ],
+    [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+      [AC_LIBTOOL_GCJ],
+      [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],
+	[AC_LIBTOOL_GCJ],
+      [ifdef([AC_PROG_GCJ],
+	     [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+       ifdef([A][M_PROG_GCJ],
+	     [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+       ifdef([LT_AC_PROG_GCJ],
+	     [define([LT_AC_PROG_GCJ],
+		defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])])
+])])# AC_PROG_LIBTOOL
+
+
+# _AC_PROG_LIBTOOL
+# ----------------
+AC_DEFUN([_AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Prevent multiple expansion
+define([AC_PROG_LIBTOOL], [])
+])# _AC_PROG_LIBTOOL
+
+
+# AC_LIBTOOL_SETUP
+# ----------------
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+AC_LIBTOOL_SYS_MAX_CMD_LEN
+AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+AC_LIBTOOL_OBJDIR
+
+AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+_LT_AC_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g']
+
+# Same as above, but do not quote variable references.
+[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g']
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+AC_CHECK_TOOL(AR, ar, false)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$SED" && SED=sed
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    AC_PATH_MAGIC
+  fi
+  ;;
+esac
+
+AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+enable_win32_dll=yes, enable_win32_dll=no)
+
+AC_ARG_ENABLE([libtool-lock],
+    [AC_HELP_STRING([--disable-libtool-lock],
+	[avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+AC_ARG_WITH([pic],
+    [AC_HELP_STRING([--with-pic],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [pic_mode="$withval"],
+    [pic_mode=default])
+test -z "$pic_mode" && pic_mode=default
+
+# Use C for the default configuration in the libtool script
+tagname=
+AC_LIBTOOL_LANG_C_CONFIG
+_LT_AC_TAGCONFIG
+])# AC_LIBTOOL_SETUP
+
+
+# _LT_AC_SYS_COMPILER
+# -------------------
+AC_DEFUN([_LT_AC_SYS_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_AC_SYS_COMPILER
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+AC_DEFUN([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+])
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+AC_DEFUN([_LT_COMPILER_BOILERPLATE],
+[ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+AC_DEFUN([_LT_LINKER_BOILERPLATE],
+[ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+])# _LT_LINKER_BOILERPLATE
+
+
+# _LT_AC_SYS_LIBPATH_AIX
+# ----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX],
+[AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_AC_SYS_LIBPATH_AIX
+
+
+# _LT_AC_SHELL_INIT(ARG)
+# ----------------------
+AC_DEFUN([_LT_AC_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+	     [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+	 [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_AC_SHELL_INIT
+
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
+[_LT_AC_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X[$]1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+[$]*
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string=`eval $cmd`) 2>/dev/null &&
+       echo_test_string=`eval $cmd` &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    IFS="$lt_save_ifs"
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+	 test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+	 echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+	 test "X$echo_testing_string" = "X$echo_test_string"; then
+	# Cool, printf works
+	:
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	export CONFIG_SHELL
+	SHELL="$CONFIG_SHELL"
+	export SHELL
+	echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      else
+	# maybe with a smaller string...
+	prev=:
+
+	for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+	  if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+	  then
+	    break
+	  fi
+	  prev="$cmd"
+	done
+
+	if test "$prev" != 'sed 50q "[$]0"'; then
+	  echo_test_string=`eval $prev`
+	  export echo_test_string
+	  exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+	else
+	  # Oops.  We lost completely, so just stick with echo.
+	  echo=echo
+	fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(ECHO)
+])])# _LT_AC_PROG_ECHO_BACKSLASH
+
+
+# _LT_AC_LOCK
+# -----------
+AC_DEFUN([_LT_AC_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+    [AC_HELP_STRING([--disable-libtool-lock],
+	[avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *ELF-32*)
+      HPUX_IA64_MODE="32"
+      ;;
+    *ELF-64*)
+      HPUX_IA64_MODE="64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+   if test "$lt_cv_prog_gnu_ld" = yes; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -melf32bsmip"
+      ;;
+    *N32*)
+      LD="${LD-ld} -melf32bmipn32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -melf64bmip"
+      ;;
+    esac
+   else
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+   fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *32-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
+        ppc64-*linux*|powerpc64-*linux*)
+          LD="${LD-ld} -m elf32ppclinux"
+          ;;
+        s390x-*linux*)
+          LD="${LD-ld} -m elf_s390"
+          ;;
+        sparc64-*linux*)
+          LD="${LD-ld} -m elf32_sparc"
+          ;;
+      esac
+      ;;
+    *64-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        ppc*-*linux*|powerpc*-*linux*)
+          LD="${LD-ld} -m elf64ppc"
+          ;;
+        s390*-*linux*)
+          LD="${LD-ld} -m elf64_s390"
+          ;;
+        sparc*-*linux*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)    LD="${LD-ld} -64" ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+  ])
+esac
+
+need_locks="$enable_libtool_lock"
+
+])# _LT_AC_LOCK
+
+
+# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
+[AC_REQUIRE([LT_AC_PROG_SED])
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+  ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $rm conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    ifelse([$5], , :, [$5])
+else
+    ifelse([$6], , :, [$6])
+fi
+])# AC_LIBTOOL_COMPILER_OPTION
+
+
+# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                          [ACTION-SUCCESS], [ACTION-FAILURE])
+# ------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
+[AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    ifelse([$4], , :, [$4])
+else
+    ifelse([$5], , :, [$5])
+fi
+])# AC_LIBTOOL_LINKER_OPTION
+
+
+# AC_LIBTOOL_SYS_MAX_CMD_LEN
+# --------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN],
+[# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ 	]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    # If test is not a shell built-in, we'll probably end up computing a
+    # maximum length that is only half of the actual maximum length, but
+    # we can't tell.
+    SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+    while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \
+	       = "XX$teststring") >/dev/null 2>&1 &&
+	    new_result=`expr "X$teststring" : ".*" 2>&1` &&
+	    lt_cv_sys_max_cmd_len=$new_result &&
+	    test $i != 17 # 1/2 MB should be enough
+    do
+      i=`expr $i + 1`
+      teststring=$teststring$teststring
+    done
+    teststring=
+    # Add a significant safety factor because C++ compilers can tack on massive
+    # amounts of additional arguments before passing them to the linker.
+    # It appears as though 1/2 is a usable value.
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+])# AC_LIBTOOL_SYS_MAX_CMD_LEN
+
+
+# _LT_AC_CHECK_DLFCN
+# ------------------
+AC_DEFUN([_LT_AC_CHECK_DLFCN],
+[AC_CHECK_HEADERS(dlfcn.h)dnl
+])# _LT_AC_CHECK_DLFCN
+
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                           ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ---------------------------------------------------------------------
+AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+    exit (status);
+}]
+EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_AC_TRY_DLOPEN_SELF
+
+
+# AC_LIBTOOL_DLOPEN_SELF
+# ----------------------
+AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+   ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen="dlopen"],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_AC_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+    	  lt_cv_dlopen_self_static, [dnl
+	  _LT_AC_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+])# AC_LIBTOOL_DLOPEN_SELF
+
+
+# AC_LIBTOOL_PROG_CC_C_O([TAGNAME])
+# ---------------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler
+AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+])
+])# AC_LIBTOOL_PROG_CC_C_O
+
+
+# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME])
+# -----------------------------------------
+# Check to see if we can do hard links to lock some files if needed
+AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS],
+[AC_REQUIRE([_LT_AC_LOCK])dnl
+
+hard_links="nottested"
+if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS
+
+
+# AC_LIBTOOL_OBJDIR
+# -----------------
+AC_DEFUN([AC_LIBTOOL_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+])# AC_LIBTOOL_OBJDIR
+
+
+# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME])
+# ----------------------------------------------
+# Check hardcoding attributes.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_AC_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \
+   test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \
+   test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_AC_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_AC_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_AC_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH
+
+
+# AC_LIBTOOL_SYS_LIB_STRIP
+# ------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP],
+[striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         AC_MSG_RESULT([yes])
+       else
+  AC_MSG_RESULT([no])
+fi
+       ;;
+   *)
+  AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+])# AC_LIBTOOL_SYS_LIB_STRIP
+
+
+# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER],
+[AC_MSG_CHECKING([dynamic linker characteristics])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[123]]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  freebsd*) # from 4.6 on
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix3*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+])# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+
+
+# _LT_AC_TAGCONFIG
+# ----------------
+AC_DEFUN([_LT_AC_TAGCONFIG],
+[AC_ARG_WITH([tags],
+    [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@],
+        [include additional configurations @<:@automatic@:>@])],
+    [tagnames="$withval"])
+
+if test -f "$ltmain" && test -n "$tagnames"; then
+  if test ! -f "${ofile}"; then
+    AC_MSG_WARN([output file `$ofile' does not exist])
+  fi
+
+  if test -z "$LTCC"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+    if test -z "$LTCC"; then
+      AC_MSG_WARN([output file `$ofile' does not look like a libtool script])
+    else
+      AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
+    fi
+  fi
+  if test -z "$LTCFLAGS"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
+  fi
+
+  # Extract list of available tagged configurations in $ofile.
+  # Note that this assumes the entire list is on one line.
+  available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
+
+  lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+  for tagname in $tagnames; do
+    IFS="$lt_save_ifs"
+    # Check whether tagname contains only valid characters
+    case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in
+    "") ;;
+    *)  AC_MSG_ERROR([invalid tag name: $tagname])
+	;;
+    esac
+
+    if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
+    then
+      AC_MSG_ERROR([tag name \"$tagname\" already exists])
+    fi
+
+    # Update the list of available tags.
+    if test -n "$tagname"; then
+      echo appending configuration tag \"$tagname\" to $ofile
+
+      case $tagname in
+      CXX)
+	if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+	    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+	    (test "X$CXX" != "Xg++"))) ; then
+	  AC_LIBTOOL_LANG_CXX_CONFIG
+	else
+	  tagname=""
+	fi
+	;;
+
+      F77)
+	if test -n "$F77" && test "X$F77" != "Xno"; then
+	  AC_LIBTOOL_LANG_F77_CONFIG
+	else
+	  tagname=""
+	fi
+	;;
+
+      GCJ)
+	if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+	  AC_LIBTOOL_LANG_GCJ_CONFIG
+	else
+	  tagname=""
+	fi
+	;;
+
+      RC)
+	AC_LIBTOOL_LANG_RC_CONFIG
+	;;
+
+      *)
+	AC_MSG_ERROR([Unsupported tag name: $tagname])
+	;;
+      esac
+
+      # Append the new tag name to the list of available tags.
+      if test -n "$tagname" ; then
+      available_tags="$available_tags $tagname"
+    fi
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  # Now substitute the updated list of available tags.
+  if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
+    mv "${ofile}T" "$ofile"
+    chmod +x "$ofile"
+  else
+    rm -f "${ofile}T"
+    AC_MSG_ERROR([unable to update list of available tagged configurations.])
+  fi
+fi
+])# _LT_AC_TAGCONFIG
+
+
+# AC_LIBTOOL_DLOPEN
+# -----------------
+# enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN],
+ [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_DLOPEN
+
+
+# AC_LIBTOOL_WIN32_DLL
+# --------------------
+# declare package support for building win32 DLLs
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_WIN32_DLL
+
+
+# AC_ENABLE_SHARED([DEFAULT])
+# ---------------------------
+# implement the --enable-shared flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([shared],
+    [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]AC_ENABLE_SHARED_DEFAULT)
+])# AC_ENABLE_SHARED
+
+
+# AC_DISABLE_SHARED
+# -----------------
+# set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)
+])# AC_DISABLE_SHARED
+
+
+# AC_ENABLE_STATIC([DEFAULT])
+# ---------------------------
+# implement the --enable-static flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([static],
+    [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]AC_ENABLE_STATIC_DEFAULT)
+])# AC_ENABLE_STATIC
+
+
+# AC_DISABLE_STATIC
+# -----------------
+# set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)
+])# AC_DISABLE_STATIC
+
+
+# AC_ENABLE_FAST_INSTALL([DEFAULT])
+# ---------------------------------
+# implement the --enable-fast-install flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([fast-install],
+    [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT)
+])# AC_ENABLE_FAST_INSTALL
+
+
+# AC_DISABLE_FAST_INSTALL
+# -----------------------
+# set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)
+])# AC_DISABLE_FAST_INSTALL
+
+
+# AC_LIBTOOL_PICMODE([MODE])
+# --------------------------
+# implement the --with-pic flag
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)
+])# AC_LIBTOOL_PICMODE
+
+
+# AC_PROG_EGREP
+# -------------
+# This is predefined starting with Autoconf 2.54, so this conditional
+# definition can be removed once we require Autoconf 2.54 or later.
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP],
+[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
+   [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi])
+ EGREP=$ac_cv_prog_egrep
+ AC_SUBST([EGREP])
+])])
+
+
+# AC_PATH_TOOL_PREFIX
+# -------------------
+# find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="ifelse([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+])# AC_PATH_TOOL_PREFIX
+
+
+# AC_PATH_MAGIC
+# -------------
+# find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# AC_PATH_MAGIC
+
+
+# AC_PROG_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+    [AC_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])
+AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])# AC_PROG_LD
+
+
+# AC_PROG_LD_GNU
+# --------------
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# AC_PROG_LD_GNU
+
+
+# AC_PROG_LD_RELOAD_FLAG
+# ----------------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+])# AC_PROG_LD_RELOAD_FLAG
+
+
+# AC_DEPLIBS_CHECK_METHOD
+# -----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_CACHE_CHECK([how to recognise dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | kfreebsd*-gnu | dragonfly*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix3*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+nto-qnx*)
+  lt_cv_deplibs_check_method=unknown
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+])# AC_DEPLIBS_CHECK_METHOD
+
+
+# AC_PROG_NM
+# ----------
+# find the pathname to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then 
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+])# AC_PROG_NM
+
+
+# AC_CHECK_LIBM
+# -------------
+# check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+])# AC_CHECK_LIBM
+
+
+# AC_LIBLTDL_CONVENIENCE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl convenience library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-convenience to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
+# it is assumed to be `libltdl'.  LIBLTDL will be prefixed with
+# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/'
+# (note the single quotes!).  If your package is not flat and you're not
+# using automake, define top_builddir and top_srcdir appropriately in
+# the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case $enable_ltdl_convenience in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+  LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  # For backwards non-gettext consistent compatibility...
+  INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_CONVENIENCE
+
+
+# AC_LIBLTDL_INSTALLABLE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl installable library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-install to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
+# and an installed libltdl is not found, it is assumed to be `libltdl'.
+# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and top_srcdir
+# appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, lt_dlinit,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+    LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    LTDLINCL=
+  fi
+  # For backwards non-gettext consistent compatibility...
+  INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_INSTALLABLE
+
+
+# AC_LIBTOOL_CXX
+# --------------
+# enable support for C++ libraries
+AC_DEFUN([AC_LIBTOOL_CXX],
+[AC_REQUIRE([_LT_AC_LANG_CXX])
+])# AC_LIBTOOL_CXX
+
+
+# _LT_AC_LANG_CXX
+# ---------------
+AC_DEFUN([_LT_AC_LANG_CXX],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([_LT_AC_PROG_CXXCPP])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX])
+])# _LT_AC_LANG_CXX
+
+# _LT_AC_PROG_CXXCPP
+# ------------------
+AC_DEFUN([_LT_AC_PROG_CXXCPP],
+[
+AC_REQUIRE([AC_PROG_CXX])
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  AC_PROG_CXXCPP
+fi
+])# _LT_AC_PROG_CXXCPP
+
+# AC_LIBTOOL_F77
+# --------------
+# enable support for Fortran 77 libraries
+AC_DEFUN([AC_LIBTOOL_F77],
+[AC_REQUIRE([_LT_AC_LANG_F77])
+])# AC_LIBTOOL_F77
+
+
+# _LT_AC_LANG_F77
+# ---------------
+AC_DEFUN([_LT_AC_LANG_F77],
+[AC_REQUIRE([AC_PROG_F77])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77])
+])# _LT_AC_LANG_F77
+
+
+# AC_LIBTOOL_GCJ
+# --------------
+# enable support for GCJ libraries
+AC_DEFUN([AC_LIBTOOL_GCJ],
+[AC_REQUIRE([_LT_AC_LANG_GCJ])
+])# AC_LIBTOOL_GCJ
+
+
+# _LT_AC_LANG_GCJ
+# ---------------
+AC_DEFUN([_LT_AC_LANG_GCJ],
+[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[],
+    [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[],
+      [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])],
+	 [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])],
+	   [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ])
+])# _LT_AC_LANG_GCJ
+
+
+# AC_LIBTOOL_RC
+# -------------
+# enable support for Windows resource files
+AC_DEFUN([AC_LIBTOOL_RC],
+[AC_REQUIRE([LT_AC_PROG_RC])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC])
+])# AC_LIBTOOL_RC
+
+
+# AC_LIBTOOL_LANG_C_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG])
+AC_DEFUN([_LT_AC_LANG_C_CONFIG],
+[lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}\n'
+
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF
+
+# Report which library types will actually be built
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case $host_os in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+    ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_C_CONFIG
+
+
+# AC_LIBTOOL_LANG_CXX_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)])
+AC_DEFUN([_LT_AC_LANG_CXX_CONFIG],
+[AC_LANG_PUSH(C++)
+AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([_LT_AC_PROG_CXXCPP])
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Dependencies to place before and after the object being linked:
+_LT_AC_TAGVAR(predep_objects, $1)=
+_LT_AC_TAGVAR(postdep_objects, $1)=
+_LT_AC_TAGVAR(predeps, $1)=
+_LT_AC_TAGVAR(postdeps, $1)=
+_LT_AC_TAGVAR(compiler_lib_search_path, $1)=
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_LD=$LD
+lt_save_GCC=$GCC
+GCC=$GXX
+lt_save_with_gnu_ld=$with_gnu_ld
+lt_save_path_LD=$lt_cv_path_LD
+if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+  lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+else
+  $as_unset lt_cv_prog_gnu_ld
+fi
+if test -n "${lt_cv_path_LDCXX+set}"; then
+  lt_cv_path_LD=$lt_cv_path_LDCXX
+else
+  $as_unset lt_cv_path_LD
+fi
+test -z "${LDCXX+set}" || LD=$LDCXX
+CC=${CXX-"c++"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+
+# We don't want -fno-exception wen compiling C++ code, so set the
+# no_builtin_flag separately
+if test "$GXX" = yes; then
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+else
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+fi
+
+if test "$GXX" = yes; then
+  # Set up default GNU C++ configuration
+
+  AC_PROG_LD
+
+  # Check if GNU C++ uses GNU ld as the underlying linker, since the
+  # archiving commands below assume that GNU ld is being used.
+  if test "$with_gnu_ld" = yes; then
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+    #     investigate it a little bit more. (MM)
+    wlarc='${wl}'
+
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
+	grep 'no-whole-archive' > /dev/null; then
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    with_gnu_ld=no
+    wlarc=
+
+    # A generic and very simple default shared library creation
+    # command for GNU C++ for the case where it uses the native
+    # linker, instead of GNU ld.  If possible, this setting should
+    # overridden to take advantage of the native linker features on
+    # the platform it is being used on.
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+  fi
+
+  # Commands to make compiler produce verbose output that lists
+  # what "hidden" libraries, object files and flags are used when
+  # linking a shared library.
+  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+else
+  GXX=no
+  with_gnu_ld=no
+  wlarc=
+fi
+
+# PORTME: fill in a description of your system's C++ link characteristics
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+_LT_AC_TAGVAR(ld_shlibs, $1)=yes
+case $host_os in
+  aix3*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+	for ld_flag in $LDFLAGS; do
+	  case $ld_flag in
+	  *-brtl*)
+	    aix_use_runtimelinking=yes
+	    break
+	    ;;
+	  esac
+	done
+	;;
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    _LT_AC_TAGVAR(archive_cmds, $1)=''
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+    if test "$GXX" = yes; then
+      case $host_os in aix4.[[012]]|aix4.[[012]].*)
+      # We only want to do this on AIX 4.2 and lower, the check
+      # below for broken collect2 doesn't work under 4.3+
+	collect2name=`${CC} -print-prog-name=collect2`
+	if test -f "$collect2name" && \
+	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	then
+	  # We have reworked collect2
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+	else
+	  # We have old collect2
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+	fi
+	;;
+      esac
+      shared_flag='-shared'
+      if test "$aix_use_runtimelinking" = yes; then
+	shared_flag="$shared_flag "'${wl}-G'
+      fi
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	shared_flag='-G'
+      else
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag='${wl}-G'
+	else
+	  shared_flag='${wl}-bM:SRE'
+	fi
+      fi
+    fi
+
+    # It seems that -bexpall does not export symbols beginning with
+    # underscore (_), so it is better to generate a list of symbols to export.
+    _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+      # Determine the default libpath from the value encoded in an empty executable.
+      _LT_AC_SYS_LIBPATH_AIX
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+     else
+      if test "$host_cpu" = ia64; then
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+      else
+	# Determine the default libpath from the value encoded in an empty executable.
+	_LT_AC_SYS_LIBPATH_AIX
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	# Warning - without using the other run time loading flags,
+	# -berok will link without error, but may produce a broken library.
+	_LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	# Exported symbols can be pulled into shared objects from archives
+	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+	# This is similar to how AIX traditionally builds its shared libraries.
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+      fi
+    fi
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+    ;;
+
+  chorus*)
+    case $cc_basename in
+      *)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+    esac
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+    # as there is no search path for DLLs.
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+    _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+    _LT_AC_TAGVAR(always_export_symbols, $1)=no
+    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+    if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      # If the export-symbols file already is a .def file (1st line
+      # is EXPORTS), use it as is; otherwise, prepend...
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	cp $export_symbols $output_objdir/$soname.def;
+      else
+	echo EXPORTS > $output_objdir/$soname.def;
+	cat $export_symbols >> $output_objdir/$soname.def;
+      fi~
+      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+  ;;
+      darwin* | rhapsody*)
+        case $host_os in
+        rhapsody* | darwin1.[[012]])
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[[012]])
+               _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+        esac
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+    if test "$GXX" = yes ; then
+      lt_int_apple_cc_single_mod=no
+      output_verbose_link_cmd='echo'
+      if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then
+       lt_int_apple_cc_single_mod=yes
+      fi
+      if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      else
+          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+        fi
+        _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+        # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+          if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+            _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          else
+            _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          fi
+            _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+          _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+          ;;
+      esac
+      fi
+        ;;
+
+  dgux*)
+    case $cc_basename in
+      ec++*)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      ghcx*)
+	# Green Hills C++ Compiler
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+    esac
+    ;;
+  freebsd[[12]]*)
+    # C++ shared libraries reported to be fairly broken before switch to ELF
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  freebsd-elf*)
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    ;;
+  freebsd* | kfreebsd*-gnu | dragonfly*)
+    # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+    # conventions
+    _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+    ;;
+  gnu*)
+    ;;
+  hpux9*)
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				# but as the default
+				# location of the library.
+
+    case $cc_basename in
+    CC*)
+      # FIXME: insert proper C++ library support
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    aCC*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      #
+      # There doesn't appear to be a way to prevent this compiler from
+      # explicitly linking system object files so we need to strip them
+      # from the output so that they don't get included in the library
+      # dependencies.
+      output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+      ;;
+    *)
+      if test "$GXX" = yes; then
+        _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+        # FIXME: insert proper C++ library support
+        _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+    ;;
+  hpux10*|hpux11*)
+    if test $with_gnu_ld = no; then
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+      case $host_cpu in
+      hppa*64*|ia64*)
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+        ;;
+      *)
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        ;;
+      esac
+    fi
+    case $host_cpu in
+    hppa*64*|ia64*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+    *)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					      # but as the default
+					      # location of the library.
+      ;;
+    esac
+
+    case $cc_basename in
+      CC*)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      aCC*)
+	case $host_cpu in
+	hppa*64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  ;;
+	*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  ;;
+	esac
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes; then
+	  if test $with_gnu_ld = no; then
+	    case $host_cpu in
+	    hppa*64*)
+	      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      ;;
+	    ia64*)
+	      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      ;;
+	    *)
+	      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      ;;
+	    esac
+	  fi
+	else
+	  # FIXME: insert proper C++ library support
+	  _LT_AC_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+    esac
+    ;;
+  interix3*)
+    _LT_AC_TAGVAR(hardcode_direct, $1)=no
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+    # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+    # Instead, shared libraries are loaded at an image base (0x10000000 by
+    # default) and relocated if they conflict, which is a slow very memory
+    # consuming and fragmenting process.  To avoid this, we pick a random,
+    # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+    # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    ;;
+  irix5* | irix6*)
+    case $cc_basename in
+      CC*)
+	# SGI C++
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	# Archives containing C++ object files must be created using
+	# "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	# necessary to make sure instantiated templates are included
+	# in the archive.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	;;
+      *)
+	if test "$GXX" = yes; then
+	  if test "$with_gnu_ld" = no; then
+	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	  else
+	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+	  fi
+	fi
+	_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+	;;
+    esac
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+    ;;
+  linux*)
+    case $cc_basename in
+      KCC*)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	_LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir'
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+	# Archives containing C++ object files must be created using
+	# "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	;;
+      icpc*)
+	# Intel C++
+	with_gnu_ld=yes
+	# version 8.0 and above of icpc choke on multiply defined symbols
+	# if we add $predep_objects and $postdep_objects, however 7.1 and
+	# earlier do not add the objects themselves.
+	case `$CC -V 2>&1` in
+	*"Version 7."*)
+  	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+  	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  ;;
+	*)  # Version 8.0 or newer
+	  tmp_idyn=
+	  case $host_cpu in
+	    ia64*) tmp_idyn=' -i_dynamic';;
+	  esac
+  	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  ;;
+	esac
+	_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	;;
+      pgCC*)
+        # Portland Group C++ compiler
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+  	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+        ;;
+      cxx*)
+	# Compaq C++
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	runpath_var=LD_RUN_PATH
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+    esac
+    ;;
+  lynxos*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  m88k*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  mvs*)
+    case $cc_basename in
+      cxx*)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+    esac
+    ;;
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+      wlarc=
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    fi
+    # Workaround some broken pre-1.5 toolchains
+    output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+    ;;
+  openbsd2*)
+    # C++ shared libraries are fairly broken
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  openbsd*)
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+    if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    fi
+    output_verbose_link_cmd='echo'
+    ;;
+  osf3*)
+    case $cc_basename in
+      KCC*)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	_LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	# Archives containing C++ object files must be created using
+	# "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+
+	;;
+      RCC*)
+	# Rational C++ 2.4.1
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      cxx*)
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	  # Commands to make compiler produce verbose output that lists
+	  # what "hidden" libraries, object files and flags are used when
+	  # linking a shared library.
+	  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+	else
+	  # FIXME: insert proper C++ library support
+	  _LT_AC_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+    esac
+    ;;
+  osf4* | osf5*)
+    case $cc_basename in
+      KCC*)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	_LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	# Archives containing C++ object files must be created using
+	# the KAI C++ compiler.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs'
+	;;
+      RCC*)
+	# Rational C++ 2.4.1
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      cxx*)
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	  echo "-hidden">> $lib.exp~
+	  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp  `test -n "$verstring" && echo -set_version	$verstring` -update_registry ${output_objdir}/so_locations -o $lib~
+	  $rm $lib.exp'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	 _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	  # Commands to make compiler produce verbose output that lists
+	  # what "hidden" libraries, object files and flags are used when
+	  # linking a shared library.
+	  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+	else
+	  # FIXME: insert proper C++ library support
+	  _LT_AC_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+    esac
+    ;;
+  psos*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  sunos4*)
+    case $cc_basename in
+      CC*)
+	# Sun C++ 4.x
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      lcc*)
+	# Lucid
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+    esac
+    ;;
+  solaris*)
+    case $cc_basename in
+      CC*)
+	# Sun C++ 4.2, 5.x and Centerline C++
+        _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes
+	_LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	$CC -G${allow_undefined_flag}  ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+	case $host_os in
+	  solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	  *)
+	    # The C++ compiler is used as linker so we must use $wl
+	    # flag to pass the commands to the underlying system
+	    # linker. We must also pass each convience library through
+	    # to the system linker between allextract/defaultextract.
+	    # The C++ compiler will combine linker options so we
+	    # cannot just pass the convience library names through
+	    # without $wl.
+	    # Supported since Solaris 2.6 (maybe 2.5.1?)
+	    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract'
+	    ;;
+	esac
+	_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+	output_verbose_link_cmd='echo'
+
+	# Archives containing C++ object files must be created using
+	# "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	# necessary to make sure instantiated templates are included
+	# in the archive.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	;;
+      gcx*)
+	# Green Hills C++ Compiler
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	# The C++ compiler must be used to create the archive.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	;;
+      *)
+	# GNU C++ compiler with Solaris linker
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+	  if $CC --version | grep -v '^2\.7' > /dev/null; then
+	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+	  else
+	    # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	    # platform.
+	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+	  fi
+
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+	fi
+	;;
+    esac
+    ;;
+  sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+    _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      *)
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+    esac
+    ;;
+  sysv5* | sco3.2v5* | sco5v6*)
+    # Note: We can NOT use -z defs as we might desire, because we do not
+    # link with -lc, and that would cause any symbols used from libc to
+    # always be unresolved, which means just about no library would
+    # ever link correctly.  If we're not using GNU ld we use -z text
+    # though, which does catch some bad symbols but isn't as heavy-handed
+    # as -z defs.
+    # For security reasons, it is highly recommended that you always
+    # use absolute paths for naming shared libraries, and exclude the
+    # DT_RUNPATH tag from executables and libraries.  But doing so
+    # requires that you compile everything twice, which is a pain.
+    # So that behaviour is only enabled if SCOABSPATH is set to a
+    # non-empty value in the environment.  Most likely only useful for
+    # creating official distributions of packages.
+    # This is a hack until libtool officially supports absolute path
+    # names for shared libraries.
+    _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+    _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+      *)
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	;;
+    esac
+    ;;
+  tandem*)
+    case $cc_basename in
+      NCC*)
+	# NonStop-UX NCC 3.20
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+    esac
+    ;;
+  vxworks*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  *)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+esac
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_AC_TAGVAR(GCC, $1)="$GXX"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_POSTDEP_PREDEP($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC=$lt_save_CC
+LDCXX=$LD
+LD=$lt_save_LD
+GCC=$lt_save_GCC
+with_gnu_ldcxx=$with_gnu_ld
+with_gnu_ld=$lt_save_with_gnu_ld
+lt_cv_path_LDCXX=$lt_cv_path_LD
+lt_cv_path_LD=$lt_save_path_LD
+lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+])# AC_LIBTOOL_LANG_CXX_CONFIG
+
+# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
+# ------------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+ifelse([$1],[],[cat > conftest.$ac_ext <<EOF
+int a;
+void foo (void) { a = 0; }
+EOF
+],[$1],[CXX],[cat > conftest.$ac_ext <<EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+EOF
+],[$1],[F77],[cat > conftest.$ac_ext <<EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+EOF
+],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  # The `*' in the case matches for architectures that use `case' in
+  # $output_verbose_cmd can trigger glob expansion during the loop
+  # eval without this substitution.
+  output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
+
+  for p in `eval $output_verbose_link_cmd`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" \
+	  || test $p = "-R"; then
+	 prev=$p
+	 continue
+       else
+	 prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 case $p in
+	 -L* | -R*)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+	   else
+	     _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then
+	   _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}"
+	 else
+	   _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}"
+	 fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then
+	   _LT_AC_TAGVAR(predep_objects, $1)="$p"
+	 else
+	   _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then
+	   _LT_AC_TAGVAR(postdep_objects, $1)="$p"
+	 else
+	   _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$rm -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+ifelse([$1],[CXX],
+[case $host_os in
+interix3*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_AC_TAGVAR(predep_objects,$1)=
+  _LT_AC_TAGVAR(postdep_objects,$1)=
+  _LT_AC_TAGVAR(postdeps,$1)=
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun'
+    ;;
+  esac
+  ;;
+esac
+])
+
+case " $_LT_AC_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+])# AC_LIBTOOL_POSTDEP_PREDEP
+
+# AC_LIBTOOL_LANG_F77_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)])
+AC_DEFUN([_LT_AC_LANG_F77_CONFIG],
+[AC_REQUIRE([AC_PROG_F77])
+AC_LANG_PUSH(Fortran 77)
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="      subroutine t\n      return\n      end\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="      program t\n      end\n"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${F77-"f77"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case $host_os in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+_LT_AC_TAGVAR(GCC, $1)="$G77"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_F77_CONFIG
+
+
+# AC_LIBTOOL_LANG_GCJ_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)])
+AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_GCJ_CONFIG
+
+
+# AC_LIBTOOL_LANG_RC_CONFIG
+# -------------------------
+# Ensure that the configuration vars for the Windows resource compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)])
+AC_DEFUN([_LT_AC_LANG_RC_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${RC-"windres"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_RC_CONFIG
+
+
+# AC_LIBTOOL_CONFIG([TAGNAME])
+# ----------------------------
+# If TAGNAME is not passed, then create an initial libtool script
+# with a default configuration from the untagged config vars.  Otherwise
+# add code to config.status for appending the configuration named by
+# TAGNAME from the matching tagged config vars.
+AC_DEFUN([AC_LIBTOOL_CONFIG],
+[# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    _LT_AC_TAGVAR(compiler, $1) \
+    _LT_AC_TAGVAR(CC, $1) \
+    _LT_AC_TAGVAR(LD, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \
+    _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \
+    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \
+    _LT_AC_TAGVAR(old_archive_cmds, $1) \
+    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \
+    _LT_AC_TAGVAR(predep_objects, $1) \
+    _LT_AC_TAGVAR(postdep_objects, $1) \
+    _LT_AC_TAGVAR(predeps, $1) \
+    _LT_AC_TAGVAR(postdeps, $1) \
+    _LT_AC_TAGVAR(compiler_lib_search_path, $1) \
+    _LT_AC_TAGVAR(archive_cmds, $1) \
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1) \
+    _LT_AC_TAGVAR(postinstall_cmds, $1) \
+    _LT_AC_TAGVAR(postuninstall_cmds, $1) \
+    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \
+    _LT_AC_TAGVAR(allow_undefined_flag, $1) \
+    _LT_AC_TAGVAR(no_undefined_flag, $1) \
+    _LT_AC_TAGVAR(export_symbols_cmds, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \
+    _LT_AC_TAGVAR(hardcode_automatic, $1) \
+    _LT_AC_TAGVAR(module_cmds, $1) \
+    _LT_AC_TAGVAR(module_expsym_cmds, $1) \
+    _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \
+    _LT_AC_TAGVAR(exclude_expsyms, $1) \
+    _LT_AC_TAGVAR(include_expsyms, $1); do
+
+    case $var in
+    _LT_AC_TAGVAR(old_archive_cmds, $1) | \
+    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \
+    _LT_AC_TAGVAR(archive_cmds, $1) | \
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \
+    _LT_AC_TAGVAR(module_cmds, $1) | \
+    _LT_AC_TAGVAR(module_expsym_cmds, $1) | \
+    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \
+    _LT_AC_TAGVAR(export_symbols_cmds, $1) | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\[$]0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'`
+    ;;
+  esac
+
+ifelse([$1], [],
+  [cfgfile="${ofile}T"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  $rm -f "$cfgfile"
+  AC_MSG_NOTICE([creating $ofile])],
+  [cfgfile="$ofile"])
+
+  cat <<__EOF__ >> "$cfgfile"
+ifelse([$1], [],
+[#! $SHELL
+
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e 1s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# The names of the tagged configurations supported by this script.
+available_tags=
+
+# ### BEGIN LIBTOOL CONFIG],
+[# ### BEGIN LIBTOOL TAG CONFIG: $tagname])
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
+
+# Is the compiler the GNU C compiler?
+with_gcc=$_LT_AC_TAGVAR(GCC, $1)
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_[]_LT_AC_TAGVAR(LD, $1)
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1)
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1)
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1)
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1)
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1)
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1)
+archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1)
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1)
+module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1)
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1)
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1)
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1)
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1)
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1)
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1)
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1)
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1)
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1)
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1)
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1)
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1)
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1)
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1)
+
+# Symbols that must always be exported.
+include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1)
+
+ifelse([$1],[],
+[# ### END LIBTOOL CONFIG],
+[# ### END LIBTOOL TAG CONFIG: $tagname])
+
+__EOF__
+
+ifelse([$1],[], [
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "$cfgfile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" || \
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+])
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+])# AC_LIBTOOL_CONFIG
+
+
+# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+
+_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+  AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI
+
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_NM])
+AC_REQUIRE([AC_OBJEXT])
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+linux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDGIRSTW]]'
+    lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+    lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ 	]]\($symcode$symcode*\)[[ 	]][[ 	]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if grep ' nm_test_var$' "$nlist" >/dev/null; then
+	if grep ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
+
+	  cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[[]] =
+{
+EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
+	  cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_save_LIBS="$LIBS"
+	  lt_save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$lt_save_LIBS"
+	  CFLAGS="$lt_save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+
+# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME])
+# ---------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC],
+[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+ ifelse([$1],[CXX],[
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | os2* | pw32*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	;;
+      *)
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix4* | aix5*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+       darwin*)
+         # PIC is the default on this platform
+         # Common symbols not allowed in MH_DYLIB files
+         case $cc_basename in
+           xlc*)
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           ;;
+         esac
+       ;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | kfreebsd*-gnu | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux*)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  icpc* | ecpc*)
+	    # Intel C++
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC*)
+	    # Portland Group C++ compiler.
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+      darwin*)
+        # PIC is the default on this platform
+        # Common symbols not allowed in MH_DYLIB files
+       case $cc_basename in
+         xlc*)
+         _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
+         _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+         ;;
+       esac
+       ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    newsos6)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    linux*)
+      case $cc_basename in
+      icc* | ecc*)
+	_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works],
+    _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1),
+    [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\"
+AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
+])
+
+
+# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME])
+# ------------------------------------
+# See if the linker supports building shared libraries.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS],
+[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ifelse([$1],[CXX],[
+  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix4* | aix5*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+  ;;
+  cygwin* | mingw*)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+],[
+  runpath_var=
+  _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+  _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_AC_TAGVAR(archive_cmds, $1)=
+  _LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)=
+  _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+  _LT_AC_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_AC_TAGVAR(hardcode_direct, $1)=no
+  _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_AC_TAGVAR(hardcode_automatic, $1)=no
+  _LT_AC_TAGVAR(module_cmds, $1)=
+  _LT_AC_TAGVAR(module_expsym_cmds, $1)=
+  _LT_AC_TAGVAR(always_export_symbols, $1)=no
+  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_AC_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+  # Just being paranoid about ensuring that cc_basename is set.
+  _LT_CC_BASENAME([$compiler])
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+  	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>/dev/null` in
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+
+      # Samuel A. Falvo II <kc5tja at dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(always_export_symbols, $1)=no
+      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    interix3*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    linux*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	tmp_addflag=
+	case $cc_basename,$host_cpu in
+	pgcc*)				# Portland Group C compiler
+	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)		# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	esac
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+	if test $supports_anon_versioning = yes; then
+	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~
+  cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+  $echo "local: *; };" >> $output_objdir/$libname.ver~
+	  $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	fi
+      else
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) 
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+	    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+	  else
+	    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then
+      runpath_var=
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+	  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+	  for ld_flag in $LDFLAGS; do
+  	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+  	    aix_use_runtimelinking=yes
+  	    break
+  	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_AC_TAGVAR(archive_cmds, $1)=''
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" && \
+  	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	  then
+  	  # We have reworked collect2
+  	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+	  else
+  	  # We have old collect2
+  	  _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+  	  # It fails to find uninstalled libraries when the uninstalled
+  	  # path is not listed in the libpath.  Setting hardcode_minus_L
+  	  # to unsupported forces relinking
+  	  _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+  	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+  	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+  	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+  	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       _LT_AC_SYS_LIBPATH_AIX
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+	if test "$host_cpu" = ia64; then
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	  _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an empty executable.
+	 _LT_AC_SYS_LIBPATH_AIX
+	 _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      # see comment about different semantics on the GNU ld section
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    bsdi[[45]]*)
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true'
+      # FIXME: Should let the user specify the lib program.
+      _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
+      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    darwin* | rhapsody*)
+      case $host_os in
+        rhapsody* | darwin1.[[012]])
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[[012]])
+               _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+      esac
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+    if test "$GCC" = yes ; then
+    	output_verbose_link_cmd='echo'
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+          ;;
+      esac
+    fi
+      ;;
+
+    dgux*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    freebsd1*)
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu | dragonfly*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	_LT_AC_TAGVAR(hardcode_direct, $1)=yes
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=no
+	  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    openbsd*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      else
+       case $host_os in
+	 openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	   _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	   _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	   ;;
+	 *)
+	   _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	   _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	   ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+	$LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+	wlarc=''
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  	$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+ 	# The compiler driver will combine linker options so we
+ 	# cannot just pass the convience library names through
+ 	# without $wl, iff we do not link with $LD.
+ 	# Luckily, gcc supports the same syntax we need for Sun Studio.
+ 	# Supported since Solaris 2.6 (maybe 2.5.1?)
+ 	case $wlarc in
+ 	'')
+ 	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;;
+ 	*)
+ 	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+ 	esac ;;
+      esac
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_AC_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+  fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_AC_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+	pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1)
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+        if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
+        then
+	  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+        else
+	  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+        fi
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)])
+      ;;
+    esac
+  fi
+  ;;
+esac
+])# AC_LIBTOOL_PROG_LD_SHLIBS
+
+
+# _LT_AC_FILE_LTDLL_C
+# -------------------
+# Be careful that the start marker always follows a newline.
+AC_DEFUN([_LT_AC_FILE_LTDLL_C], [
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+])# _LT_AC_FILE_LTDLL_C
+
+
+# _LT_AC_TAGVAR(VARNAME, [TAGNAME])
+# ---------------------------------
+AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])])
+
+
+# old names
+AC_DEFUN([AM_PROG_LIBTOOL],   [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED],  [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC],  [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD],        [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM],        [AC_PROG_NM])
+
+# This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])
+
+AC_DEFUN([LT_AC_PROG_GCJ],
+[AC_CHECK_TOOL(GCJ, gcj, no)
+  test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+  AC_SUBST(GCJFLAGS)
+])
+
+AC_DEFUN([LT_AC_PROG_RC],
+[AC_CHECK_TOOL(RC, windres, no)
+])
+
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+# LT_AC_PROG_SED
+# --------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+AC_DEFUN([LT_AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_MSG_RESULT([$SED])
+])

Added: freeswitch/trunk/libs/js/ltmain.sh
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/ltmain.sh	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,6863 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun configure.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+basename="s,^.*/,,g"
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# The name of this program:
+progname=`echo "$progpath" | $SED $basename`
+modename="$progname"
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.5.22
+TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes.
+if test -n "${ZSH_VERSION+set}" ; then
+  setopt NO_GLOB_SUBST
+fi
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit $EXIT_SUCCESS
+fi
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  SP2NL='tr \040 \012'
+  NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  SP2NL='tr \100 \n'
+  NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  $echo "$modename: not configured to build any kind of library" 1>&2
+  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit $EXIT_FAILURE
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+duplicate_deps=no
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+#####################################
+# Shell function definitions:
+# This seems to be the best place for them
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+	# Failing that, at least try and use $RANDOM to avoid a race
+	my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+	save_mktempdir_umask=`umask`
+	umask 0077
+	$mkdir "$my_tmpdir"
+	umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || {
+        $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2
+	exit $EXIT_FAILURE
+      }
+    fi
+
+    $echo "X$my_tmpdir" | $Xsed
+}
+
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid ()
+{
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
+      $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+      win32_nmres=`eval $NM -f posix -A $1 | \
+	$SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $echo $win32_libid_type
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	case $arg in
+	  *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	CC_quoted="$CC_quoted $arg"
+      done
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	    # Double-quote args containing other shell metacharacters.
+	    case $arg in
+	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	      arg="\"$arg\""
+	      ;;
+	    esac
+	    CC_quoted="$CC_quoted $arg"
+	  done
+	    case "$@ " in
+	      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  $echo "$modename: unable to infer tagged configuration"
+	  $echo "$modename: specify a tag with \`--tag'" 1>&2
+	  exit $EXIT_FAILURE
+#        else
+#          $echo "$modename: using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+
+    $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)"
+    $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $?
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2
+      exit $EXIT_FAILURE
+    fi
+}
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+    my_status=""
+
+    $show "${rm}r $my_gentop"
+    $run ${rm}r "$my_gentop"
+    $show "$mkdir $my_gentop"
+    $run $mkdir "$my_gentop"
+    my_status=$?
+    if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then
+      exit $my_status
+    fi
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
+      my_xdir="$my_gentop/$my_xlib"
+
+      $show "${rm}r $my_xdir"
+      $run ${rm}r "$my_xdir"
+      $show "$mkdir $my_xdir"
+      $run $mkdir "$my_xdir"
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then
+	exit $exit_status
+      fi
+      case $host in
+      *-darwin*)
+	$show "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	if test -z "$run"; then
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'`
+	  darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null`
+	  if test -n "$darwin_arches"; then 
+	    darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    $show "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches ; do
+	      mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+	      cd "$darwin_curdir"
+	      $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+	    done # $darwin_arches
+      ## Okay now we have a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+	      lipo -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    ${rm}r unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd "$darwin_orig_dir"
+ 	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	fi # $run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+        ;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+    done
+    func_extract_archives_result="$my_oldobjs"
+}
+# End of Shell function definitions
+#####################################
+
+# Darwin sucks
+eval std_shrext=\"$shrext_cmds\"
+
+disable_libs=no
+
+# Parse our command line options once, thoroughly.
+while test "$#" -gt 0
+do
+  arg="$1"
+  shift
+
+  case $arg in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case $prev in
+    execute_dlfiles)
+      execute_dlfiles="$execute_dlfiles $arg"
+      ;;
+    tag)
+      tagname="$arg"
+      preserve_args="${preserve_args}=$arg"
+
+      # Check whether tagname contains only valid characters
+      case $tagname in
+      *[!-_A-Za-z0-9,/]*)
+	$echo "$progname: invalid tag name: $tagname" 1>&2
+	exit $EXIT_FAILURE
+	;;
+      esac
+
+      case $tagname in
+      CC)
+	# Don't test for the "default" C tag, as we know, it's there, but
+	# not specially marked.
+	;;
+      *)
+	if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then
+	  taglist="$taglist $tagname"
+	  # Evaluate the configuration.
+	  eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`"
+	else
+	  $echo "$progname: ignoring unknown tag $tagname" 1>&2
+	fi
+	;;
+      esac
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case $arg in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    $echo
+    $echo "Copyright (C) 2005  Free Software Foundation, Inc."
+    $echo "This is free software; see the source for copying conditions.  There is NO"
+    $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+    exit $?
+    ;;
+
+  --config)
+    ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath"
+    done
+    exit $?
+    ;;
+
+  --debug)
+    $echo "$progname: enabling shell trace mode"
+    set -x
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    $echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      $echo "enable shared libraries"
+    else
+      $echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      $echo "enable static libraries"
+    else
+      $echo "disable static libraries"
+    fi
+    exit $?
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --preserve-dup-deps) duplicate_deps="yes" ;;
+
+  --quiet | --silent)
+    show=:
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --tag)
+    prevopt="--tag"
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
+  --tag=*)
+    set tag "$optarg" ${1+"$@"}
+    shift
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit $EXIT_FAILURE
+fi
+
+case $disable_libs in
+no) 
+  ;;
+shared)
+  build_libtool_libs=no
+  build_old_libs=yes
+  ;;
+static)
+  build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+  ;;
+esac
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
+    $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2
+    case $nonopt in
+    *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
+      mode=link
+      for arg
+      do
+	case $arg in
+	-c)
+	   mode=compile
+	   break
+	   ;;
+	esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+	if test -n "$nonopt"; then
+	  $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+	else
+	  $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+	fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case $mode in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg="$arg"
+	arg_mode=normal
+	;;
+
+      target )
+	libobj="$arg"
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  if test -n "$libobj" ; then
+	    $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-static | -prefer-pic | -prefer-non-pic)
+	  later="$later $arg"
+	  continue
+	  ;;
+
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+ 	  for arg in $args; do
+	    IFS="$save_ifs"
+
+	    # Double-quote args containing other shell metacharacters.
+	    # Many Bourne shells cannot handle close brackets correctly
+	    # in scan sets, so we specify it separately.
+	    case $arg in
+	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	      arg="\"$arg\""
+	      ;;
+	    esac
+	    lastarg="$lastarg $arg"
+	  done
+	  IFS="$save_ifs"
+	  lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+
+	  # Add the arguments to base_compile.
+	  base_compile="$base_compile $lastarg"
+	  continue
+	  ;;
+
+	* )
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg="$srcfile"
+	  srcfile="$arg"
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      case $lastarg in
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, and some SunOS ksh mistreat backslash-escaping
+      # in scan sets (worked around with variable expansion),
+      # and furthermore cannot handle '|' '&' '(' ')' in scan sets 
+      # at all, so we specify them separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	lastarg="\"$lastarg\""
+	;;
+      esac
+
+      base_compile="$base_compile $lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      $echo "$modename: you must specify an argument for -Xcompile"
+      exit $EXIT_FAILURE
+      ;;
+    target)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *)
+      # Get the name of the library object.
+      [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSifmso]'
+    case $libobj in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.ii) xform=ii ;;
+    *.class) xform=class ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    *.java) xform=java ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case $libobj in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -static)
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
+    case $qlibobj in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	qlibobj="\"$qlibobj\"" ;;
+    esac
+    test "X$libobj" != "X$qlibobj" \
+	&& $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' 	&()|`$[]' \
+	&& $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
+    objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+    xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$xdir" = "X$obj"; then
+      xdir=
+    else
+      xdir=$xdir/
+    fi
+    lobj=${xdir}$objdir/$objname
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $run ln "$progpath" "$lockfile" 2>/dev/null; do
+	$show "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	$echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+      $echo "$srcfile" > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+    qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
+    case $qsrcfile in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+      qsrcfile="\"$qsrcfile\"" ;;
+    esac
+
+    $run $rm "$libobj" "${libobj}T"
+
+    # Create a libtool object file (analogous to a ".la" file),
+    # but don't create it if we're doing a dry run.
+    test -z "$run" && cat > ${libobj}T <<EOF
+# $libobj - a libtool object file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+EOF
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
+
+      if test ! -d "${xdir}$objdir"; then
+	$show "$mkdir ${xdir}$objdir"
+	$run $mkdir ${xdir}$objdir
+	exit_status=$?
+	if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then
+	  exit $exit_status
+	fi
+      fi
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	command="$command -o $lobj"
+      fi
+
+      $run $rm "$lobj" "$output_obj"
+
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	test -n "$output_obj" && $run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	$show "$mv $output_obj $lobj"
+	if $run $mv $output_obj $lobj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Append the name of the PIC object to the libtool object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object='$objdir/$objname'
+
+EOF
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+        suppress_output=' >/dev/null 2>&1'
+      fi
+    else
+      # No PIC object so indicate it doesn't exist in the libtool
+      # object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object=none
+
+EOF
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	command="$command -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$obj" "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	$show "$mv $output_obj $obj"
+	if $run $mv $output_obj $obj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object='$objname'
+
+EOF
+    else
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object=none
+
+EOF
+    fi
+
+    $run $mv "${libobj}T" "${libobj}"
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $run $rm "$lockfile"
+    fi
+
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool link mode
+  link | relink)
+    modename="$modename: link"
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args="$nonopt"
+    base_compile="$nonopt $@"
+    compile_command="$nonopt"
+    finalize_command="$nonopt"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    notinst_path= # paths that contain not-installed libtool libraries
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -all-static | -static)
+	if test "X$arg" = "X-all-static"; then
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	else
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	fi
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
+	;;
+      *) qarg=$arg ;;
+      esac
+      libtool_args="$libtool_args $qarg"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  compile_command="$compile_command @OUTPUT@"
+	  finalize_command="$finalize_command @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    compile_command="$compile_command @SYMFILE@"
+	    finalize_command="$finalize_command @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      dlfiles="$dlfiles $arg"
+	    else
+	      dlprefiles="$dlprefiles $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  if test ! -f "$arg"; then
+	    $echo "$modename: symbol file \`$arg' does not exist"
+	    exit $EXIT_FAILURE
+	  fi
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat $save_arg`
+	    do
+#	      moreargs="$moreargs $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		# If there is no directory component, then add one.
+		case $arg in
+		*/* | *\\*) . $arg ;;
+		*) . ./$arg ;;
+		esac
+
+		if test -z "$pic_object" || \
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none && \
+		   test "$non_pic_object" = none; then
+		  $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+		  exit $EXIT_FAILURE
+		fi
+
+		# Extract subdirectory from the argument.
+		xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+		if test "X$xdir" = "X$arg"; then
+		  xdir=
+		else
+		  xdir="$xdir/"
+		fi
+
+		if test "$pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object="$xdir$pic_object"
+
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		      dlfiles="$dlfiles $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test "$prev" = dlprefiles; then
+		    # Preload the old-style object.
+		    dlprefiles="$dlprefiles $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  libobjs="$libobjs $pic_object"
+		  arg="$pic_object"
+		fi
+
+		# Non-PIC object.
+		if test "$non_pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object="$xdir$non_pic_object"
+
+		  # A standard non-PIC object
+		  non_pic_objects="$non_pic_objects $non_pic_object"
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object="$pic_object"
+		  non_pic_objects="$non_pic_objects $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if test -z "$run"; then
+		  $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+		  exit $EXIT_FAILURE
+		else
+		  # Dry-run case.
+
+		  # Extract subdirectory from the argument.
+		  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+		  if test "X$xdir" = "X$arg"; then
+		    xdir=
+		  else
+		    xdir="$xdir/"
+		  fi
+
+		  pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+		  non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+		  libobjs="$libobjs $pic_object"
+		  non_pic_objects="$non_pic_objects $non_pic_object"
+		fi
+	      fi
+	    done
+	  else
+	    $echo "$modename: link input file \`$save_arg' does not exist"
+	    exit $EXIT_FAILURE
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    $echo "$modename: only absolute run-paths are allowed" 1>&2
+	    exit $EXIT_FAILURE
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) rpath="$rpath $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) xrpath="$xrpath $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	xcompiler)
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  compile_command="$compile_command $qarg"
+	  finalize_command="$finalize_command $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $wl$qarg"
+	  prev=
+	  compile_command="$compile_command $wl$qarg"
+	  finalize_command="$finalize_command $wl$qarg"
+	  continue
+	  ;;
+	xcclinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  compile_command="$compile_command $qarg"
+	  finalize_command="$finalize_command $qarg"
+	  continue
+	  ;;
+	shrext)
+  	  shrext_cmds="$arg"
+	  prev=
+	  continue
+	  ;;
+	darwin_framework|darwin_framework_skip)
+	  test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg"
+	  compile_command="$compile_command $arg"
+	  finalize_command="$finalize_command $arg"
+	  prev=
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  compile_command="$compile_command $link_static_flag"
+	  finalize_command="$finalize_command $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+	continue
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  $echo "$modename: more than one -exported-symbols argument is not allowed"
+	  exit $EXIT_FAILURE
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework|-arch|-isysroot)
+	case " $CC " in
+	  *" ${arg} ${1} "* | *" ${arg}	${1} "*) 
+		prev=darwin_framework_skip ;;
+	  *) compiler_flags="$compiler_flags $arg"
+	     prev=darwin_framework ;;
+	esac
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  compile_command="$compile_command $arg"
+	  finalize_command="$finalize_command $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  if test -z "$absdir"; then
+	    $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+	    absdir="$dir"
+	    notinst_path="$notinst_path $dir"
+	  fi
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "*) ;;
+	*)
+	  deplibs="$deplibs -L$dir"
+	  lib_search_path="$lib_search_path $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    deplibs="$deplibs -framework System"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  esac
+	elif test "X$arg" = "X-lc_r"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	deplibs="$deplibs $arg"
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      -model)
+	compile_command="$compile_command $arg"
+	compiler_flags="$compiler_flags $arg"
+	finalize_command="$finalize_command $arg"
+	prev=xcompiler
+	continue
+	;;
+
+     -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+	compiler_flags="$compiler_flags $arg"
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+      # -r[0-9][0-9]* specifies the processor on the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+      # +DA*, +DD* enable 64-bit mode on the HP compiler
+      # -q* pass through compiler args for the IBM compiler
+      # -m* pass through architecture-specific compiler args for GCC
+      # -m*, -t[45]*, -txscale* pass through architecture-specific
+      # compiler args for GCC
+      # -pg pass through profiling flag for GCC
+      # @file GCC response files
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \
+      -t[45]*|-txscale*|@*)
+
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+        compile_command="$compile_command $arg"
+        finalize_command="$finalize_command $arg"
+        compiler_flags="$compiler_flags $arg"
+        continue
+        ;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # in order for the loader to find any dlls it needs.
+	  $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
+	  $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  $echo "$modename: only absolute run-paths are allowed" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) xrpath="$xrpath $dir" ;;
+	esac
+	continue
+	;;
+
+      -static)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -Wc,*)
+	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+	  case $flag in
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	    flag="\"$flag\""
+	    ;;
+	  esac
+	  arg="$arg $wl$flag"
+	  compiler_flags="$compiler_flags $flag"
+	done
+	IFS="$save_ifs"
+	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+	;;
+
+      -Wl,*)
+	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+	  case $flag in
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	    flag="\"$flag\""
+	    ;;
+	  esac
+	  arg="$arg $wl$flag"
+	  compiler_flags="$compiler_flags $wl$flag"
+	  linker_flags="$linker_flags $flag"
+	done
+	IFS="$save_ifs"
+	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # Some other compiler flag.
+      -* | +*)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+
+      *.$objext)
+	# A standard object.
+	objs="$objs $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  # If there is no directory component, then add one.
+	  case $arg in
+	  */* | *\\*) . $arg ;;
+	  *) . ./$arg ;;
+	  esac
+
+	  if test -z "$pic_object" || \
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none && \
+	     test "$non_pic_object" = none; then
+	    $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+	  if test "X$xdir" = "X$arg"; then
+	    xdir=
+ 	  else
+	    xdir="$xdir/"
+	  fi
+
+	  if test "$pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    pic_object="$xdir$pic_object"
+
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		dlfiles="$dlfiles $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test "$prev" = dlprefiles; then
+	      # Preload the old-style object.
+	      dlprefiles="$dlprefiles $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    libobjs="$libobjs $pic_object"
+	    arg="$pic_object"
+	  fi
+
+	  # Non-PIC object.
+	  if test "$non_pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object="$xdir$non_pic_object"
+
+	    # A standard non-PIC object
+	    non_pic_objects="$non_pic_objects $non_pic_object"
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object="$pic_object"
+	    non_pic_objects="$non_pic_objects $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if test -z "$run"; then
+	    $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+	    exit $EXIT_FAILURE
+	  else
+	    # Dry-run case.
+
+	    # Extract subdirectory from the argument.
+	    xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+	    if test "X$xdir" = "X$arg"; then
+	      xdir=
+	    else
+	      xdir="$xdir/"
+	    fi
+
+	    pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+	    non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+	    libobjs="$libobjs $pic_object"
+	    non_pic_objects="$non_pic_objects $non_pic_object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	deplibs="$deplibs $arg"
+	old_deplibs="$old_deplibs $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  dlfiles="$dlfiles $arg"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  dlprefiles="$dlprefiles $arg"
+	  prev=
+	else
+	  deplibs="$deplibs $arg"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+      fi
+    done # argument parsing loop
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$output_objdir" = "X$output"; then
+      output_objdir="$objdir"
+    else
+      output_objdir="$output_objdir/$objdir"
+    fi
+    # Create the object directory.
+    if test ! -d "$output_objdir"; then
+      $show "$mkdir $output_objdir"
+      $run $mkdir $output_objdir
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then
+	exit $exit_status
+      fi
+    fi
+
+    # Determine the type of output
+    case $output in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    case $host in
+    *cygwin* | *mingw* | *pw32*)
+      # don't eliminate duplications in $postdeps and $predeps
+      duplicate_compiler_generated_deps=yes
+      ;;
+    *)
+      duplicate_compiler_generated_deps=$duplicate_deps
+      ;;
+    esac
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if test "X$duplicate_deps" = "Xyes" ; then
+	case "$libs " in
+	*" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	esac
+      fi
+      libs="$libs $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+	  esac
+	  pre_post_deps="$pre_post_deps $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    case $linkmode in
+    lib)
+	passes="conv link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
+	    exit $EXIT_FAILURE
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+    for pass in $passes; do
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
+	deplibs=
+      fi
+      if test "$linkmode" = prog; then
+	case $pass in
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+	esac
+      fi
+      if test "$pass" = dlopen; then
+	# Collect dlpreopened libraries
+	save_deplibs="$deplibs"
+	deplibs=
+      fi
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    compiler_flags="$compiler_flags $deplib"
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
+	    continue
+	  fi
+	  name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
+	  for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib="$searchdir/lib${name}${search_ext}"
+	      if test -f "$lib"; then
+		if test "$search_ext" = ".la"; then
+		  found=yes
+		else
+		  found=no
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if (${SED} -e '2q' $lib |
+                    grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+		  library_names=
+		  old_library=
+		  case $lib in
+		  */* | *\\*) . $lib ;;
+		  *) . ./$lib ;;
+		  esac
+		  for l in $old_library $library_names; do
+		    ll="$l"
+		  done
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
+		    ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+		    test "X$ladir" = "X$lib" && ladir="."
+		    lib=$ladir/$old_library
+		    if test "$linkmode,$pass" = "prog,link"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+	        ;;
+	      *) ;;
+	      esac
+	    fi
+	  fi
+	  ;; # -l
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+	    ;;
+	  prog)
+	    if test "$pass" = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test "$pass" = scan; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+	    ;;
+	  *)
+	    $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) xrpath="$xrpath $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la) lib="$deplib" ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    valid_a_lib=no
+	    case $deplibs_check_method in
+	      match_pattern*)
+		set dummy $deplibs_check_method
+	        match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+		if eval $echo \"$deplib\" 2>/dev/null \
+		    | $SED 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		  valid_a_lib=yes
+		fi
+		;;
+	      pass_all)
+		valid_a_lib=yes
+		;;
+            esac
+	    if test "$valid_a_lib" != yes; then
+	      $echo
+	      $echo "*** Warning: Trying to link with static lib archive $deplib."
+	      $echo "*** I have the capability to make that library automatically link in when"
+	      $echo "*** you link to this library.  But I can only do this if you have a"
+	      $echo "*** shared version of the library, which you do not appear to have"
+	      $echo "*** because the file extensions .$libext of this argument makes me believe"
+	      $echo "*** that it is just a static archive that I should not used here."
+	    else
+	      $echo
+	      $echo "*** Warning: Linking the shared library $output against the"
+	      $echo "*** static library $deplib is not portable!"
+	      deplibs="$deplib $deplibs"
+	    fi
+	    continue
+	    ;;
+	  prog)
+	    if test "$pass" != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      newdlprefiles="$newdlprefiles $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      newdlfiles="$newdlfiles $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# Check to see that this really is a libtool archive.
+	if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$ladir" = "X$lib" && ladir="."
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	case $lib in
+	*/* | *\\*) . $lib ;;
+	*) . ./$lib ;;
+	esac
+
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+	  test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+	fi
+
+	if test "$pass" = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+	      exit $EXIT_FAILURE
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    convenience="$convenience $ladir/$objdir/$old_library"
+	    old_convenience="$old_convenience $ladir/$objdir/$old_library"
+	    tmp_libs=
+	    for deplib in $dependency_libs; do
+	      deplibs="$deplib $deplibs"
+              if test "X$duplicate_deps" = "Xyes" ; then
+	        case "$tmp_libs " in
+	        *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	        esac
+              fi
+	      tmp_libs="$tmp_libs $deplib"
+	    done
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    $echo "$modename: \`$lib' is not a convenience library" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	for l in $old_library $library_names; do
+	  linklib="$l"
+	done
+	if test -z "$linklib"; then
+	  $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  if test -z "$dlname" ||
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    dlprefiles="$dlprefiles $lib $dependency_libs"
+	  else
+	    newdlfiles="$newdlfiles $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
+	    $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    $echo "$modename: warning: library \`$lib' was moved." 1>&2
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$libdir"
+	    absdir="$libdir"
+	  fi
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    # Remove this search path later
+	    notinst_path="$notinst_path $abs_ladir"
+	  else
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
+	    # Remove this search path later
+	    notinst_path="$notinst_path $abs_ladir"
+	  fi
+	fi # $installed = yes
+	name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir"; then
+	    $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	  # Prefer using a static library (so that no silly _DYNAMIC symbols
+	  # are required to link).
+	  if test -n "$old_library"; then
+	    newdlprefiles="$newdlprefiles $dir/$old_library"
+	  # Otherwise, use the dlname, so that lt_dlopen finds it.
+	  elif test -n "$dlname"; then
+	    newdlprefiles="$newdlprefiles $dir/$dlname"
+	  else
+	    newdlprefiles="$newdlprefiles $dir/$linklib"
+	  fi
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test "$linkmode" = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test "$linkmode" = prog && test "$pass" != link; then
+	  newlib_search_path="$newlib_search_path $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test "$linkalldeplibs" = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if test "X$duplicate_deps" = "Xyes" ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test "$linkmode,$pass" = "prog,link"; then
+	  if test -n "$library_names" &&
+	     { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+	      # Make sure the rpath contains only unique directories.
+	      case "$temp_rpath " in
+	      *" $dir "*) ;;
+	      *" $absdir "*) ;;
+	      *) temp_rpath="$temp_rpath $absdir" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test "$use_static_libs" = built && test "$installed" = yes ; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
+	  if test "$installed" = no; then
+	    notinst_deplibs="$notinst_deplibs $lib"
+	    need_relink=yes
+	  fi
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on
+	  # some systems (darwin)
+	  if test "$shouldnotlink" = yes && test "$pass" = link ; then
+	    $echo
+	    if test "$linkmode" = prog; then
+	      $echo "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $echo "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $echo "*** $linklib is not portable!"
+	  fi
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    realname="$2"
+	    shift; shift
+	    libname=`eval \\$echo \"$libname_spec\"`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw*)
+		major=`expr $current - $age`
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
+	    newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      $show "extracting exported symbol list from \`$soname'"
+	      save_ifs="$IFS"; IFS='~'
+	      cmds=$extract_expsyms_cmds
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		eval cmd=\"$cmd\"
+		$show "$cmd"
+		$run eval "$cmd" || exit $?
+	      done
+	      IFS="$save_ifs"
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      $show "generating import library for \`$soname'"
+	      save_ifs="$IFS"; IFS='~'
+	      cmds=$old_archive_from_expsyms_cmds
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		eval cmd=\"$cmd\"
+		$show "$cmd"
+		$run eval "$cmd" || exit $?
+	      done
+	      IFS="$save_ifs"
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test "$linkmode" = prog || test "$mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir="-L$dir" ;;
+		  *-*-darwin* )
+		    # if the lib is a module then we can not link against
+		    # it, someone is ignoring the new warnings I added
+		    if /usr/bin/file -L $add 2> /dev/null |
+                      $EGREP ": [^:]* bundle" >/dev/null ; then
+		      $echo "** Warning, lib $linklib is a module, not a shared library"
+		      if test -z "$old_library" ; then
+		        $echo
+		        $echo "** And there doesn't seem to be a static archive available"
+		        $echo "** The link will probably fail, sorry"
+		      else
+		        add="$dir/$old_library"
+		      fi
+		    fi
+		esac
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$dir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      add_dir="$add_dir -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      $echo "$modename: configuration error: unsupported hardcode properties"
+	      exit $EXIT_FAILURE
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes && \
+		 test "$hardcode_minus_L" != yes && \
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+	        add="$inst_prefix_dir$libdir/$linklib"
+	      else
+	        add="$libdir/$linklib"
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    add_dir="$add_dir -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add="-l$name"
+	    fi
+
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test "$linkmode" = prog; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    $echo
+	    $echo "*** Warning: This system can not link to static lib archive $lib."
+	    $echo "*** I have the capability to make that library automatically link in when"
+	    $echo "*** you link to this library.  But I can only do this if you have a"
+	    $echo "*** shared version of the library, which you do not appear to have."
+	    if test "$module" = yes; then
+	      $echo "*** But as you try to build a module library, libtool will still create "
+	      $echo "*** a static module, that should work as long as the dlopening application"
+	      $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		$echo
+		$echo "*** However, this would only work if libtool was able to extract symbol"
+		$echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+		$echo "*** not find such a program.  So, this module is probably useless."
+		$echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test "$build_old_libs" = no; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test "$linkmode" = lib; then
+	  if test -n "$dependency_libs" &&
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) xrpath="$xrpath $temp_xrpath";;
+		   esac;;
+	      *) temp_deplibs="$temp_deplibs $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  fi
+
+	  newlib_search_path="$newlib_search_path $absdir"
+	  # Link against this library
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    if test "X$duplicate_deps" = "Xyes" ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done
+
+	  if test "$link_all_deplibs" != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+		dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
+		test "X$dir" = "X$deplib" && dir="."
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if grep "^installed=no" $deplib > /dev/null; then
+		  path="$absdir/$objdir"
+		else
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  if test -z "$libdir"; then
+		    $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+		    exit $EXIT_FAILURE
+		  fi
+		  if test "$absdir" != "$libdir"; then
+		    $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
+		  fi
+		  path="$absdir"
+		fi
+		depdepl=
+		case $host in
+		*-*-darwin*)
+		  # we do not want to link against static libs,
+		  # but need to link against shared
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$path/$depdepl" ; then
+		      depdepl="$path/$depdepl"
+		    fi
+		    # do not add paths which are already there
+		    case " $newlib_search_path " in
+		    *" $path "*) ;;
+		    *) newlib_search_path="$newlib_search_path $path";;
+		    esac
+		  fi
+		  path=""
+		  ;;
+		*)
+		  path="-L$path"
+		  ;;
+		esac
+		;;
+	      -l*)
+		case $host in
+		*-*-darwin*)
+		  # Again, we only want to link against shared libraries
+		  eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
+		  for tmp in $newlib_search_path ; do
+		    if test -f "$tmp/lib$tmp_libs.dylib" ; then
+		      eval depdepl="$tmp/lib$tmp_libs.dylib"
+		      break
+		    fi
+		  done
+		  path=""
+		  ;;
+		*) continue ;;
+		esac
+		;;
+	      *) continue ;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	      case " $deplibs " in
+	      *" $depdepl "*) ;;
+	      *) deplibs="$depdepl $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) lib_search_path="$lib_search_path $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	fi
+
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
+	else
+	  vars="compile_deplibs finalize_deplibs"
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) tmp_libs="$tmp_libs $deplib" ;;
+	      esac
+	      ;;
+	    *) tmp_libs="$tmp_libs $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=""
+	  ;;
+	esac
+	if test -n "$i" ; then
+	  tmp_libs="$tmp_libs $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$deplibs"; then
+	$echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	$echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      objs="$objs$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	if test "$module" = no; then
+	  $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
+	  exit $EXIT_FAILURE
+	else
+	  $echo
+	  $echo "*** Warning: Linking the shared library $output against the non-libtool"
+	  $echo "*** objects $objs is not portable!"
+	  libobjs="$libobjs $objs"
+	fi
+      fi
+
+      if test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test "$#" -gt 2; then
+	$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a `.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	if test -n "$vinfo"; then
+	  $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
+	fi
+
+	if test -n "$release"; then
+	  $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+	fi
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	IFS="$save_ifs"
+
+	if test -n "$8"; then
+	  $echo "$modename: too many parameters to \`-version-info'" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+
+	case $vinfo_number in
+	yes)
+	  number_major="$2"
+	  number_minor="$3"
+	  number_revision="$4"
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # which has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  darwin|linux|osf|windows)
+	    current=`expr $number_major + $number_minor`
+	    age="$number_minor"
+	    revision="$number_revision"
+	    ;;
+	  freebsd-aout|freebsd-elf|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
+	    ;;
+	  irix|nonstopux)
+	    current=`expr $number_major + $number_minor - 1`
+	    age="$number_minor"
+	    revision="$number_minor"
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current="$2"
+	  revision="$3"
+	  age="$4"
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+
+	case $revision in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+
+	case $age in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  major=.`expr $current - $age`
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  minor_current=`expr $current + 1`
+	  verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current";
+	  ;;
+
+	irix | nonstopux)
+	  major=`expr $current - $age + 1`
+
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring="$verstring_prefix$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test "$loop" -ne 0; do
+	    iface=`expr $revision - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="$verstring_prefix$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux)
+	  major=.`expr $current - $age`
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  major=.`expr $current - $age`
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test "$loop" -ne 0; do
+	    iface=`expr $current - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  verstring="$verstring:${current}.0"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  major=`expr $current - $age`
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  $echo "$modename: unknown library version type \`$version_type'" 1>&2
+	  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring="0.0"
+	    ;;
+	  esac
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+      fi
+
+      if test "$mode" != relink; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$echo "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
+	         if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+	         then
+		   continue
+		 fi
+	       fi
+	       removelist="$removelist $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	if test -n "$removelist"; then
+	  $show "${rm}r $removelist"
+	  $run ${rm}r $removelist
+	fi
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      for path in $notinst_path; do
+	lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
+	deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
+	dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
+      done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  temp_xrpath="$temp_xrpath -R$libdir"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) dlfiles="$dlfiles $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) dlprefiles="$dlprefiles $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    deplibs="$deplibs -framework System"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
+ 	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test "$build_libtool_need_lc" = "yes"; then
+	      deplibs="$deplibs -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $rm conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $rm conftest
+	  $LTCC $LTCFLAGS -o conftest conftest.c $deplibs
+	  if test "$?" -eq 0 ; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      name=`expr $i : '-l\(.*\)'`
+	      # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" -ne "0"; then
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    newdeplibs="$newdeplibs $i"
+		    i=""
+		    ;;
+		  esac
+	        fi
+		if test -n "$i" ; then
+		  libname=`eval \\$echo \"$libname_spec\"`
+		  deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		  set dummy $deplib_matches
+		  deplib_match=$2
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    newdeplibs="$newdeplibs $i"
+		  else
+		    droppeddeps=yes
+		    $echo
+		    $echo "*** Warning: dynamic linker does not accept needed library $i."
+		    $echo "*** I have the capability to make that library automatically link in when"
+		    $echo "*** you link to this library.  But I can only do this if you have a"
+		    $echo "*** shared version of the library, which I believe you do not have"
+		    $echo "*** because a test_compile did reveal that the linker did not use it for"
+		    $echo "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      name=`expr $i : '-l\(.*\)'`
+	      # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" != "0"; then
+		$rm conftest
+		$LTCC $LTCFLAGS -o conftest conftest.c $i
+		# Did it work?
+		if test "$?" -eq 0 ; then
+		  ldd_output=`ldd conftest`
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      newdeplibs="$newdeplibs $i"
+		      i=""
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i" ; then
+		    libname=`eval \\$echo \"$libname_spec\"`
+		    deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		    set dummy $deplib_matches
+		    deplib_match=$2
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		      newdeplibs="$newdeplibs $i"
+		    else
+		      droppeddeps=yes
+		      $echo
+		      $echo "*** Warning: dynamic linker does not accept needed library $i."
+		      $echo "*** I have the capability to make that library automatically link in when"
+		      $echo "*** you link to this library.  But I can only do this if you have a"
+		      $echo "*** shared version of the library, which you do not appear to have"
+		      $echo "*** because a test_compile did reveal that the linker did not use this one"
+		      $echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  $echo
+		  $echo "*** Warning!  Library $i is needed by this library but I was not able to"
+		  $echo "***  make it link in!  You will probably need to install it or some"
+		  $echo "*** library that it depends on before this library will be fully"
+		  $echo "*** functional.  Installing it before continuing would be even better."
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method
+	  file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    name=`expr $a_deplib : '-l\(.*\)'`
+	    # If $name is empty we are operating on a -L argument.
+            if test "$name" != "" && test  "$name" != "0"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  newdeplibs="$newdeplibs $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval \\$echo \"$libname_spec\"`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null \
+			 | grep " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+			 | ${SED} 10q \
+			 | $EGREP "$file_magic_regex" > /dev/null; then
+			newdeplibs="$newdeplibs $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		$echo
+		$echo "*** Warning: linker path does not have real file for library $a_deplib."
+		$echo "*** I have the capability to make that library automatically link in when"
+		$echo "*** you link to this library.  But I can only do this if you have a"
+		$echo "*** shared version of the library, which you do not appear to have"
+		$echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $echo "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $echo "*** with $libname and none of the candidates passed a file format test"
+		  $echo "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	    else
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	    fi
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    name=`expr $a_deplib : '-l\(.*\)'`
+	    # If $name is empty we are operating on a -L argument.
+	    if test -n "$name" && test "$name" != "0"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  newdeplibs="$newdeplibs $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval \\$echo \"$libname_spec\"`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
+		    if eval $echo \"$potent_lib\" 2>/dev/null \
+		        | ${SED} 10q \
+		        | $EGREP "$match_pattern_regex" > /dev/null; then
+		      newdeplibs="$newdeplibs $a_deplib"
+		      a_deplib=""
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		$echo
+		$echo "*** Warning: linker path does not have real file for library $a_deplib."
+		$echo "*** I have the capability to make that library automatically link in when"
+		$echo "*** you link to this library.  But I can only do this if you have a"
+		$echo "*** shared version of the library, which you do not appear to have"
+		$echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $echo "*** with $libname and none of the candidates passed a file format test"
+		  $echo "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	    else
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	    fi
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+	    -e 's/ -[LR][^ ]*//g'`
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
+	    done
+	  fi
+	  if $echo "X $tmp_deplibs" | $Xsed -e 's/[ 	]//g' \
+	    | grep . >/dev/null; then
+	    $echo
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      $echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      $echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    $echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	  fi
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library is the System framework
+	  newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	  ;;
+	esac
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    $echo
+	    $echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    $echo "*** dependencies of module $libname.  Therefore, libtool will create"
+	    $echo "*** a static module, that should work as long as the dlopening"
+	    $echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      $echo
+	      $echo "*** However, this would only work if libtool was able to extract symbol"
+	      $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      $echo "*** not find such a program.  So, this module is probably useless."
+	      $echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    $echo "*** The inter-library dependencies that have been dropped here will be"
+	    $echo "*** automatically added whenever a program is linked with this library"
+	    $echo "*** or is declared to -dlopen it."
+
+	    if test "$allow_undefined" = no; then
+	      $echo
+	      $echo "*** Since this library must not contain undefined symbols,"
+	      $echo "*** because either the platform does not support them or"
+	      $echo "*** it was explicitly requested with -no-undefined,"
+	      $echo "*** libtool will only create a static version of it."
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    new_libs="$new_libs -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) new_libs="$new_libs $deplib" ;;
+	  esac
+	  ;;
+	*) new_libs="$new_libs $deplib" ;;
+	esac
+      done
+      deplibs="$new_libs"
+
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	if test "$hardcode_into_libs" = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$mode" != relink && rpath="$compile_rpath$rpath"
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs="$libdir"
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		dep_rpath="$dep_rpath $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) perm_rpath="$perm_rpath $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir="$hardcode_libdirs"
+	    if test -n "$hardcode_libdir_flag_spec_ld"; then
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+	    else
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+	    fi
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      rpath="$rpath$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath="$finalize_shlibpath"
+	test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext_cmds\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	realname="$2"
+	shift; shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
+	fi
+
+	lib="$output_objdir/$realname"
+	linknames=
+	for link
+	do
+	  linknames="$linknames $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    $show "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $run $rm $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      eval cmd=\"$cmd\"
+	      if len=`expr "X$cmd" : ".*"` &&
+	       test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	        $show "$cmd"
+	        $run eval "$cmd" || exit $?
+	        skipped_export=false
+	      else
+	        # The command line is too long to execute in one step.
+	        $show "using reloadable object file for export list..."
+	        skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
+	      fi
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex"; then
+	      $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+	      $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+	      $run eval '$mv "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+		case " $convenience " in
+		*" $test_deplib "*) ;;
+		*)
+			tmp_deplibs="$tmp_deplibs $test_deplib"
+			;;
+		esac
+	done
+	deplibs="$tmp_deplibs"
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    generated="$generated $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    libobjs="$libobjs $func_extract_archives_result"
+	  fi
+	fi
+	
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  linker_flags="$linker_flags $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test "$mode" = relink; then
+	  $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
+	fi
+
+	# Do each of the archive commands.
+	if test "$module" = yes && test -n "$module_cmds" ; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval test_cmds=\"$module_expsym_cmds\"
+	    cmds=$module_expsym_cmds
+	  else
+	    eval test_cmds=\"$module_cmds\"
+	    cmds=$module_cmds
+	  fi
+	else
+	if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	  eval test_cmds=\"$archive_expsym_cmds\"
+	  cmds=$archive_expsym_cmds
+	else
+	  eval test_cmds=\"$archive_cmds\"
+	  cmds=$archive_cmds
+	  fi
+	fi
+
+	if test "X$skipped_export" != "X:" &&
+	   len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+	   test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise.
+	  $echo "creating reloadable object files..."
+
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+	  output_la=`$echo "X$output" | $Xsed -e "$basename"`
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  delfiles=
+	  last_robj=
+	  k=1
+	  output=$output_objdir/$output_la-${k}.$objext
+	  # Loop over the list of objects to be linked.
+	  for obj in $save_libobjs
+	  do
+	    eval test_cmds=\"$reload_cmds $objlist $last_robj\"
+	    if test "X$objlist" = X ||
+	       { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+		 test "$len" -le "$max_cmd_len"; }; then
+	      objlist="$objlist $obj"
+	    else
+	      # The command $test_cmds is almost too long, add a
+	      # command to the queue.
+	      if test "$k" -eq 1 ; then
+		# The first file doesn't have a previous command to add.
+		eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+	      else
+		# All subsequent reloadable object files will link in
+		# the last one created.
+		eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
+	      fi
+	      last_robj=$output_objdir/$output_la-${k}.$objext
+	      k=`expr $k + 1`
+	      output=$output_objdir/$output_la-${k}.$objext
+	      objlist=$obj
+	      len=1
+	    fi
+	  done
+	  # Handle the remaining objects by creating one last
+	  # reloadable object file.  All subsequent reloadable object
+	  # files will link in the last one created.
+	  test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	  eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+
+	  if ${skipped_export-false}; then
+	    $show "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $run $rm $export_symbols
+	    libobjs=$output
+	    # Append the command to create the export file.
+	    eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
+          fi
+
+	  # Set up a command to remove the reloadable object files
+	  # after they are used.
+	  i=0
+	  while test "$i" -lt "$k"
+	  do
+	    i=`expr $i + 1`
+	    delfiles="$delfiles $output_objdir/$output_la-${i}.$objext"
+	  done
+
+	  $echo "creating a temporary reloadable object file: $output"
+
+	  # Loop through the commands generated above and execute them.
+	  save_ifs="$IFS"; IFS='~'
+	  for cmd in $concat_cmds; do
+	    IFS="$save_ifs"
+	    $show "$cmd"
+	    $run eval "$cmd" || exit $?
+	  done
+	  IFS="$save_ifs"
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test "$module" = yes && test -n "$module_cmds" ; then
+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	      cmds=$module_expsym_cmds
+	    else
+	      cmds=$module_cmds
+	    fi
+	  else
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    cmds=$archive_expsym_cmds
+	  else
+	    cmds=$archive_cmds
+	    fi
+	  fi
+
+	  # Append the command to remove the reloadable object files
+	  # to the just-reset $cmds.
+	  eval cmds=\"\$cmds~\$rm $delfiles\"
+	fi
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $show "$cmd"
+	  $run eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test "$mode" = relink; then
+	      $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+	    fi
+
+	    exit $lt_exit
+	  }
+	done
+	IFS="$save_ifs"
+
+	# Restore the uninstalled library and exit
+	if test "$mode" = relink; then
+	  $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      $show "${rm}r $gentop"
+	      $run ${rm}r "$gentop"
+	    fi
+	  fi
+
+	  exit $EXIT_SUCCESS
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+	    $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$deplibs"; then
+	$echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case $output in
+      *.lo)
+	if test -n "$objs$old_deplibs"; then
+	  $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+	libobj="$output"
+	obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec
+      wl=
+
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+	else
+	  gentop="$output_objdir/${obj}x"
+	  generated="$generated $gentop"
+
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      cmds=$reload_cmds
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	eval cmd=\"$cmd\"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  $show "${rm}r $gentop"
+	  $run ${rm}r $gentop
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  $show "${rm}r $gentop"
+	  $run ${rm}r $gentop
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $run eval "echo timestamp > $libobj" || exit $?
+	exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	cmds=$reload_cmds
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $show "$cmd"
+	  $run eval "$cmd" || exit $?
+	done
+	IFS="$save_ifs"
+      fi
+
+      if test -n "$gentop"; then
+	$show "${rm}r $gentop"
+	$run ${rm}r $gentop
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
+      esac
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+	if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
+	   test "$dlopen_self_static" = unknown; then
+	  $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+	fi
+      fi
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	;;
+      esac
+
+      case $host in
+      *darwin*)
+        # Don't allow lazy linking, it breaks C++ global constructors
+        if test "$tagname" = CXX ; then
+        compile_command="$compile_command ${wl}-bind_at_load"
+        finalize_command="$finalize_command ${wl}-bind_at_load"
+        fi
+        ;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    new_libs="$new_libs -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) new_libs="$new_libs $deplib" ;;
+	  esac
+	  ;;
+	*) new_libs="$new_libs $deplib" ;;
+	esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      compile_command="$compile_command $compile_deplibs"
+      finalize_command="$finalize_command $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) perm_rpath="$perm_rpath $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$testbindir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	  dlsyms="${outputname}S.c"
+	else
+	  $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+	fi
+      fi
+
+      if test -n "$dlsyms"; then
+	case $dlsyms in
+	"") ;;
+	*.c)
+	  # Discover the nlist of each of the dlfiles.
+	  nlist="$output_objdir/${outputname}.nm"
+
+	  $show "$rm $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Parse the name list into a source file.
+	  $show "creating $output_objdir/$dlsyms"
+
+	  test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+	  if test "$dlself" = yes; then
+	    $show "generating symbol list for \`$output'"
+
+	    test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+	    # Add our own program objects to the symbol list.
+	    progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	    for arg in $progfiles; do
+	      $show "extracting global C symbols from \`$arg'"
+	      $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	    done
+
+	    if test -n "$exclude_expsyms"; then
+	      $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+
+	    if test -n "$export_symbols_regex"; then
+	      $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+
+	    # Prepare the list of exported symbols
+	    if test -z "$export_symbols"; then
+	      export_symbols="$output_objdir/$outputname.exp"
+	      $run $rm $export_symbols
+	      $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+              case $host in
+              *cygwin* | *mingw* )
+	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+		$run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+                ;;
+              esac
+	    else
+	      $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      $run eval 'mv "$nlist"T "$nlist"'
+              case $host in
+              *cygwin* | *mingw* )
+	        $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+		$run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+                ;;
+              esac
+	    fi
+	  fi
+
+	  for arg in $dlprefiles; do
+	    $show "extracting global C symbols from \`$arg'"
+	    name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
+	    $run eval '$echo ": $name " >> "$nlist"'
+	    $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -z "$run"; then
+	    # Make sure we have at least an empty file.
+	    test -f "$nlist" || : > "$nlist"
+
+	    if test -n "$exclude_expsyms"; then
+	      $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	      $mv "$nlist"T "$nlist"
+	    fi
+
+	    # Try sorting and uniquifying the output.
+	    if grep -v "^: " < "$nlist" |
+		if sort -k 3 </dev/null >/dev/null 2>&1; then
+		  sort -k 3
+		else
+		  sort +2
+		fi |
+		uniq > "$nlist"S; then
+	      :
+	    else
+	      grep -v "^: " < "$nlist" > "$nlist"S
+	    fi
+
+	    if test -f "$nlist"S; then
+	      eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+	    else
+	      $echo '/* NONE */' >> "$output_objdir/$dlsyms"
+	    fi
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+"
+
+	    case $host in
+	    *cygwin* | *mingw* )
+	  $echo >> "$output_objdir/$dlsyms" "\
+/* DATA imports from DLLs on WIN32 can't be const, because
+   runtime relocations are performed -- see ld's documentation
+   on pseudo-relocs */
+struct {
+"
+	      ;;
+	    * )
+	  $echo >> "$output_objdir/$dlsyms" "\
+const struct {
+"
+	      ;;
+	    esac
+
+
+	  $echo >> "$output_objdir/$dlsyms" "\
+  const char *name;
+  lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	  fi
+
+	  pic_flag_for_symtable=
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    case "$compile_command " in
+	    *" -static "*) ;;
+	    *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
+	    esac;;
+	  *-*-hpux*)
+	    case "$compile_command " in
+	    *" -static "*) ;;
+	    *) pic_flag_for_symtable=" $pic_flag";;
+	    esac
+	  esac
+
+	  # Now compile the dynamic symbol file.
+	  $show "(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+	  $run eval '(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+	  # Clean up the generated files.
+	  $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Transform the symbol file into the correct name.
+          case $host in
+          *cygwin* | *mingw* )
+            if test -f "$output_objdir/${outputname}.def" ; then
+              compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
+              finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
+            else
+              compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+              finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+             fi
+            ;;
+          * )
+            compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+            finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+            ;;
+          esac
+	  ;;
+	*)
+	  $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+      else
+	# We keep going just in case the user didn't refer to
+	# lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+	# really was required.
+
+	# Nullify the symbol file.
+	compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+	finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+	# Replace the output file specification.
+	compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	$show "$link_command"
+	$run eval "$link_command"
+	exit_status=$?
+
+	# Delete the generated files.
+	if test -n "$dlsyms"; then
+	  $show "$rm $output_objdir/${outputname}S.${objext}"
+	  $run $rm "$output_objdir/${outputname}S.${objext}"
+	fi
+
+	exit $exit_status
+      fi
+
+      if test -n "$shlibpath_var"; then
+	# We should set the shlibpath_var
+	rpath=
+	for dir in $temp_rpath; do
+	  case $dir in
+	  [\\/]* | [A-Za-z]:[\\/]*)
+	    # Absolute path.
+	    rpath="$rpath$dir:"
+	    ;;
+	  *)
+	    # Relative path: add a thisdir entry.
+	    rpath="$rpath\$thisdir/$dir:"
+	    ;;
+	  esac
+	done
+	temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$no_install" = yes; then
+	# We don't need to create a wrapper script.
+	link_command="$compile_var$compile_command$compile_rpath"
+	# Replace the output file specification.
+	link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$run $rm $output
+	# Link the executable and exit
+	$show "$link_command"
+	$run eval "$link_command" || exit $?
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+	$echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+	$echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+	    relink_command="$var=\"$var_value\"; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then
+	case $progpath in
+	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+	*) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
+	esac
+	qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+	qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+            output_name=`basename $output`
+            output_path=`dirname $output`
+            cwrappersource="$output_path/$objdir/lt-$output_name.c"
+            cwrapper="$output_path/$output_name.exe"
+            $rm $cwrappersource $cwrapper
+            trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+	    cat > $cwrappersource <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+
+   Currently, it simply execs the wrapper *script* "/bin/sh $output",
+   but could eventually absorb all of the scripts functionality and
+   exec $objdir/$outputname directly.
+*/
+EOF
+	    cat >> $cwrappersource<<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+        (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+/* -DDEBUG is fairly common in CFLAGS.  */
+#undef DEBUG
+#if defined DEBUGWRAPPER
+# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
+#else
+# define DEBUG(format, ...)
+#endif
+
+const char *program_name = NULL;
+
+void * xmalloc (size_t num);
+char * xstrdup (const char *string);
+const char * base_name (const char *name);
+char * find_executable(const char *wrapper);
+int    check_executable(const char *path);
+char * strendzap(char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  DEBUG("(main) argv[0]      : %s\n",argv[0]);
+  DEBUG("(main) program_name : %s\n",program_name);
+  newargz = XMALLOC(char *, argc+2);
+EOF
+
+            cat >> $cwrappersource <<EOF
+  newargz[0] = (char *) xstrdup("$SHELL");
+EOF
+
+            cat >> $cwrappersource <<"EOF"
+  newargz[1] = find_executable(argv[0]);
+  if (newargz[1] == NULL)
+    lt_fatal("Couldn't find %s", argv[0]);
+  DEBUG("(main) found exe at : %s\n",newargz[1]);
+  /* we know the script has the same name, without the .exe */
+  /* so make sure newargz[1] doesn't end in .exe */
+  strendzap(newargz[1],".exe");
+  for (i = 1; i < argc; i++)
+    newargz[i+1] = xstrdup(argv[i]);
+  newargz[argc+1] = NULL;
+
+  for (i=0; i<argc+1; i++)
+  {
+    DEBUG("(main) newargz[%d]   : %s\n",i,newargz[i]);
+    ;
+  }
+
+EOF
+
+            case $host_os in
+              mingw*)
+                cat >> $cwrappersource <<EOF
+  execv("$SHELL",(char const **)newargz);
+EOF
+              ;;
+              *)
+                cat >> $cwrappersource <<EOF
+  execv("$SHELL",newargz);
+EOF
+              ;;
+            esac
+
+            cat >> $cwrappersource <<"EOF"
+  return 127;
+}
+
+void *
+xmalloc (size_t num)
+{
+  void * p = (void *) malloc (num);
+  if (!p)
+    lt_fatal ("Memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
+;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char)name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable(const char * path)
+{
+  struct stat st;
+
+  DEBUG("(check_executable)  : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0) &&
+      (
+        /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
+#if defined (S_IXOTH)
+       ((st.st_mode & S_IXOTH) == S_IXOTH) ||
+#endif
+#if defined (S_IXGRP)
+       ((st.st_mode & S_IXGRP) == S_IXGRP) ||
+#endif
+       ((st.st_mode & S_IXUSR) == S_IXUSR))
+      )
+    return 1;
+  else
+    return 0;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise */
+char *
+find_executable (const char* wrapper)
+{
+  int has_slash = 0;
+  const char* p;
+  const char* p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char* concat_name;
+
+  DEBUG("(find_executable)  : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':')
+  {
+    concat_name = xstrdup (wrapper);
+    if (check_executable(concat_name))
+      return concat_name;
+    XFREE(concat_name);
+  }
+  else
+  {
+#endif
+    if (IS_DIR_SEPARATOR (wrapper[0]))
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable(concat_name))
+        return concat_name;
+      XFREE(concat_name);
+    }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+    {
+      has_slash = 1;
+      break;
+    }
+  if (!has_slash)
+  {
+    /* no slashes; search PATH */
+    const char* path = getenv ("PATH");
+    if (path != NULL)
+    {
+      for (p = path; *p; p = p_next)
+      {
+        const char* q;
+        size_t p_len;
+        for (q = p; *q; q++)
+          if (IS_PATH_SEPARATOR(*q))
+            break;
+        p_len = q - p;
+        p_next = (*q == '\0' ? q : q + 1);
+        if (p_len == 0)
+        {
+          /* empty path: current directory */
+          if (getcwd (tmp, LT_PATHMAX) == NULL)
+            lt_fatal ("getcwd failed");
+          tmp_len = strlen(tmp);
+          concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, tmp, tmp_len);
+          concat_name[tmp_len] = '/';
+          strcpy (concat_name + tmp_len + 1, wrapper);
+        }
+        else
+        {
+          concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, p, p_len);
+          concat_name[p_len] = '/';
+          strcpy (concat_name + p_len + 1, wrapper);
+        }
+        if (check_executable(concat_name))
+          return concat_name;
+        XFREE(concat_name);
+      }
+    }
+    /* not found in PATH; assume curdir */
+  }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal ("getcwd failed");
+  tmp_len = strlen(tmp);
+  concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable(concat_name))
+    return concat_name;
+  XFREE(concat_name);
+  return NULL;
+}
+
+char *
+strendzap(char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert(str != NULL);
+  assert(pat != NULL);
+
+  len = strlen(str);
+  patlen = strlen(pat);
+
+  if (patlen <= len)
+  {
+    str += len - patlen;
+    if (strcmp(str, pat) == 0)
+      *str = '\0';
+  }
+  return str;
+}
+
+static void
+lt_error_core (int exit_status, const char * mode,
+          const char * message, va_list ap)
+{
+  fprintf (stderr, "%s: %s: ", program_name, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+  va_end (ap);
+}
+EOF
+          # we should really use a build-platform specific compiler
+          # here, but OTOH, the wrappers (shell script and this C one)
+          # are only useful if you want to execute the "real" binary.
+          # Since the "real" binary is built for $host, then this
+          # wrapper might as well be built for $host, too.
+          $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
+          ;;
+        esac
+        $rm $output
+        trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
+
+	$echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+	$echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  $echo >> $output "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+	  $echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	$echo \"\$relink_command_output\" >&2
+	$rm \"\$progdir/\$file\"
+	exit $EXIT_FAILURE
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+	else
+	  $echo >> $output "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	# fixup the dll searchpath if we need to.
+	if test -n "$dllsearchpath"; then
+	  $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	$echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+	case $host in
+	# Backslashes separate directories on plain windows
+	*-*-mingw | *-*-os2*)
+	  $echo >> $output "\
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+	  ;;
+
+	*)
+	  $echo >> $output "\
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+	  ;;
+	esac
+	$echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit $EXIT_FAILURE
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    $echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit $EXIT_FAILURE
+  fi
+fi\
+"
+	chmod +x $output
+      fi
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$old_deplibs $non_pic_objects"
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	generated="$generated $gentop"
+
+	func_extract_archives $gentop $addlibs
+	oldobjs="$oldobjs $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       cmds=$old_archive_from_new_cmds
+      else
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+	if (for obj in $oldobjs
+	    do
+	      $echo "X$obj" | $Xsed -e 's%^.*/%%'
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  $echo "copying selected object files to avoid basename conflicts..."
+
+	  if test -z "$gentop"; then
+	    gentop="$output_objdir/${outputname}x"
+	    generated="$generated $gentop"
+
+	    $show "${rm}r $gentop"
+	    $run ${rm}r "$gentop"
+	    $show "$mkdir $gentop"
+	    $run $mkdir "$gentop"
+	    exit_status=$?
+	    if test "$exit_status" -ne 0 && test ! -d "$gentop"; then
+	      exit $exit_status
+	    fi
+	  fi
+
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		counter=`expr $counter + 1`
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      $run ln "$obj" "$gentop/$newobj" ||
+	      $run cp "$obj" "$gentop/$newobj"
+	      oldobjs="$oldobjs $gentop/$newobj"
+	      ;;
+	    *) oldobjs="$oldobjs $obj" ;;
+	    esac
+	  done
+	fi
+
+	eval cmds=\"$old_archive_cmds\"
+
+	if len=`expr "X$cmds" : ".*"` &&
+	     test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  $echo "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done
+	  for obj in $save_oldobjs
+	  do
+	    oldobjs="$objlist $obj"
+	    objlist="$objlist $obj"
+	    eval test_cmds=\"$old_archive_cmds\"
+	    if len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+	       test "$len" -le "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj" ; then
+	        RANLIB=$save_RANLIB
+	      fi
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+	      objlist=
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test "X$oldobjs" = "X" ; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+        eval cmd=\"$cmd\"
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      $show "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+	  relink_command="$var=\"$var_value\"; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+	relink_command=
+      fi
+
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		if test -z "$libdir"; then
+		  $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+		  exit $EXIT_FAILURE
+		fi
+		newdependency_libs="$newdependency_libs $libdir/$name"
+		;;
+	      *) newdependency_libs="$newdependency_libs $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+	      eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+	      if test -z "$libdir"; then
+		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+		exit $EXIT_FAILURE
+	      fi
+	      newdlfiles="$newdlfiles $libdir/$name"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+	      eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+	      if test -z "$libdir"; then
+		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+		exit $EXIT_FAILURE
+	      fi
+	      newdlprefiles="$newdlprefiles $libdir/$name"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      newdlfiles="$newdlfiles $abs"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      newdlprefiles="$newdlprefiles $abs"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $rm $output
+	  # place dlname in correct position for cygwin
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+	  esac
+	  $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test "$installed" = no && test "$need_relink" = yes; then
+	    $echo >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       $echo "X$nonopt" | grep shtool > /dev/null; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case $arg in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+	files="$files $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f) 
+      	case " $install_prog " in
+	*[\\\ /]cp\ *) ;;
+	*) prev=$arg ;;
+	esac
+	;;
+      -g | -m | -o) prev=$arg ;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	$echo "$modename: no file or destination specified" 1>&2
+      else
+	$echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test "$#" -gt 2; then
+	$echo "$modename: \`$dest' is not a directory" 1>&2
+	$echo "$help" 1>&2
+	exit $EXIT_FAILURE
+      fi
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	staticlibs="$staticlibs $file"
+	;;
+
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	library_names=
+	old_library=
+	relink_command=
+	# If there is no directory component, then add one.
+	case $file in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) current_libdirs="$current_libdirs $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) future_libdirs="$future_libdirs $libdir" ;;
+	  esac
+	fi
+
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
+	test "X$dir" = "X$file/" && dir=
+	dir="$dir$objdir"
+
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  if test "$inst_prefix_dir" = "$destdir"; then
+	    $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  $echo "$modename: warning: relinking \`$file'" 1>&2
+	  $show "$relink_command"
+	  if $run eval "$relink_command"; then :
+	  else
+	    $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names
+	if test -n "$2"; then
+	  realname="$2"
+	  shift
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  $show "$install_prog $dir/$srcname $destdir/$realname"
+	  $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
+	  if test -n "$stripme" && test -n "$striplib"; then
+	    $show "$striplib $destdir/$realname"
+	    $run eval "$striplib $destdir/$realname" || exit $?
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try `ln -sf' first, because the `ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      if test "$linkname" != "$realname"; then
+                $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+                $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+	      fi
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  cmds=$postinstall_cmds
+	  save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    eval cmd=\"$cmd\"
+	    $show "$cmd"
+	    $run eval "$cmd" || {
+	      lt_exit=$?
+
+	      # Restore the uninstalled library and exit
+	      if test "$mode" = relink; then
+		$run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+	      fi
+
+	      exit $lt_exit
+	    }
+	  done
+	  IFS="$save_ifs"
+	fi
+
+	# Install the pseudo-library for information purposes.
+	name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	instname="$dir/$name"i
+	$show "$install_prog $instname $destdir/$name"
+	$run eval "$install_prog $instname $destdir/$name" || exit $?
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	if test -n "$destfile"; then
+	  $show "$install_prog $file $destfile"
+	  $run eval "$install_prog $file $destfile" || exit $?
+	fi
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+	  $show "$install_prog $staticobj $staticdest"
+	  $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+	fi
+	exit $EXIT_SUCCESS
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=""
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      file=`$echo $file|${SED} 's,.exe$,,'`
+	      stripped_ext=".exe"
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin*|*mingw*)
+	    wrapper=`$echo $file | ${SED} -e 's,.exe$,,'`
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  # Note that it is not necessary on cygwin/mingw to append a dot to
+	  # foo even if both foo and FILE.exe exist: automatic-append-.exe
+	  # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+	  # `FILE.' does not work on cygwin managed mounts.
+	  #
+	  # If there is no directory component, then add one.
+	  case $wrapper in
+	  */* | *\\*) . ${wrapper} ;;
+	  *) . ./${wrapper} ;;
+	  esac
+
+	  # Check the variables that should have been set.
+	  if test -z "$notinst_deplibs"; then
+	    $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
+	    exit $EXIT_FAILURE
+	  fi
+
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      # If there is no directory component, then add one.
+	      case $lib in
+	      */* | *\\*) . $lib ;;
+	      *) . ./$lib ;;
+	      esac
+	    fi
+	    libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+	      finalize=no
+	    fi
+	  done
+
+	  relink_command=
+	  # Note that it is not necessary on cygwin/mingw to append a dot to
+	  # foo even if both foo and FILE.exe exist: automatic-append-.exe
+	  # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+	  # `FILE.' does not work on cygwin managed mounts.
+	  #
+	  # If there is no directory component, then add one.
+	  case $wrapper in
+	  */* | *\\*) . ${wrapper} ;;
+	  *) . ./${wrapper} ;;
+	  esac
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    if test "$finalize" = yes && test -z "$run"; then
+	      tmpdir=`func_mktempdir`
+	      file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
+	      outputname="$tmpdir/$file"
+	      # Replace the output file specification.
+	      relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+	      $show "$relink_command"
+	      if $run eval "$relink_command"; then :
+	      else
+		$echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+		${rm}r "$tmpdir"
+		continue
+	      fi
+	      file="$outputname"
+	    else
+	      $echo "$modename: warning: cannot relink \`$file'" 1>&2
+	    fi
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway 
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'`
+	    ;;
+	  esac
+	  ;;
+	esac
+	$show "$install_prog$stripme $file $destfile"
+	$run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+	test -n "$outputname" && ${rm}r "$tmpdir"
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	$show "$old_striplib $oldlib"
+	$run eval "$old_striplib $oldlib" || exit $?
+      fi
+
+      # Do each command in the postinstall commands.
+      cmds=$old_postinstall_cmds
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	eval cmd=\"$cmd\"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+	libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  cmds=$finish_cmds
+	  save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    eval cmd=\"$cmd\"
+	    $show "$cmd"
+	    $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+	  done
+	  IFS="$save_ifs"
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    test "$show" = : && exit $EXIT_SUCCESS
+
+    $echo "X----------------------------------------------------------------------" | $Xsed
+    $echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      $echo "   $libdir"
+    done
+    $echo
+    $echo "If you ever happen to want to link against installed libraries"
+    $echo "in a given directory, LIBDIR, you must either use libtool, and"
+    $echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+    $echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      $echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      $echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      $echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      $echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      $echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      $echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      $echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    $echo
+    $echo "See any operating system documentation about shared libraries for"
+    $echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    $echo "X----------------------------------------------------------------------" | $Xsed
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit $EXIT_FAILURE
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+	$echo "$modename: \`$file' is not a file" 1>&2
+	$echo "$help" 1>&2
+	exit $EXIT_FAILURE
+      fi
+
+      dir=
+      case $file in
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+
+	# If there is no directory component, then add one.
+	case $file in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  dir="$dir/$objdir"
+	else
+	  $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+	  exit $EXIT_FAILURE
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+	;;
+
+      *)
+	$echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -*) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  # If there is no directory component, then add one.
+	  case $file in
+	  */* | *\\*) . $file ;;
+	  *) . ./$file ;;
+	  esac
+
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      if test "${save_LC_ALL+set}" = set; then
+	LC_ALL="$save_LC_ALL"; export LC_ALL
+      fi
+      if test "${save_LANG+set}" = set; then
+	LANG="$save_LANG"; export LANG
+      fi
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+	$echo "export $shlibpath_var"
+      fi
+      $echo "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+    ;;
+
+  # libtool clean and uninstall mode
+  clean | uninstall)
+    modename="$modename: $mode"
+    rm="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) rm="$rm $arg"; rmforce=yes ;;
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    rmdirs=
+
+    origobjdir="$objdir"
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$dir" = "X$file"; then
+	dir=.
+	objdir="$origobjdir"
+      else
+	objdir="$dir/$origobjdir"
+      fi
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+      test "$mode" = uninstall && objdir="$dir"
+
+      # Remember objdir for removal later, being careful to avoid duplicates
+      if test "$mode" = clean; then
+	case " $rmdirs " in
+	  *" $objdir "*) ;;
+	  *) rmdirs="$rmdirs $objdir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if (test -L "$file") >/dev/null 2>&1 \
+	|| (test -h "$file") >/dev/null 2>&1 \
+	|| test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif test "$rmforce" = yes; then
+	continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  . $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    rmfiles="$rmfiles $objdir/$n"
+	  done
+	  test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+
+	  case "$mode" in
+	  clean)
+	    case "  $library_names " in
+	    # "  " in the beginning catches empty $dlname
+	    *" $dlname "*) ;;
+	    *) rmfiles="$rmfiles $objdir/$dlname" ;;
+	    esac
+	     test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+	    ;;
+	  uninstall)
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      cmds=$postuninstall_cmds
+	      save_ifs="$IFS"; IFS='~'
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		eval cmd=\"$cmd\"
+		$show "$cmd"
+		$run eval "$cmd"
+		if test "$?" -ne 0 && test "$rmforce" != yes; then
+		  exit_status=1
+		fi
+	      done
+	      IFS="$save_ifs"
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      cmds=$old_postuninstall_cmds
+	      save_ifs="$IFS"; IFS='~'
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		eval cmd=\"$cmd\"
+		$show "$cmd"
+		$run eval "$cmd"
+		if test "$?" -ne 0 && test "$rmforce" != yes; then
+		  exit_status=1
+		fi
+	      done
+	      IFS="$save_ifs"
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	    ;;
+	  esac
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+
+	  # Read the .lo file
+	  . $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" \
+	     && test "$pic_object" != none; then
+	    rmfiles="$rmfiles $dir/$pic_object"
+	  fi
+
+	  # Add non-PIC object to the list of files to remove.
+	  if test -n "$non_pic_object" \
+	     && test "$non_pic_object" != none; then
+	    rmfiles="$rmfiles $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test "$mode" = clean ; then
+	  noexename=$name
+	  case $file in
+	  *.exe)
+	    file=`$echo $file|${SED} 's,.exe$,,'`
+	    noexename=`$echo $name|${SED} 's,.exe$,,'`
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    rmfiles="$rmfiles $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	    relink_command=
+	    . $dir/$noexename
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
+	      rmfiles="$rmfiles $objdir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name" ; then
+	      rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      $show "$rm $rmfiles"
+      $run $rm $rmfiles || exit_status=1
+    done
+    objdir="$origobjdir"
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	$show "rmdir $dir"
+	$run rmdir $dir >/dev/null 2>&1
+      fi
+    done
+
+    exit $exit_status
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit $EXIT_FAILURE
+    ;;
+  esac
+
+  if test -z "$exec_cmd"; then
+    $echo "$modename: invalid operation mode \`$mode'" 1>&2
+    $echo "$generic_help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+fi # test -z "$show_help"
+
+if test -n "$exec_cmd"; then
+  eval exec $exec_cmd
+  exit $EXIT_FAILURE
+fi
+
+# We need to display help for each of the modes.
+case $mode in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --tag=TAG         use configuration variables from tag TAG
+    --version         print version information
+
+MODE must be one of the following:
+
+      clean           remove files from the build directory
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE.
+
+Report bugs to <bug-libtool at gnu.org>."
+  exit $EXIT_SUCCESS
+  ;;
+
+clean)
+  $echo \
+"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -prefer-pic       try to building PIC objects only
+  -prefer-non-pic   try to building non-PIC objects only
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+		    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+		    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+		    specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit $EXIT_FAILURE
+  ;;
+esac
+
+$echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit $?
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+disable_libs=shared
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+disable_libs=static
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:

Added: freeswitch/trunk/libs/js/nsprpub/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+Makefile
+config-defs.h
+config.cache
+config.log
+config.status

Added: freeswitch/trunk/libs/js/nsprpub/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+/.cvsignore/1.2/Sat May 12 00:53:26 2001//
+/Makefile.in/1.22/Sun Apr 25 15:00:32 2004//
+/configure/1.212/Wed Feb 22 02:39:58 2006//
+/configure.in/1.214/Wed Feb 22 02:39:58 2006//
+D

Added: freeswitch/trunk/libs/js/nsprpub/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,9 @@
+A D/admin////
+A D/build////
+A D/config////
+A D/include////
+A D/lib////
+A D/macbuild////
+A D/pkg////
+A D/pr////
+A D/tools////

Added: freeswitch/trunk/libs/js/nsprpub/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub

Added: freeswitch/trunk/libs/js/nsprpub/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,151 @@
+#! gmake
+
+# 
+# ***** 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
+
+MAKE := $(patsubst -j%,,$(MAKE)) -j1
+
+DIRS = config pr lib
+
+ifdef MOZILLA_CLIENT
+# Make nsinstall use absolute symlinks by default for Mozilla OSX builds
+# http://bugzilla.mozilla.org/show_bug.cgi?id=193164
+ifeq ($(OS_ARCH),Darwin)
+ifndef NSDISTMODE
+NSDISTMODE=absolute_symlink
+export NSDISTMODE
+endif
+endif
+endif
+
+DIST_GARBAGE = config.cache config.log config.status
+
+all:: config.status export
+
+include $(topsrcdir)/config/rules.mk
+
+config.status:: configure
+ifeq ($(OS_ARCH),WINNT)
+	sh $(srcdir)/configure --no-create --no-recursion
+else
+	./config.status --recheck && ./config.status
+endif
+
+#
+# The -ll option of zip converts CR LF to LF.
+#
+ifeq ($(OS_ARCH),WINNT)
+ZIP_ASCII_OPT = -ll
+endif
+
+# Delete config/autoconf.mk last because it is included by every makefile.
+distclean::
+	@echo "cd pr/tests; $(MAKE) $@"
+	@$(MAKE) -C pr/tests $@
+	rm -f config/autoconf.mk
+
+release::
+	echo $(BUILD_NUMBER) > $(RELEASE_DIR)/$(BUILD_NUMBER)/version.df
+	@if test -f imports.df; then \
+	    echo "cp -f imports.df $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df"; \
+	    cp -f imports.df $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df; \
+	else \
+	    echo "echo > $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df"; \
+	    echo > $(RELEASE_DIR)/$(BUILD_NUMBER)/imports.df; \
+	fi
+	cd $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
+	rm -rf META-INF; mkdir META-INF; cd META-INF; \
+	echo "Manifest-Version: 1.0" > MANIFEST.MF; \
+	echo "" >> MANIFEST.MF; \
+	cd ..; rm -f mdbinary.jar; zip -r mdbinary.jar META-INF bin lib; \
+	rm -rf META-INF; \
+	cd include; \
+	rm -rf META-INF; mkdir META-INF; cd META-INF; \
+	echo "Manifest-Version: 1.0" > MANIFEST.MF; \
+	echo "" >> MANIFEST.MF; \
+	cd ..; rm -f mdheader.jar; zip $(ZIP_ASCII_OPT) -r mdheader.jar *; \
+	rm -rf META-INF
+ifeq ($(OS_ARCH),WINNT)
+	@if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); then \
+		rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \
+		echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)"; \
+		$(topsrcdir)/config/prmkdir.bat $(MDIST_DOS)\\$(MOD_NAME)\\$(BUILD_NUMBER); \
+	fi
+	@if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); then \
+		rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+		echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)"; \
+		$(topsrcdir)/config/prmkdir.bat $(MDIST_DOS)\\$(MOD_NAME)\\$(BUILD_NUMBER)\\$(RELEASE_OBJDIR_NAME); \
+	fi
+else
+	@if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); then \
+		rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \
+		echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)"; \
+		$(NSINSTALL) -D $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \
+		chmod 775 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \
+	fi
+	@if test ! -d $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); then \
+		rm -rf $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+		echo "making directory $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)"; \
+		$(NSINSTALL) -D $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+		chmod 775 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+	fi
+endif
+	cd $(RELEASE_DIR)/$(BUILD_NUMBER); \
+	cp -f version.df imports.df $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER); \
+	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/version.df; \
+	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/imports.df; \
+	cd $(OBJDIR_NAME); \
+	cp -f mdbinary.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)/mdbinary.jar; \
+	cd include; \
+	cp -f mdheader.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME); \
+	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(RELEASE_OBJDIR_NAME)/mdheader.jar
+
+package:
+	@echo "cd pkg; $(MAKE) publish"
+	$(MAKE) -C pkg publish
+
+depend:
+	@echo "NSPR20 has no dependencies.  Skipped."

Added: freeswitch/trunk/libs/js/nsprpub/admin/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/admin/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+/explode.pl/1.2/Sun Apr 25 15:00:34 2004//
+/makeTargetDirs.sh/1.3/Sun Apr 25 15:00:34 2004//
+/repackage.sh/1.15/Wed Sep 14 23:39:55 2005//
+/symlinks.sh/1.2/Sun Apr 25 15:00:34 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/admin/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/admin/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/admin

Added: freeswitch/trunk/libs/js/nsprpub/admin/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/admin/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/admin/explode.pl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/admin/explode.pl	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,75 @@
+#!/bin/perl
+# 
+# ***** 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-2001
+# 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 *****
+
+# -----------------------------------------------------------------
+#
+# explode.pl -- Unpack .jar files into bin, lib, include directories
+#
+# syntax: perl explode.pl
+#
+# Description:
+# explode.pl unpacks the .jar files created by the NSPR build   
+# procedure. 
+#
+# Suggested use: After copying the platform directories to
+# /s/b/c/nspr20/<release>. CD to /s/b/c/nspr20/<release> and
+# run explode.pl. This will unpack the jar files into bin, lib,
+# include directories.
+#
+# -----------------------------------------------------------------
+
+ at dirs = `ls -d *.OBJ*`;
+
+foreach $dir (@dirs) {
+    chop($dir);
+    if (-l $dir) {
+        print "Skipping symbolic link $dir\n";
+        next;
+    }
+    print "Unzipping $dir/mdbinary.jar\n";
+    system ("unzip", "-o", "$dir/mdbinary.jar",
+            "-d", "$dir");
+    system ("rm", "-rf", "$dir/META-INF");
+    mkdir "$dir/include", 0755;
+    print "Unzipping $dir/mdheader.jar\n";
+    system ("unzip", "-o", "-aa",
+            "$dir/mdheader.jar",
+            "-d", "$dir/include");
+    system ("rm", "-rf", "$dir/include/META-INF");
+}
+# --- end explode.pl ----------------------------------------------

Added: freeswitch/trunk/libs/js/nsprpub/admin/makeTargetDirs.sh
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/admin/makeTargetDirs.sh	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,79 @@
+#!/bin/sh
+# 
+# ***** 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-2001
+# 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 *****
+
+# -----------------------------------------------------------------
+# makeTargetDirs.sh -- Create target directories for building NSPR
+#
+# syntax: makeTargetDirs.sh
+#
+# Description:
+# makeTargetDirs.sh creates a set of directories intended for use
+# with NSPR's autoconf based build system.
+#     
+# The enumerated directories are the same as those built for NSPR
+# 4.1.1. Adjust as needed.
+#
+# -----------------------------------------------------------------
+
+mkdir  AIX4.3_64_DBG.OBJ
+mkdir  AIX4.3_64_OPT.OBJ
+mkdir  AIX4.3_DBG.OBJ
+mkdir  AIX4.3_OPT.OBJ
+mkdir  HP-UXB.11.00_64_DBG.OBJ
+mkdir  HP-UXB.11.00_64_OPT.OBJ
+mkdir  HP-UXB.11.00_DBG.OBJ
+mkdir  HP-UXB.11.00_OPT.OBJ
+mkdir  IRIX6.5_n32_PTH_DBG.OBJ
+mkdir  IRIX6.5_n32_PTH_OPT.OBJ
+mkdir  Linux2.2_x86_glibc_PTH_DBG.OBJ
+mkdir  Linux2.2_x86_glibc_PTH_OPT.OBJ
+mkdir  Linux2.4_x86_glibc_PTH_DBG.OBJ
+mkdir  Linux2.4_x86_glibc_PTH_OPT.OBJ
+mkdir  OSF1V4.0D_DBG.OBJ
+mkdir  OSF1V4.0D_OPT.OBJ
+mkdir  SunOS5.6_DBG.OBJ
+mkdir  SunOS5.6_OPT.OBJ
+mkdir  SunOS5.7_64_DBG.OBJ
+mkdir  SunOS5.7_64_OPT.OBJ
+mkdir  WIN954.0_DBG.OBJ
+mkdir  WIN954.0_DBG.OBJD
+mkdir  WIN954.0_OPT.OBJ
+mkdir  WINNT4.0_DBG.OBJ
+mkdir  WINNT4.0_DBG.OBJD
+mkdir  WINNT4.0_OPT.OBJ
+# --- end makeTargetDirs.sh ---------------------------------------

Added: freeswitch/trunk/libs/js/nsprpub/admin/repackage.sh
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/admin/repackage.sh	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,215 @@
+#! /bin/sh
+# ***** 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-2001
+# 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 *****
+
+# ------------------------------------------------------------------
+# repackage.sh -- Repackage NSPR from /s/b/c to mozilla.org format
+#
+# syntax: repackage.sh
+#
+# Description:
+# repackage.sh creates NSPR binary distributions for mozilla.org from
+# the internal binary distributions in /share/builds/components/nspr20.
+# There are reasons why we can't just push the internal binary distributions
+# to mozilla.org. External developers prefer to use the common archive 
+# file format for their platforms, rather than the jar files we use internally.
+#
+# On Unix, we create a tar.gz file.  On Windows, we create a zip file.
+# For example: NSPR 4.1.1, these would be nspr-4.1.1.tar.gz and nspr-4.1.1.zip.
+#
+# When unpacked, nspr-4.1.1.tar.gz or nspr-4.1.1.zip should expand to a
+# nspr-4.1.1 directory that contains three subdirectories: include, lib,
+# and bin.  The header files, with the correct line endings for the
+# platform, are in nspr-4.1.1/include.  The libraries are in nspr-4.1.1/lib.
+# The executable programs are in nspr-4.1.1/bin.
+# 
+# Note! Files written with Gnu tar are not readable by some non-Gnu
+# versions. Sun, in particular.
+# 
+# 
+# 
+# 
+# ------------------------------------------------------------------
+
+FROMTOP=/share/builds/components/nspr20/v4.7
+TOTOP=./v4.7
+NSPRDIR=nspr-4.7
+SOURCETAG=NSPR_4_7_RTM
+
+#
+# enumerate Unix object directories on /s/b/c
+UNIX_OBJDIRS="
+AIX4.3_64_DBG.OBJ
+AIX4.3_64_OPT.OBJ
+AIX4.3_DBG.OBJ
+AIX4.3_OPT.OBJ
+HP-UXB.11.00_64_DBG.OBJ
+HP-UXB.11.00_64_OPT.OBJ
+HP-UXB.11.00_DBG.OBJ
+HP-UXB.11.00_OPT.OBJ
+IRIX6.5_n32_PTH_DBG.OBJ
+IRIX6.5_n32_PTH_OPT.OBJ
+Linux2.2_x86_glibc_PTH_DBG.OBJ
+Linux2.2_x86_glibc_PTH_OPT.OBJ
+Linux2.4_x86_glibc_PTH_DBG.OBJ
+Linux2.4_x86_glibc_PTH_OPT.OBJ
+OSF1V5.0_DBG.OBJ
+OSF1V5.0_OPT.OBJ
+SunOS5.6_DBG.OBJ
+SunOS5.6_OPT.OBJ
+SunOS5.8_64_DBG.OBJ
+SunOS5.8_64_OPT.OBJ
+SunOS5.8_DBG.OBJ
+SunOS5.8_OPT.OBJ
+"
+#
+# enumerate Windows object directories on /s/b/c
+WIN_OBJDIRS="
+WIN954.0_DBG.OBJ
+WIN954.0_DBG.OBJD
+WIN954.0_OPT.OBJ
+WINNT4.0_DBG.OBJ
+WINNT4.0_DBG.OBJD
+WINNT4.0_OPT.OBJ
+"
+
+#
+# Create the destination directory.
+#
+echo "removing directory $TOTOP"
+rm -rf $TOTOP
+echo "creating directory $TOTOP"
+mkdir -p $TOTOP
+
+#
+# Generate the tar.gz files for Unix platforms.
+#
+for OBJDIR in $UNIX_OBJDIRS; do
+    echo "removing directory $NSPRDIR"
+    rm -rf $NSPRDIR
+    echo "creating directory $NSPRDIR"
+    mkdir $NSPRDIR
+
+    echo "creating directory $NSPRDIR/include"
+    mkdir $NSPRDIR/include
+    echo "copying $FROMTOP/$OBJDIR/include"
+    cp -r $FROMTOP/$OBJDIR/include $NSPRDIR
+
+    echo "copying $FROMTOP/$OBJDIR/lib"
+    cp -r $FROMTOP/$OBJDIR/lib $NSPRDIR
+
+    echo "copying $FROMTOP/$OBJDIR/bin"
+    cp -r $FROMTOP/$OBJDIR/bin $NSPRDIR
+
+    echo "creating directory $TOTOP/$OBJDIR"
+    mkdir $TOTOP/$OBJDIR
+    echo "creating $TOTOP/$OBJDIR/$NSPRDIR.tar"
+    tar cvf $TOTOP/$OBJDIR/$NSPRDIR.tar $NSPRDIR
+    echo "gzipping $TOTOP/$OBJDIR/$NSPRDIR.tar"
+    gzip $TOTOP/$OBJDIR/$NSPRDIR.tar
+done
+
+#
+# Generate the zip files for Windows platforms.
+#
+for OBJDIR in $WIN_OBJDIRS; do
+    echo "removing directory $NSPRDIR"
+    rm -rf $NSPRDIR
+    echo "creating directory $NSPRDIR"
+    mkdir $NSPRDIR
+
+    echo "creating directory $NSPRDIR/include"
+    mkdir $NSPRDIR/include
+    echo "creating directory $NSPRDIR/include/private"
+    mkdir $NSPRDIR/include/private
+    echo "creating directory $NSPRDIR/include/obsolete"
+    mkdir $NSPRDIR/include/obsolete
+
+    # copy headers and adjust unix line-end to Windows line-end
+    # Note: Watch out for the "sed" command line.
+    # when editing the command, take care to preserve the "^M" as the literal
+    # cntl-M character! in vi, use "cntl-v cntl-m" to enter it!
+    #
+    headers=`ls $FROMTOP/$OBJDIR/include/*.h`
+    for header in $headers; do
+        sed -e 's/$/
/g' $header > $NSPRDIR/include/`basename $header`
+    done
+    headers=`ls $FROMTOP/$OBJDIR/include/obsolete/*.h`
+    for header in $headers; do
+        sed -e 's/$/
/g' $header > $NSPRDIR/include/obsolete/`basename $header`
+    done
+    headers=`ls $FROMTOP/$OBJDIR/include/private/*.h`
+    for header in $headers; do
+        sed -e 's/$/
/g' $header > $NSPRDIR/include/private/`basename $header`
+    done
+
+    echo "copying $FROMTOP/$OBJDIR/lib"
+    cp -r $FROMTOP/$OBJDIR/lib $NSPRDIR
+
+    echo "copying $FROMTOP/$OBJDIR/bin"
+    cp -r $FROMTOP/$OBJDIR/bin $NSPRDIR
+
+    echo "creating directory $TOTOP/$OBJDIR"
+    mkdir $TOTOP/$OBJDIR
+    echo "creating $TOTOP/$OBJDIR/$NSPRDIR.zip"
+    zip -r $TOTOP/$OBJDIR/$NSPRDIR.zip $NSPRDIR
+done
+
+#
+# package the source from CVS
+#
+echo "Packaging source"
+echo "removing directory $NSPRDIR"
+rm -rf $NSPRDIR
+echo "creating directory $NSPRDIR"
+mkdir $NSPRDIR
+myWD=`pwd`
+cd $NSPRDIR
+echo "Pulling source from CVS with tag $SOURCETAG"
+cvs co -r $SOURCETAG mozilla/nsprpub
+cd $myWD
+mkdir $TOTOP/src
+echo "Creating source tar file: $TOTOP/src/$NSPRDIR.tar"
+tar cvf $TOTOP/src/$NSPRDIR.tar $NSPRDIR
+echo "gzip $TOTOP/src/$NSPRDIR.tar"
+gzip $TOTOP/src/$NSPRDIR.tar
+
+#
+# Remove the working directory.
+#
+echo "removing directory $NSPRDIR"
+rm -rf $NSPRDIR
+# --- end repackage.sh ---------------------------------------------

Added: freeswitch/trunk/libs/js/nsprpub/admin/symlinks.sh
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/admin/symlinks.sh	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,75 @@
+#!/bin/sh
+# 
+# ***** 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-2001
+# 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 *****
+
+# -----------------------------------------------------------------
+# symlinks.sh -- create links from NSPR builds
+#
+# syntax: symlinks.sh
+# 
+# Description:
+# symlinks.sh creates some symbolic links for NSPR build targets
+# that are not actually build, but for which there are NSPR
+# binaries suitable for running on the intended target. ... got
+# that?
+# 
+# Suggested use: After copying NSPR binaries to
+# /s/b/c/nspr20/<platform> run symlinks.sh to create the links
+# for all supported platforms.
+#
+# The symlinks in this script correspond to the NSPR 4.1.1
+# release. Adjust as necessary.
+#
+# -----------------------------------------------------------------
+
+ln -s SunOS5.6_DBG.OBJ SunOS5.7_DBG.OBJ
+ln -s SunOS5.6_OPT.OBJ SunOS5.7_OPT.OBJ
+
+ln -s SunOS5.6_DBG.OBJ SunOS5.8_DBG.OBJ
+ln -s SunOS5.6_OPT.OBJ SunOS5.8_OPT.OBJ
+
+ln -s SunOS5.7_64_DBG.OBJ SunOS5.8_64_DBG.OBJ
+ln -s SunOS5.7_64_OPT.OBJ SunOS5.8_64_OPT.OBJ
+
+ln -s OSF1V4.0D_DBG.OBJ OSF1V5.0_DBG.OBJ
+ln -s OSF1V4.0D_OPT.OBJ OSF1V5.0_OPT.OBJ
+
+ln -s WINNT4.0_DBG.OBJ WINNT5.0_DBG.OBJ
+ln -s WINNT4.0_DBG.OBJD WINNT5.0_DBG.OBJD
+ln -s WINNT4.0_OPT.OBJ WINNT5.0_OPT.OBJ
+# --- end symlinks.sh ---------------------------------------------
+

Added: freeswitch/trunk/libs/js/nsprpub/build/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/build/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2 @@
+/cygwin-wrapper/1.4/Thu Aug 19 16:27:08 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/build/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/build/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+A D/autoconf////

Added: freeswitch/trunk/libs/js/nsprpub/build/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/build/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/build

Added: freeswitch/trunk/libs/js/nsprpub/build/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/build/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/build/autoconf/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/build/autoconf/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4 @@
+/config.guess/1.16/Fri Oct 14 19:22:05 2005//
+/config.sub/1.17/Fri Oct 14 19:22:05 2005//
+/install-sh/1.2/Fri Oct 15 02:42:36 1999//
+D

Added: freeswitch/trunk/libs/js/nsprpub/build/autoconf/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/build/autoconf/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/build/autoconf

Added: freeswitch/trunk/libs/js/nsprpub/build/autoconf/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/build/autoconf/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/build/autoconf/config.guess
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/build/autoconf/config.guess	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1481 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-10-13'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per at bothner.com>.
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+#### MozillaHack 
+# Netscape's hacked uname
+    xx:WINNT:* | xx:WIN95:*)
+	echo i586-pc-msvc
+	exit ;;
+###  End MozillaHack
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && {
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+		exit
+	}
+	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+#### MozillaHack 
+    *:*OpenVMS*:*:*)
+        case "${UNAME_SYSTEM}" in
+            POSIX_for_OpenVMS_AXP) echo alpha-dec-openvmsposix ;;
+            POSIX_for_OpenVMS_VAX) echo vax-dec-openvmsposix ;;
+            OpenVMS) echo alpha-dec-openvms ;;
+            *) echo unknown-dec-openvms ;;
+        esac
+        exit ;;
+#### End MozillaHack 
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:

Added: freeswitch/trunk/libs/js/nsprpub/build/autoconf/config.sub
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/build/autoconf/config.sub	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1595 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-10-13'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+#### MozillaHack 
+# mips*el
+#### End MozillaHack 
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+	| mips | mipsbe | mipseb | mips*el | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| ms1 \
+	| msp430 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m32c)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+#### MozillaHack 
+# mips*el
+#### End MozillaHack 
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mips*el-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| ms1-* \
+	| msp430-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	m32c-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+#### MozillaHack 
+	i386-msvc | msvc)
+		basic_machine=i386-pc
+		os=-msvc
+		;;
+#### End MozillaHack 
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+#### MozillaHack 
+# msvc
+#### End MozillaHack 
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -msvc* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:

Added: freeswitch/trunk/libs/js/nsprpub/build/autoconf/install-sh
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/build/autoconf/install-sh	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:  no input file specified"
+	exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+	echo "install:  no destination specified"
+	exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+	dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0

Added: freeswitch/trunk/libs/js/nsprpub/build/cygwin-wrapper
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/build/cygwin-wrapper	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,75 @@
+#!/bin/sh
+#
+# Stupid wrapper to avoid win32 dospath/cygdrive issues
+# Try not to spawn programs from within this file. If the stuff in here looks royally 
+# confusing, see bug: http://bugzilla.mozilla.org/show_bug.cgi?id=206643
+# and look at the older versions of this file that are easier to read, but
+# do basically the same thing
+#
+
+prog=$1
+shift
+if test -z "$prog"; then
+    exit 0
+fi
+
+# If $CYGDRIVE_MOUNT was not set in configure, give $mountpoint the results of mount -p
+mountpoint=$CYGDRIVE_MOUNT
+if test -z "$mountpoint"; then
+    mountpoint=`mount -p`
+    if test -z "$mountpoint"; then
+       print "Cannot determine cygwin mount points. Exiting"
+       exit 1
+    fi
+fi
+
+# Delete everything but "/cygdrive" (or other mountpoint) from mount=`mount -p`
+mountpoint=${mountpoint#*/}
+mountpoint=/${mountpoint%%[!A-Za-z0-9_]*}
+mountpoint=${mountpoint%/}
+
+args=""
+up=""
+if test "${prog}" = "-up"; then
+    up=1
+    prog=${1}
+    shift
+fi
+
+process=1
+
+# Convert the mountpoint in parameters to Win32 filenames
+# For instance: /cygdrive/c/foo -> c:/foo
+for i in "${@}"
+do
+    if test "${i}" = "-wrap"; then
+        process=1
+    else
+        if test "${i}" = "-nowrap"; then
+            process=
+        else
+            if test -n "${process}"; then
+                if test -n "${up}"; then
+                    pathname=${i#-I[a-zA-Z]:/}
+                    if ! test "${pathname}" = "${i}"; then
+                        no_i=${i#-I}
+                        driveletter=${no_i%%:*}
+                        i=-I${mountpoint}/${driveletter}/${pathname}
+                    fi
+                else
+                    eval 'leader=${i%%'${mountpoint}'/[a-zA-Z]/*}'
+                    if ! test "${leader}" = "${i}"; then
+                        eval 'pathname=${i#'${leader}${mountpoint}'/[a-zA-Z]/}'
+                        eval 'no_mountpoint=${i#'${leader}${mountpoint}'/}'
+                        driveletter=${no_mountpoint%%/*}
+                        i=${leader}${driveletter}:/${pathname}
+                    fi
+                fi
+            fi
+
+            args="${args} ${i}"
+        fi
+    fi
+done
+
+exec $prog $args

Added: freeswitch/trunk/libs/js/nsprpub/config/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,11 @@
+nfspwd
+revdepth
+my_config.mk
+my_overrides.mk
+autoconf.mk
+nsprincl.mk
+nsprincl.sh
+now
+Makefile
+nsinstall
+nspr-config

Added: freeswitch/trunk/libs/js/nsprpub/config/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,20 @@
+/.cvsignore/3.5/Fri Jul 20 00:22:11 2001//
+/Makefile.in/1.21/Wed Nov 23 06:35:18 2005//
+/autoconf.mk.in/1.36/Wed Feb 22 02:39:59 2006//
+/config.mk/3.31/Fri Apr 29 21:02:53 2005//
+/gcc_hidden.h/3.1/Fri Apr 29 21:02:53 2005//
+/libc_r.h/3.5/Sun Apr 25 15:00:34 2004//
+/make-system-wrappers.pl/3.1/Fri Apr 29 21:02:53 2005//
+/nfspwd.pl/3.5/Sun Apr 25 15:00:34 2004//
+/now.c/3.12/Sun Apr 25 15:00:34 2004//
+/nsinstall.c/3.21/Sat Dec 24 15:03:29 2005//
+/nspr-config.in/1.7/Wed May 11 00:53:41 2005//
+/nspr.m4/1.2/Sat May 12 00:36:57 2001//
+/nsprincl.mk.in/1.2/Thu Oct 14 15:05:44 1999//
+/nsprincl.sh.in/1.2/Thu Oct 14 15:05:48 1999//
+/pathsub.h/3.5/Sun Apr 25 15:00:34 2004//
+/prdepend.h/1.10/Sun Apr 25 15:00:34 2004//
+/prmkdir.bat/3.4/Sun Apr 25 15:00:34 2004//
+/rules.mk/3.63/Wed Feb 22 02:39:59 2006//
+/system-headers/3.2/Fri May  6 18:46:10 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/config/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/config

Added: freeswitch/trunk/libs/js/nsprpub/config/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/config/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,160 @@
+#! gmake
+# 
+# ***** 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
+
+# Indicate that this directory builds build tools.
+INTERNAL_TOOLS	= 1
+
+# For sanity's sake, we compile nsinstall without the wrapped system
+# headers, so that we can use it to set up the wrapped system headers.
+VISIBILITY_FLAGS =
+
+# autoconf.mk must be deleted last (from the top-level directory)
+# because it is included by every makefile.
+DIST_GARBAGE	= nsprincl.mk nsprincl.sh nspr-config
+
+RELEASE_BINS	= nspr-config
+
+include $(topsrcdir)/config/config.mk
+
+CSRCS	= now.c
+
+# This version hasn't been ported for us; the one in mozilla/config has
+ifneq ($(OS_ARCH),OS2)
+CSRCS  += nsinstall.c
+ 
+PLSRCS	= nfspwd.pl
+endif
+
+ifeq (,$(CROSS_COMPILE)$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+# Temporary workaround to disable the generation of
+# library build time because now.c uses the 'long long'
+# data type that's not available on some platforms.
+ifeq (,$(filter-out NEC NEXTSTEP QNX SCOOS UNIXWARE,$(OS_ARCH)))
+DEFINES += -DOMIT_LIB_BUILD_TIME
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+    ifeq ($(basename $(OS_RELEASE)),6)
+        ifndef NS_USE_GCC
+            ifeq ($(USE_N32),1)
+                XLDOPTS += -n32 -Wl,-woff,85
+            else
+                ifeq ($(USE_64),1)
+                    XLDOPTS += -64
+                else
+                    XLDOPTS += -32
+                endif
+            endif
+        endif
+    endif
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+    ifeq ($(USE_64),1)
+        XLDOPTS += +DD64
+    endif
+endif
+
+ifeq ($(MOZ_OS2_TOOLS),EMX)
+XCFLAGS = $(OS_CFLAGS)
+ifeq ($(MOZ_OS2_EMX_OBJECTFORMAT),OMF)
+XLDOPTS = -Zlinker /PM:VIO
+endif
+endif
+
+ifeq ($(MOZ_OS2_TOOLS),PGCC)
+XCFLAGS = $(OS_CFLAGS)
+XLDOPTS = -Zlinker /PM:VIO
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+PROGS	= $(OBJDIR)/now$(PROG_SUFFIX)
+
+ifeq (,$(CROSS_COMPILE)$(filter-out OS2 WINNT,$(OS_ARCH)))
+TARGETS = $(PROGS)
+else
+PROGS	+= $(OBJDIR)/nsinstall$(PROG_SUFFIX)
+TARGETS = $(PROGS) $(PLSRCS:.pl=)
+endif
+
+OUTOPTION = -o # end of the line
+ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET)))
+ifndef NS_USE_GCC
+OUTOPTION = -Fe
+endif
+endif
+
+# Redefine MAKE_OBJDIR for just this directory
+define MAKE_OBJDIR
+if test ! -d $(@D); then rm -rf $(@D); mkdir $(@D); else true; fi
+endef
+
+export:: $(TARGETS)
+	rm -f $(dist_bindir)/nspr-config
+
+ifdef WRAP_SYSTEM_INCLUDES
+export::
+	if test ! -d system_wrappers; then mkdir system_wrappers; fi
+	$(PERL) $(srcdir)/make-system-wrappers.pl system_wrappers < $(srcdir)/system-headers
+	$(INSTALL) system_wrappers $(dist_includedir)
+endif
+
+$(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
+	@$(MAKE_OBJDIR)
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+	$(LD) $(EXEFLAGS) $<
+else
+	$(CC) $(XCFLAGS) $< $(LDFLAGS) $(XLDOPTS) $(OUTOPTION)$@
+endif
+
+install:: nspr.m4
+	$(NSINSTALL) -D $(DESTDIR)$(datadir)/aclocal
+	$(NSINSTALL) -t -m 0644 $< $(DESTDIR)$(datadir)/aclocal

Added: freeswitch/trunk/libs/js/nsprpub/config/autoconf.mk.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/autoconf.mk.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,129 @@
+# -*- Mode: Makefile -*-
+
+INCLUDED_AUTOCONF_MK = 1
+USE_AUTOCONF	= 1
+ at SHELL_OVERRIDE@
+MOZILLA_CLIENT	= @MOZILLA_CLIENT@
+
+prefix		= @prefix@
+exec_prefix	= @exec_prefix@
+bindir		= @bindir@
+includedir	= @includedir@
+libdir		= @libdir@
+datadir		= @datadir@
+
+dist_prefix	= @dist_prefix@
+dist_bindir	= @dist_bindir@
+dist_includedir = @dist_includedir@
+dist_libdir	= @dist_libdir@
+
+DIST		= $(dist_prefix)
+
+RELEASE_OBJDIR_NAME = @RELEASE_OBJDIR_NAME@
+OBJDIR_NAME	= @OBJDIR_NAME@
+OBJDIR		= @OBJDIR@
+OBJ_SUFFIX	= @OBJ_SUFFIX@
+LIB_SUFFIX	= @LIB_SUFFIX@
+DLL_SUFFIX	= @DLL_SUFFIX@
+ASM_SUFFIX	= @ASM_SUFFIX@
+MOD_NAME	= @NSPR_MODNAME@
+
+MOD_MAJOR_VERSION = @MOD_MAJOR_VERSION@
+MOD_MINOR_VERSION = @MOD_MINOR_VERSION@
+MOD_PATCH_VERSION = @MOD_PATCH_VERSION@
+
+LIBNSPR		= @LIBNSPR@
+LIBPLC		= @LIBPLC@
+
+CROSS_COMPILE	= @CROSS_COMPILE@
+BUILD_OPT	= @MOZ_OPTIMIZE@
+
+USE_CPLUS	= @USE_CPLUS@
+USE_IPV6	= @USE_IPV6@
+USE_N32		= @USE_N32@
+USE_64		= @USE_64@
+GC_LEAK_DETECTOR = @GC_LEAK_DETECTOR@
+ENABLE_STRIP	= @ENABLE_STRIP@
+
+USE_PTHREADS	= @USE_PTHREADS@
+USE_BTHREADS	= @USE_BTHREADS@
+PTHREADS_USER	= @USE_USER_PTHREADS@
+CLASSIC_NSPR	= @USE_NSPR_THREADS@
+
+AS		= @AS@
+ASFLAGS		= @ASFLAGS@
+CC		= @CC@
+CCC		= @CXX@
+NS_USE_GCC	= @GNU_CC@
+GCC_USE_GNU_LD	= @GCC_USE_GNU_LD@
+MSC_VER		= @MSC_VER@
+AR		= @AR@
+AR_FLAGS	= @AR_FLAGS@
+LD		= @LD@
+RANLIB		= @RANLIB@
+PERL		= @PERL@
+RC		= @RC@
+RCFLAGS		= @RCFLAGS@
+STRIP		= @STRIP@
+NSINSTALL	= @NSINSTALL@
+FILTER		= @FILTER@
+IMPLIB		= @IMPLIB@
+CYGWIN_WRAPPER	= @CYGWIN_WRAPPER@
+
+OS_CPPFLAGS	= @CPPFLAGS@
+OS_CFLAGS	= $(OS_CPPFLAGS) @CFLAGS@ $(DSO_CFLAGS)
+OS_CXXFLAGS	= $(OS_CPPFLAGS) @CXXFLAGS@ $(DSO_CFLAGS)
+OS_LIBS         = @OS_LIBS@
+OS_LDFLAGS	= @LDFLAGS@
+OS_DLLFLAGS	= @OS_DLLFLAGS@
+DLLFLAGS	= @DLLFLAGS@
+EXEFLAGS  = @EXEFLAGS@
+OPTIMIZER	= @OPTIMIZER@
+
+MKSHLIB		= @MKSHLIB@
+DSO_CFLAGS	= @DSO_CFLAGS@
+DSO_LDOPTS	= @DSO_LDOPTS@
+
+RESOLVE_LINK_SYMBOLS = @RESOLVE_LINK_SYMBOLS@
+
+HOST_CC		= @HOST_CC@
+HOST_CFLAGS	= @HOST_CFLAGS@
+HOST_LDFLAGS	= @HOST_LDFLAGS@
+
+DEFINES		= @DEFINES@ @DEFS@
+
+MDCPUCFG_H	= @MDCPUCFG_H@
+PR_MD_CSRCS	= @PR_MD_CSRCS@
+PR_MD_ASFILES	= @PR_MD_ASFILES@
+PR_MD_ARCH_DIR	= @PR_MD_ARCH_DIR@
+CPU_ARCH	= @CPU_ARCH@
+
+OS_TARGET	= @OS_TARGET@
+OS_ARCH		= @OS_ARCH@
+OS_RELEASE	= @OS_RELEASE@
+OS_TEST		= @OS_TEST@
+
+NOSUCHFILE	= @NOSUCHFILE@
+AIX_LINK_OPTS	= @AIX_LINK_OPTS@
+MOZ_OBJFORMAT	= @MOZ_OBJFORMAT@
+ULTRASPARC_LIBRARY = @ULTRASPARC_LIBRARY@
+
+OBJECT_MODE	= @OBJECT_MODE@
+ifdef OBJECT_MODE
+export OBJECT_MODE
+endif
+
+VISIBILITY_FLAGS = @VISIBILITY_FLAGS@
+WRAP_SYSTEM_INCLUDES = @WRAP_SYSTEM_INCLUDES@
+
+MACOSX_DEPLOYMENT_TARGET = @MACOSX_DEPLOYMENT_TARGET@
+ifdef MACOSX_DEPLOYMENT_TARGET
+export MACOSX_DEPLOYMENT_TARGET
+endif
+
+MACOS_SDK_DIR	= @MACOS_SDK_DIR@
+
+NEXT_ROOT	= @NEXT_ROOT@
+ifdef NEXT_ROOT
+export NEXT_ROOT
+endif

Added: freeswitch/trunk/libs/js/nsprpub/config/config.mk
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/config.mk	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,164 @@
+#! gmake
+# 
+# ***** 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 *****
+
+# Configuration information for building in the NSPR source module
+
+# Define an include-at-most-once-flag
+NSPR_CONFIG_MK	= 1
+
+#
+# The variable definitions in this file are inputs to NSPR's
+# build system.  This file, if present, is included at the
+# beginning of config.mk.
+#
+# For example:
+#
+# BUILD_OPT=1
+# USE_PTHREADS=1
+# NS_USE_GCC=
+#
+ifndef topsrcdir
+topsrcdir=$(MOD_DEPTH)
+endif
+
+ifndef srcdir
+srcdir=.
+endif
+
+NFSPWD		= $(MOD_DEPTH)/config/nfspwd
+
+CFLAGS		= $(VISIBILITY_FLAGS) $(CC_ONLY_FLAGS) $(OPTIMIZER)\
+		  $(OS_CFLAGS) $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS)
+CCCFLAGS	= $(VISIBILITY_FLAGS) $(CCC_ONLY_FLAGS) $(OPTIMIZER)\
+		  $(OS_CFLAGS) $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS)
+# For purify
+NOMD_CFLAGS	= $(CC_ONLY_FLAGS) $(OPTIMIZER) $(NOMD_OS_CFLAGS)\
+		  $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS)
+NOMD_CCFLAGS	= $(CCC_ONLY_FLAGS) $(OPTIMIZER) $(NOMD_OS_CFLAGS)\
+		  $(XP_DEFINE) $(DEFINES) $(INCLUDES) $(XCFLAGS)
+
+LDFLAGS		= $(OS_LDFLAGS)
+
+define MAKE_OBJDIR
+if test ! -d $(@D); then rm -rf $(@D); $(NSINSTALL) -D $(@D); fi
+endef
+
+LINK_DLL	= $(LD) $(OS_DLLFLAGS) $(DLLFLAGS)
+
+ifeq ($(OS_ARCH),Darwin)
+PWD := $(shell pwd)
+endif
+
+ifeq (,$(CROSS_COMPILE)$(filter-out WINNT OS2, $(OS_ARCH)))
+INSTALL		= $(NSINSTALL)
+else
+ifeq ($(NSDISTMODE),copy)
+# copy files, but preserve source mtime
+INSTALL		= $(NSINSTALL) -t
+else
+ifeq ($(NSDISTMODE),absolute_symlink)
+# install using absolute symbolic links
+ifeq ($(OS_ARCH),Darwin)
+INSTALL		= $(NSINSTALL) -L $(PWD)
+else
+INSTALL		= $(NSINSTALL) -L `$(NFSPWD)`
+endif
+else
+# install using relative symbolic links
+INSTALL		= $(NSINSTALL) -R
+endif
+endif
+endif # (WINNT || OS2) && !CROSS_COMPILE
+
+DEPENDENCIES	= $(OBJDIR)/.md
+
+ifdef BUILD_DEBUG_GC
+DEFINES		+= -DDEBUG_GC
+endif
+
+GARBAGE		+= $(DEPENDENCIES) core $(wildcard core.[0-9]*)
+
+DIST_GARBAGE += Makefile
+
+####################################################################
+#
+# The NSPR-specific configuration
+#
+####################################################################
+
+DEFINES += -DFORCE_PR_LOG
+
+ifeq ($(_PR_NO_CLOCK_TIMER),1)
+DEFINES += -D_PR_NO_CLOCK_TIMER
+endif
+
+ifeq ($(USE_PTHREADS), 1)
+DEFINES += -D_PR_PTHREADS -UHAVE_CVAR_BUILT_ON_SEM
+endif
+
+ifeq ($(PTHREADS_USER), 1)
+DEFINES += -DPTHREADS_USER -UHAVE_CVAR_BUILT_ON_SEM
+endif
+
+ifeq ($(USE_IPV6),1)
+DEFINES += -D_PR_INET6
+endif
+
+ifeq ($(MOZ_UNICODE),1)
+DEFINES += -DMOZ_UNICODE
+endif
+
+####################################################################
+#
+# Configuration for the release process
+#
+####################################################################
+
+MDIST = /m/dist
+ifeq ($(OS_ARCH),WINNT)
+MDIST = //helium/dist
+MDIST_DOS = $(subst /,\\,$(MDIST))
+endif
+
+# RELEASE_DIR is ns/dist/<module name>
+
+RELEASE_DIR = $(MOD_DEPTH)/dist/release/$(MOD_NAME)
+
+RELEASE_INCLUDE_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/include
+RELEASE_BIN_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/bin
+RELEASE_LIB_DIR = $(RELEASE_DIR)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/lib

Added: freeswitch/trunk/libs/js/nsprpub/config/gcc_hidden.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/gcc_hidden.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2 @@
+/* Begin all files as hidden visibility */
+#pragma GCC visibility push(hidden)

Added: freeswitch/trunk/libs/js/nsprpub/config/libc_r.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/libc_r.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,158 @@
+/* -*- 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 ***** */
+
+/* libc_r.h  --  macros, defines, etc. to make using reentrant libc calls */
+/*               a bit easier.  This was initially done for AIX pthreads, */
+/*               but should be usable for anyone...                       */
+
+/* Most of these use locally defined space instead of static library space. */
+/* Because of this, we use the _INIT_R to declare/allocate space (stack),   */
+/* and the plain routines to actually do it..._WARNING_: avoid allocating   */
+/* memory wherever possible.  Memory allocation is fairly expensive, at     */
+/* least on AIX...use arrays instead (which allocate from the stack.)       */
+/* I know the names are a bit strange, but I wanted to be fairly certain    */
+/* that we didn't have any namespace corruption...in general, the inits are */
+/* R_<name>_INIT_R(), and the actual calls are R_<name>_R().                */
+
+#ifndef _LIBC_R_H
+#define _LIBC_R_H
+
+/************/
+/*  strtok  */
+/************/
+#define R_STRTOK_INIT_R() \
+    char *r_strtok_r=NULL
+
+#define R_STRTOK_R(return,source,delim) \     
+    return=strtok_r(source,delim,&r_strtok_r)
+
+#define R_STRTOK_NORET_R(source,delim) \
+    strtok_r(source,delim,&r_strtok_r)
+
+/**************/
+/*  strerror  */
+/**************/
+#define R_MAX_STRERROR_LEN_R 8192     /* Straight from limits.h */
+
+#define R_STRERROR_INIT_R() \
+    char r_strerror_r[R_MAX_STRERROR_LEN_R]
+
+#define R_STRERROR_R(val) \
+    strerror_r(val,r_strerror_r,R_MAX_STRERROR_LEN_R)
+
+/*****************/
+/*  time things  */
+/*****************/
+#define R_ASCTIME_INIT_R() \
+    char r_asctime_r[26]
+
+#define R_ASCTIME_R(val) \
+    asctime_r(val,r_asctime_r)
+
+#define R_CTIME_INIT_R() \
+    char r_ctime_r[26]
+
+#define R_CTIME_R(val) \
+    ctime_r(val,r_ctime_r)
+
+#define R_GMTIME_INIT_R() \
+    struct tm r_gmtime_r
+
+#define R_GMTIME_R(time) \
+    gmtime_r(time,&r_gmtime_r)
+
+#define R_LOCALTIME_INIT_R() \
+   struct tm r_localtime_r
+
+#define R_LOCALTIME_R(val) \
+   localtime_r(val,&r_localtime_r)
+    
+/***********/
+/*  crypt  */
+/***********/
+#include <crypt.h>
+#define R_CRYPT_INIT_R() \
+    CRYPTD r_cryptd_r; \
+    bzero(&r_cryptd_r,sizeof(CRYPTD)) 
+
+#define R_CRYPT_R(pass,salt) \
+    crypt_r(pass,salt,&r_cryptd_r)
+
+/**************/
+/*  pw stuff  */
+/**************/
+#define R_MAX_PW_LEN_R 1024
+/* The following must be after the last declaration, but */
+/* before the first bit of code...                       */
+#define R_GETPWNAM_INIT_R(pw_ptr) \
+    struct passwd r_getpwnam_pw_r; \
+    char r_getpwnam_line_r[R_MAX_PW_LEN_R]; \
+    pw_ptr = &r_getpwnam_pw_r
+
+#define R_GETPWNAM_R(name) \
+    getpwnam_r(name,&r_getpwnam_pw_r,r_getpwnam_line_r,R_MAX_PW_LEN_R)
+
+/*******************/
+/*  gethost stuff  */
+/*******************/
+#define R_GETHOSTBYADDR_INIT_R() \
+    struct hostent r_gethostbyaddr_r; \
+    struct hostent_data r_gethostbyaddr_data_r
+
+#define R_GETHOSTBYADDR_R(addr,len,type,xptr_ent) \
+    bzero(&r_gethostbyaddr_r,sizeof(struct hostent)); \
+    bzero(&r_gethostbyaddr_data_r,sizeof(struct hostent_data)); \
+    xptr_ent = &r_gethostbyaddr_r; \
+    if (gethostbyaddr_r(addr,len,type, \
+       &r_gethostbyaddr_r,&r_gethostbyaddr_data_r) == -1) { \
+           xptr_ent = NULL; \
+    }
+
+#define R_GETHOSTBYNAME_INIT_R() \
+    struct hostent r_gethostbyname_r; \
+    struct hostent_data r_gethostbyname_data_r
+
+#define R_GETHOSTBYNAME_R(name,xptr_ent) \
+    bzero(&r_gethostbyname_r,sizeof(struct hostent)); \
+    bzero(&r_gethostbyname_data_r,sizeof(struct hostent_data)); \
+    xptr_ent = &r_gethostbyname_r; \
+    if (gethostbyname_r(name, \
+       &r_gethostbyname_r,&r_gethostbyname_data_r) == -1) { \
+          xptr_ent = NULL; \
+    }
+
+#endif /* _LIBC_R_H */

Added: freeswitch/trunk/libs/js/nsprpub/config/make-system-wrappers.pl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/make-system-wrappers.pl	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,59 @@
+#!/usr/bin/perl
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# IBM Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2004
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Brian Ryner <bryner at brianryner.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+$output_dir = shift;
+
+while (<STDIN>) {
+    chomp;
+    if (-e "$output_dir/$_") {
+	next;
+    }
+
+    if (/(.*)\/[^\/*]/) {
+	mkdir "$output_dir/$1";
+    }
+
+    open OUT, ">$output_dir/$_";
+    print OUT "#pragma GCC system_header\n";  # suppress include_next warning
+    print OUT "#pragma GCC visibility push(default)\n";
+    print OUT "#include_next \<$_\>\n";
+    print OUT "#pragma GCC visibility pop\n";
+    close OUT;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/config/nfspwd.pl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/nfspwd.pl	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,50 @@
+#! perl
+# 
+# ***** 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 *****
+
+require "fastcwd.pl";
+
+$_ = &fastcwd;
+if (m@^/[uh]/@o || s@^/tmp_mnt/@/@o) {
+    print("$_\n");
+} elsif ((($user, $rest) = m@^/usr/people/(\w+)/(.*)@o)
+      && readlink("/u/$user") eq "/usr/people/$user") {
+    print("/u/$user/$rest\n");
+} else {
+    chop($host = `hostname`);
+    print("/h/$host$_\n");
+}

Added: freeswitch/trunk/libs/js/nsprpub/config/now.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/now.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,142 @@
+/* -*- 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 <stdio.h>
+#include <stdlib.h>
+
+#if defined(VMS)
+#include <sys/timeb.h>
+#elif defined(XP_UNIX) || defined(XP_OS2_EMX) || defined(XP_BEOS)
+#include <sys/time.h>
+#elif defined(WIN32)
+#include <windows.h>
+#elif defined(XP_OS2_VACPP)
+#include <sys/timeb.h>
+#else
+#error "Architecture not supported"
+#endif
+
+
+int main(int argc, char **argv)
+{
+#if defined(OMIT_LIB_BUILD_TIME)
+    /*
+     * Some platforms don't have any 64-bit integer type
+     * such as 'long long'.  Because we can't use NSPR's
+     * PR_snprintf in this program, it is difficult to
+     * print a static initializer for PRInt64 (a struct).
+     * So we print nothing.  The makefiles that build the
+     * shared libraries will detect the empty output string
+     * of this program and omit the library build time
+     * in PRVersionDescription.
+     */
+#elif defined(VMS)
+    long long now;
+    struct timeb b;
+    ftime(&b);
+    now = b.time;
+    now *= 1000000;
+    now += (1000 * b.millitm);
+    fprintf(stdout, "%Ld", now);
+#elif defined(XP_UNIX) || defined(XP_OS2_EMX) || defined(XP_BEOS)
+    long long now;
+    struct timeval tv;
+#ifdef HAVE_SVID_GETTOD
+    gettimeofday(&tv);
+#else
+    gettimeofday(&tv, NULL);
+#endif
+    now = ((1000000LL) * tv.tv_sec) + (long long)tv.tv_usec;
+#if defined(OSF1)
+    fprintf(stdout, "%ld", now);
+#elif defined(BEOS) && defined(__POWERPC__)
+    fprintf(stdout, "%Ld", now);  /* Metroworks on BeOS PPC */
+#else
+    fprintf(stdout, "%lld", now);
+#endif
+
+#elif defined(WIN32)
+    __int64 now;
+    FILETIME ft;
+    GetSystemTimeAsFileTime(&ft);
+    CopyMemory(&now, &ft, sizeof(now));
+    /*
+     * 116444736000000000 is the number of 100-nanosecond intervals
+     * between Jan. 1, 1601 and Jan. 1, 1970.
+     */
+#ifdef __GNUC__
+    now = (now - 116444736000000000LL) / 10LL;
+    fprintf(stdout, "%lld", now);
+#else
+    now = (now - 116444736000000000i64) / 10i64;
+    fprintf(stdout, "%I64d", now);
+#endif
+
+#elif defined(XP_OS2_VACPP)
+/* no long long or i64 so we use a string */
+#include <string.h>
+  char buf[24];
+  char tbuf[7];
+  time_t now;
+  long mtime;
+  int i;
+
+  struct timeb b;
+  ftime(&b);
+  now = b.time;
+  _ltoa(now, buf, 10);
+
+  mtime = b.millitm * 1000;
+  if (mtime == 0){
+    ++now;
+    strcat(buf, "000000");
+  } else {
+     _ltoa(mtime, tbuf, 10);
+     for (i = strlen(tbuf); i < 6; ++i)
+       strcat(buf, "0");
+     strcat(buf, tbuf);
+  }
+  fprintf(stdout, "%s", buf);
+
+#else
+#error "Architecture not supported"
+#endif
+
+    return 0;
+}  /* main */
+
+/* now.c */

Added: freeswitch/trunk/libs/js/nsprpub/config/nsinstall.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/nsinstall.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,602 @@
+/* -*- 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 ***** */
+
+/*
+** Netscape portable install command.
+**
+** Brendan Eich, 7/20/95
+*/
+#include <stdio.h>  /* OSF/1 requires this before grp.h, so put it first */
+#include <assert.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <utime.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stdarg.h>
+#ifdef USE_REENTRANT_LIBC
+#include "libc_r.h"
+#endif /* USE_REENTRANT_LIBC */
+
+#include "pathsub.h"
+
+#define HAVE_FCHMOD
+
+#if defined(BEOS)
+#undef HAVE_FCHMOD
+#endif
+
+/*
+ * Does getcwd() take NULL as the first argument and malloc
+ * the result buffer?
+ */
+#if !defined(DARWIN) && !defined(NEXTSTEP) && !defined(VMS)
+#define GETCWD_CAN_MALLOC
+#endif
+
+#ifdef NEXTSTEP
+#include <bsd/libc.h>
+
+/*
+** balazs.pataki at sztaki.hu: The getcwd is broken in NEXTSTEP (returns 0),
+** when called on a mounted fs. Did anyone notice this? Here's an ugly
+** workaround ...
+*/
+#define getcwd(b,s)   my_getcwd(b,s)
+
+static char *
+my_getcwd (char *buf, size_t size)
+{
+    FILE *pwd = popen("pwd", "r");
+    char *result = fgets(buf, size, pwd);
+
+    if (result) {
+        buf[strlen(buf)-1] = '\0';
+    }
+    pclose (pwd);
+    return buf;
+}
+#endif /* NEXTSTEP */
+
+#if defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) 
+#include <getopt.h>
+#endif
+
+#if defined(SCO) || defined(UNIXWARE) || defined(SNI) || defined(NCR) || defined(NEC) || defined(NEXTSTEP)
+#if !defined(S_ISLNK) && defined(S_IFLNK)
+#define S_ISLNK(a)	(((a) & S_IFMT) == S_IFLNK)
+#endif
+#endif
+
+#if defined(SNI)
+extern int fchmod(int fildes, mode_t mode);
+#endif
+
+#ifdef QNX
+#define d_ino d_stat.st_ino
+#endif
+
+static void
+usage(void)
+{
+    fprintf(stderr,
+	"usage: %s [-C cwd] [-L linkprefix] [-m mode] [-o owner] [-g group]\n"
+	"       %*s [-DdltR] file [file ...] directory\n",
+	program, (int)strlen(program), "");
+    exit(2);
+}
+
+static int
+mkdirs(char *path, mode_t mode)
+{
+    char *cp;
+    struct stat sb;
+    int res;
+    
+    while (*path == '/' && path[1] == '/')
+	path++;
+    while ((cp = strrchr(path, '/')) && cp[1] == '\0')
+	*cp = '\0';
+    if (cp && cp != path) {
+	*cp = '\0';
+	if ((stat(path, &sb) < 0 || !S_ISDIR(sb.st_mode)) &&
+	    mkdirs(path, mode) < 0) {
+	    return -1;
+	}
+	*cp = '/';
+    }
+    res = mkdir(path, mode);
+    if ((res != 0) && (errno == EEXIST))
+	return 0;
+     else
+	return res;
+}
+
+static uid_t
+touid(char *owner)
+{
+    struct passwd *pw;
+    uid_t uid;
+    char *cp;
+
+    pw = getpwnam(owner);
+    if (pw)
+	return pw->pw_uid;
+    uid = strtol(owner, &cp, 0);
+    if (uid == 0 && cp == owner)
+	fail("cannot find uid for %s", owner);
+    return uid;
+}
+
+static gid_t
+togid(char *group)
+{
+    struct group *gr;
+    gid_t gid;
+    char *cp;
+
+    gr = getgrnam(group);
+    if (gr)
+	return gr->gr_gid;
+    gid = strtol(group, &cp, 0);
+    if (gid == 0 && cp == group)
+	fail("cannot find gid for %s", group);
+    return gid;
+}
+
+int
+main(int argc, char **argv)
+{
+    int onlydir, dodir, dolink, dorelsymlink, dotimes, opt, len, lplen, tdlen, bnlen, exists, fromfd, tofd, cc, wc;
+    mode_t mode = 0755;
+    char *linkprefix, *owner, *group, *cp, *cwd, *todir, *toname, *name, *base, *linkname, *bp, buf[BUFSIZ];
+    uid_t uid;
+    gid_t gid;
+    struct stat sb, tosb;
+    struct utimbuf utb;
+
+    program = argv[0];
+    cwd = linkname = linkprefix = owner = group = 0;
+    onlydir = dodir = dolink = dorelsymlink = dotimes = lplen = 0;
+
+    while ((opt = getopt(argc, argv, "C:DdlL:Rm:o:g:t")) != EOF) {
+	switch (opt) {
+	  case 'C':
+	    cwd = optarg;
+	    break;
+	  case 'D':
+	    onlydir = 1;
+	    break;
+	  case 'd':
+	    dodir = 1;
+	    break;
+	  case 'l':
+	    dolink = 1;
+	    break;
+	  case 'L':
+	    linkprefix = optarg;
+	    lplen = strlen(linkprefix);
+	    dolink = 1;
+	    break;
+	  case 'R':
+	    dolink = dorelsymlink = 1;
+	    break;
+	  case 'm':
+	    mode = strtoul(optarg, &cp, 8);
+	    if (mode == 0 && cp == optarg)
+		usage();
+	    break;
+	  case 'o':
+	    owner = optarg;
+	    break;
+	  case 'g':
+	    group = optarg;
+	    break;
+	  case 't':
+	    dotimes = 1;
+	    break;
+	  default:
+	    usage();
+	}
+    }
+
+    argc -= optind;
+    argv += optind;
+    if (argc < 2 - onlydir)
+	usage();
+
+    todir = argv[argc-1];
+    if ((stat(todir, &sb) < 0 || !S_ISDIR(sb.st_mode)) &&
+	mkdirs(todir, 0777) < 0) {
+	fail("cannot make directory %s", todir);
+    }
+    if (onlydir)
+	return 0;
+
+    if (!cwd) {
+#ifdef GETCWD_CAN_MALLOC
+	cwd = getcwd(0, PATH_MAX);
+#else
+	cwd = malloc(PATH_MAX + 1);
+	cwd = getcwd(cwd, PATH_MAX);
+#endif
+    }
+    xchdir(todir);
+#ifdef GETCWD_CAN_MALLOC
+    todir = getcwd(0, PATH_MAX);
+#else
+    todir = malloc(PATH_MAX + 1);
+    todir = getcwd(todir, PATH_MAX);
+#endif
+    tdlen = strlen(todir);
+    xchdir(cwd);
+    tdlen = strlen(todir);
+
+    uid = owner ? touid(owner) : -1;
+    gid = group ? togid(group) : -1;
+
+    while (--argc > 0) {
+	name = *argv++;
+	len = strlen(name);
+	base = xbasename(name);
+	bnlen = strlen(base);
+	toname = (char*)xmalloc(tdlen + 1 + bnlen + 1);
+	sprintf(toname, "%s/%s", todir, base);
+	exists = (lstat(toname, &tosb) == 0);
+
+	if (dodir) {
+	    /* -d means create a directory, always */
+	    if (exists && !S_ISDIR(tosb.st_mode)) {
+		(void) unlink(toname);
+		exists = 0;
+	    }
+	    if (!exists && mkdir(toname, mode) < 0)
+		fail("cannot make directory %s", toname);
+	    if ((owner || group) && chown(toname, uid, gid) < 0)
+		fail("cannot change owner of %s", toname);
+	} else if (dolink) {
+	    if (*name == '/') {
+		/* source is absolute pathname, link to it directly */
+		linkname = 0;
+	    } else {
+		if (linkprefix) {
+		    /* -L implies -l and prefixes names with a $cwd arg. */
+		    len += lplen + 1;
+		    linkname = (char*)xmalloc(len + 1);
+		    sprintf(linkname, "%s/%s", linkprefix, name);
+		} else if (dorelsymlink) {
+		    /* Symlink the relative path from todir to source name. */
+		    linkname = (char*)xmalloc(PATH_MAX);
+
+		    if (*todir == '/') {
+			/* todir is absolute: skip over common prefix. */
+			lplen = relatepaths(todir, cwd, linkname);
+			strcpy(linkname + lplen, name);
+		    } else {
+			/* todir is named by a relative path: reverse it. */
+			reversepath(todir, name, len, linkname);
+			xchdir(cwd);
+		    }
+
+		    len = strlen(linkname);
+		}
+		name = linkname;
+	    }
+
+	    /* Check for a pre-existing symlink with identical content. */
+	    if (exists &&
+		(!S_ISLNK(tosb.st_mode) ||
+		 readlink(toname, buf, sizeof buf) != len ||
+		 strncmp(buf, name, len) != 0)) {
+		(void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname);
+		exists = 0;
+	    }
+	    if (!exists && symlink(name, toname) < 0)
+		fail("cannot make symbolic link %s", toname);
+#ifdef HAVE_LCHOWN
+	    if ((owner || group) && lchown(toname, uid, gid) < 0)
+		fail("cannot change owner of %s", toname);
+#endif
+
+	    if (linkname) {
+		free(linkname);
+		linkname = 0;
+	    }
+	} else {
+	    /* Copy from name to toname, which might be the same file. */
+	    fromfd = open(name, O_RDONLY);
+	    if (fromfd < 0 || fstat(fromfd, &sb) < 0)
+		fail("cannot access %s", name);
+	    if (exists && (!S_ISREG(tosb.st_mode) || access(toname, W_OK) < 0))
+		(void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname);
+	    tofd = open(toname, O_CREAT | O_WRONLY, 0666);
+	    if (tofd < 0)
+		fail("cannot create %s", toname);
+
+	    bp = buf;
+	    while ((cc = read(fromfd, bp, sizeof buf)) > 0) {
+		while ((wc = write(tofd, bp, cc)) > 0) {
+		    if ((cc -= wc) == 0)
+			break;
+		    bp += wc;
+		}
+		if (wc < 0)
+		    fail("cannot write to %s", toname);
+	    }
+	    if (cc < 0)
+		fail("cannot read from %s", name);
+
+	    if (ftruncate(tofd, sb.st_size) < 0)
+		fail("cannot truncate %s", toname);
+	    /*
+	    ** On OpenVMS we can't chmod() until the file is closed, and we
+	    ** have to utime() last since fchown/chmod alter the timestamps.
+	    */
+#ifndef VMS
+	    if (dotimes) {
+		utb.actime = sb.st_atime;
+		utb.modtime = sb.st_mtime;
+		if (utime(toname, &utb) < 0)
+		    fail("cannot set times of %s", toname);
+	    }
+#ifdef HAVE_FCHMOD
+	    if (fchmod(tofd, mode) < 0)
+#else
+	    if (chmod(toname, mode) < 0)
+#endif
+		fail("cannot change mode of %s", toname);
+#endif
+	    if ((owner || group) && fchown(tofd, uid, gid) < 0)
+		fail("cannot change owner of %s", toname);
+
+	    /* Must check for delayed (NFS) write errors on close. */
+	    if (close(tofd) < 0)
+		fail("cannot write to %s", toname);
+	    close(fromfd);
+#ifdef VMS
+	    if (chmod(toname, mode) < 0)
+		fail("cannot change mode of %s", toname);
+	    if (dotimes) {
+		utb.actime = sb.st_atime;
+		utb.modtime = sb.st_mtime;
+		if (utime(toname, &utb) < 0)
+		    fail("cannot set times of %s", toname);
+	    }
+#endif
+	}
+
+	free(toname);
+    }
+
+    free(cwd);
+    free(todir);
+    return 0;
+}
+
+/*
+** Pathname subroutines.
+**
+** Brendan Eich, 8/29/95
+*/
+
+char *program;
+
+void
+fail(char *format, ...)
+{
+    int error;
+    va_list ap;
+
+#ifdef USE_REENTRANT_LIBC
+    R_STRERROR_INIT_R();
+#endif
+
+    error = errno;
+    fprintf(stderr, "%s: ", program);
+    va_start(ap, format);
+    vfprintf(stderr, format, ap);
+    va_end(ap);
+    if (error)
+
+#ifdef USE_REENTRANT_LIBC
+    R_STRERROR_R(errno);
+	fprintf(stderr, ": %s", r_strerror_r);
+#else
+	fprintf(stderr, ": %s", strerror(errno));
+#endif
+
+    putc('\n', stderr);
+    exit(1);
+}
+
+char *
+getcomponent(char *path, char *name)
+{
+    if (*path == '\0')
+	return 0;
+    if (*path == '/') {
+	*name++ = '/';
+    } else {
+	do {
+	    *name++ = *path++;
+	} while (*path != '/' && *path != '\0');
+    }
+    *name = '\0';
+    while (*path == '/')
+	path++;
+    return path;
+}
+
+#ifdef UNIXWARE_READDIR_BUFFER_TOO_SMALL
+/* Sigh.  The static buffer in Unixware's readdir is too small. */
+struct dirent * readdir(DIR *d)
+{
+        static struct dirent *buf = NULL;
+#define MAX_PATH_LEN 1024
+
+
+        if(buf == NULL)
+                buf = (struct dirent *) malloc(sizeof(struct dirent) + MAX_PATH_LEN)
+;
+        return(readdir_r(d, buf));
+}
+#endif
+
+char *
+ino2name(ino_t ino, char *dir)
+{
+    DIR *dp;
+    struct dirent *ep;
+    char *name;
+
+    dp = opendir("..");
+    if (!dp)
+	fail("cannot read parent directory");
+    for (;;) {
+	if (!(ep = readdir(dp)))
+	    fail("cannot find current directory");
+	if (ep->d_ino == ino)
+	    break;
+    }
+    name = xstrdup(ep->d_name);
+    closedir(dp);
+    return name;
+}
+
+void *
+xmalloc(size_t size)
+{
+    void *p = malloc(size);
+    if (!p)
+	fail("cannot allocate %u bytes", size);
+    return p;
+}
+
+char *
+xstrdup(char *s)
+{
+    return strcpy((char*)xmalloc(strlen(s) + 1), s);
+}
+
+char *
+xbasename(char *path)
+{
+    char *cp;
+
+    while ((cp = strrchr(path, '/')) && cp[1] == '\0')
+	*cp = '\0';
+    if (!cp) return path;
+    return cp + 1;
+}
+
+void
+xchdir(char *dir)
+{
+    if (chdir(dir) < 0)
+	fail("cannot change directory to %s", dir);
+}
+
+int
+relatepaths(char *from, char *to, char *outpath)
+{
+    char *cp, *cp2;
+    int len;
+    char buf[NAME_MAX];
+
+    assert(*from == '/' && *to == '/');
+    for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++)
+	if (*cp == '\0')
+	    break;
+    while (cp[-1] != '/')
+	cp--, cp2--;
+    if (cp - 1 == to) {
+	/* closest common ancestor is /, so use full pathname */
+	len = strlen(strcpy(outpath, to));
+	if (outpath[len] != '/') {
+	    outpath[len++] = '/';
+	    outpath[len] = '\0';
+	}
+    } else {
+	len = 0;
+	while ((cp2 = getcomponent(cp2, buf)) != 0) {
+	    strcpy(outpath + len, "../");
+	    len += 3;
+	}
+	while ((cp = getcomponent(cp, buf)) != 0) {
+	    sprintf(outpath + len, "%s/", buf);
+	    len += strlen(outpath + len);
+	}
+    }
+    return len;
+}
+
+void
+reversepath(char *inpath, char *name, int len, char *outpath)
+{
+    char *cp, *cp2;
+    char buf[NAME_MAX];
+    struct stat sb;
+
+    cp = strcpy(outpath + PATH_MAX - (len + 1), name);
+    cp2 = inpath;
+    while ((cp2 = getcomponent(cp2, buf)) != 0) {
+	if (strcmp(buf, ".") == 0)
+	    continue;
+	if (strcmp(buf, "..") == 0) {
+	    if (stat(".", &sb) < 0)
+		fail("cannot stat current directory");
+	    name = ino2name(sb.st_ino, "..");
+	    len = strlen(name);
+	    cp -= len + 1;
+	    strcpy(cp, name);
+	    cp[len] = '/';
+	    free(name);
+	    xchdir("..");
+	} else {
+	    cp -= 3;
+	    strncpy(cp, "../", 3);
+	    xchdir(buf);
+	}
+    }
+    strcpy(outpath, cp);
+}

Added: freeswitch/trunk/libs/js/nsprpub/config/nspr-config.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/nspr-config.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,143 @@
+#!/bin/sh
+
+prefix=@prefix@
+
+major_version=@MOD_MAJOR_VERSION@
+minor_version=@MOD_MINOR_VERSION@
+patch_version=@MOD_PATCH_VERSION@
+
+usage()
+{
+	cat <<EOF
+Usage: nspr-config [OPTIONS] [LIBRARIES]
+Options:
+	[--prefix[=DIR]]
+	[--exec-prefix[=DIR]]
+	[--includedir[=DIR]]
+	[--libdir[=DIR]]
+	[--version]
+	[--libs]
+	[--cflags]
+Libraries:
+	nspr
+	plc
+	plds
+EOF
+	exit $1
+}
+
+if test $# -eq 0; then
+	usage 1 1>&2
+fi
+
+lib_nspr=yes
+lib_plc=yes
+lib_plds=yes
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      ;;
+    --prefix)
+      echo_prefix=yes
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      ;;
+    --exec-prefix)
+      echo_exec_prefix=yes
+      ;;
+    --includedir=*)
+      includedir=$optarg
+      ;;
+    --includedir)
+      echo_includedir=yes
+      ;;
+    --libdir=*)
+      libdir=$optarg
+      ;;
+    --libdir)
+      echo_libdir=yes
+      ;;
+    --version)
+      echo ${major_version}.${minor_version}.${patch_version}
+      ;;
+    --cflags)
+      echo_cflags=yes
+      ;;
+    --libs)
+      echo_libs=yes
+      ;;
+    nspr)
+      lib_nspr=yes
+      ;;
+    plc)
+      lib_plc=yes
+      ;;
+    plds)
+      lib_plds=yes
+      ;;
+    *)
+      usage 1 1>&2
+      ;;
+  esac
+  shift
+done
+
+# Set variables that may be dependent upon other variables
+if test -z "$exec_prefix"; then
+    exec_prefix=@exec_prefix@
+fi
+if test -z "$includedir"; then
+    includedir=@includedir@
+fi
+if test -z "$libdir"; then
+    libdir=@libdir@
+fi
+
+if test "$echo_prefix" = "yes"; then
+    echo $prefix
+fi
+
+if test "$echo_exec_prefix" = "yes"; then
+    echo $exec_prefix
+fi
+
+if test "$echo_includedir" = "yes"; then
+    echo $includedir
+fi
+
+if test "$echo_libdir" = "yes"; then
+    echo $libdir
+fi
+
+if test "$echo_cflags" = "yes"; then
+    echo -I$includedir
+fi
+
+if test "$echo_libs" = "yes"; then
+      libdirs=-L$libdir
+      if test -n "$lib_plds"; then
+	libdirs="$libdirs -lplds${major_version}"
+      fi
+      if test -n "$lib_plc"; then
+	libdirs="$libdirs -lplc${major_version}"
+      fi
+      if test -n "$lib_nspr"; then
+	libdirs="$libdirs -lnspr${major_version}"
+      fi
+      os_ldflags="@LDFLAGS@"
+      for i in $os_ldflags ; do
+	if echo $i | grep \^-L >/dev/null; then
+	  libdirs="$libdirs $i"
+        fi
+      done
+      echo $libdirs @OS_LIBS@
+fi      
+

Added: freeswitch/trunk/libs/js/nsprpub/config/nspr.m4
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/nspr.m4	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,67 @@
+# -*- tab-width: 4; -*-
+# Configure paths for NSPR
+# Public domain - Chris Seawood <cls at seawood.org> 2001-04-05
+# Based upon gtk.m4 (also PD) by Owen Taylor
+
+dnl AM_PATH_NSPR([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for NSPR, and define NSPR_CFLAGS and NSPR_LIBS
+AC_DEFUN(AM_PATH_NSPR,
+[dnl
+
+AC_ARG_WITH(nspr-prefix,
+	[  --with-nspr-prefix=PFX  Prefix where NSPR is installed],
+	nspr_config_prefix="$withval",
+	nspr_config_prefix="")
+
+AC_ARG_WITH(nspr-exec-prefix,
+	[  --with-nspr-exec-prefix=PFX
+                          Exec prefix where NSPR is installed],
+	nspr_config_exec_prefix="$withval",
+	nspr_config_exec_prefix="")
+
+	if test -n "$nspr_config_exec_prefix"; then
+		nspr_config_args="$nspr_config_args --exec-prefix=$nspr_config_exec_prefix"
+		if test -z "$NSPR_CONFIG"; then
+			NSPR_CONFIG=$nspr_config_exec_prefix/bin/nspr-config
+		fi
+	fi
+	if test -n "$nspr_config_prefix"; then
+		nspr_config_args="$nspr_config_args --prefix=$nspr_config_prefix"
+		if test -z "$NSPR_CONFIG"; then
+			NSPR_CONFIG=$nspr_config_prefix/bin/nspr-config
+		fi
+	fi
+
+	unset ac_cv_path_NSPR_CONFIG
+	AC_PATH_PROG(NSPR_CONFIG, nspr-config, no)
+	min_nspr_version=ifelse([$1], ,4.0.0,$1)
+	AC_MSG_CHECKING(for NSPR - version >= $min_nspr_version (skipping))
+
+	no_nspr=""
+	if test "$NSPR_CONFIG" = "no"; then
+		no_nspr="yes"
+	else
+		NSPR_CFLAGS=`$NSPR_CONFIG $nspr_config_args --cflags`
+		NSPR_LIBS=`$NSPR_CONFIG $nspr_config_args --libs`
+
+		dnl Skip version check for now
+		nspr_config_major_version=`$NSPR_CONFIG $nspr_config_args --version | \
+			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+		nspr_config_minor_version=`$NSPR_CONFIG $nspr_config_args --version | \
+			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+		nspr_config_micro_version=`$NSPR_CONFIG $nspr_config_args --version | \
+			sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+	fi
+
+	if test -z "$no_nspr"; then
+		AC_MSG_RESULT(yes)
+		ifelse([$2], , :, [$2])     
+	else
+		AC_MSG_RESULT(no)
+	fi
+
+
+	AC_SUBST(NSPR_CFLAGS)
+	AC_SUBST(NSPR_LIBS)
+
+])

Added: freeswitch/trunk/libs/js/nsprpub/config/nsprincl.mk.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/nsprincl.mk.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+# Include in Makefiles to define NSPR variables
+
+NSPR_VERSION    = @NSPR_VERSION@
+NSPR_LIB        = -lnspr at NSPR_VERSION@
+NSPR_EXTRA_LIBS = @EXTRA_LIBS@

Added: freeswitch/trunk/libs/js/nsprpub/config/nsprincl.sh.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/nsprincl.sh.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+# Include in shell scripts to define NSPR variables
+
+NSPR_VERSION=@NSPR_VERSION@
+NSPR_LIB=-lnspr$NSPR_VERSION
+NSPR_EXTRA_LIBS="@EXTRA_LIBS@"

Added: freeswitch/trunk/libs/js/nsprpub/config/pathsub.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/pathsub.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,78 @@
+/* -*- 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 pathsub_h___
+#define pathsub_h___
+/*
+** Pathname subroutines.
+**
+** Brendan Eich, 8/29/95
+*/
+#include <limits.h>
+#include <sys/types.h>
+
+#if SUNOS4
+#include "../pr/include/md/sunos4.h"
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+/*
+ * Just prevent stupidity
+ */
+#undef NAME_MAX
+#define NAME_MAX 256
+
+extern char *program;
+
+extern void fail(char *format, ...);
+extern char *getcomponent(char *path, char *name);
+extern char *ino2name(ino_t ino, char *dir);
+extern void *xmalloc(size_t size);
+extern char *xstrdup(char *s);
+extern char *xbasename(char *path);
+extern void xchdir(char *dir);
+
+/* Relate absolute pathnames from and to returning the result in outpath. */
+extern int relatepaths(char *from, char *to, char *outpath);
+
+/* XXX changes current working directory -- caveat emptor */
+extern void reversepath(char *inpath, char *name, int len, char *outpath);
+
+#endif /* pathsub_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/config/prdepend.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/prdepend.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,44 @@
+/* -*- 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) 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 ***** */
+
+/*
+ * A dummy header file that is a dependency for all the object files.
+ * Used to force a full recompilation of NSPR in Mozilla's Tinderbox
+ * depend builds.  See comments in rules.mk.
+ */
+
+#error "Do not include this header file."

Added: freeswitch/trunk/libs/js/nsprpub/config/prmkdir.bat
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/prmkdir.bat	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,38 @@
+REM 
+REM ***** BEGIN LICENSE BLOCK *****
+REM Version: MPL 1.1/GPL 2.0/LGPL 2.1
+REM
+REM The contents of this file are subject to the Mozilla Public License Version
+REM 1.1 (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM http://www.mozilla.org/MPL/
+REM
+REM Software distributed under the License is distributed on an "AS IS" basis,
+REM WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+REM for the specific language governing rights and limitations under the
+REM License.
+REM
+REM The Original Code is the Netscape Portable Runtime (NSPR).
+REM
+REM The Initial Developer of the Original Code is
+REM Netscape Communications Corporation.
+REM Portions created by the Initial Developer are Copyright (C) 1998-2000
+REM the Initial Developer. All Rights Reserved.
+REM
+REM Contributor(s):
+REM
+REM Alternatively, the contents of this file may be used under the terms of
+REM either the GNU General Public License Version 2 or later (the "GPL"), or
+REM the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+REM in which case the provisions of the GPL or the LGPL are applicable instead
+REM of those above. If you wish to allow use of your version of this file only
+REM under the terms of either the GPL or the LGPL, and not to allow others to
+REM use your version of this file under the terms of the MPL, indicate your
+REM decision by deleting the provisions above and replace them with the notice
+REM and other provisions required by the GPL or the LGPL. If you do not delete
+REM the provisions above, a recipient may use your version of this file under
+REM the terms of any one of the MPL, the GPL or the LGPL.
+REM
+REM ***** END LICENSE BLOCK *****
+
+mkdir %1

Added: freeswitch/trunk/libs/js/nsprpub/config/rules.mk
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/rules.mk	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,515 @@
+#! gmake
+# 
+# ***** 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 *****
+
+################################################################################
+# We used to have a 4 pass build process.  Now we do everything in one pass.
+#
+# export - Create generated headers and stubs. Publish public headers to
+#          dist/<arch>/include.
+#          Create libraries. Publish libraries to dist/<arch>/lib.
+#          Create programs. 
+#
+# libs - obsolete.  Now a synonym of "export".
+#
+# all - the default makefile target.  Now a synonym of "export".
+#
+# install - Install headers, libraries, and programs on the system.
+#
+# Parameters to this makefile (set these before including):
+#
+# a)
+#	TARGETS	-- the target to create 
+#			(defaults to $LIBRARY $PROGRAM)
+# b)
+#	DIRS	-- subdirectories for make to recurse on
+#			(the 'all' rule builds $TARGETS $DIRS)
+# c)
+#	CSRCS   -- .c files to compile
+#			(used to define $OBJS)
+# d)
+#	PROGRAM	-- the target program name to create from $OBJS
+#			($OBJDIR automatically prepended to it)
+# e)
+#	LIBRARY	-- the target library name to create from $OBJS
+#			($OBJDIR automatically prepended to it)
+#
+################################################################################
+
+ifndef topsrcdir
+topsrcdir=$(MOD_DEPTH)
+endif
+
+ifndef srcdir
+srcdir=.
+endif
+
+ifndef NSPR_CONFIG_MK
+include $(topsrcdir)/config/config.mk
+endif
+
+ifdef USE_AUTOCONF
+ifdef CROSS_COMPILE
+ifdef INTERNAL_TOOLS
+CC=$(HOST_CC)
+CCC=$(HOST_CXX)
+CFLAGS=$(HOST_CFLAGS)
+CXXFLAGS=$(HOST_CXXFLAGS)
+LDFLAGS=$(HOST_LDFLAGS)
+endif
+endif
+endif
+
+#
+# This makefile contains rules for building the following kinds of
+# libraries:
+# - LIBRARY: a static (archival) library
+# - SHARED_LIBRARY: a shared (dynamic link) library
+# - IMPORT_LIBRARY: an import library, used only on Windows and OS/2
+#
+# The names of these libraries can be generated by simply specifying
+# LIBRARY_NAME and LIBRARY_VERSION.
+#
+
+ifdef LIBRARY_NAME
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+
+#
+# Win95, Win16, and OS/2 require library names conforming to the 8.3 rule.
+# other platforms do not.
+#
+ifeq (,$(filter-out WIN95 OS2,$(OS_TARGET)))
+LIBRARY		= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.$(LIB_SUFFIX)
+SHARED_LIBRARY	= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
+IMPORT_LIBRARY	= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX)
+SHARED_LIB_PDB	= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).pdb
+else
+LIBRARY		= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.$(LIB_SUFFIX)
+SHARED_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
+IMPORT_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX)
+SHARED_LIB_PDB	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).pdb
+endif
+
+else
+
+LIBRARY		= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX)
+ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.1)
+SHARED_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION)_shr.a
+else
+ifdef MKSHLIB
+SHARED_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
+endif
+endif
+
+endif
+endif
+
+ifndef TARGETS
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+TARGETS		= $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY)
+ifndef BUILD_OPT
+ifdef MSC_VER
+ifneq (,$(filter-out 1100 1200,$(MSC_VER)))
+TARGETS		+= $(SHARED_LIB_PDB)
+endif
+endif
+endif
+else
+TARGETS		= $(LIBRARY) $(SHARED_LIBRARY)
+endif
+endif
+
+#
+# OBJS is the list of object files.  It can be constructed by
+# specifying CSRCS (list of C source files) and ASFILES (list
+# of assembly language source files).
+#
+
+ifndef OBJS
+OBJS		= $(addprefix $(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX))) \
+		  $(addprefix $(OBJDIR)/,$(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX)))
+endif
+
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+EXTRA_LIBS := $(patsubst -l%,$(DIST)/lib/%.$(LIB_SUFFIX),$(EXTRA_LIBS))
+endif
+
+ALL_TRASH		= $(TARGETS) $(OBJS) $(RES) $(filter-out . .., $(OBJDIR)) LOGS TAGS $(GARBAGE) \
+			  $(NOSUCHFILE) \
+			  so_locations
+
+ifeq ($(OS_ARCH),OpenVMS)
+ALL_TRASH		+= $(wildcard *.c*_defines)
+ifdef SHARED_LIBRARY
+VMS_SYMVEC_FILE		= $(SHARED_LIBRARY:.$(DLL_SUFFIX)=_symvec.opt)
+VMS_SYMVEC_FILE_MODULE	= $(srcdir)/$(LIBRARY_NAME)_symvec.opt
+ALL_TRASH		+= $(VMS_SYMVEC_FILE)
+endif
+endif
+
+ifndef RELEASE_LIBS_DEST
+RELEASE_LIBS_DEST	= $(RELEASE_LIB_DIR)
+endif
+
+ifdef DIRS
+LOOP_OVER_DIRS		=					\
+	@for d in $(DIRS); do					\
+		if test -d $$d; then				\
+			set -e;					\
+			echo "cd $$d; $(MAKE) $@";		\
+			$(MAKE) -C $$d $@;			\
+			set +e;					\
+		else						\
+			echo "Skipping non-directory $$d...";	\
+		fi;						\
+	done
+endif
+
+################################################################################
+
+all:: export
+
+export::
+	+$(LOOP_OVER_DIRS)
+
+libs:: export
+
+clean::
+	rm -rf $(OBJS) $(RES) so_locations $(NOSUCHFILE) $(GARBAGE)
+	+$(LOOP_OVER_DIRS)
+
+clobber::
+	rm -rf $(OBJS) $(RES) $(TARGETS) $(filter-out . ..,$(OBJDIR)) $(GARBAGE) so_locations $(NOSUCHFILE)
+	+$(LOOP_OVER_DIRS)
+
+realclean clobber_all::
+	rm -rf $(wildcard *.OBJ *.OBJD) dist $(ALL_TRASH)
+	+$(LOOP_OVER_DIRS)
+
+distclean::
+	rm -rf $(wildcard *.OBJ *.OBJD) dist $(ALL_TRASH) $(DIST_GARBAGE)
+	+$(LOOP_OVER_DIRS)
+
+install:: $(RELEASE_BINS) $(RELEASE_HEADERS) $(RELEASE_LIBS)
+ifdef RELEASE_BINS
+	$(NSINSTALL) -t -m 0755 $(RELEASE_BINS) $(DESTDIR)$(bindir)
+endif
+ifdef RELEASE_HEADERS
+	$(NSINSTALL) -t -m 0644 $(RELEASE_HEADERS) $(DESTDIR)$(includedir)/$(include_subdir)
+endif
+ifdef RELEASE_LIBS
+	$(NSINSTALL) -t -m 0755 $(RELEASE_LIBS) $(DESTDIR)$(libdir)/$(lib_subdir)
+endif
+	+$(LOOP_OVER_DIRS)
+
+release:: export
+ifdef RELEASE_BINS
+	@echo "Copying executable programs and scripts to release directory"
+	@if test -z "$(BUILD_NUMBER)"; then \
+		echo "BUILD_NUMBER must be defined"; \
+		false; \
+	else \
+		true; \
+	fi
+	@if test ! -d $(RELEASE_BIN_DIR); then \
+		rm -rf $(RELEASE_BIN_DIR); \
+		$(NSINSTALL) -D $(RELEASE_BIN_DIR);\
+	else \
+		true; \
+	fi
+	cp $(RELEASE_BINS) $(RELEASE_BIN_DIR)
+endif
+ifdef RELEASE_LIBS
+	@echo "Copying libraries to release directory"
+	@if test -z "$(BUILD_NUMBER)"; then \
+		echo "BUILD_NUMBER must be defined"; \
+		false; \
+	else \
+		true; \
+	fi
+	@if test ! -d $(RELEASE_LIBS_DEST); then \
+		rm -rf $(RELEASE_LIBS_DEST); \
+		$(NSINSTALL) -D $(RELEASE_LIBS_DEST);\
+	else \
+		true; \
+	fi
+	cp $(RELEASE_LIBS) $(RELEASE_LIBS_DEST)
+endif
+ifdef RELEASE_HEADERS
+	@echo "Copying header files to release directory"
+	@if test -z "$(BUILD_NUMBER)"; then \
+		echo "BUILD_NUMBER must be defined"; \
+		false; \
+	else \
+		true; \
+	fi
+	@if test ! -d $(RELEASE_HEADERS_DEST); then \
+		rm -rf $(RELEASE_HEADERS_DEST); \
+		$(NSINSTALL) -D $(RELEASE_HEADERS_DEST);\
+	else \
+		true; \
+	fi
+	cp $(RELEASE_HEADERS) $(RELEASE_HEADERS_DEST)
+endif
+	+$(LOOP_OVER_DIRS)
+
+alltags:
+	rm -f TAGS tags
+	find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs etags -a
+	find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs ctags -a
+
+$(NFSPWD):
+	cd $(@D); $(MAKE) $(@F)
+
+$(PROGRAM): $(OBJS)
+	@$(MAKE_OBJDIR)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	$(CC) $(OBJS) -Fe$@ -link $(LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS)
+else
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+	$(CC) $(OBJS) -Fe$@ $(LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS)
+else
+	$(CC) -o $@ $(CFLAGS) $(OBJS) $(LDFLAGS)
+endif
+endif
+ifdef ENABLE_STRIP
+	$(STRIP) $@
+endif
+
+$(LIBRARY): $(OBJS)
+	@$(MAKE_OBJDIR)
+	rm -f $@
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+	$(AR) $(subst /,\\,$(OBJS)) $(AR_FLAGS)
+else
+	$(AR) $(AR_FLAGS) $(OBJS) $(AR_EXTRA_ARGS)
+endif
+	$(RANLIB) $@
+
+ifeq ($(OS_TARGET), OS2)
+$(IMPORT_LIBRARY): $(MAPFILE)
+	rm -f $@
+	$(IMPLIB) $@ $(MAPFILE)
+endif
+
+$(SHARED_LIBRARY): $(OBJS) $(RES) $(MAPFILE)
+	@$(MAKE_OBJDIR)
+	rm -f $@
+ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.1)
+	echo "#!" > $(OBJDIR)/lib$(LIBRARY_NAME)_syms
+	nm -B -C -g $(OBJS) \
+		| awk '/ [T,D] / {print $$3}' \
+		| sed -e 's/^\.//' \
+		| sort -u >> $(OBJDIR)/lib$(LIBRARY_NAME)_syms
+	$(LD) $(XCFLAGS) -o $@ $(OBJS) -bE:$(OBJDIR)/lib$(LIBRARY_NAME)_syms \
+		-bM:SRE -bnoentry $(OS_LIBS) $(EXTRA_LIBS)
+else	# AIX 4.1
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	$(LINK_DLL) -MAP $(DLLBASE) $(DLL_LIBS) $(EXTRA_LIBS) $(OBJS) $(RES)
+else
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+	$(LINK_DLL) $(DLLBASE) $(OBJS) $(OS_LIBS) $(EXTRA_LIBS) $(MAPFILE)
+else	# !os2 vacpp
+ifeq ($(OS_TARGET), OpenVMS)
+	@if test ! -f $(VMS_SYMVEC_FILE); then \
+	  if test -f $(VMS_SYMVEC_FILE_MODULE); then \
+	    echo Creating component options file $(VMS_SYMVEC_FILE); \
+	    cp $(VMS_SYMVEC_FILE_MODULE) $(VMS_SYMVEC_FILE); \
+	  fi; \
+	fi
+endif	# OpenVMS
+	$(MKSHLIB) $(OBJS) $(RES) $(EXTRA_LIBS)
+endif   # OS2 vacpp
+endif	# WINNT
+endif	# AIX 4.1
+ifdef ENABLE_STRIP
+	$(STRIP) $@
+endif
+
+ifeq ($(OS_ARCH),WINNT)
+$(RES): $(RESNAME)
+	@$(MAKE_OBJDIR)
+# The resource compiler does not understand the -U option.
+ifdef NS_USE_GCC
+	$(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) -o $@ $<
+else
+	$(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES) -Fo$@ $<
+endif # GCC
+	@echo $(RES) finished
+endif
+
+$(MAPFILE): $(LIBRARY_NAME).def
+	@$(MAKE_OBJDIR)
+ifeq ($(OS_ARCH),SunOS)
+	grep -v ';-' $< | \
+	sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@
+endif
+ifeq ($(OS_ARCH),OS2)
+	echo LIBRARY $(LIBRARY_NAME)$(LIBRARY_VERSION) INITINSTANCE TERMINSTANCE > $@
+	echo PROTMODE >> $@
+	echo CODE    LOADONCALL MOVEABLE DISCARDABLE >> $@
+	echo DATA    PRELOAD MOVEABLE MULTIPLE NONSHARED >> $@
+	echo EXPORTS >> $@
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+	grep -v ';+' $< | grep -v ';-' | \
+	sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' >> $@
+else
+	grep -v ';+' $< | grep -v ';-' | \
+	sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,\([\t ]*\),\1_,' | \
+	awk 'BEGIN {ord=1;} { print($$0 " @" ord " RESIDENTNAME"); ord++;}'	>> $@
+	$(ADD_TO_DEF_FILE)
+endif
+endif
+
+#
+# Translate source filenames to absolute paths. This is required for
+# debuggers under Windows and OS/2 to find source files automatically.
+#
+
+ifeq (,$(filter-out AIX OS2,$(OS_ARCH)))
+NEED_ABSOLUTE_PATH = 1
+endif
+
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+NEED_ABSOLUTE_PATH = 1
+endif
+
+ifdef NEED_ABSOLUTE_PATH
+PWD := $(shell pwd)
+abspath = $(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(PWD)/$(1)))
+endif
+
+$(OBJDIR)/%.$(OBJ_SUFFIX): %.cpp
+	@$(MAKE_OBJDIR)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	$(CCC) -Fo$@ -c $(CCCFLAGS) $(call abspath,$<)
+else
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+	$(CCC) -Fo$@ -c $(CCCFLAGS) $(call abspath,$<)
+else
+ifdef NEED_ABSOLUTE_PATH
+	$(CCC) -o $@ -c $(CCCFLAGS) $(call abspath,$<)
+else
+	$(CCC) -o $@ -c $(CCCFLAGS) $<
+endif
+endif
+endif
+
+WCCFLAGS1 = $(subst /,\\,$(CFLAGS))
+WCCFLAGS2 = $(subst -I,-i=,$(WCCFLAGS1))
+WCCFLAGS3 = $(subst -D,-d,$(WCCFLAGS2))
+$(OBJDIR)/%.$(OBJ_SUFFIX): %.c
+	@$(MAKE_OBJDIR)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	$(CC) -Fo$@ -c $(CFLAGS) $(call abspath,$<)
+else
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+	$(CC) -Fo$@ -c $(CFLAGS) $(call abspath,$<)
+else
+ifdef NEED_ABSOLUTE_PATH
+	$(CC) -o $@ -c $(CFLAGS) $(call abspath,$<)
+else
+	$(CC) -o $@ -c $(CFLAGS) $<
+endif
+endif
+endif
+
+
+$(OBJDIR)/%.$(OBJ_SUFFIX): %.s
+	@$(MAKE_OBJDIR)
+	$(AS) -o $@ $(ASFLAGS) -c $<
+
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+$(OBJDIR)/%.$(OBJ_SUFFIX): %.asm
+	@$(MAKE_OBJDIR)
+	$(AS) -Fdo:./$(OBJDIR) $(ASFLAGS) $<
+endif
+
+%.i: %.c
+	$(CC) -C -E $(CFLAGS) $< > $*.i
+
+%: %.pl
+	rm -f $@; cp $< $@; chmod +x $@
+
+#
+# HACK ALERT
+#
+# The only purpose of this rule is to pass Mozilla's Tinderbox depend
+# builds (http://tinderbox.mozilla.org/showbuilds.cgi).  Mozilla's
+# Tinderbox builds NSPR continuously as part of the Mozilla client.
+# Because NSPR's make depend is not implemented, whenever we change
+# an NSPR header file, the depend build does not recompile the NSPR
+# files that depend on the header.
+#
+# This rule makes all the objects depend on a dummy header file.
+# Touch this dummy header file to force the depend build to recompile
+# everything.
+#
+# This rule should be removed when make depend is implemented.
+#
+
+DUMMY_DEPEND_H = $(topsrcdir)/config/prdepend.h
+
+$(filter $(OBJDIR)/%.$(OBJ_SUFFIX),$(OBJS)): $(OBJDIR)/%.$(OBJ_SUFFIX): $(DUMMY_DEPEND_H)
+
+# END OF HACK
+
+################################################################################
+# Special gmake rules.
+################################################################################
+
+#
+# Re-define the list of default suffixes, so gmake won't have to churn through
+# hundreds of built-in suffix rules for stuff we don't need.
+#
+.SUFFIXES:
+.SUFFIXES: .a .$(OBJ_SUFFIX) .c .cpp .s .h .i .pl
+
+#
+# Fake targets.  Always run these rules, even if a file/directory with that
+# name already exists.
+#
+.PHONY: all alltags clean export install libs realclean release
+
+#
+# List the target pattern of an implicit rule as a dependency of the
+# special target .PRECIOUS to preserve intermediate files made by
+# implicit rules whose target patterns match that file's name.
+# (See GNU Make documentation, Edition 0.51, May 1996, Sec. 10.4,
+# p. 107.)
+#
+.PRECIOUS: $(OBJDIR)/%.$(OBJ_SUFFIX)

Added: freeswitch/trunk/libs/js/nsprpub/config/system-headers
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/config/system-headers	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,172 @@
+Aliases.h
+arpa/inet.h
+assert.h
+bsd/libc.h
+bsd/syscall.h
+bstring.h
+builtin.h
+c_asm.h
+cf.h
+CFBundle.h
+CFData.h
+CFDictionary.h
+CFString.h
+CFURL.h
+CodeFragments.h
+commdlg.h
+crt_externs.h
+crypt.h
+ctype.h
+descrip.h
+Devices.h
+direct.h
+dirent.h
+dlfcn.h
+dl.h
+DriverServices.h
+dvidef.h
+errno.h
+Errors.h
+Events.h
+fcntl.h
+fibdef.h
+files.h
+Files.h
+float.h
+Folders.h
+Gestalt.h
+getopt.h
+grp.h
+ia64/sys/inline.h
+ifaddrs.h
+image.h
+ints.h
+iodef.h
+io.h
+iostream.h
+kernel/OS.h
+lib$routines.h
+limits.h
+loader.h
+locale.h
+LowMem.h
+MacErrors.h
+machine/builtins.h
+machine/clock.h
+machine/endian.h
+machine/inline.h
+mach/mach_init.h
+mach/mach_host.h
+mach-o/dyld.h
+MacTypes.h
+Math64.h
+math.h
+mbstring.h
+memory.h
+MixedMode.h
+model.h
+mswsock.h
+Multiprocessing.h
+mutex.h
+netdb.h
+net/if.h
+netinet/in.h
+netinet/in_systm.h
+netinet/tcp.h
+OpenTptInternet.h
+OpenTransport.h
+os2.h
+OS.h
+osreldate.h
+OSUtils.h
+poll.h
+PPCToolbox.h
+Processes.h
+process.h
+pthread.h
+pwd.h
+QDOffscreen.h
+Resources.h
+rld_interface.h
+rpc/types.h
+semaphore.h
+setjmp.h
+share.h
+signal.h
+ssdef.h
+starlet.h
+stat.h
+stdarg.h
+stddef.h
+stdio.h
+stdlib.h
+string.h
+stropts.h
+stsdef.h
+support/SupportDefs.h
+support/TLS.h
+synch.h
+sys/atomic_op.h
+syscall.h
+sys/cfgodm.h
+sys/file.h
+sys/filio.h
+sys/immu.h
+sys/ioctl.h
+sys/ipc.h
+sys/ldr.h
+sys/locking.h
+sys/lwp.h
+sys/mman.h
+sys/mpctl.h
+sys/param.h
+sys/pda.h
+sys/poll.h
+sys/prctl.h
+sys/priv.h
+sys/procfs.h
+sys/pstat.h
+sys/regset.h
+sys/resource.h
+sys/sched.h
+sys/select.h
+sys/sem.h
+sys/sendfile.h
+sys/shm.h
+sys/socket.h
+sys/stack.h
+sys/stat.h
+sys/statvfs.h
+sys/syscall.h
+sys/sysctl.h
+sys/sysmp.h
+sys/syssgi.h
+sys/systeminfo.h
+sys/timeb.h
+sys/time.h
+sys/times.h
+sys/types.h
+sys/ucontext.h
+sys/uio.h
+sys/utsname.h
+sys/wait.h
+task.h
+TextUtils.h
+thread.h
+time.h
+Timer.h
+types.h
+Types.h
+ucontext.h
+ucx$inetdef.h
+ulocks.h
+unistd.h
+unix.h
+unixlib.h
+utime.h
+wchar.h
+winbase.h
+win/compobj.h
+windef.h
+windows.h
+winsock.h

Added: freeswitch/trunk/libs/js/nsprpub/configure
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/configure	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,6304 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --with-dist-prefix=DIST_PREFIX
+                          place build files in DIST_PREFIX [dist]"
+ac_help="$ac_help
+  --with-dist-bindir=DIR  build execuatables in DIR [DIST_PREFIX/bin]"
+ac_help="$ac_help
+  --with-dist-includedir=DIR
+                          build include files in DIR [DIST_PREFIX/include/nspr]"
+ac_help="$ac_help
+  --with-dist-libdir=DIR  build library files in DIR [DIST_PREFIX/lib]"
+ac_help="$ac_help
+  --with-mozilla          Compile NSPR with Mozilla support"
+ac_help="$ac_help
+  --enable-optimize(=val) Enable code optimizations (val, ie. -O2) "
+ac_help="$ac_help
+  --disable-debug         Do not compile in debugging symbols
+  --enable-debug(=val)    Enable debugging (debug flags val)"
+ac_help="$ac_help
+  --enable-win32-target=\$t
+                          Specify win32 flavor. (WIN95 or WINNT)"
+ac_help="$ac_help
+  --enable-debug-rtl      Use the MSVC debug runtime library"
+ac_help="$ac_help
+  --enable-n32            Enable n32 ABI support (IRIX only)"
+ac_help="$ac_help
+  --enable-64bit          Enable 64-bit support (on certain platforms)"
+ac_help="$ac_help
+  --enable-mdupdate       Enable use of certain compilers' mdupdate feature"
+ac_help="$ac_help
+  --with-macos-sdk=dir    Location of platform SDK to use (Mac OS X only)"
+ac_help="$ac_help
+  --enable-macos-target=VER
+                          Set the minimum MacOS version needed at runtime
+                          [10.1 for ppc, 10.4 for x86]"
+ac_help="$ac_help
+  --enable-strip          Enable stripping of shared libs and programs"
+ac_help="$ac_help
+  --with-pthreads         Use system pthreads library as thread subsystem"
+ac_help="$ac_help
+  --enable-user-pthreads  Build using userland pthreads"
+ac_help="$ac_help
+  --enable-nspr-threads   Build using classic nspr threads"
+ac_help="$ac_help
+  --with-bthreads         Use system bthreads library as thread subsystem
+                          (BeOS only)"
+ac_help="$ac_help
+  --with-native-threads   Use native system threads as thread subsystem
+                          (Solaris only)"
+ac_help="$ac_help
+  --enable-cplus          Enable some c++ api routines"
+ac_help="$ac_help
+  --enable-ipv6           Compile ipv6 support"
+ac_help="$ac_help
+  --enable-boehm          Enable the Boehm Garbage Collector"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=config/libc_r.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi at caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in ${srcdir}/build/autoconf $srcdir/${srcdir}/build/autoconf; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in ${srcdir}/build/autoconf $srcdir/${srcdir}/build/autoconf" 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+#    configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+#    same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+#    as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:627: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:648: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+  case $nonopt in
+  NONE) target_alias=$host_alias ;;
+  *) target_alias=$nonopt ;;
+  esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:666: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+  case $nonopt in
+  NONE) build_alias=$host_alias ;;
+  *) build_alias=$nonopt ;;
+  esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+
+MOD_MAJOR_VERSION=4
+MOD_MINOR_VERSION=7
+MOD_PATCH_VERSION=0
+NSPR_MODNAME=nspr20
+_HAVE_PTHREADS=
+USE_PTHREADS=
+USE_USER_PTHREADS=
+USE_NSPR_THREADS=
+USE_N32=
+USE_64=
+USE_CPLUS=
+USE_IPV6=
+USE_MDUPDATE=
+_MACOSX_DEPLOYMENT_TARGET=
+_OPTIMIZE_FLAGS=-O
+_DEBUG_FLAGS=-g
+MOZ_DEBUG=1
+MOZ_OPTIMIZE=
+OBJDIR='$(OBJDIR_NAME)'
+OBJDIR_NAME=.
+OBJDIR_SUFFIX=OBJ
+NSINSTALL='$(MOD_DEPTH)/config/$(OBJDIR_NAME)/nsinstall'
+NOSUCHFILE=/no-such-file
+LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)'
+LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)'
+CYGWIN_WRAPPER=
+MACOS_SDK_DIR=
+NEXT_ROOT=
+
+RESOLVE_LINK_SYMBOLS=
+
+CFLAGS="${CFLAGS=}"
+CXXFLAGS="${CXXFLAGS=}"
+LDFLAGS="${LDFLAGS=}"
+HOST_CFLAGS="${HOST_CFLAGS=}"
+HOST_LDFLAGS="${HOST_LDFLAGS=}"
+
+case "$target" in
+*-cygwin*|*-mingw*)
+    # Check to see if we are really running in a msvc environemnt
+    _WIN32_MSVC=
+    for ac_prog in cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:735: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CC" && break
+done
+
+    if test "$CC" = "cl"; then
+        echo 'main() { return 0; }' > dummy.c
+        ${CC} -o dummy dummy.c >/dev/null 2>&1
+        if test $? = 0; then
+            _WIN32_MSVC=1
+            CXX=$CC
+        else
+            echo "configure: warning: $(CC) test failed.  Using normal feature tests" 1>&2
+        fi
+        rm -f dummy dummy.o dummy.obj dummy.exe dummy.c
+    fi
+    ;;
+*-msvc*)
+    _WIN32_MSVC=1
+    ;;
+*-mks*)
+    _WIN32_MSVC=1
+    ;;
+esac
+
+if test -n "$_WIN32_MSVC"; then
+    SKIP_PATH_CHECKS=1
+    SKIP_COMPILER_CHECKS=1
+    SKIP_LIBRARY_CHECKS=1
+fi
+
+dist_prefix='${MOD_DEPTH}/dist'
+dist_bindir='${dist_prefix}/bin'
+dist_includedir='${dist_prefix}/include/nspr'
+dist_libdir='${dist_prefix}/lib'
+if test "${includedir}" = '${prefix}/include'; then
+    includedir='${prefix}/include/nspr'
+fi
+
+# Check whether --with-dist-prefix or --without-dist-prefix was given.
+if test "${with_dist_prefix+set}" = set; then
+  withval="$with_dist_prefix"
+  dist_prefix=$withval
+fi
+
+
+# Check whether --with-dist-bindir or --without-dist-bindir was given.
+if test "${with_dist_bindir+set}" = set; then
+  withval="$with_dist_bindir"
+  dist_bindir=$withval
+fi
+
+
+# Check whether --with-dist-includedir or --without-dist-includedir was given.
+if test "${with_dist_includedir+set}" = set; then
+  withval="$with_dist_includedir"
+  dist_includedir=$withval
+fi
+
+
+# Check whether --with-dist-libdir or --without-dist-libdir was given.
+if test "${with_dist_libdir+set}" = set; then
+  withval="$with_dist_libdir"
+  dist_libdir=$withval
+fi
+
+
+
+
+
+
+
+# Check whether --with-mozilla or --without-mozilla was given.
+if test "${with_mozilla+set}" = set; then
+  withval="$with_mozilla"
+     if test "$withval" = "yes"; then
+            cat >> confdefs.h <<\EOF
+#define MOZILLA_CLIENT 1
+EOF
+
+            MOZILLA_CLIENT=1
+	    else
+	        MOZILLA_CLIENT=
+	    fi
+else
+  	if test -n "$MOZILLA_CLIENT"; then
+	        cat >> confdefs.h <<\EOF
+#define MOZILLA_CLIENT 1
+EOF
+
+	    fi
+fi
+
+
+# Check whether --enable-optimize or --disable-optimize was given.
+if test "${enable_optimize+set}" = set; then
+  enableval="$enable_optimize"
+   if test "$enableval" != "no"; then
+        MOZ_OPTIMIZE=1
+        if test -n "$enableval" && test "$enableval" != "yes"; then
+    	    _OPTIMIZE_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
+            _SAVE_OPTIMIZE_FLAGS=$_OPTIMIZE_FLAGS
+        fi
+      else
+        MOZ_OPTIMIZE=
+    fi 
+fi
+
+
+# Check whether --enable-debug or --disable-debug was given.
+if test "${enable_debug+set}" = set; then
+  enableval="$enable_debug"
+  	if test "$enableval" = "no"; then
+    	    MOZ_DEBUG=
+        else
+            MOZ_DEBUG=1
+            if test -n "$enableval" && test "$enableval" != "yes"; then
+                _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
+                _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS
+            fi
+        fi
+fi
+
+
+# Check whether --enable-win32-target or --disable-win32-target was given.
+if test "${enable_win32_target+set}" = set; then
+  enableval="$enable_win32_target"
+  OS_TARGET=`echo $enableval | tr a-z A-Z`
+else
+  OS_TARGET=
+fi
+
+
+# Check whether --enable-debug-rtl or --disable-debug-rtl was given.
+if test "${enable_debug_rtl+set}" = set; then
+  enableval="$enable_debug_rtl"
+   if test "$enableval" = "yes"; then
+	    USE_DEBUG_RTL=1
+      fi 
+fi
+
+
+# Check whether --enable-n32 or --disable-n32 was given.
+if test "${enable_n32+set}" = set; then
+  enableval="$enable_n32"
+   if test "$enableval" = "yes"; then
+	USE_N32=1
+      else if test "$enableval" = "no"; then
+	USE_N32=
+      fi
+    fi 
+fi
+
+
+# Check whether --enable-64bit or --disable-64bit was given.
+if test "${enable_64bit+set}" = set; then
+  enableval="$enable_64bit"
+   if test "$enableval" = "yes"; then
+	    USE_64=1
+      fi 
+fi
+
+
+# Check whether --enable-mdupdate or --disable-mdupdate was given.
+if test "${enable_mdupdate+set}" = set; then
+  enableval="$enable_mdupdate"
+   if test "$enableval" = "yes"; then
+	    USE_MDUPDATE=1
+      fi 
+fi
+
+
+# Check whether --with-macos-sdk or --without-macos-sdk was given.
+if test "${with_macos_sdk+set}" = set; then
+  withval="$with_macos_sdk"
+  MACOS_SDK_DIR=$withval
+fi
+
+
+# Check whether --enable-macos-target or --disable-macos-target was given.
+if test "${enable_macos_target+set}" = set; then
+  enableval="$enable_macos_target"
+  _MACOSX_DEPLOYMENT_TARGET=$enableval
+fi
+
+
+case "$target" in
+
+*-aix*)
+    case "${target_os}" in
+    aix3.2*)
+        USE_NSPR_THREADS=1
+        ;;
+    *)
+        USE_PTHREADS=1
+        ;;
+    esac
+    ;;
+
+esac
+
+if test -z "$CC"; then
+    case "$target" in
+
+    *-aix*)
+        if test -z "$USE_NSPR_THREADS"; then
+            CC=xlc_r
+        else
+            CC=xlc
+        fi
+    ;;
+
+    *-hpux*)
+        CC=cc
+    ;;
+
+    *-irix*)
+        CC=cc
+    ;;
+
+    *-openvms*)
+        CC=cc
+    ;;
+
+    *-osf*)
+        CC=cc
+    ;;
+
+    *-solaris*)
+        CC=cc
+    ;;
+
+    esac
+fi
+
+if test -z "$CXX"; then
+    case "$target" in
+
+    *-aix*)
+        if test -z "$USE_NSPR_THREADS"; then
+            CXX=xlC_r
+        else
+            CXX=xlC
+        fi
+    ;;
+
+    *-hpux*)
+        case "${target_os}" in
+        hpux10.30)
+            CXX=aCC
+            ;;
+        hpux11.*)
+            CXX=aCC
+            ;;
+        *)
+            CXX=CC
+            ;;
+        esac
+    ;;
+
+    *-irix*)
+        CXX=CC
+    ;;
+
+    *-openvms*)
+        CXX=cxx
+    ;;
+
+    *-osf*)
+        CXX=cxx
+    ;;
+
+    *-solaris*)
+        CXX=CC
+    ;;
+
+    esac
+fi
+
+if test -z "$SKIP_PATH_CHECKS"; then
+    # Extract the first word of "$WHOAMI whoami", so it can be a program name with args.
+set dummy $WHOAMI whoami; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1042: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_WHOAMI'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$WHOAMI" in
+  /*)
+  ac_cv_path_WHOAMI="$WHOAMI" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_WHOAMI="$WHOAMI" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_WHOAMI="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_WHOAMI" && ac_cv_path_WHOAMI="echo not_whoami"
+  ;;
+esac
+fi
+WHOAMI="$ac_cv_path_WHOAMI"
+if test -n "$WHOAMI"; then
+  echo "$ac_t""$WHOAMI" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+if test -n "$MOZ_DEBUG"; then
+    cat >> confdefs.h <<\EOF
+#define DEBUG 1
+EOF
+
+    DEFINES="$DEFINES -UNDEBUG"
+
+    case "${target_os}" in
+    beos*)
+        DEFINES="$DEFINES -DDEBUG_${USER}"
+        ;;
+    msvc*|mks*|cygwin*|mingw*|os2*)
+        DEFINES="$DEFINES -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`"
+        ;;
+    *) 
+        DEFINES="$DEFINES -DDEBUG_`$WHOAMI`"
+        ;;
+    esac
+else
+    cat >> confdefs.h <<\EOF
+#define NDEBUG 1
+EOF
+
+    DEFINES="$DEFINES -UDEBUG"
+fi
+
+if test -z "$SKIP_COMPILER_CHECKS"; then
+if test "$target" != "$host"; then
+    echo "cross compiling from $host to $target"
+    cross_compiling=yes
+
+    _SAVE_CC="$CC"
+    _SAVE_CFLAGS="$CFLAGS"
+    _SAVE_LDFLAGS="$LDFLAGS"
+
+    echo $ac_n "checking for $host compiler""... $ac_c" 1>&6
+echo "configure:1113: checking for $host compiler" >&5
+    for ac_prog in $HOST_CC gcc cc /usr/ucb/cc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1119: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_HOST_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$HOST_CC"; then
+  ac_cv_prog_HOST_CC="$HOST_CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_HOST_CC="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+HOST_CC="$ac_cv_prog_HOST_CC"
+if test -n "$HOST_CC"; then
+  echo "$ac_t""$HOST_CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$HOST_CC" && break
+done
+test -n "$HOST_CC" || HOST_CC=""""
+
+    if test -z "$HOST_CC"; then
+        { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+    fi
+    echo "$ac_t""$HOST_CC" 1>&6
+    if test -z "$HOST_CFLAGS"; then
+        HOST_CFLAGS="$CFLAGS"
+    fi
+    if test -z "$HOST_LDFLAGS"; then
+        HOST_LDFLAGS="$LDFLAGS"
+    fi
+
+    CC="$HOST_CC"
+    CFLAGS="$HOST_CFLAGS"
+    LDFLAGS="$HOST_LDFLAGS"
+
+    echo $ac_n "checking whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1165: checking whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works" >&5
+    cat > conftest.$ac_ext <<EOF
+#line 1167 "configure"
+#include "confdefs.h"
+
+int main() {
+return(0);
+; return 0; }
+EOF
+if { (eval echo configure:1174: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_prog_host_cc_works=1 echo "$ac_t""yes" 1>&6
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  { echo "configure: error: installation or configuration problem: $host compiler $HOST_CC cannot create executables." 1>&2; exit 1; } 
+fi
+rm -f conftest*
+
+    CC=$_SAVE_CC
+    CFLAGS=$_SAVE_CFLAGS
+    LDFLAGS=$_SAVE_LDFLAGS
+
+    case "$build:$target" in 
+      powerpc-apple-darwin8*:i?86-apple-darwin*)
+                                                _SAVE_CFLAGS=$CFLAGS 
+        _SAVE_CXXFLAGS=$CXXLAGS
+        CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CFLAGS"
+        CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CXXFLAGS"
+        ;;        
+    esac            
+
+    for ac_prog in $CC "${target_alias}-gcc" "${target}-gcc"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1203: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CC" && break
+done
+test -n "$CC" || CC="echo"
+
+    unset ac_cv_prog_CC
+    # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1237: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1267: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1318: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1350: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1361 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1366: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1392: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1397: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1406: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1425: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+    for ac_prog in $CXX "${target_alias}-g++" "${target}-g++"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1461: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CXX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+  echo "$ac_t""$CXX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="echo"
+
+    unset ac_cv_prog_CXX
+    for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1497: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CXX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+  echo "$ac_t""$CXX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1529: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1540 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:1545: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cxx_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cxx_cross=no
+  else
+    ac_cv_prog_cxx_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1571: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:1576: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.C <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1585: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gxx=yes
+else
+  ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:1604: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+  ac_cv_prog_cxx_g=yes
+else
+  ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+
+
+    case "$build:$target" in
+      powerpc-apple-darwin8*:i?86-apple-darwin*)
+                                CFLAGS=$_SAVE_CFLAGS
+        CXXFLAGS=$_SAVE_CXXFLAGS
+        ;;
+    esac
+
+    for ac_prog in $RANLIB "${target_alias}-ranlib" "${target}-ranlib"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1648: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$RANLIB" && break
+done
+test -n "$RANLIB" || RANLIB="echo"
+
+    for ac_prog in $AR "${target_alias}-ar" "${target}-ar"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1683: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AR="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+  echo "$ac_t""$AR" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AR" && break
+done
+test -n "$AR" || AR="echo"
+
+    for ac_prog in $AS "${target_alias}-as" "${target}-as"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1718: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$AS"; then
+  ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_AS="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+AS="$ac_cv_prog_AS"
+if test -n "$AS"; then
+  echo "$ac_t""$AS" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AS" && break
+done
+test -n "$AS" || AS="echo"
+
+    for ac_prog in $LD "${target_alias}-ld" "${target}-ld"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1753: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$LD"; then
+  ac_cv_prog_LD="$LD" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_LD="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+LD="$ac_cv_prog_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LD" && break
+done
+test -n "$LD" || LD="echo"
+
+    for ac_prog in $STRIP "${target_alias}-strip" "${target}-strip"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1788: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_STRIP="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+  echo "$ac_t""$STRIP" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$STRIP" && break
+done
+test -n "$STRIP" || STRIP="echo"
+
+    for ac_prog in $WINDRES "${target_alias}-windres" "${target}-windres"
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1823: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$WINDRES"; then
+  ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_WINDRES="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+WINDRES="$ac_cv_prog_WINDRES"
+if test -n "$WINDRES"; then
+  echo "$ac_t""$WINDRES" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$WINDRES" && break
+done
+test -n "$WINDRES" || WINDRES="echo"
+
+
+else
+    for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1860: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CXX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+  echo "$ac_t""$CXX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1892: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1903 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:1908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cxx_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cxx_cross=no
+  else
+    ac_cv_prog_cxx_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1934: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:1939: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.C <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1948: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gxx=yes
+else
+  ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:1967: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+  ac_cv_prog_cxx_g=yes
+else
+  ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+
+    if test "$CXX" = "cl" -a -z "$CC"; then
+        CC=$CXX
+    else        
+        # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2004: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2034: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2085: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:2117: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 2128 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:2133: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:2159: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:2164: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2173: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:2192: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+    fi
+    echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:2225: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 2240 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2246: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 2257 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2263: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 2274 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2280: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+    # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2307: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    for ac_prog in as
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2339: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_AS'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$AS" in
+  /*)
+  ac_cv_path_AS="$AS" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_AS="$AS" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_AS="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+AS="$ac_cv_path_AS"
+if test -n "$AS"; then
+  echo "$ac_t""$AS" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AS" && break
+done
+test -n "$AS" || AS="$CC"
+
+    for ac_prog in ar
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2380: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_AR'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$AR" in
+  /*)
+  ac_cv_path_AR="$AR" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_AR="$AR" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_AR="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+AR="$ac_cv_path_AR"
+if test -n "$AR"; then
+  echo "$ac_t""$AR" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AR" && break
+done
+test -n "$AR" || AR="echo not_ar"
+
+    for ac_prog in ld link
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2421: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$LD" in
+  /*)
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_LD="$LD" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_LD="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$LD" && break
+done
+test -n "$LD" || LD="echo not_ld"
+
+    for ac_prog in strip
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2462: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_STRIP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$STRIP" in
+  /*)
+  ac_cv_path_STRIP="$STRIP" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_STRIP="$STRIP" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_STRIP="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+STRIP="$ac_cv_path_STRIP"
+if test -n "$STRIP"; then
+  echo "$ac_t""$STRIP" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$STRIP" && break
+done
+test -n "$STRIP" || STRIP="echo not_strip"
+
+    for ac_prog in windres
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2503: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_WINDRES'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$WINDRES" in
+  /*)
+  ac_cv_path_WINDRES="$WINDRES" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_WINDRES="$WINDRES" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_WINDRES="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+WINDRES="$ac_cv_path_WINDRES"
+if test -n "$WINDRES"; then
+  echo "$ac_t""$WINDRES" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$WINDRES" && break
+done
+test -n "$WINDRES" || WINDRES="echo not_windres"
+
+    if test -z "$HOST_CC"; then
+        HOST_CC="$CC"
+    fi
+    if test -z "$HOST_CFLAGS"; then
+        HOST_CFLAGS="$CFLAGS"
+    fi
+fi
+
+if test "$GCC" = "yes"; then
+    GNU_CC=1
+fi
+if test "$GXX" = "yes"; then
+    GNU_CXX=1
+fi
+if test "`echo | $AS -v 2>&1 | grep -c GNU`" != "0"; then
+    GNU_AS=1
+fi
+rm -f a.out
+
+case "$build:$target" in
+    i?86-apple-darwin*:powerpc-apple-darwin*)
+                                cross_compiling=yes
+        ;;
+esac
+
+if test "$cross_compiling"  = "yes"; then
+    CROSS_COMPILE=1
+else
+    CROSS_COMPILE=
+fi
+
+echo $ac_n "checking for gcc -pipe support""... $ac_c" 1>&6
+echo "configure:2571: checking for gcc -pipe support" >&5
+if test -n "$GNU_CC" && test -n "$GNU_CXX" && test -n "$GNU_AS"; then
+    echo '#include <stdio.h>' > dummy-hello.c
+    echo 'int main() { printf("Hello World\n"); return 0; }' >> dummy-hello.c
+    ${CC} -S dummy-hello.c -o dummy-hello.s 2>&5
+    cat dummy-hello.s | ${AS} -o dummy-hello.S - 2>&5
+    if test $? = 0; then
+        _res_as_stdin="yes"
+    else
+        _res_as_stdin="no"
+    fi
+    if test "$_res_as_stdin" = "yes"; then
+        _SAVE_CFLAGS=$CFLAGS
+        CFLAGS="$CFLAGS -pipe"
+        cat > conftest.$ac_ext <<EOF
+#line 2586 "configure"
+#include "confdefs.h"
+ #include <stdio.h> 
+int main() {
+printf("Hello World\n");
+; return 0; }
+EOF
+if { (eval echo configure:2593: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  _res_gcc_pipe="yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  _res_gcc_pipe="no" 
+fi
+rm -f conftest*
+        CFLAGS=$_SAVE_CFLAGS
+    fi
+    if test "$_res_as_stdin" = "yes" && test "$_res_gcc_pipe" = "yes"; then
+        _res="yes";
+        CFLAGS="$CFLAGS -pipe"
+        CXXFLAGS="$CXXFLAGS -pipe"
+    else
+        _res="no"
+    fi
+    rm -f dummy-hello.c dummy-hello.s dummy-hello.S dummy-hello a.out
+    echo "$ac_t""$_res" 1>&6
+else
+    echo "$ac_t""no" 1>&6
+fi
+
+if test "$GNU_CC"; then
+    echo $ac_n "checking for visibility(hidden) attribute""... $ac_c" 1>&6
+echo "configure:2620: checking for visibility(hidden) attribute" >&5
+if eval "test \"`echo '$''{'ac_cv_visibility_hidden'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+        int foo __attribute__ ((visibility ("hidden"))) = 1;
+EOF
+        ac_cv_visibility_hidden=no
+        if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+            if grep '\.hidden.*foo' conftest.s >/dev/null; then
+                ac_cv_visibility_hidden=yes
+            fi
+        fi
+        rm -f conftest.cs
+        
+fi
+
+echo "$ac_t""$ac_cv_visibility_hidden" 1>&6
+    if test "$ac_cv_visibility_hidden" = "yes"; then
+        cat >> confdefs.h <<\EOF
+#define HAVE_VISIBILITY_HIDDEN_ATTRIBUTE 1
+EOF
+
+        echo $ac_n "checking for visibility pragma support""... $ac_c" 1>&6
+echo "configure:2644: checking for visibility pragma support" >&5
+if eval "test \"`echo '$''{'ac_cv_visibility_pragma'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#pragma GCC visibility push(hidden)
+            int foo_hidden = 1;
+#pragma GCC visibility push(default)
+            int foo_default = 1;
+EOF
+            ac_cv_visibility_pragma=no
+            if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+                if grep '\.hidden.*foo_hidden' conftest.s >/dev/null; then
+                    if ! grep '\.hidden.*foo_default' conftest.s > /dev/null; then
+                        ac_cv_visibility_pragma=yes
+                    fi
+                fi
+            fi
+            rm -f conftest.cs
+            
+fi
+
+echo "$ac_t""$ac_cv_visibility_pragma" 1>&6
+        if test "$ac_cv_visibility_pragma" = "yes"; then
+            cat >> confdefs.h <<\EOF
+#define HAVE_VISIBILITY_PRAGMA 1
+EOF
+
+            # To work around a build problem on Linux x86-64 (Bugzilla bug
+            # 293438), we use the -fvisibility=hidden flag.  This flag is less
+            # optimal than #pragma GCC visibility push(hidden) because the flag
+            # assumes that symbols defined outside the current source file have
+            # the default visibility.  This has the advantage that we don't need
+            # to wrap system header files, but has the disadvantage that calls
+            # to hidden symbols defined in other source files cannot be
+            # optimized by the compiler.  The -fvisibility=hidden flag does
+            # hide and export symbols correctly.
+            #VISIBILITY_FLAGS='-I$(dist_includedir)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h'
+            #WRAP_SYSTEM_INCLUDES=1
+            VISIBILITY_FLAGS="-fvisibility=hidden"
+            WRAP_SYSTEM_INCLUDES=
+        fi
+    fi
+fi # GNU_CC
+
+fi # SKIP_COMPILER_CHECKS
+
+if test -z "$SKIP_PATH_CHECKS"; then
+    for ac_prog in perl5 perl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2697: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$PERL" in
+  /*)
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_PERL="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+fi
+PERL="$ac_cv_path_PERL"
+if test -n "$PERL"; then
+  echo "$ac_t""$PERL" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$PERL" && break
+done
+test -n "$PERL" || PERL="echo not_perl"
+
+elif test -z "$PERL"; then
+    PERL=perl
+fi
+
+OBJ_SUFFIX=o
+LIB_SUFFIX=a
+DLL_SUFFIX=so
+ASM_SUFFIX=s
+MKSHLIB='$(LD) $(DSO_LDOPTS) -o $@'
+PR_MD_ASFILES=
+PR_MD_CSRCS=
+PR_MD_ARCH_DIR=unix
+AR_FLAGS='cr $@'
+AS='$(CC)'
+ASFLAGS='$(CFLAGS)'
+
+if test -n "$CROSS_COMPILE"; then
+    OS_ARCH=`echo $target_os | sed -e 's|/|_|g'`
+    OS_RELEASE=
+    OS_TEST="${target_cpu}"
+    case "${target_os}" in
+        linux*)       OS_ARCH=Linux ;;
+        solaris*)     OS_ARCH=SunOS OS_RELEASE=5 ;;
+        mingw*)       OS_ARCH=WINNT ;;
+        darwin*)      OS_ARCH=Darwin ;;
+    esac
+else
+    OS_ARCH=`uname -s | sed -e 's|/|_|g'`
+    OS_RELEASE=`uname -r`
+    OS_TEST=`uname -m`
+fi
+
+if test "$OS_ARCH" = "IRIX64"; then
+    OS_ARCH=IRIX
+fi
+
+if test "$OS_ARCH" = "AIX"; then
+    OS_RELEASE=`uname -v`.`uname -r`
+fi
+
+if test "$OS_ARCH" = "FreeBSD"; then
+    OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'`
+fi
+
+if test "$OS_ARCH" = "Linux"; then
+    OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'`
+    OS_RELEASE=`echo $OS_RELEASE | awk -F\. '{ print $1 "." $2 }'`
+fi
+
+if test "$OS_ARCH" = "OpenVMS"; then
+    OS_RELEASE=`uname -v`
+fi
+
+#######################################################################
+# Master "Core Components" macros for getting the OS target           #
+#######################################################################
+
+#
+# Note: OS_TARGET should be specified on the command line for gmake.
+# When OS_TARGET=WIN95 is specified, then a Windows 95 target is built.
+# The difference between the Win95 target and the WinNT target is that
+# the WinNT target uses Windows NT specific features not available
+# in Windows 95. The Win95 target will run on Windows NT, but (supposedly)
+# at lesser performance (the Win95 target uses threads; the WinNT target
+# uses fibers).
+#
+# When OS_TARGET=WIN16 is specified, then a Windows 3.11 (16bit) target
+# is built. See: win16_3.11.mk for lots more about the Win16 target.
+#
+# If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no
+# cross-compilation.
+#
+
+#
+# The following hack allows one to build on a WIN95 machine (as if
+# s/he were cross-compiling on a WINNT host for a WIN95 target).
+# It also accomodates for MKS's uname.exe.  If you never intend
+# to do development on a WIN95 machine, you don't need this hack.
+#
+case "$OS_ARCH" in
+WIN95)
+    OS_ARCH=WINNT
+    OS_TARGET=WIN95
+    ;;
+Windows_95)
+    OS_ARCH=Windows_NT
+    OS_TARGET=WIN95
+    ;;
+Windows_98)
+    OS_ARCH=Windows_NT
+    OS_TARGET=WIN95
+    ;;
+CYGWIN_9*|CYGWIN_ME*)
+    OS_ARCH='CYGWIN_NT-4.0'
+    OS_TARGET=WIN95
+    ;;
+OS_2)
+    OS_ARCH=OS2
+    OS_TARGET=OS2
+    ;;
+esac
+
+#
+# On WIN32, we also define the variable CPU_ARCH.
+#
+
+case "$OS_ARCH" in
+WINNT)
+    CPU_ARCH=`uname -p`
+    if test "$CPU_ARCH" = "I386"; then
+        CPU_ARCH=x86
+    fi
+    ;;
+Windows_NT)
+#
+# If uname -s returns "Windows_NT", we assume that we are using
+# the uname.exe in MKS toolkit.
+#
+# The -r option of MKS uname only returns the major version number.
+# So we need to use its -v option to get the minor version number.
+# Moreover, it doesn't have the -p option, so we need to use uname -m.
+#
+    OS_ARCH=WINNT
+    OS_MINOR_RELEASE=`uname -v`
+    if test "$OS_MINOR_RELEASE" = "00"; then
+        OS_MINOR_RELEASE=0
+    fi
+    OS_RELEASE="${OS_RELEASE}.${OS_MINOR_RELEASE}"
+    CPU_ARCH=`uname -m`
+    #
+    # MKS's uname -m returns "586" on a Pentium machine.
+    #
+    if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    fi
+    ;;
+CYGWIN_NT*|MINGW*_NT*)
+#
+# If uname -s returns "CYGWIN_NT-4.0", we assume that we are using
+# the uname.exe in the Cygwin tools.
+# If uname -s returns MINGW32_NT-5.1, we assume that we are using
+# the uname.exe in the MSYS tools.
+#
+    OS_RELEASE=`expr $OS_ARCH : '.*NT-\(.*\)'`
+    OS_ARCH=WINNT
+    CPU_ARCH=`uname -m`
+    #
+    # Cygwin's uname -m returns "i686" on a Pentium Pro machine.
+    #
+    if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    fi
+    ;;
+esac
+
+if test -n "$MOZILLA_CLIENT" && test "$OS_ARCH" = "WINNT"; then
+    OS_TARGET=WIN95
+    if test -n "$MOZ_DEBUG"; then
+        USE_DEBUG_RTL=1
+    fi
+fi
+if test -z "$OS_TARGET"; then
+    OS_TARGET=$OS_ARCH
+fi
+if test "$OS_TARGET" = "WIN95"; then
+    OS_RELEASE="4.0"
+fi
+if test "$OS_TARGET" = "WIN16"; then
+    OS_RELEASE=
+fi
+OS_CONFIG="${OS_TARGET}${OS_RELEASE}"
+
+
+case "$host" in
+*-mingw*)
+    NSINSTALL=nsinstall
+    ;;
+*-cygwin*|*-msvc*|*-mks*)
+    NSINSTALL='$(CYGWIN_WRAPPER) nsinstall'
+    if test `echo "${PATH}" | grep -c \;` = 0; then
+        CYGWIN_WRAPPER='sh $(topsrcdir)/build/cygwin-wrapper'
+    fi
+    ;;
+*-beos*)
+    HOST_CFLAGS="$HOST_CFLAGS -DXP_BEOS -DBeOS -DBEOS -D_POSIX_SOURCE"
+    ;;
+*os2*)
+    ;;
+*)
+    HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX"
+    ;;
+esac
+
+case "$target" in
+
+*-aix*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define AIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    DSO_LDOPTS='-brtl -bnortllib -bM:SRE -bnoentry -bexpall -blibpath:/usr/lib:/lib'
+    ac_safe=`echo "sys/atomic_op.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for sys/atomic_op.h""... $ac_c" 1>&6
+echo "configure:2944: checking for sys/atomic_op.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2949 "configure"
+#include "confdefs.h"
+#include <sys/atomic_op.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2954: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define AIX_HAVE_ATOMIC_OP_H 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    case "${target_os}" in
+    aix3.2*)
+        cat >> confdefs.h <<\EOF
+#define AIX_RENAME_SELECT 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+        AIX_LINK_OPTS='-bnso -berok'
+        PR_MD_ASFILES=os_AIX.s
+        ;;
+    aix4.1*)
+        cat >> confdefs.h <<\EOF
+#define AIX_TIMERS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define AIX4_1 1
+EOF
+
+        MKSHLIB=
+        DSO_LDOPTS=
+        AIX_LINK_OPTS='-bnso -berok'
+        LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)_shr'
+        LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)_shr'
+        ;;
+    aix4.2*)
+        cat >> confdefs.h <<\EOF
+#define AIX_TIMERS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    aix4.3*)
+        cat >> confdefs.h <<\EOF
+#define AIX_TIMERS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define AIX4_3_PLUS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_SOCKLEN_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+        USE_IPV6=1
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    *)
+        cat >> confdefs.h <<\EOF
+#define AIX_TIMERS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define AIX4_3_PLUS 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_SOCKLEN_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+        USE_IPV6=1
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    esac
+    CFLAGS="$CFLAGS -qro -qroconst"
+    AIX_WRAP='$(DIST)/lib/aixwrap.o'
+    AIX_TMP='./_aix_tmp.o'
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_aix64.cfg
+        OBJECT_MODE=64
+    else
+        MDCPUCFG_H=_aix32.cfg
+    fi
+    PR_MD_CSRCS=aix.c
+    RESOLVE_LINK_SYMBOLS=1
+    ;;
+        
+*-beos*)
+    cat >> confdefs.h <<\EOF
+#define XP_BEOS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define BeOS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define BEOS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+    DSO_LDOPTS=-nostart
+    MDCPUCFG_H=_beos.cfg
+    USE_BTHREADS=1
+    PR_MD_ARCH_DIR=beos
+    RESOLVE_LINK_SYMBOLS=1
+    case "${target_cpu}" in
+    i*86)
+        _OPTIMIZE_FLAGS=-O2
+        _DEBUG_FLAGS='-gdwarf-2 -O0'
+        MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@'
+        echo $ac_n "checking for gethostbyaddr in -lbind""... $ac_c" 1>&6
+echo "configure:3111: checking for gethostbyaddr in -lbind" >&5
+ac_lib_var=`echo bind'_'gethostbyaddr | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lbind  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3119 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyaddr();
+
+int main() {
+gethostbyaddr()
+; return 0; }
+EOF
+if { (eval echo configure:3130: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  OS_LIBS="$OS_LIBS -lbind -lsocket"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+        ;;
+    powerpc)
+        CC=mwcc
+        CCC=mwcc
+        LD=mwld
+        DSO_LDOPTS='-xms -export pragma -init _init_routine_ -term _term_routine_ -lroot -lnet /boot/develop/lib/ppc/glue-noinit.a /boot/develop/lib/ppc/init_term_dyn.o /boot/develop/lib/ppc/start_dyn.o'
+        _OPTIMIZE_FLAGS=-O2    
+        _DEBUG_FLAGS='-g -O0'
+        ;;
+    esac
+    ;;
+
+*-bsdi*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define BSDI 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NEED_BSDREGEX 1
+EOF
+
+
+    CFLAGS="$CFLAGS -Wall -Wno-format"
+    CXXFLAGS="$CXXFLAGS -Wall -Wno-format"
+
+    if echo "$OS_TEST" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    elif echo "$OS_TEST" | grep -c sparc >/dev/null; then 
+        CPU_ARCH=sparc
+    fi
+
+    MDCPUCFG_H=_bsdi.cfg
+    PR_MD_CSRCS=bsdi.c
+
+    DSO_LDOPTS=-r
+
+    case "$target_os" in
+    bsdi1.1*)
+        cat >> confdefs.h <<\EOF
+#define _PR_BSDI_JMPBUF_IS_ARRAY 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ONLY_ST_ATIME 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+        MKSHLIB=
+        DSO_CFLAGS=
+        DSO_LDOPTS=
+        ;;
+
+    bsdi2.1*)
+        cat >> confdefs.h <<\EOF
+#define _PR_TIMESPEC_HAS_TS_SEC 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_BSDI_JMPBUF_IS_ARRAY 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_DLL 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define USE_DLFCN 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ST_ATIMESPEC 1
+EOF
+
+        PR_MD_ASFILES=os_BSD_OS_386_2.s
+        ;;
+
+    bsdi4.* | bsdi5.*)
+        cat >> confdefs.h <<\EOF
+#define _PR_SELECT_CONST_TIMEVAL 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_BSDI_JMPBUF_IS_STRUCT 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_DLL 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define USE_DLFCN 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ST_ATIMESPEC 1
+EOF
+
+        MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)'
+        DSO_CFLAGS=-fPIC
+        DSO_LDOPTS='-shared -Wl,-soname,$(@:$(OBJDIR)/%.so=%.so)'
+        STRIP="$STRIP -d"
+        case "$target_os" in
+        bsdi4.2* | bsdi4.3* | bsdi5.*)
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETPROTO_R 1
+EOF
+
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETPROTO_R_POINTER 1
+EOF
+
+            ;;
+        esac
+        ;;
+    *)
+        cat >> confdefs.h <<\EOF
+#define _PR_SELECT_CONST_TIMEVAL 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_BSDI_JMPBUF_IS_STRUCT 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_DLL 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define USE_DLFCN 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ST_ATIMESPEC 1
+EOF
+
+        ;;
+    esac
+
+    ;;
+
+*-darwin*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define DARWIN 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_BSD_FLOCK 1
+EOF
+
+    CFLAGS="$CFLAGS -Wmost -fno-common"
+    case "${target_cpu}" in
+        i*86*)
+            cat >> confdefs.h <<\EOF
+#define i386 1
+EOF
+
+            CPU_ARCH=i386
+            PR_MD_ASFILES=os_Darwin_x86.s
+            ;;
+        *)
+            cat >> confdefs.h <<\EOF
+#define ppc 1
+EOF
+
+            CPU_ARCH=ppc
+            PR_MD_ASFILES=os_Darwin_ppc.s
+            ;;
+    esac
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @executable_path/$@ -headerpad_max_install_names'
+    # Use the standard preprocessor (cpp)
+    CFLAGS="$CFLAGS -no-cpp-precomp"
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    STRIP="$STRIP -x -S"
+    DLL_SUFFIX=dylib
+    USE_PTHREADS=1
+    MDCPUCFG_H=_darwin.cfg
+    PR_MD_CSRCS=darwin.c
+
+    # Add Mac OS X support for loading CFM & CFBundle plugins
+    if test -f /System/Library/Frameworks/Carbon.framework/Carbon; then
+        cat >> confdefs.h <<\EOF
+#define XP_MACOSX 1
+EOF
+
+        OS_TARGET=MacOSX
+
+        if test -n "$_MACOSX_DEPLOYMENT_TARGET" ; then
+                        export MACOSX_DEPLOYMENT_TARGET=$_MACOSX_DEPLOYMENT_TARGET
+        elif test -z "$MACOSX_DEPLOYMENT_TARGET" ; then
+                                                case "${target_cpu}" in
+                powerpc*)
+                                        export MACOSX_DEPLOYMENT_TARGET=10.1
+                    ;;
+                i*86*)
+                                        export MACOSX_DEPLOYMENT_TARGET=10.4
+                    ;;
+            esac
+        fi
+
+                        
+        if test "$MACOS_SDK_DIR"; then
+            
+            if test ! -d "$MACOS_SDK_DIR"; then
+                { echo "configure: error: SDK not found.  When using --with-macos-sdk, you must
+specify a valid SDK.  SDKs are installed when the optional cross-development
+tools are selected during the Xcode/Developer Tools installation." 1>&2; exit 1; }
+            fi
+
+            
+            CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'`
+            GCC_VERSION_FULL=`echo $CC_VERSION | $PERL -pe 's/^.*gcc version ([^ ]*).*/$1/'`
+            GCC_VERSION=`echo $GCC_VERSION_FULL | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/$1/;'`
+            
+            GCC_VERSION_MAJOR=`echo $GCC_VERSION_FULL | $PERL -pe 's/(^\d*).*/$1/;'`
+            if test "$GCC_VERSION_MAJOR" -lt "4" ; then
+                SDK_C_FRAMEWORK="-F${MACOS_SDK_DIR}/System/Library/Frameworks"
+                if test -d "${MACOS_SDK_DIR}/Library/Frameworks" ; then
+                    SDK_C_FRAMEWORK="$SDK_C_FRAMEWORK -F${MACOS_SDK_DIR}/Library/Frameworks"
+                fi
+
+                SDK_C_INCLUDE="-isystem ${MACOS_SDK_DIR}/usr/include/gcc/darwin/${GCC_VERSION} -isystem ${MACOS_SDK_DIR}/usr/include ${SDK_C_FRAMEWORK}"
+
+                CFLAGS="$CFLAGS -nostdinc ${SDK_C_INCLUDE}"
+
+                                CPP="$CPP -nostdinc ${SDK_C_INCLUDE}"
+
+                                                                                                                                                                                MACOS_SDK_LIBS="-L${MACOS_SDK_DIR}/usr/lib/gcc/darwin -L${MACOS_SDK_DIR}/usr/lib/gcc/darwin/${GCC_VERSION_FULL} -L${MACOS_SDK_DIR}/usr/lib ${SDK_C_FRAMEWORK}"
+                LDFLAGS="${MACOS_SDK_LIBS} $LDFLAGS"
+                DSO_LDOPTS="${MACOS_SDK_LIBS} $DSO_LDOPTS"
+                export NEXT_ROOT=$MACOS_SDK_DIR
+
+                if test -n "$CROSS_COMPILE" ; then
+                                                                                HOST_CC="NEXT_ROOT= $HOST_CC"
+                    HOST_CXX="NEXT_ROOT= $HOST_CXX"
+                fi
+            else
+                                                CFLAGS="$CFLAGS -isysroot ${MACOS_SDK_DIR}"
+
+                                CPP="$CPP -isysroot ${MACOS_SDK_DIR}"
+
+                                                                                                                                if test "$GCC_VERSION_FULL" != "4.0.0" ; then
+                                                            LDFLAGS="$LDFLAGS -isysroot ${MACOS_SDK_DIR}"
+                    DSO_LDOPTS="$DSO_LDOPTS -isysroot ${MACOS_SDK_DIR}"
+                else
+                                                            LDFLAGS="$LDFLAGS -Wl,-syslibroot,${MACOS_SDK_DIR}"
+                    DSO_LDOPTS="$DSO_LDOPTS -Wl,-syslibroot,${MACOS_SDK_DIR}"
+                fi
+            fi
+        fi
+    fi
+    ;;
+
+*-dgux*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define DGUX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _DGUX_SOURCE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _POSIX4A_DRAFT6_SOURCE 1
+EOF
+
+    DSO_LDOPTS=-G
+    _OPTIMIZE_FLAGS=-O2
+    _DEBUG_FLAGS=
+    MDCPUCFG_H=_dgux.cfg
+    PR_MD_CSRCS=dgux.c
+    ;;
+
+*-freebsd*)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define FREEBSD 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_BSD_FLOCK 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_SOCKLEN_T 1
+EOF
+
+    CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall"
+    MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+    if test "$MOZ_OBJFORMAT" = "elf"; then
+        DLL_SUFFIX=so
+    else
+        DLL_SUFFIX=so.1.0
+    fi
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    MDCPUCFG_H=_freebsd.cfg
+    PR_MD_CSRCS=freebsd.c
+    ;;
+
+*-hpux*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HPUX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _HPUX_SOURCE 1
+EOF
+
+    # OSF1 and HPUX report the POLLHUP event for a socket when the
+    # shutdown(SHUT_WR) operation is called for the remote end, even though
+    # the socket is still writeable. Use select(), instead of poll(), to
+    # workaround this problem.
+    cat >> confdefs.h <<\EOF
+#define _PR_POLL_WITH_SELECT 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _USE_BIG_FDS 1
+EOF
+
+    DSO_LDOPTS='-b +h $(notdir $@)'
+    PR_MD_CSRCS=hpux.c
+    if test "$OS_TEST" = "ia64"; then
+        DLL_SUFFIX=so
+        DSO_LDOPTS="$DSO_LDOPTS +b '\$\$ORIGIN'"
+        CPU_ARCH_TAG=_$OS_TEST 
+        if test -z "$USE_64"; then
+            COMPILER_TAG=_32
+        fi
+        PR_MD_ASFILES=os_HPUX_ia64.s
+    else
+        cat >> confdefs.h <<\EOF
+#define hppa 1
+EOF
+
+        DLL_SUFFIX=sl
+        PR_MD_ASFILES=os_HPUX.s
+    fi
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_hpux64.cfg
+    else
+        MDCPUCFG_H=_hpux32.cfg
+    fi
+    if test -z "$GNU_CC"; then
+        CC="$CC -Ae"
+        CXX="$CXX -ext"
+        DSO_CFLAGS=+Z
+    else
+        DSO_CFLAGS=-fPIC
+    fi
+
+    if test -n "$MOZILLA_CLIENT"; then
+        DEFAULT_IMPL_STRATEGY=_EMU
+    fi
+
+    if echo "$OS_RELEASE" | grep ^A.09 >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HPUX9 1
+EOF
+
+        DEFAULT_IMPL_STRATEGY=_EMU
+    	USE_NSPR_THREADS=1
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(A.09|B.10)' >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define HAVE_INT_LOCALTIME_R 1
+EOF
+
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.30|B.11)' >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+    fi
+
+    # HP-UX 11i (B.11.11) or higher
+    
+    case "$OS_RELEASE" in
+    [C-Z]*|B.[2-9]*|B.1[2-9]*|B.11.[2-9]*|B.11.1[1-9]*)
+        USE_IPV6=1
+        ;;
+    esac
+    
+
+    if test "$OS_RELEASE" = "B.10.01"; then
+        cat >> confdefs.h <<\EOF
+#define HPUX10 1
+EOF
+
+        DEFAULT_IMPL_STRATEGY=_EMU
+    fi
+
+    if test "$OS_RELEASE" = "B.10.10"; then
+        cat >> confdefs.h <<\EOF
+#define HPUX10 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HPUX10_10 1
+EOF
+
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$OS_RELEASE" = "B.10.20"; then
+        cat >> confdefs.h <<\EOF
+#define HPUX10 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HPUX10_20 1
+EOF
+
+        if test -z "$GNU_CC"; then
+            CFLAGS="$CFLAGS +DAportable +DS1.1"
+            CXXFLAGS="$CXXFLAGS +DAportable +DS1.1"
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$OS_RELEASE" = "B.10.30"; then
+        cat >> confdefs.h <<\EOF
+#define HPUX10 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HPUX10_30 1
+EOF
+
+        if test -z "$GNU_CC"; then
+            CFLAGS="$CFLAGS +DAportable +DS1.1"
+            CXXFLAGS="$CXXFLAGS +DAportable +DS1.1"
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if echo "$OS_RELEASE" | grep ^B.11 >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define HPUX10 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HPUX11 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _LARGEFILE64_SOURCE 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+        if test -z "$GNU_CC"; then
+            if test -z "$USE_64"; then
+                if test "$OS_TEST" = "ia64"; then
+                    CFLAGS="$CFLAGS +DD32"
+                    CXXFLAGS="$CXXFLAGS +DD32"
+                else
+                    CFLAGS="$CFLAGS +DAportable +DS2.0"
+                    CXXFLAGS="$CXXFLAGS +DAportable +DS2.0"
+                fi
+            else
+                if test "$OS_TEST" = "ia64"; then
+                    CFLAGS="$CFLAGS +DD64"
+                    CXXFLAGS="$CXXFLAGS +DD64"
+                else
+                    CFLAGS="$CFLAGS +DA2.0W +DS2.0"
+                    CXXFLAGS="$CXXFLAGS +DA2.0W +DS2.0"
+                fi
+            fi
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$DEFAULT_IMPL_STRATEGY" = "_EMU"; then
+        USE_NSPR_THREADS=1
+        USE_PTHREADS=
+        USE_USER_THREADS=
+    elif test "$DEFAULT_IMPL_STRATEGY" = "_PTH"; then
+        USE_PTHREADS=1
+        if test "$USE_NSPR_THREADS"; then
+            USE_PTHREADS=
+        fi
+        if test "$USE_USER_PTHREADS"; then
+            USE_PTHREADS=
+        fi
+    fi
+    ;;
+
+*-irix*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define IRIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _SGI_MP_SOURCE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+    PR_MD_CSRCS=irix.c
+    PR_MD_ASFILES=os_Irix.s
+    MKSHLIB='$(LD) $(DSO_LDOPTS) -rdata_shared -shared -soname $(notdir $@) -o $@'
+    STRIP="$STRIP -f"
+    RESOLVE_LINK_SYMBOLS=1
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_irix64.cfg
+    else
+        MDCPUCFG_H=_irix32.cfg
+    fi
+    case "${target_os}" in
+    irix6*)
+        cat >> confdefs.h <<\EOF
+#define IRIX6 1
+EOF
+
+        USE_PTHREADS=1
+        USE_N32=1
+        COMPILER_TAG=_n32
+        IMPL_STRATEGY=_PTH
+        ;;
+    irix5*)
+        cat >> confdefs.h <<\EOF
+#define IRIX5 1
+EOF
+
+        USE_NSPR_THREADS=1
+        ;;
+    *)
+        USE_PTHREADS=1
+        USE_N32=1
+        ;;
+    esac
+    if test "$GNU_CC"; then
+                                                        	    AS='$(CC) -Wp,-P -x assembler-with-cpp -D_ASM -mips2 $(INCLUDES)'
+	    CFLAGS="$CFLAGS -Wall -Wno-format"
+	    _OPTIMIZE_FLAGS="-O6"
+    else
+	    if test -n "$USE_N32"; then
+		AS='as -D_ASM $(INCLUDES) -n32'
+	    else
+		AS='as -D_ASM $(INCLUDES)'
+	    fi
+	    CFLAGS="$CFLAGS -fullwarn -xansi"
+	    if test "$USE_N32"; then
+	        _OPTIMIZE_FLAGS="-O -OPT:Olimit=4000"
+	    else
+	        _OPTIMIZE_FLAGS="-O -Olimit 4000"
+	    fi
+	    if test "$USE_MDUPDATE"; then
+                CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+	    fi
+	    case "${target}" in
+	    *-irix6.*)
+	        CFLAGS="$CFLAGS -multigot"
+	        DSO_LDOPTS="-no_unresolved"
+	        if test "$USE_N32"; then
+		        CFLAGS="$CFLAGS -n32 -woff 1209"
+		        DSO_LDOPTS="$DSO_LDOPTS -n32"
+	        else
+		        if test "$USE_64"; then
+		            CFLAGS="$CFLAGS -64"
+		        else
+		            CFLAGS="$CFLAGS -32"
+		        fi
+	        fi
+	        ;;
+	    *)
+	        CFLAGS="$CFLAGS -xgot"
+	        ;;
+	    esac
+    fi
+    if test "${target_os}" = "irix5.3"; then
+	    cat >> confdefs.h <<\EOF
+#define IRIX5_3 1
+EOF
+
+    fi
+    case "${target_os}" in
+	irix6.5)
+	    if test -z "$GNU_CC"; then
+		    CFLAGS="$CFLAGS -mips3"
+	    fi
+	    cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETPROTO_R 1
+EOF
+
+	    cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETPROTO_R_POINTER 1
+EOF
+
+	    cat >> confdefs.h <<\EOF
+#define _PR_HAVE_SGI_PRDA_PROCMASK 1
+EOF
+
+	    ;;
+	irix5*)
+	    ;;
+	*)
+	    cat >> confdefs.h <<\EOF
+#define _PR_HAVE_SGI_PRDA_PROCMASK 1
+EOF
+
+	    ;;
+	esac
+    ;;
+
+*-linux*|*-gnu*|*-k*bsd*-gnu)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+        IMPL_STRATEGY=_PTH
+    fi
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _GNU_SOURCE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+    case "${target_os}" in
+    linux*)
+        cat >> confdefs.h <<\EOF
+#define LINUX 1
+EOF
+
+        ;;
+    esac
+    CFLAGS="$CFLAGS -Wall"
+    CXXFLAGS="$CXXFLAGS -Wall"
+    MDCPUCFG_H=_linux.cfg
+    PR_MD_CSRCS=linux.c
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    _OPTIMIZE_FLAGS=-O2
+    _DEBUG_FLAGS="-g -fno-inline"  # most people on linux use gcc/gdb, and that
+                                   # combo is not yet good at debugging inlined
+                                   # functions (even when using DWARF2 as the
+                                   # debugging format)
+    COMPILER_TAG=_glibc
+    if echo "$OS_TEST" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    else
+        CPU_ARCH=$OS_TEST
+    fi
+    CPU_ARCH_TAG=_${CPU_ARCH}
+    case "${target_cpu}" in
+    alpha)
+        cat >> confdefs.h <<\EOF
+#define _ALPHA_ 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define __alpha 1
+EOF
+
+        CFLAGS="$CFLAGS -mieee"
+        CXXFLAGS="$CXXFLAGS -mieee"
+        ;;
+    i*86)
+        cat >> confdefs.h <<\EOF
+#define i386 1
+EOF
+
+        PR_MD_ASFILES=os_Linux_x86.s
+        ;;
+    ia64)
+        PR_MD_ASFILES=os_Linux_ia64.s
+        ;;
+    x86_64)
+        if test -n "$USE_64"; then
+            PR_MD_ASFILES=os_Linux_x86_64.s
+        else
+            cat >> confdefs.h <<\EOF
+#define i386 1
+EOF
+
+            PR_MD_ASFILES=os_Linux_x86.s
+            CC="$CC -m32"
+            CXX="$CXX -m32"
+        fi
+        ;;
+    powerpc64)
+        if test -n "$USE_64"; then
+            CC="$CC -m64"
+            CXX="$CXX -m64"
+        fi
+        ;;
+    m68k)
+        CFLAGS="$CFLAGS -m68020-60"
+        CXXFLAGS="$CXXFLAGS -m68020-60"
+        ;;
+    esac    
+    ;;
+
+*-mingw*|*-cygwin*|*-msvc*|*-mks*)
+    cat >> confdefs.h <<\EOF
+#define XP_PC 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define WIN32 1
+EOF
+
+    PR_MD_ARCH_DIR=windows
+    RESOLVE_LINK_SYMBOLS=1
+
+    if test -n "$GNU_CC"; then
+        CC="$CC -mno-cygwin"
+        CXX="$CXX -mno-cygwin"
+        DLL_SUFFIX=dll
+        MKSHLIB='$(CC) -shared -Wl,--export-all-symbols -Wl,--out-implib -Wl,$(IMPORT_LIBRARY) $(DLLBASE) -o $(subst $(OBJDIR)/,,$(SHARED_LIBRARY))'
+        RC=$WINDRES
+        # Use temp file for windres (bug 213281)
+        RCFLAGS='-O coff --use-temp-file'
+    else
+        CC=cl
+        CXX=cl
+        LD=link
+        AR='lib -NOLOGO -OUT:"$@"'
+        AR_FLAGS=
+        RANLIB='echo not_ranlib'
+        STRIP='echo not_strip'
+        RC=rc.exe
+        GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb'
+        OBJ_SUFFIX=obj
+        LIB_SUFFIX=lib
+        DLL_SUFFIX=dll
+
+        # Determine compiler version
+        CC_VERSION=`"${CC}" -v 2>&1 | grep Version | sed -e 's|.* Version ||' -e 's| .*||'`
+        _CC_MAJOR_VERSION=`echo $CC_VERSION | awk -F\. '{ print $1 }'`
+        _CC_MINOR_VERSION=`echo $CC_VERSION | awk -F\. '{ print $2 }'`
+        MSC_VER=${_CC_MAJOR_VERSION}${_CC_MINOR_VERSION}
+        
+        CFLAGS="$CFLAGS -W3 -nologo -GF -Gy"
+        DLLFLAGS='-OUT:"$@"'
+        _DEBUG_FLAGS=-Z7
+        _OPTIMIZE_FLAGS=-O2
+        if test -z "$MOZ_OPTIMIZE"; then
+            CFLAGS="$CFLAGS -Od"
+        fi
+
+        if test -n "$USE_DEBUG_RTL"; then
+            CFLAGS="$CFLAGS -MDd"
+        else
+            CFLAGS="$CFLAGS -MD"
+        fi
+
+        if test -n "$MOZ_DEBUG"; then
+            cat >> confdefs.h <<\EOF
+#define _DEBUG 1
+EOF
+
+        else
+            DEFINES="$DEFINES -U_DEBUG"
+        fi
+
+        if test -n "$MOZ_OPTIMIZE"; then
+            if test -n "$MOZ_PROFILE"; then
+                _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Z7"
+            fi
+            if test -n "$MOZ_DEBUG_SYMBOLS"; then
+                _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Zi"
+            fi
+            if test -n "$MOZ_PROFILE" -o -n "$MOZ_DEBUG_SYMBOLS"; then
+                DLLFLAGS="$DLLFLAGS -DEBUG -OPT:REF"
+                LDFLAGS="$LDFLAGS -DEBUG -OPT:REF"
+            fi
+        fi
+
+        if test -n "$MOZ_DEBUG"; then
+            DLLFLAGS="$DLLFLAGS -DEBUG"
+            LDFLAGS="$LDFLAGS -DEBUG"
+        fi
+
+        OS_DLLFLAGS="-nologo -DLL -SUBSYSTEM:WINDOWS"
+        if test "$MSC_VER" -le "1200" -a -z "$MOZ_DEBUG_SYMBOLS"; then
+            OS_DLLFLAGS="$OS_DLLFLAGS -PDB:NONE"
+        fi
+        
+        if test "$OS_TARGET" = "WINNT"; then
+            CFLAGS="$CFLAGS -GT"
+            if test "$CPU_ARCH" = "x86"; then
+                CFLAGS="$CFLAGS -G5"
+            fi
+            LIBNSPR='$(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+            LIBPLC='$(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+        else
+            LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+            LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+        fi
+    fi # GNU_CC
+
+    if test -n "$USE_STATIC_TLS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_USE_STATIC_TLS 1
+EOF
+
+    fi
+
+    if test "$OS_TARGET" = "WINNT"; then
+        cat >> confdefs.h <<\EOF
+#define WINNT 1
+EOF
+
+    else
+        cat >> confdefs.h <<\EOF
+#define WIN95 1
+EOF
+
+        # undefine WINNT as some versions of mingw gcc define it by default
+        DEFINES="$DEFINES -UWINNT"
+        cat >> confdefs.h <<\EOF
+#define _PR_GLOBAL_THREADS_ONLY 1
+EOF
+
+    fi
+
+    if test "$CPU_ARCH" = "x86"; then
+        CPU_ARCH_TAG=
+    else
+        CPU_ARCH_TAG=$CPU_ARCH
+    fi
+
+    if test -n "$USE_DEBUG_RTL"; then
+        OBJDIR_SUFFIX=OBJD
+    fi
+
+    case "$OS_TARGET" in
+    WINNT)
+	    MDCPUCFG_H=_winnt.cfg
+	    ;;
+    WIN95)
+	    MDCPUCFG_H=_win95.cfg
+	    ;;
+    WIN16)
+	    MDCPUCFG_H=_win16.cfg
+	    ;;
+    *)
+	    { echo "configure: error: Missing OS_TARGET for ${target}.  Use --enable-win32-target to set." 1>&2; exit 1; }
+   	;;
+    esac
+
+    case "$target_cpu" in
+    i*86)
+	if test -n "$USE_64"; then
+	    cat >> confdefs.h <<\EOF
+#define _AMD64_ 1
+EOF
+
+	    cat >> confdefs.h <<\EOF
+#define _M_AMD64 1
+EOF
+    
+	else		
+	    cat >> confdefs.h <<\EOF
+#define _X86_ 1
+EOF
+
+	fi
+        ;;
+    alpha)
+	    cat >> confdefs.h <<\EOF
+#define _ALPHA_ 1
+EOF
+
+   	    ;;
+    mips)
+	    cat >> confdefs.h <<\EOF
+#define _MIPS_ 1
+EOF
+
+	    ;;
+    x86_64)
+	    cat >> confdefs.h <<\EOF
+#define _AMD64_ 1
+EOF
+
+	    cat >> confdefs.h <<\EOF
+#define _M_AMD64 1
+EOF
+
+	    USE_64=1
+	    ;;
+    ia64)
+	    cat >> confdefs.h <<\EOF
+#define _IA64_ 1
+EOF
+
+	    cat >> confdefs.h <<\EOF
+#define _M_IA64 1
+EOF
+
+	    USE_64=1
+	    ;;
+    *)
+	    cat >> confdefs.h <<\EOF
+#define _CPU_ARCH_NOT_DEFINED 1
+EOF
+
+	    ;;
+    esac
+
+    if test "$USE_64"; then
+        cat >> confdefs.h <<\EOF
+#define _WIN64 1
+EOF
+
+    fi
+
+    ;;
+
+*-ncr-sysv*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NCR 1
+EOF
+
+    USE_NSPR_THREADS=1
+    if test "$OS_RELEASE" = "2.03"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ST_ATIM 1
+EOF
+
+    else
+        cat >> confdefs.h <<\EOF
+#define _PR_STAT_HAS_ST_ATIM_UNION 1
+EOF
+
+    fi
+
+    if test -z "$GNU_CC"; then
+        CFLAGS="$CFLAGS -Hnocopyr"
+        CXXFLAGS="$CXXFLAGS -Hnocopyr"
+    else
+        CFLAGS="$CFLAGS -fPIC -Wall"
+        CXXFLAGS="$CXXFLAGS -fPIC -Wall"
+        DSO_LDOPTS=-G
+    fi
+    MDCPUCFG_H=_ncr.cfg
+    PR_MD_CSRCS=ncr.c
+    ;;
+
+mips-nec-sysv*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NEC 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define nec_ews 1
+EOF
+
+    USE_NSPR_THREADS=1
+    if test -z "$GNU_CC"; then
+        CC='$(NSDEPTH)/build/hcc cc -Xa -KGnum=0 -KOlimit=4000'
+        CXX=g++
+    fi
+    OS_LIBS="$OS_LIBS -lsocket -lnsl -ldl"
+    DSO_LDOPTS=-G
+    MDCPUCFG_H=_nec.cfg
+    PR_MD_CSRCS=nec.c
+    ;;
+
+*-netbsd*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NETBSD 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_BSD_FLOCK 1
+EOF
+
+    USE_NSPR_THREADS=1
+    MDCPUCFG_H=_netbsd.cfg
+    PR_MD_CSRCS=netbsd.c
+
+    DSO_CFLAGS='-fPIC -DPIC'
+    CFLAGS="$CFLAGS -ansi -Wall"
+    CXXFLAGS="$CXXFLAGS -ansi -Wall"
+    MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)'
+
+    if test -z "$OBJECT_FMT"; then
+        if echo __ELF__ | ${CC-cc} -E - | grep -q __ELF__ 2>/dev/null; then
+            OBJECT_FMT=a.out
+            DLL_SUFFIX=so.1.0
+            DSO_LDOPTS='-shared'
+        else
+            OBJECT_FMT=ELF
+            DLL_SUFFIX=so
+            DSO_LDOPTS='-shared -Wl,-soname,$(notdir $@)'
+        fi
+    fi
+
+    if test "$LIBRUNPATH"; then
+        DSO_LDOPTS="$DSO_LDOPTS -Wl,-R$LIBRUNPATH"
+    fi
+    ;;
+
+mips-sony-newsos*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SONY 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __svr4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __svr4__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_SVID_GETTOD 1
+EOF
+
+    USE_NSPR_THREADS=1
+    CFLAGS="$CFLAGS -Xa -fullwarn"
+    CXXFLAGS="$CXXFLAGS -Xa -fullwarn"
+    DSO_LDOPTS=-G
+    MDCPUCFG_H=_sony.cfg
+    PR_MD_CSRCS=sony.c
+    ;;
+
+*-nextstep*|*-openstep*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NEXTSTEP 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_BSD_FLOCK 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+    CFLAGS="$CFLAGS -Wall -fno-common -traditional-cpp -posix"
+    CXXFLAGS="$CXXFLAGS -Wall -fno-common -traditional-cpp -posix"
+    USE_NSPR_THREADS=1
+    DLL_SUFFIX=dylib
+    MDCPUCFG_H=_nextstep.cfg
+    PR_MD_CSRCS=nextstep.c
+    ;;
+
+
+*-nto*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define NTO 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _QNX_SOURCE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+    MDCPUCFG_H=_nto.cfg
+    PR_MD_CSRCS=nto.c
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(notdir $@) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS=-shared
+    OS_LIBS="$OS_LIBS -lsocket"
+    _OPTIMIZE_FLAGS="-O1"
+    _DEBUG_FLAGS="-gstabs"
+	;;
+
+*-openbsd*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define OPENBSD 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_BSD_FLOCK 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_SOCKLEN_T 1
+EOF
+
+    CFLAGS="$CFLAGS -ansi -Wall"
+    CXXFLAGS="$CXXFLAGS -ansi -Wall"
+    DLL_SUFFIX=so.1.0
+    DSO_CFLAGS=-fPIC
+    MDCPUCFG_H=_openbsd.cfg
+    PR_MD_CSRCS=openbsd.c
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    DSO_LDOPTS='-shared -fPIC'
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    ;;
+
+*-openvms*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define VMS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PR_GETIPNODE_NOT_THREADSAFE 1
+EOF
+
+    RESOLVE_LINK_SYMBOLS=1
+    AR_FLAGS='c $@'
+    MDCPUCFG_H=_openvms.cfg
+    PR_MD_CSRCS=openvms.c
+    DSO_LDOPTS='-shared -auto_symvec $(LDFLAGS)'
+    if test -n "$MOZ_DEBUG"; then
+      DSO_LDOPTS="$DSO_LDOPTS $_DEBUG_FLAGS"
+    else
+      DSO_LDOPTS="$DSO_LDOPTS $_OPTIMIZE_FLAGS"
+    fi
+    ;;
+
+*-osf*)
+    SHELL_OVERRIDE="SHELL		= /usr/bin/ksh"
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define OSF1 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
+    # OSF1 and HPUX report the POLLHUP event for a socket when the
+    # shutdown(SHUT_WR) operation is called for the remote end, even though
+    # the socket is still writeable. Use select(), instead of poll(), to
+    # workaround this problem.
+    cat >> confdefs.h <<\EOF
+#define _PR_POLL_WITH_SELECT 1
+EOF
+
+
+    if echo "$OS_RELEASE" | egrep -c '(V2.0|V3.2)' 2>/dev/null ; then
+        USE_NSPR_THREADS=1
+    fi
+
+    if test -z "$GNU_CC"; then
+        CC="$CC -std1 -ieee_with_inexact"
+        if test "$OS_RELEASE" != "V2.0"; then
+            CC="$CC -readonly_strings"
+        fi
+        _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Olimit 4000"
+        ac_safe=`echo "machine/builtins.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for machine/builtins.h""... $ac_c" 1>&6
+echo "configure:4436: checking for machine/builtins.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 4441 "configure"
+#include "confdefs.h"
+#include <machine/builtins.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4446: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define OSF1_HAVE_MACHINE_BUILTINS_H 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    else
+        CFLAGS="$CFLAGS -mieee"
+        CXXFLAGS="$CXXFLAGS -mieee"
+    fi
+
+    if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define HAVE_INT_LOCALTIME_R 1
+EOF
+
+    else
+        cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+    fi
+    if echo $OS_RELEASE | grep -c V4.0 >/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define OSF1V4_MAP_PRIVATE_BUG 1
+EOF
+
+    fi
+    DSO_LDOPTS='-shared -all -expect_unresolved "*" -soname $(notdir $@)'
+    MDCPUCFG_H=_osf1.cfg
+    PR_MD_CSRCS=osf1.c
+    ;;
+
+*-qnx*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define QNX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+    USE_NSPR_THREADS=1
+    MDCPUCFG_H=_qnx.cfg
+    PR_MD_CSRCS=qnx.c
+    ;;
+
+*-riscos*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define RISCOS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+    USE_PTHREADS=1
+    MDCPUCFG_H=_riscos.cfg
+    PR_MD_CSRCS=riscos.c
+    DLL_SUFFIX=a
+    LD="/home/riscos/env/ro-ar cr"
+    ;;
+
+*-*-sco*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SCO 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define sco 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _SVID3 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define _PR_NEED_H_ERRNO 1
+EOF
+
+    CC='cc -b elf -KPIC'
+    CXX='$(NSDEPTH)/build/hcpp CC +.cpp +w'
+    USE_NSPR_THREADS=1
+    CPU_ARCH=x86
+    DSO_LDOPTS='-b elf -G'
+    MDCPUCFG_H=_scoos.cfg
+    PR_MD_SRCS=scoos.c
+    ;;
+
+*-sinix*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SNI 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define RELIANTUNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define sinix 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_SVID_GETTOD 1
+EOF
+
+    if echo "$OS_TEST" | grep -c 86 2>/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define i386 1
+EOF
+
+        CPU_ARCH=x86
+    else
+        CPU_ARCH=mips
+    fi
+
+    if test "$GNU_CC"; then
+        AS='$(CC) -x assembler-with-cpp'
+        if test "$CPU_ARCH" = "mips"; then
+            LD=gld
+        fi
+        CFLAGS="$CFLAGS -Wall -Wno-format"
+    else
+        AS='/usr/bin/cc'
+        _OPTIMIZE_FLAGS='-O -F Olimit,4000'
+    fi
+
+    DSO_LDOPTS='-G -z defs -h $(@:$(OBJDIR)/%.so=%.so)'
+
+    if test "$OS_RELEASE" = "5.43"; then
+        cat >> confdefs.h <<\EOF
+#define IP_MULTICAST 1
+EOF
+
+    fi
+
+    OS_LIBS="$OS_LIBS -lsocket -lnsl -lresolv -ldl -lc"
+    USE_NSPR_THREADS=1
+    MDCPUCFG_H=_reliantunix.cfg
+    PR_MD_CSRCS=reliantunix.c
+    if test "${OS_ARCH}" = "mips"; then
+        PR_MD_ASFILES=os_ReliantUNIX.s
+    fi
+    ;;
+
+*-sunos*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SUNOS4 1
+EOF
+
+    CFLAGS="$CFLAGS -Wall -Wno-format"
+    if test "$USE_MDUPDATE"; then
+        CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+    fi
+    CPU_ARCH=sparc
+    DLL_SUFFIX=so.1.0
+    DSO_LDOPTS=
+    DSO_CFLAGS=-fPIC
+    USE_NSPR_THREADS=1
+    if test "$OS_RELEASE" = "4.1.3_U1"; then
+        _OPTIMIZE_FLAGS=
+        OS_LIBS="$OS_LIBS -lm"
+    fi
+    MDCPUCFG_H=_sunos4.cfg
+    PR_MD_CSRCS=sunos4.c
+    ;;
+
+*-solaris*)
+    if test -z "$USE_USER_THREADS" && test -z "$USE_NATIVE_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __svr4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define __svr4__ 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SOLARIS 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_FCNTL_FILE_LOCKING 1
+EOF
+
+    MDCPUCFG_H=_solaris.cfg
+    PR_MD_CSRCS=solaris.c
+    LD=/usr/ccs/bin/ld
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    RESOLVE_LINK_SYMBOLS=1
+    if test -n "$GNU_CC"; then
+        DSO_CFLAGS=-fPIC
+        if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then
+            GCC_USE_GNU_LD=1
+        fi
+        DSO_LDOPTS='-shared -Wl,-h,$(notdir $@),-z,combreloc,-z,defs,-z,ignore' 
+    else
+        DSO_CFLAGS=-KPIC
+        DSO_LDOPTS='-G -h $(notdir $@) -z combreloc -z defs -z ignore'
+    fi
+    if test -n "$GNU_CC"; then
+        CFLAGS="$CFLAGS -Wall"
+        CXXFLAGS="$CXXFLAGS -Wall"
+        if test -n "$USE_MDUPDATE"; then
+            CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+            CXXFLAGS="$CXXFLAGS -MDupdate \$(DEPENDENCIES)"
+        fi
+        GCC_AS=`$CC -print-prog-name=as`
+        if test "`echo | $GCC_AS -v 2>&1 | grep -c GNU`" != "0"; then
+            GNU_AS=1
+        fi
+    else
+        CFLAGS="$CFLAGS -xstrconst"
+        CXXFLAGS="$CXXFLAGS -Qoption cg -xstrconst -features=tmplife"
+        if test -z "$MOZ_OPTIMIZE"; then
+            CFLAGS="$CFLAGS -xs"
+            CXXFLAGS="$CXXFLAGS -xs"
+        fi
+        _OPTIMIZE_FLAGS=-xO4
+    fi
+    if test -z "$GNU_AS"; then
+        ASFLAGS="$ASFLAGS -Wa,-P"
+    fi
+    if test -n "$USE_64"; then
+        if test -n "$GNU_CC"; then
+            CC="$CC -m64"
+            CXX="$CXX -m64"
+        else
+            if test "$OS_TEST" = "i86pc"; then
+                CC="$CC -xarch=amd64"
+                CXX="$CXX -xarch=amd64"
+            else
+                CC="$CC -xarch=v9"
+                CXX="$CXX -xarch=v9"
+            fi
+        fi
+    fi
+    if test "$OS_TEST" = "i86pc"; then
+        if test -z "$USE_64"; then
+            cat >> confdefs.h <<\EOF
+#define i386 1
+EOF
+
+        fi
+        CPU_ARCH_TAG=_$OS_TEST
+        # The default debug format, DWARF (-g), is not supported by gcc
+        # on i386-ANY-sysv4/solaris, but the stabs format is.  It is
+        # assumed that the Solaris assembler /usr/ccs/bin/as is used.
+        # If your gcc uses GNU as, you do not need the -Wa,-s option.
+        if test -n "$MOZ_DEBUG" && test -n "$GNU_CC"; then
+            _DEBUG_FLAGS=-gstabs
+            if test -z "$GNU_AS"; then
+                _DEBUG_FLAGS="$_DEBUG_FLAGS -Wa,-s"
+            fi
+        fi
+    fi
+    case "${target_os}" in
+    solaris2.3*)
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+        ;;
+    solaris2.4*)
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+        ;;
+    solaris2.5*)
+        cat >> confdefs.h <<\EOF
+#define SOLARIS2_5 1
+EOF
+    
+        ;;
+    *)
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        # The lfcompile64(5) man page on Solaris 2.6 says:
+        #     For applications that do not wish to conform to the POSIX or
+        #     X/Open  specifications,  the  64-bit transitional interfaces
+        #     are available by default.  No compile-time flags need to  be
+        #     set.
+        # But gcc 2.7.2.x fails to define _LARGEFILE64_SOURCE by default.
+        # The native compiler, gcc 2.8.x, and egcs don't have this problem.
+        if test -n "$GNU_CC"; then
+            cat >> confdefs.h <<\EOF
+#define _LARGEFILE64_SOURCE 1
+EOF
+
+        fi
+        ;;
+    esac
+    case "${target_os}" in
+    solaris2.3*)
+        ;;
+    solaris2.4*)
+        ;;
+    solaris2.5*)
+        ;;
+    solaris2.6*)
+        ;;
+    solaris2.7*)
+        ;;
+    *)
+        # Solaris 8 or higher has IPv6.
+        cat >> confdefs.h <<\EOF
+#define _PR_INET6 1
+EOF
+
+        ;;
+    esac
+    if test "$OS_TEST" = "sun4u"; then
+        # 64-bit Solaris requires SPARC V9 architecture, so the following
+        # is not needed.
+        if test -z "$USE_64"; then
+            ULTRASPARC_LIBRARY=nspr_flt
+        fi
+    fi
+    # Purify requires that binaries linked against nspr also
+    # be linked against -lrt (or -lposix4) so add it to OS_LIBS
+    _rev=`uname -r`
+    _librt=`echo $_rev 5.6 | awk '{ if ($1 > $2) print "-lrt"; else print "-lposix4" }'`
+    OS_LIBS="$OS_LIBS $_librt"
+    ;;
+
+*-sco-sysv5*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define UNIXWARE 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
+
+    USE_NSPR_THREADS=1
+    if echo $OS_RELEASE | grep -c 2.1 2>/dev/null; then
+        cat >> confdefs.h <<\EOF
+#define _PR_NO_LARGE_FILES 1
+EOF
+
+        CC='$(NSDEPTH)/build/hcc cc'
+        CXX='$(NSDEPTH)/build/hcpp CC'
+        MDCPUCFG_H=_unixware.cfg
+    else
+        cat >> confdefs.h <<\EOF
+#define _LARGEFILE64_SOURCE 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_OFF64_T 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_SOCKADDR_LEN 1
+EOF
+
+        MDCPUCFG_H=_unixware7.cfg
+    fi
+    PR_MD_CSRCS=unixware.c
+    DSO_LDOPTS=-G
+    CPU_ARCH=x86
+    ;;
+
+*-os2*)
+    cat >> confdefs.h <<\EOF
+#define XP_OS2 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define XP_PC 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define BSD_SELECT 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define TCPV40HDRS 1
+EOF
+
+    LIB_SUFFIX=lib
+    DLL_SUFFIX=dll
+    RC=rc.exe
+    PR_MD_ARCH_DIR=os2
+    PROG_SUFFIX=.exe
+    NSINSTALL=nsinstall
+    MDCPUCFG_H=_os2.cfg
+    RESOLVE_LINK_SYMBOLS=1
+
+    # EMX/GCC build
+    if test -n "$GNU_CC"; then
+        cat >> confdefs.h <<\EOF
+#define XP_OS2_EMX 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define OS2 1
+EOF
+
+        AR=emxomfar
+        AR_FLAGS='r $@'
+        CFLAGS="$CFLAGS -Wall -Zomf"
+        CXXFLAGS="$CFLAGS -Wall -Zomf"
+        MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+        DSO_CFLAGS=
+        DSO_LDOPTS='-Zomf -Zdll -Zmap'
+        LDFLAGS='-Zmap'
+        _OPTIMIZE_FLAGS="-O2 -s"
+        _DEBUG_FLAGS="-g -fno-inline"
+        if test -n "$MOZ_OPTIMIZE"; then
+          DSO_LDOPTS="$DSO_LDOPTS -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA"
+        fi
+        OS_LIBS="-lsocket"
+        IMPLIB='emximp -o'
+        FILTER='emxexp -o'
+
+        # GCC for OS/2 currently predefines these, but we don't want them
+        DEFINES="$DEFINES -Uunix -U__unix -U__unix__"
+
+    # Visual Age C++ build
+    elif test "$VACPP" = "yes"; then
+        cat >> confdefs.h <<\EOF
+#define XP_OS2_VACPP 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define OS2 4
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _X86_ 1
+EOF
+
+        OBJ_SUFFIX=obj
+        AS=alp
+        ASFLAGS='-Mb'
+        ASM_SUFFIX=asm
+        AR=-ilib
+        AR_FLAGS='/NOL /NOI /O:$(subst /,\\,$@)'
+        CFLAGS='/Q /qlibansi /Gd+ /Gm+ /Su4 /Mp /Tl9'
+        HOST_CFLAGS="$CFLAGS"
+        OS_CFLAGS='/Q /qlibansi /Gd+ /Gm+ /Su4 /Mp /Tl9'
+        OS_EXE_CFLAGS='/Q /qlibansi /Gd+ /Gm+ /Su4 /Mp /Tl9'
+        CXXFLAGS='/Q /qlibansi /Gd+ /Gm+ /Su4 /Mp /Tl9'
+        OS_LIBS='so32dll.lib tcp32dll.lib'
+        LD='-ilink'
+        MKSHLIB='$(LD) $(DSO_LDOPTS)'
+        IMPLIB='implib -nologo -noignorecase'
+        FILTER='cppfilt -q -B -P'
+        _OPTIMIZE_FLAGS='/O+ /Gl+ /qtune=pentium /qarch=pentium'
+        _DEBUG_FLAGS='/Ti+ '
+        LDFLAGS='/NOL /M /L'
+        DLLFLAGS='/O:$@ /DLL /INC:_dllentry /MAP:$(@:.dll=.map) /L /NOL'
+        EXEFLAGS='/OUT:$@ /PMTYPE:VIO /MAP:$(@:.exe=.map) /L /NOL'
+        if test -n "$MOZ_DEBUG"; then
+          LDFLAGS="$LDFLAGS /DE"
+          DLLFLAGS="$DLLFLAGS /DE"
+          EXEFLAGS="$EXEFLAGS /DE"
+        fi
+        if test -n "$MOZ_OPTIMIZE"; then
+          LDFLAGS="$LDFLAGS /OPTFUNC /EXEPACK:2 /PACKCODE /PACKDATA"
+          DLLFLAGS="$DLLFLAGS /OPTFUNC /EXEPACK:2 /PACKCODE /PACKDATA"
+          EXEFLAGS="$EXEFLAGS /OPTFUNC /EXEPACK:2 /PACKCODE /PACKDATA"
+        fi
+        LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+        LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+    fi
+    ;;
+
+*)
+    cat >> confdefs.h <<\EOF
+#define XP_UNIX 1
+EOF
+
+    ;;
+   
+esac
+
+if test -z "$SKIP_LIBRARY_CHECKS"; then
+
+
+
+case $target in
+*-darwin*|*-beos*)
+    ;;
+*)
+    echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:5008: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5016 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:5027: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6
+echo "configure:5044: checking for dlfcn.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 5049 "configure"
+#include "confdefs.h"
+#include <dlfcn.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5054: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  OS_LIBS="-ldl $OS_LIBS"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    ;;
+esac
+
+
+
+
+if test $ac_cv_prog_gcc = yes; then
+    echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:5087: checking whether ${CC-cc} needs -traditional" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat > conftest.$ac_ext <<EOF
+#line 5093 "configure"
+#include "confdefs.h"
+#include <sgtty.h>
+Autoconf TIOCGETP
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "$ac_pattern" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=yes
+else
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat > conftest.$ac_ext <<EOF
+#line 5111 "configure"
+#include "confdefs.h"
+#include <termio.h>
+Autoconf TCGETA
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "$ac_pattern" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+for ac_func in lchown strerror
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:5135: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 5140 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:5163: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+# Check whether --enable-strip or --disable-strip was given.
+if test "${enable_strip+set}" = set; then
+  enableval="$enable_strip"
+   if test "$enableval" = "yes"; then
+	    ENABLE_STRIP=1
+      fi 
+fi
+
+
+case "${target_os}" in
+hpux*)
+if test -z "$GNU_CC"; then
+
+    echo $ac_n "checking for +Olit support""... $ac_c" 1>&6
+echo "configure:5204: checking for +Olit support" >&5
+if eval "test \"`echo '$''{'ac_cv_hpux_usable_olit_option'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+                  ac_cv_hpux_usable_olit_option=no
+        rm -f conftest*
+        echo 'int main() { return 0; }' | cat > conftest.c
+        ${CC-cc} ${CFLAGS} +Olit=all -o conftest conftest.c > conftest.out 2>&1
+        if test $? -eq 0; then
+            if test -z "`egrep -i '(unrecognize|unknown)' conftest.out`"; then
+                ac_cv_hpux_usable_olit_option=yes
+            fi
+        fi
+        rm -f conftest*
+        
+fi
+
+echo "$ac_t""$ac_cv_hpux_usable_olit_option" 1>&6
+
+    if test "$ac_cv_hpux_usable_olit_option" = "yes"; then
+        CFLAGS="$CFLAGS +Olit=all"
+        CXXFLAGS="$CXXFLAGS +Olit=all"
+    else
+        CFLAGS="$CFLAGS +ESlit"
+        CXXFLAGS="$CXXFLAGS +ESlit"
+    fi
+fi
+;;
+esac
+
+
+
+case "$target_os" in
+darwin*)
+    _HAVE_PTHREADS=1
+    ;;
+*)
+    
+echo $ac_n "checking for pthread_create in -lpthreads""... $ac_c" 1>&6
+echo "configure:5243: checking for pthread_create in -lpthreads" >&5
+echo "
+    #include <pthread.h> 
+    void *foo(void *v) { return v; } 
+    int main() { 
+        pthread_t t;
+        if (!pthread_create(&t, 0, &foo, 0)) {
+            pthread_join(t, 0);
+        }
+        return 0;
+    }" > dummy.c ;
+    echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthreads $LDFLAGS $LIBS" 1>&5;
+    ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthreads $LDFLAGS $LIBS 2>&5;
+    _res=$? ;
+    rm -f dummy.c dummy${ac_exeext} ;
+    if test "$_res" = "0"; then
+        echo "$ac_t""yes" 1>&6
+        _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthreads"
+    else
+        echo "$ac_t""no" 1>&6
+        
+echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
+echo "configure:5265: checking for pthread_create in -lpthread" >&5
+echo "
+    #include <pthread.h> 
+    void *foo(void *v) { return v; } 
+    int main() { 
+        pthread_t t;
+        if (!pthread_create(&t, 0, &foo, 0)) {
+            pthread_join(t, 0);
+        }
+        return 0;
+    }" > dummy.c ;
+    echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthread $LDFLAGS $LIBS" 1>&5;
+    ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lpthread $LDFLAGS $LIBS 2>&5;
+    _res=$? ;
+    rm -f dummy.c dummy${ac_exeext} ;
+    if test "$_res" = "0"; then
+        echo "$ac_t""yes" 1>&6
+        _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthread"
+    else
+        echo "$ac_t""no" 1>&6
+        
+echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6
+echo "configure:5287: checking for pthread_create in -lc_r" >&5
+echo "
+    #include <pthread.h> 
+    void *foo(void *v) { return v; } 
+    int main() { 
+        pthread_t t;
+        if (!pthread_create(&t, 0, &foo, 0)) {
+            pthread_join(t, 0);
+        }
+        return 0;
+    }" > dummy.c ;
+    echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc_r $LDFLAGS $LIBS" 1>&5;
+    ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc_r $LDFLAGS $LIBS 2>&5;
+    _res=$? ;
+    rm -f dummy.c dummy${ac_exeext} ;
+    if test "$_res" = "0"; then
+        echo "$ac_t""yes" 1>&6
+        _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lc_r"
+    else
+        echo "$ac_t""no" 1>&6
+        
+echo $ac_n "checking for pthread_create in -lc""... $ac_c" 1>&6
+echo "configure:5309: checking for pthread_create in -lc" >&5
+echo "
+    #include <pthread.h> 
+    void *foo(void *v) { return v; } 
+    int main() { 
+        pthread_t t;
+        if (!pthread_create(&t, 0, &foo, 0)) {
+            pthread_join(t, 0);
+        }
+        return 0;
+    }" > dummy.c ;
+    echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc $LDFLAGS $LIBS" 1>&5;
+    ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -lc $LDFLAGS $LIBS 2>&5;
+    _res=$? ;
+    rm -f dummy.c dummy${ac_exeext} ;
+    if test "$_res" = "0"; then
+        echo "$ac_t""yes" 1>&6
+        _HAVE_PTHREADS=1
+                
+    else
+        echo "$ac_t""no" 1>&6
+        
+    fi
+
+            
+    fi
+
+        
+    fi
+
+    
+    fi
+
+    ;;
+esac
+
+# Check whether --with-pthreads or --without-pthreads was given.
+if test "${with_pthreads+set}" = set; then
+  withval="$with_pthreads"
+   if test "$withval" = "yes"; then
+	    if test -n "$_HAVE_PTHREADS"; then
+		    USE_PTHREADS=1 
+		    USE_USER_PTHREADS=
+		    USE_NSPR_THREADS=
+	    else
+		    { echo "configure: error:  --with-pthreads specified for a system without pthread support " 1>&2; exit 1; };
+	    fi
+	  else
+	    USE_PTHREADS=
+	    _PTHREAD_LDFLAGS=
+	  fi
+else
+   if test -n "$_HAVE_PTHREADS" && test -z "$USE_USER_PTHREADS" && test -z "$USE_NSPR_THREADS"; then
+	    USE_PTHREADS=1
+	    USE_USER_PTHREADS=
+	    USE_NSPR_THREADS=
+	  fi
+fi
+
+
+# Check whether --enable-user-pthreads or --disable-user-pthreads was given.
+if test "${enable_user_pthreads+set}" = set; then
+  enableval="$enable_user_pthreads"
+   if test "$enableval" = "yes"; then
+        if test -n "$_HAVE_PTHREADS"; then
+		    USE_PTHREADS=
+		    USE_USER_PTHREADS=1
+		    USE_NSPR_THREADS=
+	    else
+		    { echo "configure: error:  --enable-user-pthreads specified for a system without pthread support " 1>&2; exit 1; };
+	    fi
+	  fi
+fi
+
+
+# Check whether --enable-nspr-threads or --disable-nspr-threads was given.
+if test "${enable_nspr_threads+set}" = set; then
+  enableval="$enable_nspr_threads"
+   if test "$enableval" = "yes"; then
+	    USE_PTHREADS=
+	    USE_USER_PTHREADS=
+	    USE_NSPR_THREADS=1
+	  fi
+fi
+
+
+case "$target" in
+*-beos*)
+    # Check whether --with-bthreads or --without-bthreads was given.
+if test "${with_bthreads+set}" = set; then
+  withval="$with_bthreads"
+  	if test "$withval" = "yes"; then
+    	    USE_BTHREADS=1
+	        USE_USER_PTHREADS=
+	        USE_PTHREADS=
+	    fi
+fi
+
+    ;;
+
+*-solaris*)
+    # Check whether --with-native-threads or --without-native-threads was given.
+if test "${with_native_threads+set}" = set; then
+  withval="$with_native_threads"
+   if test "$withval" = "yes"; then
+	    USE_NATIVE_THREADS=1
+	    USE_USER_PTHREADS=
+	    USE_PTHREADS=
+	  fi
+fi
+
+    ;;
+esac
+
+fi # SKIP_LIBRARY_CHECKS
+
+# Check whether --enable-cplus or --disable-cplus was given.
+if test "${enable_cplus+set}" = set; then
+  enableval="$enable_cplus"
+   if test "$enableval" = "yes"; then
+	    USE_CPLUS=1
+      fi
+fi
+ 
+
+# Check whether --enable-ipv6 or --disable-ipv6 was given.
+if test "${enable_ipv6+set}" = set; then
+  enableval="$enable_ipv6"
+   if test "$enableval" = "yes"; then
+	    USE_IPV6=1
+      else
+	    USE_IPV6=
+      fi
+fi
+
+
+
+# Check whether --enable-boehm or --disable-boehm was given.
+if test "${enable_boehm+set}" = set; then
+  enableval="$enable_boehm"
+   if test "$enableval" = "yes"; then
+        cat >> confdefs.h <<\EOF
+#define GC_LEAK_DETECTOR 1
+EOF
+
+        GC_LEAK_DETECTOR=1
+    fi
+fi
+
+
+if test -n "$USE_PTHREADS"; then
+      rm -f conftest*
+   ac_cv_have_dash_pthread=no
+   echo $ac_n "checking whether ${CC-cc} accepts -pthread""... $ac_c" 1>&6
+echo "configure:5463: checking whether ${CC-cc} accepts -pthread" >&5
+   echo 'int main() { return 0; }' | cat > conftest.c
+   ${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1
+   if test $? -eq 0; then
+	if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthread`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then
+	    ac_cv_have_dash_pthread=yes
+		case "$target_os" in
+	    freebsd*)
+# Freebsd doesn't use -pthread for compiles, it uses them for linking
+            ;;
+	    *)
+            CFLAGS="$CFLAGS -pthread"
+            CXXFLAGS="$CXXFLAGS -pthread"
+            ;;
+        esac
+	fi
+    fi
+    rm -f conftest*
+    echo "$ac_t""$ac_cv_have_dash_pthread" 1>&6
+
+			    ac_cv_have_dash_pthreads=no
+    if test "$ac_cv_have_dash_pthread" = "no"; then
+	    echo $ac_n "checking whether ${CC-cc} accepts -pthreads""... $ac_c" 1>&6
+echo "configure:5486: checking whether ${CC-cc} accepts -pthreads" >&5
+    	echo 'int main() { return 0; }' | cat > conftest.c
+	    ${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1
+    	if test $? -eq 0; then
+	    	if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthreads`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then
+			    ac_cv_have_dash_pthreads=yes
+			    CFLAGS="$CFLAGS -pthreads"
+			    CXXFLAGS="$CXXFLAGS -pthreads"
+		    fi
+	    fi
+	    rm -f conftest*
+    	echo "$ac_t""$ac_cv_have_dash_pthreads" 1>&6
+    fi
+
+    case "$target" in
+    *-solaris*)
+        if test "$ac_cv_have_dash_pthreads" = "yes"; then
+            _PTHREAD_LDFLAGS=
+        fi
+	    ;;
+    *-freebsd*)
+	    cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
+	    cat >> confdefs.h <<\EOF
+#define _THREAD_SAFE 1
+EOF
+
+	    	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS="-pthread"
+	    else
+	        _PTHREAD_LDFLAGS="-lc_r"
+	    fi
+	    ;;
+    *-netbsd*)
+	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS="-pthread"
+	    fi
+	    ;;
+    *-bsdi*)
+	    cat >> confdefs.h <<\EOF
+#define _THREAD_SAFE 1
+EOF
+
+	    	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS=
+	    fi
+	    ;;
+    *-openbsd*)
+        if test "$ac_cv_have_dash_pthread" = "yes"; then
+            _PTHREAD_LDFLAGS=-pthread
+        fi
+        ;;
+    *-linux*|*-gnu*|*-k*bsd*-gnu)
+        cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
+        ;;
+    esac
+
+else 
+    if test -n "$USE_USER_PTHREADS"; then
+	    USE_PTHREADS=
+	    USE_NSPR_THREADS=
+    else
+        _PTHREAD_LDFLAGS=
+    fi
+fi
+
+case "$target" in
+*-aix*)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi
+    case "$target_os" in
+    aix4.1*)
+        if test -z "$USE_PTHREADS"; then
+            cat >> confdefs.h <<\EOF
+#define AIX_RENAME_SELECT 1
+EOF
+
+        fi
+        ;;
+    aix4.2*)
+        if test -z "$USE_NSPR_THREADS"; then
+            cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+        fi
+        ;;
+    aix4.3*)
+        if test -z "$USE_NSPR_THREADS"; then
+            cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+        fi
+        if test -n "$USE_PTHREADS"; then
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_THREADSAFE_GETHOST 1
+EOF
+
+        fi
+        ;;
+    *)
+        if test -z "$USE_NSPR_THREADS"; then
+            cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+        fi
+        if test -n "$USE_PTHREADS"; then
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_THREADSAFE_GETHOST 1
+EOF
+
+        fi
+        ;;
+    esac
+    ;;
+*-bsdi*)
+    if test -n "$USE_PTHREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_NEED_PTHREAD_INIT 1
+EOF
+
+    fi
+    ;;
+*-freebsd*)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi
+    ;;
+*-hpux*)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi 
+    if test "$USE_PTHREADS"; then
+        if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+            cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
+            cat >> confdefs.h <<\EOF
+#define _PR_DCETHREADS 1
+EOF
+
+        else
+            cat >> confdefs.h <<EOF
+#define _POSIX_C_SOURCE 199506L
+EOF
+
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_THREADSAFE_GETHOST 1
+EOF
+
+        fi
+    fi
+    if test "$USE_USER_PTHREADS"; then
+        cat >> confdefs.h <<EOF
+#define _POSIX_C_SOURCE 199506L
+EOF
+
+    fi
+    ;;
+*-irix*)
+    if test "${target_os}" = "irix6.5"; then
+        if test -n "$USE_PTHREADS"; then
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETHOST_R 1
+EOF
+
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETHOST_R_POINTER 1
+EOF
+
+        fi
+    fi
+    ;;
+*-linux*|*-gnu*|*-k*bsd*-gnu)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi
+    ;;
+*-mingw*|*-cygwin*|*-msvc*|*-mks*|*-os2*|*-beos*)
+        USE_PTHREADS=
+    _PTHREAD_LDFLAGS=
+    USE_USER_PTHREADS=
+    ;;
+*-netbsd*|*-openbsd*)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi
+    ;;
+*-osf*)
+    if test -n "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+    fi
+    if test -n "$USE_PTHREADS"; then
+        if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then
+            :
+        else
+            cat >> confdefs.h <<\EOF
+#define _PR_HAVE_THREADSAFE_GETHOST 1
+EOF
+
+        fi
+    fi
+    ;;
+*-solaris*)
+    if test -n "$USE_NATIVE_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_GLOBAL_THREADS_ONLY 1
+EOF
+
+    else
+        if test -n "$USE_NSPR_THREADS"; then
+            cat >> confdefs.h <<\EOF
+#define _PR_LOCAL_THREADS_ONLY 1
+EOF
+
+        fi
+    fi
+    if test -z "$USE_NSPR_THREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _REENTRANT 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define HAVE_POINTER_LOCALTIME_R 1
+EOF
+
+        if test "$OS_TEST" = "i86pc"; then
+            if test -n "$USE_64"; then
+               PR_MD_ASFILES=os_SunOS_x86_64.s
+            else
+               PR_MD_ASFILES=os_SunOS_x86.s
+            fi
+        else
+            if test -n "$USE_64"; then
+                PR_MD_ASFILES=os_SunOS_sparcv9.s
+            fi
+            if test -n "$USE_NATIVE_THREADS"; then
+                PR_MD_ASFILES="$PR_MD_ASFILES os_SunOS.s"
+            fi
+        fi
+    fi
+    ;;
+*-nto*)
+    if test -n "$USE_PTHREADS"; then
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETHOST_R 1
+EOF
+
+        cat >> confdefs.h <<\EOF
+#define _PR_HAVE_GETHOST_R_POINTER 1
+EOF
+
+    fi
+    ;;
+esac
+
+OS_LIBS="$_PTHREAD_LDFLAGS $OS_LIBS"
+
+if test -n "$_SAVE_OPTIMIZE_FLAGS"; then
+    _OPTIMIZE_FLAGS="$_SAVE_OPTIMIZE_FLAGS"
+fi
+
+if test -n "$_SAVE_DEBUG_FLAGS"; then
+    _DEBUG_FLAGS="$_SAVE_DEBUG_FLAGS"
+fi
+
+if test -n "$MOZ_OPTIMIZE"; then
+    CFLAGS="$CFLAGS $_OPTIMIZE_FLAGS"
+    CXXFLAGS="$CXXFLAGS $_OPTIMIZE_FLAGS"
+fi
+
+if test -n "$MOZ_DEBUG"; then
+    CFLAGS="$CFLAGS $_DEBUG_FLAGS"
+    CXXFLAGS="$CXXFLAGS $_DEBUG_FLAGS"
+fi
+
+if test -n "$MOZ_OPTIMIZE"; then
+    OBJDIR_TAG=_OPT
+else
+    OBJDIR_TAG=_DBG
+fi
+
+if test -n "$USE_64"; then
+    COMPILER_TAG=_64
+fi
+
+RELEASE_OBJDIR_NAME="${OS_CONFIG}${CPU_ARCH_TAG}${COMPILER_TAG}${IMPL_STRATEGY}${OBJDIR_TAG}.${OBJDIR_SUFFIX}"
+
+case "$target_os" in
+cygwin*|msvc*|mks*)
+    CC="\$(CYGWIN_WRAPPER) $CC"
+    CXX="\$(CYGWIN_WRAPPER) $CXX"
+    RC="\$(CYGWIN_WRAPPER) $RC"
+    ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+MAKEFILES="
+Makefile 
+config/Makefile
+config/autoconf.mk
+config/nsprincl.mk
+config/nsprincl.sh
+config/nspr-config
+lib/Makefile 
+lib/ds/Makefile 
+lib/libc/Makefile 
+lib/libc/include/Makefile 
+lib/libc/src/Makefile 
+lib/tests/Makefile
+pkg/Makefile
+pkg/linux/Makefile
+pkg/solaris/Makefile
+pkg/solaris/SUNWpr/Makefile
+pkg/solaris/SUNWprd/Makefile
+pr/Makefile 
+pr/include/Makefile 
+pr/include/md/Makefile 
+pr/include/obsolete/Makefile 
+pr/include/private/Makefile 
+pr/src/Makefile 
+pr/src/io/Makefile 
+pr/src/linking/Makefile 
+pr/src/malloc/Makefile 
+pr/src/md/Makefile 
+pr/src/md/${PR_MD_ARCH_DIR}/Makefile 
+pr/src/memory/Makefile 
+pr/src/misc/Makefile 
+pr/src/threads/Makefile 
+pr/tests/Makefile 
+pr/tests/dll/Makefile 
+"
+
+
+if test -z "$USE_PTHREADS" && test -z "$USE_BTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/threads/combined/Makefile"
+elif test -n "$USE_PTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/pthreads/Makefile"
+elif test -n "$USE_BTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/bthreads/Makefile"
+fi
+
+if test -n "$USE_CPLUS"; then
+    MAKEFILES="$MAKEFILES pr/src/cplus/Makefile pr/src/cplus/tests/Makefile"
+fi
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ 	`~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' ' | tr '\015' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "$MAKEFILES" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@CC@%$CC%g
+s%@dist_prefix@%$dist_prefix%g
+s%@dist_bindir@%$dist_bindir%g
+s%@dist_includedir@%$dist_includedir%g
+s%@dist_libdir@%$dist_libdir%g
+s%@WHOAMI@%$WHOAMI%g
+s%@HOST_CC@%$HOST_CC%g
+s%@CXX@%$CXX%g
+s%@RANLIB@%$RANLIB%g
+s%@AR@%$AR%g
+s%@AS@%$AS%g
+s%@LD@%$LD%g
+s%@STRIP@%$STRIP%g
+s%@WINDRES@%$WINDRES%g
+s%@CPP@%$CPP%g
+s%@PERL@%$PERL%g
+s%@SHELL_OVERRIDE@%$SHELL_OVERRIDE%g
+s%@MOZILLA_CLIENT@%$MOZILLA_CLIENT%g
+s%@HOST_CFLAGS@%$HOST_CFLAGS%g
+s%@HOST_LDFLAGS@%$HOST_LDFLAGS%g
+s%@GNU_CC@%$GNU_CC%g
+s%@GCC_USE_GNU_LD@%$GCC_USE_GNU_LD%g
+s%@MSC_VER@%$MSC_VER%g
+s%@CROSS_COMPILE@%$CROSS_COMPILE%g
+s%@MOZ_OPTIMIZE@%$MOZ_OPTIMIZE%g
+s%@USE_CPLUS@%$USE_CPLUS%g
+s%@USE_IPV6@%$USE_IPV6%g
+s%@USE_N32@%$USE_N32%g
+s%@USE_64@%$USE_64%g
+s%@OBJECT_MODE@%$OBJECT_MODE%g
+s%@GC_LEAK_DETECTOR@%$GC_LEAK_DETECTOR%g
+s%@ENABLE_STRIP@%$ENABLE_STRIP%g
+s%@USE_PTHREADS@%$USE_PTHREADS%g
+s%@USE_BTHREADS@%$USE_BTHREADS%g
+s%@USE_USER_PTHREADS@%$USE_USER_PTHREADS%g
+s%@USE_NATIVE_THREADS@%$USE_NATIVE_THREADS%g
+s%@USE_NSPR_THREADS@%$USE_NSPR_THREADS%g
+s%@LIBNSPR@%$LIBNSPR%g
+s%@LIBPLC@%$LIBPLC%g
+s%@MOD_MAJOR_VERSION@%$MOD_MAJOR_VERSION%g
+s%@MOD_MINOR_VERSION@%$MOD_MINOR_VERSION%g
+s%@MOD_PATCH_VERSION@%$MOD_PATCH_VERSION%g
+s%@NSPR_MODNAME@%$NSPR_MODNAME%g
+s%@MDCPUCFG_H@%$MDCPUCFG_H%g
+s%@PR_MD_CSRCS@%$PR_MD_CSRCS%g
+s%@PR_MD_ASFILES@%$PR_MD_ASFILES%g
+s%@PR_MD_ARCH_DIR@%$PR_MD_ARCH_DIR%g
+s%@CPU_ARCH@%$CPU_ARCH%g
+s%@OBJ_SUFFIX@%$OBJ_SUFFIX%g
+s%@LIB_SUFFIX@%$LIB_SUFFIX%g
+s%@DLL_SUFFIX@%$DLL_SUFFIX%g
+s%@ASM_SUFFIX@%$ASM_SUFFIX%g
+s%@MKSHLIB@%$MKSHLIB%g
+s%@DSO_CFLAGS@%$DSO_CFLAGS%g
+s%@DSO_LDOPTS@%$DSO_LDOPTS%g
+s%@OS_TARGET@%$OS_TARGET%g
+s%@OS_ARCH@%$OS_ARCH%g
+s%@OS_RELEASE@%$OS_RELEASE%g
+s%@OS_TEST@%$OS_TEST%g
+s%@MACOSX_DEPLOYMENT_TARGET@%$MACOSX_DEPLOYMENT_TARGET%g
+s%@DEFINES@%$DEFINES%g
+s%@AR_FLAGS@%$AR_FLAGS%g
+s%@ASFLAGS@%$ASFLAGS%g
+s%@FILTER@%$FILTER%g
+s%@IMPLIB@%$IMPLIB%g
+s%@OS_LIBS@%$OS_LIBS%g
+s%@RESOLVE_LINK_SYMBOLS@%$RESOLVE_LINK_SYMBOLS%g
+s%@AIX_LINK_OPTS@%$AIX_LINK_OPTS%g
+s%@NOSUCHFILE@%$NOSUCHFILE%g
+s%@MOZ_OBJFORMAT@%$MOZ_OBJFORMAT%g
+s%@ULTRASPARC_LIBRARY@%$ULTRASPARC_LIBRARY%g
+s%@OBJDIR@%$OBJDIR%g
+s%@OBJDIR_NAME@%$OBJDIR_NAME%g
+s%@RELEASE_OBJDIR_NAME@%$RELEASE_OBJDIR_NAME%g
+s%@NSINSTALL@%$NSINSTALL%g
+s%@OPTIMIZER@%$OPTIMIZER%g
+s%@RC@%$RC%g
+s%@RCFLAGS@%$RCFLAGS%g
+s%@DLLFLAGS@%$DLLFLAGS%g
+s%@EXEFLAGS@%$EXEFLAGS%g
+s%@OS_DLLFLAGS@%$OS_DLLFLAGS%g
+s%@CYGWIN_WRAPPER@%$CYGWIN_WRAPPER%g
+s%@VISIBILITY_FLAGS@%$VISIBILITY_FLAGS%g
+s%@WRAP_SYSTEM_INCLUDES@%$WRAP_SYSTEM_INCLUDES%g
+s%@MACOS_SDK_DIR@%$MACOS_SDK_DIR%g
+s%@NEXT_ROOT@%$NEXT_ROOT%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"$MAKEFILES"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+chmod +x config/nspr-config
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+

Added: freeswitch/trunk/libs/js/nsprpub/configure.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/configure.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2834 @@
+dnl -*- Mode: Autoconf; tab-width: 4; indent-tabs-mode: nil; -*-
+dnl 
+dnl The contents of this file are subject to the Mozilla Public
+dnl License Version 1.1 (the "License"); you may not use this file
+dnl except in compliance with the License. You may obtain a copy of
+dnl the License at http://www.mozilla.org/MPL/
+dnl 
+dnl Software distributed under the License is distributed on an "AS
+dnl IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+dnl implied. See the License for the specific language governing
+dnl rights and limitations under the License.
+dnl 
+dnl The Original Code is the Netscape Portable Runtime (NSPR).
+dnl 
+dnl The Initial Developer of the Original Code is Netscape
+dnl Communications Corporation.  Portions created by Netscape are 
+dnl Copyright (C) 1998o-2000 Netscape Communications Corporation.  All
+dnl Rights Reserved.
+dnl 
+dnl Contributor(s):
+dnl     Christopher Seawood <cls at seawood.org>
+dnl     Howard Chu <hyc at symas.com>
+dnl     Mark Mentovai <mark at moxienet.com>
+dnl 
+dnl Alternatively, the contents of this file may be used under the
+dnl terms of the GNU General Public License Version 2 or later (the
+dnl "GPL"), in which case the provisions of the GPL are applicable 
+dnl instead of those above.  If you wish to allow use of your 
+dnl version of this file only under the terms of the GPL and not to
+dnl allow others to use your version of this file under the MPL,
+dnl indicate your decision by deleting the provisions above and
+dnl replace them with the notice and other provisions required by
+dnl the GPL.  If you do not delete the provisions above, a recipient
+dnl may use your version of this file under either the MPL or the
+dnl GPL.
+dnl 
+
+AC_PREREQ(2.12)
+AC_INIT(config/libc_r.h)
+
+AC_CONFIG_AUX_DIR(${srcdir}/build/autoconf)
+AC_CANONICAL_SYSTEM
+
+dnl ========================================================
+dnl = Defaults
+dnl ========================================================
+MOD_MAJOR_VERSION=4
+MOD_MINOR_VERSION=7
+MOD_PATCH_VERSION=0
+NSPR_MODNAME=nspr20
+_HAVE_PTHREADS=
+USE_PTHREADS=
+USE_USER_PTHREADS=
+USE_NSPR_THREADS=
+USE_N32=
+USE_64=
+USE_CPLUS=
+USE_IPV6=
+USE_MDUPDATE=
+_MACOSX_DEPLOYMENT_TARGET=
+_OPTIMIZE_FLAGS=-O
+_DEBUG_FLAGS=-g
+MOZ_DEBUG=1
+MOZ_OPTIMIZE=
+OBJDIR='$(OBJDIR_NAME)'
+OBJDIR_NAME=.
+OBJDIR_SUFFIX=OBJ
+NSINSTALL='$(MOD_DEPTH)/config/$(OBJDIR_NAME)/nsinstall'
+NOSUCHFILE=/no-such-file
+LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)'
+LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)'
+CYGWIN_WRAPPER=
+MACOS_SDK_DIR=
+NEXT_ROOT=
+
+dnl Link in libraries necessary to resolve all symbols for shared libs
+RESOLVE_LINK_SYMBOLS=
+
+dnl ========================================================
+dnl =
+dnl = Dont change the following lines.  Doing so breaks:
+dnl =
+dnl = CFLAGS="-foo" ./configure
+dnl =
+dnl ========================================================
+CFLAGS="${CFLAGS=}"
+CXXFLAGS="${CXXFLAGS=}"
+LDFLAGS="${LDFLAGS=}"
+HOST_CFLAGS="${HOST_CFLAGS=}"
+HOST_LDFLAGS="${HOST_LDFLAGS=}"
+
+case "$target" in
+*-cygwin*|*-mingw*)
+    # Check to see if we are really running in a msvc environemnt
+    _WIN32_MSVC=
+    AC_CHECK_PROGS(CC, cl)
+    if test "$CC" = "cl"; then
+        echo 'main() { return 0; }' > dummy.c
+        ${CC} -o dummy dummy.c >/dev/null 2>&1
+        if test $? = 0; then
+            _WIN32_MSVC=1
+            CXX=$CC
+        else
+            AC_MSG_WARN([$(CC) test failed.  Using normal feature tests])
+        fi
+        rm -f dummy dummy.o dummy.obj dummy.exe dummy.c
+    fi
+    ;;
+*-msvc*)
+    _WIN32_MSVC=1
+    ;;
+*-mks*)
+    _WIN32_MSVC=1
+    ;;
+esac
+
+if test -n "$_WIN32_MSVC"; then
+    SKIP_PATH_CHECKS=1
+    SKIP_COMPILER_CHECKS=1
+    SKIP_LIBRARY_CHECKS=1
+fi
+
+dnl ========================================================
+dnl =
+dnl = Check options that may affect the compiler
+dnl =
+dnl ========================================================
+dist_prefix='${MOD_DEPTH}/dist'
+dist_bindir='${dist_prefix}/bin'
+dist_includedir='${dist_prefix}/include/nspr'
+dist_libdir='${dist_prefix}/lib'
+if test "${includedir}" = '${prefix}/include'; then
+    includedir='${prefix}/include/nspr'
+fi
+
+AC_ARG_WITH(dist-prefix,
+    [  --with-dist-prefix=DIST_PREFIX
+                          place build files in DIST_PREFIX [dist]],
+    dist_prefix=$withval)
+
+AC_ARG_WITH(dist-bindir,
+    [  --with-dist-bindir=DIR  build execuatables in DIR [DIST_PREFIX/bin]],
+    dist_bindir=$withval)
+
+AC_ARG_WITH(dist-includedir,
+    [  --with-dist-includedir=DIR
+                          build include files in DIR [DIST_PREFIX/include/nspr]],
+    dist_includedir=$withval)
+
+AC_ARG_WITH(dist-libdir,
+    [  --with-dist-libdir=DIR  build library files in DIR [DIST_PREFIX/lib]],
+    dist_libdir=$withval)
+
+AC_SUBST(dist_prefix)
+AC_SUBST(dist_bindir)
+AC_SUBST(dist_includedir)
+AC_SUBST(dist_libdir)
+
+dnl Check if NSPR is being compiled for Mozilla
+dnl Let --with-arg override environment setting
+dnl
+AC_ARG_WITH(mozilla,
+    [  --with-mozilla          Compile NSPR with Mozilla support],
+    [   if test "$withval" = "yes"; then
+            AC_DEFINE(MOZILLA_CLIENT)
+            MOZILLA_CLIENT=1
+	    else
+	        MOZILLA_CLIENT=
+	    fi],
+    [	if test -n "$MOZILLA_CLIENT"; then
+	        AC_DEFINE(MOZILLA_CLIENT)
+	    fi])
+
+AC_ARG_ENABLE(optimize,
+    [  --enable-optimize(=val) Enable code optimizations (val, ie. -O2) ],
+    [ if test "$enableval" != "no"; then
+        MOZ_OPTIMIZE=1
+        if test -n "$enableval" && test "$enableval" != "yes"; then
+    	    _OPTIMIZE_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
+            _SAVE_OPTIMIZE_FLAGS=$_OPTIMIZE_FLAGS
+        fi
+      else
+        MOZ_OPTIMIZE=
+    fi ])
+
+AC_ARG_ENABLE(debug,
+    [  --disable-debug         Do not compile in debugging symbols
+  --enable-debug(=val)    Enable debugging (debug flags val)],
+    [	if test "$enableval" = "no"; then
+    	    MOZ_DEBUG=
+        else
+            MOZ_DEBUG=1
+            if test -n "$enableval" && test "$enableval" != "yes"; then
+                _DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
+                _SAVE_DEBUG_FLAGS=$_DEBUG_FLAGS
+            fi
+        fi])
+
+AC_ARG_ENABLE(win32-target,
+    [  --enable-win32-target=\$t
+                          Specify win32 flavor. (WIN95 or WINNT)],
+    OS_TARGET=`echo $enableval | tr a-z A-Z`,
+    OS_TARGET=)
+
+AC_ARG_ENABLE(debug-rtl,
+    [  --enable-debug-rtl      Use the MSVC debug runtime library],
+    [ if test "$enableval" = "yes"; then
+	    USE_DEBUG_RTL=1
+      fi ])
+
+AC_ARG_ENABLE(n32,
+    [  --enable-n32            Enable n32 ABI support (IRIX only)],
+    [ if test "$enableval" = "yes"; then
+	USE_N32=1
+      else if test "$enableval" = "no"; then
+	USE_N32=
+      fi
+    fi ])
+
+AC_ARG_ENABLE(64bit,
+    [  --enable-64bit          Enable 64-bit support (on certain platforms)],
+    [ if test "$enableval" = "yes"; then
+	    USE_64=1
+      fi ])
+
+AC_ARG_ENABLE(mdupdate,
+    [  --enable-mdupdate       Enable use of certain compilers' mdupdate feature],
+    [ if test "$enableval" = "yes"; then
+	    USE_MDUPDATE=1
+      fi ])
+
+dnl ========================================================
+dnl = Mac OS X SDK support
+dnl ========================================================
+AC_ARG_WITH(macos-sdk,
+    [  --with-macos-sdk=dir    Location of platform SDK to use (Mac OS X only)],
+    MACOS_SDK_DIR=$withval)
+
+AC_ARG_ENABLE(macos-target,
+             [  --enable-macos-target=VER
+                          Set the minimum MacOS version needed at runtime
+                          [10.1 for ppc, 10.4 for x86]],
+             [_MACOSX_DEPLOYMENT_TARGET=$enableval])
+
+dnl ========================================================
+dnl =
+dnl = Set the threading model
+dnl =
+dnl ========================================================
+case "$target" in
+
+*-aix*)
+    case "${target_os}" in
+    aix3.2*)
+        USE_NSPR_THREADS=1
+        ;;
+    *)
+        USE_PTHREADS=1
+        ;;
+    esac
+    ;;
+
+esac
+
+dnl ========================================================
+dnl =
+dnl = Set the default C compiler
+dnl =
+dnl ========================================================
+if test -z "$CC"; then
+    case "$target" in
+
+    *-aix*)
+        if test -z "$USE_NSPR_THREADS"; then
+            CC=xlc_r
+        else
+            CC=xlc
+        fi
+    ;;
+
+    *-hpux*)
+        CC=cc
+    ;;
+
+    *-irix*)
+        CC=cc
+    ;;
+
+    *-openvms*)
+        CC=cc
+    ;;
+
+    *-osf*)
+        CC=cc
+    ;;
+
+    *-solaris*)
+        CC=cc
+    ;;
+
+    esac
+fi
+
+dnl ========================================================
+dnl =
+dnl = Set the default C++ compiler
+dnl =
+dnl ========================================================
+if test -z "$CXX"; then
+    case "$target" in
+
+    *-aix*)
+        if test -z "$USE_NSPR_THREADS"; then
+            CXX=xlC_r
+        else
+            CXX=xlC
+        fi
+    ;;
+
+    *-hpux*)
+        case "${target_os}" in
+        hpux10.30)
+            CXX=aCC
+            ;;
+        hpux11.*)
+            CXX=aCC
+            ;;
+        *)
+            CXX=CC
+            ;;
+        esac
+    ;;
+
+    *-irix*)
+        CXX=CC
+    ;;
+
+    *-openvms*)
+        CXX=cxx
+    ;;
+
+    *-osf*)
+        CXX=cxx
+    ;;
+
+    *-solaris*)
+        CXX=CC
+    ;;
+
+    esac
+fi
+
+if test -z "$SKIP_PATH_CHECKS"; then
+    AC_PATH_PROG(WHOAMI, $WHOAMI whoami, echo not_whoami)
+fi
+
+if test -n "$MOZ_DEBUG"; then
+    AC_DEFINE(DEBUG)
+    DEFINES="$DEFINES -UNDEBUG"
+
+    case "${target_os}" in
+    beos*)
+        DEFINES="$DEFINES -DDEBUG_${USER}"
+        ;;
+    msvc*|mks*|cygwin*|mingw*|os2*)
+        DEFINES="$DEFINES -DDEBUG_`echo ${USERNAME} | sed -e 's| |_|g'`"
+        ;;
+    *) 
+        DEFINES="$DEFINES -DDEBUG_`$WHOAMI`"
+        ;;
+    esac
+else
+    AC_DEFINE(NDEBUG)
+    DEFINES="$DEFINES -UDEBUG"
+fi
+
+if test -z "$SKIP_COMPILER_CHECKS"; then
+dnl ========================================================
+dnl Checks for compilers.
+dnl ========================================================
+if test "$target" != "$host"; then
+    echo "cross compiling from $host to $target"
+    cross_compiling=yes
+
+    _SAVE_CC="$CC"
+    _SAVE_CFLAGS="$CFLAGS"
+    _SAVE_LDFLAGS="$LDFLAGS"
+
+    AC_MSG_CHECKING([for $host compiler])
+    AC_CHECK_PROGS(HOST_CC, $HOST_CC gcc cc /usr/ucb/cc, "")
+    if test -z "$HOST_CC"; then
+        AC_MSG_ERROR([no acceptable cc found in \$PATH])
+    fi
+    AC_MSG_RESULT([$HOST_CC])
+    if test -z "$HOST_CFLAGS"; then
+        HOST_CFLAGS="$CFLAGS"
+    fi
+    if test -z "$HOST_LDFLAGS"; then
+        HOST_LDFLAGS="$LDFLAGS"
+    fi
+
+    CC="$HOST_CC"
+    CFLAGS="$HOST_CFLAGS"
+    LDFLAGS="$HOST_LDFLAGS"
+
+    AC_MSG_CHECKING([whether the $host compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works])
+    AC_TRY_COMPILE([], [return(0);], 
+        [ac_cv_prog_host_cc_works=1 AC_MSG_RESULT([yes])],
+        AC_MSG_ERROR([installation or configuration problem: $host compiler $HOST_CC cannot create executables.]) )
+
+    CC=$_SAVE_CC
+    CFLAGS=$_SAVE_CFLAGS
+    LDFLAGS=$_SAVE_LDFLAGS
+
+    case "$build:$target" in 
+      powerpc-apple-darwin8*:i?86-apple-darwin*)
+        dnl The Darwin cross compiler doesn't necessarily point itself at a
+        dnl root that has libraries for the proper architecture, it defaults
+        dnl to the system root.  The libraries in the system root on current
+        dnl versions of PPC OS X 10.4 aren't fat, so these target compiler
+        dnl checks will fail.  Fake a working SDK in that case.
+        _SAVE_CFLAGS=$CFLAGS 
+        _SAVE_CXXFLAGS=$CXXLAGS
+        CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CFLAGS"
+        CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CXXFLAGS"
+        ;;        
+    esac            
+
+    AC_CHECK_PROGS(CC, $CC "${target_alias}-gcc" "${target}-gcc", echo)
+    unset ac_cv_prog_CC
+    AC_PROG_CC
+    AC_CHECK_PROGS(CXX, $CXX "${target_alias}-g++" "${target}-g++", echo)
+    unset ac_cv_prog_CXX
+    AC_PROG_CXX
+
+    case "$build:$target" in
+      powerpc-apple-darwin8*:i?86-apple-darwin*)
+        dnl Revert the changes made above.  From this point on, the target
+        dnl compiler will never be used without applying the SDK to CFLAGS
+        dnl (see --with-macos-sdk below).
+        CFLAGS=$_SAVE_CFLAGS
+        CXXFLAGS=$_SAVE_CXXFLAGS
+        ;;
+    esac
+
+    AC_CHECK_PROGS(RANLIB, $RANLIB "${target_alias}-ranlib" "${target}-ranlib", echo)
+    AC_CHECK_PROGS(AR, $AR "${target_alias}-ar" "${target}-ar", echo)
+    AC_CHECK_PROGS(AS, $AS "${target_alias}-as" "${target}-as", echo)
+    AC_CHECK_PROGS(LD, $LD "${target_alias}-ld" "${target}-ld", echo)
+    AC_CHECK_PROGS(STRIP, $STRIP "${target_alias}-strip" "${target}-strip", echo)
+    AC_CHECK_PROGS(WINDRES, $WINDRES "${target_alias}-windres" "${target}-windres", echo)
+
+else
+    AC_PROG_CXX
+    if test "$CXX" = "cl" -a -z "$CC"; then
+        CC=$CXX
+    else        
+        AC_PROG_CC
+    fi
+    AC_PROG_CPP
+    AC_PROG_RANLIB
+    AC_PATH_PROGS(AS, as, $CC)
+    AC_PATH_PROGS(AR, ar, echo not_ar)
+    AC_PATH_PROGS(LD, ld link, echo not_ld)
+    AC_PATH_PROGS(STRIP, strip, echo not_strip)
+    AC_PATH_PROGS(WINDRES, windres, echo not_windres)
+    if test -z "$HOST_CC"; then
+        HOST_CC="$CC"
+    fi
+    if test -z "$HOST_CFLAGS"; then
+        HOST_CFLAGS="$CFLAGS"
+    fi
+fi
+
+if test "$GCC" = "yes"; then
+    GNU_CC=1
+fi
+if test "$GXX" = "yes"; then
+    GNU_CXX=1
+fi
+if test "`echo | $AS -v 2>&1 | grep -c GNU`" != "0"; then
+    GNU_AS=1
+fi
+rm -f a.out
+
+case "$build:$target" in
+    i?86-apple-darwin*:powerpc-apple-darwin*)
+        dnl cross_compiling will have erroneously been set to "no" in this
+        dnl case, because the x86 build host is able to run ppc code in a
+        dnl translated environment, making a cross compiler appear native.
+        cross_compiling=yes
+        ;;
+esac
+
+if test "$cross_compiling"  = "yes"; then
+    CROSS_COMPILE=1
+else
+    CROSS_COMPILE=
+fi
+
+dnl ========================================================
+dnl Check for gcc -pipe support
+dnl ========================================================
+AC_MSG_CHECKING([for gcc -pipe support])
+if test -n "$GNU_CC" && test -n "$GNU_CXX" && test -n "$GNU_AS"; then
+    echo '#include <stdio.h>' > dummy-hello.c
+    echo 'int main() { printf("Hello World\n"); return 0; }' >> dummy-hello.c
+    ${CC} -S dummy-hello.c -o dummy-hello.s 2>&5
+    cat dummy-hello.s | ${AS} -o dummy-hello.S - 2>&5
+    if test $? = 0; then
+        _res_as_stdin="yes"
+    else
+        _res_as_stdin="no"
+    fi
+    if test "$_res_as_stdin" = "yes"; then
+        _SAVE_CFLAGS=$CFLAGS
+        CFLAGS="$CFLAGS -pipe"
+        AC_TRY_COMPILE( [ #include <stdio.h> ],
+            [printf("Hello World\n");],
+            [_res_gcc_pipe="yes"],
+            [_res_gcc_pipe="no"] )
+        CFLAGS=$_SAVE_CFLAGS
+    fi
+    if test "$_res_as_stdin" = "yes" && test "$_res_gcc_pipe" = "yes"; then
+        _res="yes";
+        CFLAGS="$CFLAGS -pipe"
+        CXXFLAGS="$CXXFLAGS -pipe"
+    else
+        _res="no"
+    fi
+    rm -f dummy-hello.c dummy-hello.s dummy-hello.S dummy-hello a.out
+    AC_MSG_RESULT([$_res])
+else
+    AC_MSG_RESULT([no])
+fi
+
+dnl ===============================================================
+dnl Check for .hidden assembler directive and visibility attribute.
+dnl Borrowed from glibc configure.in
+dnl ===============================================================
+if test "$GNU_CC"; then
+    AC_CACHE_CHECK(for visibility(hidden) attribute,
+        ac_cv_visibility_hidden,
+        [cat > conftest.c <<EOF
+        int foo __attribute__ ((visibility ("hidden"))) = 1;
+EOF
+        ac_cv_visibility_hidden=no
+        if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+            if grep '\.hidden.*foo' conftest.s >/dev/null; then
+                ac_cv_visibility_hidden=yes
+            fi
+        fi
+        rm -f conftest.[cs]
+        ])
+    if test "$ac_cv_visibility_hidden" = "yes"; then
+        AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
+        AC_CACHE_CHECK(for visibility pragma support,
+            ac_cv_visibility_pragma,
+            [cat > conftest.c <<EOF
+#pragma GCC visibility push(hidden)
+            int foo_hidden = 1;
+#pragma GCC visibility push(default)
+            int foo_default = 1;
+EOF
+            ac_cv_visibility_pragma=no
+            if ${CC-cc} -Werror -S conftest.c -o conftest.s >/dev/null 2>&1; then
+                if grep '\.hidden.*foo_hidden' conftest.s >/dev/null; then
+                    if ! grep '\.hidden.*foo_default' conftest.s > /dev/null; then
+                        ac_cv_visibility_pragma=yes
+                    fi
+                fi
+            fi
+            rm -f conftest.[cs]
+            ])
+        if test "$ac_cv_visibility_pragma" = "yes"; then
+            AC_DEFINE(HAVE_VISIBILITY_PRAGMA)
+            # To work around a build problem on Linux x86-64 (Bugzilla bug
+            # 293438), we use the -fvisibility=hidden flag.  This flag is less
+            # optimal than #pragma GCC visibility push(hidden) because the flag
+            # assumes that symbols defined outside the current source file have
+            # the default visibility.  This has the advantage that we don't need
+            # to wrap system header files, but has the disadvantage that calls
+            # to hidden symbols defined in other source files cannot be
+            # optimized by the compiler.  The -fvisibility=hidden flag does
+            # hide and export symbols correctly.
+            #VISIBILITY_FLAGS='-I$(dist_includedir)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h'
+            #WRAP_SYSTEM_INCLUDES=1
+            VISIBILITY_FLAGS="-fvisibility=hidden"
+            WRAP_SYSTEM_INCLUDES=
+        fi
+    fi
+fi # GNU_CC
+
+fi # SKIP_COMPILER_CHECKS
+
+dnl ========================================================
+dnl Checks for programs.
+dnl ========================================================
+if test -z "$SKIP_PATH_CHECKS"; then
+    AC_PATH_PROGS(PERL, perl5 perl, echo not_perl)
+elif test -z "$PERL"; then
+    PERL=perl
+fi
+
+dnl ========================================================
+dnl Default platform specific options
+dnl ========================================================
+OBJ_SUFFIX=o
+LIB_SUFFIX=a
+DLL_SUFFIX=so
+ASM_SUFFIX=s
+MKSHLIB='$(LD) $(DSO_LDOPTS) -o $@'
+PR_MD_ASFILES=
+PR_MD_CSRCS=
+PR_MD_ARCH_DIR=unix
+AR_FLAGS='cr $@'
+AS='$(CC)'
+ASFLAGS='$(CFLAGS)'
+
+if test -n "$CROSS_COMPILE"; then
+    OS_ARCH=`echo $target_os | sed -e 's|/|_|g'`
+    OS_RELEASE=
+    OS_TEST="${target_cpu}"
+    case "${target_os}" in
+        linux*)       OS_ARCH=Linux ;;
+        solaris*)     OS_ARCH=SunOS OS_RELEASE=5 ;;
+        mingw*)       OS_ARCH=WINNT ;;
+        darwin*)      OS_ARCH=Darwin ;;
+    esac
+else
+    OS_ARCH=`uname -s | sed -e 's|/|_|g'`
+    OS_RELEASE=`uname -r`
+    OS_TEST=`uname -m`
+fi
+
+if test "$OS_ARCH" = "IRIX64"; then
+    OS_ARCH=IRIX
+fi
+
+if test "$OS_ARCH" = "AIX"; then
+    OS_RELEASE=`uname -v`.`uname -r`
+fi
+
+if test "$OS_ARCH" = "FreeBSD"; then
+    OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'`
+fi
+
+if test "$OS_ARCH" = "Linux"; then
+    OS_RELEASE=`echo $OS_RELEASE | sed 's/-.*//'`
+    OS_RELEASE=`echo $OS_RELEASE | awk -F\. '{ print $1 "." $2 }'`
+fi
+
+if test "$OS_ARCH" = "OpenVMS"; then
+    OS_RELEASE=`uname -v`
+fi
+
+#######################################################################
+# Master "Core Components" macros for getting the OS target           #
+#######################################################################
+
+#
+# Note: OS_TARGET should be specified on the command line for gmake.
+# When OS_TARGET=WIN95 is specified, then a Windows 95 target is built.
+# The difference between the Win95 target and the WinNT target is that
+# the WinNT target uses Windows NT specific features not available
+# in Windows 95. The Win95 target will run on Windows NT, but (supposedly)
+# at lesser performance (the Win95 target uses threads; the WinNT target
+# uses fibers).
+#
+# When OS_TARGET=WIN16 is specified, then a Windows 3.11 (16bit) target
+# is built. See: win16_3.11.mk for lots more about the Win16 target.
+#
+# If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no
+# cross-compilation.
+#
+
+#
+# The following hack allows one to build on a WIN95 machine (as if
+# s/he were cross-compiling on a WINNT host for a WIN95 target).
+# It also accomodates for MKS's uname.exe.  If you never intend
+# to do development on a WIN95 machine, you don't need this hack.
+#
+case "$OS_ARCH" in
+WIN95)
+    OS_ARCH=WINNT
+    OS_TARGET=WIN95
+    ;;
+Windows_95)
+    OS_ARCH=Windows_NT
+    OS_TARGET=WIN95
+    ;;
+Windows_98)
+    OS_ARCH=Windows_NT
+    OS_TARGET=WIN95
+    ;;
+CYGWIN_9*|CYGWIN_ME*)
+    OS_ARCH='CYGWIN_NT-4.0'
+    OS_TARGET=WIN95
+    ;;
+OS_2)
+    OS_ARCH=OS2
+    OS_TARGET=OS2
+    ;;
+esac
+
+#
+# On WIN32, we also define the variable CPU_ARCH.
+#
+
+case "$OS_ARCH" in
+WINNT)
+    CPU_ARCH=`uname -p`
+    if test "$CPU_ARCH" = "I386"; then
+        CPU_ARCH=x86
+    fi
+    ;;
+Windows_NT)
+#
+# If uname -s returns "Windows_NT", we assume that we are using
+# the uname.exe in MKS toolkit.
+#
+# The -r option of MKS uname only returns the major version number.
+# So we need to use its -v option to get the minor version number.
+# Moreover, it doesn't have the -p option, so we need to use uname -m.
+#
+    OS_ARCH=WINNT
+    OS_MINOR_RELEASE=`uname -v`
+    if test "$OS_MINOR_RELEASE" = "00"; then
+        OS_MINOR_RELEASE=0
+    fi
+    OS_RELEASE="${OS_RELEASE}.${OS_MINOR_RELEASE}"
+    CPU_ARCH=`uname -m`
+    #
+    # MKS's uname -m returns "586" on a Pentium machine.
+    #
+    if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    fi
+    ;;
+CYGWIN_NT*|MINGW*_NT*)
+#
+# If uname -s returns "CYGWIN_NT-4.0", we assume that we are using
+# the uname.exe in the Cygwin tools.
+# If uname -s returns MINGW32_NT-5.1, we assume that we are using
+# the uname.exe in the MSYS tools.
+#
+    OS_RELEASE=`expr $OS_ARCH : '.*NT-\(.*\)'`
+    OS_ARCH=WINNT
+    CPU_ARCH=`uname -m`
+    #
+    # Cygwin's uname -m returns "i686" on a Pentium Pro machine.
+    #
+    if echo "$CPU_ARCH" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    fi
+    ;;
+esac
+
+if test -n "$MOZILLA_CLIENT" && test "$OS_ARCH" = "WINNT"; then
+    OS_TARGET=WIN95
+    if test -n "$MOZ_DEBUG"; then
+        USE_DEBUG_RTL=1
+    fi
+fi
+if test -z "$OS_TARGET"; then
+    OS_TARGET=$OS_ARCH
+fi
+if test "$OS_TARGET" = "WIN95"; then
+    OS_RELEASE="4.0"
+fi
+if test "$OS_TARGET" = "WIN16"; then
+    OS_RELEASE=
+fi
+OS_CONFIG="${OS_TARGET}${OS_RELEASE}"
+
+dnl ========================================================
+
+dnl ========================================================
+dnl Override of system specific host options
+dnl ========================================================
+case "$host" in
+*-mingw*)
+    NSINSTALL=nsinstall
+    ;;
+*-cygwin*|*-msvc*|*-mks*)
+    NSINSTALL='$(CYGWIN_WRAPPER) nsinstall'
+    if test `echo "${PATH}" | grep -c \;` = 0; then
+        CYGWIN_WRAPPER='sh $(topsrcdir)/build/cygwin-wrapper'
+    fi
+    ;;
+*-beos*)
+    HOST_CFLAGS="$HOST_CFLAGS -DXP_BEOS -DBeOS -DBEOS -D_POSIX_SOURCE"
+    ;;
+*os2*)
+    ;;
+*)
+    HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX"
+    ;;
+esac
+
+dnl ========================================================
+dnl Override of system specific target options
+dnl ========================================================
+case "$target" in
+
+*-aix*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(AIX)
+    AC_DEFINE(SYSV)
+    DSO_LDOPTS='-brtl -bnortllib -bM:SRE -bnoentry -bexpall -blibpath:/usr/lib:/lib'
+    AC_CHECK_HEADER(sys/atomic_op.h, AC_DEFINE(AIX_HAVE_ATOMIC_OP_H))
+    case "${target_os}" in
+    aix3.2*)
+        AC_DEFINE(AIX_RENAME_SELECT)
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+        AIX_LINK_OPTS='-bnso -berok'
+        PR_MD_ASFILES=os_AIX.s
+        ;;
+    aix4.1*)
+        AC_DEFINE(AIX_TIMERS)
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+        AC_DEFINE(AIX4_1)
+        MKSHLIB=
+        DSO_LDOPTS=
+        AIX_LINK_OPTS='-bnso -berok'
+        LIBNSPR='-L$(dist_libdir) -lnspr$(MOD_MAJOR_VERSION)_shr'
+        LIBPLC='-L$(dist_libdir) -lplc$(MOD_MAJOR_VERSION)_shr'
+        ;;
+    aix4.2*)
+        AC_DEFINE(AIX_TIMERS)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    aix4.3*)
+        AC_DEFINE(AIX_TIMERS)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        AC_DEFINE(AIX4_3_PLUS)
+        AC_DEFINE(HAVE_SOCKLEN_T)
+        AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+        USE_IPV6=1
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    *)
+        AC_DEFINE(AIX_TIMERS)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        AC_DEFINE(AIX4_3_PLUS)
+        AC_DEFINE(HAVE_SOCKLEN_T)
+        AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+        USE_IPV6=1
+        AIX_LINK_OPTS='-brtl -bnso -berok'
+        ;;
+    esac
+    CFLAGS="$CFLAGS -qro -qroconst"
+    AIX_WRAP='$(DIST)/lib/aixwrap.o'
+    AIX_TMP='./_aix_tmp.o'
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_aix64.cfg
+        OBJECT_MODE=64
+    else
+        MDCPUCFG_H=_aix32.cfg
+    fi
+    PR_MD_CSRCS=aix.c
+    RESOLVE_LINK_SYMBOLS=1
+    ;;
+        
+*-beos*)
+    AC_DEFINE(XP_BEOS)
+    AC_DEFINE(BeOS)
+    AC_DEFINE(BEOS)
+    AC_DEFINE(_POSIX_SOURCE)
+    DSO_LDOPTS=-nostart
+    MDCPUCFG_H=_beos.cfg
+    USE_BTHREADS=1
+    PR_MD_ARCH_DIR=beos
+    RESOLVE_LINK_SYMBOLS=1
+    case "${target_cpu}" in
+    i*86)
+        _OPTIMIZE_FLAGS=-O2
+        _DEBUG_FLAGS='-gdwarf-2 -O0'
+        MKSHLIB='$(CCC) $(DSO_LDOPTS) -o $@'
+        AC_CHECK_LIB(bind, gethostbyaddr, [OS_LIBS="$OS_LIBS -lbind -lsocket"])
+        ;;
+    powerpc)
+        CC=mwcc
+        CCC=mwcc
+        LD=mwld
+        DSO_LDOPTS='-xms -export pragma -init _init_routine_ -term _term_routine_ -lroot -lnet /boot/develop/lib/ppc/glue-noinit.a /boot/develop/lib/ppc/init_term_dyn.o /boot/develop/lib/ppc/start_dyn.o'
+        _OPTIMIZE_FLAGS=-O2    
+        _DEBUG_FLAGS='-g -O0'
+        ;;
+    esac
+    ;;
+
+*-bsdi*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(BSDI)
+    AC_DEFINE(NEED_BSDREGEX)
+
+    CFLAGS="$CFLAGS -Wall -Wno-format"
+    CXXFLAGS="$CXXFLAGS -Wall -Wno-format"
+
+    if echo "$OS_TEST" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    elif echo "$OS_TEST" | grep -c sparc >/dev/null; then 
+        CPU_ARCH=sparc
+    fi
+
+    MDCPUCFG_H=_bsdi.cfg
+    PR_MD_CSRCS=bsdi.c
+
+    DSO_LDOPTS=-r
+
+    case "$target_os" in
+    bsdi1.1*)
+        AC_DEFINE(_PR_BSDI_JMPBUF_IS_ARRAY)
+        AC_DEFINE(_PR_STAT_HAS_ONLY_ST_ATIME)
+        AC_DEFINE(_PR_NEED_H_ERRNO)
+        MKSHLIB=
+        DSO_CFLAGS=
+        DSO_LDOPTS=
+        ;;
+
+    bsdi2.1*)
+        AC_DEFINE(_PR_TIMESPEC_HAS_TS_SEC)
+        AC_DEFINE(_PR_BSDI_JMPBUF_IS_ARRAY)
+        AC_DEFINE(HAVE_DLL)
+        AC_DEFINE(USE_DLFCN)
+        AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC)
+        PR_MD_ASFILES=os_BSD_OS_386_2.s
+        ;;
+
+    bsdi4.* | bsdi5.*)
+        AC_DEFINE(_PR_SELECT_CONST_TIMEVAL)
+        AC_DEFINE(_PR_BSDI_JMPBUF_IS_STRUCT)
+        AC_DEFINE(HAVE_DLL)
+        AC_DEFINE(USE_DLFCN)
+        AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC)
+        MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)'
+        DSO_CFLAGS=-fPIC
+        DSO_LDOPTS='-shared -Wl,-soname,$(@:$(OBJDIR)/%.so=%.so)'
+        STRIP="$STRIP -d"
+        case "$target_os" in
+        bsdi4.2* | bsdi4.3* | bsdi5.*)
+            AC_DEFINE(_PR_HAVE_GETPROTO_R)
+            AC_DEFINE(_PR_HAVE_GETPROTO_R_POINTER)
+            ;;
+        esac
+        ;;
+    *)
+        AC_DEFINE(_PR_SELECT_CONST_TIMEVAL)
+        AC_DEFINE(_PR_BSDI_JMPBUF_IS_STRUCT)
+        AC_DEFINE(HAVE_DLL)
+        AC_DEFINE(USE_DLFCN)
+        AC_DEFINE(_PR_STAT_HAS_ST_ATIMESPEC)
+        ;;
+    esac
+
+    ;;
+
+*-darwin*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(DARWIN)
+    AC_DEFINE(HAVE_BSD_FLOCK)
+    CFLAGS="$CFLAGS -Wmost -fno-common"
+    case "${target_cpu}" in
+        i*86*)
+            AC_DEFINE(i386)
+            CPU_ARCH=i386
+            PR_MD_ASFILES=os_Darwin_x86.s
+            ;;
+        *)
+            AC_DEFINE(ppc)
+            CPU_ARCH=ppc
+            PR_MD_ASFILES=os_Darwin_ppc.s
+            ;;
+    esac
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @executable_path/$@ -headerpad_max_install_names'
+    # Use the standard preprocessor (cpp)
+    CFLAGS="$CFLAGS -no-cpp-precomp"
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    STRIP="$STRIP -x -S"
+    DLL_SUFFIX=dylib
+    USE_PTHREADS=1
+    MDCPUCFG_H=_darwin.cfg
+    PR_MD_CSRCS=darwin.c
+
+    # Add Mac OS X support for loading CFM & CFBundle plugins
+    if test -f /System/Library/Frameworks/Carbon.framework/Carbon; then
+        AC_DEFINE(XP_MACOSX)
+        OS_TARGET=MacOSX
+
+        if test -n "$_MACOSX_DEPLOYMENT_TARGET" ; then
+            dnl Use the specified value
+            export MACOSX_DEPLOYMENT_TARGET=$_MACOSX_DEPLOYMENT_TARGET
+        elif test -z "$MACOSX_DEPLOYMENT_TARGET" ; then
+            dnl No value specified on the command line or in the environment,
+            dnl use the lesser of the library's minimum or the architecture's
+            dnl minimum.
+            case "${target_cpu}" in
+                powerpc*)
+                    dnl Architecture minimum 10.1
+                    export MACOSX_DEPLOYMENT_TARGET=10.1
+                    ;;
+                i*86*)
+                    dnl Architecture minimum 10.4
+                    export MACOSX_DEPLOYMENT_TARGET=10.4
+                    ;;
+            esac
+        fi
+
+        dnl MACOS_SDK_DIR will be set to the SDK location whenever one is
+        dnl in use.  NEXT_ROOT will be set and exported if it's needed for
+        dnl ld.
+
+        if test "$MACOS_SDK_DIR"; then
+            dnl Sync this section with the one in Mozilla's top level.
+
+            if test ! -d "$MACOS_SDK_DIR"; then
+                AC_MSG_ERROR([SDK not found.  When using --with-macos-sdk, you must
+specify a valid SDK.  SDKs are installed when the optional cross-development
+tools are selected during the Xcode/Developer Tools installation.])
+            fi
+
+            changequote(,)
+            CC_VERSION=`$CC -v 2>&1 | grep 'gcc version'`
+            GCC_VERSION_FULL=`echo $CC_VERSION | $PERL -pe 's/^.*gcc version ([^ ]*).*/$1/'`
+            GCC_VERSION=`echo $GCC_VERSION_FULL | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/$1/;'`
+            changequote([,])
+            GCC_VERSION_MAJOR=`echo $GCC_VERSION_FULL | $PERL -pe 's/(^\d*).*/$1/;'`
+            if test "$GCC_VERSION_MAJOR" -lt "4" ; then
+                SDK_C_FRAMEWORK="-F${MACOS_SDK_DIR}/System/Library/Frameworks"
+                if test -d "${MACOS_SDK_DIR}/Library/Frameworks" ; then
+                    SDK_C_FRAMEWORK="$SDK_C_FRAMEWORK -F${MACOS_SDK_DIR}/Library/Frameworks"
+                fi
+
+                SDK_C_INCLUDE="-isystem ${MACOS_SDK_DIR}/usr/include/gcc/darwin/${GCC_VERSION} -isystem ${MACOS_SDK_DIR}/usr/include ${SDK_C_FRAMEWORK}"
+
+                CFLAGS="$CFLAGS -nostdinc ${SDK_C_INCLUDE}"
+
+                dnl CPP needs to be set for AC_CHECK_HEADER.
+                CPP="$CPP -nostdinc ${SDK_C_INCLUDE}"
+
+                dnl ld support for -syslibroot is compiler-agnostic, but only
+                dnl available on Tiger.  Although it's possible to switch on
+                dnl the build host's OS release to use ld -syslibroot when
+                dnl available, ld -syslibroot cause warnings as long as
+                dnl NEXT_ROOT is set.  NEXT_ROOT should be set because both
+                dnl both the compiler and linker use it.
+                dnl
+                dnl LDFLAGS is for the utilities built in config (now and
+                dnl nsinstall).  DSO_LDOPTS is used when linking shared
+                dnl libraries.
+                MACOS_SDK_LIBS="-L${MACOS_SDK_DIR}/usr/lib/gcc/darwin -L${MACOS_SDK_DIR}/usr/lib/gcc/darwin/${GCC_VERSION_FULL} -L${MACOS_SDK_DIR}/usr/lib ${SDK_C_FRAMEWORK}"
+                LDFLAGS="${MACOS_SDK_LIBS} $LDFLAGS"
+                DSO_LDOPTS="${MACOS_SDK_LIBS} $DSO_LDOPTS"
+                export NEXT_ROOT=$MACOS_SDK_DIR
+
+                if test -n "$CROSS_COMPILE" ; then
+                    dnl NEXT_ROOT will be in the environment, but it
+                    dnl shouldn't be set for the build host.  HOST_CXX is
+                    dnl presently unused.
+                    HOST_CC="NEXT_ROOT= $HOST_CC"
+                    HOST_CXX="NEXT_ROOT= $HOST_CXX"
+                fi
+            else
+                dnl gcc >= 4.0 uses different paths than above, but knows
+                dnl how to find them itself.
+                CFLAGS="$CFLAGS -isysroot ${MACOS_SDK_DIR}"
+
+                dnl CPP needs to be set for AC_CHECK_HEADER.
+                CPP="$CPP -isysroot ${MACOS_SDK_DIR}"
+
+                dnl If gcc >= 4.0.0, we're guaranteed to be on Tiger, which
+                dnl has an ld that supports -syslibroot.  Don't set
+                dnl NEXT_ROOT because it will be ignored and cause
+                dnl warnings when -syslibroot is specified.
+                dnl
+                dnl Both LDFLAGS and DSO_LDOPTS are set here, see the
+                dnl gcc < 4.0 case for the explanation.
+                if test "$GCC_VERSION_FULL" != "4.0.0" ; then
+                    dnl gcc > 4.0.0 will pass -syslibroot to ld automatically
+                    dnl based on the -isysroot it receives.
+                    LDFLAGS="$LDFLAGS -isysroot ${MACOS_SDK_DIR}"
+                    DSO_LDOPTS="$DSO_LDOPTS -isysroot ${MACOS_SDK_DIR}"
+                else
+                    dnl gcc 4.0.0 doesn't pass -syslibroot to ld, it needs
+                    dnl to be explicit.
+                    LDFLAGS="$LDFLAGS -Wl,-syslibroot,${MACOS_SDK_DIR}"
+                    DSO_LDOPTS="$DSO_LDOPTS -Wl,-syslibroot,${MACOS_SDK_DIR}"
+                fi
+            fi
+        fi
+    fi
+    ;;
+
+*-dgux*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(SYSV)
+    AC_DEFINE(DGUX)
+    AC_DEFINE(_DGUX_SOURCE)
+    AC_DEFINE(_POSIX4A_DRAFT6_SOURCE)
+    DSO_LDOPTS=-G
+    _OPTIMIZE_FLAGS=-O2
+    _DEBUG_FLAGS=
+    MDCPUCFG_H=_dgux.cfg
+    PR_MD_CSRCS=dgux.c
+    ;;
+
+*-freebsd*)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(FREEBSD)
+    AC_DEFINE(HAVE_BSD_FLOCK)
+    AC_DEFINE(HAVE_SOCKLEN_T)
+    CFLAGS="$CFLAGS $(DSO_CFLAGS) -ansi -Wall"
+    MOZ_OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+    if test "$MOZ_OBJFORMAT" = "elf"; then
+        DLL_SUFFIX=so
+    else
+        DLL_SUFFIX=so.1.0
+    fi
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    MDCPUCFG_H=_freebsd.cfg
+    PR_MD_CSRCS=freebsd.c
+    ;;
+
+*-hpux*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(HPUX)
+    AC_DEFINE(_HPUX_SOURCE)
+    # OSF1 and HPUX report the POLLHUP event for a socket when the
+    # shutdown(SHUT_WR) operation is called for the remote end, even though
+    # the socket is still writeable. Use select(), instead of poll(), to
+    # workaround this problem.
+    AC_DEFINE(_PR_POLL_WITH_SELECT)
+    AC_DEFINE(_USE_BIG_FDS)
+    DSO_LDOPTS='-b +h $(notdir $@)'
+    PR_MD_CSRCS=hpux.c
+    if test "$OS_TEST" = "ia64"; then
+        DLL_SUFFIX=so
+        DSO_LDOPTS="$DSO_LDOPTS +b '\$\$ORIGIN'"
+        CPU_ARCH_TAG=_$OS_TEST 
+        if test -z "$USE_64"; then
+            COMPILER_TAG=_32
+        fi
+        PR_MD_ASFILES=os_HPUX_ia64.s
+    else
+        AC_DEFINE(hppa)
+        DLL_SUFFIX=sl
+        PR_MD_ASFILES=os_HPUX.s
+    fi
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_hpux64.cfg
+    else
+        MDCPUCFG_H=_hpux32.cfg
+    fi
+    if test -z "$GNU_CC"; then
+        CC="$CC -Ae"
+        CXX="$CXX -ext"
+        DSO_CFLAGS=+Z
+    else
+        DSO_CFLAGS=-fPIC
+    fi
+
+    if test -n "$MOZILLA_CLIENT"; then
+        DEFAULT_IMPL_STRATEGY=_EMU
+    fi
+
+    if echo "$OS_RELEASE" | grep ^A.09 >/dev/null; then
+        AC_DEFINE(_PR_NEED_H_ERRNO)
+        AC_DEFINE(HPUX9)
+        DEFAULT_IMPL_STRATEGY=_EMU
+    	USE_NSPR_THREADS=1
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(A.09|B.10)' >/dev/null; then
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+        AC_DEFINE(_PR_NEED_H_ERRNO)
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+        AC_DEFINE(HAVE_INT_LOCALTIME_R)
+    fi
+
+    if echo "$OS_RELEASE" | egrep '^(B.10.30|B.11)' >/dev/null; then
+        AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+    fi
+
+    # HP-UX 11i (B.11.11) or higher
+    changequote(<<,>>)
+    case "$OS_RELEASE" in
+    [C-Z]*|B.[2-9]*|B.1[2-9]*|B.11.[2-9]*|B.11.1[1-9]*)
+        USE_IPV6=1
+        ;;
+    esac
+    changequote([,])
+
+    if test "$OS_RELEASE" = "B.10.01"; then
+        AC_DEFINE(HPUX10)
+        DEFAULT_IMPL_STRATEGY=_EMU
+    fi
+
+    if test "$OS_RELEASE" = "B.10.10"; then
+        AC_DEFINE(HPUX10)
+        AC_DEFINE(HPUX10_10)
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$OS_RELEASE" = "B.10.20"; then
+        AC_DEFINE(HPUX10)
+        AC_DEFINE(HPUX10_20)
+        if test -z "$GNU_CC"; then
+            CFLAGS="$CFLAGS +DAportable +DS1.1"
+            CXXFLAGS="$CXXFLAGS +DAportable +DS1.1"
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$OS_RELEASE" = "B.10.30"; then
+        AC_DEFINE(HPUX10)
+        AC_DEFINE(HPUX10_30)
+        if test -z "$GNU_CC"; then
+            CFLAGS="$CFLAGS +DAportable +DS1.1"
+            CXXFLAGS="$CXXFLAGS +DAportable +DS1.1"
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if echo "$OS_RELEASE" | grep ^B.11 >/dev/null; then
+        AC_DEFINE(HPUX10)
+        AC_DEFINE(HPUX11)
+        AC_DEFINE(_LARGEFILE64_SOURCE)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+        if test -z "$GNU_CC"; then
+            if test -z "$USE_64"; then
+                if test "$OS_TEST" = "ia64"; then
+                    CFLAGS="$CFLAGS +DD32"
+                    CXXFLAGS="$CXXFLAGS +DD32"
+                else
+                    CFLAGS="$CFLAGS +DAportable +DS2.0"
+                    CXXFLAGS="$CXXFLAGS +DAportable +DS2.0"
+                fi
+            else
+                if test "$OS_TEST" = "ia64"; then
+                    CFLAGS="$CFLAGS +DD64"
+                    CXXFLAGS="$CXXFLAGS +DD64"
+                else
+                    CFLAGS="$CFLAGS +DA2.0W +DS2.0"
+                    CXXFLAGS="$CXXFLAGS +DA2.0W +DS2.0"
+                fi
+            fi
+        fi
+        DEFAULT_IMPL_STRATEGY=_PTH
+    fi
+
+    if test "$DEFAULT_IMPL_STRATEGY" = "_EMU"; then
+        USE_NSPR_THREADS=1
+        USE_PTHREADS=
+        USE_USER_THREADS=
+    elif test "$DEFAULT_IMPL_STRATEGY" = "_PTH"; then
+        USE_PTHREADS=1
+        if test "$USE_NSPR_THREADS"; then
+            USE_PTHREADS=
+        fi
+        if test "$USE_USER_PTHREADS"; then
+            USE_PTHREADS=
+        fi
+    fi
+    ;;
+
+*-irix*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(IRIX)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(_SGI_MP_SOURCE)
+    AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+    PR_MD_CSRCS=irix.c
+    PR_MD_ASFILES=os_Irix.s
+    MKSHLIB='$(LD) $(DSO_LDOPTS) -rdata_shared -shared -soname $(notdir $@) -o $@'
+    STRIP="$STRIP -f"
+    RESOLVE_LINK_SYMBOLS=1
+    if test -n "$USE_64"; then
+        MDCPUCFG_H=_irix64.cfg
+    else
+        MDCPUCFG_H=_irix32.cfg
+    fi
+    case "${target_os}" in
+    irix6*)
+        AC_DEFINE(IRIX6)
+        USE_PTHREADS=1
+        USE_N32=1
+        COMPILER_TAG=_n32
+        IMPL_STRATEGY=_PTH
+        ;;
+    irix5*)
+        AC_DEFINE(IRIX5)
+        USE_NSPR_THREADS=1
+        ;;
+    *)
+        USE_PTHREADS=1
+        USE_N32=1
+        ;;
+    esac
+    if test "$GNU_CC"; then
+        dnl
+        dnl If we are using gcc with native binutils, we need to
+        dnl suppress the
+        dnl #lineno "filename" num num
+        dnl lines, which confuse IRIX native as.  Add -Wp,-P to the
+        dnl gcc command line, which passes -P to the preprocessor.
+        dnl
+	    AS='$(CC) -Wp,-P -x assembler-with-cpp -D_ASM -mips2 $(INCLUDES)'
+	    CFLAGS="$CFLAGS -Wall -Wno-format"
+	    _OPTIMIZE_FLAGS="-O6"
+    else
+	    if test -n "$USE_N32"; then
+		AS='as -D_ASM $(INCLUDES) -n32'
+	    else
+		AS='as -D_ASM $(INCLUDES)'
+	    fi
+	    CFLAGS="$CFLAGS -fullwarn -xansi"
+	    if test "$USE_N32"; then
+	        _OPTIMIZE_FLAGS="-O -OPT:Olimit=4000"
+	    else
+	        _OPTIMIZE_FLAGS="-O -Olimit 4000"
+	    fi
+	    if test "$USE_MDUPDATE"; then
+                CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+	    fi
+	    case "${target}" in
+	    *-irix6.*)
+	        CFLAGS="$CFLAGS -multigot"
+	        DSO_LDOPTS="-no_unresolved"
+	        if test "$USE_N32"; then
+		        CFLAGS="$CFLAGS -n32 -woff 1209"
+		        DSO_LDOPTS="$DSO_LDOPTS -n32"
+	        else
+		        if test "$USE_64"; then
+		            CFLAGS="$CFLAGS -64"
+		        else
+		            CFLAGS="$CFLAGS -32"
+		        fi
+	        fi
+	        ;;
+	    *)
+	        CFLAGS="$CFLAGS -xgot"
+	        ;;
+	    esac
+    fi
+    if test "${target_os}" = "irix5.3"; then
+	    AC_DEFINE(IRIX5_3)
+    fi
+    case "${target_os}" in
+	irix6.5)
+	    if test -z "$GNU_CC"; then
+		    CFLAGS="$CFLAGS -mips3"
+	    fi
+	    AC_DEFINE(_PR_HAVE_GETPROTO_R)
+	    AC_DEFINE(_PR_HAVE_GETPROTO_R_POINTER)
+	    AC_DEFINE(_PR_HAVE_SGI_PRDA_PROCMASK)
+	    ;;
+	irix5*)
+	    ;;
+	*)
+	    AC_DEFINE(_PR_HAVE_SGI_PRDA_PROCMASK)
+	    ;;
+	esac
+    ;;
+
+*-linux*|*-gnu*|*-k*bsd*-gnu)
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+        IMPL_STRATEGY=_PTH
+    fi
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(_GNU_SOURCE)
+    AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+    case "${target_os}" in
+    linux*)
+        AC_DEFINE(LINUX)
+        ;;
+    esac
+    CFLAGS="$CFLAGS -Wall"
+    CXXFLAGS="$CXXFLAGS -Wall"
+    MDCPUCFG_H=_linux.cfg
+    PR_MD_CSRCS=linux.c
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS='-shared -Wl,-soname -Wl,$(notdir $@)'
+    _OPTIMIZE_FLAGS=-O2
+    _DEBUG_FLAGS="-g -fno-inline"  # most people on linux use gcc/gdb, and that
+                                   # combo is not yet good at debugging inlined
+                                   # functions (even when using DWARF2 as the
+                                   # debugging format)
+    COMPILER_TAG=_glibc
+    if echo "$OS_TEST" | grep -c 86 >/dev/null; then
+        CPU_ARCH=x86
+    else
+        CPU_ARCH=$OS_TEST
+    fi
+    CPU_ARCH_TAG=_${CPU_ARCH}
+    case "${target_cpu}" in
+    alpha)
+        AC_DEFINE(_ALPHA_)
+        AC_DEFINE(__alpha)
+        CFLAGS="$CFLAGS -mieee"
+        CXXFLAGS="$CXXFLAGS -mieee"
+        ;;
+    i*86)
+        AC_DEFINE(i386)
+        PR_MD_ASFILES=os_Linux_x86.s
+        ;;
+    ia64)
+        PR_MD_ASFILES=os_Linux_ia64.s
+        ;;
+    x86_64)
+        if test -n "$USE_64"; then
+            PR_MD_ASFILES=os_Linux_x86_64.s
+        else
+            AC_DEFINE(i386)
+            PR_MD_ASFILES=os_Linux_x86.s
+            CC="$CC -m32"
+            CXX="$CXX -m32"
+        fi
+        ;;
+    powerpc64)
+        if test -n "$USE_64"; then
+            CC="$CC -m64"
+            CXX="$CXX -m64"
+        fi
+        ;;
+    m68k)
+        CFLAGS="$CFLAGS -m68020-60"
+        CXXFLAGS="$CXXFLAGS -m68020-60"
+        ;;
+    esac    
+    ;;
+
+*-mingw*|*-cygwin*|*-msvc*|*-mks*)
+    AC_DEFINE(XP_PC)
+    AC_DEFINE(WIN32)
+    PR_MD_ARCH_DIR=windows
+    RESOLVE_LINK_SYMBOLS=1
+
+    if test -n "$GNU_CC"; then
+        CC="$CC -mno-cygwin"
+        CXX="$CXX -mno-cygwin"
+        DLL_SUFFIX=dll
+        MKSHLIB='$(CC) -shared -Wl,--export-all-symbols -Wl,--out-implib -Wl,$(IMPORT_LIBRARY) $(DLLBASE) -o $(subst $(OBJDIR)/,,$(SHARED_LIBRARY))'
+        RC=$WINDRES
+        # Use temp file for windres (bug 213281)
+        RCFLAGS='-O coff --use-temp-file'
+    else
+        CC=cl
+        CXX=cl
+        LD=link
+        AR='lib -NOLOGO -OUT:"$@"'
+        AR_FLAGS=
+        RANLIB='echo not_ranlib'
+        STRIP='echo not_strip'
+        RC=rc.exe
+        GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb'
+        OBJ_SUFFIX=obj
+        LIB_SUFFIX=lib
+        DLL_SUFFIX=dll
+
+        # Determine compiler version
+        CC_VERSION=`"${CC}" -v 2>&1 | grep Version | sed -e 's|.* Version ||' -e 's| .*||'`
+        _CC_MAJOR_VERSION=`echo $CC_VERSION | awk -F\. '{ print $1 }'`
+        _CC_MINOR_VERSION=`echo $CC_VERSION | awk -F\. '{ print $2 }'`
+        MSC_VER=${_CC_MAJOR_VERSION}${_CC_MINOR_VERSION}
+        
+        CFLAGS="$CFLAGS -W3 -nologo -GF -Gy"
+        DLLFLAGS='-OUT:"$@"'
+        _DEBUG_FLAGS=-Z7
+        _OPTIMIZE_FLAGS=-O2
+        if test -z "$MOZ_OPTIMIZE"; then
+            CFLAGS="$CFLAGS -Od"
+        fi
+
+        if test -n "$USE_DEBUG_RTL"; then
+            CFLAGS="$CFLAGS -MDd"
+        else
+            CFLAGS="$CFLAGS -MD"
+        fi
+
+        if test -n "$MOZ_DEBUG"; then
+            AC_DEFINE(_DEBUG)
+        else
+            DEFINES="$DEFINES -U_DEBUG"
+        fi
+
+        if test -n "$MOZ_OPTIMIZE"; then
+            if test -n "$MOZ_PROFILE"; then
+                _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Z7"
+            fi
+            if test -n "$MOZ_DEBUG_SYMBOLS"; then
+                _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Zi"
+            fi
+            if test -n "$MOZ_PROFILE" -o -n "$MOZ_DEBUG_SYMBOLS"; then
+                DLLFLAGS="$DLLFLAGS -DEBUG -OPT:REF"
+                LDFLAGS="$LDFLAGS -DEBUG -OPT:REF"
+            fi
+        fi
+
+        if test -n "$MOZ_DEBUG"; then
+            DLLFLAGS="$DLLFLAGS -DEBUG"
+            LDFLAGS="$LDFLAGS -DEBUG"
+        fi
+
+        OS_DLLFLAGS="-nologo -DLL -SUBSYSTEM:WINDOWS"
+        if test "$MSC_VER" -le "1200" -a -z "$MOZ_DEBUG_SYMBOLS"; then
+            OS_DLLFLAGS="$OS_DLLFLAGS -PDB:NONE"
+        fi
+        
+        if test "$OS_TARGET" = "WINNT"; then
+            CFLAGS="$CFLAGS -GT"
+            if test "$CPU_ARCH" = "x86"; then
+                CFLAGS="$CFLAGS -G5"
+            fi
+            LIBNSPR='$(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+            LIBPLC='$(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+        else
+            LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+            LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+        fi
+    fi # GNU_CC
+
+    if test -n "$USE_STATIC_TLS"; then
+        AC_DEFINE(_PR_USE_STATIC_TLS)
+    fi
+
+    if test "$OS_TARGET" = "WINNT"; then
+        AC_DEFINE(WINNT)
+    else
+        AC_DEFINE(WIN95)
+        # undefine WINNT as some versions of mingw gcc define it by default
+        DEFINES="$DEFINES -UWINNT"
+        AC_DEFINE(_PR_GLOBAL_THREADS_ONLY)
+    fi
+
+    if test "$CPU_ARCH" = "x86"; then
+        CPU_ARCH_TAG=
+    else
+        CPU_ARCH_TAG=$CPU_ARCH
+    fi
+
+    if test -n "$USE_DEBUG_RTL"; then
+        OBJDIR_SUFFIX=OBJD
+    fi
+
+    case "$OS_TARGET" in
+    WINNT)
+	    MDCPUCFG_H=_winnt.cfg
+	    ;;
+    WIN95)
+	    MDCPUCFG_H=_win95.cfg
+	    ;;
+    WIN16)
+	    MDCPUCFG_H=_win16.cfg
+	    ;;
+    *)
+	    AC_MSG_ERROR([Missing OS_TARGET for ${target}.  Use --enable-win32-target to set.])
+   	;;
+    esac
+
+    case "$target_cpu" in
+    i*86)
+	if test -n "$USE_64"; then
+	    AC_DEFINE(_AMD64_)
+	    AC_DEFINE(_M_AMD64)    
+	else		
+	    AC_DEFINE(_X86_)
+	fi
+        ;;
+    alpha)
+	    AC_DEFINE(_ALPHA_)
+   	    ;;
+    mips)
+	    AC_DEFINE(_MIPS_)
+	    ;;
+    x86_64)
+	    AC_DEFINE(_AMD64_)
+	    AC_DEFINE(_M_AMD64)
+	    USE_64=1
+	    ;;
+    ia64)
+	    AC_DEFINE(_IA64_)
+	    AC_DEFINE(_M_IA64)
+	    USE_64=1
+	    ;;
+    *)
+	    AC_DEFINE(_CPU_ARCH_NOT_DEFINED)
+	    ;;
+    esac
+
+    if test "$USE_64"; then
+        AC_DEFINE(_WIN64)
+    fi
+
+    ;;
+
+*-ncr-sysv*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(SYSV)
+    AC_DEFINE(NCR)
+    USE_NSPR_THREADS=1
+    if test "$OS_RELEASE" = "2.03"; then
+        AC_DEFINE(_PR_STAT_HAS_ST_ATIM)
+    else
+        AC_DEFINE(_PR_STAT_HAS_ST_ATIM_UNION)
+    fi
+
+    if test -z "$GNU_CC"; then
+        CFLAGS="$CFLAGS -Hnocopyr"
+        CXXFLAGS="$CXXFLAGS -Hnocopyr"
+    else
+        CFLAGS="$CFLAGS -fPIC -Wall"
+        CXXFLAGS="$CXXFLAGS -fPIC -Wall"
+        DSO_LDOPTS=-G
+    fi
+    MDCPUCFG_H=_ncr.cfg
+    PR_MD_CSRCS=ncr.c
+    ;;
+
+mips-nec-sysv*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(__SVR4)
+    AC_DEFINE(NEC)
+    AC_DEFINE(nec_ews)
+    USE_NSPR_THREADS=1
+    if test -z "$GNU_CC"; then
+        CC='$(NSDEPTH)/build/hcc cc -Xa -KGnum=0 -KOlimit=4000'
+        CXX=g++
+    fi
+    OS_LIBS="$OS_LIBS -lsocket -lnsl -ldl"
+    DSO_LDOPTS=-G
+    MDCPUCFG_H=_nec.cfg
+    PR_MD_CSRCS=nec.c
+    ;;
+
+*-netbsd*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(NETBSD)
+    AC_DEFINE(HAVE_BSD_FLOCK)
+    USE_NSPR_THREADS=1
+    MDCPUCFG_H=_netbsd.cfg
+    PR_MD_CSRCS=netbsd.c
+
+    DSO_CFLAGS='-fPIC -DPIC'
+    CFLAGS="$CFLAGS -ansi -Wall"
+    CXXFLAGS="$CXXFLAGS -ansi -Wall"
+    MKSHLIB='$(CC) -o $@ $(DSO_LDOPTS)'
+
+    if test -z "$OBJECT_FMT"; then
+        if echo __ELF__ | ${CC-cc} -E - | grep -q __ELF__ 2>/dev/null; then
+            OBJECT_FMT=a.out
+            DLL_SUFFIX=so.1.0
+            DSO_LDOPTS='-shared'
+        else
+            OBJECT_FMT=ELF
+            DLL_SUFFIX=so
+            DSO_LDOPTS='-shared -Wl,-soname,$(notdir $@)'
+        fi
+    fi
+
+    if test "$LIBRUNPATH"; then
+        DSO_LDOPTS="$DSO_LDOPTS -Wl,-R$LIBRUNPATH"
+    fi
+    ;;
+
+mips-sony-newsos*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SONY)
+    AC_DEFINE(SYSV)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(__svr4)
+    AC_DEFINE(__svr4__)
+    AC_DEFINE(HAVE_SVID_GETTOD)
+    USE_NSPR_THREADS=1
+    CFLAGS="$CFLAGS -Xa -fullwarn"
+    CXXFLAGS="$CXXFLAGS -Xa -fullwarn"
+    DSO_LDOPTS=-G
+    MDCPUCFG_H=_sony.cfg
+    PR_MD_CSRCS=sony.c
+    ;;
+
+*-nextstep*|*-openstep*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(NEXTSTEP)
+    AC_DEFINE(HAVE_BSD_FLOCK)
+    AC_DEFINE(_POSIX_SOURCE)
+    CFLAGS="$CFLAGS -Wall -fno-common -traditional-cpp -posix"
+    CXXFLAGS="$CXXFLAGS -Wall -fno-common -traditional-cpp -posix"
+    USE_NSPR_THREADS=1
+    DLL_SUFFIX=dylib
+    MDCPUCFG_H=_nextstep.cfg
+    PR_MD_CSRCS=nextstep.c
+    ;;
+
+
+*-nto*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(NTO)
+    AC_DEFINE(_QNX_SOURCE)
+    AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+    MDCPUCFG_H=_nto.cfg
+    PR_MD_CSRCS=nto.c
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(notdir $@) -o $@'
+    DSO_CFLAGS=-fPIC
+    DSO_LDOPTS=-shared
+    OS_LIBS="$OS_LIBS -lsocket"
+    _OPTIMIZE_FLAGS="-O1"
+    _DEBUG_FLAGS="-gstabs"
+	;;
+
+*-openbsd*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(OPENBSD)
+    AC_DEFINE(HAVE_BSD_FLOCK)
+    AC_DEFINE(HAVE_SOCKLEN_T)
+    CFLAGS="$CFLAGS -ansi -Wall"
+    CXXFLAGS="$CXXFLAGS -ansi -Wall"
+    DLL_SUFFIX=so.1.0
+    DSO_CFLAGS=-fPIC
+    MDCPUCFG_H=_openbsd.cfg
+    PR_MD_CSRCS=openbsd.c
+    if test -z "$USE_NSPR_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    DSO_LDOPTS='-shared -fPIC'
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    ;;
+
+*-openvms*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(VMS)
+    AC_DEFINE(PR_GETIPNODE_NOT_THREADSAFE)
+    RESOLVE_LINK_SYMBOLS=1
+    AR_FLAGS='c $@'
+    MDCPUCFG_H=_openvms.cfg
+    PR_MD_CSRCS=openvms.c
+    DSO_LDOPTS='-shared -auto_symvec $(LDFLAGS)'
+    if test -n "$MOZ_DEBUG"; then
+      DSO_LDOPTS="$DSO_LDOPTS $_DEBUG_FLAGS"
+    else
+      DSO_LDOPTS="$DSO_LDOPTS $_OPTIMIZE_FLAGS"
+    fi
+    ;;
+
+*-osf*)
+    SHELL_OVERRIDE="SHELL		= /usr/bin/ksh"
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(OSF1)
+    AC_DEFINE(_REENTRANT)
+    # OSF1 and HPUX report the POLLHUP event for a socket when the
+    # shutdown(SHUT_WR) operation is called for the remote end, even though
+    # the socket is still writeable. Use select(), instead of poll(), to
+    # workaround this problem.
+    AC_DEFINE(_PR_POLL_WITH_SELECT)
+
+    if echo "$OS_RELEASE" | egrep -c '(V2.0|V3.2)' 2>/dev/null ; then
+        USE_NSPR_THREADS=1
+    fi
+
+    if test -z "$GNU_CC"; then
+        CC="$CC -std1 -ieee_with_inexact"
+        if test "$OS_RELEASE" != "V2.0"; then
+            CC="$CC -readonly_strings"
+        fi
+        _OPTIMIZE_FLAGS="$_OPTIMIZE_FLAGS -Olimit 4000"
+        AC_CHECK_HEADER(machine/builtins.h, AC_DEFINE(OSF1_HAVE_MACHINE_BUILTINS_H))
+    else
+        CFLAGS="$CFLAGS -mieee"
+        CXXFLAGS="$CXXFLAGS -mieee"
+    fi
+
+    if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then
+        AC_DEFINE(HAVE_INT_LOCALTIME_R)
+    else
+        AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+        AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+    fi
+    if echo $OS_RELEASE | grep -c V4.0 >/dev/null; then
+        AC_DEFINE(OSF1V4_MAP_PRIVATE_BUG)
+    fi
+    DSO_LDOPTS='-shared -all -expect_unresolved "*" -soname $(notdir $@)'
+    MDCPUCFG_H=_osf1.cfg
+    PR_MD_CSRCS=osf1.c
+    ;;
+
+*-qnx*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(QNX)
+    AC_DEFINE(_PR_NEED_H_ERRNO)
+    USE_NSPR_THREADS=1
+    MDCPUCFG_H=_qnx.cfg
+    PR_MD_CSRCS=qnx.c
+    ;;
+
+*-riscos*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(RISCOS)
+    AC_DEFINE(_PR_NEED_H_ERRNO)
+    USE_PTHREADS=1
+    MDCPUCFG_H=_riscos.cfg
+    PR_MD_CSRCS=riscos.c
+    DLL_SUFFIX=a
+    LD="/home/riscos/env/ro-ar cr"
+    ;;
+
+*-*-sco*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SCO)
+    AC_DEFINE(sco)
+    AC_DEFINE(SYSV)
+    AC_DEFINE(_SVID3)
+    AC_DEFINE(_PR_NEED_H_ERRNO)
+    CC='cc -b elf -KPIC'
+    CXX='$(NSDEPTH)/build/hcpp CC +.cpp +w'
+    USE_NSPR_THREADS=1
+    CPU_ARCH=x86
+    DSO_LDOPTS='-b elf -G'
+    MDCPUCFG_H=_scoos.cfg
+    PR_MD_SRCS=scoos.c
+    ;;
+
+*-sinix*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(SNI)
+    AC_DEFINE(RELIANTUNIX)
+    AC_DEFINE(sinix)
+    AC_DEFINE(HAVE_SVID_GETTOD)
+    if echo "$OS_TEST" | grep -c 86 2>/dev/null; then
+        AC_DEFINE(i386)
+        CPU_ARCH=x86
+    else
+        CPU_ARCH=mips
+    fi
+
+    if test "$GNU_CC"; then
+        AS='$(CC) -x assembler-with-cpp'
+        if test "$CPU_ARCH" = "mips"; then
+            LD=gld
+        fi
+        CFLAGS="$CFLAGS -Wall -Wno-format"
+    else
+        AS='/usr/bin/cc'
+        _OPTIMIZE_FLAGS='-O -F Olimit,4000'
+    fi
+
+    DSO_LDOPTS='-G -z defs -h $(@:$(OBJDIR)/%.so=%.so)'
+
+    if test "$OS_RELEASE" = "5.43"; then
+        AC_DEFINE(IP_MULTICAST)
+    fi
+
+    OS_LIBS="$OS_LIBS -lsocket -lnsl -lresolv -ldl -lc"
+    USE_NSPR_THREADS=1
+    MDCPUCFG_H=_reliantunix.cfg
+    PR_MD_CSRCS=reliantunix.c
+    if test "${OS_ARCH}" = "mips"; then
+        PR_MD_ASFILES=os_ReliantUNIX.s
+    fi
+    ;;
+
+*-sunos*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SUNOS4)
+    CFLAGS="$CFLAGS -Wall -Wno-format"
+    if test "$USE_MDUPDATE"; then
+        CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+    fi
+    CPU_ARCH=sparc
+    DLL_SUFFIX=so.1.0
+    DSO_LDOPTS=
+    DSO_CFLAGS=-fPIC
+    USE_NSPR_THREADS=1
+    if test "$OS_RELEASE" = "4.1.3_U1"; then
+        _OPTIMIZE_FLAGS=
+        OS_LIBS="$OS_LIBS -lm"
+    fi
+    MDCPUCFG_H=_sunos4.cfg
+    PR_MD_CSRCS=sunos4.c
+    ;;
+
+*-solaris*)
+    if test -z "$USE_USER_THREADS" && test -z "$USE_NATIVE_THREADS"; then
+        USE_PTHREADS=1
+    fi
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(SYSV)
+    AC_DEFINE(__svr4)
+    AC_DEFINE(__svr4__)
+    AC_DEFINE(SOLARIS)
+    AC_DEFINE(HAVE_FCNTL_FILE_LOCKING)
+    MDCPUCFG_H=_solaris.cfg
+    PR_MD_CSRCS=solaris.c
+    LD=/usr/ccs/bin/ld
+    MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+    RESOLVE_LINK_SYMBOLS=1
+    if test -n "$GNU_CC"; then
+        DSO_CFLAGS=-fPIC
+        if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then
+            GCC_USE_GNU_LD=1
+        fi
+        DSO_LDOPTS='-shared -Wl,-h,$(notdir $@),-z,combreloc,-z,defs,-z,ignore' 
+    else
+        DSO_CFLAGS=-KPIC
+        DSO_LDOPTS='-G -h $(notdir $@) -z combreloc -z defs -z ignore'
+    fi
+    if test -n "$GNU_CC"; then
+        CFLAGS="$CFLAGS -Wall"
+        CXXFLAGS="$CXXFLAGS -Wall"
+        if test -n "$USE_MDUPDATE"; then
+            CFLAGS="$CFLAGS -MDupdate \$(DEPENDENCIES)"
+            CXXFLAGS="$CXXFLAGS -MDupdate \$(DEPENDENCIES)"
+        fi
+        GCC_AS=`$CC -print-prog-name=as`
+        if test "`echo | $GCC_AS -v 2>&1 | grep -c GNU`" != "0"; then
+            GNU_AS=1
+        fi
+    else
+        CFLAGS="$CFLAGS -xstrconst"
+        CXXFLAGS="$CXXFLAGS -Qoption cg -xstrconst -features=tmplife"
+        if test -z "$MOZ_OPTIMIZE"; then
+            CFLAGS="$CFLAGS -xs"
+            CXXFLAGS="$CXXFLAGS -xs"
+        fi
+        _OPTIMIZE_FLAGS=-xO4
+    fi
+    if test -z "$GNU_AS"; then
+        ASFLAGS="$ASFLAGS -Wa,-P"
+    fi
+    if test -n "$USE_64"; then
+        if test -n "$GNU_CC"; then
+            CC="$CC -m64"
+            CXX="$CXX -m64"
+        else
+            if test "$OS_TEST" = "i86pc"; then
+                CC="$CC -xarch=amd64"
+                CXX="$CXX -xarch=amd64"
+            else
+                CC="$CC -xarch=v9"
+                CXX="$CXX -xarch=v9"
+            fi
+        fi
+    fi
+    if test "$OS_TEST" = "i86pc"; then
+        if test -z "$USE_64"; then
+            AC_DEFINE(i386)
+        fi
+        CPU_ARCH_TAG=_$OS_TEST
+        # The default debug format, DWARF (-g), is not supported by gcc
+        # on i386-ANY-sysv4/solaris, but the stabs format is.  It is
+        # assumed that the Solaris assembler /usr/ccs/bin/as is used.
+        # If your gcc uses GNU as, you do not need the -Wa,-s option.
+        if test -n "$MOZ_DEBUG" && test -n "$GNU_CC"; then
+            _DEBUG_FLAGS=-gstabs
+            if test -z "$GNU_AS"; then
+                _DEBUG_FLAGS="$_DEBUG_FLAGS -Wa,-s"
+            fi
+        fi
+    fi
+    case "${target_os}" in
+    solaris2.3*)
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+        ;;
+    solaris2.4*)
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+        ;;
+    solaris2.5*)
+        AC_DEFINE(SOLARIS2_5)    
+        ;;
+    *)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        # The lfcompile64(5) man page on Solaris 2.6 says:
+        #     For applications that do not wish to conform to the POSIX or
+        #     X/Open  specifications,  the  64-bit transitional interfaces
+        #     are available by default.  No compile-time flags need to  be
+        #     set.
+        # But gcc 2.7.2.x fails to define _LARGEFILE64_SOURCE by default.
+        # The native compiler, gcc 2.8.x, and egcs don't have this problem.
+        if test -n "$GNU_CC"; then
+            AC_DEFINE(_LARGEFILE64_SOURCE)
+        fi
+        ;;
+    esac
+    case "${target_os}" in
+    solaris2.3*)
+        ;;
+    solaris2.4*)
+        ;;
+    solaris2.5*)
+        ;;
+    solaris2.6*)
+        ;;
+    solaris2.7*)
+        ;;
+    *)
+        # Solaris 8 or higher has IPv6.
+        AC_DEFINE(_PR_INET6)
+        ;;
+    esac
+    if test "$OS_TEST" = "sun4u"; then
+        # 64-bit Solaris requires SPARC V9 architecture, so the following
+        # is not needed.
+        if test -z "$USE_64"; then
+            ULTRASPARC_LIBRARY=nspr_flt
+        fi
+    fi
+    # Purify requires that binaries linked against nspr also
+    # be linked against -lrt (or -lposix4) so add it to OS_LIBS
+    _rev=`uname -r`
+    _librt=`echo $_rev 5.6 | awk '{ if ($1 > $2) print "-lrt"; else print "-lposix4" }'`
+    OS_LIBS="$OS_LIBS $_librt"
+    ;;
+
+*-sco-sysv5*)
+    AC_DEFINE(XP_UNIX)
+    AC_DEFINE(UNIXWARE)
+    AC_DEFINE(SVR4)
+    AC_DEFINE(SYSV)
+    USE_NSPR_THREADS=1
+    if echo $OS_RELEASE | grep -c 2.1 2>/dev/null; then
+        AC_DEFINE(_PR_NO_LARGE_FILES)
+        CC='$(NSDEPTH)/build/hcc cc'
+        CXX='$(NSDEPTH)/build/hcpp CC'
+        MDCPUCFG_H=_unixware.cfg
+    else
+        AC_DEFINE(_LARGEFILE64_SOURCE)
+        AC_DEFINE(_PR_HAVE_OFF64_T)
+        AC_DEFINE(_PR_HAVE_SOCKADDR_LEN)
+        MDCPUCFG_H=_unixware7.cfg
+    fi
+    PR_MD_CSRCS=unixware.c
+    DSO_LDOPTS=-G
+    CPU_ARCH=x86
+    ;;
+
+*-os2*)
+    AC_DEFINE(XP_OS2)
+    AC_DEFINE(XP_PC)
+    AC_DEFINE(BSD_SELECT)
+    AC_DEFINE(TCPV40HDRS)
+    LIB_SUFFIX=lib
+    DLL_SUFFIX=dll
+    RC=rc.exe
+    PR_MD_ARCH_DIR=os2
+    PROG_SUFFIX=.exe
+    NSINSTALL=nsinstall
+    MDCPUCFG_H=_os2.cfg
+    RESOLVE_LINK_SYMBOLS=1
+
+    # EMX/GCC build
+    if test -n "$GNU_CC"; then
+        AC_DEFINE(XP_OS2_EMX)
+        AC_DEFINE(OS2)
+        AR=emxomfar
+        AR_FLAGS='r $@'
+        CFLAGS="$CFLAGS -Wall -Zomf"
+        CXXFLAGS="$CFLAGS -Wall -Zomf"
+        MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+        DSO_CFLAGS=
+        DSO_LDOPTS='-Zomf -Zdll -Zmap'
+        LDFLAGS='-Zmap'
+        _OPTIMIZE_FLAGS="-O2 -s"
+        _DEBUG_FLAGS="-g -fno-inline"
+        if test -n "$MOZ_OPTIMIZE"; then
+          DSO_LDOPTS="$DSO_LDOPTS -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA"
+        fi
+        OS_LIBS="-lsocket"
+        IMPLIB='emximp -o'
+        FILTER='emxexp -o'
+
+        # GCC for OS/2 currently predefines these, but we don't want them
+        DEFINES="$DEFINES -Uunix -U__unix -U__unix__"
+
+    # Visual Age C++ build
+    elif test "$VACPP" = "yes"; then
+        AC_DEFINE(XP_OS2_VACPP)
+        AC_DEFINE(OS2,4)
+        AC_DEFINE(_X86_)
+        OBJ_SUFFIX=obj
+        AS=alp
+        ASFLAGS='-Mb'
+        ASM_SUFFIX=asm
+        AR=-ilib
+        AR_FLAGS='/NOL /NOI /O:$(subst /,\\,$@)'
+        CFLAGS='/Q /qlibansi /Gd+ /Gm+ /Su4 /Mp /Tl9'
+        HOST_CFLAGS="$CFLAGS"
+        OS_CFLAGS='/Q /qlibansi /Gd+ /Gm+ /Su4 /Mp /Tl9'
+        OS_EXE_CFLAGS='/Q /qlibansi /Gd+ /Gm+ /Su4 /Mp /Tl9'
+        CXXFLAGS='/Q /qlibansi /Gd+ /Gm+ /Su4 /Mp /Tl9'
+        OS_LIBS='so32dll.lib tcp32dll.lib'
+        LD='-ilink'
+        MKSHLIB='$(LD) $(DSO_LDOPTS)'
+        IMPLIB='implib -nologo -noignorecase'
+        FILTER='cppfilt -q -B -P'
+        _OPTIMIZE_FLAGS='/O+ /Gl+ /qtune=pentium /qarch=pentium'
+        _DEBUG_FLAGS='/Ti+ '
+        LDFLAGS='/NOL /M /L'
+        DLLFLAGS='/O:$@ /DLL /INC:_dllentry /MAP:$(@:.dll=.map) /L /NOL'
+        EXEFLAGS='/OUT:$@ /PMTYPE:VIO /MAP:$(@:.exe=.map) /L /NOL'
+        if test -n "$MOZ_DEBUG"; then
+          LDFLAGS="$LDFLAGS /DE"
+          DLLFLAGS="$DLLFLAGS /DE"
+          EXEFLAGS="$EXEFLAGS /DE"
+        fi
+        if test -n "$MOZ_OPTIMIZE"; then
+          LDFLAGS="$LDFLAGS /OPTFUNC /EXEPACK:2 /PACKCODE /PACKDATA"
+          DLLFLAGS="$DLLFLAGS /OPTFUNC /EXEPACK:2 /PACKCODE /PACKDATA"
+          EXEFLAGS="$EXEFLAGS /OPTFUNC /EXEPACK:2 /PACKCODE /PACKDATA"
+        fi
+        LIBNSPR='$(dist_libdir)/nspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+        LIBPLC='$(dist_libdir)/plc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)'
+    fi
+    ;;
+
+*)
+    AC_DEFINE(XP_UNIX)
+    ;;
+   
+esac
+
+if test -z "$SKIP_LIBRARY_CHECKS"; then
+dnl ========================================================
+dnl Check for system libraries
+dnl ========================================================
+dnl AC_CHECK_LIB(C, main)
+dnl AC_CHECK_LIB(C_r, main)
+dnl AC_CHECK_LIB(c, main)
+dnl AC_CHECK_LIB(c_r, main)
+dnl AC_CHECK_LIB(dce, main)
+dnl AC_CHECK_LIB(dl, main)
+dnl AC_CHECK_LIB(dld, main)
+dnl AC_CHECK_LIB(gen, main)
+dnl AC_CHECK_LIB(ip6, main)
+dnl AC_CHECK_LIB(l, main)
+dnl AC_CHECK_LIB(m, main)
+dnl AC_CHECK_LIB(nsl, main)
+dnl AC_CHECK_LIB(posix4, main)
+dnl AC_CHECK_LIB(prstrms, main)
+dnl AC_CHECK_LIB(prstrms_shr, main)
+dnl AC_CHECK_LIB(pthread, main)
+dnl AC_CHECK_LIB(pthreads, main)
+dnl AC_CHECK_LIB(resolv, main)
+dnl AC_CHECK_LIB(rt, main)
+dnl AC_CHECK_LIB(socket, main)
+dnl AC_CHECK_LIB(svld, main)
+dnl AC_CHECK_LIB(thread, main)
+dnl AC_CHECK_LIB(vms_jackets, main)
+
+
+dnl We don't want anything to link with libdl even if it's present on OS X, 
+dnl since it's not used and not part of the default installation.
+dnl The same goes for BeOS.
+
+case $target in
+*-darwin*|*-beos*)
+    ;;
+*)
+    AC_CHECK_LIB(dl, dlopen,
+        AC_CHECK_HEADER(dlfcn.h,
+            OS_LIBS="-ldl $OS_LIBS"))
+    ;;
+esac
+
+
+dnl ========================================================
+dnl Check for system header files.
+dnl ========================================================
+dnl AC_HEADER_DIRENT
+dnl AC_HEADER_STDC
+dnl AC_HEADER_SYS_WAIT
+dnl AC_CHECK_HEADERS(fcntl.h limits.h sys/file.h sys/ioctl.h sys/time.h unistd.h)
+
+dnl ========================================================
+dnl Check for typedefs and structs
+dnl ========================================================
+dnl AC_C_CONST
+dnl AC_TYPE_UID_T
+dnl AC_TYPE_MODE_T
+dnl AC_TYPE_OFF_T
+dnl AC_TYPE_PID_T
+dnl AC_TYPE_SIZE_T
+dnl AC_STRUCT_ST_BLKSIZE
+dnl AC_STRUCT_ST_BLOCKS
+dnl AC_STRUCT_ST_RDEV
+dnl AC_HEADER_TIME
+dnl AC_STRUCT_TM
+
+dnl ========================================================
+dnl Checks for library functions.
+dnl ========================================================
+AC_PROG_GCC_TRADITIONAL
+AC_CHECK_FUNCS(lchown strerror)
+
+dnl AC_FUNC_MEMCMP
+dnl AC_FUNC_MMAP
+dnl AC_FUNC_SETVBUF_REVERSED
+dnl AC_FUNC_STRCOLL
+dnl AC_FUNC_STRFTIME
+dnl AC_FUNC_UTIME_NULL
+dnl AC_FUNC_VPRINTF
+dnl AC_CHECK_FUNCS(ftime getcwd gethostname gettimeofday getwd mkdir mktime putenv rmdir select socket strdup strerror strstr strtol strtoul uname)
+
+dnl ========================================================
+dnl Check options
+dnl ========================================================
+
+dnl ========================================================
+dnl =
+dnl = --enable-strip
+dnl = 
+dnl = Enable stripping of libs and executables
+dnl = 
+dnl ========================================================
+AC_ARG_ENABLE(strip,
+    [  --enable-strip          Enable stripping of shared libs and programs],
+    [ if test "$enableval" = "yes"; then
+	    ENABLE_STRIP=1
+      fi ])
+
+dnl Check for hpux options
+case "${target_os}" in
+hpux*)
+if test -z "$GNU_CC"; then
+
+    AC_CACHE_CHECK(for +Olit support,
+        ac_cv_hpux_usable_olit_option,
+        dnl since aCC doesn't throw an error on invalid options,
+        dnl we have to test this the hard way
+        [ac_cv_hpux_usable_olit_option=no
+        rm -f conftest*
+        echo 'int main() { return 0; }' | cat > conftest.c
+        ${CC-cc} ${CFLAGS} +Olit=all -o conftest conftest.c > conftest.out 2>&1
+        if test $? -eq 0; then
+            if test -z "`egrep -i '(unrecognize|unknown)' conftest.out`"; then
+                ac_cv_hpux_usable_olit_option=yes
+            fi
+        fi
+        rm -f conftest*
+        ])
+
+    if test "$ac_cv_hpux_usable_olit_option" = "yes"; then
+        CFLAGS="$CFLAGS +Olit=all"
+        CXXFLAGS="$CXXFLAGS +Olit=all"
+    else
+        CFLAGS="$CFLAGS +ESlit"
+        CXXFLAGS="$CXXFLAGS +ESlit"
+    fi
+fi
+;;
+esac
+
+dnl
+dnl Apparently, some systems cannot properly check for the pthread
+dnl library unless <pthread.h> is included so we need to test
+dnl using it
+dnl
+dnl MOZ_CHECK_PTHREADS(lib, success, failure)
+AC_DEFUN(MOZ_CHECK_PTHREADS,
+[
+AC_MSG_CHECKING([for pthread_create in -l$1])
+echo "
+    #include <pthread.h> 
+    void *foo(void *v) { return v; } 
+    int main() { 
+        pthread_t t;
+        if (!pthread_create(&t, 0, &foo, 0)) {
+            pthread_join(t, 0);
+        }
+        return 0;
+    }" > dummy.c ;
+    echo "${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -l[$1] $LDFLAGS $LIBS" 1>&5;
+    ${CC-cc} -o dummy${ac_exeext} dummy.c $CFLAGS $CPPFLAGS -l[$1] $LDFLAGS $LIBS 2>&5;
+    _res=$? ;
+    rm -f dummy.c dummy${ac_exeext} ;
+    if test "$_res" = "0"; then
+        AC_MSG_RESULT([yes])
+        [$2]
+    else
+        AC_MSG_RESULT([no])
+        [$3]
+    fi
+])
+
+case "$target_os" in
+darwin*)
+    _HAVE_PTHREADS=1
+    ;;
+*)
+    MOZ_CHECK_PTHREADS(pthreads,
+        _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthreads",
+        MOZ_CHECK_PTHREADS(pthread,
+            _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthread",
+            MOZ_CHECK_PTHREADS(c_r,
+                _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lc_r",
+                MOZ_CHECK_PTHREADS(c,
+                    _HAVE_PTHREADS=1
+                )
+            )
+        )
+    )
+    ;;
+esac
+
+AC_ARG_WITH(pthreads,
+    [  --with-pthreads         Use system pthreads library as thread subsystem],
+    [ if test "$withval" = "yes"; then
+	    if test -n "$_HAVE_PTHREADS"; then
+		    USE_PTHREADS=1 
+		    USE_USER_PTHREADS=
+		    USE_NSPR_THREADS=
+	    else
+		    AC_MSG_ERROR([ --with-pthreads specified for a system without pthread support ]);
+	    fi
+	  else
+	    USE_PTHREADS=
+	    _PTHREAD_LDFLAGS=
+	  fi],
+	[ if test -n "$_HAVE_PTHREADS" && test -z "$USE_USER_PTHREADS" && test -z "$USE_NSPR_THREADS"; then
+	    USE_PTHREADS=1
+	    USE_USER_PTHREADS=
+	    USE_NSPR_THREADS=
+	  fi])
+
+AC_ARG_ENABLE(user-pthreads,
+    [  --enable-user-pthreads  Build using userland pthreads],
+    [ if test "$enableval" = "yes"; then
+        if test -n "$_HAVE_PTHREADS"; then
+		    USE_PTHREADS=
+		    USE_USER_PTHREADS=1
+		    USE_NSPR_THREADS=
+	    else
+		    AC_MSG_ERROR([ --enable-user-pthreads specified for a system without pthread support ]);
+	    fi
+	  fi])
+
+AC_ARG_ENABLE(nspr-threads,
+    [  --enable-nspr-threads   Build using classic nspr threads],
+    [ if test "$enableval" = "yes"; then
+	    USE_PTHREADS=
+	    USE_USER_PTHREADS=
+	    USE_NSPR_THREADS=1
+	  fi])
+
+case "$target" in
+*-beos*)
+    AC_ARG_WITH(bthreads,
+    [  --with-bthreads         Use system bthreads library as thread subsystem
+                          (BeOS only)],
+    [	if test "$withval" = "yes"; then
+    	    USE_BTHREADS=1
+	        USE_USER_PTHREADS=
+	        USE_PTHREADS=
+	    fi])
+    ;;
+
+*-solaris*)
+    AC_ARG_WITH(native-threads,
+    [  --with-native-threads   Use native system threads as thread subsystem
+                          (Solaris only)],
+    [ if test "$withval" = "yes"; then
+	    USE_NATIVE_THREADS=1
+	    USE_USER_PTHREADS=
+	    USE_PTHREADS=
+	  fi])
+    ;;
+esac
+
+fi # SKIP_LIBRARY_CHECKS
+
+AC_ARG_ENABLE(cplus,
+    [  --enable-cplus          Enable some c++ api routines],
+    [ if test "$enableval" = "yes"; then
+	    USE_CPLUS=1
+      fi]) 
+
+AC_ARG_ENABLE(ipv6,
+    [  --enable-ipv6           Compile ipv6 support],
+    [ if test "$enableval" = "yes"; then
+	    USE_IPV6=1
+      else
+	    USE_IPV6=
+      fi])
+
+
+AC_ARG_ENABLE(boehm,
+    [  --enable-boehm          Enable the Boehm Garbage Collector],
+    [ if test "$enableval" = "yes"; then
+        AC_DEFINE(GC_LEAK_DETECTOR)
+        GC_LEAK_DETECTOR=1
+    fi])
+
+if test -n "$USE_PTHREADS"; then
+   dnl See if -pthread is supported.
+   rm -f conftest*
+   ac_cv_have_dash_pthread=no
+   AC_MSG_CHECKING(whether ${CC-cc} accepts -pthread)
+   echo 'int main() { return 0; }' | cat > conftest.c
+   ${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1
+   if test $? -eq 0; then
+	if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthread`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then
+	    ac_cv_have_dash_pthread=yes
+		case "$target_os" in
+	    freebsd*)
+# Freebsd doesn't use -pthread for compiles, it uses them for linking
+            ;;
+	    *)
+            CFLAGS="$CFLAGS -pthread"
+            CXXFLAGS="$CXXFLAGS -pthread"
+            ;;
+        esac
+	fi
+    fi
+    rm -f conftest*
+    AC_MSG_RESULT($ac_cv_have_dash_pthread)
+
+	dnl
+	dnl See if -pthreads is supported.
+	dnl
+    ac_cv_have_dash_pthreads=no
+    if test "$ac_cv_have_dash_pthread" = "no"; then
+	    AC_MSG_CHECKING(whether ${CC-cc} accepts -pthreads)
+    	echo 'int main() { return 0; }' | cat > conftest.c
+	    ${CC-cc} -pthreads -o conftest conftest.c > conftest.out 2>&1
+    	if test $? -eq 0; then
+	    	if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthreads`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then
+			    ac_cv_have_dash_pthreads=yes
+			    CFLAGS="$CFLAGS -pthreads"
+			    CXXFLAGS="$CXXFLAGS -pthreads"
+		    fi
+	    fi
+	    rm -f conftest*
+    	AC_MSG_RESULT($ac_cv_have_dash_pthreads)
+    fi
+
+    case "$target" in
+    *-solaris*)
+        if test "$ac_cv_have_dash_pthreads" = "yes"; then
+            _PTHREAD_LDFLAGS=
+        fi
+	    ;;
+    *-freebsd*)
+	    AC_DEFINE(_REENTRANT)
+	    AC_DEFINE(_THREAD_SAFE)
+	    dnl -pthread links in -lc_r, so don't specify it explicitly.
+	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS="-pthread"
+	    else
+	        _PTHREAD_LDFLAGS="-lc_r"
+	    fi
+	    ;;
+    *-netbsd*)
+	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS="-pthread"
+	    fi
+	    ;;
+    *-bsdi*)
+	    AC_DEFINE(_THREAD_SAFE)
+	    dnl -pthread links in -lc_r, so don't specify it explicitly.
+	    if test "$ac_cv_have_dash_pthread" = "yes"; then
+	        _PTHREAD_LDFLAGS=
+	    fi
+	    ;;
+    *-openbsd*)
+        if test "$ac_cv_have_dash_pthread" = "yes"; then
+            _PTHREAD_LDFLAGS=-pthread
+        fi
+        ;;
+    *-linux*|*-gnu*|*-k*bsd*-gnu)
+        AC_DEFINE(_REENTRANT)
+        ;;
+    esac
+
+else 
+    if test -n "$USE_USER_PTHREADS"; then
+	    USE_PTHREADS=
+	    USE_NSPR_THREADS=
+    else
+        _PTHREAD_LDFLAGS=
+    fi
+fi
+dnl Special thread exceptions
+
+case "$target" in
+*-aix*)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi
+    case "$target_os" in
+    aix4.1*)
+        if test -z "$USE_PTHREADS"; then
+            AC_DEFINE(AIX_RENAME_SELECT)
+        fi
+        ;;
+    aix4.2*)
+        if test -z "$USE_NSPR_THREADS"; then
+            AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+        fi
+        ;;
+    aix4.3*)
+        if test -z "$USE_NSPR_THREADS"; then
+            AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+        fi
+        if test -n "$USE_PTHREADS"; then
+            AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST)
+        fi
+        ;;
+    *)
+        if test -z "$USE_NSPR_THREADS"; then
+            AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+        fi
+        if test -n "$USE_PTHREADS"; then
+            AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST)
+        fi
+        ;;
+    esac
+    ;;
+*-bsdi*)
+    if test -n "$USE_PTHREADS"; then
+        AC_DEFINE(_PR_NEED_PTHREAD_INIT)
+    fi
+    ;;
+*-freebsd*)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi
+    ;;
+*-hpux*)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi 
+    if test "$USE_PTHREADS"; then
+        if echo "$OS_RELEASE" | egrep '^(B.10.10|B.10.20)' >/dev/null; then
+            AC_DEFINE(_REENTRANT)
+            AC_DEFINE(_PR_DCETHREADS)
+        else
+            AC_DEFINE_UNQUOTED(_POSIX_C_SOURCE,199506L)
+            AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST)
+        fi
+    fi
+    if test "$USE_USER_PTHREADS"; then
+        AC_DEFINE_UNQUOTED(_POSIX_C_SOURCE,199506L)
+    fi
+    ;;
+*-irix*)
+    if test "${target_os}" = "irix6.5"; then
+        if test -n "$USE_PTHREADS"; then
+            AC_DEFINE(_PR_HAVE_GETHOST_R)
+            AC_DEFINE(_PR_HAVE_GETHOST_R_POINTER)
+        fi
+    fi
+    ;;
+*-linux*|*-gnu*|*-k*bsd*-gnu)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi
+    ;;
+*-mingw*|*-cygwin*|*-msvc*|*-mks*|*-os2*|*-beos*)
+    dnl win32, os2 & beos cannot use pthreads
+    USE_PTHREADS=
+    _PTHREAD_LDFLAGS=
+    USE_USER_PTHREADS=
+    ;;
+*-netbsd*|*-openbsd*)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi
+    ;;
+*-osf*)
+    if test -n "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+    fi
+    if test -n "$USE_PTHREADS"; then
+        if echo $OS_RELEASE | egrep -c '(V2.0|V3.2)' 2>/dev/null; then
+            :
+        else
+            AC_DEFINE(_PR_HAVE_THREADSAFE_GETHOST)
+        fi
+    fi
+    ;;
+*-solaris*)
+    if test -n "$USE_NATIVE_THREADS"; then
+        AC_DEFINE(_PR_GLOBAL_THREADS_ONLY)
+    else
+        if test -n "$USE_NSPR_THREADS"; then
+            AC_DEFINE(_PR_LOCAL_THREADS_ONLY)
+        fi
+    fi
+    if test -z "$USE_NSPR_THREADS"; then
+        AC_DEFINE(_REENTRANT)
+        AC_DEFINE(HAVE_POINTER_LOCALTIME_R)
+        if test "$OS_TEST" = "i86pc"; then
+            if test -n "$USE_64"; then
+               PR_MD_ASFILES=os_SunOS_x86_64.s
+            else
+               PR_MD_ASFILES=os_SunOS_x86.s
+            fi
+        else
+            if test -n "$USE_64"; then
+                PR_MD_ASFILES=os_SunOS_sparcv9.s
+            fi
+            if test -n "$USE_NATIVE_THREADS"; then
+                PR_MD_ASFILES="$PR_MD_ASFILES os_SunOS.s"
+            fi
+        fi
+    fi
+    ;;
+*-nto*)
+    if test -n "$USE_PTHREADS"; then
+        AC_DEFINE(_PR_HAVE_GETHOST_R)
+        AC_DEFINE(_PR_HAVE_GETHOST_R_POINTER)
+    fi
+    ;;
+esac
+
+OS_LIBS="$_PTHREAD_LDFLAGS $OS_LIBS"
+
+dnl If the user passed in arg to --enable-optimize or --enable-debug,
+dnl make sure that we use it.
+if test -n "$_SAVE_OPTIMIZE_FLAGS"; then
+    _OPTIMIZE_FLAGS="$_SAVE_OPTIMIZE_FLAGS"
+fi
+
+if test -n "$_SAVE_DEBUG_FLAGS"; then
+    _DEBUG_FLAGS="$_SAVE_DEBUG_FLAGS"
+fi
+
+if test -n "$MOZ_OPTIMIZE"; then
+    CFLAGS="$CFLAGS $_OPTIMIZE_FLAGS"
+    CXXFLAGS="$CXXFLAGS $_OPTIMIZE_FLAGS"
+fi
+
+if test -n "$MOZ_DEBUG"; then
+    CFLAGS="$CFLAGS $_DEBUG_FLAGS"
+    CXXFLAGS="$CXXFLAGS $_DEBUG_FLAGS"
+fi
+
+if test -n "$MOZ_OPTIMIZE"; then
+    OBJDIR_TAG=_OPT
+else
+    OBJDIR_TAG=_DBG
+fi
+
+if test -n "$USE_64"; then
+    COMPILER_TAG=_64
+fi
+
+RELEASE_OBJDIR_NAME="${OS_CONFIG}${CPU_ARCH_TAG}${COMPILER_TAG}${IMPL_STRATEGY}${OBJDIR_TAG}.${OBJDIR_SUFFIX}"
+
+dnl ========================================================
+dnl Use cygwin wrapper for win32 builds, except MSYS/MinGW
+dnl ========================================================
+case "$target_os" in
+cygwin*|msvc*|mks*)
+    CC="\$(CYGWIN_WRAPPER) $CC"
+    CXX="\$(CYGWIN_WRAPPER) $CXX"
+    RC="\$(CYGWIN_WRAPPER) $RC"
+    ;;
+esac
+
+dnl ========================================================
+dnl Substitution of found variables.
+dnl ========================================================
+AC_SUBST(SHELL_OVERRIDE)
+
+AC_SUBST(MOZILLA_CLIENT)
+AC_SUBST(CC)
+AC_SUBST(CXX)
+AC_SUBST(CFLAGS)
+AC_SUBST(CXXFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(HOST_CC)
+AC_SUBST(HOST_CFLAGS)
+AC_SUBST(LDFLAGS)
+AC_SUBST(HOST_LDFLAGS)
+AC_SUBST(GNU_CC)
+AC_SUBST(GCC_USE_GNU_LD)
+AC_SUBST(MSC_VER)
+AC_SUBST(CROSS_COMPILE)
+
+AC_SUBST(MOZ_OPTIMIZE)
+
+AC_SUBST(USE_CPLUS)
+AC_SUBST(USE_IPV6)
+AC_SUBST(USE_N32)
+AC_SUBST(USE_64)
+AC_SUBST(OBJECT_MODE)
+AC_SUBST(GC_LEAK_DETECTOR)
+AC_SUBST(ENABLE_STRIP)
+
+AC_SUBST(USE_PTHREADS)
+AC_SUBST(USE_BTHREADS)
+AC_SUBST(USE_USER_PTHREADS)
+AC_SUBST(USE_NATIVE_THREADS)
+AC_SUBST(USE_NSPR_THREADS)
+
+AC_SUBST(LIBNSPR)
+AC_SUBST(LIBPLC)
+
+AC_SUBST(MOD_MAJOR_VERSION)
+AC_SUBST(MOD_MINOR_VERSION)
+AC_SUBST(MOD_PATCH_VERSION)
+AC_SUBST(NSPR_MODNAME)
+AC_SUBST(MDCPUCFG_H)
+AC_SUBST(PR_MD_CSRCS)
+AC_SUBST(PR_MD_ASFILES)
+AC_SUBST(PR_MD_ARCH_DIR)
+AC_SUBST(CPU_ARCH)
+
+AC_SUBST(OBJ_SUFFIX)
+AC_SUBST(LIB_SUFFIX)
+AC_SUBST(DLL_SUFFIX)
+AC_SUBST(ASM_SUFFIX)
+AC_SUBST(MKSHLIB)
+AC_SUBST(DSO_CFLAGS)
+AC_SUBST(DSO_LDOPTS)
+
+AC_SUBST(OS_TARGET)
+AC_SUBST(OS_ARCH)
+AC_SUBST(OS_RELEASE)
+AC_SUBST(OS_TEST)
+AC_SUBST(MACOSX_DEPLOYMENT_TARGET)
+
+AC_SUBST(DEFINES)
+AC_SUBST(DEFS)
+AC_SUBST(AR)
+AC_SUBST(AR_FLAGS)
+AC_SUBST(AS)
+AC_SUBST(ASFLAGS)
+AC_SUBST(LD)
+AC_SUBST(RANLIB)
+AC_SUBST(PERL)
+AC_SUBST(STRIP)
+AC_SUBST(FILTER)
+AC_SUBST(IMPLIB)
+
+AC_SUBST(OS_LIBS)
+AC_SUBST(RESOLVE_LINK_SYMBOLS)
+AC_SUBST(AIX_LINK_OPTS)
+AC_SUBST(NOSUCHFILE)
+AC_SUBST(MOZ_OBJFORMAT)
+AC_SUBST(ULTRASPARC_LIBRARY)
+
+AC_SUBST(OBJDIR)
+AC_SUBST(OBJDIR_NAME)
+AC_SUBST(RELEASE_OBJDIR_NAME)
+AC_SUBST(NSINSTALL)
+AC_SUBST(OPTIMIZER)
+AC_SUBST(RC)
+AC_SUBST(RCFLAGS)
+AC_SUBST(DLLFLAGS)
+AC_SUBST(EXEFLAGS)
+AC_SUBST(OS_DLLFLAGS)
+AC_SUBST(CYGWIN_WRAPPER)
+AC_SUBST(VISIBILITY_FLAGS)
+AC_SUBST(WRAP_SYSTEM_INCLUDES)
+AC_SUBST(MACOS_SDK_DIR)
+AC_SUBST(NEXT_ROOT)
+
+dnl ========================================================
+dnl Generate output files.
+dnl ========================================================
+MAKEFILES="
+Makefile 
+config/Makefile
+config/autoconf.mk
+config/nsprincl.mk
+config/nsprincl.sh
+config/nspr-config
+lib/Makefile 
+lib/ds/Makefile 
+lib/libc/Makefile 
+lib/libc/include/Makefile 
+lib/libc/src/Makefile 
+lib/tests/Makefile
+pkg/Makefile
+pkg/linux/Makefile
+pkg/solaris/Makefile
+pkg/solaris/SUNWpr/Makefile
+pkg/solaris/SUNWprd/Makefile
+pr/Makefile 
+pr/include/Makefile 
+pr/include/md/Makefile 
+pr/include/obsolete/Makefile 
+pr/include/private/Makefile 
+pr/src/Makefile 
+pr/src/io/Makefile 
+pr/src/linking/Makefile 
+pr/src/malloc/Makefile 
+pr/src/md/Makefile 
+pr/src/md/${PR_MD_ARCH_DIR}/Makefile 
+pr/src/memory/Makefile 
+pr/src/misc/Makefile 
+pr/src/threads/Makefile 
+pr/tests/Makefile 
+pr/tests/dll/Makefile 
+"
+
+dnl lib/tests/Makefile
+dnl pr/tests/w16gui/Makefile
+dnl tools/Makefile
+
+if test -z "$USE_PTHREADS" && test -z "$USE_BTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/threads/combined/Makefile"
+elif test -n "$USE_PTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/pthreads/Makefile"
+elif test -n "$USE_BTHREADS"; then
+    MAKEFILES="$MAKEFILES pr/src/bthreads/Makefile"
+fi
+
+if test -n "$USE_CPLUS"; then
+    MAKEFILES="$MAKEFILES pr/src/cplus/Makefile pr/src/cplus/tests/Makefile"
+fi
+
+AC_OUTPUT([$MAKEFILES], [chmod +x config/nspr-config])

Added: freeswitch/trunk/libs/js/nsprpub/include/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/include/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+D

Added: freeswitch/trunk/libs/js/nsprpub/include/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/include/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/include

Added: freeswitch/trunk/libs/js/nsprpub/include/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/include/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/lib/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3 @@
+/.cvsignore/1.2/Sat May 12 01:02:30 2001//
+/Makefile.in/1.9/Sun Apr 25 15:00:34 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+A D/ds////
+A D/libc////
+A D/msgc////
+A D/prstreams////
+A D/tests////

Added: freeswitch/trunk/libs/js/nsprpub/lib/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib

Added: freeswitch/trunk/libs/js/nsprpub/lib/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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)
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2 @@
+Makefile
+_pl_bld.h

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,13 @@
+/.cvsignore/1.3/Mon May 14 22:12:54 2001//
+/MANIFEST/1.6/Fri Jan 28 00:27:07 2000//
+/Makefile.in/1.35/Wed Jun  1 14:28:25 2005//
+/plarena.c/3.13/Fri Feb 11 18:16:31 2005//
+/plarena.h/3.6/Sun Oct 19 00:10:22 2003//
+/plarenas.h/3.6/Sun Apr 25 15:00:35 2004//
+/plds.def/1.5/Tue Mar  8 03:01:04 2005//
+/plds.rc/3.6/Sun Apr 25 15:00:35 2004//
+/plds_symvec.opt/1.2/Wed Jan 15 00:00:12 2003//
+/plhash.c/3.10/Sun Apr 25 15:00:35 2004//
+/plhash.h/3.9/Sun Apr 25 15:00:35 2004//
+/plvrsion.c/3.10/Sun Apr 25 15:00:35 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/ds

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/MANIFEST
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/MANIFEST	Mon Dec 18 10:53:47 2006
@@ -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

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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
+
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/plarena.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/plarena.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,432 @@
+/* -*- 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;
+    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 */
+
+    PR_ASSERT((nb & pool->mask) == 0);
+    
+    nb = (PRUword)PL_ARENA_ALIGN(pool, nb); /* force alignment */
+
+    /* 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 = arena_freelist, p = NULL; a != NULL ; p = a, a = a->next ) {
+            if ( a->base +nb <= a->limit )  {
+                if ( p == NULL )
+                    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;
+            /* 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;
+
+    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 */

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/plarena.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/plarena.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,213 @@
+/* -*- 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, nb); \
+        PRUword _p = _a->avail; \
+        PRUword _q = _p + _nb; \
+        if (_q > _a->limit) \
+            _p = (PRUword)PL_ArenaAllocate(pool, _nb); \
+        else \
+            _a->avail = _q; \
+        p = (void *)_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, incr); \
+        PRUword _p = _a->avail; \
+        PRUword _q = _p + _incr; \
+        if (_p == (PRUword)(p) + PL_ARENA_ALIGN(pool, size) && \
+            _q <= _a->limit) { \
+            _a->avail = _q; \
+            PL_ArenaCountInplaceGrowth(pool, size, incr); \
+        } else { \
+            p = PL_ArenaGrow(pool, p, size, incr); \
+        } \
+        PL_ArenaCountGrowth(pool, size, 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___ */

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/plarenas.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/plarenas.h	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+#if defined(PLARENAS_H)
+#else  /* defined(PLARENAS_H) */
+#define PLARENAS_H
+
+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 */

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/plds.def
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/plds.def	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,83 @@
+;+#
+;+# ***** 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) 2002-2003
+;+# 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 *****
+;+#
+;+# 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;

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/plds.rc
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/plds.rc	Mon Dec 18 10:53:47 2006
@@ -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

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/plds_symvec.opt
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/plds_symvec.opt	Mon Dec 18 10:53:47 2006
@@ -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)

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/plhash.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/plhash.c	Mon Dec 18 10:53:47 2006
@@ -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;
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/plhash.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/plhash.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,165 @@
+/* -*- 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"
+
+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___ */

Added: freeswitch/trunk/libs/js/nsprpub/lib/ds/plvrsion.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/ds/plvrsion.c	Mon Dec 18 10:53:47 2006
@@ -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 */
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4 @@
+/.cvsignore/1.2/Sat May 12 01:13:53 2001//
+/Makefile.in/1.8/Sun Apr 25 15:00:35 2004//
+/README/3.1/Sat Mar 28 03:36:48 1998//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2 @@
+A D/include////
+A D/src////

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/libc

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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)
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/README
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/README	Mon Dec 18 10:53:47 2006
@@ -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.
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,10 @@
+/.cvsignore/1.2/Sat May 12 01:14:37 2001//
+/MANIFEST/1.1/Thu Jun  4 22:50:18 1998//
+/Makefile.in/1.10/Sun Apr 25 15:00:35 2004//
+/README/3.1/Sat Mar 28 03:36:48 1998//
+/plbase64.h/3.5/Sun Apr 25 15:00:35 2004//
+/plerror.h/3.5/Sun Apr 25 15:00:35 2004//
+/plgetopt.h/3.5/Sun Apr 25 15:00:35 2004//
+/plresolv.h/3.6/Tue Nov 23 00:54:04 2004//
+/plstr.h/3.8/Thu Mar 17 02:24:01 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/libc/include

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/MANIFEST
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/MANIFEST	Mon Dec 18 10:53:47 2006
@@ -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

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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
+
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/README
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/README	Mon Dec 18 10:53:47 2006
@@ -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.
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plbase64.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plbase64.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,98 @@
+/* -*- 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"
+
+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 */

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plerror.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plerror.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,66 @@
+/* -*- 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"
+
+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 */

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plgetopt.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plgetopt.h	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+** File:          plgetopt.h
+** Description:   utilities to parse argc/argv
+*/
+
+#if defined(PLGETOPT_H_)
+#else
+#define PLGETOPT_H_
+
+#include "prtypes.h"
+
+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 */
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plresolv.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plresolv.h	Mon Dec 18 10:53:47 2006
@@ -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           /* berserk 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_ */

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plstr.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/include/plstr.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,470 @@
+/* -*- 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 at 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 consistency, 
+ *  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"
+
+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., its 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 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_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 */

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2 @@
+Makefile
+_pl_bld.h

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,22 @@
+/.cvsignore/1.3/Mon May 14 22:11:59 2001//
+/Makefile.in/1.31/Wed Jun  1 14:28:26 2005//
+/README/3.1/Sat Mar 28 03:36:50 1998//
+/base64.c/3.7/Sun Apr 25 15:00:36 2004//
+/plc.def/1.6/Tue Mar  8 03:01:04 2005//
+/plc.rc/3.6/Sun Apr 25 15:00:36 2004//
+/plc_symvec.opt/1.2/Wed Jan 15 00:00:14 2003//
+/plerror.c/3.7/Sun Apr 25 15:00:36 2004//
+/plgetopt.c/3.6/Sun Apr 25 15:00:36 2004//
+/plvrsion.c/3.14/Sun Apr 25 15:00:36 2004//
+/strcat.c/3.7/Sun May  2 06:07:59 2004//
+/strccmp.c/3.7/Sun Apr 25 15:00:36 2004//
+/strchr.c/3.7/Sun Apr 25 15:00:36 2004//
+/strcmp.c/3.6/Sun Apr 25 15:00:36 2004//
+/strcpy.c/3.8/Sun May  2 06:07:59 2004//
+/strcstr.c/3.6/Sun Apr 25 15:00:36 2004//
+/strdup.c/3.7/Sun May  2 06:07:59 2004//
+/strlen.c/3.7/Sun Apr 25 15:00:36 2004//
+/strpbrk.c/3.7/Sun Apr 25 15:00:36 2004//
+/strstr.c/3.9/Sun May  2 06:07:59 2004//
+/strtok.c/1.2/Sun Apr 25 15:00:36 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/libc/src

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/README
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/README	Mon Dec 18 10:53:47 2006
@@ -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.
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/base64.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/base64.c	Mon Dec 18 10:53:47 2006
@@ -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;
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plc.def
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plc.def	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,99 @@
+;+#
+;+# ***** 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) 2002-2003
+;+# 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 *****
+;+#
+;+# 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;

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plc.rc
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plc.rc	Mon Dec 18 10:53:47 2006
@@ -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

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plc_symvec.opt
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plc_symvec.opt	Mon Dec 18 10:53:47 2006
@@ -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)

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plerror.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plerror.c	Mon Dec 18 10:53:47 2006
@@ -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 */

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plgetopt.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plgetopt.c	Mon Dec 18 10:53:47 2006
@@ -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 */

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plvrsion.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/plvrsion.c	Mon Dec 18 10:53:47 2006
@@ -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 */
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcat.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcat.c	Mon Dec 18 10:53:47 2006
@@ -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;
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strccmp.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strccmp.c	Mon Dec 18 10:53:47 2006
@@ -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]);
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strchr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strchr.c	Mon Dec 18 10:53:47 2006
@@ -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;
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcmp.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcmp.c	Mon Dec 18 10:53:47 2006
@@ -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);
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcpy.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcpy.c	Mon Dec 18 10:53:47 2006
@@ -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;
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcstr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strcstr.c	Mon Dec 18 10:53:47 2006
@@ -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;
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strdup.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strdup.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,85 @@
+/* -*- 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>
+
+PR_IMPLEMENT(char *)
+PL_strdup(const char *s)
+{
+    char *rv;
+    size_t n;
+
+    if( (const char *)0 == s )
+        s = "";
+
+    n = strlen(s) + 1;
+
+    rv = (char *)malloc(n);
+    if( (char *)0 == rv ) return rv;
+
+    (void)memcpy(rv, s, n);
+
+    return rv;
+}
+
+PR_IMPLEMENT(void)
+PL_strfree(char *s)
+{
+    free(s);
+}
+
+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);
+
+    rv = (char *)malloc(l+1);
+    if( (char *)0 == rv ) return rv;
+
+    (void)memcpy(rv, s, l);
+    rv[l] = '\0';
+
+    return rv;
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strlen.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strlen.c	Mon Dec 18 10:53:47 2006
@@ -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);
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strpbrk.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strpbrk.c	Mon Dec 18 10:53:47 2006
@@ -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;
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strstr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strstr.c	Mon Dec 18 10:53:47 2006
@@ -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;
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strtok.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/libc/src/strtok.c	Mon Dec 18 10:53:47 2006
@@ -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 at 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;
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3 @@
+/.cvsignore/1.2/Sat May 12 06:14:33 2001//
+/Makefile.in/1.8/Sun Apr 25 15:00:36 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3 @@
+A D/include////
+A D/src////
+A D/tests////

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/msgc

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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)
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,6 @@
+/.cvsignore/1.2/Sat May 12 06:15:53 2001//
+/MANIFEST/1.1/Thu Jun  4 22:48:12 1998//
+/Makefile.in/1.10/Sun Apr 25 15:00:36 2004//
+/gcint.h/3.6/Sun Apr 25 15:00:36 2004//
+/prgc.h/3.7/Tue Nov 23 00:54:05 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/msgc/include

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/MANIFEST
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/MANIFEST	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+#
+# This is a list of local files which get copied to the mozilla:dist directory
+#
+
+prgc.h

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/gcint.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/gcint.h	Mon Dec 18 10:53:47 2006
@@ -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___ */

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/prgc.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/include/prgc.h	Mon Dec 18 10:53:47 2006
@@ -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 synchronization 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;       /* highest 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___ */

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,10 @@
+/.cvsignore/1.2/Sat May 12 06:22:03 2001//
+/Makefile.in/1.13/Wed Jun  1 14:28:27 2005//
+/macgc.c/3.5/Sun Apr 25 15:00:36 2004//
+/os2gc.c/3.6/Sun Apr 25 15:00:36 2004//
+/prgcapi.c/3.6/Sun Apr 25 15:00:36 2004//
+/prmsgc.c/3.10/Mon Nov  7 22:39:00 2005//
+/unixgc.c/3.6/Sun Apr 25 15:00:36 2004//
+/win16gc.c/3.5/Sun Apr 25 15:00:36 2004//
+/win32gc.c/3.5/Sun Apr 25 15:00:36 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/msgc/src

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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	
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/macgc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/macgc.c	Mon Dec 18 10:53:47 2006
@@ -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);
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/os2gc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/os2gc.c	Mon Dec 18 10:53:47 2006
@@ -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);
+   }
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/prgcapi.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/prgcapi.c	Mon Dec 18 10:53:47 2006
@@ -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 */
+}
+
+/******************************************************************************/

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/prmsgc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/prmsgc.c	Mon Dec 18 10:53:47 2006
@@ -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_GetCurrentThread()) < 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");
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/unixgc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/unixgc.c	Mon Dec 18 10:53:47 2006
@@ -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);
+	}
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/win16gc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/win16gc.c	Mon Dec 18 10:53:47 2006
@@ -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;
+}
+
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/win32gc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/src/win32gc.c	Mon Dec 18 10:53:47 2006
@@ -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);
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+/.cvsignore/1.2/Sat May 12 06:26:43 2001//
+/Makefile.in/1.13/Wed Nov 23 06:35:19 2005//
+/gc1.c/3.6/Sun Apr 25 15:00:45 2004//
+/thrashgc.c/3.5/Sun Apr 25 15:00:45 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/msgc/tests

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,314 @@
+# 
+# ***** 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 -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)
+clean::
+	rm -f $(TARGETS)

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/gc1.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/gc1.c	Mon Dec 18 10:53:47 2006
@@ -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;
+	}
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/thrashgc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/msgc/tests/thrashgc.c	Mon Dec 18 10:53:47 2006
@@ -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;
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,7 @@
+/.cvsignore/1.2/Sat May 12 06:36:32 2001//
+/Makefile.in/1.21/Wed Jun  1 14:28:27 2005//
+/plvrsion.c/3.10/Sun Apr 25 15:00:45 2004//
+/prstrms.cpp/3.10/Sun Apr 25 15:00:45 2004//
+/prstrms.h/3.6/Sun Apr 25 15:00:45 2004//
+/prstrms.rc/3.6/Sun Apr 25 15:00:45 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+A D/tests////

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/prstreams

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/plvrsion.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/plvrsion.c	Mon Dec 18 10:53:47 2006
@@ -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 */
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/prstrms.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/prstrms.cpp	Mon Dec 18 10:53:47 2006
@@ -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

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/prstrms.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/prstrms.h	Mon Dec 18 10:53:47 2006
@@ -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 */

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/prstrms.rc
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/prstrms.rc	Mon Dec 18 10:53:47 2006
@@ -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

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+A D/testprstrm////

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/prstreams/tests

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4 @@
+/.cvsignore/1.2/Sat May 12 06:40:34 2001//
+/Makefile.in/1.10/Mon Nov  8 02:52:55 2004//
+/testprstrm.cpp/3.6/Sun Apr 25 15:00:45 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/prstreams/tests/testprstrm

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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 -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)

Added: freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/prstreams/tests/testprstrm/testprstrm.cpp	Mon Dec 18 10:53:47 2006
@@ -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;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,6 @@
+/.cvsignore/1.2/Sat May 12 01:31:18 2001//
+/Makefile.in/1.14/Mon Nov  8 02:52:55 2004//
+/arena.c/3.7/Sun Apr 25 15:00:46 2004//
+/base64t.c/3.5/Sun Apr 25 15:00:46 2004//
+/string.c/3.8/Sun Apr 25 15:00:46 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+A D/windows////

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/tests

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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 -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)
+
+
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/arena.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/arena.c	Mon Dec 18 10:53:47 2006
@@ -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 */

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/base64t.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/base64t.c	Mon Dec 18 10:53:47 2006
@@ -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*/
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/string.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/string.c	Mon Dec 18 10:53:47 2006
@@ -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*/
+}

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4 @@
+/makefile/1.9/Wed Nov 23 06:35:20 2005//
+/readme.1st/1.1/Tue Feb 23 23:09:10 1999//
+/winevent.c/1.6/Sun Apr 25 15:00:46 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/lib/tests/windows

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/makefile
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/makefile	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,84 @@
+# 
+# ***** 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 = ../../..
+
+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 -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 -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)
+
+clean::
+	rm -rf $(TARGETS)

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/readme.1st
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/readme.1st	Mon Dec 18 10:53:47 2006
@@ -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.
+

Added: freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/winevent.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/lib/tests/windows/winevent.c	Mon Dec 18 10:53:47 2006
@@ -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;
+}    

Added: freeswitch/trunk/libs/js/nsprpub/macbuild/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/macbuild/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+D

Added: freeswitch/trunk/libs/js/nsprpub/macbuild/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/macbuild/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/macbuild

Added: freeswitch/trunk/libs/js/nsprpub/macbuild/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/macbuild/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2 @@
+/Makefile.in/1.3/Fri Feb 25 20:20:51 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2 @@
+A D/linux////
+A D/solaris////

Added: freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg

Added: freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,61 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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
+
+DIRS = 
+ifeq ($(OS_TARGET),Linux)
+DIRS = linux
+endif
+ifeq ($(OS_TARGET),SunOS)
+DIRS = solaris
+endif
+
+publish::
+	+$(LOOP_OVER_DIRS)
+
+include $(topsrcdir)/config/rules.mk

Added: freeswitch/trunk/libs/js/nsprpub/pkg/linux/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/linux/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3 @@
+/Makefile.in/1.10/Fri Nov 18 21:50:20 2005//
+/sun-nspr.spec/1.6/Fri Sep  9 17:16:35 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/linux/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/linux/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg/linux

Added: freeswitch/trunk/libs/js/nsprpub/pkg/linux/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/linux/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/linux/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/linux/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,111 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: Makefile.in,v 1.10 2005/11/18 21:50:20 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MOD_DEPTH = ../..
+topsrcdir   = @top_srcdir@
+srcdir	    = @srcdir@
+VPATH	    = @srcdir@
+
+NAME        = sun-nspr
+ifndef RPM_RELEASE
+RPM_RELEASE = 1
+endif
+TOPDIR      = /usr/src/redhat
+VERSION     = `grep PR_VERSION $(dist_includedir)/prinit.h \
+                  | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//'`
+
+SPECFILE    = $(NAME).spec
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+# Force i386 for non 64 bit build
+ifneq ($(USE_64),1)
+	RPMTARGET = "--target=i386"
+	RPMLIBDIR = lib
+else
+	RPMLIBDIR = lib64
+endif
+
+publish:
+	$(MAKE) clean
+	mkdir -p SOURCES SRPMS RPMS BUILD
+	(cd $(dist_libdir) && tar cphf - libnspr4.so libplds4.so libplc4.so) \
+	| (mkdir -p opt/sun/private/$(RPMLIBDIR) && cd opt/sun/private/$(RPMLIBDIR) && tar xvfBp -)
+	(cd $(dist_includedir) && tar cphf - .) \
+	| (mkdir -p opt/sun/private/include/nspr && cd opt/sun/private/include/nspr && tar xvfBp -)
+	(cd opt/sun/private/include/nspr && \
+		rm -rf md private obsolete/pralarm.h obsolete/probslet.h obsolete/prsem.h)
+	tar czvf SOURCES/$(NAME)-$(VERSION).tar.gz opt
+	echo "%define name $(NAME)" >$(SPECFILE)
+	echo "%define version $(VERSION)" >>$(SPECFILE)
+	echo "%define release $(RPM_RELEASE)" >>$(SPECFILE)
+	echo "%define buildroot `pwd`/$(NAME)-root" >>$(SPECFILE)
+	echo "%define _topdir `pwd`" >>$(SPECFILE)
+	echo "%define _unpackaged_files_terminate_build 0" >>$(SPECFILE)
+	cat $(srcdir)/$(NAME).spec >>$(SPECFILE)
+	echo "" >>$(SPECFILE)
+	echo "%files" >>$(SPECFILE)
+	echo "%defattr(-,root,root)" >>$(SPECFILE)
+	echo "%dir /opt" >>$(SPECFILE)
+	echo "%dir /opt/sun" >>$(SPECFILE)
+	echo "%dir /opt/sun/private" >>$(SPECFILE)
+	echo "%dir /opt/sun/private/$(RPMLIBDIR)" >>$(SPECFILE)
+	find opt \( -name "*.so" \) | sed -e "s-^-/-" >>$(SPECFILE)
+	echo "" >>$(SPECFILE)
+	echo "%files devel" >>$(SPECFILE)
+	echo "%defattr(-,root,root)" >>$(SPECFILE)
+	echo "%dir /opt" >>$(SPECFILE)
+	echo "%dir /opt/sun" >>$(SPECFILE)
+	echo "%dir /opt/sun/private" >>$(SPECFILE)
+	echo "%dir /opt/sun/private/include" >>$(SPECFILE)
+	echo "%dir /opt/sun/private/include/nspr" >>$(SPECFILE)
+	echo "%dir /opt/sun/private/include/nspr/obsolete" >>$(SPECFILE)
+	find opt -type f \( -name "*.h" \) \
+		| sed -e "s-^-/-" >>$(SPECFILE)
+	rpmbuild $(RPMTARGET) -bb $(SPECFILE)
+
+clean:
+	rm -rf $(TOPDIR)/BUILD/$(NAME)
+	rm -rf SOURCES SRPMS RPMS BUILD
+	rm -rf RPMS SRPMS opt
+	rm -f $(NAME)-$(VERSION).tar.gz

Added: freeswitch/trunk/libs/js/nsprpub/pkg/linux/sun-nspr.spec
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/linux/sun-nspr.spec	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,81 @@
+Summary: Netscape Portable Runtime
+Name: %{name}
+Vendor: Sun Microsystems, Inc.
+Version: %{version}
+Release: %{release}
+Copyright: Copyright 2005 Sun Microsystems, Inc.  All rights reserved.  Use is subject to license terms.  Also under other license(s) as shown at the Description field.
+Distribution: Sun Java(TM) Enterprise System
+URL: http://www.sun.com
+Group: System Environment/Base
+Source: %{name}-%{version}.tar.gz
+ExclusiveOS: Linux
+BuildRoot: /var/tmp/%{name}-root
+        
+%description
+
+NSPR provides platform independence for non-GUI operating system
+facilities. These facilities include threads, thread synchronization,
+normal file and network I/O, interval timing and calendar time, basic
+memory management (malloc and free) and shared library linking. 
+
+See: http://www.mozilla.org/projects/nspr/about-nspr.html
+
+***** 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 security libraries.
+
+The Initial Developer of the Original Code is
+Netscape Communications Corporation.
+Portions created by the Initial Developer are Copyright (C) 1994-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 *****
+
+%package devel
+Summary: Development Libraries for the Netscape Portable Runtime
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Header files for doing development with the Netscape Portable Runtime.
+
+Under "MPL/GPL" license.
+
+%prep
+%setup -c
+
+%build
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir $RPM_BUILD_ROOT
+cd $RPM_BUILD_ROOT
+tar xvzf $RPM_SOURCE_DIR/%{name}-%{version}.tar.gz
+
+%clean
+rm -rf $RPM_BUILD_ROOT

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,8 @@
+/Makefile-devl.com/1.3/Fri Feb 25 20:20:52 2005//
+/Makefile-devl.targ/1.3/Fri Feb 25 20:20:52 2005//
+/Makefile.com/1.8/Fri Feb 25 20:20:52 2005//
+/Makefile.in/1.3/Fri Feb 25 20:20:52 2005//
+/Makefile.targ/1.6/Fri Feb 25 20:20:52 2005//
+/bld_awk_pkginfo.ksh/1.3/Fri Feb 25 20:20:52 2005//
+/proto64.mk/1.3/Fri Feb 25 20:20:52 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,9 @@
+A D/SUNWnspr////
+A D/SUNWnsprx////
+A D/SUNWpr////
+A D/SUNWpr-devl////
+A D/SUNWprd////
+A D/SUNWprdx////
+A D/SUNWprx////
+A D/SUNWprx-devl////
+A D/common_files////

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg/solaris

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile-devl.com
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile-devl.com	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,66 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: Makefile-devl.com,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MACH = $(shell mach)
+
+PUBLISH_ROOT = $(DIST)
+ifeq ($(MOD_DEPTH),../..)
+ROOT = ROOT
+else
+ROOT = $(subst ../../,,$(MOD_DEPTH))/ROOT
+endif
+
+PKGARCHIVE = $(dist_prefix)/pkgarchive
+DATAFILES = copyright
+FILES = $(DATAFILES) pkginfo
+
+PACKAGE = $(shell basename `pwd`)
+
+PRODUCT_VERSION = "$(MOD_VERSION).$(MOD_MINOR).$(MOD_PATCH)$(MOD_BETA)"
+LN = /usr/bin/ln
+
+CLOBBERFILES = $(FILES)
+
+include $(topsrcdir)/config/rules.mk
+
+# vim: ft=make

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile-devl.targ
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile-devl.targ	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,66 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: Makefile-devl.targ,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+include $(srcdir)/../proto64.mk
+
+pkginfo: pkginfo.tmpl ../awk_pkginfo
+	$(RM) $@; nawk -f ../awk_pkginfo $(srcdir)/$@.tmpl > $@
+
+pkg: $(PKGARCHIVE)
+	cat $(srcdir)/prototype | sed $(sed_proto64) > prototype
+	cp $(srcdir)/depend .
+	pkgmk -f prototype -d $(PKGARCHIVE) -r $(ROOT) -o $(PACKAGE)
+
+$(PKGARCHIVE):
+	[ -d $(PKGARCHIVE) ] || mkdir -p $(PKGARCHIVE)
+
+$(DATAFILES): %: $(srcdir)/../common_files/%
+	$(RM) $@; cp $(srcdir)/../common_files/$@ $@
+
+$(MACHDATAFILES): %: $(srcdir)/../common_files/%_$(MACH)
+	$(RM) $@; cp $(srcdir)/../common_files/$@_$(MACH) $@
+
+clobber clean::
+	-$(RM) $(CLOBBERFILES) $(CLEANFILES)
+
+.PHONY: pkg

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile.com
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile.com	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,69 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: Makefile.com,v 1.8 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MACH = $(shell mach)
+
+PUBLISH_ROOT = $(DIST)
+ifeq ($(MOD_DEPTH),../..)
+ROOT = ROOT
+else
+ROOT = $(subst ../../,,$(MOD_DEPTH))/ROOT
+endif
+
+PKGARCHIVE = $(dist_prefix)/pkgarchive
+DATAFILES = copyright
+FILES = $(DATAFILES) pkginfo
+
+PACKAGE = $(shell basename `pwd`)
+
+PRODUCT_VERSION = $(shell grep PR_VERSION $(dist_includedir)/prinit.h \
+		   | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//')
+
+LN = /usr/bin/ln
+CP = /usr/bin/cp
+
+CLOBBERFILES = $(FILES)
+
+include $(topsrcdir)/config/rules.mk
+
+# vim: ft=make

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,121 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: Makefile.in,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MOD_DEPTH = ../..
+topsrcdir   = @top_srcdir@
+srcdir	    = @srcdir@
+VPATH	    = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+abs_dist_libdir := $(shell (cd $(dist_libdir);pwd))
+abs_dist_includedir := $(shell (cd $(dist_includedir);pwd))
+
+%: %.ksh
+	$(RM) $@
+	cp $< $@
+	chmod +x $@
+
+DIRS = \
+	SUNWpr \
+	SUNWprd
+
+include $(srcdir)/Makefile.com
+
+PROTO = \
+	$(ROOT) \
+	$(ROOT)/usr/lib/mps \
+	$(ROOT)/usr/include/mps
+
+ifeq ($(MACH), sparc)
+	PROTO += $(ROOT)/usr/lib/mps/cpu/sparcv8plus
+endif
+
+ifeq ($(USE_64), 1)
+ifeq ($(MACH), sparc)
+# Sparc
+	PROTO += $(ROOT)/usr/lib/mps/sparcv9
+else
+# AMD64
+	PROTO += $(ROOT)/usr/lib/mps/amd64
+endif
+	abs_dist64_libdir = $(abs_dist_libdir)
+	abs_dist32_libdir = $(shell echo $(abs_dist_libdir) | sed -e "s|_64_OPT|_OPT|g" -e "s|_64_DBG|_DBG|g")
+	abs_dist64_includedir = $(abs_dist_includedir)
+	abs_dist32_includedir = $(shell echo $(abs_dist_includedir) | sed -e "s|_64_OPT|_OPT|g" -e "s|_64_DBG|_DBG|g")
+else
+	abs_dist32_libdir = $(abs_dist_libdir)
+	abs_dist64_libdir = $(shell echo $(abs_dist_libdir) | sed -e "s|_OPT|_64_OPT|g" -e "s|_DBG|_64_DBG|g")
+	abs_dist32_includedir = $(abs_dist_includedir)
+	abs_dist64_includedir = $(shell echo $(abs_dist_includedir) | sed -e "s|_OPT|_64_OPT|g" -e "s|_DBG|_64_DBG|g")
+endif
+
+awk_pkginfo: bld_awk_pkginfo
+	./bld_awk_pkginfo -m $(MACH) -p "$(PRODUCT_VERSION)" -o $@ -v $(PRODUCT_VERSION)
+
+all:: awk_pkginfo $(PROTO)
+publish: awk_pkginfo $(PROTO)
+	+$(LOOP_OVER_DIRS)
+
+clean clobber::
+	$(RM) awk_pkginfo bld_awk_pkginfo
+	$(RM) -r $(ROOT)
+
+$(ROOT):
+	mkdir -p $@
+
+$(ROOT)/usr/lib/mps/sparcv9:
+	mkdir -p $@
+	$(CP) -r $(abs_dist64_libdir)/*.so $@
+$(ROOT)/usr/lib/mps/amd64:
+	mkdir -p $@
+	$(CP) -r $(abs_dist64_libdir)/*.so $@
+$(ROOT)/usr/lib/mps:
+	mkdir -p $@
+	$(CP) -r $(abs_dist32_libdir)/*.so $@
+$(ROOT)/usr/lib/mps/cpu/sparcv8plus:
+	mkdir -p $@
+	$(CP) -r $(abs_dist32_libdir)/cpu/sparcv8plus/*.so $@
+$(ROOT)/usr/include/mps:
+	mkdir -p $@
+	$(CP) -r $(abs_dist32_includedir)/* $@

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile.targ
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/Makefile.targ	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,64 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: Makefile.targ,v 1.6 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+include $(srcdir)/../proto64.mk
+
+pkginfo: pkginfo.tmpl ../awk_pkginfo
+	$(RM) $@; nawk -f ../awk_pkginfo $< > $@
+
+pkg: $(PKGARCHIVE) prototype_$(MACH)
+	cp $(srcdir)/prototype_com .
+	cat $(srcdir)/prototype_$(MACH) | sed $(sed_proto64) > prototype_$(MACH)
+	cp $(srcdir)/depend .
+	pkgmk -f prototype_$(MACH) -d $(PKGARCHIVE) -r $(ROOT) -o $(PACKAGE)
+
+$(PKGARCHIVE):
+	[ -d $(PKGARCHIVE) ] || mkdir -p $(PKGARCHIVE)
+
+$(DATAFILES): %: $(srcdir)/../common_files/%
+	$(RM) $@; cp $(srcdir)/../common_files/$@ $@
+
+clobber clean::
+	-$(RM) $(CLOBBERFILES) $(CLEANFILES)
+
+.PHONY: pkg

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnspr/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnspr/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnspr/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnspr/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg/solaris/SUNWnspr

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnspr/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnspr/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnsprx/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnsprx/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnsprx/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnsprx/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg/solaris/SUNWnsprx

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnsprx/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWnsprx/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr-devl/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr-devl/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr-devl/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr-devl/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg/solaris/SUNWpr-devl

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr-devl/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr-devl/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,7 @@
+/Makefile.in/1.2/Fri Feb 25 20:20:52 2005//
+/depend/1.3/Fri Feb 25 20:20:52 2005//
+/pkginfo.tmpl/1.3/Fri Feb 25 20:20:52 2005//
+/prototype_com/1.4/Fri Feb 25 20:20:52 2005//
+/prototype_i386/1.4/Fri Feb 25 20:20:52 2005//
+/prototype_sparc/1.4/Fri Feb 25 20:20:52 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg/solaris/SUNWpr

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,58 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: Makefile.in,v 1.2 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MOD_DEPTH = ../../..
+topsrcdir   = @top_srcdir@
+srcdir	    = @srcdir@
+VPATH	    = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(srcdir)/../Makefile.com
+
+DATAFILES += 
+
+all:: $(FILES)
+publish:: all pkg
+
+include $(srcdir)/../Makefile.targ

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/depend
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/depend	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,64 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#	$Id: depend,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $
+#
+# This package information file defines software dependencies associated
+# with the pkg.  You can define three types of pkg dependencies with this file:
+#	 P indicates a prerequisite for installation
+#	 I indicates an incompatible package
+#	 R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# 	(<arch>)<version>
+# 	(<arch>)<version>
+# 	...
+# <type> <pkg.abbr> <name>
+# ...
+
+P SUNWcar	Core Architecture, (Root)
+P SUNWkvm	Core Architecture, (Kvm)
+P SUNWcsr	Core Solaris, (Root)
+P SUNWcsu	Core Solaris, (Usr)
+P SUNWcsd	Core Solaris Devices
+P SUNWcsl	Core Solaris Libraries

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/pkginfo.tmpl	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,70 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: pkginfo.tmpl,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWpr"
+NAME="Netscape Portable Runtime"
+ARCH="ISA"
+VERSION="NSPRVERS,REV=0.0.0"
+SUNW_PRODNAME="Netscape Portable Runtime"
+SUNW_PRODVERS="NSPRVERS"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Netscape Portable Runtime Interface"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/prototype_com
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/prototype_com	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,71 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: prototype_com,v 1.4 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>	# where to find pkg objects
+#!include <filename>			# include another 'prototype' file
+#!default <mode> <owner> <group>	# default used if not specified on entry
+#!<param>=<value>			# puts parameter in pkg environment
+
+# packaging files
+i copyright
+i pkginfo
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWpr
+#
+d none usr 755 root sys
+d none usr/lib 755 root bin
+d none usr/lib/mps 755 root bin
+d none usr/lib/mps/secv1 755 root bin
+f none usr/lib/mps/libnspr4.so 755 root bin
+f none usr/lib/mps/libplc4.so 755 root bin
+f none usr/lib/mps/libplds4.so 755 root bin
+s none usr/lib/mps/secv1/libnspr4.so=../libnspr4.so
+s none usr/lib/mps/secv1/libplc4.so=../libplc4.so
+s none usr/lib/mps/secv1/libplds4.so=../libplds4.so

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/prototype_i386
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/prototype_i386	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,77 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: prototype_i386,v 1.4 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>	# where to find pkg objects
+#!include <filename>			# include another 'prototype' file
+#!default <mode> <owner> <group>	# default used if not specified on entry
+#!<param>=<value>			# puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are i386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpr
+#
+#64#s none usr/lib/mps/64=amd64
+#64#s none usr/lib/mps/secv1/64=amd64
+#64#d none usr/lib/mps/amd64 755 root bin
+#64#d none usr/lib/mps/secv1/amd64 755 root bin
+#64#f none usr/lib/mps/amd64/libnspr4.so 755 root bin
+#64#f none usr/lib/mps/amd64/libplc4.so 755 root bin
+#64#f none usr/lib/mps/amd64/libplds4.so 755 root bin
+#64#s none usr/lib/mps/secv1/amd64/libnspr4.so=../../amd64/libnspr4.so
+#64#s none usr/lib/mps/secv1/amd64/libplc4.so=../../amd64/libplc4.so
+#64#s none usr/lib/mps/secv1/amd64/libplds4.so=../../amd64/libplds4.so
+

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/prototype_sparc
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWpr/prototype_sparc	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,83 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: prototype_sparc,v 1.4 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>	# where to find pkg objects
+#!include <filename>			# include another 'prototype' file
+#!default <mode> <owner> <group>	# default used if not specified on entry
+#!<param>=<value>			# puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWpr
+#
+d none usr/lib/mps/cpu 755 root bin
+d none usr/lib/mps/cpu/sparcv8plus 755 root bin
+d none usr/lib/mps/secv1/cpu 755 root bin
+d none usr/lib/mps/secv1/cpu/sparcv8plus 755 root bin
+f none usr/lib/mps/cpu/sparcv8plus/libnspr_flt4.so 755 root bin
+s none usr/lib/mps/secv1/cpu/sparcv8plus/libnspr_flt4.so=../../../cpu/sparcv8plus/libnspr_flt4.so
+#64#s none usr/lib/mps/64=sparcv9
+#64#s none usr/lib/mps/secv1/64=sparcv9
+#64#d none usr/lib/mps/sparcv9 755 root bin
+#64#d none usr/lib/mps/secv1/sparcv9 755 root bin
+#64#f none usr/lib/mps/sparcv9/libnspr4.so 755 root bin
+#64#f none usr/lib/mps/sparcv9/libplc4.so 755 root bin
+#64#f none usr/lib/mps/sparcv9/libplds4.so 755 root bin
+#64#s none usr/lib/mps/secv1/sparcv9/libnspr4.so=../../sparcv9/libnspr4.so
+#64#s none usr/lib/mps/secv1/sparcv9/libplc4.so=../../sparcv9/libplc4.so
+#64#s none usr/lib/mps/secv1/sparcv9/libplds4.so=../../sparcv9/libplds4.so
+

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+/Makefile.in/1.3/Fri Feb 25 20:20:52 2005//
+/depend/1.3/Fri Feb 25 20:20:52 2005//
+/pkginfo.tmpl/1.3/Fri Feb 25 20:20:52 2005//
+/prototype/1.3/Fri Feb 25 20:20:52 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg/solaris/SUNWprd

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,58 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: Makefile.in,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+MOD_DEPTH = ../../..
+topsrcdir   = @top_srcdir@
+srcdir      = @srcdir@
+VPATH       = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(srcdir)/../Makefile-devl.com
+
+DATAFILES += 
+
+all:: $(FILES)
+publish:: all pkg
+
+include $(srcdir)/../Makefile-devl.targ

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/depend
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/depend	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,59 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#	$Id: depend,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $
+#
+# This package information file defines software dependencies associated
+# with the pkg.  You can define three types of pkg dependencies with this file:
+#	 P indicates a prerequisite for installation
+#	 I indicates an incompatible package
+#	 R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# 	(<arch>)<version>
+# 	(<arch>)<version>
+# 	...
+# <type> <pkg.abbr> <name>
+# ...
+
+P SUNWpr	Netscape Portable Runtime

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/pkginfo.tmpl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/pkginfo.tmpl	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,70 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: pkginfo.tmpl,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWprd"
+NAME="Netscape Portable Runtime Development"
+ARCH="ISA"
+VERSION="NSPRVERS,REV=0.0.0"
+SUNW_PRODNAME="Netscape Portable Runtime Development"
+SUNW_PRODVERS="NSPRVERS"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Netscape Portable Runtime Interface Files for Development"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/prototype
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprd/prototype	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,114 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# 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 *****
+#
+#ident  "$Id: prototype,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...>        # where to find pkg objects
+#!include <filename>                    # include another 'prototype' file
+#!default <mode> <owner> <group>        # default used if not specified on entry
+#!<param>=<value>                       # puts parameter in pkg environment
+
+# packaging files
+i copyright
+i pkginfo
+i depend
+#
+# source locations relative to .h 0644 root bine prototype file
+#
+# SUNWprd
+#
+d none usr 0755 root sys
+d none usr/include 0755 root bin
+d none usr/include/mps 0755 root bin
+d none usr/include/mps/obsolete 0755 root bin
+f none usr/include/mps/obsolete/protypes.h 0644 root bin
+f none usr/include/mps/prcpucfg.h 0644 root bin
+f none usr/include/mps/nspr.h 0644 root bin
+f none usr/include/mps/pratom.h 0644 root bin
+f none usr/include/mps/prbit.h 0644 root bin
+f none usr/include/mps/prclist.h 0644 root bin
+f none usr/include/mps/prcmon.h 0644 root bin
+f none usr/include/mps/prcountr.h 0644 root bin
+f none usr/include/mps/prcvar.h 0644 root bin
+f none usr/include/mps/prdtoa.h 0644 root bin
+f none usr/include/mps/prenv.h 0644 root bin
+f none usr/include/mps/prerr.h 0644 root bin
+f none usr/include/mps/prerror.h 0644 root bin
+f none usr/include/mps/prinet.h 0644 root bin
+f none usr/include/mps/prinit.h 0644 root bin
+f none usr/include/mps/prinrval.h 0644 root bin
+f none usr/include/mps/prio.h 0644 root bin
+f none usr/include/mps/pripcsem.h 0644 root bin
+f none usr/include/mps/prlink.h 0644 root bin
+f none usr/include/mps/prlock.h 0644 root bin
+f none usr/include/mps/prlog.h 0644 root bin
+f none usr/include/mps/prlong.h 0644 root bin
+f none usr/include/mps/prmem.h 0644 root bin
+f none usr/include/mps/prmon.h 0644 root bin
+f none usr/include/mps/prmwait.h 0644 root bin
+f none usr/include/mps/prnetdb.h 0644 root bin
+f none usr/include/mps/prolock.h 0644 root bin
+f none usr/include/mps/prpdce.h 0644 root bin
+f none usr/include/mps/prprf.h 0644 root bin
+f none usr/include/mps/prproces.h 0644 root bin
+f none usr/include/mps/prrng.h 0644 root bin
+f none usr/include/mps/prrwlock.h 0644 root bin
+f none usr/include/mps/prshm.h 0644 root bin
+f none usr/include/mps/prshma.h 0644 root bin
+f none usr/include/mps/prsystem.h 0644 root bin
+f none usr/include/mps/prthread.h 0644 root bin
+f none usr/include/mps/prtime.h 0644 root bin
+f none usr/include/mps/prtpool.h 0644 root bin
+f none usr/include/mps/prtrace.h 0644 root bin
+f none usr/include/mps/prtypes.h 0644 root bin
+f none usr/include/mps/prvrsion.h 0644 root bin
+f none usr/include/mps/prwin16.h 0644 root bin
+f none usr/include/mps/plarenas.h 0644 root bin
+f none usr/include/mps/plarena.h 0644 root bin
+f none usr/include/mps/plbase64.h 0644 root bin
+f none usr/include/mps/plerror.h 0644 root bin
+f none usr/include/mps/plgetopt.h 0644 root bin
+f none usr/include/mps/plhash.h 0644 root bin
+f none usr/include/mps/plresolv.h 0644 root bin
+f none usr/include/mps/plstr.h 0644 root bin

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprdx/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprdx/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprdx/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprdx/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg/solaris/SUNWprdx

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprdx/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprdx/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx-devl/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx-devl/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx-devl/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx-devl/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg/solaris/SUNWprx-devl

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx-devl/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx-devl/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg/solaris/SUNWprx

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/SUNWprx/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/bld_awk_pkginfo.ksh	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,141 @@
+#!/usr/bin/ksh -p
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident	"$Id: bld_awk_pkginfo.ksh,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+# Simple script which builds the awk_pkginfo awk script.  This awk script
+# is used to convert the pkginfo.tmpl files into pkginfo files
+# for the build.
+#
+
+usage()
+{
+   cat <<-EOF
+usage: bld_awk_pkginfo -p <prodver> -m <mach> -o <awk_script> [-v <version>]
+EOF
+}
+
+#
+# Awk strings
+#
+# two VERSION patterns: one for Dewey decimal, one for Dewey plus ,REV=n
+# the first has one '=' the second has two or more '='
+#
+VERSION1="VERSION=[^=]*$"
+VERSION2="VERSION=[^=]*=.*$"
+PRODVERS="^SUNW_PRODVERS="
+ARCH='ARCH=\"ISA\"'
+
+#
+# parse command line
+#
+mach=""
+prodver=""
+awk_script=""
+version="NSPRVERS"
+
+while getopts o:p:m:v: c
+do
+   case $c in
+   o)
+      awk_script=$OPTARG
+      ;;
+   m)
+      mach=$OPTARG
+      ;;
+   p)
+      prodver=$OPTARG
+      ;;
+   v)
+      version=$OPTARG
+      ;;
+   \?)
+      usage
+      exit 1
+      ;;
+   esac
+done
+
+if [[ ( -z $prodver ) || ( -z $mach ) || ( -z $awk_script ) ]]
+then
+   usage
+   exit 1
+fi
+
+if [[ -f $awk_script ]]
+then
+	rm -f $awk_script
+fi
+
+#
+# Build REV= field based on date
+#
+rev=$(date "+%Y.%m.%d.%H.%M")
+
+#
+# Build awk script which will process all the
+# pkginfo.tmpl files.
+#
+# the first VERSION pattern is replaced with a leading quotation mark
+#
+rm -f $awk_script
+cat << EOF > $awk_script
+/$VERSION1/ {
+      sub(/\=[^=]*$/,"=\"$rev\"")
+      print
+      next
+   }
+/$VERSION2/ {
+      sub(/\=[^=]*$/,"=$rev\"")
+      sub(/NSPRVERS/,"$version")
+      print
+      next
+   }
+/$PRODVERS/ { 
+      printf "SUNW_PRODVERS=\"%s\"\n", "$prodver" 
+      next
+   }
+/$ARCH/ {
+      printf "ARCH=\"%s\"\n", "$mach"
+      next
+   }
+{ print }
+EOF

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2 @@
+/copyright/1.3/Fri Feb 25 20:20:53 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pkg/solaris/common_files

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/copyright
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/common_files/copyright	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,36 @@
+Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+Use is subject to license terms.
+
+Version: MPL 1.1/GPL 2.0/LGPL 2.1
+
+The contents of this package are subject to the Mozilla Public License Version
+1.1 (the "License"); you may not use this package 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.
+

Added: freeswitch/trunk/libs/js/nsprpub/pkg/solaris/proto64.mk
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pkg/solaris/proto64.mk	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,50 @@
+# 
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+# 
+# ***** 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 *****
+#
+#ident  "$Id: proto64.mk,v 1.3 2005/02/25 20:20:52 christophe.ravel.bugs%sun.com Exp $"
+#
+
+ifeq ($(USE_64), 1)
+  # Remove 64 tag
+  sed_proto64='s/\#64\#//g'
+else
+  # Strip 64 lines
+  sed_proto64='/\#64\#/d'
+endif

Added: freeswitch/trunk/libs/js/nsprpub/pr/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3 @@
+/.cvsignore/1.2/Sat May 12 01:41:04 2001//
+/Makefile.in/1.7/Sun Apr 25 15:00:46 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3 @@
+A D/include////
+A D/src////
+A D/tests////

Added: freeswitch/trunk/libs/js/nsprpub/pr/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr

Added: freeswitch/trunk/libs/js/nsprpub/pr/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,49 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is 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
+
+DIRS = include src
+
+include $(topsrcdir)/config/rules.mk

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,45 @@
+/.cvsignore/1.2/Sat May 12 01:41:57 2001//
+/MANIFEST/1.10/Wed Feb 23 23:37:52 2000//
+/Makefile.in/1.9/Sun Apr 25 15:00:47 2004//
+/gencfg.c/3.9/Sun Apr 25 15:00:47 2004//
+/nspr.h/3.12/Sun Apr 25 15:00:47 2004//
+/pratom.h/3.8/Sun Apr 25 15:00:47 2004//
+/prbit.h/3.8/Sun Apr 25 15:00:47 2004//
+/prclist.h/3.6/Sun Apr 25 15:00:47 2004//
+/prcmon.h/3.8/Sun Apr 25 15:00:47 2004//
+/prcountr.h/3.7/Sun Apr 25 15:00:47 2004//
+/prcvar.h/3.6/Sun Apr 25 15:00:47 2004//
+/prdtoa.h/3.8/Sun Apr 25 15:00:47 2004//
+/prenv.h/3.11/Sun Apr 25 15:00:47 2004//
+/prerr.h/3.9/Sun Apr 25 15:00:47 2004//
+/prerror.h/3.12/Sun Apr 25 15:00:47 2004//
+/prinet.h/3.13/Mon Jan  9 21:43:52 2006//
+/prinit.h/3.30/Wed Sep 14 23:39:55 2005//
+/prinrval.h/3.6/Sun Apr 25 15:00:47 2004//
+/prio.h/3.40/Sun Apr 25 15:00:47 2004//
+/pripcsem.h/3.7/Sun Apr 25 15:00:47 2004//
+/prlink.h/3.12/Sat Aug 13 00:20:49 2005//
+/prlock.h/3.8/Sun Apr 25 15:00:47 2004//
+/prlog.h/3.14/Sun Apr 25 15:00:47 2004//
+/prlong.h/3.13/Wed Jan 12 02:47:56 2005//
+/prmem.h/3.12/Fri Feb  4 00:20:33 2005//
+/prmon.h/3.6/Sun Apr 25 15:00:47 2004//
+/prmwait.h/3.8/Sun Apr 25 15:00:47 2004//
+/prnetdb.h/3.10/Mon Aug 30 23:31:36 2004//
+/prolock.h/3.9/Tue Nov 23 00:54:04 2004//
+/prpdce.h/3.7/Sun Apr 25 15:00:47 2004//
+/prprf.h/3.6/Sun Apr 25 15:00:47 2004//
+/prproces.h/3.9/Sun Apr 25 15:00:47 2004//
+/prrng.h/1.7/Sun Apr 25 15:00:47 2004//
+/prrwlock.h/1.7/Sun Apr 25 15:00:47 2004//
+/prshm.h/3.7/Sun Apr 25 15:00:47 2004//
+/prshma.h/3.6/Sun Apr 25 15:00:47 2004//
+/prsystem.h/3.11/Thu Jan 19 22:11:59 2006//
+/prthread.h/3.12/Fri Jul  1 20:56:49 2005//
+/prtime.h/3.10/Sun Apr 25 15:00:47 2004//
+/prtpool.h/1.6/Sun Apr 25 15:00:47 2004//
+/prtrace.h/3.7/Sun Apr 25 15:00:47 2004//
+/prtypes.h/3.32/Fri Oct 21 18:21:41 2005//
+/prvrsion.h/3.7/Sun Apr 25 15:00:47 2004//
+/prwin16.h/3.8/Sun Apr 25 15:00:47 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3 @@
+A D/md////
+A D/obsolete////
+A D/private////

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/include

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/MANIFEST
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/MANIFEST	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,52 @@
+#
+# This is a list of local files which get copied to the mozilla:dist directory
+#
+
+nspr.h
+pratom.h
+prbit.h
+prclist.h
+prcmon.h
+prcountr.h
+prcvar.h
+prdtoa.h
+prenv.h
+prerr.h
+prerror.h
+prinet.h
+prinit.h
+prinrval.h
+prio.h
+pripcsem.h
+prlink.h
+prlock.h
+prlog.h
+prlong.h
+prmem.h
+prmon.h
+prmwait.h
+prnetdb.h
+prolock.h
+prpdce.h
+prprf.h
+prproces.h
+prrng.h
+prrwlock.h
+prshm.h
+prshma.h
+prsystem.h
+prthread.h
+prtime.h
+prtpool.h
+prtrace.h
+prtypes.h
+prvrsion.h
+prwin16.h
+
+obsolete/protypes.h
+obsolete/prsem.h
+obsolete/probslet.h
+
+private/prpriv.h
+private/pprio.h
+private/pprthred.h

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,59 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is 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
+
+DIRS = md private obsolete
+
+include $(topsrcdir)/config/config.mk
+
+HEADERS = $(wildcard $(srcdir)/*.h)
+
+RELEASE_HEADERS = $(HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(RELEASE_HEADERS)
+	$(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir)

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/gencfg.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/gencfg.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,309 @@
+/* -*- 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 <stdio.h>
+
+#if defined(sgi)
+#ifndef IRIX
+	error - IRIX is not defined
+#endif
+#endif
+
+#if defined(__sun)
+#if defined(__svr4) || defined(__svr4__) || defined(__SVR4)
+#ifndef SOLARIS
+	error - SOLARIS is not defined
+#endif
+#else
+#ifndef SUNOS4
+	error - SUNOS4 is not defined
+#endif
+#endif
+#endif
+
+#if defined(__hpux)
+#ifndef HPUX
+	error - HPUX is not defined
+#endif
+#endif
+
+#if defined(__alpha) 
+#if !(defined(_WIN32)) && !(defined(OSF1)) && !(defined(__linux)) && !(defined(__FreeBSD__))
+	error - None of OSF1, _WIN32, __linux, or __FreeBSD__ is defined
+#endif
+#endif
+
+#if defined(_IBMR2)
+#ifndef AIX
+	error - AIX is not defined
+#endif
+#endif
+
+#if defined(linux)
+#ifndef LINUX
+	error - LINUX is not defined
+#endif
+#endif
+
+#if defined(bsdi)
+#ifndef BSDI
+	error - BSDI is not defined
+#endif
+#endif
+
+#if defined(M_UNIX)
+#ifndef SCO
+      error - SCO is not defined
+#endif
+#endif
+#if !defined(M_UNIX) && defined(_USLC_)
+#ifndef UNIXWARE
+      error - UNIXWARE is not defined
+#endif
+#endif
+
+#if defined(__APPLE__)
+#ifndef DARWIN
+      error - DARWIN is not defined
+#endif
+#endif
+
+#if defined(__NeXT__)
+#ifndef NEXTSTEP
+      error - NEXTSTEP is not defined
+#endif
+#endif
+
+/************************************************************************/
+
+/* Generate cpucfg.h */
+
+#ifdef XP_PC
+#ifdef WIN32
+#define INT64	_PRInt64
+#else
+#define INT64	long
+#endif
+#else
+#if defined(HPUX) || defined(NECSVR4) || defined(SCO) || defined(UNIXWARE) || defined (NCR)
+#define INT64	long
+#else
+#define INT64	long long
+#endif
+#endif
+
+struct align_short {
+    char c;
+    short a;
+};
+struct align_int {
+    char c;
+    int a;
+};
+struct align_long {
+    char c;
+    long a;
+};
+struct align_PRInt64 {
+    char c;
+    INT64 a;
+};
+struct align_fakelonglong {
+    char c;
+    struct {
+	long hi, lo;
+    } a;
+};
+struct align_float {
+    char c;
+    float a;
+};
+struct align_double {
+    char c;
+    double a;
+};
+struct align_pointer {
+    char c;
+    void *a;
+};
+
+#define ALIGN_OF(type) \
+    (((char*)&(((struct align_##type *)0)->a)) - ((char*)0))
+
+int bpb;
+
+/* Used if shell doesn't support redirection. By default, assume it does. */
+FILE *stream;
+
+static int Log2(int n)
+{
+    int log2 = 0;
+
+    if (n & (n-1))
+	log2++;
+    if (n >> 16)
+	log2 += 16, n >>= 16;
+    if (n >> 8)
+	log2 += 8, n >>= 8;
+    if (n >> 4)
+	log2 += 4, n >>= 4;
+    if (n >> 2)
+	log2 += 2, n >>= 2;
+    if (n >> 1)
+	log2++;
+    return log2;
+}
+
+/* We assume that int's are 32 bits */
+static void do64(void)
+{
+    union {
+	int i;
+	char c[4];
+    } u;
+
+    u.i = 0x01020304;
+    if (u.c[0] == 0x01) {
+	fprintf(stream, "#undef  IS_LITTLE_ENDIAN\n");
+	fprintf(stream, "#define IS_BIG_ENDIAN 1\n\n");
+    } else {
+	fprintf(stream, "#define IS_LITTLE_ENDIAN 1\n");
+	fprintf(stream, "#undef  IS_BIG_ENDIAN\n\n");
+    }
+}
+
+static void do32(void)
+{
+    union {
+	long i;
+	char c[4];
+    } u;
+
+    u.i = 0x01020304;
+    if (u.c[0] == 0x01) {
+	fprintf(stream, "#undef  IS_LITTLE_ENDIAN\n");
+	fprintf(stream, "#define IS_BIG_ENDIAN 1\n\n");
+    } else {
+	fprintf(stream, "#define IS_LITTLE_ENDIAN 1\n");
+	fprintf(stream, "#undef  IS_BIG_ENDIAN\n\n");
+    }
+}
+
+/*
+** Concievably this could actually be used; but there is lots of code out
+** there with and's and shift's in it that assumes a byte is 8 bits, so
+** forget about porting THIS code to those non 8 bit byte machines.
+*/
+static void BitsPerByte(void)
+{
+    bpb = 8;
+}
+
+int main(int argc, char **argv)
+{
+    BitsPerByte();
+
+    /* If we got a command line argument, try to use it as the stream. */
+    ++argv;
+    if(*argv) {
+        if(!(stream = fopen ( *argv, "wt" ))) {
+            fprintf(stderr, "Could not write to output file %s.\n", *argv);
+            return 1;
+        }
+    } else {
+		stream = stdout;
+	}
+
+    fprintf(stream, "#ifndef nspr_cpucfg___\n");
+    fprintf(stream, "#define nspr_cpucfg___\n\n");
+
+    fprintf(stream, "/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n");
+
+    if (sizeof(long) == 8) {
+	do64();
+    } else {
+	do32();
+    }
+    fprintf(stream, "#define PR_BYTES_PER_BYTE   %d\n", sizeof(char));
+    fprintf(stream, "#define PR_BYTES_PER_SHORT  %d\n", sizeof(short));
+    fprintf(stream, "#define PR_BYTES_PER_INT    %d\n", sizeof(int));
+    fprintf(stream, "#define PR_BYTES_PER_INT64  %d\n", 8);
+    fprintf(stream, "#define PR_BYTES_PER_LONG   %d\n", sizeof(long));
+    fprintf(stream, "#define PR_BYTES_PER_FLOAT  %d\n", sizeof(float));
+    fprintf(stream, "#define PR_BYTES_PER_DOUBLE %d\n\n", sizeof(double));
+
+    fprintf(stream, "#define PR_BITS_PER_BYTE    %d\n", bpb);
+    fprintf(stream, "#define PR_BITS_PER_SHORT   %d\n", bpb * sizeof(short));
+    fprintf(stream, "#define PR_BITS_PER_INT     %d\n", bpb * sizeof(int));
+    fprintf(stream, "#define PR_BITS_PER_INT64   %d\n", bpb * 8);
+    fprintf(stream, "#define PR_BITS_PER_LONG    %d\n", bpb * sizeof(long));
+    fprintf(stream, "#define PR_BITS_PER_FLOAT   %d\n", bpb * sizeof(float));
+    fprintf(stream, "#define PR_BITS_PER_DOUBLE  %d\n\n", 
+            bpb * sizeof(double));
+
+    fprintf(stream, "#define PR_BITS_PER_BYTE_LOG2   %d\n", Log2(bpb));
+    fprintf(stream, "#define PR_BITS_PER_SHORT_LOG2  %d\n", 
+            Log2(bpb * sizeof(short)));
+    fprintf(stream, "#define PR_BITS_PER_INT_LOG2    %d\n", 
+            Log2(bpb * sizeof(int)));
+    fprintf(stream, "#define PR_BITS_PER_INT64_LOG2  %d\n", 6);
+    fprintf(stream, "#define PR_BITS_PER_LONG_LOG2   %d\n", 
+            Log2(bpb * sizeof(long)));
+    fprintf(stream, "#define PR_BITS_PER_FLOAT_LOG2  %d\n", 
+            Log2(bpb * sizeof(float)));
+    fprintf(stream, "#define PR_BITS_PER_DOUBLE_LOG2 %d\n\n", 
+            Log2(bpb * sizeof(double)));
+
+    fprintf(stream, "#define PR_ALIGN_OF_SHORT   %d\n", ALIGN_OF(short));
+    fprintf(stream, "#define PR_ALIGN_OF_INT     %d\n", ALIGN_OF(int));
+    fprintf(stream, "#define PR_ALIGN_OF_LONG    %d\n", ALIGN_OF(long));
+    if (sizeof(INT64) < 8) {
+	/* this machine doesn't actually support PRInt64's */
+	fprintf(stream, "#define PR_ALIGN_OF_INT64   %d\n", 
+                ALIGN_OF(fakelonglong));
+    } else {
+	fprintf(stream, "#define PR_ALIGN_OF_INT64   %d\n", ALIGN_OF(PRInt64));
+    }
+    fprintf(stream, "#define PR_ALIGN_OF_FLOAT   %d\n", ALIGN_OF(float));
+    fprintf(stream, "#define PR_ALIGN_OF_DOUBLE  %d\n", ALIGN_OF(double));
+    fprintf(stream, "#define PR_ALIGN_OF_POINTER %d\n\n", ALIGN_OF(pointer));
+
+    fprintf(stream, "#endif /* nspr_cpucfg___ */\n");
+    fclose(stream);
+
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,77 @@
+/.cvsignore/1.2/Sat May 12 01:47:58 2001//
+/Makefile.in/1.21/Wed Nov 23 06:35:20 2005//
+/_aix.h/3.15/Sun Apr 25 15:00:47 2004//
+/_aix32.cfg/3.7/Sun Apr 25 15:00:47 2004//
+/_aix64.cfg/3.9/Sun Apr 25 15:00:47 2004//
+/_beos.cfg/3.5/Tue Jun 20 21:22:00 2000//
+/_beos.h/3.23/Mon Jan 17 22:00:53 2005//
+/_bsdi.cfg/3.10/Sun Apr 25 15:00:47 2004//
+/_bsdi.h/3.12/Sun Apr 25 15:00:47 2004//
+/_darwin.cfg/3.10/Wed Feb 22 02:39:59 2006//
+/_darwin.h/3.19/Mon Jan  9 18:38:36 2006//
+/_dgux.cfg/3.7/Sun Apr 25 15:00:47 2004//
+/_dgux.h/3.7/Sun Apr 25 15:00:47 2004//
+/_freebsd.cfg/3.10/Mon Nov 22 21:24:53 2004//
+/_freebsd.h/3.21/Mon Nov 22 21:24:53 2004//
+/_hpux.h/3.20/Mon Nov 21 22:15:54 2005//
+/_hpux32.cfg/3.6/Sun Apr 25 15:00:47 2004//
+/_hpux64.cfg/3.7/Sun Apr 25 15:00:47 2004//
+/_irix.h/3.15/Sun Apr 25 15:00:47 2004//
+/_irix32.cfg/3.6/Sun Apr 25 15:00:47 2004//
+/_irix64.cfg/3.6/Sun Apr 25 15:00:47 2004//
+/_linux.cfg/3.19/Sat Dec 24 08:25:22 2005//
+/_linux.h/3.45/Tue Aug  9 22:41:37 2005//
+/_macos.h/3.41/Sun Apr 25 15:00:47 2004//
+/_ncr.cfg/3.7/Sun Apr 25 15:00:47 2004//
+/_ncr.h/3.8/Sun Apr 25 15:00:47 2004//
+/_nec.cfg/3.5/Sun Apr 25 15:00:47 2004//
+/_nec.h/3.7/Sun Apr 25 15:00:47 2004//
+/_netbsd.cfg/3.10/Sun Apr 25 15:00:47 2004//
+/_netbsd.h/3.16/Wed May 19 15:39:46 2004//
+/_nextstep.cfg/3.5/Sun Apr 25 15:00:47 2004//
+/_nextstep.h/3.7/Sun Apr 25 15:00:47 2004//
+/_nspr_pthread.h/3.8/Sun Apr 25 15:00:47 2004//
+/_nto.cfg/3.7/Sun Apr 25 15:00:47 2004//
+/_nto.h/3.11/Sun Apr 25 15:00:47 2004//
+/_openbsd.cfg/3.9/Sun Apr 25 15:00:47 2004//
+/_openbsd.h/3.8/Sun Apr 25 15:00:47 2004//
+/_openvms.cfg/1.6/Sun Apr 25 15:00:47 2004//
+/_openvms.h/1.18/Sun Apr 25 15:00:47 2004//
+/_os2.cfg/3.8/Sun Apr 25 15:00:47 2004//
+/_os2.h/3.35/Fri Apr 22 21:14:03 2005//
+/_os2_errors.h/3.12/Sun Apr 25 15:00:47 2004//
+/_osf1.cfg/3.8/Sun Apr 25 15:00:47 2004//
+/_osf1.h/3.17/Sun Apr 25 15:00:47 2004//
+/_pcos.h/3.9/Sun Apr 25 15:00:47 2004//
+/_pth.h/3.32/Sat Dec 24 15:03:30 2005//
+/_qnx.cfg/3.5/Sun Apr 25 15:00:47 2004//
+/_qnx.h/3.5/Sun Apr 25 15:00:47 2004//
+/_reliantunix.cfg/3.7/Sun Apr 25 15:00:47 2004//
+/_reliantunix.h/3.8/Sun Apr 25 15:00:47 2004//
+/_rhapsody.cfg/3.7/Sun Apr 25 15:00:47 2004//
+/_rhapsody.h/3.11/Sun Apr 25 15:00:47 2004//
+/_riscos.cfg/3.2/Thu Jul 21 18:22:53 2005//
+/_riscos.h/3.2/Thu Jul 21 18:22:53 2005//
+/_scoos.cfg/3.7/Sun Apr 25 15:00:47 2004//
+/_scoos.h/3.7/Sun Apr 25 15:00:47 2004//
+/_solaris.cfg/3.5/Tue Oct 26 21:24:34 2004//
+/_solaris.h/3.28/Thu Feb 24 02:58:45 2005//
+/_sony.cfg/3.5/Sun Apr 25 15:00:47 2004//
+/_sony.h/3.6/Sun Apr 25 15:00:47 2004//
+/_sunos4.cfg/3.5/Sun Apr 25 15:00:47 2004//
+/_sunos4.h/3.6/Sun Apr 25 15:00:47 2004//
+/_unix_errors.h/3.10/Fri Apr 29 22:47:56 2005//
+/_unixos.h/3.36/Sat Dec 24 08:25:23 2005//
+/_unixware.cfg/3.7/Sun Apr 25 15:00:47 2004//
+/_unixware.h/3.7/Sun Apr 25 15:00:47 2004//
+/_unixware7.cfg/3.5/Sun Apr 25 15:00:47 2004//
+/_win16.cfg/3.5/Sun Apr 25 15:00:47 2004//
+/_win16.h/3.15/Sun Apr 25 15:00:47 2004//
+/_win32_errors.h/3.7/Sun Apr 25 15:00:47 2004//
+/_win95.cfg/3.7/Fri Oct 21 18:21:41 2005//
+/_win95.h/3.31/Fri Oct 21 18:21:41 2005//
+/_winnt.cfg/3.7/Fri Oct 21 18:21:41 2005//
+/_winnt.h/3.31/Fri Oct 21 18:21:41 2005//
+/prosdep.h/3.17/Sat Dec 24 08:25:23 2005//
+/sunos4.h/3.6/Sun Apr 25 15:00:47 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/include/md

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,81 @@
+# 
+# ***** 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
+
+# The .cfg files need to be exported and installed to support
+# cross-compilation.
+CONFIGS = $(wildcard $(srcdir)/*.cfg)
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(MDCPUCFG_H)
+	$(INSTALL) -m 444 $(CONFIGS) $(dist_includedir)/md
+	$(INSTALL) -m 444 $(srcdir)/$(MDCPUCFG_H) $(dist_includedir)
+ifeq ($(OS_ARCH),OpenVMS)
+# On OpenVMS mv updates the file's modified time, so we create a hard link.
+	cd $(dist_includedir); \
+	if test ! -f prcpucfg.h; then \
+	    dcl set file /enter=prcpucfg.h $(MDCPUCFG_H); \
+	fi
+else
+	mv -f $(dist_includedir)/$(MDCPUCFG_H) $(dist_includedir)/prcpucfg.h
+endif
+
+install::
+	$(NSINSTALL) -D $(DESTDIR)$(includedir)/md
+	cp $(srcdir)/$(MDCPUCFG_H) $(DESTDIR)$(includedir)/prcpucfg.h
+	$(NSINSTALL) -t -m 644 $(CONFIGS) $(DESTDIR)$(includedir)/md
+
+release:: export
+	@echo "Copying machine-dependent prcpucfg.h"
+	@if test -z "$(BUILD_NUMBER)"; then \
+		echo "BUILD_NUMBER must be defined"; \
+		false; \
+	fi
+	@if test ! -d $(RELEASE_INCLUDE_DIR); then \
+		rm -rf $(RELEASE_INCLUDE_DIR); \
+		$(NSINSTALL) -D $(RELEASE_INCLUDE_DIR);\
+	fi
+	cp $(srcdir)/$(MDCPUCFG_H) $(RELEASE_INCLUDE_DIR)/prcpucfg.h

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_aix.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_aix.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,254 @@
+/* -*- 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 nspr_aix_defs_h___
+#define nspr_aix_defs_h___
+
+#include <sys/types.h>
+#if defined(_PR_PTHREADS) || defined(PTHREADS_USER)
+#include <pthread.h>
+#endif
+
+/*
+ * To pick up fd_set and the poll events.
+ */
+#include <sys/select.h>
+#include <sys/poll.h>
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH          "aix"
+#define _PR_SI_SYSNAME		    "AIX"
+#define _PR_SI_ARCHITECTURE	    "rs6000"
+#define PR_DLL_SUFFIX		    ".so"
+
+#define _PR_VMBASE	 	        0x30000000
+#define _PR_STACK_VMBASE	    0x50000000
+#define _MD_DEFAULT_STACK_SIZE	(2*65536L)
+#define _MD_MINIMUM_STACK_SIZE	(2*65536L)
+#define _MD_MMAP_FLAGS		    MAP_PRIVATE
+
+#define NEED_TIME_R
+#undef  HAVE_STACK_GROWING_UP
+#undef	HAVE_WEAK_IO_SYMBOLS
+#undef	HAVE_WEAK_MALLOC_SYMBOLS
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define _PR_HAVE_SOCKADDR_LEN
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#ifdef _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_HAVE_GETADDRINFO
+#endif
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
+
+/* Timer operations */
+#if defined(AIX_TIMERS)
+extern PRIntervalTime _MD_AixGetInterval(void);
+#define _MD_GET_INTERVAL _MD_AixGetInterval
+
+extern PRIntervalTime _MD_AixIntervalPerSec(void);
+#define _MD_INTERVAL_PER_SEC _MD_AixIntervalPerSec
+
+#else  /* defined(AIX_TIMERS) */
+#define _MD_GET_INTERVAL        _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC    _PR_UNIX_TicksPerSecond
+#endif  /* defined(AIX_TIMERS) */
+
+#ifdef AIX_HAVE_ATOMIC_OP_H
+/* The atomic operations */
+#include <sys/atomic_op.h>
+#define _PR_HAVE_ATOMIC_OPS
+#ifndef IS_64
+#define _PR_HAVE_ATOMIC_CAS
+#endif
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT(val)   ((PRInt32)fetch_and_add((atomic_p)val, 1) + 1)
+#define _MD_ATOMIC_ADD(ptr, val)   ((PRInt32)fetch_and_add((atomic_p)ptr, val) + val)
+#define _MD_ATOMIC_DECREMENT(val)   ((PRInt32)fetch_and_add((atomic_p)val, -1) - 1)
+#define _MD_ATOMIC_SET(val, newval) _AIX_AtomicSet(val, newval)
+#endif /* AIX_HAVE_ATOMIC_OP_H */
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _MD_GET_SP(_t)				(_t)->md.jb[3]
+#define _MD_SET_THR_SP(_t, _sp)		((_t)->md.jb[3] = (int) (_sp - 2 * 64))
+#define PR_NUM_GCREGS				_JBLEN
+
+#define CONTEXT(_th) 				((_th)->md.jb)
+#define SAVE_CONTEXT(_th)			_setjmp(CONTEXT(_th))
+#define GOTO_CONTEXT(_th)			_longjmp(CONTEXT(_th), 1)
+
+#ifdef PTHREADS_USER
+#include "_nspr_pthread.h"
+#else
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+    PR_BEGIN_MACRO				      \
+        *status = PR_TRUE;              \
+	if (setjmp(CONTEXT(_thread))) {	\
+	    (*_main)();			\
+	}				\
+	_MD_GET_SP(_thread) = (int) (_sp - 2 * 64);		\
+    PR_END_MACRO
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode; \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    longjmp(CONTEXT(_thread), 1); \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    jmp_buf jb;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#if !defined(_PR_PTHREADS)
+#define _MD_INIT_LOCKS()
+#endif
+
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_EARLY_INIT          	_MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu)	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD			_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+#endif /* PTHREADS_USER */
+
+#ifdef AIX_RENAME_SELECT
+#define _MD_SELECT	select
+#define _MD_POLL	poll
+#endif
+
+extern void _MD_aix_map_sendfile_error(int err);
+
+#endif /* nspr_aix_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_aix32.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_aix32.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,145 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef AIX
+#define AIX
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2	5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+/* used by protypes.h only */
+#define _PR_AIX_HAVE_BSD_INT_TYPES
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_aix64.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_aix64.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,146 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef AIX
+#define AIX
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2	6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 8
+
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+/* used by protypes.h only */
+#define _PR_AIX_HAVE_BSD_INT_TYPES
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_beos.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_beos.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,147 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 
+ * 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.
+ */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_BEOS
+#define XP_BEOS
+#undef XP_UNIX
+#endif
+
+#ifndef BEOS
+#define BEOS
+#endif
+
+#define PR_AF_INET6 5  /* same as AF_INET6 */
+
+#ifdef __powerpc__
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#else
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#endif
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define	HAVE_LONG_LONG
+/*
+ * XXX These two macros need to be investigated for different architectures.
+ */
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_beos.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_beos.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,613 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 nspr_beos_defs_h___
+#define nspr_beos_defs_h___
+
+#include "prtypes.h"
+#include "prio.h"
+#include "prthread.h"
+#include "prproces.h"
+#include "prmem.h"
+#include "obsolete/prsem.h"
+#include <errno.h>
+
+#include <support/SupportDefs.h>
+#include <kernel/OS.h>
+#include <dirent.h>
+
+/*
+ * Internal configuration macros
+ */
+
+#ifdef BONE_VERSION
+#define _PR_HAVE_SOCKADDR_LEN
+#endif
+
+#define PR_LINKER_ARCH	"beos"
+#define _PR_SI_SYSNAME  "BEOS"
+#ifdef __powerpc__
+#define _PR_SI_ARCHITECTURE "ppc"
+#else
+#define _PR_SI_ARCHITECTURE "x86"
+#endif
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef	HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define _PR_NO_CLOCK_TIMER
+
+/*
+ * The Atomic operations
+ */
+
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC _MD_AtomicInit
+#define _MD_ATOMIC_INCREMENT _MD_AtomicIncrement
+#define _MD_ATOMIC_ADD _MD_AtomicAdd
+#define _MD_ATOMIC_DECREMENT _MD_AtomicDecrement
+#define _MD_ATOMIC_SET _MD_AtomicSet
+
+#define HAVE_CVAR_BUILT_ON_SEM
+#define _PR_GLOBAL_THREADS_ONLY
+#define _PR_BTHREADS
+#define _PR_NEED_FAKE_POLL
+#define _PR_HAVE_PEEK_BUFFER
+#define _PR_PEEK_BUFFER_MAX (16 * 1024)
+#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) 1
+#define _PR_CONNECT_DOES_NOT_BIND
+#define _PR_HAVE_O_APPEND
+
+/* Define threading functions and objects as native BeOS */
+struct _MDThread {
+    thread_id	tid;	/* BeOS thread handle */
+	sem_id		joinSem;	/* sems used to synchronzie joining */
+	PRBool	is_joining;	/* TRUE if someone is currently waiting to
+						   join this thread */
+};
+
+struct _MDThreadStack {
+    PRInt8	notused;
+};
+
+/*
+ * Lock and Semaphore related definitions
+ */
+
+struct _MDLock {
+    sem_id semaphoreID;
+    int32  benaphoreCount;
+};
+
+struct _MDCVar {
+    sem_id sem1;
+    sem_id sem2;
+    int16  count;
+};
+
+struct _MDSemaphore {
+    sem_id sid;
+};
+
+/*
+** CPU-related definitions
+*/
+struct _MDCPU {
+    int8		unused;
+};
+
+/*
+** Process-related definitions
+*/
+struct _MDProcess {
+    pid_t pid;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+** File- and directory-related definitions
+*/
+
+#ifndef BONE_VERSION
+#define BE_SOCK_SHUTDOWN_READ	0x01
+#define BE_SOCK_SHUTDOWN_WRITE	0x02
+#endif
+
+struct _MDFileDesc {
+    PRInt32	osfd;
+    PRInt32	sock_state;
+    PRBool	accepted_socket;
+    PRNetAddr	peer_addr;
+#ifndef BONE_VERSION
+    PRBool	connectValueValid;
+    int		connectReturnValue;
+    int		connectReturnError;
+#endif
+};
+
+struct _MDDir {
+    DIR		*d;
+};
+
+#define PR_DIRECTORY_SEPARATOR		'/'
+#define PR_DIRECTORY_SEPARATOR_STR	"/"
+#define PR_PATH_SEPARATOR		':'
+#define PR_PATH_SEPARATOR_STR		":"
+
+#define GETTIMEOFDAY(tp)	gettimeofday((tp), NULL)
+
+/* --- Memory-mapped files stuff --- not implemented on BeOS */
+
+struct _MDFileMap {
+    PRInt8 unused;
+};
+
+/*
+ * Network related definitions.
+ */
+
+#ifndef BONE_VERSION
+#define IPPROTO_IP 0
+#define AF_UNIX 2
+#define TCP_NODELAY SO_NONBLOCK
+#define SO_LINGER -1
+#define SO_ERROR 4
+#endif
+
+#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5
+
+#ifndef BONE_VERSION
+/* these aren't actually used. if they are, we're screwed */
+struct  protoent {
+    char    *p_name;        /* official protocol name */
+    char    **p_aliases;    /* alias list */
+    int     p_proto;        /* protocol # */
+};
+
+struct protoent* getprotobyname(const char* name);
+struct protoent* getprotobynumber(int number);
+#endif
+
+/*
+ * malloc() related definitions.
+ */
+
+#undef _PR_OVERRIDE_MALLOC
+
+/* Miscellaneous */
+
+#define _MD_ERRNO()             (errno)
+
+#define _MD_CLEANUP_BEFORE_EXIT _MD_cleanup_before_exit
+#define _MD_EXIT _MD_exit
+
+#define _MD_GET_ENV getenv
+#define _MD_PUT_ENV putenv
+
+#define _MD_EARLY_INIT _MD_early_init
+#define _MD_FINAL_INIT _MD_final_init
+
+/* CPU Stuff */
+
+#define _MD_INIT_CPUS _MD_init_cpus
+#define _MD_WAKEUP_CPUS _MD_wakeup_cpus
+#define _MD_START_INTERRUPTS _MD_start_interrupts
+#define _MD_STOP_INTERRUPTS _MD_stop_interrupts
+#define _MD_DISABLE_CLOCK_INTERRUPTS _MD_disable_clock_interrupts
+#define _MD_BLOCK_CLOCK_INTERRUPTS _MD_block_clock_interrupts
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS _MD_unblock_clock_interrupts
+#define _MD_CLOCK_INTERRUPT _MD_clock_interrupt
+#define _MD_INIT_STACK _MD_init_stack
+#define _MD_CLEAR_STACK _MD_clear_stack
+// #define _MD_GET_INTSOFF _MD_get_intsoff
+// #define _MD_SET_INTSOFF _MD_set_intsoff
+#define _MD_CURRENT_CPU _MD_current_cpu
+#define _MD_SET_CURRENT_CPU _MD_set_current_cpu
+#define _MD_INIT_RUNNING_CPU _MD_init_running_cpu
+#define _MD_PAUSE_CPU _MD_pause_cpu
+
+/* Thread stuff */
+
+#define _MD_CURRENT_THREAD() PR_GetCurrentThread()
+// #define _MD_GET_ATTACHED_THREAD _MD_get_attached_thread
+#define _MD_LAST_THREAD _MD_last_thread
+#define _MD_SET_CURRENT_THREAD _MD_set_current_THREAD
+#define _MD_SET_LAST_THREAD _MD_set_last_thread
+#define _MD_INIT_THREAD _MD_init_thread
+#define _MD_EXIT_THREAD _MD_exit_thread
+#define _MD_INIT_ATTACHED_THREAD _MD_init_attached_thread
+
+#define _MD_SUSPEND_THREAD _MD_suspend_thread
+#define _MD_RESUME_THREAD _MD_resume_thread
+#define _MD_SUSPEND_CPU _MD_suspend_cpu
+#define _MD_RESUME_CPU _MD_resume_cpu
+#define _MD_BEGIN_SUSPEND_ALL _MD_begin_suspend_all
+#define _MD_END_SUSPEND_ALL _MD_end_suspend_all
+#define _MD_BEGIN_RESUME_ALL _MD_begin_resume_all
+#define _MD_END_RESUME_ALL _MD_end_resume_all
+
+#define _MD_GET_SP _MD_get_sp
+
+#define _MD_CLEAN_THREAD _MD_clean_thread
+#define _MD_CREATE_PRIMORDIAL_USER_THREAD _MD_create_primordial_user_thread
+#define _MD_CREATE_USER_THREAD _MD_create_user_thread
+#define _MD_INIT_PRIMORDIAL_THREAD _MD_init_primordial_thread
+#define _MD_CREATE_THREAD _MD_create_thread
+#define _MD_YIELD _MD_yield
+#define _MD_SET_PRIORITY _MD_set_priority
+
+#define _MD_SUSPENDALL _MD_suspendall
+#define _MD_RESUMEALL _MD_resumeall
+
+#define _MD_SWITCH_CONTEXT _MD_switch_context
+#define _MD_RESTORE_CONTEXT _MD_restore_context
+
+#define _MD_WAIT _MD_wait
+#define _MD_WAKEUP_WAITER _MD_wakeup_waiter
+
+#define _MD_SETTHREADAFFINITYMASK _MD_setthreadaffinitymask
+#define _MD_GETTHREADAFFINITYMASK _MD_getthreadaffinitymask
+
+/* Thread Synchronization */
+
+#define _MD_INIT_LOCKS _MD_init_locks
+#define _MD_NEW_LOCK _MD_new_lock
+#define _MD_FREE_LOCK _MD_free_lock
+#define _MD_LOCK _MD_lock
+#define _MD_TEST_AND_LOCK _MD_test_and_lock
+#define _MD_UNLOCK _MD_unlock
+#define _MD_IOQ_LOCK _MD_ioq_lock
+#define _MD_IOQ_UNLOCK _MD_ioq_unlock
+#define _MD_NEW_SEM _MD_new_sem
+#define _MD_DESTROY_SEM _MD_destroy_sem
+#define _MD_TIMED_WAIT_SEM _MD_timed_wait_sem
+#define _MD_WAIT_SEM _MD_wait_sem
+#define _MD_POST_SEM _MD_post_sem
+// #define _MD_NEW_CV _MD_new_cv
+// #define _MD_FREE_CV _MD_free_cv
+// #define _MD_WAIT_CV _MD_wait_cv
+// #define _MD_NOTIFY_CV _MD_notify_cv
+// #define _MD_NOTIFYALL_CV _MD_notifyall_cv
+
+/* File I/O */
+
+/* don't need any I/O initializations */
+#define _MD_INIT_IO()
+#define _MD_INIT_FILEDESC(fd)
+
+#define _MD_OPEN_DIR _MD_open_dir
+#define _MD_READ_DIR _MD_read_dir
+#define _MD_CLOSE_DIR _MD_close_dir
+#define _MD_MAKE_NONBLOCK _MD_make_nonblock
+#define _MD_SET_FD_INHERITABLE _MD_set_fd_inheritable
+#define _MD_INIT_FD_INHERITABLE _MD_init_fd_inheritable
+#define _MD_QUERY_FD_INHERITABLE _MD_query_fd_inheritable
+#define _MD_OPEN _MD_open
+#define _MD_OPEN_FILE _MD_open
+#define _MD_CLOSE_FILE _MD_close_file
+#define _MD_READ _MD_read
+#define _MD_WRITE _MD_write
+#define _MD_WRITEV _MD_writev
+#define _MD_LSEEK _MD_lseek
+#define _MD_LSEEK64 _MD_lseek64
+#define _MD_FSYNC _MD_fsync
+#define _MD_DELETE _MD_delete
+#define _MD_GETFILEINFO _MD_getfileinfo
+#define _MD_GETFILEINFO64 _MD_getfileinfo64
+#define _MD_GETOPENFILEINFO _MD_getopenfileinfo
+#define _MD_GETOPENFILEINFO64 _MD_getopenfileinfo64
+#define _MD_RENAME _MD_rename
+#define _MD_ACCESS _MD_access
+#define _MD_STAT stat
+#define _MD_MKDIR _MD_mkdir
+#define _MD_MAKE_DIR _MD_mkdir
+#define _MD_RMDIR _MD_rmdir
+#define _MD_PR_POLL _MD_pr_poll
+
+/* Network I/O */
+
+#define _MD_CLOSE_SOCKET _MD_close_socket
+#define _MD_CONNECT _MD_connect
+#define _MD_ACCEPT _MD_accept
+#define _MD_BIND _MD_bind
+#define _MD_LISTEN _MD_listen
+#define _MD_SHUTDOWN _MD_shutdown
+#define _MD_RECV _MD_recv
+#define _MD_SEND _MD_send
+#define _MD_ACCEPT_READ _MD_accept_read
+#define _MD_GETSOCKNAME _MD_getsockname
+#define _MD_GETPEERNAME _MD_getpeername
+#define _MD_GETSOCKOPT _MD_getsockopt
+#define _MD_SETSOCKOPT _MD_setsockopt
+#define _MD_RECVFROM _MD_recvfrom
+#define _MD_SENDTO _MD_sendto
+#define _MD_SOCKETPAIR _MD_socketpair
+#define _MD_SOCKET _MD_socket
+#define _MD_SOCKETAVAILABLE _MD_socketavailable
+#define _MD_PIPEAVAILABLE _MD_socketavailable
+
+#define _MD_GET_SOCKET_ERROR()	(errno)
+#define _MD_GETHOSTNAME _MD_gethostname
+
+#define _MD_SELECT select
+
+/* Process management */
+
+#define _MD_CREATE_PROCESS _MD_create_process
+#define _MD_DETACH_PROCESS _MD_detach_process
+#define _MD_WAIT_PROCESS _MD_wait_process
+#define _MD_KILL_PROCESS _MD_kill_process
+
+/* Atomic data operations */
+
+// #define _MD_INIT_ATOMIC _MD_init_atomic
+// #define _MD_ATOMIC_INCREMENT _MD_atomic_increment
+// #define _MD_ATOMIC_DECREMENT _MD_atomic_decrement
+// #define _MD_ATOMIC_SET _MD_atomic_set
+
+/* memory management */
+
+#define _MD_INIT_SEGS _MD_init_segs
+#define _MD_ALLOC_SEGMENT _MD_alloc_segment
+#define _MD_FREE_SEGMENT _MD_free_segment
+
+/* Memory mapped file I/O */
+
+#define _MD_CREATE_FILE_MAP _MD_create_file_map
+#define _MD_GET_MEM_MAP_ALIGNMENT _MD_get_mem_map_alignment
+#define _MD_MEM_MAP _MD_mem_map
+#define _MD_MEM_UNMAP _MD_mem_unmap
+#define _MD_CLOSE_FILE_MAP _MD_close_file_map
+
+/* Time related */
+
+#define _MD_NOW _MD_now
+#define _MD_INTERVAL_INIT _MD_interval_init
+#define _MD_GET_INTERVAL _MD_get_interval
+#define _MD_INTERVAL_PER_SEC _MD_interval_per_sec
+
+/* File locking */
+
+#define _MD_LOCKFILE _MD_lockfile
+#define _MD_TLOCKFILE _MD_tlockfile
+#define _MD_UNLOCKFILE _MD_unlockfile
+
+/**
+ * Prototypes for machine dependent function implementations. (Too bad
+ * NSPR's MD system blows so much that we have to reiterate every stinking
+ * thing we implement here in our MD header file.)
+ */
+
+/* Miscellaneous */
+
+NSPR_API(void) _MD_cleanup_before_exit(void);
+NSPR_API(void) _MD_exit(PRIntn status);
+
+NSPR_API(char*) _MD_get_env(const char *name);
+NSPR_API(PRIntn) _MD_put_env(const char *name);
+
+NSPR_API(void) _MD_early_init(void);
+NSPR_API(void) _MD_final_init(void);
+
+/* CPU Stuff */
+
+NSPR_API(void) _MD_init_cpus();
+NSPR_API(void) _MD_wakeup_cpus();
+NSPR_API(void) _MD_start_interrupts(void);
+NSPR_API(void) _MD_stop_interrupts(void);
+NSPR_API(void) _MD_disable_clock_interrupts(void);
+NSPR_API(void) _MD_block_clock_interrupts(void);
+NSPR_API(void) _MD_unblock_clock_interrupts(void);
+NSPR_API(void) _MD_clock_interrupt(void);
+// NSPR_API(void) _MD_init_stack(PRThreadStack *ts, PRIntn redzone);
+// NSPR_API(void) _MD_clear_stack(PRThreadStack* ts);
+// NSPR_API(PRInt32) _MD_get_intsoff(void);
+// NSPR_API(void) _MD_set_intsoff(PRInt32 _val);
+// NSPR_API(_PRCPU*) _MD_current_cpu(void);
+// NSPR_API(void) _MD_set_current_cpu(_PRCPU *cpu);
+// NSPR_API(void) _MD_init_running_cpu(_PRCPU *cpu);
+NSPR_API(PRInt32) _MD_pause_cpu(PRIntervalTime timeout);
+
+/* Thread stuff */
+
+// NSPR_API(PRThread*) _MD_current_thread(void);
+NSPR_API(PRThread*) _MD_get_attached_thread(void);
+NSPR_API(PRThread*) _MD_last_thread(void);
+NSPR_API(void) _MD_set_current_thread(PRThread *thread);
+NSPR_API(void) _MD_set_last_thread(PRThread *thread);
+NSPR_API(PRStatus) _MD_init_thread(PRThread *thread);
+NSPR_API(void) _MD_exit_thread(PRThread *thread);
+NSPR_API(PRStatus) _MD_init_attached_thread(PRThread *thread);
+
+NSPR_API(void) _MD_suspend_thread(PRThread *thread);
+NSPR_API(void) _MD_resume_thread(PRThread *thread);
+// NSPR_API(void) _MD_suspend_cpu(_PRCPU  *cpu);
+// NSPR_API(void) _MD_resume_cpu(_PRCPU  *cpu);
+NSPR_API(void) _MD_begin_suspend_all(void);
+NSPR_API(void) _MD_end_suspend_all(void);
+NSPR_API(void) _MD_begin_resume_all(void);
+NSPR_API(void) _MD_end_resume_all(void);
+
+NSPR_API(void *) _MD_get_sp(PRThread *thread);
+
+NSPR_API(void) _MD_clean_thread(PRThread *thread);
+NSPR_API(void) _MD_create_primordial_user_thread(PRThread *);
+NSPR_API(PRThread*) _MD_create_user_thread(PRUint32 stacksize, void (*start)(void *), void *arg);
+NSPR_API(void) _MD_init_primordial_thread(PRThread *thread);
+NSPR_API(PRStatus) _MD_create_thread(PRThread *thread, void (*start)(void *), PRThreadPriority priority, PRThreadScope scope, PRThreadState state, PRUint32 stackSize);
+NSPR_API(void) _MD_yield(void);
+NSPR_API(void) _MD_set_priority(struct _MDThread *md, PRThreadPriority newPri);
+
+NSPR_API(void) _MD_suspendall(void);
+NSPR_API(void) _MD_resumeall(void);
+
+NSPR_API(void) _MD_init_context(PRThread *thread, char *top, void (*start) (void), PRBool *status);
+NSPR_API(void) _MD_switch_context(PRThread *thread);
+NSPR_API(void) _MD_restore_context(PRThread *thread);
+
+NSPR_API(PRStatus) _MD_wait(PRThread *, PRIntervalTime timeout);
+NSPR_API(PRStatus) _MD_wakeup_waiter(PRThread *);
+
+NSPR_API(PRInt32) _MD_setthreadaffinitymask(PRThread *thread, PRUint32 mask );
+NSPR_API(PRInt32) _MD_getthreadaffinitymask(PRThread *thread, PRUint32 *mask);
+
+/* Thread Synchronization */
+
+NSPR_API(void) _MD_init_locks(void);
+NSPR_API(PRStatus) _MD_new_lock(struct _MDLock *md);
+NSPR_API(void) _MD_free_lock(struct _MDLock *md);
+NSPR_API(void) _MD_lock(struct _MDLock *md);
+NSPR_API(PRIntn) _MD_test_and_lock(struct _MDLock *md);
+NSPR_API(void) _MD_unlock(struct _MDLock *md);
+NSPR_API(void) _MD_ioq_lock(void);
+NSPR_API(void) _MD_ioq_unlock(void);
+NSPR_API(void) _MD_new_sem(struct _MDSemaphore *md, PRUintn value);
+NSPR_API(void) _MD_destroy_sem(struct _MDSemaphore *md);
+NSPR_API(PRStatus) _MD_timed_wait_sem(struct _MDSemaphore *md, PRIntervalTime timeout);
+NSPR_API(PRStatus) _MD_wait_sem(struct _MDSemaphore *md);
+NSPR_API(void) _MD_post_sem(struct _MDSemaphore *md);
+// NSPR_API(PRInt32) _MD_new_cv(struct _MDCVar *md);
+// NSPR_API(void) _MD_free_cv(struct _MDCVar *md);
+// NSPR_API(void) _MD_wait_cv(struct _MDCVar *mdCVar, struct _MDLock *mdLock, PRIntervalTime timeout);
+// NSPR_API(void) _MD_notify_cv(struct _MDCVar *md, struct _MDLock *lock);
+// NSPR_API(void) _MD_notifyall_cv(struct _MDCVar *md, struct _MDLock *lock);
+
+/* File I/O */
+
+// NSPR_API(void) _MD_init_io(void);
+NSPR_API(PRStatus) _MD_open_dir(struct _MDDir *md,const char *name);
+NSPR_API(char *) _MD_read_dir(struct _MDDir *md, PRIntn flags);
+NSPR_API(PRInt32) _MD_close_dir(struct _MDDir *md);
+NSPR_API(void) _MD_make_nonblock(PRFileDesc *fd);
+NSPR_API(void) _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported);
+NSPR_API(void) _MD_query_fd_inheritable(PRFileDesc *fd);
+NSPR_API(PRInt32) _MD_open(const char *name, PRIntn osflags, PRIntn mode);
+NSPR_API(PRInt32) _MD_close_file(PRInt32 osfd);
+NSPR_API(PRInt32) _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount);
+NSPR_API(PRInt32) _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount);
+NSPR_API(PRInt32) _MD_writev(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_lseek(PRFileDesc *fd, PRInt32 offset, int whence);
+NSPR_API(PRInt64) _MD_lseek64(PRFileDesc *fd, PRInt64 offset, int whence);
+NSPR_API(PRInt32) _MD_fsync(PRFileDesc *fd);
+NSPR_API(PRInt32) _MD_delete(const char *name);
+NSPR_API(PRInt32) _MD_getfileinfo(const char *fn, PRFileInfo *info);
+NSPR_API(PRInt32) _MD_getfileinfo64(const char *fn, PRFileInfo64 *info);
+NSPR_API(PRInt32) _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info);
+NSPR_API(PRInt32) _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info);
+NSPR_API(PRInt32) _MD_rename(const char *from, const char *to);
+NSPR_API(PRInt32) _MD_access(const char *name, PRIntn how);
+NSPR_API(PRInt32) _MD_stat(const char *name, struct stat *buf);
+NSPR_API(PRInt32) _MD_mkdir(const char *name, PRIntn mode);
+NSPR_API(PRInt32) _MD_rmdir(const char *name);
+NSPR_API(PRInt32) _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout);
+
+/* Network I/O */
+NSPR_API(PRInt32) _MD_close_socket(PRInt32 osfd);
+NSPR_API(PRInt32) _MD_connect(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen);
+NSPR_API(PRInt32) _MD_listen(PRFileDesc *fd, PRIntn backlog);
+NSPR_API(PRInt32) _MD_shutdown(PRFileDesc *fd, PRIntn how);
+NSPR_API(PRInt32) _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_accept_read(PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout);
+// NSPR_API(PRInt32) _MD_fast_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout, PRBool fast, _PR_AcceptTimeoutCallback callback, void *callbackArg);
+// NSPR_API(PRInt32) _MD_fast_accept_read(PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout, PRBool fast, _PR_AcceptTimeoutCallback callback, void *callbackArg);
+// NSPR_API(void) _MD_update_accept_context(PRInt32 s, PRInt32 ls);
+NSPR_API(PRStatus) _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
+NSPR_API(PRStatus) _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
+NSPR_API(PRStatus) _MD_getsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen);
+NSPR_API(PRStatus) _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen);
+NSPR_API(PRInt32) _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
+NSPR_API(PRInt32) _MD_socketpair(int af, int type, int flags, PRInt32 *osfd);
+NSPR_API(PRInt32) _MD_socket(int af, int type, int flags);
+NSPR_API(PRInt32) _MD_socketavailable(PRFileDesc *fd);
+
+// NSPR_API(PRInt32) _MD_get_socket_error(void);
+NSPR_API(PRStatus) _MD_gethostname(char *name, PRUint32 namelen);
+
+/* Process management */
+
+NSPR_API(PRProcess *) _MD_create_process(const char *path, char *const *argv, char *const *envp, const PRProcessAttr *attr);
+NSPR_API(PRStatus) _MD_detach_process(PRProcess *process);
+NSPR_API(PRStatus) _MD_wait_process(PRProcess *process, PRInt32 *exitCode);
+NSPR_API(PRStatus) _MD_kill_process(PRProcess *process);
+
+/* Atomic data operations */
+
+// NSPR_API(void) _MD_init_atomic(void);
+// NSPR_API(PRInt32) _MD_atomic_increment(PRInt32 *);
+// NSPR_API(PRInt32) _MD_atomic_decrement(PRInt32 *);
+// NSPR_API(PRInt32) _MD_atomic_set(PRInt32 *, PRInt32);
+
+/* Memory management */
+
+NSPR_API(void) _MD_init_segs(void);
+NSPR_API(PRStatus) _MD_alloc_segment(PRSegment *seg, PRUint32 size, void *vaddr);
+NSPR_API(void) _MD_free_segment(PRSegment *seg);
+
+/* Memory mapped file I/O */
+
+NSPR_API(PRStatus) _MD_create_file_map(PRFileMap *fmap, PRInt64 size);
+NSPR_API(PRInt32) _MD_get_mem_map_alignment(void);
+NSPR_API(void *) _MD_mem_map(PRFileMap *fmap, PRInt64 offset, PRUint32 len);
+NSPR_API(PRStatus) _MD_mem_unmap(void *addr, PRUint32 size);
+NSPR_API(PRStatus) _MD_close_file_map(PRFileMap *fmap);
+
+/* Time related */
+
+NSPR_API(PRTime) _MD_now(void);
+NSPR_API(void) _MD_interval_init(void);
+NSPR_API(PRIntervalTime) _MD_get_interval(void);
+NSPR_API(PRIntervalTime) _MD_interval_per_sec(void);
+
+/* File locking */
+
+NSPR_API(PRStatus) _MD_lockfile(PRInt32 osfd);
+NSPR_API(PRStatus) _MD_tlockfile(PRInt32 osfd);
+NSPR_API(PRStatus) _MD_unlockfile(PRInt32 osfd);
+
+#endif /* _nspr_beos_defs_h___*/

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_bsdi.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_bsdi.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,198 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef BSDI
+#define BSDI
+#endif
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#if defined(__i386__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__sparc__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#else
+
+#error "Unknown CPU architecture"
+
+#endif
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_bsdi.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_bsdi.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,214 @@
+/* -*- 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 nspr_bsdi_defs_h___
+#define nspr_bsdi_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#include <sys/param.h>	/* for _BSDI_VERSION */
+
+#define PR_LINKER_ARCH	"bsdi"
+#define _PR_SI_SYSNAME "BSDI"
+#if defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#else
+#error "Unknown CPU architecture"
+#endif
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#define HAVE_BSD_FLOCK
+#define NEED_TIME_R
+#define _PR_HAVE_SOCKADDR_LEN
+#define _PR_NO_LARGE_FILES
+
+#define USE_SETJMP
+
+/* BSD/OS 4.3 and newer all have IPv6 support */
+#if _BSDI_VERSION >= 200105
+#define _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#endif
+
+#ifndef _PR_PTHREADS
+
+#include <setjmp.h>
+
+#if defined(_PR_BSDI_JMPBUF_IS_ARRAY)
+#define _MD_GET_SP(_t)    (_t)->md.context[2] 
+#elif defined(_PR_BSDI_JMPBUF_IS_STRUCT)
+#define _MD_GET_SP(_t)    (_t)->md.context[0].jb_esp
+#else
+#error "Unknown BSDI jmp_buf type"
+#endif
+
+#define PR_NUM_GCREGS	_JBLEN
+#define PR_CONTEXT_TYPE	jmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	  \
+{								  \
+    *status = PR_TRUE; \
+    if (setjmp(CONTEXT(_thread))) {				  \
+	_main();					  \
+    }								  \
+    _MD_GET_SP(_thread) = (int) (_sp - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;	     \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    longjmp(CONTEXT(_thread), 1);    \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+#endif /* ! _PR_PTHREADS */
+
+#define _MD_EARLY_INIT          _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+
+#include <sys/syscall.h>
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#endif /* nspr_bsdi_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_darwin.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_darwin.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,145 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#define PR_AF_INET6 30  /* same as AF_INET6 */
+
+#if defined(i386)
+#undef IS_BIG_ENDIAN
+#define  IS_LITTLE_ENDIAN 1
+#else
+#undef IS_LITTLE_ENDIAN
+#define  IS_BIG_ENDIAN 1
+#endif
+
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+#define PR_BITS_PER_DWORD   64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_darwin.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_darwin.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,287 @@
+/* -*- 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 nspr_darwin_defs_h___
+#define nspr_darwin_defs_h___
+
+#include "prthread.h"
+
+#include <sys/syscall.h>
+
+#ifdef XP_MACOSX
+#include <AvailabilityMacros.h>
+#endif
+
+#define PR_LINKER_ARCH	"darwin"
+#define _PR_SI_SYSNAME  "DARWIN"
+#ifdef __i386__
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__ppc__)
+#define _PR_SI_ARCHITECTURE "ppc"
+#endif
+#define PR_DLL_SUFFIX		".dylib"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_MACH_DYLD
+#define _PR_HAVE_SOCKADDR_LEN  
+#define _PR_STAT_HAS_ST_ATIMESPEC
+#define _PR_NO_LARGE_FILES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+
+#define _PR_INET6
+/*
+ * I'd prefer to use getipnodebyname and getipnodebyaddr but the
+ * getipnodebyname(3) man page on Mac OS X 10.2 says they are not
+ * thread-safe.  AI_V4MAPPED|AI_ADDRCONFIG doesn't work either.
+ */
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_HAVE_GETADDRINFO
+/*
+ * On Mac OS X 10.2, gethostbyaddr fails with h_errno=NO_RECOVERY
+ * if you pass an IPv4-mapped IPv6 address to it.
+ */
+#define _PR_GHBA_DISALLOW_V4MAPPED
+#ifdef XP_MACOSX
+#if !defined(MAC_OS_X_VERSION_10_3) || \
+    MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
+/*
+ * socket(AF_INET6) fails with EPROTONOSUPPORT on Mac OS X 10.1.
+ * IPv6 under OS X 10.2 and below is not complete (see bug 222031).
+ */
+#define _PR_INET6_PROBE
+#endif /* DT < 10.3 */
+#if defined(MAC_OS_X_VERSION_10_2) && \
+    MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_2
+/* Mac OS X 10.2 has inet_ntop and inet_pton. */
+#define _PR_HAVE_INET_NTOP
+#endif /* DT >= 10.2 */
+#endif /* XP_MACOSX */
+#define _PR_IPV6_V6ONLY_PROBE
+/* The IPV6_V6ONLY socket option is not defined on Mac OS X 10.1. */
+#ifndef IPV6_V6ONLY
+#define IPV6_V6ONLY 27
+#endif
+
+#if defined(__ppc__)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_DarwinPPC_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT(val)   _PR_DarwinPPC_AtomicIncrement(val)
+extern PRInt32 _PR_DarwinPPC_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT(val)   _PR_DarwinPPC_AtomicDecrement(val)
+extern PRInt32 _PR_DarwinPPC_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET(val, newval) _PR_DarwinPPC_AtomicSet(val, newval)
+extern PRInt32 _PR_DarwinPPC_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD(ptr, val)    _PR_DarwinPPC_AtomicAdd(ptr, val)
+#elif defined(__i386__)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_Darwin_x86_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT(val)   _PR_Darwin_x86_AtomicIncrement(val)
+extern PRInt32 _PR_Darwin_x86_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT(val)   _PR_Darwin_x86_AtomicDecrement(val)
+extern PRInt32 _PR_Darwin_x86_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET(val, newval) _PR_Darwin_x86_AtomicSet(val, newval)
+extern PRInt32 _PR_Darwin_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD(ptr, val)    _PR_Darwin_x86_AtomicAdd(ptr, val)
+#endif /* __i386__ */
+
+#define USE_SETJMP
+
+#if !defined(_PR_PTHREADS)
+
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	jmp_buf
+
+#define CONTEXT(_th)       ((_th)->md.context)
+#define _MD_GET_SP(_th)    (((struct sigcontext *) (_th)->md.context)->sc_onstack)
+#define PR_NUM_GCREGS	    _JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (setjmp(CONTEXT(_thread))) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) {  \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    longjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+extern PRStatus _MD_InitializeThread(PRThread *thread);
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+extern PRStatus _MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize);
+extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri);
+extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout);
+extern PRStatus _MD_WAKEUP_WAITER(PRThread *);
+extern void _MD_YIELD(void);
+
+#endif /* ! _PR_PTHREADS */
+
+#define _MD_EARLY_INIT          _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL        _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC    _PR_UNIX_TicksPerSecond
+
+extern void             _MD_EarlyInit(void);
+extern PRIntervalTime   _PR_UNIX_GetInterval(void);
+extern PRIntervalTime   _PR_UNIX_TicksPerSecond(void);
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+/* For writev() */
+#include <sys/uio.h>
+
+#endif /* nspr_darwin_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_dgux.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_dgux.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,138 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef DGUX
+#define DGUX
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_dgux.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_dgux.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,221 @@
+/* -*- 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 nspr_dgux_defs_h___
+#define nspr_dgux_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"dgux"
+#define _PR_SI_SYSNAME		"DGUX"
+#define _PR_SI_ARCHITECTURE	"x86"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE	 	0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_NETCONFIG
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define _PR_NEED_STRCASECMP
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP setjmp
+#define _LONGJMP longjmp
+#define _PR_CONTEXT_TYPE         jmp_buf
+#define _MD_GET_SP(_t)           (_t)->md.context[4]
+#define _PR_NUM_GCREGS	_JBLEN
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+{								  \
+    *status = PR_TRUE; \
+    if(_SETJMP(CONTEXT(_thread))) (*_main)(); \
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!_SETJMP(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;	     \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    _LONGJMP(CONTEXT(_thread), 1);    \
+}
+
+/* Machine-dependent (MD) data structures.
+ * Don't use SVR4 native threads (yet). 
+ */
+
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+                fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+    struct pollfd *ioq_pollfds;
+    int ioq_pollfds_size;
+#endif  /* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)               ((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)       ((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)       ((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)      ((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)      ((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)  ((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)  ((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)       ((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)      ((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)      ((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)       ((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)  ((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)  32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+ * The following are copied from _sunos.h, _aix.h.  This means
+ * some of them should probably be moved into _unixos.h.  But
+ * _irix.h seems to be quite different in regard to these macros.
+ */
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *execptfds, struct timeval *timeout);
+#define _MD_SELECT _select
+
+#define _MD_POLL _poll
+#include <poll.h>
+#include <stropts.h>
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+
+#endif /* nspr_dgux_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_freebsd.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_freebsd.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,338 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef FREEBSD
+#define FREEBSD
+#endif
+
+#define PR_AF_INET6 28  /* same as AF_INET6 */
+
+#if defined(__i386__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(__alpha__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#elif defined(__sparc__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define	HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#elif defined(__ia64__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#elif defined(__amd64__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#else
+
+#error "Unknown CPU architecture"
+
+#endif
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_freebsd.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_freebsd.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,278 @@
+/* -*- 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 nspr_freebsd_defs_h___
+#define nspr_freebsd_defs_h___
+
+#include "prthread.h"
+
+#if __FreeBSD__ >= 2
+#include <osreldate.h>  /* for __FreeBSD_version */
+#endif
+#include <sys/syscall.h>
+
+#define PR_LINKER_ARCH	"freebsd"
+#define _PR_SI_SYSNAME  "FREEBSD"
+#if defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__alpha__)
+#define _PR_SI_ARCHITECTURE "alpha"
+#elif defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#elif defined(__ia64__)
+#define _PR_SI_ARCHITECTURE "ia64"
+#elif defined(__amd64__)
+#define _PR_SI_ARCHITECTURE "amd64"
+#else
+#error "Unknown CPU architecture"
+#endif
+#if defined(__ELF__)
+#define PR_DLL_SUFFIX          ".so"
+#else
+#define PR_DLL_SUFFIX          ".so.1.0"
+#endif
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_DLFCN
+#define _PR_HAVE_SOCKADDR_LEN
+#define _PR_STAT_HAS_ST_ATIMESPEC
+#define _PR_NO_LARGE_FILES
+
+#if defined(_PR_PTHREADS)
+#if __FreeBSD_version >= 400008
+/*
+ * libc_r before this version of FreeBSD doesn't have poll().
+ * Although libc has poll(), it is not thread-safe so we can't
+ * use it in the pthreads version.
+ */
+#define _PR_POLL_AVAILABLE
+#endif
+#else
+#if __FreeBSD_version >= 300000
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#endif
+#endif
+
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+
+#if __FreeBSD_version >= 400014
+#define _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#define _PR_IPV6_V6ONLY_PROBE
+#endif
+
+#define USE_SETJMP
+
+#ifndef _PR_PTHREADS
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	sigjmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+#define _MD_GET_SP(_th)    (_th)->md.context[0]._sjb[2]
+#define PR_NUM_GCREGS	_JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (sigsetjmp(CONTEXT(_thread), 1)) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!sigsetjmp(CONTEXT(_thread), 1)) {  \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    siglongjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+extern PRStatus _MD_InitializeThread(PRThread *thread);
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+extern PRStatus _MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize);
+extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri);
+extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout);
+extern PRStatus _MD_WAKEUP_WAITER(PRThread *);
+extern void _MD_YIELD(void);
+
+#endif /* ! _PR_PTHREADS */
+
+extern void _MD_EarlyInit(void);
+extern PRIntervalTime _PR_UNIX_GetInterval(void);
+extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+#if defined(_PR_POLL_AVAILABLE)
+#include <poll.h>
+#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout)
+#endif
+
+/* freebsd has INADDR_LOOPBACK defined, but in /usr/include/rpc/types.h, and I didn't
+   want to be including that.. */
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK         (u_long)0x7F000001
+#endif
+
+/* For writev() */
+#include <sys/uio.h>
+
+#endif /* nspr_freebsd_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_hpux.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_hpux.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,273 @@
+/* -*- 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 nspr_xhppa_defs_h___
+#define nspr_xhppa_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH    "hpux"
+#define _PR_SI_SYSNAME   "HPUX"
+#ifdef __ia64
+#define _PR_SI_ARCHITECTURE "ia64"
+#define PR_DLL_SUFFIX        ".so"
+#else
+#define _PR_SI_ARCHITECTURE "hppa"
+#define PR_DLL_SUFFIX        ".sl"
+#endif
+
+#define _PR_VMBASE        0x30000000 
+#define _PR_STACK_VMBASE    0x50000000
+/*
+ * _USE_BIG_FDS increases the size of fd_set from 256 bytes to
+ * about 7500 bytes.  PR_Poll allocates three fd_sets on the
+ * stack, so it is safer to also increase the default thread
+ * stack size.
+ */
+#define _MD_DEFAULT_STACK_SIZE    (2*65536L)
+#define _MD_MINIMUM_STACK_SIZE    (2*65536L)
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#define NEED_TIME_R
+
+#define HAVE_STACK_GROWING_UP
+#undef	HAVE_WEAK_IO_SYMBOLS
+#undef	HAVE_WEAK_MALLOC_SYMBOLS
+#define	HAVE_DLL
+#ifdef IS_64
+#define USE_DLFCN
+#else
+#define USE_HPSHL
+#endif
+#ifndef HAVE_STRERROR
+#define HAVE_STRERROR
+#endif
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#define _PR_HAVE_POSIX_SEMAPHORES
+#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
+
+#if defined(__ia64)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT          _PR_ia64_AtomicIncrement
+extern PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT          _PR_ia64_AtomicDecrement
+extern PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD                _PR_ia64_AtomicAdd
+extern PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET                _PR_ia64_AtomicSet
+#endif
+
+#ifdef _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#endif
+
+#if !defined(_PR_PTHREADS)
+
+#include <syscall.h>
+#include <setjmp.h>
+
+#define USE_SETJMP
+
+#define _MD_GET_SP(_t) (*((int *)((_t)->md.jb) + 1))
+#define PR_NUM_GCREGS _JBLEN
+/* Caveat: This makes jmp_buf full of doubles. */
+#define CONTEXT(_th) ((_th)->md.jb)
+
+    /* Stack needs two frames (64 bytes) at the bottom */ \
+#define _MD_SET_THR_SP(_t, _sp)     ((_MD_GET_SP(_t)) = (int) (_sp + 64 *2))
+#define SAVE_CONTEXT(_th)           _setjmp(CONTEXT(_th))
+#define GOTO_CONTEXT(_th)           _longjmp(CONTEXT(_th), 1)
+
+#if !defined(PTHREADS_USER)
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+{ \
+    *(status) = PR_TRUE; \
+    if (_setjmp(CONTEXT(_thread))) (*_main)(); \
+    /* Stack needs two frames (64 bytes) at the bottom */ \
+    (_MD_GET_SP(_thread)) = (int) ((_sp) + 64*2); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread) \
+    if (!_setjmp(CONTEXT(_thread))) { \
+    (_thread)->md.errcode = errno; \
+    _PR_Schedule(); \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{ \
+    errno = (_thread)->md.errcode; \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    _longjmp(CONTEXT(_thread), 1); \
+}
+
+/* Machine-dependent (MD) data structures.  HP-UX has no native threads. */
+
+struct _MDThread {
+    jmp_buf jb;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+#else /* PTHREADS_USER	*/
+
+#include "_nspr_pthread.h"
+
+#endif /* PTHREADS_USER	*/
+
+#endif  /* !defined(_PR_PTHREADS) */
+
+#if !defined(PTHREADS_USER)
+#define _MD_EARLY_INIT                 	_MD_EarlyInit
+#define _MD_FINAL_INIT					_PR_UnixInit
+#endif 
+
+#if defined(HPUX_LW_TIMER)
+extern void _PR_HPUX_LW_IntervalInit(void);
+extern PRIntervalTime _PR_HPUX_LW_GetInterval(void);
+#define _MD_INTERVAL_INIT                 _PR_HPUX_LW_IntervalInit
+#define _MD_GET_INTERVAL                  _PR_HPUX_LW_GetInterval
+#define _MD_INTERVAL_PER_SEC()            1000
+#else
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+#endif
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+#include <poll.h>
+#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout)
+
+#ifdef HPUX11
+extern void _MD_hpux_map_sendfile_error(int err);
+#endif /* HPUX11 */
+
+#endif /* nspr_xhppa_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_hpux32.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_hpux32.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,142 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef HPUX
+#define HPUX
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+
+#define PR_AF_INET6 22  /* same as AF_INET6 */
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BYTES_PER_WORD_LOG2 2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#define	HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_hpux64.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_hpux64.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,143 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef HPUX
+#define HPUX
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define IS_64
+
+#define PR_AF_INET6 22  /* same as AF_INET6 */
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BYTES_PER_WORD_LOG2 3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define	HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_irix.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_irix.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,470 @@
+/* -*- 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 nspr_irix_defs_h___
+#define nspr_irix_defs_h___
+
+#define _PR_HAVE_ATOMIC_CAS
+
+/*
+ * MipsPro assembler defines _LANGUAGE_ASSEMBLY
+ */
+#ifndef _LANGUAGE_ASSEMBLY
+
+#include "prclist.h"
+#include "prthread.h"
+#include <sys/ucontext.h>
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH          "irix"
+#define _PR_SI_SYSNAME          "IRIX"
+#define _PR_SI_ARCHITECTURE     "mips"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE        0x50000000
+#define _PR_NUM_GCREGS          9
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#define _MD_DEFAULT_STACK_SIZE  65536L
+#define _MD_MIN_STACK_SIZE      16384L
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_WEAK_IO_SYMBOLS
+#define HAVE_WEAK_MALLOC_SYMBOLS
+#define HAVE_DLL
+#define USE_DLFCN
+#define _PR_HAVE_ATOMIC_OPS
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ST_ATIM
+#define _PR_HAVE_OFF64_T
+#define HAVE_POINTER_LOCALTIME_R
+#define _PR_HAVE_POSIX_SEMAPHORES
+#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
+
+#ifdef _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_HAVE_GETADDRINFO
+#endif
+
+/* Initialization entry points */
+NSPR_API(void) _MD_EarlyInit(void);
+#define _MD_EARLY_INIT _MD_EarlyInit
+
+NSPR_API(void) _MD_IrixInit(void);
+#define _MD_FINAL_INIT _MD_IrixInit
+
+#define _MD_INIT_IO()
+
+/* Timer operations */
+NSPR_API(PRIntervalTime) _MD_IrixGetInterval(void);
+#define _MD_GET_INTERVAL _MD_IrixGetInterval
+
+NSPR_API(PRIntervalTime) _MD_IrixIntervalPerSec(void);
+#define _MD_INTERVAL_PER_SEC _MD_IrixIntervalPerSec
+
+/* GC operations */
+NSPR_API(void *) _MD_GetSP(PRThread *thread);
+#define    _MD_GET_SP _MD_GetSP
+
+/* The atomic operations */
+#include <mutex.h>
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT(val) add_then_test((unsigned long*)val, 1)
+#define _MD_ATOMIC_ADD(ptr, val) add_then_test((unsigned long*)ptr, (unsigned long)val)
+#define _MD_ATOMIC_DECREMENT(val) add_then_test((unsigned long*)val, 0xffffffff)
+#define _MD_ATOMIC_SET(val, newval) test_and_set((unsigned long*)val, newval)
+
+#if defined(_PR_PTHREADS)
+#else /* defined(_PR_PTHREADS) */
+
+/************************************************************************/
+
+#include <setjmp.h>
+#include <errno.h>
+#include <unistd.h>
+#include <bstring.h>
+#include <sys/time.h>
+#include <ulocks.h>
+#include <sys/prctl.h>
+
+
+/*
+ * Data region private to each sproc. This region is setup by calling
+ * mmap(...,MAP_LOCAL,...). The private data is mapped at the same
+ * address in every sproc, but every sproc gets a private mapping.
+ *
+ * Just make sure that this structure fits in a page, as only one page
+ * is allocated for the private region.
+ */
+struct sproc_private_data {
+    struct PRThread *me;
+    struct _PRCPU *cpu;
+    struct PRThread *last;
+    PRUintn intsOff;
+	int		sproc_pid;
+};
+
+extern char *_nspr_sproc_private;
+
+#define _PR_PRDA() ((struct sproc_private_data *) _nspr_sproc_private)
+#define _MD_SET_CURRENT_THREAD(_thread) _PR_PRDA()->me = (_thread)
+#define _MD_THIS_THREAD() (_PR_PRDA()->me)
+#define _MD_LAST_THREAD() (_PR_PRDA()->last)
+#define _MD_SET_LAST_THREAD(_thread) _PR_PRDA()->last = (_thread)
+#define _MD_CURRENT_CPU() (_PR_PRDA()->cpu)
+#define _MD_SET_CURRENT_CPU(_cpu) _PR_PRDA()->cpu = (_cpu)
+#define _MD_SET_INTSOFF(_val) (_PR_PRDA()->intsOff = _val)
+#define _MD_GET_INTSOFF() (_PR_PRDA()->intsOff)
+
+#define _MD_SET_SPROC_PID(_val) (_PR_PRDA()->sproc_pid = _val)
+#define _MD_GET_SPROC_PID() (_PR_PRDA()->sproc_pid)
+
+NSPR_API(struct PRThread*) _MD_get_attached_thread(void);
+NSPR_API(struct PRThread*) _MD_get_current_thread(void);
+#define _MD_GET_ATTACHED_THREAD()	_MD_get_attached_thread()
+#define _MD_CURRENT_THREAD()	_MD_get_current_thread()
+
+#define _MD_CHECK_FOR_EXIT() {					\
+		if (_pr_irix_exit_now) {				\
+			_PR_POST_SEM(_pr_irix_exit_sem);	\
+			_MD_Wakeup_CPUs();					\
+			_exit(0);							\
+		}										\
+	}
+		
+#define _MD_ATTACH_THREAD(threadp)
+
+#define _MD_SAVE_ERRNO(_thread)			(_thread)->md.errcode = errno;
+#define _MD_RESTORE_ERRNO(_thread)		errno = (_thread)->md.errcode;
+
+extern struct _PRCPU  *_pr_primordialCPU;
+extern usema_t *_pr_irix_exit_sem;
+extern PRInt32 _pr_irix_exit_now;
+extern int _pr_irix_primoridal_cpu_fd[];
+extern PRInt32 _pr_irix_process_exit;
+extern PRInt32 _pr_irix_process_exit_code;
+
+/* Thread operations */
+#define _PR_LOCK_HEAP()	{						\
+			PRIntn _is;					\
+				if (_pr_primordialCPU) {		\
+				if (_MD_GET_ATTACHED_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_MD_GET_ATTACHED_THREAD()))	\
+						_PR_INTSOFF(_is); 	\
+					_PR_LOCK(_pr_heapLock);		\
+				}
+
+#define _PR_UNLOCK_HEAP() 	if (_pr_primordialCPU)	{		\
+					_PR_UNLOCK(_pr_heapLock);	\
+				if (_MD_GET_ATTACHED_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_MD_GET_ATTACHED_THREAD()))	\
+						_PR_INTSON(_is);	\
+				}					\
+			  }
+
+#define _PR_OPEN_POLL_SEM(_sem)  usopenpollsema(_sem, 0666)
+#define _PR_WAIT_SEM(_sem) uspsema(_sem)
+#define _PR_POST_SEM(_sem) usvsema(_sem)
+
+#define _MD_CVAR_POST_SEM(threadp)	usvsema((threadp)->md.cvar_pollsem)
+
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+struct _MDLock {
+    ulock_t lock;
+	usptr_t *arena;
+};
+
+/*
+ * disable pre-emption for the LOCAL threads when calling the arena lock
+ * routines
+ */
+
+#define _PR_LOCK(lock) {						\
+		PRIntn _is;						\
+		PRThread *me = _MD_GET_ATTACHED_THREAD();			\
+		if (me && !_PR_IS_NATIVE_THREAD(me))			\
+			_PR_INTSOFF(_is); 				\
+		ussetlock(lock);					\
+		if (me && !_PR_IS_NATIVE_THREAD(me))			\
+			_PR_FAST_INTSON(_is); 				\
+	}
+
+#define _PR_UNLOCK(lock) {						\
+		PRIntn _is;						\
+		PRThread *me = _MD_GET_ATTACHED_THREAD();			\
+		if (me && !_PR_IS_NATIVE_THREAD(me))			\
+			_PR_INTSOFF(_is); 				\
+		usunsetlock(lock);					\
+		if (me && !_PR_IS_NATIVE_THREAD(me))			\
+			_PR_FAST_INTSON(_is); 				\
+	}
+
+NSPR_API(PRStatus) _MD_NEW_LOCK(struct _MDLock *md);
+NSPR_API(void) _MD_FREE_LOCK(struct _MDLock *lockp);
+
+#define _MD_LOCK(_lockp) _PR_LOCK((_lockp)->lock)
+#define _MD_UNLOCK(_lockp) _PR_UNLOCK((_lockp)->lock)
+#define _MD_TEST_AND_LOCK(_lockp) (uscsetlock((_lockp)->lock, 1) == 0)
+
+extern ulock_t _pr_heapLock;
+
+struct _MDThread {
+    jmp_buf jb;
+    usptr_t     *pollsem_arena;
+    usema_t     *cvar_pollsem;
+    PRInt32     cvar_pollsemfd;
+    PRInt32     cvar_pollsem_select;    /* acquire sem by calling select */
+    PRInt32     cvar_wait;              /* if 1, thread is waiting on cvar Q */
+    PRInt32	id;
+    PRInt32	suspending_id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    usema_t *sem;
+};
+
+struct _MDCVar {
+    ulock_t mdcvar_lock;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+
+struct _MDCPU {
+    PRInt32 id;
+    PRInt32 suspending_id;
+    struct _MDCPU_Unix md_unix;
+};
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+    PR_BEGIN_MACRO				      \
+	int *jb = (_thread)->md.jb;		      \
+    *status = PR_TRUE;              \
+	(void) setjmp(jb);			      \
+	(_thread)->md.jb[JB_SP] = (int) ((_sp) - 64); \
+	(_thread)->md.jb[JB_PC] = (int) _main;	      \
+	_thread->no_sched = 0; \
+    PR_END_MACRO
+
+/*
+** Switch away from the current thread context by saving its state and
+** calling the thread scheduler. Reload cpu when we come back from the
+** context switch because it might have changed.
+*
+*  XXX RUNQ lock needed before clearing _PR_NO_SCHED flag, because the
+*      thread may be unr RUNQ?
+*/
+#define _MD_SWITCH_CONTEXT(_thread) \
+    PR_BEGIN_MACRO    \
+    PR_ASSERT(_thread->no_sched); \
+    if (!setjmp(_thread->md.jb)) { \
+        _MD_SAVE_ERRNO(_thread) \
+        _MD_SET_LAST_THREAD(_thread); \
+        _PR_Schedule(); \
+    } else {      \
+        PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \
+            _MD_LAST_THREAD()->no_sched = 0;			\
+    }             \
+    PR_END_MACRO
+
+/*
+** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or
+** initialized by _MD_INIT_CONTEXT.
+*/
+#define _MD_RESTORE_CONTEXT(_newThread) \
+    PR_BEGIN_MACRO \
+    int *jb = (_newThread)->md.jb; \
+    _MD_RESTORE_ERRNO(_newThread) \
+    _MD_SET_CURRENT_THREAD(_newThread); \
+    _newThread->no_sched = 1;		\
+    longjmp(jb, 1); \
+    PR_END_MACRO
+
+NSPR_API(PRStatus) _MD_InitThread(struct PRThread *thread,
+								PRBool wakeup_parent);
+NSPR_API(PRStatus) _MD_InitAttachedThread(struct PRThread *thread,
+									PRBool wakeup_parent);
+#define _MD_INIT_THREAD(thread) 			_MD_InitThread(thread, PR_TRUE)
+#define _MD_INIT_ATTACHED_THREAD(thread)		\
+						_MD_InitAttachedThread(thread, PR_FALSE)
+
+NSPR_API(void) _MD_ExitThread(struct PRThread *thread);
+#define _MD_EXIT_THREAD _MD_ExitThread
+
+NSPR_API(void) _MD_SuspendThread(struct PRThread *thread);
+#define _MD_SUSPEND_THREAD _MD_SuspendThread
+
+NSPR_API(void) _MD_ResumeThread(struct PRThread *thread);
+#define _MD_RESUME_THREAD _MD_ResumeThread
+
+NSPR_API(void) _MD_SuspendCPU(struct _PRCPU *thread);
+#define _MD_SUSPEND_CPU _MD_SuspendCPU
+
+NSPR_API(void) _MD_ResumeCPU(struct _PRCPU *thread);
+#define _MD_RESUME_CPU _MD_ResumeCPU
+
+#define _MD_BEGIN_SUSPEND_ALL()
+#define _MD_END_SUSPEND_ALL()
+#define _MD_BEGIN_RESUME_ALL()
+#define _MD_END_RESUME_ALL()
+
+NSPR_API(void) _MD_InitLocks(void);
+#define _MD_INIT_LOCKS _MD_InitLocks
+
+NSPR_API(void) _MD_CleanThread(struct PRThread *thread);
+#define _MD_CLEAN_THREAD _MD_CleanThread
+
+#define _MD_YIELD()    sginap(0)
+
+/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
+ * awaken a thread which is waiting on a lock or cvar.
+ */
+NSPR_API(PRStatus) _MD_wait(struct PRThread *, PRIntervalTime timeout);
+#define _MD_WAIT _MD_wait
+
+NSPR_API(void) _PR_MD_primordial_cpu();
+NSPR_API(void) _PR_MD_WAKEUP_PRIMORDIAL_CPU();
+
+NSPR_API(PRStatus) _MD_WakeupWaiter(struct PRThread *);
+#define _MD_WAKEUP_WAITER _MD_WakeupWaiter
+
+NSPR_API(void ) _MD_exit(PRIntn status);
+#define _MD_EXIT	_MD_exit
+
+#include "prthread.h"
+
+NSPR_API(void) _MD_SetPriority(struct _MDThread *thread,
+	PRThreadPriority newPri);
+#define _MD_SET_PRIORITY _MD_SetPriority
+
+NSPR_API(PRStatus) _MD_CreateThread(
+                        struct PRThread *thread,
+                        void (*start) (void *),
+                        PRThreadPriority priority,
+                        PRThreadScope scope,
+                        PRThreadState state,
+                        PRUint32 stackSize);
+#define _MD_CREATE_THREAD _MD_CreateThread
+
+extern void _MD_CleanupBeforeExit(void);
+#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit
+
+NSPR_API(void) _PR_MD_PRE_CLEANUP(PRThread *me);
+
+
+/* The following defines the unwrapped versions of select() and poll(). */
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *exceptfds, struct timeval *timeout);
+#define _MD_SELECT	_select
+
+#include <stropts.h>
+#include <poll.h>
+#define _MD_POLL _poll
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+
+
+#define HAVE_THREAD_AFFINITY 1
+
+NSPR_API(PRInt32) _MD_GetThreadAffinityMask(PRThread *unused, PRUint32 *mask);
+#define _MD_GETTHREADAFFINITYMASK _MD_GetThreadAffinityMask
+
+NSPR_API(void) _MD_InitRunningCPU(struct _PRCPU *cpu);
+#define    _MD_INIT_RUNNING_CPU _MD_InitRunningCPU
+
+#endif  /* defined(_PR_PTHREADS) */
+
+#endif /* _LANGUAGE_ASSEMBLY */
+
+#endif /* nspr_irix_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_irix32.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_irix32.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,149 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef _SGI_MP_SOURCE
+#define _SGI_MP_SOURCE
+#endif
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef IRIX
+#define IRIX
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_BYTES_PER_WORD_LOG2  2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define HAVE_LONG_LONG
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_irix64.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_irix64.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,148 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef _SGI_MP_SOURCE
+#define _SGI_MP_SOURCE
+#endif
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef IRIX
+#define IRIX
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define IS_64
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define HAVE_LONG_LONG
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_linux.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_linux.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,712 @@
+/* -*- 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 ***** */
+
+/*
+ * This file is used by not only Linux but also other glibc systems
+ * such as GNU/Hurd and GNU/k*BSD.
+ */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#if !defined(LINUX) && defined(__linux__)
+#define LINUX
+#endif
+
+#define PR_AF_INET6 10  /* same as AF_INET6 */
+
+#ifdef __powerpc64__
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN    1
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__powerpc__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN    1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__alpha)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__ia64__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__x86_64__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__mc68000__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     2
+#define PR_ALIGN_OF_LONG    2
+#define PR_ALIGN_OF_INT64   2
+#define PR_ALIGN_OF_FLOAT   2
+#define PR_ALIGN_OF_DOUBLE  2
+#define PR_ALIGN_OF_POINTER 2
+#define PR_ALIGN_OF_WORD    2
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__sparc__)
+
+#undef	IS_LITTLE_ENDIAN
+#define	IS_BIG_ENDIAN 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__i386__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__mips__)
+
+#ifdef __MIPSEB__
+#define IS_BIG_ENDIAN 1
+#undef  IS_LITTLE_ENDIAN
+#elif defined(__MIPSEL__)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#else
+#error "Unknown MIPS endianness."
+#endif
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__arm__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__hppa__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN    1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__s390x__)
+
+#define IS_BIG_ENDIAN 1
+#undef  IS_LITTLE_ENDIAN
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#elif defined(__s390__)
+
+#define IS_BIG_ENDIAN 1
+#undef  IS_LITTLE_ENDIAN
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#else
+
+#error "Unknown CPU architecture"
+
+#endif
+
+#define	HAVE_LONG_LONG
+#if PR_ALIGN_OF_DOUBLE == 8
+#define HAVE_ALIGNED_DOUBLES
+#endif
+#if PR_ALIGN_OF_INT64 == 8
+#define HAVE_ALIGNED_LONGLONGS
+#endif
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_linux.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_linux.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,559 @@
+/* -*- 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 nspr_linux_defs_h___
+#define nspr_linux_defs_h___
+
+#include "prthread.h"
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"linux"
+#define _PR_SI_SYSNAME  "LINUX"
+#ifdef __powerpc64__
+#define _PR_SI_ARCHITECTURE "ppc64"
+#elif defined(__powerpc__)
+#define _PR_SI_ARCHITECTURE "ppc"
+#elif defined(__alpha)
+#define _PR_SI_ARCHITECTURE "alpha"
+#elif defined(__ia64__)
+#define _PR_SI_ARCHITECTURE "ia64"
+#elif defined(__x86_64__)
+#define _PR_SI_ARCHITECTURE "x86-64"
+#elif defined(__mc68000__)
+#define _PR_SI_ARCHITECTURE "m68k"
+#elif defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#elif defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__mips__)
+#define _PR_SI_ARCHITECTURE "mips"
+#elif defined(__arm__)
+#define _PR_SI_ARCHITECTURE "arm"
+#elif defined(__hppa__)
+#define _PR_SI_ARCHITECTURE "hppa"
+#elif defined(__s390x__)
+#define _PR_SI_ARCHITECTURE "s390x"
+#elif defined(__s390__)
+#define _PR_SI_ARCHITECTURE "s390"
+#else
+#error "Unknown CPU architecture"
+#endif
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef	HAVE_STACK_GROWING_UP
+
+/*
+ * Elf linux supports dl* functions
+ */
+#define HAVE_DLL
+#define USE_DLFCN
+
+#if defined(__i386__)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT          _PR_x86_AtomicIncrement
+extern PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT          _PR_x86_AtomicDecrement
+extern PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD                _PR_x86_AtomicAdd
+extern PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET                _PR_x86_AtomicSet
+#endif
+
+#if defined(__ia64__)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT          _PR_ia64_AtomicIncrement
+extern PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT          _PR_ia64_AtomicDecrement
+extern PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD                _PR_ia64_AtomicAdd
+extern PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET                _PR_ia64_AtomicSet
+#endif
+
+#if defined(__x86_64__)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+extern PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT          _PR_x86_64_AtomicIncrement
+extern PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT          _PR_x86_64_AtomicDecrement
+extern PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD                _PR_x86_64_AtomicAdd
+extern PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET                _PR_x86_64_AtomicSet
+#endif
+
+#if defined(__alpha)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_ADD(ptr, i) ({               \
+    PRInt32 __atomic_tmp, __atomic_ret;   \
+    __asm__ __volatile__(                       \
+    "1: ldl_l   %[ret], %[val]          \n"     \
+    "   addl    %[ret], %[inc], %[tmp]  \n"     \
+    "   addl    %[ret], %[inc], %[ret]  \n"     \
+    "   stl_c   %[tmp], %[val]          \n"     \
+    "   beq     %[tmp], 2f              \n"     \
+    ".subsection 2                      \n"     \
+    "2: br      1b                      \n"     \
+    ".previous"                                 \
+    : [ret] "=&r" (__atomic_ret),               \
+      [tmp] "=&r" (__atomic_tmp),               \
+      [val] "=m" (*ptr)                         \
+    : [inc] "Ir" (i), "m" (*ptr));              \
+    __atomic_ret;                               \
+})
+#define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1)
+#define _MD_ATOMIC_DECREMENT(ptr) ({            \
+    PRInt32 __atomic_tmp, __atomic_ret;   \
+    __asm__ __volatile__(                       \
+    "1: ldl_l   %[ret], %[val]          \n"     \
+    "   subl    %[ret], 1, %[tmp]       \n"     \
+    "   subl    %[ret], 1, %[ret]       \n"     \
+    "   stl_c   %[tmp], %[val]          \n"     \
+    "   beq     %[tmp], 2f              \n"     \
+    ".subsection 2                      \n"     \
+    "2: br      1b                      \n"     \
+    ".previous"                                 \
+    : [ret] "=&r" (__atomic_ret),               \
+      [tmp] "=&r" (__atomic_tmp),               \
+      [val] "=m" (*ptr)                         \
+    : "m" (*ptr));                              \
+    __atomic_ret;                               \
+})
+#define _MD_ATOMIC_SET(ptr, n) ({               \
+    PRInt32 __atomic_tmp, __atomic_ret;   \
+    __asm__ __volatile__(                       \
+    "1: ldl_l   %[ret], %[val]          \n"     \
+    "   mov     %[newval], %[tmp]       \n"     \
+    "   stl_c   %[tmp], %[val]          \n"     \
+    "   beq     %[tmp], 2f              \n"     \
+    ".subsection 2                      \n"     \
+    "2: br      1b                      \n"     \
+    ".previous"                                 \
+    : [ret] "=&r" (__atomic_ret),               \
+      [tmp] "=&r"(__atomic_tmp),                \
+      [val] "=m" (*ptr)                         \
+    : [newval] "Ir" (n), "m" (*ptr));           \
+    __atomic_ret;                               \
+})
+#endif
+
+#define USE_SETJMP
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _PR_POLL_AVAILABLE
+#endif
+#undef _PR_USE_POLL
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#if defined(__alpha) || defined(__ia64__)
+#define _PR_HAVE_LARGE_OFF_T
+#elif (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+#define _PR_HAVE_OFF64_T
+#else
+#define _PR_NO_LARGE_FILES
+#endif
+#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+#define _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#endif
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+#if (__GLIBC__ >= 2) && defined(_PR_PTHREADS)
+#define _PR_HAVE_GETHOST_R
+#define _PR_HAVE_GETHOST_R_INT
+#endif
+
+#ifdef _PR_PTHREADS
+
+extern void _MD_CleanupBeforeExit(void);
+#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit
+
+#else  /* ! _PR_PTHREADS */
+
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	sigjmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+#ifdef __powerpc__
+/*
+ * PowerPC based MkLinux
+ *
+ * On the PowerPC, the new style jmp_buf isn't used until glibc
+ * 2.1.
+ */
+#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_GPR1]
+#else
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__misc[0]
+#endif /* glibc 2.1 or later */
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+/* aix = 64, macos = 70 */
+#define PR_NUM_GCREGS  64
+
+#elif defined(__alpha)
+/* Alpha based Linux */
+
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP]
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+#define _MD_SP_TYPE long int
+#else
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+#define _MD_SP_TYPE __ptr_t
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
+/* XXX not sure if this is correct, or maybe it should be 17? */
+#define PR_NUM_GCREGS 9
+
+#elif defined(__ia64__)
+
+#define _MD_GET_SP(_t)      ((long *)((_t)->md.context[0].__jmpbuf)[0])
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t)  &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t)  ((void *) 0)
+#define _MD_SP_TYPE         long int
+
+#define PR_NUM_GCREGS       _JBLEN
+
+#elif defined(__mc68000__)
+/* m68k based Linux */
+
+/*
+ * On the m68k, glibc still uses the old style sigjmp_buf, even
+ * in glibc 2.0.7.
+ */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+#define _MD_SP_TYPE int
+#else
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+#define _MD_SP_TYPE __ptr_t
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
+/* XXX not sure if this is correct, or maybe it should be 17? */
+#define PR_NUM_GCREGS 9
+
+#elif defined(__sparc__)
+/* Sparc */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+/*
+ * You need glibc2-2.0.7-25 or later. The libraries that came with
+ * Red Hat 5.1 are not new enough, but they are in 5.2.
+ */
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP]
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_FP] = val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_FP])
+#define _MD_SP_TYPE int
+#else
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__fp
+#define _MD_SET_FP(_t, val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) ((void *) 0)
+#define _MD_SP_TYPE __ptr_t
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
+#elif defined(__i386__)
+/* Intel based Linux */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP]
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_BP] = val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_BP])
+#define _MD_SP_TYPE int
+#else
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__bp = val)
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) &((_t)->md.context[0].__jmpbuf[0].__bp)
+#define _MD_SP_TYPE __ptr_t
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+#define PR_NUM_GCREGS   6
+
+#elif defined(__mips__)
+/* Linux/MIPS */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__fp = (val))
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[0].__fp)
+#define _MD_SP_TYPE __ptr_t
+#else
+#error "Linux/MIPS pre-glibc2 not supported yet"
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
+#elif defined(__arm__)
+/* ARM/Linux */
+#if defined(__GLIBC__) && __GLIBC__ >= 2
+#define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[20]
+#define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[19] = (val))
+#define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
+#define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[19])
+#define _MD_SP_TYPE __ptr_t
+#else
+#error "ARM/Linux pre-glibc2 not supported yet"
+#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
+
+#else
+
+#error "Unknown CPU architecture"
+
+#endif /*__powerpc__*/
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#ifdef __powerpc__
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (sigsetjmp(CONTEXT(_thread), 1)) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 128); \
+	_thread->md.sp = _MD_GET_SP_PTR(_thread); \
+	_thread->md.fp = _MD_GET_FP_PTR(_thread); \
+    _MD_SET_FP(_thread, 0); \
+}
+
+#elif defined(__mips__)
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    (void) sigsetjmp(CONTEXT(_thread), 1);  \
+    _thread->md.context[0].__jmpbuf[0].__pc = (__ptr_t) _main;  \
+    _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \
+    _thread->md.sp = _MD_GET_SP_PTR(_thread); \
+    _thread->md.fp = _MD_GET_FP_PTR(_thread); \
+    _MD_SET_FP(_thread, 0); \
+}
+
+#else
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (sigsetjmp(CONTEXT(_thread), 1)) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \
+	_thread->md.sp = _MD_GET_SP_PTR(_thread); \
+	_thread->md.fp = _MD_GET_FP_PTR(_thread); \
+    _MD_SET_FP(_thread, 0); \
+}
+
+#endif /*__powerpc__*/
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!sigsetjmp(CONTEXT(_thread), 1)) {  \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    siglongjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+	void *sp;
+	void *fp;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#include <sys/time.h>  /* for FD_SETSIZE */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+extern PRStatus _MD_InitializeThread(PRThread *thread);
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+extern PRStatus _MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize);
+extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri);
+extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout);
+extern PRStatus _MD_WAKEUP_WAITER(PRThread *);
+extern void _MD_YIELD(void);
+
+#endif /* ! _PR_PTHREADS */
+
+extern void _MD_EarlyInit(void);
+extern PRIntervalTime _PR_UNIX_GetInterval(void);
+extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT					_PR_UnixInit
+#define _MD_GET_INTERVAL                _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC            _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT __select
+
+#ifdef _PR_POLL_AVAILABLE
+#include <sys/poll.h>
+extern int __syscall_poll(struct pollfd *ufds, unsigned long int nfds,
+	int timeout);
+#define _MD_POLL __syscall_poll
+#endif
+
+/* For writev() */
+#include <sys/uio.h>
+
+extern void _MD_linux_map_sendfile_error(int err);
+
+#endif /* nspr_linux_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_macos.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_macos.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,725 @@
+/* -*- 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 prmacos_h___
+#define prmacos_h___
+
+//
+// This file contains all changes and additions which need to be made to the NSPR runtime 
+// for the Macintosh platform (specifically the Metrowerks environment).  This file should 
+// only be incluced in Macintosh builds.
+//
+
+#define PR_DLL_SUFFIX		""
+#define _PR_LOCAL_THREADS_ONLY
+#define _PR_NO_PREEMPT	1
+#define _PR_HAVE_ATOMIC_OPS 1
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlong.h"
+#include "prlock.h"
+#include "prcvar.h"
+#include "prsem.h"
+#include "prthread.h"
+#include "prtime.h"
+#include "prproces.h"
+
+#if !defined(MAC_NSPR_STANDALONE)
+#include "macstdlibextras.h"
+#endif
+
+#include <stddef.h>
+#include <setjmp.h>
+
+#include <Errors.h>
+#include <OpenTransport.h>
+#include <DriverServices.h>
+
+#define _PR_HAVE_PEEK_BUFFER
+#define _PR_PEEK_BUFFER_MAX (16 * 1024)
+#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) 1
+
+struct _MDProcess {
+    PRInt8 notused;
+};
+
+struct _MDThread {
+    jmp_buf      jb;
+    int          osErrCode;
+	PRLock *     asyncIOLock;
+	PRCondVar *  asyncIOCVar;
+    PRBool       missedIONotify;
+    PRBool       missedAsyncNotify;
+    PRBool       asyncNotifyPending;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+struct _MDCPU {
+    AbsoluteTime    lastThreadSwitch;
+    AbsoluteTime    lastWakeUpProcess;
+    PRBool          trackScheduling;
+};
+
+typedef struct _MDSocketCallerInfo {
+	PRThread *	thread;
+	void *		cookie;
+} _MDSocketCallerInfo;
+
+struct _MDFileDesc {
+    PRInt32         osfd;
+    PRPackedBool    orderlyDisconnect;
+    PRPackedBool    readReady;
+    PRPackedBool    writeReady;
+    PRPackedBool    exceptReady;
+    PRLock *        miscLock;
+
+    /* Server sockets: listen bit tells the notifier func what to do */
+    PRBool          doListen;
+
+    /* stored error for non-blocking connects, as a Unix-style error code */
+    OTReason        disconnectError;
+
+    _MDSocketCallerInfo  misc;
+    _MDSocketCallerInfo  read;
+    _MDSocketCallerInfo  write;
+};
+
+/*
+** Iinitialization Related definitions
+*/
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_MD_FinalInit
+
+/*
+** Interrupts Related definitions
+*/
+
+#define _MD_GET_INTSOFF()               (_pr_intsOff)
+
+#define _MD_INTSOFF(_is)                                  \
+    PR_BEGIN_MACRO                                        \
+        ENTER_CRITICAL_REGION();                          \
+        (_is) = _PR_MD_GET_INTSOFF();                     \
+        _PR_MD_SET_INTSOFF(1);                            \
+        LEAVE_CRITICAL_REGION();                          \
+    PR_END_MACRO
+
+#if TARGET_CARBON
+extern void _MD_SetIntsOff(PRInt32 ints);
+#define _MD_SET_INTSOFF(_val)           _MD_SetIntsOff(_val)
+#else /* not TARGET_CARBON */
+#define _MD_SET_INTSOFF(_val)           (_pr_intsOff = _val)
+#endif /* TARGET_CARBON */
+
+#define _MD_START_INTERRUPTS			_MD_StartInterrupts
+#define _MD_STOP_INTERRUPTS	    		_MD_StopInterrupts
+#define _MD_BLOCK_CLOCK_INTERRUPTS()
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS()
+#define _MD_DISABLE_CLOCK_INTERRUPTS()
+#define _MD_ENABLE_CLOCK_INTERRUPTS()
+
+/*
+** CPU Related definitions
+*/
+
+#define _MD_PAUSE_CPU		_MD_PauseCPU
+#define _MD_CLEANUP_BEFORE_EXIT()
+#define _MD_EXIT(status)	exit(status)
+#define _MD_INIT_CPUS()
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_InitRunningCPU(cpu)
+
+/*
+** Process Related definitions
+*/
+
+extern struct PRProcess * _MD_CreateProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr);
+#define _MD_CREATE_PROCESS _MD_CreateProcess
+
+extern PRStatus _MD_DetachProcess(PRProcess *process);
+#define _MD_DETACH_PROCESS _MD_DetachProcess
+
+extern PRStatus _MD_WaitProcess(PRProcess *process, PRInt32 *exitCode);
+#define _MD_WAIT_PROCESS _MD_WaitProcess
+
+extern PRStatus _MD_KillProcess(PRProcess *process);
+#define _MD_KILL_PROCESS _MD_KillProcess
+
+/*
+** Memory Segments Related definitions
+*/
+
+#define _MD_INIT_SEGS()
+
+/*
+** Thread Stacks Debugging Related definitions
+*/
+
+#define _MD_INIT_STACK		_MD_InitStack
+#define _MD_CLEAR_STACK		_MD_ClearStack
+
+/*
+** Locks Related definitions
+*/
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) (PR_SUCCESS)
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+
+/*
+** Thread Related definitions
+*/
+
+NSPR_API(PRThread *) PR_GetPrimaryThread();
+
+#if defined(powerc) || defined(__powerc)
+#define _MD_GET_PC(_t) (*((PRUint32 *)((_t)->md.jb)))
+#define _MD_GET_SP(_t) (*((PRUint32 *)((_t)->md.jb) + 2))
+#define _MD_GET_TOC(_t) (*((PRUint32 *)((_t)->md.jb) + 3))
+#define INIT_STACKPTR(stackTop) ((unsigned char*)stackTop - 128)
+#define PR_NUM_GCREGS 70
+#else
+#define _MD_GET_PC(_t) (*((PRUint32 *)((_t)->md.jb) + 6))
+#define _MD_GET_SP(_t) (*((PRUint32 *)((_t)->md.jb) + 12))
+#define INIT_STACKPTR(stackTop) ((unsigned char*)stackTop - 4)
+#define PR_NUM_GCREGS 13
+#endif
+
+#define _MD_DEFAULT_STACK_SIZE (58 * 1024)
+#define _MD_MINIMUM_STACK_SIZE (58 * 1024)
+
+/*
+** Initialize the thread machine dependent data structure
+*/
+extern PRStatus _MD_InitThread(PRThread *thread);
+#define _MD_INIT_THREAD	_MD_InitThread
+
+/*
+** Clean-up the thread machine dependent data structure
+*/
+#define	_MD_CLEAN_THREAD(_thread)						\
+    PR_BEGIN_MACRO				      					\
+	PR_DestroyCondVar(_thread->md.asyncIOCVar);			\
+	PR_DestroyLock(_thread->md.asyncIOLock);			\
+    PR_END_MACRO
+
+
+/*
+** Initialize the thread context preparing it to execute _main.
+** *sp = 0 zeros out the sp for the first stack frame so that
+** stack walking code can find the top of the stack.
+*/
+#if defined(powerc) || defined(__powerc)
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, _status)	\
+    PR_BEGIN_MACRO				      					\
+ 	unsigned char *sp;									\
+ 	unsigned long *tvect;								\
+	long **jb = (_thread)->md.jb;		      			\
+    *((PRBool *)_status) = PR_TRUE;              		\
+	(void) setjmp(jb);			      					\
+    sp = INIT_STACKPTR(_sp);							\
+    *sp = 0;                                            \
+    (_MD_GET_SP(_thread)) = (long) sp;   				\
+	tvect = (unsigned long *)_main;						\
+    (_MD_GET_PC(_thread)) = (int) *tvect;   			\
+    (_MD_GET_TOC(_thread)) = (int) *(tvect+1);   		\
+	_thread->no_sched = 0;                              \
+    PR_END_MACRO
+#else
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, _status)	\
+    PR_BEGIN_MACRO				      					\
+ 	unsigned char *sp;									\
+	long **jb = (_thread)->md.jb;		      			\
+    *((PRBool *)_status) = PR_TRUE;              		\
+	(void) setjmp(jb);			      					\
+    sp = INIT_STACKPTR(_sp);							\
+    (_MD_GET_SP(_thread)) = (long) sp;   				\
+    (_MD_GET_PC(_thread)) = (int) _main;   				\
+	_thread->no_sched = 0;                              \
+    PR_END_MACRO
+#endif
+
+/*
+** Switch away from the current thread context by saving its state and
+** calling the thread scheduler. Reload cpu when we come back from the
+** context switch because it might have changed.
+*/
+/*    	ResetTimer();	before _PR_Schedule()		   		*/
+
+
+#define _MD_SWITCH_CONTEXT(_thread)                                 \
+    PR_BEGIN_MACRO                                                  \
+    PR_ASSERT(_thread->no_sched);                                   \
+    if (!setjmp(_thread->md.jb)) {                                  \
+        _MD_SET_LAST_THREAD(_thread);                               \
+        if (_PR_MD_CURRENT_CPU()->md.trackScheduling)               \
+            _PR_MD_CURRENT_CPU()->md.lastThreadSwitch = UpTime();   \
+        _PR_Schedule();                                             \
+    } else {                                                        \
+        PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD());        \
+        _MD_LAST_THREAD()->no_sched = 0;                            \
+    }                                                               \
+    PR_END_MACRO
+
+/*
+** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or
+** initialized by _MD_INIT_CONTEXT.
+*/
+#define _MD_RESTORE_CONTEXT(_newThread)	    \
+    PR_BEGIN_MACRO			    			\
+	long **jb = (_newThread)->md.jb;	    \
+	_MD_SET_CURRENT_THREAD(_newThread); 	\
+    _newThread->no_sched = 1;		        \
+	longjmp(jb, 1);			    			\
+    PR_END_MACRO
+
+
+#define _MD_ERRNO()	 _MD_CURRENT_THREAD()->md.osErrCode
+
+extern PRStatus _MD_wait(PRThread *thread, PRIntervalTime timeout);
+#define _MD_WAIT	_MD_wait
+
+/*
+** Combined thread model related definitions
+*/
+
+#define _MD_CREATE_THREAD(a,b,c,d,e,f) (PR_SUCCESS)
+#define _MD_WAKEUP_WAITER(a)
+#define _MD_SET_PRIORITY(a,b)
+
+/*
+** File I/O Related definitions
+*/
+
+extern PRInt32 _PR_MD_WRITE_SYNC(PRFileDesc *fd, void *buf, PRInt32 amount);
+#define    _PR_MD_WRITE_SYNC _MD_WRITE_SYNC
+
+struct _MDDir {
+	short		ioVRefNum;
+	long		ioDirID;
+	short		ioFDirIndex;
+	char		*currentEntryName;
+};
+
+#define PR_DIRECTORY_SEPARATOR		'/'
+#define PR_DIRECTORY_SEPARATOR_STR	"/"
+#define PR_PATH_SEPARATOR		':'
+#define PR_PATH_SEPARATOR_STR		":"
+
+typedef enum IOOperation {
+    READ_ASYNC,
+    WRITE_ASYNC
+} IOOperation;
+
+
+#define _MD_INIT_IO()
+
+#define _MD_OPEN 					_MD_Open
+#define _MD_OPEN_FILE 				_MD_Open
+#define _MD_CLOSE_FILE 				FSClose
+#define _MD_READ(fd,buf,amount) 	ReadWriteProc(fd,buf,amount,READ_ASYNC)
+#define _MD_WRITE(fd,buf,amount) 	ReadWriteProc(fd,buf,amount,WRITE_ASYNC)
+#define _MD_WRITE_SYNC(fd,buf,amount) WriteSyncProc(fd,buf,amount)
+#define _MD_GET_FILE_ERROR() 		_PR_MD_CURRENT_THREAD()->md.osErrCode
+#define _MD_LSEEK 					_MD_LSeek
+#define _MD_FSYNC 					_MD_FSync
+
+/* to be implemented */
+#define _MD_LSEEK64(a,b,c)           LL_ZERO
+#define _MD_GETOPENFILEINFO64(fd,info)   -1
+#define _MD_GETFILEINFO64(fd,info)   -1
+
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+** File Manipulation definitions
+*/
+
+#define	_MD_RENAME 			_MD_Rename
+#define	_MD_ACCESS 			_MD_Access
+
+#define	_MD_GETFILEINFO 	_MD_GetFileInfo
+#define	_MD_GETOPENFILEINFO _MD_GetOpenFileInfo
+
+#define	_MD_STAT 			_MD_Stat
+
+#define	_MD_DELETE 			_MD_Delete
+
+extern PRStatus _MD_LockFile(PRInt32 osfd);
+#define	_MD_LOCKFILE 		_MD_LockFile
+extern PRStatus _MD_TLockFile(PRInt32 osfd);
+#define	_MD_TLOCKFILE 		_MD_TLockFile
+extern PRStatus _MD_UnlockFile(PRInt32 osfd);
+#define	_MD_UNLOCKFILE		_MD_UnlockFile
+
+/* 
+** Directory enumeration related definitions 
+*/
+
+extern PRStatus _MD_OpenDir(struct _MDDir *md,const char *name);
+#define	_MD_OPEN_DIR 		_MD_OpenDir
+
+extern char* _MD_ReadDir(struct _MDDir *md,PRIntn flags);
+#define	_MD_READ_DIR 		_MD_ReadDir
+
+#define	_MD_CLOSE_DIR 		_MD_CloseDir
+
+#define	_MD_MKDIR 			_MD_MkDir
+#define	_MD_MAKE_DIR		_MD_MkDir
+#define	_MD_RMDIR 			_MD_Delete
+
+/*
+** Pipe I/O Related definitions (not implemented)
+*/
+
+#define _MD_PIPEAVAILABLE(fd) -1
+
+/*
+** Socket I/O Related definitions
+*/
+
+#if UNIVERSAL_INTERFACES_VERSION >= 0x0330
+/* In Universal Interfaces 3.3 and later, these are enums. */
+#define IP_TTL IP_TTL
+#define IP_TOS IP_TOS
+#define IP_ADD_MEMBERSHIP IP_ADD_MEMBERSHIP
+#define IP_DROP_MEMBERSHIP IP_DROP_MEMBERSHIP
+#define IP_MULTICAST_IF IP_MULTICAST_IF
+#define IP_MULTICAST_TTL IP_MULTICAST_TTL
+#define IP_MULTICAST_LOOP IP_MULTICAST_LOOP
+#define TCP_NODELAY TCP_NODELAY
+#define TCP_MAXSEG TCP_MAXSEG
+#endif
+
+#define _MD_SOCKET 			_MD_socket
+#define _MD_BIND			_MD_bind
+#define _MD_LISTEN			_MD_listen
+#define _MD_GETSOCKNAME		_MD_getsockname
+
+extern PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen);
+#define _MD_GETSOCKOPT		_MD_getsockopt
+
+extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen);
+#define _MD_SETSOCKOPT		_MD_setsockopt
+
+#define _MD_SOCKETAVAILABLE	_MD_socketavailable
+#define _MD_ACCEPT			_MD_accept
+#define _MD_CONNECT			_MD_connect
+#define _MD_SEND			_MD_send
+#define _MD_RECV			_MD_recv
+#define _MD_CLOSE_SOCKET	_MD_closesocket
+#define _MD_SENDTO			_MD_sendto
+#define _MD_RECVFROM		_MD_recvfrom
+#define _MD_PR_POLL			_MD_poll
+#define _MD_INIT_FILEDESC	_MD_initfiledesc
+#define _MD_FREE_FILEDESC	_MD_freefiledesc
+#define _MD_MAKE_NONBLOCK	_MD_makenonblock
+#define _MD_INIT_FD_INHERITABLE _MD_initfdinheritable
+#define _MD_QUERY_FD_INHERITABLE _MD_queryfdinheritable
+
+#define _MD_GET_SOCKET_ERROR() 		_PR_MD_CURRENT_THREAD()->md.osErrCode
+
+#define _PR_MD_MAP_SELECT_ERROR(x) 	(x)
+/*
+** Netdb Related definitions
+*/
+extern PRStatus _MD_gethostname(char *name, int namelen);
+#define _MD_GETHOSTNAME		_MD_gethostname
+#define _PR_GET_HOST_ADDR_AS_NAME
+
+/* 
+	XXX _MD_WRITEV, _MD_SHUTDOWN & _MD_GETPEERNAME not done yet!!!
+*/
+#define _MD_WRITEV			_MD_writev
+#define _MD_SHUTDOWN		_MD_shutdown
+#define _MD_GETPEERNAME		_MD_getpeername
+
+
+#ifdef OLD_MACSOCK_LIBRARY
+#define _MD_SOCKET 			macsock_socket
+#define _MD_LISTEN			macsock_listen
+#define _MD_SEND(fd,buf,amount,flags,timeout)	macsock_send(fd->secret->md.osfd,buf,amount,flags)
+#define _MD_SENDTO(fd,buf,amount,flags,addr,addrlen,timeout)	macsock_sendto(fd->secret->md.osfd,buf,amount,flags,(struct sockaddr *)addr,addrlen)
+#define _MD_RECV(fd,buf,amount,flags,timeout)	macsock_recv(fd->secret->md.osfd,buf,amount,flags)
+#define _MD_RECVFROM(fd,buf,amount,flags,addr,addrlen,timeout)	macsock_recvfrom(fd->secret->md.osfd,buf,amount,flags,(struct sockaddr *)addr,addrlen)
+#define _MD_CLOSE_SOCKET	macsock_close
+#define _MD_SHUTDOWN(a,b)	(0)
+
+#define _MD_ACCEPT(fd,addr,addrlen,timeout)	macsock_accept(fd->secret->md.osfd,(struct sockaddr *)addr,addrlen)
+#define _MD_CONNECT(fd,name,namelen,timeout)	macsock_connect(fd->secret->md.osfd,(struct sockaddr *)name,namelen)
+#define _MD_BIND(fd,name,namelen)				macsock_bind(fd->secret->md.osfd,(struct sockaddr *)name,namelen)
+#define _MD_GETSOCKNAME(fd,name,namelen)		macsock_getsockname(fd->secret->md.osfd,(struct sockaddr *)name,namelen)
+#define _MD_GETPEERNAME(fd,name,namelen)		macsock_getpeername(fd->secret->md.osfd,(struct sockaddr *)name,namelen)
+#define _MD_GETSOCKOPT(fd,level,optname,optval,optlen)		macsock_getsockopt(fd->secret->md.osfd,level,optname,optval,optlen)
+#define _MD_SETSOCKOPT(fd,level,optname,optval,optlen)		macsock_setsockopt(fd->secret->md.osfd,level,optname,optval,optlen)
+#define _MD_SOCKETAVAILABLE(fd,bytes)		macsock_socketavailable(fd->secret->md.osfd,bytes)
+#endif
+
+/*
+** Memory Segements Related definitions
+*/
+
+#define _MD_INIT_SEGS()		
+#define _MD_ALLOC_SEGMENT	_MD_AllocSegment
+#define _MD_FREE_SEGMENT	_MD_FreeSegment
+
+/*
+** Time Related definitions
+*/
+
+#define _MD_GET_INTERVAL 				_MD_GetInterval
+#define _MD_INTERVAL_PER_SEC() 			PR_MSEC_PER_SEC
+#define _MD_INTERVAL_INIT()
+
+/*
+** Environemnt Related definitions
+*/
+
+extern char *_MD_GetEnv(const char *name);
+#define _MD_GET_ENV			_MD_GetEnv
+
+extern int _MD_PutEnv(const char *variableCopy);
+#define _MD_PUT_ENV			_MD_PutEnv
+
+/*
+** Following is old stuff to be looked at.
+*/
+
+#define GCPTR
+#define CALLBACK
+typedef int (*FARPROC)();
+
+
+#define MAX_NON_PRIMARY_TIME_SLICES 	6
+
+extern long gTimeSlicesOnNonPrimaryThread;
+extern struct PRThread *gPrimaryThread;
+
+// Errors not found in the Mac StdCLib
+#define EACCES  		13      	// Permission denied
+#define ENOENT			-43			// No such file or directory
+#define _OS_INVALID_FD_VALUE -1
+
+#define	STDERR_FILENO	2
+
+#if !defined(MAC_NSPR_STANDALONE)
+#define PATH_SEPARATOR 					':'
+#define PATH_SEPARATOR_STR		        ":"
+#define DIRECTORY_SEPARATOR				'/'
+#define DIRECTORY_SEPARATOR_STR			"/"
+#endif
+
+#define UNIX_THIS_DIRECTORY_STR			"./"
+#define UNIX_PARENT_DIRECTORY_STR		"../"
+
+
+// Alias a few names
+#define getenv	PR_GetEnv
+#define putenv	_MD_PutEnv
+
+#if defined(MAC_NSPR_STANDALONE)
+typedef unsigned char (*MemoryCacheFlusherProc)(size_t size);
+typedef void (*PreAllocationHookProc)(void);
+
+extern char *strdup(const char *source);
+
+extern void InstallPreAllocationHook(PreAllocationHookProc newHook);
+extern void InstallMemoryCacheFlusher(MemoryCacheFlusherProc newFlusher);
+#endif
+
+extern char *PR_GetDLLSearchPath(void);
+
+#if defined(MAC_NSPR_STANDALONE)
+extern int strcmp(const char *str1, const char *str2);
+extern int strcasecmp(const char *str1, const char *str2);
+#endif
+
+extern void MapFullToPartialMacFile(char *);
+extern char *MapPartialToFullMacFile(const char *);
+
+extern void ResetTimer(void);
+extern void PR_PeriodicIdle(void);
+extern void ActivateTimer(void);
+extern void DeactivateTimer(void);
+extern void PR_InitMemory(void);
+
+extern struct hostent *gethostbyaddr(const void *addr, int addrlen, int type);
+
+extern short GetVolumeRefNumFromName(const char *);
+
+#include <stdio.h>			// Needed to get FILE typedef
+extern FILE *_OS_FOPEN(const char *filename, const char *mode);
+//
+//	Macintosh only private parts.
+//
+
+#define	dprintTrace			";dprintf;doTrace"
+#define	dprintNoTrace		";dprintf"
+extern void dprintf(const char *format, ...);
+
+
+// Entry into the memory system's cache flushing
+#if defined(MAC_NSPR_STANDALONE)
+extern PRUint8 CallCacheFlushers(size_t blockSize);
+#endif
+
+#if defined(MAC_NSPR_STANDALONE)
+extern void* reallocSmaller(void* block, size_t newSize);
+#endif
+
+
+/*
+** PR_GetSystemInfo related definitions
+*/
+#define _PR_SI_SYSNAME          "MacOS"
+#define _PR_SI_ARCHITECTURE     "PowerPC"
+
+/*
+ * Memory-mapped files
+ */
+
+struct _MDFileMap {
+    PRInt8 unused;
+};
+
+extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
+#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
+
+extern PRInt32 _MD_GetMemMapAlignment(void);
+#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment
+
+extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
+        PRUint32 len);
+#define _MD_MEM_MAP _MD_MemMap
+
+extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
+#define _MD_MEM_UNMAP _MD_MemUnmap
+
+extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
+#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
+
+extern void SetLogFileTypeCreator(const char *logFile);
+extern int _MD_mac_get_nonblocking_connect_error(PRFileDesc* fd);
+
+
+/*
+ * Critical section support
+ */
+
+#define MAC_CRITICAL_REGIONS  TARGET_CARBON
+
+#if MAC_CRITICAL_REGIONS
+
+extern void InitCriticalRegion();
+extern void TermCriticalRegion();
+
+extern void EnterCritialRegion();
+extern void LeaveCritialRegion();
+
+#define INIT_CRITICAL_REGION()     InitCriticalRegion()
+#define TERM_CRITICAL_REGION()     TermCriticalRegion()
+
+#define ENTER_CRITICAL_REGION()     EnterCritialRegion()
+#define LEAVE_CRITICAL_REGION()     LeaveCritialRegion()
+
+#else
+
+#define INIT_CRITICAL_REGION()
+#define TERM_CRITICAL_REGION()
+
+#define ENTER_CRITICAL_REGION()
+#define LEAVE_CRITICAL_REGION()
+
+#endif
+
+
+
+/*
+ * CPU Idle support
+ */
+
+extern void InitIdleSemaphore();
+extern void TermIdleSemaphore();
+
+extern void WaitOnIdleSemaphore();
+extern void SignalIdleSemaphore();
+
+
+/*
+ * Atomic operations
+ */
+#ifdef _PR_HAVE_ATOMIC_OPS
+
+extern PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval);
+
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT(val)   OTAtomicAdd32(1, (SInt32 *)val)
+#define _MD_ATOMIC_ADD(ptr, val)    OTAtomicAdd32(val, (SInt32 *)ptr)
+#define _MD_ATOMIC_DECREMENT(val)   OTAtomicAdd32(-1, (SInt32 *)val)
+#define _MD_ATOMIC_SET(val, newval) _MD_AtomicSet(val, newval)
+
+#endif /* _PR_HAVE_ATOMIC_OPS */
+
+
+#endif /* prmacos_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_ncr.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_ncr.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,140 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef NCR
+#define NCR
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#undef	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_ncr.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_ncr.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,230 @@
+/* -*- 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 nspr_unixware_defs_h___
+#define nspr_unixware_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"ncr"
+#define _PR_SI_SYSNAME		"NCR"
+#define _PR_SI_ARCHITECTURE	"x86"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE	 	0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define _PR_RECV_BROKEN /* recv doesn't work on Unix Domain Sockets */
+
+#if !defined (HAVE_STRERROR)
+#define HAVE_STRERROR
+#endif
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_NO_LARGE_FILES
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_NETCONFIG
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define NEED_LOCALTIME_R
+#define NEED_GMTIME_R  
+#define NEED_ASCTIME_R
+#define NEED_STRTOK_R
+#define NEED_CTIME_R
+#define _PR_NEED_STRCASECMP
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP setjmp
+#define _LONGJMP longjmp
+#define _PR_CONTEXT_TYPE         jmp_buf
+#define _MD_GET_SP(_t)           (_t)->md.context[4]
+#define _PR_NUM_GCREGS	_JBLEN
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+{								  \
+    *status = PR_TRUE; \
+    if(_SETJMP(CONTEXT(_thread))) (*_main)(); \
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!_SETJMP(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;	     \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    _LONGJMP(CONTEXT(_thread), 1);    \
+}
+
+/* Machine-dependent (MD) data structures.
+ * Don't use SVR4 native threads (yet). 
+ */
+
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+ * The following are copied from _sunos.h, _aix.h.  This means
+ * some of them should probably be moved into _unixos.h.  But
+ * _irix.h seems to be quite different in regard to these macros.
+ */
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *execptfds, struct timeval *timeout);
+#define _MD_SELECT _select
+
+#define _MD_POLL _poll
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+
+#endif /* nspr_ncr_defs_h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nec.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nec.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,140 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef NEC
+#define NEC
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#undef  HAVE_LONG_LONG
+#undef  HAVE_ALIGNED_DOUBLES
+#undef  HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2  2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nec.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nec.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,196 @@
+/* -*- 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 nspr_nec_defs_h___
+#define nspr_nec_defs_h___
+ 
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH  "nec"
+#define _PR_SI_SYSNAME "NEC"
+#define _PR_SI_ARCHITECTURE "mips"
+#define PR_DLL_SUFFIX		".so"
+ 
+#define _PR_STACK_VMBASE        0x50000000
+#define _MD_DEFAULT_STACK_SIZE  65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_DLFCN
+#define NEED_TIME_R
+#define NEED_STRFTIME_LOCK
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ST_ATIM_UNION
+ 
+#include <ucontext.h>
+#include <sys/regset.h>
+ 
+#define PR_NUM_GCREGS   NGREG
+#define PR_CONTEXT_TYPE ucontext_t
+ 
+#define CONTEXT(_thread) (&(_thread)->md.context)
+ 
+#define _MD_GET_SP(_t)    (_t)->md.context.uc_mcontext.gregs[CXT_SP]
+ 
+/*
+** Initialize the thread context preparing it to execute "e(o,a)"
+*/
+#define _MD_INIT_CONTEXT(thread, _sp, _main, status)               \
+{                                                                   \
+    *status = PR_TRUE; \
+    getcontext(CONTEXT(thread));                                    \
+    CONTEXT(thread)->uc_stack.ss_sp = (char*) (thread)->stack->stackBottom; \
+    CONTEXT(thread)->uc_stack.ss_size = (thread)->stack->stackSize; \
+    _MD_GET_SP(thread) = (greg_t) _sp - 64;             \
+    makecontext(CONTEXT(thread), _main, 0);              \
+}
+ 
+#define _MD_SWITCH_CONTEXT(_thread)      \
+    if (!getcontext(CONTEXT(_thread))) { \
+        (_thread)->md.errcode = errno;      \
+        _PR_Schedule();                  \
+    }
+ 
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)   \
+{                                      \
+    ucontext_t *uc = CONTEXT(_thread); \
+    uc->uc_mcontext.gregs[CXT_V0] = 1; \
+    uc->uc_mcontext.gregs[CXT_A3] = 0; \
+    errno = (_thread)->md.errcode;     \
+    _MD_SET_CURRENT_THREAD(_thread);   \
+    setcontext(uc);                    \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_EARLY_INIT          _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+#define _MD_SELECT _select
+#define _MD_POLL _poll
+
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+ 
+#endif /* nspr_nec_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_netbsd.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_netbsd.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,289 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef NETBSD
+#define NETBSD
+#endif
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#if defined(__i386__) || defined(__arm32__) || defined(__MIPSEL__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(__sparc__) || defined(__MIPSEB__)
+
+#undef IS_LITTLE_ENDIAN
+#define  IS_BIG_ENDIAN 1
+#define HAVE_LONG_LONG
+#define  HAVE_ALIGNED_DOUBLES
+#define  HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(__alpha__)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__powerpc__) || defined(__m68k__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN    1
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#else
+
+#error Must define constants for type sizes here.
+
+#endif
+
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_netbsd.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_netbsd.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,322 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 
+ * 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.
+ */
+
+#ifndef nspr_netbsd_defs_h___
+#define nspr_netbsd_defs_h___
+
+#include <sys/syscall.h>
+#include <sys/param.h>  /* for __NetBSD_Version__ */
+
+#define PR_LINKER_ARCH	"netbsd"
+#define _PR_SI_SYSNAME  "NetBSD"
+#if defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__alpha__)
+#define _PR_SI_ARCHITECTURE "alpha"
+#elif defined(__m68k__)
+#define _PR_SI_ARCHITECTURE "m68k"
+#elif defined(__powerpc__)
+#define _PR_SI_ARCHITECTURE "powerpc"
+#elif defined(__sparc_v9__)
+#define _PR_SI_ARCHITECTURE "sparc64"
+#elif defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#elif defined(__mips__)
+#define _PR_SI_ARCHITECTURE "mips"
+#elif defined(__arm32__) || defined(__arm__) || defined(__armel__) \
+    || defined(__armeb__)
+#define _PR_SI_ARCHITECTURE "arm"
+#endif
+
+#if defined(__ELF__)
+#define PR_DLL_SUFFIX		".so"
+#else
+#define PR_DLL_SUFFIX		".so.1.0"
+#endif
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_DLFCN
+#define _PR_HAVE_SOCKADDR_LEN
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ST_ATIMESPEC
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+
+#if __NetBSD_Version__ >= 105000000
+#define _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#endif
+
+#if __NetBSD_Version__ >= 106370000
+/* NetBSD 1.6ZK */
+#define _PR_HAVE_GETPROTO_R
+#define _PR_HAVE_GETPROTO_R_INT
+#endif
+
+#define USE_SETJMP
+
+#ifndef _PR_PTHREADS
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	sigjmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#ifdef __i386__
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)			\
+{									\
+    sigsetjmp(CONTEXT(_thread), 1);					\
+    CONTEXT(_thread)[2] = (unsigned char*) ((_sp) - 128);		\
+    CONTEXT(_thread)[0] = (int) _main;					\
+    *status = PR_TRUE;							\
+}
+#define	_MD_GET_SP(_thread)	CONTEXT(_thread)[2]
+#endif
+#ifdef __sparc_v9__
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)			\
+{									\
+    sigsetjmp(CONTEXT(_thread), 1);					\
+    CONTEXT(_thread)[1] = (unsigned char*) ((_sp) - 176 - 0x7ff);	\
+    CONTEXT(_thread)[2] = (long) _main;					\
+    CONTEXT(_thread)[3] = (long) _main + 4;				\
+    *status = PR_TRUE;							\
+}
+#define	_MD_GET_SP(_thread)	(CONTEXT(_thread)[2]+0x7ff)
+#elif defined(__sparc__)
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)			\
+{									\
+    sigsetjmp(CONTEXT(_thread), 1);					\
+    CONTEXT(_thread)[2] = (unsigned char*) ((_sp) - 128);		\
+    CONTEXT(_thread)[3] = (int) _main;					\
+    CONTEXT(_thread)[4] = (int) _main + 4;				\
+    *status = PR_TRUE;							\
+}
+#define	_MD_GET_SP(_thread)	CONTEXT(_thread)[2]
+#endif
+#ifdef __powerpc__
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)			\
+{									\
+    sigsetjmp(CONTEXT(_thread), 1);					\
+    CONTEXT(_thread)[3] = (unsigned char*) ((_sp) - 128);		\
+    CONTEXT(_thread)[4] = (int) _main;					\
+    *status = PR_TRUE;							\
+}
+#define	_MD_GET_SP(_thread)	CONTEXT(_thread)[3]
+#endif
+#ifdef __m68k__
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)			\
+{									\
+    sigsetjmp(CONTEXT(_thread), 1);					\
+    CONTEXT(_thread)[2] = (unsigned char*) ((_sp) - 128);		\
+    CONTEXT(_thread)[5] = (int) _main;					\
+    *status = PR_TRUE;							\
+}
+#define	_MD_GET_SP(_thread)	CONTEXT(_thread)[2]
+#endif
+#ifdef __mips__
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)			\
+{									\
+    sigsetjmp(CONTEXT(_thread), 1);					\
+    CONTEXT(_thread)[32] = (unsigned char*) ((_sp) - 128);		\
+    CONTEXT(_thread)[2] = (int) _main;					\
+    CONTEXT(_thread)[28] = (int) _main;					\
+    *status = PR_TRUE;							\
+}
+#define	_MD_GET_SP(_thread)	CONTEXT(_thread)[32]
+#endif
+#if defined(__arm32__) || defined(__arm__) || defined(__armel__) \
+    || defined(__armeb__)
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)			\
+{									\
+    sigsetjmp(CONTEXT(_thread), 1);					\
+    CONTEXT(_thread)[23] = (unsigned char*) ((_sp) - 128);		\
+    CONTEXT(_thread)[24] = (int) _main;					\
+    *status = PR_TRUE;							\
+}
+#define	_MD_GET_SP(_thread)	CONTEXT(_thread)[23]
+#endif
+#ifdef __alpha__
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)			\
+{									\
+    sigsetjmp(CONTEXT(_thread), 1);					\
+    CONTEXT(_thread)[34] = (unsigned char*) ((_sp) - 128);		\
+    CONTEXT(_thread)[2] = (long) _main;					\
+    CONTEXT(_thread)[30] = (long) _main;				\
+    CONTEXT(_thread)[31] = (long) _main;				\
+    *status = PR_TRUE;							\
+}
+#define	_MD_GET_SP(_thread)	CONTEXT(_thread)[34]
+#endif
+#ifndef _MD_INIT_CONTEXT
+#error "Need to define _MD_INIT_CONTEXT for this platform"
+#endif
+
+#define PR_NUM_GCREGS	_JBLEN
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!sigsetjmp(CONTEXT(_thread), 1)) {  \
+        (_thread)->md.errcode = errno;  \
+        _PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    siglongjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+#endif /* ! _PR_PTHREADS */
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+#if defined(_PR_POLL_AVAILABLE)
+#include <poll.h>
+#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout)
+#endif
+
+#if NetBSD1_3 == 1L
+typedef unsigned int nfds_t;
+#endif
+
+#endif /* nspr_netbsd_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nextstep.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nextstep.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,255 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef NEXTSTEP
+#define NEXTSTEP
+#endif
+
+/*	Platform specific
+*/
+#if defined(__sparc__)
+
+/* Check these
+*/
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+/* Taken from _solaris.cfg
+*/
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+/* Taken from _solaris.cfg
+*/
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+/* Taken from _solaris.cfg
+*/
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_WORDS_PER_DWORD_LOG2  1
+
+#elif defined(__m68k__)
+
+/* Check these
+*/
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     2
+#define PR_ALIGN_OF_LONG    2
+#define PR_ALIGN_OF_INT64   2
+#define PR_ALIGN_OF_FLOAT   2
+#define PR_ALIGN_OF_DOUBLE  2
+#define PR_ALIGN_OF_POINTER 2
+
+#define PR_WORDS_PER_DWORD_LOG2  1
+
+#elif defined(__i386__)
+
+/* Check these
+*/
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+#define PR_WORDS_PER_DWORD_LOG2  1
+#endif /* defined(__somearch__) */
+
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nextstep.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nextstep.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,299 @@
+/* -*- 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 nspr_nextstep_defs_h___
+#define nspr_nextstep_defs_h___
+
+#include "prthread.h"
+
+#include <bsd/libc.h>
+#include <bsd/syscall.h>
+
+/*	syscall() is not declared in NEXTSTEP's syscall.h ...
+*/
+extern int syscall(int number, ...);
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"nextstep"
+#define _PR_SI_SYSNAME  "NEXTSTEP"
+#if defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#elif defined(__m68k__)
+#define _PR_SI_ARCHITECTURE "m68k"
+#elif defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#else
+error Unknown NEXTSTEP architecture
+#endif
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+
+#define HAVE_WEAK_MALLOC_SYMBOLS
+
+#define HAVE_DLL
+#define USE_MACH_DYLD
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#define _PR_NO_LARGE_FILES
+
+#define USE_SETJMP
+
+#ifndef _PR_PTHREADS
+
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	jmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+/* balazs.pataki at sztaki.hu:
+** __sparc__ is checked
+** __m68k__ is checked
+** __i386__ is a guess (one of the two defines should work)
+*/
+#if defined(__sparc__)
+#define _MD_GET_SP(_th)		(_th)->md.context[2]
+#elif defined(__m68k__)
+#define _MD_GET_SP(_th)		(_th)->md.context[2]
+#elif defined(__i386__)
+/* One of this two must be OK ... try using sc_onstack
+*/
+#define _MD_GET_SP(_th)    (((struct sigcontext *) (_th)->md.context)->sc_onstack)
+//#define _MD_GET_SP(_th)		(_th)->md.context[0].sc_esp
+#else
+error Unknown NEXTSTEP architecture
+#endif
+
+#define PR_NUM_GCREGS	_JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (setjmp(CONTEXT(_thread))) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (int) ((_sp) - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) {  \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    longjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+extern PRStatus _MD_InitializeThread(PRThread *thread);
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+extern PRStatus _MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize);
+extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri);
+extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout);
+extern PRStatus _MD_WAKEUP_WAITER(PRThread *);
+extern void _MD_YIELD(void);
+
+#endif /* ! _PR_PTHREADS */
+
+extern void _MD_EarlyInit(void);
+extern PRIntervalTime _PR_UNIX_GetInterval(void);
+extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+/* For writev() */
+#include <sys/uio.h>
+
+/* signal.h */
+/* 	balazs.pataki at sztaki.hu: this is stolen from sunos4.h. The things is that
+** 	NEXTSTEP doesn't support these flags for `struct sigaction's sa_flags, so
+**	I have to fake them ...
+*/
+#define SA_RESTART 0
+
+/* mmap */
+/* 	balazs.pataki at sztaki.hu: NEXTSTEP doesn't have mmap, at least not 
+**	publically. We have sys/mman.h, but it doesn't declare mmap(), and
+**	PROT_NONE is also missing. syscall.h has entries for mmap, munmap, and 
+**	mprotect so I wrap these in nextstep.c as  mmap(), munmap() and mprotect()
+**	and pray for it to work.
+**	
+*/
+caddr_t mmap(caddr_t addr, size_t len, int prot, int flags,
+          int fildes, off_t off);
+int munmap(caddr_t addr, size_t len);
+int mprotect(caddr_t addr, size_t len, int prot);
+
+/*	my_mmap() is implemented in nextstep.c and is based on map_fd() of mach.
+*/
+caddr_t my_mmap(caddr_t addr, size_t len, int prot, int flags,
+          int fildes, off_t off);
+int my_munmap(caddr_t addr, size_t len);
+
+
+/*	string.h
+*/
+/* balazs.pataki at sztaki.hu: this is missing so implemenetd in nextstep.c ...
+*/
+char *strdup(const char *s1);
+
+/* unistd.h
+*/
+/* 	balazs.pataki at sztaki.hu: these functions are hidden, though correctly 
+**	implemented in NEXTSTEP. Here I give the declaration for them to be used
+**	by prmalloc.c, and I have a wrapped syscall() version of them in nextstep.c
+*/
+int brk(void *endds);
+void *sbrk(int incr);
+
+#endif /* nspr_nextstep_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nspr_pthread.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nspr_pthread.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,283 @@
+/* -*- 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 nspr_pthread_defs_h___
+#define nspr_pthread_defs_h___
+
+#include <pthread.h>
+#include "prthread.h"
+
+#if defined(PTHREADS_USER)
+/*
+** Thread Local Storage 
+*/
+extern pthread_key_t current_thread_key;
+extern pthread_key_t current_cpu_key;
+extern pthread_key_t last_thread_key;
+extern pthread_key_t intsoff_key;
+
+#define _MD_CURRENT_THREAD() 			\
+			((struct PRThread *) pthread_getspecific(current_thread_key))
+#define _MD_CURRENT_CPU() 				\
+			((struct _PRCPU *) pthread_getspecific(current_cpu_key))
+#define _MD_LAST_THREAD()				\
+			((struct PRThread *) pthread_getspecific(last_thread_key))
+	
+#define _MD_SET_CURRENT_THREAD(newval) 			\
+	pthread_setspecific(current_thread_key, (void *)newval)
+
+#define _MD_SET_CURRENT_CPU(newval) 			\
+	pthread_setspecific(current_cpu_key, (void *)newval)
+
+#define _MD_SET_LAST_THREAD(newval)	 			\
+	pthread_setspecific(last_thread_key, (void *)newval)
+
+#define _MD_SET_INTSOFF(_val)
+#define _MD_GET_INTSOFF()	1
+	
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)			\
+    PR_BEGIN_MACRO				      							\
+        *status = PR_TRUE;              						\
+		if (SAVE_CONTEXT(_thread)) {							\
+	    	(*_main)();											\
+		}														\
+		_MD_SET_THR_SP(_thread, _sp);							\
+		_thread->no_sched = 0; 									\
+    PR_END_MACRO
+
+#define _MD_SWITCH_CONTEXT(_thread)  								\
+    PR_BEGIN_MACRO 													\
+	PR_ASSERT(_thread->no_sched);									\
+	if (!SAVE_CONTEXT(_thread)) {									\
+		(_thread)->md.errcode = errno;  							\
+		_MD_SET_LAST_THREAD(_thread);								\
+		_PR_Schedule();		     									\
+    } else {														\
+		 (_MD_LAST_THREAD())->no_sched = 0;							\
+	}																\
+    PR_END_MACRO
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)								\
+    PR_BEGIN_MACRO 													\
+    errno = (_thread)->md.errcode; 									\
+    _MD_SET_CURRENT_THREAD(_thread); 								\
+	_thread->no_sched = 1;											\
+    GOTO_CONTEXT(_thread); 											\
+    PR_END_MACRO
+
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    jmp_buf 		jb;
+    int				id;
+    int				errcode;
+	pthread_t		pthread;
+	pthread_mutex_t	pthread_mutex;
+	pthread_cond_t	pthread_cond;
+	int				wait;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+	pthread_mutex_t mutex;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+	pthread_mutex_t mutex;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    jmp_buf 			jb;
+	pthread_t 			pthread;
+	struct _MDCPU_Unix 	md_unix;
+};
+
+/*
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+*/
+
+extern pthread_mutex_t _pr_heapLock;
+
+#define _PR_LOCK(lock) pthread_mutex_lock(lock)
+
+#define _PR_UNLOCK(lock) pthread_mutex_unlock(lock)
+
+
+#define _PR_LOCK_HEAP()	{									\
+				if (_pr_primordialCPU) {					\
+					_PR_LOCK(_pr_heapLock);					\
+				}
+
+#define _PR_UNLOCK_HEAP() 	if (_pr_primordialCPU)	{		\
+					_PR_UNLOCK(_pr_heapLock);				\
+				}											\
+			  }
+
+NSPR_API(PRStatus) _MD_NEW_LOCK(struct _MDLock *md);
+NSPR_API(void) _MD_FREE_LOCK(struct _MDLock *lockp);
+
+#define _MD_LOCK(_lockp) _PR_LOCK(&(_lockp)->mutex)
+#define _MD_UNLOCK(_lockp) _PR_UNLOCK(&(_lockp)->mutex)
+
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+#define _MD_CHECK_FOR_EXIT()
+
+NSPR_API(PRStatus) _MD_InitThread(struct PRThread *thread);
+#define _MD_INIT_THREAD _MD_InitThread
+#define _MD_INIT_ATTACHED_THREAD _MD_InitThread
+
+NSPR_API(void) _MD_ExitThread(struct PRThread *thread);
+#define _MD_EXIT_THREAD _MD_ExitThread
+
+NSPR_API(void) _MD_SuspendThread(struct PRThread *thread);
+#define _MD_SUSPEND_THREAD _MD_SuspendThread
+
+NSPR_API(void) _MD_ResumeThread(struct PRThread *thread);
+#define _MD_RESUME_THREAD _MD_ResumeThread
+
+NSPR_API(void) _MD_SuspendCPU(struct _PRCPU *thread);
+#define _MD_SUSPEND_CPU _MD_SuspendCPU
+
+NSPR_API(void) _MD_ResumeCPU(struct _PRCPU *thread);
+#define _MD_RESUME_CPU _MD_ResumeCPU
+
+#define _MD_BEGIN_SUSPEND_ALL()
+#define _MD_END_SUSPEND_ALL()
+#define _MD_BEGIN_RESUME_ALL()
+#define _MD_END_RESUME_ALL()
+
+NSPR_API(void) _MD_EarlyInit(void);
+#define _MD_EARLY_INIT _MD_EarlyInit
+
+#define _MD_FINAL_INIT _PR_UnixInit
+
+NSPR_API(void) _MD_InitLocks(void);
+#define _MD_INIT_LOCKS _MD_InitLocks
+
+NSPR_API(void) _MD_CleanThread(struct PRThread *thread);
+#define _MD_CLEAN_THREAD _MD_CleanThread
+
+NSPR_API(PRStatus) _MD_CreateThread(
+                        struct PRThread *thread,
+                        void (*start) (void *),
+                        PRThreadPriority priority,
+                        PRThreadScope scope,
+                        PRThreadState state,
+                        PRUint32 stackSize);
+#define _MD_CREATE_THREAD _MD_CreateThread
+
+extern void _MD_CleanupBeforeExit(void);
+#define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit
+
+NSPR_API(void) _MD_InitRunningCPU(struct _PRCPU *cpu);
+#define    _MD_INIT_RUNNING_CPU _MD_InitRunningCPU
+
+/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
+ * awaken a thread which is waiting on a lock or cvar.
+ */
+NSPR_API(PRStatus) _MD_wait(struct PRThread *, PRIntervalTime timeout);
+#define _MD_WAIT _MD_wait
+
+NSPR_API(PRStatus) _MD_WakeupWaiter(struct PRThread *);
+#define _MD_WAKEUP_WAITER _MD_WakeupWaiter
+
+NSPR_API(void) _MD_SetPriority(struct _MDThread *thread,
+	PRThreadPriority newPri);
+#define _MD_SET_PRIORITY _MD_SetPriority
+
+#endif /* PTHREADS_USER */
+
+#endif /* nspr_pthread_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nto.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nto.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,150 @@
+/* -*- 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 ***** */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef NTO
+#define NTO
+#endif
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#ifdef __i386__
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define PR_BYTES_PER_BYTE   1L
+#define PR_BYTES_PER_SHORT  2L
+#define PR_BYTES_PER_INT    4L
+#define PR_BYTES_PER_INT64  8L
+#define PR_BYTES_PER_LONG   4L
+#define PR_BYTES_PER_FLOAT  4L
+#define PR_BYTES_PER_DOUBLE 8L
+#define PR_BYTES_PER_WORD   4L
+#define PR_BYTES_PER_DWORD  8L
+
+#define PR_BITS_PER_BYTE    8L
+#define PR_BITS_PER_SHORT   16L
+#define PR_BITS_PER_INT     32L
+#define PR_BITS_PER_INT64   64L
+#define PR_BITS_PER_LONG    32L
+#define PR_BITS_PER_FLOAT   32L
+#define PR_BITS_PER_DOUBLE  64L
+#define PR_BITS_PER_WORD    32L
+
+#define PR_BITS_PER_BYTE_LOG2   3L
+#define PR_BITS_PER_SHORT_LOG2  4L
+#define PR_BITS_PER_INT_LOG2    5L
+#define PR_BITS_PER_INT64_LOG2  6L
+#define PR_BITS_PER_LONG_LOG2   5L
+#define PR_BITS_PER_FLOAT_LOG2  5L
+#define PR_BITS_PER_DOUBLE_LOG2 6L
+#define PR_BITS_PER_WORD_LOG2   5L
+
+#define PR_ALIGN_OF_SHORT   2L
+#define PR_ALIGN_OF_INT     4L
+#define PR_ALIGN_OF_LONG    4L
+#define PR_ALIGN_OF_INT64   4L
+#define PR_ALIGN_OF_FLOAT   4L
+#define PR_ALIGN_OF_DOUBLE  4L
+#define PR_ALIGN_OF_POINTER 4L
+#define PR_ALIGN_OF_WORD    4L
+
+#define PR_BYTES_PER_WORD_LOG2   2L
+#define PR_BYTES_PER_DWORD_LOG2  3L
+#define PR_WORDS_PER_DWORD_LOG2  1L
+
+#else
+
+#error Undefined CPU Architecture
+
+#endif
+
+#define HAVE_LONG_LONG
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nto.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_nto.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,221 @@
+/* -*- 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 ***** */
+
+#ifndef nspr_nto_defs_h___
+#define nspr_nto_defs_h___
+
+/*
+** Internal configuration macros
+*/
+#define PR_LINKER_ARCH		"nto"
+#define _PR_SI_SYSNAME		"NTO"
+#define _PR_SI_ARCHITECTURE	"x86"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MINIMUM_STACK_SIZE	131072L
+#define _MD_MMAP_FLAGS		MAP_PRIVATE
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#undef  _PR_POLL_AVAILABLE
+#undef  _PR_USE_POLL
+#define _PR_HAVE_SOCKADDR_LEN
+#undef  HAVE_BSD_FLOCK
+#define HAVE_FCNTL_FILE_LOCKING
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#define _PR_HAVE_POSIX_SEMAPHORES
+
+#undef FD_SETSIZE
+#define FD_SETSIZE	4096
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+
+#undef  HAVE_STACK_GROWING_UP
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define _PR_NEED_STRCASECMP
+
+#ifndef HAVE_STRERROR
+#define HAVE_STRERROR
+#endif
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP			setjmp
+#define _LONGJMP		longjmp
+#define _PR_CONTEXT_TYPE	jmp_buf
+#define _PR_NUM_GCREGS		_JBLEN
+#define _MD_GET_SP(_t)		(_t)->md.context[7]
+
+#define CONTEXT(_th)		((_th)->md.context)
+
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	\
+{							\
+    *status = PR_TRUE;					\
+    if(_SETJMP(CONTEXT(_thread))) (*_main)();		\
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128);		\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)	\
+    if (!_SETJMP(CONTEXT(_thread))) {	\
+	(_thread)->md.errcode = errno;	\
+	_PR_Schedule();			\
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)	\
+{					\
+    errno = (_thread)->md.errcode;	\
+    _MD_SET_CURRENT_THREAD(_thread);	\
+    _LONGJMP(CONTEXT(_thread), 1);	\
+}
+
+/*
+** Machine-dependent (MD) data structures.
+*/
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+** md-specific cpu structure field
+*/
+#define _PR_MD_MAX_OSFD		FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+    struct pollfd *ioq_pollfds;
+    int ioq_pollfds_size;
+#endif
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu)	PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock)		PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_GET_INTERVAL		_PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC		_PR_UNIX_TicksPerSecond
+#define _MD_EARLY_INIT			_MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu)	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD			_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+** We wrapped the select() call.  _MD_SELECT refers to the built-in,
+** unwrapped version.
+*/
+#define _MD_SELECT		select
+
+#define SA_RESTART 0
+
+#endif /* nspr_nto_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openbsd.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openbsd.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,387 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef OPENBSD
+#define OPENBSD
+#endif
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#if defined(__i386__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(__amd64__)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+#define PR_ALIGN_OF_WORD    8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define HAVE_LONG_LONG
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+
+#elif defined(__sparc_v9__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define HAVE_LONG_LONG
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__sparc__)
+
+#undef IS_LITTLE_ENDIAN
+#define  IS_BIG_ENDIAN 1
+#define HAVE_LONG_LONG
+#define  HAVE_ALIGNED_DOUBLES
+#define  HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(__alpha__)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#elif defined(__powerpc__) || defined(__m68k__)
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN    1
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#else
+
+#error Must define constants for type sizes here.
+
+#endif
+
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openbsd.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openbsd.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,238 @@
+/* -*- 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 nspr_openbsd_defs_h___
+#define nspr_openbsd_defs_h___
+
+#include <sys/syscall.h>
+
+#define PR_LINKER_ARCH	"openbsd"
+#define _PR_SI_SYSNAME  "OPENBSD"
+#if defined(__i386__)
+#define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__alpha__)
+#define _PR_SI_ARCHITECTURE "alpha"
+#elif defined(__amd64__)
+#define _PR_SI_ARCHITECTURE "amd64"
+#elif defined(__m68k__)
+#define _PR_SI_ARCHITECTURE "m68k"
+#elif defined(__powerpc__)
+#define _PR_SI_ARCHITECTURE "powerpc"
+#elif defined(__sparc__)
+#define _PR_SI_ARCHITECTURE "sparc"
+#endif
+
+#define PR_DLL_SUFFIX		".so.1.0"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_DLFCN
+#define _PR_HAVE_SOCKADDR_LEN
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ST_ATIMESPEC
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+
+#define _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+
+#define USE_SETJMP
+
+#ifndef _PR_PTHREADS
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	sigjmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+#if defined(__i386__) || defined(__sparc__) || defined(__m68k__)
+#define JB_SP_INDEX 2
+#elif defined(__powerpc__)
+#define JB_SP_INDEX 1
+#elif defined(__alpha__)
+#define JB_SP_INDEX 34
+#elif defined(__amd64__)
+#define JB_SP_INDEX 6
+#else
+#error "Need to define SP index in jmp_buf here"
+#endif
+#define _MD_GET_SP(_th)    (_th)->md.context[JB_SP_INDEX]
+
+#define PR_NUM_GCREGS	_JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (sigsetjmp(CONTEXT(_thread), 1)) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!sigsetjmp(CONTEXT(_thread), 1)) {  \
+        (_thread)->md.errcode = errno;  \
+        _PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    siglongjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+#endif /* ! _PR_PTHREADS */
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+#include <poll.h>
+#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout)
+
+#if OpenBSD1_3 == 1L
+typedef unsigned int nfds_t;
+#endif
+
+#endif /* nspr_openbsd_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openvms.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openvms.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,146 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef VMS
+#define VMS
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+#ifdef IS_64
+#undef IS_64
+#endif
+
+#define PR_AF_INET6 26  /* same as AF_INET6 */
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32 
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_BYTES_PER_WORD_LOG2  2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openvms.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_openvms.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,332 @@
+/* -*- 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 ***** */
+
+/*
+** This is the OpenVMS machine dependant configuration file. It is based
+** on the OSF/1 machine dependant file.
+*/
+
+#ifndef nspr_openvms_defs_h___
+#define nspr_openvms_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"OpenVMS"
+#define _PR_SI_SYSNAME	"OpenVMS"
+#ifdef __alpha
+#define _PR_SI_ARCHITECTURE "alpha"
+#else
+#define _PR_SI_ARCHITECTURE "vax"
+#endif
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	131072L
+#define _MD_MINIMUM_STACK_SIZE	131072L
+
+/*
+** This is not defined on OpenVMS. I believe its only used in GC code, and
+** isn't that only used in Java? Anyway, for now, let's keep the compiler
+** happy.
+*/
+#define SA_RESTART 0
+
+/*
+** OpenVMS doesn't have these in socket.h.
+** Does in later versions!
+*/
+#if 0
+struct ip_mreq {
+    struct in_addr  imr_multiaddr;      /* IP multicast address of group */
+    struct in_addr  imr_interface;      /* local IP address of interface */
+};
+#endif
+
+/*
+ * OSF1 needs the MAP_FIXED flag to ensure that mmap returns a pointer
+ * with the upper 32 bits zero.  This is because Java sticks a pointer
+ * into an int.
+ */
+#define _MD_MMAP_FLAGS          MAP_PRIVATE|MAP_FIXED
+
+#undef  HAVE_STACK_GROWING_UP
+#undef 	HAVE_WEAK_IO_SYMBOLS
+#undef 	HAVE_WEAK_MALLOC_SYMBOLS
+#undef  HAVE_BSD_FLOCK
+
+#define NEED_TIME_R
+
+#define HAVE_DLL
+#define USE_DLFCN
+
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#define _PR_NO_LARGE_FILES
+#define _PR_STRICT_ADDR_LEN
+
+/* IPv6 support */
+#ifdef _SOCKADDR_LEN
+#define _PR_HAVE_SOCKADDR_LEN
+#endif
+#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#ifdef _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#else
+#define AF_INET6 26
+#ifndef AI_CANONNAME
+#define AI_CANONNAME 0x00000002
+struct addrinfo {
+    int ai_flags;
+    int ai_family;
+    int ai_socktype;
+    int ai_protocol;
+    size_t ai_addrlen;
+    char *ai_canonname;
+    struct sockaddr *ai_addr;
+    struct addrinfo *ai_next;
+};
+#endif
+#define AI_V4MAPPED 0x00000010
+#define AI_ALL      0x00000008
+#define AI_ADDRCONFIG 0x00000020
+#endif
+
+#define _PR_HAVE_MD_SOCKADDR_IN6
+/* if we have a quadword field defined in the structure, then its length */
+/* will be a multiple of 8, and connect() won't accept 32 (it wants 28) */
+struct _md_in6_addr {
+    union {
+        PRUint8  _S6_u8[16];
+        PRUint16 _S6_u16[8];
+        PRUint32 _S6_u32[4];
+    } _S6_un;
+};
+struct _md_sockaddr_in6 {
+    PRUint16 sin6_family;
+    PRUint16 sin6_port;
+    PRUint32 sin6_flowinfo;
+    struct _md_in6_addr sin6_addr;
+    PRUint32 sin6_scope_id;
+};
+
+#undef  USE_SETJMP
+
+#include <setjmp.h>
+
+/*
+ * A jmp_buf is actually a struct sigcontext.  The sc_sp field of
+ * struct sigcontext is the stack pointer.
+ */
+#define _MD_GET_SP(_t) (((struct sigcontext *) (_t)->md.context)->sc_sp)
+#define PR_NUM_GCREGS _JBLEN
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** I am ifdef'ing these out because that's the way they are in FT.
+*/
+#ifndef __VMS
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+{									  \
+        *status = PR_TRUE;              \
+    if (setjmp(CONTEXT(_thread))) {				\
+	(*_main)();						\
+    }								\
+    _MD_GET_SP(_thread) = (long) ((_sp) - 64);			\
+    _MD_GET_SP(_thread) &= ~15;					\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;     \
+    _MD_SET_CURRENT_THREAD(_thread);	\
+    longjmp(CONTEXT(_thread), 1);    \
+}
+
+#endif /* __VMS */
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    jmp_buf context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+                              fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+      struct pollfd *ioq_pollfds;
+      int ioq_pollfds_size;
+#endif        /* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)                 ((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)         ((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)         ((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)                ((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)                ((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)    ((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)    ((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)         ((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)                ((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)                ((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)         ((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)    ((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)        32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#ifndef _PR_PTHREADS
+#define _MD_INIT_LOCKS()
+#endif
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+ * The following are copied from _sunos.h, _aix.h.  This means
+ * some of them should probably be moved into _unixos.h.  But
+ * _irix.h seems to be quite different in regard to these macros.
+ */
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+extern PRIntervalTime _PR_UNIX_GetInterval(void);
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+void _MD_EarlyInit(void);
+#define _MD_FINAL_INIT		_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#ifdef _VMS_NOT_YET
+NSPR_API(void) _PR_InitThreads(
+  PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs);
+#endif
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/* The following defines unwrapped versions of select() and poll(). */
+extern int __select (int, fd_set *, fd_set *, fd_set *, struct timeval *);
+#define _MD_SELECT              __select
+
+#ifndef __VMS
+#define _MD_POLL __poll
+extern int __poll(struct pollfd filedes[], unsigned int nfds, int timeout);
+#endif
+
+#ifdef __VMS
+NSPR_API(void) _PR_InitCPUs(void);
+NSPR_API(void) _PR_MD_START_INTERRUPTS(void);
+#endif
+
+/*
+ * Atomic operations
+ */
+#include <machine/builtins.h>
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_ADD(ptr,val) (__ATOMIC_ADD_LONG(ptr,val) + val)
+#define _MD_ATOMIC_INCREMENT(val) (__ATOMIC_INCREMENT_LONG(val) + 1)
+#define _MD_ATOMIC_DECREMENT(val) (__ATOMIC_DECREMENT_LONG(val) - 1)
+#define _MD_ATOMIC_SET(val, newval) __ATOMIC_EXCH_LONG(val, newval)
+
+extern int thread_suspend(PRThread *thr_id);
+extern int thread_resume(PRThread *thr_id);
+
+#endif /* nspr_openvms_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_os2.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_os2.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,151 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_PC
+#define XP_PC
+#endif
+
+#ifndef XP_OS2
+#define XP_OS2
+#endif
+
+#ifndef OS2
+#define OS2
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#ifdef NO_LONG_LONG
+#undef HAVE_LONG_LONG
+#else
+#define HAVE_LONG_LONG 1
+#endif
+
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD       4
+#define PR_BYTES_PER_DWORD	8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	32
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	5
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_WORD	4
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2	2
+#define PR_BYTES_PER_DWORD_LOG2	2
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE      PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT     PR_BYTES_PER_SHORT
+#define BYTES_PER_INT       PR_BYTES_PER_INT
+#define BYTES_PER_INT64     PR_BYTES_PER_INT64
+#define BYTES_PER_LONG      PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT     PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE    PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD      PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD     PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE       PR_BITS_PER_BYTE
+#define BITS_PER_SHORT      PR_BITS_PER_SHORT
+#define BITS_PER_INT        PR_BITS_PER_INT
+#define BITS_PER_INT64      PR_BITS_PER_INT64
+#define BITS_PER_LONG       PR_BITS_PER_LONG
+#define BITS_PER_FLOAT      PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE     PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD       PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2  PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2   PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2  PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2    PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2  PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT      PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT        PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG       PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64      PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT      PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE     PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER    PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD       PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2		PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2    PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2    PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_os2.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_os2.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,594 @@
+/* -*- 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 nspr_os2_defs_h___
+#define nspr_os2_defs_h___
+
+#ifndef NO_LONG_LONG
+#define INCL_LONGLONG
+#endif
+#define INCL_DOS
+#define INCL_DOSPROCESS
+#define INCL_DOSERRORS
+#define INCL_WIN
+#define INCL_WPS
+#include <os2.h>
+#include <sys/select.h>
+
+#include "prio.h"
+
+#include <errno.h>
+
+#ifdef XP_OS2_VACPP
+/* TODO RAMSEMs need to be written for GCC/EMX */
+#define USE_RAMSEM
+#endif
+
+#ifdef USE_RAMSEM
+#pragma pack(4)
+
+#pragma pack(2)
+typedef struct _RAMSEM
+{
+   ULONG   ulTIDPID;
+   ULONG   hevSem;
+   ULONG   cLocks;
+   USHORT  cWaiting;
+   USHORT  cPosts;
+} RAMSEM, *PRAMSEM;
+
+typedef struct _CRITICAL_SECTION
+{
+    ULONG ulReserved[4]; /* Same size as RAMSEM */
+} CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION;
+#pragma pack(4)
+
+APIRET _Optlink SemRequest486(PRAMSEM, ULONG);
+APIRET _Optlink SemReleasex86(PRAMSEM, ULONG);
+#endif
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH      "os2"
+#define _PR_SI_SYSNAME        "OS2"
+#define _PR_SI_ARCHITECTURE   "x86"    /* XXXMB hardcode for now */
+
+#define HAVE_DLL
+#define _PR_GLOBAL_THREADS_ONLY
+#undef  HAVE_THREAD_AFFINITY
+#define _PR_HAVE_THREADSAFE_GETHOST
+#define _PR_HAVE_ATOMIC_OPS
+
+#define HANDLE unsigned long
+#define HINSTANCE HMODULE
+
+/* --- Common User-Thread/Native-Thread Definitions --------------------- */
+
+/* --- Globals --- */
+extern struct PRLock                      *_pr_schedLock;
+
+/* --- Typedefs --- */
+typedef void (*FiberFunc)(void *);
+
+#define PR_NUM_GCREGS           8
+typedef PRInt32	                PR_CONTEXT_TYPE[PR_NUM_GCREGS];
+#define GC_VMBASE               0x40000000
+#define GC_VMLIMIT              0x00FFFFFF
+typedef int (*FARPROC)();
+
+#define _MD_MAGIC_THREAD	0x22222222
+#define _MD_MAGIC_THREADSTACK	0x33333333
+#define _MD_MAGIC_SEGMENT	0x44444444
+#define _MD_MAGIC_DIR		0x55555555
+#define _MD_MAGIC_CV        0x66666666
+
+struct _MDSemaphore {
+   HEV sem;
+};
+
+struct _MDCPU {
+    int              unused;
+}; 
+
+struct _MDThread {
+    HEV              blocked_sema;      /* Threads block on this when waiting
+                                         * for IO or CondVar.
+                                         */
+    PRBool           inCVWaitQueue;     /* PR_TRUE if the thread is in the
+                                         * wait queue of some cond var.
+                                         * PR_FALSE otherwise.  */
+    TID              handle;            /* OS/2 thread handle */
+    void            *sp;                /* only valid when suspended */
+    PRUint32         magic;             /* for debugging */
+    PR_CONTEXT_TYPE  gcContext;         /* Thread context for GC */
+    struct PRThread *prev, *next;       /* used by the cvar wait queue to
+                                         * chain the PRThread structures
+                                         * together */
+};
+
+struct _MDThreadStack {
+    PRUint32           magic;          /* for debugging */
+};
+
+struct _MDSegment {
+    PRUint32           magic;          /* for debugging */
+};
+
+#undef PROFILE_LOCKS
+
+struct _MDDir {
+    HDIR           d_hdl;
+    union {
+        FILEFINDBUF3  small;
+        FILEFINDBUF3L large;
+    } d_entry;
+    PRBool           firstEntry;     /* Is this the entry returned
+                                      * by FindFirstFile()? */
+    PRUint32         magic;          /* for debugging */
+};
+
+struct _MDCVar {
+    PRUint32 magic;
+    struct PRThread *waitHead, *waitTail;  /* the wait queue: a doubly-
+                                            * linked list of threads
+                                            * waiting on this condition
+                                            * variable */
+    PRIntn nwait;                          /* number of threads in the
+                                            * wait queue */
+};
+
+#define _MD_CV_NOTIFIED_LENGTH 6
+typedef struct _MDNotified _MDNotified;
+struct _MDNotified {
+    PRIntn length;                     /* # of used entries in this
+                                        * structure */
+    struct {
+        struct _MDCVar *cv;            /* the condition variable notified */
+        PRIntn times;                  /* and the number of times notified */
+        struct PRThread *notifyHead;   /* list of threads to wake up */
+    } cv[_MD_CV_NOTIFIED_LENGTH];
+    _MDNotified *link;                 /* link to another of these, or NULL */
+};
+
+struct _MDLock {
+#ifdef USE_RAMSEM
+    CRITICAL_SECTION mutex;            /* this is recursive on NT */
+#else
+    HMTX mutex;                        /* this is recursive on NT */
+#endif
+
+    /*
+     * When notifying cvars, there is no point in actually
+     * waking up the threads waiting on the cvars until we've
+     * released the lock.  So, we temporarily record the cvars.
+     * When doing an unlock, we'll then wake up the waiting threads.
+     */
+    struct _MDNotified notified;     /* array of conditions notified */
+#ifdef PROFILE_LOCKS
+    PRInt32 hitcount;
+    PRInt32 misscount;
+#endif
+};
+
+struct _MDFileDesc {
+    PRInt32 osfd;    /* The osfd can come from one of three spaces:
+                      * - For stdin, stdout, and stderr, we are using
+                      *   the libc file handle (0, 1, 2), which is an int.
+                      * - For files and pipes, we are using OS/2 handles,
+                      *   which is a void*.
+                      * - For sockets, we are using int
+                      */
+};
+
+struct _MDProcess {
+   PID pid;
+};
+
+/* --- Misc stuff --- */
+#define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
+
+/* --- IO stuff --- */
+
+#define _MD_OPEN                      (_PR_MD_OPEN)
+#define _MD_OPEN_FILE                 (_PR_MD_OPEN)
+#define _MD_READ                      (_PR_MD_READ)
+#define _MD_WRITE                     (_PR_MD_WRITE)
+#define _MD_WRITEV                    (_PR_MD_WRITEV)
+#define _MD_LSEEK                     (_PR_MD_LSEEK)
+#define _MD_LSEEK64                   (_PR_MD_LSEEK64)
+extern PRInt32 _MD_CloseFile(PRInt32 osfd);
+#define _MD_CLOSE_FILE                _MD_CloseFile
+#define _MD_GETFILEINFO               (_PR_MD_GETFILEINFO)
+#define _MD_GETFILEINFO64             (_PR_MD_GETFILEINFO64)
+#define _MD_GETOPENFILEINFO           (_PR_MD_GETOPENFILEINFO)
+#define _MD_GETOPENFILEINFO64         (_PR_MD_GETOPENFILEINFO64)
+#define _MD_STAT                      (_PR_MD_STAT)
+#define _MD_RENAME                    (_PR_MD_RENAME)
+#define _MD_ACCESS                    (_PR_MD_ACCESS)
+#define _MD_DELETE                    (_PR_MD_DELETE)
+#define _MD_MKDIR                     (_PR_MD_MKDIR)
+#define _MD_MAKE_DIR                  (_PR_MD_MKDIR)
+#define _MD_RMDIR                     (_PR_MD_RMDIR)
+#define _MD_LOCKFILE                  (_PR_MD_LOCKFILE)
+#define _MD_TLOCKFILE                 (_PR_MD_TLOCKFILE)
+#define _MD_UNLOCKFILE                (_PR_MD_UNLOCKFILE)
+
+/* --- Socket IO stuff --- */
+
+/* The ones that don't map directly may need to be re-visited... */
+#ifdef XP_OS2_VACPP
+#define EPIPE                     EBADF
+#define EIO                       ECONNREFUSED
+#endif
+#define _MD_EACCES                EACCES
+#define _MD_EADDRINUSE            EADDRINUSE
+#define _MD_EADDRNOTAVAIL         EADDRNOTAVAIL
+#define _MD_EAFNOSUPPORT          EAFNOSUPPORT
+#define _MD_EAGAIN                EWOULDBLOCK
+#define _MD_EALREADY              EALREADY
+#define _MD_EBADF                 EBADF
+#define _MD_ECONNREFUSED          ECONNREFUSED
+#define _MD_ECONNRESET            ECONNRESET
+#define _MD_EFAULT                SOCEFAULT
+#define _MD_EINPROGRESS           EINPROGRESS
+#define _MD_EINTR                 EINTR
+#define _MD_EINVAL                EINVAL
+#define _MD_EISCONN               EISCONN
+#define _MD_ENETUNREACH           ENETUNREACH
+#define _MD_ENOENT                ENOENT
+#define _MD_ENOTCONN              ENOTCONN
+#define _MD_ENOTSOCK              ENOTSOCK
+#define _MD_EOPNOTSUPP            EOPNOTSUPP
+#define _MD_EWOULDBLOCK           EWOULDBLOCK
+#define _MD_GET_SOCKET_ERROR()    sock_errno()
+#ifndef INADDR_LOOPBACK /* For some reason this is not defined in OS2 tcpip */
+/*  #define INADDR_LOOPBACK         INADDR_ANY */
+#endif  
+
+#define _MD_INIT_FILEDESC(fd)
+extern void _MD_MakeNonblock(PRFileDesc *f);
+#define _MD_MAKE_NONBLOCK             _MD_MakeNonblock
+#define _MD_INIT_FD_INHERITABLE       (_PR_MD_INIT_FD_INHERITABLE)
+#define _MD_QUERY_FD_INHERITABLE      (_PR_MD_QUERY_FD_INHERITABLE)
+#define _MD_SHUTDOWN                  (_PR_MD_SHUTDOWN)
+#define _MD_LISTEN                    _PR_MD_LISTEN
+extern PRInt32 _MD_CloseSocket(PRInt32 osfd);
+#define _MD_CLOSE_SOCKET              _MD_CloseSocket
+#define _MD_SENDTO                    (_PR_MD_SENDTO)
+#define _MD_RECVFROM                  (_PR_MD_RECVFROM)
+#ifdef XP_OS2_VACPP
+#define _MD_SOCKETPAIR(s, type, proto, sv) -1
+#else
+#define _MD_SOCKETPAIR                (_PR_MD_SOCKETPAIR)
+#endif
+#define _MD_GETSOCKNAME               (_PR_MD_GETSOCKNAME)
+#define _MD_GETPEERNAME               (_PR_MD_GETPEERNAME)
+#define _MD_GETSOCKOPT                (_PR_MD_GETSOCKOPT)
+#define _MD_SETSOCKOPT                (_PR_MD_SETSOCKOPT)
+
+#define _MD_FSYNC                     _PR_MD_FSYNC
+#define _MD_SET_FD_INHERITABLE        (_PR_MD_SET_FD_INHERITABLE)
+
+#ifdef _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT          _PR_MD_ATOMIC_INCREMENT
+#define _MD_ATOMIC_ADD                _PR_MD_ATOMIC_ADD
+#define _MD_ATOMIC_DECREMENT          _PR_MD_ATOMIC_DECREMENT
+#define _MD_ATOMIC_SET                _PR_MD_ATOMIC_SET
+#endif
+
+#define _MD_INIT_IO                   (_PR_MD_INIT_IO)
+#define _MD_PR_POLL                   (_PR_MD_PR_POLL)
+
+#define _MD_SOCKET                    (_PR_MD_SOCKET)
+extern PRInt32 _MD_SocketAvailable(PRFileDesc *fd);
+#define _MD_SOCKETAVAILABLE           _MD_SocketAvailable
+#define _MD_PIPEAVAILABLE             _MD_SocketAvailable
+#define _MD_CONNECT                   (_PR_MD_CONNECT)
+extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
+        PRIntervalTime timeout);
+#define _MD_ACCEPT                    _MD_Accept
+#define _MD_BIND                      (_PR_MD_BIND)
+#define _MD_RECV                      (_PR_MD_RECV)
+#define _MD_SEND                      (_PR_MD_SEND)
+
+/* --- Scheduler stuff --- */
+/* #define _MD_PAUSE_CPU                 _PR_MD_PAUSE_CPU */
+#define _MD_PAUSE_CPU
+
+/* --- DIR stuff --- */
+#define PR_DIRECTORY_SEPARATOR        '\\'
+#define PR_DIRECTORY_SEPARATOR_STR    "\\"
+#define PR_PATH_SEPARATOR		';'
+#define PR_PATH_SEPARATOR_STR		";"
+#define _MD_ERRNO()                   errno
+#define _MD_OPEN_DIR                  (_PR_MD_OPEN_DIR)
+#define _MD_CLOSE_DIR                 (_PR_MD_CLOSE_DIR)
+#define _MD_READ_DIR                  (_PR_MD_READ_DIR)
+
+/* --- Segment stuff --- */
+#define _MD_INIT_SEGS()
+#define _MD_ALLOC_SEGMENT(seg, size, vaddr)   0
+#define _MD_FREE_SEGMENT(seg)
+
+/* --- Environment Stuff --- */
+#define _MD_GET_ENV                 (_PR_MD_GET_ENV)
+#define _MD_PUT_ENV                 (_PR_MD_PUT_ENV)
+
+/* --- Threading Stuff --- */
+#define _MD_DEFAULT_STACK_SIZE      65536L
+#define _MD_INIT_THREAD             (_PR_MD_INIT_THREAD)
+#define _MD_INIT_ATTACHED_THREAD    (_PR_MD_INIT_THREAD)
+#define _MD_CREATE_THREAD           (_PR_MD_CREATE_THREAD)
+#define _MD_YIELD                   (_PR_MD_YIELD)
+#define _MD_SET_PRIORITY            (_PR_MD_SET_PRIORITY)
+#define _MD_CLEAN_THREAD            (_PR_MD_CLEAN_THREAD)
+#define _MD_SETTHREADAFFINITYMASK   (_PR_MD_SETTHREADAFFINITYMASK)
+#define _MD_GETTHREADAFFINITYMASK   (_PR_MD_GETTHREADAFFINITYMASK)
+#define _MD_EXIT_THREAD             (_PR_MD_EXIT_THREAD)
+#define _MD_SUSPEND_THREAD          (_PR_MD_SUSPEND_THREAD)
+#define _MD_RESUME_THREAD           (_PR_MD_RESUME_THREAD)
+#define _MD_SUSPEND_CPU             (_PR_MD_SUSPEND_CPU)
+#define _MD_RESUME_CPU              (_PR_MD_RESUME_CPU)
+#define _MD_WAKEUP_CPUS             (_PR_MD_WAKEUP_CPUS)
+#define _MD_BEGIN_SUSPEND_ALL()
+#define _MD_BEGIN_RESUME_ALL()
+#define _MD_END_SUSPEND_ALL()
+#define _MD_END_RESUME_ALL()
+
+/* --- Lock stuff --- */
+#define _PR_LOCK                      _MD_LOCK
+#define _PR_UNLOCK					  _MD_UNLOCK
+
+#ifdef USE_RAMSEM
+#define _MD_NEW_LOCK                  (_PR_MD_NEW_LOCK)
+#define _MD_FREE_LOCK(lock)           (DosCloseEventSem(((PRAMSEM)(&((lock)->mutex)))->hevSem))
+#define _MD_LOCK(lock)                (SemRequest486(&((lock)->mutex), -1))
+#define _MD_TEST_AND_LOCK(lock)       (SemRequest486(&((lock)->mutex), -1),0)
+#define _MD_UNLOCK(lock)              \
+    PR_BEGIN_MACRO \
+    if (0 != (lock)->notified.length) { \
+        md_UnlockAndPostNotifies((lock), NULL, NULL); \
+    } else { \
+        SemReleasex86( &(lock)->mutex, 0 ); \
+    } \
+    PR_END_MACRO
+#else
+#define _MD_NEW_LOCK                  (_PR_MD_NEW_LOCK)
+#define _MD_FREE_LOCK(lock)           (DosCloseMutexSem((lock)->mutex))
+#define _MD_LOCK(lock)                (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT))
+#define _MD_TEST_AND_LOCK(lock)       (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT),0)
+#define _MD_UNLOCK(lock)              \
+    PR_BEGIN_MACRO \
+    if (0 != (lock)->notified.length) { \
+        md_UnlockAndPostNotifies((lock), NULL, NULL); \
+    } else { \
+        DosReleaseMutexSem((lock)->mutex); \
+    } \
+    PR_END_MACRO
+#endif
+
+/* --- lock and cv waiting --- */
+#define _MD_WAIT                      (_PR_MD_WAIT)
+#define _MD_WAKEUP_WAITER             (_PR_MD_WAKEUP_WAITER)
+
+/* --- CVar ------------------- */
+#define _MD_WAIT_CV					  (_PR_MD_WAIT_CV)
+#define _MD_NEW_CV					  (_PR_MD_NEW_CV)
+#define _MD_FREE_CV					  (_PR_MD_FREE_CV)
+#define _MD_NOTIFY_CV				  (_PR_MD_NOTIFY_CV	)
+#define _MD_NOTIFYALL_CV			  (_PR_MD_NOTIFYALL_CV)
+
+   /* XXXMB- the IOQ stuff is certainly not working correctly yet. */
+/* extern  struct _MDLock              _pr_ioq_lock; */
+#define _MD_IOQ_LOCK()                
+#define _MD_IOQ_UNLOCK()              
+
+
+/* --- Initialization stuff --- */
+#define _MD_START_INTERRUPTS()
+#define _MD_STOP_INTERRUPTS()
+#define _MD_DISABLE_CLOCK_INTERRUPTS()
+#define _MD_ENABLE_CLOCK_INTERRUPTS()
+#define _MD_BLOCK_CLOCK_INTERRUPTS()
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS()
+#define _MD_EARLY_INIT                (_PR_MD_EARLY_INIT)
+#define _MD_FINAL_INIT()
+#define _MD_INIT_CPUS()
+#define _MD_INIT_RUNNING_CPU(cpu)
+
+struct PRProcess;
+struct PRProcessAttr;
+
+#define _MD_CREATE_PROCESS _PR_CreateOS2Process
+extern struct PRProcess * _PR_CreateOS2Process(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const struct PRProcessAttr *attr
+);
+
+#define _MD_DETACH_PROCESS _PR_DetachOS2Process
+extern PRStatus _PR_DetachOS2Process(struct PRProcess *process);
+
+/* --- Wait for a child process to terminate --- */
+#define _MD_WAIT_PROCESS _PR_WaitOS2Process
+extern PRStatus _PR_WaitOS2Process(struct PRProcess *process, 
+    PRInt32 *exitCode);
+
+#define _MD_KILL_PROCESS _PR_KillOS2Process
+extern PRStatus _PR_KillOS2Process(struct PRProcess *process);
+
+#define _MD_CLEANUP_BEFORE_EXIT()
+#define _MD_EXIT                          (_PR_MD_EXIT)
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+    PR_BEGIN_MACRO \
+    *status = PR_TRUE; \
+    PR_END_MACRO
+#define _MD_SWITCH_CONTEXT
+#define _MD_RESTORE_CONTEXT
+
+/* --- Intervals --- */
+#define _MD_INTERVAL_INIT                 (_PR_MD_INTERVAL_INIT)
+#define _MD_GET_INTERVAL                  (_PR_MD_GET_INTERVAL)
+#define _MD_INTERVAL_PER_SEC              (_PR_MD_INTERVAL_PER_SEC)
+#define _MD_INTERVAL_PER_MILLISEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000)
+#define _MD_INTERVAL_PER_MICROSEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000000)
+
+/* --- Native-Thread Specific Definitions ------------------------------- */
+
+typedef struct __NSPR_TLS
+{
+    struct PRThread  *_pr_thread_last_run;
+    struct PRThread  *_pr_currentThread;
+    struct _PRCPU    *_pr_currentCPU;
+} _NSPR_TLS;
+
+extern _NSPR_TLS*  pThreadLocalStorage;
+NSPR_API(void) _PR_MD_ENSURE_TLS(void);
+
+#define _MD_GET_ATTACHED_THREAD() pThreadLocalStorage->_pr_currentThread
+extern struct PRThread * _MD_CURRENT_THREAD(void);
+#define _MD_SET_CURRENT_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentThread = (_thread)
+
+#define _MD_LAST_THREAD() pThreadLocalStorage->_pr_thread_last_run
+#define _MD_SET_LAST_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_thread_last_run = (_thread)
+
+#define _MD_CURRENT_CPU() pThreadLocalStorage->_pr_currentCPU
+#define _MD_SET_CURRENT_CPU(_cpu) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentCPU = (_cpu)
+
+/* lth. #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val)) */
+/* lth. #define _MD_GET_INTSOFF() _pr_ints_off */
+/* lth. #define _MD_INCREMENT_INTSOFF() (_pr_ints_off++) */
+/* lth. #define _MD_DECREMENT_INTSOFF() (_pr_ints_off--) */
+
+/* --- Scheduler stuff --- */
+#define LOCK_SCHEDULER()                 0
+#define UNLOCK_SCHEDULER()               0
+#define _PR_LockSched()                	 0
+#define _PR_UnlockSched()                0
+
+/* --- Initialization stuff --- */
+#define _MD_INIT_LOCKS()
+
+/* --- Stack stuff --- */
+#define _MD_INIT_STACK(stack, redzone)
+#define _MD_CLEAR_STACK(stack)
+
+/* --- Memory-mapped files stuff --- not implemented on OS/2 */
+
+struct _MDFileMap {
+    PRInt8 unused;
+};
+
+extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
+#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
+
+extern PRInt32 _MD_GetMemMapAlignment(void);
+#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment
+
+extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
+        PRUint32 len);
+#define _MD_MEM_MAP _MD_MemMap
+
+extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
+#define _MD_MEM_UNMAP _MD_MemUnmap
+
+extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
+#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
+
+/* Some stuff for setting up thread contexts */
+typedef ULONG DWORD, *PDWORD;
+
+/* The following definitions and two structures are new in OS/2 Warp 4.0.
+ */
+#ifndef CONTEXT_CONTROL
+#define CONTEXT_CONTROL        0x00000001
+#define CONTEXT_INTEGER        0x00000002
+#define CONTEXT_SEGMENTS       0x00000004
+#define CONTEXT_FLOATING_POINT 0x00000008
+#define CONTEXT_FULL           0x0000000F
+
+#pragma pack(2)
+typedef struct _FPREG {
+    ULONG      losig;    /*  Low 32-bits of the significand. */
+    ULONG      hisig;    /*  High 32-bits of the significand. */
+    USHORT     signexp;  /*  Sign and exponent. */
+} FPREG;
+typedef struct _CONTEXTRECORD {
+    ULONG     ContextFlags;
+    ULONG     ctx_env[7];
+    FPREG     ctx_stack[8];
+    ULONG     ctx_SegGs;     /*  GS register. */
+    ULONG     ctx_SegFs;     /*  FS register. */
+    ULONG     ctx_SegEs;     /*  ES register. */
+    ULONG     ctx_SegDs;     /*  DS register. */
+    ULONG     ctx_RegEdi;    /*  EDI register. */
+    ULONG     ctx_RegEsi;    /*  ESI register. */
+    ULONG     ctx_RegEax;    /*  EAX register. */
+    ULONG     ctx_RegEbx;    /*  EBX register. */
+    ULONG     ctx_RegEcx;    /*  ECX register. */
+    ULONG     ctx_RegEdx;    /*  EDX register. */
+    ULONG     ctx_RegEbp;    /*  EBP register. */
+    ULONG     ctx_RegEip;    /*  EIP register. */
+    ULONG     ctx_SegCs;     /*  CS register. */
+    ULONG     ctx_EFlags;    /*  EFLAGS register. */
+    ULONG     ctx_RegEsp;    /*  ESP register. */
+    ULONG     ctx_SegSs;     /*  SS register. */
+} CONTEXTRECORD, *PCONTEXTRECORD;
+#pragma pack()
+#endif
+
+extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
+
+/*
+#define _pr_tid            (((PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2)))->tib2_ultid)
+#define _pr_current_Thread (_system_tls[_pr_tid-1].__pr_current_thread)
+*/
+
+/* Some simple mappings of Windows API's to OS/2 API's to make our lives a
+ * little bit easier.  Only add one here if it is a DIRECT mapping.  We are
+ * not emulating anything.  Just mapping.
+ */
+#define FreeLibrary(x) DosFreeModule((HMODULE)x)
+#define OutputDebugString(x)
+                               
+extern int _MD_os2_get_nonblocking_connect_error(int osfd);
+
+#endif /* nspr_os2_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_os2_errors.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_os2_errors.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,162 @@
+/* -*- 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 nspr_os2_errors_h___
+#define nspr_os2_errors_h___
+
+#include "md/_os2.h"
+#ifndef assert
+  #include <assert.h>
+#endif  
+
+NSPR_API(void) _MD_os2_map_default_error(PRInt32 err);
+#define	_PR_MD_MAP_DEFAULT_ERROR	_MD_os2_map_default_error
+
+NSPR_API(void) _MD_os2_map_opendir_error(PRInt32 err);
+#define	_PR_MD_MAP_OPENDIR_ERROR	_MD_os2_map_opendir_error
+
+NSPR_API(void) _MD_os2_map_closedir_error(PRInt32 err);
+#define	_PR_MD_MAP_CLOSEDIR_ERROR	_MD_os2_map_closedir_error
+
+NSPR_API(void) _MD_os2_readdir_error(PRInt32 err);
+#define	_PR_MD_MAP_READDIR_ERROR	_MD_os2_readdir_error
+
+NSPR_API(void) _MD_os2_map_delete_error(PRInt32 err);
+#define	_PR_MD_MAP_DELETE_ERROR	_MD_os2_map_delete_error
+
+NSPR_API(void) _MD_os2_map_stat_error(PRInt32 err);
+#define	_PR_MD_MAP_STAT_ERROR	_MD_os2_map_stat_error
+
+NSPR_API(void) _MD_os2_map_fstat_error(PRInt32 err);
+#define	_PR_MD_MAP_FSTAT_ERROR	_MD_os2_map_fstat_error
+
+NSPR_API(void) _MD_os2_map_rename_error(PRInt32 err);
+#define	_PR_MD_MAP_RENAME_ERROR	_MD_os2_map_rename_error
+
+NSPR_API(void) _MD_os2_map_access_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCESS_ERROR	_MD_os2_map_access_error
+
+NSPR_API(void) _MD_os2_map_mkdir_error(PRInt32 err);
+#define	_PR_MD_MAP_MKDIR_ERROR	_MD_os2_map_mkdir_error
+
+NSPR_API(void) _MD_os2_map_rmdir_error(PRInt32 err);
+#define	_PR_MD_MAP_RMDIR_ERROR	_MD_os2_map_rmdir_error
+
+NSPR_API(void) _MD_os2_map_read_error(PRInt32 err);
+#define	_PR_MD_MAP_READ_ERROR	_MD_os2_map_read_error
+
+NSPR_API(void) _MD_os2_map_transmitfile_error(PRInt32 err);
+#define	_PR_MD_MAP_TRANSMITFILE_ERROR	_MD_os2_map_transmitfile_error
+
+NSPR_API(void) _MD_os2_map_write_error(PRInt32 err);
+#define	_PR_MD_MAP_WRITE_ERROR	_MD_os2_map_write_error
+
+NSPR_API(void) _MD_os2_map_lseek_error(PRInt32 err);
+#define	_PR_MD_MAP_LSEEK_ERROR	_MD_os2_map_lseek_error
+
+NSPR_API(void) _MD_os2_map_fsync_error(PRInt32 err);
+#define	_PR_MD_MAP_FSYNC_ERROR	_MD_os2_map_fsync_error
+
+NSPR_API(void) _MD_os2_map_close_error(PRInt32 err);
+#define	_PR_MD_MAP_CLOSE_ERROR	_MD_os2_map_close_error
+
+NSPR_API(void) _MD_os2_map_socket_error(PRInt32 err);
+#define	_PR_MD_MAP_SOCKET_ERROR	_MD_os2_map_socket_error
+
+NSPR_API(void) _MD_os2_map_recv_error(PRInt32 err);
+#define	_PR_MD_MAP_RECV_ERROR	_MD_os2_map_recv_error
+
+NSPR_API(void) _MD_os2_map_recvfrom_error(PRInt32 err);
+#define	_PR_MD_MAP_RECVFROM_ERROR	_MD_os2_map_recvfrom_error
+
+NSPR_API(void) _MD_os2_map_send_error(PRInt32 err);
+#define	_PR_MD_MAP_SEND_ERROR	_MD_os2_map_send_error
+
+NSPR_API(void) _MD_os2_map_sendto_error(PRInt32 err);
+#define	_PR_MD_MAP_SENDTO_ERROR	_MD_os2_map_sendto_error
+
+NSPR_API(void) _MD_os2_map_writev_error(int err);
+#define	_PR_MD_MAP_WRITEV_ERROR	_MD_os2_map_writev_error
+
+NSPR_API(void) _MD_os2_map_accept_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCEPT_ERROR	_MD_os2_map_accept_error
+
+NSPR_API(void) _MD_os2_map_acceptex_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCEPTEX_ERROR	_MD_os2_map_acceptex_error
+
+NSPR_API(void) _MD_os2_map_connect_error(PRInt32 err);
+#define	_PR_MD_MAP_CONNECT_ERROR	_MD_os2_map_connect_error
+
+NSPR_API(void) _MD_os2_map_bind_error(PRInt32 err);
+#define	_PR_MD_MAP_BIND_ERROR	_MD_os2_map_bind_error
+
+NSPR_API(void) _MD_os2_map_listen_error(PRInt32 err);
+#define	_PR_MD_MAP_LISTEN_ERROR	_MD_os2_map_listen_error
+
+NSPR_API(void) _MD_os2_map_shutdown_error(PRInt32 err);
+#define	_PR_MD_MAP_SHUTDOWN_ERROR	_MD_os2_map_shutdown_error
+
+#ifndef XP_OS2_VACPP
+NSPR_API(void) _MD_os2_map_socketpair_error(int err);
+#define	_PR_MD_MAP_SOCKETPAIR_ERROR	_MD_os2_map_socketpair_error
+#endif
+
+NSPR_API(void) _MD_os2_map_getsockname_error(PRInt32 err);
+#define	_PR_MD_MAP_GETSOCKNAME_ERROR	_MD_os2_map_getsockname_error
+
+NSPR_API(void) _MD_os2_map_getpeername_error(PRInt32 err);
+#define	_PR_MD_MAP_GETPEERNAME_ERROR	_MD_os2_map_getpeername_error
+
+NSPR_API(void) _MD_os2_map_getsockopt_error(PRInt32 err);
+#define	_PR_MD_MAP_GETSOCKOPT_ERROR	_MD_os2_map_getsockopt_error
+
+NSPR_API(void) _MD_os2_map_setsockopt_error(PRInt32 err);
+#define	_PR_MD_MAP_SETSOCKOPT_ERROR	_MD_os2_map_setsockopt_error
+
+NSPR_API(void) _MD_os2_map_open_error(PRInt32 err);
+#define	_PR_MD_MAP_OPEN_ERROR	_MD_os2_map_open_error
+
+NSPR_API(void) _MD_os2_map_gethostname_error(PRInt32 err);
+#define	_PR_MD_MAP_GETHOSTNAME_ERROR	_MD_os2_map_gethostname_error
+
+NSPR_API(void) _MD_os2_map_select_error(PRInt32 err);
+#define	_PR_MD_MAP_SELECT_ERROR	_MD_os2_map_select_error
+
+NSPR_API(void) _MD_os2_map_lockf_error(int err);
+#define _PR_MD_MAP_LOCKF_ERROR  _MD_os2_map_lockf_error
+
+#endif /* nspr_os2_errors_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_osf1.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_osf1.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,146 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef OSF1
+#define OSF1
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define	HAVE_LONG_LONG
+#define HAVE_ALIGNED_DOUBLES
+#define HAVE_ALIGNED_LONGLONGS
+#ifndef IS_64
+#define IS_64
+#endif
+
+#define PR_AF_INET6 26  /* same as AF_INET6 */
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_BYTES_PER_WORD_LOG2  3
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_osf1.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_osf1.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,255 @@
+/* -*- 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 nspr_osf1_defs_h___
+#define nspr_osf1_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"osf"
+#define _PR_SI_SYSNAME	"OSF"
+#define _PR_SI_ARCHITECTURE "alpha"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE        0x50000000
+#define _MD_DEFAULT_STACK_SIZE  131072L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#undef 	HAVE_WEAK_IO_SYMBOLS
+#undef 	HAVE_WEAK_MALLOC_SYMBOLS
+#define HAVE_DLL
+#define HAVE_BSD_FLOCK
+
+#define NEED_TIME_R
+#define USE_DLFCN
+
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#define _PR_HAVE_LARGE_OFF_T
+#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#ifdef _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#else
+#define AF_INET6 26
+#ifndef AI_CANONNAME
+#define AI_CANONNAME 0x00000002
+struct addrinfo {
+    int              ai_flags;
+    int              ai_family;
+    int              ai_socktype;
+    int              ai_protocol;
+    size_t           ai_addrlen;
+    char            *ai_canonname;
+    struct sockaddr *ai_addr;
+    struct addrinfo *ai_next;
+};
+#endif
+#define AI_V4MAPPED 0x00000010
+#define AI_ALL      0x00000008
+#define AI_ADDRCONFIG 0x00000020
+#endif
+#define _PR_HAVE_POSIX_SEMAPHORES
+#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+/*
+ * A jmp_buf is actually a struct sigcontext.  The sc_sp field of
+ * struct sigcontext is the stack pointer.
+ */
+#define _MD_GET_SP(_t) (((struct sigcontext *) (_t)->md.context)->sc_sp)
+#define PR_NUM_GCREGS _JBLEN
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+{									  \
+        *status = PR_TRUE;              \
+    if (setjmp(CONTEXT(_thread))) {				\
+	(*_main)();						\
+    }								\
+    _MD_GET_SP(_thread) = (long) ((_sp) - 64);			\
+    _MD_GET_SP(_thread) &= ~15;					\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;     \
+    _MD_SET_CURRENT_THREAD(_thread);	\
+    longjmp(CONTEXT(_thread), 1);    \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    jmp_buf context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#ifndef _PR_PTHREADS
+#define _MD_INIT_LOCKS()
+#endif
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+ * The following are copied from _sunos.h, _aix.h.  This means
+ * some of them should probably be moved into _unixos.h.  But
+ * _irix.h seems to be quite different in regard to these macros.
+ */
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/* The following defines unwrapped versions of select() and poll(). */
+#include <sys/time.h>
+extern int __select (int, fd_set *, fd_set *, fd_set *, struct timeval *);
+#define _MD_SELECT              __select
+
+#include <sys/poll.h>
+#define _MD_POLL __poll
+extern int __poll(struct pollfd filedes[], unsigned int nfds, int timeout);
+
+/*
+ * Atomic operations
+ */
+#ifdef OSF1_HAVE_MACHINE_BUILTINS_H
+#include <machine/builtins.h>
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT(val) (__ATOMIC_INCREMENT_LONG(val) + 1)
+#define _MD_ATOMIC_ADD(ptr, val)  (__ATOMIC_ADD_LONG(ptr, val) + val)
+#define _MD_ATOMIC_DECREMENT(val) (__ATOMIC_DECREMENT_LONG(val) - 1)
+#define _MD_ATOMIC_SET(val, newval) __ATOMIC_EXCH_LONG(val, newval)
+#endif /* OSF1_HAVE_MACHINE_BUILTINS_H */
+
+#endif /* nspr_osf1_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_pcos.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_pcos.h	Mon Dec 18 10:53:47 2006
@@ -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) 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 prpcos_h___
+#define prpcos_h___
+
+#define PR_DLL_SUFFIX		".dll"
+
+#include <stdlib.h>
+
+#define DIRECTORY_SEPARATOR         '\\'
+#define DIRECTORY_SEPARATOR_STR     "\\"
+#define PATH_SEPARATOR              ';'
+
+#ifdef WIN16
+#define GCPTR __far
+#else
+#define GCPTR
+#endif
+
+/*
+** Routines for processing command line arguments
+*/
+PR_BEGIN_EXTERN_C
+#ifndef XP_OS2_EMX
+extern char *optarg;
+extern int optind;
+extern int getopt(int argc, char **argv, char *spec);
+#endif
+PR_END_EXTERN_C
+
+
+/*
+** Definitions of directory structures amd functions
+** These definitions are from:
+**      <dirent.h>
+*/
+#ifdef XP_OS2_EMX
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+#include <io.h>
+#include <fcntl.h>          /* O_BINARY */
+
+#ifdef OS2
+extern PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen);
+#define _MD_GETHOSTNAME _MD_OS2GetHostName
+#else
+extern PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen);
+#define _MD_GETHOSTNAME _MD_WindowsGetHostName
+extern PRStatus _MD_WindowsGetSysInfo(PRSysInfo cmd, char *name, PRUint32 namelen);
+#define _MD_GETSYSINFO _MD_WindowsGetSysInfo
+#endif
+
+#endif /* prpcos_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_pth.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_pth.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,311 @@
+/* -*- 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 nspr_pth_defs_h_
+#define nspr_pth_defs_h_
+
+/*
+** Appropriate definitions of entry points not used in a pthreads world
+*/
+#define _PR_MD_BLOCK_CLOCK_INTERRUPTS()
+#define _PR_MD_UNBLOCK_CLOCK_INTERRUPTS()
+#define _PR_MD_DISABLE_CLOCK_INTERRUPTS()
+#define _PR_MD_ENABLE_CLOCK_INTERRUPTS()
+
+/* In good standards fashion, the DCE threads (based on posix-4) are not
+ * quite the same as newer posix implementations.  These are mostly name
+ * changes and small differences, so macros usually do the trick
+ */
+#ifdef _PR_DCETHREADS
+#define _PT_PTHREAD_MUTEXATTR_INIT        pthread_mutexattr_create
+#define _PT_PTHREAD_MUTEXATTR_DESTROY     pthread_mutexattr_delete
+#define _PT_PTHREAD_MUTEX_INIT(m, a)      pthread_mutex_init(&(m), a)
+#define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    (0 == pthread_mutex_trylock(&(m)))
+#define _PT_PTHREAD_CONDATTR_INIT         pthread_condattr_create
+#define _PT_PTHREAD_COND_INIT(m, a)       pthread_cond_init(&(m), a)
+#define _PT_PTHREAD_CONDATTR_DESTROY      pthread_condattr_delete
+
+/* Notes about differences between DCE threads and pthreads 10:
+ *   1. pthread_mutex_trylock returns 1 when it locks the mutex
+ *      0 when it does not.  The latest pthreads has a set of errno-like
+ *      return values.
+ *   2. return values from pthread_cond_timedwait are different.
+ *
+ *
+ *
+ */
+#elif defined(BSDI)
+/*
+ * Mutex and condition attributes are not supported.  The attr
+ * argument to pthread_mutex_init() and pthread_cond_init() must
+ * be passed as NULL.
+ *
+ * The memset calls in _PT_PTHREAD_MUTEX_INIT and _PT_PTHREAD_COND_INIT
+ * are to work around BSDI's using a single bit to indicate a mutex
+ * or condition variable is initialized.  This entire BSDI section
+ * will go away when BSDI releases updated threads libraries for
+ * BSD/OS 3.1 and 4.0.
+ */
+#define _PT_PTHREAD_MUTEXATTR_INIT(x)     0
+#define _PT_PTHREAD_MUTEXATTR_DESTROY(x)  /* */
+#define _PT_PTHREAD_MUTEX_INIT(m, a)      (memset(&(m), 0, sizeof(m)), \
+                                      pthread_mutex_init(&(m), NULL))
+#define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    (EBUSY == pthread_mutex_trylock(&(m)))
+#define _PT_PTHREAD_CONDATTR_INIT(x)      0
+#define _PT_PTHREAD_CONDATTR_DESTROY(x)   /* */
+#define _PT_PTHREAD_COND_INIT(m, a)       (memset(&(m), 0, sizeof(m)), \
+                                      pthread_cond_init(&(m), NULL))
+#else
+#define _PT_PTHREAD_MUTEXATTR_INIT        pthread_mutexattr_init
+#define _PT_PTHREAD_MUTEXATTR_DESTROY     pthread_mutexattr_destroy
+#define _PT_PTHREAD_MUTEX_INIT(m, a)      pthread_mutex_init(&(m), &(a))
+#if defined(FREEBSD)
+#define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    pt_pthread_mutex_is_locked(&(m))
+#else
+#define _PT_PTHREAD_MUTEX_IS_LOCKED(m)    (EBUSY == pthread_mutex_trylock(&(m)))
+#endif
+#if defined(DARWIN)
+#define _PT_PTHREAD_CONDATTR_INIT(x)      0
+#else
+#define _PT_PTHREAD_CONDATTR_INIT         pthread_condattr_init
+#endif
+#define _PT_PTHREAD_CONDATTR_DESTROY      pthread_condattr_destroy
+#define _PT_PTHREAD_COND_INIT(m, a)       pthread_cond_init(&(m), &(a))
+#endif
+
+/* The pthreads standard does not specify an invalid value for the
+ * pthread_t handle.  (0 is usually an invalid pthread identifier
+ * but there are exceptions, for example, DG/UX.)  These macros
+ * define a way to set the handle to or compare the handle with an
+ * invalid identifier.  These macros are not portable and may be
+ * more of a problem as we adapt to more pthreads implementations.
+ * They are only used in the PRMonitor functions.  Do not use them
+ * in new code.
+ *
+ * Unfortunately some of our clients depend on certain properties
+ * of our PRMonitor implementation, preventing us from replacing
+ * it by a portable implementation.
+ * - High-performance servers like the fact that PR_EnterMonitor
+ *   only calls PR_Lock and PR_ExitMonitor only calls PR_Unlock.
+ *   (A portable implementation would use a PRLock and a PRCondVar
+ *   to implement the recursive lock in a monitor and call both
+ *   PR_Lock and PR_Unlock in PR_EnterMonitor and PR_ExitMonitor.)
+ *   Unfortunately this forces us to read the monitor owner field
+ *   without holding a lock.
+ * - One way to make it safe to read the monitor owner field
+ *   without holding a lock is to make that field a PRThread*
+ *   (one should be able to read a pointer with a single machine
+ *   instruction).  However, PR_GetCurrentThread calls calloc if
+ *   it is called by a thread that was not created by NSPR.  The
+ *   malloc tracing tools in the Mozilla client use PRMonitor for
+ *   locking in their malloc, calloc, and free functions.  If
+ *   PR_EnterMonitor calls any of these functions, infinite
+ *   recursion ensues.
+ */
+#if defined(_PR_DCETHREADS)
+#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t) \
+	memset(&(t), 0, sizeof(pthread_t))
+#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t) \
+	(!memcmp(&(t), &pt_zero_tid, sizeof(pthread_t)))
+#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt)   (dt) = (st)
+#elif defined(IRIX) || defined(OSF1) || defined(AIX) || defined(SOLARIS) \
+	|| defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
+	|| defined(HPUX) || defined(FREEBSD) \
+	|| defined(NETBSD) || defined(OPENBSD) || defined(BSDI) \
+	|| defined(VMS) || defined(NTO) || defined(DARWIN) \
+	|| defined(UNIXWARE) || defined(RISCOS)
+#ifdef __GNU__
+/* Hurd pthreads don't have an invalid value for pthread_t. -- rmh */
+#error Using Hurd pthreads
+#endif
+#define _PT_PTHREAD_INVALIDATE_THR_HANDLE(t)  (t) = 0
+#define _PT_PTHREAD_THR_HANDLE_IS_INVALID(t)  (t) == 0
+#define _PT_PTHREAD_COPY_THR_HANDLE(st, dt)   (dt) = (st)
+#else 
+#error "pthreads is not supported for this architecture"
+#endif
+
+#if defined(_PR_DCETHREADS)
+#define _PT_PTHREAD_ATTR_INIT            pthread_attr_create
+#define _PT_PTHREAD_ATTR_DESTROY         pthread_attr_delete
+#define _PT_PTHREAD_CREATE(t, a, f, r)   pthread_create(t, a, f, r) 
+#define _PT_PTHREAD_KEY_CREATE           pthread_keycreate
+#define _PT_PTHREAD_ATTR_SETSCHEDPOLICY  pthread_attr_setsched
+#define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) \
+                                     (*(s) = pthread_attr_getstacksize(*(a)), 0)
+#define _PT_PTHREAD_GETSPECIFIC(k, r) \
+		pthread_getspecific((k), (pthread_addr_t *) &(r))
+#elif defined(_PR_PTHREADS)
+#define _PT_PTHREAD_ATTR_INIT            pthread_attr_init
+#define _PT_PTHREAD_ATTR_DESTROY         pthread_attr_destroy
+#define _PT_PTHREAD_CREATE(t, a, f, r)   pthread_create(t, &a, f, r) 
+#define _PT_PTHREAD_KEY_CREATE           pthread_key_create
+#define _PT_PTHREAD_ATTR_SETSCHEDPOLICY  pthread_attr_setschedpolicy
+#define _PT_PTHREAD_ATTR_GETSTACKSIZE(a, s) pthread_attr_getstacksize(a, s)
+#define _PT_PTHREAD_GETSPECIFIC(k, r)    (r) = pthread_getspecific(k)
+#else
+#error "Cannot determine pthread strategy"
+#endif
+
+#if defined(_PR_DCETHREADS)
+#define _PT_PTHREAD_EXPLICIT_SCHED      _PT_PTHREAD_DEFAULT_SCHED
+#endif
+
+/*
+ * pthread_mutex_trylock returns different values in DCE threads and
+ * pthreads.
+ */
+#if defined(_PR_DCETHREADS)
+#define PT_TRYLOCK_SUCCESS 1
+#define PT_TRYLOCK_BUSY    0
+#else
+#define PT_TRYLOCK_SUCCESS 0
+#define PT_TRYLOCK_BUSY    EBUSY
+#endif
+
+/*
+ * These platforms don't have sigtimedwait()
+ */
+#if (defined(AIX) && !defined(AIX4_3_PLUS)) \
+	|| defined(LINUX) || defined(__GNU__)|| defined(__GLIBC__) \
+	|| defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
+	|| defined(BSDI) || defined(VMS) || defined(UNIXWARE) \
+	|| defined(DARWIN)
+#define PT_NO_SIGTIMEDWAIT
+#endif
+
+/*
+ * These platforms don't have pthread_kill()
+ */
+#if defined(DARWIN)
+#define pthread_kill(thread, sig) ENOSYS
+#endif
+
+#if defined(OSF1) || defined(VMS)
+#define PT_PRIO_MIN            PRI_OTHER_MIN
+#define PT_PRIO_MAX            PRI_OTHER_MAX
+#elif defined(IRIX)
+#include <sys/sched.h>
+#define PT_PRIO_MIN            PX_PRIO_MIN
+#define PT_PRIO_MAX            PX_PRIO_MAX
+#elif defined(AIX)
+#include <sys/priv.h>
+#include <sys/sched.h>
+#ifndef PTHREAD_CREATE_JOINABLE
+#define PTHREAD_CREATE_JOINABLE     PTHREAD_CREATE_UNDETACHED
+#endif
+#define PT_PRIO_MIN            DEFAULT_PRIO
+#define PT_PRIO_MAX            DEFAULT_PRIO
+#elif defined(HPUX)
+
+#if defined(_PR_DCETHREADS)
+#define PT_PRIO_MIN            PRI_OTHER_MIN
+#define PT_PRIO_MAX            PRI_OTHER_MAX
+#else /* defined(_PR_DCETHREADS) */
+#include <sys/sched.h>
+#define PT_PRIO_MIN            sched_get_priority_min(SCHED_OTHER)
+#define PT_PRIO_MAX            sched_get_priority_max(SCHED_OTHER)
+#endif /* defined(_PR_DCETHREADS) */
+
+#elif defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
+	|| defined(FREEBSD)
+#define PT_PRIO_MIN            sched_get_priority_min(SCHED_OTHER)
+#define PT_PRIO_MAX            sched_get_priority_max(SCHED_OTHER)
+#elif defined(NTO)
+/*
+ * Neutrino has functions that return the priority range but
+ * they return invalid numbers, so I just hard coded these here
+ * for now.  Jerry.Kirk at Nexarecorp.com
+ */
+#define PT_PRIO_MIN            0
+#define PT_PRIO_MAX            30
+#elif defined(SOLARIS)
+/*
+ * Solaris doesn't seem to have macros for the min/max priorities.
+ * The range of 0-127 is mentioned in the pthread_setschedparam(3T)
+ * man pages, and pthread_setschedparam indeed allows 0-127.  However,
+ * pthread_attr_setschedparam does not allow 0; it allows 1-127.
+ */
+#define PT_PRIO_MIN            1
+#define PT_PRIO_MAX            127
+#elif defined(OPENBSD)
+#define PT_PRIO_MIN            0
+#define PT_PRIO_MAX            31
+#elif defined(NETBSD) \
+	|| defined(BSDI) || defined(DARWIN) || defined(UNIXWARE) \
+	|| defined(RISCOS) /* XXX */
+#define PT_PRIO_MIN            0
+#define PT_PRIO_MAX            126
+#else
+#error "pthreads is not supported for this architecture"
+#endif
+
+/*
+ * The _PT_PTHREAD_YIELD function is called from a signal handler.
+ * Needed for garbage collection -- Look at PR_Suspend/PR_Resume
+ * implementation.
+ */
+#if defined(_PR_DCETHREADS)
+#define _PT_PTHREAD_YIELD()            	pthread_yield()
+#elif defined(OSF1) || defined(VMS)
+/*
+ * sched_yield can't be called from a signal handler.  Must use
+ * the _np version.
+ */
+#define _PT_PTHREAD_YIELD()            	pthread_yield_np()
+#elif defined(AIX)
+extern int (*_PT_aix_yield_fcn)();
+#define _PT_PTHREAD_YIELD()			(*_PT_aix_yield_fcn)()
+#elif defined(IRIX)
+#include <time.h>
+#define _PT_PTHREAD_YIELD() \
+    PR_BEGIN_MACRO               				\
+		struct timespec onemillisec = {0};		\
+		onemillisec.tv_nsec = 1000000L;			\
+        nanosleep(&onemillisec,NULL);			\
+    PR_END_MACRO
+#elif defined(HPUX) || defined(SOLARIS) \
+	|| defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
+	|| defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
+	|| defined(BSDI) || defined(NTO) || defined(DARWIN) \
+	|| defined(UNIXWARE) || defined(RISCOS)
+#define _PT_PTHREAD_YIELD()            	sched_yield()
+#else
+#error "Need to define _PT_PTHREAD_YIELD for this platform"
+#endif
+
+#endif /* nspr_pth_defs_h_ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_qnx.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_qnx.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,96 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef QNX
+#define QNX
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#undef  HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   1
+#define PR_ALIGN_OF_INT     1
+#define PR_ALIGN_OF_LONG    1
+#define PR_ALIGN_OF_INT64   1
+#define PR_ALIGN_OF_FLOAT   1
+#define PR_ALIGN_OF_DOUBLE  1
+#define PR_ALIGN_OF_POINTER 1
+#define PR_ALIGN_OF_WORD    1
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+#define PR_WORDS_PER_DWORD_LOG2  1
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_qnx.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_qnx.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,215 @@
+/* -*- 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 nspr_qnx_defs_h___
+#define nspr_qnx_defs_h___
+
+/*
+** Internal configuration macros
+*/
+#define PR_LINKER_ARCH		"qnx"
+#define _PR_SI_SYSNAME		"QNX"
+#define _PR_SI_ARCHITECTURE	"x86"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS		MAP_PRIVATE
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#undef _PR_POLL_AVAILABLE
+#undef _PR_USE_POLL
+#define _PR_HAVE_SOCKADDR_LEN
+#define HAVE_BSD_FLOCK
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+
+#include <sys/select.h>
+
+#undef  HAVE_STACK_GROWING_UP
+#undef	HAVE_DLL
+#undef	USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define _PR_NEED_STRCASECMP
+
+#ifndef HAVE_STRERROR
+#define HAVE_STRERROR
+#endif
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP			setjmp
+#define _LONGJMP		longjmp
+#define _PR_CONTEXT_TYPE	jmp_buf
+#define _PR_NUM_GCREGS		_JBLEN
+#define _MD_GET_SP(_t)		(_t)->md.context[7]
+
+#define CONTEXT(_th)		((_th)->md.context)
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	\
+{							\
+    *status = PR_TRUE;					\
+    if(_SETJMP(CONTEXT(_thread))) (*_main)();		\
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128);		\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)	\
+    if (!_SETJMP(CONTEXT(_thread))) {	\
+	(_thread)->md.errcode = errno;	\
+	_PR_Schedule();			\
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)	\
+{					\
+    errno = (_thread)->md.errcode;	\
+    _MD_SET_CURRENT_THREAD(_thread);	\
+    _LONGJMP(CONTEXT(_thread), 1);	\
+}
+
+/*
+** Machine-dependent (MD) data structures.
+*/
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+** md-specific cpu structure field
+*/
+#define _PR_MD_MAX_OSFD		FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+    struct pollfd *ioq_pollfds;
+    int ioq_pollfds_size;
+#endif
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu)	PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock)		PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_GET_INTERVAL		_PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC		_PR_UNIX_TicksPerSecond
+#define _MD_EARLY_INIT			_MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu)	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD			_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+** We wrapped the select() call.  _MD_SELECT refers to the built-in,
+** unwrapped version.
+*/
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#define _MD_SELECT		select
+
+#define SA_RESTART 0
+
+#endif /* nspr_qnx_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_reliantunix.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_reliantunix.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,145 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef RELIANTUNIX
+#define RELIANTUNIX
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#undef HAVE_LONG_LONG
+#undef  HAVE_ALIGNED_DOUBLES
+#undef  HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD    32
+#define PR_BITS_PER_DWORD   64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2   5
+#define PR_BITS_PER_DWORD_LOG2  6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_BYTES_PER_WORD_LOG2  2
+#define PR_BYTES_PER_DWORD_LOG2 3
+#define PR_WORDS_PER_DWORD_LOG2 1
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD    4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_reliantunix.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_reliantunix.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,270 @@
+/* -*- 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 ***** */
+
+/*
+ * reliantunix.h
+ * 5/18/96 Taken from nec.h -- chrisk at netscape.com
+ * 3/14/97 Modified for nspr20 -- chrisk at netscape.com
+ */
+#ifndef nspr_reliantunix_defs_h___
+#define nspr_reliantunix_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"sinix"
+#define _PR_SI_SYSNAME	"SINIX"
+#define _PR_SI_ARCHITECTURE "mips"
+#define PR_DLL_SUFFIX ".so"
+
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	(2*65536L)
+#define _MD_MMAP_FLAGS		MAP_PRIVATE|MAP_FIXED
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define HAVE_NETCONFIG
+#define HAVE_WEAK_IO_SYMBOLS
+#define HAVE_WEAK_MALLOC_SYMBOLS
+#define _PR_RECV_BROKEN /* recv doesn't work on Unix Domain Sockets */
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ST_ATIM
+#define _PR_NO_LARGE_FILES
+
+/*
+ * Mike Patnode indicated that it is possibly safe now to use context-switching
+ * calls that do not change the signal mask, like setjmp vs. sigsetjmp.
+ * So we'll use our homegrown, getcontext/setcontext-compatible stuff which 
+ * will save us the getcontext/setcontext system calls at each context switch.
+ * It already works in FastTrack 2.01, so it should do it here :-)
+ *  - chrisk 040497
+ */
+#define USE_SETCXT /* temporarily disabled... */
+
+#include <ucontext.h>
+ 
+#ifdef USE_SETCXT
+/* use non-syscall machine language replacement */
+#define _GETCONTEXT		getcxt
+#define _SETCONTEXT		setcxt
+/* defined in os_ReliantUNIX.s */
+extern int getcxt(ucontext_t *);
+extern int setcxt(ucontext_t *);
+#else
+#define _GETCONTEXT		getcontext
+#define _SETCONTEXT		setcontext
+#endif
+
+#define _MD_GET_SP(_t)		(_t)->md.context.uc_mcontext.gpregs[CXT_SP]
+#define _PR_CONTEXT_TYPE	ucontext_t
+#define _PR_NUM_GCREGS		NGREG
+ 
+#define CONTEXT(_thread) (&(_thread)->md.context)
+
+#define _PR_IS_NATIVE_THREAD_SUPPORTED() 0
+ 
+/*
+** Machine-dependent (MD) data structures.
+*/
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+** Initialize the thread context preparing it to execute "_main()"
+** - get a nice, fresh context
+** - set its SP to the stack we allcoated for it
+** - set it to start things at "e"
+*/
+#define _MD_INIT_CONTEXT(thread, _sp, _main, status)                \
+    PR_BEGIN_MACRO                                                  \
+    *status = PR_TRUE;                                              \
+    _GETCONTEXT(CONTEXT(thread));                                   \
+    /* this is supposed to point to the stack BASE, not to SP */    \
+    CONTEXT(thread)->uc_stack.ss_sp = thread->stack->stackBottom;   \
+    CONTEXT(thread)->uc_stack.ss_size = thread->stack->stackSize;   \
+    CONTEXT(thread)->uc_mcontext.gpregs[CXT_SP] = ((unsigned long)_sp - 128) & 0xfffffff8; \
+    CONTEXT(thread)->uc_mcontext.gpregs[CXT_T9] = _main;            \
+    CONTEXT(thread)->uc_mcontext.gpregs[CXT_EPC] = _main;           \
+    CONTEXT(thread)->uc_mcontext.gpregs[CXT_RA] = 0;                \
+    thread->no_sched = 0;                                           \
+    PR_END_MACRO
+ 
+/*
+** Save current context as it is scheduled away
+*/
+#define _MD_SWITCH_CONTEXT(_thread)       \
+    PR_BEGIN_MACRO                        \
+    if (!_GETCONTEXT(CONTEXT(_thread))) { \
+	_MD_SAVE_ERRNO(_thread);          \
+	_MD_SET_LAST_THREAD(_thread);     \
+        _PR_Schedule();                   \
+    }                                     \
+    PR_END_MACRO
+ 
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT or set up
+**  by _MD_INIT_CONTEXT
+**  CXT_V0 is the register that holds the return value.
+**   We must set it to 1 so that we can see if the return from
+**   getcontext() is the result of calling getcontext() or
+**   setcontext()...
+**   setting a context got with getcontext() appears to
+**   return from getcontext(), too!
+**  CXT_A3 is the register that holds status when returning
+**   from a syscall. It is set to 0 to indicate success,
+**   because we want getcontext() on the other side of the magic
+**   door to be ok.
+*/
+#define _MD_RESTORE_CONTEXT(_thread)   \
+    PR_BEGIN_MACRO                     \
+    ucontext_t *uc = CONTEXT(_thread); \
+    uc->uc_mcontext.gpregs[CXT_V0] = 1;\
+    uc->uc_mcontext.gpregs[CXT_A3] = 0;\
+    _MD_RESTORE_ERRNO(_thread);        \
+    _MD_SET_CURRENT_THREAD(_thread);   \
+    _SETCONTEXT(uc);                   \
+    PR_END_MACRO
+
+#define _MD_SAVE_ERRNO(t)	 (t)->md.errcode = errno;
+#define _MD_RESTORE_ERRNO(t)	 errno = (t)->md.errcode;
+
+#define _MD_GET_INTERVAL	_PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC	_PR_UNIX_TicksPerSecond
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD		_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)
+#define _MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+#if !defined(S_ISSOCK) && defined(S_IFSOCK)
+#define S_ISSOCK(mode)   ((mode&0xF000) == 0xC000)
+#endif
+#if !defined(S_ISLNK) && defined(S_IFLNK)
+#define S_ISLNK(mode)   ((mode&0xA000) == 0xC000)
+#endif
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *execptfds, struct timeval *timeout);
+#define _MD_SELECT(nfds,r,w,e,tv) _select(nfds,r,w,e,tv)
+#define _MD_POLL _poll
+
+#endif /* nspr_reliantunix_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_rhapsody.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_rhapsody.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,148 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef RHAPOSDY
+#define RHAPOSDY
+#endif
+
+#define PR_AF_INET6 30  /* same as AF_INET6 */
+
+#if defined(i386)
+#undef IS_BIG_ENDIAN
+#define  IS_LITTLE_ENDIAN 1
+#else
+#undef IS_LITTLE_ENDIAN
+#define  IS_BIG_ENDIAN 1
+#endif
+
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+#define PR_BITS_PER_DWORD   64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_rhapsody.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_rhapsody.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,225 @@
+/* -*- 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 nspr_rhapsody_defs_h___
+#define nspr_rhapsody_defs_h___
+
+#include "prthread.h"
+
+#include <sys/syscall.h>
+
+#define PR_LINKER_ARCH	"rhapsody"
+#define _PR_SI_SYSNAME  "RHAPSODY"
+#ifdef i386
+#define _PR_SI_ARCHITECTURE "x86"
+#else
+#define _PR_SI_ARCHITECTURE "ppc"
+#endif
+#define PR_DLL_SUFFIX		".dylib"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_DLL
+#define USE_MACH_DYLD
+#define _PR_HAVE_SOCKADDR_LEN  
+#define _PR_STAT_HAS_ST_ATIMESPEC
+#define _PR_NO_LARGE_FILES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+
+#define USE_SETJMP
+
+#if !defined(_PR_PTHREADS)
+
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	jmp_buf
+
+#define CONTEXT(_th)       ((_th)->md.context)
+#define _MD_GET_SP(_th)    (((struct sigcontext *) (_th)->md.context)->sc_onstack)
+#define PR_NUM_GCREGS	    _JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (setjmp(CONTEXT(_thread))) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 64); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) {  \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    longjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+extern PRStatus _MD_InitializeThread(PRThread *thread);
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+extern PRStatus _MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize);
+extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri);
+extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout);
+extern PRStatus _MD_WAKEUP_WAITER(PRThread *);
+extern void _MD_YIELD(void);
+
+#endif /* ! _PR_PTHREADS */
+
+#define _MD_EARLY_INIT          _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL        _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC    _PR_UNIX_TicksPerSecond
+
+extern void             _MD_EarlyInit(void);
+extern PRIntervalTime   _PR_UNIX_GetInterval(void);
+extern PRIntervalTime   _PR_UNIX_TicksPerSecond(void);
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+/* For writev() */
+#include <sys/uio.h>
+
+#endif /* nspr_rhapsody_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_riscos.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_riscos.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,141 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef RISCOS
+#define RISCOS
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define HAVE_LONG_LONG
+#undef  HAVE_ALIGNED_DOUBLES
+#undef  HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+#define PR_ALIGN_OF_WORD    4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+#define PR_WORDS_PER_DWORD_LOG2  1
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_riscos.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_riscos.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,209 @@
+/* -*- 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): Peter Naulls <peter at chocky.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the 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 nspr_riscos_defs_h___
+#define nspr_riscos_defs_h___
+
+/*
+** Internal configuration macros
+*/
+#define PR_LINKER_ARCH		"riscos"
+#define _PR_SI_SYSNAME		"RISCOS"
+#define _PR_SI_ARCHITECTURE	"arm"
+#define PR_DLL_SUFFIX		".a"
+
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_HAVE_SOCKADDR_LEN
+#undef HAVE_BSD_FLOCK
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+#define _PR_HAVE_POSIX_SEMAPHORES
+
+#include <sys/select.h>
+#include <sys/poll.h>
+#include <kernel.h>
+
+
+#undef  HAVE_STACK_GROWING_UP
+#undef  HAVE_DLL
+#undef  USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define PT_NO_SIGTIMEDWAIT
+
+#ifndef HAVE_STRERROR
+#define HAVE_STRERROR
+#endif
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP			setjmp
+#define _LONGJMP		longjmp
+#define _PR_CONTEXT_TYPE	jmp_buf
+#define _PR_NUM_GCREGS		_JBLEN
+#define _MD_GET_SP(_t)		(_t)->md.context[7]
+
+#define CONTEXT(_th)		((_th)->md.context)
+
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	\
+{							\
+    *status = PR_TRUE;					\
+    if(_SETJMP(CONTEXT(_thread))) (*_main)();		\
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128);		\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)	\
+    if (!_SETJMP(CONTEXT(_thread))) {	\
+	(_thread)->md.errcode = errno;	\
+	_PR_Schedule();			\
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)	\
+{					\
+    errno = (_thread)->md.errcode;	\
+    _MD_SET_CURRENT_THREAD(_thread);	\
+    _LONGJMP(CONTEXT(_thread), 1);	\
+}
+
+/*
+** Machine-dependent (MD) data structures.
+*/
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+** md-specific cpu structure field
+*/
+#define _PR_MD_MAX_OSFD		FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD], fd_write_cnt[_PR_MD_MAX_OSFD], fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+    struct pollfd *ioq_pollfds;
+    int ioq_pollfds_size;
+#endif
+};
+
+#define _PR_IOQ(_cpu)	/*	*/	((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu)	PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock)		PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_GET_INTERVAL		_PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC		_PR_UNIX_TicksPerSecond
+#define _MD_EARLY_INIT			_MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu)	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD			_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+** We wrapped the select() call.  _MD_SELECT refers to the built-in,
+** unwrapped version.
+*/
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#define _MD_SELECT		select
+
+#endif /* nspr_riscos_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_scoos.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_scoos.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,140 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef SCO
+#define SCO
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#undef	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_scoos.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_scoos.h	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+#ifndef nspr_scoos5_defs_h___
+#define nspr_scoos5_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"scoos5"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_SI_SYSNAME      "SCO"
+#define _PR_SI_ARCHITECTURE "x86"
+#define _PR_STACK_VMBASE    0x50000000
+
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define	HAVE_DLL
+#define	USE_DLFCN
+
+#if !defined (HAVE_STRERROR)
+#define HAVE_STRERROR
+#endif
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define _PR_RECV_BROKEN /* recv doesn't work on Unix Domain Sockets */
+
+#define USE_SETJMP
+
+#ifdef _PR_LOCAL_THREADS_ONLY
+#include <setjmp.h>
+
+#define _MD_GET_SP(_t)  (_t)->md.jb[4]
+#define PR_NUM_GCREGS	_SIGJBLEN
+#define PR_CONTEXT_TYPE	sigjmp_buf
+
+#define CONTEXT(_th) ((_th)->md.jb)
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)				\
+{								  									\
+	*status = PR_TRUE;												\
+    if (sigsetjmp(CONTEXT(_thread),1)) {				  			\
+		(*_main)(); 												\
+    }								  								\
+    _MD_GET_SP(_thread) = (int) ((_sp) - 64);	\
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  								\
+    if (!sigsetjmp(CONTEXT(_thread), 1)) { 							\
+		(_thread)->md.errcode = errno;  							\
+		_PR_Schedule();		     									\
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)								\
+{				     												\
+    errno = (_thread)->osErrorCode;	     							\
+	_MD_SET_CURRENT_THREAD(_thread);								\
+    siglongjmp(CONTEXT(_thread), 1);    							\
+}
+
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+struct _MDThread {
+    jmp_buf jb;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_EARLY_INIT          	_MD_EarlyInit
+#define _MD_FINAL_INIT				_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) 	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         	_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define _MD_SELECT		_select
+#define _MD_POLL		_poll
+
+#endif /* nspr_scoos5_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_solaris.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_solaris.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,201 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef SOLARIS
+#define SOLARIS
+#endif
+
+#define PR_AF_INET6 26  /* same as AF_INET6 */
+
+#if defined(sparc) || defined(__sparc)
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_DOUBLE  8
+#if defined(__sparcv9)
+#define IS_64
+#endif
+#elif defined(__x86_64)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_DOUBLE  8
+#define IS_64
+#elif defined(i386) || defined(__i386)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_DOUBLE  4
+#else
+#error unknown processor
+#endif
+
+#ifdef IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   8
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   3
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    64
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   6
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_POINTER 8
+
+#else /* IS_64 */
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_POINTER 4
+
+#endif /* IS_64 */
+
+#define	HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* ifndef nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_solaris.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_solaris.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,806 @@
+/* -*- 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 nspr_solaris_defs_h___
+#define nspr_solaris_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"solaris"
+#define _PR_SI_SYSNAME	"SOLARIS"
+#ifdef sparc
+#define _PR_SI_ARCHITECTURE	"sparc"
+#elif defined(__x86_64)
+#define _PR_SI_ARCHITECTURE	"x86-64"
+#elif defined(i386)
+#define _PR_SI_ARCHITECTURE	"x86"
+#else
+#error unknown processor
+#endif
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	(2*65536L)
+#define _MD_MMAP_FLAGS          MAP_SHARED
+
+#undef  HAVE_STACK_GROWING_UP
+
+#ifndef HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+
+#undef	HAVE_WEAK_MALLOC_SYMBOLS
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define NEED_STRFTIME_LOCK
+
+/*
+ * Intel x86 has atomic instructions.
+ *
+ * Sparc v8 does not have instructions to efficiently implement
+ * atomic increment/decrement operations.  In the local threads
+ * only and pthreads versions, we use the default atomic routine
+ * implementation in pratom.c.  The obsolete global threads only
+ * version uses a global mutex_t to implement the atomic routines
+ * in solaris.c, which is actually equivalent to the default
+ * implementation.
+ *
+ * 64-bit Solaris requires sparc v9, which has atomic instructions.
+ */
+#if defined(i386) || defined(_PR_GLOBAL_THREADS_ONLY) || defined(IS_64)
+#define _PR_HAVE_ATOMIC_OPS
+#endif
+
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ST_ATIM
+#ifdef SOLARIS2_5
+#define _PR_HAVE_SYSV_SEMAPHORES
+#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+#else
+#define _PR_HAVE_POSIX_SEMAPHORES
+#define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#endif
+#define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#define _PR_ACCEPT_INHERIT_NONBLOCK
+#ifdef _PR_INET6
+#define _PR_HAVE_INET_NTOP
+#else
+#define AF_INET6 26
+struct addrinfo {
+    int ai_flags;
+    int ai_family;
+    int ai_socktype;
+    int ai_protocol;
+    size_t ai_addrlen;
+    char *ai_canonname;
+    struct sockaddr *ai_addr;
+    struct addrinfo *ai_next;
+};
+#define AI_CANONNAME 0x0010
+#define AI_V4MAPPED 0x0001 
+#define AI_ALL      0x0002
+#define AI_ADDRCONFIG   0x0004
+#define _PR_HAVE_MD_SOCKADDR_IN6
+/* isomorphic to struct in6_addr on Solaris 8 */
+struct _md_in6_addr {
+    union {
+        PRUint8  _S6_u8[16];
+        PRUint32 _S6_u32[4];
+        PRUint32 __S6_align;
+    } _S6_un;
+};
+/* isomorphic to struct sockaddr_in6 on Solaris 8 */
+struct _md_sockaddr_in6 {
+    PRUint16 sin6_family;
+    PRUint16 sin6_port;
+    PRUint32 sin6_flowinfo;
+    struct _md_in6_addr sin6_addr;
+    PRUint32 sin6_scope_id;
+    PRUint32 __sin6_src_id;
+};
+#endif
+#if defined(_PR_GLOBAL_THREADS_ONLY) || defined(_PR_PTHREADS)
+#define _PR_HAVE_GETHOST_R
+#define _PR_HAVE_GETHOST_R_POINTER
+#endif
+
+#include "prinrval.h"
+NSPR_API(PRIntervalTime) _MD_Solaris_GetInterval(void);
+#define _MD_GET_INTERVAL                  _MD_Solaris_GetInterval
+NSPR_API(PRIntervalTime) _MD_Solaris_TicksPerSecond(void);
+#define _MD_INTERVAL_PER_SEC              _MD_Solaris_TicksPerSecond
+
+#if defined(_PR_HAVE_ATOMIC_OPS)
+/*
+** Atomic Operations
+*/
+#define _MD_INIT_ATOMIC()
+
+NSPR_API(PRInt32) _MD_AtomicIncrement(PRInt32 *val);
+#define _MD_ATOMIC_INCREMENT _MD_AtomicIncrement
+
+NSPR_API(PRInt32) _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#define _MD_ATOMIC_ADD _MD_AtomicAdd
+
+NSPR_API(PRInt32) _MD_AtomicDecrement(PRInt32 *val);
+#define _MD_ATOMIC_DECREMENT _MD_AtomicDecrement
+
+NSPR_API(PRInt32) _MD_AtomicSet(PRInt32 *val, PRInt32 newval);
+#define _MD_ATOMIC_SET _MD_AtomicSet
+#endif /* _PR_HAVE_ATOMIC_OPS */
+
+#if defined(_PR_PTHREADS)
+
+NSPR_API(void)		_MD_EarlyInit(void);
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+
+#elif defined(_PR_GLOBAL_THREADS_ONLY)
+
+#include "prthread.h"
+
+#include <ucontext.h>
+
+/*
+** Iinitialization Related definitions
+*/
+
+NSPR_API(void)		_MD_EarlyInit(void);
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+
+#define _MD_GET_SP(threadp)	threadp->md.sp
+
+/*
+** Clean-up the thread machine dependent data structure
+*/
+#define	_MD_INIT_THREAD				_MD_InitializeThread
+#define	_MD_INIT_ATTACHED_THREAD	_MD_InitializeThread
+
+NSPR_API(PRStatus) _MD_CreateThread(PRThread *thread, 
+					void (*start)(void *), 
+					PRThreadPriority priority,
+					PRThreadScope scope, 
+					PRThreadState state, 
+					PRUint32 stackSize);
+#define _MD_CREATE_THREAD _MD_CreateThread
+
+#define	_PR_CONTEXT_TYPE	ucontext_t
+
+#define CONTEXT(_thread) (&(_thread)->md.context)
+
+#include <thread.h>
+#include <sys/lwp.h>
+#include <synch.h>
+
+extern struct PRLock *_pr_schedLock;
+
+/*
+** Thread Local Storage 
+*/
+
+#define THREAD_KEY_T thread_key_t
+
+extern struct PRThread *_pr_attached_thread_tls();
+extern struct PRThread *_pr_current_thread_tls();
+extern struct _PRCPU *_pr_current_cpu_tls();
+extern struct PRThread *_pr_last_thread_tls();
+
+extern THREAD_KEY_T threadid_key;
+extern THREAD_KEY_T cpuid_key;
+extern THREAD_KEY_T last_thread_key;
+
+#define _MD_GET_ATTACHED_THREAD() _pr_attached_thread_tls()
+#define _MD_CURRENT_THREAD() _pr_current_thread_tls()
+#define _MD_CURRENT_CPU() _pr_current_cpu_tls()
+#define _MD_LAST_THREAD() _pr_last_thread_tls()
+	
+#define _MD_SET_CURRENT_THREAD(newval) 			\
+	PR_BEGIN_MACRO					\
+	thr_setspecific(threadid_key, (void *)newval);	\
+	PR_END_MACRO
+
+#define _MD_SET_CURRENT_CPU(newval) 			\
+	PR_BEGIN_MACRO					\
+	thr_setspecific(cpuid_key, (void *)newval);	\
+	PR_END_MACRO
+
+#define _MD_SET_LAST_THREAD(newval)	 			\
+	PR_BEGIN_MACRO						\
+	thr_setspecific(last_thread_key, (void *)newval);	\
+	PR_END_MACRO
+	
+#define	_MD_CLEAN_THREAD(_thread)	_MD_cleanup_thread(_thread)
+extern void _MD_exit_thread(PRThread *thread);
+#define _MD_EXIT_THREAD(thread)		_MD_exit_thread(thread)
+
+#define	_MD_SUSPEND_THREAD(thread)	_MD_Suspend(thread)
+#define	_MD_RESUME_THREAD(thread)	thr_continue((thread)->md.handle)
+
+/* XXXX Needs to be defined - Prashant */
+#define _MD_SUSPEND_CPU(cpu)
+#define _MD_RESUME_CPU(cpu)
+
+extern void _MD_Begin_SuspendAll(void);
+extern void _MD_End_SuspendAll(void);
+extern void _MD_End_ResumeAll(void);
+#define _MD_BEGIN_SUSPEND_ALL()		_MD_Begin_SuspendAll()
+#define _MD_BEGIN_RESUME_ALL()		
+#define	_MD_END_SUSPEND_ALL()		_MD_End_SuspendAll()
+#define	_MD_END_RESUME_ALL()		_MD_End_ResumeAll()
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(md_lockp) (mutex_init(&((md_lockp)->lock),USYNC_THREAD,NULL) ? PR_FAILURE : PR_SUCCESS)
+#define _MD_FREE_LOCK(md_lockp) mutex_destroy(&((md_lockp)->lock))
+#define _MD_UNLOCK(md_lockp) mutex_unlock(&((md_lockp)->lock))
+#define _MD_TEST_AND_LOCK(md_lockp) mutex_trylock(&((md_lockp)->lock))
+struct _MDLock;
+NSPR_API(void) _MD_lock(struct _MDLock *md_lock);
+#undef PROFILE_LOCKS
+#ifndef PROFILE_LOCKS
+#define _MD_LOCK(md_lockp) _MD_lock(md_lockp)
+#else
+#define _MD_LOCK(md_lockp)                 \
+    PR_BEGIN_MACRO \
+    int rv = _MD_TEST_AND_LOCK(md_lockp); \
+    if (rv == 0) { \
+        (md_lockp)->hitcount++; \
+    } else { \
+        (md_lockp)->misscount++; \
+        _MD_lock(md_lockp); \
+    } \
+    PR_END_MACRO
+#endif
+
+#define _PR_LOCK_HEAP() if (_pr_heapLock) _MD_LOCK(&_pr_heapLock->md)
+#define _PR_UNLOCK_HEAP() if (_pr_heapLock) _MD_UNLOCK(&_pr_heapLock->md)
+
+#define _MD_ATTACH_THREAD(threadp)
+
+
+#define THR_KEYCREATE thr_keycreate
+#define THR_SELF thr_self
+#define _MD_NEW_CV(condp) cond_init(&((condp)->cv), USYNC_THREAD, 0)
+#define COND_WAIT(condp, mutexp) cond_wait(condp, mutexp)
+#define COND_TIMEDWAIT(condp, mutexp, tspec) \
+                                     cond_timedwait(condp, mutexp, tspec)
+#define _MD_NOTIFY_CV(condp, lockp) cond_signal(&((condp)->cv))
+#define _MD_NOTIFYALL_CV(condp,unused) cond_broadcast(&((condp)->cv))	
+#define _MD_FREE_CV(condp) cond_destroy(&((condp)->cv))
+#define _MD_YIELD() thr_yield()
+#include <time.h>
+/* 
+ * Because clock_gettime() on Solaris/x86 2.4 always generates a
+ * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
+ * which is implemented using gettimeofday().
+ */
+#if defined(i386) && defined(SOLARIS2_4)
+extern int _pr_solx86_clock_gettime(clockid_t clock_id, struct timespec *tp);
+#define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt))
+#else
+#define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt))
+#endif  /* i386 && SOLARIS2_4 */
+
+#define MUTEX_T mutex_t
+#define COND_T cond_t
+
+#define _MD_NEW_SEM(md_semp,_val)  sema_init(&((md_semp)->sem),_val,USYNC_THREAD,NULL)
+#define _MD_DESTROY_SEM(md_semp) sema_destroy(&((md_semp)->sem))
+#define _MD_WAIT_SEM(md_semp) sema_wait(&((md_semp)->sem))
+#define _MD_POST_SEM(md_semp) sema_post(&((md_semp)->sem))
+
+#define _MD_SAVE_ERRNO(_thread)
+#define _MD_RESTORE_ERRNO(_thread)
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+
+extern struct _MDLock _pr_ioq_lock;
+#define _MD_IOQ_LOCK()		_MD_LOCK(&_pr_ioq_lock)
+#define _MD_IOQ_UNLOCK()	_MD_UNLOCK(&_pr_ioq_lock)
+
+extern PRStatus _MD_wait(struct PRThread *, PRIntervalTime timeout);
+#define _MD_WAIT _MD_wait
+
+extern PRStatus _MD_WakeupWaiter(struct PRThread *);
+#define _MD_WAKEUP_WAITER _MD_WakeupWaiter
+
+NSPR_API(void) _MD_InitIO(void);
+#define _MD_INIT_IO _MD_InitIO
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+    PR_BEGIN_MACRO \
+    *status = PR_TRUE; \
+    PR_END_MACRO
+#define _MD_SWITCH_CONTEXT(_thread)
+#define _MD_RESTORE_CONTEXT(_newThread)
+
+struct _MDLock {
+    MUTEX_T lock;
+#ifdef PROFILE_LOCKS
+    PRInt32 hitcount;
+    PRInt32 misscount;
+#endif
+};
+
+struct _MDCVar {
+    COND_T cv;
+};
+
+struct _MDSemaphore {
+    sema_t sem;
+};
+
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    thread_t handle;
+    lwpid_t lwpid;
+    uint_t sp;		/* stack pointer */
+    uint_t threadID;	/* ptr to solaris-internal thread id structures */
+    struct _MDSemaphore waiter_sem;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field, common to all Unix platforms
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+/* The following defines the unwrapped versions of select() and poll(). */
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *exceptfds, struct timeval *timeout);
+#define _MD_SELECT	_select
+
+#include <poll.h>
+#define _MD_POLL _poll
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Missing function prototypes
+*/
+extern int gethostname (char *name, int namelen);
+
+PR_END_EXTERN_C
+
+#else /* _PR_GLOBAL_THREADS_ONLY */
+
+/*
+ * LOCAL_THREADS_ONLY implementation on Solaris
+ */
+
+#include "prthread.h"
+
+#include <errno.h>
+#include <ucontext.h>
+#include <sys/stack.h>
+#include <synch.h>
+
+/*
+** Iinitialization Related definitions
+*/
+
+NSPR_API(void)				_MD_EarlyInit(void);
+NSPR_API(void)				_MD_SolarisInit();
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_MD_SolarisInit
+#define	_MD_INIT_THREAD		_MD_InitializeThread
+
+#ifdef USE_SETJMP
+
+#include <setjmp.h>
+
+#define _PR_CONTEXT_TYPE	jmp_buf
+
+#ifdef sparc
+#define _MD_GET_SP(_t)		(_t)->md.context[2]
+#else
+#define _MD_GET_SP(_t)		(_t)->md.context[4]
+#endif
+
+#define PR_NUM_GCREGS		_JBLEN
+#define CONTEXT(_thread)	(_thread)->md.context
+
+#else  /* ! USE_SETJMP */
+
+#ifdef sparc
+#define	_PR_CONTEXT_TYPE	ucontext_t
+#define _MD_GET_SP(_t)		(_t)->md.context.uc_mcontext.gregs[REG_SP]
+/*
+** Sparc's use register windows. the _MD_GetRegisters for the sparc's
+** doesn't actually store anything into the argument buffer; instead the
+** register windows are homed to the stack. I assume that the stack
+** always has room for the registers to spill to...
+*/
+#define PR_NUM_GCREGS		0
+#else
+#define _PR_CONTEXT_TYPE	unsigned int edi; sigset_t oldMask, blockMask; ucontext_t
+#define _MD_GET_SP(_t)		(_t)->md.context.uc_mcontext.gregs[USP]
+#define PR_NUM_GCREGS		_JBLEN
+#endif
+
+#define CONTEXT(_thread)	(&(_thread)->md.context)
+
+#endif /* ! USE_SETJMP */
+
+#include <time.h>
+/* 
+ * Because clock_gettime() on Solaris/x86 always generates a
+ * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
+ * which is implemented using gettimeofday().
+ */
+#ifdef i386
+#define GETTIME(tt) _pr_solx86_clock_gettime(CLOCK_REALTIME, (tt))
+#else
+#define GETTIME(tt) clock_gettime(CLOCK_REALTIME, (tt))
+#endif  /* i386 */
+
+#define _MD_SAVE_ERRNO(_thread)			(_thread)->md.errcode = errno;
+#define _MD_RESTORE_ERRNO(_thread)		errno = (_thread)->md.errcode;
+
+#ifdef sparc
+
+#ifdef USE_SETJMP
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+    PR_BEGIN_MACRO				      \
+	int *context = (_thread)->md.context;	      \
+    *status = PR_TRUE;              \
+	(void) setjmp(context);			      \
+	(_thread)->md.context[1] = (int) ((_sp) - 64); \
+	(_thread)->md.context[2] = (int) _main;	      \
+	(_thread)->md.context[3] = (int) _main + 4; \
+    _thread->no_sched = 0; \
+    PR_END_MACRO
+
+#define _MD_SWITCH_CONTEXT(_thread)    \
+    if (!setjmp(CONTEXT(_thread))) { \
+	_MD_SAVE_ERRNO(_thread)    \
+	_MD_SET_LAST_THREAD(_thread);	 \
+    _MD_SET_CURRENT_THREAD(_thread);	 \
+	_PR_Schedule();		     \
+    }
+
+#define _MD_RESTORE_CONTEXT(_newThread)	    \
+{				     \
+	_MD_RESTORE_ERRNO(_newThread)	    \
+	_MD_SET_CURRENT_THREAD(_newThread); \
+    longjmp(CONTEXT(_newThread), 1);    \
+}
+
+#else
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)					\
+    PR_BEGIN_MACRO				      									\
+    ucontext_t *uc = CONTEXT(_thread);									\
+    *status = PR_TRUE;													\
+    getcontext(uc);														\
+    uc->uc_stack.ss_sp = (char *) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8);	\
+    uc->uc_stack.ss_size = _thread->stack->stackSize; 					\
+    uc->uc_stack.ss_flags = 0; 				/* ? */		        		\
+    uc->uc_mcontext.gregs[REG_SP] = (unsigned int) uc->uc_stack.ss_sp;	\
+    uc->uc_mcontext.gregs[REG_PC] = (unsigned int) _main;				\
+    uc->uc_mcontext.gregs[REG_nPC] = (unsigned int) ((char*)_main)+4;	\
+    uc->uc_flags = UC_ALL;												\
+    _thread->no_sched = 0;												\
+    PR_END_MACRO
+
+/*
+** Switch away from the current thread context by saving its state and
+** calling the thread scheduler. Reload cpu when we come back from the
+** context switch because it might have changed.
+*/
+#define _MD_SWITCH_CONTEXT(_thread)    				\
+    PR_BEGIN_MACRO                     				\
+		if (!getcontext(CONTEXT(_thread))) { 		\
+			_MD_SAVE_ERRNO(_thread);    			\
+			_MD_SET_LAST_THREAD(_thread);	 		\
+			_PR_Schedule();			 				\
+		}					 						\
+    PR_END_MACRO
+
+/*
+** Restore a thread context that was saved by _MD_SWITCH_CONTEXT or
+** initialized by _MD_INIT_CONTEXT.
+*/
+#define _MD_RESTORE_CONTEXT(_newThread)	    				\
+    PR_BEGIN_MACRO			    							\
+    	ucontext_t *uc = CONTEXT(_newThread); 				\
+    	uc->uc_mcontext.gregs[11] = 1;     					\
+		_MD_RESTORE_ERRNO(_newThread);	    				\
+		_MD_SET_CURRENT_THREAD(_newThread); 				\
+    	setcontext(uc);		       							\
+    PR_END_MACRO
+#endif
+
+#else  /* x86 solaris */
+
+#ifdef USE_SETJMP
+
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+    PR_BEGIN_MACRO \
+    *status = PR_TRUE; \
+    if (setjmp(CONTEXT(_thread))) _main(); \
+    _MD_GET_SP(_thread) = (int) ((_sp) - 64); \
+    PR_END_MACRO
+
+#define _MD_SWITCH_CONTEXT(_thread) \
+    if (!setjmp(CONTEXT(_thread))) { \
+        _MD_SAVE_ERRNO(_thread) \
+        _PR_Schedule();	\
+    }
+
+#define _MD_RESTORE_CONTEXT(_newThread) \
+{ \
+    _MD_RESTORE_ERRNO(_newThread) \
+    _MD_SET_CURRENT_THREAD(_newThread); \
+    longjmp(CONTEXT(_newThread), 1); \
+}
+
+#else /* USE_SETJMP */
+
+#define WINDOWSIZE		0
+ 
+int getedi(void);
+void setedi(int);
+ 
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+	PR_BEGIN_MACRO					\
+	ucontext_t *uc = CONTEXT(_thread);		\
+        *status = PR_TRUE;              \
+	getcontext(uc);					\
+	/* Force sp to be double aligned! */		\
+    	uc->uc_mcontext.gregs[USP] = (int) ((unsigned long)(_sp - WINDOWSIZE - SA(MINFRAME)) & 0xfffffff8);	\
+	uc->uc_mcontext.gregs[PC] = (int) _main;	\
+	(_thread)->no_sched = 0; \
+	PR_END_MACRO
+
+/* getcontext() may return 1, contrary to what the man page says */
+#define _MD_SWITCH_CONTEXT(_thread)			\
+	PR_BEGIN_MACRO					\
+	ucontext_t *uc = CONTEXT(_thread);		\
+	PR_ASSERT(_thread->no_sched);			\
+	sigfillset(&((_thread)->md.blockMask));		\
+	sigprocmask(SIG_BLOCK, &((_thread)->md.blockMask),	\
+		&((_thread)->md.oldMask));		\
+	(_thread)->md.edi = getedi();			\
+	if (! getcontext(uc)) {				\
+		sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \
+		uc->uc_mcontext.gregs[EDI] = (_thread)->md.edi;	\
+		_MD_SAVE_ERRNO(_thread)    		\
+	        _MD_SET_LAST_THREAD(_thread);	        \
+		_PR_Schedule();				\
+	} else {					\
+		sigprocmask(SIG_SETMASK, &((_thread)->md.oldMask), NULL); \
+		setedi((_thread)->md.edi);		\
+		PR_ASSERT(_MD_LAST_THREAD() !=_MD_CURRENT_THREAD()); \
+		_MD_LAST_THREAD()->no_sched = 0;	\
+	}						\
+	PR_END_MACRO
+
+/*
+** Restore a thread context, saved by _PR_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_newthread)			\
+	PR_BEGIN_MACRO					\
+	ucontext_t *uc = CONTEXT(_newthread);		\
+	uc->uc_mcontext.gregs[EAX] = 1;			\
+	_MD_RESTORE_ERRNO(_newthread)  			\
+	_MD_SET_CURRENT_THREAD(_newthread);		\
+	(_newthread)->no_sched = 1;			\
+	setcontext(uc);					\
+	PR_END_MACRO
+#endif /* USE_SETJMP */
+
+#endif /* sparc */
+
+struct _MDLock {
+	PRInt8 notused;
+};
+
+struct _MDCVar {
+	PRInt8 notused;
+};
+
+struct _MDSemaphore {
+	PRInt8 notused;
+};
+
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int errcode;
+    int id;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#ifndef _PR_PTHREADS
+#define _MD_INIT_LOCKS()
+#endif
+#define _MD_NEW_LOCK(lock)				PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu)		_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD					_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)
+#define _MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+extern PRStatus _MD_WAIT(struct PRThread *, PRIntervalTime timeout);
+extern PRStatus _MD_WAKEUP_WAITER(struct PRThread *);
+extern void     _MD_YIELD(void);
+extern PRStatus _MD_InitializeThread(PRThread *thread);
+extern void     _MD_SET_PRIORITY(struct _MDThread *thread,
+	PRThreadPriority newPri);
+extern PRStatus _MD_CREATE_THREAD(PRThread *thread, void (*start) (void *),
+	PRThreadPriority priority, PRThreadScope scope, PRThreadState state,
+        PRUint32 stackSize);
+
+NSPR_API(PRIntervalTime)				_MD_Solaris_GetInterval(void);
+#define _MD_GET_INTERVAL				_MD_Solaris_GetInterval
+NSPR_API(PRIntervalTime)				_MD_Solaris_TicksPerSecond(void);
+#define _MD_INTERVAL_PER_SEC			_MD_Solaris_TicksPerSecond
+
+/* The following defines the unwrapped versions of select() and poll(). */
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *exceptfds, struct timeval *timeout);
+#define _MD_SELECT	_select
+
+#include <stropts.h>
+#include <poll.h>
+#define _MD_POLL _poll
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Missing function prototypes
+*/
+extern int gethostname (char *name, int namelen);
+
+PR_END_EXTERN_C
+
+#endif /* _PR_GLOBAL_THREADS_ONLY */
+
+extern void _MD_solaris_map_sendfile_error(int err);
+
+#endif /* nspr_solaris_defs_h___ */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sony.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sony.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,140 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef SONY
+#define SONY
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#undef  HAVE_LONG_LONG
+#undef  HAVE_ALIGNED_DOUBLES
+#undef  HAVE_ALIGNED_LONGLONGS
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sony.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sony.h	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+#ifndef nspr_sony_defs_h___
+#define nspr_sony_defs_h___
+ 
+#define PR_LINKER_ARCH		"sony"
+#define _PR_SI_SYSNAME		"SONY"
+#define _PR_SI_ARCHITECTURE	"mips"
+#define PR_DLL_SUFFIX		".so"
+ 
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#define _MD_GET_INTERVAL	_PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC	_PR_UNIX_TicksPerSecond
+
+#if defined(_PR_LOCAL_THREADS_ONLY)
+#include <ucontext.h>
+#include <sys/regset.h>
+ 
+#define PR_NUM_GCREGS	NGREG
+#define PR_CONTEXT_TYPE	ucontext_t
+ 
+#define CONTEXT(_thread)	(&(_thread)->md.context)
+ 
+#define _MD_GET_SP(_t)		(_t)->md.context.uc_mcontext.gregs[CXT_SP]
+ 
+/*
+** Initialize the thread context preparing it to execute _main()
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)               \
+{                                                                   \
+    *status = PR_TRUE;  \
+    getcontext(CONTEXT(_thread));                                    \
+    CONTEXT(_thread)->uc_stack.ss_sp = (char*) (_thread)->stack->stackBottom; \
+    CONTEXT(_thread)->uc_stack.ss_size = (_thread)->stack->stackSize; \
+    _MD_GET_SP(_thread) = (greg_t) (_sp) - 64;             \
+    makecontext(CONTEXT(_thread), _main, 0);              \
+}
+ 
+#define _MD_SWITCH_CONTEXT(_thread)      \
+    if (!getcontext(CONTEXT(_thread))) { \
+        (_thread)->md.errcode = errno;      \
+        _PR_Schedule();                  \
+    }
+ 
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread)   \
+{                                      \
+    ucontext_t *uc = CONTEXT(_thread); \
+    uc->uc_mcontext.gregs[CXT_V0] = 1; \
+    uc->uc_mcontext.gregs[CXT_A3] = 0; \
+    _MD_SET_CURRENT_THREAD(_thread);      \
+    errno = (_thread)->md.errcode;        \
+    setcontext(uc);                    \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+    struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_EARLY_INIT          	_MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu)	_MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD			_MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/* The following defines unwrapped versions of select() and poll(). */
+extern int _select (int, fd_set *, fd_set *, fd_set *, struct timeval *);
+#define _MD_SELECT              _select
+
+#include <sys/poll.h>
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+#define _MD_POLL _poll
+ 
+#endif /* _PR_LOCAL_THREADS_ONLY */
+ 
+#undef	HAVE_STACK_GROWING_UP
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define	NEED_TIME_R
+#define NEED_STRFTIME_LOCK
+ 
+/*
+** Missing function prototypes
+*/
+extern int gethostname(char *name, int namelen);
+ 
+#endif /* nspr_sony_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sunos4.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sunos4.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,138 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef SUNOS4
+#define SUNOS4
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+#undef  HAVE_LONG_LONG
+#define	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* ifndef nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sunos4.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_sunos4.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,236 @@
+/* -*- 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 nspr_sunos_defs_h___
+#define nspr_sunos_defs_h___
+
+#include "md/sunos4.h"
+
+/* On SunOS 4, memset is declared in memory.h */
+#include <memory.h>
+#include <errno.h>
+#include <sys/syscall.h>
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"sunos"
+#define _PR_SI_SYSNAME	"SUNOS"
+#define _PR_SI_ARCHITECTURE "sparc"
+#define PR_DLL_SUFFIX		".so.1.0"
+
+/*
+** For sunos type machines, don't specify an address because the
+** NetBSD/SPARC O.S. does the wrong thing.
+*/
+#define _PR_VMBASE		0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#undef	HAVE_WEAK_IO_SYMBOLS
+#undef	HAVE_WEAK_MALLOC_SYMBOLS
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define HAVE_BSD_FLOCK
+#define _PR_NO_LARGE_FILES
+#define _PR_STAT_HAS_ONLY_ST_ATIME
+
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _MD_GET_SP(_t)    (_t)->md.context[2]
+
+#define PR_NUM_GCREGS	_JBLEN
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)	      \
+    PR_BEGIN_MACRO				      \
+	int *context = (_thread)->md.context;	      \
+        *status = PR_TRUE;              \
+	asm("ta 3");					\
+	(void) setjmp(context);			      \
+	(_thread)->md.context[2] = (int) ((_sp) - 64); \
+	(_thread)->md.context[2] &= ~7;		\
+	(_thread)->md.context[3] = (int) _main;  \
+	(_thread)->md.context[4] = (int) _main + 4;  \
+    PR_END_MACRO
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    asm("ta 3");			\
+    if (!setjmp(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;	     \
+    _MD_SET_CURRENT_THREAD(_thread);	 \
+    longjmp(CONTEXT(_thread), 1);    \
+}
+
+#pragma unknown_control_flow(longjmp)
+#pragma unknown_control_flow(setjmp)
+#pragma unknown_control_flow(_PR_Schedule)
+
+/*
+** Missing function prototypes
+*/
+
+extern int socket (int domain, int type, int protocol);
+extern int getsockname (int s, struct sockaddr *name, int *namelen);
+extern int getpeername (int s, struct sockaddr *name, int *namelen);
+extern int getsockopt (int s, int level, int optname, char* optval, int* optlen);
+extern int setsockopt (int s, int level, int optname, const char* optval, int optlen);
+extern int accept (int s, struct sockaddr *addr, int *addrlen);
+extern int listen (int s, int backlog);
+extern int brk(void *);
+extern void *sbrk(int);
+
+
+/* Machine-dependent (MD) data structures.  SunOS 4 has no native threads. */
+
+struct _MDThread {
+    jmp_buf context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/* These are copied from _solaris.h */
+
+#define _MD_EARLY_INIT          _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+#define _MD_POLL(fds,nfds,timeout) syscall(SYS_poll,fds,nfds,timeout)
+
+#endif /* nspr_sparc_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unix_errors.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unix_errors.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,171 @@
+/* -*- 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 prunixerrors_h___
+#define prunixerrors_h___
+
+#include <unistd.h>
+#include <stddef.h>
+
+PR_BEGIN_EXTERN_C
+
+extern void _MD_unix_map_default_error(int err);
+#define	_PR_MD_MAP_DEFAULT_ERROR	_MD_unix_map_default_error
+
+extern void _MD_unix_map_opendir_error(int err);
+#define	_PR_MD_MAP_OPENDIR_ERROR	_MD_unix_map_opendir_error
+
+extern void _MD_unix_map_closedir_error(int err);
+#define	_PR_MD_MAP_CLOSEDIR_ERROR	_MD_unix_map_closedir_error
+
+extern void _MD_unix_readdir_error(int err);
+#define	_PR_MD_MAP_READDIR_ERROR	_MD_unix_readdir_error
+
+extern void _MD_unix_map_unlink_error(int err);
+#define	_PR_MD_MAP_UNLINK_ERROR	_MD_unix_map_unlink_error
+
+extern void _MD_unix_map_stat_error(int err);
+#define	_PR_MD_MAP_STAT_ERROR	_MD_unix_map_stat_error
+
+extern void _MD_unix_map_fstat_error(int err);
+#define	_PR_MD_MAP_FSTAT_ERROR	_MD_unix_map_fstat_error
+
+extern void _MD_unix_map_rename_error(int err);
+#define	_PR_MD_MAP_RENAME_ERROR	_MD_unix_map_rename_error
+
+extern void _MD_unix_map_access_error(int err);
+#define	_PR_MD_MAP_ACCESS_ERROR	_MD_unix_map_access_error
+
+extern void _MD_unix_map_mkdir_error(int err);
+#define	_PR_MD_MAP_MKDIR_ERROR	_MD_unix_map_mkdir_error
+
+extern void _MD_unix_map_rmdir_error(int err);
+#define	_PR_MD_MAP_RMDIR_ERROR	_MD_unix_map_rmdir_error
+
+extern void _MD_unix_map_read_error(int err);
+#define	_PR_MD_MAP_READ_ERROR	_MD_unix_map_read_error
+
+extern void _MD_unix_map_write_error(int err);
+#define	_PR_MD_MAP_WRITE_ERROR	_MD_unix_map_write_error
+
+extern void _MD_unix_map_lseek_error(int err);
+#define	_PR_MD_MAP_LSEEK_ERROR	_MD_unix_map_lseek_error
+
+extern void _MD_unix_map_fsync_error(int err);
+#define	_PR_MD_MAP_FSYNC_ERROR	_MD_unix_map_fsync_error
+
+extern void _MD_unix_map_close_error(int err);
+#define	_PR_MD_MAP_CLOSE_ERROR	_MD_unix_map_close_error
+
+extern void _MD_unix_map_socket_error(int err);
+#define	_PR_MD_MAP_SOCKET_ERROR	_MD_unix_map_socket_error
+
+extern void _MD_unix_map_socketavailable_error(int err);
+#define	_PR_MD_MAP_SOCKETAVAILABLE_ERROR	_MD_unix_map_socketavailable_error
+
+extern void _MD_unix_map_recv_error(int err);
+#define	_PR_MD_MAP_RECV_ERROR	_MD_unix_map_recv_error
+
+extern void _MD_unix_map_recvfrom_error(int err);
+#define	_PR_MD_MAP_RECVFROM_ERROR	_MD_unix_map_recvfrom_error
+
+extern void _MD_unix_map_send_error(int err);
+#define	_PR_MD_MAP_SEND_ERROR	_MD_unix_map_send_error
+
+extern void _MD_unix_map_sendto_error(int err);
+#define	_PR_MD_MAP_SENDTO_ERROR	_MD_unix_map_sendto_error
+
+extern void _MD_unix_map_writev_error(int err);
+#define	_PR_MD_MAP_WRITEV_ERROR	_MD_unix_map_writev_error
+
+extern void _MD_unix_map_accept_error(int err);
+#define	_PR_MD_MAP_ACCEPT_ERROR	_MD_unix_map_accept_error
+
+extern void _MD_unix_map_connect_error(int err);
+#define	_PR_MD_MAP_CONNECT_ERROR	_MD_unix_map_connect_error
+
+extern void _MD_unix_map_bind_error(int err);
+#define	_PR_MD_MAP_BIND_ERROR	_MD_unix_map_bind_error
+
+extern void _MD_unix_map_listen_error(int err);
+#define	_PR_MD_MAP_LISTEN_ERROR	_MD_unix_map_listen_error
+
+extern void _MD_unix_map_shutdown_error(int err);
+#define	_PR_MD_MAP_SHUTDOWN_ERROR	_MD_unix_map_shutdown_error
+
+extern void _MD_unix_map_socketpair_error(int err);
+#define	_PR_MD_MAP_SOCKETPAIR_ERROR	_MD_unix_map_socketpair_error
+
+extern void _MD_unix_map_getsockname_error(int err);
+#define	_PR_MD_MAP_GETSOCKNAME_ERROR	_MD_unix_map_getsockname_error
+
+extern void _MD_unix_map_getpeername_error(int err);
+#define	_PR_MD_MAP_GETPEERNAME_ERROR	_MD_unix_map_getpeername_error
+
+extern void _MD_unix_map_getsockopt_error(int err);
+#define	_PR_MD_MAP_GETSOCKOPT_ERROR	_MD_unix_map_getsockopt_error
+
+extern void _MD_unix_map_setsockopt_error(int err);
+#define	_PR_MD_MAP_SETSOCKOPT_ERROR	_MD_unix_map_setsockopt_error
+
+extern void _MD_unix_map_open_error(int err);
+#define	_PR_MD_MAP_OPEN_ERROR	_MD_unix_map_open_error
+
+extern void _MD_unix_map_mmap_error(int err);
+#define	_PR_MD_MAP_MMAP_ERROR	_MD_unix_map_mmap_error
+
+extern void _MD_unix_map_gethostname_error(int err);
+#define	_PR_MD_MAP_GETHOSTNAME_ERROR	_MD_unix_map_gethostname_error
+
+extern void _MD_unix_map_select_error(int err);
+#define	_PR_MD_MAP_SELECT_ERROR	_MD_unix_map_select_error
+
+extern void _MD_unix_map_poll_error(int err);
+#define _PR_MD_MAP_POLL_ERROR _MD_unix_map_poll_error
+
+extern void _MD_unix_map_poll_revents_error(int err);
+#define _PR_MD_MAP_POLL_REVENTS_ERROR _MD_unix_map_poll_revents_error
+
+extern void _MD_unix_map_flock_error(int err);
+#define	_PR_MD_MAP_FLOCK_ERROR	_MD_unix_map_flock_error
+
+extern void _MD_unix_map_lockf_error(int err);
+#define	_PR_MD_MAP_LOCKF_ERROR	_MD_unix_map_lockf_error
+
+PR_END_EXTERN_C
+
+#endif /* prunixerrors_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixos.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixos.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,633 @@
+/* -*- 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 prunixos_h___
+#define prunixos_h___
+
+/*
+ * If FD_SETSIZE is not defined on the command line, set the default value
+ * before include select.h
+ */
+/*
+ * Linux: FD_SETSIZE is defined in /usr/include/sys/select.h and should
+ * not be redefined.
+ */
+#if !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__) \
+    && !defined(DARWIN) && !defined(NEXTSTEP)
+#ifndef FD_SETSIZE
+#define FD_SETSIZE  4096
+#endif
+#endif
+
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include "prio.h"
+#include "prmem.h"
+#include "prclist.h"
+
+/*
+ * For select(), fd_set, and struct timeval.
+ *
+ * In The Single UNIX(R) Specification, Version 2,
+ * the header file for select() is <sys/time.h>.
+ *
+ * fd_set is defined in <sys/types.h>.  Usually
+ * <sys/time.h> includes <sys/types.h>, but on some
+ * older systems <sys/time.h> does not include
+ * <sys/types.h>, so we include it explicitly.
+ */
+#include <sys/time.h>
+#include <sys/types.h>
+#if defined(AIX)  /* Only pre-4.2 AIX needs it, but for simplicity... */
+#include <sys/select.h>
+#endif
+
+#define _PR_HAVE_O_APPEND
+
+#define PR_DIRECTORY_SEPARATOR		'/'
+#define PR_DIRECTORY_SEPARATOR_STR	"/"
+#define PR_PATH_SEPARATOR		':'
+#define PR_PATH_SEPARATOR_STR		":"
+#define GCPTR
+typedef int (*FARPROC)();
+
+/*
+ * intervals at which GLOBAL threads wakeup to check for pending interrupt
+ */
+#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5
+extern PRIntervalTime intr_timeout_ticks;
+
+/*
+ * The bit flags for the in_flags and out_flags fields
+ * of _PR_UnixPollDesc
+ */
+#ifdef _PR_USE_POLL
+#define _PR_UNIX_POLL_READ    POLLIN
+#define _PR_UNIX_POLL_WRITE   POLLOUT
+#define _PR_UNIX_POLL_EXCEPT  POLLPRI
+#define _PR_UNIX_POLL_ERR     POLLERR
+#define _PR_UNIX_POLL_NVAL    POLLNVAL
+#define _PR_UNIX_POLL_HUP     POLLHUP
+#else /* _PR_USE_POLL */
+#define _PR_UNIX_POLL_READ    0x1
+#define _PR_UNIX_POLL_WRITE   0x2
+#define _PR_UNIX_POLL_EXCEPT  0x4
+#define _PR_UNIX_POLL_ERR     0x8
+#define _PR_UNIX_POLL_NVAL    0x10
+#define _PR_UNIX_POLL_HUP     0x20
+#endif /* _PR_USE_POLL */
+
+typedef struct _PRUnixPollDesc {
+	PRInt32 osfd;
+	PRInt16 in_flags;
+	PRInt16 out_flags;
+} _PRUnixPollDesc;
+
+typedef struct PRPollQueue {
+    PRCList links;        /* for linking PRPollQueue's together */
+    _PRUnixPollDesc *pds;        /* array of poll descriptors */
+    PRUintn npds;            /* length of the array */
+    PRPackedBool on_ioq;    /* is this on the async i/o work q? */
+    PRIntervalTime timeout;        /* timeout, in ticks */
+    struct PRThread *thr;
+} PRPollQueue;
+
+#define _PR_POLLQUEUE_PTR(_qp) \
+    ((PRPollQueue*) ((char*) (_qp) - offsetof(PRPollQueue,links)))
+
+
+extern PRInt32 _PR_WaitForMultipleFDs(
+    _PRUnixPollDesc *unixpds,
+    PRInt32 pdcnt,
+    PRIntervalTime timeout);
+extern void _PR_Unblock_IO_Wait(struct PRThread *thr);
+
+#if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY)
+#define _MD_CHECK_FOR_EXIT()
+#endif
+
+extern fd_set _pr_md_read_set, _pr_md_write_set, _pr_md_exception_set;
+extern PRInt16 _pr_md_read_cnt[], _pr_md_write_cnt[], _pr_md_exception_cnt[];
+extern PRInt32 _pr_md_ioq_max_osfd;
+extern PRUint32 _pr_md_ioq_timeout;
+
+struct _MDFileDesc {
+    int osfd;
+#if defined(LINUX) && defined(_PR_PTHREADS)
+    int tcp_nodelay;  /* used by pt_LinuxSendFile */
+#endif
+};
+
+struct _MDDir {
+	DIR *d;
+};
+
+struct _PRCPU;
+extern void _MD_unix_init_running_cpu(struct _PRCPU *cpu);
+
+/*
+** Make a redzone at both ends of the stack segment. Disallow access
+** to those pages of memory. It's ok if the mprotect call's don't
+** work - it just means that we don't really have a functional
+** redzone.
+*/
+#include <sys/mman.h>
+#ifndef PROT_NONE
+#define PROT_NONE 0x0
+#endif
+
+#if defined(DEBUG) && !defined(DARWIN) && !defined(NEXTSTEP)
+#if !defined(SOLARIS)	
+#include <string.h>  /* for memset() */
+#define _MD_INIT_STACK(ts,REDZONE)					\
+    PR_BEGIN_MACRO                 					\
+	(void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_NONE);	\
+	(void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\
+			REDZONE, PROT_NONE);				\
+    /*									\
+    ** Fill stack memory with something that turns into an illegal	\
+    ** pointer value. This will sometimes find runtime references to	\
+    ** uninitialized pointers. We don't do this for solaris because we	\
+    ** can use purify instead.						\
+    */									\
+    if (_pr_debugStacks) {						\
+	memset(ts->allocBase + REDZONE, 0xf7, ts->stackSize);		\
+    }									\
+    PR_END_MACRO
+#else	/* !SOLARIS	*/
+#define _MD_INIT_STACK(ts,REDZONE)					\
+    PR_BEGIN_MACRO                 					\
+	(void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_NONE);	\
+	(void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\
+			REDZONE, PROT_NONE);				\
+    PR_END_MACRO
+#endif	/* !SOLARIS	*/
+
+/*
+ * _MD_CLEAR_STACK
+ *	Allow access to the redzone pages; the access was turned off in
+ *	_MD_INIT_STACK.
+ */
+#define _MD_CLEAR_STACK(ts)						\
+    PR_BEGIN_MACRO                 					\
+	(void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_READ|PROT_WRITE);\
+	(void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\
+			REDZONE, PROT_READ|PROT_WRITE);			\
+    PR_END_MACRO
+
+#else	/* DEBUG */
+
+#define _MD_INIT_STACK(ts,REDZONE)
+#define _MD_CLEAR_STACK(ts)
+
+#endif	/* DEBUG */
+
+#if !defined(SOLARIS) 
+
+#define PR_SET_INTSOFF(newval)
+
+#endif
+
+/************************************************************************/
+
+extern void _PR_UnixInit(void);
+
+/************************************************************************/
+
+struct _MDProcess {
+    pid_t pid;
+};
+
+struct PRProcess;
+struct PRProcessAttr;
+
+/* Create a new process (fork() + exec()) */
+#define _MD_CREATE_PROCESS _MD_CreateUnixProcess
+extern struct PRProcess * _MD_CreateUnixProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const struct PRProcessAttr *attr
+);
+
+#define _MD_DETACH_PROCESS _MD_DetachUnixProcess
+extern PRStatus _MD_DetachUnixProcess(struct PRProcess *process);
+
+/* Wait for a child process to terminate */
+#define _MD_WAIT_PROCESS _MD_WaitUnixProcess
+extern PRStatus _MD_WaitUnixProcess(struct PRProcess *process,
+    PRInt32 *exitCode);
+
+#define _MD_KILL_PROCESS _MD_KillUnixProcess
+extern PRStatus _MD_KillUnixProcess(struct PRProcess *process);
+
+/************************************************************************/
+
+extern void _MD_EnableClockInterrupts(void);
+extern void _MD_DisableClockInterrupts(void);
+
+#define _MD_START_INTERRUPTS			_MD_StartInterrupts
+#define _MD_STOP_INTERRUPTS				_MD_StopInterrupts
+#define _MD_DISABLE_CLOCK_INTERRUPTS	_MD_DisableClockInterrupts
+#define _MD_ENABLE_CLOCK_INTERRUPTS		_MD_EnableClockInterrupts
+#define _MD_BLOCK_CLOCK_INTERRUPTS		_MD_BlockClockInterrupts
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS	_MD_UnblockClockInterrupts
+
+/************************************************************************/
+
+extern void		_MD_InitCPUS(void);
+#define _MD_INIT_CPUS           _MD_InitCPUS
+
+extern void		_MD_Wakeup_CPUs(void);
+#define _MD_WAKEUP_CPUS _MD_Wakeup_CPUs
+
+#define _MD_PAUSE_CPU			_MD_PauseCPU
+
+#if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY)
+#define _MD_CLEANUP_BEFORE_EXIT()
+#endif
+
+#ifndef IRIX
+#define _MD_EXIT(status)		_exit(status)
+#endif
+
+/************************************************************************/
+
+#define _MD_GET_ENV				getenv
+#define _MD_PUT_ENV				putenv
+
+/************************************************************************/
+
+#define _MD_INIT_FILEDESC(fd)
+
+extern void		_MD_MakeNonblock(PRFileDesc *fd);
+#define _MD_MAKE_NONBLOCK			_MD_MakeNonblock		
+
+/************************************************************************/
+
+#if !defined(_PR_PTHREADS)
+
+extern void		_MD_InitSegs(void);
+extern PRStatus	_MD_AllocSegment(PRSegment *seg, PRUint32 size,
+				void *vaddr);
+extern void		_MD_FreeSegment(PRSegment *seg);
+
+#define _MD_INIT_SEGS			_MD_InitSegs
+#define _MD_ALLOC_SEGMENT		_MD_AllocSegment
+#define _MD_FREE_SEGMENT		_MD_FreeSegment
+
+#endif /* !defined(_PR_PTHREADS) */
+
+/************************************************************************/
+
+#if !defined(HPUX_LW_TIMER)
+#define _MD_INTERVAL_INIT()
+#endif
+#define _MD_INTERVAL_PER_MILLISEC()	(_PR_MD_INTERVAL_PER_SEC() / 1000)
+#define _MD_INTERVAL_PER_MICROSEC()	(_PR_MD_INTERVAL_PER_SEC() / 1000000)
+
+/************************************************************************/
+
+#define _MD_ERRNO()             	(errno)
+#define _MD_GET_SOCKET_ERROR()		(errno)
+
+/************************************************************************/
+
+extern PRInt32 _MD_AvailableSocket(PRInt32 osfd);
+
+extern void _MD_StartInterrupts(void);
+extern void _MD_StopInterrupts(void);
+extern void _MD_DisableClockInterrupts(void);
+extern void _MD_BlockClockInterrupts(void);
+extern void _MD_UnblockClockInterrupts(void);
+extern void _MD_PauseCPU(PRIntervalTime timeout);
+
+extern PRStatus _MD_open_dir(struct _MDDir *, const char *);
+extern PRInt32  _MD_close_dir(struct _MDDir *);
+extern char *   _MD_read_dir(struct _MDDir *, PRIntn);
+extern PRInt32  _MD_open(const char *name, PRIntn osflags, PRIntn mode);
+extern PRInt32	_MD_delete(const char *name);
+extern PRInt32	_MD_getfileinfo(const char *fn, PRFileInfo *info);
+extern PRInt32  _MD_getfileinfo64(const char *fn, PRFileInfo64 *info);
+extern PRInt32  _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info);
+extern PRInt32  _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info);
+extern PRInt32	_MD_rename(const char *from, const char *to);
+extern PRInt32	_MD_access(const char *name, PRAccessHow how);
+extern PRInt32	_MD_mkdir(const char *name, PRIntn mode);
+extern PRInt32	_MD_rmdir(const char *name);
+extern PRInt32	_MD_accept_read(PRInt32 sock, PRInt32 *newSock,
+				PRNetAddr **raddr, void *buf, PRInt32 amount);
+extern PRInt32 	_PR_UnixSendFile(PRFileDesc *sd, PRSendFileData *sfd,
+			PRTransmitFileFlags flags, PRIntervalTime timeout);
+
+extern PRStatus _MD_LockFile(PRInt32 osfd);
+extern PRStatus _MD_TLockFile(PRInt32 osfd);
+extern PRStatus _MD_UnlockFile(PRInt32 osfd);
+
+#define _MD_OPEN_DIR(dir, name)		    _MD_open_dir(dir, name)
+#define _MD_CLOSE_DIR(dir)		        _MD_close_dir(dir)
+#define _MD_READ_DIR(dir, flags)	    _MD_read_dir(dir, flags)
+#define _MD_OPEN(name, osflags, mode)	_MD_open(name, osflags, mode)
+#define _MD_OPEN_FILE(name, osflags, mode)	_MD_open(name, osflags, mode)
+extern PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount);
+#define _MD_READ(fd,buf,amount)		    _MD_read(fd,buf,amount)
+extern PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount);
+#define _MD_WRITE(fd,buf,amount)	    _MD_write(fd,buf,amount)
+#define _MD_DELETE(name)		        _MD_delete(name)
+#define _MD_GETFILEINFO(fn, info)	    _MD_getfileinfo(fn, info)
+#define _MD_GETFILEINFO64(fn, info)	    _MD_getfileinfo64(fn, info)
+#define _MD_GETOPENFILEINFO(fd, info)	_MD_getopenfileinfo(fd, info)
+#define _MD_GETOPENFILEINFO64(fd, info)	_MD_getopenfileinfo64(fd, info)
+#define _MD_RENAME(from, to)		    _MD_rename(from, to)
+#define _MD_ACCESS(name, how)		    _MD_access(name, how)
+#define _MD_MKDIR(name, mode)		    _MD_mkdir(name, mode)
+#define _MD_MAKE_DIR(name, mode)		_MD_mkdir(name, mode)
+#define _MD_RMDIR(name)			        _MD_rmdir(name)
+#define _MD_ACCEPT_READ(sock, newSock, raddr, buf, amount)	_MD_accept_read(sock, newSock, raddr, buf, amount)
+
+#define _MD_LOCKFILE _MD_LockFile
+#define _MD_TLOCKFILE _MD_TLockFile
+#define _MD_UNLOCKFILE _MD_UnlockFile
+
+
+extern PRInt32		_MD_socket(int af, int type, int flags);
+#define _MD_SOCKET	_MD_socket
+extern PRInt32		_MD_connect(PRFileDesc *fd, const PRNetAddr *addr,
+								PRUint32 addrlen, PRIntervalTime timeout);
+#define _MD_CONNECT	_MD_connect
+extern PRInt32		_MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen,
+													PRIntervalTime timeout);
+#define _MD_ACCEPT	_MD_accept
+extern PRInt32		_MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen);
+#define _MD_BIND	_MD_bind
+extern PRInt32		_MD_listen(PRFileDesc *fd, PRIntn backlog);
+#define _MD_LISTEN	_MD_listen
+extern PRInt32		_MD_shutdown(PRFileDesc *fd, PRIntn how);
+#define _MD_SHUTDOWN	_MD_shutdown
+
+extern PRInt32		_MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, 
+                               PRIntn flags, PRIntervalTime timeout);
+#define _MD_RECV	_MD_recv
+extern PRInt32		_MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+									PRIntn flags, PRIntervalTime timeout);
+#define _MD_SEND	_MD_send
+extern PRInt32		_MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
+						PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen,
+											PRIntervalTime timeout);
+#define _MD_RECVFROM	_MD_recvfrom
+extern PRInt32 _MD_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount,
+							PRIntn flags, const PRNetAddr *addr, PRUint32 addrlen,
+												PRIntervalTime timeout);
+#define _MD_SENDTO	_MD_sendto
+extern PRInt32		_MD_writev(PRFileDesc *fd, const struct PRIOVec *iov,
+								PRInt32 iov_size, PRIntervalTime timeout);
+#define _MD_WRITEV	_MD_writev
+
+extern PRInt32		_MD_socketavailable(PRFileDesc *fd);
+#define	_MD_SOCKETAVAILABLE		_MD_socketavailable
+extern PRInt64		_MD_socketavailable64(PRFileDesc *fd);
+#define	_MD_SOCKETAVAILABLE64		_MD_socketavailable64
+
+#define	_MD_PIPEAVAILABLE		_MD_socketavailable
+
+extern PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds,
+												PRIntervalTime timeout);
+#define _MD_PR_POLL		_MD_pr_poll
+
+extern PRInt32		_MD_close(PRInt32 osfd);
+#define _MD_CLOSE_FILE	_MD_close
+extern PRInt32		_MD_lseek(PRFileDesc*, PRInt32, PRSeekWhence);
+#define _MD_LSEEK	_MD_lseek
+extern PRInt64		_MD_lseek64(PRFileDesc*, PRInt64, PRSeekWhence);
+#define _MD_LSEEK64	_MD_lseek64
+extern PRInt32		_MD_fsync(PRFileDesc *fd);
+#define _MD_FSYNC	_MD_fsync
+
+extern PRInt32 _MD_socketpair(int af, int type, int flags, PRInt32 *osfd);
+#define _MD_SOCKETPAIR		_MD_socketpair
+
+#define _MD_CLOSE_SOCKET	_MD_close
+
+#ifndef NO_NSPR_10_SUPPORT
+#define _MD_STAT	stat
+#endif
+
+extern PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr,
+											PRUint32 *addrlen);
+#define _MD_GETPEERNAME _MD_getpeername
+extern PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr,
+											PRUint32 *addrlen);
+#define _MD_GETSOCKNAME _MD_getsockname
+
+extern PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level,
+						PRInt32 optname, char* optval, PRInt32* optlen);
+#define _MD_GETSOCKOPT		_MD_getsockopt
+extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level,
+					PRInt32 optname, const char* optval, PRInt32 optlen);
+#define _MD_SETSOCKOPT		_MD_setsockopt
+
+extern PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable);
+#define _MD_SET_FD_INHERITABLE _MD_set_fd_inheritable
+
+extern void _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported);
+#define _MD_INIT_FD_INHERITABLE _MD_init_fd_inheritable
+
+extern void _MD_query_fd_inheritable(PRFileDesc *fd);
+#define _MD_QUERY_FD_INHERITABLE _MD_query_fd_inheritable
+
+extern PRStatus _MD_gethostname(char *name, PRUint32 namelen);
+#define _MD_GETHOSTNAME		_MD_gethostname
+
+extern PRStatus _MD_getsysinfo(PRSysInfo cmd, char *name, PRUint32 namelen);
+#define _MD_GETSYSINFO		_MD_getsysinfo
+
+extern int _MD_unix_get_nonblocking_connect_error(int osfd);
+
+/* Memory-mapped files */
+
+struct _MDFileMap {
+    PRIntn prot;
+    PRIntn flags;
+    PRBool isAnonFM; /* when true, PR_CloseFileMap() must close the related fd */
+};
+
+extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
+#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
+
+#define _MD_GET_MEM_MAP_ALIGNMENT() PR_GetPageSize()
+
+extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
+        PRUint32 len);
+#define _MD_MEM_MAP _MD_MemMap
+
+extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
+#define _MD_MEM_UNMAP _MD_MemUnmap
+
+extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
+#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
+
+/*
+ * The standard (XPG4) gettimeofday() (from BSD) takes two arguments.
+ * On some SVR4 derivatives, gettimeofday() takes only one argument.
+ * The GETTIMEOFDAY macro is intended to hide this difference.
+ */
+#ifdef HAVE_SVID_GETTOD
+#define GETTIMEOFDAY(tp) gettimeofday(tp)
+#else
+#define GETTIMEOFDAY(tp) gettimeofday((tp), NULL)
+#endif
+
+#if defined(_PR_PTHREADS) && !defined(_PR_POLL_AVAILABLE)
+#define _PR_NEED_FAKE_POLL
+#endif
+
+#if defined(_PR_NEED_FAKE_POLL)
+
+/*
+ * Some platforms don't have poll(), but our pthreads code calls poll().
+ * As a temporary measure, I implemented a fake poll() using select().
+ * Here are the struct and macro definitions copied from sys/poll.h
+ * on Solaris 2.5.
+ */
+
+struct pollfd {
+    int fd;
+    short events;
+    short revents;
+};
+
+/* poll events */
+
+#define	POLLIN		0x0001		/* fd is readable */
+#define	POLLPRI		0x0002		/* high priority info at fd */
+#define	POLLOUT		0x0004		/* fd is writeable (won't block) */
+#define	POLLRDNORM	0x0040		/* normal data is readable */
+#define	POLLWRNORM	POLLOUT
+#define	POLLRDBAND	0x0080		/* out-of-band data is readable */
+#define	POLLWRBAND	0x0100		/* out-of-band data is writeable */
+
+#define	POLLNORM	POLLRDNORM
+
+#define	POLLERR		0x0008		/* fd has error condition */
+#define	POLLHUP		0x0010		/* fd has been hung up on */
+#define	POLLNVAL	0x0020		/* invalid pollfd entry */
+
+extern int poll(struct pollfd *, unsigned long, int);
+
+#endif /* _PR_NEED_FAKE_POLL */
+
+/*
+** A vector of the UNIX I/O calls we use. These are here to smooth over
+** the rough edges needed for large files. All of NSPR's implmentaions
+** go through this vector using syntax of the form
+**      result = _md_iovector.xxx64(args);
+*/
+
+#if defined(SOLARIS2_5)
+/*
+** Special case: Solaris 2.5.1
+** Solaris starts to have 64-bit file I/O in 2.6.  We build on Solaris
+** 2.5.1 so that we can use the same binaries on both Solaris 2.5.1 and
+** 2.6.  At run time, we detect whether 64-bit file I/O is available by
+** looking up the 64-bit file function symbols in libc.  At build time,
+** we need to define the 64-bit file I/O datatypes that are compatible
+** with their definitions on Solaris 2.6.
+*/
+typedef PRInt64 off64_t;
+typedef PRUint64 ino64_t;
+typedef PRInt64 blkcnt64_t;
+struct stat64 {
+    dev_t st_dev;
+    long st_pad1[3];
+    ino64_t st_ino;
+    mode_t st_mode;
+    nlink_t st_nlink;
+    uid_t st_uid;
+    gid_t st_gid;
+    dev_t st_rdev;
+    long t_pad2[2];
+    off64_t st_size;
+    timestruc_t st_atim;
+    timestruc_t st_mtim;
+    timestruc_t st_ctim;
+    long st_blksize;
+    blkcnt64_t st_blocks;
+    char st_fstype[_ST_FSTYPSZ];
+    long st_pad4[8];
+};
+typedef struct stat64 _MDStat64;
+typedef off64_t _MDOff64_t;
+
+#elif defined(_PR_HAVE_OFF64_T)
+typedef struct stat64 _MDStat64;
+typedef off64_t _MDOff64_t;
+#elif defined(_PR_HAVE_LARGE_OFF_T)
+typedef struct stat _MDStat64;
+typedef off_t _MDOff64_t;
+#elif defined(_PR_NO_LARGE_FILES)
+typedef struct stat _MDStat64;
+typedef PRInt64 _MDOff64_t;
+#else
+#error "I don't know yet"
+#endif
+
+typedef PRIntn (*_MD_Fstat64)(PRIntn osfd, _MDStat64 *buf);
+typedef PRIntn (*_MD_Open64)(const char *path, int oflag, ...);
+#if defined(VMS)
+typedef PRIntn (*_MD_Stat64)(const char *path, _MDStat64 *buf, ...);
+#else
+typedef PRIntn (*_MD_Stat64)(const char *path, _MDStat64 *buf);
+#endif
+typedef _MDOff64_t (*_MD_Lseek64)(PRIntn osfd, _MDOff64_t, PRIntn whence);
+typedef void* (*_MD_Mmap64)(
+    void *addr, PRSize len, PRIntn prot, PRIntn flags,
+    PRIntn fildes, _MDOff64_t offset);
+struct _MD_IOVector
+{
+    _MD_Open64 _open64;
+    _MD_Mmap64 _mmap64;
+    _MD_Stat64 _stat64;
+    _MD_Fstat64 _fstat64;
+    _MD_Lseek64 _lseek64;
+};
+extern struct _MD_IOVector _md_iovector;
+
+#endif /* prunixos_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixware.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixware.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,140 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef UNIXWARE
+#define UNIXWARE
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#undef	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixware.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixware.h	Mon Dec 18 10:53:47 2006
@@ -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 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 nspr_unixware_defs_h___
+#define nspr_unixware_defs_h___
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH	"unixware"
+#define _PR_SI_SYSNAME		"UnixWare"
+#define _PR_SI_ARCHITECTURE	"x86"
+#define PR_DLL_SUFFIX		".so"
+
+#define _PR_VMBASE	 	0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#ifndef	HAVE_WEAK_IO_SYMBOLS
+#define	HAVE_WEAK_IO_SYMBOLS
+#endif
+#define _PR_POLL_AVAILABLE
+#define _PR_USE_POLL
+#define _PR_STAT_HAS_ST_ATIM_UNION
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_NETCONFIG
+#define	HAVE_DLL
+#define	USE_DLFCN
+#define HAVE_STRERROR
+#define NEED_STRFTIME_LOCK
+#define NEED_TIME_R
+#define _PR_NEED_STRCASECMP
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define _SETJMP setjmp
+#define _LONGJMP longjmp
+#define _PR_CONTEXT_TYPE         jmp_buf
+#define _MD_GET_SP(_t)           (_t)->md.context[4]
+#define _PR_NUM_GCREGS	_JBLEN
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+/*
+** Initialize the thread context preparing it to execute _main.
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+{								  \
+    *status = PR_TRUE; \
+    if(_SETJMP(CONTEXT(_thread))) (*_main)(); \
+    _MD_GET_SP(_thread) = (int) ((_sp) - 128); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!_SETJMP(CONTEXT(_thread))) { \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();		     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{				     \
+    errno = (_thread)->md.errcode;	     \
+    _MD_SET_CURRENT_THREAD(_thread); \
+    _LONGJMP(CONTEXT(_thread), 1);    \
+}
+
+/* Machine-dependent (MD) data structures.
+ * Don't use SVR4 native threads (yet). 
+ */
+
+struct _MDThread {
+    _PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+/*
+ * md-specific cpu structure field
+ */
+#define _PR_MD_MAX_OSFD FD_SETSIZE
+
+struct _MDCPU_Unix {
+    PRCList ioQ;
+    PRUint32 ioq_timeout;
+    PRInt32 ioq_max_osfd;
+    PRInt32 ioq_osfd_cnt;
+#ifndef _PR_USE_POLL
+    fd_set fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+#else
+	struct pollfd *ioq_pollfds;
+	int ioq_pollfds_size;
+#endif	/* _PR_USE_POLL */
+};
+
+#define _PR_IOQ(_cpu)			((_cpu)->md.md_unix.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.md_unix.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.md_unix.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.md_unix.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.md_unix.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.md_unix.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.md_unix.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.md_unix.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.md_unix.ioq_max_osfd)
+#define _PR_IOQ_OSFD_CNT(_cpu)		((_cpu)->md.md_unix.ioq_osfd_cnt)
+#define _PR_IOQ_POLLFDS(_cpu)		((_cpu)->md.md_unix.ioq_pollfds)
+#define _PR_IOQ_POLLFDS_SIZE(_cpu)	((_cpu)->md.md_unix.ioq_pollfds_size)
+
+#define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu)	32
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+/*
+ * The following are copied from _sunos.h, _aix.h.  This means
+ * some of them should probably be moved into _unixos.h.  But
+ * _irix.h seems to be quite different in regard to these macros.
+ */
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+#define _MD_EARLY_INIT		_MD_EarlyInit
+#define _MD_FINAL_INIT		_PR_UnixInit
+#define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD         _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define	_MD_SUSPEND_THREAD(thread)
+#define	_MD_RESUME_THREAD(thread)
+#define _MD_CLEAN_THREAD(_thread)
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+extern int _select(int nfds, fd_set *readfds, fd_set *writefds,
+	fd_set *execptfds, struct timeval *timeout);
+#define _MD_SELECT _select
+
+#define _MD_POLL _poll
+extern int _poll(struct pollfd *fds, unsigned long nfds, int timeout);
+
+#endif /* nspr_unixware_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixware7.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_unixware7.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,142 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef UNIXWARE
+#define UNIXWARE
+#endif
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#undef	HAVE_ALIGNED_LONGLONGS
+
+#define PR_AF_INET6 27  /* same as AF_INET6 */
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define _PR_POLL_BACKCOMPAT
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win16.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win16.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,177 @@
+/* -*- 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 ***** */
+
+/*
+** _win16.cfg -- prcpucfg.h for win16
+**
+**
+** lth. 14-Apr-1997. New. Made from _win95.cfg
+*/
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_PC
+#define XP_PC
+#endif
+
+#ifndef WIN16
+#define WIN16
+#undef  WIN32
+#endif
+
+#if defined(_M_IX86) || defined(_X86_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    2
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD	4
+#define PR_BYTES_PER_DWORD	8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     16
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	32
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    4
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	4
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     2
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD	2
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2	2
+#define PR_BYTES_PER_DWORD_LOG2	2
+
+#else /* defined(_M_IX86) || defined(_X86_) */
+
+#error unknown processor architecture
+
+#endif /* defined(_M_IX86) || defined(_X86_) */
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE      PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT     PR_BYTES_PER_SHORT
+#define BYTES_PER_INT       PR_BYTES_PER_INT
+#define BYTES_PER_INT64     PR_BYTES_PER_INT64
+#define BYTES_PER_LONG      PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT     PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE    PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD      PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD     PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE       PR_BITS_PER_BYTE
+#define BITS_PER_SHORT      PR_BITS_PER_SHORT
+#define BITS_PER_INT        PR_BITS_PER_INT
+#define BITS_PER_INT64      PR_BITS_PER_INT64
+#define BITS_PER_LONG       PR_BITS_PER_LONG
+#define BITS_PER_FLOAT      PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE     PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD       PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2  PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2   PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2  PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2    PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2  PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT      PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT        PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG       PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64      PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT      PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE     PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER    PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD       PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2		PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2    PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2    PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#undef  HAVE_LONG_LONG
+
+/*
+** HAVE_WATCOM_BUG_1
+** When HAVE_WATCOM_BUG_1 is defined, special case code is
+** used to circumvent the bug.
+** Functions declared __cdecl in DLLs returning floating point types
+** generate bad return code and will not return the intended result.
+*/
+#define HAVE_WATCOM_BUG_1
+
+/*
+** HAVE_WATCOM_BUG_2
+** When HAVE_WATCOM_BUG_2 is defined, special case code is
+** used to circumvent the bug.
+** Functions declared __cdecl in DLLs returning a structure by value
+** generate bad return values.
+** Yes, similar to Watcom Bug 1.
+*/
+#define HAVE_WATCOM_BUG_2
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win16.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win16.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,568 @@
+/* -*- 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 nspr_win16_defs_h___
+#define nspr_win16_defs_h___
+
+#include <windows.h>
+#include <winsock.h>
+#include <errno.h>
+#include <direct.h>
+
+#include "nspr.h"
+/* $$ fix this */
+#define Remind(x)
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH      "win16"
+#define _PR_SI_SYSNAME        "WIN16"
+#define _PR_SI_ARCHITECTURE   "x86"    /* XXXMB hardcode for now */
+
+#define HAVE_DLL
+#define _PR_NO_PREEMPT
+#define _PR_LOCAL_THREADS_ONLY
+#undef  _PR_GLOBAL_THREADS_ONLY
+#undef  HAVE_THREAD_AFFINITY
+#define _PR_HAVE_ATOMIC_OPS
+
+/* --- Common User-Thread/Native-Thread Definitions --------------------- */
+
+extern struct PRLock        *_pr_schedLock;
+extern char                 * _pr_top_of_task_stack;
+
+
+/* --- Typedefs --- */
+
+#define PR_NUM_GCREGS           9
+typedef PRInt32	               PR_CONTEXT_TYPE[PR_NUM_GCREGS];
+
+#define _MD_MAGIC_THREAD	0x22222222
+#define _MD_MAGIC_THREADSTACK	0x33333333
+#define _MD_MAGIC_SEGMENT	0x44444444
+#define _MD_MAGIC_DIR		0x55555555
+#define _MD_MAGIC_CV        0x66666666
+
+
+typedef struct _PRWin16PollDesc
+{
+	PRInt32 osfd;
+	PRInt16 in_flags;
+	PRInt16 out_flags;
+} _PRWin16PollDesc;
+
+typedef struct PRPollQueue
+{
+    PRCList links;              /* for linking PRPollQueue's together */
+    _PRWin16PollDesc *pds;      /* array of poll descriptors */
+    PRUintn npds;				/* length of the array */
+    PRPackedBool on_ioq;        /* is this on the async i/o work q? */
+    PRIntervalTime timeout;     /* timeout, in ticks */
+    struct PRThread *thr;
+} PRPollQueue;
+
+#define _PR_POLLQUEUE_PTR(_qp) \
+    ((PRPollQueue *) ((char*) (_qp) - offsetof(PRPollQueue,links)))
+
+NSPR_API(PRInt32) _PR_WaitForFD(PRInt32 osfd, PRUintn how,
+					PRIntervalTime timeout);
+NSPR_API(void) _PR_Unblock_IO_Wait(struct PRThread *thr);
+
+#define _PR_MD_MAX_OSFD             FD_SETSIZE
+#define _PR_IOQ(_cpu)				((_cpu)->md.ioQ)
+#define _PR_ADD_TO_IOQ(_pq, _cpu) 	PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
+#define _PR_FD_READ_SET(_cpu)		((_cpu)->md.fd_read_set)
+#define _PR_FD_READ_CNT(_cpu)		((_cpu)->md.fd_read_cnt)
+#define _PR_FD_WRITE_SET(_cpu)		((_cpu)->md.fd_write_set)
+#define _PR_FD_WRITE_CNT(_cpu)		((_cpu)->md.fd_write_cnt)
+#define _PR_FD_EXCEPTION_SET(_cpu)	((_cpu)->md.fd_exception_set)
+#define _PR_FD_EXCEPTION_CNT(_cpu)	((_cpu)->md.fd_exception_cnt)
+#define _PR_IOQ_TIMEOUT(_cpu)		((_cpu)->md.ioq_timeout)
+#define _PR_IOQ_MAX_OSFD(_cpu)		((_cpu)->md.ioq_max_osfd)
+
+struct _MDCPU {
+    PRCList		ioQ;
+    fd_set		fd_read_set, fd_write_set, fd_exception_set;
+    PRInt16		fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
+				fd_exception_cnt[_PR_MD_MAX_OSFD];
+    PRUint32	ioq_timeout;
+    PRInt32		ioq_max_osfd;
+};
+
+struct _MDThread {
+    /* The overlapped structure must be first! */
+    HANDLE           blocked_sema;      /* Threads block on this when waiting
+                                         * for IO or CondVar.
+                                         */
+    PRInt32         errcode;        /* preserved errno for this thread */
+    CATCHBUF        context;        /* thread context for Throw() */
+    void           *SP;             /* Stack pointer, used only by GarbColl */
+    int             threadNumber;   /* instrumentation: order of creation */
+	_PRWin16PollDesc thr_pd;       /* poll descriptor for i/o */
+	PRPollQueue		thr_pq;        /* i/o parameters			*/
+    void           *exceptionContext; /* mfc exception context */
+    char            guardBand[24];  /* don't overwrite this */
+    PRUint32        magic;          /* self identifier, for debug */
+};
+
+struct _MDThreadStack {
+    PRUint32           magic;          /* for debugging */
+    PRIntn          cxByteCount;    /* number of stack bytes to move */
+    char *          stackTop;       /* high address on stack */
+};
+
+struct _MDSegment {
+    PRUint32           magic;          /* for debugging */
+};
+
+
+struct _MDLock {
+    PRUint32           magic;          /* for debugging */
+    PRUint32           mutex;
+};
+
+struct _MDDir {
+    PRUint32         magic;          /* for debugging */
+    struct  dirent  *dir;
+};
+
+struct _MDCVar {
+	PRUint32        magic;
+};
+
+struct _MDSemaphore {
+	PRInt32			unused;
+};
+
+struct _MDFileDesc {
+    PRInt32 osfd;
+};
+
+struct _MDProcess {
+    HANDLE handle;
+    DWORD id;
+};
+
+/*
+** Microsoft 'struct _stat'
+** ... taken directly from msvc 1.52c's header file sys/stat.h
+** see PR_Stat() implemented in w16io.c
+** See BugSplat: 98516
+*/
+#pragma pack(push)
+#pragma pack(2)
+
+typedef unsigned short _ino_t;
+typedef short _dev_t;
+typedef long _off_t;
+
+typedef struct _MDMSStat {
+    _dev_t st_dev;
+    _ino_t st_ino;
+    unsigned short st_mode;
+    short st_nlink;
+    short st_uid;
+    short st_gid;
+    _dev_t st_rdev;
+    _off_t st_size;
+    time_t st_atime;
+    time_t st_mtime;
+    time_t st_ctime;
+} _MDMSStat;
+#pragma pack(pop)
+
+/* --- Errors --- */
+    /* These are NSPR generated error codes which need to be unique from
+     * OS error codes.
+     */
+#define _MD_UNIQUEBASE                 50000
+#define _MD_EINTERRUPTED               _MD_UNIQUEBASE + 1
+#define _MD_ETIMEDOUT                  _MD_UNIQUEBASE + 2
+#define _MD_EIO                        _MD_UNIQUEBASE + 3
+
+struct PRProcess;
+struct PRProcessAttr;
+
+/* --- Create a new process --- */
+#define _MD_CREATE_PROCESS _PR_CreateWindowsProcess
+extern struct PRProcess * _PR_CreateWindowsProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const struct PRProcessAttr *attr
+);
+
+#define _MD_DETACH_PROCESS _PR_DetachWindowsProcess
+extern PRStatus _PR_DetachWindowsProcess(struct PRProcess *process);
+
+/* --- Wait for a child process to terminate --- */
+#define _MD_WAIT_PROCESS _PR_WaitWindowsProcess
+extern PRStatus _PR_WaitWindowsProcess(struct PRProcess *process, 
+    PRInt32 *exitCode);
+
+#define _MD_KILL_PROCESS _PR_KillWindowsProcess
+extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process);
+
+
+/* --- Misc stuff --- */
+
+#define MD_ASSERTINT( x )             PR_ASSERT( (x) < 65535 )
+
+/* --- IO stuff --- */
+#define MAX_PATH    256
+#define _MD_ERRNO()                   errno
+#define GetLastError()                errno
+
+#define _MD_GET_FILE_ERROR()          errno
+#define _MD_SET_FILE_ERROR(_err)      errno = (_err)
+
+#define _MD_OPEN                      _PR_MD_OPEN
+#define _MD_READ                      _PR_MD_READ
+#define _MD_WRITE                     _PR_MD_WRITE
+#define _MD_WRITEV                    _PR_MD_WRITEV
+#define _MD_LSEEK                     _PR_MD_LSEEK
+#define _MD_LSEEK64                   _PR_MD_LSEEK64
+#define _MD_CLOSE_FILE                _PR_MD_CLOSE_FILE
+#define _MD_GETFILEINFO               _PR_MD_GETFILEINFO
+#define _MD_GETOPENFILEINFO           _PR_MD_GETOPENFILEINFO
+#define _MD_STAT                      _PR_MD_STAT
+#define _MD_RENAME                    _PR_MD_RENAME     
+#define _MD_ACCESS                    _PR_MD_ACCESS     
+#define _MD_DELETE                    _PR_MD_DELETE     
+#define _MD_MKDIR                     _PR_MD_MKDIR      
+#define _MD_RMDIR                     _PR_MD_RMDIR      
+#define _MD_LOCKFILE                  _PR_MD_LOCKFILE
+#define _MD_TLOCKFILE                 _PR_MD_TLOCKFILE
+#define _MD_UNLOCKFILE                _PR_MD_UNLOCKFILE
+
+
+/* --- Socket IO stuff --- */
+#define _MD_EACCES                WSAEACCES
+#define _MD_EADDRINUSE            WSAEADDRINUSE
+#define _MD_EADDRNOTAVAIL         WSAEADDRNOTAVAIL
+#define _MD_EAFNOSUPPORT          WSAEAFNOSUPPORT
+#define _MD_EAGAIN                WSAEWOULDBLOCK
+#define _MD_EALREADY              WSAEALREADY
+#define _MD_EBADF                 WSAEBADF
+#define _MD_ECONNREFUSED          WSAECONNREFUSED
+#define _MD_ECONNRESET            WSAECONNRESET
+#define _MD_EFAULT                WSAEFAULT
+#define _MD_EINPROGRESS           WSAEINPROGRESS
+#define _MD_EINTR                 WSAEINTR
+#define _MD_EINVAL                EINVAL
+#define _MD_EISCONN               WSAEISCONN
+#define _MD_ENETUNREACH           WSAENETUNREACH
+#define _MD_ENOENT                ENOENT
+#define _MD_ENOTCONN              WSAENOTCONN
+#define _MD_ENOTSOCK              WSAENOTSOCK
+#define _MD_EOPNOTSUPP            WSAEOPNOTSUPP
+#define _MD_EWOULDBLOCK           WSAEWOULDBLOCK
+#define _MD_GET_SOCKET_ERROR()    WSAGetLastError()
+#define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err)
+
+#define _MD_INIT_FILEDESC(fd)
+#define _MD_MAKE_NONBLOCK             _PR_MD_MAKE_NONBLOCK
+#define _MD_SHUTDOWN                  _PR_MD_SHUTDOWN
+#define _MD_LISTEN                      _PR_MD_LISTEN
+#define _MD_CLOSE_SOCKET              _PR_MD_CLOSE_SOCKET
+#define _MD_SENDTO                    _PR_MD_SENDTO
+#define _MD_RECVFROM                  _PR_MD_RECVFROM
+#define _MD_SOCKETPAIR(s, type, proto, sv) -1
+#define _MD_GETSOCKNAME               _PR_MD_GETSOCKNAME
+#define _MD_GETPEERNAME               _PR_MD_GETPEERNAME
+#define _MD_GETSOCKOPT                _PR_MD_GETSOCKOPT
+#define _MD_SETSOCKOPT                _PR_MD_SETSOCKOPT
+#define _MD_SELECT                    select
+#define _MD_FSYNC                     _PR_MD_FSYNC
+#define _MD_SOCKETAVAILABLE           _PR_MD_SOCKETAVAILABLE
+
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_INCREMENT(x)       (*x++)
+#define _MD_ATOMIC_ADD(ptr, val)      ((*x) += val)
+#define _MD_ATOMIC_DECREMENT(x)       (*x--)
+#define _MD_ATOMIC_SET(x,y)           (*x, y)
+
+#define _MD_INIT_IO                   _PR_MD_INIT_IO
+
+/* win95 doesn't have async IO */
+#define _MD_SOCKET                    _PR_MD_SOCKET
+#define _MD_CONNECT                   _PR_MD_CONNECT
+#define _MD_ACCEPT                    _PR_MD_ACCEPT
+#define _MD_BIND                      _PR_MD_BIND
+#define _MD_RECV                      _PR_MD_RECV
+#define _MD_SEND                      _PR_MD_SEND
+
+#define _MD_CHECK_FOR_EXIT()
+
+/* --- Scheduler stuff --- */
+#define _MD_PAUSE_CPU                 _PR_MD_PAUSE_CPU
+
+/* --- DIR stuff --- */
+#define PR_DIRECTORY_SEPARATOR        '\\'
+#define PR_DIRECTORY_SEPARATOR_STR    "\\"
+#define PR_PATH_SEPARATOR		';'
+#define PR_PATH_SEPARATOR_STR		";"
+#define _MD_OPEN_DIR                  _PR_MD_OPEN_DIR
+#define _MD_CLOSE_DIR                 _PR_MD_CLOSE_DIR
+#define _MD_READ_DIR                  _PR_MD_READ_DIR
+
+/* --- Segment stuff --- */
+#define _MD_INIT_SEGS()
+#define _MD_ALLOC_SEGMENT           _MD_AllocSegment
+#define _MD_FREE_SEGMENT            _MD_FreeSegment
+
+/* --- Environment Stuff --- */
+#define _MD_GET_ENV                 _PR_MD_GET_ENV
+#define _MD_PUT_ENV                 _PR_MD_PUT_ENV
+
+/* --- Threading Stuff --- */
+#define _MD_DEFAULT_STACK_SIZE      32767L
+#define _MD_INIT_THREAD             _PR_MD_INIT_THREAD
+#define _MD_CREATE_THREAD(t,f,p,sc,st,stsiz) (PR_SUCCESS)
+#define _MD_YIELD                   _PR_MD_YIELD
+#define _MD_SET_PRIORITY(t,p)            
+#define _MD_CLEAN_THREAD(t)
+#define _MD_SETTHREADAFFINITYMASK   _PR_MD_SETTHREADAFFINITYMASK
+#define _MD_GETTHREADAFFINITYMASK   _PR_MD_GETTHREADAFFINITYMASK
+#define _MD_EXIT_THREAD
+#define _MD_SUSPEND_THREAD          _PR_MD_SUSPEND_THREAD
+#define _MD_RESUME_THREAD           _PR_MD_RESUME_THREAD
+#define _MD_SUSPEND_CPU             _PR_MD_SUSPEND_CPU
+#define _MD_RESUME_CPU              _PR_MD_RESUME_CPU
+#define _MD_BEGIN_SUSPEND_ALL()
+#define _MD_BEGIN_RESUME_ALL()
+#define _MD_END_SUSPEND_ALL()
+#define _MD_END_RESUME_ALL()
+
+/* --- Lock stuff --- */
+/*
+** Win16 does not need MD locks.
+*/
+#define _PR_LOCK                    _MD_LOCK
+#define _PR_UNLOCK                  _MD_UNLOCK
+
+#define _MD_NEW_LOCK(l)             (PR_SUCCESS)
+#define _MD_FREE_LOCK(l)
+#define _MD_LOCK(l)
+#define _MD_TEST_AND_LOCK(l)        (-1)
+#define _MD_UNLOCK(l)
+
+/* --- lock and cv waiting --- */
+#define _MD_WAIT                      _PR_MD_WAIT
+#define _MD_WAKEUP_WAITER(a)
+#define _MD_WAKEUP_CPUS               _PR_MD_WAKEUP_CPUS
+
+/* --- CVar ------------------- */
+#define _MD_WAIT_CV					  _PR_MD_WAIT_CV
+#define _MD_NEW_CV					  _PR_MD_NEW_CV
+#define _MD_FREE_CV					  _PR_MD_FREE_CV
+#define _MD_NOTIFY_CV				  _PR_MD_NOTIFY_CV	
+#define _MD_NOTIFYALL_CV			  _PR_MD_NOTIFYALL_CV
+
+   /* XXXMB- the IOQ stuff is certainly not working correctly yet. */
+#define _MD_IOQ_LOCK()                
+#define _MD_IOQ_UNLOCK()              
+
+
+/* --- Initialization stuff --- */
+NSPR_API(void) _MD_INIT_RUNNING_CPU(struct _PRCPU *cpu );
+#define _MD_START_INTERRUPTS()
+#define _MD_STOP_INTERRUPTS()
+#define _MD_DISABLE_CLOCK_INTERRUPTS()
+#define _MD_ENABLE_CLOCK_INTERRUPTS()
+#define _MD_BLOCK_CLOCK_INTERRUPTS()
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS()
+#define _MD_EARLY_INIT                  _PR_MD_EARLY_INIT
+#define _MD_FINAL_INIT                  _PR_MD_FINAL_INIT
+#define _MD_INIT_CPUS()
+
+/* --- User Threading stuff --- */
+#define _MD_EXIT
+
+#define _MD_CLEANUP_BEFORE_EXIT              _PR_MD_CLEANUP_BEFORE_EXIT
+
+/* --- Intervals --- */
+#define _MD_INTERVAL_INIT                 _PR_MD_INTERVAL_INIT
+#define _MD_GET_INTERVAL                  _PR_MD_GET_INTERVAL
+#define _MD_INTERVAL_PER_SEC              _PR_MD_INTERVAL_PER_SEC
+#define _MD_INTERVAL_PER_MILLISEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000)
+#define _MD_INTERVAL_PER_MICROSEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000000)
+
+/* --- Scheduler stuff --- */
+#define LOCK_SCHEDULER()                 0
+#define UNLOCK_SCHEDULER()               0
+#define _PR_LockSched()                	 0
+#define _PR_UnlockSched()                0
+
+/* --- Initialization stuff --- */
+#define _MD_INIT_LOCKS()
+
+/* --- Stack stuff --- */
+#define _MD_INIT_STACK                   _PR_MD_INIT_STACK
+#define _MD_CLEAR_STACK(stack)
+
+/*
+** Watcom needs to see this to make the linker work.
+**
+*/
+NSPR_API(void) _PR_NativeDestroyThread(PRThread *thread);
+NSPR_API(void) _PR_UserDestroyThread(PRThread *thread);
+
+
+/*
+** If thread emulation is used, then setjmp/longjmp stores the register
+** state of each thread.
+**
+** CatchBuf layout:
+**  context[0] - IP
+**  context[1] - CS
+**  context[2] - SP
+**  context[3] - BP
+**  context[4] - SI
+**  context[5] - DI
+**  context[6] - DS
+**  context[7] - ?? (maybe flags)
+**  context[8] - SS
+*/
+#define PR_CONTEXT_TYPE     CATCHBUF
+#define PR_NUM_GCREGS       9
+
+#define _MD_GET_SP(thread)  ((thread)->md.SP)
+#define CONTEXT(_t)  ((_t)->md.context)
+
+/*
+** Initialize a thread context to run "e(o,a)" when started
+*/
+#define _MD_INIT_CONTEXT(_t, sp, epa, stat )   \
+{                                              \
+     *(stat) = PR_TRUE;                        \
+     Catch((_t)->md.context );             \
+     (_t)->md.context[0] = OFFSETOF(epa);         \
+     (_t)->md.context[1] = SELECTOROF(epa);                       \
+     (_t)->md.context[2] = OFFSETOF(_pr_top_of_task_stack - 64);  \
+     (_t)->md.context[3]  = 0;                 \
+}
+
+#define _MD_SWITCH_CONTEXT(_t)                 \
+    if (!Catch((_t)->md.context)) {            \
+        int     garbCollPlaceHolder;           \
+        (_t)->md.errcode = errno;              \
+        (_t)->md.SP = &garbCollPlaceHolder;    \
+        _PR_Schedule();                        \
+    }
+
+#define _MD_SAVE_CONTEXT(_t)                    \
+    {                                           \
+        int     garbCollPlaceHolder;            \
+        Catch((_t)->md.context);                \
+        (_t)->md.errcode = errno;               \
+        (_t)->md.SP = &garbCollPlaceHolder;     \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _PR_MD_RESTORE_CONTEXT  _MD_RESTORE_CONTEXT
+
+/*
+ * Memory-mapped files
+ */
+
+struct _MDFileMap {
+    PRInt8 unused;
+};
+
+extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
+#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
+
+extern PRInt32 _MD_GetMemMapAlignment(void);
+#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment
+
+extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
+        PRUint32 len);
+#define _MD_MEM_MAP _MD_MemMap
+
+extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
+#define _MD_MEM_UNMAP _MD_MemUnmap
+
+extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
+#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
+
+
+/* --- Error mapping ----------------------------------- */
+extern void _PR_MD_map_error( int err );
+
+#define _PR_MD_MAP_OPENDIR_ERROR        _PR_MD_map_error
+#define _PR_MD_MAP_CLOSEDIR_ERROR       _PR_MD_map_error
+#define _PR_MD_MAP_READDIR_ERROR        _PR_MD_map_error
+#define _PR_MD_MAP_DELETE_ERROR         _PR_MD_map_error
+#define _PR_MD_MAP_STAT_ERROR           _PR_MD_map_error
+#define _PR_MD_MAP_FSTAT_ERROR          _PR_MD_map_error
+#define _PR_MD_MAP_RENAME_ERROR         _PR_MD_map_error
+#define _PR_MD_MAP_ACCESS_ERROR         _PR_MD_map_error
+#define _PR_MD_MAP_MKDIR_ERROR          _PR_MD_map_error
+#define _PR_MD_MAP_RMDIR_ERROR          _PR_MD_map_error
+#define _PR_MD_MAP_READ_ERROR           _PR_MD_map_error
+#define _PR_MD_MAP_TRANSMITFILE_ERROR   _PR_MD_map_error
+#define _PR_MD_MAP_WRITE_ERROR          _PR_MD_map_error
+#define _PR_MD_MAP_LSEEK_ERROR          _PR_MD_map_error
+#define _PR_MD_MAP_FSYNC_ERROR          _PR_MD_map_error
+#define _PR_MD_MAP_CLOSE_ERROR          _PR_MD_map_error
+#define _PR_MD_MAP_SOCKET_ERROR         _PR_MD_map_error
+#define _PR_MD_MAP_RECV_ERROR           _PR_MD_map_error
+#define _PR_MD_MAP_RECVFROM_ERROR       _PR_MD_map_error
+#define _PR_MD_MAP_SEND_ERROR           _PR_MD_map_error
+#define _PR_MD_MAP_SENDTO_ERROR         _PR_MD_map_error
+#define _PR_MD_MAP_ACCEPT_ERROR         _PR_MD_map_error
+#define _PR_MD_MAP_ACCEPTEX_ERROR       _PR_MD_map_error
+#define _PR_MD_MAP_CONNECT_ERROR        _PR_MD_map_error
+#define _PR_MD_MAP_BIND_ERROR           _PR_MD_map_error
+#define _PR_MD_MAP_LISTEN_ERROR         _PR_MD_map_error
+#define _PR_MD_MAP_SHUTDOWN_ERROR       _PR_MD_map_error
+#define _PR_MD_MAP_GETSOCKNAME_ERROR    _PR_MD_map_error
+#define _PR_MD_MAP_GETPEERNAME_ERROR    _PR_MD_map_error
+#define _PR_MD_MAP_GETSOCKOPT_ERROR     _PR_MD_map_error
+#define _PR_MD_MAP_SETSOCKOPT_ERROR     _PR_MD_map_error
+#define _PR_MD_MAP_OPEN_ERROR           _PR_MD_map_error
+#define _PR_MD_MAP_GETHOSTNAME_ERROR    _PR_MD_map_error
+#define _PR_MD_MAP_SELECT_ERROR         _PR_MD_map_error
+#define _PR_MD_MAP_LOCKF_ERROR          _PR_MD_map_error
+#define _PR_MD_MAP_WSASTARTUP_ERROR     _PR_MD_map_error
+
+#endif /* nspr_win16_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win32_errors.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win32_errors.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,154 @@
+/* -*- 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 nspr_win32_errors_h___
+#define nspr_win32_errors_h___
+
+#include <windows.h>
+#include <winsock.h>
+#include <errno.h>
+
+
+extern void _MD_win32_map_default_error(PRInt32 err);
+#define _PR_MD_MAP_DEFAULT_ERROR	_MD_win32_map_default_error
+
+extern void _MD_win32_map_opendir_error(PRInt32 err);
+#define	_PR_MD_MAP_OPENDIR_ERROR	_MD_win32_map_opendir_error
+
+extern void _MD_win32_map_closedir_error(PRInt32 err);
+#define	_PR_MD_MAP_CLOSEDIR_ERROR	_MD_win32_map_closedir_error
+
+extern void _MD_unix_readdir_error(PRInt32 err);
+#define	_PR_MD_MAP_READDIR_ERROR	_MD_unix_readdir_error
+
+extern void _MD_win32_map_delete_error(PRInt32 err);
+#define	_PR_MD_MAP_DELETE_ERROR	_MD_win32_map_delete_error
+
+extern void _MD_win32_map_stat_error(PRInt32 err);
+#define	_PR_MD_MAP_STAT_ERROR	_MD_win32_map_stat_error
+
+extern void _MD_win32_map_fstat_error(PRInt32 err);
+#define	_PR_MD_MAP_FSTAT_ERROR	_MD_win32_map_fstat_error
+
+extern void _MD_win32_map_rename_error(PRInt32 err);
+#define	_PR_MD_MAP_RENAME_ERROR	_MD_win32_map_rename_error
+
+extern void _MD_win32_map_access_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCESS_ERROR	_MD_win32_map_access_error
+
+extern void _MD_win32_map_mkdir_error(PRInt32 err);
+#define	_PR_MD_MAP_MKDIR_ERROR	_MD_win32_map_mkdir_error
+
+extern void _MD_win32_map_rmdir_error(PRInt32 err);
+#define	_PR_MD_MAP_RMDIR_ERROR	_MD_win32_map_rmdir_error
+
+extern void _MD_win32_map_read_error(PRInt32 err);
+#define	_PR_MD_MAP_READ_ERROR	_MD_win32_map_read_error
+
+extern void _MD_win32_map_transmitfile_error(PRInt32 err);
+#define	_PR_MD_MAP_TRANSMITFILE_ERROR	_MD_win32_map_transmitfile_error
+
+extern void _MD_win32_map_write_error(PRInt32 err);
+#define	_PR_MD_MAP_WRITE_ERROR	_MD_win32_map_write_error
+
+extern void _MD_win32_map_lseek_error(PRInt32 err);
+#define	_PR_MD_MAP_LSEEK_ERROR	_MD_win32_map_lseek_error
+
+extern void _MD_win32_map_fsync_error(PRInt32 err);
+#define	_PR_MD_MAP_FSYNC_ERROR	_MD_win32_map_fsync_error
+
+extern void _MD_win32_map_close_error(PRInt32 err);
+#define	_PR_MD_MAP_CLOSE_ERROR	_MD_win32_map_close_error
+
+extern void _MD_win32_map_socket_error(PRInt32 err);
+#define	_PR_MD_MAP_SOCKET_ERROR	_MD_win32_map_socket_error
+
+extern void _MD_win32_map_recv_error(PRInt32 err);
+#define	_PR_MD_MAP_RECV_ERROR	_MD_win32_map_recv_error
+
+extern void _MD_win32_map_recvfrom_error(PRInt32 err);
+#define	_PR_MD_MAP_RECVFROM_ERROR	_MD_win32_map_recvfrom_error
+
+extern void _MD_win32_map_send_error(PRInt32 err);
+#define	_PR_MD_MAP_SEND_ERROR	_MD_win32_map_send_error
+
+extern void _MD_win32_map_sendto_error(PRInt32 err);
+#define	_PR_MD_MAP_SENDTO_ERROR	_MD_win32_map_sendto_error
+
+extern void _MD_win32_map_accept_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCEPT_ERROR	_MD_win32_map_accept_error
+
+extern void _MD_win32_map_acceptex_error(PRInt32 err);
+#define	_PR_MD_MAP_ACCEPTEX_ERROR	_MD_win32_map_acceptex_error
+
+extern PRInt32 _MD_win32_map_connect_error(PRInt32 err);
+#define	_PR_MD_MAP_CONNECT_ERROR	_MD_win32_map_connect_error
+
+extern void _MD_win32_map_bind_error(PRInt32 err);
+#define	_PR_MD_MAP_BIND_ERROR	_MD_win32_map_bind_error
+
+extern void _MD_win32_map_listen_error(PRInt32 err);
+#define	_PR_MD_MAP_LISTEN_ERROR	_MD_win32_map_listen_error
+
+extern void _MD_win32_map_shutdown_error(PRInt32 err);
+#define	_PR_MD_MAP_SHUTDOWN_ERROR	_MD_win32_map_shutdown_error
+
+extern void _MD_win32_map_getsockname_error(PRInt32 err);
+#define	_PR_MD_MAP_GETSOCKNAME_ERROR	_MD_win32_map_getsockname_error
+
+extern void _MD_win32_map_getpeername_error(PRInt32 err);
+#define	_PR_MD_MAP_GETPEERNAME_ERROR	_MD_win32_map_getpeername_error
+
+extern void _MD_win32_map_getsockopt_error(PRInt32 err);
+#define	_PR_MD_MAP_GETSOCKOPT_ERROR	_MD_win32_map_getsockopt_error
+
+extern void _MD_win32_map_setsockopt_error(PRInt32 err);
+#define	_PR_MD_MAP_SETSOCKOPT_ERROR	_MD_win32_map_setsockopt_error
+
+extern void _MD_win32_map_open_error(PRInt32 err);
+#define	_PR_MD_MAP_OPEN_ERROR	_MD_win32_map_open_error
+
+extern void _MD_win32_map_gethostname_error(PRInt32 err);
+#define	_PR_MD_MAP_GETHOSTNAME_ERROR	_MD_win32_map_gethostname_error
+
+extern void _MD_win32_map_select_error(PRInt32 err);
+#define	_PR_MD_MAP_SELECT_ERROR	_MD_win32_map_select_error
+
+extern void _MD_win32_map_lockf_error(int err);
+#define _PR_MD_MAP_LOCKF_ERROR  _MD_win32_map_lockf_error
+
+#endif /* nspr_win32_errors_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win95.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win95.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,298 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_PC
+#define XP_PC
+#endif
+
+#ifndef WIN32
+#define WIN32
+#endif
+
+#ifndef WIN95
+#define WIN95
+#endif
+
+#define PR_AF_INET6 23  /* same as AF_INET6 */
+
+#if defined(_M_IX86) || defined(_X86_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD	4
+#define PR_BYTES_PER_DWORD	8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	32
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	5
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD	4
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2	2
+#define PR_BYTES_PER_DWORD_LOG2	2
+
+#elif defined(_ALPHA_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_BYTES_PER_WORD_LOG2  2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(_AMD64_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD	8
+#define PR_BYTES_PER_DWORD	8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	64
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	6
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD	8
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2	3
+#define PR_BYTES_PER_DWORD_LOG2	3
+
+#elif defined(_IA64_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD	8
+#define PR_BYTES_PER_DWORD	8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	64
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	6
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD	8
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2	3
+#define PR_BYTES_PER_DWORD_LOG2	3
+
+#else /* defined(_M_IX86) || defined(_X86_) */
+
+#error unknown processor architecture
+
+#endif /* defined(_M_IX86) || defined(_X86_) */
+
+#define HAVE_LONG_LONG
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE      PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT     PR_BYTES_PER_SHORT
+#define BYTES_PER_INT       PR_BYTES_PER_INT
+#define BYTES_PER_INT64     PR_BYTES_PER_INT64
+#define BYTES_PER_LONG      PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT     PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE    PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD      PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD     PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE       PR_BITS_PER_BYTE
+#define BITS_PER_SHORT      PR_BITS_PER_SHORT
+#define BITS_PER_INT        PR_BITS_PER_INT
+#define BITS_PER_INT64      PR_BITS_PER_INT64
+#define BITS_PER_LONG       PR_BITS_PER_LONG
+#define BITS_PER_FLOAT      PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE     PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD       PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2  PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2   PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2  PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2    PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2  PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT      PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT        PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG       PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64      PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT      PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE     PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER    PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD       PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2		PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2    PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2    PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win95.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_win95.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,557 @@
+/* -*- 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 nspr_win95_defs_h___
+#define nspr_win95_defs_h___
+
+#include "prio.h"
+
+#include <windows.h>
+#include <winsock.h>
+#include <errno.h>
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH      "win32"
+#define _PR_SI_SYSNAME        "WIN95"
+#if defined(_M_IX86) || defined(_X86_)
+#define _PR_SI_ARCHITECTURE   "x86"
+#elif defined(_AMD64_)
+#define _PR_SI_ARCHITECTURE   "x86-64"
+#elif defined(_IA64_)
+#define _PR_SI_ARCHITECTURE   "ia64"
+#else
+#error unknown processor architecture
+#endif
+
+#define HAVE_DLL
+#undef  HAVE_THREAD_AFFINITY
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#ifndef _PR_INET6
+#define AF_INET6 23
+/* newer ws2tcpip.h provides these */
+#ifndef AI_CANONNAME
+#define AI_CANONNAME 0x2
+struct addrinfo {
+    int ai_flags;
+    int ai_family;
+    int ai_socktype;
+    int ai_protocol;
+    size_t ai_addrlen;
+    char *ai_canonname;
+    struct sockaddr *ai_addr;
+    struct addrinfo *ai_next;
+};
+#endif
+#define _PR_HAVE_MD_SOCKADDR_IN6
+/* isomorphic to struct in6_addr on Windows */
+struct _md_in6_addr {
+    union {
+        PRUint8  _S6_u8[16];
+        PRUint16 _S6_u16[8];
+    } _S6_un;
+};
+/* isomorphic to struct sockaddr_in6 on Windows */
+struct _md_sockaddr_in6 {
+    PRInt16 sin6_family;
+    PRUint16 sin6_port;
+    PRUint32 sin6_flowinfo;
+    struct _md_in6_addr sin6_addr;
+    PRUint32 sin6_scope_id;
+};
+#endif
+#define _PR_HAVE_THREADSAFE_GETHOST
+#define _PR_HAVE_ATOMIC_OPS
+#define PR_HAVE_WIN32_NAMED_SHARED_MEMORY
+
+/* --- Common User-Thread/Native-Thread Definitions --------------------- */
+
+/* --- Globals --- */
+extern struct PRLock                      *_pr_schedLock;
+
+/* --- Typedefs --- */
+typedef void (*FiberFunc)(void *);
+
+#define PR_NUM_GCREGS           8
+typedef PRInt32	                PR_CONTEXT_TYPE[PR_NUM_GCREGS];
+#define GC_VMBASE               0x40000000
+#define GC_VMLIMIT              0x00FFFFFF
+
+#define _MD_MAGIC_THREAD	0x22222222
+#define _MD_MAGIC_THREADSTACK	0x33333333
+#define _MD_MAGIC_SEGMENT	0x44444444
+#define _MD_MAGIC_DIR		0x55555555
+#define _MD_MAGIC_CV        0x66666666
+
+struct _MDCPU {
+    int              unused;
+};
+
+struct _MDThread {
+    HANDLE           blocked_sema;      /* Threads block on this when waiting
+                                         * for IO or CondVar.
+                                         */
+    PRBool           inCVWaitQueue;     /* PR_TRUE if the thread is in the
+                                         * wait queue of some cond var.
+                                         * PR_FALSE otherwise.  */
+    HANDLE           handle;            /* Win32 thread handle */
+    PRUint32         id;
+    void            *sp;                /* only valid when suspended */
+    PRUint32         magic;             /* for debugging */
+    PR_CONTEXT_TYPE  gcContext;         /* Thread context for GC */
+    struct PRThread *prev, *next;       /* used by the cvar wait queue to
+                                         * chain the PRThread structures
+                                         * together */
+    void (*start)(void *);              /* used by _PR_MD_CREATE_THREAD to
+                                         * pass its 'start' argument to
+                                         * pr_root. */
+};
+
+struct _MDThreadStack {
+    PRUint32           magic;          /* for debugging */
+};
+
+struct _MDSegment {
+    PRUint32           magic;          /* for debugging */
+};
+
+#undef PROFILE_LOCKS
+
+struct _MDDir {
+    HANDLE           d_hdl;
+    WIN32_FIND_DATA  d_entry;
+    PRBool           firstEntry;     /* Is this the entry returned
+                                      * by FindFirstFile()? */
+    PRUint32         magic;          /* for debugging */
+};
+
+#ifdef MOZ_UNICODE
+struct _MDDirUTF16 {
+    HANDLE           d_hdl;
+    WIN32_FIND_DATAW d_entry;
+    PRBool           firstEntry;     /* Is this the entry returned
+                                      * by FindFirstFileW()? */
+    PRUint32         magic;          /* for debugging */
+};
+#endif /* MOZ_UNICODE */
+
+struct _MDCVar {
+    PRUint32 magic;
+    struct PRThread *waitHead, *waitTail;  /* the wait queue: a doubly-
+                                            * linked list of threads
+                                            * waiting on this condition
+                                            * variable */
+    PRIntn nwait;                          /* number of threads in the
+                                            * wait queue */
+};
+
+#define _MD_CV_NOTIFIED_LENGTH 6
+typedef struct _MDNotified _MDNotified;
+struct _MDNotified {
+    PRIntn length;                     /* # of used entries in this
+                                        * structure */
+    struct {
+        struct _MDCVar *cv;            /* the condition variable notified */
+        PRIntn times;                  /* and the number of times notified */
+        struct PRThread *notifyHead;   /* list of threads to wake up */
+    } cv[_MD_CV_NOTIFIED_LENGTH];
+    _MDNotified *link;                 /* link to another of these, or NULL */
+};
+
+struct _MDLock {
+    CRITICAL_SECTION mutex;          /* this is recursive on NT */
+
+    /*
+     * When notifying cvars, there is no point in actually
+     * waking up the threads waiting on the cvars until we've
+     * released the lock.  So, we temporarily record the cvars.
+     * When doing an unlock, we'll then wake up the waiting threads.
+     */
+    struct _MDNotified notified;     /* array of conditions notified */
+#ifdef PROFILE_LOCKS
+    PRInt32 hitcount;
+    PRInt32 misscount;
+#endif
+};
+
+struct _MDSemaphore {
+    HANDLE           sem;
+};
+
+struct _MDFileDesc {
+    PROsfd osfd;     /* The osfd can come from one of three spaces:
+                      * - For stdin, stdout, and stderr, we are using
+                      *   the libc file handle (0, 1, 2), which is an int.
+                      * - For files and pipes, we are using Win32 HANDLE,
+                      *   which is a void*.
+                      * - For sockets, we are using Winsock SOCKET, which
+                      *   is a u_int.
+                      */
+};
+
+struct _MDProcess {
+    HANDLE handle;
+    DWORD id;
+};
+
+/* --- Misc stuff --- */
+#define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
+
+/* --- NT security stuff --- */
+
+extern void _PR_NT_InitSids(void);
+extern void _PR_NT_FreeSids(void);
+extern PRStatus _PR_NT_MakeSecurityDescriptorACL(
+    PRIntn mode,
+    DWORD accessTable[],
+    PSECURITY_DESCRIPTOR *resultSD,
+    PACL *resultACL
+);
+extern void _PR_NT_FreeSecurityDescriptorACL(
+    PSECURITY_DESCRIPTOR pSD, PACL pACL);
+
+/* --- IO stuff --- */
+
+#define _MD_OPEN                      _PR_MD_OPEN
+#define _MD_OPEN_FILE                 _PR_MD_OPEN_FILE
+#define _MD_READ                      _PR_MD_READ
+#define _MD_WRITE                     _PR_MD_WRITE
+#define _MD_WRITEV                    _PR_MD_WRITEV
+#define _MD_LSEEK                     _PR_MD_LSEEK
+#define _MD_LSEEK64                   _PR_MD_LSEEK64
+extern PRInt32 _MD_CloseFile(PROsfd osfd);
+#define _MD_CLOSE_FILE                _MD_CloseFile
+#define _MD_GETFILEINFO               _PR_MD_GETFILEINFO
+#define _MD_GETFILEINFO64             _PR_MD_GETFILEINFO64
+#define _MD_GETOPENFILEINFO           _PR_MD_GETOPENFILEINFO
+#define _MD_GETOPENFILEINFO64         _PR_MD_GETOPENFILEINFO64
+#define _MD_STAT                      _PR_MD_STAT
+#define _MD_RENAME                    _PR_MD_RENAME     
+#define _MD_ACCESS                    _PR_MD_ACCESS     
+#define _MD_DELETE                    _PR_MD_DELETE     
+#define _MD_MKDIR                     _PR_MD_MKDIR      
+#define _MD_MAKE_DIR                  _PR_MD_MAKE_DIR
+#define _MD_RMDIR                     _PR_MD_RMDIR      
+#define _MD_LOCKFILE                  _PR_MD_LOCKFILE
+#define _MD_TLOCKFILE                 _PR_MD_TLOCKFILE
+#define _MD_UNLOCKFILE                _PR_MD_UNLOCKFILE
+
+#ifdef MOZ_UNICODE
+/* --- UTF16 IO stuff --- */
+#define _MD_OPEN_FILE_UTF16           _PR_MD_OPEN_FILE_UTF16
+#define _MD_OPEN_DIR_UTF16            _PR_MD_OPEN_DIR_UTF16
+#define _MD_READ_DIR_UTF16            _PR_MD_READ_DIR_UTF16
+#define _MD_CLOSE_DIR_UTF16           _PR_MD_CLOSE_DIR_UTF16
+#define _MD_GETFILEINFO64_UTF16       _PR_MD_GETFILEINFO64_UTF16
+#endif /* MOZ_UNICODE */
+
+/* --- Socket IO stuff --- */
+#define _MD_EACCES                WSAEACCES
+#define _MD_EADDRINUSE            WSAEADDRINUSE
+#define _MD_EADDRNOTAVAIL         WSAEADDRNOTAVAIL
+#define _MD_EAFNOSUPPORT          WSAEAFNOSUPPORT
+#define _MD_EAGAIN                WSAEWOULDBLOCK
+#define _MD_EALREADY              WSAEALREADY
+#define _MD_EBADF                 WSAEBADF
+#define _MD_ECONNREFUSED          WSAECONNREFUSED
+#define _MD_ECONNRESET            WSAECONNRESET
+#define _MD_EFAULT                WSAEFAULT
+#define _MD_EINPROGRESS           WSAEINPROGRESS
+#define _MD_EINTR                 WSAEINTR
+#define _MD_EINVAL                EINVAL
+#define _MD_EISCONN               WSAEISCONN
+#define _MD_ENETUNREACH           WSAENETUNREACH
+#define _MD_ENOENT                ENOENT
+#define _MD_ENOTCONN              WSAENOTCONN
+#define _MD_ENOTSOCK              WSAENOTSOCK
+#define _MD_EOPNOTSUPP            WSAEOPNOTSUPP
+#define _MD_EWOULDBLOCK           WSAEWOULDBLOCK
+#define _MD_GET_SOCKET_ERROR()    WSAGetLastError()
+#define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err)
+
+#define _MD_INIT_FILEDESC(fd)
+extern void _MD_MakeNonblock(PRFileDesc *f);
+#define _MD_MAKE_NONBLOCK             _MD_MakeNonblock
+#define _MD_INIT_FD_INHERITABLE       _PR_MD_INIT_FD_INHERITABLE
+#define _MD_QUERY_FD_INHERITABLE      _PR_MD_QUERY_FD_INHERITABLE
+#define _MD_SHUTDOWN                  _PR_MD_SHUTDOWN
+#define _MD_LISTEN                    _PR_MD_LISTEN
+extern PRInt32 _MD_CloseSocket(PROsfd osfd);
+#define _MD_CLOSE_SOCKET              _MD_CloseSocket
+#define _MD_SENDTO                    _PR_MD_SENDTO
+#define _MD_RECVFROM                  _PR_MD_RECVFROM
+#define _MD_SOCKETPAIR(s, type, proto, sv) -1
+#define _MD_GETSOCKNAME               _PR_MD_GETSOCKNAME
+#define _MD_GETPEERNAME               _PR_MD_GETPEERNAME
+#define _MD_GETSOCKOPT                _PR_MD_GETSOCKOPT
+#define _MD_SETSOCKOPT                _PR_MD_SETSOCKOPT
+#define _MD_SET_FD_INHERITABLE        _PR_MD_SET_FD_INHERITABLE
+#define _MD_SELECT                    select
+#define _MD_FSYNC                     _PR_MD_FSYNC
+#define READ_FD                       1
+#define WRITE_FD                      2
+
+#define _MD_INIT_ATOMIC()
+#if defined(_M_IX86) || defined(_X86_)
+#define _MD_ATOMIC_INCREMENT          _PR_MD_ATOMIC_INCREMENT
+#define _MD_ATOMIC_ADD          	  _PR_MD_ATOMIC_ADD
+#define _MD_ATOMIC_DECREMENT          _PR_MD_ATOMIC_DECREMENT
+#else /* non-x86 processors */
+#define _MD_ATOMIC_INCREMENT(x)       InterlockedIncrement((PLONG)x)
+#define _MD_ATOMIC_ADD(ptr,val)    (InterlockedExchangeAdd((PLONG)ptr, (LONG)val) + val)
+#define _MD_ATOMIC_DECREMENT(x)       InterlockedDecrement((PLONG)x)
+#endif /* x86 */
+#define _MD_ATOMIC_SET(x,y)           InterlockedExchange((PLONG)x, (LONG)y)
+
+#define _MD_INIT_IO                   _PR_MD_INIT_IO
+
+
+/* win95 doesn't have async IO */
+#define _MD_SOCKET                    _PR_MD_SOCKET
+extern PRInt32 _MD_SocketAvailable(PRFileDesc *fd);
+#define _MD_SOCKETAVAILABLE           _MD_SocketAvailable
+#define _MD_PIPEAVAILABLE             _PR_MD_PIPEAVAILABLE
+#define _MD_CONNECT                   _PR_MD_CONNECT
+extern PROsfd _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
+        PRIntervalTime timeout);
+#define _MD_ACCEPT                    _MD_Accept
+#define _MD_BIND                      _PR_MD_BIND
+#define _MD_RECV                      _PR_MD_RECV
+#define _MD_SEND                      _PR_MD_SEND
+#define _MD_PR_POLL                   _PR_MD_PR_POLL
+
+/* --- Scheduler stuff --- */
+// #define _MD_PAUSE_CPU                 _PR_MD_PAUSE_CPU
+#define _MD_PAUSE_CPU
+
+/* --- DIR stuff --- */
+#define PR_DIRECTORY_SEPARATOR        '\\'
+#define PR_DIRECTORY_SEPARATOR_STR    "\\"
+#define PR_PATH_SEPARATOR		';'
+#define PR_PATH_SEPARATOR_STR		";"
+#define _MD_ERRNO()                   GetLastError()
+#define _MD_OPEN_DIR                  _PR_MD_OPEN_DIR
+#define _MD_CLOSE_DIR                 _PR_MD_CLOSE_DIR
+#define _MD_READ_DIR                  _PR_MD_READ_DIR
+
+/* --- Segment stuff --- */
+#define _MD_INIT_SEGS()
+#define _MD_ALLOC_SEGMENT(seg, size, vaddr)   0
+#define _MD_FREE_SEGMENT(seg)
+
+/* --- Environment Stuff --- */
+#define _MD_GET_ENV                 _PR_MD_GET_ENV
+#define _MD_PUT_ENV                 _PR_MD_PUT_ENV
+
+/* --- Threading Stuff --- */
+#define _MD_DEFAULT_STACK_SIZE            0
+#define _MD_INIT_THREAD             _PR_MD_INIT_THREAD
+#define _MD_INIT_ATTACHED_THREAD    _PR_MD_INIT_THREAD
+#define _MD_CREATE_THREAD           _PR_MD_CREATE_THREAD
+#define _MD_YIELD                   _PR_MD_YIELD
+#define _MD_SET_PRIORITY            _PR_MD_SET_PRIORITY
+#define _MD_CLEAN_THREAD            _PR_MD_CLEAN_THREAD
+#define _MD_SETTHREADAFFINITYMASK   _PR_MD_SETTHREADAFFINITYMASK
+#define _MD_GETTHREADAFFINITYMASK   _PR_MD_GETTHREADAFFINITYMASK
+#define _MD_EXIT_THREAD             _PR_MD_EXIT_THREAD
+#define _MD_EXIT                    _PR_MD_EXIT
+#define _MD_SUSPEND_THREAD          _PR_MD_SUSPEND_THREAD
+#define _MD_RESUME_THREAD           _PR_MD_RESUME_THREAD
+#define _MD_SUSPEND_CPU             _PR_MD_SUSPEND_CPU
+#define _MD_RESUME_CPU              _PR_MD_RESUME_CPU
+#define _MD_BEGIN_SUSPEND_ALL()
+#define _MD_BEGIN_RESUME_ALL()
+#define _MD_END_SUSPEND_ALL()
+#define _MD_END_RESUME_ALL()
+
+/* --- Lock stuff --- */
+#define _PR_LOCK                      _MD_LOCK
+#define _PR_UNLOCK					  _MD_UNLOCK
+
+#define _MD_NEW_LOCK(lock)            (InitializeCriticalSection(&((lock)->mutex)),(lock)->notified.length=0,(lock)->notified.link=NULL,PR_SUCCESS)
+#define _MD_FREE_LOCK(lock)           DeleteCriticalSection(&((lock)->mutex))
+#define _MD_LOCK(lock)                EnterCriticalSection(&((lock)->mutex))
+#define _MD_TEST_AND_LOCK(lock)       (EnterCriticalSection(&((lock)->mutex)),0)
+#define _MD_UNLOCK                    _PR_MD_UNLOCK
+
+/* --- lock and cv waiting --- */
+#define _MD_WAIT                      _PR_MD_WAIT
+#define _MD_WAKEUP_WAITER             _PR_MD_WAKEUP_WAITER
+
+/* --- CVar ------------------- */
+#define _MD_WAIT_CV					  _PR_MD_WAIT_CV
+#define _MD_NEW_CV					  _PR_MD_NEW_CV
+#define _MD_FREE_CV					  _PR_MD_FREE_CV
+#define _MD_NOTIFY_CV				  _PR_MD_NOTIFY_CV	
+#define _MD_NOTIFYALL_CV			  _PR_MD_NOTIFYALL_CV
+
+   /* XXXMB- the IOQ stuff is certainly not working correctly yet. */
+// extern  struct _MDLock              _pr_ioq_lock;
+#define _MD_IOQ_LOCK()                
+#define _MD_IOQ_UNLOCK()              
+
+
+/* --- Initialization stuff --- */
+#define _MD_START_INTERRUPTS()
+#define _MD_STOP_INTERRUPTS()
+#define _MD_DISABLE_CLOCK_INTERRUPTS()
+#define _MD_ENABLE_CLOCK_INTERRUPTS()
+#define _MD_BLOCK_CLOCK_INTERRUPTS()
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS()
+#define _MD_EARLY_INIT                _PR_MD_EARLY_INIT
+#define _MD_FINAL_INIT()
+#define _MD_INIT_CPUS()
+#define _MD_INIT_RUNNING_CPU(cpu)
+
+struct PRProcess;
+struct PRProcessAttr;
+
+#define _MD_CREATE_PROCESS _PR_CreateWindowsProcess
+extern struct PRProcess * _PR_CreateWindowsProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const struct PRProcessAttr *attr
+);
+
+#define _MD_DETACH_PROCESS _PR_DetachWindowsProcess
+extern PRStatus _PR_DetachWindowsProcess(struct PRProcess *process);
+
+/* --- Wait for a child process to terminate --- */
+#define _MD_WAIT_PROCESS _PR_WaitWindowsProcess
+extern PRStatus _PR_WaitWindowsProcess(struct PRProcess *process, 
+    PRInt32 *exitCode);
+
+#define _MD_KILL_PROCESS _PR_KillWindowsProcess
+extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process);
+
+#define _MD_CLEANUP_BEFORE_EXIT           _PR_MD_CLEANUP_BEFORE_EXIT
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
+    PR_BEGIN_MACRO \
+    *status = PR_TRUE; \
+    PR_END_MACRO
+#define _MD_SWITCH_CONTEXT
+#define _MD_RESTORE_CONTEXT
+
+/* --- Intervals --- */
+#define _MD_INTERVAL_INIT                 _PR_MD_INTERVAL_INIT
+#define _MD_GET_INTERVAL                  _PR_MD_GET_INTERVAL
+#define _MD_INTERVAL_PER_SEC              _PR_MD_INTERVAL_PER_SEC
+#define _MD_INTERVAL_PER_MILLISEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000)
+#define _MD_INTERVAL_PER_MICROSEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000000)
+
+/* --- Time --- */
+extern void _PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm);
+
+/* --- Native-Thread Specific Definitions ------------------------------- */
+
+extern struct PRThread * _MD_CURRENT_THREAD(void);
+
+#ifdef _PR_USE_STATIC_TLS
+extern __declspec(thread) struct PRThread *_pr_currentThread;
+#define _MD_GET_ATTACHED_THREAD() _pr_currentThread
+#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread))
+
+extern __declspec(thread) struct PRThread *_pr_thread_last_run;
+#define _MD_LAST_THREAD() _pr_thread_last_run
+#define _MD_SET_LAST_THREAD(_thread) (_pr_thread_last_run = 0)
+
+extern __declspec(thread) struct _PRCPU *_pr_currentCPU;
+#define _MD_CURRENT_CPU() _pr_currentCPU
+#define _MD_SET_CURRENT_CPU(_cpu) (_pr_currentCPU = 0)
+#else /* _PR_USE_STATIC_TLS */
+extern DWORD _pr_currentThreadIndex;
+#define _MD_GET_ATTACHED_THREAD() ((PRThread *) TlsGetValue(_pr_currentThreadIndex))
+#define _MD_SET_CURRENT_THREAD(_thread) TlsSetValue(_pr_currentThreadIndex, (_thread))
+
+extern DWORD _pr_lastThreadIndex;
+#define _MD_LAST_THREAD() ((PRThread *) TlsGetValue(_pr_lastThreadIndex))
+#define _MD_SET_LAST_THREAD(_thread) TlsSetValue(_pr_lastThreadIndex, 0)
+
+extern DWORD _pr_currentCPUIndex;
+#define _MD_CURRENT_CPU() ((struct _PRCPU *) TlsGetValue(_pr_currentCPUIndex))
+#define _MD_SET_CURRENT_CPU(_cpu) TlsSetValue(_pr_currentCPUIndex, 0)
+#endif /* _PR_USE_STATIC_TLS */
+
+/* --- Scheduler stuff --- */
+#define LOCK_SCHEDULER()                 0
+#define UNLOCK_SCHEDULER()               0
+#define _PR_LockSched()                	 0
+#define _PR_UnlockSched()                0
+
+/* --- Initialization stuff --- */
+#define _MD_INIT_LOCKS()
+
+/* --- Stack stuff --- */
+#define _MD_INIT_STACK(stack, redzone)
+#define _MD_CLEAR_STACK(stack)
+
+/* --- Memory-mapped files stuff --- */
+
+struct _MDFileMap {
+    HANDLE hFileMap;
+    DWORD dwAccess;
+};
+
+extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
+#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
+
+extern PRInt32 _MD_GetMemMapAlignment(void);
+#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment
+
+extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
+        PRUint32 len);
+#define _MD_MEM_MAP _MD_MemMap
+
+extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
+#define _MD_MEM_UNMAP _MD_MemUnmap
+
+extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
+#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
+
+/* --- Named semaphores stuff --- */
+#define _PR_HAVE_NAMED_SEMAPHORES
+#define _MD_OPEN_SEMAPHORE            _PR_MD_OPEN_SEMAPHORE
+#define _MD_WAIT_SEMAPHORE            _PR_MD_WAIT_SEMAPHORE
+#define _MD_POST_SEMAPHORE            _PR_MD_POST_SEMAPHORE
+#define _MD_CLOSE_SEMAPHORE           _PR_MD_CLOSE_SEMAPHORE
+#define _MD_DELETE_SEMAPHORE(name)    PR_SUCCESS  /* no op */
+
+#endif /* nspr_win32_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_winnt.cfg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_winnt.cfg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,298 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_PC
+#define XP_PC
+#endif
+
+#ifndef WIN32
+#define WIN32
+#endif
+
+#ifndef WINNT
+#define WINNT
+#endif
+
+#define PR_AF_INET6 23  /* same as AF_INET6 */
+
+#if defined(_M_IX86) || defined(_X86_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD	4
+#define PR_BYTES_PER_DWORD	8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD	32
+#define PR_BITS_PER_DWORD	64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	5
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD	4
+#define PR_ALIGN_OF_DWORD	8
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#define PR_BYTES_PER_WORD_LOG2	2
+#define PR_BYTES_PER_DWORD_LOG2	2
+
+#elif defined(_ALPHA_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_BYTES_PER_WORD_LOG2  2
+#define PR_BYTES_PER_DWORD_LOG2 3
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 4
+
+#elif defined(_AMD64_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD    64
+#define PR_BITS_PER_DWORD   64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	6
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD    8
+#define PR_ALIGN_OF_DWORD   8
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2	3
+#define PR_BYTES_PER_DWORD_LOG2	3
+
+#elif defined(_IA64_)
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+#define IS_64
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_WORD   8
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_DOUBLE 8
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_WORD    64
+#define PR_BITS_PER_DWORD   64
+#define PR_BITS_PER_DOUBLE  64
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_WORD_LOG2	6
+#define PR_BITS_PER_DWORD_LOG2	6
+#define PR_BITS_PER_DOUBLE_LOG2 6
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   8
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_WORD    8
+#define PR_ALIGN_OF_DWORD   8
+#define PR_ALIGN_OF_DOUBLE  8
+#define PR_ALIGN_OF_POINTER 8
+
+#define PR_BYTES_PER_WORD_LOG2	3
+#define PR_BYTES_PER_DWORD_LOG2	3
+
+#else /* defined(_M_IX86) || defined(_X86_) */
+
+#error unknown processor architecture
+
+#endif /* defined(_M_IX86) || defined(_X86_) */
+
+#define HAVE_LONG_LONG
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE      PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT     PR_BYTES_PER_SHORT
+#define BYTES_PER_INT       PR_BYTES_PER_INT
+#define BYTES_PER_INT64     PR_BYTES_PER_INT64
+#define BYTES_PER_LONG      PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT     PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE    PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD      PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD     PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE       PR_BITS_PER_BYTE
+#define BITS_PER_SHORT      PR_BITS_PER_SHORT
+#define BITS_PER_INT        PR_BITS_PER_INT
+#define BITS_PER_INT64      PR_BITS_PER_INT64
+#define BITS_PER_LONG       PR_BITS_PER_LONG
+#define BITS_PER_FLOAT      PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE     PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD       PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2  PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2 PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2   PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2 PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2  PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2 PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2    PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2  PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT      PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT        PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG       PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64      PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT      PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE     PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER    PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD       PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2		PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2    PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2    PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/_winnt.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/_winnt.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,620 @@
+/* -*- 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 nspr_win32_defs_h___
+#define nspr_win32_defs_h___
+
+/* Need to force service-pack 3 extensions to be defined by
+** setting _WIN32_WINNT to NT 4.0 for winsock.h, winbase.h, winnt.h.
+*/ 
+#ifndef  _WIN32_WINNT
+    #define _WIN32_WINNT 0x0400
+#elif   (_WIN32_WINNT < 0x0400)
+    #undef  _WIN32_WINNT
+    #define _WIN32_WINNT 0x0400
+#endif /* _WIN32_WINNT */
+
+#include <windows.h>
+#include <winsock.h>
+#ifdef __MINGW32__
+#include <mswsock.h>
+#endif
+#include <errno.h>
+
+#include "prio.h"
+#include "prclist.h"
+
+/*
+ * Internal configuration macros
+ */
+
+#define PR_LINKER_ARCH      "win32"
+#define _PR_SI_SYSNAME        "WINNT"
+#if defined(_M_IX86) || defined(_X86_)
+#define _PR_SI_ARCHITECTURE   "x86"
+#elif defined(_AMD64_)
+#define _PR_SI_ARCHITECTURE   "x86-64"
+#elif defined(_IA64_)
+#define _PR_SI_ARCHITECTURE   "ia64"
+#else
+#error unknown processor architecture
+#endif
+
+#define HAVE_DLL
+#define HAVE_CUSTOM_USER_THREADS
+#define HAVE_THREAD_AFFINITY
+#define _PR_HAVE_GETADDRINFO
+#define _PR_INET6_PROBE
+#ifndef _PR_INET6
+#define AF_INET6 23
+/* newer ws2tcpip.h provides these */
+#ifndef AI_CANONNAME
+#define AI_CANONNAME 0x2
+struct addrinfo {
+    int ai_flags;
+    int ai_family;
+    int ai_socktype;
+    int ai_protocol;
+    size_t ai_addrlen;
+    char *ai_canonname;
+    struct sockaddr *ai_addr;
+    struct addrinfo *ai_next;
+};
+#endif
+#define _PR_HAVE_MD_SOCKADDR_IN6
+/* isomorphic to struct in6_addr on Windows */
+struct _md_in6_addr {
+    union {
+        PRUint8  _S6_u8[16];
+        PRUint16 _S6_u16[8];
+    } _S6_un;
+};
+/* isomorphic to struct sockaddr_in6 on Windows */
+struct _md_sockaddr_in6 {
+    PRInt16 sin6_family;
+    PRUint16 sin6_port;
+    PRUint32 sin6_flowinfo;
+    struct _md_in6_addr sin6_addr;
+    PRUint32 sin6_scope_id;
+};
+#endif
+#define _PR_HAVE_THREADSAFE_GETHOST
+#define _PR_HAVE_ATOMIC_OPS
+#if defined(_M_IX86) || defined(_X86_)
+#define _PR_HAVE_ATOMIC_CAS
+#endif
+#define PR_HAVE_WIN32_NAMED_SHARED_MEMORY
+#define _PR_HAVE_PEEK_BUFFER
+#define _PR_PEEK_BUFFER_MAX (32 * 1024)
+#define _PR_FD_NEED_EMULATE_MSG_PEEK(fd) \
+    (!(fd)->secret->nonblocking && (fd)->secret->inheritable != _PR_TRI_TRUE)
+
+/* --- Common User-Thread/Native-Thread Definitions --------------------- */
+
+/* --- Globals --- */
+extern struct PRLock                      *_pr_schedLock;
+
+/* --- Typedefs --- */
+typedef void (*FiberFunc)(void *);
+
+#define PR_NUM_GCREGS           8
+typedef PRInt32	                PR_CONTEXT_TYPE[PR_NUM_GCREGS];
+#define GC_VMBASE               0x40000000
+#define GC_VMLIMIT              0x00FFFFFF
+
+#define _MD_MAGIC_THREAD	0x22222222
+#define _MD_MAGIC_THREADSTACK	0x33333333
+#define _MD_MAGIC_SEGMENT	0x44444444
+#define _MD_MAGIC_DIR		0x55555555
+
+struct _MDCPU {
+    int              unused;
+};
+
+enum _MDIOModel {
+    _MD_BlockingIO = 0x38,
+    _MD_MultiWaitIO = 0x49
+};
+
+typedef struct _MDOverlapped {
+    OVERLAPPED overlapped;              /* Used for async I/O */
+
+    enum _MDIOModel ioModel;            /* The I/O model to implement
+                                         * using overlapped I/O.
+                                         */
+    union {
+        struct _MDThread *mdThread;     /* For blocking I/O, this structure
+                                         * is embedded in the _MDThread
+                                         * structure.
+                                         */
+        struct {
+            PRCList links;              /* for group->io_ready list */
+            struct PRRecvWait *desc;    /* For multiwait I/O, this structure
+                                         * is associated with a PRRecvWait
+                                         * structure.
+                                         */
+            struct PRWaitGroup *group;
+            struct TimerEvent *timer;
+            DWORD error;
+        } mw;
+    } data;
+} _MDOverlapped;
+
+struct _MDThread {
+        /* The overlapped structure must be first! */
+    struct _MDOverlapped overlapped;    /* Used for async IO for this thread */
+    void            *acceptex_buf;      /* Used for AcceptEx() */
+    TRANSMIT_FILE_BUFFERS *xmit_bufs;   /* Used for TransmitFile() */
+    HANDLE           blocked_sema;      /* Threads block on this when waiting
+                                         * for IO or CondVar.
+                                         */
+    PRInt32          blocked_io_status; /* Status of the completed IO */
+    PRInt32          blocked_io_bytes;  /* Bytes transferred for completed IO */
+    PRInt32          blocked_io_error;  /* Save error if status is FALSE */
+    HANDLE           handle;
+    PRUint32         id;
+    void            *sp;                /* only valid when suspended */
+    PRUint32         magic;             /* for debugging */
+    PR_CONTEXT_TYPE  gcContext;         /* Thread context for GC */
+	struct _PRCPU    *thr_bound_cpu;		/* thread bound to cpu */
+	PRBool   		 interrupt_disabled;/* thread cannot be interrupted */
+	HANDLE 			 thr_event;			/* For native-threads-only support,
+											thread blocks on this event		*/
+
+    /* The following are used only if this is a fiber */
+    void            *fiber_id;          /* flag whether or not this is a fiber*/
+    FiberFunc        fiber_fn;          /* main fiber routine */
+    void            *fiber_arg;         /* arg to main fiber routine */
+    PRUint32         fiber_stacksize;   /* stacksize for fiber */
+    PRInt32          fiber_last_error;  /* last error for the fiber */
+    void (*start)(void *);              /* used by _PR_MD_CREATE_THREAD to
+                                         * pass its 'start' argument to
+                                         * pr_root. */
+};
+
+struct _MDThreadStack {
+    PRUint32           magic;          /* for debugging */
+};
+
+struct _MDSegment {
+    PRUint32           magic;          /* for debugging */
+};
+
+#undef PROFILE_LOCKS
+
+struct _MDLock {
+    CRITICAL_SECTION mutex;          /* this is recursive on NT */
+#ifdef PROFILE_LOCKS
+    PRInt32 hitcount;
+    PRInt32 misscount;
+#endif
+};
+
+struct _MDDir {
+    HANDLE           d_hdl;
+    WIN32_FIND_DATA  d_entry;
+    PRBool           firstEntry;     /* Is this the entry returned
+                                      * by FindFirstFile()? */
+    PRUint32         magic;          /* for debugging */
+};
+
+struct _MDCVar {
+    PRUint32         unused;
+};
+
+struct _MDSemaphore {
+    HANDLE           sem;
+};
+
+struct _MDFileDesc {
+    PROsfd osfd;     /* The osfd can come from one of three spaces:
+                      * - For stdin, stdout, and stderr, we are using
+                      *   the libc file handle (0, 1, 2), which is an int.
+                      * - For files and pipes, we are using Win32 HANDLE,
+                      *   which is a void*.
+                      * - For sockets, we are using Winsock SOCKET, which
+                      *   is a u_int.
+                      */
+    PRBool io_model_committed;  /* The io model (blocking or nonblocking)
+                                 * for this osfd has been committed and
+                                 * cannot be changed.  The osfd has been
+                                 * either associated with the io
+                                 * completion port or made nonblocking. */
+    PRBool sync_file_io;        /* Use synchronous file I/O on the osfd
+                                 * (a file handle) */
+    PRBool accepted_socket;     /* Is this an accepted socket (on the
+                                 * server side)? */
+    PRNetAddr peer_addr;        /* If this is an accepted socket, cache
+                                 * the peer's address returned by
+                                 * AcceptEx().  This is to work around
+                                 * the bug that getpeername() on an
+                                 * socket accepted by AcceptEx() returns
+                                 * an all-zero net address. */
+};
+
+struct _MDProcess {
+    HANDLE handle;
+    DWORD id;
+};
+
+
+/* --- Misc stuff --- */
+#define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
+
+/* --- NT security stuff --- */
+
+extern void _PR_NT_InitSids(void);
+extern void _PR_NT_FreeSids(void);
+extern PRStatus _PR_NT_MakeSecurityDescriptorACL(
+    PRIntn mode,
+    DWORD accessTable[],
+    PSECURITY_DESCRIPTOR *resultSD,
+    PACL *resultACL
+);
+extern void _PR_NT_FreeSecurityDescriptorACL(
+    PSECURITY_DESCRIPTOR pSD, PACL pACL);
+
+/* --- IO stuff --- */
+
+extern PRInt32 _md_Associate(HANDLE);
+extern PRInt32 _PR_MD_CLOSE(PROsfd osfd, PRBool socket);
+
+#define _MD_OPEN                      _PR_MD_OPEN
+#define _MD_OPEN_FILE                 _PR_MD_OPEN_FILE
+#define _MD_READ                      _PR_MD_READ
+#define _MD_WRITE                     _PR_MD_WRITE
+#define _MD_WRITEV                    _PR_MD_WRITEV
+#define _MD_LSEEK                     _PR_MD_LSEEK
+#define _MD_LSEEK64                   _PR_MD_LSEEK64
+#define _MD_CLOSE_FILE(f)             _PR_MD_CLOSE(f, PR_FALSE)
+#define _MD_GETFILEINFO               _PR_MD_GETFILEINFO
+#define _MD_GETFILEINFO64             _PR_MD_GETFILEINFO64
+#define _MD_GETOPENFILEINFO           _PR_MD_GETOPENFILEINFO
+#define _MD_GETOPENFILEINFO64         _PR_MD_GETOPENFILEINFO64
+#define _MD_STAT                      _PR_MD_STAT
+#define _MD_RENAME                    _PR_MD_RENAME     
+#define _MD_ACCESS                    _PR_MD_ACCESS     
+#define _MD_DELETE                    _PR_MD_DELETE     
+#define _MD_MKDIR                     _PR_MD_MKDIR      
+#define _MD_MAKE_DIR                  _PR_MD_MAKE_DIR
+#define _MD_RMDIR                     _PR_MD_RMDIR      
+#define _MD_LOCKFILE                  _PR_MD_LOCKFILE
+#define _MD_TLOCKFILE                 _PR_MD_TLOCKFILE
+#define _MD_UNLOCKFILE                _PR_MD_UNLOCKFILE
+
+/* --- Socket IO stuff --- */
+#define _MD_GET_SOCKET_ERROR()    WSAGetLastError()
+#define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err)
+
+#define _MD_INIT_FILEDESC(fd)
+#define _MD_MAKE_NONBLOCK             _PR_MD_MAKE_NONBLOCK
+#define _MD_INIT_FD_INHERITABLE       _PR_MD_INIT_FD_INHERITABLE
+#define _MD_QUERY_FD_INHERITABLE      _PR_MD_QUERY_FD_INHERITABLE
+#define _MD_SHUTDOWN                  _PR_MD_SHUTDOWN
+#define _MD_LISTEN                    _PR_MD_LISTEN
+#define _MD_CLOSE_SOCKET(s)           _PR_MD_CLOSE(s, PR_TRUE)
+#define _MD_SENDTO                    _PR_MD_SENDTO
+#define _MD_RECVFROM                  _PR_MD_RECVFROM
+#define _MD_SOCKETPAIR(s, type, proto, sv) -1
+#define _MD_GETSOCKNAME               _PR_MD_GETSOCKNAME
+#define _MD_GETPEERNAME               _PR_MD_GETPEERNAME
+#define _MD_GETSOCKOPT                _PR_MD_GETSOCKOPT
+#define _MD_SETSOCKOPT                _PR_MD_SETSOCKOPT
+#define _MD_SELECT                    select
+extern int _PR_NTFiberSafeSelect(int, fd_set *, fd_set *, fd_set *,
+    const struct timeval *);
+#define _MD_FSYNC                     _PR_MD_FSYNC
+#define _MD_SOCKETAVAILABLE           _PR_MD_SOCKETAVAILABLE
+#define _MD_PIPEAVAILABLE             _PR_MD_PIPEAVAILABLE
+#define _MD_SET_FD_INHERITABLE        _PR_MD_SET_FD_INHERITABLE
+
+#define _MD_INIT_ATOMIC()
+#if defined(_M_IX86) || defined(_X86_)
+#define _MD_ATOMIC_INCREMENT          _PR_MD_ATOMIC_INCREMENT
+#define _MD_ATOMIC_ADD          	  _PR_MD_ATOMIC_ADD
+#define _MD_ATOMIC_DECREMENT          _PR_MD_ATOMIC_DECREMENT
+#else /* non-x86 processors */
+#define _MD_ATOMIC_INCREMENT(x)       InterlockedIncrement((PLONG)x)
+#define _MD_ATOMIC_ADD(ptr,val)    (InterlockedExchangeAdd((PLONG)ptr, (LONG)val) + val)
+#define _MD_ATOMIC_DECREMENT(x)       InterlockedDecrement((PLONG)x)
+#endif /* x86 */
+#define _MD_ATOMIC_SET(x,y)           InterlockedExchange((PLONG)x, (LONG)y)
+
+#define _MD_INIT_IO                   _PR_MD_INIT_IO
+#define _MD_SOCKET                    _PR_MD_SOCKET
+#define _MD_CONNECT                   _PR_MD_CONNECT
+
+#define _MD_ACCEPT(s, a, l, to)       \
+        _MD_FAST_ACCEPT(s, a, l, to, PR_FALSE, NULL, NULL)
+#define _MD_FAST_ACCEPT(s, a, l, to, fast, cb, cba) \
+        _PR_MD_FAST_ACCEPT(s, a, l, to, fast, cb, cba)
+#define _MD_ACCEPT_READ(s, ns, ra, buf, l, t) \
+        _MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, PR_FALSE, NULL, NULL)
+#define _MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, fast, cb, cba) \
+        _PR_MD_FAST_ACCEPT_READ(s, ns, ra, buf, l, t, fast, cb, cba)
+#define _MD_UPDATE_ACCEPT_CONTEXT     _PR_MD_UPDATE_ACCEPT_CONTEXT
+
+#define _MD_BIND                      _PR_MD_BIND
+#define _MD_RECV                      _PR_MD_RECV
+#define _MD_SEND                      _PR_MD_SEND
+#define _MD_SENDFILE              	  _PR_MD_SENDFILE
+#define _MD_PR_POLL                   _PR_MD_PR_POLL
+
+/* --- Scheduler stuff --- */
+#define _MD_PAUSE_CPU                   _PR_MD_PAUSE_CPU
+
+/* --- DIR stuff --- */
+#define PR_DIRECTORY_SEPARATOR        '\\'
+#define PR_DIRECTORY_SEPARATOR_STR    "\\"
+#define PR_PATH_SEPARATOR		';'
+#define PR_PATH_SEPARATOR_STR		";"
+#define _MD_ERRNO()                   GetLastError()
+#define _MD_OPEN_DIR                  _PR_MD_OPEN_DIR
+#define _MD_CLOSE_DIR                 _PR_MD_CLOSE_DIR
+#define _MD_READ_DIR                  _PR_MD_READ_DIR
+
+/* --- Segment stuff --- */
+#define _MD_INIT_SEGS()
+#define _MD_ALLOC_SEGMENT(seg, size, vaddr)   0
+#define _MD_FREE_SEGMENT(seg)
+
+/* --- Environment Stuff --- */
+#define _MD_GET_ENV                 _PR_MD_GET_ENV
+#define _MD_PUT_ENV                 _PR_MD_PUT_ENV
+
+/* --- Threading Stuff --- */
+#define _MD_DEFAULT_STACK_SIZE            0
+#define _MD_INIT_THREAD             _PR_MD_INIT_THREAD
+#define _MD_INIT_ATTACHED_THREAD    _PR_MD_INIT_THREAD
+#define _MD_CREATE_THREAD           _PR_MD_CREATE_THREAD
+#define _MD_JOIN_THREAD             _PR_MD_JOIN_THREAD
+#define _MD_END_THREAD              _PR_MD_END_THREAD
+#define _MD_YIELD                   _PR_MD_YIELD
+#define _MD_SET_PRIORITY            _PR_MD_SET_PRIORITY
+#define _MD_CLEAN_THREAD            _PR_MD_CLEAN_THREAD
+#define _MD_SETTHREADAFFINITYMASK   _PR_MD_SETTHREADAFFINITYMASK
+#define _MD_GETTHREADAFFINITYMASK   _PR_MD_GETTHREADAFFINITYMASK
+#define _MD_EXIT_THREAD             _PR_MD_EXIT_THREAD
+#define _MD_SUSPEND_THREAD          _PR_MD_SUSPEND_THREAD
+#define _MD_RESUME_THREAD           _PR_MD_RESUME_THREAD
+#define _MD_SUSPEND_CPU             _PR_MD_SUSPEND_CPU
+#define _MD_RESUME_CPU              _PR_MD_RESUME_CPU
+#define _MD_BEGIN_SUSPEND_ALL()
+#define _MD_BEGIN_RESUME_ALL()
+#define _MD_END_SUSPEND_ALL()
+#define _MD_END_RESUME_ALL()
+
+extern void _PR_Unblock_IO_Wait(PRThread *thr);
+
+/* --- Lock stuff --- */
+#define _MD_NEW_LOCK(lock)            (InitializeCriticalSection(&((lock)->mutex)),PR_SUCCESS)
+#define _MD_FREE_LOCK(lock)           DeleteCriticalSection(&((lock)->mutex))
+#ifndef PROFILE_LOCKS
+#define _MD_LOCK(lock)                EnterCriticalSection(&((lock)->mutex))
+#define _MD_TEST_AND_LOCK(lock)       (TryEnterCriticalSection(&((lock)->mutex))== FALSE)
+#define _MD_UNLOCK(lock)              LeaveCriticalSection(&((lock)->mutex))
+#else
+#define _MD_LOCK(lock)                 \
+    PR_BEGIN_MACRO \
+    BOOL rv = TryEnterCriticalSection(&((lock)->mutex)); \
+    if (rv == TRUE) { \
+        InterlockedIncrement(&((lock)->hitcount)); \
+    } else { \
+        InterlockedIncrement(&((lock)->misscount)); \
+        EnterCriticalSection(&((lock)->mutex)); \
+    } \
+    PR_END_MACRO
+#define _MD_TEST_AND_LOCK(lock)       0  /* XXXMB */
+#define _MD_UNLOCK(lock)              LeaveCriticalSection(&((lock)->mutex))
+#endif
+#define _PR_LOCK                      _MD_LOCK
+#define _PR_UNLOCK					  _MD_UNLOCK
+
+/* --- lock and cv waiting --- */
+#define _MD_WAIT                      _PR_MD_WAIT
+#define _MD_WAKEUP_WAITER             _PR_MD_WAKEUP_WAITER
+
+   /* XXXMB- the IOQ stuff is certainly not working correctly yet. */
+extern  struct _MDLock              _pr_ioq_lock;
+#define _MD_IOQ_LOCK()                _MD_LOCK(&_pr_ioq_lock)
+#define _MD_IOQ_UNLOCK()              _MD_UNLOCK(&_pr_ioq_lock)
+
+
+/* --- Initialization stuff --- */
+#define _MD_START_INTERRUPTS()
+#define _MD_STOP_INTERRUPTS()
+#define _MD_DISABLE_CLOCK_INTERRUPTS()
+#define _MD_ENABLE_CLOCK_INTERRUPTS()
+#define _MD_BLOCK_CLOCK_INTERRUPTS()
+#define _MD_UNBLOCK_CLOCK_INTERRUPTS()
+#define _MD_EARLY_INIT                _PR_MD_EARLY_INIT
+#define _MD_FINAL_INIT()
+#define _MD_INIT_CPUS()
+#define _MD_INIT_RUNNING_CPU(cpu)
+
+struct PRProcess;
+struct PRProcessAttr;
+
+/* --- Create a new process --- */
+#define _MD_CREATE_PROCESS _PR_CreateWindowsProcess
+extern struct PRProcess * _PR_CreateWindowsProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const struct PRProcessAttr *attr
+);
+
+#define _MD_DETACH_PROCESS _PR_DetachWindowsProcess
+extern PRStatus _PR_DetachWindowsProcess(struct PRProcess *process);
+
+/* --- Wait for a child process to terminate --- */
+#define _MD_WAIT_PROCESS _PR_WaitWindowsProcess
+extern PRStatus _PR_WaitWindowsProcess(struct PRProcess *process, 
+    PRInt32 *exitCode);
+
+#define _MD_KILL_PROCESS _PR_KillWindowsProcess
+extern PRStatus _PR_KillWindowsProcess(struct PRProcess *process);
+
+/* --- User Threading stuff --- */
+#define HAVE_FIBERS
+#define _MD_CREATE_USER_THREAD            _PR_MD_CREATE_USER_THREAD
+#define _MD_CREATE_PRIMORDIAL_USER_THREAD _PR_MD_CREATE_PRIMORDIAL_USER_THREAD
+#define _MD_CLEANUP_BEFORE_EXIT           _PR_MD_CLEANUP_BEFORE_EXIT
+#define _MD_EXIT                          _PR_MD_EXIT
+#define _MD_INIT_CONTEXT                  _PR_MD_INIT_CONTEXT
+#define _MD_SWITCH_CONTEXT                _PR_MD_SWITCH_CONTEXT
+#define _MD_RESTORE_CONTEXT               _PR_MD_RESTORE_CONTEXT
+
+/* --- Intervals --- */
+#define _MD_INTERVAL_INIT                 _PR_MD_INTERVAL_INIT
+#define _MD_GET_INTERVAL                  _PR_MD_GET_INTERVAL
+#define _MD_INTERVAL_PER_SEC              _PR_MD_INTERVAL_PER_SEC
+#define _MD_INTERVAL_PER_MILLISEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000)
+#define _MD_INTERVAL_PER_MICROSEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000000)
+
+/* --- Time --- */
+extern void _PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm);
+
+/* --- Native-Thread Specific Definitions ------------------------------- */
+
+extern BOOL _pr_use_static_tls;
+
+extern __declspec(thread) struct PRThread *_pr_current_fiber;
+extern DWORD _pr_currentFiberIndex;
+
+#define _MD_GET_ATTACHED_THREAD() \
+    (_pr_use_static_tls ? _pr_current_fiber \
+    : (PRThread *) TlsGetValue(_pr_currentFiberIndex))
+
+extern struct PRThread * _MD_CURRENT_THREAD(void);
+
+#define _MD_SET_CURRENT_THREAD(_thread) \
+    PR_BEGIN_MACRO \
+        if (_pr_use_static_tls) { \
+            _pr_current_fiber = (_thread); \
+        } else { \
+            TlsSetValue(_pr_currentFiberIndex, (_thread)); \
+        } \
+    PR_END_MACRO
+
+extern __declspec(thread) struct PRThread *_pr_fiber_last_run;
+extern DWORD _pr_lastFiberIndex;
+
+#define _MD_LAST_THREAD() \
+    (_pr_use_static_tls ? _pr_fiber_last_run \
+    : (PRThread *) TlsGetValue(_pr_lastFiberIndex))
+
+#define _MD_SET_LAST_THREAD(_thread) \
+    PR_BEGIN_MACRO \
+        if (_pr_use_static_tls) { \
+            _pr_fiber_last_run = (_thread); \
+        } else { \
+            TlsSetValue(_pr_lastFiberIndex, (_thread)); \
+        } \
+    PR_END_MACRO
+
+extern __declspec(thread) struct _PRCPU *_pr_current_cpu;
+extern DWORD _pr_currentCPUIndex;
+
+#define _MD_CURRENT_CPU() \
+    (_pr_use_static_tls ? _pr_current_cpu \
+    : (struct _PRCPU *) TlsGetValue(_pr_currentCPUIndex))
+
+#define _MD_SET_CURRENT_CPU(_cpu) \
+    PR_BEGIN_MACRO \
+        if (_pr_use_static_tls) { \
+            _pr_current_cpu = (_cpu); \
+        } else { \
+            TlsSetValue(_pr_currentCPUIndex, (_cpu)); \
+        } \
+    PR_END_MACRO
+
+extern __declspec(thread) PRUintn _pr_ints_off;
+extern DWORD _pr_intsOffIndex;
+
+#define _MD_GET_INTSOFF() \
+    (_pr_use_static_tls ? _pr_ints_off \
+    : (PRUintn) TlsGetValue(_pr_intsOffIndex))
+
+#define _MD_SET_INTSOFF(_val) \
+    PR_BEGIN_MACRO \
+        if (_pr_use_static_tls) { \
+            _pr_ints_off = (_val); \
+        } else { \
+            TlsSetValue(_pr_intsOffIndex, (LPVOID) (_val)); \
+        } \
+    PR_END_MACRO
+
+/* --- Initialization stuff --- */
+#define _MD_INIT_LOCKS()
+
+/* --- Stack stuff --- */
+#define _MD_INIT_STACK(stack, redzone)
+#define _MD_CLEAR_STACK(stack)
+
+/* --- Memory-mapped files stuff --- */
+
+struct _MDFileMap {
+    HANDLE hFileMap;
+    DWORD dwAccess;
+};
+
+extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
+#define _MD_CREATE_FILE_MAP _MD_CreateFileMap
+
+extern PRInt32 _MD_GetMemMapAlignment(void);
+#define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment
+
+extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
+        PRUint32 len);
+#define _MD_MEM_MAP _MD_MemMap
+
+extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
+#define _MD_MEM_UNMAP _MD_MemUnmap
+
+extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
+#define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
+
+/* --- Named semaphores stuff --- */
+#define _PR_HAVE_NAMED_SEMAPHORES
+#define _MD_OPEN_SEMAPHORE            _PR_MD_OPEN_SEMAPHORE
+#define _MD_WAIT_SEMAPHORE            _PR_MD_WAIT_SEMAPHORE
+#define _MD_POST_SEMAPHORE            _PR_MD_POST_SEMAPHORE
+#define _MD_CLOSE_SEMAPHORE           _PR_MD_CLOSE_SEMAPHORE
+#define _MD_DELETE_SEMAPHORE(name)    PR_SUCCESS  /* no op */
+
+#endif /* nspr_win32_defs_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/prosdep.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/prosdep.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,169 @@
+/* -*- 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 prosdep_h___
+#define prosdep_h___
+
+/*
+** Get OS specific header information
+*/
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+#ifdef XP_PC
+
+#include "md/_pcos.h"
+#ifdef WINNT
+#include "md/_winnt.h"
+#include "md/_win32_errors.h"
+#elif defined(WIN95)
+#include "md/_win95.h"
+#include "md/_win32_errors.h"
+#elif defined(WIN16)
+#include "md/_win16.h"
+#elif defined(OS2)
+#include "md/_os2.h"
+#include "md/_os2_errors.h"
+#else
+#error unknown Windows platform
+#endif
+
+#elif defined XP_MAC
+
+#include "_macos.h"
+
+#elif defined(XP_UNIX)
+
+#if defined(AIX)
+#include "md/_aix.h"
+
+#elif defined(FREEBSD)
+#include "md/_freebsd.h"
+
+#elif defined(NETBSD)
+#include "md/_netbsd.h"
+
+#elif defined(OPENBSD)
+#include "md/_openbsd.h"
+
+#elif defined(BSDI)
+#include "md/_bsdi.h"
+
+#elif defined(HPUX)
+#include "md/_hpux.h"
+
+#elif defined(IRIX)
+#include "md/_irix.h"
+
+#elif defined(LINUX) || defined(__GNU__) || defined(__GLIBC__)
+#include "md/_linux.h"
+
+#elif defined(OSF1)
+#include "md/_osf1.h"
+
+#elif defined(DARWIN)
+#include "md/_darwin.h"
+
+#elif defined(NEXTSTEP)
+#include "md/_nextstep.h"
+
+#elif defined(SOLARIS)
+#include "md/_solaris.h"
+
+#elif defined(SUNOS4)
+#include "md/_sunos4.h"
+
+#elif defined(SNI)
+#include "md/_reliantunix.h"
+
+#elif defined(SONY)
+#include "md/_sony.h"
+
+#elif defined(NEC)
+#include "md/_nec.h"
+
+#elif defined(SCO)
+#include "md/_scoos.h"
+
+#elif defined(UNIXWARE)
+#include "md/_unixware.h"
+
+#elif defined(NCR)
+#include "md/_ncr.h"
+
+#elif defined(DGUX)
+#include "md/_dgux.h"
+
+#elif defined(QNX)
+#include "md/_qnx.h"
+
+#elif defined(VMS)
+#include "md/_openvms.h"
+
+#elif defined(NTO)
+#include "md/_nto.h"
+
+#elif defined(RISCOS)
+#include "md/_riscos.h"
+
+#else
+#error unknown Unix flavor
+
+#endif
+
+#include "md/_unixos.h"
+#include "md/_unix_errors.h"
+
+#elif defined(XP_BEOS)
+
+#include "md/_beos.h"
+#include "md/_unix_errors.h"
+
+#else
+
+#error "The platform is not BeOS, Unix, Windows, or Mac"
+
+#endif
+
+#ifdef _PR_PTHREADS
+#include "md/_pth.h"
+#endif
+
+PR_END_EXTERN_C
+
+#endif /* prosdep_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/md/sunos4.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/md/sunos4.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,164 @@
+/* -*- 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 pr_sunos4_h___
+#define pr_sunos4_h___
+
+#ifndef SVR4
+
+/*
+** Hodge podge of random missing prototypes for the Sunos4 system
+*/
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+#include <limits.h>
+#include <sys/types.h>
+
+#define PATH_MAX _POSIX_PATH_MAX
+
+struct timeval;
+struct timezone;
+struct itimerval;
+struct sockaddr;
+struct stat;
+struct tm;
+
+/* ctype.h */
+extern int tolower(int);
+extern int toupper(int);
+
+/* errno.h */
+extern char *sys_errlist[];
+extern int sys_nerr;
+
+#define strerror(e) sys_errlist[((unsigned)(e) < sys_nerr) ? e : 0]
+
+extern void perror(const char *);
+
+/* getopt */
+extern char *optarg;
+extern int optind;
+extern int getopt(int argc, char **argv, char *spec);
+
+/* math.h */
+extern int srandom(long val);
+extern long random(void);
+
+/* memory.h */
+#define memmove(to,from,len) bcopy((char*)(from),(char*)(to),len)
+
+extern void bcopy(const char *, char *, int);
+
+/* signal.h */
+/*
+** SunOS4 sigaction hides interrupts by default, so we can safely define
+** SA_RESTART to 0.
+*/
+#define SA_RESTART 0
+
+/* stdio.h */
+extern int printf(const char *, ...);
+extern int fprintf(FILE *, const char *, ...);
+extern int vprintf(const char *, va_list);
+extern int vfprintf(FILE *, const char *, va_list);
+extern char *vsprintf(char *, const char *, va_list);
+extern int scanf(const char *, ...);
+extern int sscanf(const char *, const char *, ...);
+extern int fscanf(FILE *, const char *, ...);
+extern int fgetc(FILE *);
+extern int fputc(int, FILE *);
+extern int fputs(const char *, FILE *);
+extern int puts(const char *);
+extern int fread(void *, size_t, size_t, FILE *);
+extern int fwrite(const char *, int, int, FILE *);
+extern int fseek(FILE *, long, int);
+extern long ftell(FILE *);
+extern int rewind(FILE *);
+extern int fflush(FILE *);
+extern int _flsbuf(unsigned char, FILE *);
+extern int fclose(FILE *);
+extern int remove(const char *);
+extern int setvbuf(FILE *, char *, int, size_t);
+extern int system(const char *);
+extern FILE *popen(const char *, const char *);
+extern int pclose(FILE *);
+
+/* stdlib.h */
+#define strtoul strtol
+
+extern int isatty(int fildes);
+extern long strtol(const char *, char **, int);
+extern int putenv(const char *);
+extern void srand48(long);
+extern long lrand48(void);
+extern double drand48(void);
+
+/* string.h */
+extern int strcasecmp(const char *, const char *);
+extern int strncasecmp(const char *, const char *, size_t);
+extern int strcoll(const char *, const char *);
+
+/* time.h */
+extern time_t mktime(struct tm *);
+extern size_t strftime(char *, size_t, const char *, const struct tm *);
+extern int gettimeofday(struct timeval *, struct timezone *);
+extern int setitimer(int, struct itimerval *, struct itimerval *);
+extern time_t time(time_t *);
+extern time_t timegm(struct tm *);
+extern struct tm *localtime(const time_t *);
+extern struct tm *gmtime(const time_t *);
+
+/* unistd.h */
+extern int rename(const char *, const char *);
+extern int ioctl(int, int, int *arg);
+extern int connect(int, struct sockaddr *, int);
+extern int readlink(const char *, char *, int);
+extern int symlink(const char *, const char *);
+extern int ftruncate(int, off_t);
+extern int fchmod(int, mode_t);
+extern int fchown(int, uid_t, gid_t);
+extern int lstat(const char *, struct stat *);
+extern int fstat(int, struct stat *);
+extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+extern int gethostname(char *, int);
+extern char *getwd(char *);
+extern int getpagesize(void);
+
+#endif /* SVR4 */
+
+#endif /* pr_sunos4_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/nspr.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/nspr.h	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+#ifndef nspr_h___
+#define nspr_h___
+
+#include "pratom.h"
+#include "prbit.h"
+#include "prclist.h"
+#include "prcmon.h"
+#include "prcvar.h"
+#include "prdtoa.h"
+#include "prenv.h"
+#include "prerror.h"
+#include "prinet.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "pripcsem.h"
+#include "prlink.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prlong.h"
+#include "prmem.h"
+#include "prmon.h"
+#include "prmwait.h"
+#include "prnetdb.h"
+#include "prprf.h"
+#include "prproces.h"
+#include "prrng.h"
+#include "prrwlock.h"
+#include "prshm.h"
+#include "prshma.h"
+#include "prsystem.h"
+#include "prthread.h"
+#include "prtime.h"
+#include "prtpool.h"
+#include "prtrace.h"
+#include "prtypes.h"
+
+#endif /* nspr_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,7 @@
+/.cvsignore/1.2/Sat May 12 01:58:29 2001//
+/Makefile.in/1.10/Sun Apr 25 15:00:48 2004//
+/pralarm.h/3.7/Sun Apr 25 15:00:48 2004//
+/probslet.h/3.11/Mon Feb  6 23:13:10 2006//
+/protypes.h/3.19/Thu Sep 15 23:15:53 2005//
+/prsem.h/3.6/Sun Apr 25 15:00:48 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/include/obsolete

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,60 @@
+# 
+# ***** 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)/obsolete
+
+include_subdir = obsolete
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(RELEASE_HEADERS)
+	$(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir)/obsolete

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/pralarm.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/pralarm.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,194 @@
+/* -*- 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:		pralarm.h
+** Description:	API to periodic alarms.
+**
+**
+** Alarms are defined to invoke some client specified function at 
+** a time in the future. The notification may be a one time event
+** or repeated at a fixed interval. The interval at which the next
+** notification takes place may be modified by the client code only
+** during the respective notification.
+**
+** The notification is delivered on a thread that is part of the
+** alarm context (PRAlarm). The thread will inherit the priority
+** of the Alarm creator.
+**
+** Any number of periodic alarms (PRAlarmID) may be created within
+** the context of a single alarm (PRAlarm). The notifications will be
+** scheduled as close to the desired time as possible.
+**
+** Repeating periodic notifies are expected to run at a fixed rate.
+** That rate is expressed as some number of notifies per period where
+** the period is much larger than a PRIntervalTime (see prinrval.h).
+*/
+
+#if !defined(pralarm_h)
+#define pralarm_h
+
+#include "prtypes.h"
+#include "prinrval.h"
+
+
+PR_BEGIN_EXTERN_C
+
+/**********************************************************************/
+/************************* TYPES AND CONSTANTS ************************/
+/**********************************************************************/
+
+typedef struct PRAlarm PRAlarm;
+typedef struct PRAlarmID PRAlarmID;
+
+typedef PRBool (PR_CALLBACK *PRPeriodicAlarmFn)(
+    PRAlarmID *id, void *clientData, PRUint32 late);
+
+/**********************************************************************/
+/****************************** FUNCTIONS *****************************/
+/**********************************************************************/
+
+/***********************************************************************
+** FUNCTION:    PR_CreateAlarm
+** DESCRIPTION:
+**  Create an alarm context.
+** INPUTS:      void
+** OUTPUTS:     None
+** RETURN:      PRAlarm*
+**  
+** SIDE EFFECTS:
+**  This creates an alarm context, which is an object used for subsequent
+**  notification creations. It also creates a thread that will be used to
+** deliver the notifications that are expected to be defined. The client
+** is resposible for destroying the context when appropriate.
+** RESTRICTIONS:
+**  None. 
+** MEMORY:      The object (PRAlarm) and a thread to support notifications.
+** ALGORITHM:   N/A
+***********************************************************************/
+NSPR_API(PRAlarm*) PR_CreateAlarm(void);
+
+/***********************************************************************
+** FUNCTION:    PR_DestroyAlarm
+** DESCRIPTION:
+**  Destroys the context created by PR_CreateAlarm().
+** INPUTS:      PRAlarm*
+** OUTPUTS:     None
+** RETURN:      PRStatus
+**  
+** SIDE EFFECTS:
+**  This destroys the context that was created by PR_CreateAlarm().
+**  If there are any active alarms (PRAlarmID), they will be cancelled.
+**  Once that is done, the thread that was used to deliver the alarms
+**  will be joined. 
+** RESTRICTIONS:
+**  None. 
+** MEMORY:      N/A
+** ALGORITHM:   N/A
+***********************************************************************/
+NSPR_API(PRStatus) PR_DestroyAlarm(PRAlarm *alarm);
+
+/***********************************************************************
+** FUNCTION:    PR_SetAlarm
+** DESCRIPTION:
+**  Creates a periodic notifier that is to be delivered to a specified
+**  function at some fixed interval.
+** INPUTS:      PRAlarm *alarm              Parent alarm context
+**              PRIntervalTime period       Interval over which the notifies
+**                                          are delivered.
+**              PRUint32 rate               The rate within the interval that
+**                                          the notifies will be delivered.
+**              PRPeriodicAlarmFn function  Entry point where the notifies
+**                                          will be delivered.
+** OUTPUTS:     None
+** RETURN:      PRAlarmID*                  Handle to the notifier just created
+**                                          or NULL if the request failed.
+**  
+** SIDE EFFECTS:
+**  A periodic notifier is created. The notifications will be delivered
+**  by the alarm's internal thread at a fixed interval whose rate is the
+**  number of interrupts per interval specified. The first notification
+**  will be delivered as soon as possible, and they will continue until
+**  the notifier routine indicates that they should cease of the alarm
+**  context is destroyed (PR_DestroyAlarm).
+** RESTRICTIONS:
+**  None. 
+** MEMORY:      Memory for the notifier object.
+** ALGORITHM:   The rate at which notifications are delivered are stated
+**              to be "'rate' notifies per 'interval'". The exact time of
+**              the notification is computed based on a epoch established
+**              when the notifier was set. Each notification is delivered
+**              not ealier than the epoch plus the fixed rate times the
+**              notification sequence number. Such notifications have the
+**              potential to be late by not more than 'interval'/'rate'.
+**              The amount of lateness of one notification is taken into
+**              account on the next in an attempt to avoid long term slew.  
+***********************************************************************/
+NSPR_API(PRAlarmID*) PR_SetAlarm(
+    PRAlarm *alarm, PRIntervalTime period, PRUint32 rate,
+    PRPeriodicAlarmFn function, void *clientData);
+
+/***********************************************************************
+** FUNCTION:    PR_ResetAlarm
+** DESCRIPTION:
+**  Resets an existing alarm.
+** INPUTS:      PRAlarmID *id               Identify of the notifier.
+**              PRIntervalTime period       Interval over which the notifies
+**                                          are delivered.
+**              PRUint32 rate               The rate within the interval that
+**                                          the notifies will be delivered.
+** OUTPUTS:     None
+** RETURN:      PRStatus                    Indication of completion.
+**  
+** SIDE EFFECTS:
+**  An existing alarm may have its period and rate redefined. The
+**  additional side effect is that the notifier's epoch is recomputed.
+**  The first notification delivered by the newly refreshed alarm is
+**  defined to be 'interval'/'rate' from the time of the reset.
+** RESTRICTIONS:
+**  This function may only be called in the notifier for that alarm.
+** MEMORY:      N/A.
+** ALGORITHM:   See PR_SetAlarm().  
+***********************************************************************/
+NSPR_API(PRStatus) PR_ResetAlarm(
+	PRAlarmID *id, PRIntervalTime period, PRUint32 rate);
+
+PR_END_EXTERN_C
+
+#endif /* !defined(pralarm_h) */
+
+/* prinrval.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/probslet.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/probslet.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,185 @@
+/* -*- 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 ***** */
+
+/*
+** A collection of things thought to be obsolete
+*/
+
+#if defined(PROBSLET_H)
+#else
+#define PROBSLET_H
+
+#include "prio.h"
+#include "private/pprio.h"  /* for PROsfd */
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Yield the current thread.  The proper function to use in place of
+** PR_Yield() is PR_Sleep() with an argument of PR_INTERVAL_NO_WAIT.
+*/
+NSPR_API(PRStatus) PR_Yield(void);
+
+/************************************************************************/
+/************* The following definitions are for select *****************/
+/************************************************************************/
+
+/*
+** The following is obsolete and will be deleted in the next release!
+** These are provided for compatibility, but are GUARANTEED to be slow.
+**
+** Override PR_MAX_SELECT_DESC if you need more space in the select set.
+*/
+#ifndef PR_MAX_SELECT_DESC
+#define PR_MAX_SELECT_DESC 1024
+#endif
+typedef struct PR_fd_set {
+    PRUint32      hsize;
+    PRFileDesc   *harray[PR_MAX_SELECT_DESC];
+    PRUint32      nsize;
+    PROsfd        narray[PR_MAX_SELECT_DESC];
+} PR_fd_set;
+
+/*
+*************************************************************************
+** FUNCTION:    PR_Select
+** DESCRIPTION:
+**
+** The call returns as soon as I/O is ready on one or more of the underlying
+** file/socket descriptors or an exceptional condition is pending. A count of the 
+** number of ready descriptors is returned unless a timeout occurs in which case 
+** zero is returned.  On return, PR_Select replaces the given descriptor sets with 
+** subsets consisting of those descriptors that are ready for the requested condition.
+** The total number of ready descriptors in all the sets is the return value.
+**
+** INPUTS:
+**   PRInt32 num             
+**       This argument is unused but is provided for select(unix) interface
+**       compatability.  All input PR_fd_set arguments are self-describing
+**       with its own maximum number of elements in the set.
+**                               
+**   PR_fd_set *readfds
+**       A set describing the io descriptors for which ready for reading
+**       condition is of interest.  
+**                               
+**   PR_fd_set *writefds
+**       A set describing the io descriptors for which ready for writing
+**       condition is of interest.  
+**                               
+**   PR_fd_set *exceptfds
+**       A set describing the io descriptors for which exception pending
+**       condition is of interest.  
+**
+**   Any of the above readfds, writefds or exceptfds may be given as NULL 
+**   pointers if no descriptors are of interest for that particular condition.                          
+**   
+**   PRIntervalTime timeout  
+**       Amount of time the call will block waiting for I/O to become ready. 
+**       If this time expires without any I/O becoming ready, the result will
+**       be zero.
+**
+** OUTPUTS:    
+**   PR_fd_set *readfds
+**       A set describing the io descriptors which are ready for reading.
+**                               
+**   PR_fd_set *writefds
+**       A set describing the io descriptors which are ready for writing.
+**                               
+**   PR_fd_set *exceptfds
+**       A set describing the io descriptors which have pending exception.
+**
+** RETURN:PRInt32
+**   Number of io descriptors with asked for conditions or zero if the function
+**   timed out or -1 on failure.  The reason for the failure is obtained by 
+**   calling PR_GetError().
+** XXX can we implement this on windoze and mac?
+**************************************************************************
+*/
+NSPR_API(PRInt32) PR_Select(
+    PRInt32 num, PR_fd_set *readfds, PR_fd_set *writefds,
+    PR_fd_set *exceptfds, PRIntervalTime timeout);
+
+/* 
+** The following are not thread safe for two threads operating on them at the
+** same time.
+**
+** The following routines are provided for manipulating io descriptor sets.
+** PR_FD_ZERO(&fdset) initializes a descriptor set fdset to the null set.
+** PR_FD_SET(fd, &fdset) includes a particular file descriptor fd in fdset.
+** PR_FD_CLR(fd, &fdset) removes a file descriptor fd from fdset.  
+** PR_FD_ISSET(fd, &fdset) is nonzero if file descriptor fd is a member of 
+** fdset, zero otherwise.
+**
+** PR_FD_NSET(osfd, &fdset) includes a particular native file descriptor osfd
+** in fdset.
+** PR_FD_NCLR(osfd, &fdset) removes a native file descriptor osfd from fdset.  
+** PR_FD_NISSET(osfd, &fdset) is nonzero if native file descriptor osfd is a member of 
+** fdset, zero otherwise.
+*/
+
+NSPR_API(void)        PR_FD_ZERO(PR_fd_set *set);
+NSPR_API(void)        PR_FD_SET(PRFileDesc *fd, PR_fd_set *set);
+NSPR_API(void)        PR_FD_CLR(PRFileDesc *fd, PR_fd_set *set);
+NSPR_API(PRInt32)     PR_FD_ISSET(PRFileDesc *fd, PR_fd_set *set);
+NSPR_API(void)        PR_FD_NSET(PROsfd osfd, PR_fd_set *set);
+NSPR_API(void)        PR_FD_NCLR(PROsfd osfd, PR_fd_set *set);
+NSPR_API(PRInt32)     PR_FD_NISSET(PROsfd osfd, PR_fd_set *set);
+
+/*
+** The next two entry points should not be in the API, but they are
+** declared here for historical reasons.
+*/
+
+NSPR_API(PRInt32) PR_GetSysfdTableMax(void);
+
+NSPR_API(PRInt32) PR_SetSysfdTableSize(PRIntn table_size);
+
+#ifndef NO_NSPR_10_SUPPORT
+#ifdef XP_MAC
+#include <stat.h>
+#else
+#include <sys/stat.h>
+#endif
+
+NSPR_API(PRInt32) PR_Stat(const char *path, struct stat *buf);
+#endif /* NO_NSPR_10_SUPPORT */
+
+PR_END_EXTERN_C
+
+#endif /* defined(PROBSLET_H) */
+
+/* probslet.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/protypes.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/protypes.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,252 @@
+/* -*- 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 ***** */
+
+/*
+ * This header typedefs the old 'native' types to the new PR<type>s.
+ * These definitions are scheduled to be eliminated at the earliest
+ * possible time. The NSPR API is implemented and documented using
+ * the new definitions.
+ */
+
+#if !defined(PROTYPES_H)
+#define PROTYPES_H
+
+typedef PRUintn uintn;
+#ifndef _XP_Core_
+typedef PRIntn intn;
+#endif
+
+/*
+ * It is trickier to define uint, int8, uint8, int16, uint16,
+ * int32, uint32, int64, and uint64 because some of these int
+ * types are defined by standard header files on some platforms.
+ * Our strategy here is to include all such standard headers
+ * first, and then define these int types only if they are not
+ * defined by those standard headers.
+ */
+
+/*
+ * BeOS defines all the int types below in its standard header
+ * file SupportDefs.h.
+ */
+#ifdef XP_BEOS
+#include <support/SupportDefs.h>
+#endif
+
+/*
+ * OpenVMS defines all the int types below in its standard
+ * header files ints.h and types.h.
+ */
+#ifdef VMS
+#include <ints.h>
+#include <types.h>
+#endif
+
+/*
+ * SVR4 typedef of uint is commonly found on UNIX machines.
+ *
+ * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h)
+ * defines the types int8, int16, int32, and int64.
+ */
+#ifdef XP_UNIX
+#include <sys/types.h>
+#endif
+
+/* model.h on HP-UX defines int8, int16, and int32. */
+#ifdef HPUX
+#include <model.h>
+#endif
+
+/*
+ * uint
+ */
+
+#if !defined(XP_BEOS) && !defined(VMS) \
+    && !defined(XP_UNIX) || defined(NTO)
+typedef PRUintn uint;
+#endif
+
+/*
+ * uint64
+ */
+
+#if !defined(XP_BEOS) && !defined(VMS)
+typedef PRUint64 uint64;
+#endif
+
+/*
+ * uint32
+ */
+
+#if !defined(XP_BEOS) && !defined(VMS)
+#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO)
+typedef PRUint32 uint32;
+#else
+typedef unsigned long uint32;
+#endif
+#endif
+
+/*
+ * uint16
+ */
+
+#if !defined(XP_BEOS) && !defined(VMS)
+typedef PRUint16 uint16;
+#endif
+
+/*
+ * uint8
+ */
+
+#if !defined(XP_BEOS) && !defined(VMS)
+typedef PRUint8 uint8;
+#endif
+
+/*
+ * int64
+ */
+
+#if !defined(XP_BEOS) && !defined(VMS) \
+    && !defined(_PR_AIX_HAVE_BSD_INT_TYPES)
+typedef PRInt64 int64;
+#endif
+
+/*
+ * int32
+ */
+
+#if !defined(XP_BEOS) && !defined(VMS) \
+    && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \
+    && !defined(HPUX)
+#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) && !defined(NTO)
+typedef PRInt32 int32;
+#else
+typedef long int32;
+#endif
+#endif
+
+/*
+ * int16
+ */
+
+#if !defined(XP_BEOS) && !defined(VMS) \
+    && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \
+    && !defined(HPUX)
+typedef PRInt16 int16;
+#endif
+
+/*
+ * int8
+ */
+
+#if !defined(XP_BEOS) && !defined(VMS) \
+    && !defined(_PR_AIX_HAVE_BSD_INT_TYPES) \
+    && !defined(HPUX)
+typedef PRInt8 int8;
+#endif
+
+typedef PRFloat64 float64;
+typedef PRUptrdiff uptrdiff_t;
+typedef PRUword uprword_t;
+typedef PRWord prword_t;
+
+
+/* Re: prbit.h */
+#define TEST_BIT	PR_TEST_BIT
+#define SET_BIT		PR_SET_BIT
+#define CLEAR_BIT	PR_CLEAR_BIT
+
+/* Re: prarena.h->plarena.h */
+#define PRArena PLArena
+#define PRArenaPool PLArenaPool
+#define PRArenaStats PLArenaStats
+#define PR_ARENA_ALIGN PL_ARENA_ALIGN
+#define PR_INIT_ARENA_POOL PL_INIT_ARENA_POOL
+#define PR_ARENA_ALLOCATE PL_ARENA_ALLOCATE
+#define PR_ARENA_GROW PL_ARENA_GROW
+#define PR_ARENA_MARK PL_ARENA_MARK
+#define PR_CLEAR_UNUSED PL_CLEAR_UNUSED
+#define PR_CLEAR_ARENA PL_CLEAR_ARENA
+#define PR_ARENA_RELEASE PL_ARENA_RELEASE
+#define PR_COUNT_ARENA PL_COUNT_ARENA
+#define PR_ARENA_DESTROY PL_ARENA_DESTROY
+#define PR_InitArenaPool PL_InitArenaPool
+#define PR_FreeArenaPool PL_FreeArenaPool
+#define PR_FinishArenaPool PL_FinishArenaPool
+#define PR_CompactArenaPool PL_CompactArenaPool
+#define PR_ArenaFinish PL_ArenaFinish
+#define PR_ArenaAllocate PL_ArenaAllocate
+#define PR_ArenaGrow PL_ArenaGrow
+#define PR_ArenaRelease PL_ArenaRelease
+#define PR_ArenaCountAllocation PL_ArenaCountAllocation
+#define PR_ArenaCountInplaceGrowth PL_ArenaCountInplaceGrowth
+#define PR_ArenaCountGrowth PL_ArenaCountGrowth
+#define PR_ArenaCountRelease PL_ArenaCountRelease
+#define PR_ArenaCountRetract PL_ArenaCountRetract
+
+/* Re: prhash.h->plhash.h */
+#define PRHashEntry PLHashEntry
+#define PRHashTable PLHashTable
+#define PRHashNumber PLHashNumber
+#define PRHashFunction PLHashFunction
+#define PRHashComparator PLHashComparator
+#define PRHashEnumerator PLHashEnumerator
+#define PRHashAllocOps PLHashAllocOps
+#define PR_NewHashTable PL_NewHashTable
+#define PR_HashTableDestroy PL_HashTableDestroy
+#define PR_HashTableRawLookup PL_HashTableRawLookup
+#define PR_HashTableRawAdd PL_HashTableRawAdd
+#define PR_HashTableRawRemove PL_HashTableRawRemove
+#define PR_HashTableAdd PL_HashTableAdd
+#define PR_HashTableRemove PL_HashTableRemove
+#define PR_HashTableEnumerateEntries PL_HashTableEnumerateEntries
+#define PR_HashTableLookup PL_HashTableLookup
+#define PR_HashTableDump PL_HashTableDump
+#define PR_HashString PL_HashString
+#define PR_CompareStrings PL_CompareStrings
+#define PR_CompareValues PL_CompareValues
+
+#if defined(XP_MAC)
+#ifndef TRUE				/* Mac standard is lower case true */
+	#define TRUE 1
+#endif
+#ifndef FALSE				/* Mac standard is lower case false */
+	#define FALSE 0
+#endif
+#endif
+
+#endif /* !defined(PROTYPES_H) */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/prsem.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/obsolete/prsem.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,96 @@
+/* -*- 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 prsem_h___
+#define prsem_h___
+
+/*
+** API for counting semaphores. Semaphores are counting synchronizing 
+** variables based on a lock and a condition variable.  They are lightweight 
+** contention control for a given count of resources.
+*/
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PRSemaphore PRSemaphore;
+
+/*
+** Create a new semaphore object.
+*/
+NSPR_API(PRSemaphore*) PR_NewSem(PRUintn value);
+
+/*
+** Destroy the given semaphore object.
+**
+*/
+NSPR_API(void) PR_DestroySem(PRSemaphore *sem);
+
+/*
+** Wait on a Semaphore.
+** 
+** This routine allows a calling thread to wait or proceed depending upon the 
+** state of the semahore sem. The thread can proceed only if the counter value 
+** of the semaphore sem is currently greater than 0. If the value of semaphore 
+** sem is positive, it is decremented by one and the routine returns immediately 
+** allowing the calling thread to continue. If the value of semaphore sem is 0, 
+** the calling thread blocks awaiting the semaphore to be released by another 
+** thread.
+** 
+** This routine can return PR_PENDING_INTERRUPT if the waiting thread 
+** has been interrupted.
+*/
+NSPR_API(PRStatus) PR_WaitSem(PRSemaphore *sem);
+
+/*
+** This routine increments the counter value of the semaphore. If other threads 
+** are blocked for the semaphore, then the scheduler will determine which ONE 
+** thread will be unblocked.
+*/
+NSPR_API(void) PR_PostSem(PRSemaphore *sem);
+
+/*
+** Returns the value of the semaphore referenced by sem without affecting
+** the state of the semaphore.  The value represents the semaphore vaule
+F** at the time of the call, but may not be the actual value when the
+** caller inspects it.
+*/
+NSPR_API(PRUintn) PR_GetValueSem(PRSemaphore *sem);
+
+PR_END_EXTERN_C
+
+#endif /* prsem_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/pratom.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/pratom.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,161 @@
+/* -*- 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 ***** */
+
+/* GLOBAL FUNCTIONS:
+** DESCRIPTION:
+**     PR Atomic operations
+*/
+
+#ifndef pratom_h___
+#define pratom_h___
+
+#include "prtypes.h"
+#include "prlock.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** FUNCTION: PR_AtomicIncrement
+** DESCRIPTION:
+**    Atomically increment a 32 bit value.
+** INPUTS:
+**    val:  a pointer to the value to increment
+** RETURN:
+**    the returned value is the result of the increment
+*/
+NSPR_API(PRInt32)	PR_AtomicIncrement(PRInt32 *val);
+
+/*
+** FUNCTION: PR_AtomicDecrement
+** DESCRIPTION:
+**    Atomically decrement a 32 bit value.
+** INPUTS:
+**    val:  a pointer to the value to decrement
+** RETURN:
+**    the returned value is the result of the decrement
+*/
+NSPR_API(PRInt32)	PR_AtomicDecrement(PRInt32 *val);
+
+/*
+** FUNCTION: PR_AtomicSet
+** DESCRIPTION:
+**    Atomically set a 32 bit value.
+** INPUTS:
+**    val: A pointer to a 32 bit value to be set
+**    newval: The newvalue to assign to val
+** RETURN:
+**    Returns the prior value
+*/
+NSPR_API(PRInt32) PR_AtomicSet(PRInt32 *val, PRInt32 newval);
+
+/*
+** FUNCTION: PR_AtomicAdd
+** DESCRIPTION:
+**    Atomically add a 32 bit value.
+** INPUTS:
+**    ptr:  a pointer to the value to increment
+**	  val:  value to be added
+** RETURN:
+**    the returned value is the result of the addition
+*/
+NSPR_API(PRInt32)	PR_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+
+/*
+** LIFO linked-list (stack)
+*/
+typedef struct PRStackElemStr PRStackElem;
+
+struct PRStackElemStr {
+    PRStackElem	*prstk_elem_next;	/* next pointer MUST be at offset 0;
+									  assembly language code relies on this */
+};
+
+typedef struct PRStackStr PRStack;
+
+/*
+** FUNCTION: PR_CreateStack
+** DESCRIPTION:
+**    Create a stack, a LIFO linked list
+** INPUTS:
+**    stack_name:  a pointer to string containing the name of the stack
+** RETURN:
+**    A pointer to the created stack, if successful, else NULL.
+*/
+NSPR_API(PRStack *)	PR_CreateStack(const char *stack_name);
+
+/*
+** FUNCTION: PR_StackPush
+** DESCRIPTION:
+**    Push an element on the top of the stack
+** INPUTS:
+**    stack:		pointer to the stack
+**    stack_elem:	pointer to the stack element
+** RETURN:
+**    None
+*/
+NSPR_API(void)			PR_StackPush(PRStack *stack, PRStackElem *stack_elem);
+
+/*
+** FUNCTION: PR_StackPop
+** DESCRIPTION:
+**    Remove the element on the top of the stack
+** INPUTS:
+**    stack:		pointer to the stack
+** RETURN:
+**    A pointer to the stack element removed from the top of the stack,
+**	  if non-empty,
+**    else NULL
+*/
+NSPR_API(PRStackElem *)	PR_StackPop(PRStack *stack);
+
+/*
+** FUNCTION: PR_DestroyStack
+** DESCRIPTION:
+**    Destroy the stack
+** INPUTS:
+**    stack:		pointer to the stack
+** RETURN:
+**    PR_SUCCESS - if successfully deleted
+**	  PR_FAILURE - if the stack is not empty
+**					PR_GetError will return
+**						PR_INVALID_STATE_ERROR - stack is not empty
+*/
+NSPR_API(PRStatus)		PR_DestroyStack(PRStack *stack);
+
+PR_END_EXTERN_C
+
+#endif /* pratom_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prbit.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prbit.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,111 @@
+/* -*- 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 prbit_h___
+#define prbit_h___
+
+#include "prtypes.h"
+PR_BEGIN_EXTERN_C
+
+/*
+** A prbitmap_t is a long integer that can be used for bitmaps
+*/
+typedef unsigned long prbitmap_t;
+
+#define PR_TEST_BIT(_map,_bit) \
+    ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] & (1L << ((_bit) & (PR_BITS_PER_LONG-1))))
+#define PR_SET_BIT(_map,_bit) \
+    ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] |= (1L << ((_bit) & (PR_BITS_PER_LONG-1))))
+#define PR_CLEAR_BIT(_map,_bit) \
+    ((_map)[(_bit)>>PR_BITS_PER_LONG_LOG2] &= ~(1L << ((_bit) & (PR_BITS_PER_LONG-1))))
+
+/*
+** Compute the log of the least power of 2 greater than or equal to n
+*/
+NSPR_API(PRIntn) PR_CeilingLog2(PRUint32 i); 
+
+/*
+** Compute the log of the greatest power of 2 less than or equal to n
+*/
+NSPR_API(PRIntn) PR_FloorLog2(PRUint32 i); 
+
+/*
+** Macro version of PR_CeilingLog2: Compute the log of the least power of
+** 2 greater than or equal to _n. The result is returned in _log2.
+*/
+#define PR_CEILING_LOG2(_log2,_n)   \
+  PR_BEGIN_MACRO                    \
+    PRUint32 j_ = (PRUint32)(_n); 	\
+    (_log2) = 0;                    \
+    if ((j_) & ((j_)-1))            \
+	(_log2) += 1;               \
+    if ((j_) >> 16)                 \
+	(_log2) += 16, (j_) >>= 16; \
+    if ((j_) >> 8)                  \
+	(_log2) += 8, (j_) >>= 8;   \
+    if ((j_) >> 4)                  \
+	(_log2) += 4, (j_) >>= 4;   \
+    if ((j_) >> 2)                  \
+	(_log2) += 2, (j_) >>= 2;   \
+    if ((j_) >> 1)                  \
+	(_log2) += 1;               \
+  PR_END_MACRO
+
+/*
+** Macro version of PR_FloorLog2: Compute the log of the greatest power of
+** 2 less than or equal to _n. The result is returned in _log2.
+**
+** This is equivalent to finding the highest set bit in the word.
+*/
+#define PR_FLOOR_LOG2(_log2,_n)   \
+  PR_BEGIN_MACRO                    \
+    PRUint32 j_ = (PRUint32)(_n); 	\
+    (_log2) = 0;                    \
+    if ((j_) >> 16)                 \
+	(_log2) += 16, (j_) >>= 16; \
+    if ((j_) >> 8)                  \
+	(_log2) += 8, (j_) >>= 8;   \
+    if ((j_) >> 4)                  \
+	(_log2) += 4, (j_) >>= 4;   \
+    if ((j_) >> 2)                  \
+	(_log2) += 2, (j_) >>= 2;   \
+    if ((j_) >> 1)                  \
+	(_log2) += 1;               \
+  PR_END_MACRO
+
+PR_END_EXTERN_C
+#endif /* prbit_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prclist.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prclist.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,140 @@
+/* -*- 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 prclist_h___
+#define prclist_h___
+
+#include "prtypes.h"
+
+typedef struct PRCListStr PRCList;
+
+/*
+** Circular linked list
+*/
+struct PRCListStr {
+    PRCList	*next;
+    PRCList	*prev;
+};
+
+/*
+** Insert element "_e" into the list, before "_l".
+*/
+#define PR_INSERT_BEFORE(_e,_l)	 \
+    PR_BEGIN_MACRO		 \
+	(_e)->next = (_l);	 \
+	(_e)->prev = (_l)->prev; \
+	(_l)->prev->next = (_e); \
+	(_l)->prev = (_e);	 \
+    PR_END_MACRO
+
+/*
+** Insert element "_e" into the list, after "_l".
+*/
+#define PR_INSERT_AFTER(_e,_l)	 \
+    PR_BEGIN_MACRO		 \
+	(_e)->next = (_l)->next; \
+	(_e)->prev = (_l);	 \
+	(_l)->next->prev = (_e); \
+	(_l)->next = (_e);	 \
+    PR_END_MACRO
+
+/*
+** Return the element following element "_e"
+*/
+#define PR_NEXT_LINK(_e)	 \
+    	((_e)->next)
+/*
+** Return the element preceding element "_e"
+*/
+#define PR_PREV_LINK(_e)	 \
+    	((_e)->prev)
+
+/*
+** Append an element "_e" to the end of the list "_l"
+*/
+#define PR_APPEND_LINK(_e,_l) PR_INSERT_BEFORE(_e,_l)
+
+/*
+** Insert an element "_e" at the head of the list "_l"
+*/
+#define PR_INSERT_LINK(_e,_l) PR_INSERT_AFTER(_e,_l)
+
+/* Return the head/tail of the list */
+#define PR_LIST_HEAD(_l) (_l)->next
+#define PR_LIST_TAIL(_l) (_l)->prev
+
+/*
+** Remove the element "_e" from it's circular list.
+*/
+#define PR_REMOVE_LINK(_e)	       \
+    PR_BEGIN_MACRO		       \
+	(_e)->prev->next = (_e)->next; \
+	(_e)->next->prev = (_e)->prev; \
+    PR_END_MACRO
+
+/*
+** Remove the element "_e" from it's circular list. Also initializes the
+** linkage.
+*/
+#define PR_REMOVE_AND_INIT_LINK(_e)    \
+    PR_BEGIN_MACRO		       \
+	(_e)->prev->next = (_e)->next; \
+	(_e)->next->prev = (_e)->prev; \
+	(_e)->next = (_e);	       \
+	(_e)->prev = (_e);	       \
+    PR_END_MACRO
+
+/*
+** Return non-zero if the given circular list "_l" is empty, zero if the
+** circular list is not empty
+*/
+#define PR_CLIST_IS_EMPTY(_l) \
+    ((_l)->next == (_l))
+
+/*
+** Initialize a circular list
+*/
+#define PR_INIT_CLIST(_l)  \
+    PR_BEGIN_MACRO	   \
+	(_l)->next = (_l); \
+	(_l)->prev = (_l); \
+    PR_END_MACRO
+
+#define PR_INIT_STATIC_CLIST(_l) \
+    {(_l), (_l)}
+
+#endif /* prclist_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prcmon.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prcmon.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,98 @@
+/* -*- 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 prcmon_h___
+#define prcmon_h___
+
+/*
+** Interface to cached monitors. Cached monitors use an address to find a
+** given PR monitor. In this way a monitor can be associated with another
+** object without preallocating a monitor for all objects.
+**
+** A hash table is used to quickly map addresses to individual monitors
+** and the system automatically grows the hash table as needed.
+**
+** Cache monitors are about 5 times slower to use than uncached monitors.
+*/
+#include "prmon.h"
+#include "prinrval.h"
+
+PR_BEGIN_EXTERN_C
+
+/**
+** Like PR_EnterMonitor except use the "address" to find a monitor in the
+** monitor cache. If successful, returns the PRMonitor now associated
+** with "address". Note that you must PR_CExitMonitor the address to
+** release the monitor cache entry (otherwise the monitor cache will fill
+** up). This call will return NULL if the monitor cache needs to be
+** expanded and the system is out of memory.
+*/
+NSPR_API(PRMonitor*) PR_CEnterMonitor(void *address);
+
+/*
+** Like PR_ExitMonitor except use the "address" to find a monitor in the
+** monitor cache.
+*/
+NSPR_API(PRStatus) PR_CExitMonitor(void *address);
+
+/*
+** Like PR_Wait except use the "address" to find a monitor in the
+** monitor cache.
+*/
+NSPR_API(PRStatus) PR_CWait(void *address, PRIntervalTime timeout);
+
+/*
+** Like PR_Notify except use the "address" to find a monitor in the
+** monitor cache.
+*/
+NSPR_API(PRStatus) PR_CNotify(void *address);
+
+/*
+** Like PR_NotifyAll except use the "address" to find a monitor in the
+** monitor cache.
+*/
+NSPR_API(PRStatus) PR_CNotifyAll(void *address);
+
+/*
+** Set a callback to be invoked each time a monitor is recycled from the cache
+** freelist, with the monitor's cache-key passed in address.
+*/
+NSPR_API(void) PR_CSetOnMonitorRecycle(void (PR_CALLBACK *callback)(void *address));
+
+PR_END_EXTERN_C
+
+#endif /* prcmon_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prcountr.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prcountr.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,557 @@
+/* -*- 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 prcountr_h___
+#define prcountr_h___
+
+/*----------------------------------------------------------------------------
+** prcountr.h -- NSPR Instrumentation counters
+**
+** The NSPR Counter Feature provides a means to "count
+** something." Counters can be dynamically defined, incremented,
+** decremented, set, and deleted under application program
+** control.
+** 																                   
+** The Counter Feature is intended to be used as instrumentation,                  
+** not as operational data. If you need a counter for operational                  
+** data, use native integral types.                                                
+** 																                   
+** Counters are 32bit unsigned intergers. On overflow, a counter                   
+** will wrap. No exception is recognized or reported.                              
+**                                                                                 
+** A counter can be dynamically created using a two level naming
+** convention. A "handle" is returned when the counter is
+** created. The counter can subsequently be addressed by its
+** handle. An API is provided to get an existing counter's handle
+** given the names with  which it was originally created. 
+** Similarly, a counter's name can be retrieved given its handle.
+** 
+** The counter naming convention is a two-level hierarchy. The
+** QName is the higher level of the hierarchy; RName is the
+** lower level. RNames can be thought of as existing within a
+** QName. The same RName can exist within multiple QNames. QNames
+** are unique. The NSPR Counter is not a near-zero overhead
+** feature. Application designers should be aware of 
+** serialization issues when using the Counter API. Creating a
+** counter locks a large asset, potentially causing a stall. This
+** suggest that applications should create counters at component
+** initialization, for example, and not create and destroy them
+** willy-nilly. ... You have been warned.
+** 
+** Incrementing and Adding to counters uses atomic operations.
+** The performance of these operations will vary from platform
+** to platform. On platforms where atomic operations are not
+** supported the overhead may be substantial.
+** 
+** When traversing the counter database with FindNext functions,
+** the instantaneous values of any given counter is that at the
+** moment of extraction. The state of the entire counter database
+** may not be viewed as atomic.
+** 
+** The counter interface may be disabled (No-Op'd) at compile
+** time. When DEBUG is defined at compile time, the Counter
+** Feature is compiled into NSPR and applications invoking it.
+** When DEBUG is not defined, the counter macros compile to
+** nothing. To force the Counter Feature to be compiled into an
+** optimized build, define FORCE_NSPR_COUNTERS at compile time
+** for both NSPR and the application intending to use it.
+** 
+** Application designers should use the macro form of the Counter
+** Feature methods to minimize performance impact in optimized
+** builds. The macros normally compile to nothing on optimized
+** builds.
+** 
+** Application designers should be aware of the effects of
+** debug and optimized build differences when using result of the
+** Counter Feature macros in expressions.
+** 
+** The Counter Feature is thread-safe and SMP safe.
+** 
+** /lth. 09-Jun-1998.
+*/
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Opaque counter handle type.
+** ... don't even think of looking in here.
+**
+*/
+typedef void *  PRCounterHandle;
+
+#define PRCOUNTER_NAME_MAX 31
+#define PRCOUNTER_DESC_MAX 255
+
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DEFINE_COUNTER() -- Define a PRCounterHandle
+** 
+** DESCRIPTION: PR_DEFINE_COUNTER() is used to define a counter
+** handle.
+** 
+*/
+#define PR_DEFINE_COUNTER(name) PRCounterHandle name
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_INIT_COUNTER_HANDLE() -- Set the value of a PRCounterHandle
+** 
+** DESCRIPTION: 
+** PR_INIT_COUNTER_HANDLE() sets the value of a PRCounterHandle
+** to value.
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_INIT_COUNTER_HANDLE(handle,value)\
+    (handle) = (PRCounterHandle)(value)
+#else
+#define PR_INIT_COUNTER_HANDLE(handle,value)
+#endif
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_CreateCounter() -- Create a counter
+** 
+** DESCRIPTION: PR_CreateCounter() creates a counter object and
+** initializes it to zero.
+** 
+** The macro form takes as its first argument the name of the
+** PRCounterHandle to receive the handle returned from
+** PR_CreateCounter().
+** 
+** INPUTS:
+**  qName: The QName for the counter object. The maximum length
+** of qName is defined by PRCOUNTER_NAME_MAX
+** 
+**  rName: The RName for the counter object. The maximum length
+** of qName is defined by PRCOUNTER_NAME_MAX
+** 
+**  descrioption: The description of the counter object. The
+** maximum length of description is defined by
+** PRCOUNTER_DESC_MAX.
+** 
+** OUTPUTS:
+** 
+** RETURNS:
+**  PRCounterHandle.
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_CREATE_COUNTER(handle,qName,rName,description)\
+   (handle) = PR_CreateCounter((qName),(rName),(description))
+#else
+#define PR_CREATE_COUNTER(handle,qName,rName,description)
+#endif
+
+NSPR_API(PRCounterHandle) 
+	PR_CreateCounter( 
+		const char *qName, 
+    	const char *rName, 
+        const char *description 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DestroyCounter() -- Destroy a counter object.
+** 
+** DESCRIPTION: PR_DestroyCounter() removes a counter and
+** unregisters its handle from the counter database.
+** 
+** INPUTS:
+**  handle: the PRCounterHandle of the counter to be destroyed.
+** 
+** OUTPUTS: 
+**  The counter is destroyed.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_DESTROY_COUNTER(handle) PR_DestroyCounter((handle))
+#else
+#define PR_DESTROY_COUNTER(handle)
+#endif
+
+NSPR_API(void) 
+	PR_DestroyCounter( 
+		PRCounterHandle handle 
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetCounterHandleFromName() -- Retreive a
+** counter's handle give its name.
+** 
+** DESCRIPTION: PR_GetCounterHandleFromName() retreives a
+** counter's handle from the counter database, given the name
+** the counter was originally created with.
+** 
+** INPUTS:
+**  qName: Counter's original QName.
+**  rName: Counter's original RName.
+** 
+** OUTPUTS:
+** 
+** RETURNS: 
+**  PRCounterHandle or PRCounterError.
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName)\
+    (handle) = PR_GetCounterHandleFromName((qName),(rName))
+#else
+#define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName)
+#endif
+
+NSPR_API(PRCounterHandle) 
+	PR_GetCounterHandleFromName( 
+    	const char *qName, 
+    	const char *rName 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetCounterNameFromHandle() -- Retreive a
+** counter's name, given its handle.
+** 
+** DESCRIPTION: PR_GetCounterNameFromHandle() retreives a
+** counter's name given its handle.
+** 
+** INPUTS:
+**  qName: Where to store a pointer to qName.
+**  rName: Where to store a pointer to rName.
+**  description: Where to store a pointer to description.
+** 
+** OUTPUTS: Pointers to the Counter Feature's copies of the names
+** used when the counters were created.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description)\
+    PR_GetCounterNameFromHandle((handle),(qName),(rName),(description))
+#else
+#define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description )
+#endif
+
+NSPR_API(void) 
+	PR_GetCounterNameFromHandle( 
+    	PRCounterHandle handle,  
+	    const char **qName, 
+	    const char **rName, 
+		const char **description 
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_IncrementCounter() -- Add one to the referenced
+** counter.
+** 
+** DESCRIPTION: Add one to the referenced counter.
+** 
+** INPUTS:
+**  handle: The PRCounterHandle of the counter to be incremented
+** 
+** OUTPUTS: The counter is incrementd.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_INCREMENT_COUNTER(handle) PR_IncrementCounter(handle)
+#else
+#define PR_INCREMENT_COUNTER(handle)
+#endif
+
+NSPR_API(void) 
+	PR_IncrementCounter( 
+		PRCounterHandle handle
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DecrementCounter() -- Subtract one from the
+** referenced counter
+** 
+** DESCRIPTION: Subtract one from the referenced counter.
+** 
+** INPUTS: 
+**  handle: The PRCounterHandle of the coutner to be
+** decremented.
+** 
+** OUTPUTS: the counter is decremented.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_DECREMENT_COUNTER(handle) PR_DecrementCounter(handle)
+#else
+#define PR_DECREMENT_COUNTER(handle)
+#endif
+
+NSPR_API(void) 
+	PR_DecrementCounter( 
+		PRCounterHandle handle
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_AddToCounter() -- Add a value to a counter.
+** 
+** DESCRIPTION: Add value to the counter referenced by handle.
+** 
+** INPUTS:
+**  handle: the PRCounterHandle of the counter to be added to.
+** 
+**  value: the value to be added to the counter.
+** 
+** OUTPUTS: new value for counter.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_ADD_TO_COUNTER(handle,value)\
+    PR_AddToCounter((handle),(value))
+#else
+#define PR_ADD_TO_COUNTER(handle,value)
+#endif
+
+NSPR_API(void) 
+	PR_AddToCounter( 
+    	PRCounterHandle handle, 
+	    PRUint32 value 
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_SubtractFromCounter() -- A value is subtracted
+** from a counter.
+** 
+** DESCRIPTION:
+** Subtract a value from a counter.
+** 
+** INPUTS:
+**  handle: the PRCounterHandle of the counter to be subtracted
+** from.
+** 
+**  value: the value to be subtracted from the counter.
+** 
+** OUTPUTS: new value for counter
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_SUBTRACT_FROM_COUNTER(handle,value)\
+    PR_SubtractFromCounter((handle),(value))
+#else
+#define PR_SUBTRACT_FROM_COUNTER(handle,value)
+#endif
+
+NSPR_API(void) 
+	PR_SubtractFromCounter( 
+    	PRCounterHandle handle, 
+	    PRUint32 value 
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetCounter() -- Retreive the value of a counter
+** 
+** DESCRIPTION:
+** Retreive the value of a counter.
+** 
+** INPUTS:
+**  handle: the PR_CounterHandle of the counter to be retreived
+** 
+** OUTPUTS:
+** 
+** RETURNS: The value of the referenced counter
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_GET_COUNTER(counter,handle)\
+    (counter) = PR_GetCounter((handle))
+#else
+#define PR_GET_COUNTER(counter,handle) 0
+#endif
+
+NSPR_API(PRUint32) 
+	PR_GetCounter( 
+		PRCounterHandle handle 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_SetCounter() -- Replace the content of counter
+** with value.
+** 
+** DESCRIPTION: The contents of the referenced counter are
+** replaced by value.
+** 
+** INPUTS:
+**  handle: the PRCounterHandle of the counter whose contents
+** are to be replaced.
+** 
+**  value: the new value of the counter.
+** 
+** OUTPUTS:
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_SET_COUNTER(handle,value) PR_SetCounter((handle),(value))
+#else
+#define PR_SET_COUNTER(handle,value)
+#endif
+
+NSPR_API(void) 
+	PR_SetCounter( 
+		PRCounterHandle handle, 
+		PRUint32 value 
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_FindNextCounterQname() -- Retreive the next QName counter
+** handle iterator
+** 
+** DESCRIPTION:
+** PR_FindNextCounterQname() retreives the first or next Qname
+** the counter data base, depending on the value of handle. When
+** handle is NULL, the function attempts to retreive the first
+** QName handle in the database. When handle is a handle previosly
+** retreived QName handle, then the function attempts to retreive
+** the next QName handle.
+** 
+** INPUTS: 
+**  handle: PRCounterHandle or NULL.
+** 
+** OUTPUTS: returned
+** 
+** RETURNS: PRCounterHandle or NULL when no more QName counter
+** handles are present.
+** 
+** RESTRICTIONS:
+**  A concurrent PR_CreateCounter() or PR_DestroyCounter() may
+** cause unpredictable results.
+** 
+** A PRCounterHandle returned from this function may only be used
+** in another PR_FindNextCounterQname() function call; other
+** operations may cause unpredictable results.
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_FIND_NEXT_COUNTER_QNAME(next,handle)\
+    (next) = PR_FindNextCounterQname((handle))
+#else
+#define PR_FIND_NEXT_COUNTER_QNAME(next,handle) NULL
+#endif
+
+NSPR_API(PRCounterHandle) 
+	PR_FindNextCounterQname( 
+        PRCounterHandle handle
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_FindNextCounterRname() -- Retreive the next RName counter
+** handle iterator
+** 
+** DESCRIPTION:
+** PR_FindNextCounterRname() retreives the first or next RNname
+** handle from the counter data base, depending on the
+** value of handle. When handle is NULL, the function attempts to
+** retreive the first RName handle in the database. When handle is
+** a handle previosly retreived RName handle, then the function
+** attempts to retreive the next RName handle.
+** 
+** INPUTS:
+**  handle: PRCounterHandle or NULL.
+**  qhandle: PRCounterHandle of a previously aquired via
+** PR_FIND_NEXT_QNAME_HANDLE()
+** 
+** OUTPUTS: returned
+** 
+** RETURNS: PRCounterHandle or NULL when no more RName counter
+** handles are present.
+** 
+** RESTRICTIONS:
+**  A concurrent PR_CreateCounter() or PR_DestroyCounter() may
+** cause unpredictable results.
+** 
+** A PRCounterHandle returned from this function may only be used
+** in another PR_FindNextCounterRname() function call; other
+** operations may cause unpredictable results.
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
+#define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle)\
+    (next) = PR_FindNextCounterRname((rhandle),(qhandle))
+#else
+#define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle)
+#endif
+
+NSPR_API(PRCounterHandle) 
+	PR_FindNextCounterRname( 
+        PRCounterHandle rhandle,
+        PRCounterHandle qhandle
+);
+
+PR_END_EXTERN_C
+
+#endif /* prcountr_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prcvar.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prcvar.h	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+#ifndef prcvar_h___
+#define prcvar_h___
+
+#include "prlock.h"
+#include "prinrval.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PRCondVar PRCondVar;
+
+/*
+** Create a new condition variable.
+**
+** 	"lock" is the lock used to protect the condition variable.
+**
+** Condition variables are synchronization objects that threads can use
+** to wait for some condition to occur.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low. In such cases, a NULL will be returned.
+*/
+NSPR_API(PRCondVar*) PR_NewCondVar(PRLock *lock);
+
+/*
+** Destroy a condition variable. There must be no thread
+** waiting on the condvar. The caller is responsible for guaranteeing
+** that the condvar is no longer in use.
+**
+*/
+NSPR_API(void) PR_DestroyCondVar(PRCondVar *cvar);
+
+/*
+** The thread that waits on a condition is blocked in a "waiting on
+** condition" state until another thread notifies the condition or a
+** caller specified amount of time expires. The lock associated with
+** the condition variable will be released, which must have be held
+** prior to the call to wait.
+**
+** Logically a notified thread is moved from the "waiting on condition"
+** state and made "ready." When scheduled, it will attempt to reacquire
+** the lock that it held when wait was called.
+**
+** The timeout has two well known values, PR_INTERVAL_NO_TIMEOUT and
+** PR_INTERVAL_NO_WAIT. The former value requires that a condition be
+** notified (or the thread interrupted) before it will resume from the
+** wait. If the timeout has a value of PR_INTERVAL_NO_WAIT, the effect
+** is to release the lock, possibly causing a rescheduling within the
+** runtime, then immediately attempting to reacquire the lock and resume.
+**
+** Any other value for timeout will cause the thread to be rescheduled
+** either due to explicit notification or an expired interval. The latter
+** must be determined by treating time as one part of the monitored data
+** being protected by the lock and tested explicitly for an expired
+** interval.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable or the thread was interrupted (PR_Interrupt()).
+** The particular reason can be extracted with PR_GetError().
+*/
+NSPR_API(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout);
+
+/*
+** Notify ONE thread that is currently waiting on 'cvar'. Which thread is
+** dependent on the implementation of the runtime. Common sense would dictate
+** that all threads waiting on a single condition have identical semantics,
+** therefore which one gets notified is not significant. 
+**
+** The calling thead must hold the lock that protects the condition, as
+** well as the invariants that are tightly bound to the condition, when
+** notify is called.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable.
+*/
+NSPR_API(PRStatus) PR_NotifyCondVar(PRCondVar *cvar);
+
+/*
+** Notify all of the threads waiting on the condition variable. The order
+** that the threads are notified is indeterminant. The lock that protects
+** the condition must be held.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable.
+*/
+NSPR_API(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar);
+
+PR_END_EXTERN_C
+
+#endif /* prcvar_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prdtoa.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prdtoa.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,90 @@
+/* -*- 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 prdtoa_h___
+#define prdtoa_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** PR_strtod() returns as a double-precision floating-point number
+** the  value represented by the character string pointed to by
+** s00. The string is scanned up to the first unrecognized
+** character.
+**a
+** If the value of se is not (char **)NULL, a  pointer  to
+** the  character terminating the scan is returned in the location pointed
+** to by se. If no number can be formed, se is set to s00, and
+** zero is returned.
+*/
+#if defined(HAVE_WATCOM_BUG_1)
+/* this is a hack to circumvent a bug in the Watcom C/C++ 11.0 compiler
+** When Watcom fixes the bug, remove the special case for Win16
+*/
+PRFloat64 __pascal __loadds __export
+#else
+NSPR_API(PRFloat64)
+#endif
+PR_strtod(const char *s00, char **se);
+
+/*
+** PR_cnvtf()
+** conversion routines for floating point
+** prcsn - number of digits of precision to generate floating
+** point value.
+*/
+NSPR_API(void) PR_cnvtf(char *buf, PRIntn bufsz, PRIntn prcsn, PRFloat64 fval);
+
+/*
+** PR_dtoa() converts double to a string.
+**
+** ARGUMENTS:
+** If rve is not null, *rve is set to point to the end of the return value.
+** If d is +-Infinity or NaN, then *decpt is set to 9999.
+**
+** mode:
+**     0 ==> shortest string that yields d when read in
+**           and rounded to nearest.
+*/
+NSPR_API(PRStatus) PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits,
+	PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize);
+
+PR_END_EXTERN_C
+
+#endif /* prdtoa_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prenv.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prenv.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,157 @@
+/* -*- 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 prenv_h___
+#define prenv_h___
+
+#include "prtypes.h"
+
+/*******************************************************************************/
+/*******************************************************************************/
+/****************** THESE FUNCTIONS MAY NOT BE THREAD SAFE *********************/
+/*******************************************************************************/
+/*******************************************************************************/
+
+PR_BEGIN_EXTERN_C
+
+/*
+** PR_GetEnv() -- Retrieve value of environment variable
+** 
+** Description:
+** PR_GetEnv() is modeled on Unix getenv().
+** 
+** 
+** Inputs: 
+**   var -- The name of the environment variable
+** 
+** Returns:
+**   The value of the environment variable 'var' or NULL if
+** the variable is undefined.
+** 
+** Restrictions:
+**   You'd think that a POSIX getenv(), putenv() would be
+**   consistently implemented everywhere. Surprise! It is not. On
+**   some platforms, a putenv() where the argument is of
+**   the form "name"  causes the named environment variable to
+**   be un-set; that is: a subsequent getenv() returns NULL. On
+**   other platforms, the putenv() fails, on others, it is a
+**   no-op. Similarly, a putenv() where the argument is of the
+**   form "name=" causes the named environment variable to be
+**   un-set; a subsequent call to getenv() returns NULL. On
+**   other platforms, a subsequent call to getenv() returns a
+**   pointer to a null-string (a byte of zero).
+** 
+**   PR_GetEnv(), PR_SetEnv() provide a consistent behavior 
+**   across all supported platforms. There are, however, some
+**   restrictions and some practices you must use to achieve
+**   consistent results everywhere.
+** 
+**   When manipulating the environment there is no way to un-set
+**   an environment variable across all platforms. We suggest
+**   you interpret the return of a pointer to null-string to
+**   mean the same as a return of NULL from PR_GetEnv().
+** 
+**   A call to PR_SetEnv() where the parameter is of the form
+**   "name" will return PR_FAILURE; the environment remains
+**   unchanged. A call to PR_SetEnv() where the parameter is
+**   of the form "name=" may un-set the envrionment variable on
+**   some platforms; on others it may set the value of the
+**   environment variable to the null-string.
+** 
+**   For example, to test for NULL return or return of the
+**   null-string from PR_GetEnv(), use the following code
+**   fragment:
+** 
+**      char *val = PR_GetEnv("foo");
+**      if ((NULL == val) || ('\0' == *val)) { 
+**          ... interpret this as un-set ... 
+**      }
+** 
+**   The caller must ensure that the string passed
+**   to PR_SetEnv() is persistent. That is: The string should
+**   not be on the stack, where it can be overwritten
+**   on return from the function calling PR_SetEnv().
+**   Similarly, the string passed to PR_SetEnv() must not be
+**   overwritten by other actions of the process. ... Some
+**   platforms use the string by reference rather than copying
+**   it into the environment space. ... You have been warned!
+** 
+**   Use of platform-native functions that manipulate the
+**   environment (getenv(), putenv(), 
+**   SetEnvironmentVariable(), etc.) must not be used with
+**   NSPR's similar functions. The platform-native functions
+**   may not be thread safe and/or may operate on different
+**   conceptual environment space than that operated upon by
+**   NSPR's functions or other environment manipulating
+**   functions on the same platform. (!)
+** 
+*/
+NSPR_API(char*) PR_GetEnv(const char *var);
+
+/*
+** PR_SetEnv() -- set, unset or change an environment variable
+** 
+** Description:
+** PR_SetEnv() is modeled on the Unix putenv() function.
+** 
+** Inputs: 
+**   string -- pointer to a caller supplied
+**   constant, persistent string of the form name=value. Where
+**   name is the name of the environment variable to be set or
+**   changed; value is the value assigned to the variable.
+**
+** Returns: 
+**   PRStatus.
+** 
+** Restrictions: 
+**   See the Restrictions documented in the description of
+**   PR_GetEnv() in this header file.
+** 
+** 
+*/
+NSPR_API(PRStatus) PR_SetEnv(const char *string);
+
+/*
+** DEPRECATED.  Use PR_SetEnv() instead.
+*/
+#ifdef XP_MAC
+NSPR_API(PRIntn) PR_PutEnv(const char *string);
+#endif
+
+PR_END_EXTERN_C
+
+#endif /* prenv_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prerr.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prerr.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,278 @@
+/* -*- 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 prerr_h___
+#define prerr_h___
+
+/*
+ *
+ * prerr.h
+ * This file is automatically generated; please do not edit it.
+ */
+
+/* Memory allocation attempt failed */
+#define PR_OUT_OF_MEMORY_ERROR                   (-6000L)
+
+/* Invalid file descriptor */
+#define PR_BAD_DESCRIPTOR_ERROR                  (-5999L)
+
+/* The operation would have blocked */
+#define PR_WOULD_BLOCK_ERROR                     (-5998L)
+
+/* Invalid memory address argument */
+#define PR_ACCESS_FAULT_ERROR                    (-5997L)
+
+/* Invalid function for file type */
+#define PR_INVALID_METHOD_ERROR                  (-5996L)
+
+/* Invalid memory address argument */
+#define PR_ILLEGAL_ACCESS_ERROR                  (-5995L)
+
+/* Some unknown error has occurred */
+#define PR_UNKNOWN_ERROR                         (-5994L)
+
+/* Operation interrupted by another thread */
+#define PR_PENDING_INTERRUPT_ERROR               (-5993L)
+
+/* function not implemented */
+#define PR_NOT_IMPLEMENTED_ERROR                 (-5992L)
+
+/* I/O function error */
+#define PR_IO_ERROR                              (-5991L)
+
+/* I/O operation timed out */
+#define PR_IO_TIMEOUT_ERROR                      (-5990L)
+
+/* I/O operation on busy file descriptor */
+#define PR_IO_PENDING_ERROR                      (-5989L)
+
+/* The directory could not be opened */
+#define PR_DIRECTORY_OPEN_ERROR                  (-5988L)
+
+/* Invalid function argument */
+#define PR_INVALID_ARGUMENT_ERROR                (-5987L)
+
+/* Network address not available (in use?) */
+#define PR_ADDRESS_NOT_AVAILABLE_ERROR           (-5986L)
+
+/* Network address type not supported */
+#define PR_ADDRESS_NOT_SUPPORTED_ERROR           (-5985L)
+
+/* Already connected */
+#define PR_IS_CONNECTED_ERROR                    (-5984L)
+
+/* Network address is invalid */
+#define PR_BAD_ADDRESS_ERROR                     (-5983L)
+
+/* Local Network address is in use */
+#define PR_ADDRESS_IN_USE_ERROR                  (-5982L)
+
+/* Connection refused by peer */
+#define PR_CONNECT_REFUSED_ERROR                 (-5981L)
+
+/* Network address is presently unreachable */
+#define PR_NETWORK_UNREACHABLE_ERROR             (-5980L)
+
+/* Connection attempt timed out */
+#define PR_CONNECT_TIMEOUT_ERROR                 (-5979L)
+
+/* Network file descriptor is not connected */
+#define PR_NOT_CONNECTED_ERROR                   (-5978L)
+
+/* Failure to load dynamic library */
+#define PR_LOAD_LIBRARY_ERROR                    (-5977L)
+
+/* Failure to unload dynamic library */
+#define PR_UNLOAD_LIBRARY_ERROR                  (-5976L)
+
+/* Symbol not found in any of the loaded dynamic libraries */
+#define PR_FIND_SYMBOL_ERROR                     (-5975L)
+
+/* Insufficient system resources */
+#define PR_INSUFFICIENT_RESOURCES_ERROR          (-5974L)
+
+/* A directory lookup on a network address has failed */
+#define PR_DIRECTORY_LOOKUP_ERROR                (-5973L)
+
+/* Attempt to access a TPD key that is out of range */
+#define PR_TPD_RANGE_ERROR                       (-5972L)
+
+/* Process open FD table is full */
+#define PR_PROC_DESC_TABLE_FULL_ERROR            (-5971L)
+
+/* System open FD table is full */
+#define PR_SYS_DESC_TABLE_FULL_ERROR             (-5970L)
+
+/* Network operation attempted on non-network file descriptor */
+#define PR_NOT_SOCKET_ERROR                      (-5969L)
+
+/* TCP-specific function attempted on a non-TCP file descriptor */
+#define PR_NOT_TCP_SOCKET_ERROR                  (-5968L)
+
+/* TCP file descriptor is already bound */
+#define PR_SOCKET_ADDRESS_IS_BOUND_ERROR         (-5967L)
+
+/* Access Denied */
+#define PR_NO_ACCESS_RIGHTS_ERROR                (-5966L)
+
+/* The requested operation is not supported by the platform */
+#define PR_OPERATION_NOT_SUPPORTED_ERROR         (-5965L)
+
+/* The host operating system does not support the protocol requested */
+#define PR_PROTOCOL_NOT_SUPPORTED_ERROR          (-5964L)
+
+/* Access to the remote file has been severed */
+#define PR_REMOTE_FILE_ERROR                     (-5963L)
+
+/* The value requested is too large to be stored in the data buffer provided */
+#define PR_BUFFER_OVERFLOW_ERROR                 (-5962L)
+
+/* TCP connection reset by peer */
+#define PR_CONNECT_RESET_ERROR                   (-5961L)
+
+/* Unused */
+#define PR_RANGE_ERROR                           (-5960L)
+
+/* The operation would have deadlocked */
+#define PR_DEADLOCK_ERROR                        (-5959L)
+
+/* The file is already locked */
+#define PR_FILE_IS_LOCKED_ERROR                  (-5958L)
+
+/* Write would result in file larger than the system allows */
+#define PR_FILE_TOO_BIG_ERROR                    (-5957L)
+
+/* The device for storing the file is full */
+#define PR_NO_DEVICE_SPACE_ERROR                 (-5956L)
+
+/* Unused */
+#define PR_PIPE_ERROR                            (-5955L)
+
+/* Unused */
+#define PR_NO_SEEK_DEVICE_ERROR                  (-5954L)
+
+/* Cannot perform a normal file operation on a directory */
+#define PR_IS_DIRECTORY_ERROR                    (-5953L)
+
+/* Symbolic link loop */
+#define PR_LOOP_ERROR                            (-5952L)
+
+/* File name is too long */
+#define PR_NAME_TOO_LONG_ERROR                   (-5951L)
+
+/* File not found */
+#define PR_FILE_NOT_FOUND_ERROR                  (-5950L)
+
+/* Cannot perform directory operation on a normal file */
+#define PR_NOT_DIRECTORY_ERROR                   (-5949L)
+
+/* Cannot write to a read-only file system */
+#define PR_READ_ONLY_FILESYSTEM_ERROR            (-5948L)
+
+/* Cannot delete a directory that is not empty */
+#define PR_DIRECTORY_NOT_EMPTY_ERROR             (-5947L)
+
+/* Cannot delete or rename a file object while the file system is busy */
+#define PR_FILESYSTEM_MOUNTED_ERROR              (-5946L)
+
+/* Cannot rename a file to a file system on another device */
+#define PR_NOT_SAME_DEVICE_ERROR                 (-5945L)
+
+/* The directory object in the file system is corrupted */
+#define PR_DIRECTORY_CORRUPTED_ERROR             (-5944L)
+
+/* Cannot create or rename a filename that already exists */
+#define PR_FILE_EXISTS_ERROR                     (-5943L)
+
+/* Directory is full.  No additional filenames may be added */
+#define PR_MAX_DIRECTORY_ENTRIES_ERROR           (-5942L)
+
+/* The required device was in an invalid state */
+#define PR_INVALID_DEVICE_STATE_ERROR            (-5941L)
+
+/* The device is locked */
+#define PR_DEVICE_IS_LOCKED_ERROR                (-5940L)
+
+/* No more entries in the directory */
+#define PR_NO_MORE_FILES_ERROR                   (-5939L)
+
+/* Encountered end of file */
+#define PR_END_OF_FILE_ERROR                     (-5938L)
+
+/* Seek error */
+#define PR_FILE_SEEK_ERROR                       (-5937L)
+
+/* The file is busy */
+#define PR_FILE_IS_BUSY_ERROR                    (-5936L)
+
+/* The I/O operation was aborted */
+#define PR_OPERATION_ABORTED_ERROR               (-5935L)
+
+/* Operation is still in progress (probably a non-blocking connect) */
+#define PR_IN_PROGRESS_ERROR                     (-5934L)
+
+/* Operation has already been initiated (probably a non-blocking connect) */
+#define PR_ALREADY_INITIATED_ERROR               (-5933L)
+
+/* The wait group is empty */
+#define PR_GROUP_EMPTY_ERROR                     (-5932L)
+
+/* Object state improper for request */
+#define PR_INVALID_STATE_ERROR                   (-5931L)
+
+/* Network is down */
+#define PR_NETWORK_DOWN_ERROR                    (-5930L)
+
+/* Socket shutdown */
+#define PR_SOCKET_SHUTDOWN_ERROR                 (-5929L)
+
+/* Connection aborted */
+#define PR_CONNECT_ABORTED_ERROR                 (-5928L)
+
+/* Host is unreachable */
+#define PR_HOST_UNREACHABLE_ERROR                (-5927L)
+
+/* The library is not loaded */
+#define PR_LIBRARY_NOT_LOADED_ERROR              (-5926L)
+
+/* Placeholder for the end of the list */
+#define PR_MAX_ERROR                             (-5925L)
+
+extern void nspr_InitializePRErrorTable(void);
+#define ERROR_TABLE_BASE_nspr (-6000L)
+
+#endif /* prerr_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prerror.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prerror.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,326 @@
+/* -*- 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 prerror_h___
+#define prerror_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef PRInt32 PRErrorCode;
+
+#define PR_NSPR_ERROR_BASE -6000
+
+#include "prerr.h"
+
+/*
+** Set error will preserve an error condition within a thread context.
+** The values stored are the NSPR (platform independent) translation of
+** the error. Also, if available, the platform specific oserror is stored.
+** If there is no appropriate OS error number, a zero my be supplied.
+*/
+NSPR_API(void) PR_SetError(PRErrorCode errorCode, PRInt32 oserr);
+
+/*
+** The text value specified may be NULL. If it is not NULL and the text length
+** is zero, the string is assumed to be a null terminated C string. Otherwise
+** the text is assumed to be the length specified and possibly include NULL
+** characters (e.g., a multi-national string).
+**
+** The text will be copied into to thread structure and remain there
+** until the next call to PR_SetError.
+*/
+NSPR_API(void) PR_SetErrorText(
+    PRIntn textLength, const char *text);
+
+/*
+** Return the current threads last set error code.
+*/
+NSPR_API(PRErrorCode) PR_GetError(void);
+
+/*
+** Return the current threads last set os error code. This is used for
+** machine specific code that desires the underlying os error.
+*/
+NSPR_API(PRInt32) PR_GetOSError(void);
+
+/*
+** Get the length of the error text. If a zero is returned, then there
+** is no text. Otherwise, the value returned is sufficient to contain
+** the error text currently available.
+*/
+NSPR_API(PRInt32) PR_GetErrorTextLength(void);
+
+/*
+** Copy the current threads current error text. Then actual number of bytes
+** copied is returned as the result. If the result is zero, the 'text' area
+** is unaffected.
+*/
+NSPR_API(PRInt32) PR_GetErrorText(char *text);
+
+
+/*
+Copyright (C) 1987, 1988 Student Information Processing Board of the
+Massachusetts Institute of Technology.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+used in advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.  M.I.T. and the M.I.T. S.I.P.B.
+make no representations about the suitability of this software for any
+purpose.  It is provided "as is" without express or implied warranty.
+*/
+
+
+/*
+ * NOTE:
+ *		The interfaces for error-code-translation described in the rest of
+ *		this file are preliminary in the 3.1 release of nspr and are subject 
+ *		to change in future releases.
+ */
+
+/*
+** Description:	Localizable error code to string function.
+**
+**
+** NSPR provides a mechanism for converting an error code to a
+** descriptive string, in a caller-specified language.
+**
+** Error codes themselves are 32 bit (signed) integers.  Typically,
+** the high order 24 bits are an identifier of which error table the
+** error code is from, and the low order 8 bits are a sequential error
+** number within the table.  NSPR supports error tables whose first
+** error code is not a multiple of 256, such error code assignments
+** should be avoided when possible.
+**
+** Error table 0 is defined to match the UNIX system call error table
+** (sys_errlist); this allows errno values to be used directly in the
+** library.  Other error table numbers are typically formed by
+** compacting together the first four characters of the error table
+** name.  The mapping between characters in the name and numeric
+** values in the error code are defined in a system-independent
+** fashion, so that two systems that can pass integral values between
+** them can reliably pass error codes without loss of meaning; this
+** should work even if the character sets used are not the
+** same. (However, if this is to be done, error table 0 should be
+** avoided, since the local system call error tables may differ.)
+**
+** Libraries defining error codes need only provide a table mapping
+** error code numbers to names and default English descriptions,
+** calling a routine to install the table, making it ``known'' to NSPR
+** library.  Once installed, a table may not be removed.  Any error
+** code the library generates can be converted to the corresponding
+** error message.  There is also a default format for error codes
+** accidentally returned before making the table known, which is of
+** the form "unknown code foo 32", where "foo" would be the name of
+** the table.
+**
+** Normally, the error code conversion routine only supports the
+** languages "i-default" and "en", returning the error-table-provided
+** English description for both languages.  The application may
+** provide a localization plugin, allowing support for additional
+** languages.
+**
+**/
+
+/**********************************************************************/
+/************************* TYPES AND CONSTANTS ************************/
+/**********************************************************************/
+
+/*
+ * PRLanguageCode --
+ *
+ *    NSPR represents a language code as a non-negative integer.
+ *    Languages 0 is always "i-default" the language you get without
+ *    explicit negotiation.  Language 1 is always "en", English
+ *    which has been explicitly negotiated.  Additional language
+ *    codes are defined by an application-provided localization plugin.
+ */
+typedef PRUint32 PRLanguageCode;
+#define PR_LANGUAGE_I_DEFAULT 0 /* i-default, the default language */
+#define PR_LANGUAGE_EN 1 /* English, explicitly negotiated */
+
+/*
+ * struct PRErrorMessage --
+ *
+ *    An error message in an error table.
+ */
+struct PRErrorMessage {
+    const char * name;    /* Macro name for error */
+    const char * en_text; /* Default English text */
+};
+
+/*
+ * struct PRErrorTable --
+ *
+ *    An error table, provided by a library.
+ */
+struct PRErrorTable {
+    const struct PRErrorMessage * msgs; /* Array of error information */
+    const char *name; /* Name of error table source */
+    PRErrorCode base; /* Error code for first error in table */
+    int n_msgs; /* Number of codes in table */
+};
+
+/*
+ * struct PRErrorCallbackPrivate --
+ *
+ *    A private structure for the localization plugin 
+ */
+struct PRErrorCallbackPrivate;
+
+/*
+ * struct PRErrorCallbackTablePrivate --
+ *
+ *    A data structure under which the localization plugin may store information,
+ *    associated with an error table, that is private to itself.
+ */
+struct PRErrorCallbackTablePrivate;
+
+/*
+ * PRErrorCallbackLookupFn --
+ *
+ *    A function of PRErrorCallbackLookupFn type is a localization
+ *    plugin callback which converts an error code into a description
+ *    in the requested language.  The callback is provided the
+ *    appropriate error table, private data for the plugin and the table.
+ *    The callback returns the appropriate UTF-8 encoded description, or NULL
+ *    if no description can be found.
+ */
+typedef const char *
+PRErrorCallbackLookupFn(PRErrorCode code, PRLanguageCode language, 
+		   const struct PRErrorTable *table,
+		   struct PRErrorCallbackPrivate *cb_private,
+		   struct PRErrorCallbackTablePrivate *table_private);
+
+/*
+ * PRErrorCallbackNewTableFn --
+ *
+ *    A function PRErrorCallbackNewTableFn type is a localization plugin
+ *    callback which is called once with each error table registered
+ *    with NSPR.  The callback is provided with the error table and
+ *    the plugin's private structure.  The callback returns any table private
+ *    data it wishes to associate with the error table.  Does not need to be thread
+ *    safe.
+ */
+typedef struct PRErrorCallbackTablePrivate *
+PRErrorCallbackNewTableFn(const struct PRErrorTable *table,
+			struct PRErrorCallbackPrivate *cb_private);
+
+/**********************************************************************/
+/****************************** FUNCTIONS *****************************/
+/**********************************************************************/
+
+/***********************************************************************
+** FUNCTION:    PR_ErrorToString
+** DESCRIPTION:
+**  Returns the UTF-8 message for an error code in
+**  the requested language.  May return the message
+**  in the default language if a translation in the requested
+**  language is not available.  The returned string is
+**  valid for the duration of the process.  Never returns NULL.
+**
+***********************************************************************/
+NSPR_API(const char *) PR_ErrorToString(PRErrorCode code,
+    PRLanguageCode language);
+
+
+/***********************************************************************
+** FUNCTION:    PR_ErrorToName
+** DESCRIPTION:
+**  Returns the macro name for an error code, or NULL
+**  if the error code is not known.  The returned string is
+**  valid for the duration of the process.
+**
+**  Does not work for error table 0, the system error codes.
+**
+***********************************************************************/
+NSPR_API(const char *) PR_ErrorToName(PRErrorCode code);
+
+
+/***********************************************************************
+** FUNCTION:    PR_ErrorLanguages
+** DESCRIPTION:
+**  Returns the RFC 1766 language tags for the language
+**  codes PR_ErrorToString() supports.  The returned array is valid
+**  for the duration of the process.  Never returns NULL.  The first
+**  item in the returned array is the language tag for PRLanguageCode 0,
+**  the second is for PRLanguageCode 1, and so on.  The array is terminated
+**  with a null pointer.
+**
+***********************************************************************/
+NSPR_API(const char * const *) PR_ErrorLanguages(void);
+
+
+/***********************************************************************
+** FUNCTION:    PR_ErrorInstallTable
+** DESCRIPTION:
+**  Registers an error table with NSPR.  Must be done exactly once per
+**  table.  Memory pointed to by `table' must remain valid for the life
+**  of the process.
+**
+**  NOT THREAD SAFE!
+**  
+***********************************************************************/
+NSPR_API(PRErrorCode) PR_ErrorInstallTable(const struct PRErrorTable *table);
+
+
+/***********************************************************************
+** FUNCTION:    PR_ErrorInstallCallback
+** DESCRIPTION:
+**  Registers an error localization plugin with NSPR.  May be called
+**  at most one time.  `languages' contains the language codes supported
+**  by this plugin.  Languages 0 and 1 must be "i-default" and "en"
+**  respectively.  `lookup' and `newtable' contain pointers to
+**  the plugin callback functions.  `cb_private' contains any information
+**  private to the plugin functions.
+**
+**  NOT THREAD SAFE!
+**
+***********************************************************************/
+NSPR_API(void) PR_ErrorInstallCallback(const char * const * languages,
+			      PRErrorCallbackLookupFn *lookup, 
+			      PRErrorCallbackNewTableFn *newtable,
+			      struct PRErrorCallbackPrivate *cb_private);
+
+PR_END_EXTERN_C
+
+#endif /* prerror_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prinet.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prinet.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,122 @@
+/* -*- 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:		prinet.h
+ * Description:
+ *     Header file used to find the system header files for socket support.
+ *     This file serves the following purposes:
+ *     - A cross-platform, "get-everything" socket header file.  On
+ *       Unix, socket support is scattered in several header files,
+ *       while Windows and Mac have a "get-everything" socket header
+ *       file.
+ *     - NSPR needs the following macro definitions and function
+ *       prototype declarations from these header files:
+ *           AF_INET
+ *           INADDR_ANY, INADDR_LOOPBACK, INADDR_BROADCAST
+ *           ntohl(), ntohs(), htonl(), ntons().
+ *       NSPR does not define its own versions of these macros and
+ *       functions.  It simply uses the native versions, which have
+ *       the same names on all supported platforms.
+ *     This file is intended to be included by nspr20 public header
+ *     files, such as prio.h.  One should not include this file directly.
+ */
+
+#ifndef prinet_h__
+#define prinet_h__
+
+#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
+#include <sys/types.h>
+#include <sys/socket.h>		/* AF_INET */
+#include <netinet/in.h>         /* INADDR_ANY, ..., ntohl(), ... */
+#ifdef XP_OS2
+#include <sys/ioctl.h>
+#endif
+#ifdef XP_UNIX
+#ifdef AIX
+/*
+ * On AIX 4.3, the header <arpa/inet.h> refers to struct
+ * ether_addr and struct sockaddr_dl that are not declared.
+ * The following struct declarations eliminate the compiler
+ * warnings.
+ */
+struct ether_addr;
+struct sockaddr_dl;
+#endif /* AIX */
+#include <arpa/inet.h>
+#endif /* XP_UNIX */
+#include <netdb.h>
+
+#if defined(FREEBSD) || defined(BSDI) || defined(QNX)
+#include <rpc/types.h> /* the only place that defines INADDR_LOOPBACK */
+#endif
+
+/*
+ * OS/2 hack.  For some reason INADDR_LOOPBACK is not defined in the
+ * socket headers.
+ */
+#if defined(OS2) && !defined(INADDR_LOOPBACK)
+#define INADDR_LOOPBACK 0x7f000001
+#endif
+
+/*
+ * Prototypes of ntohl() etc. are declared in <machine/endian.h>
+ * on these platforms.
+ */
+#if defined(BSDI) || defined(OSF1)
+#include <machine/endian.h>
+#endif
+
+#elif defined(WIN32)
+
+/* Do not include any system header files. */
+
+#elif defined(WIN16)
+
+#include <winsock.h>
+
+#elif defined(XP_MAC)
+
+#include "macsocket.h"
+
+#else
+
+#error Unknown platform
+
+#endif
+
+#endif /* prinet_h__ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prinit.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prinit.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,242 @@
+/* -*- 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 prinit_h___
+#define prinit_h___
+
+#include "prthread.h"
+#include "prtypes.h"
+#include "prwin16.h"
+#include <stdio.h>
+
+PR_BEGIN_EXTERN_C
+
+/************************************************************************/
+/**************************IDENTITY AND VERSIONING***********************/
+/************************************************************************/
+
+/*
+** NSPR's name, this should persist until at least the turn of the
+** century.
+*/
+#define PR_NAME     "NSPR"
+
+/*
+** NSPR's version is used to determine the likelihood that the version you
+** used to build your component is anywhere close to being compatible with
+** what is in the underlying library.
+**
+** The format of the version string is
+**     "<major version>.<minor version>[.<patch level>] [<Beta>]"
+*/
+#define PR_VERSION  "4.7 Beta"
+#define PR_VMAJOR   4
+#define PR_VMINOR   7
+#define PR_VPATCH   0
+#define PR_BETA     PR_TRUE
+
+/*
+** PRVersionCheck
+**
+** The basic signature of the function that is called to provide version
+** checking. The result will be a boolean that indicates the likelihood
+** that the underling library will perform as the caller expects.
+**
+** The only argument is a string, which should be the verson identifier
+** of the library in question. That string will be compared against an
+** equivalent string that represents the actual build version of the
+** exporting library.
+**
+** The result will be the logical union of the directly called library
+** and all dependent libraries.
+*/
+
+typedef PRBool (*PRVersionCheck)(const char*);
+
+/*
+** PR_VersionCheck
+**
+** NSPR's existance proof of the version check function.
+**
+** Note that NSPR has no cooperating dependencies.
+*/
+
+NSPR_API(PRBool) PR_VersionCheck(const char *importedVersion);
+
+
+/************************************************************************/
+/*******************************INITIALIZATION***************************/
+/************************************************************************/
+
+/*
+** Initialize the runtime. Attach a thread object to the currently
+** executing native thread of type "type".
+**
+** The specificaiton of 'maxPTDs' is ignored.
+*/
+NSPR_API(void) PR_Init(
+    PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs);
+
+/*
+** And alternate form of initialization, one that may become the default if
+** not the only mechanism, provides a method to get the NSPR runtime init-
+** ialized and place NSPR between the caller and the runtime library. This
+** allows main() to be treated as any other thread root function, signalling
+** its compeletion by returning and allowing the runtime to coordinate the
+** completion of the other threads of the runtime.
+**
+** The priority of the main (or primordial) thread will be PR_PRIORITY_NORMAL.
+** The thread may adjust its own priority by using PR_SetPriority(), though
+** at this time the support for priorities is somewhat weak.
+**
+** The specificaiton of 'maxPTDs' is ignored.
+**
+** The value returned by PR_Initialize is the value returned from the root
+** function, 'prmain'.
+*/
+
+typedef PRIntn (PR_CALLBACK *PRPrimordialFn)(PRIntn argc, char **argv);
+
+NSPR_API(PRIntn) PR_Initialize(
+    PRPrimordialFn prmain, PRIntn argc, char **argv, PRUintn maxPTDs);
+
+/*
+** Return PR_TRUE if PR_Init has already been called.
+*/
+NSPR_API(PRBool) PR_Initialized(void);
+
+/*
+ * Perform a graceful shutdown of NSPR.  PR_Cleanup() may be called by
+ * the primordial thread near the end of the main() function.
+ *
+ * PR_Cleanup() attempts to synchronize the natural termination of
+ * process.  It does that by blocking the caller, if and only if it is
+ * the primordial thread, until the number of user threads has dropped
+ * to zero.  When the primordial thread returns from main(), the process
+ * will immediately and silently exit.  That is, it will (if necessary)
+ * forcibly terminate any existing threads and exit without significant
+ * blocking and there will be no error messages or core files.
+ *
+ * PR_Cleanup() returns PR_SUCCESS if NSPR is successfully shutdown,
+ * or PR_FAILURE if the calling thread of this function is not the
+ * primordial thread.
+ */
+NSPR_API(PRStatus) PR_Cleanup(void);
+
+/*
+** Disable Interrupts
+**		Disables timer signals used for pre-emptive scheduling.
+*/
+NSPR_API(void) PR_DisableClockInterrupts(void);
+
+/*
+** Enables Interrupts
+**		Enables timer signals used for pre-emptive scheduling.
+*/
+NSPR_API(void) PR_EnableClockInterrupts(void);
+
+/*
+** Block Interrupts
+**		Blocks the timer signal used for pre-emptive scheduling
+*/
+NSPR_API(void) PR_BlockClockInterrupts(void);
+
+/*
+** Unblock Interrupts
+**		Unblocks the timer signal used for pre-emptive scheduling
+*/
+NSPR_API(void) PR_UnblockClockInterrupts(void);
+
+/*
+** Create extra virtual processor threads. Generally used with MP systems.
+*/
+NSPR_API(void) PR_SetConcurrency(PRUintn numCPUs);
+
+/*
+** Control the method and size of the file descriptor (PRFileDesc*)
+** cache used by the runtime. Setting 'high' to zero is for performance,
+** any other value probably for debugging (see memo on FD caching).
+*/
+NSPR_API(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high);
+
+/*
+ * Cause an immediate, nongraceful, forced termination of the process.
+ * It takes a PRIntn argument, which is the exit status code of the
+ * process.
+ */
+NSPR_API(void) PR_ProcessExit(PRIntn status);
+
+/*
+** Abort the process in a non-graceful manner. This will cause a core file,
+** call to the debugger or other moral equivalent as well as causing the
+** entire process to stop.
+*/
+NSPR_API(void) PR_Abort(void);
+
+/*
+ ****************************************************************
+ *
+ * Module initialization:
+ *
+ ****************************************************************
+ */
+
+typedef struct PRCallOnceType {
+    PRIntn initialized;
+    PRInt32 inProgress;
+    PRStatus status;
+} PRCallOnceType;
+
+typedef PRStatus (PR_CALLBACK *PRCallOnceFN)(void);
+
+typedef PRStatus (PR_CALLBACK *PRCallOnceWithArgFN)(void *arg);
+
+NSPR_API(PRStatus) PR_CallOnce(
+    PRCallOnceType *once,
+    PRCallOnceFN    func
+);
+
+NSPR_API(PRStatus) PR_CallOnceWithArg(
+    PRCallOnceType      *once,
+    PRCallOnceWithArgFN  func,
+    void                *arg
+);
+
+
+PR_END_EXTERN_C
+
+#endif /* prinit_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prinrval.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prinrval.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,175 @@
+/* -*- 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:		prinrval.h
+** Description:	API to interval timing functions of NSPR.
+**
+**
+** NSPR provides interval times that are independent of network time
+** of day values. Interval times are (in theory) accurate regardless
+** of host processing requirements and also very cheap to acquire. It
+** is expected that getting an interval time while in a synchronized
+** function (holding one's lock).
+**/
+
+#if !defined(prinrval_h)
+#define prinrval_h
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/**********************************************************************/
+/************************* TYPES AND CONSTANTS ************************/
+/**********************************************************************/
+
+typedef PRUint32 PRIntervalTime;
+
+/***********************************************************************
+** DEFINES:     PR_INTERVAL_MIN
+**              PR_INTERVAL_MAX
+** DESCRIPTION:
+**  These two constants define the range (in ticks / second) of the
+**  platform dependent type, PRIntervalTime. These constants bound both
+**  the period and the resolution of a PRIntervalTime. 
+***********************************************************************/
+#define PR_INTERVAL_MIN 1000UL
+#define PR_INTERVAL_MAX 100000UL
+
+/***********************************************************************
+** DEFINES:     PR_INTERVAL_NO_WAIT
+**              PR_INTERVAL_NO_TIMEOUT
+** DESCRIPTION:
+**  Two reserved constants are defined in the PRIntervalTime namespace.
+**  They are used to indicate that the process should wait no time (return
+**  immediately) or wait forever (never time out), respectively.
+***********************************************************************/
+#define PR_INTERVAL_NO_WAIT 0UL
+#define PR_INTERVAL_NO_TIMEOUT 0xffffffffUL
+
+/**********************************************************************/
+/****************************** FUNCTIONS *****************************/
+/**********************************************************************/
+
+/***********************************************************************
+** FUNCTION:    PR_IntervalNow
+** DESCRIPTION:
+**  Return the value of NSPR's free running interval timer. That timer
+**  can be used to establish epochs and determine intervals (be computing
+**  the difference between two times).
+** INPUTS:      void
+** OUTPUTS:     void
+** RETURN:      PRIntervalTime
+**  
+** SIDE EFFECTS:
+**  None
+** RESTRICTIONS:
+**  The units of PRIntervalTime are platform dependent. They are chosen
+**  such that they are appropriate for the host OS, yet provide sufficient
+**  resolution and period to be useful to clients. 
+** MEMORY:      N/A
+** ALGORITHM:   Platform dependent
+***********************************************************************/
+NSPR_API(PRIntervalTime) PR_IntervalNow(void);
+
+/***********************************************************************
+** FUNCTION:    PR_TicksPerSecond
+** DESCRIPTION:
+**  Return the number of ticks per second for PR_IntervalNow's clock.
+**  The value will be in the range [PR_INTERVAL_MIN..PR_INTERVAL_MAX].
+** INPUTS:      void
+** OUTPUTS:     void
+** RETURN:      PRUint32
+**  
+** SIDE EFFECTS:
+**  None
+** RESTRICTIONS:
+**  None
+** MEMORY:      N/A
+** ALGORITHM:   N/A
+***********************************************************************/
+NSPR_API(PRUint32) PR_TicksPerSecond(void);
+
+/***********************************************************************
+** FUNCTION:    PR_SecondsToInterval
+**              PR_MillisecondsToInterval
+**              PR_MicrosecondsToInterval
+** DESCRIPTION:
+**  Convert standard clock units to platform dependent intervals.
+** INPUTS:      PRUint32
+** OUTPUTS:     void
+** RETURN:      PRIntervalTime
+**  
+** SIDE EFFECTS:
+**  None
+** RESTRICTIONS:
+**  Conversion may cause overflow, which is not reported.
+** MEMORY:      N/A
+** ALGORITHM:   N/A
+***********************************************************************/
+NSPR_API(PRIntervalTime) PR_SecondsToInterval(PRUint32 seconds);
+NSPR_API(PRIntervalTime) PR_MillisecondsToInterval(PRUint32 milli);
+NSPR_API(PRIntervalTime) PR_MicrosecondsToInterval(PRUint32 micro);
+
+/***********************************************************************
+** FUNCTION:    PR_IntervalToSeconds
+**              PR_IntervalToMilliseconds
+**              PR_IntervalToMicroseconds
+** DESCRIPTION:
+**  Convert platform dependent intervals to standard clock units.
+** INPUTS:      PRIntervalTime
+** OUTPUTS:     void
+** RETURN:      PRUint32
+**  
+** SIDE EFFECTS:
+**  None
+** RESTRICTIONS:
+**  Conversion may cause overflow, which is not reported.
+** MEMORY:      N/A
+** ALGORITHM:   N/A
+***********************************************************************/
+NSPR_API(PRUint32) PR_IntervalToSeconds(PRIntervalTime ticks);
+NSPR_API(PRUint32) PR_IntervalToMilliseconds(PRIntervalTime ticks);
+NSPR_API(PRUint32) PR_IntervalToMicroseconds(PRIntervalTime ticks);
+
+PR_END_EXTERN_C
+
+
+#endif /* !defined(prinrval_h) */
+
+/* prinrval.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prio.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prio.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2030 @@
+/* -*- 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:     prio.h
+ *
+ * Description:    PR i/o related stuff, such as file system access, file
+ *         i/o, socket i/o, etc.
+ */
+
+#ifndef prio_h___
+#define prio_h___
+
+#include "prlong.h"
+#include "prtime.h"
+#include "prinrval.h"
+#include "prinet.h"
+
+PR_BEGIN_EXTERN_C
+
+/* Typedefs */
+typedef struct PRDir            PRDir;
+typedef struct PRDirEntry       PRDirEntry;
+#ifdef MOZ_UNICODE
+typedef struct PRDirUTF16       PRDirUTF16;
+typedef struct PRDirEntryUTF16  PRDirEntryUTF16;
+#endif /* MOZ_UNICODE */
+typedef struct PRFileDesc       PRFileDesc;
+typedef struct PRFileInfo       PRFileInfo;
+typedef struct PRFileInfo64     PRFileInfo64;
+typedef union  PRNetAddr        PRNetAddr;
+typedef struct PRIOMethods      PRIOMethods;
+typedef struct PRPollDesc       PRPollDesc;
+typedef struct PRFilePrivate    PRFilePrivate;
+typedef struct PRSendFileData   PRSendFileData;
+
+/*
+***************************************************************************
+** The file descriptor.
+** This is the primary structure to represent any active open socket,
+** whether it be a normal file or a network connection. Such objects
+** are stackable (or layerable). Each layer may have its own set of
+** method pointers and context private to that layer. All each layer
+** knows about its neighbors is how to get to their method table.
+***************************************************************************
+*/
+
+typedef PRIntn PRDescIdentity;          /* see: Layering file descriptors */
+
+struct PRFileDesc {
+    const PRIOMethods *methods;         /* the I/O methods table */
+    PRFilePrivate *secret;              /* layer dependent data */
+    PRFileDesc *lower, *higher;         /* pointers to adjacent layers */
+    void (PR_CALLBACK *dtor)(PRFileDesc *fd);
+                                        /* A destructor function for layer */
+    PRDescIdentity identity;            /* Identity of this particular layer  */
+};
+
+/*
+***************************************************************************
+** PRTransmitFileFlags
+**
+** Flags for PR_TransmitFile.  Pass PR_TRANSMITFILE_CLOSE_SOCKET to
+** PR_TransmitFile if the connection should be closed after the file
+** is transmitted.
+***************************************************************************
+*/
+typedef enum PRTransmitFileFlags {
+    PR_TRANSMITFILE_KEEP_OPEN = 0,    /* socket is left open after file
+                                       * is transmitted. */
+    PR_TRANSMITFILE_CLOSE_SOCKET = 1  /* socket is closed after file
+                                       * is transmitted. */
+} PRTransmitFileFlags;
+
+/*
+**************************************************************************
+** Macros for PRNetAddr
+**
+** Address families: PR_AF_INET, PR_AF_INET6, PR_AF_LOCAL
+** IP addresses: PR_INADDR_ANY, PR_INADDR_LOOPBACK, PR_INADDR_BROADCAST
+**************************************************************************
+*/
+
+#ifdef WIN32
+
+#define PR_AF_INET 2
+#define PR_AF_LOCAL 1
+#define PR_INADDR_ANY (unsigned long)0x00000000
+#define PR_INADDR_LOOPBACK 0x7f000001
+#define PR_INADDR_BROADCAST (unsigned long)0xffffffff
+
+#else /* WIN32 */
+
+#define PR_AF_INET AF_INET
+#define PR_AF_LOCAL AF_UNIX
+#define PR_INADDR_ANY INADDR_ANY
+#define PR_INADDR_LOOPBACK INADDR_LOOPBACK
+#define PR_INADDR_BROADCAST INADDR_BROADCAST
+
+#endif /* WIN32 */
+
+/*
+** Define PR_AF_INET6 in prcpucfg.h with the same
+** value as AF_INET6 on platforms with IPv6 support.
+** Otherwise define it here.
+*/
+#ifndef PR_AF_INET6
+#define PR_AF_INET6 100
+#endif
+
+#ifndef PR_AF_UNSPEC
+#define PR_AF_UNSPEC 0
+#endif
+
+/*
+**************************************************************************
+** A network address
+**
+** Only Internet Protocol (IPv4 and IPv6) addresses are supported.
+** The address family must always represent IPv4 (AF_INET, probably == 2)
+** or IPv6 (AF_INET6).
+**************************************************************************
+*************************************************************************/
+
+struct PRIPv6Addr {
+	union {
+		PRUint8  _S6_u8[16];
+		PRUint16 _S6_u16[8];
+		PRUint32 _S6_u32[4];
+		PRUint64 _S6_u64[2];
+	} _S6_un;
+};
+#define pr_s6_addr		_S6_un._S6_u8
+#define pr_s6_addr16	_S6_un._S6_u16
+#define pr_s6_addr32	_S6_un._S6_u32
+#define pr_s6_addr64 	_S6_un._S6_u64
+
+typedef struct PRIPv6Addr PRIPv6Addr;
+
+union PRNetAddr {
+    struct {
+        PRUint16 family;                /* address family (0x00ff maskable) */
+#ifdef XP_BEOS
+        char data[10];                  /* Be has a smaller structure */
+#else
+        char data[14];                  /* raw address data */
+#endif
+    } raw;
+    struct {
+        PRUint16 family;                /* address family (AF_INET) */
+        PRUint16 port;                  /* port number */
+        PRUint32 ip;                    /* The actual 32 bits of address */
+#ifdef XP_BEOS
+        char pad[4];                    /* Be has a smaller structure */
+#else
+        char pad[8];
+#endif
+    } inet;
+    struct {
+        PRUint16 family;                /* address family (AF_INET6) */
+        PRUint16 port;                  /* port number */
+        PRUint32 flowinfo;              /* routing information */
+        PRIPv6Addr ip;                  /* the actual 128 bits of address */
+        PRUint32 scope_id;              /* set of interfaces for a scope */
+    } ipv6;
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+    struct {                            /* Unix domain socket address */
+        PRUint16 family;                /* address family (AF_UNIX) */
+#ifdef XP_OS2
+        char path[108];                 /* null-terminated pathname */
+                                        /* bind fails if size is not 108. */
+#else
+        char path[104];                 /* null-terminated pathname */
+#endif
+    } local;
+#endif
+};
+
+/*
+***************************************************************************
+** PRSockOption
+**
+** The file descriptors can have predefined options set after they file
+** descriptor is created to change their behavior. Only the options in
+** the following enumeration are supported.
+***************************************************************************
+*/
+typedef enum PRSockOption
+{
+    PR_SockOpt_Nonblocking,     /* nonblocking io */
+    PR_SockOpt_Linger,          /* linger on close if data present */
+    PR_SockOpt_Reuseaddr,       /* allow local address reuse */
+    PR_SockOpt_Keepalive,       /* keep connections alive */
+    PR_SockOpt_RecvBufferSize,  /* send buffer size */
+    PR_SockOpt_SendBufferSize,  /* receive buffer size */
+
+    PR_SockOpt_IpTimeToLive,    /* time to live */
+    PR_SockOpt_IpTypeOfService, /* type of service and precedence */
+
+    PR_SockOpt_AddMember,       /* add an IP group membership */
+    PR_SockOpt_DropMember,      /* drop an IP group membership */
+    PR_SockOpt_McastInterface,  /* multicast interface address */
+    PR_SockOpt_McastTimeToLive, /* multicast timetolive */
+    PR_SockOpt_McastLoopback,   /* multicast loopback */
+
+    PR_SockOpt_NoDelay,         /* don't delay send to coalesce packets */
+    PR_SockOpt_MaxSegment,      /* maximum segment size */
+    PR_SockOpt_Broadcast,       /* enable broadcast */
+    PR_SockOpt_Last
+} PRSockOption;
+
+typedef struct PRLinger {
+	PRBool polarity;		    /* Polarity of the option's setting */
+	PRIntervalTime linger;	    /* Time to linger before closing */
+} PRLinger;
+
+typedef struct PRMcastRequest {
+	PRNetAddr mcaddr;			/* IP multicast address of group */
+	PRNetAddr ifaddr;			/* local IP address of interface */
+} PRMcastRequest;
+
+typedef struct PRSocketOptionData
+{
+    PRSockOption option;
+    union
+    {
+        PRUintn ip_ttl;             /* IP time to live */
+        PRUintn mcast_ttl;          /* IP multicast time to live */
+        PRUintn tos;                /* IP type of service and precedence */
+        PRBool non_blocking;        /* Non-blocking (network) I/O */
+        PRBool reuse_addr;          /* Allow local address reuse */
+        PRBool keep_alive;          /* Keep connections alive */
+        PRBool mcast_loopback;      /* IP multicast loopback */
+        PRBool no_delay;            /* Don't delay send to coalesce packets */
+        PRBool broadcast;           /* Enable broadcast */
+        PRSize max_segment;         /* Maximum segment size */
+        PRSize recv_buffer_size;    /* Receive buffer size */
+        PRSize send_buffer_size;    /* Send buffer size */
+        PRLinger linger;            /* Time to linger on close if data present */
+        PRMcastRequest add_member;  /* add an IP group membership */
+        PRMcastRequest drop_member; /* Drop an IP group membership */
+        PRNetAddr mcast_if;         /* multicast interface address */
+    } value;
+} PRSocketOptionData;
+
+/*
+***************************************************************************
+** PRIOVec
+**
+** The I/O vector is used by the write vector method to describe the areas
+** that are affected by the ouput operation.
+***************************************************************************
+*/
+typedef struct PRIOVec {
+    char *iov_base;
+    int iov_len;
+} PRIOVec;
+
+/*
+***************************************************************************
+** Discover what type of socket is being described by the file descriptor.
+***************************************************************************
+*/
+typedef enum PRDescType
+{
+    PR_DESC_FILE = 1,
+    PR_DESC_SOCKET_TCP = 2,
+    PR_DESC_SOCKET_UDP = 3,
+    PR_DESC_LAYERED = 4,
+    PR_DESC_PIPE = 5
+} PRDescType;
+
+typedef enum PRSeekWhence {
+    PR_SEEK_SET = 0,
+    PR_SEEK_CUR = 1,
+    PR_SEEK_END = 2
+} PRSeekWhence;
+
+NSPR_API(PRDescType) PR_GetDescType(PRFileDesc *file);
+
+/*
+***************************************************************************
+** PRIOMethods
+**
+** The I/O methods table provides procedural access to the functions of
+** the file descriptor. It is the responsibility of a layer implementor
+** to provide suitable functions at every entry point. If a layer provides
+** no functionality, it should call the next lower(higher) function of the
+** same name (e.g., return fd->lower->method->close(fd->lower));
+**
+** Not all functions are implemented for all types of files. In cases where
+** that is true, the function will return a error indication with an error
+** code of PR_INVALID_METHOD_ERROR.
+***************************************************************************
+*/
+
+typedef PRStatus (PR_CALLBACK *PRCloseFN)(PRFileDesc *fd);
+typedef PRInt32 (PR_CALLBACK *PRReadFN)(PRFileDesc *fd, void *buf, PRInt32 amount);
+typedef PRInt32 (PR_CALLBACK *PRWriteFN)(PRFileDesc *fd, const void *buf, PRInt32 amount);
+typedef PRInt32 (PR_CALLBACK *PRAvailableFN)(PRFileDesc *fd);
+typedef PRInt64 (PR_CALLBACK *PRAvailable64FN)(PRFileDesc *fd);
+typedef PRStatus (PR_CALLBACK *PRFsyncFN)(PRFileDesc *fd);
+typedef PROffset32 (PR_CALLBACK *PRSeekFN)(PRFileDesc *fd, PROffset32 offset, PRSeekWhence how);
+typedef PROffset64 (PR_CALLBACK *PRSeek64FN)(PRFileDesc *fd, PROffset64 offset, PRSeekWhence how);
+typedef PRStatus (PR_CALLBACK *PRFileInfoFN)(PRFileDesc *fd, PRFileInfo *info);
+typedef PRStatus (PR_CALLBACK *PRFileInfo64FN)(PRFileDesc *fd, PRFileInfo64 *info);
+typedef PRInt32 (PR_CALLBACK *PRWritevFN)(
+    PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
+    PRIntervalTime timeout);
+typedef PRStatus (PR_CALLBACK *PRConnectFN)(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout);
+typedef PRFileDesc* (PR_CALLBACK *PRAcceptFN) (
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout);
+typedef PRStatus (PR_CALLBACK *PRBindFN)(PRFileDesc *fd, const PRNetAddr *addr);
+typedef PRStatus (PR_CALLBACK *PRListenFN)(PRFileDesc *fd, PRIntn backlog);
+typedef PRStatus (PR_CALLBACK *PRShutdownFN)(PRFileDesc *fd, PRIntn how);
+typedef PRInt32 (PR_CALLBACK *PRRecvFN)(
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout);
+typedef PRInt32 (PR_CALLBACK *PRSendFN) (
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout);
+typedef PRInt32 (PR_CALLBACK *PRRecvfromFN)(
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout);
+typedef PRInt32 (PR_CALLBACK *PRSendtoFN)(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout);
+typedef PRInt16 (PR_CALLBACK *PRPollFN)(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
+typedef PRInt32 (PR_CALLBACK *PRAcceptreadFN)(
+    PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
+    void *buf, PRInt32 amount, PRIntervalTime t);
+typedef PRInt32 (PR_CALLBACK *PRTransmitfileFN)(
+     PRFileDesc *sd, PRFileDesc *fd, const void *headers,
+     PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime t);
+typedef PRStatus (PR_CALLBACK *PRGetsocknameFN)(PRFileDesc *fd, PRNetAddr *addr);
+typedef PRStatus (PR_CALLBACK *PRGetpeernameFN)(PRFileDesc *fd, PRNetAddr *addr);
+typedef PRStatus (PR_CALLBACK *PRGetsocketoptionFN)(
+    PRFileDesc *fd, PRSocketOptionData *data);
+typedef PRStatus (PR_CALLBACK *PRSetsocketoptionFN)(
+    PRFileDesc *fd, const PRSocketOptionData *data);
+typedef PRInt32 (PR_CALLBACK *PRSendfileFN)(
+	PRFileDesc *networkSocket, PRSendFileData *sendData,
+	PRTransmitFileFlags flags, PRIntervalTime timeout);
+typedef PRStatus (PR_CALLBACK *PRConnectcontinueFN)(
+    PRFileDesc *fd, PRInt16 out_flags);
+typedef PRIntn (PR_CALLBACK *PRReservedFN)(PRFileDesc *fd);
+
+struct PRIOMethods {
+    PRDescType file_type;           /* Type of file represented (tos)           */
+    PRCloseFN close;                /* close file and destroy descriptor        */
+    PRReadFN read;                  /* read up to specified bytes into buffer   */
+    PRWriteFN write;                /* write specified bytes from buffer        */
+    PRAvailableFN available;        /* determine number of bytes available      */
+    PRAvailable64FN available64;    /*          ditto, 64 bit                   */
+    PRFsyncFN fsync;                /* flush all buffers to permanent store     */
+    PRSeekFN seek;                  /* position the file to the desired place   */
+    PRSeek64FN seek64;              /*           ditto, 64 bit                  */
+    PRFileInfoFN fileInfo;          /* Get information about an open file       */
+    PRFileInfo64FN fileInfo64;      /*           ditto, 64 bit                  */
+    PRWritevFN writev;              /* Write segments as described by iovector  */
+    PRConnectFN connect;            /* Connect to the specified (net) address   */
+    PRAcceptFN accept;              /* Accept a connection for a (net) peer     */
+    PRBindFN bind;                  /* Associate a (net) address with the fd    */
+    PRListenFN listen;              /* Prepare to listen for (net) connections  */
+    PRShutdownFN shutdown;          /* Shutdown a (net) connection              */
+    PRRecvFN recv;                  /* Solicit up the the specified bytes       */
+    PRSendFN send;                  /* Send all the bytes specified             */
+    PRRecvfromFN recvfrom;          /* Solicit (net) bytes and report source    */
+    PRSendtoFN sendto;              /* Send bytes to (net) address specified    */
+    PRPollFN poll;                  /* Test the fd to see if it is ready        */
+    PRAcceptreadFN acceptread;      /* Accept and read on a new (net) fd        */
+    PRTransmitfileFN transmitfile;  /* Transmit at entire file                  */
+    PRGetsocknameFN getsockname;    /* Get (net) address associated with fd     */
+    PRGetpeernameFN getpeername;    /* Get peer's (net) address                 */
+    PRReservedFN reserved_fn_6;     /* reserved for future use */
+    PRReservedFN reserved_fn_5;     /* reserved for future use */
+    PRGetsocketoptionFN getsocketoption;
+                                    /* Get current setting of specified option  */
+    PRSetsocketoptionFN setsocketoption;
+                                    /* Set value of specified option            */
+    PRSendfileFN sendfile;			/* Send a (partial) file with header/trailer*/
+    PRConnectcontinueFN connectcontinue;
+                                    /* Continue a nonblocking connect */
+    PRReservedFN reserved_fn_3;		/* reserved for future use */
+    PRReservedFN reserved_fn_2;		/* reserved for future use */
+    PRReservedFN reserved_fn_1;		/* reserved for future use */
+    PRReservedFN reserved_fn_0;		/* reserved for future use */
+};
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_GetSpecialFD
+ * DESCRIPTION: Get the file descriptor that represents the standard input,
+ *              output, or error stream.
+ * INPUTS:
+ *     PRSpecialFD id
+ *         A value indicating the type of stream desired:
+ *             PR_StandardInput: standard input
+ *             PR_StandardOuput: standard output
+ *             PR_StandardError: standard error
+ * OUTPUTS: none
+ * RETURNS: PRFileDesc *
+ *     If the argument is valid, PR_GetSpecialFD returns a file descriptor
+ *     that represents the corresponding standard I/O stream.  Otherwise,
+ *     PR_GetSpecialFD returns NULL and sets error PR_INVALID_ARGUMENT_ERROR.
+ **************************************************************************
+ */
+
+typedef enum PRSpecialFD
+{
+    PR_StandardInput,          /* standard input */
+    PR_StandardOutput,         /* standard output */
+    PR_StandardError           /* standard error */
+} PRSpecialFD;
+
+NSPR_API(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD id);
+
+#define PR_STDIN	PR_GetSpecialFD(PR_StandardInput)
+#define PR_STDOUT	PR_GetSpecialFD(PR_StandardOutput)
+#define PR_STDERR	PR_GetSpecialFD(PR_StandardError)
+
+/*
+ **************************************************************************
+ * Layering file descriptors
+ *
+ * File descriptors may be layered. Each layer has it's own identity.
+ * Identities are allocated by the runtime and are to be associated
+ * (by the layer implementor) with all layers that are of that type.
+ * It is then possible to scan the chain of layers and find a layer
+ * that one recongizes and therefore predict that it will implement
+ * a desired protocol.
+ *
+ * There are three well-known identities:
+ *      PR_INVALID_IO_LAYER => an invalid layer identity, for error return
+ *      PR_TOP_IO_LAYER     => the identity of the top of the stack
+ *      PR_NSPR_IO_LAYER    => the identity used by NSPR proper
+ * PR_TOP_IO_LAYER may be used as a shorthand for identifying the topmost
+ * layer of an existing stack. Ie., the following two constructs are
+ * equivalent.
+ *
+ *      rv = PR_PushIOLayer(stack, PR_TOP_IO_LAYER, my_layer);
+ *      rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), my_layer)
+ *
+ * A string may be associated with the creation of the identity. It
+ * will be copied by the runtime. If queried the runtime will return
+ * a reference to that copied string (not yet another copy). There
+ * is no facility for deleting an identity.
+ **************************************************************************
+ */
+
+#define PR_IO_LAYER_HEAD (PRDescIdentity)-3
+#define PR_INVALID_IO_LAYER (PRDescIdentity)-1
+#define PR_TOP_IO_LAYER (PRDescIdentity)-2
+#define PR_NSPR_IO_LAYER (PRDescIdentity)0
+
+NSPR_API(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name);
+NSPR_API(const char*) PR_GetNameForIdentity(PRDescIdentity ident);
+NSPR_API(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd);
+NSPR_API(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd_stack, PRDescIdentity id);
+
+/*
+ **************************************************************************
+ * PR_GetDefaultIOMethods: Accessing the default methods table.
+ * You may get a pointer to the default methods table by calling this function.
+ * You may then select any elements from that table with which to build your
+ * layer's methods table. You may NOT modify the table directly.
+ **************************************************************************
+ */
+NSPR_API(const PRIOMethods *) PR_GetDefaultIOMethods(void);
+
+/*
+ **************************************************************************
+ * Creating a layer
+ *
+ * A new layer may be allocated by calling PR_CreateIOLayerStub(). The
+ * file descriptor returned will contain the pointer to the methods table
+ * provided. The runtime will not modify the table nor test its correctness.
+ **************************************************************************
+ */
+NSPR_API(PRFileDesc*) PR_CreateIOLayerStub(
+    PRDescIdentity ident, const PRIOMethods *methods);
+
+/*
+ **************************************************************************
+ * Creating a layer
+ *
+ * A new stack may be created by calling PR_CreateIOLayer(). The
+ * file descriptor returned will point to the top of the stack, which has
+ * the layer 'fd' as the topmost layer.
+ * 
+ * NOTE: This function creates a new style stack, which has a fixed, dummy
+ * header. The old style stack, created by a call to PR_PushIOLayer,
+ * results in modifying contents of the top layer of the stack, when
+ * pushing and popping layers of the stack.
+ **************************************************************************
+ */
+NSPR_API(PRFileDesc*) PR_CreateIOLayer(PRFileDesc* fd);
+
+/*
+ **************************************************************************
+ * Pushing a layer
+ *
+ * A file descriptor (perhaps allocated using PR_CreateIOLayerStub()) may
+ * be pushed into an existing stack of file descriptors at any point the
+ * caller deems appropriate. The new layer will be inserted into the stack
+ * just above the layer with the indicated identity.
+ *
+ * Note: Even if the identity parameter indicates the top-most layer of
+ * the stack, the value of the file descriptor describing the original
+ * stack will not change.
+ **************************************************************************
+ */
+NSPR_API(PRStatus) PR_PushIOLayer(
+    PRFileDesc *fd_stack, PRDescIdentity id, PRFileDesc *layer);
+
+/*
+ **************************************************************************
+ * Popping a layer
+ *
+ * A layer may be popped from a stack by indicating the identity of the
+ * layer to be removed. If found, a pointer to the removed object will
+ * be returned to the caller. The object then becomes the responsibility
+ * of the caller.
+ *
+ * Note: Even if the identity indicates the top layer of the stack, the
+ * reference returned will not be the file descriptor for the stack and
+ * that file descriptor will remain valid.
+ **************************************************************************
+ */
+NSPR_API(PRFileDesc*) PR_PopIOLayer(PRFileDesc *fd_stack, PRDescIdentity id);
+
+/*
+ **************************************************************************
+ * FUNCTION:    PR_Open
+ * DESCRIPTION:    Open a file for reading, writing, or both.
+ * INPUTS:
+ *     const char *name
+ *         The path name of the file to be opened
+ *     PRIntn flags
+ *         The file status flags.
+ *         It is a bitwise OR of the following bit flags (only one of
+ *         the first three flags below may be used):
+ *		PR_RDONLY        Open for reading only.
+ *		PR_WRONLY        Open for writing only.
+ *		PR_RDWR          Open for reading and writing.
+ *		PR_CREATE_FILE   If the file does not exist, the file is created
+ *                              If the file exists, this flag has no effect.
+ *      PR_SYNC          If set, each write will wait for both the file data
+ *                              and file status to be physically updated.
+ *		PR_APPEND        The file pointer is set to the end of
+ *                              the file prior to each write.
+ *		PR_TRUNCATE      If the file exists, its length is truncated to 0.
+ *      PR_EXCL          With PR_CREATE_FILE, if the file does not exist,
+ *                              the file is created. If the file already 
+ *                              exists, no action and NULL is returned
+ *
+ *     PRIntn mode
+ *         The access permission bits of the file mode, if the file is
+ *         created when PR_CREATE_FILE is on.
+ * OUTPUTS:    None
+ * RETURNS:    PRFileDesc *
+ *     If the file is successfully opened,
+ *     returns a pointer to the PRFileDesc
+ *     created for the newly opened file.
+ *     Returns a NULL pointer if the open
+ *     failed.
+ * SIDE EFFECTS:
+ * RESTRICTIONS:
+ * MEMORY:
+ *     The return value, if not NULL, points to a dynamically allocated
+ *     PRFileDesc object.
+ * ALGORITHM:
+ **************************************************************************
+ */
+
+/* Open flags */
+#define PR_RDONLY       0x01
+#define PR_WRONLY       0x02
+#define PR_RDWR         0x04
+#define PR_CREATE_FILE  0x08
+#define PR_APPEND       0x10
+#define PR_TRUNCATE     0x20
+#define PR_SYNC         0x40
+#define PR_EXCL         0x80
+
+/*
+** File modes ....
+**
+** CAVEAT: 'mode' is currently only applicable on UNIX platforms.
+** The 'mode' argument may be ignored by PR_Open on other platforms.
+**
+**   00400   Read by owner.
+**   00200   Write by owner.
+**   00100   Execute (search if a directory) by owner.
+**   00040   Read by group.
+**   00020   Write by group.
+**   00010   Execute by group.
+**   00004   Read by others.
+**   00002   Write by others
+**   00001   Execute by others.
+**
+*/
+
+NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_OpenFile
+ * DESCRIPTION:
+ *     Open a file for reading, writing, or both.
+ *     PR_OpenFile has the same prototype as PR_Open but implements
+ *     the specified file mode where possible.
+ **************************************************************************
+ */
+
+/* File mode bits */
+#define PR_IRWXU 00700  /* read, write, execute/search by owner */
+#define PR_IRUSR 00400  /* read permission, owner */
+#define PR_IWUSR 00200  /* write permission, owner */
+#define PR_IXUSR 00100  /* execute/search permission, owner */
+#define PR_IRWXG 00070  /* read, write, execute/search by group */
+#define PR_IRGRP 00040  /* read permission, group */
+#define PR_IWGRP 00020  /* write permission, group */
+#define PR_IXGRP 00010  /* execute/search permission, group */
+#define PR_IRWXO 00007  /* read, write, execute/search by others */
+#define PR_IROTH 00004  /* read permission, others */
+#define PR_IWOTH 00002  /* write permission, others */
+#define PR_IXOTH 00001  /* execute/search permission, others */
+
+NSPR_API(PRFileDesc*) PR_OpenFile(
+    const char *name, PRIntn flags, PRIntn mode);
+
+#ifdef MOZ_UNICODE
+/*
+ * EXPERIMENTAL: This function may be removed in a future release.
+ */
+NSPR_API(PRFileDesc*) PR_OpenFileUTF16(
+    const PRUnichar *name, PRIntn flags, PRIntn mode);
+#endif /* MOZ_UNICODE */
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_Close
+ * DESCRIPTION:
+ *     Close a file or socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         a pointer to a PRFileDesc.
+ * OUTPUTS:
+ *     None.
+ * RETURN:
+ *     PRStatus
+ * SIDE EFFECTS:
+ * RESTRICTIONS:
+ *     None.
+ * MEMORY:
+ *     The dynamic memory pointed to by the argument fd is freed.
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus)    PR_Close(PRFileDesc *fd);
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_Read
+ * DESCRIPTION:
+ *     Read bytes from a file or socket.
+ *     The operation will block until either an end of stream indication is
+ *     encountered, some positive number of bytes are transferred, or there
+ *     is an error. No more than 'amount' bytes will be transferred.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         pointer to the PRFileDesc object for the file or socket
+ *     void *buf
+ *         pointer to a buffer to hold the data read in.
+ *     PRInt32 amount
+ *         the size of 'buf' (in bytes)
+ * OUTPUTS:
+ * RETURN:
+ *     PRInt32
+ *         a positive number indicates the number of bytes actually read in.
+ *         0 means end of file is reached or the network connection is closed.
+ *         -1 indicates a failure. The reason for the failure is obtained
+ *         by calling PR_GetError().
+ * SIDE EFFECTS:
+ *     data is written into the buffer pointed to by 'buf'.
+ * RESTRICTIONS:
+ *     None.
+ * MEMORY:
+ *     N/A
+ * ALGORITHM:
+ *     N/A
+ **************************************************************************
+ */
+
+NSPR_API(PRInt32) PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount);
+
+/*
+ ***************************************************************************
+ * FUNCTION: PR_Write
+ * DESCRIPTION:
+ *     Write a specified number of bytes to a file or socket.  The thread
+ *     invoking this function blocks until all the data is written.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         pointer to a PRFileDesc object that refers to a file or socket
+ *     const void *buf
+ *         pointer to the buffer holding the data
+ *     PRInt32 amount
+ *         amount of data in bytes to be written from the buffer
+ * OUTPUTS:
+ *     None.
+ * RETURN: PRInt32
+ *     A positive number indicates the number of bytes successfully written.
+ *     A -1 is an indication that the operation failed. The reason
+ *     for the failure is obtained by calling PR_GetError().
+ ***************************************************************************
+ */
+
+NSPR_API(PRInt32) PR_Write(PRFileDesc *fd,const void *buf,PRInt32 amount);
+
+/*
+ ***************************************************************************
+ * FUNCTION: PR_Writev
+ * DESCRIPTION:
+ *     Write data to a socket.  The data is organized in a PRIOVec array. The
+ *     operation will block until all the data is written or the operation
+ *     fails.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         Pointer that points to a PRFileDesc object for a socket.
+ *     const PRIOVec *iov
+ *         An array of PRIOVec.  PRIOVec is a struct with the following
+ *         two fields:
+ *             char *iov_base;
+ *             int iov_len;
+ *     PRInt32 iov_size
+ *         Number of elements in the iov array. The value of this
+ *         argument must not be greater than PR_MAX_IOVECTOR_SIZE.
+ *         If it is, the method will fail (PR_BUFFER_OVERFLOW_ERROR).
+ *     PRIntervalTime timeout
+ *       Time limit for completion of the entire write operation.
+ * OUTPUTS:
+ *     None
+ * RETURN:
+ *     A positive number indicates the number of bytes successfully written.
+ *     A -1 is an indication that the operation failed. The reason
+ *     for the failure is obtained by calling PR_GetError().
+ ***************************************************************************
+ */
+
+#define PR_MAX_IOVECTOR_SIZE 16   /* 'iov_size' must be <= */
+
+NSPR_API(PRInt32) PR_Writev(
+    PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
+    PRIntervalTime timeout);
+
+/*
+ ***************************************************************************
+ * FUNCTION: PR_Delete
+ * DESCRIPTION:
+ *     Delete a file from the filesystem. The operation may fail if the
+ *     file is open.
+ * INPUTS:
+ *     const char *name
+ *         Path name of the file to be deleted.
+ * OUTPUTS:
+ *     None.
+ * RETURN: PRStatus
+ *     The function returns PR_SUCCESS if the file is successfully
+ *     deleted, otherwise it returns PR_FAILURE.
+ ***************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_Delete(const char *name);
+
+/**************************************************************************/
+
+typedef enum PRFileType
+{
+    PR_FILE_FILE = 1,
+    PR_FILE_DIRECTORY = 2,
+    PR_FILE_OTHER = 3
+} PRFileType;
+
+struct PRFileInfo {
+    PRFileType type;        /* Type of file */
+    PROffset32 size;        /* Size, in bytes, of file's contents */
+    PRTime creationTime;    /* Creation time per definition of PRTime */
+    PRTime modifyTime;      /* Last modification time per definition of PRTime */
+};
+
+struct PRFileInfo64 {
+    PRFileType type;        /* Type of file */
+    PROffset64 size;        /* Size, in bytes, of file's contents */
+    PRTime creationTime;    /* Creation time per definition of PRTime */
+    PRTime modifyTime;      /* Last modification time per definition of PRTime */
+};
+
+/****************************************************************************
+ * FUNCTION: PR_GetFileInfo, PR_GetFileInfo64
+ * DESCRIPTION:
+ *     Get the information about the file with the given path name. This is
+ *     applicable only to NSFileDesc describing 'file' types (see
+ * INPUTS:
+ *     const char *fn
+ *         path name of the file
+ * OUTPUTS:
+ *     PRFileInfo *info
+ *         Information about the given file is written into the file
+ *         information object pointer to by 'info'.
+ * RETURN: PRStatus
+ *     PR_GetFileInfo returns PR_SUCCESS if file information is successfully
+ *     obtained, otherwise it returns PR_FAILURE.
+ ***************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info);
+NSPR_API(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info);
+
+#ifdef MOZ_UNICODE
+/*
+ * EXPERIMENTAL: This function may be removed in a future release.
+ */
+NSPR_API(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info);
+#endif /* MOZ_UNICODE */
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_GetOpenFileInfo, PR_GetOpenFileInfo64
+ * DESCRIPTION:
+ *     Get information about an open file referred to by the
+ *     given PRFileDesc object.
+ * INPUTS:
+ *     const PRFileDesc *fd
+ *          A reference to a valid, open file.
+ * OUTPUTS:
+ *     Same as PR_GetFileInfo, PR_GetFileInfo64
+ * RETURN: PRStatus
+ *     PR_GetFileInfo returns PR_SUCCESS if file information is successfully
+ *     obtained, otherwise it returns PR_FAILURE.
+ ***************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_GetOpenFileInfo(PRFileDesc *fd, PRFileInfo *info);
+NSPR_API(PRStatus) PR_GetOpenFileInfo64(PRFileDesc *fd, PRFileInfo64 *info);
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_Rename
+ * DESCRIPTION:
+ *     Rename a file from the old name 'from' to the new name 'to'.
+ * INPUTS:
+ *     const char *from
+ *         The old name of the file to be renamed.
+ *     const char *to
+ *         The new name of the file.
+ * OUTPUTS:
+ *     None.
+ * RETURN: PRStatus
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus)    PR_Rename(const char *from, const char *to);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Access
+ * DESCRIPTION:
+ *     Determine accessibility of a file.
+ * INPUTS:
+ *     const char *name
+ *         path name of the file
+ *     PRAccessHow how
+ *         specifies which access permission to check for.
+ *         It can be one of the following values:
+ *             PR_ACCESS_READ_OK       Test for read permission
+ *             PR_ACCESS_WRITE_OK      Test for write permission
+ *             PR_ACCESS_EXISTS        Check existence of file
+ * OUTPUTS:
+ *     None.
+ * RETURN: PRStatus
+ *     PR_SUCCESS is returned if the requested access is permitted.
+ *     Otherwise, PR_FAILURE is returned. Additional information
+ *     regarding the reason for the failure may be retrieved from
+ *     PR_GetError().
+ *************************************************************************
+ */
+
+typedef enum PRAccessHow {
+    PR_ACCESS_EXISTS = 1,
+    PR_ACCESS_WRITE_OK = 2,
+    PR_ACCESS_READ_OK = 3
+} PRAccessHow;
+
+NSPR_API(PRStatus) PR_Access(const char *name, PRAccessHow how);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Seek, PR_Seek64
+ * DESCRIPTION:
+ *     Moves read-write file offset
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         Pointer to a PRFileDesc object.
+ *     PROffset32, PROffset64 offset
+ *         Specifies a value, in bytes, that is used in conjunction
+ *         with the 'whence' parameter to set the file pointer.  A
+ *         negative value causes seeking in the reverse direction.
+ *     PRSeekWhence whence
+ *         Specifies how to interpret the 'offset' parameter in setting
+ *         the file pointer associated with the 'fd' parameter.
+ *         Values for the 'whence' parameter are:
+ *             PR_SEEK_SET  Sets the file pointer to the value of the
+ *                          'offset' parameter
+ *             PR_SEEK_CUR  Sets the file pointer to its current location
+ *                          plus the value of the offset parameter.
+ *             PR_SEEK_END  Sets the file pointer to the size of the
+ *                          file plus the value of the offset parameter.
+ * OUTPUTS:
+ *     None.
+ * RETURN: PROffset32, PROffset64
+ *     Upon successful completion, the resulting pointer location,
+ *     measured in bytes from the beginning of the file, is returned.
+ *     If the PR_Seek() function fails, the file offset remains
+ *     unchanged, and the returned value is -1. The error code can
+ *     then be retrieved via PR_GetError().
+ *************************************************************************
+ */
+
+NSPR_API(PROffset32) PR_Seek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence);
+NSPR_API(PROffset64) PR_Seek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence);
+
+/*
+ ************************************************************************
+ * FUNCTION: PR_Available
+ * DESCRIPTION:
+ *     Determine the amount of data in bytes available for reading
+ *     in the given file or socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         Pointer to a PRFileDesc object that refers to a file or
+ *         socket.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRInt32, PRInt64
+ *     Upon successful completion, PR_Available returns the number of
+ *     bytes beyond the current read pointer that is available for
+ *     reading.  Otherwise, it returns a -1 and the reason for the
+ *     failure can be retrieved via PR_GetError().
+ ************************************************************************
+ */
+
+NSPR_API(PRInt32) PR_Available(PRFileDesc *fd);
+NSPR_API(PRInt64) PR_Available64(PRFileDesc *fd);
+
+/*
+ ************************************************************************
+ * FUNCTION: PR_Sync
+ * DESCRIPTION:
+ *     Sync any buffered data for a fd to its backing device (disk).
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         Pointer to a PRFileDesc object that refers to a file or
+ *         socket
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *     PR_SUCCESS is returned if the requested access is permitted.
+ *     Otherwise, PR_FAILURE is returned.
+ ************************************************************************
+ */
+
+NSPR_API(PRStatus)	PR_Sync(PRFileDesc *fd);
+
+/************************************************************************/
+
+struct PRDirEntry {
+    const char *name;        /* name of entry, relative to directory name */
+};
+
+#ifdef MOZ_UNICODE
+struct PRDirEntryUTF16 {
+    const PRUnichar *name;   /* name of entry in UTF16, relative to
+                              * directory name */
+};
+#endif /* MOZ_UNICODE */
+
+#if !defined(NO_NSPR_10_SUPPORT)
+#define PR_DirName(dirEntry)	(dirEntry->name)
+#endif
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_OpenDir
+ * DESCRIPTION:
+ *     Open the directory by the given name
+ * INPUTS:
+ *     const char *name
+ *         path name of the directory to be opened
+ * OUTPUTS:
+ *     None
+ * RETURN: PRDir *
+ *     If the directory is sucessfully opened, a PRDir object is
+ *     dynamically allocated and a pointer to it is returned.
+ *     If the directory cannot be opened, a NULL pointer is returned.
+ * MEMORY:
+ *     Upon successful completion, the return value points to
+ *     dynamically allocated memory.
+ *************************************************************************
+ */
+
+NSPR_API(PRDir*) PR_OpenDir(const char *name);
+
+#ifdef MOZ_UNICODE
+/*
+ * EXPERIMENTAL: This function may be removed in a future release.
+ */
+NSPR_API(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name);
+#endif /* MOZ_UNICODE */
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_ReadDir
+ * DESCRIPTION:
+ * INPUTS:
+ *     PRDir *dir
+ *         pointer to a PRDir object that designates an open directory
+ *     PRDirFlags flags
+ *           PR_SKIP_NONE     Do not skip any files
+ *           PR_SKIP_DOT      Skip the directory entry "." that
+ *                            represents the current directory
+ *           PR_SKIP_DOT_DOT  Skip the directory entry ".." that
+ *                            represents the parent directory.
+ *           PR_SKIP_BOTH     Skip both '.' and '..'
+ *           PR_SKIP_HIDDEN   Skip hidden files
+ * OUTPUTS:
+ * RETURN: PRDirEntry*
+ *     Returns a pointer to the next entry in the directory.  Returns
+ *     a NULL pointer upon reaching the end of the directory or when an
+ *     error occurs. The actual reason can be retrieved via PR_GetError().
+ *************************************************************************
+ */
+
+typedef enum PRDirFlags {
+    PR_SKIP_NONE = 0x0,
+    PR_SKIP_DOT = 0x1,
+    PR_SKIP_DOT_DOT = 0x2,
+    PR_SKIP_BOTH = 0x3,
+    PR_SKIP_HIDDEN = 0x4
+} PRDirFlags;
+
+NSPR_API(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags);
+
+#ifdef MOZ_UNICODE
+/*
+ * EXPERIMENTAL: This function may be removed in a future release.
+ */
+NSPR_API(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags);
+#endif /* MOZ_UNICODE */
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_CloseDir
+ * DESCRIPTION:
+ *     Close the specified directory.
+ * INPUTS:
+ *     PRDir *dir
+ *        The directory to be closed.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *        If successful, will return a status of PR_SUCCESS. Otherwise
+ *        a value of PR_FAILURE. The reason for the failure may be re-
+ *        trieved using PR_GetError().
+ *************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_CloseDir(PRDir *dir);
+
+#ifdef MOZ_UNICODE
+/*
+ * EXPERIMENTAL: This function may be removed in a future release.
+ */
+NSPR_API(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir);
+#endif /* MOZ_UNICODE */
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_MkDir
+ * DESCRIPTION:
+ *     Create a new directory with the given name and access mode.
+ * INPUTS:
+ *     const char *name
+ *        The name of the directory to be created. All the path components
+ *        up to but not including the leaf component must already exist.
+ *     PRIntn mode
+ *        See 'mode' definiton in PR_Open().
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *        If successful, will return a status of PR_SUCCESS. Otherwise
+ *        a value of PR_FAILURE. The reason for the failure may be re-
+ *        trieved using PR_GetError().
+ *************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_MkDir(const char *name, PRIntn mode);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_MakeDir
+ * DESCRIPTION:
+ *     Create a new directory with the given name and access mode.
+ *     PR_MakeDir has the same prototype as PR_MkDir but implements
+ *     the specified access mode where possible.
+ *************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_MakeDir(const char *name, PRIntn mode);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_RmDir
+ * DESCRIPTION:
+ *     Remove a directory by the given name.
+ * INPUTS:
+ *     const char *name
+ *        The name of the directory to be removed. All the path components
+ *        must already exist. Only the leaf component will be removed.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *        If successful, will return a status of PR_SUCCESS. Otherwise
+ *        a value of PR_FAILURE. The reason for the failure may be re-
+ *        trieved using PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_RmDir(const char *name);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_NewUDPSocket
+ * DESCRIPTION:
+ *     Create a new UDP socket.
+ * INPUTS:
+ *     None
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_NewUDPSocket returns a pointer
+ *     to the PRFileDesc created for the newly opened UDP socket.
+ *     Returns a NULL pointer if the creation of a new UDP socket failed.
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*)    PR_NewUDPSocket(void);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_NewTCPSocket
+ * DESCRIPTION:
+ *     Create a new TCP socket.
+ * INPUTS:
+ *     None
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_NewTCPSocket returns a pointer
+ *     to the PRFileDesc created for the newly opened TCP socket.
+ *     Returns a NULL pointer if the creation of a new TCP socket failed.
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*)    PR_NewTCPSocket(void);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_OpenUDPSocket
+ * DESCRIPTION:
+ *     Create a new UDP socket of the specified address family.
+ * INPUTS:
+ *     PRIntn af
+ *       Address family
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_OpenUDPSocket returns a pointer
+ *     to the PRFileDesc created for the newly opened UDP socket.
+ *     Returns a NULL pointer if the creation of a new UDP socket failed.
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*)    PR_OpenUDPSocket(PRIntn af);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_OpenTCPSocket
+ * DESCRIPTION:
+ *     Create a new TCP socket of the specified address family.
+ * INPUTS:
+ *     PRIntn af
+ *       Address family
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_NewTCPSocket returns a pointer
+ *     to the PRFileDesc created for the newly opened TCP socket.
+ *     Returns a NULL pointer if the creation of a new TCP socket failed.
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*)    PR_OpenTCPSocket(PRIntn af);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Connect
+ * DESCRIPTION:
+ *     Initiate a connection on a socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object representing a socket
+ *     PRNetAddr *addr
+ *       Specifies the address of the socket in its own communication
+ *       space.
+ *     PRIntervalTime timeout
+ *       Time limit for completion of the connect operation.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *     Upon successful completion of connection initiation, PR_Connect
+ *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
+ *     failure information can be obtained by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_Connect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_ConnectContinue
+ * DESCRIPTION:
+ *     Continue a nonblocking connect.  After a nonblocking connect
+ *     is initiated with PR_Connect() (which fails with
+ *     PR_IN_PROGRESS_ERROR), one should call PR_Poll() on the socket,
+ *     with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT.  When
+ *     PR_Poll() returns, one calls PR_ConnectContinue() on the
+ *     socket to determine whether the nonblocking connect has
+ *     completed or is still in progress.  Repeat the PR_Poll(),
+ *     PR_ConnectContinue() sequence until the nonblocking connect
+ *     has completed.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *         the file descriptor representing a socket
+ *     PRInt16 out_flags
+ *         the out_flags field of the poll descriptor returned by
+ *         PR_Poll()
+ * RETURN: PRStatus
+ *     If the nonblocking connect has successfully completed,
+ *     PR_ConnectContinue returns PR_SUCCESS.  If PR_ConnectContinue()
+ *     returns PR_FAILURE, call PR_GetError():
+ *     - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in
+ *       progress and has not completed yet.  The caller should poll
+ *       on the file descriptor for the in_flags
+ *       PR_POLL_WRITE|PR_POLL_EXCEPT and retry PR_ConnectContinue
+ *       later when PR_Poll() returns.
+ *     - Other errors: the nonblocking connect has failed with this
+ *       error code.
+ */
+
+NSPR_API(PRStatus)    PR_ConnectContinue(PRFileDesc *fd, PRInt16 out_flags);
+
+/*
+ *************************************************************************
+ * THIS FUNCTION IS DEPRECATED.  USE PR_ConnectContinue INSTEAD.
+ *
+ * FUNCTION: PR_GetConnectStatus
+ * DESCRIPTION:
+ *     Get the completion status of a nonblocking connect.  After
+ *     a nonblocking connect is initiated with PR_Connect() (which
+ *     fails with PR_IN_PROGRESS_ERROR), one should call PR_Poll()
+ *     on the socket, with the in_flags PR_POLL_WRITE | PR_POLL_EXCEPT.
+ *     When PR_Poll() returns, one calls PR_GetConnectStatus on the
+ *     PRPollDesc structure to determine whether the nonblocking
+ *     connect has succeeded or failed.
+ * INPUTS:
+ *     const PRPollDesc *pd
+ *         Pointer to a PRPollDesc whose fd member is the socket,
+ *         and in_flags must contain PR_POLL_WRITE and PR_POLL_EXCEPT.
+ *         PR_Poll() should have been called and set the out_flags.
+ * RETURN: PRStatus
+ *     If the nonblocking connect has successfully completed,
+ *     PR_GetConnectStatus returns PR_SUCCESS.  If PR_GetConnectStatus()
+ *     returns PR_FAILURE, call PR_GetError():
+ *     - PR_IN_PROGRESS_ERROR: the nonblocking connect is still in
+ *       progress and has not completed yet.
+ *     - Other errors: the nonblocking connect has failed with this
+ *       error code.
+ */
+
+NSPR_API(PRStatus)    PR_GetConnectStatus(const PRPollDesc *pd);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Accept
+ * DESCRIPTION:
+ *     Accept a connection on a socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object representing the rendezvous socket
+ *       on which the caller is willing to accept new connections.
+ *     PRIntervalTime timeout
+ *       Time limit for completion of the accept operation.
+ * OUTPUTS:
+ *     PRNetAddr *addr
+ *       Returns the address of the connecting entity in its own
+ *       communication space. It may be NULL.
+ * RETURN: PRFileDesc*
+ *     Upon successful acceptance of a connection, PR_Accept
+ *     returns a valid file descriptor. Otherwise, it returns NULL.
+ *     Further failure information can be obtained by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*) PR_Accept(
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Bind
+ * DESCRIPTION:
+ *    Bind an address to a socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object representing a socket.
+ *     PRNetAddr *addr
+ *       Specifies the address to which the socket will be bound.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *     Upon successful binding of an address to a socket, PR_Bind
+ *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
+ *     failure information can be obtained by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Listen
+ * DESCRIPTION:
+ *    Listen for connections on a socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object representing a socket that will be
+ *       used to listen for new connections.
+ *     PRIntn backlog
+ *       Specifies the maximum length of the queue of pending connections.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *     Upon successful completion of listen request, PR_Listen
+ *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
+ *     failure information can be obtained by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Shutdown
+ * DESCRIPTION:
+ *    Shut down part of a full-duplex connection on a socket.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object representing a connected socket.
+ *     PRIntn how
+ *       Specifies the kind of disallowed operations on the socket.
+ *           PR_SHUTDOWN_RCV - Further receives will be disallowed
+ *           PR_SHUTDOWN_SEND - Further sends will be disallowed
+ *           PR_SHUTDOWN_BOTH - Further sends and receives will be disallowed
+ * OUTPUTS:
+ *     None
+ * RETURN: PRStatus
+ *     Upon successful completion of shutdown request, PR_Shutdown
+ *     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
+ *     failure information can be obtained by calling PR_GetError().
+ **************************************************************************
+ */
+
+typedef enum PRShutdownHow
+{
+    PR_SHUTDOWN_RCV = 0,      /* disallow further receives */
+    PR_SHUTDOWN_SEND = 1,     /* disallow further sends */
+    PR_SHUTDOWN_BOTH = 2      /* disallow further receives and sends */
+} PRShutdownHow;
+
+NSPR_API(PRStatus)    PR_Shutdown(PRFileDesc *fd, PRShutdownHow how);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Recv
+ * DESCRIPTION:
+ *    Receive a specified number of bytes from a connected socket.
+ *     The operation will block until some positive number of bytes are 
+ *     transferred, a time out has occurred, or there is an error. 
+ *     No more than 'amount' bytes will be transferred.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       points to a PRFileDesc object representing a socket.
+ *     void *buf
+ *       pointer to a buffer to hold the data received.
+ *     PRInt32 amount
+ *       the size of 'buf' (in bytes)
+ *     PRIntn flags
+ *       must be zero or PR_MSG_PEEK.
+ *     PRIntervalTime timeout
+ *       Time limit for completion of the receive operation.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRInt32
+ *         a positive number indicates the number of bytes actually received.
+ *         0 means the network connection is closed.
+ *         -1 indicates a failure. The reason for the failure is obtained
+ *         by calling PR_GetError().
+ **************************************************************************
+ */
+
+#define PR_MSG_PEEK 0x2
+
+NSPR_API(PRInt32)    PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount,
+                PRIntn flags, PRIntervalTime timeout);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_Send
+ * DESCRIPTION:
+ *    Send a specified number of bytes from a connected socket.
+ *     The operation will block until all bytes are 
+ *     processed, a time out has occurred, or there is an error. 
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       points to a PRFileDesc object representing a socket.
+ *     void *buf
+ *       pointer to a buffer from where the data is sent.
+ *     PRInt32 amount
+ *       the size of 'buf' (in bytes)
+ *     PRIntn flags
+ *        (OBSOLETE - must always be zero)
+ *     PRIntervalTime timeout
+ *       Time limit for completion of the send operation.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRInt32
+ *     A positive number indicates the number of bytes successfully processed.
+ *     This number must always equal 'amount'. A -1 is an indication that the
+ *     operation failed. The reason for the failure is obtained by calling
+ *     PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRInt32)    PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+                                PRIntn flags, PRIntervalTime timeout);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_RecvFrom
+ * DESCRIPTION:
+ *     Receive up to a specified number of bytes from socket which may
+ *     or may not be connected.
+ *     The operation will block until one or more bytes are 
+ *     transferred, a time out has occurred, or there is an error. 
+ *     No more than 'amount' bytes will be transferred.
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       points to a PRFileDesc object representing a socket.
+ *     void *buf
+ *       pointer to a buffer to hold the data received.
+ *     PRInt32 amount
+ *       the size of 'buf' (in bytes)
+ *     PRIntn flags
+ *        (OBSOLETE - must always be zero)
+ *     PRNetAddr *addr
+ *       Specifies the address of the sending peer. It may be NULL.
+ *     PRIntervalTime timeout
+ *       Time limit for completion of the receive operation.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRInt32
+ *         a positive number indicates the number of bytes actually received.
+ *         0 means the network connection is closed.
+ *         -1 indicates a failure. The reason for the failure is obtained
+ *         by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRInt32) PR_RecvFrom(
+    PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+    PRNetAddr *addr, PRIntervalTime timeout);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_SendTo
+ * DESCRIPTION:
+ *    Send a specified number of bytes from an unconnected socket.
+ *    The operation will block until all bytes are 
+ *    sent, a time out has occurred, or there is an error. 
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       points to a PRFileDesc object representing an unconnected socket.
+ *     void *buf
+ *       pointer to a buffer from where the data is sent.
+ *     PRInt32 amount
+ *       the size of 'buf' (in bytes)
+ *     PRIntn flags
+ *        (OBSOLETE - must always be zero)
+ *     PRNetAddr *addr
+ *       Specifies the address of the peer.
+.*     PRIntervalTime timeout
+ *       Time limit for completion of the send operation.
+ * OUTPUTS:
+ *     None
+ * RETURN: PRInt32
+ *     A positive number indicates the number of bytes successfully sent.
+ *     -1 indicates a failure. The reason for the failure is obtained
+ *     by calling PR_GetError().
+ **************************************************************************
+ */
+
+NSPR_API(PRInt32) PR_SendTo(
+    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+    const PRNetAddr *addr, PRIntervalTime timeout);
+
+/*
+*************************************************************************
+** FUNCTION: PR_TransmitFile
+** DESCRIPTION:
+**    Transmitfile sends a complete file (sourceFile) across a socket 
+**    (networkSocket).  If headers is non-NULL, the headers will be sent across
+**    the socket prior to sending the file.
+** 
+**    Optionally, the PR_TRANSMITFILE_CLOSE_SOCKET flag may be passed to
+**    transmitfile.  This flag specifies that transmitfile should close the
+**    socket after sending the data.
+**
+** INPUTS:
+**    PRFileDesc *networkSocket
+**        The socket to send data over
+**    PRFileDesc *sourceFile
+**        The file to send
+**    const void *headers
+**        A pointer to headers to be sent before sending data
+**    PRInt32       hlen
+**        length of header buffers in bytes.
+**    PRTransmitFileFlags       flags
+**        If the flags indicate that the connection should be closed,
+**        it will be done immediately after transferring the file, unless
+**        the operation is unsuccessful. 
+.*     PRIntervalTime timeout
+ *        Time limit for completion of the transmit operation.
+**
+** RETURNS:
+**    Returns the number of bytes written or -1 if the operation failed.
+**    If an error occurs while sending the file, the PR_TRANSMITFILE_CLOSE_
+**    SOCKET flag is ignored. The reason for the failure is obtained
+**    by calling PR_GetError().
+**************************************************************************
+*/
+
+NSPR_API(PRInt32) PR_TransmitFile(
+    PRFileDesc *networkSocket, PRFileDesc *sourceFile,
+    const void *headers, PRInt32 hlen, PRTransmitFileFlags flags,
+    PRIntervalTime timeout);
+
+/*
+*************************************************************************
+** FUNCTION: PR_SendFile
+** DESCRIPTION:
+**    PR_SendFile sends data from a file (sendData->fd) across a socket 
+**    (networkSocket).  If specified, a header and/or trailer buffer are sent
+**	  before and after the file, respectively. The file offset, number of bytes
+** 	  of file data to send, the header and trailer buffers are specified in the
+**	  sendData argument.
+** 
+**    Optionally, if the PR_TRANSMITFILE_CLOSE_SOCKET flag is passed, the
+**    socket is closed after successfully sending the data.
+**
+** INPUTS:
+**    PRFileDesc *networkSocket
+**        The socket to send data over
+**    PRSendFileData *sendData
+**        Contains the FD, file offset and length, header and trailer
+**		  buffer specifications.
+**    PRTransmitFileFlags       flags
+**        If the flags indicate that the connection should be closed,
+**        it will be done immediately after transferring the file, unless
+**        the operation is unsuccessful. 
+.*     PRIntervalTime timeout
+ *        Time limit for completion of the send operation.
+**
+** RETURNS:
+**    Returns the number of bytes written or -1 if the operation failed.
+**    If an error occurs while sending the file, the PR_TRANSMITFILE_CLOSE_
+**    SOCKET flag is ignored. The reason for the failure is obtained
+**    by calling PR_GetError().
+**************************************************************************
+*/
+
+struct PRSendFileData {
+	PRFileDesc	*fd;			/* file to send							*/
+	PRUint32	file_offset;	/* file offset							*/
+	PRSize		file_nbytes;	/* number of bytes of file data to send	*/
+								/* if 0, send data from file_offset to	*/
+								/* end-of-file.							*/
+	const void	*header;		/* header buffer						*/
+	PRInt32		hlen;			/* header len							*/
+	const void	*trailer;		/* trailer buffer						*/
+	PRInt32		tlen;			/* trailer len							*/
+};
+
+
+NSPR_API(PRInt32) PR_SendFile(
+    PRFileDesc *networkSocket, PRSendFileData *sendData,
+	PRTransmitFileFlags flags, PRIntervalTime timeout);
+
+/*
+*************************************************************************
+** FUNCTION: PR_AcceptRead
+** DESCRIPTION:
+**    AcceptRead accepts a new connection, returns the newly created
+**    socket's descriptor and also returns the connecting peer's address.
+**    AcceptRead, as its name suggests, also receives the first block of data 
+**    sent by the peer.
+**
+** INPUTS:
+**    PRFileDesc *listenSock
+**        A socket descriptor that has been called with the PR_Listen() 
+**        function, also known as the rendezvous socket.
+**    void *buf
+**        A pointer to a buffer to receive data sent by the client.  This 
+**        buffer must be large enough to receive <amount> bytes of data
+**        and two PRNetAddr structures, plus an extra 32 bytes. See:
+**        PR_ACCEPT_READ_BUF_OVERHEAD.
+**    PRInt32 amount
+**        The number of bytes of client data to receive.  Does not include
+**        the size of the PRNetAddr structures.  If 0, no data will be read
+**        from the client.
+**    PRIntervalTime timeout
+**        The timeout interval only applies to the read portion of the 
+**        operation.  PR_AcceptRead will block indefinitely until the 
+**        connection is accepted; the read will timeout after the timeout 
+**        interval elapses.
+** OUTPUTS:
+**    PRFileDesc **acceptedSock
+**        The file descriptor for the newly connected socket.  This parameter
+**        will only be valid if the function return does not indicate failure.
+**    PRNetAddr  **peerAddr,
+**        The address of the remote socket.  This parameter will only be
+**        valid if the function return does not indicate failure.  The
+**        returned address is not guaranteed to be properly aligned.
+** 
+** RETURNS:
+**     The number of bytes read from the client or -1 on failure.  The reason 
+**     for the failure is obtained by calling PR_GetError().
+**************************************************************************
+**/       
+/* define buffer overhead constant. Add this value to the user's 
+** data length when allocating a buffer to accept data.
+**    Example:
+**    #define USER_DATA_SIZE 10
+**    char buf[USER_DATA_SIZE + PR_ACCEPT_READ_BUF_OVERHEAD];
+**    bytesRead = PR_AcceptRead( s, fd, &a, &p, USER_DATA_SIZE, ...);
+*/
+#define PR_ACCEPT_READ_BUF_OVERHEAD (32+(2*sizeof(PRNetAddr)))
+
+NSPR_API(PRInt32) PR_AcceptRead(
+    PRFileDesc *listenSock, PRFileDesc **acceptedSock,
+    PRNetAddr **peerAddr, void *buf, PRInt32 amount, PRIntervalTime timeout);
+
+/*
+*************************************************************************
+** FUNCTION: PR_NewTCPSocketPair
+** DESCRIPTION:
+**    Create a new TCP socket pair. The returned descriptors can be used
+**    interchangeably; they are interconnected full-duplex descriptors: data
+**    written to one can be read from the other and vice-versa.
+**
+** INPUTS:
+**    None
+** OUTPUTS:
+**    PRFileDesc *fds[2]
+**        The file descriptor pair for the newly created TCP sockets.
+** RETURN: PRStatus
+**     Upon successful completion of TCP socket pair, PR_NewTCPSocketPair 
+**     returns PR_SUCCESS.  Otherwise, it returns PR_FAILURE.  Further
+**     failure information can be obtained by calling PR_GetError().
+** XXX can we implement this on windoze and mac?
+**************************************************************************
+**/
+NSPR_API(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2]);
+
+/*
+*************************************************************************
+** FUNCTION: PR_GetSockName
+** DESCRIPTION:
+**    Get socket name.  Return the network address for this socket.
+**
+** INPUTS:
+**     PRFileDesc *fd
+**       Points to a PRFileDesc object representing the socket.
+** OUTPUTS:
+**     PRNetAddr *addr
+**       Returns the address of the socket in its own communication space.
+** RETURN: PRStatus
+**     Upon successful completion, PR_GetSockName returns PR_SUCCESS.  
+**     Otherwise, it returns PR_FAILURE.  Further failure information can 
+**     be obtained by calling PR_GetError().
+**************************************************************************
+**/
+NSPR_API(PRStatus)	PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr);
+
+/*
+*************************************************************************
+** FUNCTION: PR_GetPeerName
+** DESCRIPTION:
+**    Get name of the connected peer.  Return the network address for the 
+**    connected peer socket.
+**
+** INPUTS:
+**     PRFileDesc *fd
+**       Points to a PRFileDesc object representing the connected peer.
+** OUTPUTS:
+**     PRNetAddr *addr
+**       Returns the address of the connected peer in its own communication
+**       space.
+** RETURN: PRStatus
+**     Upon successful completion, PR_GetPeerName returns PR_SUCCESS.  
+**     Otherwise, it returns PR_FAILURE.  Further failure information can 
+**     be obtained by calling PR_GetError().
+**************************************************************************
+**/
+NSPR_API(PRStatus)	PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr);
+
+NSPR_API(PRStatus)	PR_GetSocketOption(
+    PRFileDesc *fd, PRSocketOptionData *data);
+
+NSPR_API(PRStatus)	PR_SetSocketOption(
+    PRFileDesc *fd, const PRSocketOptionData *data);
+
+/*
+ *********************************************************************
+ *
+ * File descriptor inheritance
+ *
+ *********************************************************************
+ */
+
+/*
+ ************************************************************************
+ * FUNCTION: PR_SetFDInheritable
+ * DESCRIPTION:
+ *    Set the inheritance attribute of a file descriptor.
+ *
+ * INPUTS:
+ *     PRFileDesc *fd
+ *       Points to a PRFileDesc object.
+ *     PRBool inheritable
+ *       If PR_TRUE, the file descriptor fd is set to be inheritable
+ *       by a child process.  If PR_FALSE, the file descriptor is set
+ *       to be not inheritable by a child process.
+ * RETURN: PRStatus
+ *     Upon successful completion, PR_SetFDInheritable returns PR_SUCCESS.  
+ *     Otherwise, it returns PR_FAILURE.  Further failure information can 
+ *     be obtained by calling PR_GetError().
+ *************************************************************************
+ */
+NSPR_API(PRStatus) PR_SetFDInheritable(
+    PRFileDesc *fd,
+    PRBool inheritable);
+
+/*
+ ************************************************************************
+ * FUNCTION: PR_GetInheritedFD
+ * DESCRIPTION:
+ *    Get an inherited file descriptor with the specified name.
+ *
+ * INPUTS:
+ *     const char *name
+ *       The name of the inherited file descriptor.
+ * RETURN: PRFileDesc *
+ *     Upon successful completion, PR_GetInheritedFD returns the
+ *     inherited file descriptor with the specified name.  Otherwise,  
+ *     it returns NULL.  Further failure information can be obtained
+ *     by calling PR_GetError().
+ *************************************************************************
+ */
+NSPR_API(PRFileDesc *) PR_GetInheritedFD(const char *name);
+
+/*
+ *********************************************************************
+ *
+ * Memory-mapped files
+ *
+ *********************************************************************
+ */
+
+typedef struct PRFileMap PRFileMap;
+
+/*
+ * protection options for read and write accesses of a file mapping
+ */
+typedef enum PRFileMapProtect {
+    PR_PROT_READONLY,     /* read only */
+    PR_PROT_READWRITE,    /* readable, and write is shared */
+    PR_PROT_WRITECOPY     /* readable, and write is private (copy-on-write) */
+} PRFileMapProtect;
+
+NSPR_API(PRFileMap *) PR_CreateFileMap(
+    PRFileDesc *fd,
+    PRInt64 size,
+    PRFileMapProtect prot);
+
+/*
+ * return the alignment (in bytes) of the offset argument to PR_MemMap
+ */
+NSPR_API(PRInt32) PR_GetMemMapAlignment(void);
+
+NSPR_API(void *) PR_MemMap(
+    PRFileMap *fmap,
+    PROffset64 offset,  /* must be aligned and sized according to the
+                         * return value of PR_GetMemMapAlignment() */
+    PRUint32 len);
+
+NSPR_API(PRStatus) PR_MemUnmap(void *addr, PRUint32 len);
+
+NSPR_API(PRStatus) PR_CloseFileMap(PRFileMap *fmap);
+
+/*
+ ******************************************************************
+ *
+ * Interprocess communication
+ *
+ ******************************************************************
+ */
+
+/*
+ * Creates an anonymous pipe and returns file descriptors for the
+ * read and write ends of the pipe.
+ */
+
+NSPR_API(PRStatus) PR_CreatePipe(
+    PRFileDesc **readPipe,
+    PRFileDesc **writePipe
+);
+
+/************************************************************************/
+/************** The following definitions are for poll ******************/
+/************************************************************************/
+
+struct PRPollDesc {
+    PRFileDesc* fd;
+    PRInt16 in_flags;
+    PRInt16 out_flags;
+};
+
+/*
+** Bit values for PRPollDesc.in_flags or PRPollDesc.out_flags. Binary-or
+** these together to produce the desired poll request.
+*/
+
+#if defined(_PR_POLL_BACKCOMPAT)
+
+#include <poll.h>
+#define PR_POLL_READ    POLLIN
+#define PR_POLL_WRITE   POLLOUT
+#define PR_POLL_EXCEPT  POLLPRI
+#define PR_POLL_ERR     POLLERR     /* only in out_flags */
+#define PR_POLL_NVAL    POLLNVAL    /* only in out_flags when fd is bad */
+#define PR_POLL_HUP     POLLHUP     /* only in out_flags */
+
+#else  /* _PR_POLL_BACKCOMPAT */
+
+#define PR_POLL_READ    0x1
+#define PR_POLL_WRITE   0x2
+#define PR_POLL_EXCEPT  0x4
+#define PR_POLL_ERR     0x8         /* only in out_flags */
+#define PR_POLL_NVAL    0x10        /* only in out_flags when fd is bad */
+#define PR_POLL_HUP     0x20        /* only in out_flags */
+
+#endif  /* _PR_POLL_BACKCOMPAT */
+
+/*
+*************************************************************************
+** FUNCTION:    PR_Poll
+** DESCRIPTION:
+**
+** The call returns as soon as I/O is ready on one or more of the underlying
+** socket objects. A count of the number of ready descriptors is
+** returned unless a timeout occurs in which case zero is returned.
+**
+** PRPollDesc.fd should be set to a pointer to a PRFileDesc object
+** representing a socket. This field can be set to NULL to indicate to
+** PR_Poll that this PRFileDesc object should be ignored.
+** PRPollDesc.in_flags should be set to the desired request
+** (read/write/except or some combination). Upon successful return from
+** this call PRPollDesc.out_flags will be set to indicate what kind of
+** i/o can be performed on the respective descriptor. PR_Poll() uses the
+** out_flags fields as scratch variables during the call. If PR_Poll()
+** returns 0 or -1, the out_flags fields do not contain meaningful values
+** and must not be used.
+**
+** INPUTS:
+**      PRPollDesc *pds         A pointer to an array of PRPollDesc
+**
+**      PRIntn npds             The number of elements in the array
+**                              If this argument is zero PR_Poll is
+**                              equivalent to a PR_Sleep(timeout).
+**
+**      PRIntervalTime timeout  Amount of time the call will block waiting
+**                              for I/O to become ready. If this time expires
+**                              w/o any I/O becoming ready, the result will
+**                              be zero.
+**
+** OUTPUTS:    None
+** RETURN:
+**      PRInt32                 Number of PRPollDesc's with events or zero
+**                              if the function timed out or -1 on failure.
+**                              The reason for the failure is obtained by
+**                              calling PR_GetError().
+**************************************************************************
+*/
+NSPR_API(PRInt32) PR_Poll(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout);
+
+/*
+**************************************************************************
+**
+** Pollable events
+**
+** A pollable event is a special kind of file descriptor.
+** The only I/O operation you can perform on a pollable event
+** is to poll it with the PR_POLL_READ flag.  You can't
+** read from or write to a pollable event.
+**
+** The purpose of a pollable event is to combine event waiting
+** with I/O waiting in a single PR_Poll call.  Pollable events
+** are implemented using a pipe or a pair of TCP sockets
+** connected via the loopback address, therefore setting and
+** waiting for pollable events are expensive operating system
+** calls.  Do not use pollable events for general thread
+** synchronization. Use condition variables instead.
+**
+** A pollable event has two states: set and unset.  Events
+** are not queued, so there is no notion of an event count.
+** A pollable event is either set or unset.
+**
+** A new pollable event is created by a PR_NewPollableEvent
+** call and is initially in the unset state.
+**
+** PR_WaitForPollableEvent blocks the calling thread until
+** the pollable event is set, and then it atomically unsets
+** the pollable event before it returns.
+**
+** To set a pollable event, call PR_SetPollableEvent.
+**
+** One can call PR_Poll with the PR_POLL_READ flag on a pollable
+** event.  When the pollable event is set, PR_Poll returns with
+** the PR_POLL_READ flag set in the out_flags.
+**
+** To close a pollable event, call PR_DestroyPollableEvent
+** (not PR_Close).
+**
+**************************************************************************
+*/
+
+NSPR_API(PRFileDesc *) PR_NewPollableEvent(void);
+
+NSPR_API(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event);
+
+NSPR_API(PRStatus) PR_SetPollableEvent(PRFileDesc *event);
+
+NSPR_API(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event);
+
+PR_END_EXTERN_C
+
+#endif /* prio_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/pripcsem.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/pripcsem.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,133 @@
+/* -*- 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 ***** */
+
+/*
+ * File: pripcsem.h
+ *
+ * Description: named semaphores for interprocess
+ * synchronization
+ *
+ * Unrelated processes obtain access to a shared semaphore
+ * by specifying its name.
+ *
+ * Our goal is to support named semaphores on at least
+ * Unix and Win32 platforms.  The implementation will use
+ * one of the three native semaphore APIs: POSIX, System V,
+ * and Win32.
+ *
+ * Because POSIX named semaphores have kernel persistence,
+ * we are forced to have a delete function in this API.
+ */
+
+#ifndef pripcsem_h___
+#define pripcsem_h___
+
+#include "prtypes.h"
+#include "prio.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+ * PRSem is an opaque structure that represents a named
+ * semaphore.
+ */
+typedef struct PRSem PRSem;
+
+/*
+ * PR_OpenSemaphore --
+ *
+ * Create or open a named semaphore with the specified name.
+ * A handle to the semaphore is returned.
+ *
+ * If the named semaphore doesn't exist and the PR_SEM_CREATE
+ * flag is specified, the named semaphore is created.  The
+ * created semaphore needs to be removed from the system with
+ * a PR_DeleteSemaphore call.
+ *
+ * If PR_SEM_CREATE is specified, the third argument is the
+ * access permission bits of the new semaphore (same
+ * interpretation as the mode argument to PR_Open) and the
+ * fourth argument is the initial value of the new semaphore.
+ * If PR_SEM_CREATE is not specified, the third and fourth
+ * arguments are ignored.
+ */
+
+#define PR_SEM_CREATE 0x1  /* create if not exist */
+#define PR_SEM_EXCL   0x2  /* fail if already exists */
+
+NSPR_API(PRSem *) PR_OpenSemaphore(
+    const char *name, PRIntn flags, PRIntn mode, PRUintn value);
+
+/*
+ * PR_WaitSemaphore --
+ *
+ * If the value of the semaphore is > 0, decrement the value and return.
+ * If the value is 0, sleep until the value becomes > 0, then decrement
+ * the value and return.
+ *
+ * The "test and decrement" operation is performed atomically.
+ */
+
+NSPR_API(PRStatus) PR_WaitSemaphore(PRSem *sem);
+
+/*
+ * PR_PostSemaphore --
+ *
+ * Increment the value of the named semaphore by 1.
+ */
+
+NSPR_API(PRStatus) PR_PostSemaphore(PRSem *sem);
+
+/*
+ * PR_CloseSemaphore --
+ *
+ * Close a named semaphore handle.
+ */
+
+NSPR_API(PRStatus) PR_CloseSemaphore(PRSem *sem);
+
+/*
+ * PR_DeleteSemaphore --
+ *
+ * Remove a named semaphore from the system.
+ */
+
+NSPR_API(PRStatus) PR_DeleteSemaphore(const char *name);
+
+PR_END_EXTERN_C
+
+#endif /* pripcsem_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/private/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/private/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/private/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/private/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,8 @@
+/.cvsignore/1.2/Sat May 12 02:03:58 2001//
+/Makefile.in/1.10/Sun Apr 25 15:00:56 2004//
+/pprio.h/3.16/Fri Oct 21 18:21:41 2005//
+/pprmwait.h/3.7/Thu Jan 20 19:02:09 2005//
+/pprthred.h/3.9/Sun Apr 25 15:00:56 2004//
+/primpl.h/3.85/Fri Oct 21 18:21:41 2005//
+/prpriv.h/3.5/Sun Apr 25 15:00:56 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/private/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/private/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/include/private

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/private/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/private/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/private/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/private/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -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
+
+RELEASE_HEADERS = pprio.h pprthred.h prpriv.h
+RELEASE_HEADERS := $(addprefix $(srcdir)/, $(RELEASE_HEADERS))
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)/private
+
+HEADERS = $(RELEASE_HEADERS) $(srcdir)/pprmwait.h $(srcdir)/primpl.h
+
+include_subdir = private
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(RELEASE_HEADERS)
+	$(INSTALL) -m 444 $(RELEASE_HEADERS) $(dist_includedir)/private

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/private/pprio.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/private/pprio.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,271 @@
+/* -*- 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:	pprio.h
+**
+** Description:	Private definitions for I/O related structures
+*/
+
+#ifndef pprio_h___
+#define pprio_h___
+
+#include "prtypes.h"
+#include "prio.h"
+
+PR_BEGIN_EXTERN_C
+
+/************************************************************************/
+/************************************************************************/
+
+#ifdef _WIN64
+typedef __int64 PROsfd;
+#else
+typedef PRInt32 PROsfd;
+#endif
+
+/* Return the method tables for files, tcp sockets and udp sockets */
+NSPR_API(const PRIOMethods*)    PR_GetFileMethods(void);
+NSPR_API(const PRIOMethods*)    PR_GetTCPMethods(void);
+NSPR_API(const PRIOMethods*)    PR_GetUDPMethods(void);
+NSPR_API(const PRIOMethods*)    PR_GetPipeMethods(void);
+
+/*
+** Convert a NSPR Socket Handle to a Native Socket handle.
+** This function will be obsoleted with the next release; avoid using it.
+*/
+NSPR_API(PROsfd)       PR_FileDesc2NativeHandle(PRFileDesc *);
+NSPR_API(void)         PR_ChangeFileDescNativeHandle(PRFileDesc *, PROsfd);
+NSPR_API(PRFileDesc*)  PR_AllocFileDesc(PROsfd osfd,
+                                         const PRIOMethods *methods);
+NSPR_API(void)         PR_FreeFileDesc(PRFileDesc *fd);
+/*
+** Import an existing OS file to NSPR. 
+*/
+NSPR_API(PRFileDesc*)  PR_ImportFile(PROsfd osfd);
+NSPR_API(PRFileDesc*)  PR_ImportPipe(PROsfd osfd);
+NSPR_API(PRFileDesc*)  PR_ImportTCPSocket(PROsfd osfd);
+NSPR_API(PRFileDesc*)  PR_ImportUDPSocket(PROsfd osfd);
+
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_CreateSocketPollFd
+ * DESCRIPTION:
+ *     Create a PRFileDesc wrapper for a native socket handle, for use with
+ *	   PR_Poll only
+ * INPUTS:
+ *     None
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_CreateSocketPollFd returns a pointer
+ *     to the PRFileDesc created for the native socket handle
+ *     Returns a NULL pointer if the create of a new PRFileDesc failed
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRFileDesc*)	PR_CreateSocketPollFd(PROsfd osfd);
+
+/*
+ *************************************************************************
+ * FUNCTION: PR_DestroySocketPollFd
+ * DESCRIPTION:
+ *     Destroy the PRFileDesc wrapper created by PR_CreateSocketPollFd
+ * INPUTS:
+ *     None
+ * OUTPUTS:
+ *     None
+ * RETURN: PRFileDesc*
+ *     Upon successful completion, PR_DestroySocketPollFd returns
+ *	   PR_SUCCESS, else PR_FAILURE
+ *
+ **************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd);
+
+
+/*
+** Macros for PR_Socket
+**
+** Socket types: PR_SOCK_STREAM, PR_SOCK_DGRAM
+*/
+
+#ifdef WIN32
+
+#define PR_SOCK_STREAM 1
+#define PR_SOCK_DGRAM 2
+
+#else /* WIN32 */
+
+#define PR_SOCK_STREAM SOCK_STREAM
+#define PR_SOCK_DGRAM SOCK_DGRAM
+
+#endif /* WIN32 */
+
+/*
+** Create a new Socket; this function is obsolete.
+*/
+NSPR_API(PRFileDesc*)	PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto);
+
+/* FUNCTION: PR_LockFile
+** DESCRIPTION:
+**    Lock a file for exclusive access.
+** RETURNS:
+**    PR_SUCCESS when the lock is held
+**    PR_FAILURE otherwise
+*/
+NSPR_API(PRStatus) PR_LockFile(PRFileDesc *fd);
+
+/* FUNCTION: PR_TLockFile
+** DESCRIPTION:
+**    Test and Lock a file for exclusive access.  Do not block if the
+**    file cannot be locked immediately.
+** RETURNS:
+**    PR_SUCCESS when the lock is held
+**    PR_FAILURE otherwise
+*/
+NSPR_API(PRStatus) PR_TLockFile(PRFileDesc *fd);
+
+/* FUNCTION: PR_UnlockFile
+** DESCRIPTION:
+**    Unlock a file which has been previously locked successfully by this
+**    process.
+** RETURNS:
+**    PR_SUCCESS when the lock is released
+**    PR_FAILURE otherwise
+*/
+NSPR_API(PRStatus) PR_UnlockFile(PRFileDesc *fd);
+
+/*
+** Emulate acceptread by accept and recv.
+*/
+NSPR_API(PRInt32) PR_EmulateAcceptRead(PRFileDesc *sd, PRFileDesc **nd,
+    PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout);
+
+/*
+** Emulate sendfile by reading from the file and writing to the socket.
+** The file is memory-mapped if memory-mapped files are supported.
+*/
+NSPR_API(PRInt32) PR_EmulateSendFile(
+    PRFileDesc *networkSocket, PRSendFileData *sendData,
+    PRTransmitFileFlags flags, PRIntervalTime timeout);
+
+#ifdef WIN32
+/* FUNCTION: PR_NTFast_AcceptRead
+** DESCRIPTION:
+**    NT has the notion of an "accept context", which is only needed in
+**    order to make certain calls.  By default, a socket connected via
+**    AcceptEx can only do a limited number of things without updating
+**    the acceptcontext.  The generic version of PR_AcceptRead always
+**    updates the accept context.  This version does not.
+**/
+NSPR_API(PRInt32) PR_NTFast_AcceptRead(PRFileDesc *sd, PRFileDesc **nd,
+              PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime t);
+
+typedef void (*_PR_AcceptTimeoutCallback)(void *);
+
+/* FUNCTION: PR_NTFast_AcceptRead_WithTimeoutCallback
+** DESCRIPTION:
+**    The AcceptEx call combines the accept with the read function.  However,
+**    our daemon threads need to be able to wakeup and reliably flush their
+**    log buffers if the Accept times out.  However, with the current blocking
+**    interface to AcceptRead, there is no way for us to timeout the Accept;
+**    this is because when we timeout the Read, we can close the newly 
+**    socket and continue; but when we timeout the accept itself, there is no
+**    new socket to timeout.  So instead, this version of the function is
+**    provided.  After the initial timeout period elapses on the accept()
+**    portion of the function, it will call the callback routine and then
+**    continue the accept.   If the timeout occurs on the read, it will 
+**    close the connection and return error.
+*/
+NSPR_API(PRInt32) PR_NTFast_AcceptRead_WithTimeoutCallback(
+              PRFileDesc *sd, 
+              PRFileDesc **nd,
+              PRNetAddr **raddr, 
+              void *buf, 
+              PRInt32 amount, 
+              PRIntervalTime t,
+              _PR_AcceptTimeoutCallback callback, 
+              void *callback_arg);
+
+/* FUNCTION: PR_NTFast_Accept
+** DESCRIPTION:
+**    NT has the notion of an "accept context", which is only needed in
+**    order to make certain calls.  By default, a socket connected via
+**    AcceptEx can only do a limited number of things without updating
+**    the acceptcontext.  The generic version of PR_Accept always
+**    updates the accept context.  This version does not.
+**/
+NSPR_API(PRFileDesc*)	PR_NTFast_Accept(PRFileDesc *fd, PRNetAddr *addr,
+                                                PRIntervalTime timeout);
+
+/* FUNCTION: PR_NTFast_Update
+** DESCRIPTION:
+**    For sockets accepted with PR_NTFast_Accept or PR_NTFastAcceptRead,
+**    this function will update the accept context for those sockets,
+**    so that the socket can make general purpose socket calls.
+**    Without calling this, the only operations supported on the socket
+**    Are PR_Read, PR_Write, PR_Transmitfile, and PR_Close.
+*/
+NSPR_API(void) PR_NTFast_UpdateAcceptContext(PRFileDesc *acceptSock, 
+                                        PRFileDesc *listenSock);
+
+
+/* FUNCTION: PR_NT_CancelIo
+** DESCRIPTION:
+**    Cancel IO operations on fd.
+*/
+NSPR_API(PRStatus) PR_NT_CancelIo(PRFileDesc *fd);
+
+
+#endif /* WIN32 */
+
+/*
+** Need external access to this on Mac so we can first set up our faux
+** environment vars
+*/
+#ifdef XP_MAC
+NSPR_API(void) PR_Init_Log(void);
+#endif
+
+
+PR_END_EXTERN_C
+
+#endif /* pprio_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/private/pprmwait.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/private/pprmwait.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,135 @@
+/* -*- 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(_PPRMWAIT_H)
+#else
+#define _PPRMWAIT_H
+
+#include "prlock.h"
+#include "prcvar.h"
+#include "prclist.h"
+#include "prthread.h"
+
+#define MAX_POLLING_INTERVAL 100
+#define _PR_POLL_COUNT_FUDGE 64
+#define _PR_DEFAULT_HASH_LENGTH 59
+
+/*
+ * Our hash table resolves collisions by open addressing with
+ * double hashing.  See Cormen, Leiserson, and Rivest,
+ * Introduction to Algorithms, p. 232, The MIT Press, 1990.
+ */
+
+#define _MW_HASH(a, m) ((((PRUptrdiff)(a) >> 4) ^ ((PRUptrdiff)(a) >> 10)) % (m))
+#define _MW_HASH2(a, m) (1 + ((((PRUptrdiff)(a) >> 4) ^ ((PRUptrdiff)(a) >> 10)) % (m - 2)))
+#define _MW_ABORTED(_rv) \
+    ((PR_FAILURE == (_rv)) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError()))
+
+typedef enum {_prmw_success, _prmw_rehash, _prmw_error} _PR_HashStory;
+
+typedef struct _PRWaiterHash
+{
+    PRUint16 count;             /* current number in hash table */
+    PRUint16 length;            /* current size of the hash table */
+    PRRecvWait *recv_wait;      /* hash table of receive wait objects */
+} _PRWaiterHash;
+
+typedef enum {_prmw_running, _prmw_stopping, _prmw_stopped} PRMWGroupState;
+
+struct PRWaitGroup
+{
+    PRCList group_link;         /* all groups are linked to each other */
+    PRCList io_ready;           /* list of I/O requests that are ready */
+    PRMWGroupState state;       /* state of this group (so we can shut down) */
+
+    PRLock *ml;                 /* lock for synchronizing this wait group */
+    PRCondVar *io_taken;        /* calling threads notify when they take I/O */
+    PRCondVar *io_complete;     /* calling threads wait here for completions */
+    PRCondVar *new_business;    /* polling thread waits here more work */
+    PRCondVar *mw_manage;       /* used to manage group lists */
+    PRThread* poller;           /* thread that's actually doing the poll() */
+    PRUint16 waiting_threads;   /* number of threads waiting for recv */
+    PRUint16 polling_count;     /* number of elements in the polling list */
+    PRUint32 p_timestamp;       /* pseudo-time group had element removed */
+    PRPollDesc *polling_list;   /* list poller builds for polling */
+    PRIntervalTime last_poll;   /* last time we polled */
+    _PRWaiterHash *waiter;      /* pointer to hash table of wait receive objects */
+
+#ifdef WINNT
+    /*
+     * On NT, idle threads are responsible for getting completed i/o.
+     * They need to add completed i/o to the io_ready list.  Since
+     * idle threads cannot use nspr locks, we have to use an md lock
+     * to protect the io_ready list.
+     */
+    _MDLock mdlock;             /* protect io_ready, waiter, and wait_list */
+    PRCList wait_list;          /* used in place of io_complete.  reuse
+                                 * waitQLinks in the PRThread structure. */
+#endif /* WINNT */
+};
+
+/**********************************************************************
+***********************************************************************
+******************** Wait group enumerations **************************
+***********************************************************************
+**********************************************************************/
+typedef struct _PRGlobalState
+{
+    PRCList group_list;         /* master of the group list */
+    PRWaitGroup *group;         /* the default (NULL) group */
+} _PRGlobalState;
+
+#ifdef WINNT
+extern PRStatus NT_HashRemoveInternal(PRWaitGroup *group, PRFileDesc *fd);
+#endif
+
+typedef enum {_PR_ENUM_UNSEALED=0, _PR_ENUM_SEALED=0x0eadface} _PREnumSeal;
+
+struct PRMWaitEnumerator
+{
+    PRWaitGroup *group;       /* group this enumerator is bound to */
+    PRThread *thread;               /* thread in midst of an enumeration */
+    _PREnumSeal seal;               /* trying to detect deleted objects */
+    PRUint32 p_timestamp;           /* when enumeration was (re)started */
+    PRRecvWait **waiter;            /* pointer into hash table */
+    PRUintn index;                  /* position in hash table */
+    void *pad[4];                   /* some room to grow */
+};
+
+#endif /* defined(_PPRMWAIT_H) */
+
+/* pprmwait.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/private/pprthred.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/private/pprthred.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,373 @@
+/* -*- 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 pprthred_h___
+#define pprthred_h___
+
+/*
+** API for PR private functions.  These calls are to be used by internal
+** developers only.
+*/
+#include "nspr.h"
+
+#if defined(XP_OS2)
+#define INCL_DOS
+#define INCL_DOSERRORS
+#define INCL_WIN
+#include <os2.h>
+#endif
+
+PR_BEGIN_EXTERN_C
+
+/*---------------------------------------------------------------------------
+** THREAD PRIVATE FUNCTIONS
+---------------------------------------------------------------------------*/
+
+/*
+** Associate a thread object with an existing native thread.
+** 	"type" is the type of thread object to attach
+** 	"priority" is the priority to assign to the thread
+** 	"stack" defines the shape of the threads stack
+**
+** This can return NULL if some kind of error occurs, or if memory is
+** tight. This call invokes "start(obj,arg)" and returns when the
+** function returns. The thread object is automatically destroyed.
+**
+** This call is not normally needed unless you create your own native
+** thread. PR_Init does this automatically for the primordial thread.
+*/
+NSPR_API(PRThread*) PR_AttachThread(PRThreadType type,
+                                     PRThreadPriority priority,
+				     PRThreadStack *stack);
+
+/*
+** Detach the nspr thread from the currently executing native thread.
+** The thread object will be destroyed and all related data attached
+** to it. The exit procs will be invoked.
+**
+** This call is not normally needed unless you create your own native
+** thread. PR_Exit will automatially detach the nspr thread object
+** created by PR_Init for the primordial thread.
+**
+** This call returns after the nspr thread object is destroyed.
+*/
+NSPR_API(void) PR_DetachThread(void);
+
+/*
+** Get the id of the named thread. Each thread is assigned a unique id
+** when it is created or attached.
+*/
+NSPR_API(PRUint32) PR_GetThreadID(PRThread *thread);
+
+/*
+** Set the procedure that is called when a thread is dumped. The procedure
+** will be applied to the argument, arg, when called. Setting the procedure
+** to NULL effectively removes it.
+*/
+typedef void (*PRThreadDumpProc)(PRFileDesc *fd, PRThread *t, void *arg);
+NSPR_API(void) PR_SetThreadDumpProc(
+    PRThread* thread, PRThreadDumpProc dump, void *arg);
+
+/*
+** Get this thread's affinity mask.  The affinity mask is a 32 bit quantity
+** marking a bit for each processor this process is allowed to run on.
+** The processor mask is returned in the mask argument.
+** The least-significant-bit represents processor 0.
+**
+** Returns 0 on success, -1 on failure.
+*/
+NSPR_API(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask);
+
+/*
+** Set this thread's affinity mask.  
+**
+** Returns 0 on success, -1 on failure.
+*/
+NSPR_API(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask );
+
+/*
+** Set the default CPU Affinity mask.
+**
+*/
+NSPR_API(PRInt32) PR_SetCPUAffinityMask(PRUint32 mask);
+
+/*
+** Show status of all threads to standard error output.
+*/
+NSPR_API(void) PR_ShowStatus(void);
+
+/*
+** Set thread recycle mode to on (1) or off (0)
+*/
+NSPR_API(void) PR_SetThreadRecycleMode(PRUint32 flag);
+
+
+/*---------------------------------------------------------------------------
+** THREAD PRIVATE FUNCTIONS FOR GARBAGE COLLECTIBLE THREADS           
+---------------------------------------------------------------------------*/
+
+/* 
+** Only Garbage collectible threads participate in resume all, suspend all and 
+** enumeration operations.  They are also different during creation when
+** platform specific action may be needed (For example, all Solaris GC able
+** threads are bound threads).
+*/
+
+/*
+** Same as PR_CreateThread except that the thread is marked as garbage
+** collectible.
+*/
+NSPR_API(PRThread*) PR_CreateThreadGCAble(PRThreadType type,
+				     void (*start)(void *arg),
+				     void *arg,
+				     PRThreadPriority priority,
+				     PRThreadScope scope,
+				     PRThreadState state,
+				     PRUint32 stackSize);
+
+/*
+** Same as PR_AttachThread except that the thread being attached is marked as 
+** garbage collectible.
+*/
+NSPR_API(PRThread*) PR_AttachThreadGCAble(PRThreadType type,
+					PRThreadPriority priority,
+					PRThreadStack *stack);
+
+/*
+** Mark the thread as garbage collectible.
+*/
+NSPR_API(void) PR_SetThreadGCAble(void);
+
+/*
+** Unmark the thread as garbage collectible.
+*/
+NSPR_API(void) PR_ClearThreadGCAble(void);
+
+/*
+** This routine prevents all other GC able threads from running. This call is needed by 
+** the garbage collector.
+*/
+NSPR_API(void) PR_SuspendAll(void);
+
+/*
+** This routine unblocks all other GC able threads that were suspended from running by 
+** PR_SuspendAll(). This call is needed by the garbage collector.
+*/
+NSPR_API(void) PR_ResumeAll(void);
+
+/*
+** Return the thread stack pointer of the given thread. 
+** Needed by the garbage collector.
+*/
+NSPR_API(void *) PR_GetSP(PRThread *thread);
+
+/*
+** Save the registers that the GC would find interesting into the thread
+** "t". isCurrent will be non-zero if the thread state that is being
+** saved is the currently executing thread. Return the address of the
+** first register to be scanned as well as the number of registers to
+** scan in "np".
+**
+** If "isCurrent" is non-zero then it is allowed for the thread context
+** area to be used as scratch storage to hold just the registers
+** necessary for scanning.
+**
+** This function simply calls the internal function _MD_HomeGCRegisters().
+*/
+NSPR_API(PRWord *) PR_GetGCRegisters(PRThread *t, int isCurrent, int *np);
+
+/*
+** (Get|Set)ExecutionEnvironent
+**
+** Used by Java to associate it's execution environment so garbage collector
+** can find it. If return is NULL, then it's probably not a collectable thread.
+**
+** There's no locking required around these calls.
+*/
+NSPR_API(void*) GetExecutionEnvironment(PRThread *thread);
+NSPR_API(void) SetExecutionEnvironment(PRThread* thread, void *environment);
+
+/*
+** Enumeration function that applies "func(thread,i,arg)" to each active
+** thread in the process. The enumerator returns PR_SUCCESS if the enumeration
+** should continue, any other value is considered failure, and enumeration
+** stops, returning the failure value from PR_EnumerateThreads.
+** Needed by the garbage collector.
+*/
+typedef PRStatus (PR_CALLBACK *PREnumerator)(PRThread *t, int i, void *arg);
+NSPR_API(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg);
+
+/* 
+** Signature of a thread stack scanning function. It is applied to every
+** contiguous group of potential pointers within a thread. Count denotes the
+** number of pointers. 
+*/
+typedef PRStatus 
+(PR_CALLBACK *PRScanStackFun)(PRThread* t,
+			      void** baseAddr, PRUword count, void* closure);
+
+/*
+** Applies scanFun to all contiguous groups of potential pointers 
+** within a thread. This includes the stack, registers, and thread-local
+** data. If scanFun returns a status value other than PR_SUCCESS the scan
+** is aborted, and the status value is returned. 
+*/
+NSPR_API(PRStatus)
+PR_ThreadScanStackPointers(PRThread* t,
+                           PRScanStackFun scanFun, void* scanClosure);
+
+/* 
+** Calls PR_ThreadScanStackPointers for every thread.
+*/
+NSPR_API(PRStatus)
+PR_ScanStackPointers(PRScanStackFun scanFun, void* scanClosure);
+
+/*
+** Returns a conservative estimate on the amount of stack space left
+** on a thread in bytes, sufficient for making decisions about whether 
+** to continue recursing or not.
+*/
+NSPR_API(PRUword)
+PR_GetStackSpaceLeft(PRThread* t);
+
+/*---------------------------------------------------------------------------
+** THREAD CPU PRIVATE FUNCTIONS             
+---------------------------------------------------------------------------*/
+
+/*
+** Get a pointer to the primordial CPU.
+*/
+NSPR_API(struct _PRCPU *) _PR_GetPrimordialCPU(void);
+
+/*---------------------------------------------------------------------------
+** THREAD SYNCHRONIZATION PRIVATE FUNCTIONS
+---------------------------------------------------------------------------*/
+
+/*
+** Create a new named monitor (named for debugging purposes).
+**  Monitors are re-entrant locks with a built-in condition variable.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low.
+*/
+NSPR_API(PRMonitor*) PR_NewNamedMonitor(const char* name);
+
+/*
+** Test and then lock the lock if it's not already locked by some other
+** thread. Return PR_FALSE if some other thread owned the lock at the
+** time of the call.
+*/
+NSPR_API(PRBool) PR_TestAndLock(PRLock *lock);
+
+/*
+** Test and then enter the mutex associated with the monitor if it's not
+** already entered by some other thread. Return PR_FALSE if some other
+** thread owned the mutex at the time of the call.
+*/
+NSPR_API(PRBool) PR_TestAndEnterMonitor(PRMonitor *mon);
+
+/*
+** Return the number of times that the current thread has entered the
+** mutex. Returns zero if the current thread has not entered the mutex.
+*/
+NSPR_API(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon);
+
+/*
+** Just like PR_CEnterMonitor except that if the monitor is owned by
+** another thread NULL is returned.
+*/
+NSPR_API(PRMonitor*) PR_CTestAndEnterMonitor(void *address);
+
+/*---------------------------------------------------------------------------
+** PLATFORM-SPECIFIC THREAD SYNCHRONIZATION FUNCTIONS
+---------------------------------------------------------------------------*/
+#if defined(XP_MAC)
+
+NSPR_API(void) PR_Mac_WaitForAsyncNotify(PRIntervalTime timeout);
+NSPR_API(void) PR_Mac_PostAsyncNotify(PRThread *thread);
+
+#endif /* XP_MAC */
+
+/*---------------------------------------------------------------------------
+** PLATFORM-SPECIFIC INITIALIZATION FUNCTIONS
+---------------------------------------------------------------------------*/
+#if defined(IRIX)
+/*
+** Irix specific initialization funtion to be called before PR_Init
+** is called by the application. Sets the CONF_INITUSERS and CONF_INITSIZE
+** attributes of the shared arena set up by nspr.
+**
+** The environment variables _NSPR_IRIX_INITUSERS and _NSPR_IRIX_INITSIZE
+** can also be used to set these arena attributes. If _NSPR_IRIX_INITUSERS
+** is set, but not _NSPR_IRIX_INITSIZE, the value of the CONF_INITSIZE
+** attribute of the nspr arena is scaled as a function of the
+** _NSPR_IRIX_INITUSERS value.
+** 
+** If the _PR_Irix_Set_Arena_Params() is called in addition to setting the
+** environment variables, the values of the environment variables are used.
+** 
+*/
+NSPR_API(void) _PR_Irix_Set_Arena_Params(PRInt32 initusers, PRInt32 initsize);
+
+#endif /* IRIX */
+
+#if defined(XP_OS2)
+/*
+** These functions need to be called at the start and end of a thread.
+** An EXCEPTIONREGISTRATIONRECORD must be declared on the stack and its
+** address passed to the two functions.
+*/
+NSPR_API(void) PR_OS2_SetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* e);
+NSPR_API(void) PR_OS2_UnsetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* e);
+#endif /* XP_OS2 */
+
+/* I think PR_GetMonitorEntryCount is useless. All you really want is this... */
+#define PR_InMonitor(m)		(PR_GetMonitorEntryCount(m) > 0)
+
+/*---------------------------------------------------------------------------
+** Special X-Lock hack for client
+---------------------------------------------------------------------------*/
+
+#ifdef XP_UNIX
+extern void PR_XLock(void);
+extern void PR_XUnlock(void);
+extern PRBool PR_XIsLocked(void);
+#endif /* XP_UNIX */
+
+PR_END_EXTERN_C
+
+#endif /* pprthred_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/private/primpl.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/private/primpl.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2148 @@
+/* -*- 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 primpl_h___
+#define primpl_h___
+
+/*
+ * HP-UX 10.10's pthread.h (DCE threads) includes dce/cma.h, which
+ * has:
+ *     #define sigaction _sigaction_sys
+ * This macro causes chaos if signal.h gets included before pthread.h.
+ * To be safe, we include pthread.h first.
+ */
+
+#if defined(_PR_PTHREADS)
+#include <pthread.h>
+#endif
+
+#if defined(_PR_BTHREADS)
+#include <kernel/OS.h>
+#endif
+
+#ifdef WINNT
+/* Need to force service-pack 3 extensions to be defined by
+** setting _WIN32_WINNT to NT 4.0 for winsock.h, winbase.h, winnt.h.
+*/
+#ifndef  _WIN32_WINNT
+    #define _WIN32_WINNT 0x0400
+#elif   (_WIN32_WINNT < 0x0400)
+    #undef  _WIN32_WINNT
+    #define _WIN32_WINNT 0x0400
+#endif /* _WIN32_WINNT */
+#endif /* WINNT */
+
+#include "nspr.h"
+#include "prpriv.h"
+
+typedef struct PRSegment PRSegment;
+
+#ifdef XP_MAC
+#include "prosdep.h"
+#include "probslet.h"
+#else
+#include "md/prosdep.h"
+#include "obsolete/probslet.h"
+#endif  /* XP_MAC */
+
+#ifdef _PR_HAVE_POSIX_SEMAPHORES
+#include <semaphore.h>
+#elif defined(_PR_HAVE_SYSV_SEMAPHORES)
+#include <sys/sem.h>
+#endif
+
+/*************************************************************************
+*****  A Word about Model Dependent Function Naming Convention ***********
+*************************************************************************/
+
+/*
+NSPR 2.0 must implement its function across a range of platforms 
+including: MAC, Windows/16, Windows/95, Windows/NT, and several
+variants of Unix. Each implementation shares common code as well 
+as having platform dependent portions. This standard describes how
+the model dependent portions are to be implemented.
+
+In header file pr/include/primpl.h, each publicly declared 
+platform dependent function is declared as:
+
+NSPR_API void _PR_MD_FUNCTION( long arg1, long arg2 );
+#define _PR_MD_FUNCTION _MD_FUNCTION
+
+In header file pr/include/md/<platform>/_<platform>.h, 
+each #define'd macro is redefined as one of:
+
+#define _MD_FUNCTION <blanks>
+#define _MD_FUNCTION <expanded macro>
+#define _MD_FUNCTION <osFunction>
+#define _MD_FUNCTION <_MD_Function>
+
+Where:
+
+<blanks> is no definition at all. In this case, the function is not implemented 
+and is never called for this platform. 
+For example: 
+#define _MD_INIT_CPUS()
+
+<expanded macro> is a C language macro expansion. 
+For example: 
+#define        _MD_CLEAN_THREAD(_thread) \
+    PR_BEGIN_MACRO \
+        PR_DestroyCondVar(_thread->md.asyncIOCVar); \
+        PR_DestroyLock(_thread->md.asyncIOLock); \
+    PR_END_MACRO
+
+<osFunction> is some function implemented by the host operating system. 
+For example: 
+#define _MD_EXIT        exit
+
+<_MD_function> is the name of a function implemented for this platform in 
+pr/src/md/<platform>/<soruce>.c file. 
+For example: 
+#define        _MD_GETFILEINFO         _MD_GetFileInfo
+
+In <source>.c, the implementation is:
+PR_IMPLEMENT(PRInt32) _MD_GetFileInfo(const char *fn, PRFileInfo *info);
+*/
+
+PR_BEGIN_EXTERN_C
+
+typedef struct _MDLock _MDLock;
+typedef struct _MDCVar _MDCVar;
+typedef struct _MDSegment _MDSegment;
+typedef struct _MDThread _MDThread;
+typedef struct _MDThreadStack _MDThreadStack;
+typedef struct _MDSemaphore _MDSemaphore;
+typedef struct _MDDir _MDDir;
+#ifdef MOZ_UNICODE
+typedef struct _MDDirUTF16 _MDDirUTF16;
+#endif /* MOZ_UNICODE */
+typedef struct _MDFileDesc _MDFileDesc;
+typedef struct _MDProcess _MDProcess;
+typedef struct _MDFileMap _MDFileMap;
+
+#if defined(_PR_PTHREADS)
+
+/*
+** The following definitions are unique to implementing NSPR using pthreads.
+** Since pthreads defines most of the thread and thread synchronization
+** stuff, this is a pretty small set.
+*/
+
+#define PT_CV_NOTIFIED_LENGTH 6
+typedef struct _PT_Notified _PT_Notified;
+struct _PT_Notified
+{
+    PRIntn length;              /* # of used entries in this structure */
+    struct
+    {
+        PRCondVar *cv;          /* the condition variable notified */
+        PRIntn times;           /* and the number of times notified */
+    } cv[PT_CV_NOTIFIED_LENGTH];
+    _PT_Notified *link;         /* link to another of these | NULL */
+};
+
+/*
+ * bits defined for pthreads 'state' field 
+ */
+#define PT_THREAD_DETACHED  0x01    /* thread can't be joined */
+#define PT_THREAD_GLOBAL    0x02    /* a global thread (unlikely) */
+#define PT_THREAD_SYSTEM    0x04    /* system (not user) thread */
+#define PT_THREAD_PRIMORD   0x08    /* this is the primordial thread */
+#define PT_THREAD_ABORTED   0x10    /* thread has been interrupted */
+#define PT_THREAD_GCABLE    0x20    /* thread is garbage collectible */
+#define PT_THREAD_SUSPENDED 0x40    /* thread has been suspended */
+#define PT_THREAD_FOREIGN   0x80    /* thread is not one of ours */
+#define PT_THREAD_BOUND     0x100    /* a bound-global thread */
+
+#define _PT_THREAD_INTERRUPTED(thr)					\
+		(!(thr->interrupt_blocked) && (thr->state & PT_THREAD_ABORTED))
+#define _PT_THREAD_BLOCK_INTERRUPT(thr)				\
+		(thr->interrupt_blocked = 1)
+#define _PT_THREAD_UNBLOCK_INTERRUPT(thr)			\
+		(thr->interrupt_blocked = 0)
+
+#ifdef GC_LEAK_DETECTOR
+/* All threads are GCable. */
+#define _PT_IS_GCABLE_THREAD(thr) 1
+#else
+#define _PT_IS_GCABLE_THREAD(thr) ((thr)->state & PT_THREAD_GCABLE)
+#endif /* GC_LEAK_DETECTOR */
+
+/* 
+** Possible values for thread's suspend field
+** Note that the first two can be the same as they are really mutually exclusive,
+** i.e. both cannot be happening at the same time. We have two symbolic names
+** just as a mnemonic.
+**/
+#define PT_THREAD_RESUMED   0x80    /* thread has been resumed */
+#define PT_THREAD_SETGCABLE 0x100   /* set the GCAble flag */
+
+#if defined(DEBUG)
+
+typedef struct PTDebug
+{
+    PRTime timeStarted;
+    PRUintn locks_created, locks_destroyed;
+    PRUintn locks_acquired, locks_released;
+    PRUintn cvars_created, cvars_destroyed;
+    PRUintn cvars_notified, delayed_cv_deletes;
+} PTDebug;
+
+#endif /* defined(DEBUG) */
+
+NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
+
+#else /* defined(_PR_PTHREADS) */
+
+NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
+
+/*
+** This section is contains those parts needed to implement NSPR on
+** platforms in general. One would assume that the pthreads implementation
+** included lots of the same types, at least conceptually.
+*/
+
+/*
+ * Local threads only.  No multiple CPU support and hence all the
+ * following routines are no-op.
+ */
+#ifdef _PR_LOCAL_THREADS_ONLY
+
+#define        _PR_MD_SUSPEND_THREAD(thread)        
+#define        _PR_MD_RESUME_THREAD(thread)        
+#define        _PR_MD_SUSPEND_CPU(cpu)        
+#define        _PR_MD_RESUME_CPU(cpu)        
+#define        _PR_MD_BEGIN_SUSPEND_ALL()        
+#define        _PR_MD_END_SUSPEND_ALL()        
+#define        _PR_MD_BEGIN_RESUME_ALL()        
+#define        _PR_MD_END_RESUME_ALL()
+#define _PR_MD_INIT_ATTACHED_THREAD(thread) PR_FAILURE
+
+#endif
+
+typedef struct _PRCPUQueue _PRCPUQueue;
+typedef struct _PRCPU _PRCPU;
+typedef struct _MDCPU _MDCPU;
+
+struct _PRCPUQueue {
+    _MDLock  runQLock;          /* lock for the run + wait queues */
+    _MDLock  sleepQLock;        /* lock for the run + wait queues */
+    _MDLock  miscQLock;         /* lock for the run + wait queues */
+
+    PRCList runQ[PR_PRIORITY_LAST + 1]; /* run queue for this CPU */
+    PRUint32  runQReadyMask;
+    PRCList sleepQ;
+    PRIntervalTime sleepQmax;
+    PRCList pauseQ;
+    PRCList suspendQ;
+    PRCList waitingToJoinQ;
+
+    PRUintn   numCPUs;          /* number of CPUs using this Q */
+};
+
+struct _PRCPU {
+    PRCList links;              /* link list of CPUs */
+    PRUint32 id;                /* id for this CPU */
+
+    union {
+        PRInt32 bits;
+        PRUint8 missed[4];
+    } u;
+    PRIntn where;               /* index into u.missed */
+    PRPackedBool paused;        /* cpu is paused */
+    PRPackedBool exit;          /* cpu should exit */
+
+    PRThread *thread;           /* native thread for this CPUThread */
+    PRThread *idle_thread;      /* user-level idle thread for this CPUThread */
+
+    PRIntervalTime last_clock;  /* the last time we went into 
+                                 * _PR_ClockInterrupt() on this CPU
+                                 */
+
+    _PRCPUQueue *queue;
+
+    _MDCPU md;
+};
+
+typedef struct _PRInterruptTable {
+    const char *name;
+    PRUintn missed_bit;
+    void (*handler)(void);
+} _PRInterruptTable;
+
+#define _PR_CPU_PTR(_qp) \
+    ((_PRCPU*) ((char*) (_qp) - offsetof(_PRCPU,links)))
+
+#if !defined(IRIX) && !defined(WIN32) && !defined(XP_OS2) \
+        && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY))
+#define _MD_GET_ATTACHED_THREAD()        (_PR_MD_CURRENT_THREAD())
+#endif
+
+#ifdef _PR_LOCAL_THREADS_ONLY 
+
+NSPR_API(struct _PRCPU *)              _pr_currentCPU;
+NSPR_API(PRThread *)                   _pr_currentThread;
+NSPR_API(PRThread *)                   _pr_lastThread;
+NSPR_API(PRInt32)                      _pr_intsOff;
+
+#define _MD_CURRENT_CPU()               (_pr_currentCPU)
+#define _MD_SET_CURRENT_CPU(_cpu)       (_pr_currentCPU = (_cpu))
+#define _MD_CURRENT_THREAD()            (_pr_currentThread)
+#define _MD_SET_CURRENT_THREAD(_thread) (_pr_currentThread = (_thread))
+#define _MD_LAST_THREAD()               (_pr_lastThread)
+#define _MD_SET_LAST_THREAD(t)          (_pr_lastThread = t)
+
+#ifndef XP_MAC
+#define _MD_GET_INTSOFF()               (_pr_intsOff)
+#define _MD_SET_INTSOFF(_val)           (_pr_intsOff = _val)
+#endif
+
+
+/* The unbalanced curly braces in these two macros are intentional */
+#define _PR_LOCK_HEAP() { PRIntn _is; if (_pr_currentCPU) _PR_INTSOFF(_is);
+#define _PR_UNLOCK_HEAP() if (_pr_currentCPU) _PR_INTSON(_is); }
+
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+extern PRInt32                  _native_threads_only;
+
+#if defined(_PR_GLOBAL_THREADS_ONLY)
+
+#define _MD_GET_INTSOFF() 0
+#define _MD_SET_INTSOFF(_val)
+#define _PR_INTSOFF(_is)
+#define _PR_FAST_INTSON(_is)
+#define _PR_INTSON(_is)
+#define _PR_THREAD_LOCK(_thread)
+#define _PR_THREAD_UNLOCK(_thread)
+#define _PR_RUNQ_LOCK(cpu)
+#define _PR_RUNQ_UNLOCK(cpu)
+#define _PR_SLEEPQ_LOCK(thread)
+#define _PR_SLEEPQ_UNLOCK(thread)
+#define _PR_MISCQ_LOCK(thread)
+#define _PR_MISCQ_UNLOCK(thread)
+#define _PR_CPU_LIST_LOCK()
+#define _PR_CPU_LIST_UNLOCK()
+
+#define _PR_ADD_RUNQ(_thread, _cpu, _pri)
+#define _PR_DEL_RUNQ(_thread)
+#define _PR_ADD_SLEEPQ(_thread, _timeout)
+#define _PR_DEL_SLEEPQ(_thread, _propogate)
+#define _PR_ADD_JOINQ(_thread, _cpu)
+#define _PR_DEL_JOINQ(_thread)
+#define _PR_ADD_SUSPENDQ(_thread, _cpu)
+#define _PR_DEL_SUSPENDQ(_thread)
+
+#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
+
+#define _PR_IS_NATIVE_THREAD(thread) 1
+#define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
+
+#else
+
+#ifdef XP_MAC
+
+#define _PR_INTSOFF(_is)        _MD_INTSOFF(_is)
+
+#else /* XP_MAC */
+
+#define _PR_INTSOFF(_is) \
+    PR_BEGIN_MACRO \
+        (_is) = _PR_MD_GET_INTSOFF(); \
+        _PR_MD_SET_INTSOFF(1); \
+    PR_END_MACRO
+
+#endif /* XP_MAC */
+
+#define _PR_FAST_INTSON(_is) \
+    PR_BEGIN_MACRO \
+        _PR_MD_SET_INTSOFF(_is); \
+    PR_END_MACRO
+
+#define _PR_INTSON(_is) \
+    PR_BEGIN_MACRO \
+        if ((_is == 0) && (_PR_MD_CURRENT_CPU())->u.bits) \
+                _PR_IntsOn((_PR_MD_CURRENT_CPU())); \
+        _PR_MD_SET_INTSOFF(_is); \
+    PR_END_MACRO
+
+#ifdef _PR_LOCAL_THREADS_ONLY 
+
+#define _PR_IS_NATIVE_THREAD(thread) 0
+#define _PR_THREAD_LOCK(_thread)
+#define _PR_THREAD_UNLOCK(_thread)
+#define _PR_RUNQ_LOCK(cpu)
+#define _PR_RUNQ_UNLOCK(cpu)
+#define _PR_SLEEPQ_LOCK(thread)
+#define _PR_SLEEPQ_UNLOCK(thread)
+#define _PR_MISCQ_LOCK(thread)
+#define _PR_MISCQ_UNLOCK(thread)
+#define _PR_CPU_LIST_LOCK()
+#define _PR_CPU_LIST_UNLOCK()
+
+#define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
+    PR_BEGIN_MACRO \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
+    _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
+    PR_END_MACRO
+
+#define _PR_DEL_RUNQ(_thread) \
+    PR_BEGIN_MACRO \
+    _PRCPU *_cpu = _thread->cpu; \
+    PRInt32 _pri = _thread->priority; \
+    PR_REMOVE_LINK(&(_thread)->links); \
+    if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
+        _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
+    PR_END_MACRO
+
+#define _PR_ADD_SLEEPQ(_thread, _timeout) \
+    _PR_AddSleepQ(_thread, _timeout);   
+
+#define _PR_DEL_SLEEPQ(_thread, _propogate) \
+    _PR_DelSleepQ(_thread, _propogate);  
+
+#define _PR_ADD_JOINQ(_thread, _cpu) \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
+
+#define _PR_DEL_JOINQ(_thread) \
+    PR_REMOVE_LINK(&(_thread)->links);
+
+#define _PR_ADD_SUSPENDQ(_thread, _cpu) \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
+
+#define _PR_DEL_SUSPENDQ(_thread) \
+    PR_REMOVE_LINK(&(_thread)->links);
+
+#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU)
+
+#define _PR_IS_NATIVE_THREAD_SUPPORTED() 0
+
+#else        /* _PR_LOCAL_THREADS_ONLY */
+
+/* These are for the "combined" thread model */
+
+#define _PR_THREAD_LOCK(_thread) \
+    _PR_MD_LOCK(&(_thread)->threadLock);
+
+#define _PR_THREAD_UNLOCK(_thread) \
+    _PR_MD_UNLOCK(&(_thread)->threadLock);
+
+#define _PR_RUNQ_LOCK(_cpu) \
+    PR_BEGIN_MACRO \
+    _PR_MD_LOCK(&(_cpu)->queue->runQLock );\
+    PR_END_MACRO
+    
+#define _PR_RUNQ_UNLOCK(_cpu) \
+    PR_BEGIN_MACRO \
+    _PR_MD_UNLOCK(&(_cpu)->queue->runQLock );\
+    PR_END_MACRO
+
+#define _PR_SLEEPQ_LOCK(_cpu) \
+    _PR_MD_LOCK(&(_cpu)->queue->sleepQLock );
+
+#define _PR_SLEEPQ_UNLOCK(_cpu) \
+    _PR_MD_UNLOCK(&(_cpu)->queue->sleepQLock );
+
+#define _PR_MISCQ_LOCK(_cpu) \
+    _PR_MD_LOCK(&(_cpu)->queue->miscQLock );
+
+#define _PR_MISCQ_UNLOCK(_cpu) \
+    _PR_MD_UNLOCK(&(_cpu)->queue->miscQLock );
+
+#define _PR_CPU_LIST_LOCK()                 _PR_MD_LOCK(&_pr_cpuLock)
+#define _PR_CPU_LIST_UNLOCK()               _PR_MD_UNLOCK(&_pr_cpuLock)
+
+#define QUEUE_RUN           0x1
+#define QUEUE_SLEEP         0x2
+#define QUEUE_JOIN          0x4
+#define QUEUE_SUSPEND       0x8
+#define QUEUE_LOCK          0x10
+
+#define _PR_ADD_RUNQ(_thread, _cpu, _pri) \
+    PR_BEGIN_MACRO \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_RUNQ(_cpu)[_pri]); \
+    _PR_RUNQREADYMASK(_cpu) |= (1L << _pri); \
+    PR_ASSERT((_thread)->queueCount == 0); \
+    (_thread)->queueCount = QUEUE_RUN; \
+    PR_END_MACRO
+
+#define _PR_DEL_RUNQ(_thread) \
+    PR_BEGIN_MACRO \
+    _PRCPU *_cpu = _thread->cpu; \
+    PRInt32 _pri = _thread->priority; \
+    PR_REMOVE_LINK(&(_thread)->links); \
+    if (PR_CLIST_IS_EMPTY(&_PR_RUNQ(_cpu)[_pri])) \
+        _PR_RUNQREADYMASK(_cpu) &= ~(1L << _pri); \
+    PR_ASSERT((_thread)->queueCount == QUEUE_RUN);\
+    (_thread)->queueCount = 0; \
+    PR_END_MACRO
+
+#define _PR_ADD_SLEEPQ(_thread, _timeout) \
+    PR_ASSERT((_thread)->queueCount == 0); \
+    (_thread)->queueCount = QUEUE_SLEEP; \
+    _PR_AddSleepQ(_thread, _timeout);  
+
+#define _PR_DEL_SLEEPQ(_thread, _propogate) \
+    PR_ASSERT((_thread)->queueCount == QUEUE_SLEEP);\
+    (_thread)->queueCount = 0; \
+    _PR_DelSleepQ(_thread, _propogate);  
+
+#define _PR_ADD_JOINQ(_thread, _cpu) \
+    PR_ASSERT((_thread)->queueCount == 0); \
+    (_thread)->queueCount = QUEUE_JOIN; \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_WAITINGTOJOINQ(_cpu));
+
+#define _PR_DEL_JOINQ(_thread) \
+    PR_ASSERT((_thread)->queueCount == QUEUE_JOIN);\
+    (_thread)->queueCount = 0; \
+    PR_REMOVE_LINK(&(_thread)->links);
+
+#define _PR_ADD_SUSPENDQ(_thread, _cpu) \
+    PR_ASSERT((_thread)->queueCount == 0); \
+    (_thread)->queueCount = QUEUE_SUSPEND; \
+    PR_APPEND_LINK(&(_thread)->links, &_PR_SUSPENDQ(_cpu));
+
+#define _PR_DEL_SUSPENDQ(_thread) \
+    PR_ASSERT((_thread)->queueCount == QUEUE_SUSPEND);\
+    (_thread)->queueCount = 0; \
+    PR_REMOVE_LINK(&(_thread)->links);
+
+#define _PR_THREAD_SWITCH_CPU(_thread, _newCPU) \
+    (_thread)->cpu = (_newCPU);
+
+#define _PR_IS_NATIVE_THREAD(thread) (thread->flags & _PR_GLOBAL_SCOPE)
+#define _PR_IS_NATIVE_THREAD_SUPPORTED() 1
+
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+#endif /* _PR_GLOBAL_THREADS_ONLY */
+
+#define _PR_SET_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 1
+#define _PR_CLEAR_RESCHED_FLAG() _PR_MD_CURRENT_CPU()->u.missed[3] = 0
+
+extern _PRInterruptTable _pr_interruptTable[];
+
+/* Bits for _pr_interruptState.u.missed[0,1] */
+#define _PR_MISSED_CLOCK    0x1
+#define _PR_MISSED_IO        0x2
+#define _PR_MISSED_CHILD    0x4
+
+extern void _PR_IntsOn(_PRCPU *cpu);
+
+NSPR_API(void) _PR_WakeupCPU(void);
+NSPR_API(void) _PR_PauseCPU(void);
+
+/************************************************************************/
+
+#define _PR_LOCK_LOCK(_lock) \
+    _PR_MD_LOCK(&(_lock)->ilock);
+#define _PR_LOCK_UNLOCK(_lock) \
+    _PR_MD_UNLOCK(&(_lock)->ilock);
+    
+extern void _PR_UnblockLockWaiter(PRLock *lock);
+
+#define _PR_LOCK_PTR(_qp) \
+    ((PRLock*) ((char*) (_qp) - offsetof(PRLock,links)))
+
+/************************************************************************/
+
+#define _PR_CVAR_LOCK(_cvar) \
+    _PR_MD_LOCK(&(_cvar)->ilock); 
+#define _PR_CVAR_UNLOCK(_cvar) \
+    _PR_MD_UNLOCK(&(_cvar)->ilock);
+
+extern PRStatus _PR_WaitCondVar(
+    PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout);
+extern PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen);
+
+NSPR_API(void) _PR_Notify(PRMonitor *mon, PRBool all, PRBool sticky);
+
+/* PRThread.flags */
+#define _PR_SYSTEM          0x01
+#define _PR_INTERRUPT       0x02
+#define _PR_ATTACHED        0x04        /* created via PR_AttachThread */
+#define _PR_PRIMORDIAL      0x08        /* the thread that called PR_Init */
+#define _PR_ON_SLEEPQ       0x10        /* thread is on the sleepQ */
+#define _PR_ON_PAUSEQ       0x20        /* thread is on the pauseQ */
+#define _PR_SUSPENDING      0x40        /* thread wants to suspend */
+#define _PR_GLOBAL_SCOPE    0x80        /* thread is global scope */
+#define _PR_IDLE_THREAD     0x200       /* this is an idle thread        */
+#define _PR_GCABLE_THREAD   0x400       /* this is a collectable thread */
+#define _PR_BOUND_THREAD    0x800       /* a bound thread */
+#define _PR_INTERRUPT_BLOCKED	0x1000	/* interrupts blocked */
+
+/* PRThread.state */
+#define _PR_UNBORN       0
+#define _PR_RUNNABLE     1
+#define _PR_RUNNING      2
+#define _PR_LOCK_WAIT    3
+#define _PR_COND_WAIT    4
+#define _PR_JOIN_WAIT    5
+#define _PR_IO_WAIT      6
+#define _PR_SUSPENDED    7
+#define _PR_DEAD_STATE   8  /* for debugging */
+
+/* PRThreadStack.flags */
+#define _PR_STACK_VM            0x1    /* using vm instead of malloc */
+#define _PR_STACK_MAPPED        0x2    /* vm is mapped */
+#define _PR_STACK_PRIMORDIAL    0x4    /* stack for primordial thread */
+
+/* 
+** If the default stcksize from the client is zero, we need to pick a machine
+** dependent value.  This is only for standard user threads.  For custom threads,
+** 0 has a special meaning.
+** Adjust stackSize. Round up to a page boundary.
+*/
+
+#ifndef _MD_MINIMUM_STACK_SIZE
+#define _MD_MINIMUM_STACK_SIZE	0
+#endif
+
+#if (!defined(HAVE_CUSTOM_USER_THREADS))
+#define        _PR_ADJUST_STACKSIZE(stackSize) \
+        PR_BEGIN_MACRO \
+    if (stackSize == 0) \
+                stackSize = _MD_DEFAULT_STACK_SIZE; \
+    if (stackSize < _MD_MINIMUM_STACK_SIZE) \
+                stackSize = _MD_MINIMUM_STACK_SIZE; \
+    stackSize = (stackSize + (1 << _pr_pageShift) - 1) >> _pr_pageShift; \
+    stackSize <<= _pr_pageShift; \
+        PR_END_MACRO
+#else
+#define        _PR_ADJUST_STACKSIZE(stackSize)
+#endif
+
+#ifdef GC_LEAK_DETECTOR
+/* All threads are GCable. */
+#define _PR_IS_GCABLE_THREAD(thr) 1
+#else
+#define _PR_IS_GCABLE_THREAD(thr) ((thr)->flags & _PR_GCABLE_THREAD)
+#endif /* GC_LEAK_DETECTOR */
+
+#define _PR_PENDING_INTERRUPT(thr)					\
+		(!((thr)->flags & _PR_INTERRUPT_BLOCKED) && ((thr)->flags & _PR_INTERRUPT))
+#define _PR_THREAD_BLOCK_INTERRUPT(thr)			\
+		(thr->flags |= _PR_INTERRUPT_BLOCKED)
+#define _PR_THREAD_UNBLOCK_INTERRUPT(thr)			\
+		(thr->flags &= ~_PR_INTERRUPT_BLOCKED)
+
+#define _PR_THREAD_PTR(_qp) \
+    ((PRThread*) ((char*) (_qp) - offsetof(PRThread,links)))
+
+#define _PR_ACTIVE_THREAD_PTR(_qp) \
+    ((PRThread*) ((char*) (_qp) - offsetof(PRThread,active)))
+
+#define _PR_THREAD_CONDQ_PTR(_qp) \
+    ((PRThread*) ((char*) (_qp) - offsetof(PRThread,waitQLinks)))
+
+#define _PR_THREAD_MD_TO_PTR(_md) \
+    ((PRThread*) ((char*) (_md) - offsetof(PRThread,md)))
+
+#define _PR_THREAD_STACK_TO_PTR(_stack) \
+    ((PRThread*) (_stack->thr))
+
+extern PRCList _pr_active_local_threadQ;
+extern PRCList _pr_active_global_threadQ;
+extern PRCList _pr_cpuQ;
+extern _MDLock  _pr_cpuLock;
+extern PRInt32 _pr_md_idle_cpus;
+
+#define _PR_ACTIVE_LOCAL_THREADQ()          _pr_active_local_threadQ
+#define _PR_ACTIVE_GLOBAL_THREADQ()         _pr_active_global_threadQ
+#define _PR_CPUQ()                          _pr_cpuQ
+#define _PR_RUNQ(_cpu)                      ((_cpu)->queue->runQ)
+#define _PR_RUNQREADYMASK(_cpu)             ((_cpu)->queue->runQReadyMask)
+#define _PR_SLEEPQ(_cpu)                    ((_cpu)->queue->sleepQ)
+#define _PR_SLEEPQMAX(_cpu)                 ((_cpu)->queue->sleepQmax)
+#define _PR_PAUSEQ(_cpu)                    ((_cpu)->queue->pauseQ)
+#define _PR_SUSPENDQ(_cpu)                  ((_cpu)->queue->suspendQ)
+#define _PR_WAITINGTOJOINQ(_cpu)            ((_cpu)->queue->waitingToJoinQ)
+
+extern PRUint32 _pr_recycleThreads;   /* Flag for behavior on thread cleanup */
+extern PRLock *_pr_deadQLock;
+extern PRUint32 _pr_numNativeDead;
+extern PRUint32 _pr_numUserDead;
+extern PRCList _pr_deadNativeQ;
+extern PRCList _pr_deadUserQ;
+#define _PR_DEADNATIVEQ     _pr_deadNativeQ
+#define _PR_DEADUSERQ       _pr_deadUserQ
+#define _PR_DEADQ_LOCK      PR_Lock(_pr_deadQLock);
+#define _PR_DEADQ_UNLOCK    PR_Unlock(_pr_deadQLock);
+#define _PR_INC_DEADNATIVE  (_pr_numNativeDead++)
+#define _PR_DEC_DEADNATIVE  (_pr_numNativeDead--)
+#define _PR_NUM_DEADNATIVE  (_pr_numNativeDead)
+#define _PR_INC_DEADUSER    (_pr_numUserDead++)
+#define _PR_DEC_DEADUSER    (_pr_numUserDead--)
+#define _PR_NUM_DEADUSER    (_pr_numUserDead)
+
+extern PRUint32 _pr_utid;
+
+extern struct _PRCPU  *_pr_primordialCPU;
+
+extern PRLock *_pr_activeLock;          /* lock for userActive and systemActive */
+extern PRInt32 _pr_userActive;          /* number of active user threads */
+extern PRInt32 _pr_systemActive;        /* number of active system threads */
+extern PRInt32 _pr_primordialExitCount; /* number of user threads left
+                                         * before the primordial thread
+                                         * can exit.  */
+extern PRCondVar *_pr_primordialExitCVar; /* the condition variable for
+                                           * notifying the primordial thread
+                                           * when all other user threads
+                                           * have terminated.  */
+
+extern PRUintn _pr_maxPTDs;
+
+extern PRLock *_pr_terminationCVLock;
+
+/*************************************************************************
+* Internal routines either called by PR itself or from machine-dependent *
+* code.                                                                  *
+*************************************************************************/
+
+extern void _PR_ClockInterrupt(void);
+
+extern void _PR_Schedule(void);
+extern void _PR_SetThreadPriority(
+    PRThread* thread, PRThreadPriority priority);
+
+/***********************************************************************
+** FUNCTION:	_PR_NewSegment()
+** DESCRIPTION:
+**   Allocate a memory segment. The "size" value is rounded up to the
+**   native system page size and a page aligned portion of memory is
+**   returned.  This memory is not part of the malloc heap. If "vaddr" is
+**   not NULL then PR tries to allocate the segment at the desired virtual
+**   address.
+** INPUTS:	size:  size of the desired memory segment
+**          vaddr:  address at which the newly aquired segment is to be
+**                  mapped into memory.
+** OUTPUTS:	a memory segment is allocated, a PRSegment is allocated
+** RETURN:	pointer to PRSegment
+***********************************************************************/
+extern PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr);
+
+/***********************************************************************
+** FUNCTION:	_PR_DestroySegment()
+** DESCRIPTION:
+**   The memory segment and the PRSegment are freed
+** INPUTS:	seg:  pointer to PRSegment to be freed
+** OUTPUTS:	the the PRSegment and its associated memory segment are freed
+** RETURN:	void
+***********************************************************************/
+extern void _PR_DestroySegment(PRSegment *seg);
+
+extern PRThreadStack * _PR_NewStack(PRUint32 stackSize);
+extern void _PR_FreeStack(PRThreadStack *stack);
+extern PRBool _PR_NotifyThread (PRThread *thread, PRThread *me);
+extern void _PR_NotifyLockedThread (PRThread *thread);
+
+NSPR_API(void) _PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout);
+NSPR_API(void) _PR_DelSleepQ(PRThread *thread, PRBool propogate_time);
+
+extern void _PR_AddThreadToRunQ(PRThread *me, PRThread *thread);
+
+NSPR_API(PRThread*) _PR_CreateThread(PRThreadType type,
+                                     void (*start)(void *arg),
+                                     void *arg,
+                                     PRThreadPriority priority,
+                                     PRThreadScope scope,
+                                     PRThreadState state,
+                                     PRUint32 stackSize,
+                     PRUint32 flags);
+
+extern void _PR_NativeDestroyThread(PRThread *thread);
+extern void _PR_UserDestroyThread(PRThread *thread);
+
+extern PRThread* _PRI_AttachThread(
+    PRThreadType type, PRThreadPriority priority,
+    PRThreadStack *stack, PRUint32 flags);
+
+extern void _PRI_DetachThread(void);
+
+
+#define _PR_IO_PENDING(_thread) ((_thread)->io_pending)
+
+NSPR_API(void) _PR_MD_INIT_CPUS();
+#define    _PR_MD_INIT_CPUS _MD_INIT_CPUS
+
+NSPR_API(void) _PR_MD_WAKEUP_CPUS();
+#define    _PR_MD_WAKEUP_CPUS _MD_WAKEUP_CPUS
+
+/* Interrupts related */
+
+NSPR_API(void) _PR_MD_START_INTERRUPTS(void);
+#define    _PR_MD_START_INTERRUPTS _MD_START_INTERRUPTS
+
+NSPR_API(void) _PR_MD_STOP_INTERRUPTS(void);
+#define    _PR_MD_STOP_INTERRUPTS _MD_STOP_INTERRUPTS
+
+NSPR_API(void) _PR_MD_ENABLE_CLOCK_INTERRUPTS(void);
+#define    _PR_MD_ENABLE_CLOCK_INTERRUPTS _MD_ENABLE_CLOCK_INTERRUPTS
+
+NSPR_API(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void);
+#define    _PR_MD_DISABLE_CLOCK_INTERRUPTS _MD_DISABLE_CLOCK_INTERRUPTS
+
+NSPR_API(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void);
+#define    _PR_MD_BLOCK_CLOCK_INTERRUPTS _MD_BLOCK_CLOCK_INTERRUPTS
+
+NSPR_API(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void);
+#define    _PR_MD_UNBLOCK_CLOCK_INTERRUPTS _MD_UNBLOCK_CLOCK_INTERRUPTS
+
+/* The _PR_MD_WAIT_LOCK and _PR_MD_WAKEUP_WAITER functions put to sleep and
+ * awaken a thread which is waiting on a lock or cvar.
+ */
+extern PRStatus _PR_MD_WAIT(PRThread *, PRIntervalTime timeout);
+#define    _PR_MD_WAIT _MD_WAIT
+
+extern PRStatus _PR_MD_WAKEUP_WAITER(PRThread *);
+#define    _PR_MD_WAKEUP_WAITER _MD_WAKEUP_WAITER
+
+#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
+NSPR_API(void) _PR_MD_CLOCK_INTERRUPT(void);
+#define    _PR_MD_CLOCK_INTERRUPT _MD_CLOCK_INTERRUPT
+#endif
+
+/* Stack debugging */
+NSPR_API(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone);
+#define    _PR_MD_INIT_STACK _MD_INIT_STACK
+
+NSPR_API(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts);
+#define    _PR_MD_CLEAR_STACK _MD_CLEAR_STACK
+
+/* CPU related */
+NSPR_API(PRInt32) _PR_MD_GET_INTSOFF(void);
+#define    _PR_MD_GET_INTSOFF _MD_GET_INTSOFF
+
+NSPR_API(void) _PR_MD_SET_INTSOFF(PRInt32 _val);
+#define    _PR_MD_SET_INTSOFF _MD_SET_INTSOFF
+
+NSPR_API(_PRCPU*) _PR_MD_CURRENT_CPU(void);
+#define    _PR_MD_CURRENT_CPU _MD_CURRENT_CPU
+
+NSPR_API(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu);
+#define    _PR_MD_SET_CURRENT_CPU _MD_SET_CURRENT_CPU
+
+NSPR_API(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu);
+#define    _PR_MD_INIT_RUNNING_CPU _MD_INIT_RUNNING_CPU
+
+/*
+ * Returns the number of threads awoken or 0 if a timeout occurred;
+ */
+extern PRInt32 _PR_MD_PAUSE_CPU(PRIntervalTime timeout);
+#define    _PR_MD_PAUSE_CPU _MD_PAUSE_CPU
+
+extern void _PR_MD_CLEANUP_BEFORE_EXIT(void);
+#define _PR_MD_CLEANUP_BEFORE_EXIT _MD_CLEANUP_BEFORE_EXIT
+
+extern void _PR_MD_EXIT(PRIntn status);
+#define    _PR_MD_EXIT _MD_EXIT
+
+/* Locks related */
+
+NSPR_API(void) _PR_MD_INIT_LOCKS(void);
+#define    _PR_MD_INIT_LOCKS _MD_INIT_LOCKS
+
+NSPR_API(PRStatus) _PR_MD_NEW_LOCK(_MDLock *md);
+#define    _PR_MD_NEW_LOCK _MD_NEW_LOCK
+
+NSPR_API(void) _PR_MD_FREE_LOCK(_MDLock *md);
+#define    _PR_MD_FREE_LOCK _MD_FREE_LOCK
+
+NSPR_API(void) _PR_MD_LOCK(_MDLock *md);
+#define    _PR_MD_LOCK _MD_LOCK
+
+/* Return 0 on success, a nonzero value on failure. */
+NSPR_API(PRIntn) _PR_MD_TEST_AND_LOCK(_MDLock *md);
+#define    _PR_MD_TEST_AND_LOCK _MD_TEST_AND_LOCK
+
+NSPR_API(void) _PR_MD_UNLOCK(_MDLock *md);
+#define    _PR_MD_UNLOCK _MD_UNLOCK
+
+NSPR_API(void) _PR_MD_IOQ_LOCK(void);
+#define    _PR_MD_IOQ_LOCK _MD_IOQ_LOCK
+
+NSPR_API(void) _PR_MD_IOQ_UNLOCK(void);
+#define    _PR_MD_IOQ_UNLOCK _MD_IOQ_UNLOCK
+
+#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
+/* Semaphore related -- only for native threads */
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+NSPR_API(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value);
+#define _PR_MD_NEW_SEM _MD_NEW_SEM
+
+NSPR_API(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md);
+#define _PR_MD_DESTROY_SEM _MD_DESTROY_SEM
+
+NSPR_API(PRStatus) _PR_MD_TIMED_WAIT_SEM(
+    _MDSemaphore *md, PRIntervalTime timeout);
+#define _PR_MD_TIMED_WAIT_SEM _MD_TIMED_WAIT_SEM
+
+NSPR_API(PRStatus) _PR_MD_WAIT_SEM(_MDSemaphore *md);
+#define _PR_MD_WAIT_SEM _MD_WAIT_SEM
+
+NSPR_API(void) _PR_MD_POST_SEM(_MDSemaphore *md);
+#define _PR_MD_POST_SEM _MD_POST_SEM
+#endif /* HAVE_CVAR_BUILT_ON_SEM */
+
+#endif
+
+/* Condition Variables related -- only for native threads */
+
+#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
+NSPR_API(PRInt32) _PR_MD_NEW_CV(_MDCVar *md);
+#define    _PR_MD_NEW_CV _MD_NEW_CV
+
+NSPR_API(void) _PR_MD_FREE_CV(_MDCVar *md);
+#define    _PR_MD_FREE_CV _MD_FREE_CV
+
+NSPR_API(void) _PR_MD_WAIT_CV(
+    _MDCVar *mdCVar,_MDLock *mdLock,PRIntervalTime timeout);
+#define    _PR_MD_WAIT_CV _MD_WAIT_CV
+
+NSPR_API(void) _PR_MD_NOTIFY_CV(_MDCVar *md, _MDLock *lock);
+#define    _PR_MD_NOTIFY_CV _MD_NOTIFY_CV
+
+NSPR_API(void) _PR_MD_NOTIFYALL_CV(_MDCVar *md, _MDLock *lock);
+#define    _PR_MD_NOTIFYALL_CV _MD_NOTIFYALL_CV
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+/* Threads related */
+NSPR_API(PRThread*) _PR_MD_CURRENT_THREAD(void);
+#define    _PR_MD_CURRENT_THREAD _MD_CURRENT_THREAD
+
+NSPR_API(PRThread*) _PR_MD_GET_ATTACHED_THREAD(void);
+#define    _PR_MD_GET_ATTACHED_THREAD _MD_GET_ATTACHED_THREAD
+
+NSPR_API(PRThread*) _PR_MD_LAST_THREAD(void);
+#define    _PR_MD_LAST_THREAD _MD_LAST_THREAD
+
+NSPR_API(void) _PR_MD_SET_CURRENT_THREAD(PRThread *thread);
+#define    _PR_MD_SET_CURRENT_THREAD _MD_SET_CURRENT_THREAD
+
+NSPR_API(void) _PR_MD_SET_LAST_THREAD(PRThread *thread);
+#define    _PR_MD_SET_LAST_THREAD _MD_SET_LAST_THREAD
+
+extern PRStatus _PR_MD_INIT_THREAD(PRThread *thread);
+#define    _PR_MD_INIT_THREAD _MD_INIT_THREAD
+
+extern void _PR_MD_EXIT_THREAD(PRThread *thread);
+#define    _PR_MD_EXIT_THREAD _MD_EXIT_THREAD
+
+#ifndef _PR_LOCAL_THREADS_ONLY /* not if only local threads supported */
+
+NSPR_API(PRStatus) _PR_MD_INIT_ATTACHED_THREAD(PRThread *thread);
+#define    _PR_MD_INIT_ATTACHED_THREAD _MD_INIT_ATTACHED_THREAD
+
+extern void _PR_MD_SUSPEND_THREAD(PRThread *thread);
+#define    _PR_MD_SUSPEND_THREAD _MD_SUSPEND_THREAD
+
+extern void _PR_MD_RESUME_THREAD(PRThread *thread);
+#define    _PR_MD_RESUME_THREAD _MD_RESUME_THREAD
+
+extern void _PR_MD_SUSPEND_CPU(_PRCPU  *cpu);
+#define    _PR_MD_SUSPEND_CPU _MD_SUSPEND_CPU
+
+extern void _PR_MD_RESUME_CPU(_PRCPU  *cpu);
+#define    _PR_MD_RESUME_CPU _MD_RESUME_CPU
+
+extern void _PR_MD_BEGIN_SUSPEND_ALL(void);
+#define    _PR_MD_BEGIN_SUSPEND_ALL _MD_BEGIN_SUSPEND_ALL
+
+extern void _PR_MD_END_SUSPEND_ALL(void);
+#define    _PR_MD_END_SUSPEND_ALL _MD_END_SUSPEND_ALL
+
+extern void _PR_MD_BEGIN_RESUME_ALL(void);
+#define    _PR_MD_BEGIN_RESUME_ALL _MD_BEGIN_RESUME_ALL
+
+extern void _PR_MD_END_RESUME_ALL(void);
+#define    _PR_MD_END_RESUME_ALL _MD_END_RESUME_ALL
+
+#if defined(IRIX) 
+NSPR_API(void) _PR_IRIX_CHILD_PROCESS(void);
+#endif        /* IRIX */
+
+#endif        /* !_PR_LOCAL_THREADS_ONLY */
+
+extern void _PR_MD_CLEAN_THREAD(PRThread *thread);
+#define    _PR_MD_CLEAN_THREAD _MD_CLEAN_THREAD
+
+#ifdef HAVE_CUSTOM_USER_THREADS
+extern void _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *);
+#define    _PR_MD_CREATE_PRIMORDIAL_USER_THREAD _MD_CREATE_PRIMORDIAL_USER_THREAD
+
+extern PRThread* _PR_MD_CREATE_USER_THREAD(
+                        PRUint32 stacksize,
+                        void (*start)(void *),
+                        void *arg);
+#define    _PR_MD_CREATE_USER_THREAD _MD_CREATE_USER_THREAD
+#endif
+
+extern PRStatus _PR_MD_CREATE_THREAD(
+                        PRThread *thread, 
+                        void (*start) (void *), 
+                        PRThreadPriority priority,                      
+                        PRThreadScope scope,
+                        PRThreadState state,
+                        PRUint32 stackSize);
+#define    _PR_MD_CREATE_THREAD _MD_CREATE_THREAD
+
+extern void _PR_MD_JOIN_THREAD(_MDThread *md);
+#define    _PR_MD_JOIN_THREAD _MD_JOIN_THREAD
+
+extern void _PR_MD_END_THREAD(void);
+#define    _PR_MD_END_THREAD _MD_END_THREAD
+
+extern void _PR_MD_YIELD(void);
+#define    _PR_MD_YIELD _MD_YIELD
+
+extern void _PR_MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
+#define    _PR_MD_SET_PRIORITY _MD_SET_PRIORITY
+
+NSPR_API(void) _PR_MD_SUSPENDALL(void);
+#define    _PR_MD_SUSPENDALL _MD_SUSPENDALL
+
+NSPR_API(void) _PR_MD_RESUMEALL(void);
+#define    _PR_MD_RESUMEALL _MD_RESUMEALL
+
+extern void _PR_MD_INIT_CONTEXT(
+    PRThread *thread, char *top, void (*start) (void), PRBool *status);
+#define    _PR_MD_INIT_CONTEXT _MD_INIT_CONTEXT
+
+extern void _PR_MD_SWITCH_CONTEXT(PRThread *thread);
+#define    _PR_MD_SWITCH_CONTEXT _MD_SWITCH_CONTEXT
+
+extern void _PR_MD_RESTORE_CONTEXT(PRThread *thread);
+#define    _PR_MD_RESTORE_CONTEXT _MD_RESTORE_CONTEXT
+
+/* Segment related */
+extern void _PR_MD_INIT_SEGS(void);
+#define    _PR_MD_INIT_SEGS _MD_INIT_SEGS
+
+extern PRStatus _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr);
+#define    _PR_MD_ALLOC_SEGMENT _MD_ALLOC_SEGMENT
+
+extern void _PR_MD_FREE_SEGMENT(PRSegment *seg);
+#define    _PR_MD_FREE_SEGMENT _MD_FREE_SEGMENT
+
+/* Directory enumeration related */
+extern PRStatus _PR_MD_OPEN_DIR(_MDDir *md,const char *name);
+#define    _PR_MD_OPEN_DIR _MD_OPEN_DIR
+
+extern char * _PR_MD_READ_DIR(_MDDir *md, PRIntn flags);
+#define    _PR_MD_READ_DIR _MD_READ_DIR
+
+extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md);
+#define    _PR_MD_CLOSE_DIR _MD_CLOSE_DIR
+
+/* Named semaphores related */
+extern PRSem * _PR_MD_OPEN_SEMAPHORE(
+    const char *osname, PRIntn flags, PRIntn mode, PRUintn value);
+#define    _PR_MD_OPEN_SEMAPHORE _MD_OPEN_SEMAPHORE
+
+extern PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem);
+#define    _PR_MD_WAIT_SEMAPHORE _MD_WAIT_SEMAPHORE
+
+extern PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem);
+#define    _PR_MD_POST_SEMAPHORE _MD_POST_SEMAPHORE
+
+extern PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem);
+#define    _PR_MD_CLOSE_SEMAPHORE _MD_CLOSE_SEMAPHORE
+
+extern PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname);
+#define    _PR_MD_DELETE_SEMAPHORE _MD_DELETE_SEMAPHORE
+
+/* I/O related */
+extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd);
+#define    _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC
+
+#ifdef XP_MAC
+extern void _PR_MD_FREE_FILEDESC(PRFileDesc *fd);
+#define    _PR_MD_FREE_FILEDESC _MD_FREE_FILEDESC
+#endif
+
+extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd);
+#define    _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK
+
+/* File I/O related */
+extern PROsfd _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode);
+#define    _PR_MD_OPEN _MD_OPEN
+
+extern PROsfd _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode);
+#define    _PR_MD_OPEN_FILE _MD_OPEN_FILE
+
+extern PRInt32 _PR_MD_CLOSE_FILE(PROsfd osfd);
+#define    _PR_MD_CLOSE_FILE _MD_CLOSE_FILE
+
+extern PRInt32 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 amount);
+#define    _PR_MD_READ _MD_READ
+
+extern PRInt32 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 amount);
+#define    _PR_MD_WRITE _MD_WRITE
+
+extern PRInt32 _PR_MD_WRITEV(
+    PRFileDesc *fd, const struct PRIOVec *iov,
+    PRInt32 iov_size, PRIntervalTime timeout);
+#define    _PR_MD_WRITEV _MD_WRITEV
+
+extern PRInt32 _PR_MD_FSYNC(PRFileDesc *fd);
+#define    _PR_MD_FSYNC _MD_FSYNC
+
+extern PRInt32 _PR_MD_DELETE(const char *name);
+#define        _PR_MD_DELETE _MD_DELETE
+
+extern PRInt32 _PR_MD_RENAME(const char *from, const char *to);
+#define _PR_MD_RENAME _MD_RENAME
+
+extern PRInt32 _PR_MD_ACCESS(const char *name, PRAccessHow how);
+#define _PR_MD_ACCESS _MD_ACCESS
+
+extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf);
+#define _PR_MD_STAT _MD_STAT
+
+extern PRInt32 _PR_MD_MKDIR(const char *name, PRIntn mode);
+#define _PR_MD_MKDIR _MD_MKDIR
+
+extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode);
+#define _PR_MD_MAKE_DIR _MD_MAKE_DIR
+
+extern PRInt32 _PR_MD_RMDIR(const char *name);
+#define _PR_MD_RMDIR _MD_RMDIR
+
+#ifdef MOZ_UNICODE
+/* UTF16 File I/O related */
+extern PRStatus _PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *md, const PRUnichar *name);
+#define    _PR_MD_OPEN_DIR_UTF16 _MD_OPEN_DIR_UTF16
+
+extern PROsfd _PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, PRIntn mode);
+#define    _PR_MD_OPEN_FILE_UTF16 _MD_OPEN_FILE_UTF16
+
+extern PRUnichar * _PR_MD_READ_DIR_UTF16(_MDDirUTF16 *md, PRIntn flags);
+#define    _PR_MD_READ_DIR_UTF16 _MD_READ_DIR_UTF16
+
+extern PRInt32 _PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *md);
+#define    _PR_MD_CLOSE_DIR_UTF16 _MD_CLOSE_DIR_UTF16
+
+extern PRInt32 _PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info);
+#define _PR_MD_GETFILEINFO64_UTF16 _MD_GETFILEINFO64_UTF16
+#endif /* MOZ_UNICODE */
+
+/* Socket I/O related */
+extern void _PR_MD_INIT_IO(void);
+#define    _PR_MD_INIT_IO _MD_INIT_IO
+
+extern PRInt32 _PR_MD_CLOSE_SOCKET(PROsfd osfd);
+#define    _PR_MD_CLOSE_SOCKET _MD_CLOSE_SOCKET
+
+extern PRInt32 _PR_MD_CONNECT(
+    PRFileDesc *fd, const PRNetAddr *addr,
+    PRUint32 addrlen, PRIntervalTime timeout);
+#define    _PR_MD_CONNECT _MD_CONNECT
+
+extern PROsfd _PR_MD_ACCEPT(
+    PRFileDesc *fd, PRNetAddr *addr,
+    PRUint32 *addrlen, PRIntervalTime timeout);
+#define    _PR_MD_ACCEPT _MD_ACCEPT
+
+extern PRInt32 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen);
+#define    _PR_MD_BIND _MD_BIND
+
+extern PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog);
+#define    _PR_MD_LISTEN _MD_LISTEN
+
+extern PRInt32 _PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how);
+#define    _PR_MD_SHUTDOWN _MD_SHUTDOWN
+
+extern PRInt32 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, 
+                               PRIntn flags, PRIntervalTime timeout);
+#define    _PR_MD_RECV _MD_RECV
+
+extern PRInt32 _PR_MD_SEND(
+    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, 
+    PRIntervalTime timeout);
+#define    _PR_MD_SEND _MD_SEND
+
+extern PRInt32 _PR_MD_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, 
+                                PRNetAddr **raddr, void *buf, PRInt32 amount,
+                                PRIntervalTime timeout);
+#define _PR_MD_ACCEPT_READ _MD_ACCEPT_READ
+
+#ifdef WIN32
+extern PROsfd _PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *addr, 
+                                PRUint32 *addrlen, PRIntervalTime timeout,
+                                PRBool fast,
+                                _PR_AcceptTimeoutCallback callback,
+                                void *callbackArg);
+
+extern PRInt32 _PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, 
+                                PRNetAddr **raddr, void *buf, PRInt32 amount,
+                                PRIntervalTime timeout, PRBool fast,
+                                _PR_AcceptTimeoutCallback callback,
+                                void *callbackArg);
+
+extern void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd s, PROsfd ls);
+#define _PR_MD_UPDATE_ACCEPT_CONTEXT _MD_UPDATE_ACCEPT_CONTEXT
+#endif /* WIN32 */
+
+extern PRInt32 _PR_MD_SENDFILE(
+    PRFileDesc *sock, PRSendFileData *sfd, 
+	PRInt32 flags, PRIntervalTime timeout);
+#define _PR_MD_SENDFILE _MD_SENDFILE
+
+extern PRStatus _PR_MD_GETSOCKNAME(
+    PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
+#define    _PR_MD_GETSOCKNAME _MD_GETSOCKNAME
+
+extern PRStatus _PR_MD_GETPEERNAME(
+    PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen);
+#define    _PR_MD_GETPEERNAME _MD_GETPEERNAME
+
+extern PRStatus _PR_MD_GETSOCKOPT(
+    PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen);
+#define    _PR_MD_GETSOCKOPT _MD_GETSOCKOPT
+
+extern PRStatus _PR_MD_SETSOCKOPT(
+    PRFileDesc *fd, PRInt32 level, PRInt32 optname,
+    const char* optval, PRInt32 optlen);
+#define    _PR_MD_SETSOCKOPT _MD_SETSOCKOPT
+
+extern PRStatus PR_CALLBACK _PR_SocketGetSocketOption(
+    PRFileDesc *fd, PRSocketOptionData *data);
+
+extern PRStatus PR_CALLBACK _PR_SocketSetSocketOption(
+    PRFileDesc *fd, const PRSocketOptionData *data);
+
+extern PRInt32 _PR_MD_RECVFROM(
+    PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+    PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout);
+#define    _PR_MD_RECVFROM _MD_RECVFROM
+
+extern PRInt32 _PR_MD_SENDTO(
+    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+    const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout);
+#define    _PR_MD_SENDTO _MD_SENDTO
+
+extern PRInt32 _PR_MD_SOCKETPAIR(int af, int type, int flags, PROsfd *osfd);
+#define    _PR_MD_SOCKETPAIR _MD_SOCKETPAIR
+
+extern PROsfd _PR_MD_SOCKET(int af, int type, int flags);
+#define    _PR_MD_SOCKET _MD_SOCKET
+
+extern PRInt32 _PR_MD_SOCKETAVAILABLE(PRFileDesc *fd);
+#define    _PR_MD_SOCKETAVAILABLE _MD_SOCKETAVAILABLE
+
+extern PRInt32 _PR_MD_PIPEAVAILABLE(PRFileDesc *fd);
+#define    _PR_MD_PIPEAVAILABLE _MD_PIPEAVAILABLE
+
+extern PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds,
+                                                                                        PRIntervalTime timeout);
+#define    _PR_MD_PR_POLL _MD_PR_POLL
+
+/*
+ * Initialize fd->secret->inheritable for a newly created fd.
+ * If 'imported' is false, the osfd (i.e., fd->secret->md.osfd)
+ * was created by NSPR and hence has the OS-dependent default
+ * inheritable attribute.  If 'imported' is true, the osfd was
+ * not created by NSPR and hence a system call is required to
+ * query its inheritable attribute.  Since we may never need to
+ * know the inheritable attribute of a fd, a platform may choose
+ * to initialize fd->secret->inheritable of an imported fd to
+ * _PR_TRI_UNKNOWN and only pay the cost of the system call
+ * (in _PR_MD_QUERY_FD_INHERITABLE) when necessary.
+ */
+extern void _PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported);
+#define    _PR_MD_INIT_FD_INHERITABLE _MD_INIT_FD_INHERITABLE
+
+extern PRStatus _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable);
+#define    _PR_MD_SET_FD_INHERITABLE _MD_SET_FD_INHERITABLE
+
+
+#define _PR_PROCESS_TIMEOUT_INTERRUPT_ERRORS(me) \
+        if (_PR_PENDING_INTERRUPT(me)) { \
+                me->flags &= ~_PR_INTERRUPT; \
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0); \
+        } else { \
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0); \
+        }                                                        
+                
+extern void *_PR_MD_GET_SP(PRThread *thread);
+#define    _PR_MD_GET_SP _MD_GET_SP
+
+#endif /* defined(_PR_PTHREADS) */
+
+/************************************************************************/
+/*************************************************************************
+** The remainder of the definitions are shared by pthreads and the classic
+** NSPR code. These too may be conditionalized.
+*************************************************************************/
+/************************************************************************/
+
+extern PROffset32 _PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence);
+#define    _PR_MD_LSEEK _MD_LSEEK
+
+extern PROffset64 _PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence);
+#define    _PR_MD_LSEEK64 _MD_LSEEK64
+
+extern PRInt32 _PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info);
+#define _PR_MD_GETFILEINFO _MD_GETFILEINFO
+
+extern PRInt32 _PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info);
+#define _PR_MD_GETFILEINFO64 _MD_GETFILEINFO64
+
+extern PRInt32 _PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info);
+#define _PR_MD_GETOPENFILEINFO _MD_GETOPENFILEINFO
+
+extern PRInt32 _PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info);
+#define _PR_MD_GETOPENFILEINFO64 _MD_GETOPENFILEINFO64
+
+
+/*****************************************************************************/
+/************************** File descriptor caching **************************/
+/*****************************************************************************/
+extern void _PR_InitFdCache(void);
+extern void _PR_CleanupFdCache(void);
+extern PRFileDesc *_PR_Getfd(void);
+extern void _PR_Putfd(PRFileDesc *fd);
+
+/*
+ * These flags are used by NSPR temporarily in the poll
+ * descriptor's out_flags field to record the mapping of
+ * NSPR's poll flags to the system poll flags.
+ *
+ * If _PR_POLL_READ_SYS_WRITE bit is set, it means the
+ * PR_POLL_READ flag specified by the topmost layer is
+ * mapped to the WRITE flag at the system layer.  Similarly
+ * for the other three _PR_POLL_XXX_SYS_YYY flags.  It is
+ * assumed that the PR_POLL_EXCEPT flag doesn't get mapped
+ * to other flags.
+ */
+#define _PR_POLL_READ_SYS_READ     0x1
+#define _PR_POLL_READ_SYS_WRITE    0x2
+#define _PR_POLL_WRITE_SYS_READ    0x4
+#define _PR_POLL_WRITE_SYS_WRITE   0x8
+
+/*
+** These methods are coerced into file descriptor methods table
+** when the intended service is inappropriate for the particular
+** type of file descriptor.
+*/
+extern PRIntn _PR_InvalidInt(void);
+extern PRInt16 _PR_InvalidInt16(void);
+extern PRInt64 _PR_InvalidInt64(void);
+extern PRStatus _PR_InvalidStatus(void);
+extern PRFileDesc *_PR_InvalidDesc(void);
+
+extern PRIOMethods _pr_faulty_methods;
+
+/*
+** The PR_NETADDR_SIZE macro can only be called on a PRNetAddr union
+** whose 'family' field is set.  It returns the size of the union
+** member corresponding to the specified address family.
+*/
+
+extern PRUintn _PR_NetAddrSize(const PRNetAddr* addr);
+
+#if defined(_PR_INET6)
+
+#define PR_NETADDR_SIZE(_addr) _PR_NetAddrSize(_addr)
+
+#elif defined(_PR_HAVE_MD_SOCKADDR_IN6)
+
+/*
+** Under the following conditions:
+** 1. _PR_INET6 is not defined;
+** 2. _PR_INET6_PROBE is defined;
+** 3. struct sockaddr_in6 has nonstandard fields at the end
+**    (e.g., on Solaris 8),
+** (_addr)->ipv6 is smaller than struct sockaddr_in6, and
+** hence we can't pass sizeof((_addr)->ipv6) to socket
+** functions such as connect because they would fail with
+** EINVAL.
+**
+** To pass the correct socket address length to socket
+** functions, define the macro _PR_HAVE_MD_SOCKADDR_IN6 and
+** define struct _md_sockaddr_in6 to be isomorphic to
+** struct sockaddr_in6.
+*/
+
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : ((_addr)->raw.family == PR_AF_INET6	\
+        ? sizeof(struct _md_sockaddr_in6)		\
+        : sizeof((_addr)->local)))
+#else
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : sizeof(struct _md_sockaddr_in6))
+#endif /* defined(XP_UNIX) */
+
+#else
+
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : ((_addr)->raw.family == PR_AF_INET6	\
+        ? sizeof((_addr)->ipv6)					\
+        : sizeof((_addr)->local)))
+#else
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : sizeof((_addr)->ipv6))
+#endif /* defined(XP_UNIX) */
+
+#endif /* defined(_PR_INET6) */
+
+extern PRStatus _PR_MapOptionName(
+    PRSockOption optname, PRInt32 *level, PRInt32 *name);
+extern void _PR_InitThreads(
+    PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs);
+
+struct PRLock {
+#if defined(_PR_PTHREADS)
+    pthread_mutex_t mutex;          /* the underlying lock */
+    _PT_Notified notified;          /* array of conditions notified */
+    PRBool locked;                  /* whether the mutex is locked */
+    pthread_t owner;                /* if locked, current lock owner */
+#elif defined(_PR_BTHREADS)
+    sem_id	semaphoreID;	    /* the underlying lock */
+    int32	benaphoreCount;	    /* number of people in lock */
+    thread_id	owner;		    /* current lock owner */
+#else /* not pthreads or Be threads */
+    PRCList links;                  /* linkage for PRThread.lockList */
+    struct PRThread *owner;         /* current lock owner */
+    PRCList waitQ;                  /* list of threads waiting for lock */
+    PRThreadPriority priority;      /* priority of lock */ 
+    PRThreadPriority boostPriority; /* boosted priority of lock owner */
+    _MDLock ilock;                  /* Internal Lock to protect user-level fields */
+#endif
+};
+
+extern void _PR_InitLocks(void);
+
+struct PRCondVar {
+    PRLock *lock;               /* associated lock that protects the condition */
+#if defined(_PR_PTHREADS)
+    pthread_cond_t cv;          /* underlying pthreads condition */
+    PRInt32 notify_pending;     /* CV has destroy pending notification */
+#elif defined(_PR_BTHREADS)
+    sem_id    sem;              /* the underlying lock */
+    sem_id    handshakeSem;     /* the lock for 'notify'-threads waiting for confirmation */
+    sem_id    signalSem;        /* the lock for threads waiting for someone to notify */
+    volatile int32    nw;       /* the number waiting */
+    volatile int32    ns;       /* the number signalling */
+    long signalBenCount;        /* the number waiting on the underlying sem */
+#else /* not pthreads or Be threads */
+    PRCList condQ;              /* Condition variable wait Q */
+    _MDLock ilock;              /* Internal Lock to protect condQ */
+    _MDCVar md;
+#endif
+};
+
+/************************************************************************/
+
+struct PRMonitor {
+    const char* name;           /* monitor name for debugging */
+#if defined(_PR_PTHREADS)
+    PRLock lock;                /* the lock structure */
+    pthread_t owner;            /* the owner of the lock or invalid */
+    PRCondVar *cvar;            /* condition variable queue */
+#else  /* defined(_PR_PTHREADS) */
+    PRCondVar *cvar;            /* associated lock and condition variable queue */
+#endif /* defined(_PR_PTHREADS) */
+    PRUint32 entryCount;        /* # of times re-entered */
+};
+
+/************************************************************************/
+
+struct PRSemaphore {
+#if defined(_PR_BTHREADS)
+    sem_id  sem;
+    int32   benaphoreCount;
+#else
+    PRCondVar *cvar;        /* associated lock and condition variable queue */
+    PRUintn count;            /* the value of the counting semaphore */
+    PRUint32 waiters;            /* threads waiting on the semaphore */
+#if defined(_PR_PTHREADS)
+#else  /* defined(_PR_PTHREADS) */
+    _MDSemaphore md;
+#endif /* defined(_PR_PTHREADS) */
+#endif /* defined(_PR_BTHREADS) */
+};
+
+NSPR_API(void) _PR_InitSem(void);
+
+/*************************************************************************/
+
+struct PRSem {
+#ifdef _PR_HAVE_POSIX_SEMAPHORES
+    sem_t *sem;
+#elif defined(_PR_HAVE_SYSV_SEMAPHORES)
+    int semid;
+#elif defined(WIN32)
+    HANDLE sem;
+#else
+    PRInt8 notused;
+#endif
+};
+
+/*************************************************************************/
+
+struct PRStackStr {
+    /* head MUST be at offset 0; assembly language code relies on this */
+#if defined(AIX)
+    volatile PRStackElem prstk_head;
+#else
+    PRStackElem prstk_head;
+#endif
+
+    PRLock *prstk_lock;
+    char *prstk_name;
+};
+
+/************************************************************************/
+
+/* XXX this needs to be exported (sigh) */
+struct PRThreadStack {
+    PRCList links;
+    PRUintn flags;
+
+    char *allocBase;            /* base of stack's allocated memory */
+    PRUint32 allocSize;         /* size of stack's allocated memory */
+    char *stackBottom;          /* bottom of stack from C's point of view */
+    char *stackTop;             /* top of stack from C's point of view */
+    PRUint32 stackSize;         /* size of usable portion of the stack */
+
+    PRSegment *seg;
+        PRThread* thr;          /* back pointer to thread owning this stack */
+
+#if defined(_PR_PTHREADS)
+#else /* defined(_PR_PTHREADS) */
+    _MDThreadStack md;
+#endif /* defined(_PR_PTHREADS) */
+};
+
+extern void _PR_DestroyThreadPrivate(PRThread*);
+
+typedef void (PR_CALLBACK *_PRStartFn)(void *);
+
+struct PRThread {
+    PRUint32 state;                 /* thread's creation state */
+    PRThreadPriority priority;      /* apparent priority, loosly defined */
+
+    void *arg;                      /* argument to the client's entry point */
+    _PRStartFn startFunc;           /* the root of the client's thread */
+
+    PRThreadStack *stack;           /* info about thread's stack (for GC) */
+    void *environment;              /* pointer to execution environment */
+
+    PRThreadDumpProc dump;          /* dump thread info out */
+    void *dumpArg;                  /* argument for the dump function */
+
+    /*
+    ** Per thread private data
+    */
+    PRUint32 tpdLength;             /* thread's current vector length */
+    void **privateData;             /* private data vector or NULL */
+    PRErrorCode errorCode;          /* current NSPR error code | zero */
+    PRInt32 osErrorCode;            /* mapping of errorCode | zero */
+    PRIntn  errorStringLength;      /* textLength from last call to PR_SetErrorText() */
+    PRInt32 errorStringSize;        /* malloc()'d size of buffer | zero */
+    char *errorString;              /* current error string | NULL */
+
+#if defined(_PR_PTHREADS)
+    pthread_t id;                   /* pthread identifier for the thread */
+    PRBool okToDelete;              /* ok to delete the PRThread struct? */
+    PRCondVar *waiting;             /* where the thread is waiting | NULL */
+    void *sp;                       /* recorded sp for garbage collection */
+    PRThread *next, *prev;          /* simple linked list of all threads */
+    PRUint32 suspend;               /* used to store suspend and resume flags */
+#ifdef PT_NO_SIGTIMEDWAIT
+    pthread_mutex_t suspendResumeMutex;
+    pthread_cond_t suspendResumeCV;
+#endif
+    PRUint32 interrupt_blocked;     /* interrupt blocked */
+    struct pollfd *syspoll_list;    /* Unix polling list used by PR_Poll */
+    PRUint32 syspoll_count;         /* number of elements in syspoll_list */
+#if defined(_PR_POLL_WITH_SELECT)
+    int *selectfd_list;             /* Unix fd's that PR_Poll selects on */
+    PRUint32 selectfd_count;        /* number of elements in selectfd_list */
+#endif
+#elif defined(_PR_BTHREADS)
+    PRUint32 flags;
+    _MDThread md;
+    PRBool io_pending;
+    PRInt32 io_fd;
+    PRBool io_suspended;
+#else /* not pthreads or Be threads */
+    _MDLock threadLock;             /* Lock to protect thread state variables.
+                                     * Protects the following fields:
+                                     *     state
+                                     *     priority
+                                     *     links
+                                     *     wait
+                                     *     cpu
+                                     */
+    PRUint32 queueCount;
+    PRUint32 waitCount;
+
+    PRCList active;                 /* on list of all active threads        */
+    PRCList links;
+    PRCList waitQLinks;             /* when thread is PR_Wait'ing */
+    PRCList lockList;               /* list of locks currently holding */
+    PRIntervalTime sleep;           /* sleep time when thread is sleeping */
+    struct _wait {
+        struct PRLock *lock;
+        struct PRCondVar *cvar;
+    } wait;
+
+    PRUint32 id;
+    PRUint32 flags;
+    PRUint32 no_sched;              /* Don't schedule the thread to run.
+                                     * This flag has relevance only when
+                                     * multiple NSPR CPUs are created.
+                                     * When a thread is de-scheduled, there
+                                     * is a narrow window of time in which
+                                     * the thread is put on the run queue
+                                     * but the scheduler is actually using
+                                     * the stack of this thread.  It is safe
+                                     * to run this thread on a different CPU
+                                     * only when its stack is not in use on
+                                     * any other CPU.  The no_sched flag is
+                                     * set during this interval to prevent
+                                     * the thread from being scheduled on a
+                                     * different CPU.
+                                     */
+
+    /* thread termination condition variable for join */
+    PRCondVar *term;
+
+    _PRCPU *cpu;                    /* cpu to which this thread is bound    */
+    PRUint32 threadAllocatedOnStack;/* boolean */
+
+    /* When an async IO is in progress and a second async IO cannot be 
+     * initiated, the io_pending flag is set to true.  Some platforms will
+     * not use the io_pending flag.  If the io_pending flag is true, then
+     * io_fd is the OS-file descriptor on which IO is pending.
+     */
+    PRBool io_pending;
+    PRInt32 io_fd;
+ 
+    /* If a timeout occurs or if an outstanding IO is interrupted and the
+     * OS doesn't support a real cancellation (NT or MAC), then the 
+     * io_suspended flag will be set to true.  The thread will be resumed
+     * but may run into trouble issuing additional IOs until the io_pending
+     * flag can be cleared 
+     */
+    PRBool io_suspended;
+
+    _MDThread md;
+#endif
+};
+
+struct PRProcessAttr {
+    PRFileDesc *stdinFd;
+    PRFileDesc *stdoutFd;
+    PRFileDesc *stderrFd;
+    char *currentDirectory;
+    char *fdInheritBuffer;
+    PRSize fdInheritBufferSize;
+    PRSize fdInheritBufferUsed;
+};
+
+struct PRProcess {
+    _MDProcess md;
+};
+
+struct PRFileMap {
+    PRFileDesc *fd;
+    PRFileMapProtect prot;
+    _MDFileMap md;
+};
+
+/************************************************************************/
+
+/*
+** File descriptors of the NSPR layer can be in one of the
+** following states (stored in the 'state' field of struct
+** PRFilePrivate):
+** - _PR_FILEDESC_OPEN: The OS fd is open.
+** - _PR_FILEDESC_CLOSED: The OS fd is closed.  The PRFileDesc
+**   is still open but is unusable.  The only operation allowed
+**   on the PRFileDesc is PR_Close().
+** - _PR_FILEDESC_FREED: The OS fd is closed and the PRFileDesc
+**   structure is freed.
+*/
+
+#define _PR_FILEDESC_OPEN       0xaaaaaaaa    /* 1010101... */
+#define _PR_FILEDESC_CLOSED     0x55555555    /* 0101010... */
+#define _PR_FILEDESC_FREED      0x11111111
+
+/*
+** A boolean type with an additional "unknown" state
+*/
+
+typedef enum {
+    _PR_TRI_TRUE = 1,
+    _PR_TRI_FALSE = 0,
+    _PR_TRI_UNKNOWN = -1
+} _PRTriStateBool;
+
+struct PRFilePrivate {
+    PRInt32 state;
+    PRBool nonblocking;
+    _PRTriStateBool inheritable;
+    PRFileDesc *next;
+    PRIntn lockCount;   /*   0: not locked
+                         *  -1: a native lockfile call is in progress
+                         * > 0: # times the file is locked */
+#ifdef _PR_HAVE_PEEK_BUFFER
+    char *peekBuffer;
+    PRInt32 peekBufSize;
+    PRInt32 peekBytes;
+#endif
+#if !defined(_PR_HAVE_O_APPEND)
+    PRBool  appendMode; /* Some platforms don't have O_APPEND or its
+                         * equivalent, so they have to seek to end of
+                         * file on write if the file was opened in
+                         * append mode.  See Bugzilla 4090, 276330. */
+#endif
+    _MDFileDesc md;
+#ifdef _PR_STRICT_ADDR_LEN
+    PRUint16 af;        /* If the platform requires passing the exact
+                         * length of the sockaddr structure for the
+                         * address family of the socket to socket
+                         * functions like accept(), we need to save
+                         * the address family of the socket. */
+#endif
+};
+
+#ifdef _WIN64
+#define PR_PRIdOSFD "lld"       /* for printing PROsfd */
+#define PR_PRIxOSFD "llx"
+#define PR_SCNdOSFD "lld"       /* for scanning PROsfd */
+#define PR_SCNxOSFD "llx"
+#else
+#define PR_PRIdOSFD "ld"        /* for printing PROsfd */
+#define PR_PRIxOSFD "lx"
+#define PR_SCNdOSFD "ld"        /* for scanning PROsfd */
+#define PR_SCNxOSFD "lx"
+#endif
+
+struct PRDir {
+    PRDirEntry d;
+    _MDDir md;
+};
+
+#ifdef MOZ_UNICODE
+struct PRDirUTF16 { 
+    PRDirEntry d; 
+    _MDDirUTF16 md; 
+}; 
+#endif /* MOZ_UNICODE */
+
+extern void _PR_InitSegs(void);
+extern void _PR_InitStacks(void);
+extern void _PR_InitTPD(void);
+extern void _PR_InitMem(void);
+extern void _PR_InitEnv(void);
+extern void _PR_InitCMon(void);
+extern void _PR_InitIO(void);
+extern void _PR_InitLog(void);
+extern void _PR_InitNet(void);
+extern void _PR_InitClock(void);
+extern void _PR_InitLinker(void);
+extern void _PR_InitAtomic(void);
+extern void _PR_InitCPUs(void);
+extern void _PR_InitDtoa(void);
+extern void _PR_InitMW(void);
+extern void _PR_InitRWLocks(void);
+extern void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me);
+extern void _PR_CleanupThread(PRThread *thread);
+extern void _PR_CleanupCallOnce(void);
+extern void _PR_CleanupMW(void);
+extern void _PR_CleanupDtoa(void);
+extern void _PR_ShutdownLinker(void);
+extern void _PR_CleanupEnv(void);
+extern void _PR_CleanupIO(void);
+extern void _PR_CleanupNet(void);
+extern void _PR_CleanupLayerCache(void);
+extern void _PR_CleanupStacks(void);
+#ifdef WINNT
+extern void _PR_CleanupCPUs(void);
+#endif
+extern void _PR_CleanupThreads(void);
+extern void _PR_CleanupTPD(void);
+extern void _PR_Cleanup(void);
+extern void _PR_LogCleanup(void);
+extern void _PR_InitLayerCache(void);
+#ifdef GC_LEAK_DETECTOR
+extern void _PR_InitGarbageCollector(void);
+#endif
+
+extern PRBool _pr_initialized;
+extern void _PR_ImplicitInitialization(void);
+extern PRBool _PR_Obsolete(const char *obsolete, const char *preferred);
+
+/************************************************************************/
+
+struct PRSegment {
+    void *vaddr;
+    PRUint32 size;
+    PRUintn flags;
+#if defined(_PR_PTHREADS)
+#else  /* defined(_PR_PTHREADS) */
+    _MDSegment md;
+#endif /* defined(_PR_PTHREADS) */
+};
+
+/* PRSegment.flags */
+#define _PR_SEG_VM    0x1
+
+/************************************************************************/
+
+extern PRInt32 _pr_pageSize;
+extern PRInt32 _pr_pageShift;
+
+extern PRLogModuleInfo *_pr_clock_lm;
+extern PRLogModuleInfo *_pr_cmon_lm;
+extern PRLogModuleInfo *_pr_io_lm;
+extern PRLogModuleInfo *_pr_cvar_lm;
+extern PRLogModuleInfo *_pr_mon_lm;
+extern PRLogModuleInfo *_pr_linker_lm;
+extern PRLogModuleInfo *_pr_sched_lm;
+extern PRLogModuleInfo *_pr_thread_lm;
+extern PRLogModuleInfo *_pr_gc_lm;
+
+extern PRFileDesc *_pr_stdin;
+extern PRFileDesc *_pr_stdout;
+extern PRFileDesc *_pr_stderr;
+
+/* Zone allocator */
+/*
+** The zone allocator code has hardcoded pthread types and
+** functions, so it can only be used in the pthreads version.
+** This can be fixed by replacing the hardcoded pthread types
+** and functions with macros that expand to the native thread
+** types and functions on each platform.
+*/
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#define _PR_ZONE_ALLOCATOR
+#endif
+
+#ifdef _PR_ZONE_ALLOCATOR
+extern void _PR_InitZones(void);
+extern void _PR_DestroyZones(void);
+#endif
+
+/* Overriding malloc, free, etc. */
+#if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \
+        && !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \
+        && !defined(PURIFY) \
+        && !defined(DARWIN) \
+        && !defined(NEXTSTEP) \
+        && !defined(QNX) \
+        && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS))
+#define _PR_OVERRIDE_MALLOC
+#endif
+
+/*************************************************************************
+* External machine-dependent code provided by each OS.                     *                                                                     *
+*************************************************************************/
+
+/* Initialization related */
+extern void _PR_MD_EARLY_INIT(void);
+#define    _PR_MD_EARLY_INIT _MD_EARLY_INIT
+
+extern void _PR_MD_INTERVAL_INIT(void);
+#define    _PR_MD_INTERVAL_INIT _MD_INTERVAL_INIT
+
+NSPR_API(void) _PR_MD_FINAL_INIT(void);
+#define    _PR_MD_FINAL_INIT _MD_FINAL_INIT
+
+/* Process control */
+
+extern PRProcess * _PR_MD_CREATE_PROCESS(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr);
+#define    _PR_MD_CREATE_PROCESS _MD_CREATE_PROCESS
+
+extern PRStatus _PR_MD_DETACH_PROCESS(PRProcess *process);
+#define    _PR_MD_DETACH_PROCESS _MD_DETACH_PROCESS
+
+extern PRStatus _PR_MD_WAIT_PROCESS(PRProcess *process, PRInt32 *exitCode);
+#define    _PR_MD_WAIT_PROCESS _MD_WAIT_PROCESS
+
+extern PRStatus _PR_MD_KILL_PROCESS(PRProcess *process);
+#define    _PR_MD_KILL_PROCESS _MD_KILL_PROCESS        
+
+/* Current Time */
+NSPR_API(PRTime) _PR_MD_NOW(void);
+#define    _PR_MD_NOW _MD_NOW
+
+/* Environment related */
+extern char* _PR_MD_GET_ENV(const char *name);
+#define    _PR_MD_GET_ENV _MD_GET_ENV
+
+extern PRIntn _PR_MD_PUT_ENV(const char *name);
+#define    _PR_MD_PUT_ENV _MD_PUT_ENV
+
+/* Atomic operations */
+
+extern void _PR_MD_INIT_ATOMIC(void);
+#define    _PR_MD_INIT_ATOMIC _MD_INIT_ATOMIC
+
+extern PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *);
+#define    _PR_MD_ATOMIC_INCREMENT _MD_ATOMIC_INCREMENT
+
+extern PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *, PRInt32);
+#define    _PR_MD_ATOMIC_ADD _MD_ATOMIC_ADD
+
+extern PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *);
+#define    _PR_MD_ATOMIC_DECREMENT _MD_ATOMIC_DECREMENT
+
+extern PRInt32 _PR_MD_ATOMIC_SET(PRInt32 *, PRInt32);
+#define    _PR_MD_ATOMIC_SET _MD_ATOMIC_SET
+
+/* Garbage collection */
+
+/*
+** Save the registers that the GC would find interesting into the thread
+** "t". isCurrent will be non-zero if the thread state that is being
+** saved is the currently executing thread. Return the address of the
+** first register to be scanned as well as the number of registers to
+** scan in "np".
+**
+** If "isCurrent" is non-zero then it is allowed for the thread context
+** area to be used as scratch storage to hold just the registers
+** necessary for scanning.
+*/
+extern PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np);
+
+/* Time intervals */
+
+extern PRIntervalTime _PR_MD_GET_INTERVAL(void);
+#define _PR_MD_GET_INTERVAL _MD_GET_INTERVAL
+
+extern PRIntervalTime _PR_MD_INTERVAL_PER_SEC(void);
+#define _PR_MD_INTERVAL_PER_SEC _MD_INTERVAL_PER_SEC
+
+/* Affinity masks */
+
+extern PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask );
+#define _PR_MD_SETTHREADAFFINITYMASK _MD_SETTHREADAFFINITYMASK
+
+extern PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask);
+#define _PR_MD_GETTHREADAFFINITYMASK _MD_GETTHREADAFFINITYMASK
+
+/* File locking */
+
+extern PRStatus _PR_MD_LOCKFILE(PROsfd osfd);
+#define    _PR_MD_LOCKFILE _MD_LOCKFILE
+
+extern PRStatus _PR_MD_TLOCKFILE(PROsfd osfd);
+#define    _PR_MD_TLOCKFILE _MD_TLOCKFILE
+
+extern PRStatus _PR_MD_UNLOCKFILE(PROsfd osfd);
+#define    _PR_MD_UNLOCKFILE _MD_UNLOCKFILE
+
+/* Memory-mapped files */
+
+extern PRStatus _PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size);
+#define _PR_MD_CREATE_FILE_MAP _MD_CREATE_FILE_MAP
+
+extern PRInt32 _PR_MD_GET_MEM_MAP_ALIGNMENT(void);
+#define _PR_MD_GET_MEM_MAP_ALIGNMENT _MD_GET_MEM_MAP_ALIGNMENT
+
+extern void * _PR_MD_MEM_MAP(
+    PRFileMap *fmap,
+    PROffset64 offset,
+    PRUint32 len);
+#define _PR_MD_MEM_MAP _MD_MEM_MAP
+
+extern PRStatus _PR_MD_MEM_UNMAP(void *addr, PRUint32 size);
+#define _PR_MD_MEM_UNMAP _MD_MEM_UNMAP
+
+extern PRStatus _PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap);
+#define _PR_MD_CLOSE_FILE_MAP _MD_CLOSE_FILE_MAP
+
+/* Named Shared Memory */
+
+/*
+** Declare PRSharedMemory.
+*/
+struct PRSharedMemory 
+{
+    char        *ipcname; /* after conversion to native */
+    PRSize      size;  /* from open */
+    PRIntn      mode;  /* from open */
+    PRIntn      flags; /* from open */
+#if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY)
+    int         id;
+#elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY)
+    int         id;
+#elif defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY)
+    HANDLE      handle;
+#else
+    PRUint32    nothing; /* placeholder, nothing behind here */
+#endif
+    PRUint32    ident; /* guard word at end of struct */
+#define _PR_SHM_IDENT 0xdeadbad
+};
+                                                      
+extern PRSharedMemory * _MD_OpenSharedMemory( 
+    const char *name,
+    PRSize      size,
+    PRIntn      flags,
+    PRIntn      mode
+);
+#define _PR_MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
+
+extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags );
+#define _PR_MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
+
+extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr );
+#define _PR_MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
+
+extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm );
+#define _PR_MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
+
+extern PRStatus _MD_DeleteSharedMemory( const char *name );
+#define _PR_MD_DELETE_SHARED_MEMORY  _MD_DeleteSharedMemory
+
+extern PRFileMap* _md_OpenAnonFileMap( 
+    const char *dirName,
+    PRSize      size,
+    PRFileMapProtect prot
+);
+#define _PR_MD_OPEN_ANON_FILE_MAP _md_OpenAnonFileMap
+
+extern PRStatus _md_ExportFileMapAsString(
+    PRFileMap *fm,
+    PRSize    bufSize,
+    char      *buf
+);
+#define _PR_MD_EXPORT_FILE_MAP_AS_STRING _md_ExportFileMapAsString
+
+extern PRFileMap * _md_ImportFileMapFromString(
+    const char *fmstring
+);
+#define _PR_MD_IMPORT_FILE_MAP_FROM_STRING _md_ImportFileMapFromString
+
+
+
+/* Interprocess communications (IPC) */
+
+/*
+ * The maximum length of an NSPR IPC name, including the
+ * terminating null byte.
+ */
+#define PR_IPC_NAME_SIZE 1024
+
+/*
+ * Types of NSPR IPC objects
+ */
+typedef enum {
+    _PRIPCSem,  /* semaphores */
+    _PRIPCShm   /* shared memory segments */
+} _PRIPCType;
+
+/*
+ * Make a native IPC name from an NSPR IPC name.
+ */
+extern PRStatus _PR_MakeNativeIPCName(
+    const char *name,  /* NSPR IPC name */
+    char *result,      /* result buffer */
+    PRIntn size,       /* size of result buffer */
+    _PRIPCType type    /* type of IPC object */
+);
+
+/* Socket call error code */
+
+NSPR_API(PRInt32) _PR_MD_GET_SOCKET_ERROR(void);
+#define    _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR
+
+/* Get name of current host */
+extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen);
+#define    _PR_MD_GETHOSTNAME _MD_GETHOSTNAME
+
+extern PRStatus _PR_MD_GETSYSINFO(PRSysInfo cmd, char *name, PRUint32 namelen);
+#define    _PR_MD_GETSYSINFO _MD_GETSYSINFO
+
+/* File descriptor inheritance */
+
+/*
+ * If fd->secret->inheritable is _PR_TRI_UNKNOWN and we need to
+ * know the inheritable attribute of the fd, call this function
+ * to find that out.  This typically requires a system call.
+ */
+extern void _PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd);
+#define    _PR_MD_QUERY_FD_INHERITABLE _MD_QUERY_FD_INHERITABLE
+
+/* --- PR_GetRandomNoise() related things --- */
+
+extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size );
+#define _PR_MD_GET_RANDOM_NOISE(buf,size) _PR_MD_GetRandomNoise((buf),(size))
+extern PRSize _pr_CopyLowBits( void *dest, PRSize dstlen, void *src, PRSize srclen );
+
+/* end PR_GetRandomNoise() related */
+
+#ifdef XP_BEOS
+
+extern PRLock *_connectLock;
+
+typedef struct _ConnectListNode {
+	PRInt32		osfd;
+	PRNetAddr	addr;
+	PRUint32	addrlen;
+	PRIntervalTime	timeout;
+} ConnectListNode;
+
+extern ConnectListNode connectList[64];
+
+extern PRUint32 connectCount;
+
+#endif /* XP_BEOS */
+
+PR_END_EXTERN_C
+
+#endif /* primpl_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/private/prpriv.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/private/prpriv.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,53 @@
+/* -*- 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 prpriv_h___
+#define prpriv_h___
+
+/*
+ * NSPR 2.0 Private API
+ */
+
+#ifndef XP_MAC
+#include "private/pprio.h"
+#include "private/pprthred.h"
+#else
+#include "pprio.h"
+#include "pprthred.h"
+#endif
+
+#endif /* prpriv_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prlink.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prlink.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,255 @@
+/* -*- 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 prlink_h___
+#define prlink_h___
+
+/*
+** API to static and dynamic linking.
+*/
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PRLibrary PRLibrary;
+
+typedef struct PRStaticLinkTable {
+    const char *name;
+    void (*fp)();
+} PRStaticLinkTable;
+
+/*
+** Change the default library path to the given string. The string is
+** copied. This call will fail if it runs out of memory.
+**
+** The string provided as 'path' is copied. The caller can do whatever is
+** convenient with the argument when the function is complete.
+*/
+NSPR_API(PRStatus) PR_SetLibraryPath(const char *path);
+
+/*
+** Return a character string which contains the path used to search for
+** dynamically loadable libraries.
+**
+** The returned value is basically a copy of a PR_SetLibraryPath().
+** The storage is allocated by the runtime and becomes the responsibilty
+** of the caller.
+*/
+NSPR_API(char*) PR_GetLibraryPath(void);
+
+/*
+** Given a directory name "dir" and a library name "lib" construct a full
+** path name that will refer to the actual dynamically loaded
+** library. This does not test for existance of said file, it just
+** constructs the full filename. The name constructed is system dependent
+** and prepared for PR_LoadLibrary. The result must be free'd when the
+** caller is done with it.
+**
+** The storage for the result is allocated by the runtime and becomes the
+** responsibility of the caller.
+*/
+NSPR_API(char*) PR_GetLibraryName(const char *dir, const char *lib);
+
+/*
+**
+** Free the memory allocated, for the caller, by PR_GetLibraryName
+*/
+NSPR_API(void) PR_FreeLibraryName(char *mem);
+
+/*
+** Given a library "name" try to load the library. The argument "name"
+** is a machine-dependent name for the library, such as the full pathname
+** returned by PR_GetLibraryName.  If the library is already loaded,
+** this function will avoid loading the library twice.
+**
+** If the library is loaded successfully, then a pointer to the PRLibrary
+** structure representing the library is returned.  Otherwise, NULL is
+** returned.
+**
+** This increments the reference count of the library.
+*/
+NSPR_API(PRLibrary*) PR_LoadLibrary(const char *name);
+
+/*
+** Each operating system has its preferred way of specifying
+** a file in the file system.  Most operating systems use
+** a pathname.  Mac OS, on the other hand, uses the FSSpec
+** structure to specify a file. PRLibSpec allows NSPR clients
+** to use the type of file specification that is most efficient
+** for a particular platform.
+**
+** On some operating systems such as Mac OS, a shared library may
+** contain code fragments that can be individually loaded.
+** PRLibSpec also allows NSPR clients to identify a code fragment
+** in a library, if code fragments are supported by the OS.
+** A code fragment can be specified by name or by an integer index.
+**
+** Right now PRLibSpec supports three types of library specification:
+** a pathname, a Mac code fragment by name, and a Mac code fragment
+** by index.
+*/
+
+typedef enum PRLibSpecType {
+    PR_LibSpec_Pathname,
+    PR_LibSpec_MacNamedFragment,   /* obsolete (for Mac OS Classic) */
+    PR_LibSpec_MacIndexedFragment  /* obsolete (for Mac OS Classic) */
+} PRLibSpecType;
+
+struct FSSpec; /* Mac OS FSSpec */
+
+typedef struct PRLibSpec {
+    PRLibSpecType type;
+    union {
+        /* if type is PR_LibSpec_Pathname */
+        const char *pathname;
+
+        /* if type is PR_LibSpec_MacNamedFragment */
+        struct {
+            const struct FSSpec *fsspec;
+            const char *name;
+        } mac_named_fragment;      /* obsolete (for Mac OS Classic) */
+
+        /* if type is PR_LibSpec_MacIndexedFragment */
+        struct {
+            const struct FSSpec *fsspec;
+            PRUint32 index;
+        } mac_indexed_fragment;    /* obsolete (for Mac OS Classic) */
+    } value;
+} PRLibSpec;
+
+/*
+** The following bit flags may be or'd together and passed
+** as the 'flags' argument to PR_LoadLibraryWithFlags.
+** Flags not supported by the underlying OS are ignored.
+*/
+
+#define PR_LD_LAZY   0x1  /* equivalent to RTLD_LAZY on Unix */
+#define PR_LD_NOW    0x2  /* equivalent to RTLD_NOW on Unix */
+#define PR_LD_GLOBAL 0x4  /* equivalent to RTLD_GLOBAL on Unix */
+#define PR_LD_LOCAL  0x8  /* equivalent to RTLD_LOCAL on Unix */
+
+/*
+** Load the specified library, in the manner specified by 'flags'.
+*/
+
+NSPR_API(PRLibrary *)
+PR_LoadLibraryWithFlags(
+    PRLibSpec libSpec,    /* the shared library */
+    PRIntn flags          /* flags that affect the loading */
+);
+
+/*
+** Unload a previously loaded library. If the library was a static
+** library then the static link table will no longer be referenced. The
+** associated PRLibrary object is freed.
+**
+** PR_FAILURE is returned if the library cannot be unloaded.
+**
+** This function decrements the reference count of the library.
+*/
+NSPR_API(PRStatus) PR_UnloadLibrary(PRLibrary *lib);
+
+/*
+** Given the name of a procedure, return the address of the function that
+** implements the procedure, or NULL if no such function can be
+** found. This does not find symbols in the main program (the ".exe");
+** use PR_LoadStaticLibrary to register symbols in the main program.
+**
+** This function does not modify the reference count of the library.
+*/
+NSPR_API(void*) PR_FindSymbol(PRLibrary *lib, const char *name);
+
+/*
+** Similar to PR_FindSymbol, except that the return value is a pointer to
+** a function, and not a pointer to void. Casting between a data pointer
+** and a function pointer is not portable according to the C standard.
+** Any function pointer can be cast to any other function pointer.
+**
+** This function does not modify the reference count of the library.
+*/
+typedef void (*PRFuncPtr)();
+NSPR_API(PRFuncPtr) PR_FindFunctionSymbol(PRLibrary *lib, const char *name);
+
+/*
+** Finds a symbol in one of the currently loaded libraries. Given the
+** name of a procedure, return the address of the function that
+** implements the procedure, and return the library that contains that
+** symbol, or NULL if no such function can be found. This does not find
+** symbols in the main program (the ".exe"); use PR_AddStaticLibrary to
+** register symbols in the main program.  
+**
+** This increments the reference count of the library.
+*/
+NSPR_API(void*) PR_FindSymbolAndLibrary(const char *name,
+						      PRLibrary* *lib);
+
+/*
+** Similar to PR_FindSymbolAndLibrary, except that the return value is
+** a pointer to a function, and not a pointer to void. Casting between a
+** data pointer and a function pointer is not portable according to the C
+** standard. Any function pointer can be cast to any other function pointer.
+**
+** This increments the reference count of the library.
+*/
+NSPR_API(PRFuncPtr) PR_FindFunctionSymbolAndLibrary(const char *name,
+						      PRLibrary* *lib);
+
+/*
+** Register a static link table with the runtime under the name
+** "name". The symbols present in the static link table will be made
+** available to PR_FindSymbol. If "name" is null then the symbols will be
+** made available to the library which represents the executable. The
+** tables are not copied.
+**
+** Returns the library object if successful, null otherwise.
+**
+** This increments the reference count of the library.
+*/
+NSPR_API(PRLibrary*) PR_LoadStaticLibrary(
+    const char *name, const PRStaticLinkTable *table);
+
+/*
+** Return the pathname of the file that the library "name" was loaded
+** from. "addr" is the address of a function defined in the library.
+**
+** The caller is responsible for freeing the result with PR_Free.
+*/
+NSPR_API(char *) PR_GetLibraryFilePathname(const char *name, PRFuncPtr addr);
+
+PR_END_EXTERN_C
+
+#endif /* prlink_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prlock.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prlock.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,121 @@
+/* -*- 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:		prlock.h
+** Description:	API to basic locking functions of NSPR.
+**
+**
+** NSPR provides basic locking mechanisms for thread synchronization.  Locks 
+** are lightweight resource contention controls that prevent multiple threads 
+** from accessing something (code/data) simultaneously.
+**/
+
+#ifndef prlock_h___
+#define prlock_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/**********************************************************************/
+/************************* TYPES AND CONSTANTS ************************/
+/**********************************************************************/
+
+/*
+ * PRLock --
+ *
+ *     NSPR represents the lock as an opaque entity to the client of the
+ *	   API.  All routines operate on a pointer to this opaque entity.
+ */
+
+typedef struct PRLock PRLock;
+
+/**********************************************************************/
+/****************************** FUNCTIONS *****************************/
+/**********************************************************************/
+
+/***********************************************************************
+** FUNCTION:    PR_NewLock
+** DESCRIPTION:
+**  Returns a pointer to a newly created opaque lock object.
+** INPUTS:      void
+** OUTPUTS:     void
+** RETURN:      PRLock*
+**   If the lock can not be created because of resource constraints, NULL
+**   is returned.
+**  
+***********************************************************************/
+NSPR_API(PRLock*) PR_NewLock(void);
+
+/***********************************************************************
+** FUNCTION:    PR_DestroyLock
+** DESCRIPTION:
+**  Destroys a given opaque lock object.
+** INPUTS:      PRLock *lock
+**              Lock to be freed.
+** OUTPUTS:     void
+** RETURN:      None
+***********************************************************************/
+NSPR_API(void) PR_DestroyLock(PRLock *lock);
+
+/***********************************************************************
+** FUNCTION:    PR_Lock
+** DESCRIPTION:
+**  Lock a lock.
+** INPUTS:      PRLock *lock
+**              Lock to locked.
+** OUTPUTS:     void
+** RETURN:      None
+***********************************************************************/
+NSPR_API(void) PR_Lock(PRLock *lock);
+
+/***********************************************************************
+** FUNCTION:    PR_Unlock
+** DESCRIPTION:
+**  Unlock a lock.  Unlocking an unlocked lock has undefined results.
+** INPUTS:      PRLock *lock
+**              Lock to unlocked.
+** OUTPUTS:     void
+** RETURN:      PR_STATUS
+**              Returns PR_FAILURE if the caller does not own the lock.
+***********************************************************************/
+NSPR_API(PRStatus) PR_Unlock(PRLock *lock);
+
+PR_END_EXTERN_C
+
+#endif /* prlock_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prlog.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prlog.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,256 @@
+/* -*- 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 prlog_h___
+#define prlog_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** prlog.h -- Declare interfaces to NSPR's Logging service
+**
+** NSPR provides a logging service that is used by NSPR itself and is
+** available to client programs.
+**
+** To use the service from a client program, you should create a
+** PRLogModuleInfo structure by calling PR_NewLogModule(). After
+** creating the LogModule, you can write to the log using the PR_LOG()
+** macro.
+**
+** Initialization of the log service is handled by NSPR initialization.
+**
+** At execution time, you must enable the log service. To enable the
+** log service, set the environment variable: NSPR_LOG_MODULES
+** variable.
+**
+** NSPR_LOG_MODULES variable has the form:
+**
+**     <moduleName>:<value>[, <moduleName>:<value>]*
+**
+** Where:
+**  <moduleName> is the name passed to PR_NewLogModule().
+**  <value> is a numeric constant, e.g. 5. This value is the maximum
+** value of a log event, enumerated by PRLogModuleLevel, that you want
+** written to the log.
+** 
+** For example: to record all events of greater value than or equal to
+** PR_LOG_ERROR for a LogModule names "gizmo", say:
+** 
+** set NSPR_LOG_MODULES=gizmo:2
+** 
+** Note that you must specify the numeric value of PR_LOG_ERROR.
+** 
+** Special LogModule names are provided for controlling NSPR's log
+** service at execution time. These controls should be set in the
+** NSPR_LOG_MODULES environment variable at execution time to affect
+** NSPR's log service for your application.
+** 
+** The special LogModule "all" enables all LogModules. To enable all
+** LogModule calls to PR_LOG(), say:
+** 
+** set NSPR_LOG_MODULES=all:5
+** 
+** The special LogModule name "sync" tells the NSPR log service to do
+** unbuffered logging.
+** 
+** The special LogModule name "bufsize:<size>" tells NSPR to set the
+** log buffer to <size>.
+**
+** The environment variable NSPR_LOG_FILE specifies the log file to use
+** unless the default of "stderr" is acceptable. For MS Windows
+** systems, NSPR_LOG_FILE can be set to a special value: "WinDebug"
+** (case sensitive). This value causes PR_LOG() output to be written
+** using the Windows API OutputDebugString(). OutputDebugString()
+** writes to the debugger window; some people find this helpful.
+** 
+**
+** To put log messages in your programs, use the PR_LOG macro:
+**
+**     PR_LOG(<module>, <level>, (<printfString>, <args>*));
+**
+** Where <module> is the address of a PRLogModuleInfo structure, and
+** <level> is one of the levels defined by the enumeration:
+** PRLogModuleLevel. <args> is a printf() style of argument list. That
+** is: (fmtstring, ...).
+**
+** Example:
+** 
+** main() {
+**    PRIntn one = 1;
+**    PRLogModuleInfo * myLm = PR_NewLogModule("gizmo");
+**    PR_LOG( myLm, PR_LOG_ALWAYS, ("Log this! %d\n", one)); 
+**    return; 
+** }
+** 
+** Note the use of printf() style arguments as the third agrument(s) to
+** PR_LOG().
+** 
+** After compiling and linking you application, set the environment:
+** 
+** set NSPR_LOG_MODULES=gizmo:5
+** set NSPR_LOG_FILE=logfile.txt
+** 
+** When you execute your application, the string "Log this! 1" will be
+** written to the file "logfile.txt".
+** 
+** Note to NSPR engineers: a number of PRLogModuleInfo structures are
+** defined and initialized in prinit.c. See this module for ideas on
+** what to log where.
+** 
+*/
+
+typedef enum PRLogModuleLevel {
+    PR_LOG_NONE = 0,                /* nothing */
+    PR_LOG_ALWAYS = 1,              /* always printed */
+    PR_LOG_ERROR = 2,               /* error messages */
+    PR_LOG_WARNING = 3,             /* warning messages */
+    PR_LOG_DEBUG = 4,               /* debug messages */
+
+    PR_LOG_NOTICE = PR_LOG_DEBUG,   /* notice messages */
+    PR_LOG_WARN = PR_LOG_WARNING,   /* warning messages */
+    PR_LOG_MIN = PR_LOG_DEBUG,      /* minimal debugging messages */
+    PR_LOG_MAX = PR_LOG_DEBUG       /* maximal debugging messages */
+} PRLogModuleLevel;
+
+/*
+** One of these structures is created for each module that uses logging.
+**    "name" is the name of the module
+**    "level" is the debugging level selected for that module
+*/
+typedef struct PRLogModuleInfo {
+    const char *name;
+    PRLogModuleLevel level;
+    struct PRLogModuleInfo *next;
+} PRLogModuleInfo;
+
+/*
+** Create a new log module.
+*/
+NSPR_API(PRLogModuleInfo*) PR_NewLogModule(const char *name);
+
+/*
+** Set the file to use for logging. Returns PR_FALSE if the file cannot
+** be created
+*/
+NSPR_API(PRBool) PR_SetLogFile(const char *name);
+
+/*
+** Set the size of the logging buffer. If "buffer_size" is zero then the
+** logging becomes "synchronous" (or unbuffered).
+*/
+NSPR_API(void) PR_SetLogBuffering(PRIntn buffer_size);
+
+/*
+** Print a string to the log. "fmt" is a PR_snprintf format type. All
+** messages printed to the log are preceeded by the name of the thread
+** and a time stamp. Also, the routine provides a missing newline if one
+** is not provided.
+*/
+NSPR_API(void) PR_LogPrint(const char *fmt, ...);
+
+/*
+** Flush the log to its file.
+*/
+NSPR_API(void) PR_LogFlush(void);
+
+/*
+** Windoze 16 can't support a large static string space for all of the
+** various debugging strings so logging is not enabled for it.
+*/
+#if (defined(DEBUG) || defined(FORCE_PR_LOG)) && !defined(WIN16)
+#define PR_LOGGING 1
+
+#define PR_LOG_TEST(_module,_level) \
+    ((_module)->level >= (_level))
+
+/*
+** Log something.
+**    "module" is the address of a PRLogModuleInfo structure
+**    "level" is the desired logging level
+**    "args" is a variable length list of arguments to print, in the following
+**       format:  ("printf style format string", ...)
+*/
+#define PR_LOG(_module,_level,_args)     \
+    PR_BEGIN_MACRO             \
+      if (PR_LOG_TEST(_module,_level)) { \
+      PR_LogPrint _args;         \
+      }                     \
+    PR_END_MACRO
+
+#else /* (defined(DEBUG) || defined(FORCE_PR_LOG)) && !defined(WIN16) */
+
+#undef PR_LOGGING
+#define PR_LOG_TEST(module,level) 0
+#define PR_LOG(module,level,args)
+
+#endif /* (defined(DEBUG) || defined(FORCE_PR_LOG)) && !defined(WIN16) */
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#ifdef PR_LOGGING
+#define PR_LOG_BEGIN    PR_LOG
+#define PR_LOG_END      PR_LOG
+#define PR_LOG_DEFINE   PR_NewLogModule
+#else
+#define PR_LOG_BEGIN(module,level,args)
+#define PR_LOG_END(module,level,args)
+#define PR_LOG_DEFINE(_name)    NULL
+#endif /* PR_LOGGING */
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#if defined(DEBUG) || defined(FORCE_PR_ASSERT)
+
+NSPR_API(void) PR_Assert(const char *s, const char *file, PRIntn ln);
+#define PR_ASSERT(_expr) \
+    ((_expr)?((void)0):PR_Assert(# _expr,__FILE__,__LINE__))
+
+#define PR_NOT_REACHED(_reasonStr) \
+    PR_Assert(_reasonStr,__FILE__,__LINE__)
+
+#else
+
+#define PR_ASSERT(expr) ((void) 0)
+#define PR_NOT_REACHED(reasonStr)
+
+#endif /* defined(DEBUG) || defined(FORCE_PR_ASSERT) */
+
+PR_END_EXTERN_C
+
+#endif /* prlog_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prlong.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prlong.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,445 @@
+/* -*- 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:                prlong.h
+** Description: Portable access to 64 bit numerics
+**
+** Long-long (64-bit signed integer type) support. Some C compilers
+** don't support 64 bit integers yet, so we use these macros to
+** support both machines that do and don't.
+**/
+#ifndef prlong_h___
+#define prlong_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/***********************************************************************
+** DEFINES:     LL_MaxInt
+**              LL_MinInt
+**              LL_Zero
+**              LL_MaxUint
+** DESCRIPTION:
+**      Various interesting constants and static variable
+**      initializer
+***********************************************************************/
+#if defined(HAVE_WATCOM_BUG_2)
+PRInt64 __pascal __loadds __export
+    LL_MaxInt(void);
+PRInt64 __pascal __loadds __export
+    LL_MinInt(void);
+PRInt64 __pascal __loadds __export
+    LL_Zero(void);
+PRUint64 __pascal __loadds __export
+    LL_MaxUint(void);
+#else
+NSPR_API(PRInt64) LL_MaxInt(void);
+NSPR_API(PRInt64) LL_MinInt(void);
+NSPR_API(PRInt64) LL_Zero(void);
+NSPR_API(PRUint64) LL_MaxUint(void);
+#endif
+
+#if defined(HAVE_LONG_LONG)
+
+#if PR_BYTES_PER_LONG == 8
+#define LL_MAXINT   9223372036854775807L
+#define LL_MININT   (-LL_MAXINT - 1L)
+#define LL_ZERO     0L
+#define LL_MAXUINT  18446744073709551615UL
+#define LL_INIT(hi, lo)  ((hi ## L << 32) + lo ## L)
+#elif (defined(WIN32) || defined(WIN16)) && !defined(__GNUC__)
+#define LL_MAXINT   9223372036854775807i64
+#define LL_MININT   (-LL_MAXINT - 1i64)
+#define LL_ZERO     0i64
+#define LL_MAXUINT  18446744073709551615ui64
+#define LL_INIT(hi, lo)  ((hi ## i64 << 32) + lo ## i64)
+#else
+#define LL_MAXINT   9223372036854775807LL
+#define LL_MININT   (-LL_MAXINT - 1LL)
+#define LL_ZERO     0LL
+#define LL_MAXUINT  18446744073709551615ULL
+#define LL_INIT(hi, lo)  ((hi ## LL << 32) + lo ## LL)
+#endif
+
+/***********************************************************************
+** MACROS:      LL_*
+** DESCRIPTION:
+**      The following macros define portable access to the 64 bit
+**      math facilities.
+**
+***********************************************************************/
+
+/***********************************************************************
+** MACROS:      LL_<relational operators>
+**
+**  LL_IS_ZERO        Test for zero
+**  LL_EQ             Test for equality
+**  LL_NE             Test for inequality
+**  LL_GE_ZERO        Test for zero or positive
+**  LL_CMP            Compare two values
+***********************************************************************/
+#define LL_IS_ZERO(a)       ((a) == 0)
+#define LL_EQ(a, b)         ((a) == (b))
+#define LL_NE(a, b)         ((a) != (b))
+#define LL_GE_ZERO(a)       ((a) >= 0)
+#define LL_CMP(a, op, b)    ((PRInt64)(a) op (PRInt64)(b))
+#define LL_UCMP(a, op, b)   ((PRUint64)(a) op (PRUint64)(b))
+
+/***********************************************************************
+** MACROS:      LL_<logical operators>
+**
+**  LL_AND            Logical and
+**  LL_OR             Logical or
+**  LL_XOR            Logical exclusion
+**  LL_OR2            A disgusting deviation
+**  LL_NOT            Negation (one's complement)
+***********************************************************************/
+#define LL_AND(r, a, b)        ((r) = (a) & (b))
+#define LL_OR(r, a, b)        ((r) = (a) | (b))
+#define LL_XOR(r, a, b)        ((r) = (a) ^ (b))
+#define LL_OR2(r, a)        ((r) = (r) | (a))
+#define LL_NOT(r, a)        ((r) = ~(a))
+
+/***********************************************************************
+** MACROS:      LL_<mathematical operators>
+**
+**  LL_NEG            Negation (two's complement)
+**  LL_ADD            Summation (two's complement)
+**  LL_SUB            Difference (two's complement)
+***********************************************************************/
+#define LL_NEG(r, a)        ((r) = -(a))
+#define LL_ADD(r, a, b)     ((r) = (a) + (b))
+#define LL_SUB(r, a, b)     ((r) = (a) - (b))
+
+/***********************************************************************
+** MACROS:      LL_<mathematical operators>
+**
+**  LL_MUL            Product (two's complement)
+**  LL_DIV            Quotient (two's complement)
+**  LL_MOD            Modulus (two's complement)
+***********************************************************************/
+#define LL_MUL(r, a, b)        ((r) = (a) * (b))
+#define LL_DIV(r, a, b)        ((r) = (a) / (b))
+#define LL_MOD(r, a, b)        ((r) = (a) % (b))
+
+/***********************************************************************
+** MACROS:      LL_<shifting operators>
+**
+**  LL_SHL            Shift left [0..64] bits
+**  LL_SHR            Shift right [0..64] bits with sign extension
+**  LL_USHR           Unsigned shift right [0..64] bits
+**  LL_ISHL           Signed shift left [0..64] bits
+***********************************************************************/
+#define LL_SHL(r, a, b)     ((r) = (PRInt64)(a) << (b))
+#define LL_SHR(r, a, b)     ((r) = (PRInt64)(a) >> (b))
+#define LL_USHR(r, a, b)    ((r) = (PRUint64)(a) >> (b))
+#define LL_ISHL(r, a, b)    ((r) = (PRInt64)(a) << (b))
+
+/***********************************************************************
+** MACROS:      LL_<conversion operators>
+**
+**  LL_L2I            Convert to signed 32 bit
+**  LL_L2UI           Convert to unsigned 32 bit
+**  LL_L2F            Convert to floating point
+**  LL_L2D            Convert to floating point
+**  LL_I2L            Convert signed to 64 bit
+**  LL_UI2L           Convert unsigned to 64 bit
+**  LL_F2L            Convert float to 64 bit
+**  LL_D2L            Convert float to 64 bit
+***********************************************************************/
+#define LL_L2I(i, l)        ((i) = (PRInt32)(l))
+#define LL_L2UI(ui, l)        ((ui) = (PRUint32)(l))
+#define LL_L2F(f, l)        ((f) = (PRFloat64)(l))
+#define LL_L2D(d, l)        ((d) = (PRFloat64)(l))
+
+#define LL_I2L(l, i)        ((l) = (PRInt64)(i))
+#define LL_UI2L(l, ui)        ((l) = (PRInt64)(ui))
+#define LL_F2L(l, f)        ((l) = (PRInt64)(f))
+#define LL_D2L(l, d)        ((l) = (PRInt64)(d))
+
+/***********************************************************************
+** MACROS:      LL_UDIVMOD
+** DESCRIPTION:
+**  Produce both a quotient and a remainder given an unsigned 
+** INPUTS:      PRUint64 a: The dividend of the operation
+**              PRUint64 b: The quotient of the operation
+** OUTPUTS:     PRUint64 *qp: pointer to quotient
+**              PRUint64 *rp: pointer to remainder
+***********************************************************************/
+#define LL_UDIVMOD(qp, rp, a, b) \
+    (*(qp) = ((PRUint64)(a) / (b)), \
+     *(rp) = ((PRUint64)(a) % (b)))
+
+#else  /* !HAVE_LONG_LONG */
+
+#define LL_MAXINT   LL_MaxInt()
+#define LL_MININT   LL_MinInt()
+#define LL_ZERO     LL_Zero()
+#define LL_MAXUINT  LL_MaxUint()
+
+#ifdef IS_LITTLE_ENDIAN
+#define LL_INIT(hi, lo) {PR_UINT32(lo), PR_UINT32(hi)}
+#else
+#define LL_INIT(hi, lo) {PR_UINT32(hi), PR_UINT32(lo)}
+#endif
+
+#define LL_IS_ZERO(a)        (((a).hi == 0) && ((a).lo == 0))
+#define LL_EQ(a, b)        (((a).hi == (b).hi) && ((a).lo == (b).lo))
+#define LL_NE(a, b)        (((a).hi != (b).hi) || ((a).lo != (b).lo))
+#define LL_GE_ZERO(a)        (((a).hi >> 31) == 0)
+
+#define LL_CMP(a, op, b)    (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \
+                 ((PRInt32)(a).hi op (PRInt32)(b).hi))
+#define LL_UCMP(a, op, b)    (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \
+                 ((a).hi op (b).hi))
+
+#define LL_AND(r, a, b)        ((r).lo = (a).lo & (b).lo, \
+                 (r).hi = (a).hi & (b).hi)
+#define LL_OR(r, a, b)        ((r).lo = (a).lo | (b).lo, \
+                 (r).hi = (a).hi | (b).hi)
+#define LL_XOR(r, a, b)        ((r).lo = (a).lo ^ (b).lo, \
+                 (r).hi = (a).hi ^ (b).hi)
+#define LL_OR2(r, a)        ((r).lo = (r).lo | (a).lo, \
+                 (r).hi = (r).hi | (a).hi)
+#define LL_NOT(r, a)        ((r).lo = ~(a).lo, \
+                 (r).hi = ~(a).hi)
+
+#define LL_NEG(r, a)        ((r).lo = -(PRInt32)(a).lo, \
+                 (r).hi = -(PRInt32)(a).hi - ((r).lo != 0))
+#define LL_ADD(r, a, b) { \
+    PRInt64 _a, _b; \
+    _a = a; _b = b; \
+    (r).lo = _a.lo + _b.lo; \
+    (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \
+}
+
+#define LL_SUB(r, a, b) { \
+    PRInt64 _a, _b; \
+    _a = a; _b = b; \
+    (r).lo = _a.lo - _b.lo; \
+    (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \
+}
+
+#define LL_MUL(r, a, b) { \
+    PRInt64 _a, _b; \
+    _a = a; _b = b; \
+    LL_MUL32(r, _a.lo, _b.lo); \
+    (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \
+}
+
+#define _lo16(a)        ((a) & PR_BITMASK(16))
+#define _hi16(a)        ((a) >> 16)
+
+#define LL_MUL32(r, a, b) { \
+     PRUint32 _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \
+     _a1 = _hi16(a), _a0 = _lo16(a); \
+     _b1 = _hi16(b), _b0 = _lo16(b); \
+     _y0 = _a0 * _b0; \
+     _y1 = _a0 * _b1; \
+     _y2 = _a1 * _b0; \
+     _y3 = _a1 * _b1; \
+     _y1 += _hi16(_y0);                         /* can't carry */ \
+     _y1 += _y2;                                /* might carry */ \
+     if (_y1 < _y2)    \
+        _y3 += (PRUint32)(PR_BIT(16));  /* propagate */ \
+     (r).lo = (_lo16(_y1) << 16) + _lo16(_y0); \
+     (r).hi = _y3 + _hi16(_y1); \
+}
+
+#define LL_UDIVMOD(qp, rp, a, b)    ll_udivmod(qp, rp, a, b)
+
+NSPR_API(void) ll_udivmod(PRUint64 *qp, PRUint64 *rp, PRUint64 a, PRUint64 b);
+
+#define LL_DIV(r, a, b) { \
+    PRInt64 _a, _b; \
+    PRUint32 _negative = (PRInt32)(a).hi < 0; \
+    if (_negative) { \
+    LL_NEG(_a, a); \
+    } else { \
+    _a = a; \
+    } \
+    if ((PRInt32)(b).hi < 0) { \
+    _negative ^= 1; \
+    LL_NEG(_b, b); \
+    } else { \
+    _b = b; \
+    } \
+    LL_UDIVMOD(&(r), 0, _a, _b); \
+    if (_negative) \
+    LL_NEG(r, r); \
+}
+
+#define LL_MOD(r, a, b) { \
+    PRInt64 _a, _b; \
+    PRUint32 _negative = (PRInt32)(a).hi < 0; \
+    if (_negative) { \
+    LL_NEG(_a, a); \
+    } else { \
+    _a = a; \
+    } \
+    if ((PRInt32)(b).hi < 0) { \
+    LL_NEG(_b, b); \
+    } else { \
+    _b = b; \
+    } \
+    LL_UDIVMOD(0, &(r), _a, _b); \
+    if (_negative) \
+    LL_NEG(r, r); \
+}
+
+#define LL_SHL(r, a, b) { \
+    if (b) { \
+    PRInt64 _a; \
+        _a = a; \
+        if ((b) < 32) { \
+        (r).lo = _a.lo << ((b) & 31); \
+        (r).hi = (_a.hi << ((b) & 31)) | (_a.lo >> (32 - (b))); \
+    } else { \
+        (r).lo = 0; \
+        (r).hi = _a.lo << ((b) & 31); \
+    } \
+    } else { \
+    (r) = (a); \
+    } \
+}
+
+/* a is an PRInt32, b is PRInt32, r is PRInt64 */
+#define LL_ISHL(r, a, b) { \
+    if (b) { \
+    PRInt64 _a; \
+    _a.lo = (a); \
+    _a.hi = 0; \
+        if ((b) < 32) { \
+        (r).lo = (a) << ((b) & 31); \
+        (r).hi = ((a) >> (32 - (b))); \
+    } else { \
+        (r).lo = 0; \
+        (r).hi = (a) << ((b) & 31); \
+    } \
+    } else { \
+    (r).lo = (a); \
+    (r).hi = 0; \
+    } \
+}
+
+#define LL_SHR(r, a, b) { \
+    if (b) { \
+    PRInt64 _a; \
+        _a = a; \
+    if ((b) < 32) { \
+        (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
+        (r).hi = (PRInt32)_a.hi >> ((b) & 31); \
+    } else { \
+        (r).lo = (PRInt32)_a.hi >> ((b) & 31); \
+        (r).hi = (PRInt32)_a.hi >> 31; \
+    } \
+    } else { \
+    (r) = (a); \
+    } \
+}
+
+#define LL_USHR(r, a, b) { \
+    if (b) { \
+    PRInt64 _a; \
+        _a = a; \
+    if ((b) < 32) { \
+        (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
+        (r).hi = _a.hi >> ((b) & 31); \
+    } else { \
+        (r).lo = _a.hi >> ((b) & 31); \
+        (r).hi = 0; \
+    } \
+    } else { \
+    (r) = (a); \
+    } \
+}
+
+#define LL_L2I(i, l)        ((i) = (l).lo)
+#define LL_L2UI(ui, l)        ((ui) = (l).lo)
+#define LL_L2F(f, l)        { double _d; LL_L2D(_d, l); (f) = (PRFloat64)_d; }
+
+#define LL_L2D(d, l) { \
+    int _negative; \
+    PRInt64 _absval; \
+ \
+    _negative = (l).hi >> 31; \
+    if (_negative) { \
+    LL_NEG(_absval, l); \
+    } else { \
+    _absval = l; \
+    } \
+    (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \
+    if (_negative) \
+    (d) = -(d); \
+}
+
+#define LL_I2L(l, i)        { PRInt32 _i = ((PRInt32)(i)) >> 31; (l).lo = (i); (l).hi = _i; }
+#define LL_UI2L(l, ui)      ((l).lo = (ui), (l).hi = 0)
+#define LL_F2L(l, f)        { double _d = (double)f; LL_D2L(l, _d); }
+
+#define LL_D2L(l, d) { \
+    int _negative; \
+    double _absval, _d_hi; \
+    PRInt64 _lo_d; \
+ \
+    _negative = ((d) < 0); \
+    _absval = _negative ? -(d) : (d); \
+ \
+    (l).hi = _absval / 4.294967296e9; \
+    (l).lo = 0; \
+    LL_L2D(_d_hi, l); \
+    _absval -= _d_hi; \
+    _lo_d.hi = 0; \
+    if (_absval < 0) { \
+    _lo_d.lo = -_absval; \
+    LL_SUB(l, l, _lo_d); \
+    } else { \
+    _lo_d.lo = _absval; \
+    LL_ADD(l, l, _lo_d); \
+    } \
+ \
+    if (_negative) \
+    LL_NEG(l, l); \
+}
+
+#endif /* !HAVE_LONG_LONG */
+
+PR_END_EXTERN_C
+
+#endif /* prlong_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prmem.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prmem.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,158 @@
+/* -*- 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: prmem.h
+** Description: API to NSPR memory management functions
+**
+*/
+#ifndef prmem_h___
+#define prmem_h___
+
+#include "prtypes.h"
+#include <stdlib.h>
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Thread safe memory allocation.
+**
+** NOTE: pr wraps up malloc, free, calloc, realloc so they are already
+** thread safe (and are not declared here - look in stdlib.h).
+*/
+
+/*
+** PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free have the same signatures
+** as their libc equivalent malloc, calloc, realloc, and free, and have
+** the same semantics.  (Note that the argument type size_t is replaced
+** by PRUint32.)  Memory allocated by PR_Malloc, PR_Calloc, or PR_Realloc
+** must be freed by PR_Free.
+*/
+
+NSPR_API(void *) PR_Malloc(PRUint32 size);
+
+NSPR_API(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize);
+
+NSPR_API(void *) PR_Realloc(void *ptr, PRUint32 size);
+
+NSPR_API(void) PR_Free(void *ptr);
+
+/*
+** The following are some convenience macros defined in terms of
+** PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free.
+*/
+
+/***********************************************************************
+** FUNCTION:	PR_MALLOC()
+** DESCRIPTION:
+**   PR_NEW() allocates an untyped item of size _size from the heap.
+** INPUTS:  _size: size in bytes of item to be allocated
+** OUTPUTS:	untyped pointer to the node allocated
+** RETURN:	pointer to node or error returned from malloc().
+***********************************************************************/
+#define PR_MALLOC(_bytes) (PR_Malloc((_bytes)))
+
+/***********************************************************************
+** FUNCTION:	PR_NEW()
+** DESCRIPTION:
+**   PR_NEW() allocates an item of type _struct from the heap.
+** INPUTS:  _struct: a data type
+** OUTPUTS:	pointer to _struct
+** RETURN:	pointer to _struct or error returns from malloc().
+***********************************************************************/
+#define PR_NEW(_struct) ((_struct *) PR_MALLOC(sizeof(_struct)))
+
+/***********************************************************************
+** FUNCTION:	PR_REALLOC()
+** DESCRIPTION:
+**   PR_REALLOC() re-allocates _ptr bytes from the heap as a _size
+**   untyped item.
+** INPUTS:	_ptr: pointer to node to reallocate
+**          _size: size of node to allocate
+** OUTPUTS:	pointer to node allocated
+** RETURN:	pointer to node allocated
+***********************************************************************/
+#define PR_REALLOC(_ptr, _size) (PR_Realloc((_ptr), (_size)))
+
+/***********************************************************************
+** FUNCTION:	PR_CALLOC()
+** DESCRIPTION:
+**   PR_CALLOC() allocates a _size bytes untyped item from the heap
+**   and sets the allocated memory to all 0x00.
+** INPUTS:	_size: size of node to allocate
+** OUTPUTS:	pointer to node allocated
+** RETURN:	pointer to node allocated
+***********************************************************************/
+#define PR_CALLOC(_size) (PR_Calloc(1, (_size)))
+
+/***********************************************************************
+** FUNCTION:	PR_NEWZAP()
+** DESCRIPTION:
+**   PR_NEWZAP() allocates an item of type _struct from the heap
+**   and sets the allocated memory to all 0x00.
+** INPUTS:	_struct: a data type
+** OUTPUTS:	pointer to _struct
+** RETURN:	pointer to _struct
+***********************************************************************/
+#define PR_NEWZAP(_struct) ((_struct*)PR_Calloc(1, sizeof(_struct)))
+
+/***********************************************************************
+** FUNCTION:	PR_DELETE()
+** DESCRIPTION:
+**   PR_DELETE() unallocates an object previosly allocated via PR_NEW()
+**   or PR_NEWZAP() to the heap.
+** INPUTS:	pointer to previously allocated object
+** OUTPUTS:	the referenced object is returned to the heap
+** RETURN:	void
+***********************************************************************/
+#define PR_DELETE(_ptr) { PR_Free(_ptr); (_ptr) = NULL; }
+
+/***********************************************************************
+** FUNCTION:	PR_FREEIF()
+** DESCRIPTION:
+**   PR_FREEIF() conditionally unallocates an object previously allocated
+**   vial PR_NEW() or PR_NEWZAP(). If the pointer to the object is
+**   equal to zero (0), the object is not released.
+** INPUTS:	pointer to previously allocated object
+** OUTPUTS:	the referenced object is conditionally returned to the heap
+** RETURN:	void
+***********************************************************************/
+#define PR_FREEIF(_ptr)	if (_ptr) PR_DELETE(_ptr)
+
+PR_END_EXTERN_C
+
+#endif /* prmem_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prmon.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prmon.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,113 @@
+/* -*- 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 prmon_h___
+#define prmon_h___
+
+#include "prtypes.h"
+#include "prinrval.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PRMonitor PRMonitor;
+
+/*
+** Create a new monitor. Monitors are re-entrant locks with a single built-in
+** condition variable.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low.
+*/
+NSPR_API(PRMonitor*) PR_NewMonitor(void);
+
+/*
+** Destroy a monitor. The caller is responsible for guaranteeing that the
+** monitor is no longer in use. There must be no thread waiting on the monitor's
+** condition variable and that the lock is not held.
+**
+*/
+NSPR_API(void) PR_DestroyMonitor(PRMonitor *mon);
+
+/*
+** Enter the lock associated with the monitor. If the calling thread currently
+** is in the monitor, the call to enter will silently succeed. In either case,
+** it will increment the entry count by one.
+*/
+NSPR_API(void) PR_EnterMonitor(PRMonitor *mon);
+
+/*
+** Decrement the entry count associated with the monitor. If the decremented
+** entry count is zero, the monitor is exited. Returns PR_FAILURE if the
+** calling thread has not entered the monitor.
+*/
+NSPR_API(PRStatus) PR_ExitMonitor(PRMonitor *mon);
+
+/*
+** Wait for a notify on the monitor's condition variable. Sleep for "ticks"
+** amount of time (if "ticks" is PR_INTERVAL_NO_TIMEOUT then the sleep is
+** indefinite).
+**
+** While the thread is waiting it exits the monitor (as if it called
+** PR_ExitMonitor as many times as it had called PR_EnterMonitor).  When
+** the wait has finished the thread regains control of the monitors lock
+** with the same entry count as before the wait began.
+**
+** The thread waiting on the monitor will be resumed when the monitor is
+** notified (assuming the thread is the next in line to receive the
+** notify) or when the "ticks" timeout elapses.
+**
+** Returns PR_FAILURE if the caller has not entered the monitor.
+*/
+NSPR_API(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime ticks);
+
+/*
+** Notify a thread waiting on the monitor's condition variable. If a thread
+** is waiting on the condition variable (using PR_Wait) then it is awakened
+** and attempts to reenter the monitor.
+*/
+NSPR_API(PRStatus) PR_Notify(PRMonitor *mon);
+
+/*
+** Notify all of the threads waiting on the monitor's condition variable.
+** All of threads waiting on the condition are scheduled to reenter the
+** monitor.
+*/
+NSPR_API(PRStatus) PR_NotifyAll(PRMonitor *mon);
+
+PR_END_EXTERN_C
+
+#endif /* prmon_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prmwait.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prmwait.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,412 @@
+/* -*- 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(_PRMWAIT_H)
+#else
+#define _PRMWAIT_H
+
+#include "prio.h"
+#include "prtypes.h"
+#include "prclist.h"
+
+PR_BEGIN_EXTERN_C
+
+/********************************************************************************/
+/********************************************************************************/
+/********************************************************************************/
+/******************************       WARNING        ****************************/
+/********************************************************************************/
+/**************************** This is work in progress. *************************/
+/************************** Do not make any assumptions *************************/
+/************************** about the stability of this *************************/
+/************************** API or the underlying imple- ************************/
+/************************** mentation.                   ************************/
+/********************************************************************************/
+/********************************************************************************/
+
+/*
+** STRUCTURE:   PRWaitGroup
+** DESCRIPTION:
+**      The client may define several wait groups in order to semantically
+**      tie a collection of file descriptors for a single purpose. This allows
+**      easier dispatching of threads that returned with active file descriptors
+**      from the wait function.
+*/
+typedef struct PRWaitGroup PRWaitGroup;
+
+/*
+** ENUMERATION: PRMWStatus
+** DESCRIPTION:
+**      This enumeration is used to indicate the completion status of
+**      a receive wait object. Generally stated, a positive value indicates
+**      that the operation is not yet complete. A zero value indicates
+**      success (similar to PR_SUCCESS) and any negative value is an
+**      indication of failure. The reason for the failure can be retrieved
+**      by calling PR_GetError().
+**
+**  PR_MW_PENDING       The operation is still pending. None of the other
+**                      fields of the object are currently valid.
+**  PR_MW_SUCCESS       The operation is complete and it was successful.
+**  PR_MW_FAILURE       The operation failed. The reason for the failure
+**                      can be retrieved by calling PR_GetError().
+**  PR_MW_TIMEOUT       The amount of time allowed for by the object's
+**                      'timeout' field has expired w/o the operation
+**                      otherwise coming to closure.
+**  PR_MW_INTERRUPT     The operation was cancelled, either by the client
+**                      calling PR_CancelWaitFileDesc() or destroying the
+**                      entire wait group (PR_DestroyWaitGroup()).
+*/
+typedef enum PRMWStatus
+{
+    PR_MW_PENDING = 1,
+    PR_MW_SUCCESS = 0,
+    PR_MW_FAILURE = -1,
+    PR_MW_TIMEOUT = -2,
+    PR_MW_INTERRUPT = -3
+} PRMWStatus;
+
+/*
+** STRUCTURE:   PRMemoryDescriptor
+** DESCRIPTION:
+**      THis is a descriptor for an interval of memory. It contains a
+**      pointer to the first byte of that memory and the length (in
+**      bytes) of the interval.
+*/
+typedef struct PRMemoryDescriptor
+{
+    void *start;                /* pointer to first byte of memory */
+    PRSize length;              /* length (in bytes) of memory interval */
+} PRMemoryDescriptor;
+
+/*
+** STRUCTURE:   PRMWaitClientData
+** DESCRIPTION:
+**      An opague stucture for which a client MAY give provide a concrete
+**      definition and associate with a receive descriptor. The NSPR runtime
+**      does not manage this field. It is completely up to the client.
+*/
+typedef struct PRMWaitClientData PRMWaitClientData;
+
+/*
+** STRUCTURE:   PRRecvWait
+** DESCRIPTION:
+**      A receive wait object contains the file descriptor that is subject
+**      to the wait and the amount of time (beginning epoch established
+**      when the object is presented to the runtime) the the channel should
+**      block before abandoning the process.
+**
+**      The success of the wait operation will be noted in the object's
+**      'outcome' field. The fields are not valid when the NSPR runtime
+**      is in possession of the object.
+**
+**      The memory descriptor describes an interval of writable memory
+**      in the caller's address space where data from an initial read
+**      can be placed. The description may indicate a null interval.
+*/
+typedef struct PRRecvWait 
+{
+    PRCList internal;           /* internal runtime linkages */
+
+    PRFileDesc *fd;             /* file descriptor associated w/ object */
+    PRMWStatus outcome;         /* outcome of the current/last operation */
+    PRIntervalTime timeout;     /* time allowed for entire operation */
+
+    PRInt32 bytesRecv;          /* number of bytes transferred into buffer */
+    PRMemoryDescriptor buffer;  /* where to store first segment of input data */
+    PRMWaitClientData *client;  /* pointer to arbitrary client defined data */
+} PRRecvWait;
+
+/*
+** STRUCTURE:   PRMWaitEnumerator
+** DESCRIPTION:
+**      An enumeration object is used to store the state of an existing
+**      enumeration over a wait group. The opaque object must be allocated
+**      by the client and the reference presented on each call to the
+**      pseudo-stateless enumerator. The enumeration objects are sharable
+**      only in serial fashion.
+*/
+typedef struct PRMWaitEnumerator PRMWaitEnumerator;
+
+
+/*
+** FUNCTION:    PR_AddWaitFileDesc
+** DESCRIPTION:
+**      This function will effectively add a file descriptor to the
+**      list of those waiting for network receive. The new descriptor
+**      will be semantically tied to the wait group specified.
+**
+**      The ownership for the storage pointed to by 'desc' is temporarily
+**      passed over the the NSPR runtime. It will be handed back by the
+**      function PR_WaitRecvReady().
+**
+**  INPUTS
+**      group       A reference to a PRWaitGroup or NULL. Wait groups are
+**                  created by calling PR_CreateWaitGroup() and are used
+**                  to semantically group various file descriptors by the
+**                  client's application.
+**      desc        A reference to a valid PRRecvWait. The object of the
+**                  reference must be preserved and not be modified
+**                  until its ownership is returned to the client.
+**  RETURN
+**      PRStatus    An indication of success. If equal to PR_FAILUE details
+**                  of the failure are avaiable via PR_GetError().
+**
+**  ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**                  Invalid 'group' identifier or duplicate 'desc' object.
+**      PR_OUT_OF_MEMORY_ERROR
+**                  Insuffient memory for internal data structures.
+**      PR_INVALID_STATE_ERROR
+**                  The group is being destroyed.
+*/
+NSPR_API(PRStatus) PR_AddWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc);
+
+/*
+** FUNCTION:    PR_WaitRecvReady
+** DESCRIPTION:
+**      PR_WaitRecvReady will block the calling thread until one of the
+**      file descriptors that have been added via PR_AddWaitFileDesc is
+**      available for input I/O.
+**  INPUT
+**      group       A pointer to a valid PRWaitGroup or NULL (the null
+**                  group. The function will block the caller until a
+**                  channel from the wait group becomes ready for receive
+**                  or there is some sort of error.
+**  RETURN
+**      PRReciveWait
+**                  When the caller is resumed it is either returned a
+**                  valid pointer to a previously added receive wait or
+**                  a NULL. If the latter, the function has terminated
+**                  for a reason that can be determined by calling
+**                  PR_GetError().
+**                  If a valid pointer is returned, the reference is to the
+**                  file descriptor contained in the receive wait object.
+**                  The outcome of the wait operation may still fail, and
+**                  if it has, that fact will be noted in the object's
+**                  outcome field. Details can be retrieved from PR_GetError().
+**
+**  ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**                  The 'group' is not known by the runtime.
+**      PR_PENDING_INTERRUPT_ERROR
+                    The thread was interrupted.
+**      PR_INVALID_STATE_ERROR
+**                  The group is being destroyed.
+*/
+NSPR_API(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group);
+
+/*
+** FUNCTION:    PR_CancelWaitFileDesc
+** DESCRIPTION:
+**      PR_CancelWaitFileDesc is provided as a means for cancelling operations
+**      on objects previously submitted by use of PR_AddWaitFileDesc(). If
+**      the runtime knows of the object, it will be marked as having failed
+**      because it was interrupted (similar to PR_Interrupt()). The first
+**      available thread waiting on the group will be made to return the
+**      PRRecvWait object with the outcome noted.
+**
+**  INPUTS
+**      group       The wait group under which the wait receive object was
+**                  added.
+**      desc        A pointer to the wait receive object that is to be
+**                  cancelled.
+**  RETURN
+**      PRStatus    If the wait receive object was located and associated
+**                  with the specified wait group, the status returned will
+**                  be PR_SUCCESS. There is still a race condition that would
+**                  permit the offected object to complete normally, but it
+**                  is assured that it will complete in the near future.
+**                  If the receive object or wait group are invalid, the
+**                  function will return with a status of PR_FAILURE.
+**
+**  ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**                  The 'group' argument is not recognized as a valid group.
+**      PR_COLLECTION_EMPTY_ERROR
+**                  There are no more receive wait objects in the group's
+**                  collection.
+**      PR_INVALID_STATE_ERROR
+**                  The group is being destroyed.
+*/
+NSPR_API(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc);
+
+/*
+** FUNCTION:    PR_CancelWaitGroup
+** DESCRIPTION:
+**      PR_CancelWaitGroup is provided as a means for cancelling operations
+**      on objects previously submitted by use of PR_AddWaitFileDesc(). Each
+**      successive call will return a pointer to a PRRecvWait object that
+**      was previously registered via PR_AddWaitFileDesc(). If no wait
+**      objects are associated with the wait group, a NULL will be returned.
+**      This function should be called in a loop until a NULL is returned
+**      to reclaim all the wait objects prior to calling PR_DestroyWaitGroup().
+**
+**  INPUTS
+**      group       The wait group under which the wait receive object was
+**                  added.
+**  RETURN
+**      PRRecvWait* If the wait group is valid and at least one receive wait
+**                  object is present in the group, that object will be
+**                  marked as PR_MW_INTERRUPT'd and removed from the group's
+**                  queues. Otherwise a NULL will be returned and the reason
+**                  for the NULL may be retrieved by calling PR_GetError().
+**
+**  ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**      PR_GROUP_EMPTY_ERROR
+*/
+NSPR_API(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group);
+
+/*
+** FUNCTION:    PR_CreateWaitGroup
+** DESCRIPTION:
+**      A wait group is an opaque object that a client may create in order
+**      to semantically group various wait requests. Each wait group is
+**      unique, including the default wait group (NULL). A wait request
+**      that was added under a wait group will only be serviced by a caller
+**      that specified the same wait group.
+**
+**  INPUT
+**      size        The size of the hash table to be used to contain the
+**                  receive wait objects. This is just the initial size.
+**                  It will grow as it needs to, but to avoid that hassle
+**                  one can suggest a suitable size initially. It should
+**                  be ~30% larger than the maximum number of receive wait
+**                  objects expected.
+**  RETURN
+**      PRWaitGroup If successful, the function will return a pointer to an
+**                  object that was allocated by and owned by the runtime.
+**                  The reference remains valid until it is explicitly destroyed
+**                  by calling PR_DestroyWaitGroup().
+**
+**  ERRORS
+**      PR_OUT_OF_MEMORY_ERROR
+*/
+NSPR_API(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size);
+
+/*
+** FUNCTION:    PR_DestroyWaitGroup
+** DESCRIPTION:
+**      Undo the effects of PR_CreateWaitGroup(). Any receive wait operations
+**      on the group will be treated as if the each had been the target of a
+**      PR_CancelWaitFileDesc().
+**
+**  INPUT
+**      group       Reference to a wait group previously allocated using
+**                  PR_CreateWaitGroup().
+**  RETURN
+**      PRStatus    Will be PR_SUCCESS if the wait group was valid and there
+**                  are no receive wait objects in that group. Otherwise
+**                  will indicate PR_FAILURE.
+**
+**  ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**                  The 'group' argument does not reference a known object.
+**      PR_INVALID_STATE_ERROR
+**                  The group still contains receive wait objects.
+*/
+NSPR_API(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group);
+
+/*
+** FUNCTION:    PR_CreateMWaitEnumerator
+** DESCRIPTION:
+**      The PR_CreateMWaitEnumerator() function returns a reference to an
+**      opaque PRMWaitEnumerator object. The enumerator object is required
+**      as an argument for each successive call in the stateless enumeration
+**      of the indicated wait group.
+**
+**      group       The wait group that the enumeration is intended to
+**                  process. It may be be the default wait group (NULL).
+** RETURN
+**      PRMWaitEnumerator* group
+**                  A reference to an object that will be used to store
+**                  intermediate state of enumerations.
+** ERRORS
+**      Errors are indicated by the function returning a NULL.
+**      PR_INVALID_ARGUMENT_ERROR
+**                  The 'group' argument does not reference a known object.
+**      PR_OUT_OF_MEMORY_ERROR
+*/
+NSPR_API(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group);
+
+/*
+** FUNCTION:    PR_DestroyMWaitEnumerator
+** DESCRIPTION:
+**      Destroys the object created by PR_CreateMWaitEnumerator(). The reference
+**      used as an argument becomes invalid.
+**
+** INPUT
+**      PRMWaitEnumerator* enumerator
+**          The PRMWaitEnumerator object to destroy.
+** RETURN
+**      PRStatus
+**          PR_SUCCESS if successful, PR_FAILURE otherwise.
+** ERRORS
+**      PR_INVALID_ARGUMENT_ERROR
+**                  The enumerator is invalid.
+*/
+NSPR_API(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator);
+
+/*
+** FUNCTION:    PR_EnumerateWaitGroup
+** DESCRIPTION:
+**      PR_EnumerateWaitGroup is a thread safe enumerator over a wait group.
+**      Each call to the enumerator must present a valid PRMWaitEnumerator
+**      rererence and a pointer to the "previous" element returned from the
+**      enumeration process or a NULL.
+**
+**      An enumeration is started by passing a NULL as the "previous" value.
+**      Subsequent calls to the enumerator must pass in the result of the
+**      previous call. The enumeration end is signaled by the runtime returning
+**      a NULL as the result.
+**
+**      Modifications to the content of the wait group are allowed during
+**      an enumeration. The effect is that the enumeration may have to be
+**      "reset" and that may result in duplicates being returned from the
+**      enumeration.
+**
+**      An enumeration may be abandoned at any time. The runtime is not
+**      keeping any state, so there are no issues in that regard.
+*/
+NSPR_API(PRRecvWait*) PR_EnumerateWaitGroup(
+    PRMWaitEnumerator *enumerator, const PRRecvWait *previous);
+   
+PR_END_EXTERN_C
+
+#endif /* defined(_PRMWAIT_H) */
+
+/* prmwait.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prnetdb.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prnetdb.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,499 @@
+/* -*- 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 prnetdb_h___
+#define prnetdb_h___
+
+#include "prtypes.h"
+#include "prio.h"
+
+PR_BEGIN_EXTERN_C
+
+
+/*
+ *********************************************************************
+ *  Translate an Internet address to/from a character string
+ *********************************************************************
+ */
+NSPR_API(PRStatus) PR_StringToNetAddr(
+    const char *string, PRNetAddr *addr);
+
+NSPR_API(PRStatus) PR_NetAddrToString(
+    const PRNetAddr *addr, char *string, PRUint32 size);
+
+/*
+** Structures returned by network data base library.  All addresses are
+** supplied in host order, and returned in network order (suitable for
+** use in system calls).
+*/
+/*
+** Beware that WINSOCK.H defines h_addrtype and h_length as short.
+** Client code does direct struct copies of hostent to PRHostEnt and
+** hence the ifdef.
+*/
+typedef struct PRHostEnt {
+    char *h_name;       /* official name of host */
+    char **h_aliases;   /* alias list */
+#if defined(WIN32) || defined(WIN16)
+    PRInt16 h_addrtype; /* host address type */
+    PRInt16 h_length;   /* length of address */
+#else
+    PRInt32 h_addrtype; /* host address type */
+    PRInt32 h_length;   /* length of address */
+#endif
+    char **h_addr_list; /* list of addresses from name server */
+} PRHostEnt;
+
+/* A safe size to use that will mostly work... */
+#if (defined(AIX) && defined(_THREAD_SAFE)) || defined(OSF1)
+#define PR_NETDB_BUF_SIZE sizeof(struct protoent_data)
+#else
+#define PR_NETDB_BUF_SIZE 1024
+#endif
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_GetHostByName()
+** Lookup a host by name.
+**
+** INPUTS:
+**  char *hostname      Character string defining the host name of interest
+**  char *buf           A scratch buffer for the runtime to return result.
+**                      This buffer is allocated by the caller.
+**  PRIntn bufsize      Number of bytes in 'buf'. A recommnded value to
+**                      use is PR_NETDB_BUF_SIZE.
+** OUTPUTS:
+**  PRHostEnt *hostentry
+**                      This structure is filled in by the runtime if
+**                      the function returns PR_SUCCESS. This structure
+**                      is allocated by the caller.
+** RETURN:
+**  PRStatus            PR_SUCCESS if the lookup succeeds. If it fails
+**                      the result will be PR_FAILURE and the reason
+**                      for the failure can be retrieved by PR_GetError().
+***********************************************************************/
+NSPR_API(PRStatus) PR_GetHostByName(
+    const char *hostname, char *buf, PRIntn bufsize, PRHostEnt *hostentry);
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_GetIPNodeByName()
+** Lookup a host by name. Equivalent to getipnodebyname(AI_DEFAULT)
+** of RFC 2553.
+**
+** INPUTS:
+**  char *hostname      Character string defining the host name of interest
+**  PRUint16 af         Address family (either PR_AF_INET or PR_AF_INET6)
+**  PRIntn flags        Specifies the types of addresses that are searched
+**                      for and the types of addresses that are returned.
+**                      The only supported flag is PR_AI_DEFAULT.
+**  char *buf           A scratch buffer for the runtime to return result.
+**                      This buffer is allocated by the caller.
+**  PRIntn bufsize      Number of bytes in 'buf'. A recommnded value to
+**                      use is PR_NETDB_BUF_SIZE.
+** OUTPUTS:
+**  PRHostEnt *hostentry
+**                      This structure is filled in by the runtime if
+**                      the function returns PR_SUCCESS. This structure
+**                      is allocated by the caller.
+** RETURN:
+**  PRStatus            PR_SUCCESS if the lookup succeeds. If it fails
+**                      the result will be PR_FAILURE and the reason
+**                      for the failure can be retrieved by PR_GetError().
+***********************************************************************/
+
+
+#define PR_AI_ALL         0x08
+#define PR_AI_V4MAPPED    0x10
+#define PR_AI_ADDRCONFIG  0x20
+#define PR_AI_NOCANONNAME 0x8000
+#define PR_AI_DEFAULT     (PR_AI_V4MAPPED | PR_AI_ADDRCONFIG)
+
+NSPR_API(PRStatus) PR_GetIPNodeByName(
+    const char *hostname,
+    PRUint16 af,
+    PRIntn flags,
+    char *buf,
+    PRIntn bufsize,
+    PRHostEnt *hostentry);
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_GetHostByAddr()
+** Lookup a host entry by its network address.
+**
+** INPUTS:
+**  char *hostaddr      IP address of host in question
+**  char *buf           A scratch buffer for the runtime to return result.
+**                      This buffer is allocated by the caller.
+**  PRIntn bufsize      Number of bytes in 'buf'. A recommnded value to
+**                      use is PR_NETDB_BUF_SIZE.
+** OUTPUTS:
+**  PRHostEnt *hostentry
+**                      This structure is filled in by the runtime if
+**                      the function returns PR_SUCCESS. This structure
+**                      is allocated by the caller.
+** RETURN:
+**  PRStatus            PR_SUCCESS if the lookup succeeds. If it fails
+**                      the result will be PR_FAILURE and the reason
+**                      for the failure can be retrieved by PR_GetError().
+***********************************************************************/
+NSPR_API(PRStatus) PR_GetHostByAddr(
+    const PRNetAddr *hostaddr, char *buf, PRIntn bufsize, PRHostEnt *hostentry);
+
+/***********************************************************************
+** FUNCTION:	PR_EnumerateHostEnt()	
+** DESCRIPTION:
+**  A stateless enumerator over a PRHostEnt structure acquired from
+**  PR_GetHostByName() PR_GetHostByAddr() to evaluate the possible
+**  network addresses.
+**
+** INPUTS:
+**  PRIntn  enumIndex   Index of the enumeration. The enumeration starts
+**                      and ends with a value of zero.
+**
+**  PRHostEnt *hostEnt  A pointer to a host entry struct that was
+**                      previously returned by PR_GetHostByName() or
+**                      PR_GetHostByAddr().
+**
+**  PRUint16 port       The port number to be assigned as part of the
+**                      PRNetAddr.
+**
+** OUTPUTS:
+**  PRNetAddr *address  A pointer to an address structure that will be
+**                      filled in by the call to the enumeration if the
+**                      result of the call is greater than zero.
+**
+** RETURN:
+**  PRIntn              The value that should be used for the next call
+**                      of the enumerator ('enumIndex'). The enumeration
+**                      is ended if this value is returned zero.
+**                      If a value of -1 is returned, the enumeration
+**                      has failed. The reason for the failure can be
+**                      retrieved by calling PR_GetError().
+***********************************************************************/
+NSPR_API(PRIntn) PR_EnumerateHostEnt(
+    PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address);
+
+/***********************************************************************
+** FUNCTION: PR_InitializeNetAddr(), 
+** DESCRIPTION:
+**  Initialize the fields of a PRNetAddr, assigning well known values as
+**  appropriate.
+**
+** INPUTS
+**  PRNetAddrValue val  The value to be assigned to the IP Address portion
+**                      of the network address. This can only specify the
+**                      special well known values that are equivalent to
+**                      INADDR_ANY and INADDR_LOOPBACK.
+**
+**  PRUint16 port       The port number to be assigned in the structure.
+**
+** OUTPUTS:
+**  PRNetAddr *addr     The address to be manipulated.
+**
+** RETURN:
+**  PRStatus            To indicate success or failure. If the latter, the
+**                      reason for the failure can be retrieved by calling
+**                      PR_GetError();
+***********************************************************************/
+typedef enum PRNetAddrValue
+{
+    PR_IpAddrNull,      /* do NOT overwrite the IP address */
+    PR_IpAddrAny,       /* assign logical INADDR_ANY to IP address */
+    PR_IpAddrLoopback,  /* assign logical INADDR_LOOPBACK  */
+    PR_IpAddrV4Mapped   /* IPv4 mapped address */
+} PRNetAddrValue;
+
+NSPR_API(PRStatus) PR_InitializeNetAddr(
+    PRNetAddrValue val, PRUint16 port, PRNetAddr *addr);
+
+/***********************************************************************
+** FUNCTION: PR_SetNetAddr(), 
+** DESCRIPTION:
+**  Set the fields of a PRNetAddr, assigning well known values as
+**  appropriate. This function is similar to PR_InitializeNetAddr
+**  but differs in that the address family is specified.
+**
+** INPUTS
+**  PRNetAddrValue val  The value to be assigned to the IP Address portion
+**                      of the network address. This can only specify the
+**                      special well known values that are equivalent to
+**                      INADDR_ANY and INADDR_LOOPBACK.
+**
+**  PRUint16 af         The address family (either PR_AF_INET or PR_AF_INET6)
+**
+**  PRUint16 port       The port number to be assigned in the structure.
+**
+** OUTPUTS:
+**  PRNetAddr *addr     The address to be manipulated.
+**
+** RETURN:
+**  PRStatus            To indicate success or failure. If the latter, the
+**                      reason for the failure can be retrieved by calling
+**                      PR_GetError();
+***********************************************************************/
+NSPR_API(PRStatus) PR_SetNetAddr(
+    PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr);
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_IsNetAddrType()
+** Determine if the network address is of the specified type.
+**
+** INPUTS:
+**  const PRNetAddr *addr   A network address.
+**  PRNetAddrValue          The type of network address 
+**
+** RETURN:
+**  PRBool                  PR_TRUE if the network address is of the
+**                          specified type, else PR_FALSE.
+***********************************************************************/
+NSPR_API(PRBool) PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val);
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_ConvertIPv4AddrToIPv6()
+** Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr
+**
+** INPUTS:
+**  PRUint32 	v4addr		IPv4 address
+**
+** OUTPUTS:
+**  PRIPv6Addr *v6addr      The converted IPv6 address
+**
+** RETURN:
+**  void
+**                       
+***********************************************************************/
+NSPR_API(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr);
+
+/***********************************************************************
+** MACRO:	
+** DESCRIPTION:	PR_NetAddrFamily()
+** Get the 'family' field of a PRNetAddr union.
+**
+** INPUTS:
+**  const PRNetAddr *addr   A network address.
+**
+** RETURN:
+**  PRUint16                The 'family' field of 'addr'.
+***********************************************************************/
+#define PR_NetAddrFamily(addr) ((addr)->raw.family)
+
+/***********************************************************************
+** MACRO:	
+** DESCRIPTION:	PR_NetAddrInetPort()
+** Get the 'port' field of a PRNetAddr union.
+**
+** INPUTS:
+**  const PRNetAddr *addr   A network address.
+**
+** RETURN:
+**  PRUint16                The 'port' field of 'addr'.
+***********************************************************************/
+#define PR_NetAddrInetPort(addr) \
+    ((addr)->raw.family == PR_AF_INET6 ? (addr)->ipv6.port : (addr)->inet.port)
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_GetProtoByName()
+** Lookup a protocol entry based on protocol's name
+**
+** INPUTS:
+**  char *protocolname  Character string of the protocol's name.
+**  char *buf           A scratch buffer for the runtime to return result.
+**                      This buffer is allocated by the caller.
+**  PRIntn bufsize      Number of bytes in 'buf'. A recommnded value to
+**                      use is PR_NETDB_BUF_SIZE.
+** OUTPUTS:
+**  PRHostEnt *PRProtoEnt
+**                      This structure is filled in by the runtime if
+**                      the function returns PR_SUCCESS. This structure
+**                      is allocated by the caller.
+** RETURN:
+**  PRStatus            PR_SUCCESS if the lookup succeeds. If it fails
+**                      the result will be PR_FAILURE and the reason
+**                      for the failure can be retrieved by PR_GetError().
+***********************************************************************/
+
+typedef struct PRProtoEnt {
+    char *p_name;       /* official protocol name */
+    char **p_aliases;   /* alias list */
+#if defined(WIN32) || defined(WIN16)
+    PRInt16 p_num;      /* protocol # */
+#else
+    PRInt32 p_num;      /* protocol # */
+#endif
+} PRProtoEnt;
+
+NSPR_API(PRStatus) PR_GetProtoByName(
+    const char* protocolname, char* buffer, PRInt32 bufsize, PRProtoEnt* result);
+
+/***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_GetProtoByNumber()
+** Lookup a protocol entry based on protocol's number
+**
+** INPUTS:
+**  PRInt32 protocolnumber
+**                      Number assigned to the protocol.
+**  char *buf           A scratch buffer for the runtime to return result.
+**                      This buffer is allocated by the caller.
+**  PRIntn bufsize      Number of bytes in 'buf'. A recommnded value to
+**                      use is PR_NETDB_BUF_SIZE.
+** OUTPUTS:
+**  PRHostEnt *PRProtoEnt
+**                      This structure is filled in by the runtime if
+**                      the function returns PR_SUCCESS. This structure
+**                      is allocated by the caller.
+** RETURN:
+**  PRStatus            PR_SUCCESS if the lookup succeeds. If it fails
+**                      the result will be PR_FAILURE and the reason
+**                      for the failure can be retrieved by PR_GetError().
+***********************************************************************/
+NSPR_API(PRStatus) PR_GetProtoByNumber(
+    PRInt32 protocolnumber, char* buffer, PRInt32 bufsize, PRProtoEnt* result);
+
+/***********************************************************************
+** FUNCTION:
+** DESCRIPTION: PR_GetAddrInfoByName()
+**  Lookup a host by name. Equivalent to getaddrinfo(host, NULL, ...) of
+**  RFC 3493.
+**
+** INPUTS:
+**  char *hostname      Character string defining the host name of interest
+**  PRUint16 af         May be PR_AF_UNSPEC or PR_AF_INET.
+**  PRIntn flags        May be either PR_AI_ADDRCONFIG or
+**                      PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME. Include
+**                      PR_AI_NOCANONNAME to suppress the determination of
+**                      the canonical name corresponding to hostname.
+** RETURN:
+**  PRAddrInfo*         Handle to a data structure containing the results
+**                      of the host lookup. Use PR_EnumerateAddrInfo to
+**                      inspect the PRNetAddr values stored in this object.
+**                      When no longer needed, this handle must be destroyed
+**                      with a call to PR_FreeAddrInfo.  If a lookup error
+**                      occurs, then NULL will be returned.
+***********************************************************************/
+typedef struct PRAddrInfo PRAddrInfo;
+
+NSPR_API(PRAddrInfo*) PR_GetAddrInfoByName(
+    const char *hostname, PRUint16 af, PRIntn flags);
+
+/***********************************************************************
+** FUNCTION:
+** DESCRIPTION: PR_FreeAddrInfo()
+**  Destroy the PRAddrInfo handle allocated by PR_GetAddrInfoByName().
+**
+** INPUTS:
+**  PRAddrInfo *addrInfo
+**                      The handle resulting from a successful call to
+**                      PR_GetAddrInfoByName().
+** RETURN:
+**  void
+***********************************************************************/
+NSPR_API(void) PR_FreeAddrInfo(PRAddrInfo *addrInfo);
+
+/***********************************************************************
+** FUNCTION:
+** DESCRIPTION: PR_EnumerateAddrInfo()
+**  A stateless enumerator over a PRAddrInfo handle acquired from
+**  PR_GetAddrInfoByName() to inspect the possible network addresses.
+**
+** INPUTS:
+**  void *enumPtr       Index pointer of the enumeration. The enumeration
+**                      starts and ends with a value of NULL.
+**  PRAddrInfo *addrInfo
+**                      The PRAddrInfo handle returned by a successful
+**                      call to PR_GetAddrInfoByName().
+**  PRUint16 port       The port number to be assigned as part of the
+**                      PRNetAddr.
+** OUTPUTS:
+**  PRNetAddr *result   A pointer to an address structure that will be
+**                      filled in by the call to the enumeration if the
+**                      result of the call is greater than zero.
+** RETURN:
+**  void*               The value that should be used for the next call
+**                      of the enumerator ('enumPtr'). The enumeration
+**                      is ended if this value is returned NULL.
+***********************************************************************/
+NSPR_API(void *) PR_EnumerateAddrInfo(
+    void *enumPtr, const PRAddrInfo *addrInfo, PRUint16 port, PRNetAddr *result);
+
+/***********************************************************************
+** FUNCTION:
+** DESCRIPTION: PR_GetCanonNameFromAddrInfo()
+**  Extracts the canonical name of the hostname passed to
+**  PR_GetAddrInfoByName().
+**
+** INPUTS:
+**  PRAddrInfo *addrInfo 
+**                      The PRAddrInfo handle returned by a successful
+**                      call to PR_GetAddrInfoByName().
+** RETURN:
+**  const char *        A const pointer to the canonical hostname stored
+**                      in the given PRAddrInfo handle. This pointer is
+**                      invalidated once the PRAddrInfo handle is destroyed
+**                      by a call to PR_FreeAddrInfo().
+***********************************************************************/
+NSPR_API(const char *) PR_GetCanonNameFromAddrInfo(
+    const PRAddrInfo *addrInfo);
+
+/***********************************************************************
+** FUNCTIONS: PR_ntohs, PR_ntohl, PR_ntohll, PR_htons, PR_htonl, PR_htonll
+**
+** DESCRIPTION: API entries for the common byte ordering routines.
+**
+**      PR_ntohs        16 bit conversion from network to host
+**      PR_ntohl        32 bit conversion from network to host
+**      PR_ntohll       64 bit conversion from network to host
+**      PR_htons        16 bit conversion from host to network
+**      PR_htonl        32 bit conversion from host to network
+**      PR_ntonll       64 bit conversion from host to network
+**
+***********************************************************************/
+NSPR_API(PRUint16) PR_ntohs(PRUint16);
+NSPR_API(PRUint32) PR_ntohl(PRUint32);
+NSPR_API(PRUint64) PR_ntohll(PRUint64);
+NSPR_API(PRUint16) PR_htons(PRUint16);
+NSPR_API(PRUint32) PR_htonl(PRUint32);
+NSPR_API(PRUint64) PR_htonll(PRUint64);
+
+PR_END_EXTERN_C
+
+#endif /* prnetdb_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prolock.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prolock.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,210 @@
+/* -*- 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 prolock_h___
+#define prolock_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** A locking mechanism, built on the existing PRLock definiion,
+** is provided that will permit applications to define a Lock
+** Hierarchy (or Lock Ordering) schema. An application designed
+** using the Ordered Lock functions will terminate with a
+** diagnostic message when a lock inversion condition is
+** detected. 
+** 
+** The lock ordering detection is complile-time enabled only. in
+** optimized builds of NSPR, the Ordered Lock functions map
+** directly to PRLock functions, providing no lock order
+** detection.
+** 
+** The Ordered Lock Facility is compiled in when DEBUG is defined at
+** compile time. Ordered Lock can be forced on in optimized builds by
+** defining FORCE_NSPR_ORDERED_LOCK at compile time. Both the
+** application using Ordered Lock and NSPR must be compiled with the
+** facility enabled to achieve the desired results.
+** 
+** Application designers should use the macro interfaces to the Ordered
+** Lock facility to ensure that it is compiled out in optimized builds.
+**
+** Application designers are responsible for defining their own
+** lock hierarchy. 
+**
+** Ordered Lock is thread-safe and SMP safe.
+**
+** See Also: prlock.h
+**
+** /lth. 10-Jun-1998.
+**
+*/
+
+/*
+** Opaque type for ordered lock.
+** ... Don't even think of looking in here.
+**
+*/
+
+#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS)
+typedef void * PROrderedLock;
+#else
+/*
+** Map PROrderedLock and methods onto PRLock when ordered locking
+** is not compiled in.
+**  
+*/
+#include "prlock.h"
+
+typedef PRLock PROrderedLock;
+#endif
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_CreateOrderedLock() -- Create an Ordered Lock
+** 
+** DESCRIPTION: PR_CreateOrderedLock() creates an ordered lock.
+** 
+** INPUTS:
+**  order: user defined order of this lock.
+**  name: name of the lock. For debugging purposes.
+** 
+** OUTPUTS: returned
+** 
+** RETURNS: PR_OrderedLock pointer
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS)
+#define PR_CREATE_ORDERED_LOCK(order,name)\
+    PR_CreateOrderedLock((order),(name))
+#else
+#define PR_CREATE_ORDERED_LOCK(order) PR_NewLock()
+#endif
+
+NSPR_API(PROrderedLock *) 
+    PR_CreateOrderedLock( 
+        PRInt32 order,
+        const char *name
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DestroyOrderedLock() -- Destroy an Ordered Lock
+** 
+** DESCRIPTION: PR_DestroyOrderedLock() destroys the ordered lock
+** referenced by lock.
+** 
+** INPUTS: lock: pointer to a PROrderedLock
+** 
+** OUTPUTS: the lock is destroyed
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS)
+#define PR_DESTROY_ORDERED_LOCK(lock) PR_DestroyOrderedLock((lock))
+#else
+#define PR_DESTROY_ORDERED_LOCK(lock) PR_DestroyLock((lock))
+#endif
+
+NSPR_API(void) 
+    PR_DestroyOrderedLock( 
+        PROrderedLock *lock 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_LockOrderedLock() -- Lock an ordered lock
+** 
+** DESCRIPTION: PR_LockOrderedLock() locks the ordered lock
+** referenced by lock. If the order of lock is less than or equal
+** to the order of the highest lock held by the locking thread,
+** the function asserts.
+** 
+** INPUTS: lock: a pointer to a PROrderedLock
+** 
+** OUTPUTS: The lock is held or the function asserts.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS)
+#define PR_LOCK_ORDERED_LOCK(lock) PR_LockOrderedLock((lock))
+#else
+#define PR_LOCK_ORDERED_LOCK(lock) PR_Lock((lock))
+#endif
+
+NSPR_API(void) 
+    PR_LockOrderedLock( 
+        PROrderedLock *lock 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_UnlockOrderedLock() -- unlock and Ordered Lock
+** 
+** DESCRIPTION: PR_UnlockOrderedLock() unlocks the lock referenced
+** by lock.
+** 
+** INPUTS: lock: a pointer to a PROrderedLock
+** 
+** OUTPUTS: the lock is unlocked
+** 
+** RETURNS:
+**  PR_SUCCESS
+**  PR_FAILURE
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined(DEBUG) || defined(FORCE_NSPR_ORDERED_LOCKS)
+#define PR_UNLOCK_ORDERED_LOCK(lock) PR_UnlockOrderedLock((lock))
+#else
+#define PR_UNLOCK_ORDERED_LOCK(lock) PR_Unlock((lock))
+#endif
+
+NSPR_API(PRStatus) 
+    PR_UnlockOrderedLock( 
+        PROrderedLock *lock 
+);
+
+PR_END_EXTERN_C
+
+#endif /* prolock_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prpdce.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prpdce.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,118 @@
+/* -*- 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:		prpdce.h
+ * Description:	This file is the API defined to allow for DCE (aka POSIX)
+ *				thread emulation in an NSPR environment. It is not the
+ *				intent that this be a fully supported API.
+ */
+
+#if !defined(PRPDCE_H)
+#define PRPDCE_H
+
+#include "prlock.h"
+#include "prcvar.h"
+#include "prtypes.h"
+#include "prinrval.h"
+
+PR_BEGIN_EXTERN_C
+
+#define _PR_NAKED_CV_LOCK (PRLock*)0xdce1dce1
+
+/*
+** Test and acquire a lock.
+**
+** If the lock is acquired by the calling thread, the
+** return value will be PR_SUCCESS. If the lock is
+** already held, by another thread or this thread, the
+** result will be PR_FAILURE.
+*/
+NSPR_API(PRStatus) PRP_TryLock(PRLock *lock);
+
+/*
+** Create a naked condition variable
+**
+** A "naked" condition variable is one that is not created bound
+** to a lock. The CV created with this function is the only type
+** that may be used in the subsequent "naked" condition variable
+** operations (see PRP_NakedWait, PRP_NakedNotify, PRP_NakedBroadcast);
+*/
+NSPR_API(PRCondVar*) PRP_NewNakedCondVar(void);
+
+/*
+** Destroy a naked condition variable
+**
+** Destroy the condition variable created by PR_NewNakedCondVar.
+*/
+NSPR_API(void) PRP_DestroyNakedCondVar(PRCondVar *cvar);
+
+/*
+** Wait on a condition
+**
+** Wait on the condition variable 'cvar'. It is asserted that
+** the lock protecting the condition 'lock' is held by the
+** calling thread. If more time expires than that declared in
+** 'timeout' the condition will be notified. Waits can be
+** interrupted by another thread.
+**
+** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar.
+*/
+NSPR_API(PRStatus) PRP_NakedWait(
+	PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout);
+
+/*
+** Notify a thread waiting on a condition
+**
+** Notify the condition specified 'cvar'.
+**
+** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar.
+*/
+NSPR_API(PRStatus) PRP_NakedNotify(PRCondVar *cvar);
+
+/*
+** Notify all threads waiting on a condition
+**
+** Notify the condition specified 'cvar'.
+**
+** NB: The CV ('cvar') must be one created using PR_NewNakedCondVar.
+*/
+NSPR_API(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar);
+
+PR_END_EXTERN_C
+
+#endif /* PRPDCE_H */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prprf.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prprf.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,154 @@
+/* -*- 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 prprf_h___
+#define prprf_h___
+
+/*
+** API for PR printf like routines. Supports the following formats
+**	%d - decimal
+**	%u - unsigned decimal
+**	%x - unsigned hex
+**	%X - unsigned uppercase hex
+**	%o - unsigned octal
+**	%hd, %hu, %hx, %hX, %ho - 16-bit versions of above
+**	%ld, %lu, %lx, %lX, %lo - 32-bit versions of above
+**	%lld, %llu, %llx, %llX, %llo - 64 bit versions of above
+**	%s - string
+**	%c - character
+**	%p - pointer (deals with machine dependent pointer size)
+**	%f - float
+**	%g - float
+*/
+#include "prtypes.h"
+#include "prio.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+PR_BEGIN_EXTERN_C
+
+/*
+** sprintf into a fixed size buffer. Guarantees that a NUL is at the end
+** of the buffer. Returns the length of the written output, NOT including
+** the NUL, or (PRUint32)-1 if an error occurs.
+*/
+NSPR_API(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...);
+
+/*
+** sprintf into a PR_MALLOC'd buffer. Return a pointer to the malloc'd
+** buffer on success, NULL on failure. Call "PR_smprintf_free" to release
+** the memory returned.
+*/
+NSPR_API(char*) PR_smprintf(const char *fmt, ...);
+
+/*
+** Free the memory allocated, for the caller, by PR_smprintf
+*/
+NSPR_API(void) PR_smprintf_free(char *mem);
+
+/*
+** "append" sprintf into a PR_MALLOC'd buffer. "last" is the last value of
+** the PR_MALLOC'd buffer. sprintf will append data to the end of last,
+** growing it as necessary using realloc. If last is NULL, PR_sprintf_append
+** will allocate the initial string. The return value is the new value of
+** last for subsequent calls, or NULL if there is a malloc failure.
+*/
+NSPR_API(char*) PR_sprintf_append(char *last, const char *fmt, ...);
+
+/*
+** sprintf into a function. The function "f" is called with a string to
+** place into the output. "arg" is an opaque pointer used by the stuff
+** function to hold any state needed to do the storage of the output
+** data. The return value is a count of the number of characters fed to
+** the stuff function, or (PRUint32)-1 if an error occurs.
+*/
+typedef PRIntn (*PRStuffFunc)(void *arg, const char *s, PRUint32 slen);
+
+NSPR_API(PRUint32) PR_sxprintf(PRStuffFunc f, void *arg, const char *fmt, ...);
+
+/*
+** fprintf to a PRFileDesc
+*/
+NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...);
+
+/*
+** va_list forms of the above.
+*/
+NSPR_API(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen, const char *fmt, va_list ap);
+NSPR_API(char*) PR_vsmprintf(const char *fmt, va_list ap);
+NSPR_API(char*) PR_vsprintf_append(char *last, const char *fmt, va_list ap);
+NSPR_API(PRUint32) PR_vsxprintf(PRStuffFunc f, void *arg, const char *fmt, va_list ap);
+NSPR_API(PRUint32) PR_vfprintf(struct PRFileDesc* fd, const char *fmt, va_list ap);
+
+/*
+***************************************************************************
+** FUNCTION: PR_sscanf
+** DESCRIPTION:
+**     PR_sscanf() scans the input character string, performs data
+**     conversions, and stores the converted values in the data objects
+**     pointed to by its arguments according to the format control
+**     string.
+**
+**     PR_sscanf() behaves the same way as the sscanf() function in the
+**     Standard C Library (stdio.h), with the following exceptions:
+**     - PR_sscanf() handles the NSPR integer and floating point types,
+**       such as PRInt16, PRInt32, PRInt64, and PRFloat64, whereas
+**       sscanf() handles the standard C types like short, int, long,
+**       and double.
+**     - PR_sscanf() has no multibyte character support, while sscanf()
+**       does.
+** INPUTS:
+**     const char *buf
+**         a character string holding the input to scan
+**     const char *fmt
+**         the format control string for the conversions
+**     ...
+**         variable number of arguments, each of them is a pointer to
+**         a data object in which the converted value will be stored
+** OUTPUTS: none
+** RETURNS: PRInt32
+**     The number of values converted and stored.
+** RESTRICTIONS:
+**    Multibyte characters in 'buf' or 'fmt' are not allowed.
+***************************************************************************
+*/
+
+NSPR_API(PRInt32) PR_sscanf(const char *buf, const char *fmt, ...);
+
+PR_END_EXTERN_C
+
+#endif /* prprf_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prproces.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prproces.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,118 @@
+/* -*- 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 prproces_h___
+#define prproces_h___
+
+#include "prtypes.h"
+#include "prio.h"
+
+PR_BEGIN_EXTERN_C
+
+/************************************************************************/
+/*****************************PROCESS OPERATIONS*************************/
+/************************************************************************/
+
+typedef struct PRProcess PRProcess;
+typedef struct PRProcessAttr PRProcessAttr;
+
+NSPR_API(PRProcessAttr *) PR_NewProcessAttr(void);
+
+NSPR_API(void) PR_ResetProcessAttr(PRProcessAttr *attr);
+
+NSPR_API(void) PR_DestroyProcessAttr(PRProcessAttr *attr);
+
+NSPR_API(void) PR_ProcessAttrSetStdioRedirect(
+    PRProcessAttr *attr,
+    PRSpecialFD stdioFd,
+    PRFileDesc *redirectFd
+);
+
+/*
+ * OBSOLETE -- use PR_ProcessAttrSetStdioRedirect instead.
+ */
+NSPR_API(void) PR_SetStdioRedirect(
+    PRProcessAttr *attr,
+    PRSpecialFD stdioFd,
+    PRFileDesc *redirectFd
+);
+
+NSPR_API(PRStatus) PR_ProcessAttrSetCurrentDirectory(
+    PRProcessAttr *attr,
+    const char *dir
+);
+
+NSPR_API(PRStatus) PR_ProcessAttrSetInheritableFD(
+    PRProcessAttr *attr,
+    PRFileDesc *fd,
+    const char *name
+);
+
+/*
+** Create a new process
+**
+** Create a new process executing the file specified as 'path' and with
+** the supplied arguments and environment.
+**
+** This function may fail because of illegal access (permissions),
+** invalid arguments or insufficient resources.
+**
+** A process may be created such that the creator can later synchronize its
+** termination using PR_WaitProcess(). 
+*/
+
+NSPR_API(PRProcess*) PR_CreateProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr);
+
+NSPR_API(PRStatus) PR_CreateProcessDetached(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr);
+
+NSPR_API(PRStatus) PR_DetachProcess(PRProcess *process);
+
+NSPR_API(PRStatus) PR_WaitProcess(PRProcess *process, PRInt32 *exitCode);
+
+NSPR_API(PRStatus) PR_KillProcess(PRProcess *process);
+
+PR_END_EXTERN_C
+
+#endif /* prproces_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prrng.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prrng.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,107 @@
+/* -*- 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 ***** */
+
+
+/*
+** prrng.h -- NSPR Random Number Generator
+** 
+**
+** lth. 29-Oct-1999.
+*/
+
+#ifndef prrng_h___ 
+#define prrng_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** PR_GetRandomNoise() -- Get random noise from the host platform
+**
+** Description:
+** PR_GetRandomNoise() provides, depending on platform, a random value.
+** The length of the random value is dependent on platform and the
+** platform's ability to provide a random value at that moment.
+**
+** The intent of PR_GetRandomNoise() is to provide a "seed" value for a
+** another random number generator that may be suitable for
+** cryptographic operations. This implies that the random value
+** provided may not be, by itself, cryptographically secure. The value
+** generated by PR_GetRandomNoise() is at best, extremely difficult to
+** predict and is as non-deterministic as the underlying platfrom can
+** provide.
+**
+** Inputs:
+**   buf -- pointer to a caller supplied buffer to contain the
+**          generated random number. buf must be at least as large as
+**          is specified in the 'size' argument.
+**
+**   size -- the requested size of the generated random number
+**
+** Outputs:
+**   a random number provided in 'buf'.
+**
+** Returns:
+**   PRSize value equal to the size of the random number actually
+**   generated, or zero. The generated size may be less than the size
+**   requested. A return value of zero means that PR_GetRandomNoise() is
+**   not implemented on this platform, or there is no available noise
+**   available to be returned at the time of the call.
+**
+** Restrictions:
+**   Calls to PR_GetRandomNoise() may use a lot of CPU on some platforms.
+**   Some platforms may block for up to a few seconds while they
+**   accumulate some noise. Busy machines generate lots of noise, but
+**   care is advised when using PR_GetRandomNoise() frequently in your
+**   application.
+**
+** History:
+**   Parts of the model dependent implementation for PR_GetRandomNoise()
+**   were taken in whole or part from code previously in Netscape's NSS
+**   component.
+**
+*/
+NSPR_API(PRSize) PR_GetRandomNoise( 
+    void    *buf,
+    PRSize  size
+);
+
+PR_END_EXTERN_C
+
+#endif /* prrng_h___ */
+/* end prrng.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prrwlock.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prrwlock.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,120 @@
+/* -*- 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:		prrwlock.h
+** Description:	API to basic reader-writer lock functions of NSPR.
+**
+**/
+
+#ifndef prrwlock_h___
+#define prrwlock_h___
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+ * PRRWLock --
+ *
+ *	The reader writer lock, PRRWLock, is an opaque object to the clients
+ *	of NSPR.  All routines operate on a pointer to this opaque entity.
+ */
+
+
+typedef struct PRRWLock PRRWLock;
+
+#define	PR_RWLOCK_RANK_NONE	0
+
+
+/***********************************************************************
+** FUNCTION:    PR_NewRWLock
+** DESCRIPTION:
+**  Returns a pointer to a newly created reader-writer lock object.
+** INPUTS:      Lock rank
+**				Lock name
+** OUTPUTS:     void
+** RETURN:      PRRWLock*
+**   If the lock cannot be created because of resource constraints, NULL
+**   is returned.
+**  
+***********************************************************************/
+NSPR_API(PRRWLock*) PR_NewRWLock(PRUint32 lock_rank, const char *lock_name);
+
+/***********************************************************************
+** FUNCTION:    PR_DestroyRWLock
+** DESCRIPTION:
+**  Destroys a given RW lock object.
+** INPUTS:      PRRWLock *lock - Lock to be freed.
+** OUTPUTS:     void
+** RETURN:      None
+***********************************************************************/
+NSPR_API(void) PR_DestroyRWLock(PRRWLock *lock);
+
+/***********************************************************************
+** FUNCTION:    PR_RWLock_Rlock
+** DESCRIPTION:
+**  Apply a read lock (non-exclusive) on a RWLock
+** INPUTS:      PRRWLock *lock - Lock to be read-locked.
+** OUTPUTS:     void
+** RETURN:      None
+***********************************************************************/
+NSPR_API(void) PR_RWLock_Rlock(PRRWLock *lock);
+
+/***********************************************************************
+** FUNCTION:    PR_RWLock_Wlock
+** DESCRIPTION:
+**  Apply a write lock (exclusive) on a RWLock
+** INPUTS:      PRRWLock *lock - Lock to write-locked.
+** OUTPUTS:     void
+** RETURN:      None
+***********************************************************************/
+NSPR_API(void) PR_RWLock_Wlock(PRRWLock *lock);
+
+/***********************************************************************
+** FUNCTION:    PR_RWLock_Unlock
+** DESCRIPTION:
+**  Release a RW lock. Unlocking an unlocked lock has undefined results.
+** INPUTS:      PRRWLock *lock - Lock to unlocked.
+** OUTPUTS:     void
+** RETURN:      void
+***********************************************************************/
+NSPR_API(void) PR_RWLock_Unlock(PRRWLock *lock);
+
+PR_END_EXTERN_C
+
+#endif /* prrwlock_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prshm.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prshm.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,289 @@
+/* -*- 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 ***** */
+
+/*
+** prshm.h -- NSPR Shared Memory
+**
+** NSPR Named Shared Memory API provides a cross-platform named
+** shared-memory interface. NSPR Named Shared Memory is modeled on
+** similar constructs in Unix and Windows operating systems. Shared
+** memory allows multiple processes to access one or more common shared
+** memory regions, using it as an inter-process communication channel.
+**
+** Notes on Platform Independence:
+**   NSPR Named Shared Memory is built on the native services offered
+**   by most platforms. The NSPR Named Shared Memory API tries to
+**   provide a least common denominator interface so that it works
+**   across all supported platforms. To ensure that it works everywhere,
+**   some platform considerations must be accomodated and the protocol
+**   for using NSPR Shared Memory API must be observed.
+**
+** Protocol:
+**   Multiple shared memories can be created using NSPR's Shared Memory
+**   feature. For each named shared memory, as defined by the name
+**   given in the PR_OpenSharedMemory() call, a protocol for using the
+**   shared memory API is required to ensure desired behavior. Failing
+**   to follow the protocol may yield unpredictable results.
+**   
+**   PR_OpenSharedMemory() will create the shared memory segment, if it
+**   does not already exist, or open a connection that the existing
+**   shared memory segment if it already exists.
+**   
+**   PR_AttachSharedMemory() should be called following
+**   PR_OpenSharedMemory() to map the memory segment to an address in
+**   the application's address space.
+**   
+**   PR_AttachSharedMemory() may be called to re-map a shared memory
+**   segment after detaching the same PRSharedMemory object. Be
+**   sure to detach it when done.
+**   
+**   PR_DetachSharedMemory() should be called to un-map the shared
+**   memory segment from the application's address space.
+**   
+**   PR_CloseSharedMemory() should be called when no further use of the
+**   PRSharedMemory object is required within a process. Following a
+**   call to  PR_CloseSharedMemory() the PRSharedMemory object is
+**   invalid and cannot be reused.
+**   
+**   PR_DeleteSharedMemory() should be called before process
+**   termination. After calling PR_DeleteSharedMemory() any further use
+**   of the shared memory associated with the name may cause
+**   unpredictable results.
+**   
+** Files:
+**   The name passed to PR_OpenSharedMemory() should be a valid filename
+**   for a unix platform. PR_OpenSharedMemory() creates file using the
+**   name passed in. Some platforms may mangle the name before creating
+**   the file and the shared memory.
+**   
+**   The unix implementation may use SysV IPC shared memory, Posix
+**   shared memory, or memory mapped files; the filename may used to
+**   define the namespace. On Windows, the name is significant, but
+**   there is no file associated with name.
+**   
+**   No assumptions about the persistence of data in the named file
+**   should be made. Depending on platform, the shared memory may be
+**   mapped onto system paging space and be discarded at process
+**   termination.
+**   
+**   All names provided to PR_OpenSharedMemory() should be valid
+**   filename syntax or name syntax for shared memory for the target
+**   platform. Referenced directories should have permissions 
+**   appropriate for writing.
+**
+** Limits:
+**   Different platforms have limits on both the number and size of
+**   shared memory resources. The default system limits on some
+**   platforms may be smaller than your requirements. These limits may
+**   be adjusted on some platforms either via boot-time options or by
+**   setting the size of the system paging space to accomodate more
+**   and/or larger shared memory segment(s).
+**
+** Security:
+**   On unix platforms, depending on implementation, contents of the
+**   backing store for the shared memory can be exposed via the file
+**   system. Set permissions and or access controls at create and attach
+**   time to ensure you get the desired security.
+**
+**   On windows platforms, no special security measures are provided.
+**
+** Example:
+**   The test case pr/tests/nameshm1.c provides an example of use as
+**   well as testing the operation of NSPR's Named Shared Memory.
+**
+** lth. 18-Aug-1999.
+*/
+
+#ifndef prshm_h___
+#define prshm_h___
+
+#include "prtypes.h"
+#include "prio.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Declare opaque type PRSharedMemory.
+*/
+typedef struct PRSharedMemory PRSharedMemory;
+
+/*
+** FUNCTION: PR_OpenSharedMemory()
+**
+** DESCRIPTION:
+**   PR_OpenSharedMemory() creates a new shared-memory segment or
+**   associates a previously created memory segment with name.
+**
+**   When parameter create is (PR_SHM_EXCL | PR_SHM_CREATE) and the
+**   shared memory already exists, the function returns NULL with the
+**   error set to PR_FILE_EXISTS_ERROR.
+**
+**   When parameter create is PR_SHM_CREATE and the shared memory
+**   already exists, a handle to that memory segment is returned. If
+**   the segment does not exist, it is created and a pointer to the
+**   related PRSharedMemory structure is returned.
+**
+**   When parameter create is 0, and the shared memory exists, a
+**   pointer to a PRSharedMemory is returned. If the shared memory does
+**   not exist, NULL is returned with the error set to
+**   PR_FILE_NOT_FOUND_ERROR.
+**
+** INPUTS:
+**   name -- the name the shared-memory segment is known as.
+**   size -- the size of the shared memory segment. 
+**   flags -- Options for creating the shared memory
+**   mode -- Same as is passed to PR_Open()
+**
+** OUTPUTS: 
+**   The shared memory is allocated.
+**
+** RETURNS: Pointer to opaque structure PRSharedMemory or NULL.
+**   NULL is returned on error. The reason for the error can be
+**   retrieved via PR_GetError() and PR_GetOSError();
+**
+*/
+NSPR_API( PRSharedMemory * )
+    PR_OpenSharedMemory(
+        const char *name,
+        PRSize      size,
+        PRIntn      flags,
+        PRIntn      mode
+);
+/* Define values for PR_OpenShareMemory(...,create) */
+#define PR_SHM_CREATE 0x1  /* create if not exist */
+#define PR_SHM_EXCL   0x2  /* fail if already exists */
+
+/*
+** FUNCTION: PR_AttachSharedMemory()
+**
+** DESCRIPTION:
+** PR_AttachSharedMemory() maps the shared-memory described by
+** shm to the current process. 
+**
+** INPUTS: 
+**   shm -- The handle returned from PR_OpenSharedMemory().
+**   flags -- options for mapping the shared memory.
+**   PR_SHM_READONLY causes the memory to be attached 
+**   read-only.
+**
+** OUTPUTS:
+**   On success, the shared memory segment represented by shm is mapped
+**   into the process' address space.
+**
+** RETURNS: Address where shared memory is mapped, or NULL.
+**   NULL is returned on error. The reason for the error can be
+**   retrieved via PR_GetError() and PR_GetOSError();
+**
+**
+*/
+NSPR_API( void * )
+    PR_AttachSharedMemory(
+        PRSharedMemory *shm,
+        PRIntn  flags
+);
+/* Define values for PR_AttachSharedMemory(...,flags) */ 
+#define PR_SHM_READONLY 0x01
+
+/*
+** FUNCTION: PR_DetachSharedMemory()
+**
+** DESCRIPTION:
+**   PR_DetachSharedMemory() detaches the shared-memory described
+**   by shm. 
+**
+** INPUTS: 
+**   shm -- The handle returned from PR_OpenSharedMemory().
+**   addr -- The address at which the memory was attached.
+**
+** OUTPUTS:
+**   The shared memory mapped to an address via a previous call to
+**   PR_AttachSharedMemory() is unmapped.
+**
+** RETURNS: PRStatus
+**
+*/
+NSPR_API( PRStatus )
+    PR_DetachSharedMemory(
+        PRSharedMemory *shm,
+        void  *addr
+);
+
+/*
+** FUNCTION: PR_CloseSharedMemory()
+**
+** DESCRIPTION:
+**   PR_CloseSharedMemory() closes the shared-memory described by
+**   shm.
+** 
+** INPUTS:
+**   shm -- The handle returned from PR_OpenSharedMemory().
+**
+** OUTPUTS:
+**   the shared memory represented by shm is closed
+**
+** RETURNS: PRStatus
+**
+*/
+NSPR_API( PRStatus )
+    PR_CloseSharedMemory(
+        PRSharedMemory *shm
+);
+
+/*
+** FUNCTION: PR_DeleteSharedMemory()
+**
+** DESCRIPTION:
+**   The shared memory resource represented by name is released.
+**
+** INPUTS:
+**   name -- the name the shared-memory segment
+**
+** OUTPUTS:
+**   depending on platform, resources may be returned to the underlying
+**   operating system.
+**
+** RETURNS: PRStatus
+**
+*/
+NSPR_API( PRStatus )
+    PR_DeleteSharedMemory( 
+        const char *name
+);
+
+PR_END_EXTERN_C
+
+#endif /* prshm_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prshma.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prshma.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,271 @@
+/* -*- 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 ***** */
+
+/*
+** prshma.h -- NSPR Anonymous Shared Memory
+**
+** NSPR provides an anonymous shared memory based on NSPR's PRFileMap
+** type. The anonymous file-mapped shared memory provides an inheritable
+** shared memory, as in: the child process inherits the shared memory.
+** Compare the file-mapped anonymous shared memory to to a named shared
+** memory described in prshm.h. The intent is to provide a shared
+** memory that is accessable only by parent and child processes. ...
+** It's a security thing.
+** 
+** Depending on the underlying platform, the file-mapped shared memory
+** may be backed by a file. ... surprise! ... On some platforms, no
+** real file backs the shared memory. On platforms where the shared
+** memory is backed by a file, the file's name in the filesystem is
+** visible to other processes for only the duration of the creation of
+** the file, hopefully a very short time. This restricts processess
+** that do not inherit the shared memory from opening the file and
+** reading or writing its contents. Further, when all processes
+** using an anonymous shared memory terminate, the backing file is
+** deleted. ... If you are not paranoid, you're not paying attention.
+** 
+** The file-mapped shared memory requires a protocol for the parent
+** process and child process to share the memory. NSPR provides two
+** protocols. Use one or the other; don't mix and match.
+** 
+** In the first protocol, the job of passing the inheritable shared
+** memory is done via helper-functions with PR_CreateProcess(). In the
+** second protocol, the parent process is responsible for creating the
+** child process; the parent and child are mutually responsible for
+** passing a FileMap string. NSPR provides helper functions for
+** extracting data from the PRFileMap object. ... See the examples
+** below.
+** 
+** Both sides should adhere strictly to the protocol for proper
+** operation. The pseudo-code below shows the use of a file-mapped
+** shared memory by a parent and child processes. In the examples, the
+** server creates the file-mapped shared memory, the client attaches to
+** it.
+**
+** First protocol.
+** Server:
+**
+**   fm = PR_OpenAnonFileMap(dirName, size, FilemapProt); 
+**   addr = PR_MemMap(fm); 
+**   attr = PR_NewProcessAttr();
+**   PR_ProcessAttrSetInheritableFileMap( attr, fm, shmname );
+**   PR_CreateProcess(Client); 
+**   PR_DestroyProcessAttr(attr);
+**   ... yadda ...
+**   PR_MemUnmap( addr );
+**   PR_CloseFileMap(fm);
+**
+**
+** Client: 
+**   ... started by server via PR_CreateProcess()
+**   fm = PR_GetInheritedFileMap( shmname );
+**   addr = PR_MemMap(fm);
+**   ... yadda ...
+**   PR_MemUnmap(addr);
+**   PR_CloseFileMap(fm);
+**
+**
+** Second Protocol:
+** Server:
+**
+**   fm = PR_OpenAnonFileMap(dirName, size, FilemapProt); 
+**   fmstring = PR_ExportFileMapAsString( fm );
+**   addr = PR_MemMap(fm); 
+**    ... application specific technique to pass fmstring to child
+**    ... yadda ... Server uses his own magic to create child
+**   PR_MemUnmap( addr );
+**   PR_CloseFileMap(fm);
+**
+**
+** Client: 
+**   ... started by server via his own magic
+**   ... application specific technique to find fmstring from parent
+**   fm = PR_ImportFileMapFromString( fmstring )
+**   addr = PR_MemMap(fm);
+**   ... yadda ...
+**   PR_MemUnmap(addr);
+**   PR_CloseFileMap(fm);
+**
+**
+** lth. 2-Jul-1999.
+**
+** Note: The second protocol was requested by NelsonB (7/1999); this is
+** to accomodate servers which already create their own child processes
+** using platform native methods.
+** 
+*/
+
+#ifndef prshma_h___
+#define prshma_h___
+
+#include "prtypes.h"
+#include "prio.h"
+#include "prproces.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** PR_OpenAnonFileMap() -- Creates an anonymous file-mapped shared memory
+**
+** Description:
+** PR_OpenAnonFileMap() creates an anonymous shared memory. If the
+** shared memory already exists, a handle is returned to that shared
+** memory object.
+**
+** On Unix platforms, PR_OpenAnonFileMap() uses 'dirName' as a
+** directory name, without the trailing '/', to contain the anonymous
+** file. A filename is generated for the name.
+**
+** On Windows platforms, dirName is ignored.
+**
+** Inputs:
+**   dirName -- A directory name to contain the anonymous file.
+**   size -- The size of the shared memory
+**   prot -- How the shared memory is mapped. See prio.h
+**   
+** Outputs:
+**   PRFileMap *
+**
+** Returns:
+**   Pointer to PRFileMap or NULL on error.
+**
+*/
+NSPR_API( PRFileMap *)
+PR_OpenAnonFileMap(
+    const char *dirName,
+    PRSize      size, 
+    PRFileMapProtect prot
+);  
+
+/*
+** PR_ProcessAttrSetInheritableFileMap() -- Prepare FileMap for export  
+**   to my children processes via PR_CreateProcess()
+**
+** Description:
+** PR_ProcessAttrSetInheritableFileMap() connects the PRFileMap to
+** PRProcessAttr with shmname. A subsequent call to PR_CreateProcess()
+** makes the PRFileMap importable by the child process.
+**
+** Inputs:
+**   attr -- PRProcessAttr, used to pass data to PR_CreateProcess()
+**   fm -- PRFileMap structure to be passed to the child process
+**   shmname -- The name for the PRFileMap; used by child.
+**
+** Outputs:
+**   PRFileMap *
+**
+** Returns:
+**   PRStatus
+**
+*/
+NSPR_API(PRStatus) 
+PR_ProcessAttrSetInheritableFileMap( 
+    PRProcessAttr   *attr,
+    PRFileMap       *fm, 
+    const char      *shmname
+);
+
+/*
+** PR_GetInheritedFileMap() -- Import a PRFileMap previously exported
+**   by my parent process via PR_CreateProcess()
+**
+** Description:
+** PR_GetInheritedFileMap() retrieves a PRFileMap object exported from
+** its parent process via PR_CreateProcess().
+**
+** Inputs:
+**    shmname -- The name provided to PR_ProcessAttrSetInheritableFileMap()
+** 
+** Outputs:
+**   PRFileMap *
+**
+** Returns:
+**   PRFileMap pointer or NULL.
+**
+*/
+NSPR_API( PRFileMap *)
+PR_GetInheritedFileMap( 
+    const char *shmname 
+);
+
+/*
+** PR_ExportFileMapAsString() -- Creates a string identifying a PRFileMap
+**
+** Description:
+** Creates an identifier, as a string, from a PRFileMap object
+** previously created with PR_OpenAnonFileMap().
+**
+** Inputs:
+**   fm -- PRFileMap pointer to be represented as a string.
+**   bufsize -- sizeof(buf)
+**   buf -- a buffer of length PR_FILEMAP_STRING_BUFSIZE
+**
+** Outputs:
+**   buf contains the stringized PRFileMap identifier
+**
+** Returns:
+**   PRStatus
+**
+*/
+NSPR_API( PRStatus )
+PR_ExportFileMapAsString( 
+    PRFileMap *fm,
+    PRSize    bufsize,
+    char      *buf
+);
+#define PR_FILEMAP_STRING_BUFSIZE 128
+
+/*
+** PR_ImportFileMapFromString() -- Creates a PRFileMap from the identifying string
+**
+** Description:
+** PR_ImportFileMapFromString() creates a PRFileMap object from a
+** string previously created by PR_ExportFileMapAsString().
+**
+** Inputs:
+**   fmstring -- string created by PR_ExportFileMapAsString()
+**
+** Returns:
+**   PRFileMap pointer or NULL.
+**
+*/
+NSPR_API( PRFileMap * )
+PR_ImportFileMapFromString( 
+    const char *fmstring
+);
+
+PR_END_EXTERN_C
+#endif /* prshma_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prsystem.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prsystem.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,140 @@
+/* -*- 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 prsystem_h___
+#define prsystem_h___
+
+/*
+** API to NSPR functions returning system info.
+*/
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Get the host' directory separator.
+**  Pathnames are then assumed to be of the form:
+**      [<sep><root_component><sep>]*(<component><sep>)<leaf_name>
+*/
+
+NSPR_API(char) PR_GetDirectorySeparator(void);
+
+/*
+** OBSOLETE -- the function name is misspelled.
+** Use PR_GetDirectorySeparator instead.
+*/
+
+NSPR_API(char) PR_GetDirectorySepartor(void);
+
+/*
+** Get the host' path separator.
+**  Paths are assumed to be of the form:
+**      <directory>[<sep><directory>]*
+*/
+
+NSPR_API(char) PR_GetPathSeparator(void);
+
+/* Types of information available via PR_GetSystemInfo(...) */
+typedef enum {
+    PR_SI_HOSTNAME,  /* the hostname with the domain name (if any)
+                      * removed */
+    PR_SI_SYSNAME,
+    PR_SI_RELEASE,
+    PR_SI_ARCHITECTURE,
+    PR_SI_HOSTNAME_UNTRUNCATED  /* the hostname exactly as configured
+                                 * on the system */
+} PRSysInfo;
+
+
+/*
+** If successful returns a null termintated string in 'buf' for
+** the information indicated in 'cmd'. If unseccussful the reason for
+** the failure can be retrieved from PR_GetError().
+**
+** The buffer is allocated by the caller and should be at least
+** SYS_INFO_BUFFER_LENGTH bytes in length.
+*/
+
+#define SYS_INFO_BUFFER_LENGTH 256
+
+NSPR_API(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen);
+
+/*
+** Return the number of bytes in a page
+*/
+NSPR_API(PRInt32) PR_GetPageSize(void);
+
+/*
+** Return log2 of the size of a page
+*/
+NSPR_API(PRInt32) PR_GetPageShift(void);
+
+/*
+** PR_GetNumberOfProcessors() -- returns the number of CPUs
+**
+** Description:
+** PR_GetNumberOfProcessors() extracts the number of processors
+** (CPUs available in an SMP system) and returns the number.
+** 
+** Parameters:
+**   none
+**
+** Returns:
+**   The number of available processors or -1 on error
+** 
+*/
+NSPR_API(PRInt32) PR_GetNumberOfProcessors( void );
+
+/*
+** PR_GetPhysicalMemorySize() -- returns the amount of system RAM
+**
+** Description:
+** PR_GetPhysicalMemorySize() determines the amount of physical RAM
+** in the system and returns the size in bytes.
+**
+** Parameters:
+**   none
+**
+** Returns:
+**   The amount of system RAM, or 0 on failure.
+**
+*/
+NSPR_API(PRUint64) PR_GetPhysicalMemorySize(void);
+
+PR_END_EXTERN_C
+
+#endif /* prsystem_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prthread.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prthread.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,286 @@
+/* -*- 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 prthread_h___
+#define prthread_h___
+
+/*
+** API for NSPR threads. On some architectures (MAC and WIN16
+** notably) pre-emptibility is not guaranteed. Hard priority scheduling
+** is not guaranteed, so programming using priority based synchronization
+** is a no-no.
+**
+** NSPR threads are scheduled based loosely on their client set priority.
+** In general, a thread of a higher priority has a statistically better
+** chance of running relative to threads of lower priority. However,
+** NSPR uses multiple strategies to provide execution vehicles for thread
+** abstraction of various host platforms. As it turns out, there is little
+** NSPR can do to affect the scheduling attributes of "GLOBAL" threads.
+** However, a semblance of GLOBAL threads is used to implement "LOCAL"
+** threads. An arbitrary number of such LOCAL threads can be assigned to
+** a single GLOBAL thread.
+**
+** For scheduling, NSPR will attempt to run the highest priority LOCAL
+** thread associated with a given GLOBAL thread. It is further assumed
+** that the host OS will apply some form of "fair" scheduling on the
+** GLOBAL threads.
+**
+** Threads have a "system flag" which when set indicates the thread
+** doesn't count for determining when the process should exit (the
+** process exits when the last user thread exits).
+**
+** Threads also have a "scope flag" which controls whether the threads
+** are scheduled in the local scope or scheduled by the OS globally. This 
+** indicates whether a thread is permanently bound to a native OS thread. 
+** An unbound thread competes for scheduling resources in the same process.
+**
+** Another flag is "state flag" which control whether the thread is joinable.
+** It allows other threads to wait for the created thread to reach completion.
+**
+** Threads can have "per-thread-data" attached to them. Each thread has a
+** per-thread error number and error string which are updated when NSPR
+** operations fail.
+*/
+#include "prtypes.h"
+#include "prinrval.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PRThread PRThread;
+typedef struct PRThreadStack PRThreadStack;
+
+typedef enum PRThreadType {
+    PR_USER_THREAD,
+    PR_SYSTEM_THREAD
+} PRThreadType;
+
+typedef enum PRThreadScope {
+    PR_LOCAL_THREAD,
+    PR_GLOBAL_THREAD,
+    PR_GLOBAL_BOUND_THREAD
+} PRThreadScope;
+
+typedef enum PRThreadState {
+    PR_JOINABLE_THREAD,
+    PR_UNJOINABLE_THREAD
+} PRThreadState;
+
+typedef enum PRThreadPriority
+{
+    PR_PRIORITY_FIRST = 0,      /* just a placeholder */
+    PR_PRIORITY_LOW = 0,        /* the lowest possible priority */
+    PR_PRIORITY_NORMAL = 1,     /* most common expected priority */
+    PR_PRIORITY_HIGH = 2,       /* slightly more aggressive scheduling */
+    PR_PRIORITY_URGENT = 3,     /* it does little good to have more than one */
+    PR_PRIORITY_LAST = 3        /* this is just a placeholder */
+} PRThreadPriority;
+
+/*
+** Create a new thread:
+**     "type" is the type of thread to create
+**     "start(arg)" will be invoked as the threads "main"
+**     "priority" will be created thread's priority
+**     "scope" will specify whether the thread is local or global
+**     "state" will specify whether the thread is joinable or not
+**     "stackSize" the size of the stack, in bytes. The value can be zero
+**        and then a machine specific stack size will be chosen.
+**
+** This can return NULL if some kind of error occurs, such as if memory is
+** tight.
+**
+** If you want the thread to start up waiting for the creator to do
+** something, enter a lock before creating the thread and then have the
+** threads start routine enter and exit the same lock. When you are ready
+** for the thread to run, exit the lock.
+**
+** If you want to detect the completion of the created thread, the thread
+** should be created joinable.  Then, use PR_JoinThread to synchrnoize the
+** termination of another thread.
+**
+** When the start function returns the thread exits. If it is the last
+** PR_USER_THREAD to exit then the process exits.
+*/
+NSPR_API(PRThread*) PR_CreateThread(PRThreadType type,
+                     void (PR_CALLBACK *start)(void *arg),
+                     void *arg,
+                     PRThreadPriority priority,
+                     PRThreadScope scope,
+                     PRThreadState state,
+                     PRUint32 stackSize);
+
+/*
+** Wait for thread termination:
+**     "thread" is the target thread 
+**
+** This can return PR_FAILURE if no joinable thread could be found 
+** corresponding to the specified target thread.
+**
+** The calling thread is blocked until the target thread completes.
+** Several threads cannot wait for the same thread to complete; one thread
+** will operate successfully and others will terminate with an error PR_FAILURE.
+** The calling thread will not be blocked if the target thread has already
+** terminated.
+*/
+NSPR_API(PRStatus) PR_JoinThread(PRThread *thread);
+
+/*
+** Return the current thread object for the currently running code.
+** Never returns NULL.
+*/
+NSPR_API(PRThread*) PR_GetCurrentThread(void);
+#ifndef NO_NSPR_10_SUPPORT
+#define PR_CurrentThread() PR_GetCurrentThread() /* for nspr1.0 compat. */
+#endif /* NO_NSPR_10_SUPPORT */
+
+/*
+** Get the priority of "thread".
+*/
+NSPR_API(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread);
+
+/*
+** Change the priority of the "thread" to "priority".
+*/
+NSPR_API(void) PR_SetThreadPriority(PRThread *thread, PRThreadPriority priority);
+
+/*
+** This routine returns a new index for per-thread-private data table. 
+** The index is visible to all threads within a process. This index can 
+** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines 
+** to save and retrieve data associated with the index for a thread.
+**
+** Each index is associationed with a destructor function ('dtor'). The function
+** may be specified as NULL when the index is created. If it is not NULL, the
+** function will be called when:
+**      - the thread exits and the private data for the associated index
+**        is not NULL,
+**      - new thread private data is set and the current private data is
+**        not NULL.
+**
+** The index independently maintains specific values for each binding thread. 
+** A thread can only get access to its own thread-specific-data.
+**
+** Upon a new index return the value associated with the index for all threads
+** is NULL, and upon thread creation the value associated with all indices for 
+** that thread is NULL. 
+**
+** Returns PR_FAILURE if the total number of indices will exceed the maximun 
+** allowed.
+*/
+typedef void (PR_CALLBACK *PRThreadPrivateDTOR)(void *priv);
+
+NSPR_API(PRStatus) PR_NewThreadPrivateIndex(
+    PRUintn *newIndex, PRThreadPrivateDTOR destructor);
+
+/*
+** Define some per-thread-private data.
+**     "tpdIndex" is an index into the per-thread private data table
+**     "priv" is the per-thread-private data 
+**
+** If the per-thread private data table has a previously registered
+** destructor function and a non-NULL per-thread-private data value,
+** the destructor function is invoked.
+**
+** This can return PR_FAILURE if the index is invalid.
+*/
+NSPR_API(PRStatus) PR_SetThreadPrivate(PRUintn tpdIndex, void *priv);
+
+/*
+** Recover the per-thread-private data for the current thread. "tpdIndex" is
+** the index into the per-thread private data table. 
+**
+** The returned value may be NULL which is indistinguishable from an error 
+** condition.
+**
+** A thread can only get access to its own thread-specific-data.
+*/
+NSPR_API(void*) PR_GetThreadPrivate(PRUintn tpdIndex);
+
+/*
+** This routine sets the interrupt request for a target thread. The interrupt
+** request remains in the thread's state until it is delivered exactly once
+** or explicitly canceled.
+**
+** A thread that has been interrupted will fail all NSPR blocking operations
+** that return a PRStatus (I/O, waiting on a condition, etc).
+**
+** PR_Interrupt may itself fail if the target thread is invalid.
+*/
+NSPR_API(PRStatus) PR_Interrupt(PRThread *thread);
+
+/*
+** Clear the interrupt request for the calling thread. If no such request
+** is pending, this operation is a noop.
+*/
+NSPR_API(void) PR_ClearInterrupt(void);
+
+/*
+** Block the interrupt for the calling thread.
+*/
+NSPR_API(void) PR_BlockInterrupt(void);
+
+/*
+** Unblock the interrupt for the calling thread.
+*/
+NSPR_API(void) PR_UnblockInterrupt(void);
+
+/*
+** Make the current thread sleep until "ticks" time amount of time
+** has expired. If "ticks" is PR_INTERVAL_NO_WAIT then the call is
+** equivalent to calling PR_Yield. Calling PR_Sleep with an argument
+** equivalent to PR_INTERVAL_NO_TIMEOUT is an error and will result
+** in a PR_FAILURE error return.
+*/
+NSPR_API(PRStatus) PR_Sleep(PRIntervalTime ticks);
+
+/*
+** Get the scoping of this thread.
+*/
+NSPR_API(PRThreadScope) PR_GetThreadScope(const PRThread *thread);
+
+/*
+** Get the type of this thread.
+*/
+NSPR_API(PRThreadType) PR_GetThreadType(const PRThread *thread);
+
+/*
+** Get the join state of this thread.
+*/
+NSPR_API(PRThreadState) PR_GetThreadState(const PRThread *thread);
+
+PR_END_EXTERN_C
+
+#endif /* prthread_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prtime.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prtime.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,298 @@
+/* -*- 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 ***** */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * prtime.h --
+ *
+ *     NSPR date and time functions
+ *
+ *-----------------------------------------------------------------------
+ */
+
+#ifndef prtime_h___
+#define prtime_h___
+
+#include "prlong.h"
+
+PR_BEGIN_EXTERN_C
+
+/**********************************************************************/
+/************************* TYPES AND CONSTANTS ************************/
+/**********************************************************************/
+
+#define PR_MSEC_PER_SEC		1000UL
+#define PR_USEC_PER_SEC		1000000UL
+#define PR_NSEC_PER_SEC		1000000000UL
+#define PR_USEC_PER_MSEC	1000UL
+#define PR_NSEC_PER_MSEC	1000000UL
+
+/*
+ * PRTime --
+ *
+ *     NSPR represents basic time as 64-bit signed integers relative
+ *     to midnight (00:00:00), January 1, 1970 Greenwich Mean Time (GMT).
+ *     (GMT is also known as Coordinated Universal Time, UTC.)
+ *     The units of time are in microseconds. Negative times are allowed
+ *     to represent times prior to the January 1970 epoch. Such values are
+ *     intended to be exported to other systems or converted to human
+ *     readable form.
+ *
+ *     Notes on porting: PRTime corresponds to time_t in ANSI C.  NSPR 1.0
+ *     simply uses PRInt64.
+ */
+
+typedef PRInt64 PRTime;
+
+/*
+ * Time zone and daylight saving time corrections applied to GMT to
+ * obtain the local time of some geographic location
+ */
+
+typedef struct PRTimeParameters {
+    PRInt32 tp_gmt_offset;     /* the offset from GMT in seconds */
+    PRInt32 tp_dst_offset;     /* contribution of DST in seconds */
+} PRTimeParameters;
+
+/*
+ * PRExplodedTime --
+ *
+ *     Time broken down into human-readable components such as year, month,
+ *     day, hour, minute, second, and microsecond.  Time zone and daylight
+ *     saving time corrections may be applied.  If they are applied, the
+ *     offsets from the GMT must be saved in the 'tm_params' field so that
+ *     all the information is available to reconstruct GMT.
+ *
+ *     Notes on porting: PRExplodedTime corrresponds to struct tm in
+ *     ANSI C, with the following differences:
+ *       - an additional field tm_usec;
+ *       - replacing tm_isdst by tm_params;
+ *       - the month field is spelled tm_month, not tm_mon;
+ *       - we use absolute year, AD, not the year since 1900.
+ *     The corresponding type in NSPR 1.0 is called PRTime.  Below is
+ *     a table of date/time type correspondence in the three APIs:
+ *         API          time since epoch          time in components
+ *       ANSI C             time_t                  struct tm
+ *       NSPR 1.0           PRInt64                   PRTime
+ *       NSPR 2.0           PRTime                  PRExplodedTime
+ */
+
+typedef struct PRExplodedTime {
+    PRInt32 tm_usec;		    /* microseconds past tm_sec (0-99999)  */
+    PRInt32 tm_sec;             /* seconds past tm_min (0-61, accomodating
+                                   up to two leap seconds) */	
+    PRInt32 tm_min;             /* minutes past tm_hour (0-59) */
+    PRInt32 tm_hour;            /* hours past tm_day (0-23) */
+    PRInt32 tm_mday;            /* days past tm_mon (1-31, note that it
+				                starts from 1) */
+    PRInt32 tm_month;           /* months past tm_year (0-11, Jan = 0) */
+    PRInt16 tm_year;            /* absolute year, AD (note that we do not
+				                count from 1900) */
+
+    PRInt8 tm_wday;		        /* calculated day of the week
+				                (0-6, Sun = 0) */
+    PRInt16 tm_yday;            /* calculated day of the year 
+				                (0-365, Jan 1 = 0) */
+
+    PRTimeParameters tm_params;  /* time parameters used by conversion */
+} PRExplodedTime;
+
+/*
+ * PRTimeParamFn --
+ *
+ *     A function of PRTimeParamFn type returns the time zone and
+ *     daylight saving time corrections for some geographic location,
+ *     given the current time in GMT.  The input argument gmt should
+ *     point to a PRExplodedTime that is in GMT, i.e., whose
+ *     tm_params contains all 0's.
+ *
+ *     For any time zone other than GMT, the computation is intended to
+ *     consist of two steps:
+ *       - Figure out the time zone correction, tp_gmt_offset.  This number
+ *         usually depends on the geographic location only.  But it may
+ *         also depend on the current time.  For example, all of China
+ *         is one time zone right now.  But this situation may change
+ *         in the future.
+ *       - Figure out the daylight saving time correction, tp_dst_offset.
+ *         This number depends on both the geographic location and the
+ *         current time.  Most of the DST rules are expressed in local
+ *         current time.  If so, one should apply the time zone correction
+ *         to GMT before applying the DST rules.
+ */
+
+typedef PRTimeParameters (PR_CALLBACK *PRTimeParamFn)(const PRExplodedTime *gmt);
+
+/**********************************************************************/
+/****************************** FUNCTIONS *****************************/
+/**********************************************************************/
+
+/*
+ * The PR_Now routine returns the current time relative to the
+ * epoch, midnight, January 1, 1970 UTC. The units of the returned
+ * value are microseconds since the epoch.
+ *
+ * The values returned are not guaranteed to advance in a linear fashion
+ * due to the application of time correction protocols which synchronize
+ * computer clocks to some external time source. Consequently it should
+ * not be depended on for interval timing.
+ *
+ * The implementation is machine dependent.
+ * Cf. time_t time(time_t *tp) in ANSI C.
+ */
+#if defined(HAVE_WATCOM_BUG_2)
+PRTime __pascal __export __loadds
+#else
+NSPR_API(PRTime) 
+#endif
+PR_Now(void);
+
+/*
+ * Expand time binding it to time parameters provided by PRTimeParamFn.
+ * The calculation is envisoned to proceed in the following steps:
+ *   - From given PRTime, calculate PRExplodedTime in GMT
+ *   - Apply the given PRTimeParamFn to the GMT that we just calculated
+ *     to obtain PRTimeParameters.
+ *   - Add the PRTimeParameters offsets to GMT to get the local time
+ *     as PRExplodedTime.
+ */
+
+NSPR_API(void) PR_ExplodeTime(
+    PRTime usecs, PRTimeParamFn params, PRExplodedTime *exploded);
+
+/* Reverse operation of PR_ExplodeTime */
+#if defined(HAVE_WATCOM_BUG_2)
+PRTime __pascal __export __loadds
+#else
+NSPR_API(PRTime) 
+#endif
+PR_ImplodeTime(const PRExplodedTime *exploded);
+
+/*
+ * Adjust exploded time to normalize field overflows after manipulation.
+ * Note that the following fields of PRExplodedTime should not be
+ * manipulated:
+ *   - tm_month and tm_year: because the number of days in a month and
+ *     number of days in a year are not constant, it is ambiguous to
+ *     manipulate the month and year fields, although one may be tempted
+ *     to.  For example, what does "a month from January 31st" mean?
+ *   - tm_wday and tm_yday: these fields are calculated by NSPR.  Users
+ *     should treat them as "read-only".
+ */
+
+NSPR_API(void) PR_NormalizeTime(
+    PRExplodedTime *exploded, PRTimeParamFn params);
+
+/**********************************************************************/
+/*********************** TIME PARAMETER FUNCTIONS *********************/
+/**********************************************************************/
+
+/* Time parameters that suit current host machine */
+NSPR_API(PRTimeParameters) PR_LocalTimeParameters(const PRExplodedTime *gmt);
+
+/* Time parameters that represent Greenwich Mean Time */
+NSPR_API(PRTimeParameters) PR_GMTParameters(const PRExplodedTime *gmt);
+
+/*
+ * Time parameters that represent the US Pacific Time Zone, with the
+ * current daylight saving time rules (for testing only)
+ */
+NSPR_API(PRTimeParameters) PR_USPacificTimeParameters(const PRExplodedTime *gmt);
+
+/*
+ * This parses a time/date string into a PRTime
+ * (microseconds after "1-Jan-1970 00:00:00 GMT").
+ * It returns PR_SUCCESS on success, and PR_FAILURE
+ * if the time/date string can't be parsed.
+ *
+ * Many formats are handled, including:
+ *
+ *   14 Apr 89 03:20:12
+ *   14 Apr 89 03:20 GMT
+ *   Fri, 17 Mar 89 4:01:33
+ *   Fri, 17 Mar 89 4:01 GMT
+ *   Mon Jan 16 16:12 PDT 1989
+ *   Mon Jan 16 16:12 +0130 1989
+ *   6 May 1992 16:41-JST (Wednesday)
+ *   22-AUG-1993 10:59:12.82
+ *   22-AUG-1993 10:59pm
+ *   22-AUG-1993 12:59am
+ *   22-AUG-1993 12:59 PM
+ *   Friday, August 04, 1995 3:54 PM
+ *   06/21/95 04:24:34 PM
+ *   20/06/95 21:07
+ *   95-06-08 19:32:48 EDT
+ *
+ * If the input string doesn't contain a description of the timezone,
+ * we consult the `default_to_gmt' to decide whether the string should
+ * be interpreted relative to the local time zone (PR_FALSE) or GMT (PR_TRUE).
+ * The correct value for this argument depends on what standard specified
+ * the time string which you are parsing.
+ */
+
+NSPR_API(PRStatus) PR_ParseTimeString (
+	const char *string,
+	PRBool default_to_gmt,
+	PRTime *result);
+
+/*
+ * FIXME: should we also have a formatting function, such as asctime, ctime,
+ * and strftime in standard C library?  But this would involve
+ * internationalization issues.  Might want to provide a US English version.
+ */
+
+/**********************************************************************/
+/*********************** OLD COMPATIBILITYFUNCTIONS *******************/
+/**********************************************************************/
+#ifndef NO_NSPR_10_SUPPORT
+
+/* Format a time value into a buffer. Same semantics as strftime() */
+NSPR_API(PRUint32) PR_FormatTime(char *buf, int buflen, const char *fmt, 
+                                           const PRExplodedTime *tm);
+
+/* Format a time value into a buffer. Time is always in US English format, regardless
+ * of locale setting.
+ */
+NSPR_API(PRUint32)
+PR_FormatTimeUSEnglish( char* buf, PRUint32 bufSize,
+                        const char* format, const PRExplodedTime* tm );
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+PR_END_EXTERN_C
+
+#endif /* prtime_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prtpool.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prtpool.h	Mon Dec 18 10:53:47 2006
@@ -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) 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 ***** */
+
+#ifndef prtpool_h___
+#define prtpool_h___
+
+#include "prtypes.h"
+#include "prthread.h"
+#include "prio.h"
+#include "prerror.h"
+
+/*
+ * NOTE:
+ *		THIS API IS A PRELIMINARY VERSION IN NSPR 4.0 AND IS SUBJECT TO
+ *		CHANGE
+ */
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PRJobIoDesc {
+    PRFileDesc *socket;
+    PRErrorCode error;
+    PRIntervalTime timeout;
+} PRJobIoDesc;
+
+typedef struct PRThreadPool PRThreadPool;
+typedef struct PRJob PRJob;
+typedef void (PR_CALLBACK *PRJobFn) (void *arg);
+
+/* Create thread pool */
+NSPR_API(PRThreadPool *)
+PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads,
+                          PRUint32 stacksize);
+
+/* queue a job */
+NSPR_API(PRJob *)
+PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable);
+
+/* queue a job, when a socket is readable */
+NSPR_API(PRJob *)
+PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod,
+							PRJobFn fn, void * arg, PRBool joinable);
+
+/* queue a job, when a socket is writeable */
+NSPR_API(PRJob *)
+PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod,
+								PRJobFn fn, void * arg, PRBool joinable);
+
+/* queue a job, when a socket has a pending connection */
+NSPR_API(PRJob *)
+PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod,
+									PRJobFn fn, void * arg, PRBool joinable);
+
+/* queue a job, when the socket connection to addr succeeds or fails */
+NSPR_API(PRJob *)
+PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod,
+			const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable);
+
+/* queue a job, when a timer exipres */
+NSPR_API(PRJob *)
+PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout,
+								PRJobFn fn, void * arg, PRBool joinable);
+/* cancel a job */
+NSPR_API(PRStatus)
+PR_CancelJob(PRJob *job);
+
+/* join a job */
+NSPR_API(PRStatus)
+PR_JoinJob(PRJob *job);
+
+/* shutdown pool */
+NSPR_API(PRStatus)
+PR_ShutdownThreadPool(PRThreadPool *tpool);
+
+/* join pool, wait for exit of all threads */
+NSPR_API(PRStatus)
+PR_JoinThreadPool(PRThreadPool *tpool);
+
+PR_END_EXTERN_C
+
+#endif /* prtpool_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prtrace.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prtrace.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,678 @@
+/* -*- 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 prtrace_h___
+#define prtrace_h___
+/*
+** prtrace.h -- NSPR's Trace Facility.  		           
+**                                                               		           
+** The Trace Facility provides a means to trace application				           
+** program events within a process. When implementing an         		           
+** application program an engineer may insert a "Trace" function 		           
+** call, passing arguments to be traced. The "Trace" function     		           
+** combines the user trace data with identifying data and        		           
+** writes this data in time ordered sequence into a circular     		           
+** in-memory buffer; when the buffer fills, it wraps.
+**                                                               		           
+** Functions are provided to set and/or re-configure the size of		           
+** the trace buffer, control what events are recorded in the			           
+** buffer, enable and disable tracing based on specific user			           
+** supplied data and other control functions. Methods are provided		           
+** to record the trace entries in the in-memory trace buffer to
+** a file.
+**                                                               		           
+** Tracing may cause a performance degredation to the application		           
+** depending on the number and placement of calls to the tracing		           
+** facility. When tracing is compiled in and all tracing is				           
+** disabled via the runtime controls, the overhead should be			           
+** minimal. ... Famous last words, eh?									           
+** 																                   
+** When DEBUG is defined at compile time, the Trace Facility is                    
+** compiled as part of NSPR and any application using NSPR's                       
+** header files will have tracing compiled in. When DEBUG is not                   
+** defined, the Trace Facility is not compiled into NSPR nor                       
+** exported in its header files.  If the Trace Facility is                         
+** desired in a non-debug build, then FORCE_NSPR_TRACE may be                      
+** defined at compile time for both the optimized build of NSPR                    
+** and the application. NSPR and any application using  NSPR's                     
+** Trace Facility must be compiled with the same level of trace                    
+** conditioning or unresolved references may be realized at link                   
+** time.                                                                           
+**                                                                                 
+** For any of the Trace Facility methods that requires a trace                     
+** handle as an input argument, the caller must ensure that the                    
+** trace handle argument is valid. An invalid trace handle                         
+** argument may cause unpredictable results.                                       
+**                                                                                 
+** Trace Facility methods are thread-safe and SMP safe.                            
+**                                                                                 
+** Users of the Trace Facility should use the defined macros to                     
+** invoke trace methods, not the function calls directly. e.g.                      
+** PR_TRACE( h1,0,1,2, ...); not PR_Trace(h1,0,1,2, ...);
+**                                                                                  
+** Application designers should be aware of the effects of
+** debug and optimized build differences when using result of the
+** Trace Facility macros in expressions.
+** 
+** See Also: prcountr.h                                                                                 
+**                                                                                  
+** /lth. 08-Jun-1998.                                                                                  
+*/
+
+#include "prtypes.h"
+#include "prthread.h"
+#include "prtime.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+** Opaque type for the trace handle 
+** ... Don't even think about looking in here.
+**
+*/
+typedef void *  PRTraceHandle;
+
+/*
+** PRTraceEntry -- A trace entry in the in-memory trace buffer
+** looks like this.
+**
+*/
+typedef struct PRTraceEntry
+{
+    PRThread        *thread;        /* The thread creating the trace entry */
+    PRTraceHandle   handle;         /* PRTraceHandle creating the trace entry */
+    PRTime          time;           /* Value of PR_Now() at time of trace entry */
+    PRUint32        userData[8];    /* user supplied trace data */
+} PRTraceEntry;
+
+/*
+** PRTraceOption -- command operands to
+** PR_[Set|Get]TraceOption(). See descriptive meanings there.
+**
+*/
+typedef enum PRTraceOption
+{
+    PRTraceBufSize,
+    PRTraceEnable,              
+    PRTraceDisable,
+    PRTraceSuspend,
+    PRTraceResume,
+    PRTraceSuspendRecording,
+    PRTraceResumeRecording,
+    PRTraceLockHandles,
+    PRTraceUnLockHandles,
+    PRTraceStopRecording
+} PRTraceOption;
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DEFINE_TRACE() -- Define a PRTraceHandle
+** 
+** DESCRIPTION: PR_DEFINE_TRACE() is used to define a trace
+** handle.
+** 
+*/
+#define PR_DEFINE_TRACE(name) PRTraceHandle name
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_INIT_TRACE_HANDLE() -- Set the value of a PRTraceHandle
+** 
+** DESCRIPTION: 
+** PR_INIT_TRACE_HANDLE() sets the value of a PRTraceHandle
+** to value. e.g. PR_INIT_TRACE_HANDLE( myHandle, NULL );
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_INIT_TRACE_HANDLE(handle,value)\
+    (handle) = (PRCounterHandle)(value)
+#else
+#define PR_INIT_TRACE_HANDLE(handle,value)
+#endif
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_CreateTrace() -- Create a trace handle
+** 
+** DESCRIPTION:
+**  PR_CreateTrace() creates a new trace handle. Tracing is
+**  enabled for this handle when it is created. The trace handle
+**  is intended for use in other Trace Facility calls.
+**  
+**  PR_CreateTrace() registers the QName, RName and description
+**  data so that this data can be retrieved later.
+** 
+** INPUTS: 
+**  qName: pointer to string. QName for this trace handle. 
+** 
+**  rName: pointer to string. RName for this trace handle. 
+** 
+**  description: pointer to string. Descriptive data about this
+**  trace handle.
+**
+** OUTPUTS:
+**  Creates the trace handle. 
+**  Registers the QName and RName with the trace facility.
+** 
+** RETURNS: 
+**  PRTraceHandle
+** 
+** RESTRICTIONS:
+**  qName is limited to 31 characters.
+**  rName is limited to 31 characters.
+**  description is limited to 255 characters.
+** 
+*/
+#define PRTRACE_NAME_MAX 31
+#define PRTRACE_DESC_MAX 255
+
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_CREATE_TRACE(handle,qName,rName,description)\
+    (handle) = PR_CreateTrace((qName),(rName),(description))
+#else
+#define PR_CREATE_TRACE(handle,qName,rName,description)
+#endif
+
+NSPR_API(PRTraceHandle)
+	PR_CreateTrace( 
+    	const char *qName,          /* QName for this trace handle */
+	    const char *rName,          /* RName for this trace handle */
+	    const char *description     /* description for this trace handle */
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_DestroyTrace() -- Destroy a trace handle
+** 
+** DESCRIPTION: 
+**  PR_DestroyTrace() removes the referenced trace handle and
+** associated QName, RName and description data from the Trace
+** Facility.
+** 
+** INPUTS: handle. A PRTraceHandle
+** 
+** OUTPUTS: 
+**  The trace handle is unregistered.
+**  The QName, RName and description are removed.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_DESTROY_TRACE(handle)\
+    PR_DestroyTrace((handle))
+#else
+#define PR_DESTROY_TRACE(handle)
+#endif
+
+NSPR_API(void) 
+	PR_DestroyTrace( 
+		PRTraceHandle handle    /* Handle to be destroyed */
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_Trace() -- Make a trace entry in the in-memory trace
+** 
+** DESCRIPTION:
+** PR_Trace() makes an entry in the in-memory trace buffer for
+** the referenced trace handle. The next logically available
+** PRTraceEntry is used; when the next trace entry would overflow
+** the trace table, the table wraps.
+**
+** PR_Trace() for a specific trace handle may be disabled by
+** calling PR_SetTraceOption() specifying PRTraceDisable for the
+** trace handle to be disabled.
+** 
+** INPUTS:
+** handle: PRTraceHandle. The trace handle for this trace.
+** 
+** userData[0..7]: unsigned 32bit integers. user supplied data
+** that is copied into the PRTraceEntry
+** 
+** OUTPUTS:
+**  A PRTraceEntry is (conditionally) formatted in the in-memory
+** trace buffer.
+** 
+** RETURNS: void.
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_TRACE(handle,ud0,ud1,ud2,ud3,ud4,ud5,ud6,ud7)\
+    PR_Trace((handle),(ud0),(ud1),(ud2),(ud3),(ud4),(ud5),(ud6),(ud7))
+#else
+#define PR_TRACE(handle,ud0,ud1,ud2,ud3,ud4,ud5,ud6,ud7)
+#endif
+
+NSPR_API(void) 
+	PR_Trace( 
+    	PRTraceHandle handle,       /* use this trace handle */
+	    PRUint32    userData0,      /* User supplied data word 0 */
+	    PRUint32    userData1,      /* User supplied data word 1 */
+	    PRUint32    userData2,      /* User supplied data word 2 */
+	    PRUint32    userData3,      /* User supplied data word 3 */
+	    PRUint32    userData4,      /* User supplied data word 4 */
+	    PRUint32    userData5,      /* User supplied data word 5 */
+	    PRUint32    userData6,      /* User supplied data word 6 */
+	    PRUint32    userData7       /* User supplied data word 7 */
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_SetTraceOption() -- Control the Trace Facility
+** 
+** DESCRIPTION:
+** PR_SetTraceOption() controls the Trace Facility. Depending on
+** command and value, attributes of the Trace Facility may be
+** changed.
+** 
+** INPUTS:
+**  command: An enumerated value in the set of PRTraceOption.
+**  value: pointer to the data to be set. Type of the data is
+**  dependent on command; for each value of command, the type
+**  and meaning of dereferenced value is shown.
+**
+**  PRTraceBufSize: unsigned long: the size of the trace buffer,
+** in bytes.
+** 
+**  PRTraceEnable: PRTraceHandle. The trace handle to be
+** enabled.
+** 
+**  PRTraceDisable: PRTraceHandle. The trace handle to be
+** disabled.
+** 
+**  PRTraceSuspend: void. value must be NULL. All tracing is
+** suspended.
+** 
+**  PRTraceResume: void. value must be NULL. Tracing for all
+** previously enabled, prior to a PRTraceSuspend, is resumed.
+** 
+**  PRTraceStopRecording: void. value must be NULL. If recording
+** (see: ** PR_RecordTraceEntries()) is being done, 
+** PRTraceStopRecording causes PR_RecordTraceEntries() to return
+** to its caller. If recording is not being done, this function
+** has no effect.
+** 
+**  PRTraceSuspendRecording: void. Must be NULL. If recording is
+** being done, PRTraceSuspendRecording causes further writes to
+** the trace file to be suspended. Data in the in-memory
+** trace buffer that would ordinarily be written to the
+** trace file will not be written. Trace entries will continue
+** to be entered in the in-memory buffer. If the Trace Facility
+** recording is already in a suspended state, the call has no
+** effect.
+** 
+**  PRTraceResumeRecording: void. value must be NULL. If
+** recording for the Trace Facility has been previously been
+** suspended, this causes recording to resume. Recording resumes
+** with the next in-memory buffer segment that would be written
+** if trace recording had not been suspended. If recording is
+** not currently suspended, the call has no effect.
+** 
+**  PRTraceLockHandles: void. value must be NULL. Locks the
+** trace handle lock. While the trace handle lock is held,
+** calls to PR_CreateTrace() will block until the lock is
+** released.
+** 
+**  PRTraceUnlockHandles: void. value must be NULL. Unlocks the
+** trace handle lock.
+** 
+** OUTPUTS:
+**  The operation of the Trace Facility may be changed.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_SET_TRACE_OPTION(command,value)\
+    PR_SetTraceOption((command),(value))
+#else
+#define PR_SET_TRACE_OPTION(command,value)
+#endif
+
+NSPR_API(void) 
+	PR_SetTraceOption( 
+	    PRTraceOption command,  /* One of the enumerated values */
+	    void *value             /* command value or NULL */
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetTraceOption() -- Retrieve settings from the Trace Facility
+** 
+** DESCRIPTION:
+** PR_GetTraceOption() retrieves the current setting of the
+** Trace Facility control depending on command.
+** 
+** 
+**  PRTraceBufSize: unsigned long: the size of the trace buffer,
+** in bytes.
+** 
+** 
+** INPUTS:
+**  command: one of the enumerated values in PRTraceOptions
+** valid for PR_GetTraceOption().
+** 
+** OUTPUTS:
+**  dependent on command.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_GET_TRACE_OPTION(command,value)\
+    PR_GetTraceOption((command),(value))
+#else
+#define PR_GET_TRACE_OPTION(command,value)
+#endif
+
+NSPR_API(void) 
+	PR_GetTraceOption( 
+    	PRTraceOption command,  /* One of the enumerated values */
+	    void *value             /* command value or NULL */
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetTraceHandleFromName() -- Retrieve an existing
+** handle by name.
+** 
+** DESCRIPTION:
+** PR_GetTraceHandleFromName() retreives an existing tracehandle
+** using the name specified by qName and rName.
+** 
+** INPUTS:
+**  qName: pointer to string. QName for this trace handle. 
+** 
+**  rName: pointer to string. RName for this trace handle. 
+** 
+** 
+** OUTPUTS: returned.
+** 
+** RETURNS: 
+**  PRTraceHandle associated with qName and rName or NULL when
+** there is no match.
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_GET_TRACE_HANDLE_FROM_NAME(handle,qName,rName)\
+    (handle) = PR_GetTraceHandleFromName((qName),(rName))
+#else
+#define PR_GET_TRACE_HANDLE_FROM_NAME(handle,qName,rName)
+#endif
+
+NSPR_API(PRTraceHandle) 
+	PR_GetTraceHandleFromName( 
+    	const char *qName,      /* QName search argument */
+        const char *rName       /* RName search argument */
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetTraceNameFromHandle() -- Retreive trace name
+** by bandle.
+** 
+** DESCRIPTION:
+** PR_GetTraceNameFromHandle() retreives the existing qName,
+** rName, and description for the referenced trace handle.
+** 
+** INPUTS: handle: PRTraceHandle.
+** 
+** OUTPUTS: pointers to the Trace Facility's copy of qName,
+** rName and description. ... Don't mess with these values.
+** They're mine.
+** 
+** RETURNS: void
+** 
+** RESTRICTIONS:
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_GET_TRACE_NAME_FROM_HANDLE(handle,qName,rName,description)\
+    PR_GetTraceNameFromHandle((handle),(qName),(rName),(description))
+#else
+#define PR_GET_TRACE_NAME_FROM_HANDLE(handle,qName,rName,description)
+#endif
+
+NSPR_API(void) 
+	PR_GetTraceNameFromHandle( 
+    	PRTraceHandle handle,       /* handle as search argument */
+	    const char **qName,         /* pointer to associated QName */
+	    const char **rName,         /* pointer to associated RName */
+    	const char **description    /* pointer to associated description */
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_FindNextTraceQname() -- Retrieive a QName handle
+** iterator.
+** 
+** DESCRIPTION:
+** PR_FindNextTraceQname() retreives the first or next trace
+** QName handle, depending on the value of handle, from the trace
+** database. The PRTraceHandle returned can be used as an
+** iterator to traverse the QName handles in the Trace database.
+** 
+** INPUTS:
+**  handle: When NULL, PR_FindNextQname() returns the first QName
+** handle. When a handle is a valid PRTraceHandle previously
+** retreived using PR_FindNextQname() the next QName handle is
+** retreived.
+** 
+** OUTPUTS: returned.
+** 
+** RETURNS: 
+**  PRTraceHandle or NULL when there are no trace handles.
+** 
+** RESTRICTIONS:
+**  Iterating thru the trace handles via FindFirst/FindNext
+** should be done under protection of the trace handle lock.
+** See: PR_SetTraceOption( PRLockTraceHandles ).
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_FIND_NEXT_TRACE_QNAME(next,handle)\
+    (next) = PR_FindNextTraceQname((handle))
+#else
+#define PR_FIND_NEXT_TRACE_QNAME(next,handle)
+#endif
+
+NSPR_API(PRTraceHandle) 
+	PR_FindNextTraceQname( 
+        PRTraceHandle handle
+);
+
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_FindNextTraceRname() -- Retrieive an RName handle
+** iterator.
+** 
+** DESCRIPTION:
+** PR_FindNextTraceRname() retreives the first or next trace
+** RName handle, depending on the value of handle, from the trace
+** database. The PRTraceHandle returned can be used as an
+** iterator to traverse the RName handles in the Trace database.
+** 
+** INPUTS:
+**  rhandle: When NULL, PR_FindNextRname() returns the first
+** RName handle. When a handle is a valid PRTraceHandle
+** previously retreived using PR_FindNextRname() the next RName
+** handle is retreived.
+**  qhandle: A valid PRTraceHandle retruned from a previous call
+** to PR_FIND_NEXT_TRACE_QNAME().
+** 
+** OUTPUTS: returned.
+** 
+** RETURNS: 
+**  PRTraceHandle or NULL when there are no trace handles.
+** 
+** RESTRICTIONS:
+**  Iterating thru the trace handles via FindNext should be done
+** under protection of the trace handle lock. See: (
+** PR_SetTraceOption( PRLockTraceHandles ).
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_FIND_NEXT_TRACE_RNAME(next,rhandle,qhandle)\
+    (next) = PR_FindNextTraceRname((rhandle),(qhandle))
+#else
+#define PR_FIND_NEXT_TRACE_RNAME(next,rhandle,qhandle)
+#endif
+
+NSPR_API(PRTraceHandle) 
+	PR_FindNextTraceRname( 
+        PRTraceHandle rhandle,
+        PRTraceHandle qhandle
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_RecordTraceEntries() -- Write trace entries to external media
+** 
+** DESCRIPTION:
+** PR_RecordTraceEntries() causes entries in the in-memory trace
+** buffer to be written to external media.
+**
+** When PR_RecordTraceEntries() is called from an application
+** thread, the function appears to block until another thread
+** calls PR_SetTraceOption() with the PRTraceStopRecording
+** option. This suggests that PR_RecordTraceEntries() should be
+** called from a user supplied thread whose only job is to
+** record trace entries. 
+** 
+** The environment variable NSPR_TRACE_LOG controls the operation
+** of this function. When NSPR_TRACE_LOG is not defined in the
+** environment, no recording of trace entries occurs. When
+** NSPR_TRACE_LOG is defined, the value of its definition must be
+** the filename of the file to receive the trace entry buffer.
+**
+** PR_RecordTraceEntries() attempts to record the in-memory
+** buffer to a file, subject to the setting of the environment
+** variable NSPR_TRACE_LOG. It is possible because of system
+** load, the thread priority of the recording thread, number of
+** active trace records being written over time, and other
+** variables that some trace records can be lost. ... In other
+** words: don't bet the farm on getting everything.
+** 
+** INPUTS: none
+** 
+** OUTPUTS: none
+** 
+** RETURNS: PR_STATUS
+**    PR_SUCCESS no errors were found.
+**    PR_FAILURE errors were found.
+** 
+** RESTRICTIONS:
+** Only one thread can call PR_RecordTraceEntries() within a
+** process.
+** 
+** On error, PR_RecordTraceEntries() may return prematurely.
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_RECORD_TRACE_ENTRIES()\
+	PR_RecordTraceEntries()
+#else
+#define PR_RECORD_TRACE_ENTRIES()
+#endif
+    
+NSPR_API(void)
+	PR_RecordTraceEntries(
+        void 
+);
+
+/* -----------------------------------------------------------------------
+** FUNCTION: PR_GetTraceEntries() -- Retreive trace entries from
+** the Trace Facility
+** 
+** DESCRIPTION:
+** PR_GetTraceEntries() retreives trace entries from the Trace
+** Facility. Up to count trace entries are copied from the Trace
+** Facility into buffer. Only those trace entries that have not
+** been copied via a previous call to PR_GetTraceEntries() are
+** copied. The actual number copied is placed in the PRInt32
+** variable pointed to by found.
+**
+** If more than count trace entries have entered the Trace
+** Facility since the last call to PR_GetTraceEntries() 
+** a lost data condition is returned. In this case, the most
+** recent count trace entries are copied into buffer and found is
+** set to count.
+** 
+** INPUTS:
+**  count. The number of trace entries to be copied into buffer.
+** 
+** 
+** OUTPUTS:
+**  buffer. An array of PRTraceEntries. The buffer is supplied
+** by the caller.
+** 
+** found: 32bit signed integer. The number of PRTraceEntries
+** actually copied. found is always less than or equal to count.
+** 
+** RETURNS: 
+**  zero when there is no lost data.
+**  non-zero when some PRTraceEntries have been lost.
+** 
+** RESTRICTIONS:
+** This is a real performance pig. The copy out operation is bad
+** enough, but depending on then frequency of calls to the
+** function, serious performance impact to the operating
+** application may be realized. ... YMMV.
+** 
+*/
+#if defined (DEBUG) || defined (FORCE_NSPR_TRACE)
+#define PR_GET_TRACE_ENTRIES(buffer,count,found)\
+        PR_GetTraceEntries((buffer),(count),(found))
+#else
+#define PR_GET_TRACE_ENTRIES(buffer,count,found)
+#endif
+
+NSPR_API(PRIntn)
+    PR_GetTraceEntries(
+        PRTraceEntry    *buffer,    /* where to write output */
+        PRInt32         count,      /* number to get */
+        PRInt32         *found      /* number you got */
+);
+
+PR_END_EXTERN_C
+
+#endif /* prtrace_h___ */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prtypes.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prtypes.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,558 @@
+/* -*- 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:                prtypes.h
+** Description: Definitions of NSPR's basic types
+**
+** Prototypes and macros used to make up for deficiencies that we have found
+** in ANSI environments.
+**
+** Since we do not wrap <stdlib.h> and all the other standard headers, authors
+** of portable code will not know in general that they need these definitions.
+** Instead of requiring these authors to find the dependent uses in their code
+** and take the following steps only in those C files, we take steps once here
+** for all C files.
+**/
+
+#ifndef prtypes_h___
+#define prtypes_h___
+
+#ifdef MDCPUCFG
+#include MDCPUCFG
+#else
+#include "prcpucfg.h"
+#endif
+
+#include <stddef.h>
+
+/***********************************************************************
+** MACROS:      PR_EXTERN
+**              PR_IMPLEMENT
+** DESCRIPTION:
+**      These are only for externally visible routines and globals.  For
+**      internal routines, just use "extern" for type checking and that
+**      will not export internal cross-file or forward-declared symbols.
+**      Define a macro for declaring procedures return types. We use this to
+**      deal with windoze specific type hackery for DLL definitions. Use
+**      PR_EXTERN when the prototype for the method is declared. Use
+**      PR_IMPLEMENT for the implementation of the method.
+**
+** Example:
+**   in dowhim.h
+**     PR_EXTERN( void ) DoWhatIMean( void );
+**   in dowhim.c
+**     PR_IMPLEMENT( void ) DoWhatIMean( void ) { return; }
+**
+**
+***********************************************************************/
+#if defined(WIN32)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT(__type) __declspec(dllimport) __type
+#define PR_IMPORT_DATA(__type) __declspec(dllimport) __type
+
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(XP_BEOS)
+
+#define PR_EXPORT(__type) extern __declspec(dllexport) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT(__type) extern __declspec(dllexport) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(dllexport) __type
+
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(WIN16)
+
+#define PR_CALLBACK_DECL        __cdecl
+
+#if defined(_WINDLL)
+#define PR_EXPORT(__type) extern __type _cdecl _export _loadds
+#define PR_IMPORT(__type) extern __type _cdecl _export _loadds
+#define PR_EXPORT_DATA(__type) extern __type _export
+#define PR_IMPORT_DATA(__type) extern __type _export
+
+#define PR_EXTERN(__type) extern __type _cdecl _export _loadds
+#define PR_IMPLEMENT(__type) __type _cdecl _export _loadds
+#define PR_EXTERN_DATA(__type) extern __type _export
+#define PR_IMPLEMENT_DATA(__type) __type _export
+
+#define PR_CALLBACK             __cdecl __loadds
+#define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK
+
+#else /* this must be .EXE */
+#define PR_EXPORT(__type) extern __type _cdecl _export
+#define PR_IMPORT(__type) extern __type _cdecl _export
+#define PR_EXPORT_DATA(__type) extern __type _export
+#define PR_IMPORT_DATA(__type) extern __type _export
+
+#define PR_EXTERN(__type) extern __type _cdecl _export
+#define PR_IMPLEMENT(__type) __type _cdecl _export
+#define PR_EXTERN_DATA(__type) extern __type _export
+#define PR_IMPLEMENT_DATA(__type) __type _export
+
+#define PR_CALLBACK             __cdecl __loadds
+#define PR_STATIC_CALLBACK(__x) __x PR_CALLBACK
+#endif /* _WINDLL */
+
+#elif defined(XP_MAC)
+
+#define PR_EXPORT(__type) extern __declspec(export) __type
+#define PR_EXPORT_DATA(__type) extern __declspec(export) __type
+#define PR_IMPORT(__type) extern __declspec(export) __type
+#define PR_IMPORT_DATA(__type) extern __declspec(export) __type
+
+#define PR_EXTERN(__type) extern __declspec(export) __type
+#define PR_IMPLEMENT(__type) __declspec(export) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(export) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(export) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#elif defined(XP_OS2_VACPP) 
+
+#define PR_EXPORT(__type) extern __type
+#define PR_EXPORT_DATA(__type) extern __type
+#define PR_IMPORT(__type) extern __type
+#define PR_IMPORT_DATA(__type) extern __type
+
+#define PR_EXTERN(__type) extern __type
+#define PR_IMPLEMENT(__type) __type
+#define PR_EXTERN_DATA(__type) extern __type
+#define PR_IMPLEMENT_DATA(__type) __type
+#define PR_CALLBACK _Optlink
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x PR_CALLBACK
+
+#else /* Unix */
+
+/* GCC 3.3 and later support the visibility attribute. */
+#if (__GNUC__ >= 4) || \
+    (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+#define PR_VISIBILITY_DEFAULT __attribute__((visibility("default")))
+#else
+#define PR_VISIBILITY_DEFAULT
+#endif
+
+#define PR_EXPORT(__type) extern PR_VISIBILITY_DEFAULT __type
+#define PR_EXPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type
+#define PR_IMPORT(__type) extern PR_VISIBILITY_DEFAULT __type
+#define PR_IMPORT_DATA(__type) extern PR_VISIBILITY_DEFAULT __type
+
+#define PR_EXTERN(__type) extern PR_VISIBILITY_DEFAULT __type
+#define PR_IMPLEMENT(__type) PR_VISIBILITY_DEFAULT __type
+#define PR_EXTERN_DATA(__type) extern PR_VISIBILITY_DEFAULT __type
+#define PR_IMPLEMENT_DATA(__type) PR_VISIBILITY_DEFAULT __type
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
+#endif
+
+#if defined(_NSPR_BUILD_)
+#define NSPR_API(__type) PR_EXPORT(__type)
+#define NSPR_DATA_API(__type) PR_EXPORT_DATA(__type)
+#else
+#define NSPR_API(__type) PR_IMPORT(__type)
+#define NSPR_DATA_API(__type) PR_IMPORT_DATA(__type)
+#endif
+
+/***********************************************************************
+** MACROS:      PR_BEGIN_MACRO
+**              PR_END_MACRO
+** DESCRIPTION:
+**      Macro body brackets so that macros with compound statement definitions
+**      behave syntactically more like functions when called.
+***********************************************************************/
+#define PR_BEGIN_MACRO  do {
+#define PR_END_MACRO    } while (0)
+
+/***********************************************************************
+** MACROS:      PR_BEGIN_EXTERN_C
+**              PR_END_EXTERN_C
+** DESCRIPTION:
+**      Macro shorthands for conditional C++ extern block delimiters.
+***********************************************************************/
+#ifdef __cplusplus
+#define PR_BEGIN_EXTERN_C       extern "C" {
+#define PR_END_EXTERN_C         }
+#else
+#define PR_BEGIN_EXTERN_C
+#define PR_END_EXTERN_C
+#endif
+
+/***********************************************************************
+** MACROS:      PR_BIT
+**              PR_BITMASK
+** DESCRIPTION:
+** Bit masking macros.  XXX n must be <= 31 to be portable
+***********************************************************************/
+#define PR_BIT(n)       ((PRUint32)1 << (n))
+#define PR_BITMASK(n)   (PR_BIT(n) - 1)
+
+/***********************************************************************
+** MACROS:      PR_ROUNDUP
+**              PR_MIN
+**              PR_MAX
+**              PR_ABS
+** DESCRIPTION:
+**      Commonly used macros for operations on compatible types.
+***********************************************************************/
+#define PR_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y))
+#define PR_MIN(x,y)     ((x)<(y)?(x):(y))
+#define PR_MAX(x,y)     ((x)>(y)?(x):(y))
+#define PR_ABS(x)       ((x)<0?-(x):(x))
+
+PR_BEGIN_EXTERN_C
+
+/************************************************************************
+** TYPES:       PRUint8
+**              PRInt8
+** DESCRIPTION:
+**  The int8 types are known to be 8 bits each. There is no type that
+**      is equivalent to a plain "char". 
+************************************************************************/
+#if PR_BYTES_PER_BYTE == 1
+typedef unsigned char PRUint8;
+/*
+** Some cfront-based C++ compilers do not like 'signed char' and
+** issue the warning message:
+**     warning: "signed" not implemented (ignored)
+** For these compilers, we have to define PRInt8 as plain 'char'.
+** Make sure that plain 'char' is indeed signed under these compilers.
+*/
+#if (defined(HPUX) && defined(__cplusplus) \
+        && !defined(__GNUC__) && __cplusplus < 199707L) \
+    || (defined(SCO) && defined(__cplusplus) \
+        && !defined(__GNUC__) && __cplusplus == 1L)
+typedef char PRInt8;
+#else
+typedef signed char PRInt8;
+#endif
+#else
+#error No suitable type for PRInt8/PRUint8
+#endif
+
+/************************************************************************
+ * MACROS:      PR_INT8_MAX
+ *              PR_INT8_MIN
+ *              PR_UINT8_MAX
+ * DESCRIPTION:
+ *  The maximum and minimum values of a PRInt8 or PRUint8.
+************************************************************************/
+
+#define PR_INT8_MAX 127
+#define PR_INT8_MIN (-128)
+#define PR_UINT8_MAX 255U
+
+/************************************************************************
+** TYPES:       PRUint16
+**              PRInt16
+** DESCRIPTION:
+**  The int16 types are known to be 16 bits each. 
+************************************************************************/
+#if PR_BYTES_PER_SHORT == 2
+typedef unsigned short PRUint16;
+typedef short PRInt16;
+#else
+#error No suitable type for PRInt16/PRUint16
+#endif
+
+/************************************************************************
+ * MACROS:      PR_INT16_MAX
+ *              PR_INT16_MIN
+ *              PR_UINT16_MAX
+ * DESCRIPTION:
+ *  The maximum and minimum values of a PRInt16 or PRUint16.
+************************************************************************/
+
+#define PR_INT16_MAX 32767
+#define PR_INT16_MIN (-32768)
+#define PR_UINT16_MAX 65535U
+
+/************************************************************************
+** TYPES:       PRUint32
+**              PRInt32
+** DESCRIPTION:
+**  The int32 types are known to be 32 bits each. 
+************************************************************************/
+#if PR_BYTES_PER_INT == 4
+typedef unsigned int PRUint32;
+typedef int PRInt32;
+#define PR_INT32(x)  x
+#define PR_UINT32(x) x ## U
+#elif PR_BYTES_PER_LONG == 4
+typedef unsigned long PRUint32;
+typedef long PRInt32;
+#define PR_INT32(x)  x ## L
+#define PR_UINT32(x) x ## UL
+#else
+#error No suitable type for PRInt32/PRUint32
+#endif
+
+/************************************************************************
+ * MACROS:      PR_INT32_MAX
+ *              PR_INT32_MIN
+ *              PR_UINT32_MAX
+ * DESCRIPTION:
+ *  The maximum and minimum values of a PRInt32 or PRUint32.
+************************************************************************/
+
+#define PR_INT32_MAX PR_INT32(2147483647)
+#define PR_INT32_MIN (-PR_INT32_MAX - 1)
+#define PR_UINT32_MAX PR_UINT32(4294967295)
+
+/************************************************************************
+** TYPES:       PRUint64
+**              PRInt64
+** DESCRIPTION:
+**  The int64 types are known to be 64 bits each. Care must be used when
+**      declaring variables of type PRUint64 or PRInt64. Different hardware
+**      architectures and even different compilers have varying support for
+**      64 bit values. The only guaranteed portability requires the use of
+**      the LL_ macros (see prlong.h).
+************************************************************************/
+#ifdef HAVE_LONG_LONG
+#if PR_BYTES_PER_LONG == 8
+typedef long PRInt64;
+typedef unsigned long PRUint64;
+#elif defined(WIN16)
+typedef __int64 PRInt64;
+typedef unsigned __int64 PRUint64;
+#elif defined(WIN32) && !defined(__GNUC__)
+typedef __int64  PRInt64;
+typedef unsigned __int64 PRUint64;
+#else
+typedef long long PRInt64;
+typedef unsigned long long PRUint64;
+#endif /* PR_BYTES_PER_LONG == 8 */
+#else  /* !HAVE_LONG_LONG */
+typedef struct {
+#ifdef IS_LITTLE_ENDIAN
+    PRUint32 lo, hi;
+#else
+    PRUint32 hi, lo;
+#endif
+} PRInt64;
+typedef PRInt64 PRUint64;
+#endif /* !HAVE_LONG_LONG */
+
+/************************************************************************
+** TYPES:       PRUintn
+**              PRIntn
+** DESCRIPTION:
+**  The PRIntn types are most appropriate for automatic variables. They are
+**      guaranteed to be at least 16 bits, though various architectures may
+**      define them to be wider (e.g., 32 or even 64 bits). These types are
+**      never valid for fields of a structure. 
+************************************************************************/
+#if PR_BYTES_PER_INT >= 2
+typedef int PRIntn;
+typedef unsigned int PRUintn;
+#else
+#error 'sizeof(int)' not sufficient for platform use
+#endif
+
+/************************************************************************
+** TYPES:       PRFloat64
+** DESCRIPTION:
+**  NSPR's floating point type is always 64 bits. 
+************************************************************************/
+typedef double          PRFloat64;
+
+/************************************************************************
+** TYPES:       PRSize
+** DESCRIPTION:
+**  A type for representing the size of objects. 
+************************************************************************/
+typedef size_t PRSize;
+
+
+/************************************************************************
+** TYPES:       PROffset32, PROffset64
+** DESCRIPTION:
+**  A type for representing byte offsets from some location. 
+************************************************************************/
+typedef PRInt32 PROffset32;
+typedef PRInt64 PROffset64;
+
+/************************************************************************
+** TYPES:       PRPtrDiff
+** DESCRIPTION:
+**  A type for pointer difference. Variables of this type are suitable
+**      for storing a pointer or pointer subtraction. 
+************************************************************************/
+typedef ptrdiff_t PRPtrdiff;
+
+/************************************************************************
+** TYPES:       PRUptrdiff
+** DESCRIPTION:
+**  A type for pointer difference. Variables of this type are suitable
+**      for storing a pointer or pointer sutraction. 
+************************************************************************/
+#ifdef _WIN64
+typedef unsigned __int64 PRUptrdiff;
+#else
+typedef unsigned long PRUptrdiff;
+#endif
+
+/************************************************************************
+** TYPES:       PRBool
+** DESCRIPTION:
+**  Use PRBool for variables and parameter types. Use PR_FALSE and PR_TRUE
+**      for clarity of target type in assignments and actual arguments. Use
+**      'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans
+**      just as you would C int-valued conditions. 
+************************************************************************/
+typedef PRIntn PRBool;
+#define PR_TRUE 1
+#define PR_FALSE 0
+
+/************************************************************************
+** TYPES:       PRPackedBool
+** DESCRIPTION:
+**  Use PRPackedBool within structs where bitfields are not desirable
+**      but minimum and consistant overhead matters.
+************************************************************************/
+typedef PRUint8 PRPackedBool;
+
+/*
+** Status code used by some routines that have a single point of failure or 
+** special status return.
+*/
+typedef enum { PR_FAILURE = -1, PR_SUCCESS = 0 } PRStatus;
+
+#ifdef MOZ_UNICODE
+/*
+ * EXPERIMENTAL: This type may be removed in a future release.
+ */
+#ifndef __PRUNICHAR__
+#define __PRUNICHAR__
+#if defined(WIN32) || defined(XP_MAC)
+typedef wchar_t PRUnichar;
+#else
+typedef PRUint16 PRUnichar;
+#endif
+#endif
+#endif /* MOZ_UNICODE */
+
+/*
+** WARNING: The undocumented data types PRWord and PRUword are
+** only used in the garbage collection and arena code.  Do not
+** use PRWord and PRUword in new code.
+**
+** A PRWord is an integer that is the same size as a void*.
+** It implements the notion of a "word" in the Java Virtual
+** Machine.  (See Sec. 3.4 "Words", The Java Virtual Machine
+** Specification, Addison-Wesley, September 1996.
+** http://java.sun.com/docs/books/vmspec/index.html.)
+*/
+#ifdef _WIN64
+typedef __int64 PRWord;
+typedef unsigned __int64 PRUword;
+#else
+typedef long PRWord;
+typedef unsigned long PRUword;
+#endif
+
+#if defined(NO_NSPR_10_SUPPORT)
+#else
+/********* ???????????????? FIX ME       ??????????????????????????? *****/
+/********************** Some old definitions until pr=>ds transition is done ***/
+/********************** Also, we are still using NSPR 1.0. GC ******************/
+/*
+** Fundamental NSPR macros, used nearly everywhere.
+*/
+
+#define PR_PUBLIC_API		PR_IMPLEMENT
+
+/*
+** Macro body brackets so that macros with compound statement definitions
+** behave syntactically more like functions when called.
+*/
+#define NSPR_BEGIN_MACRO        do {
+#define NSPR_END_MACRO          } while (0)
+
+/*
+** Macro shorthands for conditional C++ extern block delimiters.
+*/
+#ifdef NSPR_BEGIN_EXTERN_C
+#undef NSPR_BEGIN_EXTERN_C
+#endif
+#ifdef NSPR_END_EXTERN_C
+#undef NSPR_END_EXTERN_C
+#endif
+
+#ifdef __cplusplus
+#define NSPR_BEGIN_EXTERN_C     extern "C" {
+#define NSPR_END_EXTERN_C       }
+#else
+#define NSPR_BEGIN_EXTERN_C
+#define NSPR_END_EXTERN_C
+#endif
+
+#ifdef XP_MAC
+#include "protypes.h"
+#else
+#include "obsolete/protypes.h"
+#endif
+
+/********* ????????????? End Fix me ?????????????????????????????? *****/
+#endif /* NO_NSPR_10_SUPPORT */
+
+PR_END_EXTERN_C
+
+#endif /* prtypes_h___ */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prvrsion.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prvrsion.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,137 @@
+/* -*- 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 ***** */
+
+
+/* author: jstewart */
+
+#if defined(_PRVERSION_H)
+#else
+#define _PRVERSION_H
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/* All components participating in the PR version protocol must expose
+ * a structure and a function. The structure is defined below and named
+ * according to the naming conventions outlined further below.  The function
+ * is called libVersionPoint and returns a pointer to this structure.
+ */
+
+/* on NT, always pack the structure the same. */
+#ifdef _WIN32
+#pragma pack(push, 8)
+#endif
+
+typedef struct {
+    /*
+     * The first field defines which version of this structure is in use.
+     * At this time, only version 2 is specified. If this value is not 
+     * 2, you must read no further into the structure.
+     */
+    PRInt32    version; 
+  
+    /* for Version 2, this is the body format. */
+    PRInt64         buildTime;      /* 64 bits - usecs since midnight, 1/1/1970 */
+    char *          buildTimeString;/* a human readable version of the time */
+  
+    PRUint8   vMajor;               /* Major version of this component */
+    PRUint8   vMinor;               /* Minor version of this component */
+    PRUint8   vPatch;               /* Patch level of this component */
+  
+    PRBool          beta;           /* true if this is a beta component */
+    PRBool          debug;          /* true if this is a debug component */
+    PRBool          special;        /* true if this component is a special build */
+  
+    char *          filename;       /* The original filename */
+    char *          description;    /* description of this component */
+    char *          security;       /* level of security in this component */
+    char *          copyright;      /* The copyright for this file */
+    char *          comment;        /* free form field for misc usage */
+    char *          specialString;  /* the special variant for this build */
+} PRVersionDescription;
+
+/* on NT, restore the previous packing */
+#ifdef _WIN32
+#pragma pack(pop)
+#endif
+
+/*
+ * All components must define an entrypoint named libVersionPoint which
+ * is of type versionEntryPointType.
+ *
+ * For example, for a library named libfoo, we would have:
+ *
+ *   PRVersionDescription prVersionDescription_libfoo =
+ *   {
+ *       ...
+ *   };
+ *
+ *   PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void)
+ *   {
+ *       return &prVersionDescription_libfoo;
+ *   }
+ */
+typedef const PRVersionDescription *(*versionEntryPointType)(void);
+
+/* 
+ * Where you declare your libVersionPoint, do it like this: 
+ * PR_IMPLEMENT(const PRVersionDescription *) libVersionPoint(void) {
+ *  fill it in...
+ * }
+ */
+
+/*
+ * NAMING CONVENTION FOR struct
+ *
+ * all components should also expose a static PRVersionDescription
+ * The name of the struct should be calculated as follows:
+ * Take the value of filename. (If filename is not specified, calculate
+ * a short, unique string.)  Convert all non-alphanumeric characters
+ * to '_'.  To this, prepend "PRVersionDescription_".  Thus for libfoo.so,
+ * the symbol name is "PRVersionDescription_libfoo_so".
+ * so the file should have
+ * PRVersionDescription PRVersionDescription_libfoo_so { fill it in };
+ * on NT, this file should be declspec export.
+ */
+
+PR_END_EXTERN_C
+
+#endif  /* defined(_PRVERSION_H) */
+
+/* prvrsion.h */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/include/prwin16.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/include/prwin16.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,196 @@
+/* -*- 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 prwin16_h___
+#define prwin16_h___
+
+/*
+** Condition use of this header on platform.
+*/
+#if (defined(XP_PC) && !defined(_WIN32) && !defined(XP_OS2) && defined(MOZILLA_CLIENT)) || defined(WIN16)
+#include <stdio.h>
+
+PR_BEGIN_EXTERN_C
+/* 
+** Win16 stdio special case.
+** To get stdio to work for Win16, all calls to printf() and related
+** things must be called from the environment of the .EXE; calls to
+** printf() from the .DLL send output to the bit-bucket.
+**
+** To make sure that PR_fprintf(), and related functions, work correctly,
+** the actual stream I/O to stdout, stderr, stdin must be done in the
+** .EXE. To do this, a hack is placed in _MD_Write() such that the
+** fd for stdio handles results in a call to the .EXE.
+**
+** file w16stdio.c contains the functions that get called from NSPR
+** to do the actual I/O. w16stdio.o must be statically linked with
+** any application needing stdio for Win16.
+**
+** The address of these functions must be made available to the .DLL
+** so he can call back to the .EXE. To do this, function 
+** PR_MD_RegisterW16StdioCallbacks() is called from the .EXE.
+** The arguments are the functions defined in w16stdio.c
+** At runtime, MD_Write() calls the registered functions, if any
+** were registered.
+**
+** prinit.h contains a macro PR_STDIO_INIT() that calls the registration
+** function for Win16; For other platforms, the macro is a No-Op.
+**
+** Note that stdio is not operational at all on Win16 GUI applications.
+** This special case exists to provide stdio capability from the NSPR
+** .DLL for command line applications only. NSPR's test cases are
+** almost exclusively command line applications.
+**
+** See also: w16io.c, w16stdio.c
+*/
+typedef PRInt32 (PR_CALLBACK *PRStdinRead)( void *buf, PRInt32 amount);
+typedef PRInt32 (PR_CALLBACK *PRStdoutWrite)( void *buf, PRInt32 amount);
+typedef PRInt32 (PR_CALLBACK *PRStderrWrite)( void *buf, PRInt32 amount);
+
+NSPR_API(PRStatus)
+PR_MD_RegisterW16StdioCallbacks( 
+    PRStdinRead inReadf,            /* i: function pointer for stdin read       */
+    PRStdoutWrite outWritef,        /* i: function pointer for stdout write     */
+    PRStderrWrite errWritef         /* i: function pointer for stderr write     */
+    );
+
+NSPR_API(PRInt32)
+_PL_W16StdioWrite( void *buf, PRInt32 amount );
+
+NSPR_API(PRInt32)
+_PL_W16StdioRead( void *buf, PRInt32 amount );
+
+#define PR_STDIO_INIT() PR_MD_RegisterW16StdioCallbacks( \
+    _PL_W16StdioRead, _PL_W16StdioWrite, _PL_W16StdioWrite ); \
+    PR_INIT_CALLBACKS();
+
+/*
+** Win16 hackery.
+**
+*/
+struct PRMethodCallbackStr {
+    int     (PR_CALLBACK *auxOutput)(const char *outputString);
+    size_t  (PR_CALLBACK *strftime)(char *s, size_t len, const char *fmt, const struct tm *p);
+    void *  (PR_CALLBACK *malloc)( size_t size );
+    void *  (PR_CALLBACK *calloc)(size_t n, size_t size );
+    void *  (PR_CALLBACK *realloc)( void* old_blk, size_t size );
+    void    (PR_CALLBACK *free)( void *ptr );
+    void *  (PR_CALLBACK *getenv)( const char *name);
+    int     (PR_CALLBACK *putenv)( const char *assoc);
+/*    void *  (PR_CALLBACK *perror)( const char *prefix ); */
+};
+
+NSPR_API(void) PR_MDRegisterCallbacks(struct PRMethodCallbackStr *);
+
+int PR_CALLBACK _PL_W16CallBackPuts( const char *outputString );
+size_t PR_CALLBACK _PL_W16CallBackStrftime( 
+    char *s, 
+    size_t len, 
+    const char *fmt,
+    const struct tm *p );
+void * PR_CALLBACK _PL_W16CallBackMalloc( size_t size );
+void * PR_CALLBACK _PL_W16CallBackCalloc( size_t n, size_t size );
+void * PR_CALLBACK _PL_W16CallBackRealloc( 
+    void *old_blk, 
+    size_t size );
+void   PR_CALLBACK _PL_W16CallBackFree( void *ptr );
+void * PR_CALLBACK _PL_W16CallBackGetenv( const char *name );
+int PR_CALLBACK _PL_W16CallBackPutenv( const char *assoc );
+
+/*
+** Hackery! 
+**
+** These functions are provided as static link points.
+** This is to satisfy the quick port of Gromit to NSPR 2.0
+** ... Don't do this! ... alas, It may never go away.
+** 
+*/
+NSPR_API(int)     PR_MD_printf(const char *, ...);
+NSPR_API(void)    PR_MD_exit(int);
+NSPR_API(size_t)  PR_MD_strftime(char *, size_t, const char *, const struct tm *); 
+NSPR_API(int)     PR_MD_sscanf(const char *, const char *, ...);
+NSPR_API(void*)   PR_MD_malloc( size_t size );
+NSPR_API(void*)   PR_MD_calloc( size_t n, size_t size );
+NSPR_API(void*)   PR_MD_realloc( void* old_blk, size_t size );
+NSPR_API(void)    PR_MD_free( void *ptr );
+NSPR_API(char*)   PR_MD_getenv( const char *name );
+NSPR_API(int)     PR_MD_putenv( const char *assoc );
+NSPR_API(int)     PR_MD_fprintf(FILE *fPtr, const char *fmt, ...);
+
+#define PR_INIT_CALLBACKS()                         \
+    {                                               \
+        static struct PRMethodCallbackStr cbf = {   \
+            _PL_W16CallBackPuts,                    \
+            _PL_W16CallBackStrftime,                \
+            _PL_W16CallBackMalloc,                  \
+            _PL_W16CallBackCalloc,                  \
+            _PL_W16CallBackRealloc,                 \
+            _PL_W16CallBackFree,                    \
+            _PL_W16CallBackGetenv,                  \
+            _PL_W16CallBackPutenv,                  \
+        };                                          \
+        PR_MDRegisterCallbacks( &cbf );             \
+    }
+
+
+/*
+** Get the exception context for Win16 MFC applications threads
+*/
+NSPR_API(void *) PR_W16GetExceptionContext(void);
+/*
+** Set the exception context for Win16 MFC applications threads
+*/
+NSPR_API(void) PR_W16SetExceptionContext(void *context);
+
+PR_END_EXTERN_C
+#else
+/*
+** For platforms other than Win16, define
+** PR_STDIO_INIT() as a No-Op.
+*/
+#define PR_STDIO_INIT()
+#endif /* WIN16 || MOZILLA_CLIENT */
+
+#endif /* prwin16_h___ */
+
+
+
+
+
+
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2 @@
+Makefile
+_pr_bld.h

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,8 @@
+/.cvsignore/1.3/Mon May 14 22:10:58 2001//
+/Makefile.in/1.42/Tue Feb  7 01:46:18 2006//
+/nspr.def/1.13/Mon May  9 19:02:20 2005//
+/nspr.rc/3.11/Sun Apr 25 15:00:57 2004//
+/nspr_symvec.opt/1.9/Fri May  6 18:46:11 2005//
+/os2extra.def/1.2/Thu Mar 25 23:28:51 2004//
+/prvrsion.c/3.15/Sun Apr 25 15:00:57 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,11 @@
+A D/bthreads////
+A D/cplus////
+A D/cthreads////
+A D/io////
+A D/linking////
+A D/malloc////
+A D/md////
+A D/memory////
+A D/misc////
+A D/pthreads////
+A D/threads////

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,425 @@
+# 
+# ***** 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
+
+DIRS = io linking malloc md memory misc threads
+
+# For VAC++ 4 geticcdata rule in config/OS2.mk
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+CSRCS = prvrsion.c
+endif
+
+ifeq ($(USE_PTHREADS), 1)
+	DIRS += pthreads
+endif
+
+ifeq ($(USE_BTHREADS), 1)
+	DIRS += bthreads
+endif
+
+ifeq ($(USE_CPLUS), 1)
+	DIRS += cplus
+endif
+
+#
+# Define platform-dependent OS_LIBS
+#
+
+ifeq ($(OS_ARCH),SunOS)
+ifeq ($(OS_RELEASE),4.1.3_U1)
+OS_LIBS			= -lm
+else	# 4.1.3_U1
+MAPFILE = $(OBJDIR)/nsprmap.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
+#
+# In Solaris 2.6 or earlier, -lrt is called -lposix4.
+# 
+LIBRT_TEST=$(firstword $(sort 5.7 $(OS_RELEASE)))
+ifeq (5.7, $(LIBRT_TEST))
+LIBRT=-lrt
+else
+LIBRT=-lposix4
+endif
+
+ifdef USE_PTHREADS
+OS_LIBS			= -lpthread -lthread ${LIBRT} -lsocket -lnsl -ldl -lc
+else
+ifdef LOCAL_THREADS_ONLY
+OS_LIBS			= -lsocket -lnsl -ldl -lc
+else
+OS_LIBS			= -lthread ${LIBRT} -lsocket -lnsl -ldl -lc
+endif	# LOCAL_THREADS_ONLY
+endif	# USE_PTHREADS
+ifeq ($(OS_TEST),sun4u)
+ifndef USE_64
+DSO_LDOPTS	+= -Wl,-f,\$$ORIGIN/cpu/\$$ISALIST/lib$(ULTRASPARC_LIBRARY)$(LIBRARY_VERSION).so
+endif
+endif	# sun4u
+endif	# 4.1.3_U1
+endif	# SunOS
+
+ifeq ($(OS_ARCH), IRIX)
+ifeq ($(USE_PTHREADS), 1)
+OS_LIBS = -lpthread
+endif
+OS_LIBS += -lc
+endif
+
+ifeq ($(OS_ARCH),AIX)
+OS_LIBS		= -lodm -lcfg
+ifeq ($(CLASSIC_NSPR),1)
+ifeq ($(OS_RELEASE),4.1)
+OS_LIBS		+= -lsvld -lc
+else
+OS_LIBS		+= -ldl -lc
+endif
+else
+ifeq ($(OS_RELEASE),4.1)
+OS_LIBS		+= -lpthreads -lsvld -lC_r -lC -lc_r -lm /usr/lib/libc.a
+else
+OS_LIBS		+= -lpthreads -ldl -lC_r -lC -lc_r -lm /usr/lib/libc.a
+endif
+endif
+endif
+
+# On AIX, we override malloc in non-pthread versions.  On AIX 4.2 or
+# above, this requires that we use the rtl-enabled version of libc.a.
+ifeq ($(OS_ARCH),AIX)
+ifneq (,$(filter-out 3.2 4.1,$(OS_RELEASE)))
+ifneq ($(USE_PTHREADS),1)
+BUILD_AIX_RTL_LIBC = 1
+AIX_RTL_LIBC	= $(OBJDIR)/libc.a
+endif
+endif
+endif
+
+ifeq ($(OS_ARCH),OS2)
+MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def
+ADD_TO_DEF_FILE = cat $(srcdir)/os2extra.def >> $(MAPFILE)
+GARBAGE += $(MAPFILE)
+MKSHLIB += $(MAPFILE)
+endif
+
+ifeq ($(OS_ARCH),OSF1)
+ifeq ($(USE_PTHREADS), 1)
+OS_LIBS 	= -lpthread -lrt
+endif
+ifneq ($(OS_RELEASE),V2.0)
+OS_LIBS		+= -lc_r
+endif
+endif
+
+ifeq ($(OS_ARCH),Linux)
+ifeq ($(USE_PTHREADS), 1)
+OS_LIBS		= -lpthread -ldl
+else
+OS_LIBS		= -ldl
+endif
+endif
+
+ifeq ($(OS_ARCH),HP-UX)
+ifeq ($(USE_PTHREADS), 1)
+ifeq (,$(filter-out B.10.10 B.10.20,$(OS_RELEASE)))
+OS_LIBS 	= -ldce
+else
+OS_LIBS 	= -lpthread -lrt
+endif
+endif
+ifeq ($(PTHREADS_USER), 1)
+OS_LIBS 	= -lpthread
+endif
+ifeq ($(basename $(OS_RELEASE)),A.09)
+OS_LIBS		+= -ldld -L/lib/pa1.1 -lm
+else
+OS_LIBS		+= -ldld -lm -lc
+endif
+endif
+
+ifeq ($(OS_ARCH),UNIXWARE)
+OS_LIBS		= -lsocket -lc
+endif
+
+ifeq ($(OS_ARCH),NEWS-OS)
+OS_LIBS		= -lsocket -lnsl -lgen -lresolv
+endif
+
+ifeq ($(OS_ARCH),WINNT)
+ifdef NS_USE_GCC
+OS_LIBS		= -ladvapi32 -lwsock32 -lwinmm
+else
+OS_LIBS		= advapi32.lib wsock32.lib winmm.lib
+endif
+endif
+
+ifeq ($(OS_TARGET),MacOSX)
+OS_LIBS		= -framework CoreServices -framework CoreFoundation
+endif
+
+ifdef GC_LEAK_DETECTOR
+EXTRA_LIBS	= -L$(dist_libdir) -lboehm
+endif
+
+EXTRA_LIBS += $(OS_LIBS)
+
+#
+# Define platform-dependent OBJS
+#
+
+OBJS = \
+    $(OBJDIR)/prvrsion.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prfdcach.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prmwait.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prmapopt.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/priometh.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prlayer.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prlog.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prmmap.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prpolevt.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prprf.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prscanf.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prstdio.$(OBJ_SUFFIX) \
+    threads/$(OBJDIR)/prcmon.$(OBJ_SUFFIX) \
+	threads/$(OBJDIR)/prrwlock.$(OBJ_SUFFIX) \
+	threads/$(OBJDIR)/prtpd.$(OBJ_SUFFIX) \
+    linking/$(OBJDIR)/prlink.$(OBJ_SUFFIX) \
+    malloc/$(OBJDIR)/prmem.$(OBJ_SUFFIX) \
+    md/$(OBJDIR)/prosdep.$(OBJ_SUFFIX) \
+    memory/$(OBJDIR)/prshm.$(OBJ_SUFFIX) \
+    memory/$(OBJDIR)/prshma.$(OBJ_SUFFIX) \
+    memory/$(OBJDIR)/prseg.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/pralarm.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/pratom.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prcountr.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prdtoa.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prenv.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prerr.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prerror.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prerrortable.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prinit.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prinrval.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/pripc.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prlog2.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prlong.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prnetdb.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prolock.$(OBJ_SUFFIX)	 \
+    misc/$(OBJDIR)/prrng.$(OBJ_SUFFIX)	 \
+    misc/$(OBJDIR)/prsystem.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prthinfo.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prtpool.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prtrace.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/prtime.$(OBJ_SUFFIX)
+
+# ilib now rejects empty objects
+ifneq ($(MOZ_OS2_TOOLS),VACPP)
+OBJS += malloc/$(OBJDIR)/prmalloc.$(OBJ_SUFFIX)
+endif
+
+ifdef USE_PTHREADS
+OBJS += \
+    pthreads/$(OBJDIR)/ptsynch.$(OBJ_SUFFIX) \
+    pthreads/$(OBJDIR)/ptio.$(OBJ_SUFFIX) \
+    pthreads/$(OBJDIR)/ptthread.$(OBJ_SUFFIX) \
+    pthreads/$(OBJDIR)/ptmisc.$(OBJ_SUFFIX)
+else
+OBJS += \
+    io/$(OBJDIR)/prdir.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prfile.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prio.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prsocket.$(OBJ_SUFFIX) \
+    misc/$(OBJDIR)/pripcsem.$(OBJ_SUFFIX)
+
+ifndef USE_BTHREADS
+OBJS += \
+	threads/$(OBJDIR)/prcthr.$(OBJ_SUFFIX) \
+	threads/$(OBJDIR)/prdump.$(OBJ_SUFFIX) \
+	threads/$(OBJDIR)/prmon.$(OBJ_SUFFIX) \
+	threads/$(OBJDIR)/prsem.$(OBJ_SUFFIX) \
+	threads/combined/$(OBJDIR)/prucpu.$(OBJ_SUFFIX) \
+	threads/combined/$(OBJDIR)/prucv.$(OBJ_SUFFIX) \
+	threads/combined/$(OBJDIR)/prulock.$(OBJ_SUFFIX) \
+	threads/combined/$(OBJDIR)/prustack.$(OBJ_SUFFIX) \
+	threads/combined/$(OBJDIR)/pruthr.$(OBJ_SUFFIX)
+endif
+
+endif
+
+ifeq ($(USE_CPLUS), 1)
+OBJS += \
+	cplus/$(OBJDIR)/rcbase.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rccv.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rcfileio.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rcinrval.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rcio.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rclock.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rcnetdb.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rcnetio.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rcthread.$(OBJ_SUFFIX) \
+	cplus/$(OBJDIR)/rctime.$(OBJ_SUFFIX)
+endif
+
+ifdef GC_LEAK_DETECTOR
+OBJS += memory/$(OBJDIR)/prgcleak.$(OBJ_SUFFIX)
+endif
+
+ifeq ($(OS_ARCH), WINNT)
+ifndef USE_64
+ifdef NS_USE_GCC
+DLLBASE=-Wl,--image-base -Wl,0x30000000
+else
+DLLBASE=-BASE:0x30000000
+endif # GCC
+endif # !USE_64
+RES=$(OBJDIR)/nspr.res
+RESNAME=nspr.rc
+endif # WINNT
+
+include $(srcdir)/md/$(PR_MD_ARCH_DIR)/objs.mk
+ifdef USE_BTHREADS
+include $(srcdir)/bthreads/objs.mk
+endif
+
+LIBRARY_NAME = nspr
+LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
+
+RELEASE_LIBS = $(TARGETS)
+
+include $(topsrcdir)/config/rules.mk
+
+ifeq ($(BUILD_AIX_RTL_LIBC),1)
+TARGETS		+= $(AIX_RTL_LIBC)
+# XXX is this a shared library?
+endif
+
+#
+# Version information generation (begin)
+#
+ECHO = echo
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+TINC = $(OBJDIR)/_pr_bld.h
+
+ifeq ($(OS_TARGET),OS2)
+PROD = nspr$(MOD_MAJOR_VERSION).$(DLL_SUFFIX)
+else
+PROD = $(notdir $(SHARED_LIBRARY))
+endif
+
+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
+
+DEFINES		+= -D_NSPR_BUILD_
+
+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)/prvrsion.$(OBJ_SUFFIX): prvrsion.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
+
+ifeq ($(BUILD_AIX_RTL_LIBC),1)
+$(AIX_RTL_LIBC): /usr/ccs/lib/libc.a
+	rtl_enable -o $@ $<
+endif
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,11 @@
+/.cvsignore/1.2/Sat May 12 06:00:27 2001//
+/Makefile.in/1.10/Sun Apr 25 15:00:57 2004//
+/bsrcs.mk/3.6/Sun Apr 25 15:00:57 2004//
+/btcvar.c/3.9/Wed Feb 23 17:43:13 2005//
+/btlocks.c/3.7/Wed Feb 23 17:43:13 2005//
+/btmisc.c/3.5/Sun Apr 25 15:00:57 2004//
+/btmon.c/3.6/Sun Apr 25 15:00:57 2004//
+/btsem.c/3.7/Wed Feb 23 17:43:13 2005//
+/btthread.c/3.9/Mon Nov  7 22:39:00 2005//
+/objs.mk/3.6/Sun Apr 25 15:00:57 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/bthreads

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,63 @@
+# 
+# ***** 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
+
+include $(srcdir)/bsrcs.mk
+CSRCS += $(BTCSRCS)
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+include $(topsrcdir)/config/rules.mk
+
+DEFINES		+= -D_NSPR_BUILD_
+
+export:: $(TARGETS)
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/bsrcs.mk
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/bsrcs.mk	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,49 @@
+# 
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is 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 *****
+
+# this file lists the source files to be compiled (used in Makefile) and
+# then enumerated as object files (in objs.mk) for inclusion in the NSPR
+# shared library
+
+BTCSRCS = \
+	btthread.c \
+	btlocks.c \
+	btcvar.c \
+	btmon.c \
+	btsem.c \
+	btmisc.c \
+	$(NULL)

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btcvar.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btcvar.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,276 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 <kernel/OS.h>
+
+#include "primpl.h"
+
+/*
+** Create a new condition variable.
+**
+** 	"lock" is the lock used to protect the condition variable.
+**
+** Condition variables are synchronization objects that threads can use
+** to wait for some condition to occur.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low. In such cases, a NULL will be returned.
+*/
+PR_IMPLEMENT(PRCondVar*)
+    PR_NewCondVar (PRLock *lock)
+{
+    PRCondVar *cv = PR_NEW( PRCondVar );
+    PR_ASSERT( NULL != lock );
+    if( NULL != cv )
+    {
+	cv->lock = lock;
+	cv->sem = create_sem(0, "CVSem");
+	cv->handshakeSem = create_sem(0, "CVHandshake");
+	cv->signalSem = create_sem( 0, "CVSignal");
+	cv->signalBenCount = 0;
+	cv->ns = cv->nw = 0;
+	PR_ASSERT( cv->sem >= B_NO_ERROR );
+	PR_ASSERT( cv->handshakeSem >= B_NO_ERROR );
+	PR_ASSERT( cv->signalSem >= B_NO_ERROR );
+    }
+    return cv;
+} /* PR_NewCondVar */
+
+/*
+** Destroy a condition variable. There must be no thread
+** waiting on the condvar. The caller is responsible for guaranteeing
+** that the condvar is no longer in use.
+**
+*/
+PR_IMPLEMENT(void)
+    PR_DestroyCondVar (PRCondVar *cvar)
+{
+    status_t result = delete_sem( cvar->sem );
+    PR_ASSERT( result == B_NO_ERROR );
+    
+    result = delete_sem( cvar->handshakeSem );
+    PR_ASSERT( result == B_NO_ERROR );
+
+    result = delete_sem( cvar->signalSem );
+    PR_ASSERT( result == B_NO_ERROR );
+
+    PR_DELETE( cvar );
+}
+
+/*
+** The thread that waits on a condition is blocked in a "waiting on
+** condition" state until another thread notifies the condition or a
+** caller specified amount of time expires. The lock associated with
+** the condition variable will be released, which must have be held
+** prior to the call to wait.
+**
+** Logically a notified thread is moved from the "waiting on condition"
+** state and made "ready." When scheduled, it will attempt to reacquire
+** the lock that it held when wait was called.
+**
+** The timeout has two well known values, PR_INTERVAL_NO_TIMEOUT and
+** PR_INTERVAL_NO_WAIT. The former value requires that a condition be
+** notified (or the thread interrupted) before it will resume from the
+** wait. If the timeout has a value of PR_INTERVAL_NO_WAIT, the effect
+** is to release the lock, possibly causing a rescheduling within the
+** runtime, then immediately attempting to reacquire the lock and resume.
+**
+** Any other value for timeout will cause the thread to be rescheduled
+** either due to explicit notification or an expired interval. The latter
+** must be determined by treating time as one part of the monitored data
+** being protected by the lock and tested explicitly for an expired
+** interval.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable or the thread was interrupted (PR_Interrupt()).
+** The particular reason can be extracted with PR_GetError().
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_WaitCondVar (PRCondVar *cvar, PRIntervalTime timeout)
+{
+    status_t err;
+    if( timeout == PR_INTERVAL_NO_WAIT ) 
+    {
+        PR_Unlock( cvar->lock );
+        PR_Lock( cvar->lock );
+        return PR_SUCCESS;
+    }
+
+    if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) 
+    {
+        if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) 
+        {
+            atomic_add( &cvar->signalBenCount, -1 );
+            return PR_FAILURE;
+        }
+    }
+    cvar->nw += 1;
+    if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) 
+    {
+        release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+    }
+
+    PR_Unlock( cvar->lock );
+    if( timeout==PR_INTERVAL_NO_TIMEOUT ) 
+    {
+    	err = acquire_sem(cvar->sem);
+    } 
+    else 
+    {
+    	err = acquire_sem_etc(cvar->sem, 1, B_RELATIVE_TIMEOUT, PR_IntervalToMicroseconds(timeout) );
+    }
+
+    if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) 
+    {
+        while (acquire_sem(cvar->signalSem) == B_INTERRUPTED);
+    }
+
+    if (cvar->ns > 0)
+    {
+        release_sem_etc(cvar->handshakeSem, 1, B_DO_NOT_RESCHEDULE);
+        cvar->ns -= 1;
+    }
+    cvar->nw -= 1;
+    if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) 
+    {
+        release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+    }
+
+    PR_Lock( cvar->lock );
+    if(err!=B_NO_ERROR) 
+    {
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+/*
+** Notify ONE thread that is currently waiting on 'cvar'. Which thread is
+** dependent on the implementation of the runtime. Common sense would dictate
+** that all threads waiting on a single condition have identical semantics,
+** therefore which one gets notified is not significant. 
+**
+** The calling thead must hold the lock that protects the condition, as
+** well as the invariants that are tightly bound to the condition, when
+** notify is called.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_NotifyCondVar (PRCondVar *cvar)
+{
+    status_t err ;
+    if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) 
+    {
+        if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) 
+        {
+            atomic_add( &cvar->signalBenCount, -1 );
+            return PR_FAILURE;
+        }
+    }
+    if (cvar->nw > cvar->ns)
+    {
+        cvar->ns += 1;
+        release_sem_etc(cvar->sem, 1, B_DO_NOT_RESCHEDULE);
+        if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) 
+        {
+            release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+        }
+
+        while (acquire_sem(cvar->handshakeSem) == B_INTERRUPTED) 
+        {
+            err = B_INTERRUPTED; 
+        }
+    }
+    else
+    {
+        if( atomic_add( &cvar->signalBenCount, -1 ) > 1 )
+        {
+            release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+        }
+    }
+    return PR_SUCCESS; 
+}
+
+/*
+** Notify all of the threads waiting on the condition variable. The order
+** that the threads are notified is indeterminant. The lock that protects
+** the condition must be held.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_NotifyAllCondVar (PRCondVar *cvar)
+{
+    int32 handshakes;
+    status_t err = B_OK;
+
+    if( atomic_add( &cvar->signalBenCount, 1 ) > 0 ) 
+    {
+        if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) 
+        {
+            atomic_add( &cvar->signalBenCount, -1 );
+            return PR_FAILURE;
+        }
+    }
+
+    if (cvar->nw > cvar->ns)
+    {
+        handshakes = cvar->nw - cvar->ns;
+        cvar->ns = cvar->nw;				
+        release_sem_etc(cvar->sem, handshakes, B_DO_NOT_RESCHEDULE);	
+        if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) 
+        {
+            release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+        }
+
+        while (acquire_sem_etc(cvar->handshakeSem, handshakes, 0, 0) == B_INTERRUPTED) 
+        {
+            err = B_INTERRUPTED; 
+        }
+    }
+    else
+    {
+        if( atomic_add( &cvar->signalBenCount, -1 ) > 1 ) 
+        {
+            release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE);
+        }
+    }
+    return PR_SUCCESS;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btlocks.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btlocks.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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:        btlocks.c
+** Description: Implemenation for thread locks using bthreads
+** Exports:     prlock.h
+*/
+
+#include "primpl.h"
+
+#include <string.h>
+#include <sys/time.h>
+
+void
+_PR_InitLocks (void)
+{
+}
+
+PR_IMPLEMENT(PRLock*)
+    PR_NewLock (void)
+{
+    PRLock *lock;
+    status_t semresult;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    lock = PR_NEWZAP(PRLock);
+    if (lock != NULL) {
+
+	lock->benaphoreCount = 0;
+	lock->semaphoreID = create_sem( 0, "nsprLockSem" );
+	if( lock->semaphoreID < B_NO_ERROR ) {
+
+	    PR_DELETE( lock );
+	    lock = NULL;
+	}
+    }
+
+    return lock;
+}
+
+PR_IMPLEMENT(void)
+    PR_DestroyLock (PRLock* lock)
+{
+    status_t result;
+
+    PR_ASSERT(NULL != lock);
+    result = delete_sem(lock->semaphoreID);
+    PR_ASSERT(result == B_NO_ERROR);
+    PR_DELETE(lock);
+}
+
+PR_IMPLEMENT(void)
+    PR_Lock (PRLock* lock)
+{
+    PR_ASSERT(lock != NULL);
+
+    if( atomic_add( &lock->benaphoreCount, 1 ) > 0 ) {
+
+	if( acquire_sem(lock->semaphoreID ) != B_NO_ERROR ) {
+
+	    atomic_add( &lock->benaphoreCount, -1 );
+	    return;
+	}
+    }
+
+    lock->owner = find_thread( NULL );
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_Unlock (PRLock* lock)
+{
+    PR_ASSERT(lock != NULL);
+    lock->owner = NULL;
+    if( atomic_add( &lock->benaphoreCount, -1 ) > 1 ) {
+
+	release_sem_etc( lock->semaphoreID, 1, B_DO_NOT_RESCHEDULE );
+    }
+
+    return PR_SUCCESS;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btmisc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btmisc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 <stdio.h>
+
+// void _PR_InitCPUs(void) {PT_LOG("_PR_InitCPUs")}
+// void _MD_StartInterrupts(void) {PT_LOG("_MD_StartInterrupts")}
+
+/* this is a total hack.. */
+
+struct protoent* getprotobyname(const char* name)
+{
+    return 0;
+}
+
+struct protoent* getprotobynumber(int number)
+{
+    return 0;
+}
+
+/* this is needed by prinit for some reason */
+void
+_PR_InitStacks (void)
+{
+}
+
+/* this is needed by prinit for some reason */
+void
+_PR_InitTPD (void)
+{
+}
+
+/*
+** Create extra virtual processor threads. Generally used with MP systems.
+*/
+PR_IMPLEMENT(void)
+    PR_SetConcurrency (PRUintn numCPUs)
+{
+}
+
+/*
+** Set thread recycle mode to on (1) or off (0)
+*/
+PR_IMPLEMENT(void)
+    PR_SetThreadRecycleMode (PRUint32 flag)
+{
+}
+
+/*
+** Get context registers, return with error for now.
+*/
+
+PR_IMPLEMENT(PRWord *)
+_MD_HomeGCRegisters( PRThread *t, int isCurrent, int *np )
+{
+     return 0;
+}
+
+PR_IMPLEMENT(void *)
+PR_GetSP( PRThread *t )
+{
+    return 0;
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_EnumerateThreads( PREnumerator func, void *arg )
+{
+    return PR_FAILURE;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btmon.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btmon.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 <kernel/OS.h>
+
+#include "primpl.h"
+
+/*
+** Create a new monitor. Monitors are re-entrant locks with a single built-in
+** condition variable.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low.
+*/
+PR_IMPLEMENT(PRMonitor*)
+    PR_NewMonitor (void)
+{
+    PRMonitor *mon;
+    PRCondVar *cvar;
+    PRLock    *lock;
+
+    mon = PR_NEWZAP( PRMonitor );
+    if( mon )
+    {
+	lock = PR_NewLock();
+	if( !lock )
+        {
+	    PR_DELETE( mon );
+	    return( 0 );
+	}
+
+	cvar = PR_NewCondVar( lock );
+	if( !cvar )
+	{
+	    PR_DestroyLock( lock );
+	    PR_DELETE( mon );
+	    return( 0 );
+	}
+
+	mon->cvar = cvar;
+	mon->name = NULL;
+    }
+
+    return( mon );
+}
+
+PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name)
+{
+    PRMonitor* mon = PR_NewMonitor();
+    if( mon )
+    {
+        mon->name = name;
+    }
+    return mon;
+}
+
+/*
+** Destroy a monitor. The caller is responsible for guaranteeing that the
+** monitor is no longer in use. There must be no thread waiting on the
+** monitor's condition variable and that the lock is not held.
+**
+*/
+PR_IMPLEMENT(void)
+    PR_DestroyMonitor (PRMonitor *mon)
+{
+    PR_DestroyLock( mon->cvar->lock );
+    PR_DestroyCondVar( mon->cvar );
+    PR_DELETE( mon );
+}
+
+/*
+** Enter the lock associated with the monitor. If the calling thread currently
+** is in the monitor, the call to enter will silently succeed. In either case,
+** it will increment the entry count by one.
+*/
+PR_IMPLEMENT(void)
+    PR_EnterMonitor (PRMonitor *mon)
+{
+    if( mon->cvar->lock->owner == find_thread( NULL ) )
+    {
+	mon->entryCount++;
+
+    } else
+    {
+	PR_Lock( mon->cvar->lock );
+	mon->entryCount = 1;
+    }
+}
+
+/*
+** Decrement the entry count associated with the monitor. If the decremented
+** entry count is zero, the monitor is exited. Returns PR_FAILURE if the
+** calling thread has not entered the monitor.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_ExitMonitor (PRMonitor *mon)
+{
+    if( mon->cvar->lock->owner != find_thread( NULL ) )
+    {
+	return( PR_FAILURE );
+    }
+    if( --mon->entryCount == 0 )
+    {
+	return( PR_Unlock( mon->cvar->lock ) );
+    }
+    return( PR_SUCCESS );
+}
+
+/*
+** Wait for a notify on the monitor's condition variable. Sleep for "ticks"
+** amount of time (if "ticks" is PR_INTERVAL_NO_TIMEOUT then the sleep is
+** indefinite).
+**
+** While the thread is waiting it exits the monitor (as if it called
+** PR_ExitMonitor as many times as it had called PR_EnterMonitor).  When
+** the wait has finished the thread regains control of the monitors lock
+** with the same entry count as before the wait began.
+**
+** The thread waiting on the monitor will be resumed when the monitor is
+** notified (assuming the thread is the next in line to receive the
+** notify) or when the "ticks" timeout elapses.
+**
+** Returns PR_FAILURE if the caller has not entered the monitor.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_Wait (PRMonitor *mon, PRIntervalTime ticks)
+{
+    PRUint32 entryCount;
+    PRUintn  status;
+    PRThread *meThread;
+    thread_id me = find_thread( NULL );
+    meThread = PR_GetCurrentThread();
+
+    if( mon->cvar->lock->owner != me ) return( PR_FAILURE );
+
+    entryCount = mon->entryCount;
+    mon->entryCount = 0;
+
+    status = PR_WaitCondVar( mon->cvar, ticks );
+
+    mon->entryCount = entryCount;
+
+    return( status );
+}
+
+/*
+** Notify a thread waiting on the monitor's condition variable. If a thread
+** is waiting on the condition variable (using PR_Wait) then it is awakened
+** and attempts to reenter the monitor.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_Notify (PRMonitor *mon)
+{
+    if( mon->cvar->lock->owner != find_thread( NULL ) )
+    {
+	return( PR_FAILURE );
+    }
+
+    PR_NotifyCondVar( mon->cvar );
+    return( PR_SUCCESS );
+}
+
+/*
+** Notify all of the threads waiting on the monitor's condition variable.
+** All of threads waiting on the condition are scheduled to reenter the
+** monitor.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_NotifyAll (PRMonitor *mon)
+{
+    if( mon->cvar->lock->owner != find_thread( NULL ) )
+    {
+	return( PR_FAILURE );
+    }
+
+    PR_NotifyAllCondVar( mon->cvar );
+    return( PR_SUCCESS );
+}
+
+PR_IMPLEMENT(PRIntn)
+    PR_GetMonitorEntryCount(PRMonitor *mon)
+{
+    return( mon->entryCount );
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btsem.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btsem.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 <kernel/OS.h>
+
+#include "primpl.h"
+
+/*
+** Create a new semaphore object.
+*/
+PR_IMPLEMENT(PRSemaphore*)
+    PR_NewSem (PRUintn value)
+{
+	PRSemaphore *semaphore;
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	semaphore = PR_NEWZAP(PRSemaphore);
+	if (NULL != semaphore) {
+		if ((semaphore->sem = create_sem(value, "nspr_sem")) < B_NO_ERROR)
+			return NULL;
+		else 
+			return semaphore;
+	}
+	return NULL;
+}
+
+/*
+** Destroy the given semaphore object.
+**
+*/
+PR_IMPLEMENT(void)
+    PR_DestroySem (PRSemaphore *sem)
+{
+	status_t result;
+
+	PR_ASSERT(sem != NULL);
+	result = delete_sem(sem->sem);
+	PR_ASSERT(result == B_NO_ERROR);
+	PR_DELETE(sem);
+} 
+
+/*
+** Wait on a Semaphore.
+** 
+** This routine allows a calling thread to wait or proceed depending upon
+** the state of the semahore sem. The thread can proceed only if the
+** counter value of the semaphore sem is currently greater than 0. If the
+** value of semaphore sem is positive, it is decremented by one and the
+** routine returns immediately allowing the calling thread to continue. If
+** the value of semaphore sem is 0, the calling thread blocks awaiting the
+** semaphore to be released by another thread.
+** 
+** This routine can return PR_PENDING_INTERRUPT if the waiting thread 
+** has been interrupted.
+*/
+PR_IMPLEMENT(PRStatus)
+    PR_WaitSem (PRSemaphore *sem)
+{
+	PR_ASSERT(sem != NULL);
+	if (acquire_sem(sem->sem) == B_NO_ERROR)
+		return PR_SUCCESS;
+	else
+		return PR_FAILURE;
+}
+
+/*
+** This routine increments the counter value of the semaphore. If other
+** threads are blocked for the semaphore, then the scheduler will
+** determine which ONE thread will be unblocked.
+*/
+PR_IMPLEMENT(void)
+    PR_PostSem (PRSemaphore *sem)
+{
+	status_t result;
+
+	PR_ASSERT(sem != NULL);
+	result = release_sem_etc(sem->sem, 1, B_DO_NOT_RESCHEDULE);
+	PR_ASSERT(result == B_NO_ERROR);
+}
+
+/*
+** Returns the value of the semaphore referenced by sem without affecting
+** the state of the semaphore.  The value represents the semaphore value
+** at the time of the call, but may not be the actual value when the
+** caller inspects it.
+*/
+PR_IMPLEMENT(PRUintn)
+    PR_GetValueSem (PRSemaphore *sem)
+{
+	sem_info	info;
+
+	PR_ASSERT(sem != NULL);
+	get_sem_info(sem->sem, &info);
+	return info.count;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btthread.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/btthread.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,694 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 <kernel/OS.h>
+#include <support/TLS.h>
+
+#include "prlog.h"
+#include "primpl.h"
+#include "prcvar.h"
+#include "prpdce.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+/* values for PRThread.state */
+#define BT_THREAD_PRIMORD   0x01    /* this is the primordial thread */
+#define BT_THREAD_SYSTEM    0x02    /* this is a system thread */
+#define BT_THREAD_JOINABLE  0x04	/* this is a joinable thread */
+
+struct _BT_Bookeeping
+{
+    PRLock *ml;                 /* a lock to protect ourselves */
+	sem_id cleanUpSem;		/* the primoridal thread will block on this
+							   sem while waiting for the user threads */
+    PRInt32 threadCount;	/* user thred count */
+
+} bt_book = { NULL, B_ERROR, 0 };
+
+
+#define BT_TPD_LIMIT 128	/* number of TPD slots we'll provide (arbitrary) */
+
+/* these will be used to map an index returned by PR_NewThreadPrivateIndex()
+   to the corresponding beos native TLS slot number, and to the destructor
+   for that slot - note that, because it is allocated globally, this data
+   will be automatically zeroed for us when the program begins */
+static int32 tpd_beosTLSSlots[BT_TPD_LIMIT];
+static PRThreadPrivateDTOR tpd_dtors[BT_TPD_LIMIT];
+
+static vint32 tpd_slotsUsed=0;	/* number of currently-allocated TPD slots */
+static int32 tls_prThreadSlot;	/* TLS slot in which PRThread will be stored */
+
+/* this mutex will be used to synchronize access to every
+   PRThread.md.joinSem and PRThread.md.is_joining (we could
+   actually allocate one per thread, but that seems a bit excessive,
+   especially considering that there will probably be little
+   contention, PR_JoinThread() is allowed to block anyway, and the code
+   protected by the mutex is short/fast) */
+static PRLock *joinSemLock;
+
+static PRUint32 _bt_MapNSPRToNativePriority( PRThreadPriority priority );
+static PRThreadPriority _bt_MapNativeToNSPRPriority( PRUint32 priority );
+static void _bt_CleanupThread(void *arg);
+static PRThread *_bt_AttachThread();
+
+void
+_PR_InitThreads (PRThreadType type, PRThreadPriority priority,
+                 PRUintn maxPTDs)
+{
+    PRThread *primordialThread;
+    PRUint32  beThreadPriority;
+
+	/* allocate joinSem mutex */
+	joinSemLock = PR_NewLock();
+	if (joinSemLock == NULL)
+	{
+		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+		return;
+    }
+
+    /*
+    ** Create and initialize NSPR structure for our primordial thread.
+    */
+    
+    primordialThread = PR_NEWZAP(PRThread);
+    if( NULL == primordialThread )
+    {
+        PR_SetError( PR_OUT_OF_MEMORY_ERROR, 0 );
+        return;
+    }
+
+	primordialThread->md.joinSem = B_ERROR;
+
+    /*
+    ** Set the priority to the desired level.
+    */
+
+    beThreadPriority = _bt_MapNSPRToNativePriority( priority );
+    
+    set_thread_priority( find_thread( NULL ), beThreadPriority );
+    
+    primordialThread->priority = priority;
+
+
+	/* set the thread's state - note that the thread is not joinable */
+    primordialThread->state |= BT_THREAD_PRIMORD;
+	if (type == PR_SYSTEM_THREAD)
+		primordialThread->state |= BT_THREAD_SYSTEM;
+
+    /*
+    ** Allocate a TLS slot for the PRThread structure (just using
+    ** native TLS, as opposed to NSPR TPD, will make PR_GetCurrentThread()
+    ** somewhat faster, and will leave one more TPD slot for our client)
+    */
+	
+	tls_prThreadSlot = tls_allocate();
+
+    /*
+    ** Stuff our new PRThread structure into our thread specific
+    ** slot.
+    */
+
+	tls_set(tls_prThreadSlot, primordialThread);
+    
+	/* allocate lock for bt_book */
+    bt_book.ml = PR_NewLock();
+    if( NULL == bt_book.ml )
+    {
+    	PR_SetError( PR_OUT_OF_MEMORY_ERROR, 0 );
+	return;
+    }
+}
+
+PRUint32
+_bt_MapNSPRToNativePriority( PRThreadPriority priority )
+    {
+    switch( priority )
+    {
+    	case PR_PRIORITY_LOW:	 return( B_LOW_PRIORITY );
+	case PR_PRIORITY_NORMAL: return( B_NORMAL_PRIORITY );
+	case PR_PRIORITY_HIGH:	 return( B_DISPLAY_PRIORITY );
+	case PR_PRIORITY_URGENT: return( B_URGENT_DISPLAY_PRIORITY );
+	default:		 return( B_NORMAL_PRIORITY );
+    }
+}
+
+PRThreadPriority
+_bt_MapNativeToNSPRPriority(PRUint32 priority)
+    {
+	if (priority < B_NORMAL_PRIORITY)
+		return PR_PRIORITY_LOW;
+	if (priority < B_DISPLAY_PRIORITY)
+		return PR_PRIORITY_NORMAL;
+	if (priority < B_URGENT_DISPLAY_PRIORITY)
+		return PR_PRIORITY_HIGH;
+	return PR_PRIORITY_URGENT;
+}
+
+PRUint32
+_bt_mapNativeToNSPRPriority( int32 priority )
+{
+    switch( priority )
+    {
+    	case PR_PRIORITY_LOW:	 return( B_LOW_PRIORITY );
+	case PR_PRIORITY_NORMAL: return( B_NORMAL_PRIORITY );
+	case PR_PRIORITY_HIGH:	 return( B_DISPLAY_PRIORITY );
+	case PR_PRIORITY_URGENT: return( B_URGENT_DISPLAY_PRIORITY );
+	default:		 return( B_NORMAL_PRIORITY );
+    }
+}
+
+/* This method is called by all NSPR threads as they exit */
+void _bt_CleanupThread(void *arg)
+{
+	PRThread *me = PR_GetCurrentThread();
+	int32 i;
+
+	/* first, clean up all thread-private data */
+	for (i = 0; i < tpd_slotsUsed; i++)
+	{
+		void *oldValue = tls_get(tpd_beosTLSSlots[i]);
+		if ( oldValue != NULL && tpd_dtors[i] != NULL )
+			(*tpd_dtors[i])(oldValue);
+	}
+
+	/* if this thread is joinable, wait for someone to join it */
+	if (me->state & BT_THREAD_JOINABLE)
+	{
+		/* protect access to our joinSem */
+		PR_Lock(joinSemLock);
+
+		if (me->md.is_joining)
+		{
+			/* someone is already waiting to join us (they've
+			   allocated a joinSem for us) - let them know we're
+			   ready */
+			delete_sem(me->md.joinSem);
+
+			PR_Unlock(joinSemLock);
+
+		}
+		else
+    {
+			/* noone is currently waiting for our demise - it
+			   is our responsibility to allocate the joinSem
+			   and block on it */
+			me->md.joinSem = create_sem(0, "join sem");
+
+			/* we're done accessing our joinSem */
+			PR_Unlock(joinSemLock);
+
+			/* wait for someone to join us */
+			while (acquire_sem(me->md.joinSem) == B_INTERRUPTED);
+	    }
+	}
+
+	/* if this is a user thread, we must update our books */
+	if ((me->state & BT_THREAD_SYSTEM) == 0)
+	{
+		/* synchronize access to bt_book */
+    PR_Lock( bt_book.ml );
+
+		/* decrement the number of currently-alive user threads */
+	bt_book.threadCount--;
+
+		if (bt_book.threadCount == 0 && bt_book.cleanUpSem != B_ERROR) {
+			/* we are the last user thread, and the primordial thread is
+			   blocked in PR_Cleanup() waiting for us to finish - notify
+			   it */
+			delete_sem(bt_book.cleanUpSem);
+	}
+
+    PR_Unlock( bt_book.ml );
+	}
+
+	/* finally, delete this thread's PRThread */
+	PR_DELETE(me);
+}
+
+/**
+ * This is a wrapper that all threads invoke that allows us to set some
+ * things up prior to a thread's invocation and clean up after a thread has
+ * exited.
+ */
+static void*
+_bt_root (void* arg)
+	{
+    PRThread *thred = (PRThread*)arg;
+    PRIntn rv;
+    void *privData;
+    status_t result;
+    int i;
+
+	/* save our PRThread object into our TLS */
+	tls_set(tls_prThreadSlot, thred);
+
+    thred->startFunc(thred->arg);  /* run the dang thing */
+
+	/* clean up */
+	_bt_CleanupThread(NULL);
+
+	return 0;
+}
+
+PR_IMPLEMENT(PRThread*)
+    PR_CreateThread (PRThreadType type, void (*start)(void* arg), void* arg,
+                     PRThreadPriority priority, PRThreadScope scope,
+                     PRThreadState state, PRUint32 stackSize)
+{
+    PRUint32 bePriority;
+
+    PRThread* thred;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	thred = PR_NEWZAP(PRThread);
+ 	if (thred == NULL)
+	{
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+
+    thred->md.joinSem = B_ERROR;
+
+        thred->arg = arg;
+        thred->startFunc = start;
+        thred->priority = priority;
+
+	if( state == PR_JOINABLE_THREAD )
+	{
+	    thred->state |= BT_THREAD_JOINABLE;
+	}
+
+        /* keep some books */
+
+	PR_Lock( bt_book.ml );
+
+	if (type == PR_USER_THREAD)
+	{
+	    bt_book.threadCount++;
+        }
+
+	PR_Unlock( bt_book.ml );
+
+	bePriority = _bt_MapNSPRToNativePriority( priority );
+
+        thred->md.tid = spawn_thread((thread_func)_bt_root, "moz-thread",
+                                     bePriority, thred);
+        if (thred->md.tid < B_OK) {
+            PR_SetError(PR_UNKNOWN_ERROR, thred->md.tid);
+            PR_DELETE(thred);
+			return NULL;
+        }
+
+        if (resume_thread(thred->md.tid) < B_OK) {
+            PR_SetError(PR_UNKNOWN_ERROR, 0);
+            PR_DELETE(thred);
+			return NULL;
+        }
+
+    return thred;
+    }
+
+PR_IMPLEMENT(PRThread*)
+	PR_AttachThread(PRThreadType type, PRThreadPriority priority,
+					PRThreadStack *stack)
+{
+	/* PR_GetCurrentThread() will attach a thread if necessary */
+	return PR_GetCurrentThread();
+}
+
+PR_IMPLEMENT(void)
+	PR_DetachThread()
+{
+	/* we don't support detaching */
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_JoinThread (PRThread* thred)
+{
+    status_t eval, status;
+
+    PR_ASSERT(thred != NULL);
+
+	if ((thred->state & BT_THREAD_JOINABLE) == 0)
+    {
+	PR_SetError( PR_INVALID_ARGUMENT_ERROR, 0 );
+	return( PR_FAILURE );
+    }
+
+	/* synchronize access to the thread's joinSem */
+	PR_Lock(joinSemLock);
+	
+	if (thred->md.is_joining)
+	{
+		/* another thread is already waiting to join the specified
+		   thread - we must fail */
+		PR_Unlock(joinSemLock);
+		return PR_FAILURE;
+	}
+
+	/* let others know we are waiting to join */
+	thred->md.is_joining = PR_TRUE;
+
+	if (thred->md.joinSem == B_ERROR)
+	{
+		/* the thread hasn't finished yet - it is our responsibility to
+		   allocate a joinSem and wait on it */
+		thred->md.joinSem = create_sem(0, "join sem");
+
+		/* we're done changing the joinSem now */
+		PR_Unlock(joinSemLock);
+
+		/* wait for the thread to finish */
+		while (acquire_sem(thred->md.joinSem) == B_INTERRUPTED);
+
+	}
+	else
+	{
+		/* the thread has already finished, and has allocated the
+		   joinSem itself - let it know it can finally die */
+		delete_sem(thred->md.joinSem);
+		
+		PR_Unlock(joinSemLock);
+    }
+
+	/* make sure the thread is dead */
+    wait_for_thread(thred->md.tid, &eval);
+
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRThread*)
+    PR_GetCurrentThread ()
+{
+    PRThread* thred;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    thred = (PRThread *)tls_get( tls_prThreadSlot);
+	if (thred == NULL)
+	{
+		/* this thread doesn't have a PRThread structure (it must be
+		   a native thread not created by the NSPR) - assimilate it */
+		thred = _bt_AttachThread();
+	}
+    PR_ASSERT(NULL != thred);
+
+    return thred;
+}
+
+PR_IMPLEMENT(PRThreadScope)
+    PR_GetThreadScope (const PRThread* thred)
+{
+    PR_ASSERT(thred != NULL);
+    return PR_GLOBAL_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadType)
+    PR_GetThreadType (const PRThread* thred)
+{
+    PR_ASSERT(thred != NULL);
+    return (thred->state & BT_THREAD_SYSTEM) ?
+        PR_SYSTEM_THREAD : PR_USER_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadState)
+    PR_GetThreadState (const PRThread* thred)
+{
+    PR_ASSERT(thred != NULL);
+    return (thred->state & BT_THREAD_JOINABLE)?
+    					PR_JOINABLE_THREAD: PR_UNJOINABLE_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadPriority)
+    PR_GetThreadPriority (const PRThread* thred)
+{
+    PR_ASSERT(thred != NULL);
+    return thred->priority;
+}  /* PR_GetThreadPriority */
+
+PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred,
+                                        PRThreadPriority newPri)
+{
+    PRUint32 bePriority;
+
+    PR_ASSERT( thred != NULL );
+
+    thred->priority = newPri;
+    bePriority = _bt_MapNSPRToNativePriority( newPri );
+    set_thread_priority( thred->md.tid, bePriority );
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_NewThreadPrivateIndex (PRUintn* newIndex,
+                              PRThreadPrivateDTOR destructor)
+{
+	int32    index;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	/* reserve the next available tpd slot */
+	index = atomic_add( &tpd_slotsUsed, 1 );
+	if (index >= BT_TPD_LIMIT)
+	{
+		/* no slots left - decrement value, then fail */
+		atomic_add( &tpd_slotsUsed, -1 );
+		PR_SetError( PR_TPD_RANGE_ERROR, 0 );
+	    return( PR_FAILURE );
+	}
+
+	/* allocate a beos-native TLS slot for this index (the new slot
+	   automatically contains NULL) */
+	tpd_beosTLSSlots[index] = tls_allocate();
+
+	/* remember the destructor */
+	tpd_dtors[index] = destructor;
+
+    *newIndex = (PRUintn)index;
+
+    return( PR_SUCCESS );
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_SetThreadPrivate (PRUintn index, void* priv)
+{
+	void *oldValue;
+
+    /*
+    ** Sanity checking
+    */
+
+    if(index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT)
+    {
+		PR_SetError( PR_TPD_RANGE_ERROR, 0 );
+	return( PR_FAILURE );
+    }
+
+	/* if the old value isn't NULL, and the dtor for this slot isn't
+	   NULL, we must destroy the data */
+	oldValue = tls_get(tpd_beosTLSSlots[index]);
+	if (oldValue != NULL && tpd_dtors[index] != NULL)
+		(*tpd_dtors[index])(oldValue);
+
+	/* save new value */
+	tls_set(tpd_beosTLSSlots[index], priv);
+
+	    return( PR_SUCCESS );
+	}
+
+PR_IMPLEMENT(void*)
+    PR_GetThreadPrivate (PRUintn index)
+{
+	/* make sure the index is valid */
+	if (index < 0 || index >= tpd_slotsUsed || index >= BT_TPD_LIMIT)
+    {   
+		PR_SetError( PR_TPD_RANGE_ERROR, 0 );
+		return NULL;
+    }
+
+	/* return the value */
+	return tls_get( tpd_beosTLSSlots[index] );
+	}
+
+
+PR_IMPLEMENT(PRStatus)
+    PR_Interrupt (PRThread* thred)
+{
+    PRIntn rv;
+
+    PR_ASSERT(thred != NULL);
+
+    /*
+    ** there seems to be a bug in beos R5 in which calling
+    ** resume_thread() on a blocked thread returns B_OK instead
+    ** of B_BAD_THREAD_STATE (beos bug #20000422-19095).  as such,
+    ** to interrupt a thread, we will simply suspend then resume it
+    ** (no longer call resume_thread(), check for B_BAD_THREAD_STATE,
+    ** the suspend/resume to wake up a blocked thread).  this wakes
+    ** up blocked threads properly, and doesn't hurt unblocked threads
+    ** (they simply get stopped then re-started immediately)
+    */
+
+    rv = suspend_thread( thred->md.tid );
+    if( rv != B_NO_ERROR )
+    {
+        /* this doesn't appear to be a valid thread_id */
+        PR_SetError( PR_UNKNOWN_ERROR, rv );
+        return PR_FAILURE;
+    }
+
+    rv = resume_thread( thred->md.tid );
+    if( rv != B_NO_ERROR )
+    {
+        PR_SetError( PR_UNKNOWN_ERROR, rv );
+        return PR_FAILURE;
+    }
+
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(void)
+    PR_ClearInterrupt ()
+{
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_Yield ()
+{
+    /* we just sleep for long enough to cause a reschedule (100
+       microseconds) */
+    snooze(100);
+}
+
+#define BT_MILLION 1000000UL
+
+PR_IMPLEMENT(PRStatus)
+    PR_Sleep (PRIntervalTime ticks)
+{
+    bigtime_t tps;
+    status_t status;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    tps = PR_IntervalToMicroseconds( ticks );
+
+    status = snooze(tps);
+    if (status == B_NO_ERROR) return PR_SUCCESS;
+
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, status);
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+    PR_Cleanup ()
+{
+    PRThread *me = PR_GetCurrentThread();
+
+    PR_ASSERT(me->state & BT_THREAD_PRIMORD);
+    if ((me->state & BT_THREAD_PRIMORD) == 0) {
+        return PR_FAILURE;
+    }
+
+    PR_Lock( bt_book.ml );
+
+	if (bt_book.threadCount != 0)
+    {
+		/* we'll have to wait for some threads to finish - create a
+		   sem to block on */
+		bt_book.cleanUpSem = create_sem(0, "cleanup sem");
+    }
+
+    PR_Unlock( bt_book.ml );
+
+	/* note that, if all the user threads were already dead, we
+	   wouldn't have created a sem above, so this acquire_sem()
+	   will fail immediately */
+	while (acquire_sem(bt_book.cleanUpSem) == B_INTERRUPTED);
+
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(void)
+    PR_ProcessExit (PRIntn status)
+{
+    exit(status);
+}
+
+PRThread *_bt_AttachThread()
+{
+	PRThread *thread;
+	thread_info tInfo;
+
+	/* make sure this thread doesn't already have a PRThread structure */
+	PR_ASSERT(tls_get(tls_prThreadSlot) == NULL);
+
+	/* allocate a PRThread structure for this thread */
+	thread = PR_NEWZAP(PRThread);
+	if (thread == NULL)
+	{
+		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+		return NULL;
+	}
+
+	/* get the native thread's current state */
+	get_thread_info(find_thread(NULL), &tInfo);
+
+	/* initialize new PRThread */
+	thread->md.tid = tInfo.thread;
+	thread->md.joinSem = B_ERROR;
+	thread->priority = _bt_MapNativeToNSPRPriority(tInfo.priority);
+
+	/* attached threads are always non-joinable user threads */
+	thread->state = 0;
+
+	/* increment user thread count */
+	PR_Lock(bt_book.ml);
+	bt_book.threadCount++;
+	PR_Unlock(bt_book.ml);
+
+	/* store this thread's PRThread */
+	tls_set(tls_prThreadSlot, thread);
+	
+	/* the thread must call _bt_CleanupThread() before it dies, in order
+	   to clean up its PRThread, synchronize with the primordial thread,
+	   etc. */
+	on_exit_thread(_bt_CleanupThread, NULL);
+	
+	return thread;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/objs.mk
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/bthreads/objs.mk	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,43 @@
+# 
+# ***** 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 *****
+
+# This makefile appends to the variable OBJS the bthread object modules
+# that will be part of the nspr20 library.
+
+include $(srcdir)/bthreads/bsrcs.mk
+
+OBJS += $(BTCSRCS:%.c=bthreads/$(OBJDIR)/%.$(OBJ_SUFFIX))

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,25 @@
+/.cvsignore/1.2/Sat May 12 06:01:46 2001//
+/Makefile.in/1.10/Sun Apr 25 15:00:57 2004//
+/rcascii.h/1.5/Sun Apr 25 15:00:57 2004//
+/rcbase.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/rcbase.h/1.5/Sun Apr 25 15:00:57 2004//
+/rccv.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/rccv.h/1.5/Sun Apr 25 15:00:57 2004//
+/rcfileio.cpp/1.6/Sun Apr 25 15:00:57 2004//
+/rcfileio.h/1.6/Sun Apr 25 15:00:57 2004//
+/rcinrval.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/rcinrval.h/1.5/Sun Apr 25 15:00:57 2004//
+/rcio.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/rcio.h/1.6/Sun Apr 25 15:00:57 2004//
+/rclock.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/rclock.h/1.5/Sun Apr 25 15:00:57 2004//
+/rcmon.h/1.5/Sun Apr 25 15:00:57 2004//
+/rcnetdb.cpp/1.7/Sun Apr 25 15:00:57 2004//
+/rcnetdb.h/1.5/Sun Apr 25 15:00:57 2004//
+/rcnetio.cpp/1.6/Sun Apr 25 15:00:57 2004//
+/rcnetio.h/1.6/Sun Apr 25 15:00:57 2004//
+/rcthread.cpp/1.6/Mon Nov  7 22:39:00 2005//
+/rcthread.h/1.5/Sun Apr 25 15:00:57 2004//
+/rctime.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/rctime.h/1.5/Sun Apr 25 15:00:57 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+A D/tests////

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/cplus

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,75 @@
+# 
+# ***** 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
+
+CXXSRCS =           \
+	rcbase.cpp      \
+	rccv.cpp		\
+	rcfileio.cpp    \
+	rcinrval.cpp	\
+	rcio.cpp	    \
+	rclock.cpp	    \
+	rcnetdb.cpp	    \
+	rcnetio.cpp	    \
+	rcthread.cpp	\
+	rctime.cpp      \
+	$(NULL)
+
+OBJS = $(addprefix $(OBJDIR)/,$(CXXSRCS:.cpp=.$(OBJ_SUFFIX)))
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir)
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+HEADERS = $(wildcard $(srcdir)/*.h)
+
+export:: $(TARGETS)
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcascii.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcascii.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,175 @@
+/* -*- 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 ***** */
+
+/*
+** Class definitions to format ASCII data.
+*/
+
+#if defined(_RCASCII_H)
+#else
+#define _RCASCII_H
+
+/*
+** RCFormatStuff
+**  This class maintains no state - that is the responsibility of
+**  the class' client. For each call to Sx_printf(), the StuffFunction
+**  will be called for each embedded "%" in the 'fmt' string and once
+**  for each interveaning literal.
+*/
+class PR_IMPLEMENT(RCFormatStuff)
+{
+public:
+    RCFormatStuff();
+    virtual ~RCFormatStuff();
+
+    /*
+    ** Process the arbitrary argument list using as indicated by
+    ** the 'fmt' string. Each segment of the processing the stuff
+    ** function is called with the relavent translation.
+    */
+    virtual PRInt32 Sx_printf(void *state, const char *fmt, ...);
+
+    /*
+    ** The 'state' argument is not processed by the runtime. It
+    ** is merely passed from the Sx_printf() call. It is intended
+    ** to be used by the client to figure out what to do with the
+    ** new string.
+    **
+    ** The new string ('stuff') is ASCII translation driven by the
+    ** Sx_printf()'s 'fmt' string. It is not guaranteed to be a null
+    ** terminated string.
+    **
+    ** The return value is the number of bytes copied from the 'stuff'
+    ** string. It is accumulated for each of the calls to the stuff
+    ** function and returned from the original caller of Sx_printf().
+    */
+    virtual PRSize StuffFunction(
+        void *state, const char *stuff, PRSize stufflen) = 0;
+};  /* RCFormatStuff */
+
+
+/*
+** RCFormatBuffer
+**  The caller is supplying the buffer, the runtime is doing all
+**  the conversion. The object contains no state, so is reusable
+**  and reentrant.
+*/
+class PR_IMPLEMENT(RCFormatBuffer): public RCFormatStuff
+{
+public:
+    RCFormatBuffer();
+    virtual ~RCFormatBuffer();
+
+    /*
+    ** Format the trailing arguments as indicated by the 'fmt'
+    ** string. Put the result in 'buffer'. Return the number
+    ** of bytes moved into 'buffer'. 'buffer' will always be
+    ** a properly terminated string even if the convresion fails.
+    */
+    virtual PRSize Sn_printf(
+        char *buffer, PRSize length, const char *fmt, ...);
+
+    virtual char *Sm_append(char *buffer, const char *fmt, ...);
+
+private:
+    /*
+    ** This class overrides the stuff function, does not preserve
+    ** its virtual-ness and no longer allows the clients to call
+    ** it in the clear. In other words, it is now the implementation
+    ** for this class.
+    */
+    PRSize StuffFunction(void*, const char*, PRSize);
+        
+};  /* RCFormatBuffer */
+
+/*
+** RCFormat
+**  The runtime is supplying the buffer. The object has state - the
+**  buffer. Each operation must run to completion before the object
+**  can be reused. When it is, the buffer is reset (whatever that
+**  means). The result of a conversion is available via the extractor.
+**  After extracted, the memory still belongs to the class - if the
+**  caller wants to retain or modify, it must first be copied.
+*/
+class PR_IMPLEMENT(RCFormat): pubic RCFormatBuffer
+{
+public:
+    RCFormat();
+    virtual ~RCFormat();
+
+    /*
+    ** Translate the trailing arguments according to the 'fmt'
+    ** string and store the results in the object.
+    */
+    virtual PRSize Sm_printf(const char *fmt, ...);
+
+    /*
+    ** Extract the latest translation.
+    ** The object does not surrender the memory occupied by
+    ** the string. If the caller wishes to modify the data,
+    ** it must first be copied.
+    */
+    const char*();
+
+private:
+    char *buffer;
+
+    RCFormat(const RCFormat&);
+    RCFormat& operator=(const RCFormat&);
+}; /* RCFormat */
+
+/*
+** RCPrint
+**  The output is formatted and then written to an associated file
+**  descriptor. The client can provide a suitable file descriptor
+**  or can indicate that the output should be directed to one of
+**  the well-known "console" devices.
+*/
+class PR_IMPLEMENT(RCPrint): public RCFormat
+{
+    virtual ~RCPrint();
+    RCPrint(RCIO* output);
+    RCPrint(RCFileIO::SpecialFile output);
+
+    virtual PRSize Printf(const char *fmt, ...);
+private:
+    RCPrint();
+};  /* RCPrint */
+
+#endif /* defined(_RCASCII_H) */
+
+/* RCAscii.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcbase.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcbase.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,55 @@
+/* -*- 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 ***** */
+
+/*
+** RCBase.cpp - Mixin class for NSPR C++ wrappers
+*/
+
+#include "rcbase.h"
+
+RCBase::~RCBase() { }
+
+PRSize RCBase::GetErrorTextLength() { return PR_GetErrorTextLength(); }
+PRSize RCBase::CopyErrorText(char *text) { return PR_GetErrorText(text); }
+
+void RCBase::SetError(PRErrorCode error, PRInt32 oserror)
+    { PR_SetError(error, oserror); }
+
+void RCBase::SetErrorText(PRSize text_length, const char *text)
+    { PR_SetErrorText(text_length, text); }
+
+/* rcbase.cpp */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcbase.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcbase.h	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+** RCBase.h - Mixin class for NSPR C++ wrappers
+*/
+
+#if defined(_RCRUNTIME_H)
+#else
+#define _RCRUNTIME_H
+
+#include <prerror.h>
+
+/*
+** Class: RCBase (mixin)
+**
+** Generally mixed into every base class. The functions in this class are all
+** static. Therefore this entire class is just syntatic sugar. It gives the
+** illusion that errors (in particular) are retrieved via the same object
+** that just reported a failure. It also (unfortunately) might lead one to
+** believe that the errors are persistent in that object. They're not.
+*/
+
+class PR_IMPLEMENT(RCBase)
+{
+public:
+    virtual ~RCBase();
+
+    static void AbortSelf();
+
+    static PRErrorCode GetError();
+    static PRInt32 GetOSError();
+
+    static PRSize GetErrorTextLength();
+    static PRSize CopyErrorText(char *text);
+
+    static void SetError(PRErrorCode error, PRInt32 oserror);
+    static void SetErrorText(PRSize textLength, const char *text);
+
+protected:
+    RCBase() { }
+};  /* RCObject */
+
+inline PRErrorCode RCBase::GetError() { return PR_GetError(); }
+inline PRInt32 RCBase::GetOSError() { return PR_GetOSError(); }
+
+#endif  /* defined(_RCRUNTIME_H) */
+
+/* rcbase.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rccv.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rccv.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,97 @@
+/* -*- 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 ***** */
+
+/*
+** RCCondition - C++ wrapper around NSPR's PRCondVar
+*/
+
+#include "rccv.h"
+
+#include <prlog.h>
+#include <prerror.h>
+#include <prcvar.h>
+
+RCCondition::RCCondition(class RCLock *lock): RCBase()
+{
+    cv = PR_NewCondVar(lock->lock);
+    PR_ASSERT(NULL != cv);
+    timeout = PR_INTERVAL_NO_TIMEOUT;
+}  /* RCCondition::RCCondition */
+
+RCCondition::~RCCondition()
+{
+    if (NULL != cv) PR_DestroyCondVar(cv);
+}  /* RCCondition::~RCCondition */
+
+PRStatus RCCondition::Wait()
+{
+    PRStatus rv;
+    PR_ASSERT(NULL != cv);
+    if (NULL == cv)
+    {
+        SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        rv = PR_FAILURE;
+    }
+    else
+        rv = PR_WaitCondVar(cv, timeout.interval);
+    return rv;
+}  /* RCCondition::Wait */
+
+PRStatus RCCondition::Notify()
+{
+    return PR_NotifyCondVar(cv);
+}  /* RCCondition::Notify */
+
+PRStatus RCCondition::Broadcast()
+{
+    return PR_NotifyAllCondVar(cv);
+}  /* RCCondition::Broadcast */
+
+PRStatus RCCondition::SetTimeout(const RCInterval& tmo)
+{
+    if (NULL == cv)
+    {
+        SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    timeout = tmo;
+    return PR_SUCCESS;
+}  /* RCCondition::SetTimeout */
+
+RCInterval RCCondition::GetTimeout() const { return timeout; }
+
+/* rccv.cpp */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rccv.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rccv.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,96 @@
+/* -*- 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 ***** */
+
+/*
+** RCCondition - C++ wrapper around NSPR's PRCondVar
+**
+** Conditions have a notion of timeouts. A thread that waits on a condition
+** will resume execution when the condition is notified OR when a specified
+** interval of time has expired.
+**
+** Most applications don't adjust the timeouts on conditions. The literature
+** would argue that all threads waiting on a single condition must have the
+** same semantics. But if an application wishes to modify the timeout with
+** (perhaps) each wait call, that modification should be done consistantly
+** and under protection of the condition's associated lock.
+**
+** The default timeout is infinity.
+*/
+
+#if defined(_RCCOND_H)
+#else
+#define _RCCOND_H
+
+#include "rclock.h"
+#include "rcbase.h"
+#include "rcinrval.h"
+
+struct PRCondVar;
+
+class PR_IMPLEMENT(RCCondition): public RCBase
+{
+public:
+    RCCondition(RCLock*);           /* associates CV with a lock and infinite tmo */
+    virtual ~RCCondition();
+
+    virtual PRStatus Wait();        /* applies object's current timeout */
+
+    virtual PRStatus Notify();      /* perhaps ready one thread */
+    virtual PRStatus Broadcast();   /* perhaps ready many threads */
+
+    virtual PRStatus SetTimeout(const RCInterval&);
+                                    /* set object's current timeout value */
+
+private:
+    PRCondVar *cv;
+    RCInterval timeout;
+
+    RCCondition();
+    RCCondition(const RCCondition&);
+    void operator=(const RCCondition&);
+
+public:
+    RCInterval GetTimeout() const;
+};  /* RCCondition */
+
+inline RCCondition::RCCondition(): RCBase() { }
+inline RCCondition::RCCondition(const RCCondition&): RCBase() { }
+inline void RCCondition::operator=(const RCCondition&) { }
+
+#endif /* defined(_RCCOND_H) */
+
+/* RCCond.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcfileio.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcfileio.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,199 @@
+/* -*- 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 ***** */
+
+/*
+** Class implementation for normal and special file I/O (ref: prio.h)
+*/
+
+#include "rcfileio.h"
+
+#include <string.h>
+
+RCFileIO::RCFileIO(): RCIO(RCIO::file) { }
+
+RCFileIO::~RCFileIO() { if (NULL != fd) (void)Close(); }
+
+PRInt64 RCFileIO::Available()
+    { return fd->methods->available(fd); }
+
+PRStatus RCFileIO::Close()
+    { PRStatus rv = fd->methods->close(fd); fd = NULL; return rv; }
+
+PRStatus RCFileIO::Delete(const char* filename) { return PR_Delete(filename); }
+
+PRStatus RCFileIO::FileInfo(RCFileInfo* info) const
+    { return fd->methods->fileInfo64(fd, &info->info); }
+
+PRStatus RCFileIO::FileInfo(const char *name, RCFileInfo* info)
+    { return PR_GetFileInfo64(name, &info->info); }
+
+PRStatus RCFileIO::Fsync()
+    { return fd->methods->fsync(fd); }
+
+PRStatus RCFileIO::Open(const char *filename, PRIntn flags, PRIntn mode)
+{
+    fd = PR_Open(filename, flags, mode);
+    return (NULL == fd) ? PR_FAILURE : PR_SUCCESS;
+}  /* RCFileIO::Open */
+
+PRInt32 RCFileIO::Read(void *buf, PRSize amount)
+    { return fd->methods->read(fd, buf, amount); }
+
+PRInt64 RCFileIO::Seek(PRInt64 offset, RCIO::Whence how)
+{
+    PRSeekWhence whence;
+    switch (how)
+    {
+        case RCFileIO::set: whence = PR_SEEK_SET; break;
+        case RCFileIO::current: whence = PR_SEEK_CUR; break;
+        case RCFileIO::end: whence = PR_SEEK_END; break;
+        default: whence = (PRSeekWhence)-1;
+    }
+    return fd->methods->seek64(fd, offset, whence);
+}  /* RCFileIO::Seek */
+
+PRInt32 RCFileIO::Write(const void *buf, PRSize amount)
+    { return fd->methods->write(fd, buf, amount); }
+
+PRInt32 RCFileIO::Writev(
+    const PRIOVec *iov, PRSize size, const RCInterval& timeout)
+    { return fd->methods->writev(fd, iov, size, timeout); }
+
+RCIO *RCFileIO::GetSpecialFile(RCFileIO::SpecialFile special)
+{
+    PRFileDesc* fd;
+    PRSpecialFD which;
+    RCFileIO* spec = NULL;
+
+    switch (special)
+    {
+        case RCFileIO::input: which = PR_StandardInput; break;
+        case RCFileIO::output: which = PR_StandardOutput; break;
+        case RCFileIO::error: which = PR_StandardError; break;
+        default: which = (PRSpecialFD)-1;
+    }
+    fd = PR_GetSpecialFD(which);
+    if (NULL != fd)
+    {
+        spec = new RCFileIO();
+        if (NULL != spec) spec->fd = fd;
+    }
+    return spec;
+}  /* RCFileIO::GetSpecialFile */
+
+
+/*
+** The following methods have been made non-virtual and private. These
+** default implementations are intended to NEVER be called. They
+** are not valid for this type of I/O class (normal and special file).
+*/
+PRStatus RCFileIO::Connect(const RCNetAddr&, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCFileIO::GetLocalName(RCNetAddr*) const
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCFileIO::GetPeerName(RCNetAddr*) const
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCFileIO::GetSocketOption(PRSocketOptionData*) const
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCFileIO::Listen(PRIntn)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRInt16 RCFileIO::Poll(PRInt16, PRInt16*)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return 0; }
+
+PRInt32 RCFileIO::Recv(void*, PRSize, PRIntn, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+PRInt32 RCFileIO::Recvfrom(void*, PRSize, PRIntn, RCNetAddr*, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+PRInt32 RCFileIO::Send(
+    const void*, PRSize, PRIntn, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+PRInt32 RCFileIO::Sendto(
+    const void*, PRSize, PRIntn, const RCNetAddr&, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+RCIO* RCFileIO::Accept(RCNetAddr*, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return NULL; }
+
+PRStatus RCFileIO::Bind(const RCNetAddr&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRInt32 RCFileIO::AcceptRead(
+    RCIO**, RCNetAddr**, void*, PRSize, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+PRStatus RCFileIO::SetSocketOption(const PRSocketOptionData*)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCFileIO::Shutdown(RCIO::ShutdownHow)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRInt32 RCFileIO::TransmitFile(
+    RCIO*, const void*, PRSize, RCIO::FileDisposition, const RCInterval&)
+{ PR_SetError(PR_INVALID_METHOD_ERROR, 0); return -1; }
+
+/*
+** Class implementation for file information object (ref: prio.h)
+*/
+
+RCFileInfo::~RCFileInfo() { }
+
+RCFileInfo::RCFileInfo(const RCFileInfo& her): RCBase()
+    { info = her.info; }  /* RCFileInfo::RCFileInfo */
+
+RCTime RCFileInfo::CreationTime() const { return RCTime(info.creationTime); }
+
+RCTime RCFileInfo::ModifyTime() const { return RCTime(info.modifyTime); }
+
+RCFileInfo::FileType RCFileInfo::Type() const
+{
+    RCFileInfo::FileType type;
+    switch (info.type)
+    {
+        case PR_FILE_FILE: type = RCFileInfo::file; break;
+        case PR_FILE_DIRECTORY: type = RCFileInfo::directory; break;
+        default: type = RCFileInfo::other;
+    }
+    return type;
+}  /* RCFileInfo::Type */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcfileio.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcfileio.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,161 @@
+/* -*- 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 ***** */
+
+/*
+** Class definitions for normal and special file I/O (ref: prio.h)
+*/
+
+#if defined(_RCFILEIO_H)
+#else
+#define _RCFILEIO_H
+
+#include "rcio.h"
+#include "rctime.h"
+
+/*
+** One would normally create a concrete class, such as RCFileIO, but then
+** pass around more generic references, ie., RCIO.
+**
+** This subclass of RCIO hides (makes private) the methods that are not
+** applicable to normal files.
+*/
+
+class RCFileInfo;
+
+class PR_IMPLEMENT(RCFileIO): public RCIO
+{
+public:
+    RCFileIO();
+    virtual ~RCFileIO();
+
+    virtual PRInt64     Available();
+    virtual PRStatus    Close();
+    static  PRStatus    Delete(const char *name);
+    virtual PRStatus    FileInfo(RCFileInfo* info) const;
+    static  PRStatus    FileInfo(const char *name, RCFileInfo* info);
+    virtual PRStatus    Fsync();
+    virtual PRStatus    Open(const char *name, PRIntn flags, PRIntn mode);
+    virtual PRInt32     Read(void *buf, PRSize amount);
+    virtual PRInt64     Seek(PRInt64 offset, RCIO::Whence how);
+    virtual PRInt32     Write(const void *buf, PRSize amount);
+    virtual PRInt32     Writev(
+                            const PRIOVec *iov, PRSize size,
+                            const RCInterval& timeout);
+
+private:
+
+    /* These methods made private are unavailable for this object */
+    RCFileIO(const RCFileIO&);
+    void operator=(const RCFileIO&);
+
+    RCIO*       Accept(RCNetAddr* addr, const RCInterval& timeout);
+    PRInt32     AcceptRead(
+                    RCIO **newfd, RCNetAddr **address, void *buffer,
+                    PRSize amount, const RCInterval& timeout);
+    PRStatus    Bind(const RCNetAddr& addr);
+    PRStatus    Connect(const RCNetAddr& addr, const RCInterval& timeout);
+    PRStatus    GetLocalName(RCNetAddr *addr) const;
+    PRStatus    GetPeerName(RCNetAddr *addr) const;
+    PRStatus    GetSocketOption(PRSocketOptionData *data) const;
+    PRStatus    Listen(PRIntn backlog);
+    PRInt16     Poll(PRInt16 in_flags, PRInt16 *out_flags);
+    PRInt32     Recv(
+                    void *buf, PRSize amount, PRIntn flags,
+                    const RCInterval& timeout);
+    PRInt32     Recvfrom(
+                    void *buf, PRSize amount, PRIntn flags,
+                    RCNetAddr* addr, const RCInterval& timeout);
+    PRInt32     Send(
+                    const void *buf, PRSize amount, PRIntn flags,
+                    const RCInterval& timeout);
+    PRInt32     Sendto(
+                    const void *buf, PRSize amount, PRIntn flags,
+                    const RCNetAddr& addr,
+                    const RCInterval& timeout);
+    PRStatus    SetSocketOption(const PRSocketOptionData *data);
+    PRStatus    Shutdown(RCIO::ShutdownHow how);
+    PRInt32     TransmitFile(
+                    RCIO *source, const void *headers,
+                    PRSize hlen, RCIO::FileDisposition flags,
+                    const RCInterval& timeout);
+public:
+
+    /*
+    ** The following function return a valid normal file object,
+    ** Such objects can be used for scanned input and console output.
+    */
+    typedef enum {
+        input = PR_StandardInput,
+        output = PR_StandardOutput,
+        error = PR_StandardError
+    } SpecialFile;
+
+    static RCIO *GetSpecialFile(RCFileIO::SpecialFile special);
+
+};  /* RCFileIO */
+
+class PR_IMPLEMENT(RCFileInfo): public RCBase
+{
+public:
+    typedef enum {
+        file = PR_FILE_FILE,
+        directory = PR_FILE_DIRECTORY,
+        other = PR_FILE_OTHER
+    } FileType;
+
+public:
+    RCFileInfo();
+    RCFileInfo(const RCFileInfo&);
+
+    virtual ~RCFileInfo();
+
+    PRInt64 Size() const;
+    RCTime CreationTime() const;
+    RCTime ModifyTime() const;
+    RCFileInfo::FileType Type() const;
+
+friend PRStatus RCFileIO::FileInfo(RCFileInfo*) const;
+friend PRStatus RCFileIO::FileInfo(const char *name, RCFileInfo*);
+
+private:
+    PRFileInfo64 info;
+};  /* RCFileInfo */
+
+inline RCFileInfo::RCFileInfo(): RCBase() { }
+inline PRInt64 RCFileInfo::Size() const { return info.size; }
+
+#endif /* defined(_RCFILEIO_H) */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcinrval.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcinrval.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,69 @@
+/* -*- 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 ***** */
+
+/*
+** C++ interval times (ref: prinrval.h)
+**
+**  An interval is a period of time. The start of the interval (epoch)
+**  must be defined by the application. The unit of time of an interval
+**  is platform dependent, therefore so is the maximum interval that is
+**  representable. However, that interval is never less that ~12 hours.
+*/
+
+#include "rcinrval.h"
+
+RCInterval::~RCInterval() { }
+
+RCInterval::RCInterval(RCInterval::RCReservedInterval special): RCBase()
+{
+    switch (special)
+    {
+    case RCInterval::now:
+        interval = PR_IntervalNow();
+        break;
+    case RCInterval::no_timeout:
+        interval = PR_INTERVAL_NO_TIMEOUT;
+        break;
+    case RCInterval::no_wait:
+        interval = PR_INTERVAL_NO_WAIT;
+        break;
+    default:
+        break;
+    }
+}  /* RCInterval::RCInterval */
+
+/* rcinrval.cpp */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcinrval.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcinrval.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,169 @@
+/* -*- 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 ***** */
+
+/*
+** C++ interval times (ref: prinrval.h)
+**
+**  An interval is a period of time. The start of the interval (epoch)
+**  must be defined by the application. The unit of time of an interval
+**  is platform dependent, therefore so is the maximum interval that is
+**  representable. However, that interval is never less than ~6 hours.
+*/
+#if defined(_RCINTERVAL_H)
+#else
+#define _RCINTERVAL_H
+
+#include "rcbase.h"
+#include <prinrval.h>
+
+class PR_IMPLEMENT(RCInterval): public RCBase
+{
+public:
+    typedef enum {now, no_timeout, no_wait} RCReservedInterval;
+
+    virtual ~RCInterval();
+
+    RCInterval();
+
+    RCInterval(PRIntervalTime interval);
+    RCInterval(const RCInterval& copy);
+    RCInterval(RCReservedInterval special);
+
+    void SetToNow();
+
+    void operator=(const RCInterval&);
+    void operator=(PRIntervalTime interval);
+
+    PRBool operator<(const RCInterval&);
+    PRBool operator>(const RCInterval&);
+    PRBool operator==(const RCInterval&);
+    PRBool operator>=(const RCInterval&);
+    PRBool operator<=(const RCInterval&);
+
+    RCInterval operator+(const RCInterval&);
+    RCInterval operator-(const RCInterval&);
+    RCInterval& operator+=(const RCInterval&);
+    RCInterval& operator-=(const RCInterval&);
+
+    RCInterval operator/(PRUint32);
+    RCInterval operator*(PRUint32);
+    RCInterval& operator/=(PRUint32);
+    RCInterval& operator*=(PRUint32);
+
+
+    PRUint32 ToSeconds() const;
+    PRUint32 ToMilliseconds() const;
+    PRUint32 ToMicroseconds() const;
+    operator PRIntervalTime() const;
+
+    static PRIntervalTime FromSeconds(PRUint32 seconds);
+    static PRIntervalTime FromMilliseconds(PRUint32 milli);
+    static PRIntervalTime FromMicroseconds(PRUint32 micro);
+
+    friend class RCCondition;
+
+private:
+    PRIntervalTime interval;
+    
+};  /* RCInterval */
+
+
+inline RCInterval::RCInterval(): RCBase() { }
+
+inline RCInterval::RCInterval(const RCInterval& his): RCBase()
+    { interval = his.interval; }
+
+inline RCInterval::RCInterval(PRIntervalTime ticks): RCBase()
+    { interval = ticks; }
+
+inline void RCInterval::SetToNow() { interval = PR_IntervalNow(); }
+
+inline void RCInterval::operator=(const RCInterval& his)
+    { interval = his.interval; }
+
+inline void RCInterval::operator=(PRIntervalTime his)
+    { interval = his; }
+
+inline PRBool RCInterval::operator==(const RCInterval& his)
+    { return (interval == his.interval) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCInterval::operator<(const RCInterval& his)
+    { return (interval < his.interval)? PR_TRUE : PR_FALSE; }
+inline PRBool RCInterval::operator>(const RCInterval& his)
+    { return (interval > his.interval) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCInterval::operator<=(const RCInterval& his)
+    { return (interval <= his.interval) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCInterval::operator>=(const RCInterval& his)
+    { return (interval <= his.interval) ? PR_TRUE : PR_FALSE; }
+
+inline RCInterval RCInterval::operator+(const RCInterval& his)
+    { return RCInterval((PRIntervalTime)(interval + his.interval)); }
+inline RCInterval RCInterval::operator-(const RCInterval& his)
+    { return RCInterval((PRIntervalTime)(interval - his.interval)); }
+inline RCInterval& RCInterval::operator+=(const RCInterval& his)
+    { interval += his.interval; return *this; }
+inline RCInterval& RCInterval::operator-=(const RCInterval& his)
+    { interval -= his.interval; return *this; }
+
+inline RCInterval RCInterval::operator/(PRUint32 him)
+    { return RCInterval((PRIntervalTime)(interval / him)); }
+inline RCInterval RCInterval::operator*(PRUint32 him)
+    { return RCInterval((PRIntervalTime)(interval * him)); }
+
+inline RCInterval& RCInterval::operator/=(PRUint32 him)
+    { interval /= him; return *this; }
+
+inline RCInterval& RCInterval::operator*=(PRUint32 him)
+    { interval *= him; return *this; }
+
+inline PRUint32 RCInterval::ToSeconds() const
+    { return PR_IntervalToSeconds(interval); }
+inline PRUint32 RCInterval::ToMilliseconds() const
+    { return PR_IntervalToMilliseconds(interval); }
+inline PRUint32 RCInterval::ToMicroseconds() const
+    { return PR_IntervalToMicroseconds(interval); }
+inline RCInterval::operator PRIntervalTime() const { return interval; }
+
+inline PRIntervalTime RCInterval::FromSeconds(PRUint32 seconds)
+    { return PR_SecondsToInterval(seconds); }
+inline PRIntervalTime RCInterval::FromMilliseconds(PRUint32 milli)
+    { return PR_MillisecondsToInterval(milli); }
+inline PRIntervalTime RCInterval::FromMicroseconds(PRUint32 micro)
+    { return PR_MicrosecondsToInterval(micro); }
+
+#endif  /* defined(_RCINTERVAL_H) */
+
+/* RCInterval.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcio.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcio.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,46 @@
+/* -*- 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 ***** */
+
+/*
+** Base class implmenation for I/O (ref: prio.h)
+*/
+
+#include "rcio.h"
+
+RCIO::~RCIO() { }
+
+RCIO::RCIO(RCIO::RCIOType): RCBase() { }

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcio.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcio.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,148 @@
+/* -*- 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 ***** */
+
+/*
+** Base class definitions for I/O (ref: prio.h)
+**
+** This class is a virtual base class. Construction must be done by a
+** subclass, but the I/O operations can be done on a RCIO object reference.
+*/
+
+#if defined(_RCIO_H)
+#else
+#define _RCIO_H
+
+#include "rcbase.h"
+#include "rcnetdb.h"
+#include "rcinrval.h"
+
+#include "prio.h"
+
+class RCFileInfo;
+
+class PR_IMPLEMENT(RCIO): public RCBase
+{
+public:
+    typedef enum {
+        open = PR_TRANSMITFILE_KEEP_OPEN,   /* socket is left open after file
+                                             * is transmitted. */
+        close = PR_TRANSMITFILE_CLOSE_SOCKET/* socket is closed after file
+                                             * is transmitted. */
+    } FileDisposition;
+
+    typedef enum {
+        set = PR_SEEK_SET,                  /* Set to value specified */
+        current = PR_SEEK_CUR,              /* Seek relative to current position */
+        end = PR_SEEK_END                   /* seek past end of current eof */
+    } Whence;
+
+    typedef enum {
+        recv = PR_SHUTDOWN_RCV,             /* receives will be disallowed */
+        send = PR_SHUTDOWN_SEND,            /* sends will be disallowed */
+        both = PR_SHUTDOWN_BOTH             /* sends & receives will be disallowed */
+    } ShutdownHow;
+
+public:
+    virtual ~RCIO();
+
+    virtual RCIO*       Accept(RCNetAddr* addr, const RCInterval& timeout) = 0;
+    virtual PRInt32     AcceptRead(
+                            RCIO **nd, RCNetAddr **raddr, void *buf,
+                            PRSize amount, const RCInterval& timeout) = 0;
+    virtual PRInt64     Available() = 0;
+    virtual PRStatus    Bind(const RCNetAddr& addr) = 0;
+    virtual PRStatus    Close() = 0;
+    virtual PRStatus    Connect(
+                            const RCNetAddr& addr,
+                            const RCInterval& timeout) = 0;
+    virtual PRStatus    FileInfo(RCFileInfo *info) const = 0;
+    virtual PRStatus    Fsync() = 0;
+    virtual PRStatus    GetLocalName(RCNetAddr *addr) const = 0;
+    virtual PRStatus    GetPeerName(RCNetAddr *addr) const = 0;
+    virtual PRStatus    GetSocketOption(PRSocketOptionData *data) const = 0;
+    virtual PRStatus    Listen(PRIntn backlog) = 0;
+    virtual PRStatus    Open(const char *name, PRIntn flags, PRIntn mode) = 0;
+    virtual PRInt16     Poll(PRInt16 in_flags, PRInt16 *out_flags) = 0;
+    virtual PRInt32     Read(void *buf, PRSize amount) = 0;
+    virtual PRInt32     Recv(
+                            void *buf, PRSize amount, PRIntn flags,
+                            const RCInterval& timeout) = 0;
+    virtual PRInt32     Recvfrom(
+                            void *buf, PRSize amount, PRIntn flags,
+                            RCNetAddr* addr, const RCInterval& timeout) = 0;
+    virtual PRInt64     Seek(PRInt64 offset, Whence how) = 0;
+    virtual PRInt32     Send(
+                            const void *buf, PRSize amount, PRIntn flags,
+                            const RCInterval& timeout) = 0;
+    virtual PRInt32     Sendto(
+                            const void *buf, PRSize amount, PRIntn flags,
+                            const RCNetAddr& addr,
+                            const RCInterval& timeout) = 0;
+    virtual PRStatus    SetSocketOption(const PRSocketOptionData *data) = 0;
+    virtual PRStatus    Shutdown(ShutdownHow how) = 0;
+    virtual PRInt32     TransmitFile(
+                            RCIO *source, const void *headers,
+                            PRSize hlen, RCIO::FileDisposition flags,
+                            const RCInterval& timeout) = 0;
+    virtual PRInt32     Write(const void *buf, PRSize amount) = 0;
+    virtual PRInt32     Writev(
+                            const PRIOVec *iov, PRSize size,
+                            const RCInterval& timeout) = 0;
+
+protected:
+    typedef enum {
+        file = PR_DESC_FILE,
+        tcp = PR_DESC_SOCKET_TCP,
+        udp = PR_DESC_SOCKET_UDP,
+        layered = PR_DESC_LAYERED} RCIOType;
+
+    RCIO(RCIOType);
+
+    PRFileDesc *fd;  /* where the real code hides */
+
+private:
+    /* no default construction and no copies allowed */
+    RCIO();
+    RCIO(const RCIO&);
+
+};  /* RCIO */
+
+#endif /* defined(_RCIO_H) */
+
+/* RCIO.h */
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rclock.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rclock.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,72 @@
+/* -*- 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 ***** */
+/*
+** C++ access to NSPR locks (PRLock)
+*/
+
+#include "rclock.h"
+#include <prlog.h>
+
+RCLock::RCLock()
+{
+    lock = PR_NewLock();  /* it might be NULL */
+    PR_ASSERT(NULL != lock);
+}  /* RCLock::RCLock */
+
+RCLock::~RCLock()
+{
+    if (NULL != lock) PR_DestroyLock(lock);
+    lock = NULL;
+}  /* RCLock::~RCLock */
+
+void RCLock::Acquire()
+{
+    PR_ASSERT(NULL != lock);
+    PR_Lock(lock);
+}  /* RCLock::Acquire */
+
+void RCLock::Release()
+{
+    PRStatus rv;
+    PR_ASSERT(NULL != lock);
+    rv = PR_Unlock(lock);
+    PR_ASSERT(PR_SUCCESS == rv);
+}  /* RCLock::Release */
+
+/* RCLock.cpp */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rclock.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rclock.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,98 @@
+/* -*- 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 ***** */
+
+/*
+** C++ access to NSPR locks (PRLock)
+*/
+
+#if defined(_RCLOCK_H)
+#else
+#define _RCLOCK_H
+
+#include "rcbase.h"
+
+#include <prlock.h>
+
+class PR_IMPLEMENT(RCLock): public RCBase
+{
+public:
+    RCLock();
+    virtual ~RCLock();
+
+    void Acquire();                 /* non-reentrant */
+    void Release();                 /* should be by owning thread */
+
+    friend class RCCondition;
+
+private:
+    RCLock(const RCLock&);          /* can't do that */
+    void operator=(const RCLock&);  /* nor that */
+
+    PRLock *lock;
+};  /* RCLock */
+
+/*
+** Class: RCEnter
+**
+** In scope locks. You can only allocate them on the stack. The language
+** will insure that they get released (by calling the destructor) when
+** the thread leaves scope, even if via an exception.
+*/
+class PR_IMPLEMENT(RCEnter)
+{
+public:
+    ~RCEnter();                     /* releases the lock */
+    RCEnter(RCLock*);               /* acquires the lock */
+
+private:
+    RCLock *lock;
+
+    RCEnter();
+    RCEnter(const RCEnter&);
+    void operator=(const RCEnter&);
+
+    void *operator new(PRSize) { return NULL; }
+    void operator delete(void*) { }
+};  /* RCEnter */
+
+
+inline RCEnter::RCEnter(RCLock* ml) { lock = ml; lock->Acquire(); }
+inline RCEnter::~RCEnter() { lock->Release(); lock = NULL; }
+
+#endif /* defined(_RCLOCK_H) */
+
+/* RCLock.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcmon.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcmon.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,79 @@
+/* -*- 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 ***** */
+
+/*
+** Class: RCMonitor (ref prmonitor.h)
+**
+** RCMonitor.h - C++ wrapper around NSPR's monitors
+*/
+#if defined(_RCMONITOR_H)
+#else
+#define _RCMONITOR_H
+
+#include "rcbase.h"
+#include "rcinrval.h"
+
+struct PRMonitor;
+
+class PR_IMPLEMENT(RCMonitor): public RCBase
+{
+public:
+    RCMonitor();                    /* timeout is infinity */
+    virtual ~RCMonitor();
+
+    virtual void Enter();           /* reentrant entry */
+    virtual void Exit();
+
+    virtual void Notify();          /* possibly enable one thread */
+    virtual void NotifyAll();       /* enable all waiters */
+
+    virtual void Wait();            /* applies object's timeout */
+
+    virtual void SetTimeout(const RCInterval& timeout);
+
+private:
+    PRMonitor *monitor;
+    RCInterval timeout;
+
+public:
+    RCInterval GetTimeout() const;  /* get the current value */
+
+};  /* RCMonitor */
+
+#endif /* defined(_RCMONITOR_H) */
+
+/* RCMonitor.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetdb.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetdb.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,232 @@
+/* -*- 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 ***** */
+
+/*
+** Base class implementation for network access functions (ref: prnetdb.h)
+*/
+
+#include "rclock.h"
+#include "rcnetdb.h"
+
+#include <prmem.h>
+#include <prlog.h>
+#include <string.h>
+
+RCNetAddr::RCNetAddr(const RCNetAddr& his): RCBase()
+    { address = his.address; }
+
+RCNetAddr::RCNetAddr(const RCNetAddr& his, PRUint16 port): RCBase()
+{
+    address = his.address;
+    switch (address.raw.family)
+    {
+        case PR_AF_INET: address.inet.port = port; break;
+        case PR_AF_INET6: address.ipv6.port = port; break;
+        default: break;
+    }
+}  /* RCNetAddr::RCNetAddr */
+
+RCNetAddr::RCNetAddr(RCNetAddr::HostValue host, PRUint16 port): RCBase()
+{
+    PRNetAddrValue how;
+    switch (host)
+    {
+        case RCNetAddr::any: how = PR_IpAddrAny; break;
+        case RCNetAddr::loopback: how = PR_IpAddrLoopback; break;
+        default: PR_ASSERT(!"This can't happen -- and did!");
+    }
+    (void)PR_InitializeNetAddr(how, port, &address);
+}  /* RCNetAddr::RCNetAddr */
+
+RCNetAddr::~RCNetAddr() { }
+
+void RCNetAddr::operator=(const RCNetAddr& his) { address = his.address; }
+
+PRStatus RCNetAddr::FromString(const char* string)
+    { return PR_StringToNetAddr(string, &address); }
+
+void RCNetAddr::operator=(const PRNetAddr* addr) { address = *addr; }
+
+PRBool RCNetAddr::operator==(const RCNetAddr& his) const
+{
+    PRBool rv = EqualHost(his);
+    if (rv)
+    {
+        switch (address.raw.family)
+        {
+            case PR_AF_INET:
+                rv = (address.inet.port == his.address.inet.port); break;
+            case PR_AF_INET6:
+                rv = (address.ipv6.port == his.address.ipv6.port); break;
+            case PR_AF_LOCAL:
+            default: break;
+        }
+    }
+    return rv;
+}  /* RCNetAddr::operator== */
+
+PRBool RCNetAddr::EqualHost(const RCNetAddr& his) const
+{
+    PRBool rv;
+    switch (address.raw.family)
+    {
+        case PR_AF_INET:
+            rv = (address.inet.ip == his.address.inet.ip); break;
+        case PR_AF_INET6:
+            rv = (0 == memcmp(
+                &address.ipv6.ip, &his.address.ipv6.ip,
+                sizeof(address.ipv6.ip)));
+            break;
+#if defined(XP_UNIX)
+        case PR_AF_LOCAL:
+            rv = (0 == strncmp(
+                address.local.path, his.address.local.path,
+                sizeof(address.local.path)));
+            break;
+#endif
+        default: break;
+    }
+    return rv;
+}  /* RCNetAddr::operator== */
+
+PRStatus RCNetAddr::ToString(char *string, PRSize size) const
+    { return PR_NetAddrToString(&address, string, size); }
+
+/*
+** RCHostLookup
+*/
+
+RCHostLookup::~RCHostLookup()
+{
+    if (NULL != address) delete [] address;
+}  /* RCHostLookup::~RCHostLookup */
+
+RCHostLookup::RCHostLookup(): RCBase()
+{
+    address = NULL;
+    max_index = 0;
+}  /* RCHostLookup::RCHostLookup */
+
+PRStatus RCHostLookup::ByName(const char* name)
+{
+    PRStatus rv;
+    PRNetAddr addr;
+    PRHostEnt hostentry;
+    PRIntn index = 0, max;
+    RCNetAddr* vector = NULL;
+    RCNetAddr* old_vector = NULL;
+    void* buffer = PR_Malloc(PR_NETDB_BUF_SIZE);
+    if (NULL == buffer) return PR_FAILURE;
+    rv = PR_GetHostByName(name, (char*)buffer, PR_NETDB_BUF_SIZE, &hostentry);
+    if (PR_SUCCESS == rv)
+    {
+        for (max = 0, index = 0;; ++max)
+        {
+            index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
+            if (0 == index) break;
+        }
+        if (max > 0)
+        {
+            vector = new RCNetAddr[max];
+            while (--max > 0)
+            {
+                index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
+                if (0 == index) break;
+                vector[index] = &addr;
+            }
+            {
+                RCEnter entry(&ml);
+                old_vector = address;
+                address = vector;
+                max_index = max;
+            }
+            if (NULL != old_vector) delete [] old_vector;
+        }
+    }
+    if (NULL != buffer) PR_DELETE(buffer);
+    return PR_SUCCESS;
+}  /* RCHostLookup::ByName */
+
+PRStatus RCHostLookup::ByAddress(const RCNetAddr& host_addr)
+{
+    PRStatus rv;
+    PRNetAddr addr;
+    PRHostEnt hostentry;
+    PRIntn index = 0, max;
+    RCNetAddr* vector = NULL;
+    RCNetAddr* old_vector = NULL;
+    char *buffer = (char*)PR_Malloc(PR_NETDB_BUF_SIZE);
+    if (NULL == buffer) return PR_FAILURE;
+    rv = PR_GetHostByAddr(host_addr, buffer, PR_NETDB_BUF_SIZE, &hostentry);
+    if (PR_SUCCESS == rv)
+    {
+        for (max = 0, index = 0;; ++max)
+        {
+            index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
+            if (0 == index) break;
+        }
+        if (max > 0)
+        {
+            vector = new RCNetAddr[max];
+            while (--max > 0)
+            {
+                index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
+                if (0 == index) break;
+                vector[index] = &addr;
+            }
+            {
+                RCEnter entry(&ml);
+                old_vector = address;
+                address = vector;
+                max_index = max;
+            }
+            if (NULL != old_vector) delete [] old_vector;
+        }
+    }
+    if (NULL != buffer) PR_DELETE(buffer);
+    return PR_SUCCESS;
+}  /* RCHostLookup::ByAddress */
+
+const RCNetAddr* RCHostLookup::operator[](PRUintn which)
+{
+    RCNetAddr* addr = NULL;
+    if (which < max_index)
+        addr = &address[which];
+    return addr;
+}  /* RCHostLookup::operator[] */
+
+/* RCNetdb.cpp */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetdb.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetdb.h	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+** Base class definitions for network access functions (ref: prnetdb.h)
+*/
+
+#if defined(_RCNETDB_H)
+#else
+#define _RCNETDB_H
+
+#include "rclock.h"
+#include "rcbase.h"
+
+#include <prnetdb.h>
+
+class PR_IMPLEMENT(RCNetAddr): public RCBase
+{
+public:
+    typedef enum {
+        any = PR_IpAddrAny,             /* assign logical INADDR_ANY */
+        loopback = PR_IpAddrLoopback    /* assign logical INADDR_LOOPBACK */
+    } HostValue;
+
+    RCNetAddr();                        /* default constructor is unit'd object */
+    RCNetAddr(const RCNetAddr&);        /* copy constructor */
+    RCNetAddr(HostValue, PRUint16 port);/* init'd w/ 'special' assignments */
+    RCNetAddr(const RCNetAddr&, PRUint16 port);
+                                        /* copy w/ port reassigment */
+
+    virtual ~RCNetAddr();
+
+    void operator=(const RCNetAddr&);
+
+    virtual PRBool operator==(const RCNetAddr&) const;
+                                        /* compare of all relavent fields */
+    virtual PRBool EqualHost(const RCNetAddr&) const;
+                                        /* compare of just host field */
+
+
+public:
+
+    void operator=(const PRNetAddr*);   /* construction from more primitive data */
+    operator const PRNetAddr*() const;  /* extraction of underlying representation */
+    virtual PRStatus FromString(const char* string);
+                                        /* initialization from an ASCII string */
+    virtual PRStatus ToString(char *string, PRSize size) const;
+                                        /* convert internal fromat to a string */
+
+private:
+
+    PRNetAddr address;
+
+};  /* RCNetAddr */
+
+/*
+** Class: RCHostLookup
+**
+** Abstractions to look up host names and addresses.
+**
+** This is a stateful class. One looks up the host by name or by
+** address, then enumerates over a possibly empty array of network
+** addresses. The storage for the addresses is owned by the class.
+*/
+
+class RCHostLookup: public RCBase
+{
+public:
+    virtual ~RCHostLookup();
+
+    RCHostLookup();
+
+    virtual PRStatus ByName(const char* name);
+    virtual PRStatus ByAddress(const RCNetAddr&);
+
+    virtual const RCNetAddr* operator[](PRUintn);
+
+private:
+    RCLock ml;
+    PRIntn max_index;
+    RCNetAddr* address;
+
+    RCHostLookup(const RCHostLookup&);
+    RCHostLookup& operator=(const RCHostLookup&);
+};
+
+inline RCNetAddr::RCNetAddr(): RCBase() { }
+inline RCNetAddr::operator const PRNetAddr*() const { return &address; }
+
+
+#endif /* defined(_RCNETDB_H) */
+
+/* RCNetdb.h */
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetio.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetio.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,195 @@
+/* -*- 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 ***** */
+
+/*
+** Subclass implementation for streamed network I/O (ref: prio.h)
+*/
+
+#include "rcnetio.h"
+
+#include <private/pprio.h>
+
+RCNetStreamIO::~RCNetStreamIO()
+    { PRStatus rv = (fd->methods->close)(fd); fd = NULL; }
+
+RCNetStreamIO::RCNetStreamIO(): RCIO(RCIO::tcp)
+    { fd = PR_NewTCPSocket(); }
+
+RCNetStreamIO::RCNetStreamIO(PRIntn protocol): RCIO(RCIO::tcp)
+    { fd = PR_Socket(PR_AF_INET, PR_SOCK_STREAM, protocol); }
+
+RCIO* RCNetStreamIO::Accept(RCNetAddr* addr, const RCInterval& timeout)
+{
+    PRNetAddr peer;
+    RCNetStreamIO* rcio = NULL;
+    PRFileDesc* newfd = fd->methods->accept(fd, &peer, timeout);
+    if (NULL != newfd)
+    {
+        rcio = new RCNetStreamIO();
+        if (NULL != rcio)
+        {
+            *addr = &peer;
+            rcio->fd = newfd;
+        }
+        else
+            (void)(newfd->methods->close)(newfd);
+    }
+    return rcio;
+}  /* RCNetStreamIO::Accept */
+
+PRInt32 RCNetStreamIO::AcceptRead(
+    RCIO **nd, RCNetAddr **raddr, void *buf,
+    PRSize amount, const RCInterval& timeout)
+{   
+    PRNetAddr *from;
+    PRFileDesc *accepted;
+    PRInt32 rv = (fd->methods->acceptread)(
+        fd, &accepted, &from, buf, amount, timeout);
+    if (rv >= 0)
+    {
+        RCNetStreamIO *ns = new RCNetStreamIO();
+        if (NULL != *nd) ns->fd = accepted;
+        else {PR_Close(accepted); rv = -1; }
+        *nd = ns;
+    }
+    return rv;
+}  /* RCNetStreamIO::AcceptRead */
+
+PRInt64 RCNetStreamIO::Available()
+    { return (fd->methods->available64)(fd); }
+
+PRStatus RCNetStreamIO::Bind(const RCNetAddr& addr)
+    { return (fd->methods->bind)(fd, addr); }
+
+PRStatus RCNetStreamIO::Connect(const RCNetAddr& addr, const RCInterval& timeout)
+    { return (fd->methods->connect)(fd, addr, timeout); }
+
+PRStatus RCNetStreamIO::GetLocalName(RCNetAddr *addr) const
+{
+    PRNetAddr local;
+    PRStatus rv = (fd->methods->getsockname)(fd, &local);
+    if (PR_SUCCESS == rv) *addr = &local;
+    return rv;
+}  /* RCNetStreamIO::GetLocalName */
+
+PRStatus RCNetStreamIO::GetPeerName(RCNetAddr *addr) const
+{
+    PRNetAddr peer;
+    PRStatus rv = (fd->methods->getpeername)(fd, &peer);
+    if (PR_SUCCESS == rv) *addr = &peer;
+    return rv;
+}  /* RCNetStreamIO::GetPeerName */
+
+PRStatus RCNetStreamIO::GetSocketOption(PRSocketOptionData *data) const
+    { return (fd->methods->getsocketoption)(fd, data); }
+
+PRStatus RCNetStreamIO::Listen(PRIntn backlog)
+    { return (fd->methods->listen)(fd, backlog); }
+
+PRInt16 RCNetStreamIO::Poll(PRInt16 in_flags, PRInt16 *out_flags)
+    { return (fd->methods->poll)(fd, in_flags, out_flags); }
+
+PRInt32 RCNetStreamIO::Read(void *buf, PRSize amount)
+    { return (fd->methods->read)(fd, buf, amount); }
+
+PRInt32 RCNetStreamIO::Recv(
+    void *buf, PRSize amount, PRIntn flags, const RCInterval& timeout)
+    { return (fd->methods->recv)(fd, buf, amount, flags, timeout); }
+
+PRInt32 RCNetStreamIO::Recvfrom(
+    void *buf, PRSize amount, PRIntn flags,
+    RCNetAddr* addr, const RCInterval& timeout)
+{
+    PRNetAddr peer;
+    PRInt32 rv = (fd->methods->recvfrom)(
+        fd, buf, amount, flags, &peer, timeout);
+    if (-1 != rv) *addr = &peer;
+    return rv;
+}  /* RCNetStreamIO::Recvfrom */
+
+PRInt32 RCNetStreamIO::Send(
+    const void *buf, PRSize amount, PRIntn flags, const RCInterval& timeout)
+    { return (fd->methods->send)(fd, buf, amount, flags, timeout); }
+
+PRInt32 RCNetStreamIO::Sendto(
+    const void *buf, PRSize amount, PRIntn flags,
+    const RCNetAddr& addr, const RCInterval& timeout)
+    { return (fd->methods->sendto)(fd, buf, amount, flags, addr, timeout); }
+
+PRStatus RCNetStreamIO::SetSocketOption(const PRSocketOptionData *data)
+    { return (fd->methods->setsocketoption)(fd, data); }
+
+PRStatus RCNetStreamIO::Shutdown(RCIO::ShutdownHow how)
+    { return (fd->methods->shutdown)(fd, (PRIntn)how); }
+
+PRInt32 RCNetStreamIO::TransmitFile(
+    RCIO *source, const void *headers, PRSize hlen,
+    RCIO::FileDisposition flags, const RCInterval& timeout)
+{
+    RCNetStreamIO *src = (RCNetStreamIO*)source;
+    return (fd->methods->transmitfile)(
+        fd, src->fd, headers, hlen, (PRTransmitFileFlags)flags, timeout); }
+
+PRInt32 RCNetStreamIO::Write(const void *buf, PRSize amount)
+    { return (fd->methods->write)(fd, buf, amount); }
+
+PRInt32 RCNetStreamIO::Writev(
+    const PRIOVec *iov, PRSize size, const RCInterval& timeout)
+    { return (fd->methods->writev)(fd, iov, size, timeout); }
+    
+/*
+** Invalid functions
+*/
+
+PRStatus RCNetStreamIO::Close()
+    { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCNetStreamIO::FileInfo(RCFileInfo*) const
+    { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRStatus RCNetStreamIO::Fsync()
+    { return (fd->methods->fsync)(fd); }
+
+PRStatus RCNetStreamIO::Open(const char*, PRIntn, PRIntn)
+    { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+PRInt64 RCNetStreamIO::Seek(PRInt64, RCIO::Whence)
+    { PR_SetError(PR_INVALID_METHOD_ERROR, 0); return PR_FAILURE; }
+
+/* RCNetStreamIO.cpp */
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetio.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcnetio.h	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+** Subclass definitions for network I/O (ref: prio.h)
+*/
+
+#if defined(_RCNETIO_H)
+#else
+#define _RCNETIO_H
+
+#include "rcbase.h"
+#include "rcinrval.h"
+#include "rcio.h"
+#include "rcnetdb.h"
+
+#include "prio.h"
+
+class RCFileInfo;
+
+/*
+** Class: RCNetStreamIO (ref prio.h)
+**
+** Streamed (reliable) network I/O (e.g., TCP).
+** This class hides (makes private) the functions that are not applicable
+** to network I/O (i.e., those for file I/O).
+*/
+
+class PR_IMPLEMENT(RCNetStreamIO): public RCIO
+{
+
+public:
+    RCNetStreamIO();
+    virtual ~RCNetStreamIO();
+
+    virtual RCIO*       Accept(RCNetAddr* addr, const RCInterval& timeout);
+    virtual PRInt32     AcceptRead(
+                            RCIO **nd, RCNetAddr **raddr, void *buf,
+                            PRSize amount, const RCInterval& timeout);
+    virtual PRInt64     Available();
+    virtual PRStatus    Bind(const RCNetAddr& addr);
+    virtual PRStatus    Connect(
+                            const RCNetAddr& addr, const RCInterval& timeout);
+    virtual PRStatus    GetLocalName(RCNetAddr *addr) const;
+    virtual PRStatus    GetPeerName(RCNetAddr *addr) const;
+    virtual PRStatus    GetSocketOption(PRSocketOptionData *data) const;
+    virtual PRStatus    Listen(PRIntn backlog);
+    virtual PRInt16     Poll(PRInt16 in_flags, PRInt16 *out_flags);
+    virtual PRInt32     Read(void *buf, PRSize amount);
+    virtual PRInt32     Recv(
+                            void *buf, PRSize amount, PRIntn flags,
+                            const RCInterval& timeout);
+    virtual PRInt32     Recvfrom(
+                            void *buf, PRSize amount, PRIntn flags,
+                            RCNetAddr* addr, const RCInterval& timeout);
+    virtual PRInt32     Send(
+                            const void *buf, PRSize amount, PRIntn flags,
+                            const RCInterval& timeout);
+    virtual PRInt32     Sendto(
+                            const void *buf, PRSize amount, PRIntn flags,
+                            const RCNetAddr& addr,
+                            const RCInterval& timeout);
+    virtual PRStatus    SetSocketOption(const PRSocketOptionData *data);
+    virtual PRStatus    Shutdown(ShutdownHow how);
+    virtual PRInt32     TransmitFile(
+                            RCIO *source, const void *headers,
+                            PRSize hlen, RCIO::FileDisposition flags,
+                            const RCInterval& timeout);
+    virtual PRInt32     Write(const void *buf, PRSize amount);
+    virtual PRInt32     Writev(
+                            const PRIOVec *iov, PRSize size,
+                            const RCInterval& timeout);
+
+private:
+    /* functions unavailable to this clients of this class */
+    RCNetStreamIO(const RCNetStreamIO&);
+
+    PRStatus    Close();
+    PRStatus    Open(const char *name, PRIntn flags, PRIntn mode);
+    PRStatus    FileInfo(RCFileInfo *info) const;
+    PRStatus    Fsync();
+    PRInt64     Seek(PRInt64 offset, RCIO::Whence how);
+
+public:
+    RCNetStreamIO(PRIntn protocol);
+};  /* RCNetIO */
+
+#endif /* defined(_RCNETIO_H) */
+
+/* RCNetStreamIO.h */
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcthread.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcthread.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,220 @@
+/* -*- 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 ***** */
+
+/* RCThread.cpp - C++ wrapper on NSPR */
+
+#include "rcthread.h"
+#include "rcinrval.h"
+
+#include <prmem.h>
+#include <prlog.h>
+#include <stdio.h>
+#include <prinit.h>
+
+static RCPrimordialThread *primordial = NULL;
+
+void nas_Root(void *arg)
+{
+    RCThread *him = (RCThread*)arg;
+    while (RCThread::ex_unstarted == him->execution)
+        (void)PR_Sleep(PR_INTERVAL_NO_TIMEOUT);  /* wait for Start() */
+    him->RootFunction();  /* he gets a self reference */
+    if (PR_UNJOINABLE_THREAD == PR_GetThreadState(him->identity))
+        delete him;
+}  /* nas_Root */
+
+RCThread::~RCThread() { }
+
+RCThread::RCThread(): RCBase() { }
+
+RCThread::RCThread(const RCThread&): RCBase()
+{
+    PR_NOT_REACHED("Cannot call thread copy constructor");
+}  /* RCThread::RCThread */
+
+RCThread::RCThread(
+    RCThread::Scope scope, RCThread::State join, PRUint32 stackSize):
+    RCBase()
+{
+    execution = ex_unstarted;
+    identity = PR_CreateThread(
+        PR_USER_THREAD, nas_Root, this,
+        PR_GetThreadPriority(PR_GetCurrentThread()),
+        (PRThreadScope)scope, (PRThreadState)join, stackSize);
+}  /* RCThread::RCThread */
+
+void RCThread::operator=(const RCThread&)
+{
+    PR_NOT_REACHED("Cannot call thread assignment operator");
+}  /* RCThread::operator= */
+
+
+PRStatus RCThread::Start()
+{
+    PRStatus rv;
+    /* This is an unsafe check, but not too critical */
+    if (RCThread::ex_unstarted == execution)
+    {
+        execution = RCThread::ex_started;
+        rv = PR_Interrupt(identity);
+        PR_ASSERT(PR_SUCCESS == rv);
+    }
+    else
+    {
+        rv = PR_FAILURE;
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+    }
+    return rv;
+}  /* RCThread::Start */
+
+PRStatus RCThread::Join()
+{
+    PRStatus rv;
+    if (RCThread::ex_unstarted == execution)
+    {
+        rv = PR_FAILURE;
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+    }
+    else rv = PR_JoinThread(identity);
+    if (PR_SUCCESS == rv) delete this;
+    return rv;
+}  /* RCThread::Join */
+
+PRStatus RCThread::Interrupt()
+{
+    PRStatus rv;
+    if (RCThread::ex_unstarted == execution)
+    {
+        rv = PR_FAILURE;
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+    }
+    else rv = PR_Interrupt(identity);
+    return rv;
+}  /* RCThread::Interrupt */
+
+void RCThread::ClearInterrupt() { PR_ClearInterrupt(); }
+
+void RCThread::SetPriority(RCThread::Priority new_priority)
+    { PR_SetThreadPriority(identity, (PRThreadPriority)new_priority); }
+
+PRThread *RCThread::Self()
+    { return PR_GetCurrentThread(); }
+
+RCThread::Scope RCThread::GetScope() const
+    { return (RCThread::Scope)PR_GetThreadScope(identity); }
+
+RCThread::State RCThread::GetState() const
+    { return (RCThread::State)PR_GetThreadState(identity); }
+
+RCThread::Priority RCThread::GetPriority() const
+    { return (RCThread::Priority)PR_GetThreadPriority(identity); }
+    
+static void _rc_PDDestructor(RCThreadPrivateData* privateData)
+{
+    PR_ASSERT(NULL != privateData);
+    privateData->Release();
+}
+
+static PRThreadPrivateDTOR _tpd_dtor = (PRThreadPrivateDTOR)_rc_PDDestructor;
+
+PRStatus RCThread::NewPrivateIndex(PRUintn* index)
+    { return PR_NewThreadPrivateIndex(index, _tpd_dtor); }
+
+PRStatus RCThread::SetPrivateData(PRUintn index)
+    { return PR_SetThreadPrivate(index, NULL); }
+
+PRStatus RCThread::SetPrivateData(PRUintn index, RCThreadPrivateData* data)
+{
+    return PR_SetThreadPrivate(index, data);
+}
+
+RCThreadPrivateData* RCThread::GetPrivateData(PRUintn index)
+    { return (RCThreadPrivateData*)PR_GetThreadPrivate(index); }
+
+PRStatus RCThread::Sleep(const RCInterval& ticks)
+    { PRIntervalTime tmo = ticks; return PR_Sleep(tmo); }
+
+RCPrimordialThread *RCThread::WrapPrimordialThread()
+{
+    /*
+    ** This needs to take more care in insuring that the thread
+    ** being wrapped is really the primordial thread. This code
+    ** is assuming that the caller is the primordial thread, and
+    ** there's nothing to insure that.
+    */
+    if (NULL == primordial)
+    {
+        /* it doesn't have to be perfect */
+        RCPrimordialThread *me = new RCPrimordialThread();
+        PR_ASSERT(NULL != me);
+        if (NULL == primordial)
+        {
+            primordial = me;
+            me->execution = RCThread::ex_started;
+            me->identity = PR_GetCurrentThread();
+        }
+        else delete me;  /* somebody beat us to it */
+    }
+    return primordial;
+}  /* RCThread::WrapPrimordialThread */
+
+RCPrimordialThread::RCPrimordialThread(): RCThread() { }
+
+RCPrimordialThread::~RCPrimordialThread() { }
+
+void RCPrimordialThread::RootFunction()
+{
+    PR_NOT_REACHED("Primordial thread calling root function"); 
+}  /* RCPrimordialThread::RootFunction */
+ 
+PRStatus RCPrimordialThread::Cleanup() { return PR_Cleanup(); }
+
+PRStatus RCPrimordialThread::SetVirtualProcessors(PRIntn count)
+{
+    PR_SetConcurrency(count);
+    return PR_SUCCESS;
+}  /* SetVirutalProcessors */
+
+RCThreadPrivateData::RCThreadPrivateData() { }
+
+RCThreadPrivateData::RCThreadPrivateData(
+    const RCThreadPrivateData& him) { }
+
+RCThreadPrivateData::~RCThreadPrivateData() { }
+
+/* RCThread.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcthread.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rcthread.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,227 @@
+/* -*- 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 ***** */
+
+/* RCThread.h */
+
+#if defined(_RCTHREAD_H)
+#else
+#define _RCTHREAD_H
+
+#include "rcbase.h"
+
+#include <prthread.h>
+
+class RCInterval;
+
+class PR_IMPLEMENT(RCThreadPrivateData)
+{
+public:
+    RCThreadPrivateData();
+    RCThreadPrivateData(const RCThreadPrivateData&);
+
+    virtual ~RCThreadPrivateData();
+
+    virtual void Release() = 0;
+
+};  /* RCThreadPrivateData */
+
+class PR_IMPLEMENT(RCThread): public RCBase
+{
+public:
+
+    typedef enum 
+    {
+        local = PR_LOCAL_THREAD, global = PR_GLOBAL_THREAD
+    } Scope;
+
+    typedef enum
+    {
+        joinable = PR_JOINABLE_THREAD, unjoinable = PR_UNJOINABLE_THREAD
+    } State;
+
+    typedef enum
+    {
+        first = PR_PRIORITY_FIRST,
+        low = PR_PRIORITY_LOW,
+        normal = PR_PRIORITY_NORMAL,
+        high = PR_PRIORITY_HIGH,
+        urgent = PR_PRIORITY_URGENT,
+        last = PR_PRIORITY_LAST
+    } Priority;
+
+    /*
+     * Create a new thread, providing scope and joinability state.
+     */
+    RCThread(Scope scope, State state, PRUint32 stackSize=0);
+
+    /*
+     * New threads are created in a suspended state. It must be 'started"
+     * before it begins execution in the class' defined 'RootFunction()'.
+     */
+    virtual PRStatus Start();
+
+    /*
+     * If a thread is created joinable, then the thread's object exists
+     * until join is called. The thread that calls join will block until
+     * the target thread returns from it's root function.
+     */
+    virtual PRStatus Join();
+    
+    /*
+     * The priority of a newly created thread is the same as the creator.
+     * The priority may be changed either by the new thread itself, by
+     * the creator or any other arbitrary thread.
+     */   
+    virtual void SetPriority(Priority newPriority);
+
+
+    /*
+     * Interrupt another thread, causing it to stop what it
+     * is doing and return with a well known error code.
+     */
+    virtual PRStatus Interrupt();
+    
+    /*
+     * And in case a thread was interrupted and didn't get a chance
+     * to have the notification delivered, a way to cancel the pending
+     * status.
+     */
+    static void ClearInterrupt();
+    
+    /*
+     * Methods to discover the attributes of an existing thread.
+     */
+    static PRThread *Self();
+    Scope GetScope() const;
+    State GetState() const;
+    Priority GetPriority() const;
+
+    /*
+     * Thread private data
+     */
+    static PRStatus NewPrivateIndex(PRUintn* index);
+
+    /*
+     * Getting it - if you want to modify, make a copy
+     */
+    static RCThreadPrivateData* GetPrivateData(PRUintn index);
+
+    /*
+     * Setting it to <empty> - deletes existing data
+     */
+    static PRStatus SetPrivateData(PRUintn index);
+
+    /*
+     * Setting it - runtime will make a copy, freeing old iff necessary
+     */
+    static PRStatus SetPrivateData(PRUintn index, RCThreadPrivateData* data);
+
+    /*
+     * Scheduling control
+     */
+    static PRStatus Sleep(const RCInterval& ticks);
+
+    friend void nas_Root(void*);
+    friend class RCPrimordialThread;
+protected:
+
+    /*
+     * The instantiator of a class must not call the destructor. The base
+     * implementation of Join will, and if the thread is created unjoinable,
+     * then the code that called the RootFunction will call the desctructor.
+     */
+    virtual ~RCThread();
+
+private:
+
+    /*
+     * This is where a newly created thread begins execution. Returning
+     * from this function is equivalent to terminating the thread.
+     */
+    virtual void RootFunction() = 0;
+
+    PRThread *identity;
+
+    /* Threads are unstarted until started - pretty startling */
+    enum {ex_unstarted, ex_started} execution;
+
+    /* There is no public default constructor or copy constructor */
+    RCThread();
+    RCThread(const RCThread&);
+    
+    /* And there is no assignment operator */
+    void operator=(const RCThread&);
+
+public:
+    static RCPrimordialThread *WrapPrimordialThread();    
+
+ };
+ 
+/*
+** class RCPrimordialThread
+*/
+class PR_IMPLEMENT(RCPrimordialThread): public RCThread
+{
+public:
+    /*
+    ** The primordial thread can (optionally) wait for all created
+    ** threads to terminate before allowing the process to exit.
+    ** Not calling Cleanup() before returning from main() will cause
+    ** the immediate termination of the entire process, including
+    ** any running threads.
+    */
+    static PRStatus Cleanup();
+
+    /*
+    ** Only the primordial thread is allowed to adjust the number of
+    ** virtual processors of the runtime. It's a lame security thing.
+    */
+    static PRStatus SetVirtualProcessors(PRIntn count=10);
+
+friend class RCThread;
+private:
+    /*
+    ** None other than the runtime can create of destruct
+    ** a primordial thread. It is fabricated by the runtime
+    ** to wrap the thread that initiated the application.
+    */
+    RCPrimordialThread();
+    ~RCPrimordialThread();
+    void RootFunction();
+};  /* RCPrimordialThread */
+
+ #endif /* defined(_RCTHREAD_H) */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rctime.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rctime.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,66 @@
+/* -*- 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 ***** */
+
+/*
+** Class implementation for calendar time routines (ref: prtime.h)
+*/
+
+#include "rctime.h"
+
+RCTime::~RCTime() { }
+
+RCTime::RCTime(PRTime time): RCBase() { gmt = time; }
+RCTime::RCTime(const RCTime& his): RCBase() { gmt = his.gmt; }
+RCTime::RCTime(RCTime::Current): RCBase() { gmt = PR_Now(); }
+RCTime::RCTime(const PRExplodedTime& time): RCBase()
+{ gmt = PR_ImplodeTime(&time); }
+
+void RCTime::operator=(const PRExplodedTime& time)
+{ gmt = PR_ImplodeTime(&time); }
+
+RCTime RCTime::operator+(const RCTime& his)
+{ RCTime sum(gmt + his.gmt); return sum; }
+
+RCTime RCTime::operator-(const RCTime& his)
+{ RCTime difference(gmt - his.gmt); return difference; }
+
+RCTime RCTime::operator/(PRUint64 his)
+{ RCTime quotient(gmt / gmt); return quotient; }
+
+RCTime RCTime::operator*(PRUint64 his)
+{ RCTime product(gmt * his); return product; }
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rctime.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/rctime.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,138 @@
+/* -*- 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 ***** */
+
+/*
+** Class definitions for calendar time routines (ref: prtime.h)
+*/
+
+#if defined(_RCTIME_H)
+#else
+#define _RCTIME_H
+
+#include "rcbase.h"
+
+#include <prtime.h>
+
+/*
+** Class: RCTime (ref: prtime.h)
+**
+** RCTimes are objects that are intended to be used to represent calendar
+** times. They maintain units internally as microseconds since the defined
+** epoch (midnight, January 1, 1970, GMT). Conversions to and from external
+** formats (PRExplodedTime) are available.
+**
+** In general, NCTimes possess normal algebretic capabilities.
+*/
+
+class PR_IMPLEMENT(RCTime): public RCBase
+{
+public:
+    typedef enum {now} Current;
+
+    RCTime();                       /* leaves the object unitialized */
+    RCTime(Current);                /* initializes to current system time */
+    RCTime(const RCTime&);          /* copy constructor */
+    RCTime(const PRExplodedTime&);  /* construction from exploded representation */
+
+    virtual ~RCTime();
+
+    /* assignment operators */
+    void operator=(const RCTime&); 
+    void operator=(const PRExplodedTime&);
+
+    /* comparitive operators */
+    PRBool operator<(const RCTime&);
+    PRBool operator>(const RCTime&);
+    PRBool operator<=(const RCTime&);
+    PRBool operator>=(const RCTime&);
+    PRBool operator==(const RCTime&);
+
+    /* associative operators */
+    RCTime operator+(const RCTime&);
+    RCTime operator-(const RCTime&);
+    RCTime& operator+=(const RCTime&);
+    RCTime& operator-=(const RCTime&);
+
+    /* multiply and divide operators */
+    RCTime operator/(PRUint64);
+    RCTime operator*(PRUint64);
+    RCTime& operator/=(PRUint64);
+    RCTime& operator*=(PRUint64);
+
+    void Now();                     /* assign current time to object */
+
+private:
+    PRTime gmt;
+
+public:
+
+    RCTime(PRTime);                 /* construct from raw PRTime */
+    void operator=(PRTime);         /* assign from raw PRTime */
+    operator PRTime() const;        /* extract internal representation */
+};  /* RCTime */
+
+inline RCTime::RCTime(): RCBase() { }
+
+inline void RCTime::Now() { gmt = PR_Now(); }
+inline RCTime::operator PRTime() const { return gmt; }
+
+inline void RCTime::operator=(PRTime his) { gmt = his; }
+inline void RCTime::operator=(const RCTime& his) { gmt = his.gmt; }
+
+inline PRBool RCTime::operator<(const RCTime& his)
+    { return (gmt < his.gmt) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCTime::operator>(const RCTime& his)
+    { return (gmt > his.gmt) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCTime::operator<=(const RCTime& his)
+    { return (gmt <= his.gmt) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCTime::operator>=(const RCTime& his)
+    { return (gmt >= his.gmt) ? PR_TRUE : PR_FALSE; }
+inline PRBool RCTime::operator==(const RCTime& his)
+    { return (gmt == his.gmt) ? PR_TRUE : PR_FALSE; }
+
+inline RCTime& RCTime::operator+=(const RCTime& his)
+    { gmt += his.gmt; return *this; }
+inline RCTime& RCTime::operator-=(const RCTime& his)
+    { gmt -= his.gmt; return *this; }
+inline RCTime& RCTime::operator/=(PRUint64 his)
+    { gmt /= his; return *this; }
+inline RCTime& RCTime::operator*=(PRUint64 his)
+    { gmt *= his; return *this; }
+
+#endif /* defined(_RCTIME_H) */
+
+/* RCTime.h */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,10 @@
+/.cvsignore/1.2/Sat May 12 06:06:48 2001//
+/Makefile.in/1.10/Mon Nov  8 02:52:56 2004//
+/fileio.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/interval.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/ranfile.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/switch.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/thread.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/time.cpp/1.5/Sun Apr 25 15:00:57 2004//
+/tpd.cpp/1.5/Sun Apr 25 15:00:57 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/cplus/tests

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,288 @@
+# 
+# ***** 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 =           \
+	ranfile.cpp     \
+	thread.cpp      \
+	interval.cpp    \
+	time.cpp        \
+	fileio.cpp      \
+	switch.cpp      \
+	tpd.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.. -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)
+LIBPL = -lplc$(MOD_MAJOR_VERSION)
+
+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
+
+        ifeq ($(USE_PTHREADS), 1)
+            ifeq ($(OS_RELEASE), 6.2)
+                LDOPTS += -Wl,-woff,85
+            endif
+        endif
+    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), WINNT)
+ifeq ($(OS_TARGET), WIN16)
+  LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).lib
+  LIBPL = $(dist_libdir)/plc$(MOD_MAJOR_VERSION).lib
+else
+  LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO
+  LIBPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+  LIBPL = $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).$(LIB_SUFFIX)
+endif
+endif
+
+ifeq ($(OS_ARCH),OS2)
+  ifeq ($(MOZ_OS2_TOOLS),VACPP)
+    LDOPTS = -NOE -DEBUG -nologo -PMTYPE:VIO
+    LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).lib
+    LIBPLC = $(dist_libdir)/plc$(MOD_MAJOR_VERSION).lib
+  else
+    LDOPTS += -Zomf -Zlinker /PM:VIO -lstdcpp
+  endif
+endif
+
+ifneq ($(OS_ARCH), WINNT)
+PWD = $(shell pwd)
+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
+        LIBPLC = -lplc$(MOD_MAJOR_VERSION)_shr
+    else
+        LDOPTS += -brtl
+        EXTRA_LIBS = -ldl
+    endif
+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), 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
+LIBPL = $(dist_libdir)/libplc$(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), SCO_SV)
+# 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 $(LIBPL),	            >>w16link
+	echo winsock.lib            >>w16link
+	wlink @w16link.
+else
+	link $(LDOPTS) $< $(LIBPR) $(LIBPL) wsock32.lib -out:$@
+endif
+else
+ifeq ($(OS_ARCH),OS2)
+	$(LINK) $(LDOPTS) $< $(LIBGC) $(LIBPLC) $(LIBPR) $(OS_LIBS) $(EXTRA_LIBS) -o $@
+else
+	$(CCC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPL) $(EXTRA_LIBS) -o $@
+endif
+endif
+endif
+
+export:: $(TARGETS)
+clean::
+	rm -f $(TARGETS)
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/fileio.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/fileio.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,65 @@
+/* -*- 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 ***** */
+
+/* fileio.cpp - a test program */
+
+#include "rcfileio.h"
+
+#include <prlog.h>
+#include <prprf.h>
+
+#define DEFAULT_ITERATIONS 100
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    RCFileIO fd;
+    RCFileInfo info;
+    rv = fd.Open("filio.dat", PR_CREATE_FILE, 0666);
+    PR_ASSERT(PR_SUCCESS == rv);
+    rv = fd.FileInfo(&info);
+    PR_ASSERT(PR_SUCCESS == rv);
+    rv = fd.Delete("filio.dat");
+    PR_ASSERT(PR_SUCCESS == rv);
+    fd.Close();
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    return 0;
+}  /* main */
+
+/* interval.cpp */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/interval.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/interval.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,133 @@
+/* -*- 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 ***** */
+
+/* interval.cpp - a test program */
+
+#include "rclock.h"
+#include "rcthread.h"
+#include "rcinrval.h"
+#include "rccv.h"
+
+#include <prio.h>
+#include <prlog.h>
+#include <prprf.h>
+
+#define DEFAULT_ITERATIONS 100
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    RCLock ml;
+    PRStatus rv;
+    RCCondition cv(&ml);
+
+    RCInterval now, timeout, epoch, elapsed;
+    PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput);
+    PRIntn msecs, seconds, loops, iterations = DEFAULT_ITERATIONS;
+
+    /* slow, agonizing waits */
+    for (seconds = 0; seconds < 10; ++seconds)
+    {
+        timeout = RCInterval::FromSeconds(seconds);
+        cv.SetTimeout(timeout);
+        {
+            RCEnter lock(&ml);
+
+            epoch.SetToNow();
+
+            rv = cv.Wait();
+            PR_ASSERT(PR_SUCCESS == rv);
+
+            now = RCInterval(RCInterval::now);
+            elapsed = now - epoch;
+        }
+
+        PR_fprintf(
+            output, "Waiting %u seconds took %s%u milliseconds\n",
+            seconds, ((elapsed < timeout)? "**" : ""),
+            elapsed.ToMilliseconds());
+    }
+
+    /* more slow, agonizing sleeps */
+    for (seconds = 0; seconds < 10; ++seconds)
+    {
+        timeout = RCInterval::FromSeconds(seconds);
+        {
+            epoch.SetToNow();
+
+            rv = RCThread::Sleep(timeout);
+            PR_ASSERT(PR_SUCCESS == rv);
+
+            now = RCInterval(RCInterval::now);
+            elapsed = now - epoch;
+        }
+
+        PR_fprintf(
+            output, "Sleeping %u seconds took %s%u milliseconds\n",
+            seconds, ((elapsed < timeout)? "**" : ""),
+            elapsed.ToMilliseconds());
+    }
+
+    /* fast, spritely little devils */
+    for (msecs = 10; msecs < 100; msecs += 10)
+    {
+        timeout = RCInterval::FromMilliseconds(msecs);
+        cv.SetTimeout(timeout);
+        {
+            RCEnter lock(&ml);
+
+            epoch.SetToNow();
+
+            for (loops = 0; loops < iterations; ++loops)
+            {
+                rv = cv.Wait();
+                PR_ASSERT(PR_SUCCESS == rv);
+            }
+
+            now = RCInterval(RCInterval::now);
+            elapsed = now - epoch;
+        }
+        elapsed /= iterations;
+
+        PR_fprintf(
+            output, "Waiting %u msecs took %s%u milliseconds average\n",
+            msecs, ((elapsed < timeout)? "**" : ""), elapsed.ToMilliseconds());
+    }
+    return 0;
+}  /* main */
+
+/* interval.cpp */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/ranfile.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/ranfile.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,432 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**
+** Contact:     AOF<mailto:freier at netscape.com>
+**
+** Name: ranfile.c
+**
+** Description: Test to hammer on various components of NSPR
+** Modification History:
+** 20-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
+***********************************************************************/
+/* Used to get the command line option */
+#include <plgetopt.h>
+#include <prprf.h>
+#include <prio.h>
+
+#include "rccv.h"
+#include "rcthread.h"
+#include "rcfileio.h"
+#include "rclock.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static PRFileDesc *output;
+static PRIntn debug_mode = 0;
+static PRIntn failed_already = 0;
+
+class HammerData
+{
+public:
+    typedef enum {
+        sg_go, sg_stop, sg_done} Action;
+    typedef enum {
+        sg_okay, sg_open, sg_close, sg_delete, sg_write, sg_seek} Problem;
+
+	virtual ~HammerData();
+	HammerData(RCLock* lock, RCCondition *cond, PRUint32 clip);
+    virtual PRUint32 Random();
+
+    Action action;
+    Problem problem;
+    PRUint32 writes;
+    RCInterval timein;
+friend class Hammer;
+private:
+    RCLock *ml;
+    RCCondition *cv;
+    PRUint32 limit;
+
+    PRFloat64 seed;
+};  /* HammerData */
+
+class Hammer: public HammerData, public RCThread
+{
+public:
+    virtual ~Hammer();
+    Hammer(RCThread::Scope scope, RCLock* lock, RCCondition *cond, PRUint32 clip);
+
+private:
+    void RootFunction();
+
+};
+
+static PRInt32 pageSize = 1024;
+static const char* baseName = "./";
+static const char *programName = "Random File";
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Random
+** DESCRIPTION:
+**   Generate a pseudo-random number
+** INPUTS:      None
+** OUTPUTS:     None
+** RETURN:      A pseudo-random unsigned number, 32-bits wide
+** SIDE EFFECTS:
+**      Updates random seed (a static)
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:
+**      Uses the current interval timer value, promoted to a 64 bit
+**      float as a multiplier for a static residue (which begins
+**      as an uninitialized variable). The result is bits [16..48)
+**      of the product. Seed is then updated with the return value
+**      promoted to a float-64.
+***********************************************************************/
+PRUint32 HammerData::Random()
+{
+    PRUint32 rv;
+    PRUint64 shift;
+    RCInterval now = RCInterval(RCInterval::now);
+    PRFloat64 random = seed * (PRFloat64)((PRIntervalTime)now);
+    LL_USHR(shift, *((PRUint64*)&random), 16);
+    LL_L2UI(rv, shift);
+    seed = (PRFloat64)rv;
+    return rv;
+}  /* HammerData::Random */
+
+Hammer::~Hammer() { }
+
+Hammer::Hammer(
+    RCThread::Scope scope, RCLock* lock, RCCondition *cond, PRUint32 clip):
+	HammerData(lock, cond, clip), RCThread(scope, RCThread::joinable, 0) { }
+
+HammerData::~HammerData() { }
+
+HammerData::HammerData(RCLock* lock, RCCondition *cond, PRUint32 clip)
+{
+    ml = lock;
+    cv = cond;
+    writes = 0;
+    limit = clip;
+    seed = 0x58a9382;
+    action = HammerData::sg_go;
+    problem = HammerData::sg_okay;
+    timein = RCInterval(RCInterval::now);
+}  /* HammerData::HammerData */
+
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Hammer::RootFunction
+** DESCRIPTION:
+**   Hammer on the file I/O system
+** INPUTS:      A pointer to the thread's private data
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      Creates, accesses and deletes a file
+** RESTRICTIONS:
+**      (Currently) must have file create permission in "/usr/tmp".
+** MEMORY:      NA
+** ALGORITHM:
+**      This function is a root of a thread
+**      1) Creates a (hopefully) unique file in /usr/tmp/
+**      2) Writes a zero to a random number of sequential pages
+**      3) Closes the file
+**      4) Reopens the file
+**      5) Seeks to a random page within the file
+**      6) Writes a one byte on that page
+**      7) Repeat steps [5..6] for each page in the file
+**      8) Close and delete the file
+**      9) Repeat steps [1..8] until told to stop
+**     10) Notify complete and return
+***********************************************************************/
+void Hammer::RootFunction()
+{
+    PRUint32 index;
+    RCFileIO file;
+    char filename[30];
+    const char zero = 0;
+    PRStatus rv = PR_SUCCESS;
+
+    limit = (Random() % limit) + 1;
+
+    (void)sprintf(filename, "%ssg%04p.dat", baseName, this);
+
+    if (debug_mode) PR_fprintf(output, "Starting work on %s\n", filename);
+
+    while (PR_TRUE)
+    {
+        PRUint64 bytes;
+        PRUint32 minor = (Random() % limit) + 1;
+        PRUint32 random = (Random() % limit) + 1;
+        PRUint32 pages = (Random() % limit) + 10;
+        while (minor-- > 0)
+        {
+            problem = sg_okay;
+            if (action != sg_go) goto finished;
+            problem = sg_open;
+            rv = file.Open(filename, PR_RDWR|PR_CREATE_FILE, 0666);
+            if (PR_FAILURE == rv) goto finished;
+            for (index = 0; index < pages; index++)
+            {
+                problem = sg_okay;
+                if (action != sg_go) goto close;
+                problem = sg_seek;
+                bytes = file.Seek(pageSize * index, RCFileIO::set);
+                if (bytes != pageSize * index) goto close;
+                problem = sg_write;
+                bytes = file.Write(&zero, sizeof(zero));
+                if (bytes <= 0) goto close;
+                writes += 1;
+            }
+            problem = sg_close;
+            rv = file.Close();
+            if (rv != PR_SUCCESS) goto purge;
+
+            problem = sg_okay;
+            if (action != sg_go) goto purge;
+
+            problem = sg_open;
+            rv = file.Open(filename, PR_RDWR, 0666);
+            if (PR_FAILURE == rv) goto finished;
+            for (index = 0; index < pages; index++)
+            {
+                problem = sg_okay;
+                if (action != sg_go) goto close;
+                problem = sg_seek;
+                bytes = file.Seek(pageSize * index, RCFileIO::set);
+                if (bytes != pageSize * index) goto close;
+                problem = sg_write;
+                bytes = file.Write(&zero, sizeof(zero));
+                if (bytes <= 0) goto close;
+                writes += 1;
+                random = (random + 511) % pages;
+            }
+            problem = sg_close;
+            rv = file.Close();
+            if (rv != PR_SUCCESS) goto purge;
+            problem = sg_delete;
+            rv = file.Delete(filename);
+            if (rv != PR_SUCCESS) goto finished;
+       }
+    }
+
+close:
+    (void)file.Close();
+purge:
+    (void)file.Delete(filename);
+finished:
+    RCEnter scope(ml);
+    action = HammerData::sg_done;
+    cv->Notify();
+
+    if (debug_mode) PR_fprintf(output, "Ending work on %s\n", filename);
+
+    return;
+}  /* Hammer::RootFunction */
+
+static Hammer* hammer[100];
+/***********************************************************************
+** PRIVATE FUNCTION:    main
+** DESCRIPTION:
+**   Hammer on the file I/O system
+** INPUTS:      The usual argc and argv
+**              argv[0] - program name (not used)
+**              argv[1] - the number of virtual_procs to execute the major loop
+**              argv[2] - the number of threads to toss into the batch
+**              argv[3] - the clipping number applied to randoms
+**              default values: max_virtual_procs = 2, threads = 10, limit = 57
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      Creates, accesses and deletes lots of files
+** RESTRICTIONS:
+**      (Currently) must have file create permission in "/usr/tmp".
+** MEMORY:      NA
+** ALGORITHM:
+**      1) Fork a "Thread()"
+**      2) Wait for 'interleave' seconds
+**      3) For [0..'threads') repeat [1..2]
+**      4) Mark all objects to stop
+**      5) Collect the threads, accumulating the results
+**      6) For [0..'max_virtual_procs') repeat [1..5]
+**      7) Print accumulated results and exit
+**
+**      Characteristic output (from IRIX)
+**          Random File: Using max_virtual_procs = 2, threads = 10, limit = 57
+**          Random File: [min [avg] max] writes/sec average
+***********************************************************************/
+PRIntn main (PRIntn argc, char *argv[])
+{
+    RCLock ml;
+	PLOptStatus os;
+    RCCondition cv(&ml);
+    PRUint32 writesMax = 0, durationTot = 0;
+    RCThread::Scope thread_scope = RCThread::local;
+    PRUint32 writes, writesMin = 0x7fffffff, writesTot = 0;
+    PRIntn active, poll, limit = 0, max_virtual_procs = 0, threads = 0, virtual_procs;
+    RCInterval interleave(RCInterval::FromMilliseconds(10000)), duration(0);
+
+    const char *where[] = {"okay", "open", "close", "delete", "write", "seek"};
+
+	PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:t:i:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+	case 0:
+		baseName = opt->value;
+		break;
+        case 'G':  /* global threads */
+		thread_scope = RCThread::global;
+            break;
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'l':  /* limiting number */
+			limit = atoi(opt->value);
+            break;
+        case 't':  /* number of threads */
+			threads = atoi(opt->value);
+            break;
+        case 'i':  /* iteration counter */
+			max_virtual_procs = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+    output = PR_GetSpecialFD(PR_StandardOutput);
+
+ /* main test */
+ 
+    cv.SetTimeout(interleave);
+	
+    if (max_virtual_procs == 0) max_virtual_procs = 2;
+    if (limit == 0) limit = 57;
+    if (threads == 0) threads = 10;
+
+    if (debug_mode) PR_fprintf(output,
+        "%s: Using %d virtual processors, %d threads, limit = %d and %s threads\n",
+        programName, max_virtual_procs, threads, limit,
+        (thread_scope == RCThread::local) ? "LOCAL" : "GLOBAL");
+
+    for (virtual_procs = 0; virtual_procs < max_virtual_procs; ++virtual_procs)
+    {
+        if (debug_mode)
+			PR_fprintf(output,
+				"%s: Setting number of virtual processors to %d\n",
+				programName, virtual_procs + 1);
+		RCPrimordialThread::SetVirtualProcessors(virtual_procs + 1);
+        for (active = 0; active < threads; active++)
+        {
+            hammer[active] = new Hammer(thread_scope, &ml, &cv, limit);
+            hammer[active]->Start();  /* then make it roll */
+            RCThread::Sleep(interleave);  /* start them slowly */
+        }
+
+        /*
+         * The last thread started has had the opportunity to run for
+         * 'interleave' seconds. Now gather them all back in.
+         */
+        {
+            RCEnter scope(&ml);
+            for (poll = 0; poll < threads; poll++)
+            {
+                if (hammer[poll]->action == HammerData::sg_go)  /* don't overwrite done */
+                    hammer[poll]->action = HammerData::sg_stop;  /* ask him to stop */
+            }
+        }
+
+        while (active > 0)
+        {
+            for (poll = 0; poll < threads; poll++)
+            {
+                ml.Acquire();
+                while (hammer[poll]->action < HammerData::sg_done) cv.Wait();
+                ml.Release();
+
+                if (hammer[poll]->problem == HammerData::sg_okay)
+                {
+                    duration = RCInterval(RCInterval::now) - hammer[poll]->timein;
+                    writes = hammer[poll]->writes * 1000 / duration;
+                    if (writes < writesMin)  writesMin = writes;
+                    if (writes > writesMax) writesMax = writes;
+                    writesTot += hammer[poll]->writes;
+                    durationTot += duration;
+                }
+                else
+                {
+                    if (debug_mode) PR_fprintf(output,
+                        "%s: test failed %s after %ld seconds\n",
+                        programName, where[hammer[poll]->problem], duration);
+					else failed_already=1;
+                }
+                active -= 1;  /* this is another one down */
+                (void)hammer[poll]->Join();
+                hammer[poll] = NULL;
+            }
+        }
+        if (debug_mode) PR_fprintf(output,
+            "%s: [%ld [%ld] %ld] writes/sec average\n",
+            programName, writesMin,
+            writesTot * 1000 / durationTot, writesMax);
+    }
+
+        failed_already |= (PR_FAILURE == RCPrimordialThread::Cleanup());
+	    PR_fprintf(output, "%s\n", (failed_already) ? "FAIL\n" : "PASS\n");
+		return failed_already;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/switch.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/switch.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,266 @@
+/* -*- 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:            switch.cpp
+** Description:     trying to time context switches
+*/
+
+#include "rccv.h"
+#include "rcinrval.h"
+#include "rclock.h"
+#include "rcthread.h"
+
+#include <prio.h>
+#include <prlog.h>
+#include <prprf.h>
+#include <plerror.h>
+#include <plgetopt.h>
+
+#include <stdlib.h>
+
+#define INNER_LOOPS 100
+#define DEFAULT_LOOPS 100
+#define DEFAULT_THREADS 10
+
+static PRFileDesc *debug_out = NULL;
+static PRBool debug_mode = PR_FALSE, verbosity = PR_FALSE, failed = PR_FALSE;
+
+class Home: public RCCondition
+{
+public:
+    virtual ~Home();
+    Home(Home *link, RCLock* ml);
+
+public:
+    Home *next;
+    RCLock* ml;
+    PRBool twiddle;
+};  /* Home */
+
+Home::~Home() { }
+
+Home::Home(Home *link, RCLock* lock): RCCondition(lock)
+{
+    ml = lock;
+    next = link;
+    twiddle = PR_FALSE;
+}  /* Home::Home */
+
+class Shared: public Home, public RCThread
+{
+public:
+    Shared(RCThread::Scope scope, Home* link, RCLock* ml);
+
+private:
+    ~Shared();
+    void RootFunction();
+};  /* Shared */
+
+Shared::Shared(RCThread::Scope scope, Home* link, RCLock* lock):
+    Home(link, lock), RCThread(scope, RCThread::joinable) { }
+
+Shared::~Shared() { }
+
+void Shared::RootFunction()
+{
+    PRStatus status = PR_SUCCESS;
+    while (PR_SUCCESS == status)
+    {
+        RCEnter entry(ml);
+        while (twiddle && (PR_SUCCESS == status)) status = Wait();
+		if (verbosity) PR_fprintf(debug_out, "+");
+        twiddle = PR_TRUE;
+        next->twiddle = PR_FALSE;
+        next->Notify();
+    }
+}  /* Shared::RootFunction */
+
+static void Help(void)
+{
+    debug_out = PR_STDOUT;
+
+    PR_fprintf(
+		debug_out, "Usage: >./switch [-d] [-c n] [-t n] [-T n] [-G]\n");
+    PR_fprintf(
+		debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS);
+    PR_fprintf(
+		debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS);
+    PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-G n\tglobal threads only (default: FALSE)\n");
+    PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n");
+}  /* Help */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+	PLOptStatus os;
+    PRStatus status;
+    PRBool help = PR_FALSE;
+    PRUintn concurrency = 1;
+    RCThread::Scope thread_scope = RCThread::local;
+    PRUintn thread_count, inner_count, loop_count, average;
+    PRUintn thread_limit = DEFAULT_THREADS, loop_limit = DEFAULT_LOOPS;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'v':  /* verbose mode */
+			verbosity = PR_TRUE;
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+        case 'c':  /* loop counter */
+			loop_limit = atoi(opt->value);
+            break;
+        case 't':  /* thread limit */
+			thread_limit = atoi(opt->value);
+            break;
+        case 'C':  /* Concurrency limit */
+			concurrency = atoi(opt->value);
+            break;
+        case 'G':  /* global threads only */
+			thread_scope = RCThread::global;
+            break;
+        case 'h':  /* help message */
+			Help();
+			help = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (help) return -1;
+
+	if (PR_TRUE == debug_mode)
+	{
+		debug_out = PR_STDOUT;
+		PR_fprintf(debug_out, "Test parameters\n");
+		PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit);
+		PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit);
+		PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency);
+		PR_fprintf(
+			debug_out, "\tThread type: %s\n",
+			(PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
+	}
+
+    /*
+    ** The interesting part starts here
+    */
+    RCLock lock;
+    Shared* shared;
+    Home home(NULL, &lock);
+    Home* link = &home;
+    RCInterval timein, timeout = 0;
+
+    /* Build up the string of objects */
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        shared = new Shared(thread_scope, link, &lock);
+        shared->Start();  /* make it run */
+        link = (Home*)shared;
+	}
+
+    /* Pass the message around the horn a few times */
+    for (loop_count = 1; loop_count <= loop_limit; ++loop_count)
+    {
+		timein.SetToNow();
+		for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count)
+		{
+			RCEnter entry(&lock);
+			home.twiddle = PR_TRUE;
+			shared->twiddle = PR_FALSE;
+			shared->Notify();
+			while (home.twiddle)
+            {
+				failed = (PR_FAILURE == home.Wait()) ? PR_TRUE : PR_FALSE;
+            }
+		}
+		timeout += (RCInterval(RCInterval::now) - timein);
+	}
+
+    /* Figure out how well we did */
+	if (debug_mode)
+	{
+		average = timeout.ToMicroseconds()
+			/ (INNER_LOOPS * loop_limit * thread_count);
+		PR_fprintf(
+			debug_out, "Average switch times %d usecs for %d threads\n",
+            average, thread_limit);
+	}
+
+    /* Start reclamation process */
+    link = shared;
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        if (&home == link) break;
+        status = ((Shared*)link)->Interrupt();
+		if (PR_SUCCESS != status)
+        {
+            failed = PR_TRUE;
+            if (debug_mode)
+			    PL_FPrintError(debug_out, "Failed to interrupt");
+        }
+		link = link->next; 
+    }
+
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        link = shared->next;
+        status = shared->Join();
+		if (PR_SUCCESS != status)
+		{
+            failed = PR_TRUE;
+            if (debug_mode)
+			    PL_FPrintError(debug_out, "Failed to join");
+        }
+        if (&home == link) break;
+        shared = (Shared*)link;
+    }
+
+    PR_fprintf(PR_STDOUT, ((failed) ? "FAILED\n" : "PASSED\n"));
+
+    failed |= (PR_SUCCESS == RCPrimordialThread::Cleanup());
+
+    return ((failed) ? 1 : 0);
+}  /* main */
+
+/* switch.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/thread.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/thread.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,140 @@
+/* -*- 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 ***** */
+
+/* thread.cpp - a test program */
+
+#include "rcthread.h"
+
+#include <prlog.h>
+
+#include <stdio.h>
+
+class TestThread: public RCThread
+{
+public:
+    TestThread(RCThread::State state, PRIntn count);
+
+    virtual void RootFunction();
+
+protected:
+    virtual ~TestThread();
+
+private:
+    PRUint32 mydata;
+};
+
+TestThread::~TestThread() { }
+
+TestThread::TestThread(RCThread::State state, PRIntn count):
+    RCThread(RCThread::global, state, 0) { mydata = count; }
+
+void TestThread::RootFunction()
+{
+    SetPriority(RCThread::high);
+    printf("TestThread::RootFunction %d did it\n", mydata);
+}  /* TestThread::RootFunction */
+
+class Foo1
+{
+public:
+    Foo1();
+    virtual ~Foo1();
+
+    TestThread *thread;
+    PRIntn data;
+};
+
+Foo1::Foo1() 
+{
+    data = 0xafaf;
+    thread = new TestThread(RCThread::joinable, 0xafaf);
+    thread->Start();
+}
+
+Foo1::~Foo1()
+{
+    PRStatus rv = thread->Join();
+    PR_ASSERT(PR_SUCCESS == rv);
+}  /* Foo1::~Foo1 */
+
+PRIntn main(PRIntn argc, char **agrv)
+{
+    PRStatus status;
+    PRIntn count = 100;
+    RCThread *thread[10];
+    while (--count > 0)
+    {
+        TestThread *thread = new TestThread(RCThread::joinable, count);
+        status = thread->Start();  /* have to remember to start it */
+        PR_ASSERT(PR_SUCCESS == status);
+        status = thread->Join();  /* this should work */
+        PR_ASSERT(PR_SUCCESS == status);
+    }
+    while (++count < 100)
+    {
+        TestThread *thread = new TestThread(RCThread::unjoinable, count);
+        status = thread->Start();  /* have to remember to start it */
+        PR_ASSERT(PR_SUCCESS == status);
+    }
+
+    {
+        Foo1 *foo1 = new Foo1();
+        PR_ASSERT(NULL != foo1);
+        delete foo1;
+    }
+
+    {
+        for (count = 0; count < 10; ++count)
+        {
+            thread[count] = new TestThread( RCThread::joinable, count);
+            status = thread[count]->Start();  /* have to remember to start it */
+            PR_ASSERT(PR_SUCCESS == status);
+        }
+        for (count = 0; count < 10; ++count)
+        {
+            PRStatus rv = thread[count]->Join();
+            PR_ASSERT(PR_SUCCESS == rv);
+        }
+    }
+
+    (void)RCPrimordialThread::Cleanup();
+
+    return 0;
+}  /* main */
+
+/* thread.cpp */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/time.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/time.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,61 @@
+/* -*- 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 ***** */
+
+/* time.cpp - a test program */
+
+#include "rctime.h"
+
+#include <prlog.h>
+#include <prprf.h>
+
+#define DEFAULT_ITERATIONS 100
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    RCTime unitialized;
+    RCTime now(PR_Now());
+    RCTime current(RCTime::now);
+    PRTime time = current;
+
+    unitialized = now;
+    now.Now();
+
+    return 0;
+}  /* main */
+
+/* time.cpp */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/tpd.cpp
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cplus/tests/tpd.cpp	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,368 @@
+/* -*- 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:        tpd.cpp
+** Description: Exercising the thread private data bailywick.
+*/
+
+#include "prlog.h"
+#include "prprf.h"
+#include "rcthread.h"
+
+#include <string.h>
+
+#include "plgetopt.h"
+
+/*
+** class MyThread
+*/
+class MyThread: public RCThread
+{
+public:
+    MyThread();
+
+private:
+    ~MyThread();
+    void RootFunction();
+};  /* MyThread */
+
+/*
+** class MyPrivateData
+*/
+class MyPrivateData: public RCThreadPrivateData
+{
+public:
+    virtual ~MyPrivateData();
+
+    MyPrivateData();
+    MyPrivateData(char*);
+    MyPrivateData(const MyPrivateData&);
+
+    void Release();
+
+private:
+    char *string;
+};  /* MyPrivateData */
+
+static PRUintn key[128];
+static PRIntn debug = 0;
+static PRBool failed = PR_FALSE;
+static PRBool should = PR_TRUE;
+static PRBool did = PR_TRUE;
+static PRFileDesc *fout = NULL;
+
+static void PrintProgress(PRIntn line)
+{
+    failed = failed || (should && !did);
+    failed = failed || (!should && did);
+    if (debug > 0)
+    {
+        PR_fprintf(
+            fout, "@ line %d destructor should %shave been called and was%s\n",
+            line, ((should) ? "" : "NOT "), ((did) ? "" : " NOT"));
+    }
+}  /* PrintProgress */
+
+static void MyAssert(const char *expr, const char *file, PRIntn line)
+{
+    if (debug > 0)
+        (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line);
+}  /* MyAssert */
+
+#define MY_ASSERT(_expr) \
+    ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__))
+
+int main(PRIntn argc, char *argv[])
+{
+    PRStatus rv;
+    PRUintn keys;
+    MyThread *thread;
+    const RCThreadPrivateData *pd;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+    RCThread *primordial = RCThread::WrapPrimordialThread();
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            debug = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    fout = PR_STDOUT;
+
+    MyPrivateData extension = MyPrivateData("EXTENSION");
+    MyPrivateData key_string[] = {
+        "Key #0", "Key #1", "Key #2", "Key #3",
+        "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
+    
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = RCThread::NewPrivateIndex(&key[keys]);
+        key[keys + 4] = key[keys] + 4;
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* the first four should be bu null, the last four undefined and null */
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 8; ++keys)
+    {
+        pd = RCThread::GetPrivateData(key[keys]);
+        MY_ASSERT(NULL == pd);
+    }
+    PrintProgress(__LINE__);
+
+    /* initially set private data for new keys */
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = RCThread::SetPrivateData(key[keys], &key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* re-assign the private data, albeit the same content */    
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        pd = RCThread::GetPrivateData(key[keys]);
+        PR_ASSERT(NULL != pd);
+        rv = RCThread::SetPrivateData(key[keys], &key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* set private to <empty> */
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = RCThread::SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* should all be null now */
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        pd = RCThread::GetPrivateData(key[keys]);
+        PR_ASSERT(NULL == pd);
+    }
+    PrintProgress(__LINE__);
+
+    /* allocate another batch of keys and assign data to them */
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = RCThread::NewPrivateIndex(&key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+        rv = RCThread::SetPrivateData(key[keys], &extension);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* set all the extended slots to <empty> */
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = RCThread::SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    /* set all the extended slots to <empty> again (noop) */
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = RCThread::SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+
+    if (debug) PR_fprintf(fout, "Creating thread\n");
+    thread = new MyThread();
+    if (debug) PR_fprintf(fout, "Starting thread\n");
+    thread->Start();
+    if (debug) PR_fprintf(fout, "Joining thread\n");
+    (void)thread->Join();
+    if (debug) PR_fprintf(fout, "Joined thread\n");
+
+    failed |= (PR_FAILURE == RCPrimordialThread::Cleanup());
+
+    (void)PR_fprintf(
+        fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
+
+    return (failed) ? 1 : 0;
+
+}  /* main */
+
+/*
+** class MyPrivateData
+*/
+MyPrivateData::~MyPrivateData()
+{
+    PR_fprintf(
+        fout, "MyPrivateData::~MyPrivateData[%s]\n",
+        (NULL != string) ? string : "NULL");
+}  /* MyPrivateData::~MyPrivateData */
+
+MyPrivateData::MyPrivateData(): RCThreadPrivateData()
+{
+    PR_fprintf(fout, "MyPrivateData::MyPrivateData()\n");
+    string = NULL;
+}  /* MyPrivateData::MyPrivateData */
+
+MyPrivateData::MyPrivateData(char* data): RCThreadPrivateData()
+{
+    PR_fprintf(fout, "MyPrivateData::MyPrivateData(char* data)\n");
+    string = data;
+}  /* MyPrivateData:: MyPrivateData */
+
+MyPrivateData::MyPrivateData(const MyPrivateData& him): RCThreadPrivateData(him)
+{
+    PR_fprintf(fout, "MyPrivateData::MyPrivateData(const MyPrivateData& him)\n");
+    string = him.string;
+}  /* MyPrivateData:: MyPrivateData */
+
+void MyPrivateData::Release()
+{
+    if (should) did = PR_TRUE;
+    else failed = PR_TRUE;
+}  /* MyPrivateData::operator= */
+
+/*
+** class MyThread
+*/
+MyThread::~MyThread() { }
+MyThread::MyThread(): RCThread(RCThread::global, RCThread::joinable) { }
+
+
+void MyThread::RootFunction()
+{
+    PRStatus rv;
+    PRUintn keys;
+    const RCThreadPrivateData *pd;
+    
+    MyPrivateData extension = MyPrivateData("EXTENSION");
+    MyPrivateData key_string[] = {
+        "Key #0", "Key #1", "Key #2", "Key #3",
+        "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
+    
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 8; ++keys)
+    {
+        pd = GetPrivateData(key[keys]);
+        MY_ASSERT(NULL == pd);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = SetPrivateData(keys, &key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+#if !defined(DEBUG)
+    did = should = PR_FALSE;
+    for (keys = 4; keys < 8; ++keys)
+    {
+        rv = SetPrivateData(keys, &key_string[keys]);
+        MY_ASSERT(PR_FAILURE == rv);
+    }
+    PrintProgress(__LINE__);
+#endif
+    
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = SetPrivateData(key[keys], &key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = SetPrivateData(key[keys], &extension);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = SetPrivateData(key[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+}  /* MyThread::RootFunction */
+
+/* tpd.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cthreads/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cthreads/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cthreads/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cthreads/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/cthreads

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/cthreads/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/cthreads/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,19 @@
+/.cvsignore/1.2/Sat May 12 04:14:49 2001//
+/Makefile.in/1.13/Sun Apr 25 15:00:58 2004//
+/prdir.c/3.7/Sun Apr 25 15:00:58 2004//
+/prfdcach.c/3.12/Sun Apr 25 15:00:58 2004//
+/prfile.c/3.44/Tue Feb  7 01:21:00 2006//
+/prio.c/3.19/Fri Oct 21 18:21:42 2005//
+/priometh.c/3.19/Sun Apr 25 15:00:58 2004//
+/pripv6.c/3.12/Tue Jan 25 19:44:07 2005//
+/prlayer.c/3.19/Sun Apr 25 15:00:58 2004//
+/prlog.c/3.34/Mon Mar 14 21:40:15 2005//
+/prmapopt.c/3.18/Sun Apr 25 15:00:58 2004//
+/prmmap.c/3.7/Sun Apr 25 15:00:58 2004//
+/prmwait.c/3.18/Tue Mar  8 22:40:15 2005//
+/prpolevt.c/3.15/Sun Apr 25 15:00:58 2004//
+/prprf.c/3.18/Fri Jul  1 21:01:40 2005//
+/prscanf.c/3.11/Fri Aug  5 22:44:06 2005//
+/prsocket.c/3.58/Fri Oct 21 18:21:42 2005//
+/prstdio.c/3.6/Sun Apr 25 15:00:58 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/io

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,97 @@
+# 
+# ***** 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 =
+endif
+endif
+
+CSRCS = \
+    prfdcach.c \
+    prmwait.c \
+    priometh.c \
+    pripv6.c \
+	prmapopt.c \
+    prlayer.c \
+    prlog.c \
+	prmmap.c \
+    prpolevt.c \
+	prprf.c \
+	prscanf.c \
+	prstdio.c  \
+	$(NULL)
+
+ifndef USE_PTHREADS
+    CSRCS += \
+	    prdir.c \
+	    prfile.c \
+	    prio.c \
+	    prsocket.c \
+	    $(NULL)
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+# An OS/2 Optimization bug causes PR_snprintf() to produce wrong result.
+# This suppresses optimization for this single compilation unit.
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+$(OBJDIR)/prprf.obj: prprf.c
+	@$(MAKE_OBJDIR)
+	$(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $<
+endif
+
+export:: $(TARGETS)
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prdir.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prdir.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,164 @@
+/* -*- 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):
+ *   Roy Yokoyama <yokoyama at netscape.com>
+ *
+ * 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"
+
+PR_IMPLEMENT(PRDir*) PR_OpenDir(const char *name)
+{
+    PRDir *dir;
+    PRStatus sts;
+
+    dir = PR_NEW(PRDir);
+    if (dir) {
+        sts = _PR_MD_OPEN_DIR(&dir->md,name);
+        if (sts != PR_SUCCESS) {
+            PR_DELETE(dir);
+            return NULL;
+        }
+    } else {
+		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	}
+    return dir;
+}
+
+PR_IMPLEMENT(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags)
+{
+    /* _MD_READ_DIR return a char* to the name; allocation in machine-dependent code */
+    char* name = _PR_MD_READ_DIR(&dir->md, flags);
+    dir->d.name = name;
+    return name ? &dir->d : NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseDir(PRDir *dir)
+{
+PRInt32 rv;
+
+    if (dir) {
+        rv = _PR_MD_CLOSE_DIR(&dir->md);
+		PR_DELETE(dir);
+		if (rv < 0) {
+			return PR_FAILURE;
+		} else
+			return PR_SUCCESS;
+    }
+	return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_MkDir(const char *name, PRIntn mode)
+{
+PRInt32 rv;
+
+	rv = _PR_MD_MKDIR(name, mode);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_MakeDir(const char *name, PRIntn mode)
+{
+PRInt32 rv;
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+	rv = _PR_MD_MAKE_DIR(name, mode);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_RmDir(const char *name)
+{
+PRInt32 rv;
+
+	rv = _PR_MD_RMDIR(name);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
+#ifdef MOZ_UNICODE
+/*
+ *  UTF16 Interface
+ */
+PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name)
+{ 
+    PRDirUTF16 *dir;
+    PRStatus sts;
+
+    dir = PR_NEW(PRDirUTF16);
+    if (dir) {
+        sts = _PR_MD_OPEN_DIR_UTF16(&dir->md,name);
+        if (sts != PR_SUCCESS) {
+            PR_DELETE(dir);
+            return NULL;
+        }
+    } else {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return dir;
+}  
+ 
+PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags)
+{ 
+    /*
+     * _MD_READ_DIR_UTF16 return a PRUnichar* to the name; allocation in
+     * machine-dependent code
+     */
+    PRUnichar* name = _PR_MD_READ_DIR_UTF16(&dir->md, flags);
+    dir->d.name = name;
+    return name ? &dir->d : NULL;
+} 
+ 
+PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDirUTF16 *dir)
+{ 
+    PRInt32 rv; 
+
+    if (dir) {
+        rv = _PR_MD_CLOSE_DIR_UTF16(&dir->md);
+        PR_DELETE(dir);
+        if (rv < 0)
+	    return PR_FAILURE;
+        else
+	    return PR_SUCCESS;
+    } 
+    return PR_SUCCESS;
+}
+
+#endif /* MOZ_UNICODE */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prfdcach.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prfdcach.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,311 @@
+/* -*- 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 <string.h>
+
+/*****************************************************************************/
+/*****************************************************************************/
+/************************** File descriptor caching **************************/
+/*****************************************************************************/
+/*****************************************************************************/
+
+/*
+** This code is built into debuggable versions of NSPR to assist in
+** finding misused file descriptors. Since file descritors (PRFileDesc)
+** are identified by a pointer to their structure, they can be the
+** target of dangling references. Furthermore, NSPR caches and tries
+** to aggressively reuse file descriptors, leading to more ambiguity.
+** The following code will allow a debugging client to set environment
+** variables and control the number of file descriptors that will be
+** preserved before they are recycled. The environment variables are
+** NSPR_FD_CACHE_SIZE_LOW and NSPR_FD_CACHE_SIZE_HIGH. The former sets
+** the number of descriptors NSPR will allocate before beginning to
+** recycle. The latter is the maximum number permitted in the cache
+** (exclusive of those in use) at a time.
+*/
+typedef struct _PR_Fd_Cache
+{
+    PRLock *ml;
+    PRIntn count;
+    PRStack *stack;
+    PRFileDesc *head, *tail;
+    PRIntn limit_low, limit_high;
+} _PR_Fd_Cache;
+
+static _PR_Fd_Cache _pr_fd_cache;
+static PRFileDesc **stack2fd = &(((PRFileDesc*)NULL)->higher);
+
+
+/*
+** Get a FileDescriptor from the cache if one exists. If not allocate
+** a new one from the heap.
+*/
+PRFileDesc *_PR_Getfd(void)
+{
+    PRFileDesc *fd;
+    /*
+    ** $$$
+    ** This may look a little wasteful. We'll see. Right now I want to
+    ** be able to toggle between caching and not at runtime to measure
+    ** the differences. If it isn't too annoying, I'll leave it in.
+    ** $$$$
+    **
+    ** The test is against _pr_fd_cache.limit_high. If that's zero,
+    ** we're not doing the extended cache but going for performance.
+    */
+    if (0 == _pr_fd_cache.limit_high)
+    {
+        PRStackElem *pop;
+        PR_ASSERT(NULL != _pr_fd_cache.stack);
+        pop = PR_StackPop(_pr_fd_cache.stack);
+        if (NULL == pop) goto allocate;
+        fd = (PRFileDesc*)((PRPtrdiff)pop - (PRPtrdiff)stack2fd);
+    }
+    else
+    {
+        do
+        {
+            if (NULL == _pr_fd_cache.head) goto allocate;  /* nothing there */
+            if (_pr_fd_cache.count < _pr_fd_cache.limit_low) goto allocate;
+
+            /* we "should" be able to extract an fd from the cache */
+            PR_Lock(_pr_fd_cache.ml);  /* need the lock to do this safely */
+            fd = _pr_fd_cache.head;  /* protected extraction */
+            if (NULL == fd)  /* unexpected, but not fatal */
+            {
+                PR_ASSERT(0 == _pr_fd_cache.count);
+                PR_ASSERT(NULL == _pr_fd_cache.tail);
+            }
+            else
+            {
+                _pr_fd_cache.count -= 1;
+                _pr_fd_cache.head = fd->higher;
+                if (NULL == _pr_fd_cache.head)
+                {
+                    PR_ASSERT(0 == _pr_fd_cache.count);
+                    _pr_fd_cache.tail = NULL;
+                }
+                PR_ASSERT(&_pr_faulty_methods == fd->methods);
+                PR_ASSERT(PR_INVALID_IO_LAYER == fd->identity);
+                PR_ASSERT(_PR_FILEDESC_FREED == fd->secret->state);
+            }
+            PR_Unlock(_pr_fd_cache.ml);
+
+        } while (NULL == fd);  /* then go around and allocate a new one */
+    }
+
+finished:
+    fd->dtor = NULL;
+    fd->lower = fd->higher = NULL;
+    fd->identity = PR_NSPR_IO_LAYER;
+    memset(fd->secret, 0, sizeof(PRFilePrivate));
+    return fd;
+
+allocate:
+    fd = PR_NEW(PRFileDesc);
+    if (NULL != fd)
+    {
+        fd->secret = PR_NEW(PRFilePrivate);
+        if (NULL == fd->secret) PR_DELETE(fd);
+    }
+    if (NULL != fd) goto finished;
+    else return NULL;
+
+}  /* _PR_Getfd */
+
+/*
+** Return a file descriptor to the cache unless there are too many in
+** there already. If put in cache, clear the fields first.
+*/
+void _PR_Putfd(PRFileDesc *fd)
+{
+    PR_ASSERT(PR_NSPR_IO_LAYER == fd->identity);
+    fd->methods = &_pr_faulty_methods;
+    fd->identity = PR_INVALID_IO_LAYER;
+    fd->secret->state = _PR_FILEDESC_FREED;
+
+    if (0 == _pr_fd_cache.limit_high)
+    {
+        PR_StackPush(_pr_fd_cache.stack, (PRStackElem*)(&fd->higher));
+    }
+    else
+    {
+        if (_pr_fd_cache.count > _pr_fd_cache.limit_high)
+        {
+            PR_Free(fd->secret);
+            PR_Free(fd);
+        }
+        else
+        {
+            PR_Lock(_pr_fd_cache.ml);
+            if (NULL == _pr_fd_cache.tail)
+            {
+                PR_ASSERT(0 == _pr_fd_cache.count);
+                PR_ASSERT(NULL == _pr_fd_cache.head);
+                _pr_fd_cache.head = _pr_fd_cache.tail = fd;
+            }
+            else
+            {
+                PR_ASSERT(NULL == _pr_fd_cache.tail->higher);
+                _pr_fd_cache.tail->higher = fd;
+                _pr_fd_cache.tail = fd;  /* new value */
+            }
+            fd->higher = NULL;  /* always so */
+            _pr_fd_cache.count += 1;  /* count the new entry */
+            PR_Unlock(_pr_fd_cache.ml);
+        }
+    }
+}  /* _PR_Putfd */
+
+PR_IMPLEMENT(PRStatus) PR_SetFDCacheSize(PRIntn low, PRIntn high)
+{
+    /*
+    ** This can be called at any time, may adjust the cache sizes,
+    ** turn the caches off, or turn them on. It is not dependent
+    ** on the compilation setting of DEBUG.
+    */
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (low > high) low = high;  /* sanity check the params */
+    
+    PR_Lock(_pr_fd_cache.ml);
+    if (0 == high)  /* shutting down or staying down */
+    {
+        if (0 != _pr_fd_cache.limit_high)  /* shutting down */
+        {
+            _pr_fd_cache.limit_high = 0;  /* stop use */
+            /*
+            ** Hold the lock throughout - nobody's going to want it
+            ** other than another caller to this routine. Just don't
+            ** let that happen.
+            **
+            ** Put all the cached fds onto the new cache.
+            */
+            while (NULL != _pr_fd_cache.head)
+            {
+                PRFileDesc *fd = _pr_fd_cache.head;
+                _pr_fd_cache.head = fd->higher;
+                PR_StackPush(_pr_fd_cache.stack, (PRStackElem*)(&fd->higher));
+            }
+            _pr_fd_cache.limit_low = 0;
+            _pr_fd_cache.tail = NULL;
+            _pr_fd_cache.count = 0;
+        }
+    }
+    else  /* starting up or just adjusting parameters */
+    {
+        PRBool was_using_stack = (0 == _pr_fd_cache.limit_high);
+        _pr_fd_cache.limit_low = low;
+        _pr_fd_cache.limit_high = high;
+        if (was_using_stack)  /* was using stack - feed into cache */
+        {
+            PRStackElem *pop;
+            while (NULL != (pop = PR_StackPop(_pr_fd_cache.stack)))
+            {
+                PRFileDesc *fd = (PRFileDesc*)
+                    ((PRPtrdiff)pop - (PRPtrdiff)stack2fd);
+                if (NULL == _pr_fd_cache.tail) _pr_fd_cache.tail = fd;
+                fd->higher = _pr_fd_cache.head;
+                _pr_fd_cache.head = fd;
+                _pr_fd_cache.count += 1;
+            }
+        }
+    }
+    PR_Unlock(_pr_fd_cache.ml);
+    return PR_SUCCESS;
+}  /* PR_SetFDCacheSize */
+
+void _PR_InitFdCache(void)
+{
+    /*
+    ** The fd caching is enabled by default for DEBUG builds,
+    ** disabled by default for OPT builds. That default can
+    ** be overridden at runtime using environment variables
+    ** or a super-wiz-bang API.
+    */
+    const char *low = PR_GetEnv("NSPR_FD_CACHE_SIZE_LOW");
+    const char *high = PR_GetEnv("NSPR_FD_CACHE_SIZE_HIGH");
+
+    /* 
+    ** _low is allowed to be zero, _high is not.
+    ** If _high is zero, we're not doing the caching.
+    */
+
+    _pr_fd_cache.limit_low = 0;
+#if defined(DEBUG)
+    _pr_fd_cache.limit_high = FD_SETSIZE;
+#else
+    _pr_fd_cache.limit_high = 0;
+#endif  /* defined(DEBUG) */
+
+    if (NULL != low) _pr_fd_cache.limit_low = atoi(low);
+    if (NULL != high) _pr_fd_cache.limit_high = atoi(high);
+
+    if (_pr_fd_cache.limit_high < _pr_fd_cache.limit_low)
+        _pr_fd_cache.limit_high = _pr_fd_cache.limit_low;
+
+    _pr_fd_cache.ml = PR_NewLock();
+    PR_ASSERT(NULL != _pr_fd_cache.ml);
+    _pr_fd_cache.stack = PR_CreateStack("FD");
+    PR_ASSERT(NULL != _pr_fd_cache.stack);
+
+}  /* _PR_InitFdCache */
+
+void _PR_CleanupFdCache(void)
+{
+    PRFileDesc *fd, *next;
+    PRStackElem *pop;
+
+    for (fd = _pr_fd_cache.head; fd != NULL; fd = next)
+    {
+        next = fd->higher;
+        PR_DELETE(fd->secret);
+        PR_DELETE(fd);
+    }
+    PR_DestroyLock(_pr_fd_cache.ml);
+    while ((pop = PR_StackPop(_pr_fd_cache.stack)) != NULL)
+    {
+        fd = (PRFileDesc*)((PRPtrdiff)pop - (PRPtrdiff)stack2fd);
+        PR_DELETE(fd->secret);
+        PR_DELETE(fd);
+    }
+    PR_DestroyStack(_pr_fd_cache.stack);
+}  /* _PR_CleanupFdCache */
+
+/* prfdcach.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prfile.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prfile.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,846 @@
+/* -*- 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 <string.h>
+#include <fcntl.h>
+
+#ifdef XP_UNIX
+#if defined(AIX) || defined(QNX)
+/* To pick up sysconf */
+#include <unistd.h>
+#else
+/* To pick up getrlimit, setrlimit */
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+#endif /* XP_UNIX */
+
+extern PRLock *_pr_flock_lock;
+extern PRCondVar *_pr_flock_cv;
+
+static PRInt32 PR_CALLBACK FileRead(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+    PRInt32 rv = 0;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (_PR_PENDING_INTERRUPT(me)) {
+ 		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		rv = -1;
+    }
+    if (_PR_IO_PENDING(me)) {
+        PR_SetError(PR_IO_PENDING_ERROR, 0);
+	rv = -1;
+    }
+    if (rv == -1)
+    	return rv;
+
+	rv = _PR_MD_READ(fd, buf, amount);
+	if (rv < 0) {
+		PR_ASSERT(rv == -1);
+	}
+    PR_LOG(_pr_io_lm, PR_LOG_MAX, ("read -> %d", rv));
+    return rv;
+}
+
+static PRInt32 PR_CALLBACK FileWrite(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+    PRInt32 rv = 0;
+    PRInt32 temp, count;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (_PR_PENDING_INTERRUPT(me)) {
+        me->flags &= ~_PR_INTERRUPT;
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+	    rv = -1;
+    }
+    if (_PR_IO_PENDING(me)) {
+        PR_SetError(PR_IO_PENDING_ERROR, 0);
+	    rv = -1;
+    }
+    if (rv != 0)
+    	return rv;
+
+    count = 0;
+#if !defined(_PR_HAVE_O_APPEND)  /* Bugzilla: 4090, 276330 */
+    if ( PR_TRUE == fd->secret->appendMode ) {
+        rv = PR_Seek(fd, 0, PR_SEEK_END );
+        if ( -1 == rv )  {
+            return rv;
+        }
+    } /* if (fd->secret->appendMode...) */
+#endif /* _PR_HAVE_O_APPEND */
+    while (amount > 0) {
+		temp = _PR_MD_WRITE(fd, buf, amount);
+		if (temp < 0) {
+			count = -1;
+			break;
+		}
+		count += temp;
+		if (fd->secret->nonblocking) {
+			break;
+		}
+		buf = (const void*) ((const char*)buf + temp);
+		amount -= temp;
+    }
+    PR_LOG(_pr_io_lm, PR_LOG_MAX, ("write -> %d", count));
+    return count;
+}
+
+static PROffset32 PR_CALLBACK FileSeek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
+{
+    PROffset32 result;
+
+    result = _PR_MD_LSEEK(fd, offset, whence);
+    return result;
+}
+
+static PROffset64 PR_CALLBACK FileSeek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence)
+{
+#ifdef XP_MAC
+#pragma unused( fd, offset, whence )
+#endif
+    PROffset64 result;
+
+    result = _PR_MD_LSEEK64(fd, offset, whence);
+    return result;
+}
+
+static PRInt32 PR_CALLBACK FileAvailable(PRFileDesc *fd)
+{
+    PRInt32 result, cur, end;
+
+    cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR);
+
+	if (cur >= 0)
+    	end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END);
+
+    if ((cur < 0) || (end < 0)) {
+        return -1;
+    }
+
+    result = end - cur;
+    _PR_MD_LSEEK(fd, cur, PR_SEEK_SET);
+
+    return result;
+}
+
+static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc *fd)
+{
+#ifdef XP_MAC
+#pragma unused( fd )
+#endif
+    PRInt64 result, cur, end;
+    PRInt64 minus_one;
+
+    LL_I2L(minus_one, -1);
+    cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR);
+
+    if (LL_GE_ZERO(cur))
+    	end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END);
+
+    if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one;
+
+    LL_SUB(result, end, cur);
+    (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET);
+
+    return result;
+}
+
+static PRInt32 PR_CALLBACK PipeAvailable(PRFileDesc *fd)
+{
+	PRInt32 rv;
+	rv =  _PR_MD_PIPEAVAILABLE(fd);
+	return rv;		
+}
+
+static PRInt64 PR_CALLBACK PipeAvailable64(PRFileDesc *fd)
+{
+    PRInt64 rv;
+    LL_I2L(rv, _PR_MD_PIPEAVAILABLE(fd));
+	return rv;		
+}
+
+static PRStatus PR_CALLBACK PipeSync(PRFileDesc *fd)
+{
+#if defined(XP_MAC)
+#pragma unused (fd)
+#endif
+
+	return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK FileGetInfo(PRFileDesc *fd, PRFileInfo *info)
+{
+	PRInt32 rv;
+
+    rv = _PR_MD_GETOPENFILEINFO(fd, info);
+    if (rv < 0) {
+	return PR_FAILURE;
+    } else
+	return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK FileGetInfo64(PRFileDesc *fd, PRFileInfo64 *info)
+{
+#ifdef XP_MAC
+#pragma unused( fd, info )
+#endif
+    /* $$$$ NOT YET IMPLEMENTED */
+	PRInt32 rv;
+
+    rv = _PR_MD_GETOPENFILEINFO64(fd, info);
+    if (rv < 0) return PR_FAILURE;
+    else return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK FileSync(PRFileDesc *fd)
+{
+    PRInt32 result;
+    result = _PR_MD_FSYNC(fd);
+    if (result < 0) {
+		return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK FileClose(PRFileDesc *fd)
+{
+    if (!fd || !fd->secret
+            || (fd->secret->state != _PR_FILEDESC_OPEN
+            && fd->secret->state != _PR_FILEDESC_CLOSED)) {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    if (fd->secret->state == _PR_FILEDESC_OPEN) {
+        if (_PR_MD_CLOSE_FILE(fd->secret->md.osfd) < 0) {
+            return PR_FAILURE;
+        }
+        fd->secret->state = _PR_FILEDESC_CLOSED;
+    }
+    PR_FreeFileDesc(fd);
+    return PR_SUCCESS;
+}
+
+static PRInt16 PR_CALLBACK FilePoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+#ifdef XP_MAC
+#pragma unused( fd, in_flags )
+#endif
+    *out_flags = 0;
+    return in_flags;
+}  /* FilePoll */
+
+static PRIOMethods _pr_fileMethods = {
+    PR_DESC_FILE,
+    FileClose,
+    FileRead,
+    FileWrite,
+    FileAvailable,
+    FileAvailable64,
+    FileSync,
+    FileSeek,
+    FileSeek64,
+    FileGetInfo,
+    FileGetInfo64,
+    (PRWritevFN)_PR_InvalidInt,		
+    (PRConnectFN)_PR_InvalidStatus,		
+    (PRAcceptFN)_PR_InvalidDesc,		
+    (PRBindFN)_PR_InvalidStatus,		
+    (PRListenFN)_PR_InvalidStatus,		
+    (PRShutdownFN)_PR_InvalidStatus,	
+    (PRRecvFN)_PR_InvalidInt,		
+    (PRSendFN)_PR_InvalidInt,		
+    (PRRecvfromFN)_PR_InvalidInt,	
+    (PRSendtoFN)_PR_InvalidInt,		
+    FilePoll,         
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,	
+    (PRGetpeernameFN)_PR_InvalidStatus,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRGetsocketoptionFN)_PR_InvalidStatus,	
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void)
+{
+    return &_pr_fileMethods;
+}
+
+static PRIOMethods _pr_pipeMethods = {
+    PR_DESC_PIPE,
+    FileClose,
+    FileRead,
+    FileWrite,
+    PipeAvailable,
+    PipeAvailable64,
+    PipeSync,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,		
+    (PRConnectFN)_PR_InvalidStatus,		
+    (PRAcceptFN)_PR_InvalidDesc,		
+    (PRBindFN)_PR_InvalidStatus,		
+    (PRListenFN)_PR_InvalidStatus,		
+    (PRShutdownFN)_PR_InvalidStatus,	
+    (PRRecvFN)_PR_InvalidInt,		
+    (PRSendFN)_PR_InvalidInt,		
+    (PRRecvfromFN)_PR_InvalidInt,	
+    (PRSendtoFN)_PR_InvalidInt,		
+    FilePoll,         
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,	
+    (PRGetpeernameFN)_PR_InvalidStatus,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRGetsocketoptionFN)_PR_InvalidStatus,	
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void)
+{
+    return &_pr_pipeMethods;
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
+{
+    PROsfd osfd;
+    PRFileDesc *fd = 0;
+#if !defined(_PR_HAVE_O_APPEND)
+    PRBool  appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    /* Map pr open flags and mode to os specific flags */
+
+    osfd = _PR_MD_OPEN(name, flags, mode);
+    if (osfd != -1) {
+        fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
+        if (!fd) {
+            (void) _PR_MD_CLOSE_FILE(osfd);
+        } else {
+#if !defined(_PR_HAVE_O_APPEND)
+            fd->secret->appendMode = appendMode;
+#endif
+            _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
+        }
+    }
+    return fd;
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFile(
+    const char *name, PRIntn flags, PRIntn mode)
+{
+    PROsfd osfd;
+    PRFileDesc *fd = 0;
+#if !defined(_PR_HAVE_O_APPEND)
+    PRBool  appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    /* Map pr open flags and mode to os specific flags */
+
+    osfd = _PR_MD_OPEN_FILE(name, flags, mode);
+    if (osfd != -1) {
+        fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
+        if (!fd) {
+            (void) _PR_MD_CLOSE_FILE(osfd);
+        } else {
+#if !defined(_PR_HAVE_O_APPEND)
+            fd->secret->appendMode = appendMode;
+#endif
+            _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
+        }
+    }
+    return fd;
+}
+
+PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void)
+{
+#if defined(XP_UNIX) && !defined(AIX) && !defined(NEXTSTEP) && !defined(QNX)
+    struct rlimit rlim;
+
+    if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
+       /* XXX need to call PR_SetError() */
+       return -1;
+    }
+
+    return rlim.rlim_max;
+#elif defined(AIX) || defined(NEXTSTEP) || defined(QNX)
+    return sysconf(_SC_OPEN_MAX);
+#elif defined(WIN32)
+    /*
+     * There is a systemwide limit of 65536 user handles.
+     */
+    return 16384;
+#elif defined (WIN16)
+    return FOPEN_MAX;
+#elif defined(XP_OS2)
+    ULONG ulReqCount = 0;
+    ULONG ulCurMaxFH = 0;
+    DosSetRelMaxFH(&ulReqCount, &ulCurMaxFH);
+    return ulCurMaxFH;
+#elif defined (XP_MAC) || defined(XP_BEOS)
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+   return -1;
+#else
+    write me;
+#endif
+}
+
+PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(int table_size)
+{
+#if defined(XP_UNIX) && !defined(AIX) && !defined(NEXTSTEP) && !defined(QNX)
+    struct rlimit rlim;
+    PRInt32 tableMax = PR_GetSysfdTableMax();
+
+    if (tableMax < 0) 
+        return -1;
+
+    if (tableMax > FD_SETSIZE)
+        tableMax = FD_SETSIZE;
+
+    rlim.rlim_max = tableMax;
+
+    /* Grow as much as we can; even if too big */
+    if ( rlim.rlim_max < table_size )
+        rlim.rlim_cur = rlim.rlim_max;
+    else
+        rlim.rlim_cur = table_size;
+
+    if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
+        /* XXX need to call PR_SetError() */
+        return -1;
+    }
+
+    return rlim.rlim_cur;
+#elif defined(XP_OS2)
+    PRInt32 tableMax = PR_GetSysfdTableMax();
+    if (table_size > tableMax) {
+      APIRET rc = NO_ERROR;
+      rc = DosSetMaxFH(table_size);
+      if (rc == NO_ERROR)
+        return table_size;
+      else
+        return -1;
+    } 
+    return tableMax;
+#elif defined(AIX) || defined(NEXTSTEP) || defined(QNX) \
+        || defined(WIN32) || defined(WIN16) || defined(XP_BEOS)
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return -1;
+#elif defined (XP_MAC)
+#pragma unused (table_size)
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+   return -1;
+#else
+    write me;
+#endif
+}
+
+PR_IMPLEMENT(PRStatus) PR_Delete(const char *name)
+{
+	PRInt32 rv;
+
+	rv = _PR_MD_DELETE(name);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info)
+{
+	PRInt32 rv;
+
+	rv = _PR_MD_GETFILEINFO(fn, info);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info)
+{
+#ifdef XP_MAC
+#pragma unused (fn, info)
+#endif
+    PRInt32 rv;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    rv = _PR_MD_GETFILEINFO64(fn, info);
+    if (rv < 0) {
+        return PR_FAILURE;
+    } else {
+        return PR_SUCCESS;
+    }
+}
+
+PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to)
+{
+	PRInt32 rv;
+
+	rv = _PR_MD_RENAME(from, to);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how)
+{
+PRInt32 rv;
+
+	rv = _PR_MD_ACCESS(name, how);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
+/*
+** Import an existing OS file to NSPR 
+*/
+PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PROsfd osfd)
+{
+    PRFileDesc *fd = NULL;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
+    if( !fd ) {
+        (void) _PR_MD_CLOSE_FILE(osfd);
+    } else {
+        _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
+    }
+
+    return fd;
+}
+
+/*
+** Import an existing OS pipe to NSPR 
+*/
+PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PROsfd osfd)
+{
+    PRFileDesc *fd = NULL;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    fd = PR_AllocFileDesc(osfd, &_pr_pipeMethods);
+    if( !fd ) {
+        (void) _PR_MD_CLOSE_FILE(osfd);
+    } else {
+        _PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
+#ifdef WINNT
+        fd->secret->md.sync_file_io = PR_TRUE;
+#endif
+    }
+
+    return fd;
+}
+
+#ifndef NO_NSPR_10_SUPPORT
+/*
+** PR_Stat() for Win16 is defined in w16io.c
+** it is a hack to circumvent problems in Gromit and Java
+** See also: BugSplat: 98516.
+*/
+#if !defined(WIN16)
+/*
+ * This function is supposed to be for backward compatibility with
+ * nspr 1.0.  Therefore, it still uses the nspr 1.0 error-reporting
+ * mechanism -- returns a PRInt32, which is the error code when the call
+ * fails.
+ * 
+ * If we need this function in nspr 2.0, it should be changed to
+ * return PRStatus, as follows:
+ *
+ * PR_IMPLEMENT(PRStatus) PR_Stat(const char *name, struct stat *buf)
+ * {
+ *     PRInt32 rv;
+ *
+ *     rv = _PR_MD_STAT(name, buf);
+ *     if (rv < 0)
+ *         return PR_FAILURE;
+ *     else
+ *         return PR_SUCCESS;
+ * }
+ *
+ * -- wtc, 2/14/97.
+ */
+PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf)
+{
+    PRInt32 rv;
+
+    rv = _PR_MD_STAT(name, buf);
+	return rv;
+}
+
+#endif /* !defined(WIN16)  */
+#endif /* ! NO_NSPR_10_SUPPORT */
+
+PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd)
+{
+    PRStatus status = PR_SUCCESS;
+
+#ifdef WINNT
+    if (!fd->secret->md.io_model_committed) {
+        PRInt32 rv;
+        rv = _md_Associate((HANDLE)fd->secret->md.osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+#endif
+
+    PR_Lock(_pr_flock_lock);
+    while (fd->secret->lockCount == -1)
+        PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT);
+    if (fd->secret->lockCount == 0) {
+        fd->secret->lockCount = -1;
+        PR_Unlock(_pr_flock_lock);
+        status = _PR_MD_LOCKFILE(fd->secret->md.osfd);
+        PR_Lock(_pr_flock_lock);
+        fd->secret->lockCount = (status == PR_SUCCESS) ? 1 : 0;
+        PR_NotifyAllCondVar(_pr_flock_cv);
+    } else {
+        fd->secret->lockCount++;
+    }
+    PR_Unlock(_pr_flock_lock);
+ 
+    return status;
+}
+
+PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd)
+{
+    PRStatus status = PR_SUCCESS;
+
+#ifdef WINNT
+    if (!fd->secret->md.io_model_committed) {
+        PRInt32 rv;
+        rv = _md_Associate((HANDLE)fd->secret->md.osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+#endif
+
+    PR_Lock(_pr_flock_lock);
+    if (fd->secret->lockCount == 0) {
+        status = _PR_MD_TLOCKFILE(fd->secret->md.osfd);
+        PR_ASSERT(status == PR_SUCCESS || fd->secret->lockCount == 0);
+        if (status == PR_SUCCESS)
+            fd->secret->lockCount = 1;
+    } else {
+        fd->secret->lockCount++;
+    }
+    PR_Unlock(_pr_flock_lock);
+
+    return status;
+}
+
+PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd)
+{
+    PRStatus rv = PR_SUCCESS;
+
+    PR_Lock(_pr_flock_lock);
+    if (fd->secret->lockCount == 1) {
+        rv = _PR_MD_UNLOCKFILE(fd->secret->md.osfd);
+        if (rv == PR_SUCCESS) 
+            fd->secret->lockCount = 0;
+    } else {
+        fd->secret->lockCount--;
+    }
+    PR_Unlock(_pr_flock_lock);
+
+    return rv;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CreatePipe(
+    PRFileDesc **readPipe,
+    PRFileDesc **writePipe
+)
+{
+#if defined(XP_MAC)
+#pragma unused (readPipe, writePipe)
+#endif
+
+#ifdef WIN32
+    HANDLE readEnd, writeEnd;
+    SECURITY_ATTRIBUTES pipeAttributes;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    ZeroMemory(&pipeAttributes, sizeof(pipeAttributes));
+    pipeAttributes.nLength = sizeof(pipeAttributes);
+    pipeAttributes.bInheritHandle = TRUE;
+    if (CreatePipe(&readEnd, &writeEnd, &pipeAttributes, 0) == 0) {
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        return PR_FAILURE;
+    }
+    *readPipe = PR_AllocFileDesc((PROsfd)readEnd, &_pr_pipeMethods);
+    if (NULL == *readPipe) {
+        CloseHandle(readEnd);
+        CloseHandle(writeEnd);
+        return PR_FAILURE;
+    }
+    *writePipe = PR_AllocFileDesc((PROsfd)writeEnd, &_pr_pipeMethods);
+    if (NULL == *writePipe) {
+        PR_Close(*readPipe);
+        CloseHandle(writeEnd);
+        return PR_FAILURE;
+    }
+#ifdef WINNT
+    (*readPipe)->secret->md.sync_file_io = PR_TRUE;
+    (*writePipe)->secret->md.sync_file_io = PR_TRUE;
+#endif
+    (*readPipe)->secret->inheritable = _PR_TRI_TRUE;
+    (*writePipe)->secret->inheritable = _PR_TRI_TRUE;
+    return PR_SUCCESS;
+#elif defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
+#ifdef XP_OS2
+    HFILE pipefd[2];
+#else
+    int pipefd[2];
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#ifdef XP_OS2
+    if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) {
+#else
+    if (pipe(pipefd) == -1) {
+#endif
+        /* XXX map pipe error */
+        PR_SetError(PR_UNKNOWN_ERROR, errno);
+        return PR_FAILURE;
+    }
+    *readPipe = PR_AllocFileDesc(pipefd[0], &_pr_pipeMethods);
+    if (NULL == *readPipe) {
+        close(pipefd[0]);
+        close(pipefd[1]);
+        return PR_FAILURE;
+    }
+    *writePipe = PR_AllocFileDesc(pipefd[1], &_pr_pipeMethods);
+    if (NULL == *writePipe) {
+        PR_Close(*readPipe);
+        close(pipefd[1]);
+        return PR_FAILURE;
+    }
+#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
+    _PR_MD_MAKE_NONBLOCK(*readPipe);
+#endif
+    _PR_MD_INIT_FD_INHERITABLE(*readPipe, PR_FALSE);
+#ifndef XP_BEOS /* Pipes are nonblocking on BeOS */
+    _PR_MD_MAKE_NONBLOCK(*writePipe);
+#endif
+    _PR_MD_INIT_FD_INHERITABLE(*writePipe, PR_FALSE);
+    return PR_SUCCESS;
+#else
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+#endif
+}
+
+#ifdef MOZ_UNICODE
+/* ================ UTF16 Interfaces ================================ */
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16(
+    const PRUnichar *name, PRIntn flags, PRIntn mode)
+{ 
+    PROsfd osfd;
+    PRFileDesc *fd = 0;
+#if !defined(_PR_HAVE_O_APPEND)
+    PRBool  appendMode = ( PR_APPEND & flags )? PR_TRUE : PR_FALSE;
+#endif
+   
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+  
+    /* Map pr open flags and mode to os specific flags */
+    osfd = _PR_MD_OPEN_FILE_UTF16(name, flags, mode);
+    if (osfd != -1) {
+        fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
+        if (!fd) {
+            (void) _PR_MD_CLOSE_FILE(osfd);
+        } else {
+#if !defined(_PR_HAVE_O_APPEND)
+            fd->secret->appendMode = appendMode;
+#endif
+            _PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
+        }
+    }
+    return fd;
+}
+ 
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info)
+{
+#ifdef XP_MAC
+#pragma unused (fn, info)
+#endif
+    PRInt32 rv;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    rv = _PR_MD_GETFILEINFO64_UTF16(fn, info);
+    if (rv < 0) {
+        return PR_FAILURE;
+    } else {
+        return PR_SUCCESS;
+    }
+}
+
+/* ================ UTF16 Interfaces ================================ */
+#endif /* MOZ_UNICODE */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prio.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prio.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,202 @@
+/* -*- 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 <string.h> /* for memset() */
+
+
+/************************************************************************/
+
+PRLock *_pr_flock_lock;
+PRCondVar *_pr_flock_cv;
+
+void _PR_InitIO(void)
+{
+    const PRIOMethods *methods = PR_GetFileMethods();
+
+    _PR_InitFdCache();
+
+    _pr_flock_lock = PR_NewLock();
+    _pr_flock_cv = PR_NewCondVar(_pr_flock_lock);
+
+#ifdef WIN32
+    _pr_stdin = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_INPUT_HANDLE),
+            methods);
+    _pr_stdout = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_OUTPUT_HANDLE),
+            methods);
+    _pr_stderr = PR_AllocFileDesc((PROsfd)GetStdHandle(STD_ERROR_HANDLE),
+            methods);
+#ifdef WINNT
+    _pr_stdin->secret->md.sync_file_io = PR_TRUE;
+    _pr_stdout->secret->md.sync_file_io = PR_TRUE;
+    _pr_stderr->secret->md.sync_file_io = PR_TRUE;
+#endif
+#else
+    _pr_stdin = PR_AllocFileDesc(0, methods);
+    _pr_stdout = PR_AllocFileDesc(1, methods);
+    _pr_stderr = PR_AllocFileDesc(2, methods);
+#endif
+    _PR_MD_INIT_FD_INHERITABLE(_pr_stdin, PR_TRUE);
+    _PR_MD_INIT_FD_INHERITABLE(_pr_stdout, PR_TRUE);
+    _PR_MD_INIT_FD_INHERITABLE(_pr_stderr, PR_TRUE);
+
+    _PR_MD_INIT_IO();
+}
+
+void _PR_CleanupIO(void)
+{
+    PR_FreeFileDesc(_pr_stdin);
+    _pr_stdin = NULL;
+    PR_FreeFileDesc(_pr_stdout);
+    _pr_stdout = NULL;
+    PR_FreeFileDesc(_pr_stderr);
+    _pr_stderr = NULL;
+
+    if (_pr_flock_cv) {
+        PR_DestroyCondVar(_pr_flock_cv);
+        _pr_flock_cv = NULL;
+    }
+    if (_pr_flock_lock) {
+        PR_DestroyLock(_pr_flock_lock);
+        _pr_flock_lock = NULL;
+    }
+
+    _PR_CleanupFdCache();
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd)
+{
+    PRFileDesc *result = NULL;
+    PR_ASSERT((int) osfd >= PR_StandardInput && osfd <= PR_StandardError);
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    
+    switch (osfd)
+    {
+        case PR_StandardInput: result = _pr_stdin; break;
+        case PR_StandardOutput: result = _pr_stdout; break;
+        case PR_StandardError: result = _pr_stderr; break;
+        default:
+            (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    }
+    return result;
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
+    PROsfd osfd, const PRIOMethods *methods)
+{
+    PRFileDesc *fd;
+
+#ifdef XP_UNIX
+	/*
+	 * Assert that the file descriptor is small enough to fit in the
+	 * fd_set passed to select
+	 */
+	PR_ASSERT(osfd < FD_SETSIZE);
+#endif
+    fd = _PR_Getfd();
+    if (fd) {
+        /* Initialize the members of PRFileDesc and PRFilePrivate */
+        fd->methods = methods;
+        fd->secret->state = _PR_FILEDESC_OPEN;
+	fd->secret->md.osfd = osfd;
+        _PR_MD_INIT_FILEDESC(fd);
+    } else {
+	    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+
+    return fd;
+}
+
+PR_IMPLEMENT(void) PR_FreeFileDesc(PRFileDesc *fd)
+{
+    PR_ASSERT(fd);
+#ifdef XP_MAC
+	_PR_MD_FREE_FILEDESC(fd);
+#endif
+    _PR_Putfd(fd);
+}
+
+/*
+** Wait for some i/o to finish on one or more more poll descriptors.
+*/
+PR_IMPLEMENT(PRInt32) PR_Poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+	return(_PR_MD_PR_POLL(pds, npds, timeout));
+}
+
+/*
+** Set the inheritance attribute of a file descriptor.
+*/
+PR_IMPLEMENT(PRStatus) PR_SetFDInheritable(
+    PRFileDesc *fd,
+    PRBool inheritable)
+{
+#if defined(XP_UNIX) || defined(WIN32) || defined(XP_OS2) || defined(XP_BEOS)
+    /*
+     * Only a non-layered, NSPR file descriptor can be inherited
+     * by a child process.
+     */
+    if (fd->identity != PR_NSPR_IO_LAYER) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if (fd->secret->inheritable != inheritable) {
+        if (_PR_MD_SET_FD_INHERITABLE(fd, inheritable) == PR_FAILURE) {
+            return PR_FAILURE;
+        }
+        fd->secret->inheritable = inheritable;
+    }
+    return PR_SUCCESS;
+#else
+#ifdef XP_MAC
+#pragma unused (fd, inheritable)
+#endif
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+#endif
+}
+
+/*
+** This function only has a useful implementation in the debug build of
+** the pthreads version.
+*/
+PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg)
+{
+    /* do nothing */
+}  /* PT_FPrintStats */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/priometh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/priometh.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,628 @@
+/* -*- 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 <string.h>
+
+/*****************************************************************************/
+/************************** Invalid I/O method object ************************/
+/*****************************************************************************/
+PRIOMethods _pr_faulty_methods = {
+    (PRDescType)0,
+    (PRCloseFN)_PR_InvalidStatus,
+    (PRReadFN)_PR_InvalidInt,
+    (PRWriteFN)_PR_InvalidInt,
+    (PRAvailableFN)_PR_InvalidInt,
+    (PRAvailable64FN)_PR_InvalidInt64,
+    (PRFsyncFN)_PR_InvalidStatus,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+    (PRPollFN)_PR_InvalidInt16,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt
+};
+
+PRIntn _PR_InvalidInt(void)
+{
+    PR_ASSERT(!"I/O method is invalid");
+    PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+    return -1;
+}  /* _PR_InvalidInt */
+
+PRInt16 _PR_InvalidInt16(void)
+{
+    PR_ASSERT(!"I/O method is invalid");
+    PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+    return -1;
+}  /* _PR_InvalidInt */
+
+PRInt64 _PR_InvalidInt64(void)
+{
+    PRInt64 rv;
+    LL_I2L(rv, -1);
+    PR_ASSERT(!"I/O method is invalid");
+    PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+    return rv;
+}  /* _PR_InvalidInt */
+
+/*
+ * An invalid method that returns PRStatus
+ */
+
+PRStatus _PR_InvalidStatus(void)
+{
+    PR_ASSERT(!"I/O method is invalid");
+    PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+    return PR_FAILURE;
+}  /* _PR_InvalidDesc */
+
+/*
+ * An invalid method that returns a pointer
+ */
+
+PRFileDesc *_PR_InvalidDesc(void)
+{
+    PR_ASSERT(!"I/O method is invalid");
+    PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+    return NULL;
+}  /* _PR_InvalidDesc */
+
+PR_IMPLEMENT(PRDescType) PR_GetDescType(PRFileDesc *file)
+{
+    return file->methods->file_type;
+}
+
+PR_IMPLEMENT(PRStatus) PR_Close(PRFileDesc *fd)
+{
+    return (fd->methods->close)(fd);
+}
+
+PR_IMPLEMENT(PRInt32) PR_Read(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+	return((fd->methods->read)(fd,buf,amount));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Write(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+	return((fd->methods->write)(fd,buf,amount));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
+{
+	return((fd->methods->seek)(fd, offset, whence));
+}
+
+PR_IMPLEMENT(PRInt64) PR_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
+{
+	return((fd->methods->seek64)(fd, offset, whence));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Available(PRFileDesc *fd)
+{
+	return((fd->methods->available)(fd));
+}
+
+PR_IMPLEMENT(PRInt64) PR_Available64(PRFileDesc *fd)
+{
+	return((fd->methods->available64)(fd));
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetOpenFileInfo(PRFileDesc *fd, PRFileInfo *info)
+{
+	return((fd->methods->fileInfo)(fd, info));
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetOpenFileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
+{
+	return((fd->methods->fileInfo64)(fd, info));
+}
+
+PR_IMPLEMENT(PRStatus) PR_Sync(PRFileDesc *fd)
+{
+	return((fd->methods->fsync)(fd));
+}
+
+PR_IMPLEMENT(PRStatus) PR_Connect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	return((fd->methods->connect)(fd,addr,timeout));
+}
+
+PR_IMPLEMENT(PRStatus) PR_ConnectContinue(
+    PRFileDesc *fd, PRInt16 out_flags)
+{
+	return((fd->methods->connectcontinue)(fd,out_flags));
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_Accept(PRFileDesc *fd, PRNetAddr *addr,
+PRIntervalTime timeout)
+{
+	return((fd->methods->accept)(fd,addr,timeout));
+}
+
+PR_IMPLEMENT(PRStatus) PR_Bind(PRFileDesc *fd, const PRNetAddr *addr)
+{
+	return((fd->methods->bind)(fd,addr));
+}
+
+PR_IMPLEMENT(PRStatus) PR_Shutdown(PRFileDesc *fd, PRShutdownHow how)
+{
+	return((fd->methods->shutdown)(fd,how));
+}
+
+PR_IMPLEMENT(PRStatus) PR_Listen(PRFileDesc *fd, PRIntn backlog)
+{
+	return((fd->methods->listen)(fd,backlog));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Recv(PRFileDesc *fd, void *buf, PRInt32 amount,
+PRIntn flags, PRIntervalTime timeout)
+{
+	return((fd->methods->recv)(fd,buf,amount,flags,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+PRIntn flags, PRIntervalTime timeout)
+{
+	return((fd->methods->send)(fd,buf,amount,flags,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_Writev(PRFileDesc *fd, const PRIOVec *iov,
+PRInt32 iov_size, PRIntervalTime timeout)
+{
+    if (iov_size > PR_MAX_IOVECTOR_SIZE)
+    {
+        PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
+        return -1;
+    }
+	return((fd->methods->writev)(fd,iov,iov_size,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
+PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
+{
+	return((fd->methods->recvfrom)(fd,buf,amount,flags,addr,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_SendTo(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	return((fd->methods->sendto)(fd,buf,amount,flags,addr,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_TransmitFile(
+    PRFileDesc *sd, PRFileDesc *fd, const void *hdr, PRInt32 hlen,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+	return((sd->methods->transmitfile)(sd,fd,hdr,hlen,flags,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_AcceptRead(
+    PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
+    void *buf, PRInt32 amount, PRIntervalTime timeout)
+{
+	return((sd->methods->acceptread)(sd, nd, raddr, buf, amount,timeout));
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetSockName(PRFileDesc *fd, PRNetAddr *addr)
+{
+	return((fd->methods->getsockname)(fd,addr));
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
+{
+	return((fd->methods->getpeername)(fd,addr));
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetSocketOption(
+    PRFileDesc *fd, PRSocketOptionData *data)
+{
+	return((fd->methods->getsocketoption)(fd, data));
+}
+
+PR_IMPLEMENT(PRStatus) PR_SetSocketOption(
+    PRFileDesc *fd, const PRSocketOptionData *data)
+{
+	return((fd->methods->setsocketoption)(fd, data));
+}
+
+PR_IMPLEMENT(PRInt32) PR_SendFile(
+	PRFileDesc *sd, PRSendFileData *sfd,
+	PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+	return((sd->methods->sendfile)(sd,sfd,flags,timeout));
+}
+
+PR_IMPLEMENT(PRInt32) PR_EmulateAcceptRead(
+    PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
+    void *buf, PRInt32 amount, PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+    PRNetAddr remote;
+    PRFileDesc *accepted = NULL;
+
+    /*
+    ** The timeout does not apply to the accept portion of the
+    ** operation - it waits indefinitely.
+    */
+    accepted = PR_Accept(sd, &remote, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == accepted) return rv;
+
+    rv = PR_Recv(accepted, buf, amount, 0, timeout);
+    if (rv >= 0)
+    {
+        /* copy the new info out where caller can see it */
+#define AMASK ((PRPtrdiff)7)  /* mask for alignment of PRNetAddr */
+        PRPtrdiff aligned = (PRPtrdiff)buf + amount + AMASK;
+        *raddr = (PRNetAddr*)(aligned & ~AMASK);
+        memcpy(*raddr, &remote, PR_NETADDR_SIZE(&remote));
+        *nd = accepted;
+        return rv;
+    }
+
+    PR_Close(accepted);
+    return rv;
+}
+
+/*
+ * PR_EmulateSendFile
+ *
+ *    Send file sfd->fd across socket sd. If header/trailer are specified
+ *    they are sent before and after the file, respectively.
+ *
+ *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
+ *    
+ *    return number of bytes sent or -1 on error
+ *
+ */
+
+#if defined(XP_UNIX) || defined(WIN32)
+
+/*
+ * An implementation based on memory-mapped files
+ */
+
+#define SENDFILE_MMAP_CHUNK	(256 * 1024)
+
+PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(
+    PRFileDesc *sd, PRSendFileData *sfd,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    PRInt32 rv, count = 0;
+    PRInt32 len, file_bytes, index = 0;
+    PRFileInfo info;
+    PRIOVec iov[3];
+    PRFileMap *mapHandle = NULL;
+    void *addr = (void*)0; /* initialized to some arbitrary value. Keeps compiler warnings down. */
+    PRUint32 file_mmap_offset, alignment;
+    PRInt64 zero64;
+    PROffset64 file_mmap_offset64;
+    PRUint32 addr_offset, mmap_len;
+
+    /* Get file size */
+    if (PR_SUCCESS != PR_GetOpenFileInfo(sfd->fd, &info)) {
+        count = -1;
+        goto done;
+    }
+    if (sfd->file_nbytes &&
+            (info.size < (sfd->file_offset + sfd->file_nbytes))) {
+        /*
+         * there are fewer bytes in file to send than specified
+         */
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        count = -1;
+        goto done;
+    }
+    if (sfd->file_nbytes)
+        file_bytes = sfd->file_nbytes;
+    else
+        file_bytes = info.size - sfd->file_offset;
+
+    alignment = PR_GetMemMapAlignment();
+
+    /* number of initial bytes to skip in mmap'd segment */
+    addr_offset = sfd->file_offset % alignment;
+
+    /* find previous mmap alignment boundary */
+    file_mmap_offset = sfd->file_offset - addr_offset;
+
+    /*
+     * If the file is large, mmap and send the file in chunks so as
+     * to not consume too much virtual address space
+     */
+    mmap_len = PR_MIN(file_bytes + addr_offset, SENDFILE_MMAP_CHUNK);
+    len = mmap_len - addr_offset;
+
+    /*
+     * Map in (part of) file. Take care of zero-length files.
+     */
+    if (len) {
+        LL_I2L(zero64, 0);
+        mapHandle = PR_CreateFileMap(sfd->fd, zero64, PR_PROT_READONLY);
+        if (!mapHandle) {
+            count = -1;
+            goto done;
+        }
+        LL_I2L(file_mmap_offset64, file_mmap_offset);
+        addr = PR_MemMap(mapHandle, file_mmap_offset64, mmap_len);
+        if (!addr) {
+            count = -1;
+            goto done;
+        }
+    }
+    /*
+     * send headers first, followed by the file
+     */
+    if (sfd->hlen) {
+        iov[index].iov_base = (char *) sfd->header;
+        iov[index].iov_len = sfd->hlen;
+        index++;
+    }
+    if (len) {
+        iov[index].iov_base = (char*)addr + addr_offset;
+        iov[index].iov_len = len;
+        index++;
+    }
+    if ((file_bytes == len) && (sfd->tlen)) {
+        /*
+         * all file data is mapped in; send the trailer too
+         */
+        iov[index].iov_base = (char *) sfd->trailer;
+        iov[index].iov_len = sfd->tlen;
+        index++;
+    }
+    rv = PR_Writev(sd, iov, index, timeout);
+    if (len)
+        PR_MemUnmap(addr, mmap_len);
+    if (rv < 0) {
+        count = -1;
+        goto done;
+    }
+
+    PR_ASSERT(rv == sfd->hlen + len + ((len == file_bytes) ? sfd->tlen : 0));
+
+    file_bytes -= len;
+    count += rv;
+    if (!file_bytes)    /* header, file and trailer are sent */
+        goto done;
+
+    /*
+     * send remaining bytes of the file, if any
+     */
+    len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK);
+    while (len > 0) {
+        /*
+         * Map in (part of) file
+         */
+        file_mmap_offset = sfd->file_offset + count - sfd->hlen;
+        PR_ASSERT((file_mmap_offset % alignment) == 0);
+
+        LL_I2L(file_mmap_offset64, file_mmap_offset);
+        addr = PR_MemMap(mapHandle, file_mmap_offset64, len);
+        if (!addr) {
+            count = -1;
+            goto done;
+        }
+        rv = PR_Send(sd, addr, len, 0, timeout);
+        PR_MemUnmap(addr, len);
+        if (rv < 0) {
+            count = -1;
+            goto done;
+        }
+
+        PR_ASSERT(rv == len);
+        file_bytes -= rv;
+        count += rv;
+        len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK);
+    }
+    PR_ASSERT(0 == file_bytes);
+    if (sfd->tlen) {
+        rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout);
+        if (rv >= 0) {
+            PR_ASSERT(rv == sfd->tlen);
+            count += rv;
+        } else
+            count = -1;
+    }
+done:
+    if (mapHandle)
+        PR_CloseFileMap(mapHandle);
+    if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET))
+        PR_Close(sd);
+    return count;
+}
+
+#else
+
+PR_IMPLEMENT(PRInt32) PR_EmulateSendFile(
+    PRFileDesc *sd, PRSendFileData *sfd,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    PRInt32 rv, count = 0;
+    PRInt32 rlen;
+    const void * buffer;
+    PRInt32 buflen;
+    PRInt32 sendbytes, readbytes;
+    char *buf;
+
+#define _SENDFILE_BUFSIZE   (16 * 1024)
+
+    buf = (char*)PR_MALLOC(_SENDFILE_BUFSIZE);
+    if (buf == NULL) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+
+    /*
+     * send header first
+     */
+    buflen = sfd->hlen;
+    buffer = sfd->header;
+    while (buflen) {
+        rv = PR_Send(sd, buffer, buflen, 0, timeout);
+        if (rv < 0) {
+            /* PR_Send() has invoked PR_SetError(). */
+            rv = -1;
+            goto done;
+        } else {
+            count += rv;
+            buffer = (const void*) ((const char*)buffer + rv);
+            buflen -= rv;
+        }
+    }
+
+    /*
+     * send file next
+     */
+    if (PR_Seek(sfd->fd, sfd->file_offset, PR_SEEK_SET) < 0) {
+        rv = -1;
+        goto done;
+    }
+    sendbytes = sfd->file_nbytes;
+    if (sendbytes == 0) {
+        /* send entire file */
+        while ((rlen = PR_Read(sfd->fd, buf, _SENDFILE_BUFSIZE)) > 0) {
+            while (rlen) {
+                char *bufptr = buf;
+
+                rv =  PR_Send(sd, bufptr, rlen, 0, timeout);
+                if (rv < 0) {
+                    /* PR_Send() has invoked PR_SetError(). */
+                    rv = -1;
+                    goto done;
+                } else {
+                    count += rv;
+                    bufptr = ((char*)bufptr + rv);
+                    rlen -= rv;
+                }
+            }
+        }
+        if (rlen < 0) {
+            /* PR_Read() has invoked PR_SetError(). */
+            rv = -1;
+            goto done;
+        }
+    } else {
+        readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE);
+        while (readbytes && ((rlen = PR_Read(sfd->fd, buf, readbytes)) > 0)) {
+            while (rlen) {
+                char *bufptr = buf;
+
+                rv =  PR_Send(sd, bufptr, rlen, 0, timeout);
+                if (rv < 0) {
+                    /* PR_Send() has invoked PR_SetError(). */
+                    rv = -1;
+                    goto done;
+                } else {
+                    count += rv;
+                    sendbytes -= rv;
+                    bufptr = ((char*)bufptr + rv);
+                    rlen -= rv;
+                }
+            }
+            readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE);
+        }
+        if (rlen < 0) {
+            /* PR_Read() has invoked PR_SetError(). */
+            rv = -1;
+            goto done;
+        } else if (sendbytes != 0) {
+            /*
+             * there are fewer bytes in file to send than specified
+             */
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            rv = -1;
+            goto done;
+        }
+    }
+
+    /*
+     * send trailer last
+     */
+    buflen = sfd->tlen;
+    buffer = sfd->trailer;
+    while (buflen) {
+        rv =  PR_Send(sd, buffer, buflen, 0, timeout);
+        if (rv < 0) {
+            /* PR_Send() has invoked PR_SetError(). */
+            rv = -1;
+            goto done;
+        } else {
+            count += rv;
+            buffer = (const void*) ((const char*)buffer + rv);
+            buflen -= rv;
+        }
+    }
+    rv = count;
+
+done:
+    if (buf)
+        PR_DELETE(buf);
+    if ((rv >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET))
+        PR_Close(sd);
+    return rv;
+}
+
+#endif
+
+/* priometh.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/pripv6.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/pripv6.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,382 @@
+/* -*- 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:        pripv6.c
+** Description: Support for various functions unique to IPv6
+*/
+#include "primpl.h"
+#include <string.h>
+
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+
+static PRIOMethods ipv6_to_v4_tcpMethods;
+static PRIOMethods ipv6_to_v4_udpMethods;
+static PRDescIdentity _pr_ipv6_to_ipv4_id;
+extern PRBool IsValidNetAddr(const PRNetAddr *addr);
+extern PRIPv6Addr _pr_in6addr_any;
+extern PRIPv6Addr _pr_in6addr_loopback;
+
+/*
+ * convert an IPv4-mapped IPv6 addr to an IPv4 addr
+ */
+static void _PR_ConvertToIpv4NetAddr(const PRNetAddr *src_v6addr,
+											PRNetAddr *dst_v4addr)
+{
+const PRUint8 *srcp;
+
+	PR_ASSERT(PR_AF_INET6 == src_v6addr->ipv6.family);
+
+	if (PR_IsNetAddrType(src_v6addr, PR_IpAddrV4Mapped)) {
+		srcp = src_v6addr->ipv6.ip.pr_s6_addr;
+		memcpy((char *) &dst_v4addr->inet.ip, srcp + 12, 4);
+    } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrAny)) {
+        dst_v4addr->inet.ip = htonl(INADDR_ANY);
+    } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrLoopback)) {
+        dst_v4addr->inet.ip = htonl(INADDR_LOOPBACK);
+    }
+	dst_v4addr->inet.family = PR_AF_INET;
+	dst_v4addr->inet.port = src_v6addr->ipv6.port;
+}
+
+/*
+ * convert an IPv4 addr to an IPv4-mapped IPv6 addr
+ */
+static void _PR_ConvertToIpv6NetAddr(const PRNetAddr *src_v4addr,
+                                            PRNetAddr *dst_v6addr)
+{
+PRUint8 *dstp;
+
+	PR_ASSERT(PR_AF_INET == src_v4addr->inet.family);
+	dst_v6addr->ipv6.family = PR_AF_INET6;
+	dst_v6addr->ipv6.port = src_v4addr->inet.port;
+
+ 	if (htonl(INADDR_ANY) == src_v4addr->inet.ip) {
+		dst_v6addr->ipv6.ip = _pr_in6addr_any;
+	} else {
+		dstp = dst_v6addr->ipv6.ip.pr_s6_addr;
+		memset(dstp, 0, 10);
+		memset(dstp + 10, 0xff, 2);
+		memcpy(dstp + 12,(char *) &src_v4addr->inet.ip, 4);
+	}
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketBind(PRFileDesc *fd,
+								const PRNetAddr *addr)
+{
+	PRNetAddr tmp_ipv4addr;
+	const PRNetAddr *tmp_addrp;
+	PRFileDesc *lo = fd->lower;
+
+	if (PR_AF_INET6 != addr->raw.family) {
+        PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return PR_FAILURE;
+	}
+	if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+    			PR_IsNetAddrType(addr, PR_IpAddrAny)) {
+		_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+		tmp_addrp = &tmp_ipv4addr;
+	} else {
+        PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+		return PR_FAILURE;
+	}
+	return((lo->methods->bind)(lo,tmp_addrp));
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketConnect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	PRNetAddr tmp_ipv4addr;
+	const PRNetAddr *tmp_addrp;
+
+	if (PR_AF_INET6 != addr->raw.family) {
+        PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return PR_FAILURE;
+	}
+	if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+			PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
+		_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+		tmp_addrp = &tmp_ipv4addr;
+	} else {
+        PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+		return PR_FAILURE;
+	}
+	return (fd->lower->methods->connect)(fd->lower, tmp_addrp, timeout);
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketSendTo(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	PRNetAddr tmp_ipv4addr;
+	const PRNetAddr *tmp_addrp;
+
+	if (PR_AF_INET6 != addr->raw.family) {
+        PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return PR_FAILURE;
+	}
+	if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+			PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
+		_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+		tmp_addrp = &tmp_ipv4addr;
+	} else {
+        PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+		return PR_FAILURE;
+	}
+    return (fd->lower->methods->sendto)(
+        fd->lower, buf, amount, flags, tmp_addrp, timeout);
+}
+
+static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept (
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRStatus rv;
+    PRFileDesc *newfd;
+    PRFileDesc *newstack;
+	PRNetAddr tmp_ipv4addr;
+    PRNetAddr *addrlower = NULL;
+
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    newstack = PR_NEW(PRFileDesc);
+    if (NULL == newstack)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    *newstack = *fd;  /* make a copy of the accepting layer */
+
+    if (addr)
+        addrlower = &tmp_ipv4addr;
+    newfd = (fd->lower->methods->accept)(fd->lower, addrlower, timeout);
+    if (NULL == newfd)
+    {
+        PR_DELETE(newstack);
+        return NULL;
+    }
+    if (addr)
+        _PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, addr);
+
+    rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return newfd;  /* that's it */
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd,
+			PRFileDesc **nd, PRNetAddr **ipv6_raddr, void *buf, PRInt32 amount,
+							PRIntervalTime timeout)
+{
+    PRInt32 nbytes;
+    PRStatus rv;
+	PRNetAddr tmp_ipv4addr;
+    PRFileDesc *newstack;
+
+    PR_ASSERT(sd != NULL);
+    PR_ASSERT(sd->lower != NULL);
+
+    newstack = PR_NEW(PRFileDesc);
+    if (NULL == newstack)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+    *newstack = *sd;  /* make a copy of the accepting layer */
+
+    nbytes = sd->lower->methods->acceptread(
+        sd->lower, nd, ipv6_raddr, buf, amount, timeout);
+    if (-1 == nbytes)
+    {
+        PR_DELETE(newstack);
+        return nbytes;
+    }
+	tmp_ipv4addr = **ipv6_raddr;	/* copy */
+	_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, *ipv6_raddr);
+
+    /* this PR_PushIOLayer call cannot fail */
+    rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return nbytes;
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetName(PRFileDesc *fd,
+										PRNetAddr *ipv6addr)
+{
+	PRStatus result;
+	PRNetAddr tmp_ipv4addr;
+
+	result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr);
+	if (PR_SUCCESS == result) {
+		_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+		PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+	}
+	return result;
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetPeerName(PRFileDesc *fd,
+										PRNetAddr *ipv6addr)
+{
+	PRStatus result;
+	PRNetAddr tmp_ipv4addr;
+
+	result = (fd->lower->methods->getpeername)(fd->lower, &tmp_ipv4addr);
+	if (PR_SUCCESS == result) {
+		_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+		PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+	}
+	return result;
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketRecvFrom(PRFileDesc *fd, void *buf,
+			PRInt32 amount, PRIntn flags, PRNetAddr *ipv6addr,
+				PRIntervalTime timeout)
+{
+	PRNetAddr tmp_ipv4addr;
+	PRInt32 result;
+
+    result = (fd->lower->methods->recvfrom)(
+        fd->lower, buf, amount, flags, &tmp_ipv4addr, timeout);
+	if (-1 != result) {
+		_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+		PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+	}
+	return result;
+}
+
+#if defined(_PR_INET6_PROBE)
+PRBool _pr_ipv6_is_present;
+extern PRBool _pr_test_ipv6_socket(void);
+
+#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+extern PRStatus _pr_find_getipnodebyname(void);
+#endif
+
+#if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO)
+extern PRStatus _pr_find_getaddrinfo(void);
+#endif
+
+static PRBool
+_pr_probe_ipv6_presence(void)
+{
+#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    if (_pr_find_getipnodebyname() != PR_SUCCESS)
+        return PR_FALSE;
+#endif
+
+#if !defined(_PR_INET6) && defined(_PR_HAVE_GETADDRINFO)
+    if (_pr_find_getaddrinfo() != PR_SUCCESS)
+        return PR_FALSE;
+#endif
+
+    return _pr_test_ipv6_socket();
+}
+#endif  /* _PR_INET6_PROBE */
+
+PRStatus _pr_init_ipv6()
+{
+    const PRIOMethods *stubMethods;
+
+#if defined(_PR_INET6_PROBE)
+    _pr_ipv6_is_present = _pr_probe_ipv6_presence();
+    if (PR_TRUE == _pr_ipv6_is_present)
+        return PR_SUCCESS;
+#endif
+
+    _pr_ipv6_to_ipv4_id = PR_GetUniqueIdentity("Ipv6_to_Ipv4 layer");
+    PR_ASSERT(PR_INVALID_IO_LAYER != _pr_ipv6_to_ipv4_id);
+
+	stubMethods = PR_GetDefaultIOMethods();
+
+	ipv6_to_v4_tcpMethods = *stubMethods;  /* first get the entire batch */
+	/* then override the ones we care about */
+	ipv6_to_v4_tcpMethods.connect = Ipv6ToIpv4SocketConnect;
+	ipv6_to_v4_tcpMethods.bind = Ipv6ToIpv4SocketBind;
+	ipv6_to_v4_tcpMethods.accept = Ipv6ToIpv4SocketAccept;
+	ipv6_to_v4_tcpMethods.acceptread = Ipv6ToIpv4SocketAcceptRead;
+	ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName;
+	ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
+/*
+	ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
+	ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
+*/
+	ipv6_to_v4_udpMethods = *stubMethods;  /* first get the entire batch */
+	/* then override the ones we care about */
+	ipv6_to_v4_udpMethods.connect = Ipv6ToIpv4SocketConnect;
+	ipv6_to_v4_udpMethods.bind = Ipv6ToIpv4SocketBind;
+	ipv6_to_v4_udpMethods.sendto = Ipv6ToIpv4SocketSendTo;
+	ipv6_to_v4_udpMethods.recvfrom = Ipv6ToIpv4SocketRecvFrom;
+	ipv6_to_v4_udpMethods.getsockname = Ipv6ToIpv4SocketGetName;
+	ipv6_to_v4_udpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
+/*
+	ipv6_to_v4_udpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
+	ipv6_to_v4_udpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
+*/
+	return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd)
+{
+	PRFileDesc *ipv6_fd = NULL;
+
+	/*
+	 * For platforms with no support for IPv6 
+	 * create layered socket for IPv4-mapped IPv6 addresses
+	 */
+	if (fd->methods->file_type == PR_DESC_SOCKET_TCP)
+		ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
+									&ipv6_to_v4_tcpMethods);
+	else
+		ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
+									&ipv6_to_v4_udpMethods);
+	if (NULL == ipv6_fd) {
+		goto errorExit;
+	} 
+	ipv6_fd->secret = NULL;
+
+	if (PR_PushIOLayer(fd, PR_TOP_IO_LAYER, ipv6_fd) == PR_FAILURE) {
+		goto errorExit;
+	}
+
+	return PR_SUCCESS;
+errorExit:
+
+	if (ipv6_fd)
+		ipv6_fd->dtor(ipv6_fd);
+	return PR_FAILURE;
+}
+
+#endif /* !defined(_PR_INET6) || defined(_PR_INET6_PROBE) */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prlayer.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prlayer.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,768 @@
+/* -*- 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:        prlayer.c
+** Description: Routines for handling pushable protocol modules on sockets.
+*/
+
+#include "primpl.h"
+#include "prerror.h"
+#include "prmem.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prio.h"
+
+#include <string.h> /* for memset() */
+static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack);
+
+void PR_CALLBACK pl_FDDestructor(PRFileDesc *fd)
+{
+    PR_ASSERT(fd != NULL);
+    if (NULL != fd->lower) fd->lower->higher = fd->higher;
+    if (NULL != fd->higher) fd->higher->lower = fd->lower;
+    PR_DELETE(fd);
+}
+
+/*
+** Default methods that just call down to the next fd.
+*/
+static PRStatus PR_CALLBACK pl_TopClose (PRFileDesc *fd)
+{
+    PRFileDesc *top, *lower;
+	PRStatus rv;
+
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+    PR_ASSERT(fd->secret == NULL);
+    PR_ASSERT(fd->methods->file_type == PR_DESC_LAYERED);
+
+	if (PR_IO_LAYER_HEAD == fd->identity) {
+		/*
+		 * new style stack; close all the layers, before deleting the
+		 * stack head
+		 */
+		rv = fd->lower->methods->close(fd->lower);
+		_PR_DestroyIOLayer(fd);
+		return rv;
+	} else if ((fd->higher) && (PR_IO_LAYER_HEAD == fd->higher->identity)) {
+		/*
+		 * lower layers of new style stack
+		 */
+		lower = fd->lower;
+		/*
+		 * pop and cleanup current layer
+		 */
+    	top = PR_PopIOLayer(fd->higher, PR_TOP_IO_LAYER);
+		top->dtor(top);
+		/*
+		 * then call lower layer
+		 */
+		return (lower->methods->close(lower));
+	} else {
+		/* old style stack */
+    	top = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
+		top->dtor(top);
+		return (fd->methods->close)(fd);
+	}
+}
+
+static PRInt32 PR_CALLBACK pl_DefRead (PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->read)(fd->lower, buf, amount);
+}
+
+static PRInt32 PR_CALLBACK pl_DefWrite (
+    PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->write)(fd->lower, buf, amount);
+}
+
+static PRInt32 PR_CALLBACK pl_DefAvailable (PRFileDesc *fd)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->available)(fd->lower);
+}
+
+static PRInt64 PR_CALLBACK pl_DefAvailable64 (PRFileDesc *fd)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->available64)(fd->lower);
+}
+
+static PRStatus PR_CALLBACK pl_DefFsync (PRFileDesc *fd)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->fsync)(fd->lower);
+}
+
+static PRInt32 PR_CALLBACK pl_DefSeek (
+    PRFileDesc *fd, PRInt32 offset, PRSeekWhence how)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->seek)(fd->lower, offset, how);
+}
+
+static PRInt64 PR_CALLBACK pl_DefSeek64 (
+    PRFileDesc *fd, PRInt64 offset, PRSeekWhence how)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->seek64)(fd->lower, offset, how);
+}
+
+static PRStatus PR_CALLBACK pl_DefFileInfo (PRFileDesc *fd, PRFileInfo *info)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->fileInfo)(fd->lower, info);
+}
+
+static PRStatus PR_CALLBACK pl_DefFileInfo64 (PRFileDesc *fd, PRFileInfo64 *info)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->fileInfo64)(fd->lower, info);
+}
+
+static PRInt32 PR_CALLBACK pl_DefWritev (PRFileDesc *fd, const PRIOVec *iov,
+    PRInt32 size, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->writev)(fd->lower, iov, size, timeout);
+}
+
+static PRStatus PR_CALLBACK pl_DefConnect (
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->connect)(fd->lower, addr, timeout);
+}
+
+static PRStatus PR_CALLBACK pl_DefConnectcontinue (
+    PRFileDesc *fd, PRInt16 out_flags)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->connectcontinue)(fd->lower, out_flags);
+}
+
+static PRFileDesc* PR_CALLBACK pl_TopAccept (
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRStatus rv;
+    PRFileDesc *newfd, *layer = fd;
+    PRFileDesc *newstack;
+	PRBool newstyle_stack = PR_FALSE;
+
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+	/* test for new style stack */
+	while (NULL != layer->higher)
+		layer = layer->higher;
+	newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE;
+    newstack = PR_NEW(PRFileDesc);
+    if (NULL == newstack)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    *newstack = *fd;  /* make a copy of the accepting layer */
+
+    newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout);
+    if (NULL == newfd)
+    {
+        PR_DELETE(newstack);
+        return NULL;
+    }
+
+    if (newstyle_stack) {
+		newstack->lower = newfd;
+		newfd->higher = newstack;
+		return newstack;
+	} else {
+		/* this PR_PushIOLayer call cannot fail */
+		rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
+		PR_ASSERT(PR_SUCCESS == rv);
+    	return newfd;  /* that's it */
+	}
+}
+
+static PRStatus PR_CALLBACK pl_DefBind (PRFileDesc *fd, const PRNetAddr *addr)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->bind)(fd->lower, addr);
+}
+
+static PRStatus PR_CALLBACK pl_DefListen (PRFileDesc *fd, PRIntn backlog)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->listen)(fd->lower, backlog);
+}
+
+static PRStatus PR_CALLBACK pl_DefShutdown (PRFileDesc *fd, PRIntn how)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->shutdown)(fd->lower, how);
+}
+
+static PRInt32 PR_CALLBACK pl_DefRecv (
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->recv)(
+        fd->lower, buf, amount, flags, timeout);
+}
+
+static PRInt32 PR_CALLBACK pl_DefSend (
+    PRFileDesc *fd, const void *buf,
+    PRInt32 amount, PRIntn flags, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->send)(fd->lower, buf, amount, flags, timeout);
+}
+
+static PRInt32 PR_CALLBACK pl_DefRecvfrom (
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->recvfrom)(
+        fd->lower, buf, amount, flags, addr, timeout);
+}
+
+static PRInt32 PR_CALLBACK pl_DefSendto (
+    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+    const PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->sendto)(
+        fd->lower, buf, amount, flags, addr, timeout);
+}
+
+static PRInt16 PR_CALLBACK pl_DefPoll (
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags);
+}
+
+static PRInt32 PR_CALLBACK pl_DefAcceptread (
+    PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr, void *buf,
+    PRInt32 amount, PRIntervalTime t)
+{
+    PRInt32 nbytes;
+    PRStatus rv;
+    PRFileDesc *newstack;
+    PRFileDesc *layer = sd;
+	PRBool newstyle_stack = PR_FALSE;
+
+    PR_ASSERT(sd != NULL);
+    PR_ASSERT(sd->lower != NULL);
+
+	/* test for new style stack */
+	while (NULL != layer->higher)
+		layer = layer->higher;
+	newstyle_stack = (PR_IO_LAYER_HEAD == layer->identity) ? PR_TRUE : PR_FALSE;
+    newstack = PR_NEW(PRFileDesc);
+    if (NULL == newstack)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+    *newstack = *sd;  /* make a copy of the accepting layer */
+
+    nbytes = sd->lower->methods->acceptread(
+        sd->lower, nd, raddr, buf, amount, t);
+    if (-1 == nbytes)
+    {
+        PR_DELETE(newstack);
+        return nbytes;
+    }
+    if (newstyle_stack) {
+		newstack->lower = *nd;
+		(*nd)->higher = newstack;
+		*nd = newstack;
+		return nbytes;
+	} else {
+		/* this PR_PushIOLayer call cannot fail */
+		rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack);
+		PR_ASSERT(PR_SUCCESS == rv);
+		return nbytes;
+	}
+}
+
+static PRInt32 PR_CALLBACK pl_DefTransmitfile (
+    PRFileDesc *sd, PRFileDesc *fd, const void *headers, PRInt32 hlen,
+    PRTransmitFileFlags flags, PRIntervalTime t)
+{
+    PR_ASSERT(sd != NULL);
+    PR_ASSERT(sd->lower != NULL);
+
+    return sd->lower->methods->transmitfile(
+        sd->lower, fd, headers, hlen, flags, t);
+}
+
+static PRStatus PR_CALLBACK pl_DefGetsockname (PRFileDesc *fd, PRNetAddr *addr)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->getsockname)(fd->lower, addr);
+}
+
+static PRStatus PR_CALLBACK pl_DefGetpeername (PRFileDesc *fd, PRNetAddr *addr)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->getpeername)(fd->lower, addr);
+}
+
+static PRStatus PR_CALLBACK pl_DefGetsocketoption (
+    PRFileDesc *fd, PRSocketOptionData *data)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->getsocketoption)(fd->lower, data);
+}
+
+static PRStatus PR_CALLBACK pl_DefSetsocketoption (
+    PRFileDesc *fd, const PRSocketOptionData *data)
+{
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    return (fd->lower->methods->setsocketoption)(fd->lower, data);
+}
+
+static PRInt32 PR_CALLBACK pl_DefSendfile (
+	PRFileDesc *sd, PRSendFileData *sfd,
+	PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    PR_ASSERT(sd != NULL);
+    PR_ASSERT(sd->lower != NULL);
+
+    return sd->lower->methods->sendfile(
+        sd->lower, sfd, flags, timeout);
+}
+
+/* Methods for the top of the stack.  Just call down to the next fd. */
+static PRIOMethods pl_methods = {
+    PR_DESC_LAYERED,
+    pl_TopClose,
+    pl_DefRead,
+    pl_DefWrite,
+    pl_DefAvailable,
+    pl_DefAvailable64,
+    pl_DefFsync,
+    pl_DefSeek,
+    pl_DefSeek64,
+    pl_DefFileInfo,
+    pl_DefFileInfo64,
+    pl_DefWritev,
+    pl_DefConnect,
+    pl_TopAccept,
+    pl_DefBind,
+    pl_DefListen,
+    pl_DefShutdown,
+    pl_DefRecv,
+    pl_DefSend,
+    pl_DefRecvfrom,
+    pl_DefSendto,
+    pl_DefPoll,
+    pl_DefAcceptread,
+    pl_DefTransmitfile,
+    pl_DefGetsockname,
+    pl_DefGetpeername,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    pl_DefGetsocketoption,
+    pl_DefSetsocketoption,
+    pl_DefSendfile,
+    pl_DefConnectcontinue,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt
+};
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetDefaultIOMethods(void)
+{
+    return &pl_methods;
+}  /* PR_GetDefaultIOMethods */
+
+PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayerStub(
+    PRDescIdentity ident, const PRIOMethods *methods)
+{
+    PRFileDesc *fd = NULL;
+    PR_ASSERT((PR_NSPR_IO_LAYER != ident) && (PR_TOP_IO_LAYER != ident));
+    if ((PR_NSPR_IO_LAYER == ident) || (PR_TOP_IO_LAYER == ident))
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    else
+    {
+        fd = PR_NEWZAP(PRFileDesc);
+        if (NULL == fd)
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        else
+        {
+            fd->methods = methods;
+            fd->dtor = pl_FDDestructor;
+            fd->identity = ident;
+        }
+    }
+    return fd;
+}  /* PR_CreateIOLayerStub */
+
+/*
+ * PR_CreateIOLayer
+ *		Create a new style stack, where the stack top is a dummy header.
+ *		Unlike the old style stacks, the contents of the stack head
+ *		are not modified when a layer is pushed onto or popped from a new
+ *		style stack.
+ */
+
+PR_IMPLEMENT(PRFileDesc*) PR_CreateIOLayer(PRFileDesc *top)
+{
+    PRFileDesc *fd = NULL;
+
+	fd = PR_NEWZAP(PRFileDesc);
+	if (NULL == fd)
+		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	else
+	{
+		fd->methods = &pl_methods;
+		fd->dtor = pl_FDDestructor;
+		fd->identity = PR_IO_LAYER_HEAD;
+		fd->higher = NULL;
+		fd->lower = top;
+		top->higher = fd;
+		top->lower = NULL;
+	}
+    return fd;
+}  /* PR_CreateIOLayer */
+
+/*
+ * _PR_DestroyIOLayer
+ *		Delete the stack head of a new style stack.
+ */
+
+static PRStatus _PR_DestroyIOLayer(PRFileDesc *stack)
+{
+    if (NULL == stack)
+        return PR_FAILURE;
+    else {
+        PR_DELETE(stack);
+    	return PR_SUCCESS;
+    }
+}  /* _PR_DestroyIOLayer */
+
+PR_IMPLEMENT(PRStatus) PR_PushIOLayer(
+    PRFileDesc *stack, PRDescIdentity id, PRFileDesc *fd)
+{
+    PRFileDesc *insert = PR_GetIdentitiesLayer(stack, id);
+
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(stack != NULL);
+    PR_ASSERT(insert != NULL);
+    PR_ASSERT(PR_IO_LAYER_HEAD != id);
+    if ((NULL == stack) || (NULL == fd) || (NULL == insert))
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    if (stack == insert)
+    {
+		/* going on top of the stack */
+		/* old-style stack */	
+		PRFileDesc copy = *stack;
+		*stack = *fd;
+		*fd = copy;
+		fd->higher = stack;
+		stack->lower = fd;
+		stack->higher = NULL;
+	} else {
+        /*
+		 * going somewhere in the middle of the stack for both old and new
+		 * style stacks, or going on top of stack for new style stack
+		 */
+        fd->lower = insert;
+        fd->higher = insert->higher;
+
+        insert->higher->lower = fd;
+        insert->higher = fd;
+    }
+
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_PopIOLayer(PRFileDesc *stack, PRDescIdentity id)
+{
+    PRFileDesc *extract = PR_GetIdentitiesLayer(stack, id);
+
+    PR_ASSERT(0 != id);
+    PR_ASSERT(NULL != stack);
+    PR_ASSERT(NULL != extract);
+    if ((NULL == stack) || (0 == id) || (NULL == extract))
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return NULL;
+    }
+
+    if (extract == stack) {
+        /* popping top layer of the stack */
+		/* old style stack */
+        PRFileDesc copy = *stack;
+        extract = stack->lower;
+        *stack = *extract;
+        *extract = copy;
+        stack->higher = NULL;
+	} else if ((PR_IO_LAYER_HEAD == stack->identity) &&
+					(extract == stack->lower) && (extract->lower == NULL)) {
+			/*
+			 * new style stack
+			 * popping the only layer in the stack; delete the stack too
+			 */
+			stack->lower = NULL;
+			_PR_DestroyIOLayer(stack);
+	} else {
+		/* for both kinds of stacks */
+        extract->lower->higher = extract->higher;
+        extract->higher->lower = extract->lower;
+    }
+    extract->higher = extract->lower = NULL;
+    return extract;
+}  /* PR_PopIOLayer */
+
+#define ID_CACHE_INCREMENT 16
+typedef struct _PRIdentity_cache
+{
+    PRLock *ml;
+    char **name;
+    PRIntn length;
+    PRDescIdentity ident;
+} _PRIdentity_cache;
+
+static _PRIdentity_cache identity_cache;
+
+PR_IMPLEMENT(PRDescIdentity) PR_GetUniqueIdentity(const char *layer_name)
+{
+    PRDescIdentity identity, length;
+    char **names = NULL, *name = NULL, **old = NULL;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    PR_ASSERT((PRDescIdentity)0x7fff > identity_cache.ident);
+
+    if (NULL != layer_name)
+    {
+        name = (char*)PR_Malloc(strlen(layer_name) + 1);
+        if (NULL == name)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return PR_INVALID_IO_LAYER;
+        }
+        strcpy(name, layer_name);
+    }
+
+    /* this initial code runs unsafe */
+retry:
+    PR_ASSERT(NULL == names);
+    length = identity_cache.length;
+    if (length < (identity_cache.ident + 1))
+    {
+        length += ID_CACHE_INCREMENT;
+        names = (char**)PR_CALLOC(length * sizeof(char*));
+        if (NULL == names)
+        {
+            if (NULL != name) PR_DELETE(name);
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return PR_INVALID_IO_LAYER;
+        }
+    }
+
+    /* now we get serious about thread safety */
+    PR_Lock(identity_cache.ml);
+    PR_ASSERT(identity_cache.ident <= identity_cache.length);
+    identity = identity_cache.ident + 1;
+    if (identity > identity_cache.length)  /* there's no room */
+    {
+        /* we have to do something - hopefully it's already done */
+        if ((NULL != names) && (length >= identity))
+        {
+            /* what we did is still okay */
+            memcpy(
+                names, identity_cache.name,
+                identity_cache.length * sizeof(char*));
+            old = identity_cache.name;
+            identity_cache.name = names;
+            identity_cache.length = length;
+            names = NULL;
+        }
+        else
+        {
+            PR_ASSERT(identity_cache.ident <= identity_cache.length);
+            PR_Unlock(identity_cache.ml);
+            if (NULL != names) PR_DELETE(names);
+            goto retry;
+        }
+    }
+    if (NULL != name) /* there's a name to be stored */
+    {
+        identity_cache.name[identity] = name;
+    }
+    identity_cache.ident = identity;
+    PR_ASSERT(identity_cache.ident <= identity_cache.length);
+    PR_Unlock(identity_cache.ml);
+
+    if (NULL != old) PR_DELETE(old);
+    if (NULL != names) PR_DELETE(names);
+
+    return identity;
+}  /* PR_GetUniqueIdentity */
+
+PR_IMPLEMENT(const char*) PR_GetNameForIdentity(PRDescIdentity ident)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (PR_TOP_IO_LAYER == ident) return NULL;
+
+    PR_ASSERT(ident <= identity_cache.ident);
+    return (ident > identity_cache.ident) ? NULL : identity_cache.name[ident];
+}  /* PR_GetNameForIdentity */
+
+PR_IMPLEMENT(PRDescIdentity) PR_GetLayersIdentity(PRFileDesc* fd)
+{
+    PR_ASSERT(NULL != fd);
+    if (PR_IO_LAYER_HEAD == fd->identity) {
+    	PR_ASSERT(NULL != fd->lower);
+    	return fd->lower->identity;
+	} else
+    	return fd->identity;
+}  /* PR_GetLayersIdentity */
+
+PR_IMPLEMENT(PRFileDesc*) PR_GetIdentitiesLayer(PRFileDesc* fd, PRDescIdentity id)
+{
+    PRFileDesc *layer = fd;
+
+    if (PR_TOP_IO_LAYER == id) {
+    	if (PR_IO_LAYER_HEAD == fd->identity)
+			return fd->lower;
+		else 
+			return fd;
+	}
+
+    for (layer = fd; layer != NULL; layer = layer->lower)
+    {
+        if (id == layer->identity) return layer;
+    }
+    for (layer = fd; layer != NULL; layer = layer->higher)
+    {
+        if (id == layer->identity) return layer;
+    }
+    return NULL;
+}  /* PR_GetIdentitiesLayer */
+
+void _PR_InitLayerCache(void)
+{
+    memset(&identity_cache, 0, sizeof(identity_cache));
+    identity_cache.ml = PR_NewLock();
+    PR_ASSERT(NULL != identity_cache.ml);
+}  /* _PR_InitLayerCache */
+
+void _PR_CleanupLayerCache(void)
+{
+    if (identity_cache.ml)
+    {
+        PR_DestroyLock(identity_cache.ml);
+        identity_cache.ml = NULL;
+    }
+
+    if (identity_cache.name)
+    {
+        PRDescIdentity ident;
+
+        for (ident = 0; ident <= identity_cache.ident; ident++)
+            PR_DELETE(identity_cache.name[ident]);
+
+        PR_DELETE(identity_cache.name);
+    }
+}  /* _PR_CleanupLayerCache */
+
+/* prlayer.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prlog.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prlog.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,547 @@
+/* -*- 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 ***** */
+
+/*
+ * Contributors:
+ *
+ * This Original Code has been modified by IBM Corporation.
+ * Modifications made by IBM described herein are
+ * Copyright (c) International Business Machines Corporation, 2000.
+ * Modifications to Mozilla code or documentation identified per
+ * MPL Section 3.3
+ *
+ * Date         Modified by     Description of modification
+ * 04/10/2000   IBM Corp.       Added DebugBreak() definitions for OS/2
+ */
+
+#include "primpl.h"
+#include "prenv.h"
+#include "prprf.h"
+#include <string.h>
+
+/*
+ * Lock used to lock the log.
+ *
+ * We can't define _PR_LOCK_LOG simply as PR_Lock because PR_Lock may
+ * contain assertions.  We have to avoid assertions in _PR_LOCK_LOG
+ * because PR_ASSERT calls PR_LogPrint, which in turn calls _PR_LOCK_LOG.
+ * This can lead to infinite recursion.
+ */
+static PRLock *_pr_logLock;
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
+#define _PR_LOCK_LOG() PR_Lock(_pr_logLock);
+#define _PR_UNLOCK_LOG() PR_Unlock(_pr_logLock);
+#elif defined(_PR_GLOBAL_THREADS_ONLY)
+#define _PR_LOCK_LOG() { _PR_LOCK_LOCK(_pr_logLock)
+#define _PR_UNLOCK_LOG() _PR_LOCK_UNLOCK(_pr_logLock); }
+#else
+
+#define _PR_LOCK_LOG() \
+{ \
+    PRIntn _is; \
+    PRThread *_me = _PR_MD_CURRENT_THREAD(); \
+    if (!_PR_IS_NATIVE_THREAD(_me)) \
+        _PR_INTSOFF(_is); \
+    _PR_LOCK_LOCK(_pr_logLock)
+
+#define _PR_UNLOCK_LOG() \
+    _PR_LOCK_UNLOCK(_pr_logLock); \
+    PR_ASSERT(_me == _PR_MD_CURRENT_THREAD()); \
+    if (!_PR_IS_NATIVE_THREAD(_me)) \
+        _PR_INTSON(_is); \
+}
+
+#endif
+
+#if defined(XP_PC)
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#endif
+
+/*
+ * On NT, we can't define _PUT_LOG as PR_Write or _PR_MD_WRITE,
+ * because every asynchronous file io operation leads to a fiber context
+ * switch.  So we define _PUT_LOG as fputs (from stdio.h).  A side
+ * benefit is that fputs handles the LF->CRLF translation.  This
+ * code can also be used on other platforms with file stream io.
+ */
+#if defined(WIN32) || defined(XP_OS2)
+#define _PR_USE_STDIO_FOR_LOGGING
+#endif
+
+/*
+** Coerce Win32 log output to use OutputDebugString() when
+** NSPR_LOG_FILE is set to "WinDebug".
+*/
+#if defined(XP_PC)
+#define WIN32_DEBUG_FILE (FILE*)-2
+#endif
+
+/* Macros used to reduce #ifdef pollution */
+
+#if defined(_PR_USE_STDIO_FOR_LOGGING) && defined(XP_PC)
+#define _PUT_LOG(fd, buf, nb) \
+    PR_BEGIN_MACRO \
+    if (logFile == WIN32_DEBUG_FILE) { \
+        char savebyte = buf[nb]; \
+        buf[nb] = '\0'; \
+        OutputDebugString(buf); \
+        buf[nb] = savebyte; \
+    } else { \
+        fwrite(buf, 1, nb, fd); \
+        fflush(fd); \
+    } \
+    PR_END_MACRO
+#elif defined(_PR_USE_STDIO_FOR_LOGGING)
+#define _PUT_LOG(fd, buf, nb) {fwrite(buf, 1, nb, fd); fflush(fd);}
+#elif defined(_PR_PTHREADS)
+#define _PUT_LOG(fd, buf, nb) PR_Write(fd, buf, nb)
+#elif defined(XP_MAC)
+#define _PUT_LOG(fd, buf, nb) _PR_MD_WRITE_SYNC(fd, buf, nb)
+#else
+#define _PUT_LOG(fd, buf, nb) _PR_MD_WRITE(fd, buf, nb)
+#endif
+
+/************************************************************************/
+
+static PRLogModuleInfo *logModules;
+
+static char *logBuf = NULL;
+static char *logp;
+static char *logEndp;
+#ifdef _PR_USE_STDIO_FOR_LOGGING
+static FILE *logFile = NULL;
+#else
+static PRFileDesc *logFile = 0;
+#endif
+
+#define LINE_BUF_SIZE           512
+#define DEFAULT_BUF_SIZE        16384
+
+#ifdef _PR_NEED_STRCASECMP
+
+/*
+ * strcasecmp is defined in /usr/ucblib/libucb.a on some platforms
+ * such as NCR and Unixware.  Linking with both libc and libucb
+ * may cause some problem, so I just provide our own implementation
+ * of strcasecmp here.
+ */
+
+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'
+};
+
+PRIntn 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]);
+}
+
+#endif /* _PR_NEED_STRCASECMP */
+
+void _PR_InitLog(void)
+{
+    char *ev;
+
+    _pr_logLock = PR_NewLock();
+
+    ev = PR_GetEnv("NSPR_LOG_MODULES");
+    if (ev && ev[0]) {
+        char module[64];  /* Security-Critical: If you change this
+                           * size, you must also change the sscanf
+                           * format string to be size-1.
+                           */
+        PRBool isSync = PR_FALSE;
+        PRIntn evlen = strlen(ev), pos = 0;
+        PRInt32 bufSize = DEFAULT_BUF_SIZE;
+        while (pos < evlen) {
+            PRIntn level = 1, count = 0, delta = 0;
+            count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-]%n:%d%n",
+                           module, &delta, &level, &delta);
+            pos += delta;
+            if (count == 0) break;
+
+            /*
+            ** If count == 2, then we got module and level. If count
+            ** == 1, then level defaults to 1 (module enabled).
+            */
+            if (strcasecmp(module, "sync") == 0) {
+                isSync = PR_TRUE;
+            } else if (strcasecmp(module, "bufsize") == 0) {
+                if (level >= LINE_BUF_SIZE) {
+                    bufSize = level;
+                }
+            } else {
+                PRLogModuleInfo *lm = logModules;
+                PRBool skip_modcheck =
+                    (0 == strcasecmp (module, "all")) ? PR_TRUE : PR_FALSE;
+
+                while (lm != NULL) {
+                    if (skip_modcheck) lm -> level = (PRLogModuleLevel)level;
+                    else if (strcasecmp(module, lm->name) == 0) {
+                        lm->level = (PRLogModuleLevel)level;
+                        break;
+                    }
+                    lm = lm->next;
+                }
+            }
+            /*found:*/
+            count = sscanf(&ev[pos], " , %n", &delta);
+            pos += delta;
+            if (count == EOF) break;
+        }
+        PR_SetLogBuffering(isSync ? bufSize : 0);
+
+        ev = PR_GetEnv("NSPR_LOG_FILE");
+        if (ev && ev[0]) {
+            if (!PR_SetLogFile(ev)) {
+#ifdef XP_PC
+                char* str = PR_smprintf("Unable to create nspr log file '%s'\n", ev);
+                if (str) {
+                    OutputDebugString(str);
+                    PR_smprintf_free(str);
+                }
+#else
+                fprintf(stderr, "Unable to create nspr log file '%s'\n", ev);
+#endif
+            }
+        } else {
+#ifdef _PR_USE_STDIO_FOR_LOGGING
+            logFile = stderr;
+#else
+            logFile = _pr_stderr;
+#endif
+        }
+    }
+}
+
+void _PR_LogCleanup(void)
+{
+    PRLogModuleInfo *lm = logModules;
+
+    PR_LogFlush();
+
+#ifdef _PR_USE_STDIO_FOR_LOGGING
+    if (logFile
+        && logFile != stdout
+        && logFile != stderr
+#ifdef XP_PC
+        && logFile != WIN32_DEBUG_FILE
+#endif
+        ) {
+        fclose(logFile);
+    }
+#else
+    if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) {
+        PR_Close(logFile);
+    }
+#endif
+
+    while (lm != NULL) {
+        PRLogModuleInfo *next = lm->next;
+        free((/*const*/ char *)lm->name);
+        PR_Free(lm);
+        lm = next;
+    }
+    logModules = NULL;
+
+    if (_pr_logLock) {
+        PR_DestroyLock(_pr_logLock);
+        _pr_logLock = NULL;
+    }
+}
+
+static void _PR_SetLogModuleLevel( PRLogModuleInfo *lm )
+{
+    char *ev;
+
+    ev = PR_GetEnv("NSPR_LOG_MODULES");
+    if (ev && ev[0]) {
+        char module[64];  /* Security-Critical: If you change this
+                           * size, you must also change the sscanf
+                           * format string to be size-1.
+                           */
+        PRIntn evlen = strlen(ev), pos = 0;
+        while (pos < evlen) {
+            PRIntn level = 1, count = 0, delta = 0;
+
+            count = sscanf(&ev[pos], "%63[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-]%n:%d%n",
+                           module, &delta, &level, &delta);
+            pos += delta;
+            if (count == 0) break;
+
+            /*
+            ** If count == 2, then we got module and level. If count
+            ** == 1, then level defaults to 1 (module enabled).
+            */
+            if (lm != NULL)
+            {
+                if ((strcasecmp(module, "all") == 0)
+                    || (strcasecmp(module, lm->name) == 0))
+                {
+                    lm->level = (PRLogModuleLevel)level;
+                }
+            }
+            count = sscanf(&ev[pos], " , %n", &delta);
+            pos += delta;
+            if (count == EOF) break;
+        }
+    }
+} /* end _PR_SetLogModuleLevel() */
+
+PR_IMPLEMENT(PRLogModuleInfo*) PR_NewLogModule(const char *name)
+{
+    PRLogModuleInfo *lm;
+
+        if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    lm = PR_NEWZAP(PRLogModuleInfo);
+    if (lm) {
+        lm->name = strdup(name);
+        lm->level = PR_LOG_NONE;
+        lm->next = logModules;
+        logModules = lm;
+        _PR_SetLogModuleLevel(lm);
+    }
+    return lm;
+}
+
+PR_IMPLEMENT(PRBool) PR_SetLogFile(const char *file)
+{
+#ifdef _PR_USE_STDIO_FOR_LOGGING
+    FILE *newLogFile;
+
+#ifdef XP_PC
+    if ( strcmp( file, "WinDebug") == 0)
+    {
+        newLogFile = WIN32_DEBUG_FILE;
+    }
+    else
+#endif
+    {
+        newLogFile = fopen(file, "w");
+        if (!newLogFile)
+            return PR_FALSE;
+
+        /* We do buffering ourselves. */
+        setvbuf(newLogFile, NULL, _IONBF, 0);
+    }
+    if (logFile
+        && logFile != stdout
+        && logFile != stderr
+#ifdef XP_PC
+        && logFile != WIN32_DEBUG_FILE
+#endif
+        ) {
+        fclose(logFile);
+    }
+    logFile = newLogFile;
+    return PR_TRUE;
+#else
+    PRFileDesc *newLogFile;
+
+    newLogFile = PR_Open(file, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0666);
+    if (newLogFile) {
+        if (logFile && logFile != _pr_stdout && logFile != _pr_stderr) {
+            PR_Close(logFile);
+        }
+        logFile = newLogFile;
+#if defined(XP_MAC)
+        SetLogFileTypeCreator(file);
+#endif
+    }
+    return (PRBool) (newLogFile != 0);
+#endif /* _PR_USE_STDIO_FOR_LOGGING */
+}
+
+PR_IMPLEMENT(void) PR_SetLogBuffering(PRIntn buffer_size)
+{
+    PR_LogFlush();
+
+    if (logBuf)
+        PR_DELETE(logBuf);
+
+    if (buffer_size >= LINE_BUF_SIZE) {
+        logp = logBuf = (char*) PR_MALLOC(buffer_size);
+        logEndp = logp + buffer_size;
+    }
+}
+
+PR_IMPLEMENT(void) PR_LogPrint(const char *fmt, ...)
+{
+    va_list ap;
+    char line[LINE_BUF_SIZE];
+    PRUint32 nb;
+    PRThread *me;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (!logFile) {
+        return;
+    }
+
+    va_start(ap, fmt);
+    me = PR_GetCurrentThread();
+    nb = PR_snprintf(line, sizeof(line)-1, "%ld[%p]: ",
+#if defined(_PR_DCETHREADS)
+             /* The problem is that for _PR_DCETHREADS, pthread_t is not a 
+              * pointer, but a structure; so you can't easily print it...
+              */
+                     me ? &(me->id): 0L, me);
+#elif defined(_PR_BTHREADS)
+		     me, me);
+#else
+                     me ? me->id : 0L, me);
+#endif
+
+    nb += PR_vsnprintf(line+nb, sizeof(line)-nb-1, fmt, ap);
+    if (nb && (line[nb-1] != '\n')) {
+#ifndef XP_MAC
+        line[nb++] = '\n';
+#else
+        line[nb++] = '\015';
+#endif 
+        line[nb] = '\0';
+    } else {
+#ifdef XP_MAC
+        line[nb-1] = '\015';
+#endif
+    }
+    va_end(ap);
+
+    _PR_LOCK_LOG();
+    if (logBuf == 0) {
+        _PUT_LOG(logFile, line, nb);
+    } else {
+        if (logp + nb > logEndp) {
+            _PUT_LOG(logFile, logBuf, logp - logBuf);
+            logp = logBuf;
+        }
+        memcpy(logp, line, nb);
+        logp += nb;
+    }
+    _PR_UNLOCK_LOG();
+    PR_LogFlush();
+}
+
+PR_IMPLEMENT(void) PR_LogFlush(void)
+{
+    if (logBuf && logFile) {
+        _PR_LOCK_LOG();
+            if (logp > logBuf) {
+                _PUT_LOG(logFile, logBuf, logp - logBuf);
+                logp = logBuf;
+            }
+        _PR_UNLOCK_LOG();
+    }
+}
+
+PR_IMPLEMENT(void) PR_Abort(void)
+{
+    PR_LogPrint("Aborting");
+    abort();
+}
+
+#if defined(XP_OS2)
+/*
+ * Added definitions for DebugBreak() for 2 different OS/2 compilers.
+ * Doing the int3 on purpose for Visual Age so that a developer can
+ * step over the instruction if so desired.  Not always possible if
+ * trapping due to exception handling IBM-AKR
+ */
+#if defined(XP_OS2_VACPP)
+#include <builtin.h>
+static void DebugBreak(void) { _interrupt(3); }
+#elif defined(XP_OS2_EMX)
+static void DebugBreak(void) { asm("int $3"); }
+#else
+static void DebugBreak(void) { }
+#endif
+#endif /* XP_OS2 */
+
+PR_IMPLEMENT(void) PR_Assert(const char *s, const char *file, PRIntn ln)
+{
+    PR_LogPrint("Assertion failure: %s, at %s:%d\n", s, file, ln);
+#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
+    fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
+#endif
+#ifdef XP_MAC
+    dprintf("Assertion failure: %s, at %s:%d\n", s, file, ln);
+#endif
+#if defined(WIN32) || defined(XP_OS2)
+    DebugBreak();
+#endif
+#ifndef XP_MAC
+    abort();
+#endif
+}
+
+#ifdef XP_MAC
+PR_IMPLEMENT(void) PR_Init_Log(void)
+{
+	_PR_InitLog();
+}
+#endif

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prmapopt.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prmapopt.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,517 @@
+/* -*- 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 ***** */
+
+/*
+ * This file defines _PR_MapOptionName().  The purpose of putting
+ * _PR_MapOptionName() in a separate file is to work around a Winsock
+ * header file problem on Windows NT.
+ *
+ * On Windows NT, if we define _WIN32_WINNT to be 0x0400 (in order
+ * to use Service Pack 3 extensions), windows.h includes winsock2.h
+ * (instead of winsock.h), which doesn't define many socket options
+ * defined in winsock.h.
+ *
+ * We need the socket options defined in winsock.h.  So this file
+ * includes winsock.h, with _WIN32_WINNT undefined.
+ */
+
+#if defined(WINNT) || defined(__MINGW32__)
+#include <winsock.h>
+#endif
+
+/* MinGW doesn't define these in its winsock.h. */
+#ifdef __MINGW32__
+#ifndef IP_TTL
+#define IP_TTL 7
+#endif
+#ifndef IP_TOS
+#define IP_TOS 8
+#endif
+#endif
+
+#include "primpl.h"
+
+#if defined(NEXTSTEP)
+/* NEXTSTEP is special: this must come before netinet/tcp.h. */
+#include <netinet/in_systm.h>  /* n_short, n_long, n_time */
+#endif
+
+#if defined(XP_UNIX) || defined(OS2) || (defined(XP_BEOS) && defined(BONE_VERSION))
+#include <netinet/tcp.h>  /* TCP_NODELAY, TCP_MAXSEG */
+#endif
+
+#ifndef _PR_PTHREADS
+
+PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
+{
+    PRStatus rv;
+    PRInt32 length;
+    PRInt32 level, name;
+
+    /*
+     * PR_SockOpt_Nonblocking is a special case that does not
+     * translate to a getsockopt() call
+     */
+    if (PR_SockOpt_Nonblocking == data->option)
+    {
+        data->value.non_blocking = fd->secret->nonblocking;
+        return PR_SUCCESS;
+    }
+
+    rv = _PR_MapOptionName(data->option, &level, &name);
+    if (PR_SUCCESS == rv)
+    {
+        switch (data->option)
+        {
+            case PR_SockOpt_Linger:
+            {
+#if !defined(XP_BEOS) || defined(BONE_VERSION)
+                struct linger linger;
+                length = sizeof(linger);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char *) &linger, &length);
+                if (PR_SUCCESS == rv)
+                {
+                    PR_ASSERT(sizeof(linger) == length);
+                    data->value.linger.polarity =
+                        (linger.l_onoff) ? PR_TRUE : PR_FALSE;
+                    data->value.linger.linger =
+                        PR_SecondsToInterval(linger.l_linger);
+                }
+                break;
+#else
+                PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+                return PR_FAILURE;
+#endif
+            }
+            case PR_SockOpt_Reuseaddr:
+            case PR_SockOpt_Keepalive:
+            case PR_SockOpt_NoDelay:
+            case PR_SockOpt_Broadcast:
+            {
+#ifdef WIN32 /* Winsock */
+                BOOL value;
+#else
+                PRIntn value;
+#endif
+                length = sizeof(value);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&value, &length);
+                if (PR_SUCCESS == rv)
+                    data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE;
+                break;
+            }
+            case PR_SockOpt_McastLoopback:
+            {
+#ifdef WIN32 /* Winsock */
+                BOOL bool;
+#else
+                PRUint8 bool;
+#endif
+                length = sizeof(bool);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&bool, &length);
+                if (PR_SUCCESS == rv)
+                    data->value.mcast_loopback = (0 == bool) ? PR_FALSE : PR_TRUE;
+                break;
+            }
+            case PR_SockOpt_RecvBufferSize:
+            case PR_SockOpt_SendBufferSize:
+            case PR_SockOpt_MaxSegment:
+            {
+                PRIntn value;
+                length = sizeof(value);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&value, &length);
+                if (PR_SUCCESS == rv)
+                    data->value.recv_buffer_size = value;
+                break;
+            }
+            case PR_SockOpt_IpTimeToLive:
+            case PR_SockOpt_IpTypeOfService:
+            {
+                /* These options should really be an int (or PRIntn). */
+                length = sizeof(PRUintn);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&data->value.ip_ttl, &length);
+                break;
+            }
+            case PR_SockOpt_McastTimeToLive:
+            {
+#ifdef WIN32 /* Winsock */
+                int ttl;
+#else
+                PRUint8 ttl;
+#endif
+                length = sizeof(ttl);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&ttl, &length);
+                if (PR_SUCCESS == rv)
+                    data->value.mcast_ttl = ttl;
+                break;
+            }
+#ifdef IP_ADD_MEMBERSHIP
+            case PR_SockOpt_AddMember:
+            case PR_SockOpt_DropMember:
+            {
+                struct ip_mreq mreq;
+                length = sizeof(mreq);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name, (char*)&mreq, &length);
+                if (PR_SUCCESS == rv)
+                {
+                    data->value.add_member.mcaddr.inet.ip =
+                        mreq.imr_multiaddr.s_addr;
+                    data->value.add_member.ifaddr.inet.ip =
+                        mreq.imr_interface.s_addr;
+                }
+                break;
+            }
+#endif /* IP_ADD_MEMBERSHIP */
+            case PR_SockOpt_McastInterface:
+            {
+                /* This option is a struct in_addr. */
+                length = sizeof(data->value.mcast_if.inet.ip);
+                rv = _PR_MD_GETSOCKOPT(
+                    fd, level, name,
+                    (char*)&data->value.mcast_if.inet.ip, &length);
+                break;
+            }
+            default:
+                PR_NOT_REACHED("Unknown socket option");
+                break;
+        }  
+    }
+    return rv;
+}  /* _PR_SocketGetSocketOption */
+
+PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data)
+{
+    PRStatus rv;
+    PRInt32 level, name;
+
+    /*
+     * PR_SockOpt_Nonblocking is a special case that does not
+     * translate to a setsockopt call.
+     */
+    if (PR_SockOpt_Nonblocking == data->option)
+    {
+#ifdef WINNT
+        PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE)
+            || (fd->secret->nonblocking == data->value.non_blocking));
+        if (fd->secret->md.io_model_committed
+            && (fd->secret->nonblocking != data->value.non_blocking))
+        {
+            /*
+             * On NT, once we have associated a socket with the io
+             * completion port, we can't disassociate it.  So we
+             * can't change the nonblocking option of the socket
+             * afterwards.
+             */
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return PR_FAILURE;
+        }
+#endif
+        fd->secret->nonblocking = data->value.non_blocking;
+        return PR_SUCCESS;
+    }
+
+    rv = _PR_MapOptionName(data->option, &level, &name);
+    if (PR_SUCCESS == rv)
+    {
+        switch (data->option)
+        {
+            case PR_SockOpt_Linger:
+            {
+#if !defined(XP_BEOS) || defined(BONE_VERSION)
+                struct linger linger;
+                linger.l_onoff = data->value.linger.polarity;
+                linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger);
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&linger, sizeof(linger));
+                break;
+#else
+                PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+                return PR_FAILURE;
+#endif
+            }
+            case PR_SockOpt_Reuseaddr:
+            case PR_SockOpt_Keepalive:
+            case PR_SockOpt_NoDelay:
+            case PR_SockOpt_Broadcast:
+            {
+#ifdef WIN32 /* Winsock */
+                BOOL value;
+#else
+                PRIntn value;
+#endif
+                value = (data->value.reuse_addr) ? 1 : 0;
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&value, sizeof(value));
+                break;
+            }
+            case PR_SockOpt_McastLoopback:
+            {
+#ifdef WIN32 /* Winsock */
+                BOOL bool;
+#else
+                PRUint8 bool;
+#endif
+                bool = data->value.mcast_loopback ? 1 : 0;
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&bool, sizeof(bool));
+                break;
+            }
+            case PR_SockOpt_RecvBufferSize:
+            case PR_SockOpt_SendBufferSize:
+            case PR_SockOpt_MaxSegment:
+            {
+                PRIntn value = data->value.recv_buffer_size;
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&value, sizeof(value));
+                break;
+            }
+            case PR_SockOpt_IpTimeToLive:
+            case PR_SockOpt_IpTypeOfService:
+            {
+                /* These options should really be an int (or PRIntn). */
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&data->value.ip_ttl, sizeof(PRUintn));
+                break;
+            }
+            case PR_SockOpt_McastTimeToLive:
+            {
+#ifdef WIN32 /* Winsock */
+                int ttl;
+#else
+                PRUint8 ttl;
+#endif
+                ttl = data->value.mcast_ttl;
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&ttl, sizeof(ttl));
+                break;
+            }
+#ifdef IP_ADD_MEMBERSHIP
+            case PR_SockOpt_AddMember:
+            case PR_SockOpt_DropMember:
+            {
+                struct ip_mreq mreq;
+                mreq.imr_multiaddr.s_addr =
+                    data->value.add_member.mcaddr.inet.ip;
+                mreq.imr_interface.s_addr =
+                    data->value.add_member.ifaddr.inet.ip;
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&mreq, sizeof(mreq));
+                break;
+            }
+#endif /* IP_ADD_MEMBERSHIP */
+            case PR_SockOpt_McastInterface:
+            {
+                /* This option is a struct in_addr. */
+                rv = _PR_MD_SETSOCKOPT(
+                    fd, level, name, (char*)&data->value.mcast_if.inet.ip,
+                    sizeof(data->value.mcast_if.inet.ip));
+                break;
+            }
+            default:
+                PR_NOT_REACHED("Unknown socket option");
+                break;
+        }  
+    }
+    return rv;
+}  /* _PR_SocketSetSocketOption */
+
+#endif /* ! _PR_PTHREADS */
+
+/*
+ *********************************************************************
+ *********************************************************************
+ **
+ ** Make sure that the following is at the end of this file,
+ ** because we will be playing with macro redefines.
+ **
+ *********************************************************************
+ *********************************************************************
+ */
+
+#if defined(VMS)
+/*
+** Sad but true. The DEC C header files define the following socket options
+** differently to what UCX is expecting. The values that UCX expects are
+** defined in SYS$LIBRARY:UCX$INETDEF.H. We redefine them here to the values
+** that UCX expects. Note that UCX V4.x will only accept these values while
+** UCX V5.x will accept either. So in theory this hack can be removed once
+** UCX V5 is the minimum.
+*/
+#undef IP_MULTICAST_IF
+#undef IP_MULTICAST_TTL
+#undef IP_MULTICAST_LOOP
+#undef IP_ADD_MEMBERSHIP
+#undef IP_DROP_MEMBERSHIP
+#include <ucx$inetdef.h>
+#define IP_MULTICAST_IF    UCX$C_IP_MULTICAST_IF
+#define IP_MULTICAST_TTL   UCX$C_IP_MULTICAST_TTL
+#define IP_MULTICAST_LOOP  UCX$C_IP_MULTICAST_LOOP
+#define IP_ADD_MEMBERSHIP  UCX$C_IP_ADD_MEMBERSHIP
+#define IP_DROP_MEMBERSHIP UCX$C_IP_DROP_MEMBERSHIP
+#endif
+
+/*
+ * Not every platform has all the socket options we want to
+ * support.  Some older operating systems such as SunOS 4.1.3
+ * don't have the IP multicast socket options.  Win32 doesn't
+ * have TCP_MAXSEG.
+ *
+ * To deal with this problem, we define the missing socket
+ * options as _PR_NO_SUCH_SOCKOPT.  _PR_MapOptionName() fails with
+ * PR_OPERATION_NOT_SUPPORTED_ERROR if a socket option not
+ * available on the platform is requested.
+ */
+
+/*
+ * Sanity check.  SO_LINGER and TCP_NODELAY should be available
+ * on all platforms.  Just to make sure we have included the
+ * appropriate header files.  Then any undefined socket options
+ * are really missing.
+ */
+
+#if !defined(SO_LINGER)
+#error "SO_LINGER is not defined"
+#endif
+
+/*
+ * Some platforms, such as NCR 2.03, don't have TCP_NODELAY defined
+ * in <netinet/tcp.h>
+ */
+#if !defined(NCR)
+#if !defined(TCP_NODELAY)
+#error "TCP_NODELAY is not defined"
+#endif
+#endif
+
+/*
+ * Make sure the value of _PR_NO_SUCH_SOCKOPT is not
+ * a valid socket option.
+ */
+#define _PR_NO_SUCH_SOCKOPT -1
+
+#ifndef SO_KEEPALIVE
+#define SO_KEEPALIVE        _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef SO_SNDBUF
+#define SO_SNDBUF           _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef SO_RCVBUF
+#define SO_RCVBUF           _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_MULTICAST_IF                 /* set/get IP multicast interface   */
+#define IP_MULTICAST_IF     _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_MULTICAST_TTL                /* set/get IP multicast timetolive  */
+#define IP_MULTICAST_TTL    _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_MULTICAST_LOOP               /* set/get IP multicast loopback    */
+#define IP_MULTICAST_LOOP   _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_ADD_MEMBERSHIP               /* add  an IP group membership      */
+#define IP_ADD_MEMBERSHIP   _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_DROP_MEMBERSHIP              /* drop an IP group membership      */
+#define IP_DROP_MEMBERSHIP  _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_TTL                          /* set/get IP Time To Live          */
+#define IP_TTL              _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef IP_TOS                          /* set/get IP Type Of Service       */
+#define IP_TOS              _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef TCP_NODELAY                     /* don't delay to coalesce data     */
+#define TCP_NODELAY         _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef TCP_MAXSEG                      /* maxumum segment size for tcp     */
+#define TCP_MAXSEG          _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef SO_BROADCAST                 /* enable broadcast on udp sockets */
+#define SO_BROADCAST        _PR_NO_SUCH_SOCKOPT
+#endif
+
+PRStatus _PR_MapOptionName(
+    PRSockOption optname, PRInt32 *level, PRInt32 *name)
+{
+    static PRInt32 socketOptions[PR_SockOpt_Last] =
+    {
+        0, SO_LINGER, SO_REUSEADDR, SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF,
+        IP_TTL, IP_TOS, IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
+        IP_MULTICAST_IF, IP_MULTICAST_TTL, IP_MULTICAST_LOOP,
+        TCP_NODELAY, TCP_MAXSEG, SO_BROADCAST
+    };
+    static PRInt32 socketLevels[PR_SockOpt_Last] =
+    {
+        0, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET, SOL_SOCKET,
+        IPPROTO_IP, IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
+        IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
+        IPPROTO_TCP, IPPROTO_TCP, SOL_SOCKET
+    };
+
+    if ((optname < PR_SockOpt_Linger)
+    || (optname >= PR_SockOpt_Last))
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    if (socketOptions[optname] == _PR_NO_SUCH_SOCKOPT)
+    {
+        PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
+        return PR_FAILURE;
+    }
+    *name = socketOptions[optname];
+    *level = socketLevels[optname];
+    return PR_SUCCESS;
+}  /* _PR_MapOptionName */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prmmap.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prmmap.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,93 @@
+/* -*- 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 ***** */
+
+/*
+ *********************************************************************
+ *
+ * Memory-mapped files
+ *
+ *********************************************************************
+ */
+
+#include "primpl.h"
+
+PR_IMPLEMENT(PRFileMap *) PR_CreateFileMap(
+    PRFileDesc *fd,
+    PRInt64 size,
+    PRFileMapProtect prot)
+{
+    PRFileMap *fmap;
+
+    PR_ASSERT(prot == PR_PROT_READONLY || prot == PR_PROT_READWRITE
+            || prot == PR_PROT_WRITECOPY);
+    fmap = PR_NEWZAP(PRFileMap);
+    if (NULL == fmap) {
+	PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	return NULL;
+    }
+    fmap->fd = fd;
+    fmap->prot = prot;
+    if (_PR_MD_CREATE_FILE_MAP(fmap, size) == PR_SUCCESS) {
+	return fmap;
+    } else {
+	PR_DELETE(fmap);
+	return NULL;
+    }
+}
+
+PR_IMPLEMENT(PRInt32) PR_GetMemMapAlignment(void)
+{
+    return _PR_MD_GET_MEM_MAP_ALIGNMENT();
+}
+
+PR_IMPLEMENT(void *) PR_MemMap(
+    PRFileMap *fmap,
+    PROffset64 offset,
+    PRUint32 len)
+{
+    return _PR_MD_MEM_MAP(fmap, offset, len);
+}
+
+PR_IMPLEMENT(PRStatus) PR_MemUnmap(void *addr, PRUint32 len)
+{
+    return _PR_MD_MEM_UNMAP(addr, len);
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseFileMap(PRFileMap *fmap)
+{
+    return _PR_MD_CLOSE_FILE_MAP(fmap);
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prmwait.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prmwait.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1491 @@
+/* -*- 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 "pprmwait.h"
+
+#define _MW_REHASH_MAX 11
+
+static PRLock *mw_lock = NULL;
+static _PRGlobalState *mw_state = NULL;
+
+static PRIntervalTime max_polling_interval;
+
+#ifdef WINNT
+
+typedef struct TimerEvent {
+    PRIntervalTime absolute;
+    void (*func)(void *);
+    void *arg;
+    LONG ref_count;
+    PRCList links;
+} TimerEvent;
+
+#define TIMER_EVENT_PTR(_qp) \
+    ((TimerEvent *) ((char *) (_qp) - offsetof(TimerEvent, links)))
+
+struct {
+    PRLock *ml;
+    PRCondVar *new_timer;
+    PRCondVar *cancel_timer;
+    PRThread *manager_thread;
+    PRCList timer_queue;
+} tm_vars;
+
+static PRStatus TimerInit(void);
+static void TimerManager(void *arg);
+static TimerEvent *CreateTimer(PRIntervalTime timeout,
+    void (*func)(void *), void *arg);
+static PRBool CancelTimer(TimerEvent *timer);
+
+static void TimerManager(void *arg)
+{
+    PRIntervalTime now;
+    PRIntervalTime timeout;
+    PRCList *head;
+    TimerEvent *timer;
+
+    PR_Lock(tm_vars.ml);
+    while (1)
+    {
+        if (PR_CLIST_IS_EMPTY(&tm_vars.timer_queue))
+        {
+            PR_WaitCondVar(tm_vars.new_timer, PR_INTERVAL_NO_TIMEOUT);
+        }
+        else
+        {
+            now = PR_IntervalNow();
+            head = PR_LIST_HEAD(&tm_vars.timer_queue);
+            timer = TIMER_EVENT_PTR(head);
+            if ((PRInt32) (now - timer->absolute) >= 0)
+            {
+                PR_REMOVE_LINK(head);
+                /*
+                 * make its prev and next point to itself so that
+                 * it's obvious that it's not on the timer_queue.
+                 */
+                PR_INIT_CLIST(head);
+                PR_ASSERT(2 == timer->ref_count);
+                PR_Unlock(tm_vars.ml);
+                timer->func(timer->arg);
+                PR_Lock(tm_vars.ml);
+                timer->ref_count -= 1;
+                if (0 == timer->ref_count)
+                {
+                    PR_NotifyAllCondVar(tm_vars.cancel_timer);
+                }
+            }
+            else
+            {
+                timeout = (PRIntervalTime)(timer->absolute - now);
+                PR_WaitCondVar(tm_vars.new_timer, timeout);
+            } 
+        }
+    }
+    PR_Unlock(tm_vars.ml);
+}
+
+static TimerEvent *CreateTimer(
+    PRIntervalTime timeout,
+    void (*func)(void *),
+    void *arg)
+{
+    TimerEvent *timer;
+    PRCList *links, *tail;
+    TimerEvent *elem;
+
+    timer = PR_NEW(TimerEvent);
+    if (NULL == timer)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return timer;
+    }
+    timer->absolute = PR_IntervalNow() + timeout;
+    timer->func = func;
+    timer->arg = arg;
+    timer->ref_count = 2;
+    PR_Lock(tm_vars.ml);
+    tail = links = PR_LIST_TAIL(&tm_vars.timer_queue);
+    while (links->prev != tail)
+    {
+        elem = TIMER_EVENT_PTR(links);
+        if ((PRInt32)(timer->absolute - elem->absolute) >= 0)
+        {
+            break;
+        }
+        links = links->prev;
+    }
+    PR_INSERT_AFTER(&timer->links, links);
+    PR_NotifyCondVar(tm_vars.new_timer);
+    PR_Unlock(tm_vars.ml);
+    return timer;
+}
+
+static PRBool CancelTimer(TimerEvent *timer)
+{
+    PRBool canceled = PR_FALSE;
+
+    PR_Lock(tm_vars.ml);
+    timer->ref_count -= 1;
+    if (timer->links.prev == &timer->links)
+    {
+        while (timer->ref_count == 1)
+        {
+            PR_WaitCondVar(tm_vars.cancel_timer, PR_INTERVAL_NO_TIMEOUT);
+        }
+    }
+    else
+    {
+        PR_REMOVE_LINK(&timer->links);
+        canceled = PR_TRUE;
+    }
+    PR_Unlock(tm_vars.ml);
+    PR_DELETE(timer);
+    return canceled; 
+}
+
+static PRStatus TimerInit(void)
+{
+    tm_vars.ml = PR_NewLock();
+    if (NULL == tm_vars.ml)
+    {
+        goto failed;
+    }
+    tm_vars.new_timer = PR_NewCondVar(tm_vars.ml);
+    if (NULL == tm_vars.new_timer)
+    {
+        goto failed;
+    }
+    tm_vars.cancel_timer = PR_NewCondVar(tm_vars.ml);
+    if (NULL == tm_vars.cancel_timer)
+    {
+        goto failed;
+    }
+    PR_INIT_CLIST(&tm_vars.timer_queue);
+    tm_vars.manager_thread = PR_CreateThread(
+        PR_SYSTEM_THREAD, TimerManager, NULL, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+    if (NULL == tm_vars.manager_thread)
+    {
+        goto failed;
+    }
+    return PR_SUCCESS;
+
+failed:
+    if (NULL != tm_vars.cancel_timer)
+    {
+        PR_DestroyCondVar(tm_vars.cancel_timer);
+    }
+    if (NULL != tm_vars.new_timer)
+    {
+        PR_DestroyCondVar(tm_vars.new_timer);
+    }
+    if (NULL != tm_vars.ml)
+    {
+        PR_DestroyLock(tm_vars.ml);
+    }
+    return PR_FAILURE;
+}
+
+#endif /* WINNT */
+
+/******************************************************************/
+/******************************************************************/
+/************************ The private portion *********************/
+/******************************************************************/
+/******************************************************************/
+void _PR_InitMW(void)
+{
+#ifdef WINNT
+    /*
+     * We use NT 4's InterlockedCompareExchange() to operate
+     * on PRMWStatus variables.
+     */
+    PR_ASSERT(sizeof(PVOID) == sizeof(PRMWStatus));
+    TimerInit();
+#endif
+    mw_lock = PR_NewLock();
+    PR_ASSERT(NULL != mw_lock);
+    mw_state = PR_NEWZAP(_PRGlobalState);
+    PR_ASSERT(NULL != mw_state);
+    PR_INIT_CLIST(&mw_state->group_list);
+    max_polling_interval = PR_MillisecondsToInterval(MAX_POLLING_INTERVAL);
+}  /* _PR_InitMW */
+
+void _PR_CleanupMW(void)
+{
+    PR_DestroyLock(mw_lock);
+    mw_lock = NULL;
+    if (mw_state->group) {
+        PR_DestroyWaitGroup(mw_state->group);
+        /* mw_state->group is set to NULL as a side effect. */
+    }
+    PR_DELETE(mw_state);
+}  /* _PR_CleanupMW */
+
+static PRWaitGroup *MW_Init2(void)
+{
+    PRWaitGroup *group = mw_state->group;  /* it's the null group */
+    if (NULL == group)  /* there is this special case */
+    {
+        group = PR_CreateWaitGroup(_PR_DEFAULT_HASH_LENGTH);
+        if (NULL == group) goto failed_alloc;
+        PR_Lock(mw_lock);
+        if (NULL == mw_state->group)
+        {
+            mw_state->group = group;
+            group = NULL;
+        }
+        PR_Unlock(mw_lock);
+        if (group != NULL) (void)PR_DestroyWaitGroup(group);
+        group = mw_state->group;  /* somebody beat us to it */
+    }
+failed_alloc:
+    return group;  /* whatever */
+}  /* MW_Init2 */
+
+static _PR_HashStory MW_AddHashInternal(PRRecvWait *desc, _PRWaiterHash *hash)
+{
+    /*
+    ** The entries are put in the table using the fd (PRFileDesc*) of
+    ** the receive descriptor as the key. This allows us to locate
+    ** the appropriate entry aqain when the poll operation finishes.
+    **
+    ** The pointer to the file descriptor object is first divided by
+    ** the natural alignment of a pointer in the belief that object
+    ** will have at least that many zeros in the low order bits.
+    ** This may not be a good assuption.
+    **
+    ** We try to put the entry in by rehashing _MW_REHASH_MAX times. After
+    ** that we declare defeat and force the table to be reconstructed.
+    ** Since some fds might be added more than once, won't that cause
+    ** collisions even in an empty table?
+    */
+    PRIntn rehash = _MW_REHASH_MAX;
+    PRRecvWait **waiter;
+    PRUintn hidx = _MW_HASH(desc->fd, hash->length);
+    PRUintn hoffset = 0;
+
+    while (rehash-- > 0)
+    {
+        waiter = &hash->recv_wait;
+        if (NULL == waiter[hidx])
+        {
+            waiter[hidx] = desc;
+            hash->count += 1;
+#if 0
+            printf("Adding 0x%x->0x%x ", desc, desc->fd);
+            printf(
+                "table[%u:%u:*%u]: 0x%x->0x%x\n",
+                hidx, hash->count, hash->length, waiter[hidx], waiter[hidx]->fd);
+#endif
+            return _prmw_success;
+        }
+        if (desc == waiter[hidx])
+        {
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);  /* desc already in table */
+            return _prmw_error;
+        }
+#if 0
+        printf("Failing 0x%x->0x%x ", desc, desc->fd);
+        printf(
+            "table[*%u:%u:%u]: 0x%x->0x%x\n",
+            hidx, hash->count, hash->length, waiter[hidx], waiter[hidx]->fd);
+#endif
+        if (0 == hoffset)
+        {
+            hoffset = _MW_HASH2(desc->fd, hash->length);
+            PR_ASSERT(0 != hoffset);
+        }
+        hidx = (hidx + hoffset) % (hash->length);
+    }
+    return _prmw_rehash;    
+}  /* MW_AddHashInternal */
+
+static _PR_HashStory MW_ExpandHashInternal(PRWaitGroup *group)
+{
+    PRRecvWait **desc;
+    PRUint32 pidx, length;
+    _PRWaiterHash *newHash, *oldHash = group->waiter;
+    PRBool retry;
+    _PR_HashStory hrv;
+
+    static const PRInt32 prime_number[] = {
+        _PR_DEFAULT_HASH_LENGTH, 179, 521, 907, 1427,
+        2711, 3917, 5021, 8219, 11549, 18911, 26711, 33749, 44771};
+    PRUintn primes = (sizeof(prime_number) / sizeof(PRInt32));
+
+    /* look up the next size we'd like to use for the hash table */
+    for (pidx = 0; pidx < primes; ++pidx)
+    {
+        if (prime_number[pidx] == oldHash->length)
+        {
+            break;
+        }
+    }
+    /* table size must be one of the prime numbers */
+    PR_ASSERT(pidx < primes);
+
+    /* if pidx == primes - 1, we can't expand the table any more */
+    while (pidx < primes - 1)
+    {
+        /* next size */
+        ++pidx;
+        length = prime_number[pidx];
+
+        /* allocate the new hash table and fill it in with the old */
+        newHash = (_PRWaiterHash*)PR_CALLOC(
+            sizeof(_PRWaiterHash) + (length * sizeof(PRRecvWait*)));
+        if (NULL == newHash)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return _prmw_error;
+        }
+
+        newHash->length = length;
+        retry = PR_FALSE;
+        for (desc = &oldHash->recv_wait;
+            newHash->count < oldHash->count; ++desc)
+        {
+            PR_ASSERT(desc < &oldHash->recv_wait + oldHash->length);
+            if (NULL != *desc)
+            {
+                hrv = MW_AddHashInternal(*desc, newHash);
+                PR_ASSERT(_prmw_error != hrv);
+                if (_prmw_success != hrv)
+                {
+                    PR_DELETE(newHash);
+                    retry = PR_TRUE;
+                    break;
+                }
+            }
+        }
+        if (retry) continue;
+
+        PR_DELETE(group->waiter);
+        group->waiter = newHash;
+        group->p_timestamp += 1;
+        return _prmw_success;
+    }
+
+    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    return _prmw_error;  /* we're hosed */
+}  /* MW_ExpandHashInternal */
+
+#ifndef WINNT
+static void _MW_DoneInternal(
+    PRWaitGroup *group, PRRecvWait **waiter, PRMWStatus outcome)
+{
+    /*
+    ** Add this receive wait object to the list of finished I/O
+    ** operations for this particular group. If there are other
+    ** threads waiting on the group, notify one. If not, arrange
+    ** for this thread to return.
+    */
+
+#if 0
+    printf("Removing 0x%x->0x%x\n", *waiter, (*waiter)->fd);
+#endif
+    (*waiter)->outcome = outcome;
+    PR_APPEND_LINK(&((*waiter)->internal), &group->io_ready);
+    PR_NotifyCondVar(group->io_complete);
+    PR_ASSERT(0 != group->waiter->count);
+    group->waiter->count -= 1;
+    *waiter = NULL;
+}  /* _MW_DoneInternal */
+#endif /* WINNT */
+
+static PRRecvWait **_MW_LookupInternal(PRWaitGroup *group, PRFileDesc *fd)
+{
+    /*
+    ** Find the receive wait object corresponding to the file descriptor.
+    ** Only search the wait group specified.
+    */
+    PRRecvWait **desc;
+    PRIntn rehash = _MW_REHASH_MAX;
+    _PRWaiterHash *hash = group->waiter;
+    PRUintn hidx = _MW_HASH(fd, hash->length);
+    PRUintn hoffset = 0;
+    
+    while (rehash-- > 0)
+    {
+        desc = (&hash->recv_wait) + hidx;
+        if ((*desc != NULL) && ((*desc)->fd == fd)) return desc;
+        if (0 == hoffset)
+        {
+            hoffset = _MW_HASH2(fd, hash->length);
+            PR_ASSERT(0 != hoffset);
+        }
+        hidx = (hidx + hoffset) % (hash->length);
+    }
+    return NULL;
+}  /* _MW_LookupInternal */
+
+#ifndef WINNT
+static PRStatus _MW_PollInternal(PRWaitGroup *group)
+{
+    PRRecvWait **waiter;
+    PRStatus rv = PR_FAILURE;
+    PRInt32 count, count_ready;
+    PRIntervalTime polling_interval;
+
+    group->poller = PR_GetCurrentThread();
+
+    while (PR_TRUE)
+    {
+        PRIntervalTime now, since_last_poll;
+        PRPollDesc *poll_list;
+
+        while (0 == group->waiter->count)
+        {
+            PRStatus st;
+            st = PR_WaitCondVar(group->new_business, PR_INTERVAL_NO_TIMEOUT);
+            if (_prmw_running != group->state)
+            {
+                PR_SetError(PR_INVALID_STATE_ERROR, 0);
+                goto aborted;
+            }
+            if (_MW_ABORTED(st)) goto aborted;
+        }
+
+        /*
+        ** There's something to do. See if our existing polling list
+        ** is large enough for what we have to do?
+        */
+
+        while (group->polling_count < group->waiter->count)
+        {
+            PRUint32 old_count = group->waiter->count;
+            PRUint32 new_count = PR_ROUNDUP(old_count, _PR_POLL_COUNT_FUDGE);
+            PRSize new_size = sizeof(PRPollDesc) * new_count;
+            PRPollDesc *old_polling_list = group->polling_list;
+
+            PR_Unlock(group->ml);
+            poll_list = (PRPollDesc*)PR_CALLOC(new_size);
+            if (NULL == poll_list)
+            {
+                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                PR_Lock(group->ml);
+                goto failed_alloc;
+            }
+            if (NULL != old_polling_list)
+                PR_DELETE(old_polling_list);
+            PR_Lock(group->ml);
+            if (_prmw_running != group->state)
+            {
+                PR_SetError(PR_INVALID_STATE_ERROR, 0);
+                goto aborted;
+            }
+            group->polling_list = poll_list;
+            group->polling_count = new_count;
+        }
+
+        now = PR_IntervalNow();
+        polling_interval = max_polling_interval;
+        since_last_poll = now - group->last_poll;
+
+        waiter = &group->waiter->recv_wait;
+        poll_list = group->polling_list;
+        for (count = 0; count < group->waiter->count; ++waiter)
+        {
+            PR_ASSERT(waiter < &group->waiter->recv_wait
+                + group->waiter->length);
+            if (NULL != *waiter)  /* a live one! */
+            {
+                if ((PR_INTERVAL_NO_TIMEOUT != (*waiter)->timeout)
+                && (since_last_poll >= (*waiter)->timeout))
+                    _MW_DoneInternal(group, waiter, PR_MW_TIMEOUT);
+                else
+                {
+                    if (PR_INTERVAL_NO_TIMEOUT != (*waiter)->timeout)
+                    {
+                        (*waiter)->timeout -= since_last_poll;
+                        if ((*waiter)->timeout < polling_interval)
+                            polling_interval = (*waiter)->timeout;
+                    }
+                    PR_ASSERT(poll_list < group->polling_list
+                        + group->polling_count);
+                    poll_list->fd = (*waiter)->fd;
+                    poll_list->in_flags = PR_POLL_READ;
+                    poll_list->out_flags = 0;
+#if 0
+                    printf(
+                        "Polling 0x%x[%d]: [fd: 0x%x, tmo: %u]\n",
+                        poll_list, count, poll_list->fd, (*waiter)->timeout);
+#endif
+                    poll_list += 1;
+                    count += 1;
+                }
+            }
+        } 
+
+        PR_ASSERT(count == group->waiter->count);
+
+        /*
+        ** If there are no more threads waiting for completion,
+        ** we need to return.
+        */
+        if ((!PR_CLIST_IS_EMPTY(&group->io_ready))
+        && (1 == group->waiting_threads)) break;
+
+        if (0 == count) continue;  /* wait for new business */
+
+        group->last_poll = now;
+
+        PR_Unlock(group->ml);
+
+        count_ready = PR_Poll(group->polling_list, count, polling_interval);
+
+        PR_Lock(group->ml);
+
+        if (_prmw_running != group->state)
+        {
+            PR_SetError(PR_INVALID_STATE_ERROR, 0);
+            goto aborted;
+        }
+        if (-1 == count_ready)
+        {
+            goto failed_poll;  /* that's a shame */
+        }
+        else if (0 < count_ready)
+        {
+            for (poll_list = group->polling_list; count > 0;
+            poll_list++, count--)
+            {
+                PR_ASSERT(
+                    poll_list < group->polling_list + group->polling_count);
+                if (poll_list->out_flags != 0)
+                {
+                    waiter = _MW_LookupInternal(group, poll_list->fd);
+                    /*
+                    ** If 'waiter' is NULL, that means the wait receive
+                    ** descriptor has been canceled.
+                    */
+                    if (NULL != waiter)
+                        _MW_DoneInternal(group, waiter, PR_MW_SUCCESS);
+                }
+            }
+        }
+        /*
+        ** If there are no more threads waiting for completion,
+        ** we need to return.
+        ** This thread was "borrowed" to do the polling, but it really
+        ** belongs to the client.
+        */
+        if ((!PR_CLIST_IS_EMPTY(&group->io_ready))
+        && (1 == group->waiting_threads)) break;
+    }
+
+    rv = PR_SUCCESS;
+
+aborted:
+failed_poll:
+failed_alloc:
+    group->poller = NULL;  /* we were that, not we ain't */
+    if ((_prmw_running == group->state) && (group->waiting_threads > 1))
+    {
+        /* Wake up one thread to become the new poller. */
+        PR_NotifyCondVar(group->io_complete);
+    }
+    return rv;  /* we return with the lock held */
+}  /* _MW_PollInternal */
+#endif /* !WINNT */
+
+static PRMWGroupState MW_TestForShutdownInternal(PRWaitGroup *group)
+{
+    PRMWGroupState rv = group->state;
+    /*
+    ** Looking at the group's fields is safe because
+    ** once the group's state is no longer running, it
+    ** cannot revert and there is a safe check on entry
+    ** to make sure no more threads are made to wait.
+    */
+    if ((_prmw_stopping == rv)
+    && (0 == group->waiting_threads))
+    {
+        rv = group->state = _prmw_stopped;
+        PR_NotifyCondVar(group->mw_manage);
+    }
+    return rv;
+}  /* MW_TestForShutdownInternal */
+
+#ifndef WINNT
+static void _MW_InitialRecv(PRCList *io_ready)
+{
+    PRRecvWait *desc = (PRRecvWait*)io_ready;
+    if ((NULL == desc->buffer.start)
+    || (0 == desc->buffer.length))
+        desc->bytesRecv = 0;
+    else
+    {
+        desc->bytesRecv = (desc->fd->methods->recv)(
+            desc->fd, desc->buffer.start,
+            desc->buffer.length, 0, desc->timeout);
+        if (desc->bytesRecv < 0)  /* SetError should already be there */
+            desc->outcome = PR_MW_FAILURE;
+    }
+}  /* _MW_InitialRecv */
+#endif
+
+#ifdef WINNT
+static void NT_TimeProc(void *arg)
+{
+    _MDOverlapped *overlapped = (_MDOverlapped *)arg;
+    PRRecvWait *desc =  overlapped->data.mw.desc;
+    PRFileDesc *bottom;
+    
+    if (InterlockedCompareExchange((PVOID *)&desc->outcome,
+        (PVOID)PR_MW_TIMEOUT, (PVOID)PR_MW_PENDING) != (PVOID)PR_MW_PENDING)
+    {
+        /* This wait recv descriptor has already completed. */
+        return;
+    }
+
+    /* close the osfd to abort the outstanding async io request */
+    /* $$$$
+    ** Little late to be checking if NSPR's on the bottom of stack,
+    ** but if we don't check, we can't assert that the private data
+    ** is what we think it is.
+    ** $$$$
+    */
+    bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER);
+    PR_ASSERT(NULL != bottom);
+    if (NULL != bottom)  /* now what!?!?! */
+    {
+        bottom->secret->state = _PR_FILEDESC_CLOSED;
+        if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR)
+        {
+            fprintf(stderr, "closesocket failed: %d\n", WSAGetLastError());
+            PR_ASSERT(!"What shall I do?");
+        }
+    }
+    return;
+}  /* NT_TimeProc */
+
+static PRStatus NT_HashRemove(PRWaitGroup *group, PRFileDesc *fd)
+{
+    PRRecvWait **waiter;
+
+    _PR_MD_LOCK(&group->mdlock);
+    waiter = _MW_LookupInternal(group, fd);
+    if (NULL != waiter)
+    {
+        group->waiter->count -= 1;
+        *waiter = NULL;
+    }
+    _PR_MD_UNLOCK(&group->mdlock);
+    return (NULL != waiter) ? PR_SUCCESS : PR_FAILURE;
+}
+
+PRStatus NT_HashRemoveInternal(PRWaitGroup *group, PRFileDesc *fd)
+{
+    PRRecvWait **waiter;
+
+    waiter = _MW_LookupInternal(group, fd);
+    if (NULL != waiter)
+    {
+        group->waiter->count -= 1;
+        *waiter = NULL;
+    }
+    return (NULL != waiter) ? PR_SUCCESS : PR_FAILURE;
+}
+#endif /* WINNT */
+
+/******************************************************************/
+/******************************************************************/
+/********************** The public API portion ********************/
+/******************************************************************/
+/******************************************************************/
+PR_IMPLEMENT(PRStatus) PR_AddWaitFileDesc(
+    PRWaitGroup *group, PRRecvWait *desc)
+{
+    _PR_HashStory hrv;
+    PRStatus rv = PR_FAILURE;
+#ifdef WINNT
+    _MDOverlapped *overlapped;
+    HANDLE hFile;
+    BOOL bResult;
+    DWORD dwError;
+    PRFileDesc *bottom;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    if ((NULL == group) && (NULL == (group = MW_Init2())))
+    {
+        return rv;
+    }
+
+    PR_ASSERT(NULL != desc->fd);
+
+    desc->outcome = PR_MW_PENDING;  /* nice, well known value */
+    desc->bytesRecv = 0;  /* likewise, though this value is ambiguious */
+
+    PR_Lock(group->ml);
+
+    if (_prmw_running != group->state)
+    {
+        /* Not allowed to add after cancelling the group */
+        desc->outcome = PR_MW_INTERRUPT;
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        PR_Unlock(group->ml);
+        return rv;
+    }
+
+#ifdef WINNT
+    _PR_MD_LOCK(&group->mdlock);
+#endif
+
+    /*
+    ** If the waiter count is zero at this point, there's no telling
+    ** how long we've been idle. Therefore, initialize the beginning
+    ** of the timing interval. As long as the list doesn't go empty,
+    ** it will maintain itself.
+    */
+    if (0 == group->waiter->count)
+        group->last_poll = PR_IntervalNow();
+
+    do
+    {
+        hrv = MW_AddHashInternal(desc, group->waiter);
+        if (_prmw_rehash != hrv) break;
+        hrv = MW_ExpandHashInternal(group);  /* gruesome */
+        if (_prmw_success != hrv) break;
+    } while (PR_TRUE);
+
+#ifdef WINNT
+    _PR_MD_UNLOCK(&group->mdlock);
+#endif
+
+    PR_NotifyCondVar(group->new_business);  /* tell the world */
+    rv = (_prmw_success == hrv) ? PR_SUCCESS : PR_FAILURE;
+    PR_Unlock(group->ml);
+
+#ifdef WINNT
+    overlapped = PR_NEWZAP(_MDOverlapped);
+    if (NULL == overlapped)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        NT_HashRemove(group, desc->fd);
+        return rv;
+    }
+    overlapped->ioModel = _MD_MultiWaitIO;
+    overlapped->data.mw.desc = desc;
+    overlapped->data.mw.group = group;
+    if (desc->timeout != PR_INTERVAL_NO_TIMEOUT)
+    {
+        overlapped->data.mw.timer = CreateTimer(
+            desc->timeout,
+            NT_TimeProc,
+            overlapped);
+        if (0 == overlapped->data.mw.timer)
+        {
+            NT_HashRemove(group, desc->fd);
+            PR_DELETE(overlapped);
+            /*
+             * XXX It appears that a maximum of 16 timer events can
+             * be outstanding. GetLastError() returns 0 when I try it.
+             */
+            PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, GetLastError());
+            return PR_FAILURE;
+        }
+    }
+
+    /* Reach to the bottom layer to get the OS fd */
+    bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER);
+    PR_ASSERT(NULL != bottom);
+    if (NULL == bottom)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    hFile = (HANDLE)bottom->secret->md.osfd; 
+    if (!bottom->secret->md.io_model_committed)
+    {
+        PRInt32 st;
+        st = _md_Associate(hFile);
+        PR_ASSERT(0 != st);
+        bottom->secret->md.io_model_committed = PR_TRUE;
+    }
+    bResult = ReadFile(hFile,
+        desc->buffer.start,
+        (DWORD)desc->buffer.length,
+        NULL,
+        &overlapped->overlapped);
+    if (FALSE == bResult && (dwError = GetLastError()) != ERROR_IO_PENDING)
+    {
+        if (desc->timeout != PR_INTERVAL_NO_TIMEOUT)
+        {
+            if (InterlockedCompareExchange((PVOID *)&desc->outcome,
+                (PVOID)PR_MW_FAILURE, (PVOID)PR_MW_PENDING)
+                == (PVOID)PR_MW_PENDING)
+            {
+                CancelTimer(overlapped->data.mw.timer);
+            }
+            NT_HashRemove(group, desc->fd);
+            PR_DELETE(overlapped);
+        }
+        _PR_MD_MAP_READ_ERROR(dwError);
+        rv = PR_FAILURE;
+    }
+#endif
+
+    return rv;
+}  /* PR_AddWaitFileDesc */
+
+PR_IMPLEMENT(PRRecvWait*) PR_WaitRecvReady(PRWaitGroup *group)
+{
+    PRCList *io_ready = NULL;
+#ifdef WINNT
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    _MDOverlapped *overlapped;    
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    if ((NULL == group) && (NULL == (group = MW_Init2()))) goto failed_init;
+
+    PR_Lock(group->ml);
+
+    if (_prmw_running != group->state)
+    {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        goto invalid_state;
+    }
+
+    group->waiting_threads += 1;  /* the polling thread is counted */
+
+#ifdef WINNT
+    _PR_MD_LOCK(&group->mdlock);
+    while (PR_CLIST_IS_EMPTY(&group->io_ready))
+    {
+        _PR_THREAD_LOCK(me);
+        me->state = _PR_IO_WAIT;
+        PR_APPEND_LINK(&me->waitQLinks, &group->wait_list);
+        if (!_PR_IS_NATIVE_THREAD(me))
+        {
+            _PR_SLEEPQ_LOCK(me->cpu);
+            _PR_ADD_SLEEPQ(me, PR_INTERVAL_NO_TIMEOUT);
+            _PR_SLEEPQ_UNLOCK(me->cpu);
+        }
+        _PR_THREAD_UNLOCK(me);
+        _PR_MD_UNLOCK(&group->mdlock);
+        PR_Unlock(group->ml);
+        _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+        me->state = _PR_RUNNING;
+        PR_Lock(group->ml);
+        _PR_MD_LOCK(&group->mdlock);
+        if (_PR_PENDING_INTERRUPT(me)) {
+            PR_REMOVE_LINK(&me->waitQLinks);
+            _PR_MD_UNLOCK(&group->mdlock);
+            me->flags &= ~_PR_INTERRUPT;
+            me->io_suspended = PR_FALSE;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+            goto aborted;
+        }
+    }
+    io_ready = PR_LIST_HEAD(&group->io_ready);
+    PR_ASSERT(io_ready != NULL);
+    PR_REMOVE_LINK(io_ready);
+    _PR_MD_UNLOCK(&group->mdlock);
+    overlapped = (_MDOverlapped *)
+        ((char *)io_ready - offsetof(_MDOverlapped, data));
+    io_ready = &overlapped->data.mw.desc->internal;
+#else
+    do
+    {
+        /*
+        ** If the I/O ready list isn't empty, have this thread
+        ** return with the first receive wait object that's available.
+        */
+        if (PR_CLIST_IS_EMPTY(&group->io_ready))
+        {
+            /*
+            ** Is there a polling thread yet? If not, grab this thread
+            ** and use it.
+            */
+            if (NULL == group->poller)
+            {
+                /*
+                ** This thread will stay do polling until it becomes the only one
+                ** left to service a completion. Then it will return and there will
+                ** be none left to actually poll or to run completions.
+                **
+                ** The polling function should only return w/ failure or
+                ** with some I/O ready.
+                */
+                if (PR_FAILURE == _MW_PollInternal(group)) goto failed_poll;
+            }
+            else
+            {
+                /*
+                ** There are four reasons a thread can be awakened from
+                ** a wait on the io_complete condition variable.
+                ** 1. Some I/O has completed, i.e., the io_ready list
+                **    is nonempty.
+                ** 2. The wait group is canceled.
+                ** 3. The thread is interrupted.
+                ** 4. The current polling thread has to leave and needs
+                **    a replacement.
+                ** The logic to find a new polling thread is made more
+                ** complicated by all the other possible events.
+                ** I tried my best to write the logic clearly, but
+                ** it is still full of if's with continue and goto.
+                */
+                PRStatus st;
+                do 
+                {
+                    st = PR_WaitCondVar(group->io_complete, PR_INTERVAL_NO_TIMEOUT);
+                    if (_prmw_running != group->state)
+                    {
+                        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+                        goto aborted;
+                    }
+                    if (_MW_ABORTED(st) || (NULL == group->poller)) break;
+                } while (PR_CLIST_IS_EMPTY(&group->io_ready));
+
+                /*
+                ** The thread is interrupted and has to leave.  It might
+                ** have also been awakened to process ready i/o or be the
+                ** new poller.  To be safe, if either condition is true,
+                ** we awaken another thread to take its place.
+                */
+                if (_MW_ABORTED(st))
+                {
+                    if ((NULL == group->poller
+                    || !PR_CLIST_IS_EMPTY(&group->io_ready))
+                    && group->waiting_threads > 1)
+                        PR_NotifyCondVar(group->io_complete);
+                    goto aborted;
+                }
+
+                /*
+                ** A new poller is needed, but can I be the new poller?
+                ** If there is no i/o ready, sure.  But if there is any
+                ** i/o ready, it has a higher priority.  I want to
+                ** process the ready i/o first and wake up another
+                ** thread to be the new poller.
+                */ 
+                if (NULL == group->poller)
+                {
+                    if (PR_CLIST_IS_EMPTY(&group->io_ready))
+                        continue;
+                    if (group->waiting_threads > 1)
+                        PR_NotifyCondVar(group->io_complete);
+                }
+            }
+            PR_ASSERT(!PR_CLIST_IS_EMPTY(&group->io_ready));
+        }
+        io_ready = PR_LIST_HEAD(&group->io_ready);
+        PR_NotifyCondVar(group->io_taken);
+        PR_ASSERT(io_ready != NULL);
+        PR_REMOVE_LINK(io_ready);
+    } while (NULL == io_ready);
+
+failed_poll:
+
+#endif
+
+aborted:
+
+    group->waiting_threads -= 1;
+invalid_state:
+    (void)MW_TestForShutdownInternal(group);
+    PR_Unlock(group->ml);
+
+failed_init:
+    if (NULL != io_ready)
+    {
+        /* If the operation failed, record the reason why */
+        switch (((PRRecvWait*)io_ready)->outcome)
+        {
+            case PR_MW_PENDING:
+                PR_ASSERT(0);
+                break;
+            case PR_MW_SUCCESS:
+#ifndef WINNT
+                _MW_InitialRecv(io_ready);
+#endif
+                break;
+#ifdef WINNT
+            case PR_MW_FAILURE:
+                _PR_MD_MAP_READ_ERROR(overlapped->data.mw.error);
+                break;
+#endif
+            case PR_MW_TIMEOUT:
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                break;
+            case PR_MW_INTERRUPT:
+                PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                break;
+            default: break;
+        }
+#ifdef WINNT
+        if (NULL != overlapped->data.mw.timer)
+        {
+            PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
+                != overlapped->data.mw.desc->timeout);
+            CancelTimer(overlapped->data.mw.timer);
+        }
+        else
+        {
+            PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
+                == overlapped->data.mw.desc->timeout);
+        }
+        PR_DELETE(overlapped);
+#endif
+    }
+    return (PRRecvWait*)io_ready;
+}  /* PR_WaitRecvReady */
+
+PR_IMPLEMENT(PRStatus) PR_CancelWaitFileDesc(PRWaitGroup *group, PRRecvWait *desc)
+{
+#if !defined(WINNT)
+    PRRecvWait **recv_wait;
+#endif
+    PRStatus rv = PR_SUCCESS;
+    if (NULL == group) group = mw_state->group;
+    PR_ASSERT(NULL != group);
+    if (NULL == group)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    PR_Lock(group->ml);
+
+    if (_prmw_running != group->state)
+    {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        rv = PR_FAILURE;
+        goto unlock;
+    }
+
+#ifdef WINNT
+    if (InterlockedCompareExchange((PVOID *)&desc->outcome,
+        (PVOID)PR_MW_INTERRUPT, (PVOID)PR_MW_PENDING) == (PVOID)PR_MW_PENDING)
+    {
+        PRFileDesc *bottom = PR_GetIdentitiesLayer(desc->fd, PR_NSPR_IO_LAYER);
+        PR_ASSERT(NULL != bottom);
+        if (NULL == bottom)
+        {
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            goto unlock;
+        }
+        bottom->secret->state = _PR_FILEDESC_CLOSED;
+#if 0
+        fprintf(stderr, "cancel wait recv: closing socket\n");
+#endif
+        if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR)
+        {
+            fprintf(stderr, "closesocket failed: %d\n", WSAGetLastError());
+            exit(1);
+        }
+    }
+#else
+    if (NULL != (recv_wait = _MW_LookupInternal(group, desc->fd)))
+    {
+        /* it was in the wait table */
+        _MW_DoneInternal(group, recv_wait, PR_MW_INTERRUPT);
+        goto unlock;
+    }
+    if (!PR_CLIST_IS_EMPTY(&group->io_ready))
+    {
+        /* is it already complete? */
+        PRCList *head = PR_LIST_HEAD(&group->io_ready);
+        do
+        {
+            PRRecvWait *done = (PRRecvWait*)head;
+            if (done == desc) goto unlock;
+            head = PR_NEXT_LINK(head);
+        } while (head != &group->io_ready);
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    rv = PR_FAILURE;
+
+#endif
+unlock:
+    PR_Unlock(group->ml);
+    return rv;
+}  /* PR_CancelWaitFileDesc */
+
+PR_IMPLEMENT(PRRecvWait*) PR_CancelWaitGroup(PRWaitGroup *group)
+{
+    PRRecvWait **desc;
+    PRRecvWait *recv_wait = NULL;
+#ifdef WINNT
+    _MDOverlapped *overlapped;
+    PRRecvWait **end;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+#endif
+
+    if (NULL == group) group = mw_state->group;
+    PR_ASSERT(NULL != group);
+    if (NULL == group)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return NULL;
+    }
+
+    PR_Lock(group->ml);
+    if (_prmw_stopped != group->state)
+    {
+        if (_prmw_running == group->state)
+            group->state = _prmw_stopping;  /* so nothing new comes in */
+        if (0 == group->waiting_threads)  /* is there anybody else? */
+            group->state = _prmw_stopped;  /* we can stop right now */
+        else
+        {
+            PR_NotifyAllCondVar(group->new_business);
+            PR_NotifyAllCondVar(group->io_complete);
+        }
+        while (_prmw_stopped != group->state)
+            (void)PR_WaitCondVar(group->mw_manage, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+#ifdef WINNT
+    _PR_MD_LOCK(&group->mdlock);
+#endif
+    /* make all the existing descriptors look done/interrupted */
+#ifdef WINNT
+    end = &group->waiter->recv_wait + group->waiter->length;
+    for (desc = &group->waiter->recv_wait; desc < end; ++desc)
+    {
+        if (NULL != *desc)
+        {
+            if (InterlockedCompareExchange((PVOID *)&(*desc)->outcome,
+                (PVOID)PR_MW_INTERRUPT, (PVOID)PR_MW_PENDING)
+                == (PVOID)PR_MW_PENDING)
+            {
+                PRFileDesc *bottom = PR_GetIdentitiesLayer(
+                    (*desc)->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);
+                if (NULL == bottom)
+                {
+                    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+                    goto invalid_arg;
+                }
+                bottom->secret->state = _PR_FILEDESC_CLOSED;
+#if 0
+                fprintf(stderr, "cancel wait group: closing socket\n");
+#endif
+                if (closesocket(bottom->secret->md.osfd) == SOCKET_ERROR)
+                {
+                    fprintf(stderr, "closesocket failed: %d\n",
+                        WSAGetLastError());
+                    exit(1);
+                }
+            }
+        }
+    }
+    while (group->waiter->count > 0)
+    {
+        _PR_THREAD_LOCK(me);
+        me->state = _PR_IO_WAIT;
+        PR_APPEND_LINK(&me->waitQLinks, &group->wait_list);
+        if (!_PR_IS_NATIVE_THREAD(me))
+        {
+            _PR_SLEEPQ_LOCK(me->cpu);
+            _PR_ADD_SLEEPQ(me, PR_INTERVAL_NO_TIMEOUT);
+            _PR_SLEEPQ_UNLOCK(me->cpu);
+        }
+        _PR_THREAD_UNLOCK(me);
+        _PR_MD_UNLOCK(&group->mdlock);
+        PR_Unlock(group->ml);
+        _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+        me->state = _PR_RUNNING;
+        PR_Lock(group->ml);
+        _PR_MD_LOCK(&group->mdlock);
+    }
+#else
+    for (desc = &group->waiter->recv_wait; group->waiter->count > 0; ++desc)
+    {
+        PR_ASSERT(desc < &group->waiter->recv_wait + group->waiter->length);
+        if (NULL != *desc)
+            _MW_DoneInternal(group, desc, PR_MW_INTERRUPT);
+    }
+#endif
+
+    /* take first element of finished list and return it or NULL */
+    if (PR_CLIST_IS_EMPTY(&group->io_ready))
+        PR_SetError(PR_GROUP_EMPTY_ERROR, 0);
+    else
+    {
+        PRCList *head = PR_LIST_HEAD(&group->io_ready);
+        PR_REMOVE_AND_INIT_LINK(head);
+#ifdef WINNT
+        overlapped = (_MDOverlapped *)
+            ((char *)head - offsetof(_MDOverlapped, data));
+        head = &overlapped->data.mw.desc->internal;
+        if (NULL != overlapped->data.mw.timer)
+        {
+            PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
+                != overlapped->data.mw.desc->timeout);
+            CancelTimer(overlapped->data.mw.timer);
+        }
+        else
+        {
+            PR_ASSERT(PR_INTERVAL_NO_TIMEOUT
+                == overlapped->data.mw.desc->timeout);
+        }
+        PR_DELETE(overlapped);
+#endif
+        recv_wait = (PRRecvWait*)head;
+    }
+#ifdef WINNT
+invalid_arg:
+    _PR_MD_UNLOCK(&group->mdlock);
+#endif
+    PR_Unlock(group->ml);
+
+    return recv_wait;
+}  /* PR_CancelWaitGroup */
+
+PR_IMPLEMENT(PRWaitGroup*) PR_CreateWaitGroup(PRInt32 size /* ignored */)
+{
+#ifdef XP_MAC
+#pragma unused (size)
+#endif
+    PRWaitGroup *wg;
+
+    if (NULL == (wg = PR_NEWZAP(PRWaitGroup)))
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto failed;
+    }
+    /* the wait group itself */
+    wg->ml = PR_NewLock();
+    if (NULL == wg->ml) goto failed_lock;
+    wg->io_taken = PR_NewCondVar(wg->ml);
+    if (NULL == wg->io_taken) goto failed_cvar0;
+    wg->io_complete = PR_NewCondVar(wg->ml);
+    if (NULL == wg->io_complete) goto failed_cvar1;
+    wg->new_business = PR_NewCondVar(wg->ml);
+    if (NULL == wg->new_business) goto failed_cvar2;
+    wg->mw_manage = PR_NewCondVar(wg->ml);
+    if (NULL == wg->mw_manage) goto failed_cvar3;
+
+    PR_INIT_CLIST(&wg->group_link);
+    PR_INIT_CLIST(&wg->io_ready);
+
+    /* the waiters sequence */
+    wg->waiter = (_PRWaiterHash*)PR_CALLOC(
+        sizeof(_PRWaiterHash) +
+        (_PR_DEFAULT_HASH_LENGTH * sizeof(PRRecvWait*)));
+    if (NULL == wg->waiter)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto failed_waiter;
+    }
+    wg->waiter->count = 0;
+    wg->waiter->length = _PR_DEFAULT_HASH_LENGTH;
+
+#ifdef WINNT
+    _PR_MD_NEW_LOCK(&wg->mdlock);
+    PR_INIT_CLIST(&wg->wait_list);
+#endif /* WINNT */
+
+    PR_Lock(mw_lock);
+    PR_APPEND_LINK(&wg->group_link, &mw_state->group_list);
+    PR_Unlock(mw_lock);
+    return wg;
+
+failed_waiter:
+    PR_DestroyCondVar(wg->mw_manage);
+failed_cvar3:
+    PR_DestroyCondVar(wg->new_business);
+failed_cvar2:
+    PR_DestroyCondVar(wg->io_complete);
+failed_cvar1:
+    PR_DestroyCondVar(wg->io_taken);
+failed_cvar0:
+    PR_DestroyLock(wg->ml);
+failed_lock:
+    PR_DELETE(wg);
+    wg = NULL;
+
+failed:
+    return wg;
+}  /* MW_CreateWaitGroup */
+
+PR_IMPLEMENT(PRStatus) PR_DestroyWaitGroup(PRWaitGroup *group)
+{
+    PRStatus rv = PR_SUCCESS;
+    if (NULL == group) group = mw_state->group;
+    PR_ASSERT(NULL != group);
+    if (NULL != group)
+    {
+        PR_Lock(group->ml);
+        if ((group->waiting_threads == 0)
+        && (group->waiter->count == 0)
+        && PR_CLIST_IS_EMPTY(&group->io_ready))
+        {
+            group->state = _prmw_stopped;
+        }
+        else
+        {
+            PR_SetError(PR_INVALID_STATE_ERROR, 0);
+            rv = PR_FAILURE;
+        }
+        PR_Unlock(group->ml);
+        if (PR_FAILURE == rv) return rv;
+
+        PR_Lock(mw_lock);
+        PR_REMOVE_LINK(&group->group_link);
+        PR_Unlock(mw_lock);
+
+#ifdef WINNT
+        /*
+         * XXX make sure wait_list is empty and waiter is empty.
+         * These must be checked while holding mdlock.
+         */
+        _PR_MD_FREE_LOCK(&group->mdlock);
+#endif
+
+        PR_DELETE(group->waiter);
+        PR_DELETE(group->polling_list);
+        PR_DestroyCondVar(group->mw_manage);
+        PR_DestroyCondVar(group->new_business);
+        PR_DestroyCondVar(group->io_complete);
+        PR_DestroyCondVar(group->io_taken);
+        PR_DestroyLock(group->ml);
+        if (group == mw_state->group) mw_state->group = NULL;
+        PR_DELETE(group);
+    }
+    else
+    {
+        /* The default wait group is not created yet. */
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        rv = PR_FAILURE;
+    }
+    return rv;
+}  /* PR_DestroyWaitGroup */
+
+/**********************************************************************
+***********************************************************************
+******************** Wait group enumerations **************************
+***********************************************************************
+**********************************************************************/
+
+PR_IMPLEMENT(PRMWaitEnumerator*) PR_CreateMWaitEnumerator(PRWaitGroup *group)
+{
+    PRMWaitEnumerator *enumerator = PR_NEWZAP(PRMWaitEnumerator);
+    if (NULL == enumerator) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    else
+    {
+        enumerator->group = group;
+        enumerator->seal = _PR_ENUM_SEALED;
+    }
+    return enumerator;
+}  /* PR_CreateMWaitEnumerator */
+
+PR_IMPLEMENT(PRStatus) PR_DestroyMWaitEnumerator(PRMWaitEnumerator* enumerator)
+{
+    PR_ASSERT(NULL != enumerator);
+    PR_ASSERT(_PR_ENUM_SEALED == enumerator->seal);
+    if ((NULL == enumerator) || (_PR_ENUM_SEALED != enumerator->seal))
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    enumerator->seal = _PR_ENUM_UNSEALED;
+    PR_Free(enumerator);
+    return PR_SUCCESS;
+}  /* PR_DestroyMWaitEnumerator */
+
+PR_IMPLEMENT(PRRecvWait*) PR_EnumerateWaitGroup(
+    PRMWaitEnumerator *enumerator, const PRRecvWait *previous)
+{
+    PRRecvWait *result = NULL;
+    
+    /* entry point sanity checking */
+    PR_ASSERT(NULL != enumerator);
+    PR_ASSERT(_PR_ENUM_SEALED == enumerator->seal);
+    if ((NULL == enumerator)
+    || (_PR_ENUM_SEALED != enumerator->seal)) goto bad_argument;
+
+    /* beginning of enumeration */
+    if (NULL == previous)
+    {
+        if (NULL == enumerator->group)
+        {
+            enumerator->group = mw_state->group;
+            if (NULL == enumerator->group)
+            {
+                PR_SetError(PR_GROUP_EMPTY_ERROR, 0);
+                return NULL;
+            }
+        }
+        enumerator->waiter = &enumerator->group->waiter->recv_wait;
+        enumerator->p_timestamp = enumerator->group->p_timestamp;
+        enumerator->thread = PR_GetCurrentThread();
+        enumerator->index = 0;
+    }
+    /* continuing an enumeration */
+    else
+    {
+        PRThread *me = PR_GetCurrentThread();
+        PR_ASSERT(me == enumerator->thread);
+        if (me != enumerator->thread) goto bad_argument;
+
+        /* need to restart the enumeration */
+        if (enumerator->p_timestamp != enumerator->group->p_timestamp)
+            return PR_EnumerateWaitGroup(enumerator, NULL);
+    }
+
+    /* actually progress the enumeration */
+#if defined(WINNT)
+    _PR_MD_LOCK(&enumerator->group->mdlock);
+#else
+    PR_Lock(enumerator->group->ml);
+#endif
+    while (enumerator->index++ < enumerator->group->waiter->length)
+    {
+        if (NULL != (result = *(enumerator->waiter)++)) break;
+    }
+#if defined(WINNT)
+    _PR_MD_UNLOCK(&enumerator->group->mdlock);
+#else
+    PR_Unlock(enumerator->group->ml);
+#endif
+
+    return result;  /* what we live for */
+
+bad_argument:
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return NULL;  /* probably ambiguous */
+}  /* PR_EnumerateWaitGroup */
+
+/* prmwait.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prpolevt.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prpolevt.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,530 @@
+/* -*- 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 ***** */
+
+/*
+ *********************************************************************
+ *
+ * Pollable events
+ *
+ * Pollable events are implemented using layered I/O.  The only
+ * I/O methods that are implemented for pollable events are poll
+ * and close.  No other methods can be invoked on a pollable
+ * event.
+ *
+ * A pipe or socket pair is created and the pollable event layer
+ * is pushed onto the read end.  A pointer to the write end is
+ * saved in the PRFilePrivate structure of the pollable event.
+ *
+ *********************************************************************
+ */
+
+#include "prinit.h"
+#include "prio.h"
+#include "prmem.h"
+#include "prerror.h"
+#include "prlog.h"
+
+#ifdef VMS
+
+/*
+ * On OpenVMS we use an event flag instead of a pipe or a socket since
+ * event flags are much more efficient on OpenVMS.
+ */
+#include "pprio.h"
+#include <lib$routines.h>
+#include <starlet.h>
+#include <stsdef.h>
+
+PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
+{
+    unsigned int status;
+    int flag = -1;
+    PRFileDesc *event;
+
+    /*
+    ** Allocate an event flag and clear it.
+    */
+    status = lib$get_ef(&flag);
+    if ((!$VMS_STATUS_SUCCESS(status)) || (flag == -1)) {
+        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, status);
+        return NULL;
+    }
+    sys$clref(flag);
+
+    /*
+    ** Give NSPR the event flag's negative value. We do this because our
+    ** select interprets a negative fd as an event flag rather than a
+    ** regular file fd.
+    */
+    event = PR_CreateSocketPollFd(-flag);
+    if (NULL == event) {
+        lib$free_ef(&flag);
+        return NULL;
+    }
+
+    return event;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)
+{
+    int flag = -PR_FileDesc2NativeHandle(event);
+    PR_DestroySocketPollFd(event);
+    lib$free_ef(&flag);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)
+{
+    /*
+    ** Just set the event flag.
+    */
+    unsigned int status;
+    status = sys$setef(-PR_FileDesc2NativeHandle(event));
+    if (!$VMS_STATUS_SUCCESS(status)) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, status);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
+{
+    /*
+    ** Just clear the event flag.
+    */
+    unsigned int status;
+    status = sys$clref(-PR_FileDesc2NativeHandle(event));
+    if (!$VMS_STATUS_SUCCESS(status)) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, status);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+#elif defined (XP_MAC)
+
+#include "primpl.h"
+
+/*
+ * On Mac, local sockets cannot be used, because the networking stack
+ * closes them when the machine goes to sleep. Instead, we'll use a simple
+ * flag.
+ */
+
+
+/*
+ * PRFilePrivate structure for the NSPR pollable events layer
+ */
+typedef struct PRPollableDesc {
+    PRBool      gotEvent;
+    PRThread    *pollingThread;
+} PRPollableDesc;
+
+static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd);
+
+static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
+
+static PRIOMethods _pr_mac_polevt_methods = {
+    PR_DESC_LAYERED,
+    _pr_MacPolEvtClose,
+    (PRReadFN)_PR_InvalidInt,
+    (PRWriteFN)_PR_InvalidInt,
+    (PRAvailableFN)_PR_InvalidInt,
+    (PRAvailable64FN)_PR_InvalidInt64,
+    (PRFsyncFN)_PR_InvalidStatus,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+    _pr_MacPolEvtPoll,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRDescIdentity _pr_mac_polevt_id;
+static PRCallOnceType _pr_mac_polevt_once_control;
+static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void);
+
+static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    PRPollableDesc   *pollDesc = (PRPollableDesc *)fd->secret;
+    PR_ASSERT(pollDesc);
+
+    // set the current thread so that we can wake up the poll thread
+    pollDesc->pollingThread = PR_GetCurrentThread();
+
+    if ((in_flags & PR_POLL_READ) && pollDesc->gotEvent)
+        *out_flags = PR_POLL_READ;
+    else
+        *out_flags = 0;
+    return pollDesc->gotEvent ? 1 : 0;
+}
+
+static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void)
+{
+    _pr_mac_polevt_id = PR_GetUniqueIdentity("NSPR pollable events");
+    if (PR_INVALID_IO_LAYER == _pr_mac_polevt_id) {
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd)
+{
+    PRPollableDesc   *pollDesc = (PRPollableDesc *)fd->secret;
+    PR_ASSERT(NULL == fd->higher && NULL == fd->lower);
+    PR_ASSERT(pollDesc);
+    PR_DELETE(pollDesc);
+    fd->dtor(fd);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
+{
+    PRFileDesc      *event;
+    PRPollableDesc   *pollDesc;
+    
+    if (PR_CallOnce(&_pr_mac_polevt_once_control, _pr_MacPolEvtInit) == PR_FAILURE) {
+        return NULL;
+    }
+
+    event = PR_CreateIOLayerStub(_pr_mac_polevt_id, &_pr_mac_polevt_methods);
+    if (NULL == event) {
+        return NULL;
+    } 
+
+    /*
+    ** Allocate an event flag and clear it.
+    */
+    pollDesc = PR_NEW(PRPollableDesc);
+    if (!pollDesc) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+
+    pollDesc->gotEvent = PR_FALSE;
+    pollDesc->pollingThread = NULL;
+    
+    event->secret = (PRFilePrivate*)pollDesc;
+    return event;
+
+errorExit:
+
+    if (event) {
+        PR_DELETE(event->secret);
+        event->dtor(event);
+    }
+    return NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)
+{
+    return PR_Close(event);
+}
+
+/* from macsockotpt.c. I wish there was a cleaner way */
+extern void WakeUpNotifiedThread(PRThread *thread, OTResult result);
+
+PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)
+{
+    PRPollableDesc   *pollDesc = (PRPollableDesc *)event->secret;
+    PR_ASSERT(pollDesc);
+    PR_ASSERT(pollDesc->pollingThread->state != _PR_DEAD_STATE);
+    
+    if (pollDesc->pollingThread->state == _PR_DEAD_STATE)
+      return PR_FAILURE;
+
+    pollDesc->gotEvent = PR_TRUE;
+    
+    if (pollDesc->pollingThread)
+        WakeUpNotifiedThread(pollDesc->pollingThread, noErr);
+        
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
+{
+    PRPollableDesc   *pollDesc = (PRPollableDesc *)event->secret;
+    PRStatus status;    
+    PR_ASSERT(pollDesc);
+    
+    /*
+      FIXME: Danger Will Robinson!
+      
+      The current implementation of PR_WaitForPollableEvent is somewhat
+      bogus; it makes the assumption that, in Mozilla, this will only
+      ever be called when PR_Poll has returned, telling us that an
+      event has been set.
+    */
+    
+    PR_ASSERT(pollDesc->gotEvent);
+    
+    status = (pollDesc->gotEvent) ? PR_SUCCESS : PR_FAILURE;
+    pollDesc->gotEvent = PR_FALSE;
+    return status;    
+}
+
+#else /* VMS */
+
+/*
+ * These internal functions are declared in primpl.h,
+ * but we can't include primpl.h because the definition
+ * of struct PRFilePrivate in this file (for the pollable
+ * event layer) will conflict with the definition of
+ * struct PRFilePrivate in primpl.h (for the NSPR layer).
+ */
+extern PRIntn _PR_InvalidInt(void);
+extern PRInt64 _PR_InvalidInt64(void);
+extern PRStatus _PR_InvalidStatus(void);
+extern PRFileDesc *_PR_InvalidDesc(void);
+
+/*
+ * PRFilePrivate structure for the NSPR pollable events layer
+ */
+struct PRFilePrivate {
+    PRFileDesc *writeEnd;  /* the write end of the pipe/socketpair */
+};
+
+static PRStatus PR_CALLBACK _pr_PolEvtClose(PRFileDesc *fd);
+
+static PRInt16 PR_CALLBACK _pr_PolEvtPoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
+
+static PRIOMethods _pr_polevt_methods = {
+    PR_DESC_LAYERED,
+    _pr_PolEvtClose,
+    (PRReadFN)_PR_InvalidInt,
+    (PRWriteFN)_PR_InvalidInt,
+    (PRAvailableFN)_PR_InvalidInt,
+    (PRAvailable64FN)_PR_InvalidInt64,
+    (PRFsyncFN)_PR_InvalidStatus,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+    _pr_PolEvtPoll,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRDescIdentity _pr_polevt_id;
+static PRCallOnceType _pr_polevt_once_control;
+static PRStatus PR_CALLBACK _pr_PolEvtInit(void);
+
+static PRInt16 PR_CALLBACK _pr_PolEvtPoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags);
+}
+
+static PRStatus PR_CALLBACK _pr_PolEvtInit(void)
+{
+    _pr_polevt_id = PR_GetUniqueIdentity("NSPR pollable events");
+    if (PR_INVALID_IO_LAYER == _pr_polevt_id) {
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+#if !defined(XP_UNIX)
+#define USE_TCP_SOCKETPAIR
+#endif
+
+PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
+{
+    PRFileDesc *event;
+    PRFileDesc *fd[2]; /* fd[0] is the read end; fd[1] is the write end */
+#ifdef USE_TCP_SOCKETPAIR
+    PRSocketOptionData socket_opt;
+    PRStatus rv;
+#endif
+
+    fd[0] = fd[1] = NULL;
+
+    if (PR_CallOnce(&_pr_polevt_once_control, _pr_PolEvtInit) == PR_FAILURE) {
+        return NULL;
+    }
+
+    event = PR_CreateIOLayerStub(_pr_polevt_id, &_pr_polevt_methods);
+    if (NULL == event) {
+        goto errorExit;
+    } 
+    event->secret = PR_NEW(PRFilePrivate);
+    if (event->secret == NULL) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+
+#ifndef USE_TCP_SOCKETPAIR
+    if (PR_CreatePipe(&fd[0], &fd[1]) == PR_FAILURE) {
+        fd[0] = fd[1] = NULL;
+        goto errorExit;
+    }
+#else
+    if (PR_NewTCPSocketPair(fd) == PR_FAILURE) {
+        fd[0] = fd[1] = NULL;
+        goto errorExit;
+    }
+	/*
+	 * set the TCP_NODELAY option to reduce notification latency
+	 */
+    socket_opt.option = PR_SockOpt_NoDelay;
+    socket_opt.value.no_delay = PR_TRUE;
+    rv = PR_SetSocketOption(fd[1], &socket_opt);
+    PR_ASSERT(PR_SUCCESS == rv);
+#endif
+
+    event->secret->writeEnd = fd[1];
+    if (PR_PushIOLayer(fd[0], PR_TOP_IO_LAYER, event) == PR_FAILURE) {
+        goto errorExit;
+    }
+
+    return fd[0];
+
+errorExit:
+    if (fd[0]) {
+        PR_Close(fd[0]);
+        PR_Close(fd[1]);
+    }
+    if (event) {
+        PR_DELETE(event->secret);
+        event->dtor(event);
+    }
+    return NULL;
+}
+
+static PRStatus PR_CALLBACK _pr_PolEvtClose(PRFileDesc *fd)
+{
+    PRFileDesc *event;
+
+    event = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
+    PR_ASSERT(NULL == event->higher && NULL == event->lower);
+    PR_Close(fd);
+    PR_Close(event->secret->writeEnd);
+    PR_DELETE(event->secret);
+    event->dtor(event);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)
+{
+    return PR_Close(event);
+}
+
+static const char magicChar = '\x38';
+
+PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)
+{
+    if (PR_Write(event->secret->writeEnd, &magicChar, 1) != 1) {
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
+{
+    char buf[1024];
+    PRInt32 nBytes;
+#ifdef DEBUG
+    PRIntn i;
+#endif
+
+    nBytes = PR_Read(event->lower, buf, sizeof(buf));
+    if (nBytes == -1) {
+        return PR_FAILURE;
+    }
+
+#ifdef DEBUG
+    /*
+     * Make sure people do not write to the pollable event fd
+     * directly.
+     */
+    for (i = 0; i < nBytes; i++) {
+        PR_ASSERT(buf[i] == magicChar);
+    }
+#endif
+
+    return PR_SUCCESS;
+}
+
+#endif /* VMS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prprf.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prprf.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1228 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 ***** */
+
+/*
+** Portable safe sprintf code.
+**
+** Author: Kipp E.B. Hickman
+*/
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include "primpl.h"
+#include "prprf.h"
+#include "prlong.h"
+#include "prlog.h"
+#include "prmem.h"
+
+/*
+** WARNING: This code may *NOT* call PR_LOG (because PR_LOG calls it)
+*/
+
+/*
+** XXX This needs to be internationalized!
+*/
+
+typedef struct SprintfStateStr SprintfState;
+
+struct SprintfStateStr {
+    int (*stuff)(SprintfState *ss, const char *sp, PRUint32 len);
+
+    char *base;
+    char *cur;
+    PRUint32 maxlen;
+
+    int (*func)(void *arg, const char *sp, PRUint32 len);
+    void *arg;
+};
+
+/*
+** Numbered Argument
+*/
+struct NumArg {
+    int type;           /* type of the numbered argument    */
+    union {             /* the numbered argument            */
+	int i;
+	unsigned int ui;
+	PRInt32 i32;
+	PRUint32 ui32;
+	PRInt64 ll;
+	PRUint64 ull;
+	double d;
+	const char *s;
+	int *ip;
+    } u;
+};
+
+#define NAS_DEFAULT_NUM 20  /* default number of NumberedArgument array */
+
+
+#define TYPE_INT16	0
+#define TYPE_UINT16	1
+#define TYPE_INTN	2
+#define TYPE_UINTN	3
+#define TYPE_INT32	4
+#define TYPE_UINT32	5
+#define TYPE_INT64	6
+#define TYPE_UINT64	7
+#define TYPE_STRING	8
+#define TYPE_DOUBLE	9
+#define TYPE_INTSTR	10
+#define TYPE_UNKNOWN	20
+
+#define FLAG_LEFT	0x1
+#define FLAG_SIGNED	0x2
+#define FLAG_SPACED	0x4
+#define FLAG_ZEROS	0x8
+#define FLAG_NEG	0x10
+
+/*
+** Fill into the buffer using the data in src
+*/
+static int fill2(SprintfState *ss, const char *src, int srclen, int width,
+		int flags)
+{
+    char space = ' ';
+    int rv;
+
+    width -= srclen;
+    if ((width > 0) && ((flags & FLAG_LEFT) == 0)) {	/* Right adjusting */
+	if (flags & FLAG_ZEROS) {
+	    space = '0';
+	}
+	while (--width >= 0) {
+	    rv = (*ss->stuff)(ss, &space, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	}
+    }
+
+    /* Copy out the source data */
+    rv = (*ss->stuff)(ss, src, srclen);
+    if (rv < 0) {
+	return rv;
+    }
+
+    if ((width > 0) && ((flags & FLAG_LEFT) != 0)) {	/* Left adjusting */
+	while (--width >= 0) {
+	    rv = (*ss->stuff)(ss, &space, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	}
+    }
+    return 0;
+}
+
+/*
+** Fill a number. The order is: optional-sign zero-filling conversion-digits
+*/
+static int fill_n(SprintfState *ss, const char *src, int srclen, int width,
+		  int prec, int type, int flags)
+{
+    int zerowidth = 0;
+    int precwidth = 0;
+    int signwidth = 0;
+    int leftspaces = 0;
+    int rightspaces = 0;
+    int cvtwidth;
+    int rv;
+    char sign;
+
+    if ((type & 1) == 0) {
+	if (flags & FLAG_NEG) {
+	    sign = '-';
+	    signwidth = 1;
+	} else if (flags & FLAG_SIGNED) {
+	    sign = '+';
+	    signwidth = 1;
+	} else if (flags & FLAG_SPACED) {
+	    sign = ' ';
+	    signwidth = 1;
+	}
+    }
+    cvtwidth = signwidth + srclen;
+
+    if (prec > 0) {
+	if (prec > srclen) {
+	    precwidth = prec - srclen;		/* Need zero filling */
+	    cvtwidth += precwidth;
+	}
+    }
+
+    if ((flags & FLAG_ZEROS) && (prec < 0)) {
+	if (width > cvtwidth) {
+	    zerowidth = width - cvtwidth;	/* Zero filling */
+	    cvtwidth += zerowidth;
+	}
+    }
+
+    if (flags & FLAG_LEFT) {
+	if (width > cvtwidth) {
+	    /* Space filling on the right (i.e. left adjusting) */
+	    rightspaces = width - cvtwidth;
+	}
+    } else {
+	if (width > cvtwidth) {
+	    /* Space filling on the left (i.e. right adjusting) */
+	    leftspaces = width - cvtwidth;
+	}
+    }
+    while (--leftspaces >= 0) {
+	rv = (*ss->stuff)(ss, " ", 1);
+	if (rv < 0) {
+	    return rv;
+	}
+    }
+    if (signwidth) {
+	rv = (*ss->stuff)(ss, &sign, 1);
+	if (rv < 0) {
+	    return rv;
+	}
+    }
+    while (--precwidth >= 0) {
+	rv = (*ss->stuff)(ss, "0", 1);
+	if (rv < 0) {
+	    return rv;
+	}
+    }
+    while (--zerowidth >= 0) {
+	rv = (*ss->stuff)(ss, "0", 1);
+	if (rv < 0) {
+	    return rv;
+	}
+    }
+    rv = (*ss->stuff)(ss, src, srclen);
+    if (rv < 0) {
+	return rv;
+    }
+    while (--rightspaces >= 0) {
+	rv = (*ss->stuff)(ss, " ", 1);
+	if (rv < 0) {
+	    return rv;
+	}
+    }
+    return 0;
+}
+
+/*
+** Convert a long into its printable form
+*/
+static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix,
+		 int type, int flags, const char *hexp)
+{
+    char cvtbuf[100];
+    char *cvt;
+    int digits;
+
+    /* according to the man page this needs to happen */
+    if ((prec == 0) && (num == 0)) {
+	return 0;
+    }
+
+    /*
+    ** Converting decimal is a little tricky. In the unsigned case we
+    ** need to stop when we hit 10 digits. In the signed case, we can
+    ** stop when the number is zero.
+    */
+    cvt = cvtbuf + sizeof(cvtbuf);
+    digits = 0;
+    while (num) {
+	int digit = (((unsigned long)num) % radix) & 0xF;
+	*--cvt = hexp[digit];
+	digits++;
+	num = (long)(((unsigned long)num) / radix);
+    }
+    if (digits == 0) {
+	*--cvt = '0';
+	digits++;
+    }
+
+    /*
+    ** Now that we have the number converted without its sign, deal with
+    ** the sign and zero padding.
+    */
+    return fill_n(ss, cvt, digits, width, prec, type, flags);
+}
+
+/*
+** Convert a 64-bit integer into its printable form
+*/
+static int cvt_ll(SprintfState *ss, PRInt64 num, int width, int prec, int radix,
+		  int type, int flags, const char *hexp)
+{
+    char cvtbuf[100];
+    char *cvt;
+    int digits;
+    PRInt64 rad;
+
+    /* according to the man page this needs to happen */
+    if ((prec == 0) && (LL_IS_ZERO(num))) {
+	return 0;
+    }
+
+    /*
+    ** Converting decimal is a little tricky. In the unsigned case we
+    ** need to stop when we hit 10 digits. In the signed case, we can
+    ** stop when the number is zero.
+    */
+    LL_I2L(rad, radix);
+    cvt = cvtbuf + sizeof(cvtbuf);
+    digits = 0;
+    while (!LL_IS_ZERO(num)) {
+	PRInt32 digit;
+	PRInt64 quot, rem;
+	LL_UDIVMOD(&quot, &rem, num, rad);
+	LL_L2I(digit, rem);
+	*--cvt = hexp[digit & 0xf];
+	digits++;
+	num = quot;
+    }
+    if (digits == 0) {
+	*--cvt = '0';
+	digits++;
+    }
+
+    /*
+    ** Now that we have the number converted without its sign, deal with
+    ** the sign and zero padding.
+    */
+    return fill_n(ss, cvt, digits, width, prec, type, flags);
+}
+
+/*
+** Convert a double precision floating point number into its printable
+** form.
+**
+** XXX stop using sprintf to convert floating point
+*/
+static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1)
+{
+    char fin[20];
+    char fout[300];
+    int amount = fmt1 - fmt0;
+
+    PR_ASSERT((amount > 0) && (amount < sizeof(fin)));
+    if (amount >= sizeof(fin)) {
+	/* Totally bogus % command to sprintf. Just ignore it */
+	return 0;
+    }
+    memcpy(fin, fmt0, amount);
+    fin[amount] = 0;
+
+    /* Convert floating point using the native sprintf code */
+#ifdef DEBUG
+    {
+        const char *p = fin;
+        while (*p) {
+            PR_ASSERT(*p != 'L');
+            p++;
+        }
+    }
+#endif
+    sprintf(fout, fin, d);
+
+    /*
+    ** This assert will catch overflow's of fout, when building with
+    ** debugging on. At least this way we can track down the evil piece
+    ** of calling code and fix it!
+    */
+    PR_ASSERT(strlen(fout) < sizeof(fout));
+
+    return (*ss->stuff)(ss, fout, strlen(fout));
+}
+
+/*
+** Convert a string into its printable form.  "width" is the output
+** width. "prec" is the maximum number of characters of "s" to output,
+** where -1 means until NUL.
+*/
+static int cvt_s(SprintfState *ss, const char *s, int width, int prec,
+		 int flags)
+{
+    int slen;
+
+    if (prec == 0)
+	return 0;
+
+    /* Limit string length by precision value */
+    slen = s ? strlen(s) : 6;
+    if (prec > 0) {
+	if (prec < slen) {
+	    slen = prec;
+	}
+    }
+
+    /* and away we go */
+    return fill2(ss, s ? s : "(null)", slen, width, flags);
+}
+
+/*
+** BuildArgArray stands for Numbered Argument list Sprintf
+** for example,  
+**	fmp = "%4$i, %2$d, %3s, %1d";
+** the number must start from 1, and no gap among them
+*/
+
+static struct NumArg* BuildArgArray( const char *fmt, va_list ap, int* rv, struct NumArg* nasArray )
+{
+    int number = 0, cn = 0, i;
+    const char* p;
+    char  c;
+    struct NumArg* nas;
+    
+
+    /*
+    **	first pass:
+    **	determine how many legal % I have got, then allocate space
+    */
+
+    p = fmt;
+    *rv = 0;
+    i = 0;
+    while( ( c = *p++ ) != 0 ){
+	if( c != '%' )
+	    continue;
+	if( ( c = *p++ ) == '%' )	/* skip %% case */
+	    continue;
+
+	while( c != 0 ){
+	    if( c > '9' || c < '0' ){
+		if( c == '$' ){		/* numbered argument case */
+		    if( i > 0 ){
+			*rv = -1;
+			return NULL;
+		    }
+		    number++;
+		} else{			/* non-numbered argument case */
+		    if( number > 0 ){
+			*rv = -1;
+			return NULL;
+		    }
+		    i = 1;
+		}
+		break;
+	    }
+
+	    c = *p++;
+	}
+    }
+
+    if( number == 0 ){
+	return NULL;
+    }
+
+    
+    if( number > NAS_DEFAULT_NUM ){
+	nas = (struct NumArg*)PR_MALLOC( number * sizeof( struct NumArg ) );
+	if( !nas ){
+	    *rv = -1;
+	    return NULL;
+	}
+    } else {
+	nas = nasArray;
+    }
+
+    for( i = 0; i < number; i++ ){
+	nas[i].type = TYPE_UNKNOWN;
+    }
+
+
+    /*
+    ** second pass:
+    ** set nas[].type
+    */
+
+    p = fmt;
+    while( ( c = *p++ ) != 0 ){
+    	if( c != '%' )	continue;
+	    c = *p++;
+	if( c == '%' )	continue;
+
+	cn = 0;
+	while( c && c != '$' ){	    /* should imporve error check later */
+	    cn = cn*10 + c - '0';
+	    c = *p++;
+	}
+
+	if( !c || cn < 1 || cn > number ){
+	    *rv = -1;
+	    break;
+        }
+
+	/* nas[cn] starts from 0, and make sure nas[cn].type is not assigned */
+        cn--;
+	if( nas[cn].type != TYPE_UNKNOWN )
+	    continue;
+
+        c = *p++;
+
+        /* width */
+        if (c == '*') {
+	    /* not supported feature, for the argument is not numbered */
+	    *rv = -1;
+	    break;
+	}
+
+	while ((c >= '0') && (c <= '9')) {
+	    c = *p++;
+	}
+
+	/* precision */
+	if (c == '.') {
+	    c = *p++;
+	    if (c == '*') {
+	        /* not supported feature, for the argument is not numbered */
+	        *rv = -1;
+	        break;
+	    }
+
+	    while ((c >= '0') && (c <= '9')) {
+		c = *p++;
+	    }
+	}
+
+	/* size */
+	nas[cn].type = TYPE_INTN;
+	if (c == 'h') {
+	    nas[cn].type = TYPE_INT16;
+	    c = *p++;
+	} else if (c == 'L') {
+	    /* XXX not quite sure here */
+	    nas[cn].type = TYPE_INT64;
+	    c = *p++;
+	} else if (c == 'l') {
+	    nas[cn].type = TYPE_INT32;
+	    c = *p++;
+	    if (c == 'l') {
+	        nas[cn].type = TYPE_INT64;
+	        c = *p++;
+	    }
+	}
+
+	/* format */
+	switch (c) {
+	case 'd':
+	case 'c':
+	case 'i':
+	case 'o':
+	case 'u':
+	case 'x':
+	case 'X':
+	    break;
+
+	case 'e':
+	case 'f':
+	case 'g':
+	    nas[ cn ].type = TYPE_DOUBLE;
+	    break;
+
+	case 'p':
+	    /* XXX should use cpp */
+	    if (sizeof(void *) == sizeof(PRInt32)) {
+		nas[ cn ].type = TYPE_UINT32;
+	    } else if (sizeof(void *) == sizeof(PRInt64)) {
+	        nas[ cn ].type = TYPE_UINT64;
+	    } else if (sizeof(void *) == sizeof(PRIntn)) {
+	        nas[ cn ].type = TYPE_UINTN;
+	    } else {
+	        nas[ cn ].type = TYPE_UNKNOWN;
+	    }
+	    break;
+
+	case 'C':
+	case 'S':
+	case 'E':
+	case 'G':
+	    /* XXX not supported I suppose */
+	    PR_ASSERT(0);
+	    nas[ cn ].type = TYPE_UNKNOWN;
+	    break;
+
+	case 's':
+	    nas[ cn ].type = TYPE_STRING;
+	    break;
+
+	case 'n':
+	    nas[ cn ].type = TYPE_INTSTR;
+	    break;
+
+	default:
+	    PR_ASSERT(0);
+	    nas[ cn ].type = TYPE_UNKNOWN;
+	    break;
+	}
+
+	/* get a legal para. */
+	if( nas[ cn ].type == TYPE_UNKNOWN ){
+	    *rv = -1;
+	    break;
+	}
+    }
+
+
+    /*
+    ** third pass
+    ** fill the nas[cn].ap
+    */
+
+    if( *rv < 0 ){
+	if( nas != nasArray )
+	    PR_DELETE( nas );
+	return NULL;
+    }
+
+    cn = 0;
+    while( cn < number ){
+	if( nas[cn].type == TYPE_UNKNOWN ){
+	    cn++;
+	    continue;
+	}
+
+	switch( nas[cn].type ){
+	case TYPE_INT16:
+	case TYPE_UINT16:
+	case TYPE_INTN:
+	    nas[cn].u.i = va_arg( ap, int );
+	    break;
+
+	case TYPE_UINTN:
+	    nas[cn].u.ui = va_arg( ap, unsigned int );
+	    break;
+
+	case TYPE_INT32:
+	    nas[cn].u.i32 = va_arg( ap, PRInt32 );
+	    break;
+
+	case TYPE_UINT32:
+	    nas[cn].u.ui32 = va_arg( ap, PRUint32 );
+	    break;
+
+	case TYPE_INT64:
+	    nas[cn].u.ll = va_arg( ap, PRInt64 );
+	    break;
+
+	case TYPE_UINT64:
+	    nas[cn].u.ull = va_arg( ap, PRUint64 );
+	    break;
+
+	case TYPE_STRING:
+	    nas[cn].u.s = va_arg( ap, char* );
+	    break;
+
+	case TYPE_INTSTR:
+	    nas[cn].u.ip = va_arg( ap, int* );
+	    break;
+
+	case TYPE_DOUBLE:
+	    nas[cn].u.d = va_arg( ap, double );
+	    break;
+
+	default:
+	    if( nas != nasArray )
+		PR_DELETE( nas );
+	    *rv = -1;
+	    return NULL;
+	}
+
+	cn++;
+    }
+
+
+    return nas;
+}
+
+/*
+** The workhorse sprintf code.
+*/
+static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
+{
+    char c;
+    int flags, width, prec, radix, type;
+    union {
+	char ch;
+	int i;
+	long l;
+	PRInt64 ll;
+	double d;
+	const char *s;
+	int *ip;
+    } u;
+    const char *fmt0;
+    static char *hex = "0123456789abcdef";
+    static char *HEX = "0123456789ABCDEF";
+    char *hexp;
+    int rv, i;
+    struct NumArg* nas = NULL;
+    struct NumArg* nap;
+    struct NumArg  nasArray[ NAS_DEFAULT_NUM ];
+    char  pattern[20];
+    const char* dolPt = NULL;  /* in "%4$.2f", dolPt will point to . */
+
+
+    /*
+    ** build an argument array, IF the fmt is numbered argument
+    ** list style, to contain the Numbered Argument list pointers
+    */
+
+    nas = BuildArgArray( fmt, ap, &rv, nasArray );
+    if( rv < 0 ){
+	/* the fmt contains error Numbered Argument format, jliu at netscape.com */
+	PR_ASSERT(0);
+	return rv;
+    }
+
+    while ((c = *fmt++) != 0) {
+	if (c != '%') {
+	    rv = (*ss->stuff)(ss, fmt - 1, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	    continue;
+	}
+	fmt0 = fmt - 1;
+
+	/*
+	** Gobble up the % format string. Hopefully we have handled all
+	** of the strange cases!
+	*/
+	flags = 0;
+	c = *fmt++;
+	if (c == '%') {
+	    /* quoting a % with %% */
+	    rv = (*ss->stuff)(ss, fmt - 1, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	    continue;
+	}
+
+	if( nas != NULL ){
+	    /* the fmt contains the Numbered Arguments feature */
+	    i = 0;
+	    while( c && c != '$' ){	    /* should imporve error check later */
+		i = ( i * 10 ) + ( c - '0' );
+		c = *fmt++;
+	    }
+
+	    if( nas[i-1].type == TYPE_UNKNOWN ){
+		if( nas && ( nas != nasArray ) )
+		    PR_DELETE( nas );
+		return -1;
+	    }
+
+	    nap = &nas[i-1];
+	    dolPt = fmt;
+	    c = *fmt++;
+	}
+
+	/*
+	 * Examine optional flags.  Note that we do not implement the
+	 * '#' flag of sprintf().  The ANSI C spec. of the '#' flag is
+	 * somewhat ambiguous and not ideal, which is perhaps why
+	 * the various sprintf() implementations are inconsistent
+	 * on this feature.
+	 */
+	while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) {
+	    if (c == '-') flags |= FLAG_LEFT;
+	    if (c == '+') flags |= FLAG_SIGNED;
+	    if (c == ' ') flags |= FLAG_SPACED;
+	    if (c == '0') flags |= FLAG_ZEROS;
+	    c = *fmt++;
+	}
+	if (flags & FLAG_SIGNED) flags &= ~FLAG_SPACED;
+	if (flags & FLAG_LEFT) flags &= ~FLAG_ZEROS;
+
+	/* width */
+	if (c == '*') {
+	    c = *fmt++;
+	    width = va_arg(ap, int);
+	} else {
+	    width = 0;
+	    while ((c >= '0') && (c <= '9')) {
+		width = (width * 10) + (c - '0');
+		c = *fmt++;
+	    }
+	}
+
+	/* precision */
+	prec = -1;
+	if (c == '.') {
+	    c = *fmt++;
+	    if (c == '*') {
+		c = *fmt++;
+		prec = va_arg(ap, int);
+	    } else {
+		prec = 0;
+		while ((c >= '0') && (c <= '9')) {
+		    prec = (prec * 10) + (c - '0');
+		    c = *fmt++;
+		}
+	    }
+	}
+
+	/* size */
+	type = TYPE_INTN;
+	if (c == 'h') {
+	    type = TYPE_INT16;
+	    c = *fmt++;
+	} else if (c == 'L') {
+	    /* XXX not quite sure here */
+	    type = TYPE_INT64;
+	    c = *fmt++;
+	} else if (c == 'l') {
+	    type = TYPE_INT32;
+	    c = *fmt++;
+	    if (c == 'l') {
+		type = TYPE_INT64;
+		c = *fmt++;
+	    }
+	}
+
+	/* format */
+	hexp = hex;
+	switch (c) {
+	  case 'd': case 'i':			/* decimal/integer */
+	    radix = 10;
+	    goto fetch_and_convert;
+
+	  case 'o':				/* octal */
+	    radix = 8;
+	    type |= 1;
+	    goto fetch_and_convert;
+
+	  case 'u':				/* unsigned decimal */
+	    radix = 10;
+	    type |= 1;
+	    goto fetch_and_convert;
+
+	  case 'x':				/* unsigned hex */
+	    radix = 16;
+	    type |= 1;
+	    goto fetch_and_convert;
+
+	  case 'X':				/* unsigned HEX */
+	    radix = 16;
+	    hexp = HEX;
+	    type |= 1;
+	    goto fetch_and_convert;
+
+	  fetch_and_convert:
+	    switch (type) {
+	      case TYPE_INT16:
+		u.l = nas ? nap->u.i : va_arg(ap, int);
+		if (u.l < 0) {
+		    u.l = -u.l;
+		    flags |= FLAG_NEG;
+		}
+		goto do_long;
+	      case TYPE_UINT16:
+		u.l = (nas ? nap->u.i : va_arg(ap, int)) & 0xffff;
+		goto do_long;
+	      case TYPE_INTN:
+		u.l = nas ? nap->u.i : va_arg(ap, int);
+		if (u.l < 0) {
+		    u.l = -u.l;
+		    flags |= FLAG_NEG;
+		}
+		goto do_long;
+	      case TYPE_UINTN:
+		u.l = (long)(nas ? nap->u.ui : va_arg(ap, unsigned int));
+		goto do_long;
+
+	      case TYPE_INT32:
+		u.l = nas ? nap->u.i32 : va_arg(ap, PRInt32);
+		if (u.l < 0) {
+		    u.l = -u.l;
+		    flags |= FLAG_NEG;
+		}
+		goto do_long;
+	      case TYPE_UINT32:
+		u.l = (long)(nas ? nap->u.ui32 : va_arg(ap, PRUint32));
+	      do_long:
+		rv = cvt_l(ss, u.l, width, prec, radix, type, flags, hexp);
+		if (rv < 0) {
+		    return rv;
+		}
+		break;
+
+	      case TYPE_INT64:
+		u.ll = nas ? nap->u.ll : va_arg(ap, PRInt64);
+		if (!LL_GE_ZERO(u.ll)) {
+		    LL_NEG(u.ll, u.ll);
+		    flags |= FLAG_NEG;
+		}
+		goto do_longlong;
+	      case TYPE_UINT64:
+		u.ll = nas ? nap->u.ull : va_arg(ap, PRUint64);
+	      do_longlong:
+		rv = cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp);
+		if (rv < 0) {
+		    return rv;
+		}
+		break;
+	    }
+	    break;
+
+	  case 'e':
+	  case 'E':
+	  case 'f':
+	  case 'g':
+	    u.d = nas ? nap->u.d : va_arg(ap, double);
+	    if( nas != NULL ){
+		i = fmt - dolPt;
+		if( i < sizeof( pattern ) ){
+		    pattern[0] = '%';
+		    memcpy( &pattern[1], dolPt, i );
+		    rv = cvt_f(ss, u.d, pattern, &pattern[i+1] );
+		}
+	    } else
+		rv = cvt_f(ss, u.d, fmt0, fmt);
+
+	    if (rv < 0) {
+		return rv;
+	    }
+	    break;
+
+	  case 'c':
+	    u.ch = nas ? nap->u.i : va_arg(ap, int);
+            if ((flags & FLAG_LEFT) == 0) {
+                while (width-- > 1) {
+                    rv = (*ss->stuff)(ss, " ", 1);
+                    if (rv < 0) {
+                        return rv;
+                    }
+                }
+            }
+	    rv = (*ss->stuff)(ss, &u.ch, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+            if (flags & FLAG_LEFT) {
+                while (width-- > 1) {
+                    rv = (*ss->stuff)(ss, " ", 1);
+                    if (rv < 0) {
+                        return rv;
+                    }
+                }
+            }
+	    break;
+
+	  case 'p':
+	    if (sizeof(void *) == sizeof(PRInt32)) {
+	    	type = TYPE_UINT32;
+	    } else if (sizeof(void *) == sizeof(PRInt64)) {
+	    	type = TYPE_UINT64;
+	    } else if (sizeof(void *) == sizeof(int)) {
+		type = TYPE_UINTN;
+	    } else {
+		PR_ASSERT(0);
+		break;
+	    }
+	    radix = 16;
+	    goto fetch_and_convert;
+
+#if 0
+	  case 'C':
+	  case 'S':
+	  case 'E':
+	  case 'G':
+	    /* XXX not supported I suppose */
+	    PR_ASSERT(0);
+	    break;
+#endif
+
+	  case 's':
+	    u.s = nas ? nap->u.s : va_arg(ap, const char*);
+	    rv = cvt_s(ss, u.s, width, prec, flags);
+	    if (rv < 0) {
+		return rv;
+	    }
+	    break;
+
+	  case 'n':
+	    u.ip = nas ? nap->u.ip : va_arg(ap, int*);
+	    if (u.ip) {
+		*u.ip = ss->cur - ss->base;
+	    }
+	    break;
+
+	  default:
+	    /* Not a % token after all... skip it */
+#if 0
+	    PR_ASSERT(0);
+#endif
+	    rv = (*ss->stuff)(ss, "%", 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	    rv = (*ss->stuff)(ss, fmt - 1, 1);
+	    if (rv < 0) {
+		return rv;
+	    }
+	}
+    }
+
+    /* Stuff trailing NUL */
+    rv = (*ss->stuff)(ss, "\0", 1);
+
+    if( nas && ( nas != nasArray ) ){
+	PR_DELETE( nas );
+    }
+
+    return rv;
+}
+
+/************************************************************************/
+
+static int FuncStuff(SprintfState *ss, const char *sp, PRUint32 len)
+{
+    int rv;
+
+    rv = (*ss->func)(ss->arg, sp, len);
+    if (rv < 0) {
+	return rv;
+    }
+    ss->maxlen += len;
+    return 0;
+}
+
+PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg, 
+                                 const char *fmt, ...)
+{
+    va_list ap;
+    PRUint32 rv;
+
+    va_start(ap, fmt);
+    rv = PR_vsxprintf(func, arg, fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+PR_IMPLEMENT(PRUint32) PR_vsxprintf(PRStuffFunc func, void *arg, 
+                                  const char *fmt, va_list ap)
+{
+    SprintfState ss;
+    int rv;
+
+    ss.stuff = FuncStuff;
+    ss.func = func;
+    ss.arg = arg;
+    ss.maxlen = 0;
+    rv = dosprintf(&ss, fmt, ap);
+    return (rv < 0) ? (PRUint32)-1 : ss.maxlen;
+}
+
+/*
+** Stuff routine that automatically grows the malloc'd output buffer
+** before it overflows.
+*/
+static int GrowStuff(SprintfState *ss, const char *sp, PRUint32 len)
+{
+    ptrdiff_t off;
+    char *newbase;
+    PRUint32 newlen;
+
+    off = ss->cur - ss->base;
+    if (off + len >= ss->maxlen) {
+	/* Grow the buffer */
+	newlen = ss->maxlen + ((len > 32) ? len : 32);
+	if (ss->base) {
+	    newbase = (char*) PR_REALLOC(ss->base, newlen);
+	} else {
+	    newbase = (char*) PR_MALLOC(newlen);
+	}
+	if (!newbase) {
+	    /* Ran out of memory */
+	    return -1;
+	}
+	ss->base = newbase;
+	ss->maxlen = newlen;
+	ss->cur = ss->base + off;
+    }
+
+    /* Copy data */
+    while (len) {
+	--len;
+	*ss->cur++ = *sp++;
+    }
+    PR_ASSERT((PRUint32)(ss->cur - ss->base) <= ss->maxlen);
+    return 0;
+}
+
+/*
+** sprintf into a malloc'd buffer
+*/
+PR_IMPLEMENT(char *) PR_smprintf(const char *fmt, ...)
+{
+    va_list ap;
+    char *rv;
+
+    va_start(ap, fmt);
+    rv = PR_vsmprintf(fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+/*
+** Free memory allocated, for the caller, by PR_smprintf
+*/
+PR_IMPLEMENT(void) PR_smprintf_free(char *mem)
+{
+	PR_DELETE(mem);
+}
+
+PR_IMPLEMENT(char *) PR_vsmprintf(const char *fmt, va_list ap)
+{
+    SprintfState ss;
+    int rv;
+
+    ss.stuff = GrowStuff;
+    ss.base = 0;
+    ss.cur = 0;
+    ss.maxlen = 0;
+    rv = dosprintf(&ss, fmt, ap);
+    if (rv < 0) {
+	if (ss.base) {
+	    PR_DELETE(ss.base);
+	}
+	return 0;
+    }
+    return ss.base;
+}
+
+/*
+** Stuff routine that discards overflow data
+*/
+static int LimitStuff(SprintfState *ss, const char *sp, PRUint32 len)
+{
+    PRUint32 limit = ss->maxlen - (ss->cur - ss->base);
+
+    if (len > limit) {
+	len = limit;
+    }
+    while (len) {
+	--len;
+	*ss->cur++ = *sp++;
+    }
+    return 0;
+}
+
+/*
+** sprintf into a fixed size buffer. Make sure there is a NUL at the end
+** when finished.
+*/
+PR_IMPLEMENT(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...)
+{
+    va_list ap;
+    PRUint32 rv;
+
+    PR_ASSERT((PRInt32)outlen > 0);
+    if ((PRInt32)outlen <= 0) {
+	return 0;
+    }
+
+    va_start(ap, fmt);
+    rv = PR_vsnprintf(out, outlen, fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+PR_IMPLEMENT(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen,const char *fmt,
+                                  va_list ap)
+{
+    SprintfState ss;
+    PRUint32 n;
+
+    PR_ASSERT((PRInt32)outlen > 0);
+    if ((PRInt32)outlen <= 0) {
+	return 0;
+    }
+
+    ss.stuff = LimitStuff;
+    ss.base = out;
+    ss.cur = out;
+    ss.maxlen = outlen;
+    (void) dosprintf(&ss, fmt, ap);
+
+    /* If we added chars, and we didn't append a null, do it now. */
+    if( (ss.cur != ss.base) && (*(ss.cur - 1) != '\0') )
+        *(ss.cur - 1) = '\0';
+
+    n = ss.cur - ss.base;
+    return n ? n - 1 : n;
+}
+
+PR_IMPLEMENT(char *) PR_sprintf_append(char *last, const char *fmt, ...)
+{
+    va_list ap;
+    char *rv;
+
+    va_start(ap, fmt);
+    rv = PR_vsprintf_append(last, fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+PR_IMPLEMENT(char *) PR_vsprintf_append(char *last, const char *fmt, va_list ap)
+{
+    SprintfState ss;
+    int rv;
+
+    ss.stuff = GrowStuff;
+    if (last) {
+	int lastlen = strlen(last);
+	ss.base = last;
+	ss.cur = last + lastlen;
+	ss.maxlen = lastlen;
+    } else {
+	ss.base = 0;
+	ss.cur = 0;
+	ss.maxlen = 0;
+    }
+    rv = dosprintf(&ss, fmt, ap);
+    if (rv < 0) {
+	if (ss.base) {
+	    PR_DELETE(ss.base);
+	}
+	return 0;
+    }
+    return ss.base;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prscanf.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prscanf.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,669 @@
+/* -*- 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 ***** */
+
+/*
+ * Scan functions for NSPR types
+ *
+ * Author: Wan-Teh Chang
+ *
+ * Acknowledgment: The implementation is inspired by the source code
+ * in P.J. Plauger's "The Standard C Library," Prentice-Hall, 1992.
+ */
+
+#include <limits.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef SUNOS4
+#include "md/sunos4.h"  /* for strtoul */
+#endif
+#include "prprf.h"
+#include "prdtoa.h"
+#include "prlog.h"
+#include "prerror.h"
+
+/*
+ * A function that reads a character from 'stream'.
+ * Returns the character read, or EOF if end of stream is reached.
+ */
+typedef int (*_PRGetCharFN)(void *stream);
+
+/*
+ * A function that pushes the character 'ch' back to 'stream'.
+ */
+typedef void (*_PRUngetCharFN)(void *stream, int ch); 
+
+/*
+ * The size specifier for the integer and floating point number
+ * conversions in format control strings.
+ */
+typedef enum {
+    _PR_size_none,  /* No size specifier is given */
+    _PR_size_h,     /* The 'h' specifier, suggesting "short" */
+    _PR_size_l,     /* The 'l' specifier, suggesting "long" */
+    _PR_size_L,     /* The 'L' specifier, meaning a 'long double' */
+    _PR_size_ll     /* The 'll' specifier, suggesting "long long" */
+} _PRSizeSpec;
+
+/*
+ * The collection of data that is passed between the scan function
+ * and its subordinate functions.  The fields of this structure
+ * serve as the input or output arguments for these functions.
+ */
+typedef struct {
+    _PRGetCharFN get;        /* get a character from input stream */
+    _PRUngetCharFN unget;    /* unget (push back) a character */
+    void *stream;            /* argument for get and unget */
+    va_list ap;              /* the variable argument list */
+    int nChar;               /* number of characters read from 'stream' */
+
+    PRBool assign;           /* assign, or suppress assignment? */
+    int width;               /* field width */
+    _PRSizeSpec sizeSpec;    /* 'h', 'l', 'L', or 'll' */
+
+    PRBool converted;        /* is the value actually converted? */
+} ScanfState;
+
+#define GET(state) ((state)->nChar++, (state)->get((state)->stream))
+#define UNGET(state, ch) \
+        ((state)->nChar--, (state)->unget((state)->stream, ch))
+
+/*
+ * The following two macros, GET_IF_WITHIN_WIDTH and WITHIN_WIDTH,
+ * are always used together.
+ *
+ * GET_IF_WITHIN_WIDTH calls the GET macro and assigns its return
+ * value to 'ch' only if we have not exceeded the field width of
+ * 'state'.  Therefore, after GET_IF_WITHIN_WIDTH, the value of
+ * 'ch' is valid only if the macro WITHIN_WIDTH evaluates to true.
+ */
+
+#define GET_IF_WITHIN_WIDTH(state, ch) \
+        if (--(state)->width >= 0) { \
+            (ch) = GET(state); \
+        }
+#define WITHIN_WIDTH(state) ((state)->width >= 0)
+
+/*
+ * _pr_strtoull:
+ *     Convert a string to an unsigned 64-bit integer.  The string
+ *     'str' is assumed to be a representation of the integer in
+ *     base 'base'.
+ *
+ * Warning: 
+ *     - Only handle base 8, 10, and 16.
+ *     - No overflow checking.
+ */
+
+static PRUint64
+_pr_strtoull(const char *str, char **endptr, int base)
+{
+    static const int BASE_MAX = 16;
+    static const char digits[] = "0123456789abcdef";
+    char *digitPtr;
+    PRUint64 x;    /* return value */
+    PRInt64 base64;
+    const char *cPtr;
+    PRBool negative;
+    const char *digitStart;
+
+    PR_ASSERT(base == 0 || base == 8 || base == 10 || base == 16);
+    if (base < 0 || base == 1 || base > BASE_MAX) {
+        if (endptr) {
+            *endptr = (char *) str;
+            return LL_ZERO;
+        }
+    }
+
+    cPtr = str;
+    while (isspace(*cPtr)) {
+        ++cPtr;
+    }
+
+    negative = PR_FALSE;
+    if (*cPtr == '-') {
+        negative = PR_TRUE;
+        cPtr++;
+    } else if (*cPtr == '+') {
+        cPtr++;
+    }
+
+    if (base == 16) {
+        if (*cPtr == '0' && (cPtr[1] == 'x' || cPtr[1] == 'X')) {
+            cPtr += 2;
+        }
+    } else if (base == 0) {
+        if (*cPtr != '0') {
+            base = 10;
+        } else if (cPtr[1] == 'x' || cPtr[1] == 'X') {
+            base = 16;
+            cPtr += 2;
+        } else {
+            base = 8;
+        } 
+    }
+    PR_ASSERT(base != 0);
+    LL_I2L(base64, base);
+    digitStart = cPtr;
+
+    /* Skip leading zeros */
+    while (*cPtr == '0') {
+        cPtr++;
+    }
+
+    LL_I2L(x, 0);
+    while ((digitPtr = (char*)memchr(digits, tolower(*cPtr), base)) != NULL) {
+        PRUint64 d;
+
+        LL_I2L(d, (digitPtr - digits));
+        LL_MUL(x, x, base64);
+        LL_ADD(x, x, d);
+        cPtr++;
+    }
+
+    if (cPtr == digitStart) {
+        if (endptr) {
+            *endptr = (char *) str;
+        }
+        return LL_ZERO;
+    }
+
+    if (negative) {
+#ifdef HAVE_LONG_LONG
+        /* The cast to a signed type is to avoid a compiler warning */
+        x = -(PRInt64)x;
+#else
+        LL_NEG(x, x);
+#endif
+    }
+
+    if (endptr) {
+        *endptr = (char *) cPtr;
+    }
+    return x;
+}
+
+/*
+ * The maximum field width (in number of characters) that is enough
+ * (may be more than necessary) to represent a 64-bit integer or
+ * floating point number.
+ */
+#define FMAX 31
+#define DECIMAL_POINT '.'
+
+static PRStatus
+GetInt(ScanfState *state, int code)
+{
+    char buf[FMAX + 1], *p;
+    int ch;
+    static const char digits[] = "0123456789abcdefABCDEF";
+    PRBool seenDigit = PR_FALSE;
+    int base;
+    int dlen;
+
+    switch (code) {
+        case 'd': case 'u':
+            base = 10;
+            break;
+        case 'i':
+            base = 0;
+            break;
+        case 'x': case 'X': case 'p':
+            base = 16;
+            break;
+        case 'o':
+            base = 8;
+            break;
+        default:
+            return PR_FAILURE;
+    }
+    if (state->width == 0 || state->width > FMAX) {
+        state->width = FMAX;
+    }
+    p = buf;
+    GET_IF_WITHIN_WIDTH(state, ch);
+    if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+    }
+    if (WITHIN_WIDTH(state) && ch == '0') {
+        seenDigit = PR_TRUE;
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+        if (WITHIN_WIDTH(state)
+                && (ch == 'x' || ch == 'X')
+                && (base == 0 || base == 16)) {
+            base = 16;
+            *p++ = ch;
+            GET_IF_WITHIN_WIDTH(state, ch);
+        } else if (base == 0) {
+            base = 8;
+        }
+    }
+    if (base == 0 || base == 10) {
+        dlen = 10;
+    } else if (base == 8) {
+        dlen = 8;
+    } else {
+        PR_ASSERT(base == 16);
+        dlen = 16 + 6; /* 16 digits, plus 6 in uppercase */
+    }
+    while (WITHIN_WIDTH(state) && memchr(digits, ch, dlen)) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+        seenDigit = PR_TRUE;
+    }
+    if (WITHIN_WIDTH(state)) {
+        UNGET(state, ch);
+    }
+    if (!seenDigit) {
+        return PR_FAILURE;
+    }
+    *p = '\0';
+    if (state->assign) {
+        if (code == 'd' || code == 'i') {
+            if (state->sizeSpec == _PR_size_ll) {
+                PRInt64 llval = _pr_strtoull(buf, NULL, base);
+                *va_arg(state->ap, PRInt64 *) = llval;
+            } else {
+                long lval = strtol(buf, NULL, base);
+
+                if (state->sizeSpec == _PR_size_none) {
+                    *va_arg(state->ap, PRIntn *) = lval;
+                } else if (state->sizeSpec == _PR_size_h) {
+                    *va_arg(state->ap, PRInt16 *) = (PRInt16)lval;
+                } else if (state->sizeSpec == _PR_size_l) {
+                    *va_arg(state->ap, PRInt32 *) = lval;
+                } else {
+                    return PR_FAILURE;
+                }
+            }
+        } else {
+            if (state->sizeSpec == _PR_size_ll) {
+                PRUint64 llval = _pr_strtoull(buf, NULL, base);
+                *va_arg(state->ap, PRUint64 *) = llval;
+            } else {
+                unsigned long lval = strtoul(buf, NULL, base);
+
+                if (state->sizeSpec == _PR_size_none) {
+                    *va_arg(state->ap, PRUintn *) = lval;
+                } else if (state->sizeSpec == _PR_size_h) {
+                    *va_arg(state->ap, PRUint16 *) = (PRUint16)lval;
+                } else if (state->sizeSpec == _PR_size_l) {
+                    *va_arg(state->ap, PRUint32 *) = lval;
+                } else {
+                    return PR_FAILURE;
+                }
+            }
+        }
+        state->converted = PR_TRUE;
+    }
+    return PR_SUCCESS;
+}
+
+static PRStatus
+GetFloat(ScanfState *state)
+{
+    char buf[FMAX + 1], *p;
+    int ch;
+    PRBool seenDigit = PR_FALSE;
+
+    if (state->width == 0 || state->width > FMAX) {
+        state->width = FMAX;
+    }
+    p = buf;
+    GET_IF_WITHIN_WIDTH(state, ch);
+    if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+    }
+    while (WITHIN_WIDTH(state) && isdigit(ch)) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+        seenDigit = PR_TRUE;
+    }
+    if (WITHIN_WIDTH(state) && ch == DECIMAL_POINT) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+        while (WITHIN_WIDTH(state) && isdigit(ch)) {
+            *p++ = ch;
+            GET_IF_WITHIN_WIDTH(state, ch);
+            seenDigit = PR_TRUE;
+        }
+    }
+
+    /*
+     * This is not robust.  For example, "1.2e+" would confuse
+     * the code below to read 'e' and '+', only to realize that
+     * it should have stopped at "1.2".  But we can't push back
+     * more than one character, so there is nothing I can do.
+     */
+
+    /* Parse exponent */
+    if (WITHIN_WIDTH(state) && (ch == 'e' || ch == 'E') && seenDigit) {
+        *p++ = ch;
+        GET_IF_WITHIN_WIDTH(state, ch);
+        if (WITHIN_WIDTH(state) && (ch == '+' || ch == '-')) {
+            *p++ = ch;
+            GET_IF_WITHIN_WIDTH(state, ch);
+        }
+        while (WITHIN_WIDTH(state) && isdigit(ch)) {
+            *p++ = ch;
+            GET_IF_WITHIN_WIDTH(state, ch);
+        }
+    }
+    if (WITHIN_WIDTH(state)) {
+        UNGET(state, ch);
+    }
+    if (!seenDigit) {
+        return PR_FAILURE;
+    }
+    *p = '\0';
+    if (state->assign) {
+        PRFloat64 dval = PR_strtod(buf, NULL);
+
+        state->converted = PR_TRUE;
+        if (state->sizeSpec == _PR_size_l) {
+            *va_arg(state->ap, PRFloat64 *) = dval;
+        } else if (state->sizeSpec == _PR_size_L) {
+#if defined(OSF1) || defined(IRIX)
+            *va_arg(state->ap, double *) = dval;
+#else
+            *va_arg(state->ap, long double *) = dval;
+#endif
+        } else {
+            *va_arg(state->ap, float *) = (float) dval;
+        }
+    }
+    return PR_SUCCESS;
+}
+
+/*
+ * Convert, and return the end of the conversion spec.
+ * Return NULL on error.
+ */
+
+static const char *
+Convert(ScanfState *state, const char *fmt)
+{
+    const char *cPtr;
+    int ch;
+    char *cArg = NULL;
+
+    state->converted = PR_FALSE;
+    cPtr = fmt;
+    if (*cPtr != 'c' && *cPtr != 'n' && *cPtr != '[') {
+        do {
+            ch = GET(state);
+        } while (isspace(ch));
+        UNGET(state, ch);
+    }
+    switch (*cPtr) {
+        case 'c':
+            if (state->assign) {
+                cArg = va_arg(state->ap, char *);
+            }
+            if (state->width == 0) {
+                state->width = 1;
+            }
+            for (; state->width > 0; state->width--) {
+                ch = GET(state);
+                if (ch == EOF) {
+                    return NULL;
+                } else if (state->assign) {
+                    *cArg++ = ch;
+                }
+            }
+            if (state->assign) {
+                state->converted = PR_TRUE;
+            }
+            break;
+        case 'p':
+        case 'd': case 'i': case 'o':
+        case 'u': case 'x': case 'X':
+            if (GetInt(state, *cPtr) == PR_FAILURE) {
+                return NULL;
+            }
+            break;
+        case 'e': case 'E': case 'f':
+        case 'g': case 'G':
+            if (GetFloat(state) == PR_FAILURE) {
+                return NULL;
+            }
+            break;
+        case 'n':
+            /* do not consume any input */
+            if (state->assign) {
+                switch (state->sizeSpec) {
+                    case _PR_size_none:
+                        *va_arg(state->ap, PRIntn *) = state->nChar;
+                        break;
+                    case _PR_size_h:
+                        *va_arg(state->ap, PRInt16 *) = state->nChar;
+                        break;
+                    case _PR_size_l:
+                        *va_arg(state->ap, PRInt32 *) = state->nChar;
+                        break;
+                    case _PR_size_ll:
+                        LL_I2L(*va_arg(state->ap, PRInt64 *), state->nChar);
+                        break;
+                    default:
+                        PR_ASSERT(0);
+                }
+            }
+            break;
+        case 's':
+            if (state->width == 0) {
+                state->width = INT_MAX;
+            }
+            if (state->assign) {
+                cArg = va_arg(state->ap, char *);
+            }
+            for (; state->width > 0; state->width--) {
+                ch = GET(state);
+                if ((ch == EOF) || isspace(ch)) {
+                    UNGET(state, ch);
+                    break;
+                }
+                if (state->assign) {
+                    *cArg++ = ch;
+                }
+            }
+            if (state->assign) {
+                *cArg = '\0';
+                state->converted = PR_TRUE;
+            }
+            break;
+        case '%':
+            ch = GET(state);
+            if (ch != '%') {
+                UNGET(state, ch);
+                return NULL;
+            }
+            break;
+        case '[':
+            {
+                PRBool complement = PR_FALSE;
+                const char *closeBracket;
+                size_t n;
+
+                if (*++cPtr == '^') {
+                    complement = PR_TRUE;
+                    cPtr++;
+                }
+                closeBracket = strchr(*cPtr == ']' ? cPtr + 1 : cPtr, ']');
+                if (closeBracket == NULL) {
+                    return NULL;
+                }
+                n = closeBracket - cPtr;
+                if (state->width == 0) {
+                    state->width = INT_MAX;
+                }
+                if (state->assign) {
+                    cArg = va_arg(state->ap, char *);
+                }
+                for (; state->width > 0; state->width--) {
+                    ch = GET(state);
+                    if ((ch == EOF) 
+                            || (!complement && !memchr(cPtr, ch, n))
+                            || (complement && memchr(cPtr, ch, n))) {
+                        UNGET(state, ch);
+                        break;
+                    }
+                    if (state->assign) {
+                        *cArg++ = ch;
+                    }
+                }
+                if (state->assign) {
+                    *cArg = '\0';
+                    state->converted = PR_TRUE;
+                }
+                cPtr = closeBracket;
+            }
+            break;
+        default:
+            return NULL;
+    }
+    return cPtr;
+}
+
+static PRInt32
+DoScanf(ScanfState *state, const char *fmt)
+{
+    PRInt32 nConverted = 0;
+    const char *cPtr;
+    int ch;
+
+    state->nChar = 0;
+    cPtr = fmt;
+    while (1) {
+        if (isspace(*cPtr)) {
+            /* white space: skip */
+            do {
+                cPtr++;
+            } while (isspace(*cPtr));
+            do {
+                ch = GET(state);
+            } while (isspace(ch));
+            UNGET(state, ch);
+        } else if (*cPtr == '%') {
+            /* format spec: convert */
+            cPtr++;
+            state->assign = PR_TRUE;
+            if (*cPtr == '*') {
+                cPtr++;
+                state->assign = PR_FALSE;
+            }
+            for (state->width = 0; isdigit(*cPtr); cPtr++) {
+                state->width = state->width * 10 + *cPtr - '0';
+            }
+            state->sizeSpec = _PR_size_none;
+            if (*cPtr == 'h') {
+                cPtr++;
+                state->sizeSpec = _PR_size_h;
+            } else if (*cPtr == 'l') {
+                cPtr++;
+                if (*cPtr == 'l') {
+                    cPtr++;
+                    state->sizeSpec = _PR_size_ll;
+                } else {
+                    state->sizeSpec = _PR_size_l;
+                }
+            } else if (*cPtr == 'L') {
+                cPtr++;
+                state->sizeSpec = _PR_size_L;
+            }
+            cPtr = Convert(state, cPtr);
+            if (cPtr == NULL) {
+                return (nConverted > 0 ? nConverted : EOF);
+            }
+            if (state->converted) {
+                nConverted++;
+            }
+            cPtr++;
+        } else {
+            /* others: must match */
+            if (*cPtr == '\0') {
+                return nConverted;
+            }
+            ch = GET(state);
+            if (ch != *cPtr) {
+                UNGET(state, ch);
+                return nConverted;
+            }
+            cPtr++;
+        }
+    }
+}
+
+static int
+StringGetChar(void *stream)
+{
+    char *cPtr = *((char **) stream);
+
+    if (*cPtr == '\0') {
+        return EOF;
+    } else {
+        *((char **) stream) = cPtr + 1;
+        return (unsigned char) *cPtr;
+    }
+}
+
+static void
+StringUngetChar(void *stream, int ch)
+{
+    char *cPtr = *((char **) stream);
+
+    if (ch != EOF) {
+        *((char **) stream) = cPtr - 1;
+    }
+}
+
+PR_IMPLEMENT(PRInt32)
+PR_sscanf(const char *buf, const char *fmt, ...)
+{
+    PRInt32 rv;
+    ScanfState state;
+
+    state.get = &StringGetChar;
+    state.unget = &StringUngetChar;
+    state.stream = (void *) &buf;
+    va_start(state.ap, fmt);
+    rv = DoScanf(&state, fmt);
+    va_end(state.ap);
+    return rv;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prsocket.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prsocket.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1843 @@
+/* -*- 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 <string.h>
+
+/************************************************************************/
+
+/* These two functions are only used in assertions. */
+#if defined(DEBUG)
+
+PRBool IsValidNetAddr(const PRNetAddr *addr)
+{
+    if ((addr != NULL)
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+	    && (addr->raw.family != PR_AF_LOCAL)
+#endif
+	    && (addr->raw.family != PR_AF_INET6)
+	    && (addr->raw.family != PR_AF_INET)) {
+        return PR_FALSE;
+    }
+    return PR_TRUE;
+}
+
+static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
+{
+    /*
+     * The definition of the length of a Unix domain socket address
+     * is not uniform, so we don't check it.
+     */
+    if ((addr != NULL)
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+            && (addr->raw.family != AF_UNIX)
+#endif
+            && (PR_NETADDR_SIZE(addr) != addr_len)) {
+#if defined(LINUX) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 1
+        /*
+         * In glibc 2.1, struct sockaddr_in6 is 24 bytes.  In glibc 2.2
+         * and in the 2.4 kernel, struct sockaddr_in6 has the scope_id
+         * field and is 28 bytes.  It is possible for socket functions
+         * to return an addr_len greater than sizeof(struct sockaddr_in6).
+         * We need to allow that.  (Bugzilla bug #77264)
+         */
+        if ((PR_AF_INET6 == addr->raw.family)
+                && (sizeof(addr->ipv6) == addr_len)) {
+            return PR_TRUE;
+        }
+#endif
+        /*
+         * The accept(), getsockname(), etc. calls on some platforms
+         * do not set the actual socket address length on return.
+         * In this case, we verifiy addr_len is still the value we
+         * passed in (i.e., sizeof(PRNetAddr)).
+         */
+#if defined(QNX)
+        if (sizeof(PRNetAddr) == addr_len) {
+            return PR_TRUE;
+        }
+#endif
+        return PR_FALSE;
+    }
+    return PR_TRUE;
+}
+
+#endif /* DEBUG */
+
+static PRInt32 PR_CALLBACK SocketWritev(PRFileDesc *fd, const PRIOVec *iov,
+PRInt32 iov_size, PRIntervalTime timeout)
+{
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+	int w = 0;
+	const PRIOVec *tmp_iov;
+#define LOCAL_MAXIOV    8
+	PRIOVec local_iov[LOCAL_MAXIOV];
+	PRIOVec *iov_copy = NULL;
+	int tmp_out;
+	int index, iov_cnt;
+	int count=0, sz = 0;    /* 'count' is the return value. */
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return -1;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return -1;
+	}
+
+    /*
+     * Assume the first writev will succeed.  Copy iov's only on
+     * failure.
+     */
+    tmp_iov = iov;
+    for (index = 0; index < iov_size; index++)
+        sz += iov[index].iov_len;
+
+	iov_cnt = iov_size;
+
+	while (sz > 0) {
+
+		w = _PR_MD_WRITEV(fd, tmp_iov, iov_cnt, timeout);
+		if (w < 0) {
+			count = -1;
+			break;
+		}
+		count += w;
+		if (fd->secret->nonblocking) {
+			break;
+		}
+		sz -= w;
+
+		if (sz > 0) {
+			/* find the next unwritten vector */
+			for ( index = 0, tmp_out = count;
+				tmp_out >= iov[index].iov_len;
+				tmp_out -= iov[index].iov_len, index++){;} /* nothing to execute */
+
+			if (tmp_iov == iov) {
+				/*
+				 * The first writev failed so we
+				 * must copy iov's around.
+				 * Avoid calloc/free if there
+				 * are few enough iov's.
+				 */
+				if (iov_size - index <= LOCAL_MAXIOV)
+					iov_copy = local_iov;
+				else if ((iov_copy = (PRIOVec *) PR_CALLOC((iov_size - index) *
+					sizeof *iov_copy)) == NULL) {
+					PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+					return -1;
+				}
+				tmp_iov = iov_copy;
+			}
+
+			PR_ASSERT(tmp_iov == iov_copy);
+
+			/* fill in the first partial read */
+			iov_copy[0].iov_base = &(((char *)iov[index].iov_base)[tmp_out]);
+			iov_copy[0].iov_len = iov[index].iov_len - tmp_out;
+			index++;
+
+			/* copy the remaining vectors */
+			for (iov_cnt=1; index<iov_size; iov_cnt++, index++) {
+				iov_copy[iov_cnt].iov_base = iov[index].iov_base;
+				iov_copy[iov_cnt].iov_len = iov[index].iov_len;
+			}
+		}
+	}
+
+	if (iov_copy != local_iov)
+		PR_DELETE(iov_copy);
+	return count;
+}
+
+/************************************************************************/
+
+PR_IMPLEMENT(PRFileDesc *) PR_ImportTCPSocket(PROsfd osfd)
+{
+PRFileDesc *fd;
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+	fd = PR_AllocFileDesc(osfd, PR_GetTCPMethods());
+	if (fd != NULL) {
+		_PR_MD_MAKE_NONBLOCK(fd);
+		_PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
+	} else
+		_PR_MD_CLOSE_SOCKET(osfd);
+	return(fd);
+}
+
+PR_IMPLEMENT(PRFileDesc *) PR_ImportUDPSocket(PROsfd osfd)
+{
+PRFileDesc *fd;
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+	fd = PR_AllocFileDesc(osfd, PR_GetUDPMethods());
+	if (fd != NULL) {
+		_PR_MD_MAKE_NONBLOCK(fd);
+		_PR_MD_INIT_FD_INHERITABLE(fd, PR_TRUE);
+	} else
+		_PR_MD_CLOSE_SOCKET(osfd);
+	return(fd);
+}
+
+
+static const PRIOMethods* PR_GetSocketPollFdMethods(void);
+
+PR_IMPLEMENT(PRFileDesc*) PR_CreateSocketPollFd(PROsfd osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    fd = _PR_Getfd();
+
+    if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    else
+    {
+        fd->secret->md.osfd = osfd;
+        fd->secret->inheritable = _PR_TRI_FALSE;
+    	fd->secret->state = _PR_FILEDESC_OPEN;
+        fd->methods = PR_GetSocketPollFdMethods();
+    }
+
+    return fd;
+}  /* PR_CreateSocketPollFD */
+
+PR_IMPLEMENT(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd)
+{
+    if (NULL == fd)
+    {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+    fd->secret->state = _PR_FILEDESC_CLOSED;
+    _PR_Putfd(fd);
+    return PR_SUCCESS;
+}  /* PR_DestroySocketPollFd */
+
+static PRStatus PR_CALLBACK SocketConnect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	PRInt32 rv;    /* Return value of _PR_MD_CONNECT */
+    const PRNetAddr *addrp = addr;
+#if defined(_PR_INET6)
+	PRNetAddr addrCopy;
+#endif
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return PR_FAILURE;
+	}
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+	}
+#endif
+
+	rv = _PR_MD_CONNECT(fd, addrp, PR_NETADDR_SIZE(addr), timeout);
+	PR_LOG(_pr_io_lm, PR_LOG_MAX, ("connect -> %d", rv));
+	if (rv == 0)
+		return PR_SUCCESS;
+	else
+		return PR_FAILURE;
+}
+
+static PRStatus PR_CALLBACK SocketConnectContinue(
+    PRFileDesc *fd, PRInt16 out_flags)
+{
+    PROsfd osfd;
+    int err;
+
+    if (out_flags & PR_POLL_NVAL) {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0) {
+        PR_ASSERT(out_flags == 0);
+        PR_SetError(PR_IN_PROGRESS_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    osfd = fd->secret->md.osfd;
+
+#if defined(XP_UNIX)
+
+    err = _MD_unix_get_nonblocking_connect_error(osfd);
+    if (err != 0) {
+        _PR_MD_MAP_CONNECT_ERROR(err);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+
+#elif defined(WIN32) || defined(WIN16)
+
+#if defined(WIN32)
+    /*
+     * The sleep circumvents a bug in Win32 WinSock.
+     * See Microsoft Knowledge Base article ID: Q165989.
+     */
+    Sleep(0);
+#endif /* WIN32 */
+
+    if (out_flags & PR_POLL_EXCEPT) {
+        int len = sizeof(err);
+        if (getsockopt(osfd, (int)SOL_SOCKET, SO_ERROR, (char *) &err, &len)
+                == SOCKET_ERROR) {
+            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+            return PR_FAILURE;
+        }
+        if (err != 0) {
+            _PR_MD_MAP_CONNECT_ERROR(err);
+        } else {
+            PR_SetError(PR_UNKNOWN_ERROR, 0);
+        }
+        return PR_FAILURE;
+    }
+
+    PR_ASSERT(out_flags & PR_POLL_WRITE);
+    return PR_SUCCESS;
+
+#elif defined(XP_OS2)
+
+    err = _MD_os2_get_nonblocking_connect_error(osfd);
+    if (err != 0) {
+        _PR_MD_MAP_CONNECT_ERROR(err);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+
+#elif defined(XP_MAC)
+
+    err = _MD_mac_get_nonblocking_connect_error(fd);
+    if (err == -1)
+        return PR_FAILURE;
+	else     
+		return PR_SUCCESS;
+
+#elif defined(XP_BEOS)
+
+#ifdef BONE_VERSION  /* bug 122364 */
+    /* temporary workaround until getsockopt(SO_ERROR) works in BONE */
+    if (out_flags & PR_POLL_EXCEPT) {
+        PR_SetError(PR_CONNECT_REFUSED_ERROR, 0);
+        return PR_FAILURE;
+    }
+    PR_ASSERT(out_flags & PR_POLL_WRITE);
+    return PR_SUCCESS;
+#else
+    err = _MD_beos_get_nonblocking_connect_error(fd);
+    if( err != 0 ) {
+        _PR_MD_MAP_CONNECT_ERROR(err);
+        return PR_FAILURE;
+    }
+    else
+        return PR_SUCCESS;
+#endif /* BONE_VERSION */
+
+#else
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+#endif
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
+{
+    /* Find the NSPR layer and invoke its connectcontinue method */
+    PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+
+    if (NULL == bottom) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    return SocketConnectContinue(bottom, pd->out_flags);
+}
+
+static PRFileDesc* PR_CALLBACK SocketAccept(PRFileDesc *fd, PRNetAddr *addr,
+PRIntervalTime timeout)
+{
+	PROsfd osfd;
+	PRFileDesc *fd2;
+	PRUint32 al;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+#ifdef WINNT
+	PRNetAddr addrCopy;
+#endif
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return 0;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return 0;
+	}
+
+#ifdef WINNT
+	if (addr == NULL) {
+		addr = &addrCopy;
+	}
+#endif
+	al = sizeof(PRNetAddr);
+	osfd = _PR_MD_ACCEPT(fd, addr, &al, timeout);
+	if (osfd == -1)
+		return 0;
+
+	fd2 = PR_AllocFileDesc(osfd, PR_GetTCPMethods());
+	if (!fd2) {
+		_PR_MD_CLOSE_SOCKET(osfd);
+		return NULL;
+	}
+
+	fd2->secret->nonblocking = fd->secret->nonblocking;
+	fd2->secret->inheritable = fd->secret->inheritable;
+#ifdef WINNT
+	if (!fd2->secret->nonblocking && fd2->secret->inheritable != _PR_TRI_TRUE) {
+		/*
+		 * The new socket has been associated with an I/O
+		 * completion port.  There is no going back.
+		 */
+		fd2->secret->md.io_model_committed = PR_TRUE;
+	}
+	PR_ASSERT(al == PR_NETADDR_SIZE(addr));
+	fd2->secret->md.accepted_socket = PR_TRUE;
+	memcpy(&fd2->secret->md.peer_addr, addr, al);
+#endif
+
+	/*
+	 * On some platforms, the new socket created by accept()
+	 * inherits the nonblocking (or overlapped io) attribute
+	 * of the listening socket.  As an optimization, these
+	 * platforms can skip the following _PR_MD_MAKE_NONBLOCK
+	 * call.
+	 * 
+	 * On Mac, we MUST make this call, because _PR_MD_MAKE_NONBLOCK
+	 * (which maps to _MD_makenonblock, see macsockotpt.c)
+	 * installs the async notifier routine needed to make blocking
+	 * I/O work properly.
+	 */
+#if !defined(SOLARIS) && !defined(IRIX) && !defined(WINNT)
+	_PR_MD_MAKE_NONBLOCK(fd2);
+#endif
+
+#ifdef _PR_INET6
+	if (addr && (AF_INET6 == addr->raw.family))
+        addr->raw.family = PR_AF_INET6;
+#endif
+	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+	PR_ASSERT(IsValidNetAddrLen(addr, al) == PR_TRUE);
+
+	return fd2;
+}
+
+#ifdef WINNT
+PR_IMPLEMENT(PRFileDesc*) PR_NTFast_Accept(PRFileDesc *fd, PRNetAddr *addr,
+PRIntervalTime timeout)
+{
+	PROsfd osfd;
+	PRFileDesc *fd2;
+	PRIntn al;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+	PRNetAddr addrCopy;
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return 0;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return 0;
+	}
+
+		if (addr == NULL) {
+			addr = &addrCopy;
+		}
+		al = PR_NETADDR_SIZE(addr);
+		osfd = _PR_MD_FAST_ACCEPT(fd, addr, &al, timeout, PR_TRUE, NULL, NULL);
+		if (osfd == -1) {
+			return 0;
+		}
+
+	fd2 = PR_AllocFileDesc(osfd, PR_GetTCPMethods());
+	if (!fd2) {
+		_PR_MD_CLOSE_SOCKET(osfd);
+	} else {
+		fd2->secret->nonblocking = fd->secret->nonblocking;
+		fd2->secret->md.io_model_committed = PR_TRUE;
+	        PR_ASSERT(al == PR_NETADDR_SIZE(addr));
+        	fd2->secret->md.accepted_socket = PR_TRUE;
+        	memcpy(&fd2->secret->md.peer_addr, addr, al);
+#ifdef _PR_INET6
+		if (AF_INET6 == addr->raw.family)
+        	addr->raw.family = PR_AF_INET6;
+#endif
+	}
+	return fd2;
+}
+#endif /* WINNT */
+
+
+static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr)
+{
+	PRInt32 result;
+    const PRNetAddr *addrp = addr;
+#if defined(_PR_INET6)
+	PRNetAddr addrCopy;
+#endif
+
+	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+
+#ifdef XP_UNIX
+	if (addr->raw.family == AF_UNIX) {
+		/* Disallow relative pathnames */
+		if (addr->local.path[0] != '/') {
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+			return PR_FAILURE;
+		}
+	}
+#endif /* XP_UNIX */
+
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+	}
+#endif
+	result = _PR_MD_BIND(fd, addrp, PR_NETADDR_SIZE(addr));
+	if (result < 0) {
+		return PR_FAILURE;
+	}
+	return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK SocketListen(PRFileDesc *fd, PRIntn backlog)
+{
+	PRInt32 result;
+
+	result = _PR_MD_LISTEN(fd, backlog);
+	if (result < 0) {
+		return PR_FAILURE;
+	}
+	return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK SocketShutdown(PRFileDesc *fd, PRIntn how)
+{
+	PRInt32 result;
+
+	result = _PR_MD_SHUTDOWN(fd, how);
+	if (result < 0) {
+		return PR_FAILURE;
+	}
+	return PR_SUCCESS;
+}
+
+static PRInt32 PR_CALLBACK SocketRecv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+PRIntervalTime timeout)
+{
+	PRInt32 rv;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if ((flags != 0) && (flags != PR_MSG_PEEK)) {
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+	}
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return -1;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return -1;
+	}
+
+	PR_LOG(_pr_io_lm, PR_LOG_MAX,
+		("recv: fd=%p osfd=%" PR_PRIdOSFD " buf=%p amount=%d flags=%d",
+		fd, fd->secret->md.osfd, buf, amount, flags));
+
+#ifdef _PR_HAVE_PEEK_BUFFER
+	if (fd->secret->peekBytes != 0) {
+		rv = (amount < fd->secret->peekBytes) ?
+			amount : fd->secret->peekBytes;
+		memcpy(buf, fd->secret->peekBuffer, rv);
+		if (flags == 0) {
+			/* consume the bytes in the peek buffer */
+			fd->secret->peekBytes -= rv;
+			if (fd->secret->peekBytes != 0) {
+				memmove(fd->secret->peekBuffer,
+					fd->secret->peekBuffer + rv,
+					fd->secret->peekBytes);
+			}
+		}
+		return rv;
+	}
+
+	/* allocate peek buffer, if necessary */
+	if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) {
+		PR_ASSERT(0 == fd->secret->peekBytes);
+		/* impose a max size on the peek buffer */
+		if (amount > _PR_PEEK_BUFFER_MAX) {
+			amount = _PR_PEEK_BUFFER_MAX;
+		}
+		if (fd->secret->peekBufSize < amount) {
+			if (fd->secret->peekBuffer) {
+				PR_Free(fd->secret->peekBuffer);
+			}
+			fd->secret->peekBufSize = amount;
+			fd->secret->peekBuffer = PR_Malloc(amount);
+			if (NULL == fd->secret->peekBuffer) {
+				fd->secret->peekBufSize = 0;
+				PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+				return -1;
+			}
+		}
+	}
+#endif
+
+	rv = _PR_MD_RECV(fd, buf, amount, flags, timeout);
+	PR_LOG(_pr_io_lm, PR_LOG_MAX, ("recv -> %d, error = %d, os error = %d",
+		rv, PR_GetError(), PR_GetOSError()));
+
+#ifdef _PR_HAVE_PEEK_BUFFER
+	if ((PR_MSG_PEEK == flags) && _PR_FD_NEED_EMULATE_MSG_PEEK(fd)) {
+		if (rv > 0) {
+			memcpy(fd->secret->peekBuffer, buf, rv);
+			fd->secret->peekBytes = rv;
+		}
+	}
+#endif
+
+	return rv;
+}
+
+static PRInt32 PR_CALLBACK SocketRead(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+	return SocketRecv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
+}
+
+static PRInt32 PR_CALLBACK SocketSend(PRFileDesc *fd, const void *buf, PRInt32 amount,
+PRIntn flags, PRIntervalTime timeout)
+{
+	PRInt32 temp, count;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return -1;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return -1;
+	}
+
+	count = 0;
+	while (amount > 0) {
+		PR_LOG(_pr_io_lm, PR_LOG_MAX,
+		    ("send: fd=%p osfd=%" PR_PRIdOSFD " buf=%p amount=%d",
+		    fd, fd->secret->md.osfd, buf, amount));
+		temp = _PR_MD_SEND(fd, buf, amount, flags, timeout);
+		if (temp < 0) {
+					count = -1;
+					break;
+				}
+
+		count += temp;
+		if (fd->secret->nonblocking) {
+			break;
+		}
+		buf = (const void*) ((const char*)buf + temp);
+
+		amount -= temp;
+	}
+	PR_LOG(_pr_io_lm, PR_LOG_MAX, ("send -> %d", count));
+	return count;
+}
+
+static PRInt32 PR_CALLBACK SocketWrite(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+	return SocketSend(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
+}
+
+static PRStatus PR_CALLBACK SocketClose(PRFileDesc *fd)
+{
+	if (!fd || !fd->secret
+			|| (fd->secret->state != _PR_FILEDESC_OPEN
+			&& fd->secret->state != _PR_FILEDESC_CLOSED)) {
+		PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+		return PR_FAILURE;
+	}
+
+	if (fd->secret->state == _PR_FILEDESC_OPEN) {
+		if (_PR_MD_CLOSE_SOCKET(fd->secret->md.osfd) < 0) {
+			return PR_FAILURE;
+		}
+		fd->secret->state = _PR_FILEDESC_CLOSED;
+	}
+
+#ifdef _PR_HAVE_PEEK_BUFFER
+	if (fd->secret->peekBuffer) {
+		PR_ASSERT(fd->secret->peekBufSize > 0);
+		PR_DELETE(fd->secret->peekBuffer);
+		fd->secret->peekBufSize = 0;
+		fd->secret->peekBytes = 0;
+	}
+#endif
+
+	PR_FreeFileDesc(fd);
+	return PR_SUCCESS;
+}
+
+static PRInt32 PR_CALLBACK SocketAvailable(PRFileDesc *fd)
+{
+	PRInt32 rv;
+#ifdef _PR_HAVE_PEEK_BUFFER
+	if (fd->secret->peekBytes != 0) {
+		return fd->secret->peekBytes;
+	}
+#endif
+	rv =  _PR_MD_SOCKETAVAILABLE(fd);
+	return rv;		
+}
+
+static PRInt64 PR_CALLBACK SocketAvailable64(PRFileDesc *fd)
+{
+    PRInt64 rv;
+#ifdef _PR_HAVE_PEEK_BUFFER
+    if (fd->secret->peekBytes != 0) {
+        LL_I2L(rv, fd->secret->peekBytes);
+        return rv;
+    }
+#endif
+    LL_I2L(rv, _PR_MD_SOCKETAVAILABLE(fd));
+	return rv;		
+}
+
+static PRStatus PR_CALLBACK SocketSync(PRFileDesc *fd)
+{
+#if defined(XP_MAC)
+#pragma unused (fd)
+#endif
+
+	return PR_SUCCESS;
+}
+
+static PRInt32 PR_CALLBACK SocketSendTo(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	PRInt32 temp, count;
+    const PRNetAddr *addrp = addr;
+#if defined(_PR_INET6)
+	PRNetAddr addrCopy;
+#endif
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return -1;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return -1;
+	}
+
+	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+	}
+#endif
+
+	count = 0;
+	while (amount > 0) {
+		temp = _PR_MD_SENDTO(fd, buf, amount, flags,
+		    addrp, PR_NETADDR_SIZE(addr), timeout);
+		if (temp < 0) {
+					count = -1;
+					break;
+				}
+		count += temp;
+		if (fd->secret->nonblocking) {
+			break;
+		}
+		buf = (const void*) ((const char*)buf + temp);
+		amount -= temp;
+	}
+	return count;
+}
+
+static PRInt32 PR_CALLBACK SocketRecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
+PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
+{
+	PRInt32 rv;
+	PRUint32 al;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return -1;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return -1;
+	}
+
+	al = sizeof(PRNetAddr);
+	rv = _PR_MD_RECVFROM(fd, buf, amount, flags, addr, &al, timeout);
+#ifdef _PR_INET6
+	if (addr && (AF_INET6 == addr->raw.family))
+        addr->raw.family = PR_AF_INET6;
+#endif
+	return rv;
+}
+
+static PRInt32 PR_CALLBACK SocketAcceptRead(PRFileDesc *sd, PRFileDesc **nd, 
+PRNetAddr **raddr, void *buf, PRInt32 amount,
+PRIntervalTime timeout)
+{
+	PRInt32 rv;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return -1;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return -1;
+	}
+	/* The socket must be in blocking mode. */
+	if (sd->secret->nonblocking) {
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+	}
+	*nd = NULL;
+
+#if defined(WINNT)
+	{
+	PROsfd newSock;
+	PRNetAddr *raddrCopy;
+
+	if (raddr == NULL) {
+		raddr = &raddrCopy;
+	}
+	rv = _PR_MD_ACCEPT_READ(sd, &newSock, raddr, buf, amount, timeout);
+	if (rv < 0) {
+		rv = -1;
+	} else {
+		/* Successfully accepted and read; create the new PRFileDesc */
+		*nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods());
+		if (*nd == 0) {
+			_PR_MD_CLOSE_SOCKET(newSock);
+			/* PR_AllocFileDesc() has invoked PR_SetError(). */
+			rv = -1;
+		} else {
+			(*nd)->secret->md.io_model_committed = PR_TRUE;
+			(*nd)->secret->md.accepted_socket = PR_TRUE;
+			memcpy(&(*nd)->secret->md.peer_addr, *raddr,
+				PR_NETADDR_SIZE(*raddr));
+#ifdef _PR_INET6
+			if (AF_INET6 == *raddr->raw.family)
+        		*raddr->raw.family = PR_AF_INET6;
+#endif
+		}
+	}
+	}
+#else
+	rv = PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout);
+#endif
+	return rv;
+}
+
+#ifdef WINNT
+PR_IMPLEMENT(PRInt32) PR_NTFast_AcceptRead(PRFileDesc *sd, PRFileDesc **nd, 
+PRNetAddr **raddr, void *buf, PRInt32 amount,
+PRIntervalTime timeout)
+{
+	PRInt32 rv;
+	PROsfd newSock;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+	PRNetAddr *raddrCopy;
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return -1;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return -1;
+	}
+	*nd = NULL;
+
+	if (raddr == NULL) {
+		raddr = &raddrCopy;
+	}
+	rv = _PR_MD_FAST_ACCEPT_READ(sd, &newSock, raddr, buf, amount, 
+	    timeout, PR_TRUE, NULL, NULL);
+	if (rv < 0) {
+		rv = -1;
+	} else {
+		/* Successfully accepted and read; create the new PRFileDesc */
+		*nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods());
+		if (*nd == 0) {
+			_PR_MD_CLOSE_SOCKET(newSock);
+			/* PR_AllocFileDesc() has invoked PR_SetError(). */
+			rv = -1;
+		} else {
+			(*nd)->secret->md.io_model_committed = PR_TRUE;
+			(*nd)->secret->md.accepted_socket = PR_TRUE;
+			memcpy(&(*nd)->secret->md.peer_addr, *raddr,
+				PR_NETADDR_SIZE(*raddr));
+#ifdef _PR_INET6
+			if (AF_INET6 == *raddr->raw.family)
+        		*raddr->raw.family = PR_AF_INET6;
+#endif
+		}
+	}
+	return rv;
+}
+
+PR_IMPLEMENT(PRInt32) PR_NTFast_AcceptRead_WithTimeoutCallback(
+PRFileDesc *sd, PRFileDesc **nd, 
+PRNetAddr **raddr, void *buf, PRInt32 amount,
+PRIntervalTime timeout,
+_PR_AcceptTimeoutCallback callback,
+void *callbackArg)
+{
+	PRInt32 rv;
+	PROsfd newSock;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+	PRNetAddr *raddrCopy;
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return -1;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return -1;
+	}
+	*nd = NULL;
+
+	if (raddr == NULL) {
+		raddr = &raddrCopy;
+	}
+	rv = _PR_MD_FAST_ACCEPT_READ(sd, &newSock, raddr, buf, amount,
+	    timeout, PR_TRUE, callback, callbackArg);
+	if (rv < 0) {
+		rv = -1;
+	} else {
+		/* Successfully accepted and read; create the new PRFileDesc */
+		*nd = PR_AllocFileDesc(newSock, PR_GetTCPMethods());
+		if (*nd == 0) {
+			_PR_MD_CLOSE_SOCKET(newSock);
+			/* PR_AllocFileDesc() has invoked PR_SetError(). */
+			rv = -1;
+		} else {
+			(*nd)->secret->md.io_model_committed = PR_TRUE;
+			(*nd)->secret->md.accepted_socket = PR_TRUE;
+			memcpy(&(*nd)->secret->md.peer_addr, *raddr,
+				PR_NETADDR_SIZE(*raddr));
+#ifdef _PR_INET6
+			if (AF_INET6 == *raddr->raw.family)
+        		*raddr->raw.family = PR_AF_INET6;
+#endif
+		}
+	}
+	return rv;
+}
+#endif /* WINNT */
+
+#ifdef WINNT
+PR_IMPLEMENT(void)
+PR_NTFast_UpdateAcceptContext(PRFileDesc *socket, PRFileDesc *acceptSocket)
+{
+	_PR_MD_UPDATE_ACCEPT_CONTEXT(
+		socket->secret->md.osfd, acceptSocket->secret->md.osfd);
+}
+#endif /* WINNT */
+
+static PRInt32 PR_CALLBACK SocketSendFile(
+    PRFileDesc *sd, PRSendFileData *sfd,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+	PRInt32 rv;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return -1;
+	}
+	if (_PR_IO_PENDING(me)) {
+		PR_SetError(PR_IO_PENDING_ERROR, 0);
+		return -1;
+	}
+	/* The socket must be in blocking mode. */
+	if (sd->secret->nonblocking) {
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+	}
+#if defined(WINNT)
+	rv = _PR_MD_SENDFILE(sd, sfd, flags, timeout);
+	if ((rv >= 0) && (flags == PR_TRANSMITFILE_CLOSE_SOCKET)) {
+		/*
+		 * This should be kept the same as SocketClose, except
+		 * that _PR_MD_CLOSE_SOCKET(sd->secret->md.osfd) should
+		 * not be called because the socket will be recycled.
+		 */
+		PR_FreeFileDesc(sd);
+	}
+#else
+	rv = PR_EmulateSendFile(sd, sfd, flags, timeout);
+#endif	/* WINNT */
+
+	return rv;
+}
+
+static PRInt32 PR_CALLBACK SocketTransmitFile(PRFileDesc *sd, PRFileDesc *fd, 
+const void *headers, PRInt32 hlen, PRTransmitFileFlags flags,
+PRIntervalTime timeout)
+{
+	PRSendFileData sfd;
+
+	sfd.fd = fd;
+	sfd.file_offset = 0;
+	sfd.file_nbytes = 0;
+	sfd.header = headers;
+	sfd.hlen = hlen;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+
+	return(SocketSendFile(sd, &sfd, flags, timeout));
+}
+
+static PRStatus PR_CALLBACK SocketGetName(PRFileDesc *fd, PRNetAddr *addr)
+{
+	PRInt32 result;
+	PRUint32 addrlen;
+
+	addrlen = sizeof(PRNetAddr);
+	result = _PR_MD_GETSOCKNAME(fd, addr, &addrlen);
+	if (result < 0) {
+		return PR_FAILURE;
+	}
+#ifdef _PR_INET6
+	if (AF_INET6 == addr->raw.family)
+        addr->raw.family = PR_AF_INET6;
+#endif
+	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+	PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
+	return PR_SUCCESS;
+}
+
+static PRStatus PR_CALLBACK SocketGetPeerName(PRFileDesc *fd, PRNetAddr *addr)
+{
+	PRInt32 result;
+	PRUint32 addrlen;
+
+	addrlen = sizeof(PRNetAddr);
+	result = _PR_MD_GETPEERNAME(fd, addr, &addrlen);
+	if (result < 0) {
+		return PR_FAILURE;
+	}
+#ifdef _PR_INET6
+	if (AF_INET6 == addr->raw.family)
+        addr->raw.family = PR_AF_INET6;
+#endif
+	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+	PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
+	return PR_SUCCESS;
+}
+
+static PRInt16 PR_CALLBACK SocketPoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+#ifdef XP_MAC
+#pragma unused( fd, in_flags )
+#endif
+    *out_flags = 0;
+    return in_flags;
+}  /* SocketPoll */
+
+static PRIOMethods tcpMethods = {
+	PR_DESC_SOCKET_TCP,
+	SocketClose,
+	SocketRead,
+	SocketWrite,
+	SocketAvailable,
+	SocketAvailable64,
+	SocketSync,
+	(PRSeekFN)_PR_InvalidInt,
+	(PRSeek64FN)_PR_InvalidInt64,
+	(PRFileInfoFN)_PR_InvalidStatus,
+	(PRFileInfo64FN)_PR_InvalidStatus,
+	SocketWritev,
+	SocketConnect,
+	SocketAccept,
+	SocketBind,
+	SocketListen,
+	SocketShutdown,
+	SocketRecv,
+	SocketSend,
+	(PRRecvfromFN)_PR_InvalidInt,
+	(PRSendtoFN)_PR_InvalidInt,
+	SocketPoll,
+	SocketAcceptRead,
+	SocketTransmitFile,
+	SocketGetName,
+	SocketGetPeerName,
+	(PRReservedFN)_PR_InvalidInt,
+	(PRReservedFN)_PR_InvalidInt,
+	_PR_SocketGetSocketOption,
+	_PR_SocketSetSocketOption,
+    SocketSendFile, 
+    SocketConnectContinue,
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRIOMethods udpMethods = {
+	PR_DESC_SOCKET_UDP,
+	SocketClose,
+	SocketRead,
+	SocketWrite,
+	SocketAvailable,
+	SocketAvailable64,
+	SocketSync,
+	(PRSeekFN)_PR_InvalidInt,
+	(PRSeek64FN)_PR_InvalidInt64,
+	(PRFileInfoFN)_PR_InvalidStatus,
+	(PRFileInfo64FN)_PR_InvalidStatus,
+	SocketWritev,
+	SocketConnect,
+	(PRAcceptFN)_PR_InvalidDesc,
+	SocketBind,
+	SocketListen,
+	SocketShutdown,
+	SocketRecv,
+	SocketSend,
+	SocketRecvFrom,
+	SocketSendTo,
+	SocketPoll,
+	(PRAcceptreadFN)_PR_InvalidInt,
+	(PRTransmitfileFN)_PR_InvalidInt,
+	SocketGetName,
+	SocketGetPeerName,
+	(PRReservedFN)_PR_InvalidInt,
+	(PRReservedFN)_PR_InvalidInt,
+	_PR_SocketGetSocketOption,
+	_PR_SocketSetSocketOption,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+
+static PRIOMethods socketpollfdMethods = {
+    (PRDescType) 0,
+    (PRCloseFN)_PR_InvalidStatus,
+    (PRReadFN)_PR_InvalidInt,
+    (PRWriteFN)_PR_InvalidInt,
+    (PRAvailableFN)_PR_InvalidInt,
+    (PRAvailable64FN)_PR_InvalidInt64,
+    (PRFsyncFN)_PR_InvalidStatus,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+	SocketPoll,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods()
+{
+	return &tcpMethods;
+}
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods()
+{
+	return &udpMethods;
+}
+
+static const PRIOMethods* PR_GetSocketPollFdMethods()
+{
+    return &socketpollfdMethods;
+}  /* PR_GetSocketPollFdMethods */
+
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+PR_EXTERN(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd);
+
+#if defined(_PR_INET6_PROBE)
+
+PR_EXTERN(PRBool) _pr_ipv6_is_present;
+
+PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket()
+{
+	PROsfd osfd;
+
+	osfd = _PR_MD_SOCKET(AF_INET6, SOCK_STREAM, 0);
+	if (osfd != -1) {
+		_PR_MD_CLOSE_SOCKET(osfd);
+		return PR_TRUE;
+	}
+	return PR_FALSE;
+}
+#endif	/* _PR_INET6_PROBE */
+
+#endif
+
+PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
+{
+	PROsfd osfd;
+	PRFileDesc *fd;
+	PRInt32 tmp_domain = domain;
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+	if (PR_AF_INET != domain
+			&& PR_AF_INET6 != domain
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+			&& PR_AF_LOCAL != domain
+#endif
+			) {
+		PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return NULL;
+	}
+
+#if defined(_PR_INET6_PROBE)
+	if (PR_AF_INET6 == domain) {
+		if (_pr_ipv6_is_present == PR_FALSE) 
+			domain = AF_INET;
+		else
+			domain = AF_INET6;
+	}
+#elif defined(_PR_INET6)
+	if (PR_AF_INET6 == domain)
+		domain = AF_INET6;
+#else
+	if (PR_AF_INET6 == domain)
+		domain = AF_INET;
+#endif	/* _PR_INET6 */
+	osfd = _PR_MD_SOCKET(domain, type, proto);
+	if (osfd == -1) {
+		return 0;
+	}
+	if (type == SOCK_STREAM)
+		fd = PR_AllocFileDesc(osfd, PR_GetTCPMethods());
+	else
+		fd = PR_AllocFileDesc(osfd, PR_GetUDPMethods());
+	/*
+	 * Make the sockets non-blocking
+	 */
+	if (fd != NULL) {
+		_PR_MD_MAKE_NONBLOCK(fd);
+		_PR_MD_INIT_FD_INHERITABLE(fd, PR_FALSE);
+#if defined(_PR_INET6_PROBE) || !defined(_PR_INET6)
+		/*
+		 * For platforms with no support for IPv6 
+		 * create layered socket for IPv4-mapped IPv6 addresses
+		 */
+		if (PR_AF_INET6 == tmp_domain && PR_AF_INET == domain) {
+			if (PR_FAILURE == _pr_push_ipv6toipv4_layer(fd)) {
+				PR_Close(fd);
+				fd = NULL;
+			}
+		}
+#endif
+	} else
+		_PR_MD_CLOSE_SOCKET(osfd);
+
+	return fd;
+}
+
+PR_IMPLEMENT(PRFileDesc *) PR_NewTCPSocket(void)
+{
+	PRInt32 domain = AF_INET;
+
+	return PR_Socket(domain, SOCK_STREAM, 0);
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void)
+{
+	PRInt32 domain = AF_INET;
+
+	return PR_Socket(domain, SOCK_DGRAM, 0);
+}
+
+PR_IMPLEMENT(PRFileDesc *) PR_OpenTCPSocket(PRIntn af)
+{
+	return PR_Socket(af, SOCK_STREAM, 0);
+}
+
+PR_IMPLEMENT(PRFileDesc*) PR_OpenUDPSocket(PRIntn af)
+{
+	return PR_Socket(af, SOCK_DGRAM, 0);
+}
+
+PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *f[])
+{
+#ifdef XP_UNIX
+	PRInt32 rv, osfd[2];
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	rv = _PR_MD_SOCKETPAIR(AF_UNIX, SOCK_STREAM, 0, osfd);
+	if (rv == -1) {
+		return PR_FAILURE;
+	}
+
+	f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods());
+	if (!f[0]) {
+		_PR_MD_CLOSE_SOCKET(osfd[0]);
+		_PR_MD_CLOSE_SOCKET(osfd[1]);
+		/* PR_AllocFileDesc() has invoked PR_SetError(). */
+		return PR_FAILURE;
+	}
+	f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods());
+	if (!f[1]) {
+		PR_Close(f[0]);
+		_PR_MD_CLOSE_SOCKET(osfd[1]);
+		/* PR_AllocFileDesc() has invoked PR_SetError(). */
+		return PR_FAILURE;
+	}
+	_PR_MD_MAKE_NONBLOCK(f[0]);
+	_PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE);
+	_PR_MD_MAKE_NONBLOCK(f[1]);
+	_PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE);
+	return PR_SUCCESS;
+#elif defined(WINNT)
+    /*
+     * A socket pair is often used for interprocess communication,
+     * so we need to make sure neither socket is associated with
+     * the I/O completion port; otherwise it can't be used by a
+     * child process.
+     *
+     * The default implementation below cannot be used for NT
+     * because PR_Accept would have associated the I/O completion
+     * port with the listening and accepted sockets.
+     */
+    SOCKET listenSock;
+    SOCKET osfd[2];
+    struct sockaddr_in selfAddr, peerAddr;
+    int addrLen;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    osfd[0] = osfd[1] = INVALID_SOCKET;
+    listenSock = socket(AF_INET, SOCK_STREAM, 0);
+    if (listenSock == INVALID_SOCKET) {
+        goto failed;
+    }
+    selfAddr.sin_family = AF_INET;
+    selfAddr.sin_port = 0;
+    selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* BugZilla: 35408 */
+    addrLen = sizeof(selfAddr);
+    if (bind(listenSock, (struct sockaddr *) &selfAddr,
+            addrLen) == SOCKET_ERROR) {
+        goto failed;
+    }
+    if (getsockname(listenSock, (struct sockaddr *) &selfAddr,
+            &addrLen) == SOCKET_ERROR) {
+        goto failed;
+    }
+    if (listen(listenSock, 5) == SOCKET_ERROR) {
+        goto failed;
+    }
+    osfd[0] = socket(AF_INET, SOCK_STREAM, 0);
+    if (osfd[0] == INVALID_SOCKET) {
+        goto failed;
+    }
+    selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+    /*
+     * Only a thread is used to do the connect and accept.
+     * I am relying on the fact that connect returns
+     * successfully as soon as the connect request is put
+     * into the listen queue (but before accept is called).
+     * This is the behavior of the BSD socket code.  If
+     * connect does not return until accept is called, we
+     * will need to create another thread to call connect.
+     */
+    if (connect(osfd[0], (struct sockaddr *) &selfAddr,
+            addrLen) == SOCKET_ERROR) {
+        goto failed;
+    }
+    /*
+     * A malicious local process may connect to the listening
+     * socket, so we need to verify that the accepted connection
+     * is made from our own socket osfd[0].
+     */
+    if (getsockname(osfd[0], (struct sockaddr *) &selfAddr,
+            &addrLen) == SOCKET_ERROR) {
+        goto failed;
+    }
+    osfd[1] = accept(listenSock, (struct sockaddr *) &peerAddr, &addrLen);
+    if (osfd[1] == INVALID_SOCKET) {
+        goto failed;
+    }
+    if (peerAddr.sin_port != selfAddr.sin_port) {
+        /* the connection we accepted is not from osfd[0] */
+        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+        goto failed;
+    }
+    closesocket(listenSock);
+
+    f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods());
+    if (!f[0]) {
+        closesocket(osfd[0]);
+        closesocket(osfd[1]);
+        /* PR_AllocFileDesc() has invoked PR_SetError(). */
+        return PR_FAILURE;
+    }
+    f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods());
+    if (!f[1]) {
+        PR_Close(f[0]);
+        closesocket(osfd[1]);
+        /* PR_AllocFileDesc() has invoked PR_SetError(). */
+        return PR_FAILURE;
+    }
+    _PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE);
+    _PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE);
+    return PR_SUCCESS;
+
+failed:
+    if (listenSock != INVALID_SOCKET) {
+        closesocket(listenSock);
+    }
+    if (osfd[0] != INVALID_SOCKET) {
+        closesocket(osfd[0]);
+    }
+    if (osfd[1] != INVALID_SOCKET) {
+        closesocket(osfd[1]);
+    }
+    return PR_FAILURE;
+#else /* not Unix or NT */
+    /*
+     * default implementation
+     */
+    PRFileDesc *listenSock;
+    PRNetAddr selfAddr, peerAddr;
+    PRUint16 port;
+
+    f[0] = f[1] = NULL;
+    listenSock = PR_NewTCPSocket();
+    if (listenSock == NULL) {
+        goto failed;
+    }
+    PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */
+    if (PR_Bind(listenSock, &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+    if (PR_GetSockName(listenSock, &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+    port = ntohs(selfAddr.inet.port);
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+        goto failed;
+    }
+    f[0] = PR_NewTCPSocket();
+    if (f[0] == NULL) {
+        goto failed;
+    }
+#ifdef _PR_CONNECT_DOES_NOT_BIND
+    /*
+     * If connect does not implicitly bind the socket (e.g., on
+     * BeOS), we have to bind the socket so that we can get its
+     * port with getsockname later.
+     */
+    PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr);
+    if (PR_Bind(f[0], &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+#endif
+    PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr);
+
+    /*
+     * Only a thread is used to do the connect and accept.
+     * I am relying on the fact that PR_Connect returns
+     * successfully as soon as the connect request is put
+     * into the listen queue (but before PR_Accept is called).
+     * This is the behavior of the BSD socket code.  If
+     * connect does not return until accept is called, we
+     * will need to create another thread to call connect.
+     */
+    if (PR_Connect(f[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT)
+            == PR_FAILURE) {
+        goto failed;
+    }
+    /*
+     * A malicious local process may connect to the listening
+     * socket, so we need to verify that the accepted connection
+     * is made from our own socket f[0].
+     */
+    if (PR_GetSockName(f[0], &selfAddr) == PR_FAILURE) {
+        goto failed;
+    }
+    f[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT);
+    if (f[1] == NULL) {
+        goto failed;
+    }
+    if (peerAddr.inet.port != selfAddr.inet.port) {
+        /* the connection we accepted is not from f[0] */
+        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+        goto failed;
+    }
+    PR_Close(listenSock);
+    return PR_SUCCESS;
+
+failed:
+    if (listenSock) {
+        PR_Close(listenSock);
+    }
+    if (f[0]) {
+        PR_Close(f[0]);
+    }
+    if (f[1]) {
+        PR_Close(f[1]);
+    }
+    return PR_FAILURE;
+#endif
+}
+
+PR_IMPLEMENT(PROsfd)
+PR_FileDesc2NativeHandle(PRFileDesc *fd)
+{
+    if (fd) {
+        fd = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER);
+    }
+    if (!fd) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+    return fd->secret->md.osfd;
+}
+
+PR_IMPLEMENT(void)
+PR_ChangeFileDescNativeHandle(PRFileDesc *fd, PROsfd handle)
+{
+	if (fd)
+		fd->secret->md.osfd = handle;
+}
+
+/*
+** Select compatibility
+**
+*/
+
+PR_IMPLEMENT(void) PR_FD_ZERO(PR_fd_set *set)
+{
+	memset(set, 0, sizeof(PR_fd_set));
+}
+
+PR_IMPLEMENT(void) PR_FD_SET(PRFileDesc *fh, PR_fd_set *set)
+{
+	PR_ASSERT( set->hsize < PR_MAX_SELECT_DESC );
+
+	set->harray[set->hsize++] = fh;
+}
+
+PR_IMPLEMENT(void) PR_FD_CLR(PRFileDesc *fh, PR_fd_set *set)
+{
+	PRUint32 index, index2;
+
+	for (index = 0; index<set->hsize; index++)
+		if (set->harray[index] == fh) {
+			for (index2=index; index2 < (set->hsize-1); index2++) {
+				set->harray[index2] = set->harray[index2+1];
+			}
+			set->hsize--;
+			break;
+		}
+}
+
+PR_IMPLEMENT(PRInt32) PR_FD_ISSET(PRFileDesc *fh, PR_fd_set *set)
+{
+	PRUint32 index;
+	for (index = 0; index<set->hsize; index++)
+		if (set->harray[index] == fh) {
+			return 1;
+		}
+	return 0;
+}
+
+PR_IMPLEMENT(void) PR_FD_NSET(PROsfd fd, PR_fd_set *set)
+{
+	PR_ASSERT( set->nsize < PR_MAX_SELECT_DESC );
+
+	set->narray[set->nsize++] = fd;
+}
+
+PR_IMPLEMENT(void) PR_FD_NCLR(PROsfd fd, PR_fd_set *set)
+{
+	PRUint32 index, index2;
+
+	for (index = 0; index<set->nsize; index++)
+		if (set->narray[index] == fd) {
+			for (index2=index; index2 < (set->nsize-1); index2++) {
+				set->narray[index2] = set->narray[index2+1];
+			}
+			set->nsize--;
+			break;
+		}
+}
+
+PR_IMPLEMENT(PRInt32) PR_FD_NISSET(PROsfd fd, PR_fd_set *set)
+{
+	PRUint32 index;
+	for (index = 0; index<set->nsize; index++)
+		if (set->narray[index] == fd) {
+			return 1;
+		}
+	return 0;
+}
+
+
+#if !defined(NEED_SELECT)
+#if !defined(XP_MAC)
+#include "obsolete/probslet.h"
+#else
+#include "probslet.h"
+#endif
+
+#define PD_INCR 20
+
+static PRPollDesc *_pr_setfd(
+    PR_fd_set *set, PRInt16 flags, PRPollDesc *polldesc)
+{
+    PRUintn fsidx, pdidx;
+    PRPollDesc *poll = polldesc;
+
+    if (NULL == set) return poll;
+
+	/* First set the pr file handle osfds */
+	for (fsidx = 0; fsidx < set->hsize; fsidx++)
+	{
+	    for (pdidx = 0; 1; pdidx++)
+        {
+            if ((PRFileDesc*)-1 == poll[pdidx].fd)
+            {
+                /* our vector is full - extend and condition it */
+                poll = (PRPollDesc*)PR_Realloc(
+                    poll, (pdidx + 1 + PD_INCR) * sizeof(PRPollDesc));
+                if (NULL == poll) goto out_of_memory;
+                memset(
+                    poll + pdidx * sizeof(PRPollDesc),
+                    0, PD_INCR * sizeof(PRPollDesc));
+                poll[pdidx + PD_INCR].fd = (PRFileDesc*)-1;
+            }
+            if ((NULL == poll[pdidx].fd)
+            || (poll[pdidx].fd == set->harray[fsidx]))
+            {
+                /* PR_ASSERT(0 == (poll[pdidx].in_flags & flags)); */
+                /* either empty or prevously defined */
+                poll[pdidx].fd = set->harray[fsidx];  /* possibly redundant */
+                poll[pdidx].in_flags |= flags;  /* possibly redundant */
+                break;
+            }
+        }
+	}
+
+#if 0
+	/* Second set the native osfds */
+	for (fsidx = 0; fsidx < set->nsize; fsidx++)
+	{
+	    for (pdidx = 0; ((PRFileDesc*)-1 != poll[pdidx].fd); pdidx++)
+        {
+            if ((PRFileDesc*)-1 == poll[pdidx].fd)
+            {
+                /* our vector is full - extend and condition it */
+                poll = PR_Realloc(
+                    poll, (pdidx + PD_INCR) * sizeof(PRPollDesc));
+                if (NULL == poll) goto out_of_memory;
+                memset(
+                    poll + pdidx * sizeof(PRPollDesc),
+                    0, PD_INCR * sizeof(PRPollDesc));
+                poll[(pdidx + PD_INCR)].fd = (PRFileDesc*)-1;
+            }
+            if ((NULL == poll[pdidx].fd)
+            || (poll[pdidx].fd == set->narray[fsidx]))
+            {
+                /* either empty or prevously defined */
+                poll[pdidx].fd = set->narray[fsidx];
+                PR_ASSERT(0 == (poll[pdidx].in_flags & flags));
+                poll[pdidx].in_flags |= flags;
+                break;
+            }
+        }
+	}
+#endif /* 0 */
+
+	return poll;
+
+out_of_memory:
+    if (NULL != polldesc) PR_DELETE(polldesc);
+    return NULL;
+}  /* _pr_setfd */
+
+#endif /* !defined(NEED_SELECT) */
+
+PR_IMPLEMENT(PRInt32) PR_Select(
+    PRInt32 unused, PR_fd_set *pr_rd, PR_fd_set *pr_wr, 
+    PR_fd_set *pr_ex, PRIntervalTime timeout)
+{
+
+#if !defined(NEED_SELECT)
+    PRInt32 npds = 0; 
+    /*
+    ** Find out how many fds are represented in the three lists.
+    ** Then allocate a polling descriptor for the logical union
+    ** (there can't be any overlapping) and call PR_Poll().
+    */
+
+    PRPollDesc *copy, *poll;
+
+    static PRBool warning = PR_TRUE;
+    if (warning) warning = _PR_Obsolete( "PR_Select()", "PR_Poll()");
+
+    /* try to get an initial guesss at how much space we need */
+    npds = 0;
+    if ((NULL != pr_rd) && ((pr_rd->hsize + pr_rd->nsize - npds) > 0))
+        npds = pr_rd->hsize + pr_rd->nsize;
+    if ((NULL != pr_wr) && ((pr_wr->hsize + pr_wr->nsize - npds) > 0))
+        npds = pr_wr->hsize + pr_wr->nsize;
+    if ((NULL != pr_ex) && ((pr_ex->hsize + pr_ex->nsize - npds) > 0))
+        npds = pr_ex->hsize + pr_ex->nsize;
+
+    if (0 == npds)
+    {
+        PR_Sleep(timeout);
+        return 0;
+    }
+
+    copy = poll = (PRPollDesc*)PR_Calloc(npds + PD_INCR, sizeof(PRPollDesc));
+    if (NULL == poll) goto out_of_memory;
+    poll[npds + PD_INCR - 1].fd = (PRFileDesc*)-1;
+
+    poll = _pr_setfd(pr_rd, PR_POLL_READ, poll);
+    if (NULL == poll) goto out_of_memory;
+    poll = _pr_setfd(pr_wr, PR_POLL_WRITE, poll);
+    if (NULL == poll) goto out_of_memory;
+    poll = _pr_setfd(pr_ex, PR_POLL_EXCEPT, poll);
+    if (NULL == poll) goto out_of_memory;
+    unused = 0;
+    while (NULL != poll[unused].fd && (PRFileDesc*)-1 != poll[unused].fd)
+    {
+        ++unused;
+    }
+
+    PR_ASSERT(unused > 0);
+    npds = PR_Poll(poll, unused, timeout);
+
+    if (npds > 0)
+    {
+        /* Copy the results back into the fd sets */
+        if (NULL != pr_rd) pr_rd->nsize = pr_rd->hsize = 0;
+        if (NULL != pr_wr) pr_wr->nsize = pr_wr->hsize = 0;
+        if (NULL != pr_ex) pr_ex->nsize = pr_ex->hsize = 0;
+        for (copy = &poll[unused - 1]; copy >= poll; --copy)
+        {
+            if (copy->out_flags & PR_POLL_NVAL)
+            {
+                PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+                npds = -1;
+                break;
+            }
+            if (copy->out_flags & PR_POLL_READ)
+                if (NULL != pr_rd) pr_rd->harray[pr_rd->hsize++] = copy->fd;
+            if (copy->out_flags & PR_POLL_WRITE)
+                if (NULL != pr_wr) pr_wr->harray[pr_wr->hsize++] = copy->fd;
+            if (copy->out_flags & PR_POLL_EXCEPT)
+                if (NULL != pr_ex) pr_ex->harray[pr_ex->hsize++] = copy->fd;
+        }
+    }
+    PR_DELETE(poll);
+
+    return npds;
+out_of_memory:
+    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    return -1;    
+
+#endif /* !defined(NEED_SELECT) */
+    
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/io/prstdio.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/io/prstdio.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+#include "primpl.h"
+
+#include <string.h>
+
+/*
+** fprintf to a PRFileDesc
+*/
+PR_IMPLEMENT(PRUint32) PR_fprintf(PRFileDesc* fd, const char *fmt, ...)
+{
+    va_list ap;
+    PRUint32 rv;
+
+    va_start(ap, fmt);
+    rv = PR_vfprintf(fd, fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+PR_IMPLEMENT(PRUint32) PR_vfprintf(PRFileDesc* fd, const char *fmt, va_list ap)
+{
+    /* XXX this could be better */
+    PRUint32 rv, len;
+    char* msg = PR_vsmprintf(fmt, ap);
+    len = strlen(msg);
+#ifdef XP_OS2
+    /*
+     * OS/2 really needs a \r for every \n.
+     * In the future we should try to use scatter-gather instead of a
+     * succession of PR_Write.
+     */
+    if (isatty(PR_FileDesc2NativeHandle(fd))) {
+        PRUint32 last = 0, idx;
+        PRInt32 tmp;
+        rv = 0;
+        for (idx = 0; idx < len+1; idx++) {
+            if ((idx - last > 0) && (('\n' == msg[idx]) || (idx == len))) {
+                tmp = PR_Write(fd, msg + last, idx - last);
+                if (tmp >= 0) {
+                    rv += tmp;
+                }
+                last = idx;
+            }
+            /*
+             * if current character is \n, and
+             * previous character isn't \r, and
+             * next character isn't \r
+             */
+            if (('\n' == msg[idx]) &&
+                ((0 == idx) || ('\r' != msg[idx-1])) &&
+                ('\r' != msg[idx+1])) {
+                /* add extra \r */
+                tmp = PR_Write(fd, "\r", 1);
+                if (tmp >= 0) {
+                    rv += tmp;
+                }
+            }
+        }
+    } else {
+        rv = PR_Write(fd, msg, len);
+    }
+#else
+    rv = PR_Write(fd, msg, len);
+#endif
+    PR_DELETE(msg);
+    return rv;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/linking/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/linking/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/linking/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/linking/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4 @@
+/.cvsignore/1.2/Sat May 12 04:20:22 2001//
+/Makefile.in/1.18/Sat Jan  7 00:51:38 2006//
+/prlink.c/3.85/Sat Jan  7 01:03:12 2006//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/linking/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/linking/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/linking

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/linking/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/linking/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/linking/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/linking/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,75 @@
+# 
+# ***** 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 =
+endif
+endif
+
+CSRCS =           \
+	prlink.c   \
+	$(NULL)
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+# On Mac OS X use flat #includes.
+ifeq ($(OS_TARGET),MacOSX)
+INCLUDES    += -I$(MACOS_SDK_DIR)/Developer/Headers/FlatCarbon
+endif
+
+DEFINES += -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/linking/prlink.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/linking/prlink.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1742 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 
+ * 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): Steve Streeter (Hewlett-Packard Company)
+ * 
+ * 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.
+ */
+
+#include "primpl.h"
+
+#include <string.h>
+
+#ifdef XP_BEOS
+#include <image.h>
+#endif
+
+#ifdef XP_MACOSX
+#include <CodeFragments.h>
+#include <TextUtils.h>
+#include <Types.h>
+#include <Aliases.h>
+#include <CFURL.h>
+#include <CFBundle.h>
+#include <CFString.h>
+#include <CFDictionary.h>
+#include <CFData.h>
+#endif
+
+#ifdef XP_UNIX
+#ifdef USE_DLFCN
+#include <dlfcn.h>
+/* Define these on systems that don't have them. */
+#ifndef RTLD_NOW
+#define RTLD_NOW 0
+#endif
+#ifndef RTLD_LAZY
+#define RTLD_LAZY RTLD_NOW
+#endif
+#ifndef RTLD_GLOBAL
+#define RTLD_GLOBAL 0
+#endif
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 0
+#endif
+#ifdef AIX
+#include <sys/ldr.h>
+#endif
+#ifdef OSF1
+#include <loader.h>
+#include <rld_interface.h>
+#endif
+#elif defined(USE_HPSHL)
+#include <dl.h>
+#elif defined(USE_MACH_DYLD)
+#include <mach-o/dyld.h>
+#endif
+#endif /* XP_UNIX */
+
+#define _PR_DEFAULT_LD_FLAGS PR_LD_LAZY
+
+#ifdef VMS
+/* These are all require for the PR_GetLibraryFilePathname implementation */
+#include <descrip.h>
+#include <dvidef.h>
+#include <fibdef.h>
+#include <iodef.h>
+#include <lib$routines.h>
+#include <ssdef.h>
+#include <starlet.h>
+#include <stsdef.h>
+#include <unixlib.h>
+
+#pragma __nostandard 
+#pragma __member_alignment __save
+#pragma __nomember_alignment
+#ifdef __INITIAL_POINTER_SIZE
+#pragma __required_pointer_size __save 
+#pragma __required_pointer_size __short
+#endif
+ 
+typedef struct _imcb {
+    struct _imcb *imcb$l_flink;         
+    struct _imcb *imcb$l_blink;         
+    unsigned short int imcb$w_size;     
+    unsigned char imcb$b_type;          
+    char imcb$b_resv_1;                 
+    unsigned char imcb$b_access_mode;   
+    unsigned char imcb$b_act_code;      
+    unsigned short int imcb$w_chan;     
+    unsigned int imcb$l_flags;		
+    char imcb$t_image_name [40];        
+    unsigned int imcb$l_symvec_size; 
+    unsigned __int64 imcb$q_ident;
+    void *imcb$l_starting_address;
+    void *imcb$l_end_address;
+} IMCB;
+ 
+#pragma __member_alignment __restore
+#ifdef __INITIAL_POINTER_SIZE 
+#pragma __required_pointer_size __restore
+#endif
+#pragma __standard
+ 
+typedef struct {
+    short   buflen;
+    short   itmcode;
+    void    *buffer;
+    void    *retlen;
+} ITMLST;
+
+typedef struct {
+    short cond;
+    short count;
+    int   rest;
+} IOSB;
+
+typedef unsigned long int ulong_t;
+
+struct _imcb *IAC$GL_IMAGE_LIST = NULL;
+
+#define MAX_DEVNAM 64
+#define MAX_FILNAM 255
+#endif  /* VMS */
+
+/*
+ * On these platforms, symbols have a leading '_'.
+ */
+#if defined(SUNOS4) || defined(DARWIN) || defined(NEXTSTEP) \
+    || defined(WIN16) || defined(XP_OS2) \
+    || ((defined(OPENBSD) || defined(NETBSD)) && !defined(__ELF__))
+#define NEED_LEADING_UNDERSCORE
+#endif
+
+/************************************************************************/
+
+struct PRLibrary {
+    char*                       name;  /* Our own copy of the name string */
+    PRLibrary*                  next;
+    int                         refCount;
+    const PRStaticLinkTable*    staticTable;
+
+#ifdef XP_PC
+#ifdef XP_OS2
+    HMODULE                     dlh;
+#else
+    HINSTANCE                   dlh;
+#endif
+#endif
+
+#ifdef XP_MACOSX
+    CFragConnectionID           connection;
+    CFBundleRef                 bundle;
+    Ptr                         main;
+    CFMutableDictionaryRef      wrappers;
+    const struct mach_header*   image;
+#endif
+
+#ifdef XP_UNIX
+#if defined(USE_HPSHL)
+    shl_t                       dlh;
+#elif defined(USE_MACH_DYLD)
+    NSModule                    dlh;
+#else
+    void*                       dlh;
+#endif 
+#endif 
+
+#ifdef XP_BEOS
+    void*                       dlh;
+    void*                       stub_dlh;
+#endif
+};
+
+static PRLibrary *pr_loadmap;
+static PRLibrary *pr_exe_loadmap;
+static PRMonitor *pr_linker_lock;
+static char* _pr_currentLibPath = NULL;
+
+static PRLibrary *pr_LoadLibraryByPathname(const char *name, PRIntn flags);
+
+/************************************************************************/
+
+#if !defined(USE_DLFCN) && !defined(HAVE_STRERROR)
+static char* errStrBuf = NULL;
+#define ERR_STR_BUF_LENGTH    20
+static char* errno_string(PRIntn oserr)
+{
+    if (errStrBuf == NULL)
+        errStrBuf = PR_MALLOC(ERR_STR_BUF_LENGTH);
+    PR_snprintf(errStrBuf, ERR_STR_BUF_LENGTH, "error %d", oserr);
+    return errStrBuf;
+}
+#endif
+
+static void DLLErrorInternal(PRIntn oserr)
+/*
+** This whole function, and most of the code in this file, are run
+** with a big hairy lock wrapped around it. Not the best of situations,
+** but will eventually come up with the right answer.
+*/
+{
+    const char *error = NULL;
+#ifdef USE_DLFCN
+    error = dlerror();  /* $$$ That'll be wrong some of the time - AOF */
+#elif defined(HAVE_STRERROR)
+    error = strerror(oserr);  /* this should be okay */
+#else
+    error = errno_string(oserr);
+#endif
+    if (NULL != error)
+        PR_SetErrorText(strlen(error), error);
+}  /* DLLErrorInternal */
+
+void _PR_InitLinker(void)
+{
+    PRLibrary *lm = NULL;
+#if defined(XP_UNIX)
+    void *h;
+#endif
+
+    if (!pr_linker_lock) {
+        pr_linker_lock = PR_NewNamedMonitor("linker-lock");
+    }
+    PR_EnterMonitor(pr_linker_lock);
+
+#if defined(XP_PC)
+    lm = PR_NEWZAP(PRLibrary);
+    lm->name = strdup("Executable");
+        /* 
+        ** In WIN32, GetProcAddress(...) expects a module handle in order to
+        ** get exported symbols from the executable...
+        **
+        ** However, in WIN16 this is accomplished by passing NULL to 
+        ** GetProcAddress(...)
+        */
+#if defined(_WIN32)
+        lm->dlh = GetModuleHandle(NULL);
+#else
+        lm->dlh = (HINSTANCE)NULL;
+#endif /* ! _WIN32 */
+
+    lm->refCount    = 1;
+    lm->staticTable = NULL;
+    pr_exe_loadmap  = lm;
+    pr_loadmap      = lm;
+
+#elif defined(XP_UNIX)
+#ifdef HAVE_DLL
+#ifdef USE_DLFCN
+    h = dlopen(0, RTLD_LAZY);
+    if (!h) {
+        char *error;
+        
+        DLLErrorInternal(_MD_ERRNO());
+        error = (char*)PR_MALLOC(PR_GetErrorTextLength());
+        (void) PR_GetErrorText(error);
+        fprintf(stderr, "failed to initialize shared libraries [%s]\n",
+            error);
+        PR_DELETE(error);
+        abort();/* XXX */
+    }
+#elif defined(USE_HPSHL)
+    h = NULL;
+    /* don't abort with this NULL */
+#elif defined(USE_MACH_DYLD)
+    h = NULL; /* XXXX  toshok */
+#else
+#error no dll strategy
+#endif /* USE_DLFCN */
+
+    lm = PR_NEWZAP(PRLibrary);
+    if (lm) {
+        lm->name = strdup("a.out");
+        lm->refCount = 1;
+        lm->dlh = h;
+        lm->staticTable = NULL;
+    }
+    pr_exe_loadmap = lm;
+    pr_loadmap = lm;
+#endif /* HAVE_DLL */
+#endif /* XP_UNIX */
+
+    if (lm) {
+        PR_LOG(_pr_linker_lm, PR_LOG_MIN,
+            ("Loaded library %s (init)", lm->name));
+    }
+
+    PR_ExitMonitor(pr_linker_lock);
+}
+
+#if defined(WIN16)
+/*
+ * _PR_ShutdownLinker unloads all dlls loaded by the application via
+ * calls to PR_LoadLibrary
+ */
+void _PR_ShutdownLinker(void)
+{
+    PR_EnterMonitor(pr_linker_lock);
+
+    while (pr_loadmap) {
+    if (pr_loadmap->refCount > 1) {
+#ifdef DEBUG
+        fprintf(stderr, "# Forcing library to unload: %s (%d outstanding references)\n",
+            pr_loadmap->name, pr_loadmap->refCount);
+#endif
+        pr_loadmap->refCount = 1;
+    }
+    PR_UnloadLibrary(pr_loadmap);
+    }
+    
+    PR_ExitMonitor(pr_linker_lock);
+
+    PR_DestroyMonitor(pr_linker_lock);
+    pr_linker_lock = NULL;
+}
+#else
+/*
+ * _PR_ShutdownLinker was originally only used on WIN16 (see above),
+ * but I think it should also be used on other platforms.  However,
+ * I disagree with the original implementation's unloading the dlls
+ * for the application.  Any dlls that still remain on the pr_loadmap
+ * list when NSPR shuts down are application programming errors.  The
+ * only exception is pr_exe_loadmap, which was added to the list by
+ * NSPR and hence should be cleaned up by NSPR.
+ */
+void _PR_ShutdownLinker(void)
+{
+    /* FIXME: pr_exe_loadmap should be destroyed. */
+    
+    PR_DestroyMonitor(pr_linker_lock);
+    pr_linker_lock = NULL;
+
+    if (_pr_currentLibPath) {
+        free(_pr_currentLibPath);
+        _pr_currentLibPath = NULL;
+    }
+
+#if !defined(USE_DLFCN) && !defined(HAVE_STRERROR)
+    PR_DELETE(errStrBuf);
+#endif
+}
+#endif
+
+/******************************************************************************/
+
+PR_IMPLEMENT(PRStatus) PR_SetLibraryPath(const char *path)
+{
+    PRStatus rv = PR_SUCCESS;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    PR_EnterMonitor(pr_linker_lock);
+    if (_pr_currentLibPath) {
+        free(_pr_currentLibPath);
+    }
+    if (path) {
+        _pr_currentLibPath = strdup(path);
+        if (!_pr_currentLibPath) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        rv = PR_FAILURE;
+        }
+    } else {
+        _pr_currentLibPath = 0;
+    }
+    PR_ExitMonitor(pr_linker_lock);
+    return rv;
+}
+
+/*
+** Return the library path for finding shared libraries.
+*/
+PR_IMPLEMENT(char *) 
+PR_GetLibraryPath(void)
+{
+    char *ev;
+    char *copy = NULL;  /* a copy of _pr_currentLibPath */
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    PR_EnterMonitor(pr_linker_lock);
+    if (_pr_currentLibPath != NULL) {
+        goto exit;
+    }
+
+    /* initialize pr_currentLibPath */
+
+#ifdef XP_PC
+    ev = getenv("LD_LIBRARY_PATH");
+    if (!ev) {
+    ev = ".;\\lib";
+    }
+    ev = strdup(ev);
+#endif
+
+#if defined(XP_UNIX) || defined(XP_BEOS)
+#if defined(USE_DLFCN) || defined(USE_MACH_DYLD) || defined(XP_BEOS)
+    {
+    char *p=NULL;
+    int len;
+
+#ifdef XP_BEOS
+    ev = getenv("LIBRARY_PATH");
+    if (!ev) {
+        ev = "%A/lib:/boot/home/config/lib:/boot/beos/system/lib";
+    }
+#else
+    ev = getenv("LD_LIBRARY_PATH");
+    if (!ev) {
+        ev = "/usr/lib:/lib";
+    }
+#endif
+    len = strlen(ev) + 1;        /* +1 for the null */
+
+    p = (char*) malloc(len);
+    if (p) {
+        strcpy(p, ev);
+    }   /* if (p)  */
+    ev = p;
+    PR_LOG(_pr_io_lm, PR_LOG_NOTICE, ("linker path '%s'", ev));
+
+    }
+#else
+    /* AFAIK there isn't a library path with the HP SHL interface --Rob */
+    ev = strdup("");
+#endif
+#endif
+
+    /*
+     * If ev is NULL, we have run out of memory
+     */
+    _pr_currentLibPath = ev;
+
+  exit:
+    if (_pr_currentLibPath) {
+        copy = strdup(_pr_currentLibPath);
+    }
+    PR_ExitMonitor(pr_linker_lock);
+    if (!copy) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return copy;
+}
+
+/*
+** Build library name from path, lib and extensions
+*/
+PR_IMPLEMENT(char*) 
+PR_GetLibraryName(const char *path, const char *lib)
+{
+    char *fullname;
+
+#ifdef XP_PC
+    if (strstr(lib, PR_DLL_SUFFIX) == NULL)
+    {
+        if (path) {
+            fullname = PR_smprintf("%s\\%s%s", path, lib, PR_DLL_SUFFIX);
+        } else {
+            fullname = PR_smprintf("%s%s", lib, PR_DLL_SUFFIX);
+        }
+    } else {
+        if (path) {
+            fullname = PR_smprintf("%s\\%s", path, lib);
+        } else {
+            fullname = PR_smprintf("%s", lib);
+        }
+    }
+#endif /* XP_PC */
+#if defined(XP_UNIX) || defined(XP_BEOS)
+    if (strstr(lib, PR_DLL_SUFFIX) == NULL)
+    {
+        if (path) {
+            fullname = PR_smprintf("%s/lib%s%s", path, lib, PR_DLL_SUFFIX);
+        } else {
+            fullname = PR_smprintf("lib%s%s", lib, PR_DLL_SUFFIX);
+        }
+    } else {
+        if (path) {
+            fullname = PR_smprintf("%s/%s", path, lib);
+        } else {
+            fullname = PR_smprintf("%s", lib);
+        }
+    }
+#endif /* XP_UNIX || XP_BEOS */
+    return fullname;
+}
+
+/*
+** Free the memory allocated, for the caller, by PR_GetLibraryName
+*/
+PR_IMPLEMENT(void) 
+PR_FreeLibraryName(char *mem)
+{
+    PR_smprintf_free(mem);
+}
+
+static PRLibrary* 
+pr_UnlockedFindLibrary(const char *name)
+{
+    PRLibrary* lm = pr_loadmap;
+    const char* np = strrchr(name, PR_DIRECTORY_SEPARATOR);
+    np = np ? np + 1 : name;
+    while (lm) {
+    const char* cp = strrchr(lm->name, PR_DIRECTORY_SEPARATOR);
+    cp = cp ? cp + 1 : lm->name;
+#ifdef WIN32
+        /* Windows DLL names are case insensitive... */
+    if (strcmpi(np, cp) == 0) 
+#elif defined(XP_OS2)
+    if (stricmp(np, cp) == 0)
+#else
+    if (strcmp(np, cp)  == 0) 
+#endif
+    {
+        /* found */
+        lm->refCount++;
+        PR_LOG(_pr_linker_lm, PR_LOG_MIN,
+           ("%s incr => %d (find lib)",
+            lm->name, lm->refCount));
+        return lm;
+    }
+    lm = lm->next;
+    }
+    return NULL;
+}
+
+PR_IMPLEMENT(PRLibrary*)
+PR_LoadLibraryWithFlags(PRLibSpec libSpec, PRIntn flags)
+{
+    if (flags == 0) {
+        flags = _PR_DEFAULT_LD_FLAGS;
+    }
+    switch (libSpec.type) {
+        case PR_LibSpec_Pathname:
+            return pr_LoadLibraryByPathname(libSpec.value.pathname, flags);
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return NULL;
+    }
+}
+            
+PR_IMPLEMENT(PRLibrary*) 
+PR_LoadLibrary(const char *name)
+{
+    PRLibSpec libSpec;
+
+    libSpec.type = PR_LibSpec_Pathname;
+    libSpec.value.pathname = name;
+    return PR_LoadLibraryWithFlags(libSpec, 0);
+}
+
+#if defined(USE_MACH_DYLD)
+static NSModule
+pr_LoadMachDyldModule(const char *name)
+{
+    NSObjectFileImage ofi;
+    NSModule h = NULL;
+    if (NSCreateObjectFileImageFromFile(name, &ofi)
+            == NSObjectFileImageSuccess) {
+        h = NSLinkModule(ofi, name, NSLINKMODULE_OPTION_PRIVATE
+                         | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
+        /*
+         * TODO: If NSLinkModule fails, use NSLinkEditError to retrieve
+         * error information.
+         */
+        if (NSDestroyObjectFileImage(ofi) == FALSE) {
+            if (h) {
+                (void)NSUnLinkModule(h, NSUNLINKMODULE_OPTION_NONE);
+                h = NULL;
+            }
+        }
+    }
+    return h;
+}
+#endif
+
+#ifdef XP_MACOSX
+
+/*
+** macLibraryLoadProc is a function definition for a Mac shared library
+** loading method. The "name" param is the same full or partial pathname
+** that was passed to pr_LoadLibraryByPathName. The function must fill
+** in the fields of "lm" which apply to its library type. Returns
+** PR_SUCCESS if successful.
+*/
+
+typedef PRStatus (*macLibraryLoadProc)(const char *name, PRLibrary *lm);
+
+#ifdef __ppc__
+
+/*
+** CFM and its TVectors only exist on PowerPC.  Other OS X architectures
+** only use Mach-O as a native binary format.
+*/
+
+static void* TV2FP(CFMutableDictionaryRef dict, const char* name, void *tvp)
+{
+    static uint32 glue[6] = { 0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420 };
+    uint32* newGlue = NULL;
+
+    if (tvp != NULL) {
+        CFStringRef nameRef = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);
+        if (nameRef) {
+            CFMutableDataRef glueData = (CFMutableDataRef) CFDictionaryGetValue(dict, nameRef);
+            if (glueData == NULL) {
+                glueData = CFDataCreateMutable(NULL, sizeof(glue));
+                if (glueData != NULL) {
+                    newGlue = (uint32*) CFDataGetMutableBytePtr(glueData);
+                    memcpy(newGlue, glue, sizeof(glue));
+                    newGlue[0] |= ((UInt32)tvp >> 16);
+                    newGlue[1] |= ((UInt32)tvp & 0xFFFF);
+                    MakeDataExecutable(newGlue, sizeof(glue));
+                    CFDictionaryAddValue(dict, nameRef, glueData);
+                    CFRelease(glueData);
+
+                    PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("TV2FP: created wrapper for CFM function %s().", name));
+                }
+            } else {
+                PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("TV2FP: found wrapper for CFM function %s().", name));
+
+                newGlue = (uint32*) CFDataGetMutableBytePtr(glueData);
+            }
+            CFRelease(nameRef);
+        }
+    }
+    
+    return newGlue;
+}
+
+static PRStatus
+pr_LoadViaCFM(const char *name, PRLibrary *lm)
+{
+    OSErr err;
+    Str255 errName;
+    FSRef ref;
+    FSSpec fileSpec;
+    Boolean tempUnusedBool;
+
+    /*
+     * Make an FSSpec from the path name and call GetDiskFragment.
+     */
+
+    /* Use direct conversion of POSIX path to FSRef to FSSpec. */
+    err = FSPathMakeRef((const UInt8*)name, &ref, NULL);
+    if (err != noErr)
+        return PR_FAILURE;
+    err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL,
+                           &fileSpec, NULL);
+    if (err != noErr)
+        return PR_FAILURE;
+
+    /* Resolve an alias if this was one */
+    err = ResolveAliasFile(&fileSpec, true, &tempUnusedBool,
+                           &tempUnusedBool);
+    if (err != noErr)
+        return PR_FAILURE;
+
+    /* Finally, try to load the library */
+    err = GetDiskFragment(&fileSpec, 0, kCFragGoesToEOF, fileSpec.name,
+                          kLoadCFrag, &lm->connection, &lm->main, errName);
+
+    if (err == noErr && lm->connection) {
+        /*
+         * if we're a mach-o binary, need to wrap all CFM function
+         * pointers. need a hash-table of already seen function
+         * pointers, etc.
+         */
+        lm->wrappers = CFDictionaryCreateMutable(NULL, 16,
+                       &kCFTypeDictionaryKeyCallBacks,
+                       &kCFTypeDictionaryValueCallBacks);
+        if (lm->wrappers) {
+            lm->main = TV2FP(lm->wrappers, "main", lm->main);
+        } else
+            err = memFullErr;
+    }
+    return (err == noErr) ? PR_SUCCESS : PR_FAILURE;
+}
+#endif /* __ppc__ */
+
+/*
+** Creates a CFBundleRef if the pathname refers to a Mac OS X bundle
+** directory. The caller is responsible for calling CFRelease() to
+** deallocate.
+*/
+
+static PRStatus
+pr_LoadCFBundle(const char *name, PRLibrary *lm)
+{
+    CFURLRef bundleURL;
+    CFBundleRef bundle = NULL;
+    char pathBuf[PATH_MAX];
+    const char *resolvedPath;
+    CFStringRef pathRef;
+
+    /* Takes care of relative paths and symlinks */
+    resolvedPath = realpath(name, pathBuf);
+    if (!resolvedPath)
+        return PR_FAILURE;
+        
+    pathRef = CFStringCreateWithCString(NULL, pathBuf, kCFStringEncodingUTF8);
+    if (pathRef) {
+        bundleURL = CFURLCreateWithFileSystemPath(NULL, pathRef,
+                                                  kCFURLPOSIXPathStyle, true);
+        if (bundleURL) {
+            bundle = CFBundleCreate(NULL, bundleURL);
+            CFRelease(bundleURL);
+        }
+        CFRelease(pathRef);
+    }
+
+    lm->bundle = bundle;
+    return (bundle != NULL) ? PR_SUCCESS : PR_FAILURE;
+}
+
+static PRStatus
+pr_LoadViaDyld(const char *name, PRLibrary *lm)
+{
+    lm->dlh = pr_LoadMachDyldModule(name);
+    if (lm->dlh == NULL) {
+        lm->image = NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ON_ERROR
+                               | NSADDIMAGE_OPTION_WITH_SEARCHING);
+        /*
+         * TODO: If NSAddImage fails, use NSLinkEditError to retrieve
+         * error information.
+         */
+    }
+    return (lm->dlh != NULL || lm->image != NULL) ? PR_SUCCESS : PR_FAILURE;
+}
+
+#endif /* XP_MACOSX */
+
+/*
+** Dynamically load a library. Only load libraries once, so scan the load
+** map first.
+*/
+static PRLibrary*
+pr_LoadLibraryByPathname(const char *name, PRIntn flags)
+{
+    PRLibrary *lm;
+    PRLibrary* result;
+    PRInt32 oserr;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    /* See if library is already loaded */
+    PR_EnterMonitor(pr_linker_lock);
+
+    result = pr_UnlockedFindLibrary(name);
+    if (result != NULL) goto unlock;
+
+    lm = PR_NEWZAP(PRLibrary);
+    if (lm == NULL) {
+        oserr = _MD_ERRNO();
+        goto unlock;
+    }
+    lm->staticTable = NULL;
+
+#ifdef XP_OS2  /* Why isn't all this stuff in MD code?! */
+    {
+        HMODULE h;
+        UCHAR pszError[_MAX_PATH];
+        ULONG ulRc = NO_ERROR;
+
+          ulRc = DosLoadModule(pszError, _MAX_PATH, (PSZ) name, &h);
+          if (ulRc != NO_ERROR) {
+              oserr = ulRc;
+              PR_DELETE(lm);
+              goto unlock;
+          }
+          lm->name = strdup(name);
+          lm->dlh  = h;
+          lm->next = pr_loadmap;
+          pr_loadmap = lm;
+    }
+#endif /* XP_OS2 */
+
+#if defined(WIN32) || defined(WIN16)
+    {
+    HINSTANCE h;
+
+    h = LoadLibrary(name);
+    if (h < (HINSTANCE)HINSTANCE_ERROR) {
+        oserr = _MD_ERRNO();
+        PR_DELETE(lm);
+        goto unlock;
+    }
+    lm->name = strdup(name);
+    lm->dlh = h;
+    lm->next = pr_loadmap;
+    pr_loadmap = lm;
+    }
+#endif /* WIN32 || WIN16 */
+
+#ifdef XP_MACOSX
+    {
+    int     i;
+    PRStatus status;
+
+    static const macLibraryLoadProc loadProcs[] = {
+#ifdef __ppc__
+        pr_LoadViaDyld, pr_LoadCFBundle, pr_LoadViaCFM
+#else  /* __ppc__ */
+        pr_LoadViaDyld, pr_LoadCFBundle
+#endif /* __ppc__ */
+    };
+
+    for (i = 0; i < sizeof(loadProcs) / sizeof(loadProcs[0]); i++) {
+        if ((status = loadProcs[i](name, lm)) == PR_SUCCESS)
+            break;
+    }
+    if (status != PR_SUCCESS) {
+        oserr = cfragNoLibraryErr;
+        PR_DELETE(lm);
+        goto unlock;        
+    }
+    lm->name = strdup(name);
+    lm->next = pr_loadmap;
+    pr_loadmap = lm;
+    }
+#endif
+
+#if defined(XP_UNIX) && !defined(XP_MACOSX)
+#ifdef HAVE_DLL
+    {
+#if defined(USE_DLFCN)
+#ifdef NTO
+    /* Neutrino needs RTLD_GROUP to load Netscape plugins. (bug 71179) */
+    int dl_flags = RTLD_GROUP;
+#elif defined(AIX)
+    /* AIX needs RTLD_MEMBER to load an archive member.  (bug 228899) */
+    int dl_flags = RTLD_MEMBER;
+#else
+    int dl_flags = 0;
+#endif
+    void *h;
+
+    if (flags & PR_LD_LAZY) {
+        dl_flags |= RTLD_LAZY;
+    }
+    if (flags & PR_LD_NOW) {
+        dl_flags |= RTLD_NOW;
+    }
+    if (flags & PR_LD_GLOBAL) {
+        dl_flags |= RTLD_GLOBAL;
+    }
+    if (flags & PR_LD_LOCAL) {
+        dl_flags |= RTLD_LOCAL;
+    }
+    h = dlopen(name, dl_flags);
+#elif defined(USE_HPSHL)
+    int shl_flags = 0;
+    shl_t h;
+
+    /*
+     * Use the DYNAMIC_PATH flag only if 'name' is a plain file
+     * name (containing no directory) to match the behavior of
+     * dlopen().
+     */
+    if (strchr(name, PR_DIRECTORY_SEPARATOR) == NULL) {
+        shl_flags |= DYNAMIC_PATH;
+    }
+    if (flags & PR_LD_LAZY) {
+        shl_flags |= BIND_DEFERRED;
+    }
+    if (flags & PR_LD_NOW) {
+        shl_flags |= BIND_IMMEDIATE;
+    }
+    /* No equivalent of PR_LD_GLOBAL and PR_LD_LOCAL. */
+    h = shl_load(name, shl_flags, 0L);
+#elif defined(USE_MACH_DYLD)
+    NSModule h = pr_LoadMachDyldModule(name);
+#else
+#error Configuration error
+#endif
+    if (!h) {
+        oserr = _MD_ERRNO();
+        PR_DELETE(lm);
+        goto unlock;
+    }
+    lm->name = strdup(name);
+    lm->dlh = h;
+    lm->next = pr_loadmap;
+    pr_loadmap = lm;
+    }
+#endif /* HAVE_DLL */
+#endif /* XP_UNIX */
+
+    lm->refCount = 1;
+
+#ifdef XP_BEOS
+    {
+        image_info info;
+        int32 cookie = 0;
+        image_id imageid = B_ERROR;
+        image_id stubid = B_ERROR;
+        PRLibrary *p;
+
+        for (p = pr_loadmap; p != NULL; p = p->next) {
+            /* hopefully, our caller will always use the same string
+               to refer to the same library */
+            if (strcmp(name, p->name) == 0) {
+                /* we've already loaded this library */
+                imageid = info.id;
+                lm->refCount++;
+                break;
+            }
+        }
+
+        if(imageid == B_ERROR) {
+            /* it appears the library isn't yet loaded - load it now */
+            char stubName [B_PATH_NAME_LENGTH + 1];
+
+            /* the following is a work-around to a "bug" in the beos -
+               the beos system loader allows only 32M (system-wide)
+               to be used by code loaded as "add-ons" (code loaded
+               through the 'load_add_on()' system call, which includes
+               mozilla components), but allows 256M to be used by
+               shared libraries.
+               
+               unfortunately, mozilla is too large to fit into the
+               "add-on" space, so we must trick the loader into
+               loading some of the components as shared libraries.  this
+               is accomplished by creating a "stub" add-on (an empty
+               shared object), and linking it with the component
+               (the actual .so file generated by the build process,
+               without any modifications).  when this stub is loaded
+               by load_add_on(), the loader will automatically load the
+               component into the shared library space.
+            */
+
+            strcpy(stubName, name);
+            strcat(stubName, ".stub");
+
+            /* first, attempt to load the stub (thereby loading the
+               component as a shared library */
+            if ((stubid = load_add_on(stubName)) > B_ERROR) {
+                /* the stub was loaded successfully. */
+                imageid = B_FILE_NOT_FOUND;
+
+                cookie = 0;
+                while (get_next_image_info(0, &cookie, &info) == B_OK) {
+                    const char *endOfSystemName = strrchr(info.name, '/');
+                    const char *endOfPassedName = strrchr(name, '/');
+                    if( 0 == endOfSystemName ) 
+                        endOfSystemName = info.name;
+                    else
+                        endOfSystemName++;
+                    if( 0 == endOfPassedName )
+                        endOfPassedName = name;
+                    else
+                        endOfPassedName++;
+                    if (strcmp(endOfSystemName, endOfPassedName) == 0) {
+                        /* this is the actual component - remember it */
+                        imageid = info.id;
+                        break;
+                    }
+                }
+
+            } else {
+                /* we failed to load the "stub" - try to load the
+                   component directly as an add-on */
+                stubid = B_ERROR;
+                imageid = load_add_on(name);
+            }
+        }
+
+        if (imageid <= B_ERROR) {
+            oserr = imageid;
+            PR_DELETE( lm );
+            goto unlock;
+        }
+        lm->name = strdup(name);
+        lm->dlh = (void*)imageid;
+        lm->stub_dlh = (void*)stubid;
+        lm->next = pr_loadmap;
+        pr_loadmap = lm;
+    }
+#endif
+
+    result = lm;    /* success */
+    PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (load lib)", lm->name));
+
+  unlock:
+    if (result == NULL) {
+        PR_SetError(PR_LOAD_LIBRARY_ERROR, oserr);
+        DLLErrorInternal(oserr);  /* sets error text */
+    }
+    PR_ExitMonitor(pr_linker_lock);
+    return result;
+}
+
+/*
+** Unload a shared library which was loaded via PR_LoadLibrary
+*/
+PR_IMPLEMENT(PRStatus) 
+PR_UnloadLibrary(PRLibrary *lib)
+{
+    int result = 0;
+    PRStatus status = PR_SUCCESS;
+
+    if ((lib == 0) || (lib->refCount <= 0)) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    PR_EnterMonitor(pr_linker_lock);
+    if (--lib->refCount > 0) {
+    PR_LOG(_pr_linker_lm, PR_LOG_MIN,
+           ("%s decr => %d",
+        lib->name, lib->refCount));
+    goto done;
+    }
+
+#ifdef XP_BEOS
+    if(((image_id)lib->stub_dlh) == B_ERROR)
+        unload_add_on( (image_id) lib->dlh );
+    else
+        unload_add_on( (image_id) lib->stub_dlh);
+#endif
+
+#ifdef XP_UNIX
+#ifdef HAVE_DLL
+#ifdef USE_DLFCN
+    result = dlclose(lib->dlh);
+#elif defined(USE_HPSHL)
+    result = shl_unload(lib->dlh);
+#elif defined(USE_MACH_DYLD)
+    result = NSUnLinkModule(lib->dlh, NSUNLINKMODULE_OPTION_NONE) ? 0 : -1;
+#else
+#error Configuration error
+#endif
+#endif /* HAVE_DLL */
+#endif /* XP_UNIX */
+#ifdef XP_PC
+    if (lib->dlh) {
+        FreeLibrary((HINSTANCE)(lib->dlh));
+        lib->dlh = (HINSTANCE)NULL;
+    }
+#endif  /* XP_PC */
+
+#ifdef XP_MACOSX
+    /* Close the connection */
+    if (lib->connection)
+        CloseConnection(&(lib->connection));
+    if (lib->bundle)
+        CFRelease(lib->bundle);
+    if (lib->wrappers)
+        CFRelease(lib->wrappers);
+    /* No way to unload an image (lib->image) */
+#endif
+
+    /* unlink from library search list */
+    if (pr_loadmap == lib)
+        pr_loadmap = pr_loadmap->next;
+    else if (pr_loadmap != NULL) {
+        PRLibrary* prev = pr_loadmap;
+        PRLibrary* next = pr_loadmap->next;
+        while (next != NULL) {
+            if (next == lib) {
+                prev->next = next->next;
+                goto freeLib;
+            }
+            prev = next;
+            next = next->next;
+        }
+        /*
+         * fail (the library is not on the _pr_loadmap list),
+         * but don't wipe out an error from dlclose/shl_unload.
+         */
+        PR_ASSERT(!"_pr_loadmap and lib->refCount inconsistent");
+        if (result == 0) {
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            status = PR_FAILURE;
+        }
+    }
+    /*
+     * We free the PRLibrary structure whether dlclose/shl_unload
+     * succeeds or not.
+     */
+
+  freeLib:
+    PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Unloaded library %s", lib->name));
+    free(lib->name);
+    lib->name = NULL;
+    PR_DELETE(lib);
+    if (result != 0) {
+        PR_SetError(PR_UNLOAD_LIBRARY_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        status = PR_FAILURE;
+    }
+
+done:
+    PR_ExitMonitor(pr_linker_lock);
+    return status;
+}
+
+static void* 
+pr_FindSymbolInLib(PRLibrary *lm, const char *name)
+{
+    void *f = NULL;
+#ifdef XP_OS2
+    int rc;
+#endif
+
+    if (lm->staticTable != NULL) {
+        const PRStaticLinkTable* tp;
+        for (tp = lm->staticTable; tp->name; tp++) {
+            if (strcmp(name, tp->name) == 0) {
+                return (void*) tp->fp;
+            }
+        }
+        /* 
+        ** If the symbol was not found in the static table then check if
+        ** the symbol was exported in the DLL... Win16 only!!
+        */
+#if !defined(WIN16) && !defined(XP_BEOS)
+        PR_SetError(PR_FIND_SYMBOL_ERROR, 0);
+        return (void*)NULL;
+#endif
+    }
+    
+#ifdef XP_OS2
+    rc = DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f);
+#if defined(NEED_LEADING_UNDERSCORE)
+    /*
+     * Older plugins (not built using GCC) will have symbols that are not
+     * underscore prefixed.  We check for that here.
+     */
+    if (rc != NO_ERROR) {
+        name++;
+        DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f);
+    }
+#endif
+#endif  /* XP_OS2 */
+
+#if defined(WIN32) || defined(WIN16)
+    f = GetProcAddress(lm->dlh, name);
+#endif  /* WIN32 || WIN16 */
+
+#ifdef XP_MACOSX
+/* add this offset to skip the leading underscore in name */
+#define SYM_OFFSET 1
+    if (lm->bundle) {
+        CFStringRef nameRef = CFStringCreateWithCString(NULL, name + SYM_OFFSET, kCFStringEncodingASCII);
+        if (nameRef) {
+            f = CFBundleGetFunctionPointerForName(lm->bundle, nameRef);
+            CFRelease(nameRef);
+        }
+    }
+    if (lm->connection) {
+        Ptr                 symAddr;
+        CFragSymbolClass    symClass;
+        Str255              pName;
+        
+        PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Looking up symbol: %s", name + SYM_OFFSET));
+        
+        c2pstrcpy(pName, name + SYM_OFFSET);
+        
+        f = (FindSymbol(lm->connection, pName, &symAddr, &symClass) == noErr) ? symAddr : NULL;
+        
+#ifdef __ppc__
+        /* callers expect mach-o function pointers, so must wrap tvectors with glue. */
+        if (f && symClass == kTVectorCFragSymbol) {
+            f = TV2FP(lm->wrappers, name + SYM_OFFSET, f);
+        }
+#endif /* __ppc__ */
+        
+        if (f == NULL && strcmp(name + SYM_OFFSET, "main") == 0) f = lm->main;
+    }
+    if (lm->image) {
+        NSSymbol symbol;
+        symbol = NSLookupSymbolInImage(lm->image, name,
+                 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
+                 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
+        if (symbol != NULL)
+            f = NSAddressOfSymbol(symbol);
+        else
+            f = NULL;
+    }
+#undef SYM_OFFSET
+#endif /* XP_MACOSX */
+
+#ifdef XP_BEOS
+    if( B_NO_ERROR != get_image_symbol( (image_id)lm->dlh, name, B_SYMBOL_TYPE_TEXT, &f ) ) {
+        f = NULL;
+    }
+#endif
+
+#ifdef XP_UNIX
+#ifdef HAVE_DLL
+#ifdef USE_DLFCN
+    f = dlsym(lm->dlh, name);
+#elif defined(USE_HPSHL)
+    if (shl_findsym(&lm->dlh, name, TYPE_PROCEDURE, &f) == -1) {
+        f = NULL;
+    }
+#elif defined(USE_MACH_DYLD)
+    if (lm->dlh) {
+        NSSymbol symbol;
+        symbol = NSLookupSymbolInModule(lm->dlh, name);
+        if (symbol != NULL)
+            f = NSAddressOfSymbol(symbol);
+        else
+            f = NULL;
+    }
+#endif
+#endif /* HAVE_DLL */
+#endif /* XP_UNIX */
+    if (f == NULL) {
+        PR_SetError(PR_FIND_SYMBOL_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+    }
+    return f;
+}
+
+/*
+** Called by class loader to resolve missing native's
+*/
+PR_IMPLEMENT(void*) 
+PR_FindSymbol(PRLibrary *lib, const char *raw_name)
+{
+    void *f = NULL;
+#if defined(NEED_LEADING_UNDERSCORE)
+    char *name;
+#else
+    const char *name;
+#endif
+    /*
+    ** Mangle the raw symbol name in any way that is platform specific.
+    */
+#if defined(NEED_LEADING_UNDERSCORE)
+    /* Need a leading _ */
+    name = PR_smprintf("_%s", raw_name);
+#elif defined(AIX)
+    /*
+    ** AIX with the normal linker put's a "." in front of the symbol
+    ** name.  When use "svcc" and "svld" then the "." disappears. Go
+    ** figure.
+    */
+    name = raw_name;
+#else
+    name = raw_name;
+#endif
+
+    PR_EnterMonitor(pr_linker_lock);
+    PR_ASSERT(lib != NULL);
+    f = pr_FindSymbolInLib(lib, name);
+
+#if defined(NEED_LEADING_UNDERSCORE)
+    PR_smprintf_free(name);
+#endif
+
+    PR_ExitMonitor(pr_linker_lock);
+    return f;
+}
+
+/*
+** Return the address of the function 'raw_name' in the library 'lib'
+*/
+PR_IMPLEMENT(PRFuncPtr) 
+PR_FindFunctionSymbol(PRLibrary *lib, const char *raw_name)
+{
+    return ((PRFuncPtr) PR_FindSymbol(lib, raw_name));
+}
+
+PR_IMPLEMENT(void*) 
+PR_FindSymbolAndLibrary(const char *raw_name, PRLibrary* *lib)
+{
+    void *f = NULL;
+#if defined(NEED_LEADING_UNDERSCORE)
+    char *name;
+#else
+    const char *name;
+#endif
+    PRLibrary* lm;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    /*
+    ** Mangle the raw symbol name in any way that is platform specific.
+    */
+#if defined(NEED_LEADING_UNDERSCORE)
+    /* Need a leading _ */
+    name = PR_smprintf("_%s", raw_name);
+#elif defined(AIX)
+    /*
+    ** AIX with the normal linker put's a "." in front of the symbol
+    ** name.  When use "svcc" and "svld" then the "." disappears. Go
+    ** figure.
+    */
+    name = raw_name;
+#else
+    name = raw_name;
+#endif
+
+    PR_EnterMonitor(pr_linker_lock);
+
+    /* search all libraries */
+    for (lm = pr_loadmap; lm != NULL; lm = lm->next) {
+        f = pr_FindSymbolInLib(lm, name);
+        if (f != NULL) {
+            *lib = lm;
+            lm->refCount++;
+            PR_LOG(_pr_linker_lm, PR_LOG_MIN,
+                       ("%s incr => %d (for %s)",
+                    lm->name, lm->refCount, name));
+            break;
+        }
+    }
+#if defined(NEED_LEADING_UNDERSCORE)
+    PR_smprintf_free(name);
+#endif
+
+    PR_ExitMonitor(pr_linker_lock);
+    return f;
+}
+
+PR_IMPLEMENT(PRFuncPtr) 
+PR_FindFunctionSymbolAndLibrary(const char *raw_name, PRLibrary* *lib)
+{
+    return ((PRFuncPtr) PR_FindSymbolAndLibrary(raw_name, lib));
+}
+
+/*
+** Add a static library to the list of loaded libraries. If LoadLibrary
+** is called with the name then we will pretend it was already loaded
+*/
+PR_IMPLEMENT(PRLibrary*) 
+PR_LoadStaticLibrary(const char *name, const PRStaticLinkTable *slt)
+{
+    PRLibrary *lm=NULL;
+    PRLibrary* result = NULL;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    /* See if library is already loaded */
+    PR_EnterMonitor(pr_linker_lock);
+
+    /* If the lbrary is already loaded, then add the static table information... */
+    result = pr_UnlockedFindLibrary(name);
+    if (result != NULL) {
+        PR_ASSERT( (result->staticTable == NULL) || (result->staticTable == slt) );
+        result->staticTable = slt;
+        goto unlock;
+    }
+
+    /* Add library to list...Mark it static */
+    lm = PR_NEWZAP(PRLibrary);
+    if (lm == NULL) goto unlock;
+
+    lm->name = strdup(name);
+    lm->refCount    = 1;
+    lm->dlh         = pr_exe_loadmap ? pr_exe_loadmap->dlh : 0;
+    lm->staticTable = slt;
+    lm->next        = pr_loadmap;
+    pr_loadmap      = lm;
+
+    result = lm;    /* success */
+    PR_ASSERT(lm->refCount == 1);
+  unlock:
+    PR_LOG(_pr_linker_lm, PR_LOG_MIN, ("Loaded library %s (static lib)", lm->name));
+    PR_ExitMonitor(pr_linker_lock);
+    return result;
+}
+
+PR_IMPLEMENT(char *)
+PR_GetLibraryFilePathname(const char *name, PRFuncPtr addr)
+{
+#if defined(USE_DLFCN) && (defined(SOLARIS) || defined(FREEBSD) \
+        || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__))
+    Dl_info dli;
+    char *result;
+
+    if (dladdr((void *)addr, &dli) == 0) {
+        PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        return NULL;
+    }
+    result = PR_Malloc(strlen(dli.dli_fname)+1);
+    if (result != NULL) {
+        strcpy(result, dli.dli_fname);
+    }
+    return result;
+#elif defined(USE_MACH_DYLD)
+    char *result;
+    const char *image_name;
+    int i, count = _dyld_image_count();
+
+    for (i = 0; i < count; i++) {
+        image_name = _dyld_get_image_name(i);
+        if (strstr(image_name, name) != NULL) {
+            result = PR_Malloc(strlen(image_name)+1);
+            if (result != NULL) {
+                strcpy(result, image_name);
+            }
+            return result;
+        }
+    }
+    PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
+    return NULL;
+#elif defined(AIX)
+    char *result;
+#define LD_INFO_INCREMENT 64
+    struct ld_info *info;
+    unsigned int info_length = LD_INFO_INCREMENT * sizeof(struct ld_info);
+    struct ld_info *infop;
+    int loadflags = L_GETINFO | L_IGNOREUNLOAD;
+
+    for (;;) {
+        info = PR_Malloc(info_length);
+        if (info == NULL) {
+            return NULL;
+        }
+        /* If buffer is too small, loadquery fails with ENOMEM. */
+        if (loadquery(loadflags, info, info_length) != -1) {
+            break;
+        }
+        /*
+         * Calling loadquery when compiled for 64-bit with the
+         * L_IGNOREUNLOAD flag can cause an invalid argument error
+         * on AIX 5.1. Detect this error the first time that
+         * loadquery is called, and try calling it again without
+         * this flag set.
+         */
+        if (errno == EINVAL && (loadflags & L_IGNOREUNLOAD)) {
+            loadflags &= ~L_IGNOREUNLOAD;
+            if (loadquery(loadflags, info, info_length) != -1) {
+                break;
+            }
+        }
+        PR_Free(info);
+        if (errno != ENOMEM) {
+            /* should not happen */
+            _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
+            return NULL;
+        }
+        /* retry with a larger buffer */
+        info_length += LD_INFO_INCREMENT * sizeof(struct ld_info);
+    }
+
+    for (infop = info;
+         ;
+         infop = (struct ld_info *)((char *)infop + infop->ldinfo_next)) {
+        unsigned long start = (unsigned long)infop->ldinfo_dataorg;
+        unsigned long end = start + infop->ldinfo_datasize;
+        if (start <= (unsigned long)addr && end > (unsigned long)addr) {
+            result = PR_Malloc(strlen(infop->ldinfo_filename)+1);
+            if (result != NULL) {
+                strcpy(result, infop->ldinfo_filename);
+            }
+            break;
+        }
+        if (!infop->ldinfo_next) {
+            PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
+            result = NULL;
+            break;
+        }
+    }
+    PR_Free(info);
+    return result;
+#elif defined(OSF1)
+    /* Contributed by Steve Streeter of HP */
+    ldr_process_t process, ldr_my_process();
+    ldr_module_t mod_id;
+    ldr_module_info_t info;
+    ldr_region_t regno;
+    ldr_region_info_t reginfo;
+    size_t retsize;
+    int rv;
+    char *result;
+
+    /* Get process for which dynamic modules will be listed */
+
+    process = ldr_my_process();
+
+    /* Attach to process */
+
+    rv = ldr_xattach(process);
+    if (rv) {
+        /* should not happen */
+        _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
+        return NULL;
+    }
+
+    /* Print information for list of modules */
+
+    mod_id = LDR_NULL_MODULE;
+
+    for (;;) {
+
+        /* Get information for the next module in the module list. */
+
+        ldr_next_module(process, &mod_id);
+        if (ldr_inq_module(process, mod_id, &info, sizeof(info),
+                           &retsize) != 0) {
+            /* No more modules */
+            break;
+        }
+        if (retsize < sizeof(info)) {
+            continue;
+        }
+
+        /*
+         * Get information for each region in the module and check if any
+         * contain the address of this function.
+         */
+
+        for (regno = 0; ; regno++) {
+            if (ldr_inq_region(process, mod_id, regno, &reginfo,
+                               sizeof(reginfo), &retsize) != 0) {
+                /* No more regions */
+                break;
+            }
+            if (((unsigned long)reginfo.lri_mapaddr <=
+                (unsigned long)addr) &&
+                (((unsigned long)reginfo.lri_mapaddr + reginfo.lri_size) >
+                (unsigned long)addr)) {
+                /* Found it. */
+                result = PR_Malloc(strlen(info.lmi_name)+1);
+                if (result != NULL) {
+                    strcpy(result, info.lmi_name);
+                }
+                return result;
+            }
+        }
+    }
+    PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
+    return NULL;
+#elif defined(VMS)
+    /* Contributed by Colin Blake of HP */
+    struct _imcb	*icb;
+    ulong_t 		status;
+    char                device_name[MAX_DEVNAM];
+    int                 device_name_len;
+    $DESCRIPTOR         (device_name_desc, device_name);
+    struct fibdef	fib;
+    struct dsc$descriptor_s fib_desc = 
+	{ sizeof(struct fibdef), DSC$K_DTYPE_Z, DSC$K_CLASS_S, (char *)&fib } ;
+    IOSB		iosb;
+    ITMLST		devlst[2] = {
+            		{MAX_DEVNAM, DVI$_ALLDEVNAM, device_name, &device_name_len},
+            		{0,0,0,0}};
+    short               file_name_len;
+    char                file_name[MAX_FILNAM+1];
+    char		*result = NULL;
+    struct dsc$descriptor_s file_name_desc = 
+	{ MAX_FILNAM, DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *) &file_name[0] } ;
+
+    /*
+    ** The address for the process image list could change in future versions
+    ** of the operating system. 7FFD0688 is valid for V7.2 and V7.3 releases,
+    ** so we use that for the default, but allow an environment variable
+    ** (logical name) to override.
+    */
+    if (IAC$GL_IMAGE_LIST == NULL) {
+        char *p = getenv("MOZILLA_IAC_GL_IMAGE_LIST");
+        if (p)
+            IAC$GL_IMAGE_LIST = (struct _imcb *) strtol(p,NULL,0);
+        else
+            IAC$GL_IMAGE_LIST = (struct _imcb *) 0x7FFD0688;
+    }
+
+    for (icb = IAC$GL_IMAGE_LIST->imcb$l_flink;
+         icb != IAC$GL_IMAGE_LIST;
+         icb = icb->imcb$l_flink) {
+        if (((void *)addr >= icb->imcb$l_starting_address) && 
+	    ((void *)addr <= icb->imcb$l_end_address)) {
+	    /*
+	    ** This is the correct image.
+	    ** Get the device name.
+	    */
+	    status = sys$getdviw(0,icb->imcb$w_chan,0,&devlst,0,0,0,0);
+	    if ($VMS_STATUS_SUCCESS(status))
+		device_name_desc.dsc$w_length = device_name_len;
+
+	    /*
+	    ** Get the FID.
+	    */
+	    memset(&fib,0,sizeof(struct fibdef));
+	    status = sys$qiow(0,icb->imcb$w_chan,IO$_ACCESS,&iosb,
+                		0,0,&fib_desc,0,0,0,0,0);
+
+	    /*
+	    ** If we got the FID, now look up its name (if for some reason
+	    ** we didn't get the device name, this call will fail).
+	    */
+	    if (($VMS_STATUS_SUCCESS(status)) && ($VMS_STATUS_SUCCESS(iosb.cond))) {
+		status = lib$fid_to_name (
+                    &device_name_desc,
+                    &fib.fib$w_fid,
+                    &file_name_desc,
+                    &file_name_len,
+                    0, 0);
+
+		/*
+		** If we succeeded then remove the version number and
+		** return a copy of the UNIX format version of the file name.
+		*/
+		if ($VMS_STATUS_SUCCESS(status)) {
+		    char *p, *result;
+		    file_name[file_name_len] = 0;
+		    p = strrchr(file_name,';');
+		    if (p) *p = 0;
+		    p = decc$translate_vms(&file_name[0]);
+		    result = PR_Malloc(strlen(p)+1);
+		    if (result != NULL) {
+			strcpy(result, p);
+		    }
+		    return result;
+		}
+            }
+	}
+    }
+
+    /* Didn't find it */
+    PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
+    return NULL;
+
+#elif defined(HPUX) && defined(USE_HPSHL)
+    int index;
+    struct shl_descriptor desc;
+    char *result;
+
+    for (index = 0; shl_get_r(index, &desc) == 0; index++) {
+        if (strstr(desc.filename, name) != NULL) {
+            result = PR_Malloc(strlen(desc.filename)+1);
+            if (result != NULL) {
+                strcpy(result, desc.filename);
+            }
+            return result;
+        }
+    }
+    /*
+     * Since the index value of a library is decremented if
+     * a library preceding it in the shared library search
+     * list was unloaded, it is possible that we missed some
+     * libraries as we went up the list.  So we should go
+     * down the list to be sure that we not miss anything.
+     */
+    for (index--; index >= 0; index--) {
+        if ((shl_get_r(index, &desc) == 0)
+                && (strstr(desc.filename, name) != NULL)) {
+            result = PR_Malloc(strlen(desc.filename)+1);
+            if (result != NULL) {
+                strcpy(result, desc.filename);
+            }
+            return result;
+        }
+    }
+    PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, 0);
+    return NULL;
+#elif defined(HPUX) && defined(USE_DLFCN)
+    struct load_module_desc desc;
+    char *result;
+    const char *module_name;
+
+    if (dlmodinfo((unsigned long)addr, &desc, sizeof desc, NULL, 0, 0) == 0) {
+        PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        return NULL;
+    }
+    module_name = dlgetname(&desc, sizeof desc, NULL, 0, 0);
+    if (module_name == NULL) {
+        /* should not happen */
+        _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        return NULL;
+    }
+    result = PR_Malloc(strlen(module_name)+1);
+    if (result != NULL) {
+        strcpy(result, module_name);
+    }
+    return result;
+#elif defined(WIN32)
+    HMODULE handle;
+    char module_name[MAX_PATH];
+    char *result;
+
+    handle = GetModuleHandle(name);
+    if (handle == NULL) {
+        PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        return NULL;
+    }
+    if (GetModuleFileName(handle, module_name, sizeof module_name) == 0) {
+        /* should not happen */
+        _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
+        return NULL;
+    }
+    result = PR_Malloc(strlen(module_name)+1);
+    if (result != NULL) {
+        strcpy(result, module_name);
+    }
+    return result;
+#elif defined(XP_OS2)
+    HMODULE module = NULL;
+    char module_name[_MAX_PATH];
+    char *result;
+    APIRET ulrc = DosQueryModFromEIP(&module, NULL, 0, NULL, NULL, (ULONG) addr);
+    if ((NO_ERROR != ulrc) || (NULL == module) ) {
+        PR_SetError(PR_LIBRARY_NOT_LOADED_ERROR, _MD_ERRNO());
+        DLLErrorInternal(_MD_ERRNO());
+        return NULL;
+    }
+    ulrc = DosQueryModuleName(module, sizeof module_name, module_name);
+    if (NO_ERROR != ulrc) {
+        /* should not happen */
+        _PR_MD_MAP_DEFAULT_ERROR(_MD_ERRNO());
+        return NULL;
+    }
+    result = PR_Malloc(strlen(module_name)+1);
+    if (result != NULL) {
+        strcpy(result, module_name);
+    }
+    return result;
+#else
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+#endif
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+/.cvsignore/1.2/Sat May 12 04:22:54 2001//
+/Makefile.in/1.11/Sun Apr 25 15:00:58 2004//
+/prmalloc.c/3.8/Sun Apr 25 15:00:58 2004//
+/prmem.c/3.19/Thu Jul 21 18:22:53 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/malloc

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,67 @@
+# 
+# ***** 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 =
+endif
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES += -D_NSPR_BUILD_
+
+CSRCS = prmalloc.c prmem.c
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/prmalloc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/prmalloc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1174 @@
+/* -*- 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"
+
+/*
+** We override malloc etc. on any platform which has preemption +
+** nspr20 user level threads.  When we're debugging, we can make our
+** version of malloc fail occasionally.
+*/
+#ifdef _PR_OVERRIDE_MALLOC
+
+/*
+** Thread safe version of malloc, calloc, realloc, free
+*/
+#include <stdarg.h>
+
+#ifdef DEBUG
+#define SANITY
+#define EXTRA_SANITY
+#else
+#undef SANITY
+#undef EXTRA_SANITY
+#endif
+
+/* Forward decls */
+void *_PR_UnlockedMalloc(size_t size);
+void _PR_UnlockedFree(void *ptr);
+void *_PR_UnlockedRealloc(void *ptr, size_t size);
+void *_PR_UnlockedCalloc(size_t n, size_t elsize);
+
+/************************************************************************/
+
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk at FreeBSD.ORG> wrote this file.  As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ */
+
+/*
+ * Defining SANITY will enable some checks which will tell you if the users
+ * program did botch something
+ */
+
+/*
+ * Defining EXTRA_SANITY will enable some checks which are mostly related
+ * to internal conditions in malloc.c
+ */
+
+/*
+ * Very verbose progress on stdout...
+ */
+#if 0
+#  define TRACE(foo)    printf  foo
+static int malloc_event;
+#else
+#  define TRACE(foo)	
+#endif
+
+/* XXX Pick a number, any number */
+#   define malloc_pagesize		4096UL
+#   define malloc_pageshift		12UL
+
+#ifdef XP_UNIX
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif
+
+/*
+ * This structure describes a page's worth of chunks.
+ */
+
+struct pginfo {
+    struct pginfo	*next;	/* next on the free list */
+    char		*page;	/* Pointer to the page */
+    u_short		size;	/* size of this page's chunks */
+    u_short		shift;	/* How far to shift for this size chunks */
+    u_short		free;	/* How many free chunks */
+    u_short		total;	/* How many chunk */
+    u_long		bits[1]; /* Which chunks are free */
+};
+
+struct pgfree {
+    struct pgfree	*next;	/* next run of free pages */
+    struct pgfree	*prev;	/* prev run of free pages */
+    char		*page;	/* pointer to free pages */
+    char		*end;	/* pointer to end of free pages */
+    u_long		size;	/* number of bytes free */
+};
+
+/*
+ * How many bits per u_long in the bitmap.
+ * Change only if not 8 bits/byte
+ */
+#define	MALLOC_BITS	(8*sizeof(u_long))
+
+/*
+ * Magic values to put in the page_directory
+ */
+#define MALLOC_NOT_MINE	((struct pginfo*) 0)
+#define MALLOC_FREE 	((struct pginfo*) 1)
+#define MALLOC_FIRST	((struct pginfo*) 2)
+#define MALLOC_FOLLOW	((struct pginfo*) 3)
+#define MALLOC_MAGIC	((struct pginfo*) 4)
+
+/*
+ * Set to one when malloc_init has been called
+ */
+static	unsigned	initialized;
+
+/*
+ * The size of a page.
+ * Must be a integral multiplum of the granularity of mmap(2).
+ * Your toes will curl if it isn't a power of two
+ */
+#define malloc_pagemask	((malloc_pagesize)-1)
+
+/*
+ * The size of the largest chunk.
+ * Half a page.
+ */
+#define malloc_maxsize	((malloc_pagesize)>>1)
+
+/*
+ * malloc_pagesize == 1 << malloc_pageshift
+ */
+#ifndef malloc_pageshift
+static	unsigned	malloc_pageshift;
+#endif /* malloc_pageshift */
+
+/*
+ * The smallest allocation we bother about.
+ * Must be power of two
+ */
+#ifndef malloc_minsize
+static	unsigned  malloc_minsize;
+#endif /* malloc_minsize */
+
+/*
+ * The largest chunk we care about.
+ * Must be smaller than pagesize
+ * Must be power of two
+ */
+#ifndef malloc_maxsize
+static	unsigned  malloc_maxsize;
+#endif /* malloc_maxsize */
+
+#ifndef malloc_cache
+static	unsigned  malloc_cache;
+#endif /* malloc_cache */
+
+/*
+ * The offset from pagenumber to index into the page directory
+ */
+static	u_long  malloc_origo;
+
+/*
+ * The last index in the page directory we care about
+ */
+static	u_long  last_index;
+
+/*
+ * Pointer to page directory.
+ * Allocated "as if with" malloc
+ */
+static	struct	pginfo **page_dir;
+
+/*
+ * How many slots in the page directory
+ */
+static	unsigned	malloc_ninfo;
+
+/*
+ * Free pages line up here 
+ */
+static struct pgfree	free_list;
+
+/*
+ * Abort() if we fail to get VM ?
+ */
+static int malloc_abort;
+
+#ifdef SANITY
+/*
+ * Are we trying to die ?
+ */
+static int suicide;
+#endif
+
+/*
+ * dump statistics
+ */
+static int malloc_stats;
+
+/*
+ * always realloc ?
+ */
+static int malloc_realloc;
+
+/*
+ * my last break.
+ */
+static void *malloc_brk;
+
+/*
+ * one location cache for free-list holders
+ */
+static struct pgfree *px;
+
+static int set_pgdir(void *ptr, struct  pginfo *info);
+static int extend_page_directory(u_long index);
+
+#ifdef SANITY
+void
+malloc_dump(FILE *fd)
+{
+    struct pginfo **pd;
+    struct pgfree *pf;
+    int j;
+
+    pd = page_dir;
+
+    /* print out all the pages */
+    for(j=0;j<=last_index;j++) {
+	fprintf(fd,"%08lx %5d ",(j+malloc_origo) << malloc_pageshift,j);
+	if (pd[j] == MALLOC_NOT_MINE) {
+	    for(j++;j<=last_index && pd[j] == MALLOC_NOT_MINE;j++)
+		;
+	    j--;
+	    fprintf(fd,".. %5d not mine\n",	j);
+	} else if (pd[j] == MALLOC_FREE) {
+	    for(j++;j<=last_index && pd[j] == MALLOC_FREE;j++)
+		;
+	    j--;
+	    fprintf(fd,".. %5d free\n", j);
+	} else if (pd[j] == MALLOC_FIRST) {
+	    for(j++;j<=last_index && pd[j] == MALLOC_FOLLOW;j++)
+		;
+	    j--;
+	    fprintf(fd,".. %5d in use\n", j);
+	} else if (pd[j] < MALLOC_MAGIC) {
+	    fprintf(fd,"(%p)\n", pd[j]);
+	} else {
+	    fprintf(fd,"%p %d (of %d) x %d @ %p --> %p\n",
+		pd[j],pd[j]->free, pd[j]->total, 
+		pd[j]->size, pd[j]->page, pd[j]->next);
+	}
+    }
+
+    for(pf=free_list.next; pf; pf=pf->next) {
+	fprintf(fd,"Free: @%p [%p...%p[ %ld ->%p <-%p\n",
+		pf,pf->page,pf->end,pf->size,pf->prev,pf->next);
+	if (pf == pf->next) {
+		fprintf(fd,"Free_list loops.\n");
+		break;
+	}
+    }
+
+    /* print out various info */
+    fprintf(fd,"Minsize\t%d\n",malloc_minsize);
+    fprintf(fd,"Maxsize\t%ld\n",malloc_maxsize);
+    fprintf(fd,"Pagesize\t%ld\n",malloc_pagesize);
+    fprintf(fd,"Pageshift\t%ld\n",malloc_pageshift);
+    fprintf(fd,"FirstPage\t%ld\n",malloc_origo);
+    fprintf(fd,"LastPage\t%ld %lx\n",last_index+malloc_pageshift,
+	(last_index + malloc_pageshift) << malloc_pageshift);
+    fprintf(fd,"Break\t%ld\n",(u_long)sbrk(0) >> malloc_pageshift);
+}
+
+static void wrterror(char *fmt, ...)
+{
+    char *q = "malloc() error: ";
+    char buf[100];
+    va_list ap;
+
+    suicide = 1;
+
+    va_start(ap, fmt);
+    PR_vsnprintf(buf, sizeof(buf), fmt, ap);
+    va_end(ap);
+    fputs(q, stderr);
+    fputs(buf, stderr);
+
+    malloc_dump(stderr);
+    PR_Abort();
+}
+
+static void wrtwarning(char *fmt, ...)
+{
+    char *q = "malloc() warning: ";
+    char buf[100];
+    va_list ap;
+
+    va_start(ap, fmt);
+    PR_vsnprintf(buf, sizeof(buf), fmt, ap);
+    va_end(ap);
+    fputs(q, stderr);
+    fputs(buf, stderr);
+}
+#endif /* SANITY */
+
+
+/*
+ * Allocate a number of pages from the OS
+ */
+static caddr_t
+map_pages(int pages, int update)
+{
+    caddr_t result,tail;
+
+    result = ((caddr_t)sbrk(0)) + malloc_pagemask - 1;
+    result = (caddr_t) ((u_long)result & ~malloc_pagemask);
+    tail = result + (pages << malloc_pageshift);
+    if (!brk(tail)) {
+	last_index = ((u_long)tail >> malloc_pageshift) - malloc_origo -1;
+	malloc_brk = tail;
+	TRACE(("%6d S %p .. %p\n",malloc_event++, result, tail));
+	if (!update || last_index < malloc_ninfo ||
+	  extend_page_directory(last_index))
+	    return result;
+    }
+    TRACE(("%6d s %d %p %d\n",malloc_event++,pages,sbrk(0),errno));
+#ifdef EXTRA_SANITY
+    wrterror("map_pages fails\n");
+#endif
+    return 0;
+}
+
+#define set_bit(_pi,_bit) \
+    (_pi)->bits[(_bit)/MALLOC_BITS] |= 1L<<((_bit)%MALLOC_BITS)
+
+#define clr_bit(_pi,_bit) \
+    (_pi)->bits[(_bit)/MALLOC_BITS] &= ~(1L<<((_bit)%MALLOC_BITS));
+
+#define tst_bit(_pi,_bit) \
+    ((_pi)->bits[(_bit)/MALLOC_BITS] & (1L<<((_bit)%MALLOC_BITS)))
+
+/*
+ * Extend page directory
+ */
+static int
+extend_page_directory(u_long index)
+{
+    struct  pginfo **young, **old;
+    int i;
+
+    TRACE(("%6d E %lu\n",malloc_event++,index));
+    
+    /* Make it this many pages */
+    i = index * sizeof *page_dir;
+    i /= malloc_pagesize;
+    i += 2;
+
+    /* Get new pages, if you used this much mem you don't care :-) */
+    young = (struct pginfo**) map_pages(i,0);
+    if (!young)
+	return 0;
+
+    /* Copy the old stuff */
+    memset(young, 0, i * malloc_pagesize);
+    memcpy(young, page_dir,
+	    malloc_ninfo * sizeof *page_dir);
+
+    /* register the new size */
+    malloc_ninfo = i * malloc_pagesize / sizeof *page_dir;
+
+    /* swap the pointers */
+    old = page_dir;
+    page_dir = young;
+
+    /* Mark the pages */
+    index = ((u_long)young >> malloc_pageshift) - malloc_origo;
+    page_dir[index] = MALLOC_FIRST;
+    while (--i) {
+	page_dir[++index] = MALLOC_FOLLOW;
+    }
+
+    /* Now free the old stuff */
+    _PR_UnlockedFree(old);
+    return 1;
+}
+
+/*
+ * Set entry in page directory.
+ * Extend page directory if need be.
+ */
+static int
+set_pgdir(void *ptr, struct  pginfo *info)
+{
+    u_long index = ((u_long)ptr >> malloc_pageshift) - malloc_origo;
+
+    if (index >= malloc_ninfo && !extend_page_directory(index))
+	return 0;
+    page_dir[index] = info;
+    return 1;
+}
+
+/*
+ * Initialize the world
+ */
+static void
+malloc_init (void)
+{
+    int i;
+    char *p;
+
+    TRACE(("%6d I\n",malloc_event++));
+#ifdef DEBUG
+    for (p=getenv("MALLOC_OPTIONS"); p && *p; p++) {
+	switch (*p) {
+	    case 'a': malloc_abort = 0; break;
+	    case 'A': malloc_abort = 1; break;
+	    case 'd': malloc_stats = 0; break;
+	    case 'D': malloc_stats = 1; break;
+	    case 'r': malloc_realloc = 0; break;
+	    case 'R': malloc_realloc = 1; break;
+	    default:
+		wrtwarning("Unknown chars in MALLOC_OPTIONS\n");
+		break;
+	}
+    }
+#endif
+
+#ifndef malloc_pagesize
+    /* determine our pagesize */
+    malloc_pagesize = getpagesize();
+#endif /* malloc_pagesize */
+
+#ifndef malloc_pageshift
+    /* determine how much we shift by to get there */
+    for (i = malloc_pagesize; i > 1; i >>= 1)
+	malloc_pageshift++;
+#endif /* malloc_pageshift */
+
+#ifndef malloc_cache
+    malloc_cache = 50 << malloc_pageshift;	
+#endif /* malloc_cache */
+
+#ifndef malloc_minsize
+    /*
+     * find the smallest size allocation we will bother about.
+     * this is determined as the smallest allocation that can hold
+     * it's own pginfo;
+     */
+    i = 2;
+    for(;;) {
+	int j;
+
+	/* Figure out the size of the bits */
+	j = malloc_pagesize/i;
+	j /= 8;
+	if (j < sizeof(u_long))
+		j = sizeof (u_long);
+	if (sizeof(struct pginfo) + j - sizeof (u_long) <= i)
+		break;
+	i += i;
+    }
+    malloc_minsize = i;
+#endif /* malloc_minsize */
+
+
+    /* Allocate one page for the page directory */
+    page_dir = (struct pginfo **) map_pages(1,0);
+#ifdef SANITY
+    if (!page_dir)
+	wrterror("fatal: my first mmap failed.  (check limits ?)\n");
+#endif
+
+    /*
+     * We need a maximum of malloc_pageshift buckets, steal these from the
+     * front of the page_directory;
+     */
+    malloc_origo = (u_long) page_dir >> malloc_pageshift;
+    malloc_origo -= malloc_pageshift;
+
+    /* Clear it */
+    memset(page_dir,0,malloc_pagesize);
+
+    /* Find out how much it tells us */
+    malloc_ninfo = malloc_pagesize / sizeof *page_dir;
+
+    /* Plug the page directory into itself */
+    i = set_pgdir(page_dir,MALLOC_FIRST);
+#ifdef SANITY
+    if (!i)
+	wrterror("fatal: couldn't set myself in the page directory\n");
+#endif
+
+    /* Been here, done that */
+    initialized++;
+}
+
+/*
+ * Allocate a number of complete pages
+ */
+static void *malloc_pages(size_t size)
+{
+    void *p,*delay_free = 0;
+    int i;
+    struct pgfree *pf;
+    u_long index;
+
+    /* How many pages ? */
+    size += (malloc_pagesize-1);
+    size &= ~malloc_pagemask;
+
+    p = 0;
+    /* Look for free pages before asking for more */
+    for(pf = free_list.next; pf; pf = pf->next) {
+#ifdef EXTRA_SANITY
+	if (pf->page == pf->end)
+	    wrterror("zero entry on free_list\n");
+	if (pf->page > pf->end) {
+	    TRACE(("%6d !s %p %p %p <%d>\n",malloc_event++,
+		pf,pf->page,pf->end,__LINE__));
+	    wrterror("sick entry on free_list\n");
+	}
+	if ((void*)pf->page >= (void*)sbrk(0))
+	    wrterror("entry on free_list past brk\n");
+	if (page_dir[((u_long)pf->page >> malloc_pageshift) - malloc_origo] 
+	  != MALLOC_FREE) {
+	    TRACE(("%6d !f %p %p %p <%d>\n",malloc_event++,
+		pf,pf->page,pf->end,__LINE__));
+	    wrterror("non-free first page on free-list\n");
+	}
+	if (page_dir[((u_long)pf->end >> malloc_pageshift) - 1 - malloc_origo] 
+	  != MALLOC_FREE)
+	    wrterror("non-free last page on free-list\n");
+#endif /* EXTRA_SANITY */
+	if (pf->size < size) 
+	    continue;
+	else if (pf->size == size) {
+	    p = pf->page;
+	    if (pf->next)
+		    pf->next->prev = pf->prev;
+	    pf->prev->next = pf->next;
+	    delay_free = pf;
+	    break;
+	} else {
+	    p = pf->page;
+	    pf->page += size;
+	    pf->size -= size;
+	    break;
+        }
+    }
+#ifdef EXTRA_SANITY
+    if (p && page_dir[((u_long)p >> malloc_pageshift) - malloc_origo] 
+      != MALLOC_FREE) {
+	wrterror("allocated non-free page on free-list\n");
+    }
+#endif /* EXTRA_SANITY */
+
+    size >>= malloc_pageshift;
+
+    /* Map new pages */
+    if (!p)
+	p = map_pages(size,1);
+
+    if (p) {
+	/* Mark the pages in the directory */
+	index = ((u_long)p >> malloc_pageshift) - malloc_origo;
+	page_dir[index] = MALLOC_FIRST;
+	for (i=1;i<size;i++)
+	    page_dir[index+i] = MALLOC_FOLLOW;
+    }
+    if (delay_free) {
+	if (!px) 
+	    px = (struct pgfree*)delay_free;
+	else
+	    _PR_UnlockedFree(delay_free);
+    }
+    return p;
+}
+
+/*
+ * Allocate a page of fragments
+ */
+
+static int
+malloc_make_chunks(int bits)
+{
+    struct  pginfo *bp;
+    void *pp;
+    int i,k,l;
+
+    /* Allocate a new bucket */
+    pp = malloc_pages(malloc_pagesize);
+    if (!pp)
+	return 0;
+    l = sizeof *bp - sizeof(u_long);
+    l += sizeof(u_long) *
+	(((malloc_pagesize >> bits)+MALLOC_BITS-1) / MALLOC_BITS);
+    if ((1<<(bits)) <= l+l) {
+	bp = (struct  pginfo *)pp;
+    } else {
+	bp = (struct  pginfo *)_PR_UnlockedMalloc(l);
+    }
+    if (!bp)
+	return 0;
+    bp->size = (1<<bits);
+    bp->shift = bits;
+    bp->total = bp->free = malloc_pagesize >> bits;
+    bp->next = page_dir[bits];
+    bp->page = (char*)pp;
+    i = set_pgdir(pp,bp);
+    if (!i)
+	return 0;
+
+    /* We can safely assume that there is nobody in this chain */
+    page_dir[bits] = bp;
+
+    /* set all valid bits in the bits */
+    k = bp->total;
+    i = 0;
+/*
+    for(;k-i >= MALLOC_BITS; i += MALLOC_BITS)
+	bp->bits[i / MALLOC_BITS] = ~0;
+*/
+    for(; i < k; i++)
+	set_bit(bp,i);
+
+    if (bp != pp)
+	return 1;
+
+    /* We may have used the first ones already */
+    for(i=0;l > 0;i++) {
+	clr_bit(bp,i);
+	bp->free--;
+	bp->total--;
+	l -= (1 << bits);
+    }
+    return 1;
+}
+
+/*
+ * Allocate a fragment
+ */
+static void *malloc_bytes(size_t size)
+{
+    size_t s;
+    int j;
+    struct  pginfo *bp;
+    int k;
+    u_long *lp, bf;
+
+    /* Don't bother with anything less than this */
+    if (size < malloc_minsize) {
+	size = malloc_minsize;
+    }
+
+    /* Find the right bucket */
+    j = 1;
+    s = size - 1;
+    while (s >>= 1) {
+        j++;
+    }
+
+    /* If it's empty, make a page more of that size chunks */
+    if (!page_dir[j] && !malloc_make_chunks(j))
+	return 0;
+
+    /* Find first word of bitmap which isn't empty */
+    bp = page_dir[j];
+    for (lp = bp->bits; !*lp; lp++)
+	;
+
+    /* Find that bit */
+    bf = *lp;
+    k = 0;
+    while ((bf & 1) == 0) {
+	bf >>= 1;
+	k++;
+    }
+
+    *lp ^= 1L<<k;                       /* clear it */
+    bp->free--;
+    if (!bp->free) {
+	page_dir[j] = bp->next;
+	bp->next = 0;
+    }
+    k += (lp - bp->bits)*MALLOC_BITS;
+    return bp->page + (k << bp->shift);
+}
+
+void *_PR_UnlockedMalloc(size_t size)
+{
+    void *result;
+
+    /* Round up to a multiple of 8 bytes */
+    if (size & 7) {
+	size = size + 8 - (size & 7);
+    }
+
+    if (!initialized)
+	malloc_init();
+
+#ifdef SANITY
+    if (suicide)
+	PR_Abort();
+#endif
+
+    if (size <= malloc_maxsize)
+	result =  malloc_bytes(size);
+    else
+	result =  malloc_pages(size);
+#ifdef SANITY
+    if (malloc_abort && !result)
+	wrterror("malloc() returns NULL\n");
+#endif
+    TRACE(("%6d M %p %d\n",malloc_event++,result,size));
+
+    return result;
+}
+
+void *_PR_UnlockedMemalign(size_t alignment, size_t size)
+{
+    void *result;
+
+    /*
+     * alignment has to be a power of 2
+     */
+
+    if ((size <= alignment) && (alignment <= malloc_maxsize))
+		size = alignment;	
+    else
+           	size += alignment - 1;	
+
+    /* Round up to a multiple of 8 bytes */
+    if (size & 7) {
+	size = size + 8 - (size & 7);
+    }
+
+    if (!initialized)
+	malloc_init();
+
+#ifdef SANITY
+    if (suicide)
+	abort();
+#endif
+
+    if (size <= malloc_maxsize)
+	result =  malloc_bytes(size);
+    else
+	result =  malloc_pages(size);
+#ifdef SANITY
+    if (malloc_abort && !result)
+	wrterror("malloc() returns NULL\n");
+#endif
+    TRACE(("%6d A %p %d\n",malloc_event++,result,size));
+
+    if ((u_long)result & (alignment - 1))
+    	return ((void *)(((u_long)result + alignment)  & ~(alignment - 1)));
+    else
+    	return result;
+}
+
+void *_PR_UnlockedCalloc(size_t n, size_t nelem)
+{
+    void *p;
+
+    /* Compute total size and then round up to a double word amount */
+    n *= nelem;
+    if (n & 7) {
+	n = n + 8 - (n & 7);
+    }
+
+    /* Get the memory */
+    p = _PR_UnlockedMalloc(n);
+    if (p) {
+	/* Zero it */
+	memset(p, 0, n);
+    }
+    return p;
+}
+
+/*
+ * Change an allocation's size
+ */
+void *_PR_UnlockedRealloc(void *ptr, size_t size)
+{
+    void *p;
+    u_long osize,page,index,tmp_index;
+    struct pginfo **mp;
+
+    if (!initialized)
+	malloc_init();
+
+#ifdef SANITY
+    if (suicide)
+	PR_Abort();
+#endif
+
+    /* used as free() */
+    TRACE(("%6d R %p %d\n",malloc_event++, ptr, size));
+    if (ptr && !size) {
+	_PR_UnlockedFree(ptr);
+	return _PR_UnlockedMalloc (1);
+    }
+
+    /* used as malloc() */
+    if (!ptr) {
+	p = _PR_UnlockedMalloc(size);
+	return p;
+    }
+
+    /* Find the page directory entry for the page in question */
+    page = (u_long)ptr >> malloc_pageshift;
+    index = page - malloc_origo;
+
+    /*
+     * check if memory was allocated by memalign
+     */
+    tmp_index = index;
+    while (page_dir[tmp_index] == MALLOC_FOLLOW)
+	tmp_index--;
+    if (tmp_index != index) {
+	/*
+	 * memalign-allocated memory
+	 */
+	index = tmp_index;
+	page = index + malloc_origo;			
+	ptr = (void *) (page << malloc_pageshift);
+    }
+    TRACE(("%6d R2 %p %d\n",malloc_event++, ptr, size));
+
+    /* make sure it makes sense in some fashion */
+    if (index < malloc_pageshift || index > last_index) {
+#ifdef SANITY
+	wrtwarning("junk pointer passed to realloc()\n");
+#endif
+	return 0;
+    }
+
+    /* find the size of that allocation, and see if we need to relocate */
+    mp = &page_dir[index];
+    if (*mp == MALLOC_FIRST) {
+	osize = malloc_pagesize;
+	while (mp[1] == MALLOC_FOLLOW) {
+	    osize += malloc_pagesize;
+	    mp++;
+	}
+        if (!malloc_realloc && 
+		size < osize && 
+		size > malloc_maxsize &&
+	    size > (osize - malloc_pagesize)) {
+	    return ptr;
+	}
+    } else if (*mp >= MALLOC_MAGIC) {
+	osize = (*mp)->size;
+	if (!malloc_realloc &&
+		size < osize && 
+	    (size > (*mp)->size/2 || (*mp)->size == malloc_minsize)) {
+	    return ptr;
+	}
+    } else {
+#ifdef SANITY
+	wrterror("realloc() of wrong page.\n");
+#endif
+    }
+
+    /* try to reallocate */
+    p = _PR_UnlockedMalloc(size);
+
+    if (p) {
+	/* copy the lesser of the two sizes */
+	if (osize < size)
+	    memcpy(p,ptr,osize);
+	else
+	    memcpy(p,ptr,size);
+	_PR_UnlockedFree(ptr);
+    }
+#ifdef DEBUG
+    else if (malloc_abort)
+	wrterror("realloc() returns NULL\n");
+#endif
+
+    return p;
+}
+
+/*
+ * Free a sequence of pages
+ */
+
+static void
+free_pages(char *ptr, u_long page, int index, struct pginfo *info)
+{
+    int i;
+    struct pgfree *pf,*pt;
+    u_long l;
+    char *tail;
+
+    TRACE(("%6d FP %p %d\n",malloc_event++, ptr, page));
+    /* Is it free already ? */
+    if (info == MALLOC_FREE) {
+#ifdef SANITY
+	wrtwarning("freeing free page at %p.\n", ptr);
+#endif
+	return;
+    }
+
+#ifdef SANITY
+    /* Is it not the right place to begin ? */
+    if (info != MALLOC_FIRST)
+	wrterror("freeing wrong page.\n");
+
+    /* Is this really a pointer to a page ? */
+    if ((u_long)ptr & malloc_pagemask)
+	wrterror("freeing messed up page pointer.\n");
+#endif
+
+    /* Count how many pages it is anyway */
+    page_dir[index] = MALLOC_FREE;
+    for (i = 1; page_dir[index+i] == MALLOC_FOLLOW; i++)
+	page_dir[index + i] = MALLOC_FREE;
+
+    l = i << malloc_pageshift;
+
+    tail = ptr+l;
+
+    /* add to free-list */
+    if (!px)
+	px = (struct pgfree*)_PR_UnlockedMalloc(sizeof *pt);
+    /* XXX check success */
+    px->page = ptr;
+    px->end =  tail;
+    px->size = l;
+    if (!free_list.next) {
+	px->next = free_list.next;
+	px->prev = &free_list;
+	free_list.next = px;
+	pf = px;
+	px = 0;
+    } else {
+	tail = ptr+l;
+	for(pf = free_list.next; pf->next && pf->end < ptr; pf = pf->next)
+	    ;
+	for(; pf; pf = pf->next) {
+	    if (pf->end == ptr ) {
+		/* append to entry */
+		pf->end += l;
+		pf->size += l;
+		if (pf->next && pf->end == pf->next->page ) {
+		    pt = pf->next;
+		    pf->end = pt->end;
+		    pf->size += pt->size;
+		    pf->next = pt->next;
+		    if (pf->next)
+			pf->next->prev = pf;
+		    _PR_UnlockedFree(pt);
+		}
+	    } else if (pf->page == tail) {
+		/* prepend to entry */
+		pf->size += l;
+		pf->page = ptr;
+	    } else if (pf->page > ptr) {
+		px->next = pf;
+		px->prev = pf->prev;
+		pf->prev = px;
+		px->prev->next = px;
+		pf = px;
+		px = 0;
+	    } else if (!pf->next) {
+		px->next = 0;
+		px->prev = pf;
+		pf->next = px;
+		pf = px;
+		px = 0;
+	    } else {
+		continue;
+	    }
+	    break;
+	}
+    }
+    if (!pf->next &&
+      pf->size > malloc_cache &&
+      pf->end == malloc_brk &&
+      malloc_brk == (void*)sbrk(0)) {
+	pf->end = pf->page + malloc_cache;
+	pf->size = malloc_cache;
+	TRACE(("%6d U %p %d\n",malloc_event++,pf->end,pf->end - pf->page));
+	brk(pf->end);
+	malloc_brk = pf->end;
+	/* Find the page directory entry for the page in question */
+	page = (u_long)pf->end >> malloc_pageshift;
+	index = page - malloc_origo;
+	/* Now update the directory */
+	for(i=index;i <= last_index;)
+	    page_dir[i++] = MALLOC_NOT_MINE;
+	last_index = index - 1;
+    }
+}
+
+/*
+ * Free a chunk, and possibly the page it's on, if the page becomes empty.
+ */
+
+static void
+free_bytes(void *ptr, u_long page, int index, struct pginfo *info)
+{
+    int i;
+    struct pginfo **mp;
+    void *vp;
+
+    /* Make sure that pointer is multiplum of chunk-size */
+#ifdef SANITY
+    if ((u_long)ptr & (info->size - 1))
+	wrterror("freeing messed up chunk pointer\n");
+#endif
+
+    /* Find the chunk number on the page */
+    i = ((u_long)ptr & malloc_pagemask) >> info->shift;
+
+    /* See if it's free already */
+    if (tst_bit(info,i)) {
+#ifdef SANITY
+	wrtwarning("freeing free chunk at %p\n", ptr);
+#endif
+	return;
+    }
+
+    /* Mark it free */
+    set_bit(info,i);
+    info->free++;
+
+    /* If the page was full before, we need to put it on the queue now */
+    if (info->free == 1) {
+	mp = page_dir + info->shift;
+	while (*mp && (*mp)->next && (*mp)->next->page < info->page)
+	    mp = &(*mp)->next;
+	info->next = *mp;
+	*mp = info;
+	return;
+    }
+
+    /* If this page isn't empty, don't do anything. */
+    if (info->free != info->total)
+	return;
+
+    /* We may want to keep at least one page of each size chunks around.  */
+    mp = page_dir + info->shift;
+    if (0 && (*mp == info) && !info->next)
+	return;
+
+    /* Find & remove this page in the queue */
+    while (*mp != info) {
+	mp = &((*mp)->next);
+#ifdef EXTRA_SANITY
+	if (!*mp) {
+		TRACE(("%6d !q %p\n",malloc_event++,info));
+		wrterror("Not on queue\n");
+	}
+#endif
+    }
+    *mp = info->next;
+
+    /* Free the page & the info structure if need be */
+    set_pgdir(info->page,MALLOC_FIRST);
+    if((void*)info->page == (void*)info) {
+	_PR_UnlockedFree(info->page);
+    } else {
+	vp = info->page;
+	_PR_UnlockedFree(info);
+	_PR_UnlockedFree(vp);
+    }
+}
+
+void _PR_UnlockedFree(void *ptr)
+{
+    u_long page;
+    struct pginfo *info;
+    int index, tmp_index;
+
+    TRACE(("%6d F %p\n",malloc_event++,ptr));
+    /* This is legal */
+    if (!ptr)
+	return;
+
+#ifdef SANITY
+    /* There wouldn't be anything to free */
+    if (!initialized) {
+	wrtwarning("free() called before malloc() ever got called\n");
+	return;
+    }
+#endif
+
+#ifdef SANITY
+    if (suicide)
+	PR_Abort();
+#endif
+
+    /* Find the page directory entry for the page in question */
+    page = (u_long)ptr >> malloc_pageshift;
+    index = page - malloc_origo;
+
+    /*
+     * check if memory was allocated by memalign
+     */
+    tmp_index = index;
+    while (page_dir[tmp_index] == MALLOC_FOLLOW)
+	tmp_index--;
+    if (tmp_index != index) {
+	/*
+	 * memalign-allocated memory
+	 */
+	index = tmp_index;
+	page = index + malloc_origo;			
+	ptr = (void *) (page << malloc_pageshift);
+    }
+    /* make sure it makes sense in some fashion */
+    if (index < malloc_pageshift) {
+#ifdef SANITY
+	wrtwarning("junk pointer %p (low) passed to free()\n", ptr);
+#endif
+	return;
+    }
+    if (index > last_index) {
+#ifdef SANITY
+	wrtwarning("junk pointer %p (high) passed to free()\n", ptr);
+#endif
+	return;
+    }
+
+    /* handle as page-allocation or chunk allocation */
+    info = page_dir[index];
+    if (info < MALLOC_MAGIC)
+        free_pages((char*)ptr, page, index, info);
+    else 
+	free_bytes(ptr,page,index,info);
+    return;
+}
+#endif /* _PR_OVERRIDE_MALLOC */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/prmem.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/malloc/prmem.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,726 @@
+/* -*- 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 ***** */
+
+/*
+** Thread safe versions of malloc, free, realloc, calloc and cfree.
+*/
+
+#include "primpl.h"
+
+#ifdef _PR_ZONE_ALLOCATOR
+
+/*
+** The zone allocator code must use native mutexes and cannot
+** use PRLocks because PR_NewLock calls PR_Calloc, resulting
+** in cyclic dependency of initialization.
+*/
+
+#include <string.h>	
+
+union memBlkHdrUn;
+
+typedef struct MemoryZoneStr {
+    union memBlkHdrUn    *head;         /* free list */
+    pthread_mutex_t       lock;
+    size_t                blockSize;    /* size of blocks on this free list */
+    PRUint32              locked;       /* current state of lock */
+    PRUint32              contention;   /* counter: had to wait for lock */
+    PRUint32              hits;         /* allocated from free list */
+    PRUint32              misses;       /* had to call malloc */
+    PRUint32              elements;     /* on free list */
+} MemoryZone;
+
+typedef union memBlkHdrUn {
+    unsigned char filler[48];  /* fix the size of this beast */
+    struct memBlkHdrStr {
+        union memBlkHdrUn    *next;
+        MemoryZone           *zone;
+        size_t                blockSize;
+        size_t                requestedSize;
+        PRUint32              magic;
+    } s;
+} MemBlockHdr;
+
+#define MEM_ZONES     7
+#define THREAD_POOLS 11  /* prime number for modulus */
+#define ZONE_MAGIC  0x0BADC0DE
+
+static MemoryZone zones[MEM_ZONES][THREAD_POOLS];
+
+static PRBool use_zone_allocator = PR_FALSE;
+
+static void pr_ZoneFree(void *ptr);
+
+void
+_PR_DestroyZones(void)
+{   
+    int i, j;
+
+    if (!use_zone_allocator)
+        return;
+    
+    for (j = 0; j < THREAD_POOLS; j++) {
+        for (i = 0; i < MEM_ZONES; i++) {
+            MemoryZone *mz = &zones[i][j];
+            pthread_mutex_destroy(&mz->lock);
+            while (mz->head) {
+                MemBlockHdr *hdr = mz->head;
+                mz->head = hdr->s.next;  /* unlink it */
+                free(hdr);
+                mz->elements--;
+            }
+        }
+    } 
+    use_zone_allocator = PR_FALSE;
+} 
+
+/*
+** pr_FindSymbolInProg
+**
+** Find the specified data symbol in the program and return
+** its address.
+*/
+
+#ifdef HAVE_DLL
+
+#ifdef USE_DLFCN
+
+#include <dlfcn.h>
+
+static void *
+pr_FindSymbolInProg(const char *name)
+{
+    void *h;
+    void *sym;
+
+    h = dlopen(0, RTLD_LAZY);
+    if (h == NULL)
+        return NULL;
+    sym = dlsym(h, name);
+    (void)dlclose(h);
+    return sym;
+}
+
+#elif defined(USE_HPSHL)
+
+#include <dl.h>
+
+static void *
+pr_FindSymbolInProg(const char *name)
+{
+    shl_t h = NULL;
+    void *sym;
+
+    if (shl_findsym(&h, name, TYPE_DATA, &sym) == -1)
+        return NULL;
+    return sym;
+}
+
+#elif defined(USE_MACH_DYLD)
+
+static void *
+pr_FindSymbolInProg(const char *name)
+{
+    /* FIXME: not implemented */
+    return NULL;
+}
+
+#else
+
+#error "The zone allocator is not supported on this platform"
+
+#endif
+
+#else /* !defined(HAVE_DLL) */
+
+static void *
+pr_FindSymbolInProg(const char *name)
+{
+    /* can't be implemented */
+    return NULL;
+}
+
+#endif /* HAVE_DLL */
+
+void
+_PR_InitZones(void)
+{
+    int i, j;
+    char *envp;
+    PRBool *sym;
+
+    if ((sym = (PRBool *)pr_FindSymbolInProg("nspr_use_zone_allocator")) != NULL) {
+        use_zone_allocator = *sym;
+    } else if ((envp = getenv("NSPR_USE_ZONE_ALLOCATOR")) != NULL) {
+        use_zone_allocator = (atoi(envp) == 1);
+    }
+
+    if (!use_zone_allocator)
+        return;
+
+    for (j = 0; j < THREAD_POOLS; j++) { 
+        for (i = 0; i < MEM_ZONES; i++) {
+            MemoryZone *mz = &zones[i][j];
+            int rv = pthread_mutex_init(&mz->lock, NULL);
+            PR_ASSERT(0 == rv);
+            if (rv != 0) {
+                goto loser;
+            } 
+            mz->blockSize = 16 << ( 2 * i);
+        }
+    }
+    return;
+
+loser:
+    _PR_DestroyZones();
+    return;
+}
+
+PR_IMPLEMENT(void)
+PR_FPrintZoneStats(PRFileDesc *debug_out)
+{
+    int i, j;
+
+    for (j = 0; j < THREAD_POOLS; j++) {
+        for (i = 0; i < MEM_ZONES; i++) {
+            MemoryZone   *mz   = &zones[i][j];
+            MemoryZone    zone = *mz;
+            if (zone.elements || zone.misses || zone.hits) {
+                PR_fprintf(debug_out,
+"pool: %d, zone: %d, size: %d, free: %d, hit: %d, miss: %d, contend: %d\n",
+                    j, i, zone.blockSize, zone.elements,
+                    zone.hits, zone.misses, zone.contention);
+            }
+	}
+    }
+}
+
+static void *
+pr_ZoneMalloc(PRUint32 size)
+{
+    void         *rv;
+    unsigned int  zone;
+    size_t        blockSize;
+    MemBlockHdr  *mb, *mt;
+    MemoryZone   *mz;
+
+    /* Always allocate a non-zero amount of bytes */
+    if (size < 1) {
+        size = 1;
+    }
+    for (zone = 0, blockSize = 16; zone < MEM_ZONES; ++zone, blockSize <<= 2) {
+        if (size <= blockSize) {
+            break;
+        }
+    }
+    if (zone < MEM_ZONES) {
+        pthread_t me = pthread_self();
+        unsigned int pool = (PRUptrdiff)me % THREAD_POOLS;
+        PRUint32     wasLocked;
+        mz = &zones[zone][pool];
+        wasLocked = mz->locked;
+        pthread_mutex_lock(&mz->lock);
+        mz->locked = 1;
+        if (wasLocked)
+            mz->contention++;
+        if (mz->head) {
+            mb = mz->head;
+            PR_ASSERT(mb->s.magic == ZONE_MAGIC);
+            PR_ASSERT(mb->s.zone  == mz);
+            PR_ASSERT(mb->s.blockSize == blockSize);
+            PR_ASSERT(mz->blockSize == blockSize);
+
+            mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);
+            PR_ASSERT(mt->s.magic == ZONE_MAGIC);
+            PR_ASSERT(mt->s.zone  == mz);
+            PR_ASSERT(mt->s.blockSize == blockSize);
+
+            mz->hits++;
+            mz->elements--;
+            mz->head = mb->s.next;    /* take off free list */
+            mz->locked = 0;
+            pthread_mutex_unlock(&mz->lock);
+
+            mt->s.next          = mb->s.next          = NULL;
+            mt->s.requestedSize = mb->s.requestedSize = size;
+
+            rv = (void *)(mb + 1);
+            return rv;
+        }
+
+        mz->misses++;
+        mz->locked = 0;
+        pthread_mutex_unlock(&mz->lock);
+
+        mb = (MemBlockHdr *)malloc(blockSize + 2 * (sizeof *mb));
+        if (!mb) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return NULL;
+        }
+        mb->s.next          = NULL;
+        mb->s.zone          = mz;
+        mb->s.magic         = ZONE_MAGIC;
+        mb->s.blockSize     = blockSize;
+        mb->s.requestedSize = size;
+
+        mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);
+        memcpy(mt, mb, sizeof *mb);
+
+        rv = (void *)(mb + 1);
+        return rv;
+    }
+
+    /* size was too big.  Create a block with no zone */
+    blockSize = (size & 15) ? size + 16 - (size & 15) : size;
+    mb = (MemBlockHdr *)malloc(blockSize + 2 * (sizeof *mb));
+    if (!mb) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    mb->s.next          = NULL;
+    mb->s.zone          = NULL;
+    mb->s.magic         = ZONE_MAGIC;
+    mb->s.blockSize     = blockSize;
+    mb->s.requestedSize = size;
+
+    mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);
+    memcpy(mt, mb, sizeof *mb);
+
+    rv = (void *)(mb + 1);
+    return rv;
+}
+
+
+static void *
+pr_ZoneCalloc(PRUint32 nelem, PRUint32 elsize)
+{
+    PRUint32 size = nelem * elsize;
+    void *p = pr_ZoneMalloc(size);
+    if (p) {
+        memset(p, 0, size);
+    }
+    return p;
+}
+
+static void *
+pr_ZoneRealloc(void *oldptr, PRUint32 bytes)
+{
+    void         *rv;
+    MemBlockHdr  *mb;
+    int           ours;
+    MemBlockHdr   phony;
+
+    if (!oldptr)
+        return pr_ZoneMalloc(bytes);
+    mb = (MemBlockHdr *)((char *)oldptr - (sizeof *mb));
+    if (mb->s.magic != ZONE_MAGIC) {
+        /* Maybe this just came from ordinary malloc */
+#ifdef DEBUG
+        fprintf(stderr,
+            "Warning: reallocing memory block %p from ordinary malloc\n",
+            oldptr);
+#endif
+        /*
+         * We are going to realloc oldptr.  If realloc succeeds, the
+         * original value of oldptr will point to freed memory.  So this
+         * function must not fail after a successfull realloc call.  We
+         * must perform any operation that may fail before the realloc
+         * call.
+         */
+        rv = pr_ZoneMalloc(bytes);  /* this may fail */
+        if (!rv) {
+            return rv;
+        }
+
+        /* We don't know how big it is.  But we can fix that. */
+        oldptr = realloc(oldptr, bytes);
+        /*
+         * If realloc returns NULL, this function loses the original
+         * value of oldptr.  This isn't a leak because the caller of
+         * this function still has the original value of oldptr.
+         */
+        if (!oldptr) {
+            if (bytes) {
+                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                pr_ZoneFree(rv);
+                return oldptr;
+            }
+        }
+        phony.s.requestedSize = bytes;
+        mb = &phony;
+        ours = 0;
+    } else {
+        size_t blockSize = mb->s.blockSize;
+        MemBlockHdr *mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);
+
+        PR_ASSERT(mt->s.magic == ZONE_MAGIC);
+        PR_ASSERT(mt->s.zone  == mb->s.zone);
+        PR_ASSERT(mt->s.blockSize == blockSize);
+	
+        if (bytes <= blockSize) {
+            /* The block is already big enough. */
+            mt->s.requestedSize = mb->s.requestedSize = bytes;
+            return oldptr;
+        }
+        ours = 1;
+        rv = pr_ZoneMalloc(bytes);
+        if (!rv) {
+            return rv;
+        }
+    }
+    
+    if (oldptr && mb->s.requestedSize)
+        memcpy(rv, oldptr, mb->s.requestedSize);
+    if (ours)
+        pr_ZoneFree(oldptr);
+    else if (oldptr)
+        free(oldptr);
+    return rv;
+}
+
+static void
+pr_ZoneFree(void *ptr)
+{
+    MemBlockHdr  *mb, *mt;
+    MemoryZone   *mz;
+    size_t        blockSize;
+    PRUint32      wasLocked;
+
+    if (!ptr)
+        return;
+
+    mb = (MemBlockHdr *)((char *)ptr - (sizeof *mb));
+
+    if (mb->s.magic != ZONE_MAGIC) {
+        /* maybe this came from ordinary malloc */
+#ifdef DEBUG
+        fprintf(stderr,
+            "Warning: freeing memory block %p from ordinary malloc\n", ptr);
+#endif
+        free(ptr);
+        return;
+    }
+
+    blockSize = mb->s.blockSize;
+    mz        = mb->s.zone;
+    mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);
+    PR_ASSERT(mt->s.magic == ZONE_MAGIC);
+    PR_ASSERT(mt->s.zone  == mz);
+    PR_ASSERT(mt->s.blockSize == blockSize);
+    if (!mz) {
+        PR_ASSERT(blockSize > 65536);
+        /* This block was not in any zone.  Just free it. */
+        free(mb);
+        return;
+    }
+    PR_ASSERT(mz->blockSize == blockSize);
+    wasLocked = mz->locked;
+    pthread_mutex_lock(&mz->lock);
+    mz->locked = 1;
+    if (wasLocked)
+        mz->contention++;
+    mt->s.next = mb->s.next = mz->head;        /* put on head of list */
+    mz->head = mb;
+    mz->elements++;
+    mz->locked = 0;
+    pthread_mutex_unlock(&mz->lock);
+}
+
+PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    return use_zone_allocator ? pr_ZoneMalloc(size) : malloc(size);
+}
+
+PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    return use_zone_allocator ?
+        pr_ZoneCalloc(nelem, elsize) : calloc(nelem, elsize);
+}
+
+PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    return use_zone_allocator ? pr_ZoneRealloc(ptr, size) : realloc(ptr, size);
+}
+
+PR_IMPLEMENT(void) PR_Free(void *ptr)
+{
+    if (use_zone_allocator)
+        pr_ZoneFree(ptr);
+    else
+        free(ptr);
+}
+
+#else /* !defined(_PR_ZONE_ALLOCATOR) */
+
+/*
+** The PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free functions simply
+** call their libc equivalents now.  This may seem redundant, but it
+** ensures that we are calling into the same runtime library.  On
+** Win32, it is possible to have multiple runtime libraries (e.g.,
+** objects compiled with /MD and /MDd) in the same process, and
+** they maintain separate heaps, which cannot be mixed.
+*/
+PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size)
+{
+#if defined (WIN16)
+    return PR_MD_malloc( (size_t) size);
+#else
+    return malloc(size);
+#endif
+}
+
+PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize)
+{
+#if defined (WIN16)
+    return PR_MD_calloc( (size_t)nelem, (size_t)elsize );
+    
+#else
+    return calloc(nelem, elsize);
+#endif
+}
+
+PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size)
+{
+#if defined (WIN16)
+    return PR_MD_realloc( ptr, (size_t) size);
+#else
+    return realloc(ptr, size);
+#endif
+}
+
+PR_IMPLEMENT(void) PR_Free(void *ptr)
+{
+#if defined (WIN16)
+    PR_MD_free( ptr );
+#else
+    free(ptr);
+#endif
+}
+
+#endif /* _PR_ZONE_ALLOCATOR */
+
+/*
+** Complexity alert!
+**
+** If malloc/calloc/free (etc.) were implemented to use pr lock's then
+** the entry points could block when called if some other thread had the
+** lock.
+**
+** Most of the time this isn't a problem. However, in the case that we
+** are using the thread safe malloc code after PR_Init but before
+** PR_AttachThread has been called (on a native thread that nspr has yet
+** to be told about) we could get royally screwed if the lock was busy
+** and we tried to context switch the thread away. In this scenario
+** 	PR_CURRENT_THREAD() == NULL
+**
+** To avoid this unfortunate case, we use the low level locking
+** facilities for malloc protection instead of the slightly higher level
+** locking. This makes malloc somewhat faster so maybe it's a good thing
+** anyway.
+*/
+#ifdef _PR_OVERRIDE_MALLOC
+
+/* Imports */
+extern void *_PR_UnlockedMalloc(size_t size);
+extern void *_PR_UnlockedMemalign(size_t alignment, size_t size);
+extern void _PR_UnlockedFree(void *ptr);
+extern void *_PR_UnlockedRealloc(void *ptr, size_t size);
+extern void *_PR_UnlockedCalloc(size_t n, size_t elsize);
+
+static PRBool _PR_malloc_initialised = PR_FALSE;
+
+#ifdef _PR_PTHREADS
+static pthread_mutex_t _PR_MD_malloc_crustylock;
+
+#define _PR_Lock_Malloc() {						\
+    				if(PR_TRUE == _PR_malloc_initialised) { \
+					PRStatus rv;			\
+					rv = pthread_mutex_lock(&_PR_MD_malloc_crustylock); \
+					PR_ASSERT(0 == rv);		\
+				}
+
+#define _PR_Unlock_Malloc() 	if(PR_TRUE == _PR_malloc_initialised) { \
+					PRStatus rv;			\
+					rv = pthread_mutex_unlock(&_PR_MD_malloc_crustylock); \
+					PR_ASSERT(0 == rv);		\
+				}					\
+			  }
+#else /* _PR_PTHREADS */
+static _MDLock _PR_MD_malloc_crustylock;
+
+#ifdef IRIX
+#define _PR_Lock_Malloc() {						\
+			   PRIntn _is;					\
+    				if(PR_TRUE == _PR_malloc_initialised) { \
+				if (_PR_MD_GET_ATTACHED_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_PR_MD_GET_ATTACHED_THREAD()))	\
+						_PR_INTSOFF(_is); 	\
+					_PR_MD_LOCK(&_PR_MD_malloc_crustylock); \
+				}
+
+#define _PR_Unlock_Malloc() 	if(PR_TRUE == _PR_malloc_initialised) { \
+					_PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \
+				if (_PR_MD_GET_ATTACHED_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_PR_MD_GET_ATTACHED_THREAD()))	\
+						_PR_INTSON(_is);	\
+				}					\
+			  }
+#else	/* IRIX */
+#define _PR_Lock_Malloc() {						\
+			   PRIntn _is;					\
+    				if(PR_TRUE == _PR_malloc_initialised) { \
+				if (_PR_MD_CURRENT_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_PR_MD_CURRENT_THREAD()))	\
+						_PR_INTSOFF(_is); 	\
+					_PR_MD_LOCK(&_PR_MD_malloc_crustylock); \
+				}
+
+#define _PR_Unlock_Malloc() 	if(PR_TRUE == _PR_malloc_initialised) { \
+					_PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \
+				if (_PR_MD_CURRENT_THREAD() && 		\
+					!_PR_IS_NATIVE_THREAD( 		\
+					_PR_MD_CURRENT_THREAD()))	\
+						_PR_INTSON(_is);	\
+				}					\
+			  }
+#endif	/* IRIX	*/
+#endif /* _PR_PTHREADS */
+
+PR_IMPLEMENT(PRStatus) _PR_MallocInit(void)
+{
+    PRStatus rv = PR_SUCCESS;
+
+    if( PR_TRUE == _PR_malloc_initialised ) return PR_SUCCESS;
+
+#ifdef _PR_PTHREADS
+    {
+	int status;
+	pthread_mutexattr_t mattr;
+
+	status = _PT_PTHREAD_MUTEXATTR_INIT(&mattr);
+	PR_ASSERT(0 == status);
+	status = _PT_PTHREAD_MUTEX_INIT(_PR_MD_malloc_crustylock, mattr);
+	PR_ASSERT(0 == status);
+	status = _PT_PTHREAD_MUTEXATTR_DESTROY(&mattr);
+	PR_ASSERT(0 == status);
+    }
+#else /* _PR_PTHREADS */
+    _MD_NEW_LOCK(&_PR_MD_malloc_crustylock);
+#endif /* _PR_PTHREADS */
+
+    if( PR_SUCCESS == rv )
+    {
+        _PR_malloc_initialised = PR_TRUE;
+    }
+
+    return rv;
+}
+
+void *malloc(size_t size)
+{
+    void *p;
+    _PR_Lock_Malloc();
+    p = _PR_UnlockedMalloc(size);
+    _PR_Unlock_Malloc();
+    return p;
+}
+
+#if defined(IRIX)
+void *memalign(size_t alignment, size_t size)
+{
+    void *p;
+    _PR_Lock_Malloc();
+    p = _PR_UnlockedMemalign(alignment, size);
+    _PR_Unlock_Malloc();
+    return p;
+}
+
+void *valloc(size_t size)
+{
+    return(memalign(sysconf(_SC_PAGESIZE),size));
+}
+#endif	/* IRIX */
+
+void free(void *ptr)
+{
+    _PR_Lock_Malloc();
+    _PR_UnlockedFree(ptr);
+    _PR_Unlock_Malloc();
+}
+
+void *realloc(void *ptr, size_t size)
+{
+    void *p;
+    _PR_Lock_Malloc();
+    p = _PR_UnlockedRealloc(ptr, size);
+    _PR_Unlock_Malloc();
+    return p;
+}
+
+void *calloc(size_t n, size_t elsize)
+{
+    void *p;
+    _PR_Lock_Malloc();
+    p = _PR_UnlockedCalloc(n, elsize);
+    _PR_Unlock_Malloc();
+    return p;
+}
+
+void cfree(void *p)
+{
+    _PR_Lock_Malloc();
+    _PR_UnlockedFree(p);
+    _PR_Unlock_Malloc();
+}
+
+void _PR_InitMem(void)
+{
+    PRStatus rv;
+    rv = _PR_MallocInit();
+    PR_ASSERT(PR_SUCCESS == rv);
+}
+
+#endif /* _PR_OVERRIDE_MALLOC */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4 @@
+/.cvsignore/1.2/Sat May 12 04:24:53 2001//
+/Makefile.in/1.12/Sun Apr 25 15:00:58 2004//
+/prosdep.c/3.12/Sat Dec 24 08:25:29 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+A D/beos////
+A D/mac////
+A D/os2////
+A D/unix////
+A D/windows////

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/md

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,64 @@
+# 
+# ***** 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
+
+DIRS = $(PR_MD_ARCH_DIR)
+
+CSRCS =          \
+	prosdep.c \
+	$(NULL)
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,17 @@
+/.cvsignore/1.2/Sat May 12 06:08:09 2001//
+/Makefile.in/1.10/Sun Apr 25 15:00:59 2004//
+/bcpu.c/3.6/Sun Apr 25 15:00:59 2004//
+/beos.c/3.5/Sun Apr 25 15:00:59 2004//
+/beos_errors.c/3.8/Wed Mar  9 22:57:05 2005//
+/bfile.c/3.15/Wed Mar  9 22:57:05 2005//
+/bmemory.c/3.5/Sun Apr 25 15:00:59 2004//
+/bmisc.c/3.6/Sun Apr 25 15:00:59 2004//
+/bmmap.c/3.7/Sun Apr 25 15:00:59 2004//
+/bnet.c/3.15/Sun Apr 25 15:00:59 2004//
+/bproc.c/3.6/Sun Apr 25 15:00:59 2004//
+/brng.c/3.4/Wed Aug 30 16:59:51 2000//
+/bseg.c/3.6/Sun Apr 25 15:00:59 2004//
+/bsrcs.mk/3.6/Sun Apr 25 15:00:59 2004//
+/btime.c/3.5/Sun Apr 25 15:00:59 2004//
+/objs.mk/3.6/Sun Apr 25 15:00:59 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/md/beos

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,60 @@
+# 
+# ***** 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
+
+include $(srcdir)/bsrcs.mk
+CSRCS += $(MDCSRCS)
+
+TARGETS		= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bcpu.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bcpu.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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"
+
+PR_EXTERN(void) _PR_MD_INIT_CPUS();
+PR_EXTERN(void) _PR_MD_WAKEUP_CPUS();
+PR_EXTERN(void) _PR_MD_START_INTERRUPTS(void);
+PR_EXTERN(void) _PR_MD_STOP_INTERRUPTS(void);
+PR_EXTERN(void) _PR_MD_DISABLE_CLOCK_INTERRUPTS(void);
+PR_EXTERN(void) _PR_MD_BLOCK_CLOCK_INTERRUPTS(void);
+PR_EXTERN(void) _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(void);
+PR_EXTERN(void) _PR_MD_CLOCK_INTERRUPT(void);
+PR_EXTERN(void) _PR_MD_INIT_STACK(PRThreadStack *ts, PRIntn redzone);
+PR_EXTERN(void) _PR_MD_CLEAR_STACK(PRThreadStack* ts);
+PR_EXTERN(PRInt32) _PR_MD_GET_INTSOFF(void);
+PR_EXTERN(void) _PR_MD_SET_INTSOFF(PRInt32 _val);
+PR_EXTERN(_PRCPU*) _PR_MD_CURRENT_CPU(void);
+PR_EXTERN(void) _PR_MD_SET_CURRENT_CPU(_PRCPU *cpu);
+PR_EXTERN(void) _PR_MD_INIT_RUNNING_CPU(_PRCPU *cpu);
+PR_EXTERN(PRInt32) _PR_MD_PAUSE_CPU(PRIntervalTime timeout);

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/beos.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/beos.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,264 @@
+/* -*- 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 <signal.h>
+#include <unistd.h>
+#include <memory.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+/*
+ * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or
+ * PRInt32* pointer to a _PRSockLen_t* pointer.
+ */
+#define _PRSockLen_t int
+
+/*
+** Global lock variable used to bracket calls into rusty libraries that
+** aren't thread safe (like libc, libX, etc).
+*/
+static PRLock *_pr_rename_lock = NULL;
+static PRMonitor *_pr_Xfe_mon = NULL;
+
+/*
+ * Variables used by the GC code, initialized in _MD_InitSegs().
+ * _pr_zero_fd should be a static variable.  Unfortunately, there is
+ * still some Unix-specific code left in function PR_GrowSegment()
+ * in file memory/prseg.c that references it, so it needs
+ * to be a global variable for now.
+ */
+PRInt32 _pr_zero_fd = -1;
+static PRLock *_pr_md_lock = NULL;
+
+sigset_t timer_set;
+
+void _PR_UnixInit()
+{
+	struct sigaction sigact;
+	int rv;
+
+	sigemptyset(&timer_set);
+
+	sigact.sa_handler = SIG_IGN;
+	sigemptyset(&sigact.sa_mask);
+	sigact.sa_flags = 0;
+	rv = sigaction(SIGPIPE, &sigact, 0);
+	PR_ASSERT(0 == rv);
+
+	_pr_rename_lock = PR_NewLock();
+	PR_ASSERT(NULL != _pr_rename_lock);
+	_pr_Xfe_mon = PR_NewMonitor();
+	PR_ASSERT(NULL != _pr_Xfe_mon);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_Now --
+ *
+ *     Returns the current time in microseconds since the epoch.
+ *     The epoch is midnight January 1, 1970 GMT.
+ *     The implementation is machine dependent.  This is the Unix
+ *     implementation.
+ *     Cf. time_t time(time_t *tp)
+ *
+ *-----------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRTime)
+PR_Now(void)
+{
+	struct timeval tv;
+	PRInt64 s, us, s2us;
+
+	GETTIMEOFDAY(&tv);
+	LL_I2L(s2us, PR_USEC_PER_SEC);
+	LL_I2L(s, tv.tv_sec);
+	LL_I2L(us, tv.tv_usec);
+	LL_MUL(s, s, s2us);
+	LL_ADD(s, s, us);
+	return s;
+}
+
+PRIntervalTime
+_PR_UNIX_GetInterval()
+{
+	struct timeval time;
+	PRIntervalTime ticks;
+
+	(void)GETTIMEOFDAY(&time);  /* fallicy of course */
+	ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
+	ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC;  /* so's that */
+	return ticks;
+}  /* _PR_SUNOS_GetInterval */
+
+PRIntervalTime _PR_UNIX_TicksPerSecond()
+{
+	return 1000;  /* this needs some work :) */
+}
+
+/************************************************************************/
+
+/*
+** Special hacks for xlib. Xlib/Xt/Xm is not re-entrant nor is it thread
+** safe.  Unfortunately, neither is mozilla. To make these programs work
+** in a pre-emptive threaded environment, we need to use a lock.
+*/
+
+void PR_XLock()
+{
+	PR_EnterMonitor(_pr_Xfe_mon);
+}
+
+void PR_XUnlock()
+{
+	PR_ExitMonitor(_pr_Xfe_mon);
+}
+
+PRBool PR_XIsLocked()
+{
+	return (PR_InMonitor(_pr_Xfe_mon)) ? PR_TRUE : PR_FALSE;
+}
+
+void PR_XWait(int ms)
+{
+	PR_Wait(_pr_Xfe_mon, PR_MillisecondsToInterval(ms));
+}
+
+void PR_XNotify(void)
+{
+	PR_Notify(_pr_Xfe_mon);
+}
+
+void PR_XNotifyAll(void)
+{
+	PR_NotifyAll(_pr_Xfe_mon);
+}
+
+#if !defined(BEOS)
+#ifdef HAVE_BSD_FLOCK
+
+#include <sys/file.h>
+
+PR_IMPLEMENT(PRStatus)
+_MD_LOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = flock(f, LOCK_EX);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_TLOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = flock(f, LOCK_EX|LOCK_NB);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_UNLOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = flock(f, LOCK_UN);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+#else
+
+PR_IMPLEMENT(PRStatus)
+_MD_LOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = lockf(f, F_LOCK, 0);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_TLOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = lockf(f, F_TLOCK, 0);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_UNLOCKFILE (PRInt32 f)
+{
+	PRInt32 rv;
+	rv = lockf(f, F_ULOCK, 0);
+	if (rv == 0)
+		return PR_SUCCESS;
+	_PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+	return PR_FAILURE;
+}
+#endif
+
+PR_IMPLEMENT(PRStatus)
+  _MD_GETHOSTNAME (char *name, PRUint32 namelen)
+{
+    PRIntn rv;
+
+    rv = gethostname(name, namelen);
+    if (0 == rv) {
+		return PR_SUCCESS;
+    }
+	_PR_MD_MAP_GETHOSTNAME_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+#endif

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/beos_errors.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/beos_errors.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1526 @@
+/* -*- 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 "prtypes.h"
+#include "md/_unix_errors.h"
+#include "prerror.h"
+#include <errno.h>
+
+void _MD_unix_map_opendir_error(int err)
+{
+	switch (err) {
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EMFILE:
+			PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ENFILE:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_closedir_error(int err)
+{
+	switch (err) {
+		case EINVAL:
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_readdir_error(int err)
+{
+
+	switch (err) {
+		case 0:
+		case ENOENT:
+			PR_SetError(PR_NO_MORE_FILES_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#ifdef IRIX
+#ifdef IRIX5_3
+#else
+		case EDIRCORRUPTED:
+			PR_SetError(PR_DIRECTORY_CORRUPTED_ERROR, err);
+			break;
+#endif
+#endif
+#ifdef EOVERFLOW
+		case EOVERFLOW:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+#endif
+		case EINVAL:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+#ifdef EBADMSG
+		case EBADMSG:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+#endif
+		case EDEADLK:
+			PR_SetError(PR_DEADLOCK_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ENOLCK:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+#ifdef ENOLINK
+		case ENOLINK:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+#endif
+		case ENXIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_unlink_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EBUSY:
+			PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EPERM:
+			PR_SetError(PR_IS_DIRECTORY_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_stat_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+#ifdef EOVERFLOW
+		case EOVERFLOW:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_fstat_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ETIMEDOUT:
+#ifdef ENOLINK
+		case ENOLINK:
+#endif
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+#ifdef EOVERFLOW
+		case EOVERFLOW:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_rename_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EBUSY:
+			PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err);
+			break;
+#ifdef EDQUOT
+		case EDQUOT:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+#endif
+		case EEXIST:
+			PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case EISDIR:
+			PR_SetError(PR_IS_DIRECTORY_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOSPC:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		case EXDEV:
+			PR_SetError(PR_NOT_SAME_DEVICE_ERROR, err);
+			break;
+		case EMLINK:
+			PR_SetError(PR_MAX_DIRECTORY_ENTRIES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_access_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_mkdir_error(int err)
+{
+	switch (err) {
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EEXIST:
+			PR_SetError(PR_FILE_EXISTS_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case EMLINK:
+			PR_SetError(PR_MAX_DIRECTORY_ENTRIES_ERROR, err);
+			break;
+		case ENOSPC:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+#ifdef EDQUOT
+		case EDQUOT:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+#endif
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_rmdir_error(int err)
+{
+
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EBUSY:
+			PR_SetError(PR_FILESYSTEM_MOUNTED_ERROR, err);
+			break;
+		case EEXIST:
+			PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_read_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#ifdef EBADMSG
+		case EBADMSG:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+#endif
+		case EDEADLK:
+			PR_SetError(PR_DEADLOCK_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ENOLCK:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ENXIO:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EISDIR:
+			PR_SetError(PR_IS_DIRECTORY_ERROR, err);
+			break;
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+#ifdef ENOLINK
+		case ENOLINK:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_write_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EDEADLK:
+			PR_SetError(PR_DEADLOCK_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EFBIG:
+			PR_SetError(PR_FILE_TOO_BIG_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ENOLCK:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case ENOSPC:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		case ENXIO:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		case ERANGE:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+#ifdef EDQUOT
+		case EDQUOT:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+#endif
+#ifdef ENOLINK
+		case ENOLINK:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_lseek_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ESPIPE:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_fsync_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#ifdef ENOLINK
+		case ENOLINK:
+#endif
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_METHOD_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_close_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+#ifdef ENOLINK
+		case ENOLINK:
+#endif
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_socket_error(int err)
+{
+	switch (err) {
+		case EPROTONOSUPPORT:
+			PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err);
+			break;
+		case EMFILE:
+			PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ENFILE:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+#if !defined(SCO)
+		case ENOBUFS:
+#endif /* !defined(SCO) */
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_socketavailable_error(int err)
+{
+	PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+}
+
+void _MD_unix_map_recv_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_recvfrom_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case ECONNRESET:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_send_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+#if !defined(BEOS)
+		case EMSGSIZE:
+#endif
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+#if !defined(SCO)
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif /* !defined(SCO) */
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_sendto_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+#if !defined(BEOS)
+		case EMSGSIZE:
+#endif
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+#if !defined(SCO)
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif /* !defined(SCO) */
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_writev_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ECONNRESET:
+		case EPIPE:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_accept_error(int err)
+{
+	switch (err) {
+		case EAGAIN:
+#if EWOULDBLOCK != EAGAIN
+		case EWOULDBLOCK:
+#endif
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+#if !defined(BEOS)
+		case EOPNOTSUPP:
+#endif
+		case ENODEV:
+			PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EMFILE:
+			PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ENFILE:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+#ifdef EPROTO
+		case EPROTO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_connect_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EADDRNOTAVAIL:
+			PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err);
+			break;
+		case EINPROGRESS:
+			PR_SetError(PR_IN_PROGRESS_ERROR, err);
+			break;
+		case EALREADY:
+			PR_SetError(PR_ALREADY_INITIATED_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case EAFNOSUPPORT:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_IO_TIMEOUT_ERROR, err);
+			break;
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case ENETUNREACH:
+			PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err);
+			break;
+		case EADDRINUSE:
+			PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		/*
+		 * UNIX domain sockets are not supported in NSPR
+		 */
+		case EACCES:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EIO:
+#if defined(UNIXWARE) || defined(SNI) || defined(NEC)
+			/*
+			 * On some platforms, if we connect to a port on
+			 * the local host (the loopback address) that no
+			 * process is listening on, we get EIO instead
+			 * of ECONNREFUSED.
+			 */
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+#else
+			PR_SetError(PR_IO_ERROR, err);
+#endif
+			break;
+		case ELOOP:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		case ENOENT:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		case ENXIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case EPROTOTYPE:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_bind_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EADDRNOTAVAIL:
+			PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err);
+			break;
+		case EADDRINUSE:
+			PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_SOCKET_ADDRESS_IS_BOUND_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		/*
+		 * UNIX domain sockets are not supported in NSPR
+		 */
+		case EIO:
+		case EISDIR:
+		case ELOOP:
+		case ENOENT:
+		case ENOTDIR:
+		case EROFS:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_listen_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+#if !defined(BEOS)
+		case EOPNOTSUPP:
+			PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_shutdown_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case ENOTCONN:
+			PR_SetError(PR_NOT_CONNECTED_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_socketpair_error(int err)
+{
+	switch (err) {
+		case EMFILE:
+			PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case EAFNOSUPPORT:
+		case EPROTONOSUPPORT:
+#if !defined(BEOS)
+		case EOPNOTSUPP:
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_getsockname_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#if !defined(SCO)
+		case ENOBUFS:
+#endif /* !defined(SCO) */
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_getpeername_error(int err)
+{
+
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case ENOTCONN:
+			PR_SetError(PR_NOT_CONNECTED_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#if !defined(SCO)
+		case ENOBUFS:
+#endif /* !defined(SCO) */
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_getsockopt_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case ENOPROTOOPT:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_setsockopt_error(int err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+#if !defined(BEOS)
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#endif
+		case ENOPROTOOPT:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+		case ENOMEM:
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_open_error(int err)
+{
+	switch (err) {
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EAGAIN:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case EBUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case EEXIST:
+			PR_SetError(PR_FILE_EXISTS_ERROR, err);
+			break;
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case EIO:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case EISDIR:
+			PR_SetError(PR_IS_DIRECTORY_ERROR, err);
+			break;
+		case ELOOP:
+			PR_SetError(PR_LOOP_ERROR, err);
+			break;
+		case EMFILE:
+			PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ENAMETOOLONG:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ENFILE:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ENODEV:
+		case ENOENT:
+		case ENXIO:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ENOSPC:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+#ifdef ENOSR
+		case ENOSR:
+#endif
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ENOTDIR:
+			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
+			break;
+		case EPERM:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_REMOTE_FILE_ERROR, err);
+			break;
+		case EROFS:
+			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_mmap_error(int err)
+{
+
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EAGAIN:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ENOMEM:
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_unix_map_gethostname_error(int err)
+{
+    switch (err) {
+		case EFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}
+
+void _MD_unix_map_select_error(int err)
+{
+    switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EINTR:
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}
+
+void _MD_unix_map_poll_error(int err)
+{
+    PRErrorCode prerror;
+    switch (err) {
+        case EAGAIN:
+            prerror = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case EINVAL:
+            prerror = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case EFAULT:
+            prerror = PR_ACCESS_FAULT_ERROR;
+            break;
+        default:
+            prerror = PR_UNKNOWN_ERROR;
+            break;
+    }
+    PR_SetError(prerror, err);
+}
+
+void _MD_unix_map_flock_error(int err)
+{
+    switch (err) {
+		case EBADF:
+		case EINVAL:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EWOULDBLOCK:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}
+
+void _MD_unix_map_lockf_error(int err)
+{
+    switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case EDEADLK:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}
+
+#ifdef HPUX11
+void _MD_hpux_map_sendfile_error(int oserror)
+{
+    PRErrorCode prerror;
+
+    switch (oserror) {
+        case ENOTSOCK:
+            prerror = PR_NOT_SOCKET_ERROR;
+            break;
+        case EFAULT:
+            prerror = PR_ACCESS_FAULT_ERROR;
+            break;
+        case ENOBUFS:
+            prerror = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case EINVAL:
+            prerror = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case ENOTCONN:
+            prerror = PR_NOT_CONNECTED_ERROR;
+            break;
+        case EPIPE:
+            prerror = PR_CONNECT_RESET_ERROR;
+            break;
+        case ENOMEM:
+            prerror = PR_OUT_OF_MEMORY_ERROR;
+            break;
+        case EOPNOTSUPP:
+            prerror = PR_NOT_TCP_SOCKET_ERROR;
+            break;
+        default:
+            prerror = PR_UNKNOWN_ERROR;
+    }
+    PR_SetError(prerror, oserror); 
+}
+#endif /* HPUX11 */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bfile.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bfile.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,902 @@
+/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */
+/* 
+ * 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.
+ */
+
+#include "primpl.h"
+
+/*
+** Global lock variable used to bracket calls into rusty libraries that
+** aren't thread safe (like libc, libX, etc).
+*/
+static PRLock *_pr_rename_lock = NULL; 
+
+void
+_MD_InitIO (void)
+{
+}
+
+PRStatus
+_MD_open_dir (_MDDir *md,const char *name)
+{
+int err;
+
+	md->d = opendir(name);
+	if (!md->d) {
+		err = _MD_ERRNO();
+		_PR_MD_MAP_OPENDIR_ERROR(err);
+		return PR_FAILURE;
+	}
+	return PR_SUCCESS;
+}
+
+char*
+_MD_read_dir (_MDDir *md, PRIntn flags)
+{
+struct dirent *de;
+int err;
+
+	for (;;) {
+		/*
+		 * XXX: readdir() is not MT-safe
+		 */
+		_MD_ERRNO() = 0;
+		de = readdir(md->d);
+
+		if (!de) {
+			err = _MD_ERRNO();
+			_PR_MD_MAP_READDIR_ERROR(err);
+			return 0;
+		}
+
+		if ((flags & PR_SKIP_DOT) &&
+		    (de->d_name[0] == '.') && (de->d_name[1] == 0))
+			continue;
+
+		if ((flags & PR_SKIP_DOT_DOT) &&
+		    (de->d_name[0] == '.') && (de->d_name[1] == '.') &&
+		    (de->d_name[2] == 0))
+			continue;
+
+		if ((flags & PR_SKIP_HIDDEN) && (de->d_name[1] == '.'))
+			continue;
+
+		break;
+	}
+	return de->d_name;
+}
+
+
+PRInt32
+_MD_close_dir (_MDDir *md)
+{
+int rv = 0, err;
+
+	if (md->d) {
+		rv = closedir(md->d);
+		if (rv == -1) {
+			err = _MD_ERRNO();
+			_PR_MD_MAP_CLOSEDIR_ERROR(err);
+		}
+	}
+	return(rv);
+}
+
+void
+_MD_make_nonblock (PRFileDesc *fd)
+{
+	int blocking = 1;
+	setsockopt(fd->secret->md.osfd, SOL_SOCKET, SO_NONBLOCK, &blocking, sizeof(blocking));
+
+}
+
+PRStatus
+_MD_set_fd_inheritable (PRFileDesc *fd, PRBool inheritable)
+{
+        int rv;
+	
+        rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC);
+        if (-1 == rv) {
+                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+                return PR_FAILURE;
+        }
+        return PR_SUCCESS;
+}
+
+void
+_MD_init_fd_inheritable (PRFileDesc *fd, PRBool imported)
+{
+	if (imported) {
+		fd->secret->inheritable = _PR_TRI_UNKNOWN;
+	} else {
+		int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
+		if (flags == -1) {
+			PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+			return;
+		}
+		fd->secret->inheritable = (flags & FD_CLOEXEC) ? 
+			_PR_TRI_TRUE : _PR_TRI_FALSE;
+	}
+}
+
+void
+_MD_query_fd_inheritable (PRFileDesc *fd)
+{
+	int flags;
+	
+	PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
+	flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
+	PR_ASSERT(-1 != flags);
+	fd->secret->inheritable = (flags & FD_CLOEXEC) ?
+		_PR_TRI_FALSE : _PR_TRI_TRUE;
+}
+
+PRInt32
+_MD_open (const char *name, PRIntn flags, PRIntn mode)
+{
+	PRInt32 osflags;
+	PRInt32 rv, err;
+
+	if (flags & PR_RDWR) {
+		osflags = O_RDWR;
+	} else if (flags & PR_WRONLY) {
+		osflags = O_WRONLY;
+	} else {
+		osflags = O_RDONLY;
+	}
+
+	if (flags & PR_EXCL)
+		osflags |= O_EXCL;
+	if (flags & PR_APPEND)
+		osflags |= O_APPEND;
+	if (flags & PR_TRUNCATE)
+		osflags |= O_TRUNC;
+	if (flags & PR_SYNC) {
+/* Ummmm.  BeOS doesn't appear to
+   support sync in any way shape or
+   form. */
+		return PR_NOT_IMPLEMENTED_ERROR;
+	}
+
+	/*
+	** On creations we hold the 'create' lock in order to enforce
+	** the semantics of PR_Rename. (see the latter for more details)
+	*/
+	if (flags & PR_CREATE_FILE)
+	{
+		osflags |= O_CREAT ;
+		if (NULL !=_pr_rename_lock)
+		    PR_Lock(_pr_rename_lock);
+	}
+
+        rv = open(name, osflags, mode);
+
+        if (rv < 0) {
+                err = _MD_ERRNO();
+                _PR_MD_MAP_OPEN_ERROR(err);
+        }                                                                      
+
+    if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock))
+        PR_Unlock(_pr_rename_lock);
+        return rv;
+}
+
+PRInt32
+_MD_close_file (PRInt32 osfd)
+{
+PRInt32 rv, err;
+
+	rv = close(osfd);
+	if (rv == -1) {
+		err = _MD_ERRNO();
+		_PR_MD_MAP_CLOSE_ERROR(err);
+	}
+	return(rv);
+}
+
+PRInt32
+_MD_read (PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+    PRInt32 rv, err;
+    PRInt32 osfd = fd->secret->md.osfd;
+
+    rv = read( osfd, buf, amount );
+    if (rv < 0) {
+	err = _MD_ERRNO();
+	_PR_MD_MAP_READ_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32
+_MD_write (PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+    PRInt32 rv, err;
+    PRInt32 osfd = fd->secret->md.osfd;
+
+    rv = write( osfd, buf, amount );
+
+    if( rv < 0 ) {
+
+	err = _MD_ERRNO();
+	_PR_MD_MAP_WRITE_ERROR(err);
+    }
+    return( rv );
+}
+
+#ifndef BONE_VERSION /* Writev moves to bnet.c with BONE */
+PRInt32
+_MD_writev (PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
+	    PRIntervalTime timeout)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+#endif
+
+PRInt32
+_MD_lseek (PRFileDesc *fd, PRInt32 offset, int whence)
+{
+PRInt32 rv, err;
+
+    rv = lseek (fd->secret->md.osfd, offset, whence);
+    if (rv == -1) {
+        err = _MD_ERRNO();
+	_PR_MD_MAP_LSEEK_ERROR(err);
+    }
+    return( rv );
+}
+
+PRInt64
+_MD_lseek64 (PRFileDesc *fd, PRInt64 offset, int whence)
+{
+PRInt32 rv, err;
+
+/* According to the BeOS headers, lseek accepts a
+ * variable of type off_t for the offset, and off_t
+ * is defined to be a 64-bit value.  So no special
+ * cracking needs to be done on "offset".
+ */
+
+    rv = lseek (fd->secret->md.osfd, offset, whence);
+    if (rv == -1) {
+        err = _MD_ERRNO();
+	_PR_MD_MAP_LSEEK_ERROR(err);
+    }
+    return( rv );
+}
+
+PRInt32
+_MD_fsync (PRFileDesc *fd)
+{
+PRInt32 rv, err;
+
+    rv = fsync(fd->secret->md.osfd);
+    if (rv == -1) {
+	err = _MD_ERRNO();
+	_PR_MD_MAP_FSYNC_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32
+_MD_delete (const char *name)
+{
+PRInt32 rv, err;
+
+    rv = unlink(name);
+    if (rv == -1)
+    {
+	err = _MD_ERRNO();
+        _PR_MD_MAP_UNLINK_ERROR(err);
+    }
+    return (rv);
+}
+
+PRInt32
+_MD_getfileinfo (const char *fn, PRFileInfo *info)
+{
+struct stat sb;
+PRInt32 rv, err;
+PRInt64 s, s2us;
+
+	rv = stat(fn, &sb);
+	if (rv < 0) {
+		err = _MD_ERRNO();
+		_PR_MD_MAP_STAT_ERROR(err);
+	} else if (info) {
+		if (S_IFREG & sb.st_mode)
+			info->type = PR_FILE_FILE;
+		else if (S_IFDIR & sb.st_mode)
+			info->type = PR_FILE_DIRECTORY;
+		else
+			info->type = PR_FILE_OTHER;
+
+		/* Must truncate file size for the 32 bit
+		   version */
+		info->size = (sb.st_size & 0xffffffff);
+		LL_I2L(s, sb.st_mtime);
+		LL_I2L(s2us, PR_USEC_PER_SEC);
+		LL_MUL(s, s, s2us);
+		info->modifyTime = s;
+		LL_I2L(s, sb.st_ctime);
+		LL_MUL(s, s, s2us);
+		info->creationTime = s;
+	}
+	return rv;
+}
+
+PRInt32
+_MD_getfileinfo64 (const char *fn, PRFileInfo64 *info)
+{
+struct stat sb;
+PRInt32 rv, err;
+PRInt64 s, s2us;
+
+	rv = stat(fn, &sb);
+	if (rv < 0) {
+		err = _MD_ERRNO();
+		_PR_MD_MAP_STAT_ERROR(err);
+	} else if (info) {
+		if (S_IFREG & sb.st_mode)
+			info->type = PR_FILE_FILE;
+		else if (S_IFDIR & sb.st_mode)
+			info->type = PR_FILE_DIRECTORY;
+		else
+			info->type = PR_FILE_OTHER;
+	
+		/* For the 64 bit version we can use
+		 * the native st_size without modification
+		 */
+		info->size = sb.st_size;
+		LL_I2L(s, sb.st_mtime);
+		LL_I2L(s2us, PR_USEC_PER_SEC);
+		LL_MUL(s, s, s2us);
+		info->modifyTime = s;
+		LL_I2L(s, sb.st_ctime);
+		LL_MUL(s, s, s2us);
+		info->creationTime = s;
+	}
+	return rv;
+}
+
+PRInt32
+_MD_getopenfileinfo (const PRFileDesc *fd, PRFileInfo *info)
+{
+        struct stat sb;
+        PRInt64 s, s2us;
+        PRInt32 rv, err;
+
+        rv = fstat(fd->secret->md.osfd, &sb);
+        if (rv < 0) {
+                        err = _MD_ERRNO();
+                        _PR_MD_MAP_FSTAT_ERROR(err);
+        } else if (info) {
+                if (info) {
+                        if (S_IFREG & sb.st_mode)
+                                info->type = PR_FILE_FILE ;
+                        else if (S_IFDIR & sb.st_mode)
+                                info->type = PR_FILE_DIRECTORY;
+                        else
+                                info->type = PR_FILE_OTHER;
+			/* Use lower 32 bits of file size */
+                        info->size = ( sb.st_size & 0xffffffff);
+                        LL_I2L(s, sb.st_mtime);
+                        LL_I2L(s2us, PR_USEC_PER_SEC);
+                        LL_MUL(s, s, s2us);
+                        info->modifyTime = s;
+                        LL_I2L(s, sb.st_ctime);
+                        LL_MUL(s, s, s2us);
+                        info->creationTime = s;
+                }
+        }
+        return rv;
+}
+
+PRInt32
+_MD_getopenfileinfo64 (const PRFileDesc *fd, PRFileInfo64 *info)
+{
+        struct stat sb;
+        PRInt64 s, s2us;
+        PRInt32 rv, err;
+
+        rv = fstat(fd->secret->md.osfd, &sb);
+        if (rv < 0) {
+                        err = _MD_ERRNO();
+                        _PR_MD_MAP_FSTAT_ERROR(err);
+        } else if (info) {
+                if (info) {
+                        if (S_IFREG & sb.st_mode)
+                                info->type = PR_FILE_FILE ;
+                        else if (S_IFDIR & sb.st_mode)
+                                info->type = PR_FILE_DIRECTORY;
+                        else
+                                info->type = PR_FILE_OTHER;
+                        info->size = sb.st_size;
+                        LL_I2L(s, sb.st_mtime);
+                        LL_I2L(s2us, PR_USEC_PER_SEC);
+                        LL_MUL(s, s, s2us);
+                        info->modifyTime = s;
+                        LL_I2L(s, sb.st_ctime);
+                        LL_MUL(s, s, s2us);
+                        info->creationTime = s;
+                }
+        }
+        return rv;
+}
+
+PRInt32
+_MD_rename (const char *from, const char *to)
+{
+    PRInt32 rv = -1, err;
+
+    /*
+    ** This is trying to enforce the semantics of WINDOZE' rename
+    ** operation. That means one is not allowed to rename over top
+    ** of an existing file. Holding a lock across these two function
+    ** and the open function is known to be a bad idea, but ....
+    */
+    if (NULL != _pr_rename_lock)
+        PR_Lock(_pr_rename_lock);
+    if (0 == access(to, F_OK))
+        PR_SetError(PR_FILE_EXISTS_ERROR, 0);
+    else
+    {
+            rv = rename(from, to);
+            if (rv < 0) {
+                    err = _MD_ERRNO();
+                    _PR_MD_MAP_RENAME_ERROR(err);
+            }
+    }
+    if (NULL != _pr_rename_lock)
+        PR_Unlock(_pr_rename_lock);
+    return rv; 
+}
+
+PRInt32
+_MD_access (const char *name, PRIntn how)
+{
+PRInt32 rv, err;
+int checkFlags;
+struct stat buf;
+
+	switch (how) {
+		case PR_ACCESS_WRITE_OK:
+			checkFlags = S_IWUSR | S_IWGRP | S_IWOTH;
+			break;
+		
+		case PR_ACCESS_READ_OK:
+			checkFlags = S_IRUSR | S_IRGRP | S_IROTH;
+			break;
+		
+		case PR_ACCESS_EXISTS:
+			/* we don't need to examine st_mode. */
+			break;
+		
+		default:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+			return -1;
+	}
+
+	rv = stat(name, &buf);
+	if (rv == 0 && how != PR_ACCESS_EXISTS && (!(buf.st_mode & checkFlags))) {
+		PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0);
+		return -1;
+	}
+
+	if (rv < 0) {
+		err = _MD_ERRNO();
+		_PR_MD_MAP_STAT_ERROR(err);
+	}
+
+	return(rv);
+}
+
+PRInt32
+_MD_stat (const char *name, struct stat *buf)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+
+PRInt32
+_MD_mkdir (const char *name, PRIntn mode)
+{
+    status_t rv;
+    int err;
+
+    /*
+    ** This lock is used to enforce rename semantics as described
+    ** in PR_Rename. Look there for more fun details.
+    */
+    if (NULL !=_pr_rename_lock)
+        PR_Lock(_pr_rename_lock);
+
+    rv = mkdir(name, mode);
+    if (rv < 0) {
+	err = _MD_ERRNO();
+	_PR_MD_MAP_MKDIR_ERROR(err);
+    }
+    if (NULL !=_pr_rename_lock)
+        PR_Unlock(_pr_rename_lock);
+    return rv; 
+}
+
+PRInt32
+_MD_rmdir (const char *name)
+{
+int rv, err;
+
+        rv = rmdir(name);
+        if (rv == -1) {
+                        err = _MD_ERRNO();
+                        _PR_MD_MAP_RMDIR_ERROR(err);
+        }
+        return rv;
+}
+
+PRInt32
+_MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+	PRInt32 rv = 0;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+	/*
+	 * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL().
+	 */
+	fd_set rd, wt, ex;
+	PRFileDesc *bottom;
+	PRPollDesc *pd, *epd;
+	PRInt32 maxfd = -1, ready, err;
+	PRIntervalTime remaining, elapsed, start;
+
+	struct timeval tv, *tvp = NULL;
+
+	if (_PR_PENDING_INTERRUPT(me))
+	{
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+		return -1;
+	}
+
+	if (0 == npds) {
+		PR_Sleep(timeout);
+		return rv;
+	}
+
+	FD_ZERO(&rd);
+	FD_ZERO(&wt);
+	FD_ZERO(&ex);
+
+	ready = 0;
+	for (pd = pds, epd = pd + npds; pd < epd; pd++)
+	{
+		PRInt16 in_flags_read = 0, in_flags_write = 0;
+		PRInt16 out_flags_read = 0, out_flags_write = 0; 
+		
+		if ((NULL != pd->fd) && (0 != pd->in_flags))
+		{
+			if (pd->in_flags & PR_POLL_READ)
+			{
+				in_flags_read = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
+			}
+			if (pd->in_flags & PR_POLL_WRITE)
+			{
+				in_flags_write = (pd->fd->methods->poll)(pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
+			}
+			if ((0 != (in_flags_read & out_flags_read))
+			    || (0 != (in_flags_write & out_flags_write)))
+			{
+				/* this one's ready right now */
+				if (0 == ready)
+				{
+					/*
+					 * We will have to return without calling the
+					 * system poll/select function.  So zero the
+					 * out_flags fields of all the poll descriptors
+					 * before this one. 
+					 */
+					PRPollDesc *prev;
+					for (prev = pds; prev < pd; prev++)
+					{
+						prev->out_flags = 0;
+					}
+				}
+				ready += 1;
+				pd->out_flags = out_flags_read | out_flags_write;
+			}
+			else
+			{
+				pd->out_flags = 0;  /* pre-condition */
+				
+				/* make sure this is an NSPR supported stack */
+				bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+				PR_ASSERT(NULL != bottom);  /* what to do about that? */
+				if ((NULL != bottom)
+				    && (_PR_FILEDESC_OPEN == bottom->secret->state))
+				{
+					if (0 == ready)
+					{
+						PRInt32 osfd = bottom->secret->md.osfd; 
+						if (osfd > maxfd) maxfd = osfd;
+						if (in_flags_read & PR_POLL_READ)
+						{
+							pd->out_flags |= _PR_POLL_READ_SYS_READ;
+							FD_SET(osfd, &rd);
+						}
+						if (in_flags_read & PR_POLL_WRITE)
+						{
+							pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
+							FD_SET(osfd, &wt);
+						}
+						if (in_flags_write & PR_POLL_READ)
+						{
+							pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
+							FD_SET(osfd, &rd);
+						}
+						if (in_flags_write & PR_POLL_WRITE)
+						{
+							pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
+							FD_SET(osfd, &wt);
+						}
+						if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);
+					}
+				}
+				else
+				{
+					if (0 == ready)
+					{
+						PRPollDesc *prev;
+						for (prev = pds; prev < pd; prev++)
+						{
+							prev->out_flags = 0;
+						}
+					}
+					ready += 1;  /* this will cause an abrupt return */
+					pd->out_flags = PR_POLL_NVAL;  /* bogii */
+				}
+			}
+		}
+		else
+		{
+			pd->out_flags = 0;
+		}
+	}
+
+	if (0 != ready) return ready;  /* no need to block */
+
+	remaining = timeout;
+	start = PR_IntervalNow(); 
+
+ retry:
+	if (timeout != PR_INTERVAL_NO_TIMEOUT)
+	{
+		PRInt32 ticksPerSecond = PR_TicksPerSecond();
+		tv.tv_sec = remaining / ticksPerSecond;
+		tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
+		tvp = &tv;
+	}
+	
+	ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);
+	
+	if (ready == -1 && errno == EINTR)
+	{
+		if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
+		else
+		{
+			elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
+			if (elapsed > timeout) ready = 0;  /* timed out */
+			else
+			{
+				remaining = timeout - elapsed;
+				goto retry; 
+			}
+		}
+	} 
+
+	/*
+	** Now to unravel the select sets back into the client's poll
+	** descriptor list. Is this possibly an area for pissing away
+	** a few cycles or what?
+	*/
+	if (ready > 0)
+	{
+		ready = 0;
+		for (pd = pds, epd = pd + npds; pd < epd; pd++)
+		{
+			PRInt16 out_flags = 0;
+			if ((NULL != pd->fd) && (0 != pd->in_flags))
+			{
+				PRInt32 osfd;
+				bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+				PR_ASSERT(NULL != bottom);
+				
+				osfd = bottom->secret->md.osfd; 
+				
+				if (FD_ISSET(osfd, &rd))
+				{
+					if (pd->out_flags & _PR_POLL_READ_SYS_READ)
+						out_flags |= PR_POLL_READ;
+					if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
+						out_flags |= PR_POLL_WRITE;
+				}
+				if (FD_ISSET(osfd, &wt))
+				{
+					if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
+						out_flags |= PR_POLL_READ;
+					if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
+						out_flags |= PR_POLL_WRITE;
+				}
+				if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
+
+/* Workaround for nonblocking connects under net_server */
+#ifndef BONE_VERSION 		
+				if (out_flags)
+				{
+					/* check if it is a pending connect */
+					int i = 0, j = 0;
+					PR_Lock( _connectLock );
+					for( i = 0; i < connectCount; i++ ) 
+					{
+						if(connectList[i].osfd == osfd)
+						{
+							int connectError;
+							int connectResult;
+					
+							connectResult = connect(connectList[i].osfd,
+							                        &connectList[i].addr,
+							                        connectList[i].addrlen);
+							connectError = errno;
+					
+							if(connectResult < 0 ) 
+							{
+								if(connectError == EINTR || connectError == EWOULDBLOCK ||
+					  		   connectError == EINPROGRESS || connectError == EALREADY)
+								{
+									break;
+								}
+							}
+					
+							if(i == (connectCount - 1))
+							{
+								connectList[i].osfd = -1;
+							} else {
+								for(j = i; j < connectCount; j++ )
+								{
+									memcpy( &connectList[j], &connectList[j+1],
+									        sizeof(connectList[j]));
+								}
+							}
+							connectCount--;
+					
+							bottom->secret->md.connectReturnValue = connectResult;
+							bottom->secret->md.connectReturnError = connectError;
+							bottom->secret->md.connectValueValid = PR_TRUE;
+							break;
+						}
+					}
+					PR_Unlock( _connectLock );
+				}
+#endif
+			}
+			pd->out_flags = out_flags;
+			if (out_flags) ready++;
+		}
+		PR_ASSERT(ready > 0);
+	}
+	else if (ready < 0)
+	{ 
+		err = _MD_ERRNO();
+		if (err == EBADF)
+		{
+			/* Find the bad fds */
+			ready = 0;
+			for (pd = pds, epd = pd + npds; pd < epd; pd++)
+			{
+				pd->out_flags = 0;
+				if ((NULL != pd->fd) && (0 != pd->in_flags))
+				{
+					bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+					if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)
+					{
+						pd->out_flags = PR_POLL_NVAL;
+						ready++;
+					}
+				}
+			}
+			PR_ASSERT(ready > 0);
+		}
+		else _PR_MD_MAP_SELECT_ERROR(err);
+	}
+	
+	return ready;
+}  /* _MD_pr_poll */
+
+/*
+ * File locking.
+ */
+
+PRStatus
+_MD_lockfile (PRInt32 osfd)
+{
+    PRInt32 rv;
+    struct flock linfo;
+
+    linfo.l_type = 
+    linfo.l_whence = SEEK_SET;
+    linfo.l_start = 0;
+    linfo.l_len = 0;
+
+    rv = fcntl(osfd, F_SETLKW, &linfo);
+    if (rv == 0)
+	return PR_SUCCESS;
+
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_tlockfile (PRInt32 osfd)
+{
+    PRInt32 rv;
+    struct flock linfo;
+
+    linfo.l_type = 
+    linfo.l_whence = SEEK_SET;
+    linfo.l_start = 0;
+    linfo.l_len = 0;
+
+    rv = fcntl(osfd, F_SETLK, &linfo);
+    if (rv == 0)
+	return PR_SUCCESS;
+
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_unlockfile (PRInt32 osfd)
+{
+    PRInt32 rv;
+    struct flock linfo;
+
+    linfo.l_type = 
+    linfo.l_whence = SEEK_SET;
+    linfo.l_start = 0;
+    linfo.l_len = 0;
+
+    rv = fcntl(osfd, F_UNLCK, &linfo);
+
+    if (rv == 0)
+	return PR_SUCCESS;
+
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bmemory.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bmemory.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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"
+
+PR_EXTERN(void) _PR_MD_INIT_SEGS(void);
+PR_EXTERN(PRStatus) _PR_MD_ALLOC_SEGMENT(PRSegment *seg, PRUint32 size, void *vaddr);
+PR_EXTERN(void) _PR_MD_FREE_SEGMENT(PRSegment *seg);

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bmisc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bmisc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 <stdlib.h>
+
+PRLock *_connectLock = NULL;
+
+#ifndef BONE_VERSION
+/* Workaround for nonblocking connects under net_server */
+PRUint32 connectCount = 0;
+ConnectListNode connectList[64];
+#endif
+                                   
+void
+_MD_cleanup_before_exit (void)
+{
+}
+
+void
+_MD_exit (PRIntn status)
+{
+    exit(status);
+}
+
+void
+_MD_early_init (void)
+{
+}
+
+static PRLock *monitor = NULL;
+
+void
+_MD_final_init (void)
+{
+    _connectLock = PR_NewLock();
+    PR_ASSERT(NULL != _connectLock); 
+#ifndef BONE_VERSION   
+    /* Workaround for nonblocking connects under net_server */
+    connectCount = 0;
+#endif
+}
+
+void
+_MD_AtomicInit (void)
+{
+    if (monitor == NULL) {
+        monitor = PR_NewLock();
+    }
+}
+
+/*
+** This is exceedingly messy.  atomic_add returns the last value, NSPR expects the new value.
+** We just add or subtract 1 from the result.  The actual memory update is atomic.
+*/
+
+PRInt32
+_MD_AtomicAdd( PRInt32 *ptr, PRInt32 val )
+{
+    return( ( atomic_add( (long *)ptr, val ) ) + val );
+}
+
+PRInt32
+_MD_AtomicIncrement( PRInt32 *val )
+{
+    return( ( atomic_add( (long *)val, 1 ) ) + 1 );
+}
+
+PRInt32
+_MD_AtomicDecrement( PRInt32 *val )
+{
+    return( ( atomic_add( (long *)val, -1 ) ) - 1 );
+}
+
+PRInt32
+_MD_AtomicSet( PRInt32 *val, PRInt32 newval )
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+    PR_Lock(monitor);
+    rv = *val;
+    *val = newval;
+    PR_Unlock(monitor);
+    return rv;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bmmap.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bmmap.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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"
+
+PR_EXTERN(PRStatus)
+_PR_MD_CREATE_FILE_MAP(PRFileMap *fmap, PRInt64 size)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return PR_FAILURE;
+}
+
+PR_EXTERN(PRInt32)
+_PR_MD_GET_MEM_MAP_ALIGNMENT(void)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return -1;
+}
+
+PR_EXTERN(void *)
+_PR_MD_MEM_MAP(PRFileMap *fmap, PRInt64 offset, PRUint32 len)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return 0;
+}
+
+PR_EXTERN(PRStatus)
+_PR_MD_MEM_UNMAP(void *addr, PRUint32 size)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return PR_FAILURE;
+}
+
+PR_EXTERN(PRStatus)
+_PR_MD_CLOSE_FILE_MAP(PRFileMap *fmap)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return PR_FAILURE;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bnet.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bnet.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,929 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 <signal.h>
+#include <unistd.h>
+#include <memory.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+/*
+ * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or
+ * PRInt32* pointer to a _PRSockLen_t* pointer.
+ */
+#define _PRSockLen_t int
+
+
+/*
+** Global lock variable used to bracket calls into rusty libraries that
+** aren't thread safe (like libc, libX, etc).
+*/
+static PRLock *_pr_rename_lock = NULL;
+static PRMonitor *_pr_Xfe_mon = NULL;
+
+#define READ_FD     1
+#define WRITE_FD    2
+
+/*
+** This is a support routine to handle "deferred" i/o on sockets. 
+** It uses "select", so it is subject to all of the BeOS limitations
+** (only READ notification, only sockets)
+*/
+
+/*
+ * socket_io_wait --
+ *
+ * wait for socket i/o, periodically checking for interrupt
+ *
+ */
+
+static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
+                              PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+    struct timeval tv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntervalTime epoch, now, elapsed, remaining;
+    PRBool wait_for_remaining;
+    PRInt32 syserror;
+    fd_set rd_wr;
+
+    switch (timeout) {
+    case PR_INTERVAL_NO_WAIT:
+        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        break;
+    case PR_INTERVAL_NO_TIMEOUT:
+        /*
+         * This is a special case of the 'default' case below.
+         * Please see the comments there.
+         */
+        tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+        tv.tv_usec = 0;
+        FD_ZERO(&rd_wr);
+        do {
+            FD_SET(osfd, &rd_wr);
+            if (fd_type == READ_FD)
+                rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
+            else
+                rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
+            if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+#ifdef BONE_VERSION
+                _PR_MD_MAP_SELECT_ERROR(syserror);
+#else
+                if (syserror == EBADF) {
+                    PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
+                } else {
+                    PR_SetError(PR_UNKNOWN_ERROR, syserror);
+                }
+#endif
+                break;
+            }
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                rv = -1;
+                break;
+            }
+        } while (rv == 0 || (rv == -1 && syserror == EINTR));
+        break;
+    default:
+        now = epoch = PR_IntervalNow();
+        remaining = timeout;
+        FD_ZERO(&rd_wr);
+        do {
+            /*
+             * We block in _MD_SELECT for at most
+             * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
+             * so that there is an upper limit on the delay
+             * before the interrupt bit is checked.
+             */
+            wait_for_remaining = PR_TRUE;
+            tv.tv_sec = PR_IntervalToSeconds(remaining);
+            if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
+                wait_for_remaining = PR_FALSE;
+                tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+                tv.tv_usec = 0;
+            } else {
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                                 remaining -
+                                 PR_SecondsToInterval(tv.tv_sec));
+            }
+            FD_SET(osfd, &rd_wr);
+            if (fd_type == READ_FD)
+                rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
+            else
+                rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
+            /*
+             * we don't consider EINTR a real error
+             */
+            if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+#ifdef BONE_VERSION
+                _PR_MD_MAP_SELECT_ERROR(syserror);
+#else
+                if (syserror == EBADF) {
+                    PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
+                } else {
+                    PR_SetError(PR_UNKNOWN_ERROR, syserror);
+                }
+#endif
+                break;
+            }
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                rv = -1;
+                break;
+            }
+            /*
+             * We loop again if _MD_SELECT timed out or got interrupted
+             * by a signal, and the timeout deadline has not passed yet.
+             */
+            if (rv == 0 || (rv == -1 && syserror == EINTR)) {
+                /*
+                 * If _MD_SELECT timed out, we know how much time
+                 * we spent in blocking, so we can avoid a
+                 * PR_IntervalNow() call.
+                 */
+                if (rv == 0) {
+                    if (wait_for_remaining) {
+                        now += remaining;
+                    } else {
+                        now += PR_SecondsToInterval(tv.tv_sec)
+                               + PR_MicrosecondsToInterval(tv.tv_usec);
+                    }
+                } else {
+                    now = PR_IntervalNow();
+                }
+                elapsed = (PRIntervalTime) (now - epoch);
+                if (elapsed >= timeout) {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                    rv = -1;
+                    break;
+                } else {
+                    remaining = timeout - elapsed;
+                }
+            }
+        } while (rv == 0 || (rv == -1 && syserror == EINTR));
+        break;
+    }
+    return(rv);
+}
+
+PRInt32
+_MD_recv (PRFileDesc *fd, void *buf, PRInt32 amount, PRInt32 flags,
+          PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+#ifndef BONE_VERSION
+    if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_READ) {
+        _PR_MD_MAP_RECV_ERROR(EPIPE);
+        return -1;
+    }
+#endif
+
+#ifdef BONE_VERSION
+    /*
+    ** Gah, stupid hack.  If reading a zero amount, instantly return success.
+    ** BONE beta 6 returns EINVAL for reads of zero bytes, which parts of
+    ** mozilla use to check for socket availability.
+    */
+
+    if( 0 == amount ) return(0);
+#endif
+
+    while ((rv = recv(osfd, buf, amount, flags)) == -1) {
+        err = _MD_ERRNO();
+
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            /* If socket was supposed to be blocking,
+            wait a while for the condition to be
+            satisfied. */
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+
+        } else
+            break;
+    }
+
+    if (rv < 0) {
+        _PR_MD_MAP_RECV_ERROR(err);
+    }
+
+done:
+    return(rv);
+}
+
+PRInt32
+_MD_recvfrom (PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+              PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((*addrlen = PR_NETADDR_SIZE(addr)),
+            ((rv = recvfrom(osfd, buf, amount, flags,
+                            (struct sockaddr *) addr,
+                            (_PRSockLen_t *)addrlen)) == -1)) {
+        err = _MD_ERRNO();
+
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                goto done;
+
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
+            continue;
+        } else {
+            break;
+        }
+    }
+
+    if (rv < 0) {
+        _PR_MD_MAP_RECVFROM_ERROR(err);
+    }
+
+done:
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv != -1) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    return(rv);
+}
+
+PRInt32
+_MD_send (PRFileDesc *fd, const void *buf, PRInt32 amount, PRInt32 flags,
+          PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+#ifndef BONE_VERSION
+    if (fd->secret->md.sock_state & BE_SOCK_SHUTDOWN_WRITE)
+    {
+        _PR_MD_MAP_SEND_ERROR(EPIPE);
+        return -1;
+    }
+#endif
+
+    while ((rv = send(osfd, buf, amount, flags)) == -1) {
+        err = _MD_ERRNO();
+
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+
+#ifndef BONE_VERSION
+            if( _PR_PENDING_INTERRUPT(me)) {
+
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+
+            /* in UNIX implementations, you could do a socket_io_wait here.
+             * but since BeOS doesn't yet support WRITE notification in select,
+             * you're spanked.
+             */
+            snooze( 10000L );
+            continue;
+#else /* BONE_VERSION */
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
+                goto done;
+#endif
+
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
+            continue;
+
+        } else {
+            break;
+        }
+    }
+
+#ifdef BONE_VERSION
+    /*
+     * optimization; if bytes sent is less than "amount" call
+     * select before returning. This is because it is likely that
+     * the next writev() call will return EWOULDBLOCK.
+     */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+        && (timeout != PR_INTERVAL_NO_WAIT)) {
+        if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
+            rv = -1;
+            goto done;
+        }
+    }
+#endif /* BONE_VERSION */
+    
+    if (rv < 0) {
+        _PR_MD_MAP_SEND_ERROR(err);
+    }
+
+#ifdef BONE_VERSION
+done:
+#endif
+    return(rv);
+}
+
+PRInt32
+_MD_sendto (PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+            const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+
+    while ((rv = sendto(osfd, buf, amount, flags,
+                        (struct sockaddr *) &addrCopy, addrlen)) == -1) {
+#else
+    while ((rv = sendto(osfd, buf, amount, flags,
+                        (struct sockaddr *) addr, addrlen)) == -1) {
+#endif
+        err = _MD_ERRNO();
+
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+
+#ifdef BONE_VERSION
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
+                goto done;
+#endif
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
+            continue;
+
+        } else {
+            break;
+        }
+    }
+
+    if (rv < 0) {
+        _PR_MD_MAP_SENDTO_ERROR(err);
+    }
+
+#ifdef BONE_VERSION
+done:
+#endif
+    return(rv);
+}
+
+#ifdef BONE_VERSION
+
+PRInt32 _MD_writev(
+    PRFileDesc *fd, const PRIOVec *iov,
+    PRInt32 iov_size, PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 index, amount = 0;
+    PRInt32 osfd = fd->secret->md.osfd;
+
+    /*
+     * Calculate the total number of bytes to be sent; needed for
+     * optimization later.
+     * We could avoid this if this number was passed in; but it is
+     * probably not a big deal because iov_size is usually small (less than
+     * 3)
+     */
+    if (!fd->secret->nonblocking) {
+        for (index=0; index<iov_size; index++) {
+            amount += iov[index].iov_len;
+        }
+    }
+
+    while ((rv = writev(osfd, (const struct iovec*)iov, iov_size)) == -1) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK))    {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0)
+                goto done;
+
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+
+    /*
+     * optimization; if bytes sent is less than "amount" call
+     * select before returning. This is because it is likely that
+     * the next writev() call will return EWOULDBLOCK.
+     */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+        && (timeout != PR_INTERVAL_NO_WAIT)) {
+        if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
+            rv = -1;
+            goto done;
+        }
+    }
+
+
+    if (rv < 0) {
+        _PR_MD_MAP_WRITEV_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+#endif /* BONE_VERSION */
+
+PRInt32
+_MD_accept (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen,
+            PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((rv = accept(osfd, (struct sockaddr *) addr,
+                        (_PRSockLen_t *)addrlen)) == -1) {
+        err = _MD_ERRNO();
+
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            /* If it's SUPPOSED to be a blocking thread, wait
+             * a while to see if the triggering condition gets
+             * satisfied.
+             */
+            /* Assume that we're always using a native thread */
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))) {
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_ACCEPT_ERROR(err);
+    } else if (addr != NULL) {
+        /* bug 134099 */
+        err = getpeername(rv, (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
+    }
+done:
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv != -1) {
+        /* Mask off the first byte of struct sockaddr (the length field) */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    return(rv);
+}
+
+PRInt32
+_MD_connect (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen,
+             PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 osfd = fd->secret->md.osfd;
+
+#ifndef BONE_VERSION
+    fd->secret->md.connectValueValid = PR_FALSE;
+#endif
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+#endif
+
+    /* (Copied from unix.c)
+     * We initiate the connection setup by making a nonblocking connect()
+     * call.  If the connect() call fails, there are two cases we handle
+     * specially:
+     * 1. The connect() call was interrupted by a signal.  In this case
+     *    we simply retry connect().
+     * 2. The NSPR socket is nonblocking and connect() fails with
+     *    EINPROGRESS.  We first wait until the socket becomes writable.
+     *    Then we try to find out whether the connection setup succeeded
+     *    or failed.
+     */
+
+retry:
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) {
+#else
+    if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) {
+#endif
+        err = _MD_ERRNO();
+#ifndef BONE_VERSION
+        fd->secret->md.connectReturnValue = rv;
+        fd->secret->md.connectReturnError = err;
+        fd->secret->md.connectValueValid = PR_TRUE;
+#endif
+        if( err == EINTR ) {
+
+            if( _PR_PENDING_INTERRUPT(me)) {
+
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+#ifndef BONE_VERSION
+            snooze( 100000L );
+#endif
+            goto retry;
+        }
+
+#ifndef BONE_VERSION
+        if(!fd->secret->nonblocking && ((err == EINPROGRESS) || (err==EAGAIN) || (err==EALREADY))) {
+
+            /*
+            ** There's no timeout on this connect, but that's not
+            ** a big deal, since the connect times out anyways
+            ** after 30 seconds.   Just sleep for 1/10th of a second
+            ** and retry until we go through or die.
+            */
+
+            if( _PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+
+            goto retry;
+        }
+
+        if( fd->secret->nonblocking && ((err == EAGAIN) || (err == EINPROGRESS))) {
+            PR_Lock(_connectLock);
+            if (connectCount < sizeof(connectList)/sizeof(connectList[0])) {
+                connectList[connectCount].osfd = osfd;
+                memcpy(&connectList[connectCount].addr, addr, addrlen);
+                connectList[connectCount].addrlen = addrlen;
+                connectList[connectCount].timeout = timeout;
+                connectCount++;
+                PR_Unlock(_connectLock);
+                _PR_MD_MAP_CONNECT_ERROR(err);
+            } else {
+                PR_Unlock(_connectLock);
+                PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+            }
+            return rv;
+        }
+#else /* BONE_VERSION */
+        if(!fd->secret->nonblocking && (err == EINTR)) {
+
+            rv = socket_io_wait(osfd, WRITE_FD, timeout);
+            if (rv == -1) {
+                return -1;
+            }
+
+            PR_ASSERT(rv == 1);
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+            err = _MD_beos_get_nonblocking_connect_error(osfd);
+            if (err != 0) {
+                _PR_MD_MAP_CONNECT_ERROR(err);
+                return -1;
+            }
+            return 0;
+        }
+#endif
+
+        _PR_MD_MAP_CONNECT_ERROR(err);
+    }
+
+    return rv;
+}
+
+PRInt32
+_MD_bind (PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
+{
+    PRInt32 rv, err;
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+    rv = bind(fd->secret->md.osfd, (struct sockaddr *) &addrCopy, (int )addrlen);
+#else
+    rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen);
+#endif
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_BIND_ERROR(err);
+    }
+
+    return(rv);
+}
+
+PRInt32
+_MD_listen (PRFileDesc *fd, PRIntn backlog)
+{
+    PRInt32 rv, err;
+
+#ifndef BONE_VERSION
+    /* Bug workaround!  Setting listen to 0 on Be accepts no connections.
+    ** On most UN*Xes this sets the default.
+    */
+
+    if( backlog == 0 ) backlog = 5;
+#endif
+
+    rv = listen(fd->secret->md.osfd, backlog);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_LISTEN_ERROR(err);
+    }
+
+    return(rv);
+}
+
+PRInt32
+_MD_shutdown (PRFileDesc *fd, PRIntn how)
+{
+    PRInt32 rv, err;
+
+#ifndef BONE_VERSION
+    if (how == PR_SHUTDOWN_SEND)
+        fd->secret->md.sock_state = BE_SOCK_SHUTDOWN_WRITE;
+    else if (how == PR_SHUTDOWN_RCV)
+        fd->secret->md.sock_state = BE_SOCK_SHUTDOWN_READ;
+    else if (how == PR_SHUTDOWN_BOTH) {
+        fd->secret->md.sock_state = (BE_SOCK_SHUTDOWN_WRITE | BE_SOCK_SHUTDOWN_READ);
+    }
+
+    return 0;
+#else /* BONE_VERSION */
+    rv = shutdown(fd->secret->md.osfd, how);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SHUTDOWN_ERROR(err);
+    }
+    return(rv);
+#endif
+}
+
+PRInt32
+_MD_socketpair (int af, int type, int flags, PRInt32 *osfd)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+
+PRInt32
+_MD_close_socket (PRInt32 osfd)
+{
+#ifdef BONE_VERSION
+    close( osfd );
+#else
+    closesocket( osfd );
+#endif
+}
+
+PRStatus
+_MD_getsockname (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockname(fd->secret->md.osfd,
+                     (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv == 0) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETSOCKNAME_ERROR(err);
+    }
+
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_MD_getpeername (PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getpeername(fd->secret->md.osfd,
+                     (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
+
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv == 0) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETPEERNAME_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_MD_getsockopt (PRFileDesc *fd, PRInt32 level,
+                PRInt32 optname, char* optval, PRInt32* optlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockopt(fd->secret->md.osfd, level, optname,
+                    optval, (_PRSockLen_t *)optlen);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETSOCKOPT_ERROR(err);
+    }
+
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_MD_setsockopt (PRFileDesc *fd, PRInt32 level,
+                PRInt32 optname, const char* optval, PRInt32 optlen)
+{
+    PRInt32 rv, err;
+
+    rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SETSOCKOPT_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRInt32
+_MD_accept_read (PRFileDesc *sd, PRInt32 *newSock, PRNetAddr **raddr,
+                 void *buf, PRInt32 amount, PRIntervalTime timeout)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+
+#ifndef BONE_VERSION
+PRInt32
+_MD_socket (int af, int type, int flags)
+{
+    PRInt32 osfd, err;
+
+    osfd = socket( af, type, 0 );
+
+    if( -1 == osfd ) {
+
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SOCKET_ERROR( err );
+    }
+
+    return( osfd );
+}
+#else
+PRInt32
+_MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
+{
+    PRInt32 osfd, err;
+
+    osfd = socket(domain, type, proto);
+
+    if (osfd == -1) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SOCKET_ERROR(err);
+    }
+
+    return(osfd);
+}
+#endif
+
+PRInt32
+_MD_socketavailable (PRFileDesc *fd)
+{
+#ifdef BONE_VERSION
+    PRInt32 result;
+
+    if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) {
+        _PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO());
+        return -1;
+    }
+    return result;
+#else
+    return PR_NOT_IMPLEMENTED_ERROR;
+#endif
+}
+
+PRInt32
+_MD_get_socket_error (void)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+
+PRStatus
+_MD_gethostname (char *name, PRUint32 namelen)
+{
+    PRInt32 rv, err;
+
+    rv = gethostname(name, namelen);
+    if (rv == 0)
+    {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETHOSTNAME_ERROR(err);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+#ifndef BONE_VERSION
+PRInt32
+_MD_beos_get_nonblocking_connect_error(PRFileDesc *fd)
+{
+    int rv;
+    int flags = 0;
+
+    rv = recv(fd->secret->md.osfd, NULL, 0, flags);
+    PR_ASSERT(-1 == rv || 0 == rv);
+    if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) {
+        return errno;
+    }
+    return 0;  /* no error */
+}
+#else
+PRInt32
+_MD_beos_get_nonblocking_connect_error(int osfd)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+    //    int err;
+    //    _PRSockLen_t optlen = sizeof(err);
+    //    if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) {
+    //        return errno;
+    //    } else {
+    //        return err;
+    //    }
+}
+#endif /* BONE_VERSION */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bproc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bproc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; tab-width: 8; c-basic-offset: 8 -*- */
+/* ***** 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 <stdio.h>
+#include <signal.h>
+
+#define _PR_SIGNALED_EXITSTATUS 256
+
+PRProcess*
+_MD_create_process (const char *path, char *const *argv,
+		    char *const *envp, const PRProcessAttr *attr)
+{
+	PRProcess *process;
+	int nEnv, idx;
+	char *const *childEnvp;
+	char **newEnvp = NULL;
+	int flags;
+
+	process = PR_NEW(PRProcess);
+	if (!process) {
+		PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+		return NULL;
+	}
+
+	childEnvp = envp;
+	if (attr && attr->fdInheritBuffer) {
+		if (NULL == childEnvp) {
+			childEnvp = environ;
+		}
+		for (nEnv = 0; childEnvp[nEnv]; nEnv++) {
+		}
+		newEnvp = (char **) PR_MALLOC((nEnv + 2) * sizeof(char *));
+		if (NULL == newEnvp) {
+			PR_DELETE(process);
+			PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+			return NULL;
+		}
+		for (idx = 0; idx < nEnv; idx++) {
+			newEnvp[idx] = childEnvp[idx];
+		}
+		newEnvp[idx++] = attr->fdInheritBuffer;
+		newEnvp[idx] = NULL;
+		childEnvp = newEnvp;
+	}
+
+	process->md.pid = fork();
+
+	if ((pid_t) -1 == process->md.pid) {
+		PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, errno);
+		PR_DELETE(process);
+		if (newEnvp) {
+			PR_DELETE(newEnvp);
+		}
+		return NULL;
+	} else if (0 == process->md.pid) {  /* the child process */
+		/*
+		 * If the child process needs to exit, it must call _exit().
+		 * Do not call exit(), because exit() will flush and close
+		 * the standard I/O file descriptors, and hence corrupt
+		 * the parent process's standard I/O data structures.
+		 */
+
+		if (attr) {
+			/* the osfd's to redirect stdin, stdout, and stderr to */
+			int in_osfd = -1, out_osfd = -1, err_osfd = -1;
+
+			if (attr->stdinFd
+			    && attr->stdinFd->secret->md.osfd != 0) {
+				in_osfd = attr->stdinFd->secret->md.osfd;
+				if (dup2(in_osfd, 0) != 0) {
+					_exit(1);  /* failed */
+				}
+				flags = fcntl(0, F_GETFL, 0);
+				if (flags & O_NONBLOCK) {
+					fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
+				}
+			}
+			if (attr->stdoutFd
+			    && attr->stdoutFd->secret->md.osfd != 1) {
+				out_osfd = attr->stdoutFd->secret->md.osfd;
+				if (dup2(out_osfd, 1) != 1) {
+					_exit(1);  /* failed */
+				}
+				flags = fcntl(1, F_GETFL, 0);
+				if (flags & O_NONBLOCK) {
+					fcntl(1, F_SETFL, flags & ~O_NONBLOCK);
+				}
+			}
+			if (attr->stderrFd
+			    && attr->stderrFd->secret->md.osfd != 2) {
+				err_osfd = attr->stderrFd->secret->md.osfd;
+				if (dup2(err_osfd, 2) != 2) {
+					_exit(1);  /* failed */
+				}
+				flags = fcntl(2, F_GETFL, 0);
+				if (flags & O_NONBLOCK) {
+					fcntl(2, F_SETFL, flags & ~O_NONBLOCK);
+				}
+			}
+			if (in_osfd != -1) {
+				close(in_osfd);
+			}
+			if (out_osfd != -1 && out_osfd != in_osfd) {
+				close(out_osfd);
+			}
+			if (err_osfd != -1 && err_osfd != in_osfd
+			    && err_osfd != out_osfd) {
+				close(err_osfd);
+			}
+			if (attr->currentDirectory) {
+				if (chdir(attr->currentDirectory) < 0) {
+					_exit(1);  /* failed */
+				}
+			}
+		}
+
+		if (childEnvp) {
+			(void)execve(path, argv, childEnvp);
+		} else {
+			/* Inherit the environment of the parent. */
+			(void)execv(path, argv);
+		}
+		/* Whoops! It returned. That's a bad sign. */
+		_exit(1);
+	}
+
+	if (newEnvp) {
+		PR_DELETE(newEnvp);
+	}
+
+	return process;
+}
+
+PRStatus
+_MD_detach_process (PRProcess *process)
+{
+	/* If we kept a process table like unix does,
+	 * we'd remove the entry here.
+	 * Since we dont', just delete the process variable
+	 */
+	PR_DELETE(process);
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_wait_process (PRProcess *process, PRInt32 *exitCode)
+{
+	PRStatus retVal = PR_SUCCESS;
+	int ret, status;
+	
+	/* Ignore interruptions */
+	do {
+		ret = waitpid(process->md.pid, &status, 0);
+	} while (ret == -1 && errno == EINTR);
+
+	/*
+	 * waitpid() cannot return 0 because we did not invoke it
+	 * with the WNOHANG option.
+	 */ 
+	PR_ASSERT(0 != ret);
+
+	if (ret < 0) {
+                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+		return PR_FAILURE;
+	}
+
+	/* If child process exited normally, return child exit code */
+	if (WIFEXITED(status)) {
+		*exitCode = WEXITSTATUS(status);
+	} else {
+		PR_ASSERT(WIFSIGNALED(status));
+		*exitCode = _PR_SIGNALED_EXITSTATUS;
+	}		
+
+	PR_DELETE(process);
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_kill_process (PRProcess *process)
+{
+	PRErrorCode prerror;
+	PRInt32 oserror;
+	
+	if (kill(process->md.pid, SIGKILL) == 0) {
+		return PR_SUCCESS;
+	}
+	oserror = errno;
+	switch (oserror) {
+        case EPERM:
+		prerror = PR_NO_ACCESS_RIGHTS_ERROR;
+		break;
+        case ESRCH:
+		prerror = PR_INVALID_ARGUMENT_ERROR;
+		break;
+        default:
+		prerror = PR_UNKNOWN_ERROR;
+		break;
+	}
+	PR_SetError(prerror, oserror);
+	return PR_FAILURE;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/brng.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/brng.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 
+ * 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) 1999-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.
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <assert.h>
+#include <time.h>
+#include "primpl.h"
+
+extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size )
+{
+    struct timeval tv;
+    int n = 0;
+    int s;
+
+    GETTIMEOFDAY(&tv);
+
+    if ( size >= 0 ) {
+        s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec));
+        size -= s;
+        n += s;
+    }
+    if ( size >= 0 ) {
+        s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec));
+        size -= s;
+        n += s;
+    }
+
+    return n;
+} /* end _PR_MD_GetRandomNoise() */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bseg.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bseg.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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"
+
+PR_IMPLEMENT(void)
+    _MD_init_segs (void)
+{
+}
+
+PR_IMPLEMENT(PRStatus)
+    _MD_alloc_segment (PRSegment *seg, PRUint32 size, void *vaddr)
+{
+    return PR_NOT_IMPLEMENTED_ERROR;
+}
+
+PR_IMPLEMENT(void)
+    _MD_free_segment (PRSegment *seg)
+{
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bsrcs.mk
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/bsrcs.mk	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,54 @@
+# 
+# ***** 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 *****
+
+
+# this file lists the source files to be compiled (used in Makefile) and
+# then enumerated as object files (in objs.mk) for inclusion in the NSPR
+# shared library
+
+MDCSRCS =             \
+	beos.c        \
+	beos_errors.c \
+	bfile.c       \
+	bmisc.c       \
+	bnet.c        \
+	bproc.c       \
+	brng.c        \
+	bseg.c        \
+	btime.c       \
+	bmmap.c       \
+	$(NULL)

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/btime.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/btime.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 <kernel/OS.h>
+
+static bigtime_t start;
+
+PRTime
+_MD_now (void)
+{
+    return (PRTime)real_time_clock_usecs();
+}
+
+void
+_MD_interval_init (void)
+{
+    /* grab the base interval time */
+    start = real_time_clock_usecs();
+}
+
+PRIntervalTime
+_MD_get_interval (void)
+{
+    return( (PRIntervalTime) real_time_clock_usecs() / 10 );
+
+#if 0
+    /* return the number of tens of microseconds that have elapsed since
+       we were initialized */
+    bigtime_t now = real_time_clock_usecs();
+    now -= start;
+    now /= 10;
+    return (PRIntervalTime)now;
+#endif
+}
+
+PRIntervalTime
+_MD_interval_per_sec (void)
+{
+    return 100000L;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/objs.mk
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/beos/objs.mk	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,43 @@
+# 
+# ***** 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 *****
+
+# This makefile appends to the variable OBJS the platform-dependent
+# object modules that will be part of the nspr20 library.
+
+include $(srcdir)/md/beos/bsrcs.mk
+
+OBJS += $(MDCSRCS:%.c=md/beos/$(OBJDIR)/%.$(OBJ_SUFFIX))

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,18 @@
+/MANIFEST/1.1/Thu Jun  4 22:51:07 1998//
+/MacErrorHandling.h/3.4/Sun Apr 25 15:00:59 2004//
+/macdll.c/3.12/Sun Apr 25 15:00:59 2004//
+/macdll.h/1.5/Sun Apr 25 15:00:59 2004//
+/macio.c/3.37/Sun Apr 25 15:00:59 2004//
+/macio.h/1.4/Sun Apr 25 15:00:59 2004//
+/macrng.c/1.7/Sun Apr 25 15:00:59 2004//
+/macsocket.h/3.8/Sun Apr 25 15:00:59 2004//
+/macsockotpt.c/3.42/Sun Apr 25 15:00:59 2004//
+/macthr.c/3.22/Sun Apr 25 15:00:59 2004//
+/mactime.c/3.8/Sun Apr 25 15:00:59 2004//
+/mactime.h/1.4/Sun Apr 25 15:00:59 2004//
+/mdcriticalregion.c/1.4/Sun Apr 25 15:00:59 2004//
+/mdcriticalregion.h/1.3/Sun Apr 25 15:00:59 2004//
+/mdmac.c/3.20/Mon Nov  7 22:39:01 2005//
+/mdmac.h/1.4/Sun Apr 25 15:00:59 2004//
+/prcpucfg.h/3.11/Sun Apr 25 15:00:59 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/md/mac

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/MANIFEST
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/MANIFEST	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,7 @@
+#
+# This is a list of local files which get copied to the mozilla:dist directory
+#
+
+MacErrorHandling.h
+macsocket.h
+prcpucfg.h

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/MacErrorHandling.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/MacErrorHandling.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,668 @@
+/* ***** 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 ***** */
+
+/*********************************************************************
+
+FILENAME
+	Exceptions.h
+	
+DESCRIPTION
+	A collection of routines and macros to handle assertions and
+	exceptions.
+
+COPYRIGHT
+	Copyright © Apple Computer, Inc. 1989-1991
+	All rights reserved.
+
+ROUTINES
+	EXTERNALS
+		dprintf
+		check_dprintf
+		checkpos_dprintf
+
+MACROS
+	EXTERNALS
+		check
+		ncheck
+		check_action
+		ncheck_action
+		require
+		nrequire
+		require_action
+		nrequire_action
+		resume
+
+MODIFICATION HISTORY
+	Nov 12 95		BKJ		Moved to MetroWerks environment & the NSPR
+		
+NOTE
+	To keep code size down, use these routines and macros with the C
+	compiler option -b2 or -b3. This will eliminate duplicate strings
+	within a procedure.
+
+*********************************************************************/
+
+#ifndef __MACERRORHANDLING__
+#define __MACERRORHANDLING__
+
+/*********************************************************************
+
+INCLUDES
+
+*********************************************************************/
+
+#include	<Types.h>
+
+/*<FF>*/
+/*********************************************************************
+
+CONSTANTS AND CONTROL
+
+*********************************************************************/
+
+/*
+	These defines are used to control the amount of information
+	displayed when an assertion fails. DEBUGOFF and WARN will run
+	silently. MIN will simply break into the debugger. ON will break
+	and display the assertion that failed and the exception (for
+	require statements). FULL will also display the source file name
+	and line number. SYM does a SysBreak and is usefull when using a
+	symbolic debugger like SourceBug or SADE. They should be set into
+	DEBUGLEVEL. The default LEVEL is OFF.
+*/
+
+#define DEBUGOFF		0
+#define DEBUGWARN		1
+#define DEBUGMIN		2
+#define DEBUGON			3
+#define DEBUGFULL		4
+#define DEBUGSYM		6
+
+#ifndef	DEBUGLEVEL
+#define	DEBUGLEVEL	DEBUGOFF
+#endif	DEBUGLEVEL
+
+/*
+	resumeLabel is used to control the insertion of labels for use with
+	the resume macro. If you do not use the resume macro and you wish
+	to have multible exceptions per label then you can add the
+	following define to you source code.
+	
+*/
+#define resumeLabel(exception)											// Multiple exceptions per label
+// #define resumeLabel(exception)	resume_ ## exception:				// Single exception per label
+
+
+/*
+	traceon and debugon are used to test for options
+*/
+
+#define	traceon	((DEBUGLEVEL > DEBUGWARN) && defined(TRACEON))
+#define	debugon	(DEBUGLEVEL > DEBUGWARN)
+
+/*
+	Add some macros for DEBUGMIN and DEBUGSYM to keep the size down.
+*/
+
+#define	__DEBUGSMALL	((DEBUGLEVEL == DEBUGMIN) ||			\
+								 (DEBUGLEVEL == DEBUGSYM))
+
+#if	DEBUGLEVEL == DEBUGMIN
+#define	__DebuggerBreak	Debugger()
+#elif	DEBUGLEVEL == DEBUGSYM
+#define  __DebuggerBreak	SysBreak()
+#endif
+
+
+/*<FF>*/
+/*********************************************************************
+
+MACRO
+	check(assertion)
+
+DESCRIPTION
+	If debugging is on then check will test assertion and if it fails
+	break into the debugger. Otherwise check does nothing.
+
+*********************************************************************/
+
+#if	__DEBUGSMALL
+
+#define check(assertion)															\
+	do {																			\
+		if (assertion) ;															\
+		else __DebuggerBreak;														\
+	} while (false)
+
+#elif	DEBUGLEVEL == DEBUGON
+
+#define check(assertion)															\
+	do {																			\
+		if (assertion) ;															\
+		else {																		\
+			dprintf(notrace, "Assertion \"%s\" Failed",	#assertion);				\
+		}																			\
+	} while (false)
+
+#elif	DEBUGLEVEL == DEBUGFULL
+
+#define check(assertion)															\
+	do {																			\
+		if (assertion) ;															\
+		else {																		\
+			dprintf(notrace,	"Assertion \"%s\" Failed\n"							\
+									"File: %s\n"									\
+									"Line: %d",										\
+				#assertion, __FILE__, __LINE__);									\
+		}																			\
+	} while (false)
+	
+#else
+
+#define check(assertion)
+
+#endif
+
+/*<FF>*/
+/*********************************************************************
+
+MACRO
+	ncheck(assertion)
+
+DESCRIPTION
+	If debugging is on then ncheck will test !assertion and if it fails
+	break into the debugger. Otherwise ncheck does nothing.
+
+*********************************************************************/
+
+#if	__DEBUGSMALL
+
+#define ncheck(assertion)													\
+	do {																	\
+		if (assertion) __DebuggerBreak;										\
+	} while (false)
+
+#elif	DEBUGLEVEL == DEBUGON
+
+#define ncheck(assertion)													\
+	do {																	\
+		void*	__privateAssertion	= (void*)(assertion);					\
+																			\
+		if (__privateAssertion) {											\
+			dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed",		\
+				#assertion, __privateAssertion);							\
+		}																	\
+	} while (false)
+
+#elif	DEBUGLEVEL == DEBUGFULL
+
+#define ncheck(assertion)													\
+	do {																	\
+		void*	__privateAssertion	= (void*)(assertion);					\
+																			\
+		if (__privateAssertion) {											\
+			dprintf(notrace,	"Assertion \"!(%s [= %#08X])\" Failed\n"	\
+									"File: %s\n"							\
+									"Line: %d",								\
+			#assertion, __privateAssertion, __FILE__, __LINE__);			\
+		}																	\
+	} while (false)
+
+#else
+
+#define ncheck(assertion)
+
+#endif
+
+/*<FF>*/
+/*********************************************************************
+
+MACRO
+	check_action(assertion, action)
+
+DESCRIPTION
+	If debugging is on then check_action will test assertion and if it
+	fails break into the debugger then execute action. Otherwise
+	check_action does nothing.
+	
+*********************************************************************/
+
+#if	__DEBUGSMALL
+
+#define check_action(assertion, action)										\
+	do {																	\
+		if (assertion) ;													\
+		else {																\
+			__DebuggerBreak;												\
+			{ action }														\
+	} while (false)
+
+#elif	DEBUGLEVEL == DEBUGON
+
+#define check_action(assertion, action)										\
+	do {																	\
+		if (assertion) ;													\
+		else {																\
+			dprintf(notrace, "Assertion \"%s\" Failed",	#assertion);		\
+			{ action }														\
+		}																	\
+	} while (false)
+
+#elif	DEBUGLEVEL == DEBUGFULL
+
+#define check_action(assertion, action)										\
+	do {																	\
+		if (assertion) ;													\
+		else {																\
+			dprintf(notrace,	"Assertion \"%s\" Failed\n"					\
+									"File: %s\n"							\
+									"Line: %d",								\
+				#assertion, __FILE__, __LINE__);							\
+			{ action }														\
+		}																	\
+	} while (false)
+
+#else
+
+#define check_action(assertion, action)
+
+#endif
+
+/*<FF>*/
+/**************************************************************************************
+
+MACRO
+	ncheck_action(assertion, action)
+
+DESCRIPTION
+	If debugging is on then ncheck_action will test !assertion and if
+	it fails break into the debugger then execute action. Otherwise
+	ncheck_action does nothing.
+
+*********************************************************************/
+
+#if	__DEBUGSMALL
+
+#define ncheck_action(assertion, action)									\
+	do {																	\
+		if (assertion) {													\
+			__DebuggerBreak;												\
+			{ action }														\
+		}																	\
+	} while (false)
+
+#elif	DEBUGLEVEL == DEBUGON
+
+#define ncheck_action(assertion, action)									\
+	do {																	\
+		void*	__privateAssertion	= (void*)(assertion);					\
+																			\
+		if (__privateAssertion) {											\
+			dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed",		\
+				#assertion, __privateAssertion);							\
+			{ action }														\
+		}																	\
+	} while (false)
+
+#elif DEBUGLEVEL == DEBUGFULL
+
+#define ncheck_action(assertion, action)									\
+	do {																	\
+		void*	__privateAssertion	= (void*)(assertion);					\
+																			\
+		if (__privateAssertion) {											\
+			dprintf(notrace,	"Assertion \"!(%s [= %#08X])\" Failed\n"	\
+									"File: %s\n"							\
+									"Line: %d",								\
+			#assertion, __privateAssertion, __FILE__, __LINE__);			\
+			{ action }														\
+		}																	\
+	} while (false)
+
+#else
+
+#define ncheck_action(assertion, action)
+
+#endif
+
+/*<FF>*/
+/*********************************************************************
+
+MACRO
+	require(assertion, exception)
+
+DESCRIPTION
+	require will test assertion and if it fails:
+		break into the debugger if debugging is on.
+		goto exception.
+
+*********************************************************************/
+
+#if	__DEBUGSMALL
+
+#define require(assertion, exception)										\
+	do {																	\
+		if (assertion) ;													\
+		else {																\
+			__DebuggerBreak;												\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#elif	DEBUGLEVEL == DEBUGON
+
+#define require(assertion, exception)										\
+	do {																	\
+		if (assertion) ;													\
+		else {																\
+			dprintf(notrace,	"Assertion \"%s\" Failed\n"					\
+									"Exception \"%s\" Raised",				\
+			#assertion, #exception);										\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#elif DEBUGLEVEL == DEBUGFULL
+
+#define require(assertion, exception)										\
+	do {																	\
+		if (assertion) ;													\
+		else {																\
+			dprintf(notrace,	"Assertion \"%s\" Failed\n"					\
+									"Exception \"%s\" Raised\n"				\
+									"File: %s\n"							\
+									"Line: %d",								\
+				#assertion, #exception, __FILE__, __LINE__);				\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#else
+
+#define require(assertion, exception)										\
+	do {																	\
+		if (assertion) ;													\
+		else {																\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#endif
+
+/*<FF>*/
+/*********************************************************************
+
+MACRO
+	nrequire(assertion, exception)
+
+DESCRIPTION
+	nrequire will test !assertion and if it fails:
+		break into the debugger if debugging is on.
+		goto exception.
+
+*********************************************************************/
+
+#if	__DEBUGSMALL
+
+#define nrequire(assertion, exception)										\
+	do {																	\
+		if (assertion) {													\
+			DebugStr();														\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#elif	DEBUGLEVEL == DEBUGON
+
+#define nrequire(assertion, exception)										\
+	do {																	\
+		void*	__privateAssertion	= (void*)(assertion);					\
+																			\
+		if (__privateAssertion) {											\
+			dprintf(notrace,	"Assertion \"!(%s [= %#08X])\" Failed\n"	\
+									"Exception \"%s\" Raised",				\
+				#assertion, __privateAssertion, #exception);				\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#elif DEBUGLEVEL == DEBUGFULL
+
+#define nrequire(assertion, exception)										\
+	do {																	\
+		void*	__privateAssertion	= (void*)(assertion);					\
+																			\
+		if (__privateAssertion) {											\
+			dprintf(notrace,	"Assertion \"!(%s [= %#08X])\" Failed\n"	\
+									"Exception \"%s\" Raised\n"				\
+									"File: %s\n"							\
+									"Line: %d",								\
+				#assertion, __privateAssertion, #exception, __FILE__,		\
+				__LINE__);													\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#else
+
+#define nrequire(assertion, exception)										\
+	do {																	\
+		if (assertion) {													\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#endif
+
+/*<FF>*/
+/*********************************************************************
+
+MACRO
+	require_action(assertion, exception, action)
+
+DESCRIPTION
+	require_action will test assertion and if it fails:
+		break into the debugger if debugging is on.
+		execute action.
+		goto exception.
+
+*********************************************************************/
+
+#if	__DEBUGSMALL
+
+#define require_action(assertion, exception, action)						\
+	do {																	\
+		if (assertion) ;													\
+		else {																\
+			__DebuggerBreak;												\
+			{ action }														\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#elif	DEBUGLEVEL == DEBUGON
+
+#define require_action(assertion, exception, action)						\
+	do {																	\
+		if (assertion) ;													\
+		else {																\
+			dprintf(notrace,	"Assertion \"%s\" Failed\n"					\
+									"Exception \"%s\" Raised",				\
+			#assertion, #exception);										\
+			{ action }														\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#elif DEBUGLEVEL == DEBUGFULL
+
+#define require_action(assertion, exception, action)						\
+	do {																	\
+		if (assertion) ;													\
+		else {																\
+			dprintf(notrace,	"Assertion \"%s\" Failed\n"					\
+									"Exception \"%s\" Raised\n"				\
+									"File: %s\n"							\
+									"Line: %d",								\
+				#assertion, #exception, __FILE__, __LINE__);				\
+			{ action }														\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#else
+
+#define require_action(assertion, exception, action)						\
+	do {																	\
+		if (assertion) ;													\
+		else {																\
+			{ action }														\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#endif
+
+/*<FF>*/
+/*********************************************************************
+
+MACRO
+	nrequire_action(assertion, exception, action)
+
+DESCRIPTION
+	nrequire_action will test !assertion and if it fails:
+		break into the debugger if debugging is on.
+		execute action.
+		goto exception.
+
+*********************************************************************/
+
+#if	__DEBUGSMALL
+
+#define nrequire_action(assertion, exception, action)						\
+	do {																	\
+		if (assertion) {													\
+			__DebuggerBreak;												\
+			{ action }														\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#elif DEBUGLEVEL == DEBUGON
+
+#define nrequire_action(assertion, exception, action)						\
+	do {																	\
+		void*	__privateAssertion	= (void*)(assertion);					\
+																			\
+		if (__privateAssertion) {											\
+			dprintf(notrace,	"Assertion \"!(%s [= %#08X])\" Failed\n"	\
+									"Exception \"%s\" Raised",				\
+				#assertion, __privateAssertion, #exception);				\
+			{ action }														\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#elif DEBUGLEVEL == DEBUGFULL
+
+#define nrequire_action(assertion, exception, action)						\
+	do {																	\
+		void*	__privateAssertion	= (void*)(assertion);					\
+																			\
+		if (__privateAssertion) {											\
+			dprintf(notrace,	"Assertion \"!(%s [= %#08X])\" Failed\n"	\
+									"Exception \"%s\" Raised\n"				\
+									"File: %s\n"							\
+									"Line: %d",								\
+				#assertion, __privateAssertion, #exception, __FILE__,		\
+				__LINE__);													\
+			{ action }														\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#else
+
+#define nrequire_action(assertion, exception, action)						\
+	do {																	\
+		if (assertion) {													\
+			{ action }														\
+			goto exception;													\
+			resumeLabel(exception);											\
+		}																	\
+	} while (false)
+
+#endif
+	
+/*<FF>*/
+/*********************************************************************
+
+MACRO
+	resume(exception)
+
+DESCRIPTION
+	resume will resume execution after the n/require/_action statement
+	specified by exception. Resume lables must be on (the default) in
+	order to use resume. If an action form of require was used then the
+	action will not be re-executed.
+
+*********************************************************************/
+
+
+#define resume(exception)													\
+	do {																	\
+		goto resume_ ## exception;											\
+	} while (false)
+
+
+/*<FF>*/
+/********************************************************************/
+#endif

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macdll.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macdll.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,587 @@
+/* -*- 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 <Files.h>
+#include <Errors.h>
+#include <Folders.h>
+#include <CodeFragments.h>
+#include <Aliases.h>
+#include <Resources.h>
+
+#include "IterateDirectory.h"		/* MoreFiles */
+
+#include "MacErrorHandling.h"
+#include "macdll.h"
+#include "mdmac.h"
+#include "macio.h"
+
+#include "primpl.h"
+#include "plstr.h"
+
+/*
+	turds used to iterate through the directories looking
+	for the desired library.
+*/
+
+struct GetSharedLibraryFilterProcData
+{
+	Boolean				inRecursive;
+	StringPtr			inName;
+	
+	Boolean				outFound;
+	CFragConnectionID	outID;
+	Ptr					outAddress;
+	OSErr				outError;
+};
+typedef struct GetSharedLibraryFilterProcData GetSharedLibraryFilterProcData;
+
+static pascal void
+GetSharedLibraryFilterProc(const CInfoPBRec* const inCpb, Boolean* inWantQuit, void *inFilterData);
+
+
+/*
+	NSGetSharedLibrary
+	
+	Unfortunately CFM doesn't support user specified loader paths,
+	so we emulate the behavior.  Effectively this is a GetSharedLibrary
+	where the loader path is user defined.
+*/
+
+OSErr
+NSGetSharedLibrary(Str255 inLibName, CFragConnectionID* outID, Ptr* outMainAddr)
+{
+	char*		curLibPath;
+	char*		freeCurLibPath;
+	OSErr		tempErr;
+	Boolean		recursive;
+	FSSpec		curFolder;	
+	GetSharedLibraryFilterProcData filterData;
+	char		*endCurLibPath;
+	Boolean		done;
+	
+	filterData.outFound = false;
+	filterData.outID = (CFragConnectionID)(-1);
+	filterData.outAddress = NULL;
+	filterData.inName = inLibName;
+		
+	freeCurLibPath = curLibPath = PR_GetLibraryPath();
+	
+	if (curLibPath == NULL)
+		return (cfragNoLibraryErr);
+	
+	tempErr = cfragNoLibraryErr;
+	
+	do
+	{
+		endCurLibPath = PL_strchr(curLibPath, PR_PATH_SEPARATOR);
+		done = (endCurLibPath == NULL);
+
+#if 0
+		// we overload the first character of a path if it's :
+		// then we want to recursively search that path
+		// see if path should be recursive
+		if (*curLibPath == ':')
+		{
+			// ':' is an illegal character in the name of a file
+			// if we start any path with this, we want to allow 
+			// search recursively
+			curLibPath++;
+			recursive = true;
+		}
+		else
+#endif
+		{
+			recursive = false;
+		}
+		
+		if (!done)
+			*endCurLibPath = '\0';	// NULL terminate the string
+		
+		// convert to FSSpec
+		tempErr = ConvertUnixPathToFSSpec(curLibPath, &curFolder);	
+
+		// now look in this directory
+		if (noErr == tempErr)
+		{
+			filterData.inRecursive = recursive;
+			FSpIterateDirectory(&curFolder, recursive ? 0 : 1, &GetSharedLibraryFilterProc, &filterData);
+			
+			if (filterData.outFound)
+			{
+				*outID = filterData.outID;
+				*outMainAddr = filterData.outAddress;
+				tempErr = noErr;
+				break;
+			}
+			else 
+			{
+				tempErr = cfragNoLibraryErr;
+			}
+		}
+		
+		curLibPath = endCurLibPath + 1;	// skip to next path (past the '\0');
+	} while (!done);
+
+	free(freeCurLibPath);
+	return (tempErr);
+}
+
+
+static Boolean
+LibInPefContainer(const FSSpec* inSpec, StringPtr inName, UInt32* outCodeOffset, UInt32* outCodeLength);
+
+
+/*
+	GetSharedLibraryFilterProc
+	
+	Callback to FSpIterateDirectory, finds a library with the name matching the
+	data in inFilterData (of type GetSharedLibraryFilterProcData).  Forces a quit
+	when a match is found.
+*/
+
+static pascal void
+GetSharedLibraryFilterProc(const CInfoPBRec* const inCpb, Boolean* inWantQuit, void *inFilterData)
+{
+	GetSharedLibraryFilterProcData* pFilterData = (GetSharedLibraryFilterProcData*) inFilterData;
+
+	if ((inCpb->hFileInfo.ioFlAttrib & (1 << ioDirFlg)) == 0)
+	{
+		FSSpec	fragSpec;
+		OSErr	tempErr;
+		Str255	errName;
+		Boolean	crap;
+		UInt32	codeOffset;
+		UInt32	codeLength;
+		
+		// it's a file
+		
+		// ¥ fix-me do we really want to allow all 'APPL's' for in which to find this library?
+		switch (inCpb->hFileInfo.ioFlFndrInfo.fdType)
+		{
+			case kCFragLibraryFileType:
+			case 'APPL':
+				tempErr = FSMakeFSSpec(inCpb->hFileInfo.ioVRefNum, inCpb->hFileInfo.ioFlParID, inCpb->hFileInfo.ioNamePtr, &fragSpec);
+
+				// this shouldn't fail
+				if (noErr != tempErr)
+				{
+					return;
+				}
+				
+				// resolve an alias if this was one
+				tempErr = ResolveAliasFile(&fragSpec, true, &crap, &crap);
+
+				// if got here we have a shlb (or app-like shlb)
+				if (noErr != tempErr)
+				{
+					// probably couldn't resolve an alias
+					return;
+				}
+		
+				break;
+			default:
+				return;
+		}
+	
+		// see if this symbol is in this fragment
+		if (LibInPefContainer(&fragSpec, pFilterData->inName, &codeOffset, &codeLength))
+			tempErr = GetDiskFragment(&fragSpec, codeOffset, codeLength, fragSpec.name, kLoadCFrag, &pFilterData->outID, &pFilterData->outAddress, errName);
+		else
+			return;
+				
+		// stop if we found a library by that name
+		if (noErr == tempErr)
+		{			
+			*inWantQuit = true;
+			pFilterData->outFound = true;
+			pFilterData->outError = tempErr;
+		}
+	}
+	// FSpIterateDirectory will automagically call us for subsequent sub-dirs if necessary
+}
+
+
+/*
+	LibInPefContainer
+	
+	Tell whether library inName is contained it the file pointed to by inSpec.
+	Return the codeOffset and codeLength information, for a subsequent
+	call to GetDiskFragment.
+*/
+
+static Boolean
+LibInPefContainer(const FSSpec* inSpec, StringPtr inName, UInt32* outCodeOffset, UInt32* outCodeLength)
+{
+	short					refNum;
+	CFragResourceHandle		hCfrg;
+	CFragResourceMember*	pCurItem;
+	UInt32					curLibIndex;
+	Boolean					found;
+	
+	// asume we didn't find it
+	found = false;
+	
+	// open the resource fork, if we can't bail
+	refNum = FSpOpenResFile(inSpec, fsRdPerm);
+	require(-1 != refNum, Exit);
+	
+	// grab out the alias record, if it's not there bail
+	hCfrg = (CFragResourceHandle) Get1Resource(kCFragResourceType, kCFragResourceID);
+	require(NULL != hCfrg, CloseResourceAndExit);
+	
+	HLock((Handle)hCfrg);
+	
+	// get ptr to first item
+	pCurItem = &(*hCfrg)->firstMember;
+	for (curLibIndex = 0; curLibIndex < (*hCfrg)->memberCount; curLibIndex++)
+	{
+		// is this our library?
+		if ((pCurItem->name[0] == inName[0]) &&
+			(strncmp((char*) inName + 1, (char*) pCurItem->name + 1, PR_MIN(pCurItem->name[0], inName[0])) == 0))
+		{
+			*outCodeOffset = pCurItem->offset;
+			*outCodeLength = pCurItem->length;
+			found = true;
+		}
+		
+		// skip to next one
+		pCurItem = (CFragResourceMember*) ((char*) pCurItem + pCurItem->memberSize);						
+	}
+	
+	HUnlock((Handle)hCfrg);
+	
+CloseResourceAndExit:
+	CloseResFile(refNum);
+Exit:
+	return (found);
+
+}
+
+
+/*
+	NSFindSymbol
+	
+	Workaround bug in CFM FindSymbol (in at least 7.5.5) where symbols with lengths
+	greater than 63 chars cause a "paramErr".  We iterate through all symbols
+	in the library to find the desired symbol.
+*/
+
+OSErr
+NSFindSymbol(CFragConnectionID inID, Str255 inSymName, Ptr*	outMainAddr, CFragSymbolClass *outSymClass)
+{
+	OSErr	err;
+	
+	if (inSymName[0] > 63)
+	{
+		/* 
+			if there are greater than 63 characters in the
+			name, CFM FindSymbol fails, so let's iterate through all
+			of the symbols in the fragment and grab it 
+			that way.
+		*/
+		long 	symbolCount;
+		Str255	curSymName;
+		long	curIndex;
+		Boolean found;
+		
+		found = false;
+		err = CountSymbols(inID, &symbolCount);
+		if (noErr == err)
+		{
+			/* now iterate through all the symbols in the library */
+			/* per DTS the indices apparently go 0 to n-1 */
+			for (curIndex = 0; (curIndex <= symbolCount - 1 && !found); curIndex++)
+			{
+				err = GetIndSymbol(inID, curIndex, curSymName, outMainAddr, outSymClass);
+				if (noErr == err && curSymName[0] == inSymName[0] && !strncmp((char*)curSymName + 1, (char*)inSymName + 1, curSymName[0]))
+				{
+					/* found our symbol */
+					found = true;
+				}
+			}
+			
+			/* if we didn't find it set the error code so below it won't take this symbol */
+			if (!found)
+				err = cfragNoSymbolErr;
+		}	
+	}
+	else
+	{	
+		err = FindSymbol(inID, inSymName, outMainAddr, outSymClass);
+	}
+	
+	return (err);
+}
+
+
+#pragma mark -
+
+
+/*-----------------------------------------------------------------
+
+	GetNamedFragmentOffsets
+
+	Get the offsets into the data fork of the named fragment,
+	by reading the 'cfrg' resoruce.
+
+-----------------------------------------------------------------*/
+OSErr GetNamedFragmentOffsets(const FSSpec *fileSpec, const char* fragmentName,
+							UInt32 *outOffset, UInt32 *outLength)
+{
+	CFragResourceHandle		cFragHandle;
+	short									fileRefNum;
+	OSErr									err = noErr;
+	
+	fileRefNum = FSpOpenResFile(fileSpec, fsRdPerm);
+	err = ResError();
+	if (err != noErr) return err;
+
+	cFragHandle = (CFragResourceHandle)Get1Resource(kCFragResourceType, kCFragResourceID);	
+	if (!cFragHandle)
+	{
+		err = resNotFound;
+		goto done;
+	}
+	
+	/* nothing here moves memory, so no need to lock the handle */
+	
+	err = cfragNoLibraryErr;			/* in case of failure */
+	*outOffset = 0;
+	*outLength = 0;
+	
+	/* Now look for the named fragment */
+	if ((**cFragHandle).memberCount > 0)
+	{
+		CFragResourceMemberPtr	memberPtr;
+		UInt16									i;
+		
+		for (	i = 0, memberPtr = &(**cFragHandle).firstMember;
+					i < (**cFragHandle).memberCount;
+					i ++, memberPtr = (CFragResourceMemberPtr)((char *)memberPtr + memberPtr->memberSize))
+		{
+			char		memberName[256];
+			UInt16	nameLen = PR_MIN(memberPtr->name[0], 255);
+		
+			// avoid malloc here for speed
+			strncpy(memberName, (char *)&memberPtr->name[1], nameLen);
+			memberName[nameLen] = '\0';
+		
+			// fragment names are case insensitive, so act like the system
+			if (PL_strcasecmp(memberName, fragmentName) == 0)
+			{
+				*outOffset = memberPtr->offset;
+				*outLength = memberPtr->length;
+				err = noErr;
+				break;
+			}
+		}
+	}
+	
+	/* Resource handle will go away when the res fork is closed */
+	
+done:
+	CloseResFile(fileRefNum);
+	return err;
+}
+
+
+/*-----------------------------------------------------------------
+
+	GetIndexedFragmentOffsets
+	
+	Get the offsets into the data fork of the indexed fragment,
+	by reading the 'cfrg' resoruce.
+
+-----------------------------------------------------------------*/
+OSErr GetIndexedFragmentOffsets(const FSSpec *fileSpec, UInt32 fragmentIndex,
+							UInt32 *outOffset, UInt32 *outLength, char **outFragmentName)
+{
+	CFragResourceHandle		cFragHandle;
+	short									fileRefNum;
+	OSErr									err = noErr;
+	
+	fileRefNum = FSpOpenResFile(fileSpec, fsRdPerm);
+	err = ResError();
+	if (err != noErr) return err;
+
+	cFragHandle = (CFragResourceHandle)Get1Resource(kCFragResourceType, kCFragResourceID);	
+	if (!cFragHandle)
+	{
+		err = resNotFound;
+		goto done;
+	}
+		
+	err = cfragNoLibraryErr;			/* in case of failure */
+	*outOffset = 0;
+	*outLength = 0;
+	*outFragmentName = NULL;
+	
+	/* the CStrFromPStr mallocs, so might move memory */
+	HLock((Handle)cFragHandle);
+	
+	/* Now look for the named fragment */
+	if ((**cFragHandle).memberCount > 0)
+	{
+		CFragResourceMemberPtr	memberPtr;
+		UInt16									i;
+		
+		for (	i = 0, memberPtr = &(**cFragHandle).firstMember;
+					i < (**cFragHandle).memberCount;
+					i ++, memberPtr = (CFragResourceMemberPtr)((char *)memberPtr + memberPtr->memberSize))
+		{
+			
+			if (i == fragmentIndex)
+			{
+				char	*fragmentStr;
+				CStrFromPStr(memberPtr->name, &fragmentStr);
+				if (!fragmentStr)		/* test for allocation failure */
+				{
+					err = memFullErr;
+					break;
+				}
+				
+				*outFragmentName = fragmentStr;
+				*outOffset = memberPtr->offset;
+				*outLength = memberPtr->length;
+				err = noErr;
+				break;
+			}
+		}
+	}
+	
+	HUnlock((Handle)cFragHandle);
+	
+	/* Resource handle will go away when the res fork is closed */
+	
+done:
+	CloseResFile(fileRefNum);
+	return err;
+}
+
+
+/*-----------------------------------------------------------------
+
+	NSLoadNamedFragment
+	
+	Load the named fragment from the specified file. Aliases must
+	have been resolved by this point.
+
+-----------------------------------------------------------------*/
+
+OSErr NSLoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName, CFragConnectionID *outConnectionID)
+{
+    UInt32      fragOffset, fragLength;
+    short       fragNameLength;
+    Ptr             main;
+    Str255      fragName;
+    Str255      errName;
+    OSErr           err;
+    
+    err = GetNamedFragmentOffsets(fileSpec, fragmentName, &fragOffset, &fragLength);
+    if (err != noErr) return err;
+    
+    // convert fragment name to pascal string
+    fragNameLength = strlen(fragmentName);
+    if (fragNameLength > 255)
+        fragNameLength = 255;
+    BlockMoveData(fragmentName, &fragName[1], fragNameLength);
+    fragName[0] = fragNameLength;
+    
+    // Note that we pass the fragment name as the 4th param to GetDiskFragment.
+    // This value affects the ability of debuggers, and the Talkback system,
+    // to match code fragments with symbol files
+    err = GetDiskFragment(fileSpec, fragOffset, fragLength, fragName, 
+                    kLoadCFrag, outConnectionID, &main, errName);
+
+    return err;
+}
+
+
+/*-----------------------------------------------------------------
+
+	NSLoadIndexedFragment
+	
+	Load the indexed fragment from the specified file. Aliases must
+	have been resolved by this point.
+	
+	*outFragName is a malloc'd block containing the fragment name,
+	if returning noErr.
+
+-----------------------------------------------------------------*/
+
+OSErr NSLoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragmentIndex,
+                            char** outFragName, CFragConnectionID *outConnectionID)
+{
+    UInt32      fragOffset, fragLength;
+    char        *fragNameBlock = NULL;
+    Ptr         main;
+    Str255      fragName = "\p";
+    Str255      errName;
+    OSErr       err;
+
+    *outFragName = NULL;
+    
+    err = GetIndexedFragmentOffsets(fileSpec, fragmentIndex, &fragOffset, &fragLength, &fragNameBlock);
+    if (err != noErr) return err;
+                
+    if (fragNameBlock)
+    {
+        UInt32 nameLen = strlen(fragNameBlock);
+        if (nameLen > 63)
+            nameLen = 63;
+        BlockMoveData(fragNameBlock, &fragName[1], nameLen);
+        fragName[0] = nameLen;
+    }
+
+    // Note that we pass the fragment name as the 4th param to GetDiskFragment.
+    // This value affects the ability of debuggers, and the Talkback system,
+    // to match code fragments with symbol files
+    err = GetDiskFragment(fileSpec, fragOffset, fragLength, fragName, 
+                    kLoadCFrag, outConnectionID, &main, errName);
+    if (err != noErr)
+    {
+        free(fragNameBlock);
+        return err;
+    }
+
+    *outFragName = fragNameBlock;
+    return noErr;
+}
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macdll.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macdll.h	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+#ifndef macdll_h__
+#define macdll_h__
+
+#include "prtypes.h"
+
+OSErr GetNamedFragmentOffsets(const FSSpec *fileSpec, const char* fragmentName,
+							UInt32 *outOffset, UInt32 *outLength);
+OSErr GetIndexedFragmentOffsets(const FSSpec *fileSpec, UInt32 fragmentIndex,
+							UInt32 *outOffset, UInt32 *outLength, char **outFragmentName);
+							
+OSErr NSLoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName, CFragConnectionID *outConnectionID);
+OSErr NSLoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragmentIndex,
+							char** outFragName, CFragConnectionID *outConnectionID);
+
+
+OSErr NSGetSharedLibrary(Str255 inLibName, CFragConnectionID* outID, Ptr* outMainAddr);
+OSErr NSFindSymbol(CFragConnectionID inID, Str255 inSymName,
+							Ptr*	outMainAddr, CFragSymbolClass *outSymClass);
+
+#endif /* macdll_h__ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macio.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macio.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1949 @@
+/* -*- 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 <Types.h>
+#include <Files.h>
+#include <Devices.h>
+#include <Folders.h>
+#include <Errors.h>
+#include <Resources.h>
+#include <Processes.h>
+#include <TextUtils.h>
+
+#include <fcntl.h>
+
+#include "FullPath.h"		/* MoreFiles */
+
+#include "primpl.h"
+#include "MacErrorHandling.h"
+#include "mdmac.h"
+
+#include "macio.h"
+
+/* forward declarations */
+extern unsigned long gJanuaryFirst1970Seconds;
+
+extern void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout);
+extern void DoneWaitingOnThisThread(PRThread *thread);
+extern void AsyncNotify(PRThread *thread);
+
+
+/* PB for Read and Write */
+struct ExtendedParamBlock {
+	/* PB must be first so that the file system can get the right data. */
+ 	ParamBlockRec 	pb;
+	PRThread 		*thread;
+};
+typedef struct ExtendedParamBlock ExtendedParamBlock;
+
+
+/* XXX Not done yet for 68K */
+/* I/O completion routne for _MD_READ and _MD_WRITE */
+static void AsyncIOCompletion (ExtendedParamBlock *pbAsyncPtr)
+{
+    _PRCPU *cpu = _PR_MD_CURRENT_CPU();
+    PRThread *thread = pbAsyncPtr->thread;    
+    PRIntn is;
+    
+    if (_PR_MD_GET_INTSOFF()) {
+        thread->md.missedIONotify = PR_TRUE;
+        cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+    } else {
+        _PR_INTSOFF(is);
+
+        thread->md.osErrCode = noErr;
+        DoneWaitingOnThisThread(thread);
+
+        _PR_FAST_INTSON(is);
+    }
+
+    SignalIdleSemaphore();
+}
+
+void  _MD_SetError(OSErr oserror)
+{
+    PRErrorCode code;
+
+    switch (oserror) {
+      case memFullErr:
+        code = PR_OUT_OF_MEMORY_ERROR;
+        break;
+      case fnfErr:
+        code = PR_FILE_NOT_FOUND_ERROR;
+        break;
+      case dupFNErr:
+        code = PR_FILE_EXISTS_ERROR;
+        break;
+      case ioErr:
+        code = PR_IO_ERROR;
+        break;
+      case nsvErr:
+      case wrgVolTypErr:
+        code = PR_INVALID_DEVICE_STATE_ERROR;
+        break;
+      case bdNamErr:
+      case fsRnErr:
+        code = PR_NAME_TOO_LONG_ERROR;
+        break;
+      case tmfoErr:
+        code = PR_INSUFFICIENT_RESOURCES_ERROR;
+        break;
+      case opWrErr:
+      case wrPermErr:
+      case permErr:
+      case afpAccessDenied:
+        code = PR_NO_ACCESS_RIGHTS_ERROR;
+        break;
+      case afpObjectTypeErr:
+        code = PR_DIRECTORY_LOOKUP_ERROR;
+        break;
+      case wPrErr:
+      case vLckdErr:
+        code = PR_DEVICE_IS_LOCKED_ERROR;
+        break;
+      case fLckdErr:
+        code = PR_FILE_IS_LOCKED_ERROR;
+        break;
+      case dirNFErr:
+        code = PR_NOT_DIRECTORY_ERROR;
+        break;
+      case dirFulErr:
+        code = PR_MAX_DIRECTORY_ENTRIES_ERROR;
+        break;
+      case dskFulErr:
+        code = PR_NO_DEVICE_SPACE_ERROR;
+        break;
+      case rfNumErr:
+      case fnOpnErr:
+        code = PR_BAD_DESCRIPTOR_ERROR;
+        break;
+      case eofErr:
+        code = PR_END_OF_FILE_ERROR;
+        break;
+      case posErr:
+      case gfpErr:
+        code = PR_FILE_SEEK_ERROR;
+        break;
+      case fBsyErr:
+        code = PR_FILE_IS_BUSY_ERROR;
+        break;
+      case extFSErr:
+        code = PR_REMOTE_FILE_ERROR;
+        break;
+      case abortErr:
+        code = PR_PENDING_INTERRUPT_ERROR;
+        break;
+      case paramErr:
+        code = PR_INVALID_ARGUMENT_ERROR;
+        break;
+      case unimpErr:
+        code = PR_NOT_IMPLEMENTED_ERROR;
+        break;
+    }
+
+    PR_SetError(code, oserror);
+}
+
+void _MD_IOInterrupt(void)
+{
+    PRCList *qp;
+    PRThread *thread, *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
+
+    _PR_SLEEPQ_LOCK(me->cpu);
+    qp = _PR_PAUSEQ(me->cpu).next;
+    while (qp != &_PR_PAUSEQ(me->cpu)) {
+
+		thread = _PR_THREAD_PTR(qp);
+		PR_ASSERT(thread->flags & _PR_ON_PAUSEQ);
+
+		qp = qp->next;
+		
+		if (thread->md.missedIONotify) {
+			thread->md.missedIONotify = PR_FALSE;
+			DoneWaitingOnThisThread(thread);
+		}
+
+		if (thread->md.missedAsyncNotify) {
+			thread->md.missedAsyncNotify = PR_FALSE;
+			AsyncNotify(thread);
+		}
+    }
+    qp = _PR_SLEEPQ(me->cpu).next;
+    while (qp != &_PR_SLEEPQ(me->cpu)) {
+
+		thread = _PR_THREAD_PTR(qp);
+		PR_ASSERT(thread->flags & _PR_ON_SLEEPQ);
+
+		qp = qp->next;
+		
+		if (thread->md.missedIONotify) {
+			thread->md.missedIONotify = PR_FALSE;
+			DoneWaitingOnThisThread(thread);
+		}
+
+		if (thread->md.missedAsyncNotify) {
+			thread->md.missedAsyncNotify = PR_FALSE;
+			AsyncNotify(thread);
+		}
+    }
+	_PR_SLEEPQ_UNLOCK(thread->cpu);
+}
+
+/* 
+** All PR_read and PR_Write calls are synchronous from caller's perspective.
+** They are internally made asynchronous calls.  This gives cpu to other
+** user threads while the async io is in progress.
+*/
+PRInt32 ReadWriteProc(PRFileDesc *fd, void *buf, PRUint32 bytes, IOOperation op)
+{
+	PRInt32 refNum = fd->secret->md.osfd;
+	OSErr				err;
+	ExtendedParamBlock 	pbAsync;
+	PRThread			*me = _PR_MD_CURRENT_THREAD();
+	_PRCPU *cpu = _PR_MD_CURRENT_CPU();
+
+	/* quick hack to allow PR_fprintf, etc to work with stderr, stdin, stdout */
+	/* note, if a user chooses "seek" or the like as an operation in another function */
+	/* this will not work */
+	if (refNum >= 0 && refNum < 3)
+	{
+		switch (refNum)
+		{
+				case 0:
+					/* stdin - not on a Mac for now */
+					err = paramErr;
+					goto ErrorExit;
+					break;
+				case 1: /* stdout */
+				case 2: /* stderr */
+					puts(buf);
+					break;
+		}
+		
+		return (bytes);
+	}
+	else
+	{
+		static IOCompletionUPP	sCompletionUPP = NULL;
+		
+		PRBool  doingAsync = PR_FALSE;
+		
+		/* allocate the callback Universal Procedure Pointer (UPP). This actually allocates
+		   a 32 byte Ptr in the heap, so only do this once
+		*/
+		if (!sCompletionUPP)
+			sCompletionUPP = NewIOCompletionUPP((IOCompletionProcPtr)&AsyncIOCompletion);
+			
+		/* grab the thread so we know which one to post to at completion */
+		pbAsync.thread	= me;
+
+		pbAsync.pb.ioParam.ioCompletion	= sCompletionUPP;
+		pbAsync.pb.ioParam.ioResult		= noErr;
+		pbAsync.pb.ioParam.ioRefNum		= refNum;
+		pbAsync.pb.ioParam.ioBuffer		= buf;
+		pbAsync.pb.ioParam.ioReqCount	= bytes;
+		pbAsync.pb.ioParam.ioPosMode	= fsAtMark;
+		pbAsync.pb.ioParam.ioPosOffset	= 0;
+
+		/* 
+		** Issue the async read call and wait for the io semaphore associated
+		** with this thread.
+		** Async file system calls *never* return error values, so ignore their
+		** results (see <http://developer.apple.com/technotes/fl/fl_515.html>);
+		** the completion routine is always called.
+		*/
+		me->io_fd = refNum;
+		me->md.osErrCode = noErr;
+		if (op == READ_ASYNC)
+		{
+			/*
+			**  Skanky optimization so that reads < 20K are actually done synchronously
+			**  to optimize performance on small reads (e.g. registry reads on startup)
+			*/
+			if ( bytes > 20480L )
+			{
+				doingAsync = PR_TRUE;
+				me->io_pending = PR_TRUE;
+				
+				(void)PBReadAsync(&pbAsync.pb);
+			}
+			else
+			{
+				pbAsync.pb.ioParam.ioCompletion = NULL;
+				me->io_pending = PR_FALSE;
+				
+				err = PBReadSync(&pbAsync.pb);
+				if (err != noErr && err != eofErr)
+					goto ErrorExit;
+			}
+		}
+		else
+		{
+			doingAsync = PR_TRUE;
+			me->io_pending = PR_TRUE;
+
+			/* writes are currently always async */
+			(void)PBWriteAsync(&pbAsync.pb);
+		}
+		
+		if (doingAsync) {
+			WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+		}
+	}
+	
+	err = me->md.osErrCode;
+	if (err != noErr)
+		goto ErrorExit;
+
+	err = pbAsync.pb.ioParam.ioResult;
+	if (err != noErr && err != eofErr)
+		goto ErrorExit;
+	
+	return pbAsync.pb.ioParam.ioActCount;
+
+ErrorExit:
+	me->md.osErrCode = err;
+	_MD_SetError(err);
+	return -1;
+}
+
+/*
+Special WriteSyncProc for logging only.  IO occurs synchronously.  Otherwise,
+logging internal to NSPR causes ReadWriteProc above to recurse on PR_WaitSem logging.
+*/
+PRInt32 WriteSyncProc(PRFileDesc *fd, void *buf, PRUint32 bytes)
+{
+	PRInt32				refNum = fd->secret->md.osfd;
+	OSErr				err;
+ 	ParamBlockRec 		pb;
+	PRThread			*me = _PR_MD_CURRENT_THREAD();
+	
+	if (refNum >= 0 && refNum < 3)
+	{
+		PR_ASSERT(FALSE);	/* writing to these is hazardous to a Mac's health (refNum 2 is the system file) */
+		err = paramErr;
+		goto ErrorExit;
+	}
+
+	pb.ioParam.ioCompletion	= NULL;
+	pb.ioParam.ioResult		= noErr;
+	pb.ioParam.ioRefNum		= refNum;
+	pb.ioParam.ioBuffer		= buf;
+	pb.ioParam.ioReqCount	= bytes;
+	pb.ioParam.ioPosMode	= fsAtMark;
+	pb.ioParam.ioPosOffset	= 0;
+
+	err = PBWriteSync(&pb);
+
+	if (err != noErr)
+		goto ErrorExit;
+	else
+		return pb.ioParam.ioActCount;
+
+ErrorExit:
+	me->md.osErrCode = err;
+	_MD_SetError(err);
+    return -1;
+}
+
+/* File I/O functions called by PR I/O routines */
+PRInt32 _MD_Open(const char *path, PRIntn flags, int mode)
+{
+// Macintosh doesn't really have mode bits, just drop them
+#pragma unused (mode)
+
+	OSErr 				err;
+ 	HParamBlockRec 		hpb;
+ 	ParamBlockRec 		pb;
+	char	 			*macFileName = NULL;
+	Str255				pascalName;
+	PRInt8 				perm;
+
+    err = ConvertUnixPathToMacPath(path, &macFileName);
+	
+	if (err != noErr)
+		goto ErrorExit;
+
+	hpb.ioParam.ioCompletion	= NULL;
+	PStrFromCStr(macFileName, pascalName);
+	PR_DELETE(macFileName);
+	hpb.ioParam.ioNamePtr 	= pascalName;
+	hpb.ioParam.ioVRefNum 	= 0;
+	hpb.ioParam.ioVersNum 	= 0;
+	hpb.fileParam.ioDirID	= 0;
+
+	if (flags & PR_RDWR)
+		perm = fsRdWrPerm;
+	else if (flags & PR_WRONLY)
+		perm = fsWrPerm;
+	else
+		perm = fsRdPerm;	
+	hpb.ioParam.ioPermssn 	= perm;
+
+	
+    if (flags & PR_CREATE_FILE) {
+		err = PBHCreateSync(&hpb);
+               
+       /* If opening with the PR_EXCL flag the existence of the file prior to opening is an error */
+       if ((flags & PR_EXCL) &&  (err == dupFNErr)) {
+           err = PR_FILE_EXISTS_ERROR;
+           goto ErrorExit;
+       }
+       
+       if ((err != noErr) && (err != dupFNErr))
+          goto ErrorExit;
+	}
+ 
+    err = PBHOpenDFSync(&hpb);
+
+	if (err != noErr)
+		goto ErrorExit;
+
+	if (flags & PR_TRUNCATE) {
+		pb.ioParam.ioCompletion = NULL;
+		pb.ioParam.ioRefNum = hpb.ioParam.ioRefNum;
+		pb.ioParam.ioMisc = NULL;
+		err = PBSetEOFSync(&pb);
+		if (err != noErr)
+			goto ErrorExit;
+	} else if (flags & PR_APPEND) {
+		pb.ioParam.ioCompletion = NULL;
+		pb.ioParam.ioRefNum = hpb.ioParam.ioRefNum;
+		pb.ioParam.ioPosMode = fsFromLEOF;
+		pb.ioParam.ioPosOffset = 0;
+		err = PBSetFPosSync(&pb);
+		if (err != noErr)
+			goto ErrorExit;
+	}
+	return hpb.ioParam.ioRefNum;
+		
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return -1;
+}
+
+/* _MD_CLOSE_FILE, _MD_READ, _MD_WRITE, _MD_GET_FILE_ERROR are defined in _macos.h */
+
+PROffset32 _MD_LSeek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence how)
+{
+	PRInt32 refNum = fd->secret->md.osfd;
+	OSErr 	err = noErr;
+	long	curPos, endPos;
+
+	/* compute new mark */
+	switch (how) {
+		case PR_SEEK_SET:
+			endPos = offset;
+			break;
+		
+		case PR_SEEK_CUR:
+			err = GetFPos(refNum, &curPos);
+			endPos = curPos + offset;
+			break;
+		
+		case PR_SEEK_END:
+			err = GetEOF(refNum, &curPos);
+			endPos = curPos + offset;
+			break;
+
+		default:
+			err = paramErr;
+			break;
+	}
+
+	/* set the new mark and extend the file if seeking beyond current EOF */
+	/* making sure to set the mark after any required extend */
+	if (err == noErr) {
+		err = SetFPos(refNum, fsFromStart, endPos);
+		if (err == eofErr) {
+			err = SetEOF(refNum, endPos);
+			if (err == noErr) {
+				err = SetFPos(refNum, fsFromStart, endPos);
+			}
+		}
+	}
+
+	if (err == noErr) {
+		return endPos;
+	} else {
+		_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	    _MD_SetError(err);
+		return -1;
+	}
+}
+
+PRInt32 _MD_FSync(PRFileDesc *fd)
+{
+	PRInt32 refNum = fd->secret->md.osfd;
+	OSErr 	err;
+ 	ParamBlockRec 		pb;
+
+	pb.ioParam.ioCompletion		= NULL;
+	pb.ioParam.ioRefNum 		= refNum;
+
+	err = PBFlushFileSync(&pb);
+	if (err != noErr)
+		goto ErrorExit;
+		
+	return 0;
+
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return -1;	
+}
+
+#include "plstr.h"
+
+PRStatus _MD_OpenDir(_MDDir *mdDir,const char *name)
+{
+	// Emulate the Unix opendir() routine.
+
+	OSErr 				err;
+ 	CInfoPBRec 			pb;
+	char				*macDirName = NULL;
+	char				*position = NULL;
+	char				volumeName[32];
+	Str255				pascalName;
+
+	// Get the Macintosh path
+	err = ConvertUnixPathToMacPath(name, &macDirName);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	// Get the vRefNum
+	position = PL_strchr(macDirName, PR_PATH_SEPARATOR);
+	if ((position == macDirName) || (position == NULL))
+		mdDir->ioVRefNum = 0;										// Use application relative searching
+	else {
+		memset(volumeName, 0, sizeof(volumeName));
+		strncpy(volumeName, macDirName, position-macDirName);
+		mdDir->ioVRefNum = GetVolumeRefNumFromName(volumeName);
+	}
+
+	// Get info about the object.
+	PStrFromCStr(macDirName, pascalName);
+	PR_DELETE(macDirName);
+	
+	pb.dirInfo.ioNamePtr = pascalName;
+	pb.dirInfo.ioVRefNum = mdDir->ioVRefNum;
+	pb.dirInfo.ioDrDirID = 0;
+	pb.dirInfo.ioFDirIndex = 0;
+	err = PBGetCatInfoSync(&pb);
+	if (err != noErr)
+		goto ErrorExit;
+		
+	// Are we dealing with a directory?
+	if ((pb.dirInfo.ioFlAttrib & ioDirMask) == 0) {
+		err = dirNFErr;
+		goto ErrorExit;
+	}
+	
+	/* This is a directory, store away the pertinent information.
+	** We post increment.  I.e. index is always the nth. item we 
+	** should get on the next call
+	*/
+	mdDir->ioDirID = pb.dirInfo.ioDrDirID;
+	mdDir->currentEntryName = NULL;
+	mdDir->ioFDirIndex = 1;
+	return PR_SUCCESS;
+	
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return PR_FAILURE;
+}
+
+char *_MD_ReadDir(_MDDir *mdDir, PRIntn flags)
+{
+	// Emulate the Unix readdir() routine.
+
+	// Mac doesnÕt have the concept of .(PR_SKIP_DOT) & ..(PR_SKIP_DOT_DOT)
+
+	OSErr 				err;
+	CInfoPBRec			pb;
+	char				*returnedCStr;
+	Str255				pascalName = "\p";
+	PRBool				foundEntry;
+	
+	PR_ASSERT(mdDir != NULL);
+
+	do {
+
+	// Release the last name read.
+	PR_DELETE(mdDir->currentEntryName);
+	mdDir->currentEntryName = NULL;
+		
+	// WeÕve got all the info we need, just get info about this guy.
+	pb.hFileInfo.ioNamePtr = pascalName;
+	pb.hFileInfo.ioVRefNum = mdDir->ioVRefNum;
+	pb.hFileInfo.ioFDirIndex = mdDir->ioFDirIndex;
+	pb.hFileInfo.ioDirID = mdDir->ioDirID;
+	err = PBGetCatInfoSync(&pb);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	// Convert the Pascal string to a C string (actual allocation occurs in CStrFromPStr)
+	CStrFromPStr(pascalName, &returnedCStr);
+	
+	mdDir->currentEntryName = returnedCStr;
+	mdDir->ioFDirIndex++;
+	
+	// If it is not a hidden file and the flags did not specify skipping, we are done.
+	if ((flags & PR_SKIP_HIDDEN) && (pb.hFileInfo.ioFlFndrInfo.fdFlags & fInvisible))
+		foundEntry = PR_FALSE;
+	else
+		foundEntry = PR_TRUE;	
+	
+	} while (!foundEntry);
+	
+	return (mdDir->currentEntryName);
+
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return NULL;
+}
+
+
+void _MD_CloseDir(_MDDir *mdDir)
+{
+	// Emulate the Unix closedir() routine
+
+	PR_DELETE(mdDir->currentEntryName);
+}
+
+PRInt32 _MD_MkDir(char *unixPath, PRIntn mode)
+{
+	HFileParam		fpb;
+	Str255			pascalName = "\p";
+	char			*cMacPath = NULL;
+	OSErr			err;
+
+	#pragma unused (mode)	// Mode is ignored on the Mac
+
+	if (unixPath) {
+    	err = ConvertUnixPathToMacPath(unixPath, &cMacPath);
+		if (err != noErr)
+			goto ErrorExit;
+
+    	PStrFromCStr(cMacPath, pascalName);
+		PR_DELETE(cMacPath);
+		fpb.ioNamePtr = pascalName;
+		fpb.ioVRefNum = 0;
+		fpb.ioDirID = 0L;
+
+		err = PBDirCreateSync((HParmBlkPtr)&fpb);
+		if (err != noErr)
+			goto ErrorExit;
+	}
+
+	return 0;
+	
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return -1;
+}
+
+PRInt32 _MD_Delete(char *unixPath)
+{
+	HFileParam		fpb;
+	Str255			pascalName = "\p";
+	char			*cMacPath = NULL;
+	OSErr			err;
+
+	if (unixPath) {
+    	err = ConvertUnixPathToMacPath(unixPath, &cMacPath);
+		if (err != noErr)
+			goto ErrorExit;
+
+    	PStrFromCStr(cMacPath, pascalName);
+		PR_DELETE(cMacPath);
+		fpb.ioNamePtr = pascalName;
+		fpb.ioVRefNum = 0;
+		fpb.ioDirID = 0L;
+
+		err = PBHDeleteSync((HParmBlkPtr)&fpb);
+		if (err != noErr)
+			goto ErrorExit;
+	}
+
+	return 0;
+	
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return -1;
+}
+
+PRInt32 _MD_Rename(char *fromUnixPath, char *toUnixPath)
+{
+	OSErr			err;
+	FSSpec			fromSpec;
+	FSSpec			toSpec;
+	FSSpec			destDirSpec;
+	FSSpec			beforeRenameSpec;
+
+	if (fromUnixPath && toUnixPath) {
+    	err = ConvertUnixPathToFSSpec(fromUnixPath, &fromSpec);
+		if (err != noErr)
+			goto ErrorExit;
+
+    	err = ConvertUnixPathToFSSpec(toUnixPath, &toSpec);
+		if (err != noErr && err != fnfErr)
+			goto ErrorExit;
+
+    	/* make an FSSpec for the destination directory */
+		err = FSMakeFSSpec(toSpec.vRefNum, toSpec.parID, nil, &destDirSpec);
+		if (err != noErr) /* parent directory must exist */
+			goto ErrorExit;
+
+		// move it to the directory specified
+    	err = FSpCatMove(&fromSpec, &destDirSpec);
+		if (err != noErr)
+			goto ErrorExit;
+	    
+	    // make a new FSSpec for the file or directory in its new location	
+		err = FSMakeFSSpec(toSpec.vRefNum, toSpec.parID, fromSpec.name, &beforeRenameSpec);
+		if (err != noErr)
+			goto ErrorExit;
+    	
+    	// rename the file or directory
+    	err = FSpRename(&beforeRenameSpec, toSpec.name);
+		if (err != noErr)
+			goto ErrorExit;
+
+	} else {
+		err = paramErr;
+		goto ErrorExit;
+	}
+
+	return 0;
+	
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return -1;
+}
+
+#define kWriteAccessAllowed (0x100)
+PRInt32 _MD_Access(char *unixPath, int amode)
+{
+	//
+	// Emulate the Unix access routine
+	//
+	
+	OSErr			err;
+	CInfoPBRec		pb;
+	FCBPBRec		fcbpb;
+	char			*cMacPath = NULL;
+	Str255			pascalMacPath;
+	struct stat		info;
+	
+	// Convert to a Mac style path
+	err = ConvertUnixPathToMacPath(unixPath, &cMacPath);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	err = stat(cMacPath, &info);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	
+	// If all weÕre doing is checking for the existence of the file, weÕre out of here.
+	// On the Mac, if a file exists, you can read from it.
+	// This doesnÕt handle remote AppleShare volumes.  Does it need to?
+	if ((amode == PR_ACCESS_EXISTS) || (amode == PR_ACCESS_READ_OK)) {
+		goto success;
+	}
+	
+	PStrFromCStr(cMacPath, pascalMacPath);
+	
+	pb.hFileInfo.ioNamePtr = pascalMacPath;
+	pb.hFileInfo.ioVRefNum = info.st_dev;
+	pb.hFileInfo.ioDirID = 0;
+	pb.hFileInfo.ioFDirIndex = 0;
+	
+	err = PBGetCatInfoSync(&pb);
+	if (err != noErr)
+		goto ErrorExit;
+	// Check out all the access permissions.
+	
+	if (amode == PR_ACCESS_WRITE_OK) {
+		fcbpb.ioNamePtr = NULL;
+		fcbpb.ioVRefNum = pb.hFileInfo.ioVRefNum;
+		fcbpb.ioRefNum = pb.hFileInfo.ioFRefNum;
+		fcbpb.ioFCBIndx = 0;
+	
+		err = PBGetFCBInfoSync(&fcbpb);
+		if (err != noErr)
+			goto ErrorExit;
+	
+		/* Look at Inside Mac IV-180 */
+		if ((fcbpb.ioFCBFlags & kWriteAccessAllowed) == 0) {
+			err = permErr;
+			goto ErrorExit;
+		}
+	}
+	
+success:
+	PR_DELETE(cMacPath);
+	return 0;
+	
+ErrorExit:
+	if (cMacPath != NULL)
+		PR_DELETE(cMacPath);
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return -1;
+}
+
+PRInt32 _MD_GetFileInfo(char *unixPath, PRFileInfo *info)
+{
+	CInfoPBRec		pb;
+	OSErr			err;
+	char			*cMacPath = NULL;
+	Str255			pascalMacPath;
+	PRTime			oneMillion, dateInMicroSeconds;
+	
+	// Convert to a Mac style path
+	err = ConvertUnixPathToMacPath(unixPath, &cMacPath);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	PStrFromCStr(cMacPath, pascalMacPath);
+	PR_DELETE(cMacPath);
+	
+	pb.hFileInfo.ioNamePtr = pascalMacPath;
+	pb.hFileInfo.ioVRefNum = 0;
+	pb.hFileInfo.ioDirID = 0;
+	pb.hFileInfo.ioFDirIndex = 0;
+	
+	err = PBGetCatInfoSync(&pb);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	if (pb.hFileInfo.ioFlAttrib & ioDirMask) {
+		info->type = PR_FILE_DIRECTORY;
+		info->size = 0;
+	} else {
+		info->type = PR_FILE_FILE;
+		info->size = pb.hFileInfo.ioFlLgLen + pb.hFileInfo.ioFlRLgLen;
+	}
+
+	pb.hFileInfo.ioFlCrDat -= gJanuaryFirst1970Seconds;
+	LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlCrDat);
+	LL_I2L(oneMillion, PR_USEC_PER_SEC);
+	LL_MUL(info->creationTime, oneMillion, dateInMicroSeconds);
+
+	pb.hFileInfo.ioFlMdDat -= gJanuaryFirst1970Seconds;
+	LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlMdDat);
+	LL_MUL(info->modifyTime, oneMillion, dateInMicroSeconds);
+
+	return 0;
+	
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return -1;
+}
+
+PRInt32 _MD_GetOpenFileInfo(const PRFileDesc *fd, PRFileInfo *info)
+{
+	OSErr			err;
+	FCBPBRec		fcbpb;
+	CInfoPBRec		pb;
+	Str255			pascalMacPath;
+	PRTime			oneMillion, dateInMicroSeconds;
+	
+	fcbpb.ioNamePtr = pascalMacPath;
+	fcbpb.ioVRefNum = 0;
+	fcbpb.ioRefNum = fd->secret->md.osfd;
+	fcbpb.ioFCBIndx = 0;
+	
+	err = PBGetFCBInfoSync(&fcbpb);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	info->type = PR_FILE_FILE;
+	info->size = fcbpb.ioFCBEOF;
+
+	pb.hFileInfo.ioNamePtr = pascalMacPath;
+	pb.hFileInfo.ioVRefNum = fcbpb.ioFCBVRefNum;
+	pb.hFileInfo.ioDirID = fcbpb.ioFCBParID;
+	pb.hFileInfo.ioFDirIndex = 0;
+	
+	err = PBGetCatInfoSync(&pb);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	pb.hFileInfo.ioFlCrDat -= gJanuaryFirst1970Seconds;
+	LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlCrDat);
+	LL_I2L(oneMillion, PR_USEC_PER_SEC);
+	LL_MUL(info->creationTime, oneMillion, dateInMicroSeconds);
+
+	pb.hFileInfo.ioFlMdDat -= gJanuaryFirst1970Seconds;
+	LL_I2L(dateInMicroSeconds, pb.hFileInfo.ioFlMdDat);
+	LL_MUL(info->modifyTime, oneMillion, dateInMicroSeconds);
+
+	return 0;
+	
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return -1;
+}
+
+PRInt32 _MD_Stat(const char *path, struct stat *buf)
+{
+	OSErr	err;
+	char	*macFileName = NULL;
+	
+    err = ConvertUnixPathToMacPath(path, &macFileName);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	err = stat(macFileName, buf);
+	if (err != noErr)
+		goto ErrorExit;
+		
+	PR_DELETE(macFileName);
+	
+	return 0;
+
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return -1;
+}
+
+PRStatus _MD_LockFile(PRInt32 fd)
+{
+	OSErr			err;
+	FCBPBRec		fcbpb;
+	HFileParam		fpb;
+	Str255			pascalName;
+	
+	fcbpb.ioNamePtr = pascalName;
+	fcbpb.ioVRefNum = 0;
+	fcbpb.ioRefNum = fd;
+	fcbpb.ioFCBIndx = 0;
+	
+	err = PBGetFCBInfoSync(&fcbpb);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	fpb.ioCompletion = NULL;
+	fpb.ioNamePtr = pascalName;
+	fpb.ioVRefNum = fcbpb.ioFCBVRefNum;
+	fpb.ioDirID = fcbpb.ioFCBParID;
+
+	err = PBHSetFLockSync((HParmBlkPtr)&fpb);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	return PR_SUCCESS;
+	
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return PR_FAILURE;
+}
+
+PRStatus _MD_TLockFile(PRInt32 fd)
+{
+	return (_MD_LockFile(fd));
+}
+
+PRStatus _MD_UnlockFile(PRInt32 fd)
+{
+	OSErr			err;
+	FCBPBRec		fcbpb;
+	HFileParam		fpb;
+	Str255			pascalName;
+	
+	fcbpb.ioNamePtr = pascalName;
+	fcbpb.ioVRefNum = 0;
+	fcbpb.ioRefNum = fd;
+	fcbpb.ioFCBIndx = 0;
+	
+	err = PBGetFCBInfoSync(&fcbpb);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	fpb.ioCompletion = NULL;
+	fpb.ioNamePtr = pascalName;
+	fpb.ioVRefNum = fcbpb.ioFCBVRefNum;
+	fpb.ioDirID = fcbpb.ioFCBParID;
+
+	err = PBHRstFLockSync((HParmBlkPtr)&fpb);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	return PR_SUCCESS;
+	
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return PR_FAILURE;
+}
+
+void SetLogFileTypeCreator(const char *logFile)
+{
+	HParamBlockRec pb;
+	OSErr err;
+	Str31 pName;
+
+	PStrFromCStr(logFile, pName);
+	pb.fileParam.ioCompletion = nil;
+	pb.fileParam.ioNamePtr = pName;
+	pb.fileParam.ioVRefNum = 0;
+	pb.fileParam.ioFDirIndex = 0;
+	pb.fileParam.ioDirID = 0;
+	err = PBHGetFInfoSync(&pb);
+	PR_ASSERT(err == noErr);
+
+	pb.fileParam.ioDirID = 0;
+	pb.fileParam.ioFlFndrInfo.fdType = 'TEXT';
+	pb.fileParam.ioFlFndrInfo.fdCreator = 'ttxt';
+	err = PBHSetFInfoSync(&pb);
+	PR_ASSERT(err == noErr);
+}
+
+#if DEVELOPER_DEBUG
+PR_IMPLEMENT (void)
+SetupMacPrintfLog(char *logFile)
+{
+	/*
+	 * We do _PR_InitLog() twice.  The first to force the implicit initialization which
+	 * will set logging to highest levels in _MD_EARLY_INIT.  Then, change the env variable
+	 * to disable kernel logging and call _PR_InitLog() again to make it effective.  Since
+	 * we are using logging to log test program output, we disable kernel logging to avoid
+	 * all Kernel logging output.
+	 */
+#ifdef PR_INTERNAL_LOGGING
+	_PR_InitLog();
+	_MD_PutEnv("NSPR_LOG_MODULES=clock:0,cmon:0,io:0,mon:0,linker:0,cvar:0,sched:0,thread:0");
+	_PR_InitLog();
+#endif
+	PR_ASSERT(PR_SetLogFile(logFile) == PR_TRUE);
+	
+	SetLogFileTypeCreator(logFile);
+}
+#endif
+
+
+/*
+********************** Old name related stuff that is unchanged. **********************
+*/
+
+#if !defined(MAC_NSPR_STANDALONE)
+
+short GetVolumeRefNumFromName(const char *cTgtVolName)
+{
+	OSErr				err;
+	Str32				pVolName;
+	char				*cVolName = NULL;
+	HParamBlockRec		hPB;
+	short				refNum = 0;
+	
+	hPB.volumeParam.ioVolIndex = 0;
+	hPB.volumeParam.ioNamePtr = pVolName;
+	do {
+		hPB.volumeParam.ioVolIndex++;
+		err = PBHGetVInfoSync(&hPB);
+		CStrFromPStr(pVolName, &cVolName);
+		if (strcmp(cTgtVolName, cVolName) == 0) {
+			refNum =  hPB.volumeParam.ioVRefNum;
+			PR_DELETE(cVolName);
+			break;
+		}
+		PR_DELETE(cVolName);
+	} while (err == noErr);
+	
+	return refNum;
+}
+
+static OSErr CreateMacPathFromUnixPath(const char *unixPath, char **macPath)
+{
+	// Given a Unix style path with '/' directory separators, this allocates 
+	// a path with Mac style directory separators in the path.
+	//
+	// It does not do any special directory translation; use ConvertUnixPathToMacPath
+	// for that.
+	
+	const char	*src;
+	char		*tgt;
+	OSErr		err = noErr;
+
+	PR_ASSERT(unixPath != nil);
+	if (nil == unixPath) {
+		err = paramErr;
+		goto exit;
+	}
+
+	// If unixPath is a zero-length string, we copy ":" into
+	// macPath, so we need a minimum of two bytes to handle
+	// the case of ":". 
+	*macPath = malloc(strlen(unixPath) + 2);	// Will be enough extra space.
+	require_action (*macPath != NULL, exit, err = memFullErr;);
+
+	src = unixPath;
+	tgt = *macPath;
+	
+	if (PL_strchr(src, PR_DIRECTORY_SEPARATOR) == src)				// If weÕre dealing with an absolute
+		src++;													// path, skip the separator
+	else
+		*(tgt++) = PR_PATH_SEPARATOR;	
+		
+	if (PL_strstr(src, UNIX_THIS_DIRECTORY_STR) == src)			// If it starts with /
+		src += 2;												// skip it.
+		
+	while (*src) 
+	{				// deal with the rest of the path
+		if (PL_strstr(src, UNIX_PARENT_DIRECTORY_STR) == src) {	// Going up?
+			*(tgt++) = PR_PATH_SEPARATOR;						// simply add an extra colon.
+			src +=3;
+		}
+		else if (*src == PR_DIRECTORY_SEPARATOR) {					// Change the separator
+			*(tgt++) = PR_PATH_SEPARATOR;
+			src++;
+		}
+		else
+			*(tgt++) = *(src++);
+	}
+	
+	*tgt = NULL;							// make sure itÕs null terminated.
+
+exit:
+	return err;
+}
+
+
+static ProcessInfoRec gNavigatorProcInfo;
+static FSSpec gGutsFolder;
+static FSSpec gNetscapeFolder;
+
+static OSErr SetupRequiredFSSpecs(void)
+{
+	OSErr err;
+	CInfoPBRec pb;
+	ProcessSerialNumber curPSN = {0, kCurrentProcess};	
+	
+	gNavigatorProcInfo.processInfoLength = sizeof(ProcessInfoRec);
+	gNavigatorProcInfo.processName = NULL;
+	gNavigatorProcInfo.processAppSpec = &gNetscapeFolder;
+
+	err = GetProcessInformation (&curPSN, &gNavigatorProcInfo);
+	if (err != noErr)
+		goto ErrorExit;
+
+	/* guts folder resides at the same place as the app file itself */
+	gGutsFolder = gNetscapeFolder;
+	/* How else do we do this hack??? 
+	 * Should NSPR have a string resource for this ?
+	 */
+	GetIndString( gGutsFolder.name, 300, 34);
+
+	/* 
+	 * vRefNum and parentDirID are now set up correctly for the app file itself. 
+	 * parentDirID is the Netscape Folder's ID.  Then Find it's parent ID to
+	 * set up the FSSpec and its own name.
+	 */
+
+	pb.dirInfo.ioCompletion = NULL;
+	pb.dirInfo.ioNamePtr = gNetscapeFolder.name;
+	pb.dirInfo.ioVRefNum = gNetscapeFolder.vRefNum;
+	pb.dirInfo.ioFDirIndex = -1;
+	pb.dirInfo.ioDrDirID = gNetscapeFolder.parID;
+	
+	err = PBGetCatInfoSync(&pb);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	gNetscapeFolder.parID = pb.dirInfo.ioDrParID;
+	
+	return noErr;	
+
+ErrorExit:
+	return err;
+}
+
+static OSErr FindGutsFolder(FSSpec *foundSpec)
+{
+	OSErr err;
+	
+	if (gNavigatorProcInfo.processInfoLength == 0) { /* Uninitialized? */
+		err = SetupRequiredFSSpecs();
+		if (err != noErr)
+			goto ErrorExit;
+	} 
+	
+	*foundSpec = gGutsFolder;
+	
+	return noErr;	
+
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+    return err;	
+}
+
+static OSErr FindNetscapeFolder(FSSpec *foundSpec)
+{
+	OSErr err;
+	
+	if (gNavigatorProcInfo.processInfoLength == 0) { /* Uninitialized? */
+		err = SetupRequiredFSSpecs();
+		if (err != noErr)
+			goto ErrorExit;
+	} 
+	
+	*foundSpec = gNetscapeFolder;
+	
+	return noErr;	
+
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+    return err;	
+}
+
+
+PR_IMPLEMENT (OSErr)
+ConvertUnixPathToMacPath(const char *unixPath, char **macPath)
+{	
+		OSErr		err = noErr;
+		
+	//	******** HACK ALERT ********
+	//
+	//	Java really wants long file names (>31 chars).  We truncate file names 
+	//	greater than 31 characters long.  Truncation is from the middle.
+	//
+	//	Convert UNIX style path names (with . and / separators) into a Macintosh
+	//	style path (with :).
+	//
+	// There are also a couple of special paths that need to be dealt with
+	// by translating them to the appropriate Mac special folders.  These include:
+	//
+	//			/usr/tmp/file  =>  {TempFolder}file
+	//
+	// The file conversions we need to do are as follows:
+	//
+	//			file			=>		file
+	//			dir/file		=>		:dir:file
+	//			./file			=>		file
+	//			../file			=>		::file
+	//			../dir/file		=>		::dir:file
+	//			/file			=>		::BootDrive:file
+	//			/dir/file		=>		::BootDrive:dir:file
+	
+	
+	if (!strcmp(unixPath, "."))
+	{
+		*macPath = malloc(sizeof(":"));
+		if (*macPath == NULL)
+			err = memFullErr;
+		(*macPath)[0] = ':';
+		(*macPath)[1] = '\0';
+	}
+	else
+	
+	if (*unixPath != PR_DIRECTORY_SEPARATOR) {				// Not root relative, just convert it.
+		err = CreateMacPathFromUnixPath(unixPath, macPath);
+	}
+	
+	else {
+		// WeÕre root-relative.  This is either a special Unix directory, or a 
+		// full path (which weÕll support on the Mac since they might be generated).
+		// This is not condoning the use of full-paths on the Macintosh for file 
+		// specification.
+		
+		FSSpec		foundSpec;
+		short		pathBufferSize;
+#if DEBUG	
+		char		*temp;
+#endif
+		int		tempLen;
+
+		// Are we dealing with the temp folder?
+		if ((strncmp(unixPath, "/usr/tmp", strlen("/usr/tmp")) == 0) || 
+			((strncmp(unixPath, "/tmp", strlen("/tmp")) == 0))) {
+		    CInfoPBRec pb;
+
+			unixPath = PL_strchr(unixPath, PR_DIRECTORY_SEPARATOR);
+			if (strncmp(unixPath, "/tmp", strlen("/tmp")) == 0) // skip past temp spec
+				unixPath += 5;	
+			else
+				unixPath += 9;	
+							
+			err = FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder,	// Create if needed
+								&foundSpec.vRefNum, &foundSpec.parID);
+			if (err == noErr) {
+				pb.dirInfo.ioCompletion = NULL;
+				pb.dirInfo.ioNamePtr = foundSpec.name;
+				pb.dirInfo.ioVRefNum = foundSpec.vRefNum;
+				pb.dirInfo.ioFDirIndex = -1;
+				pb.dirInfo.ioDrDirID = foundSpec.parID;
+				
+				err = PBGetCatInfoSync(&pb);
+				foundSpec.parID = pb.dirInfo.ioDrParID;
+			}
+		}
+		
+		else if (!strncmp(unixPath, "/usr/local/netscape/", (tempLen = strlen("/usr/local/netscape/")))) {
+			
+			unixPath += tempLen;
+			
+			if (!strncmp(unixPath, "RequiredGuts/", (tempLen = strlen("RequiredGuts/"))))
+			{
+				unixPath += tempLen;
+				err = FindGutsFolder(&foundSpec);
+			}
+			else if (!strncmp(unixPath, "bin/", (tempLen = strlen("bin/"))))
+			{
+				unixPath += tempLen;
+				err = FindNetscapeFolder(&foundSpec);
+			}			
+			else if (*unixPath == '\0')
+			{
+				// it's /usr/local/netscape
+				err = FindGutsFolder(&foundSpec);
+			}
+
+		}
+		
+		else {
+			// This is a root relative directory, weÕll just convert the whole thing.
+			err = CreateMacPathFromUnixPath(unixPath, macPath);
+			goto Exit_ConvertUnixPathToMacPath;
+		}
+	
+
+		
+		// WeÕre dealing with a special folder
+		if (err == noErr)
+		{
+			Handle	hPathStr;
+			// Get the path to the root-relative directory
+			err = FSpGetFullPath(&foundSpec, &pathBufferSize, &hPathStr);		// NewHandle's hPathStr
+			 
+			if (noErr == err)
+			{
+				// convert handle to c-string
+				// add one for NULL termination
+				// pathBufferSize is now one greater than the length of the string
+				pathBufferSize++;	
+				
+				*macPath = (char*) malloc(sizeof(char) * pathBufferSize);
+				(*macPath)[pathBufferSize - 1] = '\0';
+				BlockMoveData(*hPathStr, *macPath, pathBufferSize - 1);
+			
+				DisposeHandle(hPathStr);
+			}
+		}
+		
+		if (err == noErr)
+		{
+			UInt32	unixPathLeft;
+			UInt32	macPathLen;
+
+			unixPathLeft =  strlen(unixPath);
+			macPathLen = strlen(*macPath);
+			
+
+			// copy over the remaining file name, converting
+			if (pathBufferSize - 1 < macPathLen + unixPathLeft) 
+			{
+				// need to grow string
+				*macPath = realloc(*macPath, macPathLen + unixPathLeft + 1);
+				err = (*macPath == NULL ? memFullErr : noErr);
+			}
+			
+			if (err == noErr)
+			{
+				// carefully remove the '/''s out of the unix path.  If we see an "escaped" /
+				// we will leave it in there, otherwise we take it out and replace it with a :
+				// we have to do this before we convert to a mac-path, so we can tell what is
+				// really a path separator and what is in the name of a file or directory
+				// Make sure that all of the /Õs are :Õs in the final pathname
+				// effectively we do a
+				// strcat(*macPath, unixPath); while replace all occurrences of / with : in unixPath
+				char*		dp;
+				const char*	sp;
+				
+				sp = unixPath;
+				dp = *macPath + macPathLen;
+				
+				for (;*sp != '\0'; sp++, dp++) 
+				{
+					if (*sp == PR_DIRECTORY_SEPARATOR)
+					{
+						// if we can look at the previous character
+						if (sp > unixPath)					
+						{
+							// check to see if previous character is an escape
+							if (sp[-1] == '\\')
+							{
+								// leave it in, and cycle
+								continue;
+							}
+							else
+							{
+								*dp = PR_PATH_SEPARATOR;
+							}
+						}
+						else				
+							*dp = PR_PATH_SEPARATOR;
+					}
+					else
+					{
+						// just copy;
+						*dp = *sp;
+					}
+				}
+				
+				*dp = '\0';   // NULL terminate *macPath
+			}
+#if DEBUG	
+			// we used to check here, now we check above, we leave this in
+			// the debug build to make sure we didn't screw up
+			// Make sure that all of the /Õs are :Õs in the final pathname
+			for (temp = *macPath + strlen(*macPath) - strlen(unixPath); *temp != '\0'; temp++) {
+
+				if (*temp == PR_DIRECTORY_SEPARATOR)
+				{
+					DebugStr("\pFound a slash");	
+					*temp = PR_PATH_SEPARATOR;
+				}
+			}
+#endif
+		}
+	}
+	
+	
+Exit_ConvertUnixPathToMacPath:
+
+	return err;
+}
+
+// Hey! Before you delete this "hack" you should look at how it's being
+// used by sun-java/netscape/applet/appletStubs.c.
+PR_IMPLEMENT (OSErr)
+ConvertMacPathToUnixPath(const char *macPath, char **unixPath) 
+{
+	// *** HACK ***
+	// Get minimal version working
+	
+	char		*unixPathPtr;
+	
+	*unixPath = malloc(strlen(macPath) + 2);	// Add one for the front slash, one for null
+	if (*unixPath == NULL)
+		return (memFullErr);
+		
+	unixPathPtr = *unixPath;
+	
+	*unixPathPtr++ = PR_DIRECTORY_SEPARATOR;
+	
+	do {
+		// Translate all colons to slashes
+		if (*macPath == PR_PATH_SEPARATOR)
+			*unixPathPtr = PR_DIRECTORY_SEPARATOR;
+		else
+			*unixPathPtr = *macPath;
+
+		unixPathPtr++;
+		macPath++;
+	} while (*macPath != NULL);
+	
+	// Terminate the string
+	*unixPathPtr = '\0';
+	
+	return (noErr);
+}
+
+OSErr
+ConvertUnixPathToFSSpec(const char *unixPath, FSSpec *fileSpec)
+{
+    char*                   macPath;
+    OSErr                   convertError;
+    int                             len;
+    
+    convertError = ConvertUnixPathToMacPath(unixPath, &macPath);
+    if (convertError != noErr)
+    	return convertError;
+
+    len = strlen(macPath);
+
+    if (*macPath == PR_PATH_SEPARATOR)
+    {
+        if (len < sizeof(Str255))
+        {
+            short   vRefNum;
+            long    dirID;
+            Str255  pascalMacPath;
+            
+            convertError = HGetVol(NULL, &vRefNum, &dirID);
+            if (convertError == noErr)
+            {
+                PStrFromCStr(macPath, pascalMacPath);
+                convertError = FSMakeFSSpec(vRefNum, dirID, pascalMacPath, fileSpec);
+            }
+        }
+        else
+            convertError = paramErr;
+    }
+    else
+    {
+    	convertError = FSpLocationFromFullPath(len, macPath, fileSpec);
+	    if (convertError == fnfErr)
+	    {
+			CInfoPBRec		pb;
+			Str255	pascalMacPath;
+			OSErr err;
+			
+			PStrFromCStr(macPath, pascalMacPath);
+			/* 
+			FSpLocationFromFullPath does not work for directories unless there is
+			a ":" at the end.  We will make sure of an existence of a directory.
+			If so, the returned fileSpec is valid from FSpLocationFromFullPath eventhough
+			it returned an error.
+			*/
+			pb.hFileInfo.ioNamePtr = pascalMacPath;
+			pb.hFileInfo.ioVRefNum = 0;
+			pb.hFileInfo.ioDirID = 0;
+			pb.hFileInfo.ioFDirIndex = 0;
+			
+			err = PBGetCatInfoSync(&pb);
+			if (err == noErr)
+				convertError = noErr;
+		}
+    }
+    
+    free(macPath);
+    
+    return (convertError);
+}
+ 
+
+FILE *_OS_FOPEN(const char *filename, const char *mode) 
+{
+	OSErr	err = noErr;
+	char	*macFileName = NULL;
+	FILE	*result;
+	
+    err = ConvertUnixPathToMacPath(filename, &macFileName);
+	if (err != noErr)
+		goto ErrorExit;
+	
+	result = fopen(macFileName, mode);
+		
+	PR_DELETE(macFileName);
+	
+	return result;
+
+ErrorExit:
+	_PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+	_MD_SetError(err);
+    return NULL;
+}
+
+#else
+
+short GetVolumeRefNumFromName(const char *cTgtVolName)
+{
+	OSErr				err;
+	Str32				pVolName;
+	char				*cVolName = NULL;
+	HParamBlockRec		hPB;
+	short				refNum = 0;
+	
+	hPB.volumeParam.ioVolIndex = 0;
+	hPB.volumeParam.ioNamePtr = pVolName;
+	do {
+		hPB.volumeParam.ioVolIndex++;
+		err = PBHGetVInfoSync(&hPB);
+		CStrFromPStr(pVolName, &cVolName);
+		if (strcmp(cTgtVolName, cVolName) == 0) {
+			refNum =  hPB.volumeParam.ioVRefNum;
+			PR_DELETE(cVolName);
+			break;
+		}
+		PR_DELETE(cVolName);
+	} while (err == noErr);
+	
+	return refNum;
+}
+
+
+
+static OSErr GetFullPath(short vRefNum, long dirID, char **fullPath, int *strSize)
+{
+	Str255			pascalDirName;
+	char			cDirName[256];
+	char			*tmpPath = NULL;						// needed since sprintf isnÕt safe
+	CInfoPBRec		myPB;
+	OSErr			err = noErr;
+	
+	
+	// get the full path of the temp folder.
+	*strSize = 256;
+	*fullPath = NULL;
+	*fullPath = malloc(*strSize);	// How big should this thing be?
+	require_action (*fullPath != NULL, errorExit, err = memFullErr;);
+		
+	tmpPath = malloc(*strSize);
+	require_action (tmpPath != NULL, errorExit, err = memFullErr;);
+
+	strcpy(*fullPath, "");				// Clear C result
+	strcpy(tmpPath, "");
+	pascalDirName[0] = 0;				// Clear Pascal intermediate string
+	
+	myPB.dirInfo.ioNamePtr = &pascalDirName[0];
+	myPB.dirInfo.ioVRefNum = vRefNum;
+	myPB.dirInfo.ioDrParID = dirID;
+	myPB.dirInfo.ioFDirIndex = -1;				// Getting info about
+	
+	do {
+		myPB.dirInfo.ioDrDirID = myPB.dirInfo.ioDrParID;
+
+		err = PBGetCatInfoSync(&myPB);
+		require(err == noErr, errorExit);
+			
+		// Move the name into C domain
+		memcpy(&cDirName, &pascalDirName, 256);
+		p2cstr((unsigned char *)&cDirName);							// Changes in place!
+		
+		if ((strlen(cDirName) + strlen(*fullPath)) > *strSize) {
+			// We need to grow the string, do it in 256 byte chunks
+			(*strSize) += 256;										
+			*fullPath = PR_REALLOC(*fullPath, *strSize);
+			require_action (*fullPath != NULL, errorExit, err = memFullErr;);
+
+			tmpPath = PR_REALLOC(tmpPath, *strSize);
+			require_action (tmpPath != NULL, errorExit, err = memFullErr;);
+		}
+		sprintf(tmpPath, "%s:%s", cDirName, *fullPath);
+		strcpy(*fullPath, tmpPath);
+	} while (myPB.dirInfo.ioDrDirID != fsRtDirID);
+	
+	PR_DELETE(tmpPath);
+	
+	return noErr;
+	
+	
+errorExit:
+	PR_DELETE(*fullPath);
+	PR_DELETE(tmpPath);
+	
+	return err;
+
+}
+
+static OSErr CreateMacPathFromUnixPath(const char *unixPath, char **macPath)
+{
+	// Given a Unix style path with '/' directory separators, this allocates 
+	// a path with Mac style directory separators in the path.
+	//
+	// It does not do any special directory translation; use ConvertUnixPathToMacPath
+	// for that.
+	
+	const char	*src;
+	char		*tgt;
+	OSErr		err = noErr;
+
+	PR_ASSERT(unixPath != nil);
+	if (nil == unixPath) {
+		err = paramErr;
+		goto exit;
+	}
+
+	// If unixPath is a zero-length string, we copy ":" into
+	// macPath, so we need a minimum of two bytes to handle
+	// the case of ":". 
+	*macPath = malloc(strlen(unixPath) + 2);	// Will be enough extra space.
+	require_action (*macPath != NULL, exit, err = memFullErr;);
+
+	src = unixPath;
+	tgt = *macPath;
+	
+	if (PL_strchr(src, PR_DIRECTORY_SEPARATOR) == src)				// If weÕre dealing with an absolute
+		src++;													// path, skip the separator
+	else
+		*(tgt++) = PR_PATH_SEPARATOR;	
+		
+	if (PL_strstr(src, UNIX_THIS_DIRECTORY_STR) == src)			// If it starts with ./
+		src += 2;												// skip it.
+		
+	while (*src) 
+	{				// deal with the rest of the path
+		if (PL_strstr(src, UNIX_PARENT_DIRECTORY_STR) == src) {	// Going up?
+			*(tgt++) = PR_PATH_SEPARATOR;						// simply add an extra colon.
+			src +=3;
+		}
+		else if (*src == PR_DIRECTORY_SEPARATOR) {					// Change the separator
+			*(tgt++) = PR_PATH_SEPARATOR;
+			src++;
+		}
+		else
+			*(tgt++) = *(src++);
+	}
+	
+	*tgt = NULL;							// make sure itÕs null terminated.
+
+exit:
+	return err;
+}
+
+static OSErr ConvertUnixPathToMacPath(const char *unixPath, char **macPath)
+{	
+		OSErr		err = noErr;
+		
+
+	//
+	//	Convert UNIX style path names (with . and / separators) into a Macintosh
+	//	style path (with :).
+	//
+	// There are also a couple of special paths that need to be dealt with
+	// by translating them to the appropriate Mac special folders.  These include:
+	//
+	//			/usr/tmp/file  =>  {TempFolder}file
+	//
+	// The file conversions we need to do are as follows:
+	//
+	//			file			=>		file
+	//			dir/file		=>		:dir:file
+	//			./file			=>		file
+	//			../file			=>		::file
+	//			../dir/file		=>		::dir:file
+	//			/file			=>		::BootDrive:file
+	//			/dir/file		=>		::BootDrive:dir:file
+	
+	
+	if (*unixPath != PR_DIRECTORY_SEPARATOR) {				// Not root relative, just convert it.
+		err = CreateMacPathFromUnixPath(unixPath, macPath);
+	}
+	
+	else {
+		// WeÕre root-relative.  This is either a special Unix directory, or a 
+		// full path (which weÕll support on the Mac since they might be generated).
+		// This is not condoning the use of full-paths on the Macintosh for file 
+		// specification.
+		
+		short		foundVRefNum;
+		long		foundDirID;
+		int			pathBufferSize;
+		char		*temp;
+		char		isNetscapeDir = false;
+
+		// Are we dealing with the temp folder?
+		if (strncmp(unixPath, "/usr/tmp", strlen("/usr/tmp")) == 0){
+			unixPath += 8;
+			if (*unixPath == PR_DIRECTORY_SEPARATOR)
+				unixPath++;														// Skip the slash
+			err = FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder,	// Create if needed
+								&foundVRefNum, &foundDirID);
+		}
+		
+		if (strncmp(unixPath, "/tmp", strlen("/tmp")) == 0) {
+			unixPath += 4;															// Skip the slash
+			if (*unixPath == PR_DIRECTORY_SEPARATOR)
+				unixPath++;														// Skip the slash
+			err = FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder,	// Create if needed
+								&foundVRefNum, &foundDirID);
+		}
+		
+		else if (strncmp(unixPath, "/usr", strlen("/usr")) == 0) {
+		
+			int		usrNetscapePathLen;
+			
+			usrNetscapePathLen = strlen("/usr/local/netscape/");
+		
+			if (strncmp(unixPath, "/usr/local/netscape/", usrNetscapePathLen) == 0) {
+				unixPath += usrNetscapePathLen;				
+//				err = FindPreferencesFolder(&foundVRefNum, &foundDirID);
+				err = paramErr;
+				isNetscapeDir = true;
+			}
+			
+			else {
+				dprintf("Unable to translate Unix file path %s to Mac path\n", unixPath);
+				err = -1;
+				goto Exit_ConvertUnixPathToMacPath;
+			}
+
+		}
+		
+		else {
+			// This is a root relative directory, weÕll just convert the whole thing.
+			err = CreateMacPathFromUnixPath(unixPath, macPath);
+			goto Exit_ConvertUnixPathToMacPath;
+		}
+	
+		// WeÕre dealing with a special folder
+		if (err == noErr)
+			// Get the path to the root-relative directory
+			err = GetFullPath(foundVRefNum, foundDirID, macPath, &pathBufferSize);		// mallocs macPath
+		
+		if (err == noErr){
+			
+			// copy over the remaining file name, converting
+			if (pathBufferSize < (strlen(*macPath) + strlen(unixPath))) {
+				// need to grow string
+				*macPath = PR_REALLOC(*macPath, (strlen(*macPath) + strlen(unixPath) + 
+					(isNetscapeDir ? strlen("Netscape Ä:") : 0)));
+				err = (*macPath == NULL ? memFullErr : noErr);
+			}
+			
+			if (isNetscapeDir)
+				strcat(*macPath, "Netscape Ä:");
+		
+			if (err == noErr)
+				strcat(*macPath, unixPath);
+			
+			//	Make sure that all of the /Õs are :Õs in the final pathname
+				
+			for (temp = *macPath + strlen(*macPath) - strlen(unixPath); *temp != '\0'; temp++) {
+				if (*temp == PR_DIRECTORY_SEPARATOR)
+					*temp = PR_PATH_SEPARATOR;
+			}
+
+		}
+	}
+	
+	
+Exit_ConvertUnixPathToMacPath:
+
+	return err;
+}
+
+OSErr
+ConvertUnixPathToFSSpec(const char *unixPath, FSSpec *fileSpec)
+{
+    char*                   macPath;
+    OSErr                   convertError;
+    int                             len;
+    
+    convertError = ConvertUnixPathToMacPath(unixPath, &macPath);
+    if (convertError != noErr)
+    	return convertError;
+
+    len = strlen(macPath);
+
+    if (*macPath == PR_PATH_SEPARATOR)
+    {
+        if (len < sizeof(Str255))
+        {
+            short   vRefNum;
+            long    dirID;
+            Str255  pascalMacPath;
+            
+            convertError = HGetVol(NULL, &vRefNum, &dirID);
+            if (convertError == noErr)
+            {
+                PStrFromCStr(macPath, pascalMacPath);
+                convertError = FSMakeFSSpec(vRefNum, dirID, pascalMacPath, fileSpec);
+            }
+        }
+        else
+            convertError = paramErr;
+    }
+    else
+    {
+    	convertError = FSpLocationFromFullPath(len, macPath, fileSpec);
+    }
+    
+    free(macPath);
+    
+    return (convertError);
+}
+ 
+
+#endif
+
+/*
+ **********************************************************************
+ *
+ * Memory-mapped files are not implementable on the Mac.
+ *
+ **********************************************************************
+ */
+
+PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size)
+{
+#pragma unused (fmap, size)
+
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRInt32 _MD_GetMemMapAlignment(void)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return -1;
+}
+
+void * _MD_MemMap(
+    PRFileMap *fmap,
+    PROffset64 offset,
+    PRUint32 len)
+{
+#pragma unused (fmap, offset, len)
+
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PRStatus _MD_MemUnmap(void *addr, PRUint32 len)
+{
+#pragma unused (addr, len)
+
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRStatus _MD_CloseFileMap(PRFileMap *fmap)
+{
+#pragma unused (fmap)
+
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macio.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macio.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,51 @@
+/* -*- 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 macio_h__
+#define macio_h__
+
+
+PR_BEGIN_EXTERN_C
+
+OSErr ConvertUnixPathToMacPath(const char *, char **);
+OSErr ConvertUnixPathToFSSpec(const char *unixPath, FSSpec *fileSpec);
+
+PR_END_EXTERN_C
+
+
+#endif /* macio_h__ */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macrng.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macrng.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,52 @@
+/* -*- 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 ***** */
+
+
+/* XXX are all these headers required for a call to TickCount()? */
+#include <Events.h>
+#include <OSUtils.h>
+#include <QDOffscreen.h>
+#include <PPCToolbox.h>
+#include <Processes.h>
+#include <LowMem.h>
+#include "primpl.h"
+
+extern PRSize _PR_MD_GetRandomNoise( buf, size )
+{
+    uint32 c = TickCount();
+    return _pr_CopyLowBits((void *)buf, size,  &c, sizeof(c));
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macsocket.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macsocket.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,238 @@
+/* -*- 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 macksocket_h___
+#define macksocket_h___
+
+// macsock.h
+// Interface visible to xp code
+// C socket type definitions and routines
+// from sys/socket.h
+#include <Files.h>
+#include <OpenTptInternet.h>	// All the internet typedefs
+#include <utime.h>				// For timeval
+/*
+ * sleep and delay conflict with the same in unistd.h from Metrowerks.  OT
+ * defines them as 
+ *
+ *    extern pascal void		OTDelay(UInt32 seconds);
+ *    extern pascal void		OTIdle(void);
+ *
+ *    #define sleep(x)	OTDelay(x)
+ *    #define delay(x)	OTDelay(x)
+ */
+
+#undef sleep
+#undef delay
+
+#pragma once
+
+#include "prio.h"
+
+struct sockaddr {
+	unsigned char	sa_len;			/* total length */
+	unsigned char	sa_family;		/* address family */
+	char	sa_data[14];		/* actually longer; address value */
+};
+
+// from netinet/in.h
+struct in_addr {
+	unsigned long s_addr;
+};
+
+struct sockaddr_in {
+	unsigned char	sin_len;
+	unsigned char	sin_family;		// AF_INET
+	unsigned short	sin_port;
+	struct	in_addr sin_addr;
+	char		sin_zero[8];
+};
+
+struct	hostent {
+	char	*h_name;	/* official name of host */
+	char	**h_aliases;	/* alias list */
+	int	h_addrtype;	/* host address type */
+	int	h_length;	/* length of address */
+	char	**h_addr_list;	/* list of addresses from name server */
+#define	h_addr	h_addr_list[0]	/* address, for backward compatiblity */
+};
+
+// Necessary network defines, found by grepping unix headers when XP code would not compile
+#define FIONBIO 1
+#define SOCK_STREAM 1
+#define SOCK_DGRAM 		2
+#define IPPROTO_TCP 	INET_TCP		// Default TCP protocol
+#define IPPROTO_UDP		INET_UDP		// Default UDP protocol
+#define INADDR_ANY		kOTAnyInetAddress
+#define SOL_SOCKET		XTI_GENERIC		// Any type of socket
+#define SO_REUSEADDR	IP_REUSEADDR
+#define SO_BROADCAST	IP_BROADCAST
+#define MSG_PEEK		0x2				// Just look at a message waiting, donÕt actually read it.
+
+typedef unsigned long u_long;
+
+/* ldap.h has its own definition of fd_set */
+/* select support */
+#if !defined(FD_SET)
+#define	NBBY    8
+typedef long    fd_mask;
+#define NFDBITS (sizeof(fd_mask) * NBBY)	/* bits per mask */
+
+#ifndef howmany
+#define howmany(x, y)   (((x)+((y)-1))/(y))
+#endif
+#define FD_SETSIZE 64
+typedef	struct fd_set{
+    fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
+} fd_set;
+
+#define	FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define	FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define	FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define	FD_ZERO(p)      memset (p, 0, sizeof(*(p)))
+#endif /* !FD_SET */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern unsigned long inet_addr(const char *cp);
+extern char *inet_ntoa(struct in_addr in);
+
+inline unsigned long htonl(unsigned long hostlong) {return hostlong;}
+inline unsigned long ntohl(unsigned long netlong) {return netlong;}
+inline unsigned short ntohs(unsigned short netshort) {return netshort;}
+inline unsigned short htons(unsigned short hostshort) {return hostshort;}
+
+
+// UNIX look-alike routines
+// They make sure that the arguments passed in are valid, and then
+//
+extern struct hostent *macsock_gethostbyaddr(const void *addr, int addrlen, int type);
+
+extern int macsock_socket(int domain, int type, int protocol);
+extern int macsock_ioctl(int sID, unsigned int request, void *value);
+extern int macsock_connect(int sID, struct sockaddr *name, int namelen);
+extern int macsock_write(int sID, const void *buffer, unsigned buflen);
+extern int macsock_read(int sID, void *buf, unsigned nbyte);
+extern int macsock_close(int sID);
+
+extern int macsock_accept(int sID, struct sockaddr *addr, int *addrlen);
+extern int macsock_bind(int sID, const struct sockaddr *name, int namelen);
+extern int macsock_listen(int sID, int backlog);
+
+extern int macsock_shutdown(int sID, int how);
+extern int macsock_getpeername(int sID, struct sockaddr *name, int *namelen);
+extern int macsock_getsockname(int sID, struct sockaddr *name, int *namelen);
+extern int macsock_getsockopt(int sID, int level, int optname, void *optval,int *optlen);
+extern int macsock_setsockopt(int sID, int level, int optname, const void *optval,int optlen);
+extern int macsock_socketavailable(int sID, size_t *bytesAvailable);
+extern int macsock_dup(int sID);
+
+extern int macsock_send(int sID, const void *msg, int len, int flags);
+extern int macsock_sendto(int sID, const void *msg, int len, int flags, struct sockaddr *toAddr, int toLen);
+extern int macsock_recvfrom(int sID, void *buf, int len, int flags, struct sockaddr *from, int *fromLen);
+extern int macsock_recv(int sID, void *buf, int len, int flags);
+
+extern int select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
+
+
+#define macsock_gethostbyaddr PR_GetHostByAddr
+#define macsock_socket PR_Socket
+#define macsock_connect PR_Connect
+#define macsock_write PR_Write
+#define macsock_read PR_Read
+#define macsock_close PR_Close
+#define macsock_accept PR_Accept
+#define macsock_bind PR_Bind
+#define macsock_listen PR_Listen
+#define macsock_shutdown PR_Shutdown
+#define macsock_getpeername PR_GetPeerName
+#define macsock_getsockname PR_GetSockName
+#define macsock_socketavailable PR_SocketAvailable
+#define macsock_send PR_Send
+#define macsock_sendto PR_SendTo
+#define macsock_recvfrom PR_RecvFrom
+#define macsock_recv PR_Recv
+
+#ifdef __cplusplus
+}
+#endif
+//extern int errno;
+
+/*
+macsock_sendmsg
+macsock_readv
+macsock_writev
+*/
+
+/* New definitions that are not defined in macsock.h in macsock library */
+struct	protoent {
+    char	*p_name;		/* official protocol name */
+    char	**p_aliases;	/* alias list */
+    int		p_proto;		/* protocol # */
+};
+
+extern struct protoent *getprotobyname(const char * name);
+extern struct protoent *getprotobynumber(int number);
+
+extern int gethostname (char *name, int namelen);
+extern struct hostent *gethostbyname(const char * name);
+extern struct hostent *gethostbyaddr(const void *addr, int addrlen, int type);
+
+#define INADDR_LOOPBACK	0x7F000001
+
+#define SO_KEEPALIVE	TCP_KEEPALIVE
+#define SO_RCVBUF		XTI_RCVBUF
+#define SO_SNDBUF		XTI_SNDBUF
+#define SO_LINGER       XTI_LINGER          /* linger on close if data present */
+
+#define IPPROTO_IP		INET_IP
+
+/* Get/Set sock opt until fixed in NSPR 2.0 */
+struct  linger {
+        int     l_onoff;                /* option on/off */
+        int     l_linger;               /* linger time */
+};
+
+struct ip_mreq {
+        struct in_addr  imr_multiaddr;  /* IP multicast address of group */
+        struct in_addr  imr_interface;  /* local IP address of interface */
+};
+
+#endif /* macksocket_h___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macsockotpt.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macsockotpt.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2321 @@
+/* -*- 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 ***** */
+
+/* This turns on UNIX style errors in OT 1.1 headers */
+#define OTUNIXERRORS 1
+
+#include <string.h>
+
+#include <Gestalt.h>
+#include <Files.h>
+#include <OpenTransport.h>
+#include <OSUtils.h>
+
+#define GESTALT_OPEN_TPT_PRESENT        gestaltOpenTptPresentMask
+#define GESTALT_OPEN_TPT_TCP_PRESENT    gestaltOpenTptTCPPresentMask
+
+#include <OpenTptInternet.h>    // All the internet typedefs
+
+#if (UNIVERSAL_INTERFACES_VERSION >= 0x0330)
+// for some reason Apple removed this typedef.
+typedef struct OTConfiguration	OTConfiguration;
+#endif
+
+#include "primpl.h"
+
+typedef enum SndRcvOpCode {
+    kSTREAM_SEND,
+    kSTREAM_RECEIVE,
+    kDGRAM_SEND,
+    kDGRAM_RECEIVE
+} SndRcvOpCode;
+
+static struct {
+	PRLock *    lock;
+	InetSvcRef  serviceRef;
+	PRThread *  thread;
+	void *      cookie;
+} dnsContext;
+
+
+static pascal void  DNSNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie);
+static pascal void  NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie);
+static pascal void  RawEndpointNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie);
+
+static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady);
+
+void
+WakeUpNotifiedThread(PRThread *thread, OTResult result);
+
+extern void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout);
+extern void DoneWaitingOnThisThread(PRThread *thread);
+
+#if TARGET_CARBON
+OTClientContextPtr  clientContext = NULL;
+
+#define INIT_OPEN_TRANSPORT()	InitOpenTransportInContext(kInitOTForExtensionMask, &clientContext)
+#define OT_OPEN_INTERNET_SERVICES(config, flags, err)	OTOpenInternetServicesInContext(config, flags, err, clientContext)
+#define OT_OPEN_ENDPOINT(config, flags, info, err)		OTOpenEndpointInContext(config, flags, info, err, clientContext)
+
+#else
+
+#define INIT_OPEN_TRANSPORT()	InitOpenTransport()
+#define OT_OPEN_INTERNET_SERVICES(config, flags, err)	OTOpenInternetServices(config, flags, err)
+#define OT_OPEN_ENDPOINT(config, flags, info, err)		OTOpenEndpoint(config, flags, info, err)
+#endif /* TARGET_CARBON */
+
+static OTNotifyUPP	DNSNotifierRoutineUPP;
+static OTNotifyUPP NotifierRoutineUPP;
+static OTNotifyUPP RawEndpointNotifierRoutineUPP;
+
+void _MD_InitNetAccess()
+{
+    OSErr       err;
+    OSStatus    errOT;
+    PRBool      hasOTTCPIP = PR_FALSE;
+    PRBool      hasOT = PR_FALSE;
+    long        gestaltResult;
+
+    err = Gestalt(gestaltOpenTpt, &gestaltResult);
+    if (err == noErr)
+        if (gestaltResult & GESTALT_OPEN_TPT_PRESENT)
+            hasOT = PR_TRUE;
+    
+    if (hasOT)
+        if (gestaltResult & GESTALT_OPEN_TPT_TCP_PRESENT)
+            hasOTTCPIP = PR_TRUE;
+        
+    PR_ASSERT(hasOTTCPIP == PR_TRUE);
+
+    DNSNotifierRoutineUPP	=  NewOTNotifyUPP(DNSNotifierRoutine);
+    NotifierRoutineUPP		=  NewOTNotifyUPP(NotifierRoutine);
+    RawEndpointNotifierRoutineUPP = NewOTNotifyUPP(RawEndpointNotifierRoutine);
+
+    errOT = INIT_OPEN_TRANSPORT();
+    PR_ASSERT(err == kOTNoError);
+
+	dnsContext.serviceRef = NULL;
+	dnsContext.lock = PR_NewLock();
+	PR_ASSERT(dnsContext.lock != NULL);
+
+	dnsContext.thread = _PR_MD_CURRENT_THREAD();
+	dnsContext.cookie = NULL;
+	
+/* XXX Does not handle absence of open tpt and tcp yet! */
+}
+
+static void _MD_FinishInitNetAccess()
+{
+    OSStatus    errOT;
+
+	if (dnsContext.serviceRef)
+		return;
+		
+    dnsContext.serviceRef = OT_OPEN_INTERNET_SERVICES(kDefaultInternetServicesPath, NULL, &errOT);
+    if (errOT != kOTNoError) {
+        dnsContext.serviceRef = NULL;
+        return;    /* no network -- oh well */
+    }
+    
+    PR_ASSERT((dnsContext.serviceRef != NULL) && (errOT == kOTNoError));
+
+    /* Install notify function for DNR Address To String completion */
+    errOT = OTInstallNotifier(dnsContext.serviceRef, DNSNotifierRoutineUPP, &dnsContext);
+    PR_ASSERT(errOT == kOTNoError);
+
+    /* Put us into async mode */
+    errOT = OTSetAsynchronous(dnsContext.serviceRef);
+    PR_ASSERT(errOT == kOTNoError);
+}
+
+
+static pascal void  DNSNotifierRoutine(void * contextPtr, OTEventCode otEvent, OTResult result, void * cookie)
+{
+#pragma unused(contextPtr)
+    _PRCPU *    cpu    = _PR_MD_CURRENT_CPU(); 
+	OSStatus    errOT;
+
+		dnsContext.thread->md.osErrCode = result;
+		dnsContext.cookie = cookie;
+	
+	switch (otEvent) {
+		case T_DNRSTRINGTOADDRCOMPLETE:
+				if (_PR_MD_GET_INTSOFF()) {
+					dnsContext.thread->md.missedIONotify = PR_TRUE;
+					cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+				} else {
+					DoneWaitingOnThisThread(dnsContext.thread);
+				}
+				break;
+		
+        case kOTProviderWillClose:
+                errOT = OTSetSynchronous(dnsContext.serviceRef);
+                // fall through to kOTProviderIsClosed case
+		
+        case kOTProviderIsClosed:
+                errOT = OTCloseProvider((ProviderRef)dnsContext.serviceRef);
+                dnsContext.serviceRef = nil;
+
+				if (_PR_MD_GET_INTSOFF()) {
+					dnsContext.thread->md.missedIONotify = PR_TRUE;
+					cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+				} else {
+					DoneWaitingOnThisThread(dnsContext.thread);
+				}
+                break;
+
+        default: // or else we don't handle the event
+	            PR_ASSERT(otEvent==NULL);
+		
+	}
+	// or else we don't handle the event
+	
+	SignalIdleSemaphore();
+}
+
+
+static void macsock_map_error(OSStatus err)
+{
+    _PR_MD_CURRENT_THREAD()->md.osErrCode = err;
+
+    if (IsEError(err) || (err >= EPERM && err <= ELASTERRNO)) {
+    switch (IsEError(err) ? OSStatus2E(err) : err) {
+        case EBADF:
+            PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+            break;
+        case EADDRNOTAVAIL:
+            PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err);
+            break;
+        case EINPROGRESS:
+            PR_SetError(PR_IN_PROGRESS_ERROR, err);
+            break;
+        case EWOULDBLOCK:
+        case EAGAIN:
+            PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+            break;
+        case ENOTSOCK:
+            PR_SetError(PR_NOT_SOCKET_ERROR, err);
+            break;
+        case ETIMEDOUT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, err);
+            break;
+        case ECONNREFUSED:
+            PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+            break;
+        case ENETUNREACH:
+            PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err);
+            break;
+        case EADDRINUSE:
+            PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
+            break;
+        case EFAULT:
+            PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+            break;
+        case EINTR:
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
+            break;
+        case EINVAL:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+            break;
+        case EIO:
+            PR_SetError(PR_IO_ERROR, err);
+            break;
+        case ENOENT:
+            PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+            break;
+        case ENXIO:
+            PR_SetError(PR_IO_ERROR, err);
+            break;
+        case EPROTOTYPE:
+            PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err);
+            break;
+        case EOPNOTSUPP:
+            PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, err);
+            break;
+        default:
+            PR_SetError(PR_UNKNOWN_ERROR, err);
+            break;
+        }
+    } else {
+    PR_ASSERT(IsXTIError(err));
+    switch (err) {
+        case kOTNoDataErr:
+        case kOTFlowErr:
+            PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+            break;
+        default:
+            PR_SetError(PR_UNKNOWN_ERROR, err);
+            break;
+        }
+    }
+}
+
+static void PrepareForAsyncCompletion(PRThread * thread, PRInt32 osfd)
+{
+    thread->io_pending       = PR_TRUE;
+    thread->io_fd            = osfd;
+    thread->md.osErrCode     = noErr;
+}
+
+
+void
+WakeUpNotifiedThread(PRThread *thread, OTResult result)
+{
+    _PRCPU *      cpu      = _PR_MD_CURRENT_CPU(); 
+
+	if (thread) {
+		thread->md.osErrCode = result;
+		if (_PR_MD_GET_INTSOFF()) {
+			thread->md.missedIONotify = PR_TRUE;
+			cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+		} else {
+			DoneWaitingOnThisThread(thread);
+		}
+	}
+	
+	SignalIdleSemaphore();
+}
+
+// Notification routine
+// Async callback routine.
+// A5 is OK. Cannot allocate memory here
+// Ref: http://gemma.apple.com/techpubs/mac/NetworkingOT/NetworkingWOT-100.html
+//
+static pascal void  NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
+{
+    PRFilePrivate *secret  = (PRFilePrivate *) contextPtr;
+    _MDFileDesc * md       = &(secret->md);
+    EndpointRef   endpoint = (EndpointRef)secret->md.osfd;
+    PRThread *    readThread   = NULL;          // also used for 'misc'
+    PRThread *    writeThread  = NULL;
+    OSStatus      err;
+    OTResult      resultOT;
+    TDiscon       discon;
+
+    switch (code)
+    {
+// OTLook Events - 
+        case T_LISTEN:        // A connection request is available
+            // If md->doListen is true, then PR_Listen has been
+            // called on this endpoint; therefore, we're ready to
+            // accept connections. But we'll do that with PR_Accept
+            // (which calls OTListen, OTAccept, etc) instead of 
+            // doing it here. 
+            if (md->doListen) {
+                readThread = secret->md.misc.thread;
+                secret->md.misc.thread    = NULL;
+                secret->md.misc.cookie    = cookie;
+                break;
+            } else {
+                // Reject the connection, we're not listening
+                OTSndDisconnect(endpoint, NULL);
+            }
+            break;
+
+        case T_CONNECT:      // Confirmation of a connect request
+            // cookie = sndCall parameter from OTConnect()
+            err = OTRcvConnect(endpoint, NULL);
+            PR_ASSERT(err == kOTNoError);
+
+            // wake up waiting thread, if any.
+            writeThread = secret->md.write.thread;
+            secret->md.write.thread    = NULL;
+            secret->md.write.cookie    = cookie;            
+            break;
+
+        case T_DATA:        // Standard data is available
+            // Mark this socket as readable.
+            secret->md.readReady = PR_TRUE;
+
+            // wake up waiting thread, if any
+            readThread = secret->md.read.thread;
+            secret->md.read.thread    = NULL;
+            secret->md.read.cookie    = cookie;
+            break;
+
+        case T_EXDATA:      // Expedited data is available
+            PR_ASSERT(!"T_EXDATA Not implemented");
+            return;
+
+        case T_DISCONNECT:  // A disconnect is available
+            discon.udata.len = 0;
+            err = OTRcvDisconnect(endpoint, &discon);
+            PR_ASSERT(err == kOTNoError);
+            secret->md.exceptReady = PR_TRUE;       // XXX Check this
+
+            md->disconnectError = discon.reason;    // save for _MD_mac_get_nonblocking_connect_error
+
+            // wake up waiting threads, if any
+            result = -3199 - discon.reason; // obtain the negative error code
+            if ((readThread = secret->md.read.thread) != NULL) {
+                secret->md.read.thread    = NULL;
+                secret->md.read.cookie    = cookie;
+            }
+
+            if ((writeThread = secret->md.write.thread) != NULL) {
+                secret->md.write.thread    = NULL;
+                secret->md.write.cookie    = cookie;
+            }
+            break;
+
+        case T_ERROR:       // obsolete/unused in library
+            PR_ASSERT(!"T_ERROR Not implemented");
+            return;
+
+        case T_UDERR:       // UDP Send error; clear the error
+            (void) OTRcvUDErr((EndpointRef) cookie, NULL);
+            break;
+
+        case T_ORDREL:      // An orderly release is available
+            err = OTRcvOrderlyDisconnect(endpoint);
+            PR_ASSERT(err == kOTNoError);
+            secret->md.readReady      = PR_TRUE;   // mark readable (to emulate bsd sockets)
+            // remember connection is closed, so we can return 0 on read or receive
+            secret->md.orderlyDisconnect = PR_TRUE;
+            
+            readThread = secret->md.read.thread;
+            secret->md.read.thread    = NULL;
+            secret->md.read.cookie    = cookie;
+            break;		
+
+        case T_GODATA:   // Flow control lifted on standard data
+            secret->md.writeReady = PR_TRUE;
+            resultOT = OTLook(endpoint);        // clear T_GODATA event
+            PR_ASSERT(resultOT == T_GODATA);
+            
+            // wake up waiting thread, if any
+            writeThread = secret->md.write.thread;
+            secret->md.write.thread    = NULL;
+            secret->md.write.cookie    = cookie;
+            break;
+
+        case T_GOEXDATA: // Flow control lifted on expedited data
+            PR_ASSERT(!"T_GOEXDATA Not implemented");
+            return;
+
+        case T_REQUEST:  // An Incoming request is available
+            PR_ASSERT(!"T_REQUEST Not implemented");
+            return;
+
+        case T_REPLY:    // An Incoming reply is available
+            PR_ASSERT(!"T_REPLY Not implemented");
+            return;
+
+        case T_PASSCON:  // State is now T_DATAXFER
+            // OTAccept() complete, receiving endpoint in T_DATAXFER state
+            // cookie = OTAccept() resRef parameter
+            break;
+
+        case T_RESET:    // Protocol has been reset
+            PR_ASSERT(!"T_RESET Not implemented");
+            return;
+            
+// Async Completion Events
+        case T_BINDCOMPLETE:
+        case T_UNBINDCOMPLETE:
+        case T_ACCEPTCOMPLETE:
+        case T_OPTMGMTCOMPLETE:
+        case T_GETPROTADDRCOMPLETE:
+            readThread = secret->md.misc.thread;
+            secret->md.misc.thread    = NULL;
+            secret->md.misc.cookie    = cookie;
+            break;
+
+//      case T_OPENCOMPLETE:            // we open endpoints in synchronous mode
+//      case T_REPLYCOMPLETE:
+//      case T_DISCONNECTCOMPLETE:      // we don't call OTSndDisconnect()
+//      case T_RESOLVEADDRCOMPLETE:
+//      case T_GETINFOCOMPLETE:
+//      case T_SYNCCOMPLETE:
+//      case T_MEMORYRELEASED:          // only if OTAckSends() called on endpoint
+//      case T_REGNAMECOMPLETE:
+//      case T_DELNAMECOMPLETE:
+//      case T_LKUPNAMECOMPLETE:
+//      case T_LKUPNAMERESULT:
+        // OpenTptInternet.h
+//      case T_DNRSTRINGTOADDRCOMPLETE: // DNS is handled by dnsContext in DNSNotifierRoutine()
+//      case T_DNRADDRTONAMECOMPLETE:
+//      case T_DNRSYSINFOCOMPLETE:
+//      case T_DNRMAILEXCHANGECOMPLETE:
+//      case T_DNRQUERYCOMPLETE:
+        default:
+            // we should probably have a bit more sophisticated handling of kOTSystemSleep, etc.
+            // PR_ASSERT(code != 0);
+            return;
+    }
+
+    if (readThread)
+        WakeUpNotifiedThread(readThread, result);
+
+    if (writeThread && (writeThread != readThread))
+        WakeUpNotifiedThread(writeThread, result);
+}
+
+
+static OSErr CreateSocket(int type, EndpointRef *endpoint)
+{
+    OSStatus err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    char *  configName;
+    OTConfiguration *config;
+    EndpointRef ep;
+
+    // for now we just create the endpoint
+    // we'll make it asynchronous and give it a notifier routine in _MD_makenonblock()
+
+    switch (type){
+        case SOCK_STREAM:   configName = kTCPName;  break;
+        case SOCK_DGRAM:    configName = kUDPName;  break;
+    }
+    config = OTCreateConfiguration(configName);
+    ep = OT_OPEN_ENDPOINT(config, 0, NULL, &err);
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    *endpoint = ep;
+    PR_ASSERT(*endpoint != NULL);
+
+    return kOTNoError;
+
+ErrorExit:
+    return err;
+}
+
+
+// Errors returned:
+// kOTXXXX - OT returned error
+// EPROTONOSUPPORT - bad socket type/protocol
+// ENOBUFS - not enough space for another socket, or failure in socket creation routine
+PRInt32 _MD_socket(int domain, int type, int protocol)
+{
+    OSStatus    err;
+    EndpointRef endpoint;
+    
+    _MD_FinishInitNetAccess();
+
+    // We only deal with internet domain
+    if (domain != AF_INET) {
+        err = kEPROTONOSUPPORTErr;
+        goto ErrorExit;
+    }
+    
+    // We only know about tcp & udp
+    if ((type != SOCK_STREAM) && (type != SOCK_DGRAM)) {
+        err = kEPROTONOSUPPORTErr;
+        goto ErrorExit;
+    }
+    
+    // Convert default types to specific types.
+    if (protocol == 0)  {
+        if (type == SOCK_DGRAM)
+            protocol = IPPROTO_UDP;
+        else if (type == SOCK_STREAM)
+            protocol = IPPROTO_TCP;
+    }
+    
+    // Only support default protocol for tcp
+    if ((type == SOCK_STREAM)  && (protocol != IPPROTO_TCP)) {
+        err = kEPROTONOSUPPORTErr;
+        goto ErrorExit;
+    }
+                
+    // Only support default protocol for udp
+    if ((type == SOCK_DGRAM)  && (protocol != IPPROTO_UDP)) {
+        err = kEPROTONOSUPPORTErr;
+        goto ErrorExit;
+    }
+        
+    // Create a socket, we might run out of memory
+    err = CreateSocket(type, &endpoint);
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    PR_ASSERT((PRInt32)endpoint != -1);
+
+    return ((PRInt32)endpoint);
+
+ErrorExit:
+    macsock_map_error(err);
+    return -1;
+}
+
+
+// Errors:
+// EBADF  -- bad socket id
+// EFAULT -- bad address format
+PRInt32 _MD_bind(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen)
+{
+    OSStatus err;
+    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;
+    TBind bindReq;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRUint32 retryCount = 0;
+
+    if (endpoint == NULL) {
+        err = kEBADFErr;
+        goto ErrorExit;
+    }
+        
+    if (addr == NULL) {
+        err = kEFAULTErr;
+        goto ErrorExit;
+    }
+        
+/*
+ * There seems to be a bug with OT related to OTBind failing with kOTNoAddressErr even though
+ * a proper legal address was supplied.  This happens very rarely and just retrying the
+ * operation after a certain time (less than 1 sec. does not work) seems to succeed.
+ */
+
+TryAgain:
+    // setup our request
+    bindReq.addr.len = addrlen;
+        
+    bindReq.addr.maxlen = addrlen;
+    bindReq.addr.buf = (UInt8*) addr;
+    bindReq.qlen = 1;
+
+	PR_Lock(fd->secret->md.miscLock);
+    PrepareForAsyncCompletion(me, fd->secret->md.osfd);
+	fd->secret->md.misc.thread = me;
+
+    err = OTBind(endpoint, &bindReq, NULL);
+    if (err != kOTNoError) {
+	    me->io_pending = PR_FALSE;
+	    PR_Unlock(fd->secret->md.miscLock);
+        goto ErrorExit;
+	}
+
+    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+	PR_Unlock(fd->secret->md.miscLock);
+
+    err = me->md.osErrCode;
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    return kOTNoError;
+
+ErrorExit:
+    if ((err == kOTNoAddressErr) && (++retryCount <= 4)) {
+        unsigned long finalTicks;
+    
+        Delay(100,&finalTicks);
+        goto TryAgain;
+    }
+    macsock_map_error(err);
+    return -1;
+}
+
+
+// Errors:
+// EBADF -- bad socket id
+PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    OSStatus err = 0;
+    EndpointRef endpoint = (EndpointRef) osfd;
+    TBind bindReq;
+    PRNetAddr addr;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if ((fd == NULL) || (endpoint == NULL)) {
+		err = EBADF;
+		goto ErrorExit;
+	}
+
+    if (backlog == 0)
+        backlog = 1;
+
+    if (endpoint == NULL) {
+        err = EBADF;
+        goto ErrorExit;
+    }
+        
+    addr.inet.family = AF_INET;
+    addr.inet.port = addr.inet.ip = 0;
+
+    bindReq.addr.maxlen = PR_NETADDR_SIZE (&addr);
+    bindReq.addr.len = 0;
+    bindReq.addr.buf = (UInt8*) &addr;
+    bindReq.qlen = 0;
+    
+    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
+	fd->secret->md.misc.thread = me; // tell notifier routine what to wake up
+
+    err = OTGetProtAddress(endpoint, &bindReq, NULL);
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+
+    err = me->md.osErrCode;
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
+	fd->secret->md.misc.thread = me; // tell notifier routine what to wake up
+
+    err = OTUnbind(endpoint);
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+
+    err = me->md.osErrCode;
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+	/* tell the notifier func that we are interested in pending connections */
+	fd->secret->md.doListen = PR_TRUE;
+	/* accept up to (backlog) pending connections at any one time */
+    bindReq.qlen = backlog;
+    
+    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
+	fd->secret->md.misc.thread = me; // tell notifier routine what to wake up
+
+    err = OTBind(endpoint, &bindReq, NULL);
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+
+    err = me->md.osErrCode;
+    if (err != kOTNoError)
+    {
+    	// If OTBind failed, we're really not ready to listen after all.
+		fd->secret->md.doListen = PR_FALSE;
+        goto ErrorExit;
+    }
+
+    return kOTNoError;
+
+ErrorExit:
+	me->io_pending = PR_FALSE; // clear pending wait state if any
+    macsock_map_error(err);
+    return -1;
+}
+
+
+// Errors:
+// EBADF -- bad socket id
+PRInt32 _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
+{
+    OSStatus err;
+    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;
+    TBind bindReq;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (endpoint == NULL) {
+        err = kEBADFErr;
+        goto ErrorExit;
+    }
+        
+    if (addr == NULL) {
+        err = kEFAULTErr;
+        goto ErrorExit;
+    }
+
+    bindReq.addr.len = *addrlen;
+    bindReq.addr.maxlen = *addrlen;
+    bindReq.addr.buf = (UInt8*) addr;
+    bindReq.qlen = 0;
+    
+	PR_Lock(fd->secret->md.miscLock);
+    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
+	fd->secret->md.misc.thread = me;
+
+    err = OTGetProtAddress(endpoint, &bindReq, NULL);
+    if (err != kOTNoError) {
+	    me->io_pending = PR_FALSE;
+	    PR_Unlock(fd->secret->md.miscLock);
+        goto ErrorExit;
+	}
+
+    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+	PR_Unlock(fd->secret->md.miscLock);
+
+    err = me->md.osErrCode;
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    *addrlen = PR_NETADDR_SIZE(addr);
+    return kOTNoError;
+
+ErrorExit:
+    macsock_map_error(err);
+    return -1;
+}
+
+
+PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen)
+{
+    OSStatus err;
+    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;
+    TOptMgmt cmd;
+    TOption *opt;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    unsigned char optionBuffer[kOTOptionHeaderSize + sizeof(PRSocketOptionData)];
+    
+    if (endpoint == NULL) {
+        err = kEBADFErr;
+        goto ErrorExit;
+    }
+    
+    /* 
+    OT wants IPPROTO_IP for level and not XTI_GENERIC.  SO_REUSEADDR and SO_KEEPALIVE 
+    are equated to IP level and TCP level options respectively and hence we need to set 
+    the level correctly.
+    */
+    if (level == SOL_SOCKET) {
+        if (optname == SO_REUSEADDR)
+            level = IPPROTO_IP;
+        else if (optname == SO_KEEPALIVE)
+            level = INET_TCP;
+    }
+
+    opt = (TOption *)&optionBuffer[0];
+    opt->len = sizeof(TOption);
+    opt->level = level;
+    opt->name = optname;
+    opt->status = 0;
+    
+    cmd.opt.len = sizeof(TOption);
+    cmd.opt.maxlen = sizeof(optionBuffer);
+    cmd.opt.buf = (UInt8*)optionBuffer;
+    cmd.flags = T_CURRENT;
+
+	PR_Lock(fd->secret->md.miscLock);
+    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
+	fd->secret->md.misc.thread = me;
+
+    err = OTOptionManagement(endpoint, &cmd, &cmd);
+    if (err != kOTNoError) {
+	    me->io_pending = PR_FALSE;
+	    PR_Unlock(fd->secret->md.miscLock);
+        goto ErrorExit;
+	}
+
+    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+	PR_Unlock(fd->secret->md.miscLock);
+
+    err = me->md.osErrCode;
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    if (opt->status == T_FAILURE || opt->status == T_NOTSUPPORT){
+        err = kEOPNOTSUPPErr;
+        goto ErrorExit;
+    }
+
+    PR_ASSERT(opt->status == T_SUCCESS);
+
+    switch (optname) {
+        case SO_LINGER:
+            *((t_linger*)optval) = *((t_linger*)&opt->value);
+            *optlen = sizeof(t_linger);
+            break;
+        case SO_REUSEADDR:
+        case TCP_NODELAY:
+        case SO_KEEPALIVE:
+        case SO_RCVBUF:
+        case SO_SNDBUF:
+            *((PRIntn*)optval) = *((PRIntn*)&opt->value);
+            *optlen = sizeof(PRIntn);
+            break;
+        case IP_MULTICAST_LOOP:
+            *((PRUint8*)optval) = *((PRIntn*)&opt->value);
+            *optlen = sizeof(PRUint8);
+            break;
+        case IP_TTL:
+            *((PRUintn*)optval) = *((PRUint8*)&opt->value);
+            *optlen = sizeof(PRUintn);
+            break;
+        case IP_MULTICAST_TTL:
+            *((PRUint8*)optval) = *((PRUint8*)&opt->value);
+            *optlen = sizeof(PRUint8);
+            break;
+        case IP_ADD_MEMBERSHIP:
+        case IP_DROP_MEMBERSHIP:
+            {
+            /* struct ip_mreq and TIPAddMulticast are the same size and optval 
+               is pointing to struct ip_mreq */
+            *((struct ip_mreq *)optval) = *((struct ip_mreq *)&opt->value);
+            *optlen = sizeof(struct ip_mreq);
+            break;
+            }
+        case IP_MULTICAST_IF:
+            {
+            *((PRUint32*)optval) = *((PRUint32*)&opt->value);
+            *optlen = sizeof(PRUint32);
+            break;
+            }
+        /*case IP_TOS:*/ /*IP_TOS has same value as TCP_MAXSEG */
+        case TCP_MAXSEG:
+            if (level == IPPROTO_TCP) { /* it is TCP_MAXSEG */
+                *((PRIntn*)optval) = *((PRIntn*)&opt->value);
+                *optlen = sizeof(PRIntn);
+            } else { /* it is IP_TOS */
+                *((PRUintn*)optval) = *((PRUint8*)&opt->value);
+                *optlen = sizeof(PRUintn);
+            }
+            break;
+        default:
+            PR_ASSERT(0);
+            break;    
+    }
+    
+    return PR_SUCCESS;
+
+ErrorExit:
+    macsock_map_error(err);
+    return PR_FAILURE;
+}
+
+
+PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen)
+{
+    OSStatus err;
+    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;
+    TOptMgmt cmd;
+    TOption *opt;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    unsigned char optionBuffer[kOTOptionHeaderSize + sizeof(PRSocketOptionData) + 1];
+    
+    if (endpoint == NULL) {
+        err = kEBADFErr;
+        goto ErrorExit;
+    }
+    
+    /* 
+    OT wants IPPROTO_IP for level and not XTI_GENERIC.  SO_REUSEADDR and SO_KEEPALIVE 
+    are equated to IP level and TCP level options respectively and hence we need to set 
+    the level correctly.
+    */
+    if (level == SOL_SOCKET) {
+        if (optname == SO_REUSEADDR)
+            level = IPPROTO_IP;
+        else if (optname == SO_KEEPALIVE)
+            level = INET_TCP;
+    }
+
+    opt = (TOption *)&optionBuffer[0];
+    opt->len = kOTOptionHeaderSize + optlen;
+
+    /* special case adjustments for length follow */
+    if (optname == SO_KEEPALIVE) /* we need to pass the timeout value for OT */
+        opt->len = kOTOptionHeaderSize + sizeof(t_kpalive);
+    if (optname == IP_MULTICAST_TTL || optname == IP_TTL) /* it is an unsigned char value */
+        opt->len = kOTOneByteOptionSize;
+    if (optname == IP_TOS && level == IPPROTO_IP)
+        opt->len = kOTOneByteOptionSize;
+
+    opt->level = level;
+    opt->name = optname;
+    opt->status = 0;
+    
+    cmd.opt.len = opt->len;
+    cmd.opt.maxlen = sizeof(optionBuffer);
+    cmd.opt.buf = (UInt8*)optionBuffer;
+    
+    optionBuffer[opt->len] = 0;
+    
+    cmd.flags = T_NEGOTIATE;
+
+    switch (optname) {
+        case SO_LINGER:
+            *((t_linger*)&opt->value) = *((t_linger*)optval);
+            break;
+        case SO_REUSEADDR:
+        case TCP_NODELAY:
+        case SO_RCVBUF:
+        case SO_SNDBUF:
+            *((PRIntn*)&opt->value) = *((PRIntn*)optval);
+            break;
+        case IP_MULTICAST_LOOP:
+            if (*optval != 0)
+                opt->value[0] = T_YES;
+            else
+                opt->value[0] = T_NO;
+            break;
+        case SO_KEEPALIVE:
+            {
+            t_kpalive *kpalive = (t_kpalive *)&opt->value;
+            
+            kpalive->kp_onoff = *((long*)optval);
+            kpalive->kp_timeout = 10; /* timeout in minutes */
+            break;
+            }
+        case IP_TTL:
+            *((unsigned char*)&opt->value) = *((PRUintn*)optval);
+            break;
+        case IP_MULTICAST_TTL:
+            *((unsigned char*)&opt->value) = *optval;
+            break;
+        case IP_ADD_MEMBERSHIP:
+        case IP_DROP_MEMBERSHIP:
+            {
+            /* struct ip_mreq and TIPAddMulticast are the same size and optval 
+               is pointing to struct ip_mreq */
+            *((TIPAddMulticast *)&opt->value) = *((TIPAddMulticast *)optval);
+            break;
+            }
+        case IP_MULTICAST_IF:
+            {
+            *((PRUint32*)&opt->value) = *((PRUint32*)optval);
+            break;
+            }
+        /*case IP_TOS:*/ /*IP_TOS has same value as TCP_MAXSEG */
+        case TCP_MAXSEG:
+            if (level == IPPROTO_TCP) { /* it is TCP_MAXSEG */
+                *((PRIntn*)&opt->value) = *((PRIntn*)optval);
+            } else { /* it is IP_TOS */
+                *((unsigned char*)&opt->value) = *((PRUintn*)optval);
+            }
+            break;
+        default:
+            PR_ASSERT(0);
+            break;    
+    }
+    
+	PR_Lock(fd->secret->md.miscLock);
+    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
+	fd->secret->md.misc.thread = me;
+
+    err = OTOptionManagement(endpoint, &cmd, &cmd);
+    if (err != kOTNoError) {
+	    me->io_pending = PR_FALSE;
+	    PR_Unlock(fd->secret->md.miscLock);
+        goto ErrorExit;
+	}
+
+    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+	PR_Unlock(fd->secret->md.miscLock);
+
+    err = me->md.osErrCode;
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    if (opt->status == T_FAILURE || opt->status == T_NOTSUPPORT){
+        err = kEOPNOTSUPPErr;
+        goto ErrorExit;
+    }
+    
+    if (level == IPPROTO_TCP && optname == TCP_MAXSEG && opt->status == T_READONLY) {
+        err = kEOPNOTSUPPErr;
+        goto ErrorExit;
+    }
+
+    PR_ASSERT(opt->status == T_SUCCESS);
+
+    return PR_SUCCESS;
+
+ErrorExit:
+    macsock_map_error(err);
+    return PR_FAILURE;
+}
+
+
+PRInt32 _MD_socketavailable(PRFileDesc *fd)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    OSStatus err;
+    EndpointRef endpoint = (EndpointRef) osfd;
+    size_t bytes;
+
+    if (endpoint == NULL) {
+        err = kEBADFErr;
+        goto ErrorExit;
+    }
+    
+    bytes = 0;
+    
+    err = OTCountDataBytes(endpoint, &bytes);
+    if ((err == kOTLookErr) ||         // Not really errors, we just need to do a read,
+        (err == kOTNoDataErr))        // or there's nothing there.
+        err = kOTNoError;
+        
+    if (err != kOTNoError)
+        goto ErrorExit;
+        
+    return bytes;
+
+ErrorExit:
+    macsock_map_error(err);
+    return -1;
+}
+
+
+typedef struct RawEndpointAndThread
+{
+	PRThread *  thread;
+	EndpointRef endpoint;
+} RawEndpointAndThread;
+
+// Notification routine for raw endpoints not yet attached to a PRFileDesc.
+// Async callback routine.
+// A5 is OK. Cannot allocate memory here
+static pascal void  RawEndpointNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
+{
+    RawEndpointAndThread *endthr = (RawEndpointAndThread *) contextPtr;
+    PRThread *    thread   = endthr->thread;
+    EndpointRef * endpoint = endthr->endpoint;
+    _PRCPU *      cpu      = _PR_MD_CURRENT_CPU(); 
+    OSStatus      err;
+    OTResult	  resultOT;
+
+    switch (code)
+    {
+// OTLook Events - 
+        case T_LISTEN:        // A connection request is available
+            PR_ASSERT(!"T_EXDATA not implemented for raw endpoints");
+            break;
+			
+        case T_CONNECT:      // Confirmation of a connect request
+			// cookie = sndCall parameter from OTConnect()
+            err = OTRcvConnect(endpoint, NULL);
+            PR_ASSERT(err == kOTNoError);
+
+			// wake up waiting thread
+            break;
+
+        case T_DATA:        // Standard data is available
+			break;
+
+        case T_EXDATA:      // Expedited data is available
+            PR_ASSERT(!"T_EXDATA Not implemented for raw endpoints");
+			return;
+
+        case T_DISCONNECT:  // A disconnect is available
+            err = OTRcvDisconnect(endpoint, NULL);
+            PR_ASSERT(err == kOTNoError);
+            break;
+		
+        case T_ERROR:       // obsolete/unused in library
+            PR_ASSERT(!"T_ERROR Not implemented for raw endpoints");
+			return;		
+		
+        case T_UDERR:       // UDP Send error; clear the error
+			(void) OTRcvUDErr((EndpointRef) cookie, NULL);
+            break;
+
+        case T_ORDREL:      // An orderly release is available
+            err = OTRcvOrderlyDisconnect(endpoint);
+            PR_ASSERT(err == kOTNoError);
+            break;		
+
+        case T_GODATA:   // Flow control lifted on standard data
+			resultOT = OTLook(endpoint);		// clear T_GODATA event
+			PR_ASSERT(resultOT == T_GODATA);
+			
+			// wake up waiting thread, if any
+            break;
+
+        case T_GOEXDATA: // Flow control lifted on expedited data
+            PR_ASSERT(!"T_GOEXDATA Not implemented");
+			return;
+
+        case T_REQUEST:  // An Incoming request is available
+            PR_ASSERT(!"T_REQUEST Not implemented");
+            return;
+
+        case T_REPLY:    // An Incoming reply is available
+            PR_ASSERT(!"T_REPLY Not implemented");
+            return;
+
+        case T_PASSCON:  // State is now T_DATAXFER
+			// OTAccept() complete, receiving endpoint in T_DATAXFER state
+			// cookie = OTAccept() resRef parameter
+			break;
+            
+// Async Completion Events
+        case T_BINDCOMPLETE:
+        case T_UNBINDCOMPLETE:
+        case T_ACCEPTCOMPLETE:
+        case T_OPTMGMTCOMPLETE:
+        case T_GETPROTADDRCOMPLETE:
+            break;
+
+		// for other OT events, see NotifierRoutine above
+        default:
+            return;
+    }
+
+	if (thread) {
+		thread->md.osErrCode = result;
+		if (_PR_MD_GET_INTSOFF()) {
+			thread->md.asyncNotifyPending = PR_TRUE;
+			cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+		} else {
+			DoneWaitingOnThisThread(thread);
+		}
+	}
+
+	SignalIdleSemaphore();
+}
+
+PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    OSStatus err;
+    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    TBind bindReq;
+    PRNetAddr bindAddr;
+    PRInt32 newosfd = -1;
+    TCall call;
+    PRNetAddr callAddr;
+    RawEndpointAndThread *endthr = NULL;
+
+    if (endpoint == NULL) {
+        err = kEBADFErr;
+        goto ErrorExit;
+    }
+        
+    memset(&call, 0 , sizeof(call));
+
+    if (addr != NULL) {
+        call.addr.maxlen = *addrlen;
+        call.addr.len = *addrlen;
+        call.addr.buf = (UInt8*) addr;
+    } else {
+        call.addr.maxlen = sizeof(callAddr);
+        call.addr.len = sizeof(callAddr);
+        call.addr.buf = (UInt8*) &callAddr;
+    }
+
+	do {
+	    PrepareForAsyncCompletion(me, fd->secret->md.osfd);
+	    fd->secret->md.misc.thread = me;
+	    
+	    // Perform the listen. 
+	    err = OTListen (endpoint, &call);
+	    if (err == kOTNoError)
+	    	break; // got the call information
+	    else if ((!fd->secret->nonblocking) && (err == kOTNoDataErr)) {
+	        WaitOnThisThread(me, timeout);
+	        err = me->md.osErrCode;
+	        if ((err != kOTNoError) && (err != kOTNoDataErr))
+	        	goto ErrorExit;
+			// we can get kOTNoError here, but still need
+			// to loop back to call OTListen, in order
+			// to get call info for OTAccept
+	    } else {
+	    	goto ErrorExit; // we're nonblocking, and/or we got an error
+	    }   
+	}
+	while(1);
+
+    newosfd = _MD_socket(AF_INET, SOCK_STREAM, 0);
+    if (newosfd == -1)
+        return -1;
+            
+	// Attach the raw endpoint handler to this endpoint for now.
+	endthr = (RawEndpointAndThread *) PR_Malloc(sizeof(RawEndpointAndThread));
+	endthr->thread = me;
+	endthr->endpoint = (EndpointRef) newosfd;
+	
+	err = OTInstallNotifier((ProviderRef) newosfd, RawEndpointNotifierRoutineUPP, endthr);
+    PR_ASSERT(err == kOTNoError);
+    
+	err = OTSetAsynchronous((EndpointRef) newosfd);
+	PR_ASSERT(err == kOTNoError);
+
+    // Bind to a local port; let the system assign it.
+    bindAddr.inet.family = AF_INET;
+    bindAddr.inet.port = bindAddr.inet.ip = 0;
+
+    bindReq.addr.maxlen = PR_NETADDR_SIZE (&bindAddr);
+    bindReq.addr.len = 0;
+    bindReq.addr.buf = (UInt8*) &bindAddr;
+    bindReq.qlen = 0;
+
+    PrepareForAsyncCompletion(me, newosfd);    
+    err = OTBind((EndpointRef) newosfd, &bindReq, NULL);
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    WaitOnThisThread(me, timeout);
+
+    err = me->md.osErrCode;
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    PrepareForAsyncCompletion(me, newosfd);    
+
+    err = OTAccept (endpoint, (EndpointRef) newosfd, &call);
+ 	if ((err != kOTNoError) && (err != kOTNoDataErr))
+        goto ErrorExit;
+
+    WaitOnThisThread(me, timeout);
+
+    err = me->md.osErrCode;
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    if (addrlen != NULL)
+        *addrlen = call.addr.len;
+
+	// Remove the temporary notifier we installed to set up the new endpoint.
+	OTRemoveNotifier((EndpointRef) newosfd);
+	PR_Free(endthr); // free the temporary context we set up for this endpoint
+
+    return newosfd;
+
+ErrorExit:
+	me->io_pending = PR_FALSE; // clear pending wait state if any
+    if (newosfd != -1)
+        _MD_closesocket(newosfd);
+    macsock_map_error(err);
+    return -1;
+}
+
+
+PRInt32 _MD_connect(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    OSStatus err;
+    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    TCall sndCall;
+    TBind bindReq;
+    PRNetAddr bindAddr;
+
+    if (endpoint == NULL) {
+        err = kEBADFErr;
+        goto ErrorExit;
+    }
+        
+    if (addr == NULL) {
+        err = kEFAULTErr;
+        goto ErrorExit;
+    }
+    
+    // Bind to a local port; let the system assign it.
+
+    bindAddr.inet.family = AF_INET;
+    bindAddr.inet.port = bindAddr.inet.ip = 0;
+
+    bindReq.addr.maxlen = PR_NETADDR_SIZE (&bindAddr);
+    bindReq.addr.len = 0;
+    bindReq.addr.buf = (UInt8*) &bindAddr;
+    bindReq.qlen = 0;
+    
+    PR_Lock(fd->secret->md.miscLock);
+    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
+    fd->secret->md.misc.thread = me;
+
+    err = OTBind(endpoint, &bindReq, NULL);
+    if (err != kOTNoError) {
+      me->io_pending = PR_FALSE;
+      PR_Unlock(fd->secret->md.miscLock);
+      goto ErrorExit;
+    }
+
+    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+    PR_Unlock(fd->secret->md.miscLock);
+
+    err = me->md.osErrCode;
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    memset(&sndCall, 0 , sizeof(sndCall));
+
+    sndCall.addr.maxlen = addrlen;
+    sndCall.addr.len = addrlen;
+    sndCall.addr.buf = (UInt8*) addr;
+
+    if (!fd->secret->nonblocking) {    
+      PrepareForAsyncCompletion(me, fd->secret->md.osfd);
+      PR_ASSERT(fd->secret->md.write.thread == NULL);
+      fd->secret->md.write.thread = me;
+    }
+
+    err = OTConnect (endpoint, &sndCall, NULL);
+    if (err == kOTNoError) {
+      PR_ASSERT(!"OTConnect returned kOTNoError in async mode!?!");	
+    }
+    if (fd->secret->nonblocking) {
+      if (err == kOTNoDataErr)
+      err = EINPROGRESS;
+      goto ErrorExit;
+    } else {
+      if (err != kOTNoError && err != kOTNoDataErr) {
+        me->io_pending = PR_FALSE;
+        goto ErrorExit;
+      }
+    }
+	
+    WaitOnThisThread(me, timeout);
+
+    err = me->md.osErrCode;
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    return kOTNoError;
+
+ErrorExit:
+    macsock_map_error(err);
+    return -1;
+}
+
+
+// Errors:
+// EBADF -- bad socket id
+// EFAULT -- bad buffer
+static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount, 
+                               PRIntn flags, PRIntervalTime timeout, SndRcvOpCode opCode)
+{
+    OSStatus err;
+    OTResult result;
+    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 bytesLeft = amount;
+
+    PR_ASSERT(flags == 0 ||
+        (opCode == kSTREAM_RECEIVE && flags == PR_MSG_PEEK));
+    PR_ASSERT(opCode == kSTREAM_SEND || opCode == kSTREAM_RECEIVE);
+    
+    if (endpoint == NULL) {
+        err = kEBADFErr;
+        goto ErrorExit;
+    }
+        
+    if (buf == NULL) {
+        err = kEFAULTErr;
+        goto ErrorExit;
+    }
+
+    PR_ASSERT(opCode == kSTREAM_SEND ? fd->secret->md.write.thread == NULL :
+                                       fd->secret->md.read.thread  == NULL);
+
+    while (bytesLeft > 0)
+    {
+        Boolean disabledNotifications = OTEnterNotifier(endpoint);
+    
+        PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
+
+        if (opCode == kSTREAM_SEND) {
+        	do {
+				fd->secret->md.write.thread = me;
+				fd->secret->md.writeReady = PR_FALSE;				// expect the worst
+	            result = OTSnd(endpoint, buf, bytesLeft, NULL);
+				fd->secret->md.writeReady = (result != kOTFlowErr);
+				if (fd->secret->nonblocking)							// hope for the best
+					break;
+				else {
+
+					// We drop through on anything other than a blocking write.
+					if (result != kOTFlowErr)
+						break;
+
+					// Blocking write, but the pipe is full. Turn notifications on and
+					// wait for an event, hoping that it's a T_GODATA event.
+                    if (disabledNotifications) {
+                        OTLeaveNotifier(endpoint);
+                        disabledNotifications = false;
+                    }
+					WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+					result = me->md.osErrCode;
+					if (result != kOTNoError) // got interrupted, or some other error
+						break;
+
+					// Prepare to loop back and try again
+					disabledNotifications = OTEnterNotifier(endpoint);
+  			   		PrepareForAsyncCompletion(me, fd->secret->md.osfd);  
+				}
+			}
+			while(1);
+        } else {
+        	do {
+				fd->secret->md.read.thread = me;
+				fd->secret->md.readReady = PR_FALSE;				// expect the worst			
+	            result = OTRcv(endpoint, buf, bytesLeft, NULL);
+	            if (fd->secret->nonblocking) {
+					fd->secret->md.readReady = (result != kOTNoDataErr);
+					break;
+				} else {
+					if (result != kOTNoDataErr) {
+			      		// If we successfully read a blocking socket, check for more data.
+			      		// According to IM:OT, we should be able to rely on OTCountDataBytes
+			      		// to tell us whether there is a nonzero amount of data pending.
+			        	size_t count;
+			        	OSErr tmpResult;
+			        	tmpResult = OTCountDataBytes(endpoint, &count);
+				        fd->secret->md.readReady = ((tmpResult == kOTNoError) && (count > 0));
+						break;
+				    }
+
+					// Blocking read, but no data available. Turn notifications on and
+					// wait for an event on this endpoint, and hope that we get a T_DATA event.
+                    if (disabledNotifications) {
+                        OTLeaveNotifier(endpoint);
+                        disabledNotifications = false;
+                    }
+					WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+					result = me->md.osErrCode;
+					if (result != kOTNoError) // interrupted thread, etc.
+						break;
+
+					// Prepare to loop back and try again
+					disabledNotifications = OTEnterNotifier(endpoint);
+  			   		PrepareForAsyncCompletion(me, fd->secret->md.osfd);  
+				}
+			}
+			// Retry read if we had to wait for data to show up.
+			while(1);
+        }
+
+		me->io_pending = PR_FALSE;
+		
+        if (opCode == kSTREAM_SEND)
+            fd->secret->md.write.thread = NULL;
+        else
+            fd->secret->md.read.thread  = NULL;
+
+        // turn notifications back on
+        if (disabledNotifications)
+            OTLeaveNotifier(endpoint);
+
+        if (result > 0) {
+            buf = (void *) ( (UInt32) buf + (UInt32)result );
+            bytesLeft -= result;
+            if (opCode == kSTREAM_RECEIVE) {
+                amount = result;
+                goto NormalExit;
+            }
+        } else {
+			switch (result) {
+				case kOTLookErr:
+				    PR_ASSERT(!"call to OTLook() required after all.");
+					break;
+				
+				case kOTFlowErr:
+				case kOTNoDataErr:
+				case kEAGAINErr:
+				case kEWOULDBLOCKErr:
+					if (fd->secret->nonblocking) {
+					
+					    if (bytesLeft == amount) {  // no data was sent
+						    err = result;
+						    goto ErrorExit;
+						}
+						
+						// some data was sent
+						amount -= bytesLeft;
+						goto NormalExit;
+					}
+
+					WaitOnThisThread(me, timeout);
+					err = me->md.osErrCode;
+					if (err != kOTNoError)
+						goto ErrorExit;				
+					break;
+					
+				case kOTOutStateErr:	// if provider already closed, fall through to handle error
+					if (fd->secret->md.orderlyDisconnect) {
+						amount = 0;
+						goto NormalExit;
+					}
+					// else fall through
+				default:
+					err = result;
+					goto ErrorExit;
+			}
+		}
+    }
+
+NormalExit:
+    PR_ASSERT(opCode == kSTREAM_SEND ? fd->secret->md.write.thread == NULL :
+                                       fd->secret->md.read.thread  == NULL);
+    return amount;
+
+ErrorExit:
+    PR_ASSERT(opCode == kSTREAM_SEND ? fd->secret->md.write.thread == NULL :
+                                       fd->secret->md.read.thread  == NULL);
+    macsock_map_error(err);
+    return -1;
+}
+
+
+PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, 
+                               PRIntn flags, PRIntervalTime timeout)
+{
+    return (SendReceiveStream(fd, buf, amount, flags, timeout, kSTREAM_RECEIVE));
+}
+
+
+PRInt32 _MD_send(PRFileDesc *fd,const void *buf, PRInt32 amount, 
+                               PRIntn flags, PRIntervalTime timeout)
+{
+    return (SendReceiveStream(fd, (void *)buf, amount, flags, timeout, kSTREAM_SEND));
+}
+
+
+// Errors:
+// EBADF -- bad socket id
+// EFAULT -- bad buffer
+static PRInt32 SendReceiveDgram(PRFileDesc *fd, void *buf, PRInt32 amount, 
+                               PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, 
+                               PRIntervalTime timeout, SndRcvOpCode opCode)
+{
+    OSStatus err;
+    EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 bytesLeft = amount;
+    TUnitData dgram;
+
+    PR_ASSERT(flags == 0);
+    
+    if (endpoint == NULL) {
+        err = kEBADFErr;
+        goto ErrorExit;
+    }
+        
+    if (buf == NULL || addr == NULL) {
+        err = kEFAULTErr;
+        goto ErrorExit;
+    }
+    
+    if (opCode != kDGRAM_SEND && opCode != kDGRAM_RECEIVE) {
+        err = kEINVALErr;
+        goto ErrorExit;
+    }
+        
+    memset(&dgram, 0 , sizeof(dgram));
+    dgram.addr.maxlen = *addrlen;
+    dgram.addr.len = *addrlen;
+    dgram.addr.buf = (UInt8*) addr;
+    dgram.udata.maxlen = amount;
+    dgram.udata.len = amount;
+    dgram.udata.buf = (UInt8*) buf;    
+
+    while (bytesLeft > 0) {
+    
+        PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
+
+        if (opCode == kDGRAM_SEND) {
+			fd->secret->md.write.thread = me;
+			fd->secret->md.writeReady = PR_FALSE;				// expect the worst
+            err = OTSndUData(endpoint, &dgram);
+			if (err != kOTFlowErr)							// hope for the best
+				fd->secret->md.writeReady = PR_TRUE;
+		} else {
+			fd->secret->md.read.thread = me;
+			fd->secret->md.readReady = PR_FALSE;				// expect the worst			
+            err = OTRcvUData(endpoint, &dgram, NULL);
+			if (err != kOTNoDataErr)							// hope for the best
+				fd->secret->md.readReady = PR_TRUE;
+		}
+
+        if (err == kOTNoError) {
+            buf = (void *) ( (UInt32) buf + (UInt32)dgram.udata.len );
+            bytesLeft -= dgram.udata.len;
+            dgram.udata.buf = (UInt8*) buf;    
+            me->io_pending = PR_FALSE;
+        } else {
+            PR_ASSERT(err == kOTNoDataErr || err == kOTOutStateErr);
+            WaitOnThisThread(me, timeout);
+            err = me->md.osErrCode;
+            if (err != kOTNoError)
+                goto ErrorExit;
+        }
+    }
+
+    if (opCode == kDGRAM_RECEIVE)
+        *addrlen = dgram.addr.len;
+
+    return amount;
+
+ErrorExit:
+    macsock_map_error(err);
+    return -1;
+}
+
+
+PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, 
+                               PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen,
+                               PRIntervalTime timeout)
+{
+    return (SendReceiveDgram(fd, buf, amount, flags, addr, addrlen,
+                            timeout, kDGRAM_RECEIVE));
+}
+
+
+PRInt32 _MD_sendto(PRFileDesc *fd,const void *buf, PRInt32 amount, 
+                               PRIntn flags, PRNetAddr *addr, PRUint32 addrlen,
+                               PRIntervalTime timeout)
+{
+    return (SendReceiveDgram(fd, (void *)buf, amount, flags, addr, &addrlen,
+                            timeout, kDGRAM_SEND));
+}
+
+
+PRInt32 _MD_closesocket(PRInt32 osfd)
+{
+    OSStatus err;
+    EndpointRef endpoint = (EndpointRef) osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (endpoint == NULL) {
+        err = kEBADFErr;
+        goto ErrorExit;
+    }
+        
+    if (me->io_pending && me->io_fd == osfd)
+        me->io_pending = PR_FALSE;
+
+    (void) OTSndOrderlyDisconnect(endpoint);
+    err = OTCloseProvider(endpoint);
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    return kOTNoError;
+
+ErrorExit:
+    macsock_map_error(err);
+    return -1;
+}
+
+
+PRInt32 _MD_writev(PRFileDesc *fd, const struct PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout)
+{
+#pragma unused (fd, iov, iov_size, timeout)
+
+    PR_ASSERT(0);
+    _PR_MD_CURRENT_THREAD()->md.osErrCode = unimpErr;
+    return -1;
+}
+
+// OT endpoint states are documented here:
+// http://gemma.apple.com/techpubs/mac/NetworkingOT/NetworkingWOT-27.html#MARKER-9-65
+//
+static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady)
+{
+    OTResult resultOT;
+    // hack to emulate BSD sockets; say that a socket that has disconnected
+    // is still readable.
+    size_t   availableData = 1;
+    if (!fd->secret->md.orderlyDisconnect)
+        OTCountDataBytes((EndpointRef)fd->secret->md.osfd, &availableData);
+
+    *readReady = fd->secret->md.readReady && (availableData > 0);
+    *exceptReady = fd->secret->md.exceptReady;
+
+    resultOT = OTGetEndpointState((EndpointRef)fd->secret->md.osfd);
+    switch (resultOT) {
+        case T_IDLE:
+        case T_UNBND:
+            // the socket is not connected. Emulating BSD sockets,
+            // we mark it readable and writable. The next PR_Read
+            // or PR_Write will then fail. Usually, in this situation,
+            // fd->secret->md.exceptReady is also set, and returned if
+            // anyone is polling for it.
+            *readReady = PR_FALSE;
+            *writeReady = PR_FALSE;
+            break;
+
+        case T_DATAXFER:        // data transfer
+            *writeReady = fd->secret->md.writeReady;
+            break;
+
+        case T_INREL:           // incoming orderly release
+            *writeReady = fd->secret->md.writeReady;
+            break;
+
+        case T_OUTCON:          // outgoing connection pending  
+        case T_INCON:           // incoming connection pending
+        case T_OUTREL:          // outgoing orderly release
+        default:
+            *writeReady = PR_FALSE;
+    }
+    
+    return  *readReady || *writeReady || *exceptReady;
+}
+
+// check to see if any of the poll descriptors have data available
+// for reading or writing, by calling their poll methods (layered IO).
+static PRInt32 CheckPollDescMethods(PRPollDesc *pds, PRIntn npds, PRInt16 *outReadFlags, PRInt16 *outWriteFlags)
+{
+    PRInt32     ready = 0;
+    PRPollDesc  *pd, *epd;
+    PRInt16     *readFlag, *writeFlag;
+    
+    for (pd = pds, epd = pd + npds, readFlag = outReadFlags, writeFlag = outWriteFlags;
+        pd < epd;
+        pd++, readFlag++, writeFlag++)
+    {
+        PRInt16  in_flags_read = 0,  in_flags_write = 0;
+        PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+        pd->out_flags = 0;
+
+        if (NULL == pd->fd || pd->in_flags == 0) continue;
+
+        if (pd->in_flags & PR_POLL_READ)
+        {
+            in_flags_read = (pd->fd->methods->poll)(
+                pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
+        }
+
+        if (pd->in_flags & PR_POLL_WRITE)
+        {
+            in_flags_write = (pd->fd->methods->poll)(
+                pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
+        }
+
+        if ((0 != (in_flags_read & out_flags_read)) ||
+            (0 != (in_flags_write & out_flags_write)))
+        {
+            ready += 1;  /* some layer has buffer input */
+            pd->out_flags = out_flags_read | out_flags_write;
+        }
+        
+        *readFlag = in_flags_read;
+        *writeFlag = in_flags_write;
+    }
+
+    return ready;
+}
+
+// check to see if any of OT endpoints of the poll descriptors have data available
+// for reading or writing.
+static PRInt32 CheckPollDescEndpoints(PRPollDesc *pds, PRIntn npds, const PRInt16 *inReadFlags, const PRInt16 *inWriteFlags)
+{
+    PRInt32 ready = 0;
+    PRPollDesc *pd, *epd;
+    const PRInt16   *readFlag, *writeFlag;
+    
+    for (pd = pds, epd = pd + npds, readFlag = inReadFlags, writeFlag = inWriteFlags;
+         pd < epd;
+        pd++, readFlag++, writeFlag++)
+    {
+        PRFileDesc *bottomFD;
+        PRBool      readReady, writeReady, exceptReady;
+        PRInt16     in_flags_read = *readFlag;
+        PRInt16     in_flags_write = *writeFlag;
+
+        if (NULL == pd->fd || pd->in_flags == 0) continue;
+
+        if ((pd->in_flags & ~pd->out_flags) == 0) {
+            ready++;
+            continue;
+        }
+
+        bottomFD = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+        /* bottomFD can be NULL for pollable sockets */
+        if (bottomFD)
+        {
+            if (_PR_FILEDESC_OPEN == bottomFD->secret->state)
+            {
+                if (GetState(bottomFD, &readReady, &writeReady, &exceptReady))
+                {
+                    if (readReady)
+                    {
+                        if (in_flags_read & PR_POLL_READ)
+                            pd->out_flags |= PR_POLL_READ;
+                        if (in_flags_write & PR_POLL_READ)
+                            pd->out_flags |= PR_POLL_WRITE;
+                    }
+                    if (writeReady)
+                    {
+                        if (in_flags_read & PR_POLL_WRITE)
+                            pd->out_flags |= PR_POLL_READ;
+                        if (in_flags_write & PR_POLL_WRITE)
+                            pd->out_flags |= PR_POLL_WRITE;
+                    }
+                    if (exceptReady && (pd->in_flags & PR_POLL_EXCEPT))
+                    {
+                        pd->out_flags |= PR_POLL_EXCEPT;
+                    }
+                }
+                if (0 != pd->out_flags) ready++;
+            }
+            else    /* bad state */
+            {
+                ready += 1;  /* this will cause an abrupt return */
+                pd->out_flags = PR_POLL_NVAL;  /* bogii */
+            }
+        }
+    }
+
+    return ready;
+}
+
+
+// see how many of the poll descriptors are ready
+static PRInt32 CountReadyPollDescs(PRPollDesc *pds, PRIntn npds)
+{
+    PRInt32 ready = 0;
+    PRPollDesc *pd, *epd;
+    
+    for (pd = pds, epd = pd + npds; pd < epd; pd++)
+    {
+        if (pd->out_flags)
+            ready ++;
+    }
+
+    return ready;
+}
+
+// set or clear the poll thread on the poll descriptors
+static void SetDescPollThread(PRPollDesc *pds, PRIntn npds, PRThread* thread)
+{
+    PRInt32     ready = 0;
+    PRPollDesc *pd, *epd;
+
+    for (pd = pds, epd = pd + npds; pd < epd; pd++)
+    {   
+        if (pd->fd)
+        { 
+            PRFileDesc *bottomFD = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+            if (bottomFD && (_PR_FILEDESC_OPEN == bottomFD->secret->state))
+            {
+                if (pd->in_flags & PR_POLL_READ) {
+                    PR_ASSERT(thread == NULL || bottomFD->secret->md.read.thread == NULL);
+                    bottomFD->secret->md.read.thread = thread;
+                }
+
+                if (pd->in_flags & PR_POLL_WRITE) {
+                    // it's possible for the writing thread to be non-null during
+                    // a non-blocking connect, so we assert that we're on
+                    // the same thread, or the thread is null.
+                    // Note that it's strictly possible for the connect and poll
+                    // to be on different threads, so ideally we need to assert
+                    // that if md.write.thread is non-null, there is a non-blocking
+                    // connect in progress.
+                    PR_ASSERT(thread == NULL ||
+                        (bottomFD->secret->md.write.thread == NULL ||
+                         bottomFD->secret->md.write.thread == thread));
+                    bottomFD->secret->md.write.thread = thread;
+                }
+            }
+        }
+    }
+}
+
+
+#define DESCRIPTOR_FLAGS_ARRAY_SIZE     32
+
+PRInt32 _MD_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    PRInt16     readFlagsArray[DESCRIPTOR_FLAGS_ARRAY_SIZE];
+    PRInt16     writeFlagsArray[DESCRIPTOR_FLAGS_ARRAY_SIZE];
+    
+    PRInt16     *readFlags  = readFlagsArray;
+    PRInt16     *writeFlags = writeFlagsArray;
+
+    PRInt16     *ioFlags = NULL;
+    
+    PRThread    *thread = _PR_MD_CURRENT_THREAD();
+    PRInt32     ready;
+    
+    if (npds > DESCRIPTOR_FLAGS_ARRAY_SIZE)
+    {
+        // we allocate a single double-size array. The first half is used
+        // for read flags, and the second half for write flags.
+        ioFlags = (PRInt16*)PR_Malloc(sizeof(PRInt16) * npds * 2);
+        if (!ioFlags)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return -1;
+        }
+        
+        readFlags = ioFlags;
+        writeFlags = &ioFlags[npds];
+    }
+
+    // we have to be outside the lock when calling this, since
+    // it can call arbitrary user code (including other socket
+    // entry points)
+    ready = CheckPollDescMethods(pds, npds, readFlags, writeFlags);
+
+    if (!ready && timeout != PR_INTERVAL_NO_WAIT) {
+        intn        is;
+        
+
+        _PR_INTSOFF(is);
+        PR_Lock(thread->md.asyncIOLock);
+        PrepareForAsyncCompletion(thread, 0);
+
+        SetDescPollThread(pds, npds, thread);
+
+        (void)CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);
+
+        PR_Unlock(thread->md.asyncIOLock);
+        _PR_FAST_INTSON(is);
+
+        ready = CountReadyPollDescs(pds, npds);
+
+        if (ready == 0) {
+            WaitOnThisThread(thread, timeout);
+
+            // since we may have been woken by a pollable event firing,
+            // we have to check both poll methods and endpoints.
+            (void)CheckPollDescMethods(pds, npds, readFlags, writeFlags);
+            ready = CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);
+        }
+        
+        thread->io_pending = PR_FALSE;
+        SetDescPollThread(pds, npds, NULL);
+    }
+    else {
+        ready = CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);
+    }
+
+    if (readFlags != readFlagsArray)
+        PR_Free(ioFlags);
+    
+    return ready;
+}
+
+
+void _MD_initfiledesc(PRFileDesc *fd)
+{
+	// Allocate a PR_Lock to arbitrate miscellaneous OT calls for this endpoint between threads
+	// We presume that only one thread will be making Read calls (Recv/Accept) and that only
+	// one thread will be making Write calls (Send/Connect) on the endpoint at a time.
+	if (fd->methods->file_type == PR_DESC_SOCKET_TCP ||
+		fd->methods->file_type == PR_DESC_SOCKET_UDP )
+	{
+		PR_ASSERT(fd->secret->md.miscLock == NULL);
+		fd->secret->md.miscLock = PR_NewLock();
+		PR_ASSERT(fd->secret->md.miscLock != NULL);
+		fd->secret->md.orderlyDisconnect = PR_FALSE;
+		fd->secret->md.readReady = PR_FALSE;		// let's not presume we have data ready to read
+		fd->secret->md.writeReady = PR_TRUE;		// let's presume we can write unless we hear otherwise
+		fd->secret->md.exceptReady = PR_FALSE;
+	}
+}
+
+
+void _MD_freefiledesc(PRFileDesc *fd)
+{
+	if (fd->secret->md.miscLock)
+	{
+		PR_ASSERT(fd->methods->file_type == PR_DESC_SOCKET_TCP || fd->methods->file_type == PR_DESC_SOCKET_UDP);
+		PR_DestroyLock(fd->secret->md.miscLock);
+		fd->secret->md.miscLock = NULL;
+	} else {
+		PR_ASSERT(fd->methods->file_type != PR_DESC_SOCKET_TCP && PR_DESC_SOCKET_TCP != PR_DESC_SOCKET_UDP);
+	}
+}
+
+// _MD_makenonblock is also used for sockets meant to be used for blocking I/O,
+// in order to install the notifier routine for async completion.
+void _MD_makenonblock(PRFileDesc *fd)
+{
+	// We simulate non-blocking mode using async mode rather
+	// than put the endpoint in non-blocking mode.
+	// We need to install the PRFileDesc as the contextPtr for the NotifierRoutine, but it
+	// didn't exist at the time the endpoint was created.  It does now though...
+	ProviderRef	endpointRef = (ProviderRef)fd->secret->md.osfd;
+	OSStatus	err;
+	
+	// Install fd->secret as the contextPtr for the Notifier function associated with this 
+	// endpoint. We use this instead of the fd itself because:
+	//            (a) in cases where you import I/O layers, the containing 
+	//                fd changes, but the secret structure does not;
+	//            (b) the notifier func refers only to the secret data structure
+	//                anyway.
+	err = OTInstallNotifier(endpointRef, NotifierRoutineUPP, fd->secret);
+	PR_ASSERT(err == kOTNoError);
+	
+	// Now that we have a NotifierRoutine installed, we can make the endpoint asynchronous
+	err = OTSetAsynchronous(endpointRef);
+	PR_ASSERT(err == kOTNoError);
+}
+
+
+void _MD_initfdinheritable(PRFileDesc *fd, PRBool imported)
+{
+	/* XXX this function needs to be implemented */
+	fd->secret->inheritable = _PR_TRI_UNKNOWN;
+}
+
+
+void _MD_queryfdinheritable(PRFileDesc *fd)
+{
+	/* XXX this function needs to be implemented */
+	PR_ASSERT(0);
+}
+
+
+PR_IMPLEMENT(PRInt32) _MD_shutdown(PRFileDesc *fd, PRIntn how)
+{
+#pragma unused (fd, how)
+
+/* Just succeed silently!!! */
+return (0);
+}
+
+
+PR_IMPLEMENT(PRStatus) 
+_MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+	EndpointRef ep = (EndpointRef) fd->secret->md.osfd;
+	InetAddress inetAddr;
+	TBind peerAddr;
+	OSErr err;
+	
+	if (*addrlen < sizeof(InetAddress)) {
+
+		err = (OSErr) kEINVALErr;
+		goto ErrorExit;
+	}
+
+    peerAddr.addr.maxlen = sizeof(InetAddress);
+    peerAddr.addr.len = 0;
+    peerAddr.addr.buf = (UInt8*) &inetAddr;
+    peerAddr.qlen = 0;
+
+    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    
+	fd->secret->md.misc.thread = me; // tell notifier routine what to wake up
+
+	err = OTGetProtAddress(ep, NULL, &peerAddr);
+	
+    if (err != kOTNoError)
+        goto ErrorExit;
+
+    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+
+    err = me->md.osErrCode;
+    if ((err == kOTNoError) && (peerAddr.addr.len < sizeof(InetAddress)))
+    	err = kEBADFErr; // we don't understand the address we got
+    if (err != kOTNoError)
+    	goto ErrorExit;
+    	
+    // Translate the OT peer information into an NSPR address.
+    addr->inet.family = AF_INET;
+    addr->inet.port = (PRUint16) inetAddr.fPort;
+    addr->inet.ip = (PRUint32) inetAddr.fHost;
+    
+    *addrlen = PR_NETADDR_SIZE(addr); // return the amount of data obtained
+	return PR_SUCCESS;
+
+ErrorExit:
+    macsock_map_error(err);
+    return PR_FAILURE;
+}
+
+
+PR_IMPLEMENT(unsigned long) inet_addr(const char *cp)
+{
+    OSStatus err;
+    InetHost host;    
+
+    _MD_FinishInitNetAccess();
+
+    err = OTInetStringToHost((char*) cp, &host);
+    if (err != kOTNoError)
+        return -1;
+    
+    return host;
+}
+
+
+static char *sAliases[1] = {NULL};
+static struct hostent sHostEnt = {NULL, &sAliases[0], AF_INET, sizeof (long), NULL};
+static InetHostInfo sHostInfo;
+static InetHost *sAddresses[kMaxHostAddrs+1];
+
+
+PR_IMPLEMENT(struct hostent *) gethostbyname(const char * name)
+{
+    OSStatus err;
+    PRUint32 index;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    	_MD_FinishInitNetAccess();
+
+    me->io_pending       = PR_TRUE;
+    me->io_fd            = NULL;
+    me->md.osErrCode     = noErr;
+	
+	PR_Lock(dnsContext.lock);	// so we can safely store our thread ptr in dnsContext
+	dnsContext.thread = me;		// so we know what thread to wake up when OTInetStringToAddress completes
+
+    err = OTInetStringToAddress(dnsContext.serviceRef, (char *)name, &sHostInfo);
+    if (err != kOTNoError) {
+        me->io_pending = PR_FALSE;
+        me->md.osErrCode = err;
+        goto ErrorExit;
+    }
+
+    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);
+	PR_Unlock(dnsContext.lock);
+
+    if (me->md.osErrCode != kOTNoError)
+        goto ErrorExit;
+
+    sHostEnt.h_name = sHostInfo.name;
+    for (index=0; index<kMaxHostAddrs && sHostInfo.addrs[index] != NULL; index++)
+        sAddresses[index] = &sHostInfo.addrs[index];
+    sAddresses[index] = NULL;    
+    sHostEnt.h_addr_list = (char **)sAddresses;
+
+    return (&sHostEnt);
+
+ErrorExit:
+    return NULL;
+}
+
+
+PR_IMPLEMENT(struct hostent *) gethostbyaddr(const void *addr, int addrlen, int type)
+{
+    PR_ASSERT(type == AF_INET);
+    PR_ASSERT(addrlen == sizeof(struct in_addr));
+
+    	_MD_FinishInitNetAccess();
+
+    OTInetHostToString((InetHost)addr, sHostInfo.name);
+    
+    return (gethostbyname(sHostInfo.name));
+}
+
+
+PR_IMPLEMENT(char *) inet_ntoa(struct in_addr addr)
+{
+    _MD_FinishInitNetAccess();
+
+    OTInetHostToString((InetHost)addr.s_addr, sHostInfo.name);
+    
+    return sHostInfo.name;
+}
+
+
+PRStatus _MD_gethostname(char *name, int namelen)
+{
+    OSStatus err;
+    InetInterfaceInfo info;
+
+    _MD_FinishInitNetAccess();
+
+    /*
+     *    On a Macintosh, we don't have the concept of a local host name.
+     *    We do though have an IP address & everyone should be happy with
+     *     a string version of that for a name.
+     *    The alternative here is to ping a local DNS for our name, they
+     *    will often know it.  This is the cheap, easiest, and safest way out.
+     */
+
+    /* Make sure the string is as long as the longest possible address */
+    if (namelen < strlen("123.123.123.123")) {
+        err = kEINVALErr;
+        goto ErrorExit;
+    }
+
+    err = OTInetGetInterfaceInfo(&info, kDefaultInetInterface);
+    if (err != kOTNoError)
+        goto ErrorExit;
+    
+    OTInetHostToString(info.fAddress, name);
+    
+    return PR_SUCCESS;
+
+ErrorExit:
+    macsock_map_error(err);
+    return PR_FAILURE;
+}
+
+
+#define kIPName        "ip"
+static struct protoent sIPProto = {kIPName, NULL, INET_IP};
+static struct protoent sTCPProto = {kTCPName, NULL, INET_TCP};
+static struct protoent sUDPProto = {kUDPName, NULL, INET_UDP};
+
+PR_IMPLEMENT(struct protoent *) getprotobyname(const char * name)
+{
+    if (strcmp(name, kIPName) == 0)
+        return (&sIPProto);
+        
+    if (strcmp(name, kTCPName) == 0)
+        return (&sTCPProto);
+        
+    if (strcmp(name, kUDPName) == 0)
+        return (&sUDPProto);
+        
+ErrorExit:
+    macsock_map_error(kEINVALErr);
+    return NULL;
+}
+
+
+PR_IMPLEMENT(struct protoent *) getprotobynumber(int number)
+{
+    if (number == INET_IP)
+        return (&sIPProto);
+        
+    if (number == INET_TCP)
+        return (&sTCPProto);
+        
+    if (number == INET_UDP)
+        return (&sUDPProto);
+        
+ErrorExit:
+    macsock_map_error(kEINVALErr);
+    return NULL;
+}
+
+
+int _MD_mac_get_nonblocking_connect_error(PRFileDesc* fd)
+{
+    EndpointRef endpoint = (EndpointRef)fd->secret->md.osfd;
+    OTResult    resultOT = OTGetEndpointState(endpoint);
+
+    switch (resultOT)    {
+        case T_OUTCON:
+            macsock_map_error(EINPROGRESS);
+            return -1;
+            
+        case T_DATAXFER:
+            return 0;
+            
+        case T_IDLE:
+            macsock_map_error(fd->secret->md.disconnectError);
+            fd->secret->md.disconnectError = 0;
+            return -1;
+
+        case T_INREL:
+            macsock_map_error(ENOTCONN);
+            return -1;
+
+        default:
+            PR_ASSERT(0);
+            return -1;
+    }
+
+    return -1;      // not reached
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macthr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/macthr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,721 @@
+/* -*- 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 <string.h>
+
+#include <MacTypes.h>
+#include <Timer.h>
+#include <OSUtils.h>
+#include <Math64.h>
+#include <LowMem.h>
+#include <Multiprocessing.h>
+#include <Gestalt.h>
+
+#include "mdcriticalregion.h"
+
+TimerUPP	gTimerCallbackUPP	= NULL;
+PRThread *	gPrimaryThread		= NULL;
+
+ProcessSerialNumber		gApplicationProcess;
+
+PR_IMPLEMENT(PRThread *) PR_GetPrimaryThread()
+{
+	return gPrimaryThread;
+}
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark CREATING MACINTOSH THREAD STACKS
+
+#if defined(GC_LEAK_DETECTOR)
+extern void* GC_malloc_atomic(PRUint32 size);
+#endif
+
+/*
+**	Allocate a new memory segment.  We allocate it from our figment heap.  Currently,
+**	it is being used for per thread stack space.
+**	
+**	Return the segment's access rights and size.  vaddr is used on Unix platforms to
+**	map an existing address for the segment.
+*/
+PRStatus _MD_AllocSegment(PRSegment *seg, PRUint32 size, void *vaddr)
+{
+	PR_ASSERT(seg != 0);
+	PR_ASSERT(size != 0);
+	PR_ASSERT(vaddr == 0);
+
+	/*	
+	** Take the actual memory for the segment out of our Figment heap.
+	*/
+
+#if defined(GC_LEAK_DETECTOR)
+	seg->vaddr = (char *)GC_malloc_atomic(size);
+#else
+	seg->vaddr = (char *)malloc(size);
+#endif
+
+	if (seg->vaddr == NULL) {
+
+#if DEBUG
+		DebugStr("\p_MD_AllocSegment failed.");
+#endif
+
+		return PR_FAILURE;
+	}
+
+	seg->size = size;	
+
+	return PR_SUCCESS;
+}
+
+
+/*
+**	Free previously allocated memory segment.
+*/
+void _MD_FreeSegment(PRSegment *seg)
+{
+	PR_ASSERT((seg->flags & _PR_SEG_VM) == 0);
+
+	if (seg->vaddr != NULL)
+		free(seg->vaddr);
+}
+
+
+/*
+**	The thread's stack has been allocated and its fields are already properly filled
+**	in by PR.  Perform any debugging related initialization here.
+**
+**	Put a recognizable pattern so that we can find it from Macsbug.
+**	Put a cookie at the top of the stack so that we can find it from Macsbug.
+*/
+void _MD_InitStack(PRThreadStack *ts, int redZoneBytes)
+	{
+#pragma unused (redZoneBytes)
+#if DEVELOPER_DEBUG
+	//	Put a cookie at the top of the stack so that we can find 
+	//	it from Macsbug.
+	
+	memset(ts->allocBase, 0xDC, ts->stackSize);
+	
+	((UInt32 *)ts->stackTop)[-1] = 0xBEEFCAFE;
+	((UInt32 *)ts->stackTop)[-2] = (UInt32)gPrimaryThread;
+	((UInt32 *)ts->stackTop)[-3] = (UInt32)(ts);
+	((UInt32 *)ts->stackBottom)[0] = 0xCAFEBEEF;
+#else
+#pragma unused (ts)
+#endif	
+	}
+
+extern void _MD_ClearStack(PRThreadStack *ts)
+	{
+#if DEVELOPER_DEBUG
+	//	Clear out our cookies. 
+	
+	memset(ts->allocBase, 0xEF, ts->allocSize);
+	((UInt32 *)ts->stackTop)[-1] = 0;
+	((UInt32 *)ts->stackTop)[-2] = 0;
+	((UInt32 *)ts->stackTop)[-3] = 0;
+	((UInt32 *)ts->stackBottom)[0] = 0;
+#else
+#pragma unused (ts)
+#endif
+	}
+
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark TIME MANAGER-BASED CLOCK
+
+// On Mac OS X, it's possible for the application to spend lots of time
+// in WaitNextEvent, yielding to other applications. Since NSPR threads are
+// cooperative here, this means that NSPR threads will also get very little
+// time to run. To kick ourselves out of a WaitNextEvent call when we have
+// determined that it's time to schedule another thread, the Timer Task
+// (which fires every 8ms, even when other apps have the CPU) calls WakeUpProcess.
+// We only want to do this on Mac OS X; the gTimeManagerTaskDoesWUP variable
+// indicates when we're running on that OS.
+//
+// Note that the TimerCallback makes use of gApplicationProcess. We need to
+// have set this up before the first possible run of the timer task; we do
+// so in _MD_EarlyInit().
+static Boolean  gTimeManagerTaskDoesWUP;
+
+static TMTask   gTimeManagerTaskElem;
+
+extern void _MD_IOInterrupt(void);
+_PRInterruptTable _pr_interruptTable[] = {
+    { "clock", _PR_MISSED_CLOCK, _PR_ClockInterrupt, },
+    { "i/o", _PR_MISSED_IO, _MD_IOInterrupt, },
+    { 0 }
+};
+
+#define kMacTimerInMiliSecs 8L
+
+pascal void TimerCallback(TMTaskPtr tmTaskPtr)
+{
+    _PRCPU *cpu = _PR_MD_CURRENT_CPU();
+    PRIntn is;
+
+    if (_PR_MD_GET_INTSOFF()) {
+        cpu->u.missed[cpu->where] |= _PR_MISSED_CLOCK;
+        PrimeTime((QElemPtr)tmTaskPtr, kMacTimerInMiliSecs);
+        return;
+    }
+
+    _PR_INTSOFF(is);
+
+    //	And tell nspr that a clock interrupt occured.
+    _PR_ClockInterrupt();
+	
+    if ((_PR_RUNQREADYMASK(cpu)) >> ((_PR_MD_CURRENT_THREAD()->priority))) {
+        if (gTimeManagerTaskDoesWUP) {
+            // We only want to call WakeUpProcess if we know that NSPR has managed to switch threads
+            // since the last call, otherwise we end up spewing out WakeUpProcess() calls while the
+            // application is blocking somewhere. This can interfere with events loops other than
+            // our own (see bug 158927).
+            if (UnsignedWideToUInt64(cpu->md.lastThreadSwitch) > UnsignedWideToUInt64(cpu->md.lastWakeUpProcess))
+            {
+                WakeUpProcess(&gApplicationProcess);
+                cpu->md.lastWakeUpProcess = UpTime();
+            }
+        }
+        _PR_SET_RESCHED_FLAG();
+	}
+	
+    _PR_FAST_INTSON(is);
+
+    //	Reset the clock timer so that we fire again.
+    PrimeTime((QElemPtr)tmTaskPtr, kMacTimerInMiliSecs);
+}
+
+
+void _MD_StartInterrupts(void)
+{
+	gPrimaryThread = _PR_MD_CURRENT_THREAD();
+
+	gTimeManagerTaskDoesWUP = RunningOnOSX();
+
+	if ( !gTimerCallbackUPP )
+		gTimerCallbackUPP = NewTimerUPP(TimerCallback);
+
+	//	Fill in the Time Manager queue element
+	
+	gTimeManagerTaskElem.tmAddr = (TimerUPP)gTimerCallbackUPP;
+	gTimeManagerTaskElem.tmCount = 0;
+	gTimeManagerTaskElem.tmWakeUp = 0;
+	gTimeManagerTaskElem.tmReserved = 0;
+
+	//	Make sure that our time manager task is ready to go.
+	InsTime((QElemPtr)&gTimeManagerTaskElem);
+	
+	PrimeTime((QElemPtr)&gTimeManagerTaskElem, kMacTimerInMiliSecs);
+}
+
+void _MD_StopInterrupts(void)
+{
+	if (gTimeManagerTaskElem.tmAddr != NULL) {
+		RmvTime((QElemPtr)&gTimeManagerTaskElem);
+		gTimeManagerTaskElem.tmAddr = NULL;
+	}
+}
+
+
+#define MAX_PAUSE_TIMEOUT_MS    500
+
+void _MD_PauseCPU(PRIntervalTime timeout)
+{
+    if (timeout != PR_INTERVAL_NO_WAIT)
+    {
+        // There is a race condition entering the critical section
+        // in AsyncIOCompletion (and probably elsewhere) that can
+        // causes deadlock for the duration of this timeout. To
+        // work around this, use a max 500ms timeout for now.
+        // See bug 99561 for details.
+        if (PR_IntervalToMilliseconds(timeout) > MAX_PAUSE_TIMEOUT_MS)
+            timeout = PR_MillisecondsToInterval(MAX_PAUSE_TIMEOUT_MS);
+
+        WaitOnIdleSemaphore(timeout);
+        (void) _MD_IOInterrupt();
+    }
+}
+
+void _MD_InitRunningCPU(_PRCPU* cpu)
+{
+    cpu->md.trackScheduling = RunningOnOSX();
+    if (cpu->md.trackScheduling) {
+        AbsoluteTime    zeroTime = {0, 0};
+        cpu->md.lastThreadSwitch = UpTime();
+        cpu->md.lastWakeUpProcess = zeroTime;
+    }
+}
+
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark THREAD SUPPORT FUNCTIONS
+
+#include <OpenTransport.h> /* for error codes */
+
+PRStatus _MD_InitThread(PRThread *thread)
+{
+	thread->md.asyncIOLock = PR_NewLock();
+	PR_ASSERT(thread->md.asyncIOLock != NULL);
+	thread->md.asyncIOCVar = PR_NewCondVar(thread->md.asyncIOLock);
+	PR_ASSERT(thread->md.asyncIOCVar != NULL);
+
+	if (thread->md.asyncIOLock == NULL || thread->md.asyncIOCVar == NULL)
+		return PR_FAILURE;
+	else
+		return PR_SUCCESS;
+}
+
+PRStatus _MD_wait(PRThread *thread, PRIntervalTime timeout)
+{
+#pragma unused (timeout)
+
+	_MD_SWITCH_CONTEXT(thread);
+	return PR_SUCCESS;
+}
+
+
+void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout)
+{
+    intn is;
+    PRIntervalTime timein = PR_IntervalNow();
+	PRStatus status = PR_SUCCESS;
+
+    // Turn interrupts off to avoid a race over lock ownership with the callback
+    // (which can fire at any time). Interrupts may stay off until we leave
+    // this function, or another NSPR thread turns them back on. They certainly
+    // stay off until PR_WaitCondVar() relinquishes the asyncIOLock lock, which
+    // is what we care about.
+	_PR_INTSOFF(is);
+	PR_Lock(thread->md.asyncIOLock);
+	if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+	    while ((thread->io_pending) && (status == PR_SUCCESS))
+	        status = PR_WaitCondVar(thread->md.asyncIOCVar, PR_INTERVAL_NO_TIMEOUT);
+	} else {
+	    while ((thread->io_pending) && ((PRIntervalTime)(PR_IntervalNow() - timein) < timeout) && (status == PR_SUCCESS))
+	        status = PR_WaitCondVar(thread->md.asyncIOCVar, timeout);
+	}
+	if ((status == PR_FAILURE) && (PR_GetError() == PR_PENDING_INTERRUPT_ERROR)) {
+		thread->md.osErrCode = kEINTRErr;
+	} else if (thread->io_pending) {
+		thread->md.osErrCode = kETIMEDOUTErr;
+		PR_SetError(PR_IO_TIMEOUT_ERROR, kETIMEDOUTErr);
+	}
+
+	thread->io_pending = PR_FALSE;
+	PR_Unlock(thread->md.asyncIOLock);
+	_PR_FAST_INTSON(is);
+}
+
+
+void DoneWaitingOnThisThread(PRThread *thread)
+{
+    intn is;
+
+    PR_ASSERT(thread->md.asyncIOLock->owner == NULL);
+
+	// DoneWaitingOnThisThread() is called from OT notifiers and async file I/O
+	// callbacks that can run at "interrupt" time (Classic Mac OS) or on pthreads
+	// that may run concurrently with the main threads (Mac OS X). They can thus
+	// be called when any NSPR thread is running, or even while NSPR is in a
+	// thread context switch. It is therefore vital that we can guarantee to
+	// be able to get the asyncIOLock without blocking (thus avoiding code
+	// that makes assumptions about the current NSPR thread etc). To achieve
+	// this, we use NSPR interrrupts as a semaphore on the lock; all code 
+	// that grabs the lock also disables interrupts for the time the lock
+	// is held. Callers of DoneWaitingOnThisThread() thus have to check whether
+	// interrupts are already off, and, if so, simply set the missed_IO flag on
+	// the CPU rather than calling this function.
+	
+	_PR_INTSOFF(is);
+	PR_Lock(thread->md.asyncIOLock);
+	thread->io_pending = PR_FALSE;
+	/* let the waiting thread know that async IO completed */
+	PR_NotifyCondVar(thread->md.asyncIOCVar);
+	PR_Unlock(thread->md.asyncIOLock);
+	_PR_FAST_INTSON(is);
+}
+
+
+PR_IMPLEMENT(void) PR_Mac_WaitForAsyncNotify(PRIntervalTime timeout)
+{
+    intn is;
+    PRIntervalTime timein = PR_IntervalNow();
+	PRStatus status = PR_SUCCESS;
+    PRThread *thread = _PR_MD_CURRENT_THREAD();
+
+    // See commments in WaitOnThisThread()
+	_PR_INTSOFF(is);
+	PR_Lock(thread->md.asyncIOLock);
+	if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+	    while ((!thread->md.asyncNotifyPending) && (status == PR_SUCCESS))
+	        status = PR_WaitCondVar(thread->md.asyncIOCVar, PR_INTERVAL_NO_TIMEOUT);
+	} else {
+	    while ((!thread->md.asyncNotifyPending) && ((PRIntervalTime)(PR_IntervalNow() - timein) < timeout) && (status == PR_SUCCESS))
+	        status = PR_WaitCondVar(thread->md.asyncIOCVar, timeout);
+	}
+	if ((status == PR_FAILURE) && (PR_GetError() == PR_PENDING_INTERRUPT_ERROR)) {
+		thread->md.osErrCode = kEINTRErr;
+	} else if (!thread->md.asyncNotifyPending) {
+		thread->md.osErrCode = kETIMEDOUTErr;
+		PR_SetError(PR_IO_TIMEOUT_ERROR, kETIMEDOUTErr);
+	}
+	thread->md.asyncNotifyPending = PR_FALSE;
+	PR_Unlock(thread->md.asyncIOLock);
+	_PR_FAST_INTSON(is);
+}
+
+
+void AsyncNotify(PRThread *thread)
+{
+    intn is;
+	
+    PR_ASSERT(thread->md.asyncIOLock->owner == NULL);
+
+    // See commments in DoneWaitingOnThisThread()
+	_PR_INTSOFF(is);
+	PR_Lock(thread->md.asyncIOLock);
+	thread->md.asyncNotifyPending = PR_TRUE;
+	/* let the waiting thread know that async IO completed */
+	PR_NotifyCondVar(thread->md.asyncIOCVar);
+	PR_Unlock(thread->md.asyncIOLock);
+	_PR_FAST_INTSON(is);
+}
+
+
+PR_IMPLEMENT(void) PR_Mac_PostAsyncNotify(PRThread *thread)
+{
+	_PRCPU *  cpu = _PR_MD_CURRENT_CPU();
+	
+	if (_PR_MD_GET_INTSOFF()) {
+		thread->md.missedAsyncNotify = PR_TRUE;
+		cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+	} else {
+		AsyncNotify(thread);
+	}
+}
+
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark PROCESS SUPPORT FUNCTIONS
+
+PRProcess * _MD_CreateProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+#pragma unused (path, argv, envp, attr)
+
+	PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
+	return NULL;
+}
+
+PRStatus _MD_DetachProcess(PRProcess *process)
+{
+#pragma unused (process)
+
+	PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
+	return PR_FAILURE;
+}
+
+PRStatus _MD_WaitProcess(PRProcess *process, PRInt32 *exitCode)
+{
+#pragma unused (process, exitCode)
+
+	PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
+	return PR_FAILURE;
+}
+
+PRStatus _MD_KillProcess(PRProcess *process)
+{
+#pragma unused (process)
+
+	PR_SetError(PR_NOT_IMPLEMENTED_ERROR, unimpErr);
+	return PR_FAILURE;
+}
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark ATOMIC OPERATIONS
+
+#ifdef _PR_HAVE_ATOMIC_OPS
+PRInt32
+_MD_AtomicSet(PRInt32 *val, PRInt32 newval)
+{
+    PRInt32 rv;
+    do  {
+        rv = *val;
+    } while (!OTCompareAndSwap32(rv, newval, (UInt32*)val));
+
+    return rv;
+}
+
+#endif // _PR_HAVE_ATOMIC_OPS
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark INTERRUPT SUPPORT
+
+#if TARGET_CARBON
+
+/*
+     This critical region support is required for Mac NSPR to work correctly on dual CPU
+     machines on Mac OS X. This note explains why.
+
+     NSPR uses a timer task, and has callbacks for async file I/O and Open Transport
+     whose runtime behaviour differs depending on environment. On "Classic" Mac OS
+     these run at "interrupt" time (OS-level interrupts, that is, not NSPR interrupts),
+     and can thus preempt other code, but they always run to completion.
+
+     On Mac OS X, these are all emulated using MP tasks, which sit atop pthreads. Thus,
+     they can be preempted at any time (and not necessarily run to completion), and can
+     also run *concurrently* with eachother, and with application code, on multiple
+     CPU machines. Note that all NSPR threads are emulated, and all run on the main
+     application MP task.
+
+     We thus have to use MP critical sections to protect data that is shared between
+     the various callbacks and the main MP thread. It so happens that NSPR has this
+     concept of software interrupts, and making interrupt-off times be critical
+     sections works.
+
+*/
+
+
+/*  
+    Whether to use critical regions. True if running on Mac OS X and later
+*/
+
+PRBool  gUseCriticalRegions;
+
+/*
+    Count of the number of times we've entered the critical region.
+    We need this because ENTER_CRITICAL_REGION() will *not* block when
+    called from different NSPR threads (which all run on one MP thread),
+    and we need to ensure that when code turns interrupts back on (by
+    settings _pr_intsOff to 0) we exit the critical section enough times
+    to leave it.
+*/
+
+PRInt32 gCriticalRegionEntryCount;
+
+
+void _MD_SetIntsOff(PRInt32 ints)
+{
+    ENTER_CRITICAL_REGION();
+    gCriticalRegionEntryCount ++;
+    
+    _pr_intsOff = ints;
+    
+    if (!ints)
+    {
+        PRInt32     i = gCriticalRegionEntryCount;
+
+        gCriticalRegionEntryCount = 0;
+        for ( ;i > 0; i --) {
+            LEAVE_CRITICAL_REGION();
+        }
+    }
+}
+
+
+#endif /* TARGET_CARBON */
+
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark CRITICAL REGION SUPPORT
+
+
+static PRBool RunningOnOSX()
+{
+    long    systemVersion;
+    OSErr   err = Gestalt(gestaltSystemVersion, &systemVersion);
+    return (err == noErr) && (systemVersion >= 0x00001000);
+}
+
+
+#if MAC_CRITICAL_REGIONS
+
+MDCriticalRegionID  gCriticalRegion;
+
+void InitCriticalRegion()
+{
+    OSStatus    err;    
+    
+    // we only need to do critical region stuff on Mac OS X    
+    gUseCriticalRegions = RunningOnOSX();
+    if (!gUseCriticalRegions) return;
+    
+    err = MD_CriticalRegionCreate(&gCriticalRegion);
+    PR_ASSERT(err == noErr);
+}
+
+void TermCriticalRegion()
+{
+    OSStatus    err;    
+
+    if (!gUseCriticalRegions) return;
+
+    err = MD_CriticalRegionDelete(gCriticalRegion);
+    PR_ASSERT(err == noErr);
+}
+
+
+void EnterCritialRegion()
+{
+    OSStatus    err;
+    
+    if (!gUseCriticalRegions) return;
+
+    PR_ASSERT(gCriticalRegion != kInvalidID);
+    
+    /* Change to a non-infinite timeout for debugging purposes */
+    err = MD_CriticalRegionEnter(gCriticalRegion, kDurationForever /* 10000 * kDurationMillisecond */ );
+    PR_ASSERT(err == noErr);
+}
+
+void LeaveCritialRegion()
+{
+    OSStatus    err;    
+
+    if (!gUseCriticalRegions) return;
+
+    PR_ASSERT(gCriticalRegion != kInvalidID);
+
+    err = MD_CriticalRegionExit(gCriticalRegion);
+    PR_ASSERT(err == noErr);
+}
+
+
+#endif // MAC_CRITICAL_REGIONS
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark IDLE SEMAPHORE SUPPORT
+
+/*
+     Since the WaitNextEvent() in _MD_PauseCPU() is causing all sorts of
+     headache under Mac OS X we're going to switch to MPWaitOnSemaphore()
+     which should do what we want
+*/
+
+#if TARGET_CARBON
+PRBool					gUseIdleSemaphore = PR_FALSE;
+MPSemaphoreID			gIdleSemaphore = NULL;
+#endif
+
+void InitIdleSemaphore()
+{
+    // we only need to do idle semaphore stuff on Mac OS X
+#if TARGET_CARBON
+	gUseIdleSemaphore = RunningOnOSX();
+	if (gUseIdleSemaphore)
+	{
+		OSStatus  err = MPCreateSemaphore(1 /* max value */, 0 /* initial value */, &gIdleSemaphore);
+		PR_ASSERT(err == noErr);
+	}
+#endif
+}
+
+void TermIdleSemaphore()
+{
+#if TARGET_CARBON
+	if (gUseIdleSemaphore)
+	{
+		OSStatus  err = MPDeleteSemaphore(gIdleSemaphore);
+		PR_ASSERT(err == noErr);
+		gUseIdleSemaphore = NULL;
+	}
+#endif
+}
+
+
+void WaitOnIdleSemaphore(PRIntervalTime timeout)
+{
+#if TARGET_CARBON
+	if (gUseIdleSemaphore)
+	{
+		OSStatus  err = MPWaitOnSemaphore(gIdleSemaphore, kDurationMillisecond * PR_IntervalToMilliseconds(timeout));
+		PR_ASSERT(err == noErr);
+	}
+	else
+#endif
+	{
+		EventRecord   theEvent;
+		/*
+		** Calling WaitNextEvent() here is suboptimal. This routine should
+		** pause the process until IO or the timeout occur, yielding time to
+		** other processes on operating systems that require this (Mac OS classic).
+		** WaitNextEvent() may incur too much latency, and has other problems,
+		** such as the potential to drop suspend/resume events.
+		*/
+		(void)WaitNextEvent(nullEvent, &theEvent, 1, NULL);
+	}
+}
+
+
+void SignalIdleSemaphore()
+{
+#if TARGET_CARBON
+	if (gUseIdleSemaphore)
+	{
+		// often we won't be waiting on the semaphore here, so ignore any errors
+		(void)MPSignalSemaphore(gIdleSemaphore);
+	}
+	else
+#endif
+	{
+		WakeUpProcess(&gApplicationProcess);
+	}
+}
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mactime.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mactime.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,253 @@
+/* -*- 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 <OSUtils.h>
+#include <Timer.h>
+
+#include "primpl.h"
+
+#include "mactime.h"
+
+unsigned long gJanuaryFirst1970Seconds;
+
+/*
+ * The geographic location and time zone information of a Mac
+ * are stored in extended parameter RAM.  The ReadLocation
+ * produdure uses the geographic location record, MachineLocation,
+ * to read the geographic location and time zone information in
+ * extended parameter RAM.
+ *
+ * Because serial port and SLIP conflict with ReadXPram calls,
+ * we cache the call here.
+ *
+ * Caveat: this caching will give the wrong result if a session
+ * extend across the DST changeover time.
+ */
+
+static void MyReadLocation(MachineLocation *loc)
+{
+    static MachineLocation storedLoc;
+    static Boolean didReadLocation = false;
+    
+    if (!didReadLocation) {
+        ReadLocation(&storedLoc);
+        didReadLocation = true;
+    }
+    *loc = storedLoc;
+}
+
+static long GMTDelta(void)
+{
+    MachineLocation loc;
+    long gmtDelta;
+
+    MyReadLocation(&loc);
+    gmtDelta = loc.u.gmtDelta & 0x00ffffff;
+    if (gmtDelta & 0x00800000) {    /* test sign extend bit */
+        gmtDelta |= 0xff000000;
+    }
+    return gmtDelta;
+}
+
+void MacintoshInitializeTime(void)
+{
+    /*
+     * The NSPR epoch is midnight, Jan. 1, 1970 GMT.
+     *
+     * At midnight Jan. 1, 1970 GMT, the local time was
+     *     midnight Jan. 1, 1970 + GMTDelta().
+     *
+     * Midnight Jan. 1, 1970 is 86400 * (365 * (1970 - 1904) + 17)
+     *     = 2082844800 seconds since the Mac epoch.
+     * (There were 17 leap years from 1904 to 1970.)
+     *
+     * So the NSPR epoch is 2082844800 + GMTDelta() seconds since
+     * the Mac epoch.  Whew! :-)
+     */
+    gJanuaryFirst1970Seconds = 2082844800 + GMTDelta();
+}
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_Now --
+ *
+ *     Returns the current time in microseconds since the epoch.
+ *     The epoch is midnight January 1, 1970 GMT.
+ *     The implementation is machine dependent.  This is the Mac
+ *     Implementation.
+ *     Cf. time_t time(time_t *tp)
+ *
+ *-----------------------------------------------------------------------
+ */
+
+PRTime PR_Now(void)
+{
+    unsigned long currentTime;    /* unsigned 32-bit integer, ranging
+                                     from midnight Jan. 1, 1904 to 
+                                     6:28:15 AM Feb. 6, 2040 */
+    PRTime retVal;
+    int64  usecPerSec;
+
+    /*
+     * Get the current time expressed as the number of seconds
+     * elapsed since the Mac epoch, midnight, Jan. 1, 1904 (local time).
+     * On a Mac, current time accuracy is up to a second.
+     */
+    GetDateTime(&currentTime);
+
+    /*
+     * Express the current time relative to the NSPR epoch,
+     * midnight, Jan. 1, 1970 GMT.
+     *
+     * At midnight Jan. 1, 1970 GMT, the local time was
+     *     midnight Jan. 1, 1970 + GMTDelta().
+     *
+     * Midnight Jan. 1, 1970 is 86400 * (365 * (1970 - 1904) + 17)
+     *     = 2082844800 seconds since the Mac epoch.
+     * (There were 17 leap years from 1904 to 1970.)
+     *
+     * So the NSPR epoch is 2082844800 + GMTDelta() seconds since
+     * the Mac epoch.  Whew! :-)
+     */
+    currentTime = currentTime - 2082844800 - GMTDelta();
+
+    /* Convert seconds to microseconds */
+    LL_I2L(usecPerSec, PR_USEC_PER_SEC);
+    LL_I2L(retVal, currentTime);
+    LL_MUL(retVal, retVal, usecPerSec);
+
+    return retVal;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * PR_LocalTimeParameters --
+ * 
+ *     returns the time parameters for the local time zone
+ *
+ *     This is the machine-dependent implementation for Mac.
+ *
+ *     Caveat: On a Mac, we only know the GMT and DST offsets for
+ *     the current time, not for the time in question.
+ *     Mac has no support for DST handling.
+ *     DST changeover is all manually set by the user.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+PRTimeParameters PR_LocalTimeParameters(const PRExplodedTime *gmt)
+{
+#pragma unused (gmt)
+
+    PRTimeParameters retVal;
+    MachineLocation loc;
+
+    MyReadLocation(&loc);
+
+    /* 
+     * On a Mac, the GMT value is in seconds east of GMT.  For example,
+     * San Francisco is at -28,800 seconds (8 hours * 3600 seconds per hour)
+     * east of GMT.  The gmtDelta field is a 3-byte value contained in a
+     * long word, so you must take care to get it properly.
+     */
+
+    retVal.tp_gmt_offset = loc.u.gmtDelta & 0x00ffffff;
+    if (retVal.tp_gmt_offset & 0x00800000) {    /* test sign extend bit */
+	retVal.tp_gmt_offset |= 0xff000000;
+    }
+
+    /*
+     * The daylight saving time value, dlsDelta, is a signed byte
+     * value representing the offset for the hour field -- whether
+     * to add 1 hour, subtract 1 hour, or make no change at all.
+     */
+
+    if (loc.u.dlsDelta) {
+    	retVal.tp_gmt_offset -= 3600;
+    	retVal.tp_dst_offset = 3600;
+    } else {
+    	retVal.tp_dst_offset = 0;
+    }
+    return retVal;
+}
+
+PRIntervalTime _MD_GetInterval(void)
+{
+    PRIntervalTime retVal;
+    PRUint64 upTime, microtomilli;	
+
+    /*
+     * Use the Microseconds procedure to obtain the number of
+     * microseconds elapsed since system startup time.
+     */
+    Microseconds((UnsignedWide *)&upTime);
+    LL_I2L(microtomilli, PR_USEC_PER_MSEC);
+    LL_DIV(upTime, upTime, microtomilli);
+    LL_L2I(retVal, upTime);
+	
+    return retVal;
+}
+
+struct tm *Maclocaltime(const time_t * t)
+{
+	DateTimeRec dtr;
+	MachineLocation loc;
+	time_t macLocal = *t + gJanuaryFirst1970Seconds; /* GMT Mac */
+	static struct tm statictime;
+	static const short monthday[12] =
+		{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
+
+	SecondsToDate(macLocal, &dtr);
+	statictime.tm_sec = dtr.second;
+	statictime.tm_min = dtr.minute;
+	statictime.tm_hour = dtr.hour;
+	statictime.tm_mday = dtr.day;
+	statictime.tm_mon = dtr.month - 1;
+	statictime.tm_year = dtr.year - 1900;
+	statictime.tm_wday = dtr.dayOfWeek - 1;
+	statictime.tm_yday = monthday[statictime.tm_mon]
+		+ statictime.tm_mday - 1;
+	if (2 < statictime.tm_mon && !(statictime.tm_year & 3))
+		++statictime.tm_yday;
+	MyReadLocation(&loc);
+	statictime.tm_isdst = loc.u.dlsDelta;
+	return(&statictime);
+}
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mactime.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mactime.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,51 @@
+/* -*- 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 mactime_h__
+#define mactime_h__
+
+
+PR_BEGIN_EXTERN_C
+
+void MacintoshInitializeTime(void);
+
+
+PR_END_EXTERN_C
+
+
+#endif /* mactime_h__ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdcriticalregion.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdcriticalregion.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: NULL; 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):
+ *   George Warner, Apple Computer Inc.
+ *   Simon Fraser  <sfraser at netscape.com>
+ *
+ * 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 "mdcriticalregion.h"
+#include <MacErrors.h>
+
+/*
+  This code is a replacement for MPEnterCriticalRegion/MPLeaveCriticalRegion,
+  which is broken on Mac OS 10.0.x builds, but fixed in 10.1. This code works
+  everywhere.
+*/
+
+
+typedef struct MDCriticalRegionData_struct {
+  MPTaskID        mMPTaskID;          /* Who's in the critical region? */
+  UInt32          mDepthCount;        /* How deep? */
+  MPSemaphoreID   mMPSemaphoreID;     /* ready semaphore */
+} MDCriticalRegionData, *MDCriticalRegionDataPtr;
+
+
+OSStatus
+MD_CriticalRegionCreate(MDCriticalRegionID * outCriticalRegionID)
+{
+  MDCriticalRegionDataPtr newCriticalRegionPtr;
+  MPSemaphoreID           mpSemaphoreID;
+  OSStatus                err = noErr;
+
+  if (outCriticalRegionID == NULL)
+    return paramErr;
+
+  *outCriticalRegionID = NULL;
+
+  newCriticalRegionPtr = (MDCriticalRegionDataPtr)MPAllocateAligned(sizeof(MDCriticalRegionData),
+                        kMPAllocateDefaultAligned, kMPAllocateClearMask);
+  if (newCriticalRegionPtr == NULL)
+    return memFullErr;
+
+  // Note: this semaphore is pre-fired (ready!)
+  err = MPCreateBinarySemaphore(&mpSemaphoreID);
+  if (err == noErr)
+  {
+    newCriticalRegionPtr->mMPTaskID = kInvalidID;
+    newCriticalRegionPtr->mDepthCount = 0;
+    newCriticalRegionPtr->mMPSemaphoreID = mpSemaphoreID;
+
+    *outCriticalRegionID = (MDCriticalRegionID)newCriticalRegionPtr;
+  }
+  else
+  {
+    MPFree((LogicalAddress)newCriticalRegionPtr);
+  }
+
+  return err;
+}
+
+OSStatus
+MD_CriticalRegionDelete(MDCriticalRegionID inCriticalRegionID)
+{
+  MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
+  OSStatus                err = noErr;
+
+  if (criticalRegion == NULL)
+    return paramErr;
+
+  if ((criticalRegion->mMPTaskID != kInvalidID) && (criticalRegion->mDepthCount > 0))
+    return kMPInsufficientResourcesErr;
+
+  if (criticalRegion->mMPSemaphoreID != kInvalidID)
+    err = MPDeleteSemaphore(criticalRegion->mMPSemaphoreID);
+  if (noErr != err) return err;
+
+  criticalRegion->mMPSemaphoreID = kInvalidID;
+  MPFree((LogicalAddress) criticalRegion);
+
+  return noErr;
+}
+
+OSStatus
+MD_CriticalRegionEnter(MDCriticalRegionID inCriticalRegionID, Duration inTimeout)
+{
+  MDCriticalRegionDataPtr criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
+  MPTaskID                currentTaskID = MPCurrentTaskID();
+  OSStatus                err = noErr;
+
+  if (criticalRegion == NULL)
+    return paramErr;
+
+  // if I'm inside the critical region...
+  if (currentTaskID == criticalRegion->mMPTaskID)
+  {
+    // bump my depth
+    criticalRegion->mDepthCount++;
+    // and continue
+    return noErr;
+  }
+
+  // wait for the ready semaphore
+  err = MPWaitOnSemaphore(criticalRegion->mMPSemaphoreID, inTimeout);
+  // we didn't get it. return the error
+  if (noErr != err) return err;
+
+  // we got it!
+  criticalRegion->mMPTaskID = currentTaskID;
+  criticalRegion->mDepthCount = 1;
+
+  return noErr;
+}
+
+OSStatus
+MD_CriticalRegionExit(MDCriticalRegionID inCriticalRegionID)
+{
+  MDCriticalRegionDataPtr   criticalRegion = (MDCriticalRegionDataPtr)inCriticalRegionID;
+  MPTaskID                  currentTaskID = MPCurrentTaskID();
+  OSStatus                  err = noErr;
+
+  // if we don't own the critical region...
+  if (currentTaskID != criticalRegion->mMPTaskID)
+    return kMPInsufficientResourcesErr;
+
+  // if we aren't at a depth...
+  if (criticalRegion->mDepthCount == 0)
+    return kMPInsufficientResourcesErr;
+
+  // un-bump my depth
+  criticalRegion->mDepthCount--;
+
+  // if we just bottomed out...
+  if (criticalRegion->mDepthCount == 0)
+  {
+    // release ownership of the structure
+    criticalRegion->mMPTaskID = kInvalidID;
+    // and signal the ready semaphore
+    err = MPSignalSemaphore(criticalRegion->mMPSemaphoreID);
+  }
+  return err;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdcriticalregion.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdcriticalregion.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,59 @@
+/* -*- 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):
+ *   George Warner, Apple Computer Inc.
+ *   Simon Fraser  <sfraser at netscape.com>
+ *
+ * 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 mdcriticalregion_h___
+#define mdcriticalregion_h___
+
+
+#ifndef __MULTIPROCESSING__
+#include <Multiprocessing.h>
+#endif
+
+typedef struct OpaqueMDCriticalRegionID*  MDCriticalRegionID;
+
+OSStatus MD_CriticalRegionCreate(MDCriticalRegionID * pMDCriticalRegionID);
+
+OSStatus MD_CriticalRegionDelete(MDCriticalRegionID pMDCriticalRegionID);
+
+OSStatus MD_CriticalRegionEnter(MDCriticalRegionID pMDCriticalRegionID, Duration pTimeout);
+
+OSStatus MD_CriticalRegionExit(MDCriticalRegionID pMDCriticalRegionID);
+
+#endif /* mdcriticalregion_h___ */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdmac.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdmac.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,776 @@
+/* -*- 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 <Types.h>
+#include <Timer.h>
+#include <Files.h>
+#include <Errors.h>
+#include <Folders.h>
+#include <Gestalt.h>
+#include <Events.h>
+#include <Processes.h>
+#include <TextUtils.h>
+#include <MixedMode.h>
+#include <LowMem.h>
+
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stat.h>
+#include <stdarg.h>
+#include <unix.h>
+
+#include "MacErrorHandling.h"
+
+#include "primpl.h"
+#include "prgc.h"
+
+#include "mactime.h"
+
+#include "mdmac.h"
+
+// undefine getenv, so that _MD_GetEnv can call the version in NSStdLib::nsEnvironment.cpp.
+#undef getenv
+
+//
+// Local routines
+//
+unsigned char GarbageCollectorCacheFlusher(PRUint32 size);
+
+extern PRThread *gPrimaryThread;
+extern ProcessSerialNumber gApplicationProcess;     // in macthr.c
+
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark CREATING MACINTOSH THREAD STACKS
+
+
+enum {
+	uppExitToShellProcInfo 				= kPascalStackBased,
+	uppStackSpaceProcInfo				= kRegisterBased 
+										  | RESULT_SIZE(SIZE_CODE(sizeof(long)))
+										  | REGISTER_RESULT_LOCATION(kRegisterD0)
+		 								  | REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(UInt16)))
+};
+
+typedef CALLBACK_API( long , StackSpacePatchPtr )(UInt16 trapNo);
+typedef REGISTER_UPP_TYPE(StackSpacePatchPtr)	StackSpacePatchUPP;
+
+StackSpacePatchUPP	  gStackSpacePatchUPP = NULL;
+UniversalProcPtr	  gStackSpacePatchCallThru = NULL;
+long				(*gCallOSTrapUniversalProc)(UniversalProcPtr,ProcInfoType,...) = NULL;
+
+
+pascal long StackSpacePatch(UInt16 trapNo)
+{
+	char		tos;
+	PRThread	*thisThread;
+	
+	thisThread = PR_GetCurrentThread();
+	
+	//	If we are the primary thread, then call through to the
+	//	good ol' fashion stack space implementation.  Otherwise,
+	//	compute it by hand.
+	if ((thisThread == gPrimaryThread) || 	
+		(&tos < thisThread->stack->stackBottom) || 
+		(&tos > thisThread->stack->stackTop)) {
+		return gCallOSTrapUniversalProc(gStackSpacePatchCallThru, uppStackSpaceProcInfo, trapNo);
+	}
+	else {
+		return &tos - thisThread->stack->stackBottom;
+	}
+}
+
+
+static void InstallStackSpacePatch(void)
+{
+	long				systemVersion;
+	OSErr				err;
+	CFragConnectionID	connID;
+	Str255				errMessage;
+	Ptr					interfaceLibAddr;
+	CFragSymbolClass	symClass;
+	UniversalProcPtr	(*getOSTrapAddressProc)(UInt16);
+	void				(*setOSTrapAddressProc)(StackSpacePatchUPP, UInt16);
+	UniversalProcPtr	(*newRoutineDescriptorProc)(ProcPtr,ProcInfoType,ISAType);
+	
+
+	err = Gestalt(gestaltSystemVersion,&systemVersion);
+	if (systemVersion >= 0x00000A00)	// we don't need to patch StackSpace()
+		return;
+
+	// open connection to "InterfaceLib"
+	err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
+											&connID, &interfaceLibAddr, errMessage);
+	PR_ASSERT(err == noErr);
+	if (err != noErr)
+		return;
+
+	// get symbol GetOSTrapAddress
+	err = FindSymbol(connID, "\pGetOSTrapAddress", &(Ptr)getOSTrapAddressProc, &symClass);
+	if (err != noErr)
+		return;
+
+	// get symbol SetOSTrapAddress
+	err = FindSymbol(connID, "\pSetOSTrapAddress", &(Ptr)setOSTrapAddressProc, &symClass);
+	if (err != noErr)
+		return;
+	
+	// get symbol NewRoutineDescriptor
+	err = FindSymbol(connID, "\pNewRoutineDescriptor", &(Ptr)newRoutineDescriptorProc, &symClass);
+	if (err != noErr)
+		return;
+	
+	// get symbol CallOSTrapUniversalProc
+	err = FindSymbol(connID, "\pCallOSTrapUniversalProc", &(Ptr)gCallOSTrapUniversalProc, &symClass);
+	if (err != noErr)
+		return;
+
+	// get and set trap address for StackSpace (A065)
+	gStackSpacePatchCallThru = getOSTrapAddressProc(0x0065);
+	if (gStackSpacePatchCallThru)
+	{
+		gStackSpacePatchUPP =
+			(StackSpacePatchUPP)newRoutineDescriptorProc((ProcPtr)(StackSpacePatch), uppStackSpaceProcInfo, GetCurrentArchitecture());
+		setOSTrapAddressProc(gStackSpacePatchUPP, 0x0065);
+	}
+
+#if DEBUG
+	StackSpace();
+#endif
+}
+
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark ENVIRONMENT VARIABLES
+
+
+typedef struct EnvVariable EnvVariable;
+
+struct EnvVariable {
+	char 			*variable;
+	char			*value;
+	EnvVariable		*next;
+};
+
+EnvVariable		*gEnvironmentVariables = NULL;
+
+char *_MD_GetEnv(const char *name)
+{
+	EnvVariable 	*currentVariable = gEnvironmentVariables;
+
+	while (currentVariable) {
+		if (!strcmp(currentVariable->variable, name))
+			return currentVariable->value;
+			
+		currentVariable = currentVariable->next;
+	}
+
+	return getenv(name);
+}
+
+PR_IMPLEMENT(int) 
+_MD_PutEnv(const char *string)
+{
+	EnvVariable 	*currentVariable = gEnvironmentVariables;
+	char			*variableCopy,
+				    *value,
+					*current;
+					
+	variableCopy = strdup(string);
+	PR_ASSERT(variableCopy != NULL);
+
+	current = variableCopy;
+	while (*current != '=')
+		current++;
+
+	*current = 0;
+	current++;
+
+	value = current;
+
+	while (currentVariable) {
+		if (!strcmp(currentVariable->variable, variableCopy))
+			break;
+		
+		currentVariable = currentVariable->next;
+	}
+
+	if (currentVariable == NULL) {
+		currentVariable = PR_NEW(EnvVariable);
+		
+		if (currentVariable == NULL) {
+			PR_DELETE(variableCopy);
+			return -1;
+		}
+		
+		currentVariable->variable = strdup(variableCopy);
+		currentVariable->value = strdup(value);
+		currentVariable->next = gEnvironmentVariables;
+		gEnvironmentVariables = currentVariable;
+	}
+	
+	else {
+		PR_DELETE(currentVariable->value);
+		currentVariable->value = strdup(current);
+
+		/* This is a temporary hack.  Working on a real fix, remove this when done. */
+		/* OK, there are two ways to access the  */
+		/* library path, getenv() and PR_GetLibraryPath().  Take a look at PR_GetLibraryPath(). */
+		/* You'll see that we keep the path in a global which is intialized at startup from */
+		/* a call to getenv().  From then on, they have nothing in common. */
+		/* We need to keep them in synch.  */
+		if (strcmp(currentVariable->variable, "LD_LIBRARY_PATH") == 0)
+			PR_SetLibraryPath(currentVariable->value);
+	}
+	
+	PR_DELETE(variableCopy);
+	return 0;
+}
+
+
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark MISCELLANEOUS
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(t->md.jb);
+    }
+    *np = sizeof(t->md.jb) / sizeof(PRUint32);
+    return (PRWord*) (t->md.jb);
+}
+
+void _MD_GetRegisters(PRUint32 *to)
+{
+  (void) setjmp((void*) to);
+}
+
+void _MD_EarlyInit()
+{
+	Handle				environmentVariables;
+
+	GetCurrentProcess(&gApplicationProcess);
+
+	INIT_CRITICAL_REGION();
+	InitIdleSemaphore();
+
+#if !defined(MAC_NSPR_STANDALONE)
+	// MacintoshInitializeMemory();  Moved to mdmacmem.c: AllocateRawMemory(Size blockSize)
+#else
+	MacintoshInitializeMemory();
+#endif
+	MacintoshInitializeTime();
+	
+	//	Install resource-controlled environment variables.
+	
+	environmentVariables = GetResource('Envi', 128);
+	if (environmentVariables != NULL) {
+	
+		Size 	resourceSize;
+		char	*currentPutEnvString = (char *)*environmentVariables,
+				*currentScanChar = currentPutEnvString;
+				
+		resourceSize = GetHandleSize(environmentVariables);			
+		DetachResource(environmentVariables);
+		HLock(environmentVariables);
+		
+		while (resourceSize--) {
+		
+			if ((*currentScanChar == '\n') || (*currentScanChar == '\r')) {
+				*currentScanChar = 0;
+				_MD_PutEnv (currentPutEnvString);
+				currentPutEnvString = currentScanChar + 1;
+			}
+		
+			currentScanChar++;
+		
+		}
+		
+		DisposeHandle(environmentVariables);
+
+	}
+
+#ifdef PR_INTERNAL_LOGGING
+	_MD_PutEnv ("NSPR_LOG_MODULES=clock:6,cmon:6,io:6,mon:6,linker:6,cvar:6,sched:6,thread:6");
+#endif
+
+	InstallStackSpacePatch();
+}
+
+void _MD_FinalInit()
+{
+	_MD_InitNetAccess();
+}
+
+void PR_InitMemory(void) {
+#ifndef NSPR_AS_SHARED_LIB
+	//	Needed for Mac browsers without Java.  We don't want them calling PR_INIT, since it
+	//	brings in all of the thread support.  But we do need to allow them to initialize
+	//	the NSPR memory package.
+	//	This should go away when all clients of the NSPR want threads AND memory.
+	MacintoshInitializeMemory();
+#endif
+}
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark TERMINATION
+
+
+//	THIS IS *** VERY *** IMPORTANT... our CFM Termination proc.
+//	This allows us to deactivate our Time Mananger task even
+//	if we are not totally gracefully exited.  If this is not
+//	done then we will randomly crash at later times when the
+//	task is called after the app heap is gone.
+
+#if TARGET_CARBON
+extern OTClientContextPtr	clientContext;
+#define CLOSE_OPEN_TRANSPORT()	CloseOpenTransportInContext(clientContext)
+
+#else
+
+#define CLOSE_OPEN_TRANSPORT()	CloseOpenTransport()
+#endif /* TARGET_CARBON */
+
+extern pascal void __NSTerminate(void);
+
+void CleanupTermProc(void)
+{
+	_MD_StopInterrupts();	// deactive Time Manager task
+
+	CLOSE_OPEN_TRANSPORT();
+	TermIdleSemaphore();
+	TERM_CRITICAL_REGION();
+	
+	__NSTerminate();
+}
+
+
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark STRING OPERATIONS
+
+#if !defined(MAC_NSPR_STANDALONE)
+
+//	PStrFromCStr converts the source C string to a destination
+//	pascal string as it copies. The dest string will
+//	be truncated to fit into an Str255 if necessary.
+//  If the C String pointer is NULL, the pascal string's length is set to zero
+//
+void 
+PStrFromCStr(const char* src, Str255 dst)
+{
+	short 	length  = 0;
+	
+	// handle case of overlapping strings
+	if ( (void*)src == (void*)dst )
+	{
+		unsigned char*		curdst = &dst[1];
+		unsigned char		thisChar;
+				
+		thisChar = *(const unsigned char*)src++;
+		while ( thisChar != '\0' ) 
+		{
+			unsigned char	nextChar;
+			
+			// use nextChar so we don't overwrite what we are about to read
+			nextChar = *(const unsigned char*)src++;
+			*curdst++ = thisChar;
+			thisChar = nextChar;
+			
+			if ( ++length >= 255 )
+				break;
+		}
+	}
+	else if ( src != NULL )
+	{
+		unsigned char*		curdst = &dst[1];
+		short 				overflow = 255;		// count down so test it loop is faster
+		register char		temp;
+	
+		// Can't do the K&R C thing of "while (*s++ = *t++)" because it will copy trailing zero
+		// which might overrun pascal buffer.  Instead we use a temp variable.
+		while ( (temp = *src++) != 0 ) 
+		{
+			*(char*)curdst++ = temp;
+				
+			if ( --overflow <= 0 )
+				break;
+		}
+		length = 255 - overflow;
+	}
+	dst[0] = length;
+}
+
+
+void CStrFromPStr(ConstStr255Param pString, char **cString)
+{
+	// Allocates a cString and copies a Pascal string into it.
+	unsigned int	len;
+	
+	len = pString[0];
+	*cString = malloc(len+1);
+	
+	if (*cString != NULL) {
+		strncpy(*cString, (char *)&pString[1], len);
+		(*cString)[len] = NULL;
+	}
+}
+
+
+void dprintf(const char *format, ...)
+{
+#if DEBUG
+    va_list ap;
+	Str255 buffer;
+	
+	va_start(ap, format);
+	buffer[0] = PR_vsnprintf((char *)buffer + 1, sizeof(buffer) - 1, format, ap);
+	va_end(ap);
+	
+	DebugStr(buffer);
+#endif /* DEBUG */
+}
+
+#else
+
+void debugstr(const char *debuggerMsg)
+{
+	Str255		pStr;
+	
+	PStrFromCStr(debuggerMsg, pStr);
+	DebugStr(pStr);
+}
+
+
+char *strdup(const char *source)
+{
+	char 	*newAllocation;
+	size_t	stringLength;
+
+	PR_ASSERT(source);
+	
+	stringLength = strlen(source) + 1;
+	
+	newAllocation = (char *)PR_MALLOC(stringLength);
+	if (newAllocation == NULL)
+		return NULL;
+	BlockMoveData(source, newAllocation, stringLength);
+	return newAllocation;
+}
+
+//	PStrFromCStr converts the source C string to a destination
+//	pascal string as it copies. The dest string will
+//	be truncated to fit into an Str255 if necessary.
+//  If the C String pointer is NULL, the pascal string's length is set to zero
+//
+void PStrFromCStr(const char* src, Str255 dst)
+{
+	short 	length  = 0;
+	
+	// handle case of overlapping strings
+	if ( (void*)src == (void*)dst )
+	{
+		unsigned char*		curdst = &dst[1];
+		unsigned char		thisChar;
+				
+		thisChar = *(const unsigned char*)src++;
+		while ( thisChar != '\0' ) 
+		{
+			unsigned char	nextChar;
+			
+			// use nextChar so we don't overwrite what we are about to read
+			nextChar = *(const unsigned char*)src++;
+			*curdst++ = thisChar;
+			thisChar = nextChar;
+			
+			if ( ++length >= 255 )
+				break;
+		}
+	}
+	else if ( src != NULL )
+	{
+		unsigned char*		curdst = &dst[1];
+		short 				overflow = 255;		// count down so test it loop is faster
+		register char		temp;
+	
+		// Can't do the K&R C thing of "while (*s++ = *t++)" because it will copy trailing zero
+		// which might overrun pascal buffer.  Instead we use a temp variable.
+		while ( (temp = *src++) != 0 ) 
+		{
+			*(char*)curdst++ = temp;
+				
+			if ( --overflow <= 0 )
+				break;
+		}
+		length = 255 - overflow;
+	}
+	dst[0] = length;
+}
+
+
+void CStrFromPStr(ConstStr255Param pString, char **cString)
+{
+	// Allocates a cString and copies a Pascal string into it.
+	unsigned int	len;
+	
+	len = pString[0];
+	*cString = PR_MALLOC(len+1);
+	
+	if (*cString != NULL) {
+		strncpy(*cString, (char *)&pString[1], len);
+		(*cString)[len] = NULL;
+	}
+}
+
+
+size_t strlen(const char *source)
+{
+	size_t currentLength = 0;
+	
+	if (source == NULL)
+		return currentLength;
+			
+	while (*source++ != '\0')
+		currentLength++;
+		
+	return currentLength;
+}
+
+int strcmpcore(const char *str1, const char *str2, int caseSensitive)
+{
+	char 	currentChar1, currentChar2;
+
+	while (1) {
+	
+		currentChar1 = *str1;
+		currentChar2 = *str2;
+		
+		if (!caseSensitive) {
+			
+			if ((currentChar1 >= 'a') && (currentChar1 <= 'z'))
+				currentChar1 += ('A' - 'a');
+		
+			if ((currentChar2 >= 'a') && (currentChar2 <= 'z'))
+				currentChar2 += ('A' - 'a');
+		
+		}
+	
+		if (currentChar1 == '\0')
+			break;
+	
+		if (currentChar1 != currentChar2)
+			return currentChar1 - currentChar2;
+			
+		str1++;
+		str2++;
+	
+	}
+	
+	return currentChar1 - currentChar2;
+}
+
+int strcmp(const char *str1, const char *str2)
+{
+	return strcmpcore(str1, str2, true);
+}
+
+int strcasecmp(const char *str1, const char *str2)
+{
+	return strcmpcore(str1, str2, false);
+}
+
+
+void *memcpy(void *to, const void *from, size_t size)
+{
+	if (size != 0) {
+#if DEBUG
+		if ((UInt32)to < 0x1000)
+			DebugStr("\pmemcpy has illegal to argument");
+		if ((UInt32)from < 0x1000)
+			DebugStr("\pmemcpy has illegal from argument");
+#endif
+		BlockMoveData(from, to, size);
+	}
+	return to;
+}
+
+void dprintf(const char *format, ...)
+{
+    va_list ap;
+	char	*buffer;
+	
+	va_start(ap, format);
+	buffer = (char *)PR_vsmprintf(format, ap);
+	va_end(ap);
+	
+	debugstr(buffer);
+	PR_DELETE(buffer);
+}
+
+void
+exit(int result)
+{
+#pragma unused (result)
+
+		ExitToShell();
+}
+
+void abort(void)
+{
+	exit(-1);
+}
+
+#endif
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark FLUSHING THE GARBAGE COLLECTOR
+
+#if !defined(MAC_NSPR_STANDALONE)
+
+unsigned char GarbageCollectorCacheFlusher(PRUint32)
+{
+
+    PRIntn is;
+
+	UInt32		oldPriority;
+
+	//	If java wasn't completely initialized, then bail 
+	//	harmlessly.
+	
+	if (PR_GetGCInfo()->lock == NULL)
+		return false;
+
+#if DEBUG
+	if (_MD_GET_INTSOFF() == 1)
+		DebugStr("\pGarbageCollectorCacheFlusher at interrupt time!");
+#endif
+
+	//	The synchronization here is very tricky.  We really
+	//	don't want any other threads to run while we are 
+	//	cleaning up the gc heap... they could call malloc,
+	//	and then we would be in trouble in a big way.  So,
+	//	we jack up our priority and that of the finalizer
+	//	so that we won't yield to other threads.
+	//	dkc 5/17/96
+
+	oldPriority = PR_GetThreadPriority(PR_GetCurrentThread());
+	_PR_INTSOFF(is);
+	_PR_SetThreadPriority(PR_GetCurrentThread(), (PRThreadPriority)30);
+	_PR_INTSON(is);
+
+	//	Garbage collect twice.  This will finalize any
+	//	dangling AWT resources (images, components), and
+	//	then free up their GC space, too.
+	//	dkc 2/15/96
+	//  interrupts must be on during PR_GC
+	
+	PR_GC();
+	
+	//	By setting the finalizer priority to 31, then we 
+	//	ensure it will run before us.  When it finishes
+	//	its list of finalizations, it returns to us
+	//	for the second garbage collection.
+	
+	PR_Yield();
+
+	PR_GC();
+	
+	//	Restore our old priorities.
+	
+	_PR_INTSOFF(is);
+	_PR_SetThreadPriority(PR_GetCurrentThread(), (PRThreadPriority)oldPriority);
+	_PR_INTSON(is);
+
+	return false;
+}
+
+#endif
+
+//##############################################################################
+//##############################################################################
+#pragma mark -
+#pragma mark MISCELLANEOUS-HACKS
+
+
+//
+//		***** HACK  FIX THESE ****
+//
+extern long _MD_GetOSName(char *buf, long count)
+{
+	long	len;
+	
+	len = PR_snprintf(buf, count, "Mac OS");
+	
+	return 0;
+}
+
+extern long _MD_GetOSVersion(char *buf, long count)
+{
+	long	len;
+	
+	len = PR_snprintf(buf, count, "7.5");
+
+	return 0;
+}
+
+extern long _MD_GetArchitecture(char *buf, long count)
+{
+	long	len;
+	
+#if defined(TARGET_CPU_PPC) && TARGET_CPU_PPC	
+	len = PR_snprintf(buf, count, "PowerPC");
+#else
+	len = PR_snprintf(buf, count, "Motorola68k");
+#endif
+
+	return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdmac.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/mdmac.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,51 @@
+/* -*- 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 mdmac_h__
+#define mdmac_h__
+
+
+PR_BEGIN_EXTERN_C
+
+void PStrFromCStr(const char* src, Str255 dst);
+void CStrFromPStr(ConstStr255Param pString, char **cString);
+
+PR_END_EXTERN_C
+
+
+#endif /* mdmac_h__ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/prcpucfg.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/mac/prcpucfg.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,136 @@
+/* -*- 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 nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_MAC
+#define XP_MAC
+#endif
+
+#undef  IS_LITTLE_ENDIAN
+#define IS_BIG_ENDIAN 1
+
+#define	HAVE_LONG_LONG
+
+#define PR_AF_INET6 30  /* same as AF_INET6 */
+
+#define PR_BYTES_PER_BYTE   1L
+#define PR_BYTES_PER_SHORT  2L
+#define PR_BYTES_PER_INT    4L
+#define PR_BYTES_PER_INT64  8L
+#define PR_BYTES_PER_LONG   4L
+#define PR_BYTES_PER_FLOAT  4L
+#define PR_BYTES_PER_DOUBLE 8L
+#define PR_BYTES_PER_WORD   4L
+#define PR_BYTES_PER_DWORD  8L
+
+#define PR_BITS_PER_BYTE    8L
+#define PR_BITS_PER_SHORT   16L
+#define PR_BITS_PER_INT     32L
+#define PR_BITS_PER_INT64   64L
+#define PR_BITS_PER_LONG    32L
+#define PR_BITS_PER_FLOAT   32L
+#define PR_BITS_PER_DOUBLE  64L
+#define PR_BITS_PER_WORD    32L
+
+#define PR_BITS_PER_BYTE_LOG2   3L
+#define PR_BITS_PER_SHORT_LOG2  4L
+#define PR_BITS_PER_INT_LOG2    5L
+#define PR_BITS_PER_INT64_LOG2  6L
+#define PR_BITS_PER_LONG_LOG2   5L
+#define PR_BITS_PER_FLOAT_LOG2  5L
+#define PR_BITS_PER_DOUBLE_LOG2 6L
+#define PR_BITS_PER_WORD_LOG2   5L
+
+#define PR_ALIGN_OF_SHORT   2L
+#define PR_ALIGN_OF_INT     4L
+#define PR_ALIGN_OF_LONG    4L
+#define PR_ALIGN_OF_INT64   2L
+#define PR_ALIGN_OF_FLOAT   4L
+#define PR_ALIGN_OF_DOUBLE  4L
+#define PR_ALIGN_OF_POINTER 4L
+#define PR_ALIGN_OF_WORD    4L
+
+#define PR_BYTES_PER_WORD_LOG2   2L
+#define PR_BYTES_PER_DWORD_LOG2  3L
+#define PR_WORDS_PER_DWORD_LOG2  1L
+
+#ifndef NO_NSPR_10_SUPPORT
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2		PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2		PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,18 @@
+/.cvsignore/1.2/Sat May 12 06:11:46 2001//
+/Makefile.in/1.16/Sun Apr 25 15:00:59 2004//
+/objs.mk/1.7/Sun Apr 25 15:00:59 2004//
+/os2_errors.c/3.9/Sun Apr 25 15:00:59 2004//
+/os2cv.c/3.14/Sun Apr 25 15:00:59 2004//
+/os2emx.s/1.3/Mon Jan  9 17:43:52 2006//
+/os2gc.c/3.7/Sun Apr 25 15:00:59 2004//
+/os2inrval.c/3.10/Tue Jan 25 22:24:12 2005//
+/os2io.c/3.17/Fri Apr 22 21:14:03 2005//
+/os2misc.c/3.24/Mon Nov 22 21:06:12 2004//
+/os2poll.c/3.14/Sun Apr 25 15:00:59 2004//
+/os2rng.c/1.6/Sun Apr 25 15:00:59 2004//
+/os2sem.c/3.6/Sun Apr 25 15:00:59 2004//
+/os2sock.c/3.17/Fri Apr 22 21:14:03 2005//
+/os2thred.c/3.17/Sun Apr 25 15:00:59 2004//
+/os2vaclegacy.s/3.1/Tue Sep 16 01:57:42 2003//
+/os2vacpp.asm/1.7/Mon Jan  9 17:43:52 2006//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/md/os2

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,85 @@
+# 
+# ***** 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), OS2)
+CSRCS = \
+    os2misc.c \
+    os2sem.c   \
+    os2inrval.c \
+    os2gc.c \
+    os2thred.c \
+    os2io.c \
+    os2cv.c \
+    os2sock.c \
+    os2_errors.c \
+    os2poll.c \
+    os2rng.c \
+    $(NULL)
+endif
+
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+ASFILES = os2vacpp.asm
+endif
+
+ifeq ($(MOZ_OS2_TOOLS),EMX)
+ASFILES = os2emx.s os2vaclegacy.s
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
+
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/objs.mk
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/objs.mk	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,65 @@
+# 
+# ***** 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 *****
+
+# This makefile appends to the variable OBJS the platform-dependent
+# object modules that will be part of the nspr20 library.
+
+CSRCS = \
+	os2io.c      \
+	os2sock.c    \
+	os2thred.c   \
+	os2cv.c      \
+	os2gc.c      \
+	os2misc.c    \
+	os2inrval.c  \
+	os2sem.c     \
+	os2_errors.c \
+	os2poll.c    \
+	os2rng.c     \
+	$(NULL)
+
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+ASFILES = os2vacpp.asm
+endif
+
+ifeq ($(MOZ_OS2_TOOLS),EMX)
+ASFILES = os2emx.s os2vaclegacy.s
+endif
+
+OBJS += $(addprefix md/os2/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX)))  \
+	$(addprefix md/os2/$(OBJDIR)/,$(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX)))
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2_errors.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2_errors.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1129 @@
+/* -*- 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 "prerror.h"
+#include "primpl.h"
+
+void _MD_os2_map_default_error(PRInt32 err)
+{
+	switch (err) {
+		case EWOULDBLOCK:
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case EMSGSIZE:
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+void _MD_os2_map_opendir_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_FILE_NOT_FOUND:
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+      case ERROR_INVALID_ADDRESS:
+      case ERROR_INVALID_ACCESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+      case ERROR_INVALID_NAME:
+      case ERROR_INVALID_PARAMETER:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+      case ERROR_TOO_MANY_OPEN_FILES:
+		case ERROR_NOT_DOS_DISK:
+		case ERROR_NOT_READY:
+		case ERROR_OPEN_FAILED:
+      case ERROR_PATH_BUSY:
+      case ERROR_CANNOT_MAKE:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+      case ERROR_DRIVE_LOCKED:
+      case ERROR_DEVICE_IN_USE:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_SHARING_BUFFER_EXCEEDED:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_closedir_error(PRInt32 err)
+{
+	switch (err) {
+      case ERROR_FILE_NOT_FOUND:
+      case ERROR_ACCESS_DENIED:
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_readdir_error(PRInt32 err)
+{
+
+	switch (err) {
+		case ERROR_NO_MORE_FILES:
+			PR_SetError(PR_NO_MORE_FILES_ERROR, err);
+			break;
+		case ERROR_FILE_NOT_FOUND:
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_DOS_DISK:
+		case ERROR_LOCK_VIOLATION:
+		case ERROR_BROKEN_PIPE:
+		case ERROR_NOT_READY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+      case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_delete_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_FILE_NOT_FOUND:
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+		case ERROR_SHARING_VIOLATION:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+/* The error code for stat() is in errno. */
+void _MD_os2_map_stat_error(PRInt32 err)
+{
+    switch (err) {
+        case ENOENT:
+            PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+            break;
+        case EACCES:
+            PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+            break;
+        default:
+            PR_SetError(PR_UNKNOWN_ERROR, err);
+    }
+}
+
+void _MD_os2_map_fstat_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_rename_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_FILE_NOT_FOUND:
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_INVALID_NAME:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_ALREADY_EXISTS:
+		case ERROR_FILE_EXISTS:
+			PR_SetError(PR_FILE_EXISTS_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+/* The error code for access() is in errno. */
+void _MD_os2_map_access_error(PRInt32 err)
+{
+    switch (err) {
+        case ENOENT:
+            PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+            break;
+        case EACCES:
+            PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+            break;
+        default:
+            PR_SetError(PR_UNKNOWN_ERROR, err);
+    }
+}
+
+void _MD_os2_map_mkdir_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ALREADY_EXISTS:
+		case ERROR_FILE_EXISTS:
+			PR_SetError(PR_FILE_EXISTS_ERROR, err);
+			break;
+		case ERROR_FILE_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_INVALID_NAME:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_TOO_MANY_OPEN_FILES:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DISK_FULL:
+		case ERROR_HANDLE_DISK_FULL:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_rmdir_error(PRInt32 err)
+{
+
+	switch (err) {
+		case ERROR_FILE_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_INVALID_NAME:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_TOO_MANY_OPEN_FILES:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_read_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+		case ERROR_SHARING_VIOLATION:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break; 
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_transmitfile_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+		case ERROR_SHARING_VIOLATION:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_TOO_MANY_OPEN_FILES:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_write_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ACCESS_DENIED:
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+		case ERROR_SHARING_VIOLATION:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+		case ERROR_DISK_FULL:
+      case ERROR_HANDLE_DISK_FULL:
+      case ENOSPC:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case EMSGSIZE:
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_lseek_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_SEEK_ON_DEVICE:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_fsync_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ACCESS_DENIED:
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DISK_FULL:
+		case ERROR_HANDLE_DISK_FULL:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_close_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_INVALID_HANDLE:
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_socket_error(PRInt32 err)
+{
+	switch (err) {
+		case EPROTONOSUPPORT:
+			PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_recv_error(PRInt32 err)
+{
+	switch (err) {
+		case EWOULDBLOCK:
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_recvfrom_error(PRInt32 err)
+{
+	switch (err) {
+		case EWOULDBLOCK:
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_send_error(PRInt32 err)
+{
+	switch (err) {
+		case EWOULDBLOCK:
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case EMSGSIZE:
+		case EINVAL:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case EISCONN:
+			PR_SetError(PR_IS_CONNECTED_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ERROR_NETNAME_DELETED:
+			PR_SetError(PR_CONNECT_RESET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_sendto_error(PRInt32 err)
+{
+  _MD_os2_map_default_error(err);
+}
+
+void _MD_os2_map_writev_error(int err)
+{
+  _MD_os2_map_default_error(err);
+}
+
+void _MD_os2_map_accept_error(PRInt32 err)
+{
+  _MD_os2_map_default_error(err);
+}
+
+void _MD_os2_map_acceptex_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+/*
+ * An error code of 0 means that the nonblocking connect succeeded.
+ */
+
+int _MD_os2_get_nonblocking_connect_error(int osfd)
+{
+    int err;
+    int len = sizeof(err);
+    if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &len) == -1) {
+        return sock_errno();
+    } else {
+        return err;
+    }
+}
+
+void _MD_os2_map_connect_error(PRInt32 err)
+{
+	switch (err) {
+       case EWOULDBLOCK:
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+        case EINPROGRESS:
+			PR_SetError(PR_IN_PROGRESS_ERROR, err);
+			break;
+		case EALREADY:
+		case EINVAL:
+			PR_SetError(PR_ALREADY_INITIATED_ERROR, err);
+			break;
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case EADDRNOTAVAIL:
+			PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case EAFNOSUPPORT:
+			PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+			break;
+		case ETIMEDOUT:
+			PR_SetError(PR_IO_TIMEOUT_ERROR, err);
+			break;
+		case ECONNREFUSED:
+			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+			break;
+		case ENETUNREACH:
+			PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err);
+			break;
+		case EADDRINUSE:
+			PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
+			break;
+      case EISCONN:
+         PR_SetError(PR_IS_CONNECTED_ERROR, err);
+         break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_bind_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case EADDRNOTAVAIL:
+			PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err);
+			break;
+		case EADDRINUSE:
+			PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
+			break;
+		case EACCES:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case EINVAL:
+			PR_SetError(PR_SOCKET_ADDRESS_IS_BOUND_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_listen_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case EOPNOTSUPP:
+			PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_shutdown_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case ENOTCONN:
+			PR_SetError(PR_NOT_CONNECTED_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+#ifndef XP_OS2_VACPP
+void _MD_os2_map_socketpair_error(PRInt32 err)
+{
+  switch (err) {
+    case ENOMEM:
+      PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+      break;
+    case EAFNOSUPPORT:
+      PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+      break;
+    case EPROTONOSUPPORT:
+      PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err);
+      break;
+    case EOPNOTSUPP:
+      PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err);
+      break;
+    case EPROTOTYPE:
+      PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+      break;
+    default:
+      _MD_os2_map_default_error(err);
+      return;
+  }
+}
+#endif
+
+void _MD_os2_map_getsockname_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_getpeername_error(PRInt32 err)
+{
+
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case ENOTCONN:
+			PR_SetError(PR_NOT_CONNECTED_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ENOBUFS:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_getsockopt_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case ENOPROTOOPT:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case EINVAL:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_setsockopt_error(PRInt32 err)
+{
+	switch (err) {
+		case EBADF:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ENOTSOCK:
+			PR_SetError(PR_NOT_SOCKET_ERROR, err);
+			break;
+		case ENOPROTOOPT:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case EINVAL:
+			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_open_error(PRInt32 err)
+{
+	switch (err) {
+		case ERROR_ALREADY_EXISTS:
+		case ERROR_FILE_EXISTS:
+			PR_SetError(PR_FILE_EXISTS_ERROR, err);
+			break;
+		case ERROR_FILE_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_INVALID_NAME:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+			break;
+		case ERROR_NOT_READY:
+		case ERROR_OPEN_FAILED:
+		case ERROR_PATH_BUSY:
+			PR_SetError(PR_IO_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_FILENAME_EXCED_RANGE:
+			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
+			break;
+		case ERROR_TOO_MANY_OPEN_FILES:
+			PR_SetError(PR_SYS_DESC_TABLE_FULL_ERROR, err);
+			break;
+		case ERROR_PATH_NOT_FOUND:
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		case ERROR_DISK_FULL:
+		case ERROR_HANDLE_DISK_FULL:
+			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
+			break;
+		case ERROR_WRITE_PROTECT:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+	}
+}
+
+void _MD_os2_map_gethostname_error(PRInt32 err)
+{
+    switch (err) {
+#ifdef SOCEFAULT
+		case SOCEFAULT:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+#endif
+		case ENETDOWN:
+		case EINPROGRESS:
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}
+
+void _MD_os2_map_select_error(PRInt32 err)
+{
+    PRErrorCode prerror;
+
+    switch (err) {
+        /*
+         * OS/2 select() only works on sockets.  So in this
+         * context, ENOTSOCK is equivalent to EBADF on Unix.
+         */
+        case ENOTSOCK:
+            prerror = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        case EINVAL:
+            prerror = PR_INVALID_ARGUMENT_ERROR;
+            break;
+#ifdef SOCEFAULT
+        case SOCEFAULT:
+            prerror = PR_ACCESS_FAULT_ERROR;
+            break;
+#endif
+        default:
+            prerror = PR_UNKNOWN_ERROR;
+    }
+    PR_SetError(prerror, err);
+}
+
+void _MD_os2_map_lockf_error(PRInt32 err)
+{
+    switch (err) {
+		case ERROR_ACCESS_DENIED:
+			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+			break;
+		case ERROR_INVALID_HANDLE:
+			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+			break;
+		case ERROR_INVALID_ADDRESS:
+			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+			break;
+		case ERROR_DRIVE_LOCKED:
+		case ERROR_LOCKED:
+		case ERROR_SHARING_VIOLATION:
+			PR_SetError(PR_FILE_IS_LOCKED_ERROR, err);
+			break;
+		case ERROR_NOT_ENOUGH_MEMORY:
+		case ERROR_MORE_DATA:
+			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+			break;
+		default:
+			PR_SetError(PR_UNKNOWN_ERROR, err);
+			break;
+    }
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2cv.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2cv.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,432 @@
+/* -*- 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 ***** */
+
+/*
+ *  os2cv.c -- OS/2 Machine-Dependent Code for Condition Variables
+ *
+ *  We implement our own condition variable wait queue.  Each thread
+ *  has a semaphore object (thread->md.blocked_sema) to block on while
+ *  waiting on a condition variable.
+ *
+ *  We use a deferred condition notify algorithm.  When PR_NotifyCondVar
+ *  or PR_NotifyAllCondVar is called, the condition notifies are simply
+ *  recorded in the _MDLock structure.  We defer the condition notifies
+ *  until right after we unlock the lock.  This way the awakened threads
+ *  have a better chance to reaquire the lock.
+ */
+ 
+#include "primpl.h"
+
+#ifdef USE_RAMSEM
+ULONG _Far16 _Pascal Dos16GetInfoSeg(PSEL pselGlobal, PSEL pselLocal);
+
+#ifdef XP_OS2_EMX
+typedef unsigned short BOOL16;
+#endif
+
+typedef struct _LINFOSEG
+{
+    USHORT  pidCurrent;
+    USHORT  pidParent;
+    USHORT  prtyCurrent;
+    USHORT  tidCurrent;
+    USHORT  sgCurrent;
+    UCHAR   rfProcStatus;
+    UCHAR   dummy1;
+    BOOL16  fForeground;
+    UCHAR   typProcess;
+    UCHAR   dummy2;
+    SEL     selEnvironment;
+    USHORT  offCmdLine;
+    USHORT  cbDataSegment;
+    USHORT  cbStack;
+    USHORT  cbHeap;
+    USHORT  hmod;
+    SEL     selDS;
+    SEL     selPack;
+    SEL     selPackShr;
+    SEL     selPackPck;
+    ULONG   ulReserved;
+} LINFOSEG;
+typedef LINFOSEG FAR *PLINFOSEG;
+
+PLINFOSEG plisCurrent = NULL;
+#endif
+
+/*
+ * AddThreadToCVWaitQueueInternal --
+ *
+ * Add the thread to the end of the condition variable's wait queue.
+ * The CV's lock must be locked when this function is called.
+ */
+
+static void
+AddThreadToCVWaitQueueInternal(PRThread *thred, struct _MDCVar *cv)
+{
+    PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL)
+            || (cv->waitTail == NULL && cv->waitHead == NULL));
+    cv->nwait += 1;
+    thred->md.inCVWaitQueue = PR_TRUE;
+    thred->md.next = NULL;
+    thred->md.prev = cv->waitTail;
+    if (cv->waitHead == NULL) {
+        cv->waitHead = thred;
+    } else {
+        cv->waitTail->md.next = thred;
+    }
+    cv->waitTail = thred;
+}
+
+/*
+ * md_UnlockAndPostNotifies --
+ *
+ * Unlock the lock, and then do the deferred condition notifies.
+ * If waitThred and waitCV are not NULL, waitThred is added to
+ * the wait queue of waitCV before the lock is unlocked.
+ *
+ * This function is called by _PR_MD_WAIT_CV and _PR_MD_UNLOCK,
+ * the two places where a lock is unlocked.
+ */
+void
+md_UnlockAndPostNotifies(
+    _MDLock *lock,
+    PRThread *waitThred,
+    _MDCVar *waitCV)
+{
+    PRIntn index;
+    _MDNotified post;
+    _MDNotified *notified, *prev = NULL;
+
+    /*
+     * Time to actually notify any conditions that were affected
+     * while the lock was held.  Get a copy of the list that's in
+     * the lock structure and then zero the original.  If it's
+     * linked to other such structures, we own that storage.
+     */
+    post = lock->notified;  /* a safe copy; we own the lock */
+
+#if defined(DEBUG)
+    memset(&lock->notified, 0, sizeof(_MDNotified));  /* reset */
+#else
+    lock->notified.length = 0;  /* these are really sufficient */
+    lock->notified.link = NULL;
+#endif
+
+    /* 
+     * Figure out how many threads we need to wake up.
+     */
+    notified = &post;  /* this is where we start */
+    do {
+        for (index = 0; index < notified->length; ++index) {
+            _MDCVar *cv = notified->cv[index].cv;
+            PRThread *thred;
+            int i;
+            
+            /* Fast special case: no waiting threads */
+            if (cv->waitHead == NULL) {
+                notified->cv[index].notifyHead = NULL;
+                continue;
+            }
+
+            /* General case */
+            if (-1 == notified->cv[index].times) {
+                /* broadcast */
+                thred = cv->waitHead;
+                while (thred != NULL) {
+                    thred->md.inCVWaitQueue = PR_FALSE;
+                    thred = thred->md.next;
+                }
+                notified->cv[index].notifyHead = cv->waitHead;
+                cv->waitHead = cv->waitTail = NULL;
+                cv->nwait = 0;
+            } else {
+                thred = cv->waitHead;
+                i = notified->cv[index].times;
+                while (thred != NULL && i > 0) {
+                    thred->md.inCVWaitQueue = PR_FALSE;
+                    thred = thred->md.next;
+                    i--;
+                }
+                notified->cv[index].notifyHead = cv->waitHead;
+                cv->waitHead = thred;
+                if (cv->waitHead == NULL) {
+                    cv->waitTail = NULL;
+                } else {
+                    if (cv->waitHead->md.prev != NULL) {
+                        cv->waitHead->md.prev->md.next = NULL;
+                        cv->waitHead->md.prev = NULL;
+                    }
+                }
+                cv->nwait -= notified->cv[index].times - i;
+            }
+        }
+        notified = notified->link;
+    } while (NULL != notified);
+
+    if (waitThred) {
+        AddThreadToCVWaitQueueInternal(waitThred, waitCV);
+    }
+
+    /* Release the lock before notifying */
+#ifdef USE_RAMSEM
+      SemReleasex86(&lock->mutex, 0);
+#else
+      DosReleaseMutexSem(lock->mutex);
+#endif
+
+    notified = &post;  /* this is where we start */
+    do {
+        for (index = 0; index < notified->length; ++index) {
+            PRThread *thred;
+            PRThread *next;
+
+            thred = notified->cv[index].notifyHead;
+            while (thred != NULL) {
+                BOOL rv;
+
+                next = thred->md.next;
+                thred->md.prev = thred->md.next = NULL;
+                rv = DosPostEventSem(thred->md.blocked_sema);
+                PR_ASSERT(rv == NO_ERROR);
+                thred = next;
+            }
+        }
+        prev = notified;
+        notified = notified->link;
+        if (&post != prev) PR_DELETE(prev);
+    } while (NULL != notified);
+}
+
+/*
+ * Notifies just get posted to the protecting mutex.  The
+ * actual notification is done when the lock is released so that
+ * MP systems don't contend for a lock that they can't have.
+ */
+static void md_PostNotifyToCvar(_MDCVar *cvar, _MDLock *lock,
+        PRBool broadcast)
+{
+    PRIntn index = 0;
+    _MDNotified *notified = &lock->notified;
+
+    while (1) {
+        for (index = 0; index < notified->length; ++index) {
+            if (notified->cv[index].cv == cvar) {
+                if (broadcast) {
+                    notified->cv[index].times = -1;
+                } else if (-1 != notified->cv[index].times) {
+                    notified->cv[index].times += 1;
+                }
+                return;
+            }
+        }
+        /* if not full, enter new CV in this array */
+        if (notified->length < _MD_CV_NOTIFIED_LENGTH) break;
+
+        /* if there's no link, create an empty array and link it */
+        if (NULL == notified->link) {
+            notified->link = PR_NEWZAP(_MDNotified);
+        }
+
+        notified = notified->link;
+    }
+
+    /* A brand new entry in the array */
+    notified->cv[index].times = (broadcast) ? -1 : 1;
+    notified->cv[index].cv = cvar;
+    notified->length += 1;
+}
+
+/*
+ * _PR_MD_NEW_CV() -- Creating new condition variable
+ * ... Solaris uses cond_init() in similar function.
+ *
+ * returns: -1 on failure
+ *          0 when it succeeds.
+ *
+ */
+PRInt32
+_PR_MD_NEW_CV(_MDCVar *cv)
+{
+    cv->magic = _MD_MAGIC_CV;
+    /*
+     * The waitHead, waitTail, and nwait fields are zeroed
+     * when the PRCondVar structure is created.
+     */
+    return 0;
+} 
+
+void _PR_MD_FREE_CV(_MDCVar *cv)
+{
+    cv->magic = (PRUint32)-1;
+    return;
+}
+
+/*
+ *  _PR_MD_WAIT_CV() -- Wait on condition variable
+ */
+void
+_PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout )
+{
+    PRThread *thred = _PR_MD_CURRENT_THREAD();
+    ULONG rv, count;
+    ULONG msecs = (timeout == PR_INTERVAL_NO_TIMEOUT) ?
+            SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(timeout);
+
+    /*
+     * If we have pending notifies, post them now.
+     */
+    if (0 != lock->notified.length) {
+        md_UnlockAndPostNotifies(lock, thred, cv);
+    } else {
+        AddThreadToCVWaitQueueInternal(thred, cv);
+#ifdef USE_RAMSEM
+        SemReleasex86( &lock->mutex, 0 );
+#else
+        DosReleaseMutexSem(lock->mutex); 
+#endif
+    }
+
+    /* Wait for notification or timeout; don't really care which */
+    rv = DosWaitEventSem(thred->md.blocked_sema, msecs);
+    if (rv == NO_ERROR) {
+        DosResetEventSem(thred->md.blocked_sema, &count);
+    }
+
+#ifdef USE_RAMSEM
+    SemRequest486(&(lock->mutex), -1);
+#else
+    DosRequestMutexSem((lock->mutex), SEM_INDEFINITE_WAIT);
+#endif
+
+    PR_ASSERT(rv == NO_ERROR || rv == ERROR_TIMEOUT);
+
+    if(rv == ERROR_TIMEOUT)
+    {
+       if (thred->md.inCVWaitQueue) {
+           PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL)
+                   || (cv->waitTail == NULL && cv->waitHead == NULL));
+           cv->nwait -= 1;
+           thred->md.inCVWaitQueue = PR_FALSE;
+           if (cv->waitHead == thred) {
+               cv->waitHead = thred->md.next;
+               if (cv->waitHead == NULL) {
+                   cv->waitTail = NULL;
+               } else {
+                   cv->waitHead->md.prev = NULL;
+               }
+           } else {
+               PR_ASSERT(thred->md.prev != NULL);
+               thred->md.prev->md.next = thred->md.next;
+               if (thred->md.next != NULL) {
+                   thred->md.next->md.prev = thred->md.prev;
+               } else {
+                   PR_ASSERT(cv->waitTail == thred);
+                   cv->waitTail = thred->md.prev;
+               }
+           }
+           thred->md.next = thred->md.prev = NULL;
+       } else {
+           /*
+            * This thread must have been notified, but the
+            * SemRelease call happens after SemRequest
+            * times out.  Wait on the semaphore again to make it
+            * non-signaled.  We assume this wait won't take long.
+            */
+           rv = DosWaitEventSem(thred->md.blocked_sema, SEM_INDEFINITE_WAIT);
+           if (rv == NO_ERROR) {
+               DosResetEventSem(thred->md.blocked_sema, &count);
+           }
+           PR_ASSERT(rv == NO_ERROR);
+       }
+    }
+    PR_ASSERT(thred->md.inCVWaitQueue == PR_FALSE);
+    return;
+} /* --- end _PR_MD_WAIT_CV() --- */
+
+void
+_PR_MD_NOTIFY_CV(_MDCVar *cv, _MDLock *lock)
+{
+    md_PostNotifyToCvar(cv, lock, PR_FALSE);
+    return;
+}
+
+PRStatus
+_PR_MD_NEW_LOCK(_MDLock *lock)
+{
+#ifdef USE_RAMSEM
+    // It's better if this API traps when pCriticalSect is not a valid
+    // pointer, because we can't return an error code and if we just return
+    // the API caller will have nasty bugs that are hard to find.
+   
+    PRAMSEM pramsem = (PRAMSEM)(&(lock->mutex));
+    /* First time, set up addresses of processor specific functions
+     */
+    if (plisCurrent == NULL)
+    {
+        SEL selGlobal = 0, selLocal = 0;
+   
+        /* Convert 16 bit global information segment to 32 bit address
+         * by performing CRMA on the 16 bit address: "shift" operation
+         * to convert sel to flat, "and" operation to mask the address
+         * to 32-bit
+         */
+        Dos16GetInfoSeg(&selGlobal, &selLocal);
+        plisCurrent = (PLINFOSEG)(((ULONG)selLocal << 13) &
+                      (ULONG)0x1fff0000);
+   
+    }
+   
+    memset(pramsem, 0, sizeof(pramsem));
+    DosCreateEventSem(0, &pramsem->hevSem, DC_SEM_SHARED, 0);
+   
+    lock->notified.length=0;
+    lock->notified.link=NULL;
+    return PR_SUCCESS;
+#else
+    DosCreateMutexSem(0, &(lock->mutex), 0, 0);
+    (lock)->notified.length=0;
+    (lock)->notified.link=NULL;
+    return PR_SUCCESS;
+#endif
+}
+
+void
+_PR_MD_NOTIFYALL_CV(_MDCVar *cv, _MDLock *lock)
+{
+    md_PostNotifyToCvar(cv, lock, PR_TRUE);
+    return;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2emx.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2emx.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,110 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ 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) 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.
+/ 
+
+/ PRInt32 __PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
+/
+/ Atomically increment the integer pointed to by 'val' and return
+/ the result of the increment.
+/
+    .text
+    .globl __PR_MD_ATOMIC_INCREMENT
+    .align 4
+__PR_MD_ATOMIC_INCREMENT:
+    movl 4(%esp), %ecx
+    movl $1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    incl %eax
+    ret
+
+/ PRInt32 __PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
+/
+/ Atomically decrement the integer pointed to by 'val' and return
+/ the result of the decrement.
+/
+    .text
+    .globl __PR_MD_ATOMIC_DECREMENT
+    .align 4
+__PR_MD_ATOMIC_DECREMENT:
+    movl 4(%esp), %ecx
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    decl %eax
+    ret
+
+/ PRInt32 __PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+/
+/ Atomically set the integer pointed to by 'val' to the new
+/ value 'newval' and return the old value.
+/
+/ An alternative implementation:
+/   .text
+/   .globl __PR_MD_ATOMIC_SET
+/   .align 4
+/__PR_MD_ATOMIC_SET:
+/   movl 4(%esp), %ecx
+/   movl 8(%esp), %edx
+/   movl (%ecx), %eax
+/retry:
+/   lock
+/   cmpxchgl %edx, (%ecx)
+/   jne retry
+/   ret
+/
+    .text
+    .globl __PR_MD_ATOMIC_SET
+    .align 4
+__PR_MD_ATOMIC_SET:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    xchgl %eax, (%ecx)
+    ret
+
+/ PRInt32 __PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+/
+/ Atomically add 'val' to the integer pointed to by 'ptr'
+/ and return the result of the addition.
+/
+    .text
+    .globl __PR_MD_ATOMIC_ADD
+    .align 4
+__PR_MD_ATOMIC_ADD:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    movl %eax, %edx
+    lock
+    xaddl %eax, (%ecx)
+    addl %edx, %eax
+    ret

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2gc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2gc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,90 @@
+/* -*- 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 "primpl.h"
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) 
+{
+    CONTEXTRECORD context;
+    context.ContextFlags = CONTEXT_INTEGER;
+
+    if (_PR_IS_NATIVE_THREAD(t)) {
+        context.ContextFlags |= CONTEXT_CONTROL;
+        if (QueryThreadContext(t->md.handle, CONTEXT_CONTROL, &context)) {
+            t->md.gcContext[0] = context.ctx_RegEax;
+            t->md.gcContext[1] = context.ctx_RegEbx;
+            t->md.gcContext[2] = context.ctx_RegEcx;
+            t->md.gcContext[3] = context.ctx_RegEdx;
+            t->md.gcContext[4] = context.ctx_RegEsi;
+            t->md.gcContext[5] = context.ctx_RegEdi;
+            t->md.gcContext[6] = context.ctx_RegEsp;
+            t->md.gcContext[7] = context.ctx_RegEbp;
+            *np = PR_NUM_GCREGS;
+        } else {
+            PR_ASSERT(0);/* XXX */
+        }
+    }
+    return (PRWord *)&t->md.gcContext;
+}
+
+/* This function is not used right now, but is left as a reference.
+ * If you ever need to get the fiberID from the currently running fiber, 
+ * this is it.
+ */
+void *
+GetMyFiberID()
+{
+    void *fiberData = 0;
+
+    /* A pointer to our tib entry is found at FS:[18]
+     * At offset 10h is the fiberData pointer.  The context of the 
+     * fiber is stored in there.  
+     */
+#ifdef HAVE_ASM
+    __asm {
+        mov    EDX, FS:[18h]
+        mov    EAX, DWORD PTR [EDX+10h]
+        mov    [fiberData], EAX
+    }
+#endif
+  
+    return fiberData;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2inrval.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2inrval.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,112 @@
+/* -*- 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 ***** */
+
+/*
+ * OS/2 interval timers
+ *
+ */
+
+#include "primpl.h"
+
+static PRBool useHighResTimer = PR_FALSE;
+PRIntervalTime _os2_ticksPerSec = -1;
+PRIntn _os2_bitShift = 0;
+PRInt32 _os2_highMask = 0;
+   
+void
+_PR_MD_INTERVAL_INIT()
+{
+    char *envp;
+    ULONG timerFreq;
+    APIRET rc;
+
+    if ((envp = getenv("NSPR_OS2_NO_HIRES_TIMER")) != NULL) {
+        if (atoi(envp) == 1)
+           return;
+    }
+
+    timerFreq = 0; /* OS/2 high-resolution timer frequency in Hz */
+    rc = DosTmrQueryFreq(&timerFreq);
+    if (NO_ERROR == rc) {
+        useHighResTimer = PR_TRUE;
+        PR_ASSERT(timerFreq != 0);
+        while (timerFreq > PR_INTERVAL_MAX) {
+            timerFreq >>= 1;
+            _os2_bitShift++;
+            _os2_highMask = (_os2_highMask << 1)+1;
+        }
+
+        _os2_ticksPerSec = timerFreq;
+        PR_ASSERT(_os2_ticksPerSec > PR_INTERVAL_MIN);
+    }
+}
+
+PRIntervalTime
+_PR_MD_GET_INTERVAL()
+{
+    if (useHighResTimer) {
+        QWORD timestamp;
+        PRInt32 top;
+        APIRET rc = DosTmrQueryTime(&timestamp);
+        if (NO_ERROR != rc) {
+            return -1;
+        }
+        /* Sadly, nspr requires the interval to range from 1000 ticks per
+         * second to only 100000 ticks per second. DosTmrQueryTime is too
+         * high resolution...
+         */
+        top = timestamp.ulHi & _os2_highMask;
+        top = top << (32 - _os2_bitShift);
+        timestamp.ulLo = timestamp.ulLo >> _os2_bitShift;   
+        timestamp.ulLo = timestamp.ulLo + top; 
+        return (PRUint32)timestamp.ulLo;
+    } else {
+        ULONG msCount = -1;
+        DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &msCount, sizeof(msCount));
+        return msCount;
+    }
+}
+
+PRIntervalTime
+_PR_MD_INTERVAL_PER_SEC()
+{
+    if (useHighResTimer) {
+        return _os2_ticksPerSec;
+    } else {
+        return 1000;
+    }
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2io.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2io.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,983 @@
+/* -*- 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 ***** */
+
+
+/*
+ * This Original Code has been modified by IBM Corporation.
+ * Modifications made by IBM described herein are
+ * Copyright (c) International Business Machines
+ * Corporation, 2000
+ *
+ * Modifications to Mozilla code or documentation
+ * identified per MPL Section 3.3
+ *
+ * Date             Modified by     Description of modification
+ * 03/23/2000       IBM Corp.       Changed write() to DosWrite(). EMX i/o
+ *                                  calls cannot be intermixed with DosXXX
+ *                                  calls since EMX remaps file/socket
+ *                                  handles.
+ * 04/27/2000       IBM Corp.       Changed open file to be more like NT and
+ *                                  better handle PR_TRUNCATE | PR_CREATE_FILE
+ *                                  and also fixed _PR_MD_SET_FD_INHERITABLE
+ */
+
+/* OS2 IO module
+ *
+ * Assumes synchronous I/O.
+ *
+ */
+
+#include "primpl.h"
+#include "prio.h"
+#include <ctype.h>
+#include <string.h>
+#ifdef XP_OS2_VACPP
+#include <direct.h>
+#else
+#include <limits.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+struct _MDLock               _pr_ioq_lock;
+
+static PRBool isWSEB = PR_FALSE; /* whether we are using an OS/2 kernel that supports large files */
+
+typedef APIRET (*DosOpenLType)(PSZ pszFileName, PHFILE pHf, PULONG pulAction,
+                            LONGLONG cbFile, ULONG ulAttribute,
+                            ULONG fsOpenFlags, ULONG fsOpenMode,
+                            PEAOP2 peaop2);
+
+typedef APIRET (*DosSetFileLocksLType)(HFILE hFile, PFILELOCKL pflUnlock,
+                                    PFILELOCKL pflLock, ULONG timeout,
+                                    ULONG flags);
+
+typedef APIRET (*DosSetFilePtrLType)(HFILE hFile, LONGLONG ib, ULONG method,
+                                  PLONGLONG ibActual);
+
+DosOpenLType myDosOpenL;
+DosSetFileLocksLType myDosSetFileLocksL;
+DosSetFilePtrLType myDosSetFilePtrL;
+
+void
+_PR_MD_INIT_IO()
+{
+    APIRET rc;
+    HMODULE module;
+
+    sock_init();
+    
+    rc = DosLoadModule(NULL, 0, "DOSCALL1", &module);
+    if (rc != NO_ERROR)
+    {
+        return;
+    }
+    rc = DosQueryProcAddr(module, 981, NULL, (PFN*) &myDosOpenL);
+    if (rc != NO_ERROR)
+    {
+        return;
+    }
+    rc = DosQueryProcAddr(module, 986, NULL, (PFN*) &myDosSetFileLocksL);
+    if (rc != NO_ERROR)
+    {
+        return;
+    }
+    rc = DosQueryProcAddr(module, 988, NULL, (PFN*) &myDosSetFilePtrL);
+    if (rc != NO_ERROR)
+    {
+        return;
+    }
+    isWSEB = PR_TRUE;
+}
+
+PRStatus
+_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PRInt32 rv;
+    ULONG count;
+
+    PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
+        SEM_INDEFINITE_WAIT : PR_IntervalToMilliseconds(ticks);
+    rv = DosWaitEventSem(thread->md.blocked_sema, msecs);
+    DosResetEventSem(thread->md.blocked_sema, &count); 
+    switch(rv) 
+    {
+        case NO_ERROR:
+            return PR_SUCCESS;
+            break;
+        case ERROR_TIMEOUT:
+            _PR_THREAD_LOCK(thread);
+            if (thread->state == _PR_IO_WAIT) {
+			  ;
+            } else {
+                if (thread->wait.cvar != NULL) {
+                    thread->wait.cvar = NULL;
+                    _PR_THREAD_UNLOCK(thread);
+                } else {
+                    /* The CVAR was notified just as the timeout
+                     * occurred.  This led to us being notified twice.
+                     * call SemRequest() to clear the semaphore.
+                     */
+                    _PR_THREAD_UNLOCK(thread);
+                    rv = DosWaitEventSem(thread->md.blocked_sema, 0);
+                    DosResetEventSem(thread->md.blocked_sema, &count); 
+                    PR_ASSERT(rv == NO_ERROR);
+                }
+            }
+            return PR_SUCCESS;
+            break;
+        default:
+            break;
+    }
+    return PR_FAILURE;
+}
+PRStatus
+_PR_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if ( _PR_IS_NATIVE_THREAD(thread) ) 
+    {
+        if (DosPostEventSem(thread->md.blocked_sema) != NO_ERROR)
+            return PR_FAILURE;
+        else
+			return PR_SUCCESS;
+	}
+}
+
+
+/* --- FILE IO ----------------------------------------------------------- */
+/*
+ *  _PR_MD_OPEN() -- Open a file
+ *
+ *  returns: a fileHandle
+ *
+ *  The NSPR open flags (osflags) are translated into flags for OS/2
+ *
+ *  Mode seems to be passed in as a unix style file permissions argument
+ *  as in 0666, in the case of opening the logFile. 
+ *
+ */
+PRInt32
+_PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
+{
+    HFILE file;
+    PRInt32 access = OPEN_SHARE_DENYNONE;
+    PRInt32 flags = 0L;
+    APIRET rc = 0;
+    PRUword actionTaken;
+
+    if (osflags & PR_SYNC) access |= OPEN_FLAGS_WRITE_THROUGH;
+
+    if (osflags & PR_RDONLY)
+        access |= OPEN_ACCESS_READONLY;
+    else if (osflags & PR_WRONLY)
+        access |= OPEN_ACCESS_WRITEONLY;
+    else if(osflags & PR_RDWR)
+        access |= OPEN_ACCESS_READWRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+    {
+        flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
+    }
+    else if (osflags & PR_CREATE_FILE)
+    {
+        if (osflags & PR_TRUNCATE)
+            flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
+        else
+            flags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
+    } 
+    else
+    {
+        if (osflags & PR_TRUNCATE)
+            flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
+        else
+            flags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
+    }
+
+    do {
+        if (isWSEB)
+        {
+                rc = myDosOpenL((char*)name,
+                     &file,            /* file handle if successful */
+                     &actionTaken,     /* reason for failure        */
+                     0,                /* initial size of new file  */
+                     FILE_NORMAL,      /* file system attributes    */
+                     flags,            /* Open flags                */
+                     access,           /* Open mode and rights      */
+                     0);               /* OS/2 Extended Attributes  */
+        }
+        else
+        {
+                rc = DosOpen((char*)name,
+                     &file,            /* file handle if successful */
+                     &actionTaken,     /* reason for failure        */
+                     0,                /* initial size of new file  */
+                     FILE_NORMAL,      /* file system attributes    */
+                     flags,            /* Open flags                */
+                     access,           /* Open mode and rights      */
+                     0);               /* OS/2 Extended Attributes  */
+        };
+        if (rc == ERROR_TOO_MANY_OPEN_FILES) {
+            ULONG CurMaxFH = 0;
+            LONG ReqCount = 20;
+            APIRET rc2;
+            rc2 = DosSetRelMaxFH(&ReqCount, &CurMaxFH);
+            if (rc2 != NO_ERROR) {
+                break;
+            }
+        }
+    } while (rc == ERROR_TOO_MANY_OPEN_FILES);
+
+    if (rc != NO_ERROR) {
+        _PR_MD_MAP_OPEN_ERROR(rc);
+        return -1; 
+    }
+
+    return (PRInt32)file;
+}
+
+PRInt32
+_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
+{
+    ULONG bytes;
+    int rv;
+
+    rv = DosRead((HFILE)fd->secret->md.osfd,
+                 (PVOID)buf,
+                 len,
+                 &bytes);
+    
+    if (rv != NO_ERROR) 
+    {
+        /* ERROR_HANDLE_EOF can only be returned by async io */
+        PR_ASSERT(rv != ERROR_HANDLE_EOF);
+        if (rv == ERROR_BROKEN_PIPE)
+            return 0;
+		else {
+			_PR_MD_MAP_READ_ERROR(rv);
+        return -1;
+    }
+    }
+    return (PRInt32)bytes;
+}
+
+PRInt32
+_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
+{
+    PRInt32 bytes;
+    int rv; 
+
+    rv = DosWrite((HFILE)fd->secret->md.osfd,
+                  (PVOID)buf,
+                  len,
+                  (PULONG)&bytes);
+
+    if (rv != NO_ERROR) 
+    {
+        _PR_MD_MAP_WRITE_ERROR(rv);
+        return -1;
+    }
+
+    if (len != bytes) {
+        rv = ERROR_DISK_FULL;
+        _PR_MD_MAP_WRITE_ERROR(rv);
+        return -1;
+    }
+
+    return bytes;
+} /* --- end _PR_MD_WRITE() --- */
+
+PRInt32
+_PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
+{
+    PRInt32 rv;
+    PRUword newLocation;
+
+    rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, offset, whence, &newLocation);
+
+	if (rv != NO_ERROR) {
+		_PR_MD_MAP_LSEEK_ERROR(rv);
+		return -1;
+	} else
+		return newLocation;
+}
+
+PRInt64
+_PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
+{
+#ifdef NO_LONG_LONG
+    PRInt64 result;
+    PRInt32 rv, low = offset.lo, hi = offset.hi;
+    PRUword newLocation;
+
+    rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, low, whence, &newLocation);
+    rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, hi, FILE_CURRENT, &newLocation);
+
+  	if (rv != NO_ERROR) {
+		_PR_MD_MAP_LSEEK_ERROR(rv);
+		hi = newLocation = -1;
+   }
+
+    result.lo = newLocation;
+    result.hi = hi;
+	return result;
+
+#else
+    PRInt32 where, rc, lo = (PRInt32)offset, hi = (PRInt32)(offset >> 32);
+    PRUint64 rv;
+    PRUint32 newLocation, uhi;
+    PRUint64 newLocationL;
+
+    switch (whence)
+      {
+      case PR_SEEK_SET:
+        where = FILE_BEGIN;
+        break;
+      case PR_SEEK_CUR:
+        where = FILE_CURRENT;
+        break;
+      case PR_SEEK_END:
+        where = FILE_END;
+        break;
+      default:
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+    if (isWSEB)
+    {
+        rc = myDosSetFilePtrL((HFILE)fd->secret->md.osfd, offset, where, (PLONGLONG)&newLocationL);
+    }
+    else
+    {
+        rc = DosSetFilePtr((HFILE)fd->secret->md.osfd, lo, where, (PULONG)&newLocation);
+    }
+     
+    if (rc != NO_ERROR) {
+      _PR_MD_MAP_LSEEK_ERROR(rc);
+      return -1;
+    }
+    
+    if (isWSEB)
+    {
+        return newLocationL;
+    }
+
+    uhi = (PRUint32)hi;
+    PR_ASSERT((PRInt32)uhi >= 0);
+    rv = uhi;
+    PR_ASSERT((PRInt64)rv >= 0);
+    rv = (rv << 32);
+    PR_ASSERT((PRInt64)rv >= 0);
+    rv += newLocation;
+    PR_ASSERT((PRInt64)rv >= 0);
+    return (PRInt64)rv;
+#endif
+}
+
+PRInt32
+_PR_MD_FSYNC(PRFileDesc *fd)
+{
+    PRInt32 rc = DosResetBuffer((HFILE)fd->secret->md.osfd);
+
+    if (rc != NO_ERROR) {
+   	if (rc != ERROR_ACCESS_DENIED) {	
+   			_PR_MD_MAP_FSYNC_ERROR(rc);
+   	    return -1;
+   	}
+    }
+    return 0;
+}
+
+PRInt32
+_MD_CloseFile(PRInt32 osfd)
+{
+    PRInt32 rv;
+    
+    rv = DosClose((HFILE)osfd);
+ 	if (rv != NO_ERROR)
+		_PR_MD_MAP_CLOSE_ERROR(rv);
+    return rv;
+}
+
+
+/* --- DIR IO ------------------------------------------------------------ */
+#define GetFileFromDIR(d)       (isWSEB?(d)->d_entry.large.achName:(d)->d_entry.small.achName)
+#define GetFileAttr(d)          (isWSEB?(d)->d_entry.large.attrFile:(d)->d_entry.small.attrFile)
+
+void FlipSlashes(char *cp, int len)
+{
+    while (--len >= 0) {
+    if (cp[0] == '/') {
+        cp[0] = PR_DIRECTORY_SEPARATOR;
+    }
+    cp++;
+    }
+}
+
+/*
+**
+** Local implementations of standard Unix RTL functions which are not provided
+** by the VAC RTL.
+**
+*/
+
+PRInt32
+_PR_MD_CLOSE_DIR(_MDDir *d)
+{
+   PRInt32 rc;
+
+    if ( d ) {
+      rc = DosFindClose(d->d_hdl);
+      if(rc == NO_ERROR){
+        d->magic = (PRUint32)-1;
+        return PR_SUCCESS;
+		} else {
+			_PR_MD_MAP_CLOSEDIR_ERROR(rc);
+        	return PR_FAILURE;
+		}
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return PR_FAILURE;
+}
+
+
+PRStatus
+_PR_MD_OPEN_DIR(_MDDir *d, const char *name)
+{
+    char filename[ CCHMAXPATH ];
+    PRUword numEntries, rc;
+
+    numEntries = 1;
+
+    PR_snprintf(filename, CCHMAXPATH, "%s%s%s",
+                name, PR_DIRECTORY_SEPARATOR_STR, "*.*");
+    FlipSlashes( filename, strlen(filename) );
+
+    d->d_hdl = HDIR_CREATE;
+
+    if (isWSEB)
+    {
+        rc = DosFindFirst( filename,
+                           &d->d_hdl,
+                           FILE_DIRECTORY | FILE_HIDDEN,
+                           &(d->d_entry.large),
+                           sizeof(d->d_entry.large),
+                           &numEntries,
+                           FIL_STANDARDL);
+    }
+    else
+    {
+        rc = DosFindFirst( filename,
+                           &d->d_hdl,
+                           FILE_DIRECTORY | FILE_HIDDEN,
+                           &(d->d_entry.small),
+                           sizeof(d->d_entry.small),
+                           &numEntries,
+                           FIL_STANDARD);
+    }
+    if ( rc != NO_ERROR ) {
+		_PR_MD_MAP_OPENDIR_ERROR(rc);
+        return PR_FAILURE;
+    }
+    d->firstEntry = PR_TRUE;
+    d->magic = _MD_MAGIC_DIR;
+    return PR_SUCCESS;
+}
+
+char *
+_PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
+{
+    PRUword numFiles = 1;
+    BOOL rv;
+    char *fileName;
+    USHORT fileAttr;
+
+    if ( d ) {
+       while (1) {
+           if (d->firstEntry) {
+               d->firstEntry = PR_FALSE;
+               rv = NO_ERROR;
+           } else {
+               rv = DosFindNext(d->d_hdl,
+                                &(d->d_entry),
+                                sizeof(d->d_entry),
+                                &numFiles);
+           }
+           if (rv != NO_ERROR) {
+               break;
+           }
+           fileName = GetFileFromDIR(d);
+           fileAttr = GetFileAttr(d);
+           if ( (flags & PR_SKIP_DOT) &&
+                (fileName[0] == '.') && (fileName[1] == '\0'))
+                continue;
+           if ( (flags & PR_SKIP_DOT_DOT) &&
+                (fileName[0] == '.') && (fileName[1] == '.') &&
+                (fileName[2] == '\0'))
+                continue;
+			/*
+			 * XXX
+			 * Is this the correct definition of a hidden file on OS/2?
+			 */
+           if ((flags & PR_SKIP_NONE) && (fileAttr & FILE_HIDDEN))
+                return fileName;
+           else if ((flags & PR_SKIP_HIDDEN) && (fileAttr & FILE_HIDDEN))
+                continue;
+           return fileName;
+        }
+        PR_ASSERT(NO_ERROR != rv);
+			_PR_MD_MAP_READDIR_ERROR(rv);
+        return NULL;
+		}
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return NULL;
+}
+
+PRInt32
+_PR_MD_DELETE(const char *name)
+{
+    PRInt32 rc = DosDelete((char*)name);
+    if(rc == NO_ERROR) {
+        return 0;
+    } else {
+		_PR_MD_MAP_DELETE_ERROR(rc);
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_STAT(const char *fn, struct stat *info)
+{
+    PRInt32 rv;
+    char filename[CCHMAXPATH];
+
+    PR_snprintf(filename, CCHMAXPATH, "%s", fn);
+    FlipSlashes(filename, strlen(filename));
+
+    rv = _stat((char*)filename, info);
+    if (-1 == rv) {
+        /*
+         * Check for MSVC runtime library _stat() bug.
+         * (It's really a bug in FindFirstFile().)
+         * If a pathname ends in a backslash or slash,
+         * e.g., c:\temp\ or c:/temp/, _stat() will fail.
+         * Note: a pathname ending in a slash (e.g., c:/temp/)
+         * can be handled by _stat() on NT but not on Win95.
+         *
+         * We remove the backslash or slash at the end and
+         * try again.  
+         *
+         * Not sure if this happens on OS/2 or not,
+         * but it doesn't hurt to be careful.
+         */
+
+        int len = strlen(fn);
+        if (len > 0 && len <= _MAX_PATH
+                && (fn[len - 1] == '\\' || fn[len - 1] == '/')) {
+            char newfn[_MAX_PATH + 1];
+
+            strcpy(newfn, fn);
+            newfn[len - 1] = '\0';
+            rv = _stat(newfn, info);
+        }
+    }
+
+    if (-1 == rv) {
+        _PR_MD_MAP_STAT_ERROR(errno);
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info)
+{
+    struct stat sb;
+    PRInt32 rv;
+    PRInt64 s, s2us;
+ 
+    if ( (rv = _PR_MD_STAT(fn, &sb)) == 0 ) {
+        if (info) {
+            if (S_IFREG & sb.st_mode)
+                info->type = PR_FILE_FILE ;
+            else if (S_IFDIR & sb.st_mode)
+                info->type = PR_FILE_DIRECTORY;
+            else
+                info->type = PR_FILE_OTHER;
+            info->size = sb.st_size;
+            LL_I2L(s2us, PR_USEC_PER_SEC);
+            LL_I2L(s, sb.st_mtime);
+            LL_MUL(s, s, s2us);
+            info->modifyTime = s;
+            LL_I2L(s, sb.st_ctime);
+            LL_MUL(s, s, s2us);
+            info->creationTime = s;
+        }
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
+{
+    PRFileInfo info32;
+    PRInt32 rv = _PR_MD_GETFILEINFO(fn, &info32);
+    if (rv != 0)
+    {
+        return rv;
+    }
+    info->type = info32.type;
+    LL_UI2L(info->size,info32.size);
+    info->modifyTime = info32.modifyTime;
+    info->creationTime = info32.creationTime;
+    
+    if (isWSEB)
+    {
+        APIRET rc ;
+        FILESTATUS3L fstatus;
+
+        rc = DosQueryPathInfo(fn, FIL_STANDARDL, &fstatus, sizeof(fstatus));
+
+        if (NO_ERROR != rc)
+        {
+            _PR_MD_MAP_OPEN_ERROR(rc);
+            return -1;
+        }
+
+        if (! (fstatus.attrFile & FILE_DIRECTORY))
+        {
+            info->size = fstatus.cbFile;
+        }
+    }
+
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
+{
+   /* For once, the VAC compiler/library did a nice thing.
+    * The file handle used by the C runtime is the same one
+    * returned by the OS when you call DosOpen().  This means
+    * that you can take an OS HFILE and use it with C file
+    * functions.  The only caveat is that you have to call
+    * _setmode() first to initialize some junk.  This is
+    * immensely useful because I did not have a clue how to
+    * implement this function otherwise.  The windows folks
+    * took the source from the Microsoft C library source, but
+    * IBM wasn't kind enough to ship the source with VAC.
+    * On second thought, the needed function could probably
+    * be gotten from the OS/2 GNU library source, but the
+    * point is now moot.
+    */
+   struct stat hinfo;
+    PRInt64 s, s2us;
+
+    _setmode(fd->secret->md.osfd, O_BINARY);
+    if(fstat((int)fd->secret->md.osfd, &hinfo) != NO_ERROR) {
+		_PR_MD_MAP_FSTAT_ERROR(errno);
+        return -1;
+	}
+
+    if (hinfo.st_mode & S_IFDIR)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_FILE;
+
+    info->size = hinfo.st_size;
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(s, hinfo.st_mtime);
+    LL_MUL(s, s, s2us);
+    info->modifyTime = s;
+    LL_I2L(s, hinfo.st_ctime);
+    LL_MUL(s, s, s2us);
+    info->creationTime = s;
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
+{
+    PRFileInfo info32;
+    PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, &info32);
+    if (0 == rv)
+    {
+       info->type = info32.type;
+       LL_UI2L(info->size,info32.size);
+    
+       info->modifyTime = info32.modifyTime;
+       info->creationTime = info32.creationTime;
+    }
+    
+    if (isWSEB)
+    {
+        APIRET rc ;
+        FILESTATUS3L fstatus;
+
+        rc = DosQueryFileInfo(fd->secret->md.osfd, FIL_STANDARDL, &fstatus, sizeof(fstatus));
+
+        if (NO_ERROR != rc)
+        {
+            _PR_MD_MAP_OPEN_ERROR(rc);
+            return -1;
+        }
+
+        if (! (fstatus.attrFile & FILE_DIRECTORY))
+        {
+            info->size = fstatus.cbFile;
+        }
+    }
+
+    return rv;
+}
+
+
+PRInt32
+_PR_MD_RENAME(const char *from, const char *to)
+{
+   PRInt32 rc;
+    /* Does this work with dot-relative pathnames? */
+    if ( (rc = DosMove((char *)from, (char *)to)) == NO_ERROR) {
+        return 0;
+    } else {
+		_PR_MD_MAP_RENAME_ERROR(rc);
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_ACCESS(const char *name, PRAccessHow how)
+{
+  PRInt32 rv;
+    switch (how) {
+      case PR_ACCESS_WRITE_OK:
+        rv = access(name, 02);
+		break;
+      case PR_ACCESS_READ_OK:
+        rv = access(name, 04);
+		break;
+      case PR_ACCESS_EXISTS:
+        return access(name, 00);
+	  	break;
+      default:
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+    }
+	if (rv < 0)
+		_PR_MD_MAP_ACCESS_ERROR(errno);
+    return rv;
+}
+
+PRInt32
+_PR_MD_MKDIR(const char *name, PRIntn mode)
+{
+   PRInt32 rc;
+    /* XXXMB - how to translate the "mode"??? */
+    if ((rc = DosCreateDir((char *)name, NULL))== NO_ERROR) {
+        return 0;
+    } else {
+		_PR_MD_MAP_MKDIR_ERROR(rc);
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_RMDIR(const char *name)
+{
+   PRInt32 rc;
+    if ( (rc = DosDeleteDir((char *)name)) == NO_ERROR) {
+        return 0;
+    } else {
+		_PR_MD_MAP_RMDIR_ERROR(rc);
+        return -1;
+    }
+}
+
+PRStatus
+_PR_MD_LOCKFILE(PRInt32 f)
+{
+    PRInt32   rv;
+    FILELOCK lock, unlock;
+    FILELOCKL lockL, unlockL;
+    
+    lock.lOffset = 0;
+    lockL.lOffset = 0;
+    lock.lRange = 0xffffffff;
+    lockL.lRange =  0xffffffffffffffff;
+    unlock.lOffset = 0;
+    unlock.lRange = 0;
+    unlockL.lOffset = 0;
+    unlockL.lRange = 0;
+
+    /*
+     * loop trying to DosSetFileLocks(),
+     * pause for a few miliseconds when can't get the lock
+     * and try again
+     */
+    for( rv = FALSE; rv == FALSE; /* do nothing */ )
+    {
+        if (isWSEB)
+        {
+	    rv = myDosSetFileLocksL( (HFILE) f,
+			                    &unlockL, &lockL,
+			                    0, 0);
+        }
+        else
+        {
+	    rv = DosSetFileLocks( (HFILE) f,
+			                    &unlock, &lock,
+			                    0, 0);
+        }
+		if ( rv != NO_ERROR )
+        {
+            DosSleep( 50 );  /* Sleep() a few milisecs and try again. */
+        }            
+    } /* end for() */
+    return PR_SUCCESS;
+} /* end _PR_MD_LOCKFILE() */
+
+PRStatus
+_PR_MD_TLOCKFILE(PRInt32 f)
+{
+    return _PR_MD_LOCKFILE(f);
+} /* end _PR_MD_TLOCKFILE() */
+
+
+PRStatus
+_PR_MD_UNLOCKFILE(PRInt32 f)
+{
+    PRInt32   rv;
+    FILELOCK lock, unlock;
+    FILELOCKL lockL, unlockL;
+    
+    lock.lOffset = 0;
+    lockL.lOffset = 0;
+    lock.lRange = 0;
+    lockL.lRange = 0;
+    unlock.lOffset = 0;
+    unlockL.lOffset = 0;
+    unlock.lRange = 0xffffffff;
+    unlockL.lRange = 0xffffffffffffffff;
+    
+    if (isWSEB)
+    {
+        rv = myDosSetFileLocksL( (HFILE) f,
+                                        &unlockL, &lockL,
+                                        0, 0);
+    }
+    else
+    {
+        rv = DosSetFileLocks( (HFILE) f,
+                                    &unlock, &lock,
+                                    0, 0);
+    }
+            
+    if ( rv != NO_ERROR )
+    {
+        return PR_SUCCESS;
+    }
+    else
+    {
+        return PR_FAILURE;
+    }
+} /* end _PR_MD_UNLOCKFILE() */
+
+PRStatus
+_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
+{
+    APIRET rc = 0;
+    ULONG flags;
+    switch (fd->methods->file_type)
+    {
+        case PR_DESC_PIPE:
+        case PR_DESC_FILE:
+            rc = DosQueryFHState((HFILE)fd->secret->md.osfd, &flags);
+            if (rc != NO_ERROR) {
+                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+                return PR_FAILURE;
+            }
+
+            if (inheritable)
+              flags &= ~OPEN_FLAGS_NOINHERIT;
+            else
+              flags |= OPEN_FLAGS_NOINHERIT;
+
+            /* Mask off flags DosSetFHState don't want. */
+            flags &= (OPEN_FLAGS_WRITE_THROUGH | OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_NOINHERIT);
+            rc = DosSetFHState((HFILE)fd->secret->md.osfd, flags);
+            if (rc != NO_ERROR) {
+                PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+                return PR_FAILURE;
+            }
+            break;
+
+        case PR_DESC_LAYERED:
+            /* what to do here? */
+            PR_SetError(PR_UNKNOWN_ERROR, 87 /*ERROR_INVALID_PARAMETER*/);
+            return PR_FAILURE;
+
+        case PR_DESC_SOCKET_TCP:
+        case PR_DESC_SOCKET_UDP:
+            /* These are global on OS/2. */
+            break;
+    }
+
+    return PR_SUCCESS;
+}
+
+void
+_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported)
+{
+    /* XXX this function needs to be implemented */
+    fd->secret->inheritable = _PR_TRI_UNKNOWN;
+}
+
+void
+_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd)
+{
+    /* XXX this function needs to be reviewed */
+    ULONG flags;
+
+    PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
+    if (DosQueryFHState((HFILE)fd->secret->md.osfd, &flags) == 0) {
+        if (flags & OPEN_FLAGS_NOINHERIT) {
+            fd->secret->inheritable = _PR_TRI_FALSE;
+        } else {
+            fd->secret->inheritable = _PR_TRI_TRUE;
+        }
+    }
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2misc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2misc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,566 @@
+/* -*- 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):
+ *   Davide Bresolin <davide at teamos2.it>
+ *
+ * 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 ***** */
+
+/*
+ * os2misc.c
+ *
+ */
+#include <string.h>
+#include "primpl.h"
+
+extern int   _CRT_init(void);
+extern void  _CRT_term(void);
+extern void __ctordtorInit(int flag);
+extern void __ctordtorTerm(int flag);
+
+char *
+_PR_MD_GET_ENV(const char *name)
+{
+    return getenv(name);
+}
+
+PRIntn
+_PR_MD_PUT_ENV(const char *name)
+{
+    return putenv(name);
+}
+
+
+/*
+ **************************************************************************
+ **************************************************************************
+ **
+ **     Date and time routines
+ **
+ **************************************************************************
+ **************************************************************************
+ */
+
+#include <sys/timeb.h>
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_Now --
+ *
+ *     Returns the current time in microseconds since the epoch.
+ *     The epoch is midnight January 1, 1970 GMT.
+ *     The implementation is machine dependent.  This is the
+ *     implementation for OS/2.
+ *     Cf. time_t time(time_t *tp)
+ *
+ *-----------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRTime)
+PR_Now(void)
+{
+    PRInt64 s, ms, ms2us, s2us;
+    struct timeb b;
+
+    ftime(&b);
+    LL_I2L(ms2us, PR_USEC_PER_MSEC);
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(s, b.time);
+    LL_I2L(ms, b.millitm);
+    LL_MUL(ms, ms, ms2us);
+    LL_MUL(s, s, s2us);
+    LL_ADD(s, s, ms);
+    return s;       
+}
+
+
+/*
+ ***********************************************************************
+ ***********************************************************************
+ *
+ * Process creation routines
+ *
+ ***********************************************************************
+ ***********************************************************************
+ */
+
+/*
+ * Assemble the command line by concatenating the argv array.
+ * On success, this function returns 0 and the resulting command
+ * line is returned in *cmdLine.  On failure, it returns -1.
+ */
+static int assembleCmdLine(char *const *argv, char **cmdLine)
+{
+    char *const *arg;
+    int cmdLineSize;
+
+    /*
+     * Find out how large the command line buffer should be.
+     */
+    cmdLineSize = 1; /* final null */
+    for (arg = argv+1; *arg; arg++) {
+        cmdLineSize += strlen(*arg) + 1; /* space in between */
+    }
+    *cmdLine = PR_MALLOC(cmdLineSize);
+    if (*cmdLine == NULL) {
+        return -1;
+    }
+
+    (*cmdLine)[0] = '\0';
+
+    for (arg = argv+1; *arg; arg++) {
+        if (arg > argv +1) {
+            strcat(*cmdLine, " ");
+        }
+        strcat(*cmdLine, *arg);
+    } 
+    return 0;
+}
+
+/*
+ * Assemble the environment block by concatenating the envp array
+ * (preserving the terminating null byte in each array element)
+ * and adding a null byte at the end.
+ *
+ * Returns 0 on success.  The resulting environment block is returned
+ * in *envBlock.  Note that if envp is NULL, a NULL pointer is returned
+ * in *envBlock.  Returns -1 on failure.
+ */
+static int assembleEnvBlock(char **envp, char **envBlock)
+{
+    char *p;
+    char *q;
+    char **env;
+    char *curEnv;
+    char *cwdStart, *cwdEnd;
+    int envBlockSize;
+
+    PPIB ppib = NULL;
+    PTIB ptib = NULL;
+
+    if (envp == NULL) {
+        *envBlock = NULL;
+        return 0;
+    }
+
+    if(DosGetInfoBlocks(&ptib, &ppib) != NO_ERROR)
+       return -1;
+
+    curEnv = ppib->pib_pchenv;
+
+    cwdStart = curEnv;
+    while (*cwdStart) {
+        if (cwdStart[0] == '=' && cwdStart[1] != '\0'
+                && cwdStart[2] == ':' && cwdStart[3] == '=') {
+            break;
+        }
+        cwdStart += strlen(cwdStart) + 1;
+    }
+    cwdEnd = cwdStart;
+    if (*cwdEnd) {
+        cwdEnd += strlen(cwdEnd) + 1;
+        while (*cwdEnd) {
+            if (cwdEnd[0] != '=' || cwdEnd[1] == '\0'
+                    || cwdEnd[2] != ':' || cwdEnd[3] != '=') {
+                break;
+            }
+            cwdEnd += strlen(cwdEnd) + 1;
+        }
+    }
+    envBlockSize = cwdEnd - cwdStart;
+
+    for (env = envp; *env; env++) {
+        envBlockSize += strlen(*env) + 1;
+    }
+    envBlockSize++;
+
+    p = *envBlock = PR_MALLOC(envBlockSize);
+    if (p == NULL) {
+        return -1;
+    }
+
+    q = cwdStart;
+    while (q < cwdEnd) {
+        *p++ = *q++;
+    }
+
+    for (env = envp; *env; env++) {
+        q = *env;
+        while (*q) {
+            *p++ = *q++;
+        }
+        *p++ = '\0';
+    }
+    *p = '\0';
+    return 0;
+}
+
+/*
+ * For qsort.  We sort (case-insensitive) the environment strings
+ * before generating the environment block.
+ */
+static int compare(const void *arg1, const void *arg2)
+{
+    return stricmp(* (char**)arg1, * (char**)arg2);
+}
+
+PRProcess * _PR_CreateOS2Process(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    PRProcess *proc = NULL;
+    char *cmdLine = NULL;
+    char **newEnvp = NULL;
+    char *envBlock = NULL;
+   
+    STARTDATA startData = {0};
+    APIRET    rc;
+    ULONG     ulAppType = 0;
+    PID       pid = 0;
+    char     *pEnvWPS = NULL;
+    char     *pszComSpec;
+    char      pszEXEName[CCHMAXPATH] = "";
+    char      pszFormatString[CCHMAXPATH];
+    char      pszObjectBuffer[CCHMAXPATH];
+    char     *pszFormatResult = NULL;
+
+    /*
+     * Variables for DosExecPgm
+     */
+    char szFailed[CCHMAXPATH];
+    char *pszCmdLine = NULL;
+    RESULTCODES procInfo;
+    HFILE hStdIn  = 0,
+          hStdOut = 0,
+          hStdErr = 0;
+    HFILE hStdInSave  = -1,
+          hStdOutSave = -1,
+          hStdErrSave = -1;
+
+    proc = PR_NEW(PRProcess);
+    if (!proc) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+   
+    if (assembleCmdLine(argv, &cmdLine) == -1) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+   
+    if (envp == NULL) {
+        newEnvp = NULL;
+    } else {
+        int i;
+        int numEnv = 0;
+        while (envp[numEnv]) {
+            numEnv++;
+        }
+        newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *));
+        for (i = 0; i <= numEnv; i++) {
+            newEnvp[i] = envp[i];
+        }
+        qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare);
+    }
+    if (assembleEnvBlock(newEnvp, &envBlock) == -1) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+  
+    rc = DosQueryAppType(path, &ulAppType);
+    if (rc != NO_ERROR) {
+       char *pszDot = strrchr(path, '.');
+       if (pszDot) {
+          /* If it is a CMD file, launch the users command processor */
+          if (!stricmp(pszDot, ".cmd")) {
+             rc = DosScanEnv("COMSPEC", &pszComSpec);
+             if (!rc) {
+                strcpy(pszFormatString, "/C %s %s");
+                strcpy(pszEXEName, pszComSpec);
+                ulAppType = FAPPTYP_WINDOWCOMPAT;
+             }
+          }
+       }
+    }
+    if (ulAppType == 0) {
+       PR_SetError(PR_UNKNOWN_ERROR, 0);
+       goto errorExit;
+    }
+ 
+    if ((ulAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) {
+        startData.SessionType = SSF_TYPE_PM;
+    }
+    else if (ulAppType & FAPPTYP_WINDOWCOMPAT) {
+        startData.SessionType = SSF_TYPE_WINDOWABLEVIO;
+    }
+    else {
+        startData.SessionType = SSF_TYPE_DEFAULT;
+    }
+ 
+    if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL))
+    {
+        strcpy(pszEXEName, "WINOS2.COM");
+        startData.SessionType = PROG_31_STDSEAMLESSVDM;
+        strcpy(pszFormatString, "/3 %s %s");
+    }
+ 
+    startData.InheritOpt = SSF_INHERTOPT_SHELL;
+ 
+    if (pszEXEName[0]) {
+        pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine));
+        sprintf(pszFormatResult, pszFormatString, path, cmdLine);
+        startData.PgmInputs = pszFormatResult;
+    } else {
+        strcpy(pszEXEName, path);
+        startData.PgmInputs = cmdLine;
+    }
+    startData.PgmName = pszEXEName;
+ 
+    startData.Length = sizeof(startData);
+    startData.Related = SSF_RELATED_INDEPENDENT;
+    startData.ObjectBuffer = pszObjectBuffer;
+    startData.ObjectBuffLen = CCHMAXPATH;
+    startData.Environment = envBlock;
+ 
+    if (attr) {
+        /* On OS/2, there is really no way to pass file handles for stdin,
+         * stdout, and stderr to a new process.  Instead, we can make it
+         * a child process and make the given file handles a copy of our
+         * stdin, stdout, and stderr.  The child process then inherits
+         * ours, and we set ours back.  Twisted and gross I know. If you
+         * know a better way, please use it.
+         */
+        if (attr->stdinFd) {
+            hStdIn = 0;
+            DosDupHandle(hStdIn, &hStdInSave);
+            DosDupHandle((HFILE) attr->stdinFd->secret->md.osfd, &hStdIn);
+        }
+
+        if (attr->stdoutFd) {
+            hStdOut = 1;
+            DosDupHandle(hStdOut, &hStdOutSave);
+            DosDupHandle((HFILE) attr->stdoutFd->secret->md.osfd, &hStdOut);
+        }
+
+        if (attr->stderrFd) {
+            hStdErr = 2;
+            DosDupHandle(hStdErr, &hStdErrSave);
+            DosDupHandle((HFILE) attr->stderrFd->secret->md.osfd, &hStdErr);
+        }
+        /*
+         * Build up the Command Line for DosExecPgm
+         */
+        pszCmdLine = PR_MALLOC(strlen(pszEXEName) +
+                               strlen(startData.PgmInputs) + 3);
+        sprintf(pszCmdLine, "%s%c%s%c", pszEXEName, '\0',
+                startData.PgmInputs, '\0');
+        rc = DosExecPgm(szFailed,
+                        CCHMAXPATH,
+                        EXEC_ASYNCRESULT,
+                        pszCmdLine,
+                        envBlock,
+                        &procInfo,
+                        pszEXEName);
+        PR_DELETE(pszCmdLine);
+
+        /* Restore our old values.  Hope this works */
+        if (hStdInSave != -1) {
+            DosDupHandle(hStdInSave, &hStdIn);
+            DosClose(hStdInSave);
+        }
+
+        if (hStdOutSave != -1) {
+            DosDupHandle(hStdOutSave, &hStdOut);
+            DosClose(hStdOutSave);
+        }
+
+        if (hStdErrSave != -1) {
+            DosDupHandle(hStdErrSave, &hStdErr);
+            DosClose(hStdErrSave);
+        }
+
+        if (rc != NO_ERROR) {
+            /* XXX what error code? */
+            PR_SetError(PR_UNKNOWN_ERROR, rc);
+            goto errorExit;
+        }
+
+        proc->md.pid = procInfo.codeTerminate;
+    } else {	
+        /*
+         * If no STDIN/STDOUT redirection is not needed, use DosStartSession
+         * to create a new, independent session
+         */
+        rc = DosStartSession(&startData, &ulAppType, &pid);
+
+        if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) {
+            PR_SetError(PR_UNKNOWN_ERROR, rc);
+            goto errorExit;
+        }
+ 
+        proc->md.pid = pid;
+    }
+
+    if (pszFormatResult) {
+        PR_DELETE(pszFormatResult);
+    }
+
+    PR_DELETE(cmdLine);
+    if (newEnvp) {
+        PR_DELETE(newEnvp);
+    }
+    if (envBlock) {
+        PR_DELETE(envBlock);
+    }
+    return proc;
+
+errorExit:
+    if (cmdLine) {
+        PR_DELETE(cmdLine);
+    }
+    if (newEnvp) {
+        PR_DELETE(newEnvp);
+    }
+    if (envBlock) {
+        PR_DELETE(envBlock);
+    }
+    if (proc) {
+        PR_DELETE(proc);
+    }
+    return NULL;
+}  /* _PR_CreateOS2Process */
+
+PRStatus _PR_DetachOS2Process(PRProcess *process)
+{
+    /* On OS/2, a process is either created as a child or not. 
+     * You can't 'detach' it later on.
+     */
+    PR_DELETE(process);
+    return PR_SUCCESS;
+}
+
+/*
+ * XXX: This will currently only work on a child process.
+ */
+PRStatus _PR_WaitOS2Process(PRProcess *process,
+    PRInt32 *exitCode)
+{
+    ULONG ulRetVal;
+    RESULTCODES results;
+    PID pidEnded = 0;
+
+    ulRetVal = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, 
+                            &results,
+                            &pidEnded, process->md.pid);
+
+    if (ulRetVal != NO_ERROR) {
+       printf("\nDosWaitChild rc = %lu\n", ulRetVal);
+        PR_SetError(PR_UNKNOWN_ERROR, ulRetVal);
+        return PR_FAILURE;
+    }
+    PR_DELETE(process);
+    return PR_SUCCESS;
+}
+
+PRStatus _PR_KillOS2Process(PRProcess *process)
+{
+   ULONG ulRetVal;
+    if ((ulRetVal = DosKillProcess(DKP_PROCESS, process->md.pid)) == NO_ERROR) {
+	return PR_SUCCESS;
+    }
+    PR_SetError(PR_UNKNOWN_ERROR, ulRetVal);
+    return PR_FAILURE;
+}
+
+PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen)
+{
+    PRIntn rv;
+
+    rv = gethostname(name, (PRInt32) namelen);
+    if (0 == rv) {
+        return PR_SUCCESS;
+    }
+	_PR_MD_MAP_GETHOSTNAME_ERROR(sock_errno());
+    return PR_FAILURE;
+}
+
+void
+_PR_MD_WAKEUP_CPUS( void )
+{
+    return;
+}    
+
+
+/*
+ **********************************************************************
+ *
+ * Memory-mapped files are not supported on OS/2 (or Win16).
+ *
+ **********************************************************************
+ */
+
+PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRInt32 _MD_GetMemMapAlignment(void)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return -1;
+}
+
+void * _MD_MemMap(
+    PRFileMap *fmap,
+    PROffset64 offset,
+    PRUint32 len)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PRStatus _MD_MemUnmap(void *addr, PRUint32 len)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRStatus _MD_CloseFileMap(PRFileMap *fmap)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2poll.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2poll.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,382 @@
+/* -*- 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 ***** */
+
+/*
+ * This file implements _PR_MD_PR_POLL for OS/2.
+ */
+
+#ifdef XP_OS2_EMX
+ #include <sys/time.h> /* For timeval. */
+#endif
+
+#include "primpl.h"
+
+#ifndef BSD_SELECT
+/* Utility functions called when using OS/2 select */
+
+PRBool IsSocketSet( PRInt32 osfd, int* socks, int start, int count )
+{
+  int i;
+  PRBool isSet = PR_FALSE;
+
+  for( i = start; i < start+count; i++ )
+  {
+    if( socks[i] == osfd )
+      isSet = PR_TRUE;
+  }
+  
+  return isSet; 
+}
+#endif
+
+PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+#ifdef BSD_SELECT
+    fd_set rd, wt, ex;
+#else
+    int rd, wt, ex;
+    int* socks;
+    unsigned long msecs;
+    int i, j;
+#endif
+    PRFileDesc *bottom;
+    PRPollDesc *pd, *epd;
+    PRInt32 maxfd = -1, ready, err;
+    PRIntervalTime remaining, elapsed, start;
+
+#ifdef BSD_SELECT
+    struct timeval tv, *tvp = NULL;
+
+    FD_ZERO(&rd);
+    FD_ZERO(&wt);
+    FD_ZERO(&ex);
+#else
+    rd = 0;
+    wt = 0;
+    ex = 0;
+    socks = (int) PR_MALLOC( npds * 3 * sizeof(int) );
+    
+    if (!socks)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+#endif
+
+    ready = 0;
+    for (pd = pds, epd = pd + npds; pd < epd; pd++)
+    {
+        PRInt16 in_flags_read = 0, in_flags_write = 0;
+        PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+        if ((NULL != pd->fd) && (0 != pd->in_flags))
+        {
+            if (pd->in_flags & PR_POLL_READ)
+            {
+                in_flags_read = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
+            }
+            if (pd->in_flags & PR_POLL_WRITE)
+            {
+                in_flags_write = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
+            }
+            if ((0 != (in_flags_read & out_flags_read)) ||
+                (0 != (in_flags_write & out_flags_write)))
+            {
+                /* this one's ready right now */
+                if (0 == ready)
+                {
+                    /*
+                     * We will have to return without calling the
+                     * system poll/select function.  So zero the
+                     * out_flags fields of all the poll descriptors
+                     * before this one.
+                     */
+                    PRPollDesc *prev;
+                    for (prev = pds; prev < pd; prev++)
+                    {
+                        prev->out_flags = 0;
+                    }
+                }
+                ready += 1;
+                pd->out_flags = out_flags_read | out_flags_write;
+            }
+            else
+            {
+                pd->out_flags = 0;  /* pre-condition */
+
+                /* make sure this is an NSPR supported stack */
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                if ((NULL != bottom) &&
+                    (_PR_FILEDESC_OPEN == bottom->secret->state))
+                {
+                    if (0 == ready)
+                    {
+                        PRInt32 osfd = bottom->secret->md.osfd;
+                        if (osfd > maxfd) 
+                            maxfd = osfd;
+                        if (in_flags_read & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
+#ifdef BSD_SELECT
+                            FD_SET(osfd, &rd);
+#else
+                            socks[rd] = osfd;
+                            rd++;              
+#endif
+                        }
+                        if (in_flags_read & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
+#ifdef BSD_SELECT
+                            FD_SET(osfd, &wt);
+#else
+                            socks[npds+wt] = osfd;
+                            wt++;              
+#endif
+                        }
+                        if (in_flags_write & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
+#ifdef BSD_SELECT
+                            FD_SET(osfd, &rd);
+#else
+                            socks[rd] = osfd;
+                            rd++;              
+#endif
+                        }
+                        if (in_flags_write & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
+#ifdef BSD_SELECT
+                            FD_SET(osfd, &wt);
+#else
+                            socks[npds+wt] = osfd;
+                            wt++;              
+#endif
+                        }
+                        if (pd->in_flags & PR_POLL_EXCEPT)
+                        {
+#ifdef BSD_SELECT
+                            FD_SET(osfd, &ex);
+#else
+                            socks[npds*2+ex] = osfd;
+                            ex++;
+#endif
+                        }
+                    }
+                }
+                else
+                {
+                    if (0 == ready)
+                    {
+                        PRPollDesc *prev;
+                        for (prev = pds; prev < pd; prev++)
+                        {
+                            prev->out_flags = 0;
+                        }
+                    }
+                    ready += 1;  /* this will cause an abrupt return */
+                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
+                }
+            }
+        }
+        else
+        {
+            pd->out_flags = 0;
+        }
+    }
+
+    if (0 != ready)
+    {
+#ifndef BSD_SELECT
+        PR_Free(socks);
+#endif
+        return ready;  /* no need to block */
+    }
+
+    remaining = timeout;
+    start = PR_IntervalNow();
+
+retry:
+#ifdef BSD_SELECT
+    if (timeout != PR_INTERVAL_NO_TIMEOUT)
+    {
+        PRInt32 ticksPerSecond = PR_TicksPerSecond();
+        tv.tv_sec = remaining / ticksPerSecond;
+        tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
+        tvp = &tv;
+    }
+
+    ready = bsdselect(maxfd + 1, &rd, &wt, &ex, tvp);
+#else
+    switch (timeout)
+    {
+        case PR_INTERVAL_NO_WAIT:
+            msecs = 0;
+            break;
+        case PR_INTERVAL_NO_TIMEOUT:
+            msecs = -1;
+            break;
+        default:
+            msecs = PR_IntervalToMilliseconds(remaining);
+    }
+
+     /* compact array */
+    for( i = rd, j = npds; j < npds+wt; i++,j++ )
+        socks[i] = socks[j];
+    for( i = rd+wt, j = npds*2; j < npds*2+ex; i++,j++ )
+        socks[i] = socks[j];
+    
+    ready = os2_select(socks, rd, wt, ex, msecs);
+#endif
+
+    if (ready == -1 && errno == EINTR)
+    {
+        if (timeout == PR_INTERVAL_NO_TIMEOUT)
+            goto retry;
+        else
+        {
+            elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
+            if (elapsed > timeout)
+                ready = 0;  /* timed out */
+            else
+            {
+                remaining = timeout - elapsed;
+                goto retry;
+            }
+        }
+    }
+
+    /*
+    ** Now to unravel the select sets back into the client's poll
+    ** descriptor list. Is this possibly an area for pissing away
+    ** a few cycles or what?
+    */
+    if (ready > 0)
+    {
+        ready = 0;
+        for (pd = pds, epd = pd + npds; pd < epd; pd++)
+        {
+            PRInt16 out_flags = 0;
+            if ((NULL != pd->fd) && (0 != pd->in_flags))
+            {
+                PRInt32 osfd;
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);
+
+                osfd = bottom->secret->md.osfd;
+
+#ifdef BSD_SELECT
+                if (FD_ISSET(osfd, &rd))
+#else
+                if( IsSocketSet(osfd, socks, 0, rd) )        
+#endif
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+
+#ifdef BSD_SELECT
+                if (FD_ISSET(osfd, &wt))
+#else
+                if( IsSocketSet(osfd, socks, rd, wt) )        
+#endif
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+
+#ifdef BSD_SELECT
+                if (FD_ISSET(osfd, &ex))
+#else
+                if( IsSocketSet(osfd, socks, rd+wt, ex) )        
+#endif
+                {
+                    out_flags |= PR_POLL_EXCEPT;
+                }
+            }
+            pd->out_flags = out_flags;
+            if (out_flags) ready++;
+        }
+        PR_ASSERT(ready > 0);
+    }
+    else if (ready < 0)
+    {
+        err = _MD_ERRNO();
+        if (err == EBADF)
+        {
+            /* Find the bad fds */
+            int optval;
+            int optlen = sizeof(optval);
+            ready = 0;
+            for (pd = pds, epd = pd + npds; pd < epd; pd++)
+            {
+                pd->out_flags = 0;
+                if ((NULL != pd->fd) && (0 != pd->in_flags))
+                {
+                    bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                    if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET,
+                        SO_TYPE, (char *) &optval, &optlen) == -1)
+                    {
+                        PR_ASSERT(sock_errno() == ENOTSOCK);
+                        if (sock_errno() == ENOTSOCK)
+                        {
+                            pd->out_flags = PR_POLL_NVAL;
+                            ready++;
+                        }
+                    }
+                }
+            }
+            PR_ASSERT(ready > 0);
+        }
+        else
+            _PR_MD_MAP_SELECT_ERROR(err);
+    }
+
+#ifndef BSD_SELECT
+    PR_Free(socks);
+#endif
+    return ready;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2rng.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2rng.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,110 @@
+/* -*- 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 ***** */
+
+
+#define INCL_DOS
+#define INCL_DOSERRORS
+#include <os2.h>
+#include <stdlib.h>
+#include <time.h>
+#include "primpl.h"
+
+static BOOL clockTickTime(unsigned long *phigh, unsigned long *plow)
+{
+    APIRET rc = NO_ERROR;
+    QWORD qword = {0,0};
+
+    rc = DosTmrQueryTime(&qword);
+    if (rc != NO_ERROR)
+       return FALSE;
+
+    *phigh = qword.ulHi;
+    *plow  = qword.ulLo;
+
+    return TRUE;
+}
+
+extern PRSize _PR_MD_GetRandomNoise(void *buf, PRSize size )
+{
+    unsigned long high = 0;
+    unsigned long low  = 0;
+    clock_t val = 0;
+    int n = 0;
+    int nBytes = 0;
+    time_t sTime;
+
+    if (size <= 0)
+       return 0;
+
+    clockTickTime(&high, &low);
+
+    /* get the maximally changing bits first */
+    nBytes = sizeof(low) > size ? size : sizeof(low);
+    memcpy(buf, &low, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+       return n;
+
+    nBytes = sizeof(high) > size ? size : sizeof(high);
+    memcpy(((char *)buf) + n, &high, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+       return n;
+
+    /* get the number of milliseconds that have elapsed since application started */
+    val = clock();
+
+    nBytes = sizeof(val) > size ? size : sizeof(val);
+    memcpy(((char *)buf) + n, &val, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+       return n;
+
+    /* get the time in seconds since midnight Jan 1, 1970 */
+    time(&sTime);
+    nBytes = sizeof(sTime) > size ? size : sizeof(sTime);
+    memcpy(((char *)buf) + n, &sTime, nBytes);
+    n += nBytes;
+
+    return n;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2sem.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2sem.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,93 @@
+/* -*- 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 ***** */
+
+/*
+ * OS/2-specific semaphore handling code.
+ *
+ */
+
+#include "primpl.h"
+
+
+void
+_PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value)
+{
+   int rv;
+
+    /* Our Sems don't support a value > 1 */
+    PR_ASSERT(value <= 1);
+
+    rv = DosCreateEventSem(NULL, &md->sem, 0, 0);
+    PR_ASSERT(rv == NO_ERROR);
+}
+
+void
+_PR_MD_DESTROY_SEM(_MDSemaphore *md)
+{
+   int rv;
+   rv = DosCloseEventSem(md->sem);
+   PR_ASSERT(rv == NO_ERROR);
+
+}
+
+PRStatus
+_PR_MD_TIMED_WAIT_SEM(_MDSemaphore *md, PRIntervalTime ticks)
+{
+    int rv;
+    rv = DosWaitEventSem(md->sem, PR_IntervalToMilliseconds(ticks));
+
+    if (rv == NO_ERROR)
+        return PR_SUCCESS;
+    else
+        return PR_FAILURE;
+}
+
+PRStatus
+_PR_MD_WAIT_SEM(_MDSemaphore *md)
+{
+    return _PR_MD_TIMED_WAIT_SEM(md, PR_INTERVAL_NO_TIMEOUT);
+}
+
+void
+_PR_MD_POST_SEM(_MDSemaphore *md)
+{
+   int rv;
+   rv = DosPostEventSem(md->sem);
+   PR_ASSERT(rv == NO_ERROR); 
+}
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2sock.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2sock.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,684 @@
+/* -*- 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 ***** */
+
+/* OS/2 Sockets module
+ *
+ */
+
+/*Note from DSR111297 - it should be noted that there are two flavors of select() on OS/2    */
+/*There is standard BSD (which is kind of slow) and a new flavor of select() that takes      */
+/*an integer list of sockets, the number of read sockets, write sockets, except sockets, and */
+/*a millisecond count for timeout. In the interest of performance I have choosen the OS/2    */
+/*specific version of select(). See OS/2 TCP/IP Programmer's Toolkit for more info.          */ 
+
+#include "primpl.h"
+
+#ifdef XP_OS2_EMX
+ #include <sys/time.h> /* For timeval. */
+#endif
+
+#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5
+#define READ_FD   1
+#define WRITE_FD  2
+
+#ifdef XP_OS2_VACPP
+#define _OS2_WRITEV writev
+#define _OS2_IOCTL ioctl
+#else
+#define _OS2_WRITEV so_writev
+#define _OS2_IOCTL so_ioctl
+#endif
+
+/* --- SOCKET IO --------------------------------------------------------- */
+
+
+PRInt32
+_PR_MD_SOCKET(int domain, int type, int flags)
+{
+    PRInt32 osfd, err;
+
+    osfd = socket(domain, type, flags);
+
+    if (osfd == -1) 
+    {
+        err = sock_errno();
+        _PR_MD_MAP_SOCKET_ERROR(err);
+    }
+
+    return(osfd);
+}
+
+/*
+** _MD_CloseSocket() -- Close a socket
+**
+*/
+PRInt32
+_MD_CloseSocket(PRInt32 osfd)
+{
+    PRInt32 rv, err;
+
+    rv = soclose(osfd);
+    if (rv == -1) {
+        err = sock_errno();
+        _PR_MD_MAP_CLOSE_ERROR(err);
+    }
+    return rv;
+}
+
+PRInt32
+_MD_SocketAvailable(PRFileDesc *fd)
+{
+    PRInt32 result;
+
+    if (_OS2_IOCTL(fd->secret->md.osfd, FIONREAD, (char *) &result, sizeof(result)) < 0) {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, sock_errno());
+        return -1;
+    }
+    return result;
+}
+
+static PRInt32
+socket_io_wait( PRInt32 osfd, PRInt32 fd_type, PRIntervalTime timeout )
+{
+    PRInt32 rv = -1;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntervalTime epoch, now, elapsed, remaining;
+    PRBool wait_for_remaining;
+    PRInt32 syserror;
+#ifdef BSD_SELECT
+    struct timeval tv;
+    fd_set rd_wr;
+#else
+    int socks[1];
+    long lTimeout;
+#endif
+
+    switch (timeout) {
+        case PR_INTERVAL_NO_WAIT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+            break;
+        case PR_INTERVAL_NO_TIMEOUT:
+            /*
+             * This is a special case of the 'default' case below.
+             * Please see the comments there.
+             */
+#ifdef BSD_SELECT
+            tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+            tv.tv_usec = 0;
+            FD_ZERO(&rd_wr);
+            do {
+                FD_SET(osfd, &rd_wr);
+                if (fd_type == READ_FD)
+                    rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv);
+                else
+                    rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv);
+#else
+            lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000; 
+            do {
+                socks[0] = osfd;
+                if (fd_type == READ_FD)
+                    rv = os2_select(socks, 1, 0, 0, lTimeout);
+                else
+                    rv = os2_select(socks, 0, 1, 0, lTimeout);
+#endif                    
+                if (rv == -1 && (syserror = sock_errno()) != EINTR) {
+                    _PR_MD_MAP_SELECT_ERROR(syserror);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+        default:
+            now = epoch = PR_IntervalNow();
+            remaining = timeout;
+#ifdef BSD_SELECT
+            FD_ZERO(&rd_wr);
+#endif
+            do {
+                /*
+                 * We block in select for at most
+                 * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
+                 * so that there is an upper limit on the delay
+                 * before the interrupt bit is checked.
+                 */
+#ifdef BSD_SELECT
+                wait_for_remaining = PR_TRUE;
+                tv.tv_sec = PR_IntervalToSeconds(remaining);
+                if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
+                    wait_for_remaining = PR_FALSE;
+                    tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+                    tv.tv_usec = 0;
+                } else {
+                    tv.tv_usec = PR_IntervalToMicroseconds(
+                        remaining -
+                        PR_SecondsToInterval(tv.tv_sec));
+                }
+                FD_SET(osfd, &rd_wr);
+                if (fd_type == READ_FD)
+                    rv = bsdselect(osfd + 1, &rd_wr, NULL, NULL, &tv);
+                else
+                    rv = bsdselect(osfd + 1, NULL, &rd_wr, NULL, &tv);
+#else
+                wait_for_remaining = PR_TRUE;
+                lTimeout = PR_IntervalToMilliseconds(remaining);
+                if (lTimeout > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) {
+                    wait_for_remaining = PR_FALSE;
+                    lTimeout = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
+                }
+                socks[0] = osfd;
+                if (fd_type == READ_FD)
+                    rv = os2_select(socks, 1, 0, 0, lTimeout);
+                else
+                    rv = os2_select(socks, 0, 1, 0, lTimeout);
+#endif
+                /*
+                 * we don't consider EINTR a real error
+                 */
+                if (rv == -1 && (syserror = sock_errno()) != EINTR) {
+                    _PR_MD_MAP_SELECT_ERROR(syserror);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+                /*
+                 * We loop again if select timed out or got interrupted
+                 * by a signal, and the timeout deadline has not passed yet.
+                 */
+                if (rv == 0 || (rv == -1 && syserror == EINTR)) {
+                    /*
+                     * If select timed out, we know how much time
+                     * we spent in blocking, so we can avoid a
+                     * PR_IntervalNow() call.
+                     */
+                    if (rv == 0) {
+                        if (wait_for_remaining) {
+                            now += remaining;
+                        } else {
+#ifdef BSD_SELECT
+                            now += PR_SecondsToInterval(tv.tv_sec)
+                                + PR_MicrosecondsToInterval(tv.tv_usec);
+#else
+                            now += PR_MillisecondsToInterval(lTimeout);
+#endif
+                        }
+                    } else {
+                        now = PR_IntervalNow();
+                    }
+                    elapsed = (PRIntervalTime) (now - epoch);
+                    if (elapsed >= timeout) {
+                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                        rv = -1;
+                        break;
+                    } else {
+                        remaining = timeout - elapsed;
+                    }
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+        }
+    return(rv);
+}
+
+PRInt32
+_MD_Accept(PRFileDesc *fd, PRNetAddr *addr,
+           PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((rv = accept(osfd, (struct sockaddr*) addr, (int*)addrlen)) == -1)
+    {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK) || (err == ECONNABORTED))
+        {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+                if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                    goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_ACCEPT_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, 
+               PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRNetAddr addrCopy = *addr; /* Work around a bug in OS/2 where connect
+                                 * modifies the sockaddr structure.
+                                 * See Bugzilla bug 100776. */
+
+     /*
+      * We initiate the connection setup by making a nonblocking connect()
+      * call.  If the connect() call fails, there are two cases we handle
+      * specially:
+      * 1. The connect() call was interrupted by a signal.  In this case
+      *    we simply retry connect().
+      * 2. The NSPR socket is nonblocking and connect() fails with
+      *    EINPROGRESS.  We first wait until the socket becomes writable.
+      *    Then we try to find out whether the connection setup succeeded
+      *    or failed.
+      */
+
+retry:
+    if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1)
+    {
+        err = sock_errno();
+
+        if (err == EINTR) {
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+            goto retry;
+        }
+
+        if (!fd->secret->nonblocking && (err == EINPROGRESS))
+        {
+            /*
+             * socket_io_wait() may return -1 or 1.
+             */
+
+            rv = socket_io_wait(osfd, WRITE_FD, timeout);
+            if (rv == -1) {
+                return -1;
+            }
+
+            PR_ASSERT(rv == 1);
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+            err = _MD_os2_get_nonblocking_connect_error(osfd);
+            if (err != 0) {
+                _PR_MD_MAP_CONNECT_ERROR(err);
+                return -1;
+            }
+            return 0;
+        }
+        
+        _PR_MD_MAP_CONNECT_ERROR(err);
+    }
+
+    return rv;
+}  /* _MD_connect */
+
+PRInt32
+_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
+{
+    PRInt32 rv, err;
+    rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen);
+    if (rv < 0) {
+        err = sock_errno();
+        _PR_MD_MAP_BIND_ERROR(err);
+    }
+    return(rv);
+}
+
+
+PRInt32
+_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog)
+{
+    PRInt32 rv, err;
+    rv = listen(fd->secret->md.osfd, backlog);
+    if (rv < 0)  {
+        err = sock_errno();
+        _PR_MD_MAP_DEFAULT_ERROR(err);
+    }
+    return(rv);
+}
+
+
+PRInt32
+_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 
+            PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((rv = recv(osfd,buf,amount,flags)) == -1)
+    {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_RECV_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+            PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((rv = send(osfd,buf,amount,flags)) == -1)
+    {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+
+     /*
+      * optimization; if bytes sent is less than "amount" call
+      * select before returning. This is because it is likely that
+      * the next send() call will return EWOULDBLOCK.
+      */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+        && (timeout != PR_INTERVAL_NO_WAIT))
+    {
+        if (socket_io_wait(osfd, WRITE_FD, timeout)< 0) {
+            rv = -1;
+            goto done;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_SEND_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+              const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    while ((rv = sendto(osfd, buf, amount, flags,
+           (struct sockaddr *) addr, addrlen)) == -1)
+    {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK))
+        {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_SENDTO_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+                PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while( (*addrlen = PR_NETADDR_SIZE(addr)),
+           ((rv = recvfrom(osfd, buf, amount, flags,
+             (struct sockaddr *) addr, (int *)addrlen)) == -1))
+    {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_RECVFROM_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size,
+              PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 index, amount = 0;
+    PRInt32 osfd = fd->secret->md.osfd;
+
+     /*
+      * Calculate the total number of bytes to be sent; needed for
+      * optimization later.
+      * We could avoid this if this number was passed in; but it is
+      * probably not a big deal because iov_size is usually small (less than
+      * 3)
+      */
+    if (!fd->secret->nonblocking) {
+        for (index=0; index<iov_size; index++) {
+            amount += iov[index].iov_len;
+        }
+    }
+
+    while ((rv = _OS2_WRITEV(osfd, (const struct iovec*)iov, iov_size)) == -1) {
+        err = sock_errno();
+        if ((err == EWOULDBLOCK))    {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0)
+                goto done;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+
+     /*
+      * optimization; if bytes sent is less than "amount" call
+      * select before returning. This is because it is likely that
+      * the next writev() call will return EWOULDBLOCK.
+      */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+          && (timeout != PR_INTERVAL_NO_WAIT)) {
+        if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
+            rv = -1;
+            goto done;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_WRITEV_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how)
+{
+    PRInt32 rv;
+
+    rv = shutdown(fd->secret->md.osfd, how);
+    if (rv < 0)
+        _PR_MD_MAP_SHUTDOWN_ERROR(sock_errno());
+    return rv;
+}
+
+#ifndef XP_OS2_VACPP
+PRInt32
+_PR_MD_SOCKETPAIR(int af, int type, int flags, PRInt32 *osfd)
+{
+    PRInt32 rv, err;
+
+    rv = socketpair(af, type, flags, osfd);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SOCKETPAIR_ERROR(err);
+    }
+    return rv;
+}
+#endif
+
+PRStatus
+_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockname(fd->secret->md.osfd,
+                     (struct sockaddr *) addr, (int *)addrlen);
+    if (rv < 0) {
+        err = sock_errno();
+        _PR_MD_MAP_GETSOCKNAME_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getpeername(fd->secret->md.osfd,
+                     (struct sockaddr *) addr, (int *)addrlen);
+    if (rv < 0) {
+        err = sock_errno();
+        _PR_MD_MAP_GETPEERNAME_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname,
+                  char* optval, PRInt32* optlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockopt(fd->secret->md.osfd, level, optname, optval, (int *)optlen);
+    if (rv < 0) {
+        err = sock_errno();
+        _PR_MD_MAP_GETSOCKOPT_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus
+_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname,
+                  const char* optval, PRInt32 optlen)
+{
+    PRInt32 rv, err;
+
+    rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv < 0) {
+        err = sock_errno();
+        _PR_MD_MAP_SETSOCKOPT_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+void
+_MD_MakeNonblock(PRFileDesc *fd)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 err;
+    PRUint32  one = 1;
+    
+    if (osfd <= 2) {
+        /* Don't mess around with stdin, stdout or stderr */
+        return;
+    }
+
+    err = _OS2_IOCTL( osfd, FIONBIO, (char *) &one, sizeof(one));
+    if ( err != 0 )
+    {
+        err = sock_errno();
+        _PR_MD_MAP_SOCKET_ERROR(err);
+    }
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2thred.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2thred.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,407 @@
+/* -*- 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 <process.h>  /* for _beginthread() */
+
+#ifdef XP_OS2_VACPP
+#include <time.h>     /* for _tzset() */
+#endif
+
+#ifdef XP_OS2_EMX
+#include <signal.h>
+#endif
+
+#include <float.h>
+
+/* --- globals ------------------------------------------------ */
+_NSPR_TLS*        pThreadLocalStorage = 0;
+_PRInterruptTable             _pr_interruptTable[] = { { 0 } };
+APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
+
+void
+_PR_MD_ENSURE_TLS(void)
+{
+   if(!pThreadLocalStorage)
+   {
+      /* Allocate thread local storage (TLS).  Note, that only 32 bytes can
+       * be allocated at a time. 
+       */
+      int rc = DosAllocThreadLocalMemory(sizeof(_NSPR_TLS) / 4, (PULONG*)&pThreadLocalStorage);
+      PR_ASSERT(rc == NO_ERROR);
+      memset(pThreadLocalStorage, 0, sizeof(_NSPR_TLS));
+   }
+}
+
+void
+_PR_MD_EARLY_INIT()
+{
+   HMODULE hmod;
+
+   if (DosLoadModule(NULL, 0, "DOSCALL1", &hmod) == 0)
+       DosQueryProcAddr(hmod, 877, "DOSQUERYTHREADCONTEXT",
+                        (PFN *)&QueryThreadContext);
+
+#ifdef XP_OS2_VACPP
+   _tzset();
+#endif
+}
+
+static void
+_pr_SetThreadMDHandle(PRThread *thread)
+{
+   PTIB ptib;
+   PPIB ppib;
+   PRUword rc;
+
+   rc = DosGetInfoBlocks(&ptib, &ppib);
+
+   thread->md.handle = ptib->tib_ptib2->tib2_ultid;
+}
+
+/* On OS/2, some system function calls seem to change the FPU control word,
+ * such that we crash with a floating underflow exception.  The FIX_FPU() call
+ * in jsnum.c does not always work, as sometimes FIX_FPU() is called BEFORE the
+ * OS/2 system call that horks the FPU control word.  So, we set an exception
+ * handler that covers any floating point exceptions and resets the FPU CW to
+ * the required value.
+ */
+static ULONG
+_System OS2_FloatExcpHandler(PEXCEPTIONREPORTRECORD p1,
+                             PEXCEPTIONREGISTRATIONRECORD p2,
+                             PCONTEXTRECORD p3,
+                             PVOID pv)
+{
+#ifdef DEBUG_pedemonte
+    printf("Entering exception handler; ExceptionNum = %x\n", p1->ExceptionNum);
+    switch(p1->ExceptionNum) {
+        case XCPT_FLOAT_DENORMAL_OPERAND:
+            printf("got XCPT_FLOAT_DENORMAL_OPERAND\n");
+            break;
+        case XCPT_FLOAT_DIVIDE_BY_ZERO:
+            printf("got XCPT_FLOAT_DIVIDE_BY_ZERO\n");
+            break;
+        case XCPT_FLOAT_INEXACT_RESULT:
+            printf("got XCPT_FLOAT_INEXACT_RESULT\n");
+            break;
+        case XCPT_FLOAT_INVALID_OPERATION:
+            printf("got XCPT_FLOAT_INVALID_OPERATION\n");
+            break;
+        case XCPT_FLOAT_OVERFLOW:
+            printf("got XCPT_FLOAT_OVERFLOW\n");
+            break;
+        case XCPT_FLOAT_STACK_CHECK:
+            printf("got XCPT_FLOAT_STACK_CHECK\n");
+            break;
+        case XCPT_FLOAT_UNDERFLOW:
+            printf("got XCPT_FLOAT_UNDERFLOW\n");
+            break;
+    }
+#endif
+
+    switch(p1->ExceptionNum) {
+        case XCPT_FLOAT_DENORMAL_OPERAND:
+        case XCPT_FLOAT_DIVIDE_BY_ZERO:
+        case XCPT_FLOAT_INEXACT_RESULT:
+        case XCPT_FLOAT_INVALID_OPERATION:
+        case XCPT_FLOAT_OVERFLOW:
+        case XCPT_FLOAT_STACK_CHECK:
+        case XCPT_FLOAT_UNDERFLOW:
+        {
+            unsigned cw = p3->ctx_env[0];
+            if ((cw & MCW_EM) != MCW_EM) {
+                /* Mask out all floating point exceptions */
+                p3->ctx_env[0] |= MCW_EM;
+                /* Following two lines set precision to 53 bit mantissa.  See jsnum.c */
+                p3->ctx_env[0] &= ~MCW_PC;
+                p3->ctx_env[0] |= PC_53;
+                return XCPT_CONTINUE_EXECUTION;
+            }
+        }
+    }
+    return XCPT_CONTINUE_SEARCH;
+}
+
+PR_IMPLEMENT(void)
+PR_OS2_SetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* excpreg)
+{
+    /* setup the exception handler for the thread */
+    APIRET rv;
+    excpreg->ExceptionHandler = OS2_FloatExcpHandler;
+    excpreg->prev_structure = NULL;
+    rv = DosSetExceptionHandler(excpreg);
+    PR_ASSERT(rv == NO_ERROR);
+}
+
+PR_IMPLEMENT(void)
+PR_OS2_UnsetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* excpreg)
+{
+    /* unset exception handler */
+    APIRET rv = DosUnsetExceptionHandler(excpreg);
+    PR_ASSERT(rv == NO_ERROR);
+}
+
+PRStatus
+_PR_MD_INIT_THREAD(PRThread *thread)
+{
+   APIRET rv;
+
+   if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
+      _pr_SetThreadMDHandle(thread);
+   }
+
+   /* Create the blocking IO semaphore */
+   rv = DosCreateEventSem(NULL, &(thread->md.blocked_sema), 0, 0);
+   return (rv == NO_ERROR) ? PR_SUCCESS : PR_FAILURE;
+}
+
+typedef struct param_store
+{
+    void (*start)(void *);
+    PRThread* thread;
+} PARAMSTORE;
+
+/* This is a small intermediate function that sets/unsets the exception
+   handler before calling the initial thread function */
+static void
+ExcpStartFunc(void* arg)
+{
+    EXCEPTIONREGISTRATIONRECORD excpreg;
+    PARAMSTORE params, *pParams = arg;
+
+    PR_OS2_SetFloatExcpHandler(&excpreg);
+
+    params = *pParams;
+    PR_Free(pParams);
+    params.start(params.thread);
+
+    PR_OS2_UnsetFloatExcpHandler(&excpreg);
+}
+
+PRStatus
+_PR_MD_CREATE_THREAD(PRThread *thread, 
+                  void (*start)(void *), 
+                  PRThreadPriority priority, 
+                  PRThreadScope scope, 
+                  PRThreadState state, 
+                  PRUint32 stackSize)
+{
+    PARAMSTORE* params = PR_Malloc(sizeof(PARAMSTORE));
+    params->start = start;
+    params->thread = thread;
+#ifdef XP_OS2_VACPP /* No exception handler for VACPP */
+    thread->md.handle = thread->id = (TID) _beginthread(
+                    (void(* _Optlink)(void*))start,
+                    NULL, 
+                    thread->stack->stackSize,
+                    thread);
+#else
+    thread->md.handle = thread->id = (TID) _beginthread(ExcpStartFunc,
+                                                        NULL, 
+                                                        thread->stack->stackSize,
+                                                        params);
+#endif
+    if(thread->md.handle == -1) {
+        return PR_FAILURE;
+    }
+
+    /*
+     * On OS/2, a thread is created with a thread priority of
+     * THREAD_PRIORITY_NORMAL
+     */
+
+    if (priority != PR_PRIORITY_NORMAL) {
+        _PR_MD_SET_PRIORITY(&(thread->md), priority);
+    }
+
+    return PR_SUCCESS;
+}
+
+void
+_PR_MD_YIELD(void)
+{
+    /* Isn't there some problem with DosSleep(0) on OS/2? */
+    DosSleep(0);
+}
+
+void
+_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
+{
+    int nativePri;
+    BOOL rv;
+
+    if (newPri < PR_PRIORITY_FIRST) {
+        newPri = PR_PRIORITY_FIRST;
+    } else if (newPri > PR_PRIORITY_LAST) {
+        newPri = PR_PRIORITY_LAST;
+    }
+    switch (newPri) {
+        case PR_PRIORITY_LOW:
+            nativePri = PRTYC_IDLETIME;
+            break;
+        case PR_PRIORITY_NORMAL:
+            nativePri = PRTYC_REGULAR;
+            break;
+        case PR_PRIORITY_HIGH:
+            nativePri = PRTYC_FOREGROUNDSERVER;
+            break;
+        case PR_PRIORITY_URGENT:
+            nativePri = PRTYC_TIMECRITICAL;
+    }
+    rv = DosSetPriority(PRTYS_THREAD, nativePri, 0, thread->handle);
+    PR_ASSERT(rv == NO_ERROR);
+    if (rv != NO_ERROR) {
+	PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+                ("PR_SetThreadPriority: can't set thread priority\n"));
+    }
+    return;
+}
+
+void
+_PR_MD_CLEAN_THREAD(PRThread *thread)
+{
+    APIRET rv;
+
+    if (thread->md.blocked_sema) {
+        rv = DosCloseEventSem(thread->md.blocked_sema);
+        PR_ASSERT(rv == NO_ERROR);
+        thread->md.blocked_sema = 0;
+    }
+
+    if (thread->md.handle) {
+        thread->md.handle = 0;
+    }
+}
+
+void
+_PR_MD_EXIT_THREAD(PRThread *thread)
+{
+    _PR_MD_CLEAN_THREAD(thread);
+    _PR_MD_SET_CURRENT_THREAD(NULL);
+}
+
+
+void
+_PR_MD_EXIT(PRIntn status)
+{
+    _exit(status);
+}
+
+#ifdef HAVE_THREAD_AFFINITY
+PR_EXTERN(PRInt32) 
+_PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask )
+{
+   /* Can we do this on OS/2?  Only on SMP versions? */
+   PR_ASSERT(!"Not implemented");
+   return 0;
+
+ /* This is what windows does:
+    int rv;
+
+    rv = SetThreadAffinityMask(thread->md.handle, mask);
+
+    return rv?0:-1;
+  */
+}
+
+PR_EXTERN(PRInt32)
+_PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask)
+{
+   /* Can we do this on OS/2?  Only on SMP versions? */
+   PR_ASSERT(!"Not implemented");
+   return 0;
+
+ /* This is what windows does:
+    PRInt32 rv, system_mask;
+
+    rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask);
+    
+    return rv?0:-1;
+  */
+}
+#endif /* HAVE_THREAD_AFFINITY */
+
+void
+_PR_MD_SUSPEND_CPU(_PRCPU *cpu) 
+{
+    _PR_MD_SUSPEND_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_RESUME_CPU(_PRCPU *cpu)
+{
+    _PR_MD_RESUME_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_SUSPEND_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+       APIRET rc;
+
+        /* XXXMB - DosSuspendThread() is not a blocking call; how do we
+         * know when the thread is *REALLY* suspended?
+         */
+       rc = DosSuspendThread(thread->md.handle);
+       PR_ASSERT(rc == NO_ERROR);
+    }
+}
+
+void
+_PR_MD_RESUME_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        DosResumeThread(thread->md.handle);
+    }
+}
+
+
+PRThread*
+_MD_CURRENT_THREAD(void)
+{
+    PRThread *thread;
+
+    thread = _MD_GET_ATTACHED_THREAD();
+
+    if (NULL == thread) {
+        thread = _PRI_AttachThread(PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0);
+    }
+
+    PR_ASSERT(thread != NULL);
+    return thread;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2vaclegacy.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2vaclegacy.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,74 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ 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 InnoTek
+/ Systemberatung GmbH.
+/ Portions created by the Initial Developer are Copyright (C) 2003
+/ the Initial Developer. All Rights Reserved.
+/ 
+/ Contributor(s):
+/    InnoTek Systemberatung GmbH / Knut St. Osmundsen
+/ 
+/ 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.
+/ 
+
+    .text
+    .align 4
+    .globl PR_NewMonitor
+PR_NewMonitor:
+    jmp _PR_NewMonitor
+
+    .align 4
+    .globl PR_EnterMonitor
+PR_EnterMonitor:
+    mov     %eax,  4(%esp) 
+    jmp _PR_EnterMonitor
+
+    .align 4
+    .globl PR_ExitMonitor 
+PR_ExitMonitor:
+    mov     %eax,  4(%esp) 
+    jmp _PR_ExitMonitor 
+
+
+    
+    .align 4
+    .globl PR_AttachThread
+PR_AttachThread:
+    mov     %eax,  4(%esp) 
+    mov     %edx,  8(%esp) 
+    mov     %ecx, 12(%esp)
+    jmp _PR_AttachThread
+    
+    .align 4
+    .globl PR_DetachThread
+PR_DetachThread:
+    jmp _PR_DetachThread
+    
+    .align 4
+    .globl PR_GetCurrentThread
+PR_GetCurrentThread:
+    jmp _PR_GetCurrentThread
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2vacpp.asm
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/os2/os2vacpp.asm	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,266 @@
+; -*- Mode: asm; tab-width: 8; c-basic-offset: 4 -*-
+
+; ***** BEGIN LICENSE BLOCK *****
+; Version: MPL 1.1/GPL 2.0/LGPL 2.1
+;
+; The contents of this file are subject to the Mozilla Public License Version
+; 1.1 (the "License"); you may not use this file except in compliance with
+; the License. You may obtain a copy of the License at
+; http://www.mozilla.org/MPL/
+;
+; Software distributed under the License is distributed on an "AS IS" basis,
+; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+; for the specific language governing rights and limitations under the
+; License.
+;
+; The Original Code is the Netscape Portable Runtime (NSPR).
+;
+; The Initial Developer of the Original Code is
+; IBM Corporation.
+; Portions created by the Initial Developer are Copyright (C) 2001
+; 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 *****
+
+; Windows uses inline assembly for their atomic functions, so we have
+; created an assembly file for VACPP on OS/2.
+;
+; This assembly file also contains an implementation of RAM semaphores.
+;
+; Notes:
+;   The ulTIDPID element of the RAMSEM structure is overloaded in the 386
+;   implementation to hold the TID:PID in the lower 31 bits and the lock
+;   bit in the high bit
+
+        page ,132
+
+        .486P
+        ASSUME  CS:FLAT,  DS:FLAT,  SS:FLAT,  ES:FLAT,  FS:FLAT
+
+        EXTRN   Dos32PostEventSem:PROC
+        EXTRN   Dos32WaitEventSem:PROC
+        EXTRN   Dos32ResetEventSem:PROC
+
+ramsem  STRUC
+        ramsem_ulTIDPID         DD      ?
+        ramsem_hevSem           DD      ?
+        ramsem_cLocks           DD      ?
+        ramsem_cWaiting         DW      ?
+        ramsem_cPosts           DW      ?
+ramsem  ENDS
+
+ERROR_SEM_TIMEOUT               equ     121
+ERROR_NOT_OWNER                 equ     288
+SEM_RELEASE_UNOWNED             equ     1
+SEM_RELEASE_ALL                 equ     2
+TS_LOCKBIT                      equ     31
+
+
+DATA    SEGMENT DWORD USE32 PUBLIC 'DATA'
+
+        EXTRN   plisCurrent:DWORD
+
+DATA    ENDS
+
+CODE32  SEGMENT USE32 PUBLIC 'CODE'
+
+        PUBLIC  SemRequest486
+        PUBLIC  SemReleasex86
+
+        PUBLIC  _PR_MD_ATOMIC_SET
+        PUBLIC  _PR_MD_ATOMIC_ADD
+        PUBLIC  _PR_MD_ATOMIC_INCREMENT
+        PUBLIC  _PR_MD_ATOMIC_DECREMENT
+
+;;;---------------------------------------------------------------------------
+;;; APIRET _Optlink SemRequest(PRAMSEM pramsem, ULONG ulTimeout);
+;;;
+;;; Registers:
+;;;   EAX - packed TID:PID word
+;;;   ECX - address of RAMSEM structure
+;;;   EDX - length of timeout in milli-seconds
+;;;---------------------------------------------------------------------------
+
+        ALIGN   10H
+SemRequest486     PROC
+        push    ebx                                  ; Save ebx (volatile)
+        mov     ecx, eax                             ; PRAMSEM must be in ecx,
+                                                     ; not eax, for cmpxchg
+
+        mov     ebx, dword ptr [plisCurrent]
+        mov     eax, dword ptr [ebx+4]               ; Place thread id in high
+                                                     ; word, process id in low
+        mov     ax,  word ptr [ebx]                  ; word
+        mov     ebx,eax
+
+req486_test:
+        xor     eax,eax
+        cmp     (ramsem PTR [ecx]).ramsem_ulTIDPID, ebx ; If we own the sem, just
+        jz short req486_inc_exit                      ; increment the use count
+
+        lock inc     (ramsem PTR [ecx]).ramsem_cWaiting ; inc waiting flag
+
+;       lock                                         ; Uncomment for SMP
+        DB      0F0h
+;       cmpxchg (ramsem PTR [ecx]).ramsem_ulTIDPID, ebx
+;         (byte 3 is the offset of ulProcessThread into the RAMSEM structure)
+        DB      00Fh
+        DB      0B1h
+        DB      019h
+        jnz short req486_sleep
+
+req486_inc_exit:
+   lock inc     (ramsem PTR [ecx]).ramsem_cLocks
+
+req486_exit:
+        pop     ebx                                  ; Restore ebx
+        ret
+
+req486_sleep:
+        push    ecx                                  ; Save ecx (volatile)
+        push    edx                                  ; Save edx (volatile)
+        push    edx                                  ; timeout
+        push    (ramsem PTR [ecx]).ramsem_hevSem
+        call    Dos32WaitEventSem
+        add     esp, 8
+        pop     edx                                  ; restore edx
+        pop     ecx                                  ; restore ecx
+        or      eax, eax
+        jne     req486_exit                          ; Exit, if error
+
+        push    ecx                                  ; Save ecx (volatile)
+        push    edx                                  ; Save edx (volatile)
+        sub     esp, 4                               ; Use stack space for
+        push    esp                                  ;  dummy pulPostCt
+        push    (ramsem PTR [ecx]).ramsem_hevSem
+        call    Dos32ResetEventSem
+        add     esp, 12
+        pop     edx                                  ; restore edx
+        pop     ecx                                  ; restore ecx
+        jmp     req486_test                          ; Retry the semaphore
+
+SemRequest486     ENDP
+
+;;;---------------------------------------------------------------------
+;;; APIRET _Optlink SemReleasex86(PRAMSEM pramsem, ULONG flFlags);
+;;;
+;;; Registers:
+;;;   EAX - address of RAMSEM structure
+;;;   ECX - temporary variable
+;;;   EDX - flags
+;;;---------------------------------------------------------------------
+
+        ALIGN   10H
+SemReleasex86     PROC
+        test    edx, SEM_RELEASE_UNOWNED             ; If set, don't bother
+        jnz short rel_ownerok                        ; getting/checking PID/TID
+
+        push    ebx                                  ; Save ebx (volatile)
+        mov     ebx, dword ptr [plisCurrent]
+        mov     ecx, dword ptr [ebx+4]               ; Place thread id in high
+                                                     ; word, process id in low
+        mov     cx,  word ptr [ebx]                  ; word
+        pop     ebx                                  ; Restore ebx
+
+        sub     ecx, (ramsem PTR [eax]).ramsem_ulTIDPID ; This thread the owner?
+        shl     ecx,1                                ; Don't compare top bit
+        jnz short rel_notowner
+
+rel_ownerok:
+        test    edx, SEM_RELEASE_ALL
+        jnz short rel_clear
+
+   lock dec     (ramsem PTR [eax]).ramsem_cLocks
+        jnz short rel_exit
+
+rel_disown:
+        mov     (ramsem PTR [eax]).ramsem_ulTIDPID, 0
+
+   lock inc     (ramsem PTR [eax]).ramsem_cPosts
+        mov     cx, (ramsem PTR [eax]).ramsem_cWaiting
+        cmp     (ramsem PTR [eax]).ramsem_cPosts, cx
+        jne short rel_post
+
+rel_exit:
+        xor     eax, eax
+        ret
+
+rel_clear:
+   lock mov     (ramsem PTR [eax]).ramsem_cLocks,0
+        jmp     rel_disown
+
+rel_notowner:
+        mov     eax, ERROR_NOT_OWNER
+        ret
+
+rel_post:
+        mov     (ramsem PTR [eax]).ramsem_cPosts, cx
+        push    (ramsem PTR [eax]).ramsem_hevSem
+        call    Dos32PostEventSem
+        add     esp,4
+        xor     eax,eax
+        ret
+SemReleasex86     ENDP
+
+;;;---------------------------------------------------------------------
+;;; PRInt32 _Optlink _PR_MD_ATOMIC_SET(PRInt32* val, PRInt32 newval)
+;;;---------------------------------------------------------------------
+        ALIGN   10H
+_PR_MD_ATOMIC_SET     proc
+        xchg    dword ptr [eax],edx
+        mov eax, edx;
+        ret
+_PR_MD_ATOMIC_SET     endp
+
+;;;---------------------------------------------------------------------
+;;; PRInt32 _Optlink _PR_MD_ATOMIC_ADD(PRInt32* ptr, PRInt32 val)
+;;;---------------------------------------------------------------------
+        ALIGN   10H
+_PR_MD_ATOMIC_ADD     proc
+        mov ecx, edx
+        lock xadd dword ptr [eax], edx
+        mov eax, edx
+        add eax, ecx
+        ret
+_PR_MD_ATOMIC_ADD     endp
+
+;;;---------------------------------------------------------------------
+;;; PRInt32 _Optlink _PR_MD_ATOMIC_INCREMENT(PRInt32* val)
+;;;---------------------------------------------------------------------
+        ALIGN   10H
+_PR_MD_ATOMIC_INCREMENT     proc
+        mov edx, 1
+        lock xadd dword ptr [eax], edx
+        mov eax, edx
+        inc eax
+        ret
+_PR_MD_ATOMIC_INCREMENT     endp
+
+;;;---------------------------------------------------------------------
+;;; PRInt32 _Optlink _PR_MD_ATOMIC_DECREMENT(PRInt32* val)
+;;;---------------------------------------------------------------------
+        ALIGN   10H
+_PR_MD_ATOMIC_DECREMENT     proc
+        mov edx, 0ffffffffh
+        lock xadd dword ptr [eax], edx
+        mov eax, edx
+        dec eax
+        ret
+_PR_MD_ATOMIC_DECREMENT     endp
+
+CODE32  ENDS
+END

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/prosdep.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/prosdep.c	Mon Dec 18 10:53:47 2006
@@ -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 "prbit.h"
+#include "prsystem.h"
+
+#ifdef XP_UNIX
+#include <unistd.h>
+#endif
+#ifdef SUNOS4
+#include "md/sunos4.h"
+#endif
+#ifdef _WIN32
+#include <windows.h>
+#endif 
+#ifdef XP_BEOS
+#include <OS.h>
+#endif
+
+PRInt32 _pr_pageShift;
+PRInt32 _pr_pageSize;
+
+/*
+** Get system page size
+*/
+static void GetPageSize(void)
+{
+	PRInt32 pageSize;
+
+    /* Get page size */
+#ifdef XP_UNIX
+#if defined SUNOS4 || defined BSDI || defined AIX \
+        || defined LINUX || defined __GNU__ || defined __GLIBC__ \
+        || defined FREEBSD || defined NETBSD || defined OPENBSD \
+        || defined DARWIN || defined NEXTSTEP
+    _pr_pageSize = getpagesize();
+#elif defined(HPUX)
+    /* I have no idea. Don't get me started. --Rob */
+    _pr_pageSize = sysconf(_SC_PAGE_SIZE);
+#else
+    _pr_pageSize = sysconf(_SC_PAGESIZE);
+#endif
+#endif /* XP_UNIX */
+
+#ifdef XP_MAC
+    _pr_pageSize = 4096;
+#endif /* XP_MAC */
+
+#ifdef XP_BEOS
+    _pr_pageSize = B_PAGE_SIZE;
+#endif
+
+#ifdef XP_PC
+#ifdef _WIN32
+    SYSTEM_INFO info;
+    GetSystemInfo(&info);
+    _pr_pageSize = info.dwPageSize;
+#else
+    _pr_pageSize = 4096;
+#endif
+#endif /* XP_PC */
+
+	pageSize = _pr_pageSize;
+	PR_CEILING_LOG2(_pr_pageShift, pageSize);
+}
+
+PR_IMPLEMENT(PRInt32) PR_GetPageShift(void)
+{
+    if (!_pr_pageSize) {
+	GetPageSize();
+    }
+    return _pr_pageShift;
+}
+
+PR_IMPLEMENT(PRInt32) PR_GetPageSize(void)
+{
+    if (!_pr_pageSize) {
+	GetPageSize();
+    }
+    return _pr_pageSize;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,54 @@
+/.cvsignore/1.2/Sat May 12 04:29:27 2001//
+/Makefile.in/1.26/Sun Apr 25 15:00:59 2004//
+/aix.c/3.11/Sun Apr 25 15:00:59 2004//
+/aixwrap.c/3.6/Sun Apr 25 15:00:59 2004//
+/bsdi.c/3.6/Sun Apr 25 15:00:59 2004//
+/darwin.c/3.11/Sun Apr 25 15:00:59 2004//
+/dgux.c/3.5/Sun Apr 25 15:00:59 2004//
+/freebsd.c/3.7/Sun Apr 25 15:00:59 2004//
+/hpux.c/3.7/Sun Apr 25 15:00:59 2004//
+/irix.c/3.14/Sun Apr 25 15:00:59 2004//
+/linux.c/3.8/Sun Apr 25 15:00:59 2004//
+/ncr.c/3.6/Sun Apr 25 15:00:59 2004//
+/nec.c/3.5/Sun Apr 25 15:00:59 2004//
+/netbsd.c/3.5/Sun Apr 25 15:00:59 2004//
+/nextstep.c/3.5/Sun Apr 25 15:00:59 2004//
+/nto.c/3.6/Sun Apr 25 15:00:59 2004//
+/objs.mk/3.34/Sun Apr 25 15:00:59 2004//
+/openbsd.c/3.5/Sun Apr 25 15:00:59 2004//
+/openvms.c/1.9/Sun Apr 25 15:00:59 2004//
+/os_AIX.s/3.5/Tue Jun 20 21:32:22 2000//
+/os_BSD_386_2.s/3.5/Tue Jun 20 21:32:26 2000//
+/os_Darwin_ppc.s/3.1/Sat Feb 22 15:00:13 2003//
+/os_Darwin_x86.s/1.1/Mon Jan  9 18:38:54 2006//
+/os_HPUX.s/1.3/Tue Jun 20 21:32:29 2000//
+/os_HPUX_ia64.s/1.2/Mon Nov 21 22:49:19 2005//
+/os_Irix.s/3.5/Tue Jun 20 21:32:31 2000//
+/os_Linux_ia64.s/3.5/Mon Nov 21 22:49:19 2005//
+/os_Linux_x86.s/3.8/Mon Jan  9 17:43:52 2006//
+/os_Linux_x86_64.s/1.2/Mon Jan  9 17:43:52 2006//
+/os_ReliantUNIX.s/3.5/Tue Jun 20 21:32:36 2000//
+/os_SunOS.s/3.6/Tue Jun 20 21:32:39 2000//
+/os_SunOS_sparcv9.s/3.1/Sun Jun 24 01:39:51 2001//
+/os_SunOS_ultrasparc.s/3.8/Tue Jun 20 21:32:43 2000//
+/os_SunOS_x86.s/3.10/Mon Jan  9 17:43:52 2006//
+/os_SunOS_x86_64.s/1.2/Mon Jan  9 17:43:52 2006//
+/osf1.c/3.7/Sun Apr 25 15:00:59 2004//
+/pthreads_user.c/3.8/Sun Apr 25 15:00:59 2004//
+/qnx.c/3.5/Sun Apr 25 15:00:59 2004//
+/reliantunix.c/3.6/Sun Apr 25 15:00:59 2004//
+/rhapsody.c/3.8/Sun Apr 25 15:00:59 2004//
+/riscos.c/3.1/Fri Jul  1 22:26:36 2005//
+/scoos.c/3.6/Sun Apr 25 15:00:59 2004//
+/solaris.c/3.16/Sun Apr 25 15:00:59 2004//
+/sony.c/3.5/Sun Apr 25 15:00:59 2004//
+/sunos4.c/3.5/Sun Apr 25 15:00:59 2004//
+/unix.c/3.52/Sat Dec 24 08:25:29 2005//
+/unix_errors.c/3.26/Wed Mar  9 22:57:05 2005//
+/unixware.c/3.8/Sun Apr 25 15:00:59 2004//
+/uxpoll.c/3.11/Sun Apr 25 15:00:59 2004//
+/uxproces.c/3.20/Sat Dec 24 08:25:29 2005//
+/uxrng.c/1.19/Sat Dec 24 08:25:29 2005//
+/uxshm.c/3.11/Sun Apr 25 15:00:59 2004//
+/uxwrap.c/3.15/Sat Apr 30 00:19:33 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/md/unix

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,135 @@
+# 
+# ***** 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
+
+CSRCS =          \
+	unix.c    \
+	unix_errors.c    \
+	uxproces.c \
+	uxrng.c \
+	uxshm.c \
+	uxwrap.c \
+	$(NULL)
+
+ifneq ($(USE_PTHREADS),1)
+CSRCS += uxpoll.c
+endif
+
+ifeq ($(PTHREADS_USER),1)
+CSRCS += pthreads_user.c
+endif
+
+CSRCS += $(PR_MD_CSRCS)
+ASFILES += $(PR_MD_ASFILES)
+
+TARGETS = $(OBJS)
+
+ifeq ($(OS_ARCH),SunOS)
+	ifneq ($(OS_RELEASE),4.1.3_U1)
+		ifeq ($(OS_TEST),sun4u)
+		ifdef USE_64
+			ULTRASPARC_ASFILES = os_SunOS_sparcv9.s
+			ULTRASPARC_ASOBJS = $(addprefix $(OBJDIR)/,$(ULTRASPARC_ASFILES:.s=.$(OBJ_SUFFIX)))
+		else
+			LIBRARY_NAME = $(ULTRASPARC_LIBRARY)
+			LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
+			ULTRASPARC_ASFILES = os_SunOS_ultrasparc.s
+			ULTRASPARC_ASOBJS = $(addprefix $(OBJDIR)/,$(ULTRASPARC_ASFILES:.s=.$(OBJ_SUFFIX)))
+			TARGETS		+= $(ULTRASPARC_ASOBJS) $(SHARED_LIBRARY)
+			RELEASE_LIBS = $(SHARED_LIBRARY)
+			RELEASE_LIBS_DEST = $(RELEASE_LIB_DIR)/cpu/sparcv8plus
+			lib_subdir = cpu/sparcv8plus
+		endif
+		endif
+	endif
+endif
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
+ifeq ($(OS_ARCH),SunOS)
+ifneq ($(OS_RELEASE),4.1.3_U1)
+ifeq ($(OS_TEST),sun4u)
+
+ifdef USE_64
+$(ULTRASPARC_ASOBJS): $(ULTRASPARC_ASFILES)
+	/usr/ccs/bin/as -o $@ -K PIC -P -D_ASM -D__STDC__=0 -xarch=v9 $<
+else
+$(SHARED_LIBRARY): $(ULTRASPARC_ASOBJS)
+	$(LD) -G -z text -z endfiltee -o $@ $(ULTRASPARC_ASOBJS)
+	$(INSTALL) -m 444 $@ $(dist_libdir)/cpu/sparcv8plus
+	$(INSTALL) -m 444 $@ $(dist_bindir)/cpu/sparcv8plus
+#
+# The -f $(ORIGIN)/... linker flag uses the real file, after symbolic links
+# are resolved, as the origin.  If NSDISTMODE is not "copy", libnspr4.so
+# will be installed as a symbolic link in $(dist_libdir), pointing to the
+# real libnspr4.so file in pr/src.  Therefore we need to install an
+# additional copy of libnspr_flt4.so in pr/src/cpu/sparcv8plus.
+#
+ifneq ($(NSDISTMODE),copy)
+	$(INSTALL) -m 444 $@ ../../cpu/sparcv8plus
+endif
+
+ifneq ($(NSDISTMODE),copy)
+clobber realclean clobber_all distclean::
+	rm -rf ../../cpu
+endif
+
+$(ULTRASPARC_ASOBJS): $(ULTRASPARC_ASFILES)
+	/usr/ccs/bin/as -o $@ -K PIC -P -D_ASM -D__STDC__=0 -xarch=v8plus $<
+
+clean::
+	rm -rf $(ULTRASPARC_ASOBJS)
+endif
+
+endif
+endif
+endif

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/aix.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/aix.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,333 @@
+/* -*- 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"
+
+#ifdef AIX_HAVE_ATOMIC_OP_H
+#include <sys/atomic_op.h>
+
+PRInt32 _AIX_AtomicSet(PRInt32 *val, PRInt32 newval)
+{
+    PRIntn oldval;
+    boolean_t stored;
+    oldval = fetch_and_add((atomic_p)val, 0);
+    do
+    {
+        stored = compare_and_swap((atomic_p)val, &oldval, newval);
+    } while (!stored);
+    return oldval;
+}  /* _AIX_AtomicSet */
+#endif /* AIX_HAVE_ATOMIC_OP_H */
+
+#if defined(AIX_TIMERS)
+
+#include <sys/time.h>
+
+static PRUint32 _aix_baseline_epoch;
+
+static void _MD_AixIntervalInit(void)
+{
+    timebasestruct_t real_time;
+    read_real_time(&real_time, TIMEBASE_SZ);
+    (void)time_base_to_time(&real_time, TIMEBASE_SZ);
+    _aix_baseline_epoch = real_time.tb_high;
+}  /* _MD_AixIntervalInit */
+
+PRIntervalTime _MD_AixGetInterval(void)
+{
+    PRIntn rv;
+    PRUint64 temp;
+    timebasestruct_t real_time;
+    read_real_time(&real_time, TIMEBASE_SZ);
+    (void)time_base_to_time(&real_time, TIMEBASE_SZ);
+    /* tb_high is in seconds, tb_low in 10(-9)seconds */
+    temp = 1000000000ULL * (PRUint64)(real_time.tb_high - _aix_baseline_epoch);
+    temp += (PRUint64)real_time.tb_low;  /* everything's 10(-9) seconds */
+    temp >>= 16;  /* now it's something way different */
+    return (PRIntervalTime)temp;
+}  /* _MD_AixGetInterval */
+
+PRIntervalTime _MD_AixIntervalPerSec(void)
+{
+    return 1000000000ULL >> 16;  /* that's 15258, I think */
+}  /* _MD_AixIntervalPerSec */
+
+#endif /* defined(AIX_TIMERS) */
+
+#if !defined(PTHREADS_USER)
+
+#if defined(_PR_PTHREADS)
+
+/*
+ * AIX 4.3 has sched_yield().  AIX 4.2 has pthread_yield().
+ * So we look up the appropriate function pointer at run time.
+ */
+
+#include <dlfcn.h>
+
+int (*_PT_aix_yield_fcn)() = NULL;
+int _pr_aix_send_file_use_disabled = 0;
+
+void _MD_EarlyInit(void)
+{
+    void *main_app_handle;
+	char *evp;
+
+    main_app_handle = dlopen(NULL, RTLD_NOW);
+    PR_ASSERT(NULL != main_app_handle);
+
+    _PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle, "sched_yield");
+    if (!_PT_aix_yield_fcn) {
+        _PT_aix_yield_fcn = (int(*)())dlsym(main_app_handle,"pthread_yield");
+        PR_ASSERT(NULL != _PT_aix_yield_fcn);
+    }
+    dlclose(main_app_handle);
+
+	if (evp = getenv("NSPR_AIX_SEND_FILE_USE_DISABLED")) {
+		if (1 == atoi(evp))
+			_pr_aix_send_file_use_disabled = 1;
+	}
+
+#if defined(AIX_TIMERS)
+    _MD_AixIntervalInit();
+#endif
+}
+
+#else /* _PR_PTHREADS */
+
+void _MD_EarlyInit(void)
+{
+#if defined(AIX_TIMERS)
+    _MD_AixIntervalInit();
+#endif
+}
+
+#endif /* _PR_PTHREADS */
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+PR_IMPLEMENT(void)
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for AIX */
+PR_IMPLEMENT(void)
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for AIX.");
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for AIX.");
+}
+#endif /* _PR_PTHREADS */
+#endif /* PTHREADS_USER */
+
+/*
+ * NSPR 2.0 overrides the system select() and poll() functions.
+ * On AIX 4.2, we use dlopen("/unix", RTLD_NOW) and dlsym() to get
+ * at the original system select() and poll() functions.
+ */
+
+#if !defined(AIX_RENAME_SELECT)
+
+#include <sys/select.h>
+#include <sys/poll.h>
+#include <dlfcn.h>
+
+static int (*aix_select_fcn)() = NULL;
+static int (*aix_poll_fcn)() = NULL;
+
+int _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
+{
+    int rv;
+
+    if (!aix_select_fcn) {
+        void *aix_handle;
+
+	aix_handle = dlopen("/unix", RTLD_NOW);
+	if (!aix_handle) {
+	    PR_SetError(PR_UNKNOWN_ERROR, 0);
+	    return -1;
+	}
+	aix_select_fcn = (int(*)())dlsym(aix_handle,"select");
+        dlclose(aix_handle);
+	if (!aix_select_fcn) {
+	    PR_SetError(PR_UNKNOWN_ERROR, 0);
+	    return -1;
+	}
+    }
+    rv = (*aix_select_fcn)(width, r, w, e, t);
+    return rv;
+}
+
+int _MD_POLL(void *listptr, unsigned long nfds, long timeout)
+{
+    int rv;
+
+    if (!aix_poll_fcn) {
+        void *aix_handle;
+
+	aix_handle = dlopen("/unix", RTLD_NOW);
+	if (!aix_handle) {
+	    PR_SetError(PR_UNKNOWN_ERROR, 0);
+	    return -1;
+	}
+	aix_poll_fcn = (int(*)())dlsym(aix_handle,"poll");
+        dlclose(aix_handle);
+	if (!aix_poll_fcn) {
+	    PR_SetError(PR_UNKNOWN_ERROR, 0);
+	    return -1;
+	}
+    }
+    rv = (*aix_poll_fcn)(listptr, nfds, timeout);
+    return rv;
+}
+
+#else
+
+/*
+ * In AIX versions prior to 4.2, we use the two-step rename/link trick.
+ * The binary must contain at least one "poll" symbol for linker's rename
+ * to work.  So we must have this dummy function that references poll().
+ */
+#include <sys/poll.h>
+void _pr_aix_dummy()
+{
+    poll(0,0,0);
+}
+
+#endif /* !defined(AIX_RENAME_SELECT) */
+
+#ifdef _PR_HAVE_ATOMIC_CAS
+
+#include "pratom.h"
+
+#define _PR_AIX_ATOMIC_LOCK	-1
+
+PR_IMPLEMENT(void)
+PR_StackPush(PRStack *stack, PRStackElem *stack_elem)
+{
+PRStackElem *addr;
+boolean_t locked = TRUE;
+
+	/* Is it safe to cast a pointer to an int? */
+	PR_ASSERT(sizeof(int) == sizeof(PRStackElem *));
+	do {
+		while ((addr = stack->prstk_head.prstk_elem_next) ==
+											(PRStackElem *)_PR_AIX_ATOMIC_LOCK)
+			;
+		locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
+							(int) addr, _PR_AIX_ATOMIC_LOCK);
+	} while (locked == TRUE);
+	stack_elem->prstk_elem_next = addr;
+	_clear_lock((atomic_p)&stack->prstk_head.prstk_elem_next, (int)stack_elem);
+    return;
+}
+
+PR_IMPLEMENT(PRStackElem *)
+PR_StackPop(PRStack *stack)
+{
+PRStackElem *element;
+boolean_t locked = TRUE;
+
+	/* Is it safe to cast a pointer to an int? */
+	PR_ASSERT(sizeof(int) == sizeof(PRStackElem *));
+	do {
+		while ((element = stack->prstk_head.prstk_elem_next) ==
+										(PRStackElem *) _PR_AIX_ATOMIC_LOCK)
+			;
+		locked = _check_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
+							(int)element, _PR_AIX_ATOMIC_LOCK);
+	} while (locked == TRUE);
+
+	if (element == NULL) {
+		_clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next, NULL);
+	} else {
+		_clear_lock((atomic_p) &stack->prstk_head.prstk_elem_next,
+										(int) element->prstk_elem_next);
+	}
+	return element;
+}
+
+#endif	/* _PR_HAVE_ATOMIC_CAS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/aixwrap.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/aixwrap.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,65 @@
+/* -*- 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:		aixwrap.c
+ * Description:
+ *     This file contains a single function, _MD_SELECT(), which simply
+ *     invokes the select() function.  This file is used in an ugly
+ *     hack to override the system select() function on AIX releases
+ *     prior to 4.2.  (On AIX 4.2, we use a different mechanism to
+ *     override select().)
+ */
+
+#ifndef AIX_RENAME_SELECT
+#error aixwrap.c should only be used on AIX 3.2 or 4.1
+#else
+
+#include <sys/select.h>
+#include <sys/poll.h>
+
+int _MD_SELECT(int width, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
+{
+    return select(width, r, w, e, t);
+}
+
+int _MD_POLL(void *listptr, unsigned long nfds, long timeout)
+{
+    return poll(listptr, nfds, timeout);
+}
+
+#endif /* AIX_RENAME_SELECT */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/bsdi.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/bsdi.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,119 @@
+/* -*- 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 <signal.h>
+
+void _MD_EarlyInit(void)
+{
+    /*
+     * Ignore FPE because coercion of a NaN to an int causes SIGFPE
+     * to be raised.
+     */
+    struct sigaction act;
+
+    act.sa_handler = SIG_IGN;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_RESTART;
+    sigaction(SIGFPE, &act, 0);
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+    *np = 0;
+    return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for BSDI */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for BSDI.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for BSDI.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/darwin.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/darwin.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,110 @@
+/* -*- 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"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#if !defined(_PR_PTHREADS)
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#if !defined(_PR_PTHREADS)
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Darwin */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Darwin.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Darwin.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
+
+/* darwin.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/dgux.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/dgux.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,109 @@
+/* -*- 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"
+
+/*
+ * using only NSPR threads here
+ *
+ *  Copied from the UnixWare implementation.  Should be kept in sync
+ *  with ../../../include/md/_dgux.h.
+ */
+
+#include <setjmp.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+        (void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+        PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for DG/UX */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for DG/UX.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for DG/UX.");
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/freebsd.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/freebsd.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,119 @@
+/* -*- 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 <signal.h>
+
+void _MD_EarlyInit(void)
+{
+    /*
+     * Ignore FPE because coercion of a NaN to an int causes SIGFPE
+     * to be raised.
+     */
+    struct sigaction act;
+
+    act.sa_handler = SIG_IGN;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_RESTART;
+    sigaction(SIGFPE, &act, 0);
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) sigsetjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for FreeBSD */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for FreeBSD.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for FreeBSD.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/hpux.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/hpux.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,261 @@
+/* -*- 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 <setjmp.h>
+
+#if defined(HPUX_LW_TIMER)
+
+#include <machine/inline.h>
+#include <machine/clock.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/pstat.h>
+
+int __lw_get_thread_times(int which, int64_t *sample, int64_t *time);
+
+static double msecond_per_itick;
+
+void _PR_HPUX_LW_IntervalInit(void)
+{
+    struct pst_processor psp;
+    int iticksperclktick, clk_tck;
+    int rv;
+
+    rv = pstat_getprocessor(&psp, sizeof(psp), 1, 0);
+    PR_ASSERT(rv != -1);
+
+    iticksperclktick = psp.psp_iticksperclktick;
+    clk_tck = sysconf(_SC_CLK_TCK);
+    msecond_per_itick = (1000.0)/(double)(iticksperclktick * clk_tck);
+}
+
+PRIntervalTime _PR_HPUX_LW_GetInterval(void)
+{
+    int64_t time, sample;
+
+    __lw_get_thread_times(1, &sample, &time);
+    /*
+     * Division is slower than float multiplication.
+     * return (time / iticks_per_msecond);
+     */
+    return (time * msecond_per_itick);
+}
+#endif  /* HPUX_LW_TIMER */
+
+#if !defined(PTHREADS_USER)
+
+void _MD_EarlyInit(void)
+{
+#ifndef _PR_PTHREADS
+    /*
+     * The following piece of code is taken from ns/nspr/src/md_HP-UX.c.
+     * In the comment for revision 1.6, dated 1995/09/11 23:33:34,
+     * robm says:
+     *     This version has some problems which need to be addressed.
+     *     First, intercept all system calls and prevent them from
+     *     executing the library code which performs stack switches
+     *     before normal system call invocation.  In order for library
+     *     calls which make system calls to work (like stdio), however,
+     *     we must also allocate our own stack and switch the primordial
+     *     stack to use it. This isn't so bad, except that I fudged the
+     *     backtrace length when copying the old stack to the new one.
+     *
+     * This is the original comment of robm in the code:
+     *    XXXrobm Horrific. To avoid a problem with HP's system call
+     *    code, we allocate a new stack for the primordial thread and
+     *    use it. However, we don't know how far back the original stack
+     *    goes. We should create a routine that performs a backtrace and
+     *    finds out just how much we need to copy. As a temporary measure,
+     *    I just copy an arbitrary guess.
+     *
+     * In an email to servereng dated 2 Jan 1997, Mike Patnode (mikep)
+     * suggests that this only needs to be done for HP-UX 9.
+     */
+#ifdef HPUX9
+#define PIDOOMA_STACK_SIZE 524288
+#define BACKTRACE_SIZE 8192
+    {
+        jmp_buf jb;
+        char *newstack;
+        char *oldstack;
+
+        if(!setjmp(jb)) {
+            newstack = (char *) PR_MALLOC(PIDOOMA_STACK_SIZE);
+	    oldstack = (char *) (*(((int *) jb) + 1) - BACKTRACE_SIZE);
+            memcpy(newstack, oldstack, BACKTRACE_SIZE);
+            *(((int *) jb) + 1) = (int) (newstack + BACKTRACE_SIZE);
+            longjmp(jb, 1);
+        }
+    }
+#endif  /* HPUX9 */
+#endif  /* !_PR_PTHREADS */
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for HP-UX */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for HP-UX.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for HP-UX.");
+}
+#endif /* _PR_PTHREADS */
+
+void
+_MD_suspend_thread(PRThread *thread)
+{
+#ifdef _PR_PTHREADS
+#endif
+}
+
+void
+_MD_resume_thread(PRThread *thread)
+{
+#ifdef _PR_PTHREADS
+#endif
+}
+#endif /* PTHREADS_USER */
+
+/*
+ * The HP version of strchr is buggy. It looks past the end of the
+ * string and causes a segmentation fault when our (NSPR) version
+ * of malloc is used.
+ *
+ * A better solution might be to put a cushion in our malloc just in
+ * case HP's version of strchr somehow gets used instead of this one.
+ */
+char *
+strchr(const char *s, int c)
+{
+    char ch;
+
+    if (!s) {
+        return NULL;
+    }
+
+    ch = (char) c;
+
+    while ((*s) && ((*s) != ch)) {
+        s++;
+    }
+
+    if ((*s) == ch) {
+        return (char *) s;
+    }
+
+    return NULL;
+}
+
+/*
+ * Implemementation of memcmp in HP-UX (verified on releases A.09.03,
+ * A.09.07, and B.10.10) dumps core if called with:
+ * 1. First operand with address = 1(mod 4).
+ * 2. Size = 1(mod 4)
+ * 3. Last byte of the second operand is the last byte of the page and 
+ *    next page is not accessible(not mapped or protected)
+ * Thus, using the following naive version (tons of optimizations are
+ * possible;^)
+ */
+
+int memcmp(const void *s1, const void *s2, size_t n)
+{
+    register unsigned char *p1 = (unsigned char *) s1,
+            *p2 = (unsigned char *) s2;
+
+    while (n-- > 0) {
+        register int r = ((int) ((unsigned int) *p1)) 
+                - ((int) ((unsigned int) *p2));
+        if (r) return r;
+        p1++; p2++;
+    }
+    return 0; 
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/irix.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/irix.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1680 @@
+/* -*- 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 <signal.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/syssgi.h>
+#include <sys/time.h>
+#include <sys/immu.h>
+#include <sys/utsname.h>
+#include <sys/sysmp.h>
+#include <sys/pda.h>
+#include <sys/prctl.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include <sys/procfs.h>
+#include <task.h>
+#include <dlfcn.h>
+
+static void _MD_IrixIntervalInit(void);
+
+#if defined(_PR_PTHREADS)
+/*
+ * for compatibility with classic nspr
+ */
+void _PR_IRIX_CHILD_PROCESS()
+{
+}
+#else  /* defined(_PR_PTHREADS) */
+
+static void irix_detach_sproc(void);
+char *_nspr_sproc_private;    /* ptr. to private region in every sproc */
+
+extern PRUintn    _pr_numCPU;
+
+typedef struct nspr_arena {
+	PRCList links;
+	usptr_t *usarena;
+} nspr_arena;
+
+#define ARENA_PTR(qp) \
+	((nspr_arena *) ((char*) (qp) - offsetof(nspr_arena , links)))
+
+static usptr_t *alloc_new_arena(void);
+
+PRCList arena_list = PR_INIT_STATIC_CLIST(&arena_list);
+ulock_t arena_list_lock;
+nspr_arena first_arena;
+int	_nspr_irix_arena_cnt = 1;
+
+PRCList sproc_list = PR_INIT_STATIC_CLIST(&sproc_list);
+ulock_t sproc_list_lock;
+
+typedef struct sproc_data {
+	void (*entry) (void *, size_t);
+	unsigned inh;
+	void *arg;
+	caddr_t sp;
+	size_t len;
+	int *pid;
+	int creator_pid;
+} sproc_data;
+
+typedef struct sproc_params {
+	PRCList links;
+	sproc_data sd;
+} sproc_params;
+
+#define SPROC_PARAMS_PTR(qp) \
+	((sproc_params *) ((char*) (qp) - offsetof(sproc_params , links)))
+
+long	_nspr_irix_lock_cnt = 0;
+long	_nspr_irix_sem_cnt = 0;
+long	_nspr_irix_pollsem_cnt = 0;
+
+usptr_t *_pr_usArena;
+ulock_t _pr_heapLock;
+
+usema_t *_pr_irix_exit_sem;
+PRInt32 _pr_irix_exit_now = 0;
+PRInt32 _pr_irix_process_exit_code = 0;	/* exit code for PR_ProcessExit */
+PRInt32 _pr_irix_process_exit = 0; /* process exiting due to call to
+										   PR_ProcessExit */
+
+int _pr_irix_primoridal_cpu_fd[2] = { -1, -1 };
+static void (*libc_exit)(int) = NULL;
+static void *libc_handle = NULL;
+
+#define _NSPR_DEF_INITUSERS		100	/* default value of CONF_INITUSERS */
+#define _NSPR_DEF_INITSIZE		(4 * 1024 * 1024)	/* 4 MB */
+
+int _irix_initusers = _NSPR_DEF_INITUSERS;
+int _irix_initsize = _NSPR_DEF_INITSIZE;
+
+PRIntn _pr_io_in_progress, _pr_clock_in_progress;
+
+PRInt32 _pr_md_irix_sprocs_created, _pr_md_irix_sprocs_failed;
+PRInt32 _pr_md_irix_sprocs = 1;
+PRCList _pr_md_irix_sproc_list =
+PR_INIT_STATIC_CLIST(&_pr_md_irix_sproc_list);
+
+sigset_t ints_off;
+extern sigset_t timer_set;
+
+#if !defined(PR_SETABORTSIG)
+#define PR_SETABORTSIG 18
+#endif
+/*
+ * terminate the entire application if any sproc exits abnormally
+ */
+PRBool _nspr_terminate_on_error = PR_TRUE;
+
+/*
+ * exported interface to set the shared arena parameters
+ */
+void _PR_Irix_Set_Arena_Params(PRInt32 initusers, PRInt32 initsize)
+{
+    _irix_initusers = initusers;
+    _irix_initsize = initsize;
+}
+
+static usptr_t *alloc_new_arena()
+{
+    return(usinit("/dev/zero"));
+}
+
+static PRStatus new_poll_sem(struct _MDThread *mdthr, int val)
+{
+PRIntn _is;
+PRStatus rv = PR_SUCCESS;
+usema_t *sem = NULL;
+PRCList *qp;
+nspr_arena *arena;
+usptr_t *irix_arena;
+PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	_PR_LOCK(arena_list_lock);
+	for (qp = arena_list.next; qp != &arena_list; qp = qp->next) {
+		arena = ARENA_PTR(qp);
+		sem = usnewpollsema(arena->usarena, val);
+		if (sem != NULL) {
+			mdthr->cvar_pollsem = sem;
+			mdthr->pollsem_arena = arena->usarena;
+			break;
+		}
+	}
+	if (sem == NULL) {
+		/*
+		 * If no space left in the arena allocate a new one.
+		 */
+		if (errno == ENOMEM) {
+			arena = PR_NEWZAP(nspr_arena);
+			if (arena != NULL) {
+				irix_arena = alloc_new_arena();
+				if (irix_arena) {
+					PR_APPEND_LINK(&arena->links, &arena_list);
+					_nspr_irix_arena_cnt++;
+					arena->usarena = irix_arena;
+					sem = usnewpollsema(arena->usarena, val);
+					if (sem != NULL) {
+						mdthr->cvar_pollsem = sem;
+						mdthr->pollsem_arena = arena->usarena;
+					} else
+						rv = PR_FAILURE;
+				} else {
+					PR_DELETE(arena);
+					rv = PR_FAILURE;
+				}
+
+			} else
+				rv = PR_FAILURE;
+		} else
+			rv = PR_FAILURE;
+	}
+	_PR_UNLOCK(arena_list_lock);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+	if (rv == PR_SUCCESS)
+		_MD_ATOMIC_INCREMENT(&_nspr_irix_pollsem_cnt);
+	return rv;
+}
+
+static void free_poll_sem(struct _MDThread *mdthr)
+{
+PRIntn _is;
+PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	usfreepollsema(mdthr->cvar_pollsem, mdthr->pollsem_arena);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+	_MD_ATOMIC_DECREMENT(&_nspr_irix_pollsem_cnt);
+}
+
+static PRStatus new_lock(struct _MDLock *lockp)
+{
+PRIntn _is;
+PRStatus rv = PR_SUCCESS;
+ulock_t lock = NULL;
+PRCList *qp;
+nspr_arena *arena;
+usptr_t *irix_arena;
+PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	_PR_LOCK(arena_list_lock);
+	for (qp = arena_list.next; qp != &arena_list; qp = qp->next) {
+		arena = ARENA_PTR(qp);
+		lock = usnewlock(arena->usarena);
+		if (lock != NULL) {
+			lockp->lock = lock;
+			lockp->arena = arena->usarena;
+			break;
+		}
+	}
+	if (lock == NULL) {
+		/*
+		 * If no space left in the arena allocate a new one.
+		 */
+		if (errno == ENOMEM) {
+			arena = PR_NEWZAP(nspr_arena);
+			if (arena != NULL) {
+				irix_arena = alloc_new_arena();
+				if (irix_arena) {
+					PR_APPEND_LINK(&arena->links, &arena_list);
+					_nspr_irix_arena_cnt++;
+					arena->usarena = irix_arena;
+					lock = usnewlock(irix_arena);
+					if (lock != NULL) {
+						lockp->lock = lock;
+						lockp->arena = arena->usarena;
+					} else
+						rv = PR_FAILURE;
+				} else {
+					PR_DELETE(arena);
+					rv = PR_FAILURE;
+				}
+
+			} else
+				rv = PR_FAILURE;
+		} else
+			rv = PR_FAILURE;
+	}
+	_PR_UNLOCK(arena_list_lock);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+	if (rv == PR_SUCCESS)
+		_MD_ATOMIC_INCREMENT(&_nspr_irix_lock_cnt);
+	return rv;
+}
+
+static void free_lock(struct _MDLock *lockp)
+{
+PRIntn _is;
+PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	usfreelock(lockp->lock, lockp->arena);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+	_MD_ATOMIC_DECREMENT(&_nspr_irix_lock_cnt);
+}
+
+void _MD_FREE_LOCK(struct _MDLock *lockp)
+{
+	PRIntn _is;
+	PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	free_lock(lockp);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+}
+
+/*
+ * _MD_get_attached_thread
+ *		Return the thread pointer of the current thread if it is attached.
+ *
+ *		This function is needed for Irix because the thread-local-storage is
+ *		implemented by mmapin'g a page with the MAP_LOCAL flag. This causes the
+ *		sproc-private page to inherit contents of the page of the caller of sproc().
+ */
+PRThread *_MD_get_attached_thread(void)
+{
+
+	if (_MD_GET_SPROC_PID() == get_pid())
+		return _MD_THIS_THREAD();
+	else
+		return 0;
+}
+
+/*
+ * _MD_get_current_thread
+ *		Return the thread pointer of the current thread (attaching it if
+ *		necessary)
+ */
+PRThread *_MD_get_current_thread(void)
+{
+PRThread *me;
+
+	me = _MD_GET_ATTACHED_THREAD();
+    if (NULL == me) {
+        me = _PRI_AttachThread(
+            PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0);
+    }
+    PR_ASSERT(me != NULL);
+	return(me);
+}
+
+/*
+ * irix_detach_sproc
+ *		auto-detach a sproc when it exits
+ */
+void irix_detach_sproc(void)
+{
+PRThread *me;
+
+	me = _MD_GET_ATTACHED_THREAD();
+	if ((me != NULL) && (me->flags & _PR_ATTACHED)) {
+		_PRI_DetachThread();
+	}
+}
+
+
+PRStatus _MD_NEW_LOCK(struct _MDLock *lockp)
+{
+    PRStatus rv;
+    PRIntn is;
+    PRThread *me = _MD_GET_ATTACHED_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(is);
+	rv = new_lock(lockp);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(is);
+	return rv;
+}
+
+static void
+sigchld_handler(int sig)
+{
+    pid_t pid;
+    int status;
+
+    /*
+     * If an sproc exited abnormally send a SIGKILL signal to all the
+     * sprocs in the process to terminate the application
+     */
+    while ((pid = waitpid(0, &status, WNOHANG)) > 0) {
+        if (WIFSIGNALED(status) && ((WTERMSIG(status) == SIGSEGV) ||
+            (WTERMSIG(status) == SIGBUS) ||
+            (WTERMSIG(status) == SIGABRT) ||
+            (WTERMSIG(status) == SIGILL))) {
+
+				prctl(PR_SETEXITSIG, SIGKILL);
+				_exit(status);
+			}
+    }
+}
+
+static void save_context_and_block(int sig)
+{
+PRThread *me = _PR_MD_CURRENT_THREAD();
+_PRCPU *cpu = _PR_MD_CURRENT_CPU();
+
+	/*
+	 * save context
+	 */
+	(void) setjmp(me->md.jb);
+	/*
+	 * unblock the suspending thread
+	 */
+	if (me->cpu) {
+		/*
+		 * I am a cpu thread, not a user-created GLOBAL thread
+		 */
+		unblockproc(cpu->md.suspending_id);	
+	} else {
+		unblockproc(me->md.suspending_id);	
+	}
+	/*
+	 * now, block current thread
+	 */
+	blockproc(getpid());
+}
+
+/*
+** The irix kernel has a bug in it which causes async connect's which are
+** interrupted by a signal to fail terribly (EADDRINUSE is returned). 
+** We work around the bug by blocking signals during the async connect
+** attempt.
+*/
+PRInt32 _MD_irix_connect(
+    PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout)
+{
+    PRInt32 rv;
+    sigset_t oldset;
+
+    sigprocmask(SIG_BLOCK, &ints_off, &oldset);
+    rv = connect(osfd, addr, addrlen);
+    sigprocmask(SIG_SETMASK, &oldset, 0);
+
+    return(rv);
+}
+
+#include "prprf.h"
+
+/********************************************************************/
+/********************************************************************/
+/*************** Various thread like things for IRIX ****************/
+/********************************************************************/
+/********************************************************************/
+
+void *_MD_GetSP(PRThread *t)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    void *sp;
+
+    if (me == t)
+        (void) setjmp(t->md.jb);
+
+    sp = (void *)(t->md.jb[JB_SP]);
+    PR_ASSERT((sp >= (void *) t->stack->stackBottom) &&
+        (sp <= (void *) (t->stack->stackBottom + t->stack->stackSize)));
+    return(sp);
+}
+
+void _MD_InitLocks()
+{
+    char buf[200];
+    char *init_users, *init_size;
+
+    PR_snprintf(buf, sizeof(buf), "/dev/zero");
+
+    if (init_users = getenv("_NSPR_IRIX_INITUSERS"))
+        _irix_initusers = atoi(init_users);
+
+    if (init_size = getenv("_NSPR_IRIX_INITSIZE"))
+        _irix_initsize = atoi(init_size);
+
+    usconfig(CONF_INITUSERS, _irix_initusers);
+    usconfig(CONF_INITSIZE, _irix_initsize);
+    usconfig(CONF_AUTOGROW, 1);
+    usconfig(CONF_AUTORESV, 1);
+	if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0) {
+		perror("PR_Init: unable to config mutex arena");
+		exit(-1);
+	}
+
+    _pr_usArena = usinit(buf);
+    if (!_pr_usArena) {
+        fprintf(stderr,
+            "PR_Init: Error - unable to create lock/monitor arena\n");
+        exit(-1);
+    }
+    _pr_heapLock = usnewlock(_pr_usArena);
+	_nspr_irix_lock_cnt++;
+
+    arena_list_lock = usnewlock(_pr_usArena);
+	_nspr_irix_lock_cnt++;
+
+    sproc_list_lock = usnewlock(_pr_usArena);
+	_nspr_irix_lock_cnt++;
+
+	_pr_irix_exit_sem = usnewsema(_pr_usArena, 0);
+	_nspr_irix_sem_cnt = 1;
+
+	first_arena.usarena = _pr_usArena;
+	PR_INIT_CLIST(&first_arena.links);
+	PR_APPEND_LINK(&first_arena.links, &arena_list);
+}
+
+/* _PR_IRIX_CHILD_PROCESS is a private API for Server group */
+void _PR_IRIX_CHILD_PROCESS()
+{
+extern PRUint32 _pr_global_threads;
+
+    PR_ASSERT(_PR_MD_CURRENT_CPU() == _pr_primordialCPU);
+    PR_ASSERT(_pr_numCPU == 1);
+    PR_ASSERT(_pr_global_threads == 0);
+    /*
+     * save the new pid
+     */
+    _pr_primordialCPU->md.id = getpid();
+	_MD_SET_SPROC_PID(getpid());	
+}
+
+static PRStatus pr_cvar_wait_sem(PRThread *thread, PRIntervalTime timeout)
+{
+    int rv;
+
+#ifdef _PR_USE_POLL
+	struct pollfd pfd;
+	int msecs;
+
+	if (timeout == PR_INTERVAL_NO_TIMEOUT)
+		msecs = -1;
+	else
+		msecs  = PR_IntervalToMilliseconds(timeout);
+#else
+    struct timeval tv, *tvp;
+    fd_set rd;
+
+	if(timeout == PR_INTERVAL_NO_TIMEOUT)
+		tvp = NULL;
+	else {
+		tv.tv_sec = PR_IntervalToSeconds(timeout);
+		tv.tv_usec = PR_IntervalToMicroseconds(
+		timeout - PR_SecondsToInterval(tv.tv_sec));
+		tvp = &tv;
+	}
+	FD_ZERO(&rd);
+	FD_SET(thread->md.cvar_pollsemfd, &rd);
+#endif
+
+    /*
+     * call uspsema only if a previous select call on this semaphore
+     * did not timeout
+     */
+    if (!thread->md.cvar_pollsem_select) {
+        rv = _PR_WAIT_SEM(thread->md.cvar_pollsem);
+		PR_ASSERT(rv >= 0);
+	} else
+        rv = 0;
+again:
+    if(!rv) {
+#ifdef _PR_USE_POLL
+		pfd.events = POLLIN;
+		pfd.fd = thread->md.cvar_pollsemfd;
+		rv = _MD_POLL(&pfd, 1, msecs);
+#else
+		rv = _MD_SELECT(thread->md.cvar_pollsemfd + 1, &rd, NULL,NULL,tvp);
+#endif
+        if ((rv == -1) && (errno == EINTR)) {
+			rv = 0;
+			goto again;
+		}
+		PR_ASSERT(rv >= 0);
+	}
+
+    if (rv > 0) {
+        /*
+         * acquired the semaphore, call uspsema next time
+         */
+        thread->md.cvar_pollsem_select = 0;
+        return PR_SUCCESS;
+    } else {
+        /*
+         * select timed out; must call select, not uspsema, when trying
+         * to acquire the semaphore the next time
+         */
+        thread->md.cvar_pollsem_select = 1;
+        return PR_FAILURE;
+    }
+}
+
+PRStatus _MD_wait(PRThread *thread, PRIntervalTime ticks)
+{
+    if ( thread->flags & _PR_GLOBAL_SCOPE ) {
+	_MD_CHECK_FOR_EXIT();
+        if (pr_cvar_wait_sem(thread, ticks) == PR_FAILURE) {
+	    _MD_CHECK_FOR_EXIT();
+            /*
+             * wait timed out
+             */
+            _PR_THREAD_LOCK(thread);
+            if (thread->wait.cvar) {
+                /*
+                 * The thread will remove itself from the waitQ
+                 * of the cvar in _PR_WaitCondVar
+                 */
+                thread->wait.cvar = NULL;
+                thread->state =  _PR_RUNNING;
+                _PR_THREAD_UNLOCK(thread);
+            }  else {
+                _PR_THREAD_UNLOCK(thread);
+                /*
+             * This thread was woken up by a notifying thread
+             * at the same time as a timeout; so, consume the
+             * extra post operation on the semaphore
+             */
+	        _MD_CHECK_FOR_EXIT();
+            pr_cvar_wait_sem(thread, PR_INTERVAL_NO_TIMEOUT);
+            }
+	    _MD_CHECK_FOR_EXIT();
+        }
+    } else {
+        _PR_MD_SWITCH_CONTEXT(thread);
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus _MD_WakeupWaiter(PRThread *thread)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntn is;
+
+	PR_ASSERT(_pr_md_idle_cpus >= 0);
+    if (thread == NULL) {
+		if (_pr_md_idle_cpus)
+        	_MD_Wakeup_CPUs();
+    } else if (!_PR_IS_NATIVE_THREAD(thread)) {
+		if (_pr_md_idle_cpus)
+       		_MD_Wakeup_CPUs();
+    } else {
+		PR_ASSERT(_PR_IS_NATIVE_THREAD(thread));
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_INTSOFF(is);
+		_MD_CVAR_POST_SEM(thread);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+    } 
+    return PR_SUCCESS;
+}
+
+void create_sproc (void (*entry) (void *, size_t), unsigned inh,
+					void *arg, caddr_t sp, size_t len, int *pid)
+{
+sproc_params sparams;
+char data;
+int rv;
+PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (!_PR_IS_NATIVE_THREAD(me) && (_PR_MD_CURRENT_CPU()->id == 0)) {
+		*pid = sprocsp(entry,		/* startup func		*/
+						inh,        /* attribute flags	*/
+						arg,     	/* thread param		*/
+						sp,         /* stack address	*/
+						len);       /* stack size		*/
+	} else {
+		sparams.sd.entry = entry;
+		sparams.sd.inh = inh;
+		sparams.sd.arg = arg;
+		sparams.sd.sp = sp;
+		sparams.sd.len = len;
+		sparams.sd.pid = pid;
+		sparams.sd.creator_pid = getpid();
+		_PR_LOCK(sproc_list_lock);
+		PR_APPEND_LINK(&sparams.links, &sproc_list);
+		rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1);
+		PR_ASSERT(rv == 1);
+		_PR_UNLOCK(sproc_list_lock);
+		blockproc(getpid());
+	}
+}
+
+/*
+ * _PR_MD_WAKEUP_PRIMORDIAL_CPU
+ *
+ *		wakeup cpu 0
+ */
+
+void _PR_MD_WAKEUP_PRIMORDIAL_CPU()
+{
+char data = '0';
+int rv;
+
+	rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1);
+	PR_ASSERT(rv == 1);
+}
+
+/*
+ * _PR_MD_primordial_cpu
+ *
+ *		process events that need to executed by the primordial cpu on each
+ *		iteration through the idle loop
+ */
+
+void _PR_MD_primordial_cpu()
+{
+PRCList *qp;
+sproc_params *sp;
+int pid;
+
+	_PR_LOCK(sproc_list_lock);
+	while ((qp = sproc_list.next) != &sproc_list) {
+		sp = SPROC_PARAMS_PTR(qp);
+		PR_REMOVE_LINK(&sp->links);
+		pid = sp->sd.creator_pid;
+		(*(sp->sd.pid)) = sprocsp(sp->sd.entry,		/* startup func    */
+							sp->sd.inh,            	/* attribute flags     */
+							sp->sd.arg,     		/* thread param     */
+							sp->sd.sp,             	/* stack address    */
+							sp->sd.len);         	/* stack size     */
+		unblockproc(pid);
+	}
+	_PR_UNLOCK(sproc_list_lock);
+}
+
+PRStatus _MD_CreateThread(PRThread *thread, 
+void (*start)(void *), 
+PRThreadPriority priority, 
+PRThreadScope scope, 
+PRThreadState state, 
+PRUint32 stackSize)
+{
+    typedef void (*SprocEntry) (void *, size_t);
+    SprocEntry spentry = (SprocEntry)start;
+    PRIntn is;
+	PRThread *me = _PR_MD_CURRENT_THREAD();	
+	PRInt32 pid;
+	PRStatus rv;
+
+	if (!_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(is);
+    thread->md.cvar_pollsem_select = 0;
+    thread->flags |= _PR_GLOBAL_SCOPE;
+
+	thread->md.cvar_pollsemfd = -1;
+	if (new_poll_sem(&thread->md,0) == PR_FAILURE) {
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+		return PR_FAILURE;
+	}
+	thread->md.cvar_pollsemfd =
+		_PR_OPEN_POLL_SEM(thread->md.cvar_pollsem);
+	if ((thread->md.cvar_pollsemfd < 0)) {
+		free_poll_sem(&thread->md);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+		return PR_FAILURE;
+	}
+
+    create_sproc(spentry,            /* startup func    */
+    			PR_SALL,            /* attribute flags     */
+    			(void *)thread,     /* thread param     */
+    			NULL,               /* stack address    */
+    			stackSize, &pid);         /* stack size     */
+    if (pid > 0) {
+        _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs_created);
+        _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs);
+		rv = PR_SUCCESS;
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return rv;
+    } else {
+        close(thread->md.cvar_pollsemfd);
+        thread->md.cvar_pollsemfd = -1;
+		free_poll_sem(&thread->md);
+        thread->md.cvar_pollsem = NULL;
+        _MD_ATOMIC_INCREMENT(&_pr_md_irix_sprocs_failed);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return PR_FAILURE;
+    }
+}
+
+void _MD_CleanThread(PRThread *thread)
+{
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        close(thread->md.cvar_pollsemfd);
+        thread->md.cvar_pollsemfd = -1;
+		free_poll_sem(&thread->md);
+        thread->md.cvar_pollsem = NULL;
+    }
+}
+
+void _MD_SetPriority(_MDThread *thread, PRThreadPriority newPri)
+{
+    return;
+}
+
+extern void _MD_unix_terminate_waitpid_daemon(void);
+
+void
+_MD_CleanupBeforeExit(void)
+{
+    extern PRInt32    _pr_cpus_exit;
+
+    _MD_unix_terminate_waitpid_daemon();
+
+	_pr_irix_exit_now = 1;
+    if (_pr_numCPU > 1) {
+        /*
+         * Set a global flag, and wakeup all cpus which will notice the flag
+         * and exit.
+         */
+        _pr_cpus_exit = getpid();
+        _MD_Wakeup_CPUs();
+        while(_pr_numCPU > 1) {
+            _PR_WAIT_SEM(_pr_irix_exit_sem);
+            _pr_numCPU--;
+        }
+    }
+    /*
+     * cause global threads on the recycle list to exit
+     */
+     _PR_DEADQ_LOCK;
+     if (_PR_NUM_DEADNATIVE != 0) {
+	PRThread *thread;
+    	PRCList *ptr;
+
+        ptr = _PR_DEADNATIVEQ.next;
+        while( ptr != &_PR_DEADNATIVEQ ) {
+        	thread = _PR_THREAD_PTR(ptr);
+		_MD_CVAR_POST_SEM(thread);
+                ptr = ptr->next;
+        } 
+     }
+     _PR_DEADQ_UNLOCK;
+     while(_PR_NUM_DEADNATIVE > 1) {
+	_PR_WAIT_SEM(_pr_irix_exit_sem);
+	_PR_DEC_DEADNATIVE;
+     }
+}
+
+#ifdef _PR_HAVE_SGI_PRDA_PROCMASK
+extern void __sgi_prda_procmask(int);
+#endif
+
+PRStatus
+_MD_InitAttachedThread(PRThread *thread, PRBool wakeup_parent)
+{
+	PRStatus rv = PR_SUCCESS;
+
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+		if (new_poll_sem(&thread->md,0) == PR_FAILURE) {
+			return PR_FAILURE;
+		}
+		thread->md.cvar_pollsemfd =
+			_PR_OPEN_POLL_SEM(thread->md.cvar_pollsem);
+		if ((thread->md.cvar_pollsemfd < 0)) {
+			free_poll_sem(&thread->md);
+			return PR_FAILURE;
+		}
+		if (_MD_InitThread(thread, PR_FALSE) == PR_FAILURE) {
+			close(thread->md.cvar_pollsemfd);
+			thread->md.cvar_pollsemfd = -1;
+			free_poll_sem(&thread->md);
+			thread->md.cvar_pollsem = NULL;
+			return PR_FAILURE;
+		}
+    }
+	return rv;
+}
+
+PRStatus
+_MD_InitThread(PRThread *thread, PRBool wakeup_parent)
+{
+    struct sigaction sigact;
+	PRStatus rv = PR_SUCCESS;
+
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+		thread->md.id = getpid();
+        setblockproccnt(thread->md.id, 0);
+		_MD_SET_SPROC_PID(getpid());	
+#ifdef _PR_HAVE_SGI_PRDA_PROCMASK
+		/*
+		 * enable user-level processing of sigprocmask(); this is an
+		 * undocumented feature available in Irix 6.2, 6.3, 6.4 and 6.5
+		 */
+		__sgi_prda_procmask(USER_LEVEL);
+#endif
+		/*
+		 * set up SIGUSR1 handler; this is used to save state
+		 */
+		sigact.sa_handler = save_context_and_block;
+		sigact.sa_flags = SA_RESTART;
+		/*
+		 * Must mask clock interrupts
+		 */
+		sigact.sa_mask = timer_set;
+		sigaction(SIGUSR1, &sigact, 0);
+
+
+		/*
+		 * PR_SETABORTSIG is a new command implemented in a patch to
+		 * Irix 6.2, 6.3 and 6.4. This causes a signal to be sent to all
+		 * sprocs in the process when one of them terminates abnormally
+		 *
+		 */
+		if (prctl(PR_SETABORTSIG, SIGKILL) < 0) {
+			/*
+			 *  if (errno == EINVAL)
+			 *
+			 *	PR_SETABORTSIG not supported under this OS.
+			 *	You may want to get a recent kernel rollup patch that
+			 *	supports this feature.
+			 */
+		}
+		/*
+		 * SIGCLD handler for detecting abormally-terminating
+		 * sprocs and for reaping sprocs
+		 */
+		sigact.sa_handler = sigchld_handler;
+		sigact.sa_flags = SA_RESTART;
+		sigact.sa_mask = ints_off;
+		sigaction(SIGCLD, &sigact, NULL);
+    }
+	return rv;
+}
+
+/*
+ * PR_Cleanup should be executed on the primordial sproc; migrate the thread
+ * to the primordial cpu
+ */
+
+void _PR_MD_PRE_CLEANUP(PRThread *me)
+{
+PRIntn is;
+_PRCPU *cpu = _pr_primordialCPU;
+
+	PR_ASSERT(cpu);
+
+	me->flags |= _PR_BOUND_THREAD;	
+
+	if (me->cpu->id != 0) {
+		_PR_INTSOFF(is);
+		_PR_RUNQ_LOCK(cpu);
+		me->cpu = cpu;
+		me->state = _PR_RUNNABLE;
+		_PR_ADD_RUNQ(me, cpu, me->priority);
+		_PR_RUNQ_UNLOCK(cpu);
+		_MD_Wakeup_CPUs();
+
+		_PR_MD_SWITCH_CONTEXT(me);
+
+		_PR_FAST_INTSON(is);
+		PR_ASSERT(me->cpu->id == 0);
+	}
+}
+
+/*
+ * process exiting
+ */
+PR_EXTERN(void ) _MD_exit(PRIntn status)
+{
+PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	/*
+	 * the exit code of the process is the exit code of the primordial
+	 * sproc
+	 */
+	if (!_PR_IS_NATIVE_THREAD(me) && (_PR_MD_CURRENT_CPU()->id == 0)) {
+		/*
+		 * primordial sproc case: call _exit directly
+		 * Cause SIGKILL to be sent to other sprocs
+		 */
+		prctl(PR_SETEXITSIG, SIGKILL);
+		_exit(status);
+	} else {
+		int rv;
+		char data;
+		sigset_t set;
+
+		/*
+		 * non-primordial sproc case: cause the primordial sproc, cpu 0,
+		 * to wakeup and call _exit
+		 */
+		_pr_irix_process_exit = 1;
+		_pr_irix_process_exit_code = status;
+		rv = write(_pr_irix_primoridal_cpu_fd[1], &data, 1);
+		PR_ASSERT(rv == 1);
+		/*
+		 * block all signals and wait for SIGKILL to terminate this sproc
+		 */
+		sigfillset(&set);
+		sigsuspend(&set);
+		/*
+		 * this code doesn't (shouldn't) execute
+		 */
+		prctl(PR_SETEXITSIG, SIGKILL);
+		_exit(status);
+	}
+}
+
+/*
+ * Override the exit() function in libc to cause the process to exit
+ * when the primodial/main nspr thread calls exit. Calls to exit by any
+ * other thread simply result in a call to the exit function in libc.
+ * The exit code of the process is the exit code of the primordial
+ * sproc.
+ */
+
+void exit(int status)
+{
+PRThread *me, *thr;
+PRCList *qp;
+
+	if (!_pr_initialized)  {
+		if (!libc_exit) {
+
+			if (!libc_handle)
+				libc_handle = dlopen("libc.so",RTLD_NOW);
+			if (libc_handle)
+				libc_exit = (void (*)(int)) dlsym(libc_handle, "exit");
+		}
+		if (libc_exit)
+			(*libc_exit)(status);
+		else
+			_exit(status);
+	}
+
+	me = _PR_MD_CURRENT_THREAD();
+
+	if (me == NULL) 		/* detached thread */
+		(*libc_exit)(status);
+
+	PR_ASSERT(_PR_IS_NATIVE_THREAD(me) ||
+						(_PR_MD_CURRENT_CPU())->id == me->cpu->id);
+
+	if (me->flags & _PR_PRIMORDIAL) {
+
+		me->flags |= _PR_BOUND_THREAD;	
+
+		PR_ASSERT((_PR_MD_CURRENT_CPU())->id == me->cpu->id);
+		if (me->cpu->id != 0) {
+			_PRCPU *cpu = _pr_primordialCPU;
+			PRIntn is;
+
+			_PR_INTSOFF(is);
+			_PR_RUNQ_LOCK(cpu);
+			me->cpu = cpu;
+			me->state = _PR_RUNNABLE;
+			_PR_ADD_RUNQ(me, cpu, me->priority);
+			_PR_RUNQ_UNLOCK(cpu);
+			_MD_Wakeup_CPUs();
+
+			_PR_MD_SWITCH_CONTEXT(me);
+
+			_PR_FAST_INTSON(is);
+		}
+
+		PR_ASSERT((_PR_MD_CURRENT_CPU())->id == 0);
+
+		if (prctl(PR_GETNSHARE) > 1) {
+#define SPROC_EXIT_WAIT_TIME 5
+			int sleep_cnt = SPROC_EXIT_WAIT_TIME;
+
+			/*
+			 * sprocs still running; caue cpus and recycled global threads
+			 * to exit
+			 */
+			_pr_irix_exit_now = 1;
+			if (_pr_numCPU > 1) {
+				_MD_Wakeup_CPUs();
+			}
+			 _PR_DEADQ_LOCK;
+			 if (_PR_NUM_DEADNATIVE != 0) {
+				PRThread *thread;
+				PRCList *ptr;
+
+				ptr = _PR_DEADNATIVEQ.next;
+				while( ptr != &_PR_DEADNATIVEQ ) {
+					thread = _PR_THREAD_PTR(ptr);
+					_MD_CVAR_POST_SEM(thread);
+					ptr = ptr->next;
+				} 
+			 }
+
+			while (sleep_cnt-- > 0) {
+				if (waitpid(0, NULL, WNOHANG) >= 0) 
+					sleep(1);
+				else
+					break;
+			}
+			prctl(PR_SETEXITSIG, SIGKILL);
+		}
+		(*libc_exit)(status);
+	} else {
+		/*
+		 * non-primordial thread; simply call exit in libc.
+		 */
+		(*libc_exit)(status);
+	}
+}
+
+
+void
+_MD_InitRunningCPU(_PRCPU *cpu)
+{
+    extern int _pr_md_pipefd[2];
+
+    _MD_unix_init_running_cpu(cpu);
+    cpu->md.id = getpid();
+	_MD_SET_SPROC_PID(getpid());	
+	if (_pr_md_pipefd[0] >= 0) {
+    	_PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[0];
+#ifndef _PR_USE_POLL
+    	FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu));
+#endif
+	}
+}
+
+void
+_MD_ExitThread(PRThread *thread)
+{
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        _MD_ATOMIC_DECREMENT(&_pr_md_irix_sprocs);
+        _MD_CLEAN_THREAD(thread);
+        _MD_SET_CURRENT_THREAD(NULL);
+    }
+}
+
+void
+_MD_SuspendCPU(_PRCPU *cpu)
+{
+    PRInt32 rv;
+
+	cpu->md.suspending_id = getpid();
+	rv = kill(cpu->md.id, SIGUSR1);
+	PR_ASSERT(rv == 0);
+	/*
+	 * now, block the current thread/cpu until woken up by the suspended
+	 * thread from it's SIGUSR1 signal handler
+	 */
+	blockproc(getpid());
+
+}
+
+void
+_MD_ResumeCPU(_PRCPU *cpu)
+{
+    unblockproc(cpu->md.id);
+}
+
+#if 0
+/*
+ * save the register context of a suspended sproc
+ */
+void get_context(PRThread *thr)
+{
+    int len, fd;
+    char pidstr[24];
+    char path[24];
+
+    /*
+     * open the file corresponding to this process in procfs
+     */
+    sprintf(path,"/proc/%s","00000");
+    len = strlen(path);
+    sprintf(pidstr,"%d",thr->md.id);
+    len -= strlen(pidstr);
+    sprintf(path + len,"%s",pidstr);
+    fd = open(path,O_RDONLY);
+    if (fd >= 0) {
+        (void) ioctl(fd, PIOCGREG, thr->md.gregs);
+        close(fd);
+    }
+    return;
+}
+#endif	/* 0 */
+
+void
+_MD_SuspendThread(PRThread *thread)
+{
+    PRInt32 rv;
+
+    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&
+        _PR_IS_GCABLE_THREAD(thread));
+
+	thread->md.suspending_id = getpid();
+	rv = kill(thread->md.id, SIGUSR1);
+	PR_ASSERT(rv == 0);
+	/*
+	 * now, block the current thread/cpu until woken up by the suspended
+	 * thread from it's SIGUSR1 signal handler
+	 */
+	blockproc(getpid());
+}
+
+void
+_MD_ResumeThread(PRThread *thread)
+{
+    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&
+        _PR_IS_GCABLE_THREAD(thread));
+    (void)unblockproc(thread->md.id);
+}
+
+/*
+ * return the set of processors available for scheduling procs in the
+ * "mask" argument
+ */
+PRInt32 _MD_GetThreadAffinityMask(PRThread *unused, PRUint32 *mask)
+{
+    PRInt32 nprocs, rv;
+    struct pda_stat *pstat;
+#define MAX_PROCESSORS    32
+
+    nprocs = sysmp(MP_NPROCS);
+    if (nprocs < 0)
+        return(-1);
+    pstat = (struct pda_stat*)PR_MALLOC(sizeof(struct pda_stat) * nprocs);
+    if (pstat == NULL)
+        return(-1);
+    rv = sysmp(MP_STAT, pstat);
+    if (rv < 0) {
+        PR_DELETE(pstat);
+        return(-1);
+    }
+    /*
+     * look at the first 32 cpus
+     */
+    nprocs = (nprocs > MAX_PROCESSORS) ? MAX_PROCESSORS : nprocs;
+    *mask = 0;
+    while (nprocs) {
+        if ((pstat->p_flags & PDAF_ENABLED) &&
+            !(pstat->p_flags & PDAF_ISOLATED)) {
+            *mask |= (1 << pstat->p_cpuid);
+        }
+        nprocs--;
+        pstat++;
+    }
+    return 0;
+}
+
+static char *_thr_state[] = {
+    "UNBORN",
+    "RUNNABLE",
+    "RUNNING",
+    "LOCK_WAIT",
+    "COND_WAIT",
+    "JOIN_WAIT",
+    "IO_WAIT",
+    "SUSPENDED",
+    "DEAD"
+};
+
+void _PR_List_Threads()
+{
+    PRThread *thr;
+    void *handle;
+    struct _PRCPU *cpu;
+    PRCList *qp;
+    int len, fd;
+    char pidstr[24];
+    char path[24];
+    prpsinfo_t pinfo;
+
+
+    printf("\n%s %-s\n"," ","LOCAL Threads");
+    printf("%s %-s\n"," ","----- -------");
+    printf("%s %-14s %-10s %-12s %-3s %-10s %-10s %-12s\n\n"," ",
+        "Thread", "State", "Wait-Handle",
+        "Cpu","Stk-Base","Stk-Sz","SP");
+    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
+        qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) {
+        thr = _PR_ACTIVE_THREAD_PTR(qp);
+        printf("%s 0x%-12x %-10s "," ",thr,_thr_state[thr->state]);
+        if (thr->state == _PR_LOCK_WAIT)
+            handle = thr->wait.lock;
+        else if (thr->state == _PR_COND_WAIT)
+            handle = thr->wait.cvar;
+        else
+            handle = NULL;
+        if (handle)
+            printf("0x%-10x ",handle);
+        else
+            printf("%-12s "," ");
+        printf("%-3d ",thr->cpu->id);
+        printf("0x%-8x ",thr->stack->stackBottom);
+        printf("0x%-8x ",thr->stack->stackSize);
+        printf("0x%-10x\n",thr->md.jb[JB_SP]);
+    }
+
+    printf("\n%s %-s\n"," ","GLOBAL Threads");
+    printf("%s %-s\n"," ","------ -------");
+    printf("%s %-14s %-6s %-12s %-12s %-12s %-12s\n\n"," ","Thread",
+        "Pid","State","Wait-Handle",
+        "Stk-Base","Stk-Sz");
+
+    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
+        qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) {
+        thr = _PR_ACTIVE_THREAD_PTR(qp);
+        if (thr->cpu != NULL)
+            continue;        /* it is a cpu thread */
+        printf("%s 0x%-12x %-6d "," ",thr,thr->md.id);
+        /*
+         * check if the sproc is still running
+         * first call prctl(PR_GETSHMASK,pid) to check if
+         * the process is part of the share group (the pid
+         * could have been recycled by the OS)
+         */
+        if (prctl(PR_GETSHMASK,thr->md.id) < 0) {
+            printf("%-12s\n","TERMINATED");
+            continue;
+        }
+        /*
+         * Now, check if the sproc terminated and is in zombie
+         * state
+         */
+        sprintf(path,"/proc/pinfo/%s","00000");
+        len = strlen(path);
+        sprintf(pidstr,"%d",thr->md.id);
+        len -= strlen(pidstr);
+        sprintf(path + len,"%s",pidstr);
+        fd = open(path,O_RDONLY);
+        if (fd >= 0) {
+            if (ioctl(fd, PIOCPSINFO, &pinfo) < 0)
+                printf("%-12s ","TERMINATED");
+            else if (pinfo.pr_zomb)
+                printf("%-12s ","TERMINATED");
+            else
+                printf("%-12s ",_thr_state[thr->state]);
+            close(fd);
+        } else {
+            printf("%-12s ","TERMINATED");
+        }
+
+        if (thr->state == _PR_LOCK_WAIT)
+            handle = thr->wait.lock;
+        else if (thr->state == _PR_COND_WAIT)
+            handle = thr->wait.cvar;
+        else
+            handle = NULL;
+        if (handle)
+            printf("%-12x ",handle);
+        else
+            printf("%-12s "," ");
+        printf("0x%-10x ",thr->stack->stackBottom);
+        printf("0x%-10x\n",thr->stack->stackSize);
+    }
+
+    printf("\n%s %-s\n"," ","CPUs");
+    printf("%s %-s\n"," ","----");
+    printf("%s %-14s %-6s %-12s \n\n"," ","Id","Pid","State");
+
+
+    for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {
+        cpu = _PR_CPU_PTR(qp);
+        printf("%s %-14d %-6d "," ",cpu->id,cpu->md.id);
+        /*
+         * check if the sproc is still running
+         * first call prctl(PR_GETSHMASK,pid) to check if
+         * the process is part of the share group (the pid
+         * could have been recycled by the OS)
+         */
+        if (prctl(PR_GETSHMASK,cpu->md.id) < 0) {
+            printf("%-12s\n","TERMINATED");
+            continue;
+        }
+        /*
+         * Now, check if the sproc terminated and is in zombie
+         * state
+         */
+        sprintf(path,"/proc/pinfo/%s","00000");
+        len = strlen(path);
+        sprintf(pidstr,"%d",cpu->md.id);
+        len -= strlen(pidstr);
+        sprintf(path + len,"%s",pidstr);
+        fd = open(path,O_RDONLY);
+        if (fd >= 0) {
+            if (ioctl(fd, PIOCPSINFO, &pinfo) < 0)
+                printf("%-12s\n","TERMINATED");
+            else if (pinfo.pr_zomb)
+                printf("%-12s\n","TERMINATED");
+            else
+                printf("%-12s\n","RUNNING");
+            close(fd);
+        } else {
+            printf("%-12s\n","TERMINATED");
+        }
+
+    }
+    fflush(stdout);
+}
+#endif /* defined(_PR_PTHREADS) */ 
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#if !defined(_PR_PTHREADS)
+    if (isCurrent) {
+        (void) setjmp(t->md.jb);
+    }
+    *np = sizeof(t->md.jb) / sizeof(PRWord);
+    return (PRWord *) (t->md.jb);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+void _MD_EarlyInit(void)
+{
+#if !defined(_PR_PTHREADS)
+    char *eval;
+    int fd;
+	extern int __ateachexit(void (*func)(void));
+
+    sigemptyset(&ints_off);
+    sigaddset(&ints_off, SIGALRM);
+    sigaddset(&ints_off, SIGIO);
+    sigaddset(&ints_off, SIGCLD);
+
+    if (eval = getenv("_NSPR_TERMINATE_ON_ERROR"))
+        _nspr_terminate_on_error = (0 == atoi(eval) == 0) ? PR_FALSE : PR_TRUE;
+
+    fd = open("/dev/zero",O_RDWR , 0);
+    if (fd < 0) {
+        perror("open /dev/zero failed");
+        exit(1);
+    }
+    /*
+     * Set up the sproc private data area.
+     * This region exists at the same address, _nspr_sproc_private, for
+     * every sproc, but each sproc gets a private copy of the region.
+     */
+    _nspr_sproc_private = (char*)mmap(0, _pr_pageSize, PROT_READ | PROT_WRITE,
+        MAP_PRIVATE| MAP_LOCAL, fd, 0);
+    if (_nspr_sproc_private == (void*)-1) {
+        perror("mmap /dev/zero failed");
+        exit(1);
+    }
+	_MD_SET_SPROC_PID(getpid());	
+    close(fd);
+	__ateachexit(irix_detach_sproc);
+#endif
+    _MD_IrixIntervalInit();
+}  /* _MD_EarlyInit */
+
+void _MD_IrixInit(void)
+{
+#if !defined(_PR_PTHREADS)
+    struct sigaction sigact;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+	int rv;
+
+#ifdef _PR_HAVE_SGI_PRDA_PROCMASK
+	/*
+	 * enable user-level processing of sigprocmask(); this is an undocumented
+	 * feature available in Irix 6.2, 6.3, 6.4 and 6.5
+	 */
+	__sgi_prda_procmask(USER_LEVEL);
+#endif
+
+	/*
+	 * set up SIGUSR1 handler; this is used to save state
+	 * during PR_SuspendAll
+	 */
+	sigact.sa_handler = save_context_and_block;
+	sigact.sa_flags = SA_RESTART;
+	sigact.sa_mask = ints_off;
+	sigaction(SIGUSR1, &sigact, 0);
+
+    /*
+     * Change the name of the core file from core to core.pid,
+     * This is inherited by the sprocs created by this process
+     */
+#ifdef PR_COREPID
+    prctl(PR_COREPID, 0, 1);
+#endif
+    /*
+     * Irix-specific terminate on error processing
+     */
+	/*
+	 * PR_SETABORTSIG is a new command implemented in a patch to
+	 * Irix 6.2, 6.3 and 6.4. This causes a signal to be sent to all
+	 * sprocs in the process when one of them terminates abnormally
+	 *
+	 */
+	if (prctl(PR_SETABORTSIG, SIGKILL) < 0) {
+		/*
+		 *  if (errno == EINVAL)
+		 *
+		 *	PR_SETABORTSIG not supported under this OS.
+		 *	You may want to get a recent kernel rollup patch that
+		 *	supports this feature.
+		 *
+		 */
+	}
+	/*
+	 * PR_SETEXITSIG -  send the SIGCLD signal to the parent
+	 *            sproc when any sproc terminates
+	 *
+	 *    This is used to cause the entire application to
+	 *    terminate when    any sproc terminates abnormally by
+	 *     receipt of a SIGSEGV, SIGBUS or SIGABRT signal.
+	 *    If this is not done, the application may seem
+	 *     "hung" to the user because the other sprocs may be
+	 *    waiting for resources held by the
+	 *    abnormally-terminating sproc.
+	 */
+	prctl(PR_SETEXITSIG, 0);
+
+	sigact.sa_handler = sigchld_handler;
+	sigact.sa_flags = SA_RESTART;
+	sigact.sa_mask = ints_off;
+	sigaction(SIGCLD, &sigact, NULL);
+
+    /*
+     * setup stack fields for the primordial thread
+     */
+    me->stack->stackSize = prctl(PR_GETSTACKSIZE);
+    me->stack->stackBottom = me->stack->stackTop - me->stack->stackSize;
+
+    rv = pipe(_pr_irix_primoridal_cpu_fd);
+    PR_ASSERT(rv == 0);
+#ifndef _PR_USE_POLL
+    _PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0];
+    FD_SET(_pr_irix_primoridal_cpu_fd[0], &_PR_FD_READ_SET(me->cpu));
+#endif
+
+	libc_handle = dlopen("libc.so",RTLD_NOW);
+	PR_ASSERT(libc_handle != NULL);
+	libc_exit = (void (*)(int)) dlsym(libc_handle, "exit");
+	PR_ASSERT(libc_exit != NULL);
+	/* dlclose(libc_handle); */
+
+#endif /* _PR_PTHREADS */
+
+    _PR_UnixInit();
+}
+
+/**************************************************************************/
+/************** code and such for NSPR 2.0's interval times ***************/
+/**************************************************************************/
+
+#define PR_PSEC_PER_SEC 1000000000000ULL  /* 10^12 */
+
+#ifndef SGI_CYCLECNTR_SIZE
+#define SGI_CYCLECNTR_SIZE      165     /* Size user needs to use to read CC */
+#endif
+
+static PRIntn mmem_fd = -1;
+static PRIntn clock_width = 0;
+static void *iotimer_addr = NULL;
+static PRUint32 pr_clock_mask = 0;
+static PRUint32 pr_clock_shift = 0;
+static PRIntervalTime pr_ticks = 0;
+static PRUint32 pr_clock_granularity = 1;
+static PRUint32 pr_previous = 0, pr_residual = 0;
+static PRUint32 pr_ticks_per_second = 0;
+
+extern PRIntervalTime _PR_UNIX_GetInterval(void);
+extern PRIntervalTime _PR_UNIX_TicksPerSecond(void);
+
+static void _MD_IrixIntervalInit(void)
+{
+    /*
+     * As much as I would like, the service available through this
+     * interface on R3000's (aka, IP12) just isn't going to make it.
+     * The register is only 24 bits wide, and rolls over at a verocious
+     * rate.
+     */
+    PRUint32 one_tick = 0;
+    struct utsname utsinfo;
+    uname(&utsinfo);
+    if ((strncmp("IP12", utsinfo.machine, 4) != 0)
+        && ((mmem_fd = open("/dev/mmem", O_RDONLY)) != -1))
+    {
+        int poffmask = getpagesize() - 1;
+        __psunsigned_t phys_addr, raddr, cycleval;
+
+        phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval);
+        raddr = phys_addr & ~poffmask;
+        iotimer_addr = mmap(
+            0, poffmask, PROT_READ, MAP_PRIVATE, mmem_fd, (__psint_t)raddr);
+
+        clock_width = syssgi(SGI_CYCLECNTR_SIZE);
+        if (clock_width < 0)
+        {
+            /* 
+             * We must be executing on a 6.0 or earlier system, since the
+             * SGI_CYCLECNTR_SIZE call is not supported.
+             * 
+             * The only pre-6.1 platforms with 64-bit counters are
+             * IP19 and IP21 (Challenge, PowerChallenge, Onyx).
+             */
+            if (!strncmp(utsinfo.machine, "IP19", 4) ||
+                !strncmp(utsinfo.machine, "IP21", 4))
+                clock_width = 64;
+            else
+                clock_width = 32;
+        }
+
+        /*
+         * 'cycleval' is picoseconds / increment of the counter.
+         * I'm pushing for a tick to be 100 microseconds, 10^(-4).
+         * That leaves 10^(-8) left over, or 10^8 / cycleval.
+         * Did I do that right?
+         */
+
+        one_tick =  100000000UL / cycleval ;  /* 100 microseconds */
+
+        while (0 != one_tick)
+        {
+            pr_clock_shift += 1;
+            one_tick = one_tick >> 1;
+            pr_clock_granularity = pr_clock_granularity << 1;
+        }
+        pr_clock_mask = pr_clock_granularity - 1;  /* to make a mask out of it */
+        pr_ticks_per_second = PR_PSEC_PER_SEC
+                / ((PRUint64)pr_clock_granularity * (PRUint64)cycleval);
+            
+        iotimer_addr = (void*)
+            ((__psunsigned_t)iotimer_addr + (phys_addr & poffmask));
+    }
+    else
+    {
+        pr_ticks_per_second = _PR_UNIX_TicksPerSecond();
+    }
+}  /* _MD_IrixIntervalInit */
+
+PRIntervalTime _MD_IrixIntervalPerSec(void)
+{
+    return pr_ticks_per_second;
+}
+
+PRIntervalTime _MD_IrixGetInterval(void)
+{
+    if (mmem_fd != -1)
+    {
+        if (64 == clock_width)
+        {
+            PRUint64 temp = *(PRUint64*)iotimer_addr;
+            pr_ticks = (PRIntervalTime)(temp >> pr_clock_shift);
+        }
+        else
+        {
+            PRIntervalTime ticks = pr_ticks;
+            PRUint32 now = *(PRUint32*)iotimer_addr, temp;
+            PRUint32 residual = pr_residual, previous = pr_previous;
+
+            temp = now - previous + residual;
+            residual = temp & pr_clock_mask;
+            ticks += temp >> pr_clock_shift;
+
+            pr_previous = now;
+            pr_residual = residual;
+            pr_ticks = ticks;
+        }
+    }
+    else
+    {
+        /*
+         * No fast access. Use the time of day clock. This isn't the
+         * right answer since this clock can get set back, tick at odd
+         * rates, and it's expensive to acqurie.
+         */
+        pr_ticks = _PR_UNIX_GetInterval();
+    }
+    return pr_ticks;
+}  /* _MD_IrixGetInterval */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/linux.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/linux.c	Mon Dec 18 10:53:47 2006
@@ -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 "primpl.h"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifdef _PR_PTHREADS
+
+extern void _MD_unix_terminate_waitpid_daemon(void);
+
+void _MD_CleanupBeforeExit(void)
+{
+    _MD_unix_terminate_waitpid_daemon();
+}
+
+#else /* ! _PR_PTHREADS */
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	/*
+	 * set the pointers to the stack-pointer and frame-pointer words in the
+	 * context structure; this is for debugging use.
+	 */
+	thread->md.sp = _MD_GET_SP_PTR(thread);
+	thread->md.fp = _MD_GET_FP_PTR(thread);
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Linux */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Linux.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Linux.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/ncr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/ncr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,395 @@
+/* -*- 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 ***** */
+
+/*
+ * NCR 3.0  - cloned from UnixWare by ruslan
+ */
+#include "primpl.h"
+
+#include <setjmp.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+#ifdef ALARMS_BREAK_TCP /* I don't think they do */
+
+PRInt32 _MD_connect(PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _connect(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+}
+
+PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _accept(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+    return(rv);
+}
+#endif
+
+/*
+ * These are also implemented in pratom.c using NSPR locks.  Any reason
+ * this might be better or worse?  If you like this better, define
+ * _PR_HAVE_ATOMIC_OPS in include/md/unixware.h
+ */
+#ifdef _PR_HAVE_ATOMIC_OPS
+/* Atomic operations */
+#include  <stdio.h>
+static FILE *_uw_semf;
+
+void
+_MD_INIT_ATOMIC(void)
+{
+    /* Sigh.  Sure wish SYSV semaphores weren't such a pain to use */
+    if ((_uw_semf = tmpfile()) == NULL)
+        PR_ASSERT(0);
+
+    return;
+}
+
+void
+_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)++;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    flockfile(_uw_semf);
+    (*ptr) += val;
+    unflockfile(_uw_semf);
+}
+
+
+void
+_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)--;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    flockfile(_uw_semf);
+    *val = newval;
+    unflockfile(_uw_semf);
+}
+#endif
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Unixware */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Unixware.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRUintn priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Unixware.");
+    return PR_FAILURE;
+}
+
+/*
+ This is temp. replacement for localtime_r. Normally PR_ExplodeTime should
+ be used as to my understanding
+*/
+
+/*
+** $$$$$ THEN WHY ARE WE DOING THIS? - AOF $$$$$
+*/
+
+#define NEED_LOCALTIME_R
+#define NEED_GMTIME_R
+#define NEED_ASCTIME_R
+#define NEED_STRTOK_R
+#define NEED_CTIME_R
+
+#if defined (NEED_LOCALTIME_R) || defined (NEED_CTIME_R) || defined (NEED_ASCTIME_R) || defined (NEED_GMTIME_R) || defined (NEED_STRTOK_R)
+#include "prlock.h"
+#endif
+
+#if defined (NEED_LOCALTIME_R)
+
+static PRLock *localtime_r_monitor = NULL;
+
+struct tm *localtime_r (const time_t *clock, struct tm *result)
+{
+    struct tm *tmPtr;
+    int needLock = PR_Initialized();  /* We need to use a lock to protect
+                                       * against NSPR threads only when the
+                                       * NSPR thread system is activated. */
+
+    if (needLock) {
+        if (localtime_r_monitor == NULL) {
+
+            localtime_r_monitor = PR_NewLock();
+        }
+        PR_Lock(localtime_r_monitor);
+    }
+
+    /*
+     * On Windows, localtime() returns a NULL pointer if 'clock'
+     * represents a time before midnight January 1, 1970.  In
+     * that case, we also return a NULL pointer and the struct tm
+     * object pointed to by 'result' is not modified.
+     */
+
+    tmPtr = localtime(clock);
+    if (tmPtr) {
+        *result = *tmPtr;
+    } else {
+        result = NULL;
+    }
+
+    if (needLock) PR_Unlock(localtime_r_monitor);
+
+    return result;
+}
+
+#endif
+
+#if defined (NEED_GMTIME_R)
+
+static PRLock *gmtime_r_monitor = NULL;
+
+struct tm *gmtime_r (const time_t *clock, struct tm *result)
+{
+    struct tm *tmPtr;
+    int needLock = PR_Initialized();  /* We need to use a lock to protect
+                                       * against NSPR threads only when the
+                                       * NSPR thread system is activated. */
+
+    if (needLock) {
+        if (gmtime_r_monitor == NULL) {
+            gmtime_r_monitor = PR_NewLock();
+        }
+        PR_Lock(gmtime_r_monitor);
+    }
+
+    tmPtr = gmtime(clock);
+    if (tmPtr) {
+        *result = *tmPtr;
+    } else {
+        result = NULL;
+    }
+
+    if (needLock) PR_Unlock(gmtime_r_monitor);
+
+    return result;
+}
+
+#endif
+
+#if defined (NEED_CTIME_R)
+
+static PRLock *ctime_r_monitor = NULL;
+
+char  *ctime_r (const time_t *clock, char *buf, int buflen)
+{
+    char *cbuf;
+    int needLock = PR_Initialized();  /* We need to use a lock to protect
+                                       * against NSPR threads only when the
+                                       * NSPR thread system is activated. */
+
+    if (needLock) {
+
+        if (ctime_r_monitor == NULL) {
+            ctime_r_monitor = PR_NewLock();
+        }
+        PR_Lock(ctime_r_monitor);
+    }
+
+    cbuf = ctime (clock);
+    if (cbuf) {
+        strncpy (buf, cbuf, buflen - 1);
+        buf[buflen - 1] = 0;
+    }
+
+    if (needLock) PR_Unlock(ctime_r_monitor);
+
+    return cbuf;
+}
+
+#endif
+
+#if defined (NEED_ASCTIME_R)
+
+static PRLock *asctime_r_monitor = NULL;
+
+
+char  *asctime_r (const struct tm  *tm, char *buf, int buflen)
+{
+    char *cbuf;
+    int needLock = PR_Initialized();  /* We need to use a lock to protect
+                                       * against NSPR threads only when the
+                                       * NSPR thread system is activated. */
+
+    if (needLock) {
+        if (asctime_r_monitor == NULL) {
+            asctime_r_monitor = PR_NewLock();
+        }
+        PR_Lock(asctime_r_monitor);
+    }
+
+    cbuf = asctime (tm);
+    if (cbuf) {
+        strncpy (buf, cbuf, buflen - 1);
+        buf[buflen - 1] = 0;
+    }
+
+    if (needLock) PR_Unlock(asctime_r_monitor);
+
+    return cbuf;
+
+}
+#endif
+
+#if defined (NEED_STRTOK_R)
+
+char *
+strtok_r (s, delim, last)
+        register char *s;
+        register const char *delim;
+        register char **last;
+{
+        register char *spanp;
+        register int c, sc;
+        char *tok;
+
+
+        if (s == NULL && (s = *last) == NULL)
+                return (NULL);
+
+        /*
+         * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+         */
+cont:
+
+        c = *s++;
+        for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+                if (c == sc)
+                        goto cont;
+        }
+
+        if (c == 0) {           /* no non-delimiter characters */
+                *last = NULL;
+                return (NULL);
+        }
+        tok = s - 1;
+
+        /*
+         * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+         * Note that delim must have one NUL; we stop if we see that, too.
+         */
+        for (;;) {
+                c = *s++;
+                spanp = (char *)delim;
+                do {
+                        if ((sc = *spanp++) == c) {
+                                if (c == 0)
+                                        s = NULL;
+
+                                else
+                                        s[-1] = 0;
+                                *last = s;
+                                return (tok);
+                        }
+                } while (sc != 0);
+        }
+        /* NOTREACHED */
+}
+
+#endif

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/nec.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/nec.c	Mon Dec 18 10:53:47 2006
@@ -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 "primpl.h"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for NEC */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for NEC.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for NEC.");
+	return PR_FAILURE;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/netbsd.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/netbsd.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,121 @@
+/* -*- 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 <signal.h>
+#include <poll.h>
+#include <sys/syscall.h>
+
+void _MD_EarlyInit(void)
+{
+    /*
+     * Ignore FPE because coercion of a NaN to an int causes SIGFPE
+     * to be raised.
+     */
+    struct sigaction act;
+
+    act.sa_handler = SIG_IGN;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_RESTART;
+    sigaction(SIGFPE, &act, 0);
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+        (void) sigsetjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+    *np = 0;
+    return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+        PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for NetBSD */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for NetBSD.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for NetBSD.");
+    return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/nextstep.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/nextstep.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,284 @@
+/* -*- 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"
+
+#import <mach/mach.h>
+#import <mach/mach_error.h>
+#import <mach-o/dyld.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <syscall.h>
+
+
+
+/*	These functions are hidden in NEXTSTEP, but beacuse they have syscall()
+**	entries I can wrap these into their corresponding missing function.
+*/
+caddr_t
+mmap(caddr_t addr, size_t len, int prot, int flags,
+          int fildes, off_t off)
+{
+	return (caddr_t) syscall (SYS_mmap, addr, len, prot, flags, fildes, off);
+}
+
+int
+munmap(caddr_t addr, size_t len)
+{
+	return syscall (SYS_munmap, addr, len);
+}
+
+int
+mprotect(caddr_t addr, size_t len, int prot)
+{
+	return syscall (SYS_mprotect, addr, len, prot);
+}
+
+
+/* If found the brk() symbol in the sahred libraries but no syscall() entry ...
+** I don't know whether it will work ...
+int brk(void *endds)
+{
+	return syscall ();
+}
+*/
+
+void *sbrk(int incr)
+{
+	return (void *) syscall (SYS_sbrk, incr);
+}
+
+/*	These are my mach based versions, untested and probably bad ...
+*/
+caddr_t my_mmap(caddr_t addr, size_t len, int prot, int flags,
+          int fildes, off_t off)
+{
+	kern_return_t ret_val;
+	
+	/*	First map ...
+	*/
+	ret_val = map_fd ( fildes, 					/* fd				*/
+	                  (vm_offset_t) off,		/* offset			*/
+					  (vm_offset_t*)&addr,		/* address			*/
+					  TRUE, 					/* find_space		*/
+					  (vm_size_t) len);			/* size				*/
+
+	if (ret_val != KERN_SUCCESS) {
+    	mach_error("Error calling map_fd() in mmap", ret_val );
+		return (caddr_t)0;
+	}
+	
+	/*	... then protect (this is probably bad)
+	*/
+	ret_val = vm_protect( task_self(),			/* target_task 		*/
+						 (vm_address_t)addr,	/* address			*/
+						 (vm_size_t) len,		/* size 			*/
+						 FALSE,					/* set_maximum		*/
+						 (vm_prot_t) prot);		/* new_protection	*/
+	if (ret_val != KERN_SUCCESS) {
+		mach_error("vm_protect in mmap()", ret_val );
+		return (caddr_t)0;
+	}
+	
+	return addr;
+}
+
+int my_munmap(caddr_t addr, size_t len)
+{
+	kern_return_t ret_val;
+
+	ret_val = vm_deallocate(task_self(),
+	 						(vm_address_t) addr,
+							(vm_size_t) len);
+
+	if (ret_val != KERN_SUCCESS) {
+		mach_error("vm_deallocate in munmap()", ret_val);
+		return -1;
+	}
+	
+	return 0;
+}
+
+int my_mprotect(caddr_t addr, size_t len, int prot)
+{
+	vm_prot_t mach_prot;
+	kern_return_t ret_val;
+	
+	switch (prot) {
+		case PROT_READ:		mach_prot = VM_PROT_READ;		break;
+		case PROT_WRITE:	mach_prot = VM_PROT_WRITE;		break;
+		case PROT_EXEC:		mach_prot = VM_PROT_EXECUTE;	break;
+		case PROT_NONE:		mach_prot = VM_PROT_NONE;		break;
+	}
+	
+	ret_val = vm_protect(task_self(),			/* target_task 		*/
+						 (vm_address_t)addr,	/* address			*/
+						 (vm_size_t) len,		/* size 			*/
+						 FALSE,					/* set_maximum		*/
+						 (vm_prot_t) prot);		/* new_protection	*/
+
+	if (ret_val != KERN_SUCCESS) {
+		mach_error("vm_protect in mprotect()", ret_val);
+		return -1;
+	}
+	
+	return 0;
+}
+
+char *strdup(const char *s1)
+{
+	int len = strlen (s1);
+	char *copy = (char*) malloc (len+1);
+	
+	if (copy == (char*)0)
+		return (char*)0;
+
+	strcpy (copy, s1);
+
+	return copy;
+}
+
+/* Stub rld functions
+*/
+extern NSObjectFileImageReturnCode NSCreateObjectFileImageFromFile(
+    const char *pathName,
+    NSObjectFileImage *objectFileImage)
+{
+	return NSObjectFileImageFailure;
+}
+
+extern void * NSAddressOfSymbol(
+    NSSymbol symbol)
+{
+	return NULL;
+}
+
+extern NSModule NSLinkModule(
+    NSObjectFileImage objectFileImage, 
+    const char *moduleName, /* can be NULL */
+    enum bool bindNow)
+{
+	return NULL;
+}
+
+extern NSSymbol NSLookupAndBindSymbol(
+    const char *symbolName)
+{
+	return NULL;
+}
+
+extern enum bool NSUnLinkModule(
+    NSModule module, 
+    enum bool keepMemoryMapped)
+{
+	return 0;
+}
+
+
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) sigsetjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for NEXTSTEP */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for NEXTSTEP.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for NEXTSTEP.");
+	return PR_FAILURE;
+}
+
+#endif

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/nto.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/nto.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,66 @@
+/* -*- 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 "primpl.h"
+
+#include <setjmp.h>
+
+/* Fake this out */
+int socketpair (int foo, int foo2, int foo3, int sv[2])
+{
+	printf("error in socketpair\n");
+	exit (-1);
+}
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+    (void) setjmp(CONTEXT(t));
+    }
+
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/objs.mk
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/objs.mk	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,63 @@
+# 
+# ***** 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 *****
+
+# This makefile appends to the variable OBJS the platform-dependent
+# object modules that will be part of the nspr20 library.
+
+CSRCS =          \
+	unix.c    \
+	unix_errors.c \
+	uxproces.c \
+	uxrng.c \
+	uxshm.c \
+	uxwrap.c \
+	$(NULL)
+
+ifneq ($(USE_PTHREADS),1)
+CSRCS += uxpoll.c
+endif
+
+ifeq ($(PTHREADS_USER),1)
+CSRCS += pthreads_user.c
+endif
+
+CSRCS	+= $(PR_MD_CSRCS)
+ASFILES += $(PR_MD_ASFILES)
+
+OBJS += $(addprefix md/unix/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX)))  \
+	$(addprefix md/unix/$(OBJDIR)/,$(ASFILES:.s=.$(OBJ_SUFFIX)))
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/openbsd.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/openbsd.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,121 @@
+/* -*- 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 <signal.h>
+#include <poll.h>
+#include <sys/syscall.h>
+
+void _MD_EarlyInit(void)
+{
+    /*
+     * Ignore FPE because coercion of a NaN to an int causes SIGFPE
+     * to be raised.
+     */
+    struct sigaction act;
+
+    act.sa_handler = SIG_IGN;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_RESTART;
+    sigaction(SIGFPE, &act, 0);
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+        (void) sigsetjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+    *np = 0;
+    return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+        PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for OpenBSD */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for OpenBSD.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OpenBSD.");
+    return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/openvms.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/openvms.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,286 @@
+/* -*- 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"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for OSF1 */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for OSF1.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OSF1.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
+
+#ifdef _PR_HAVE_ATOMIC_CAS
+
+#include <c_asm.h>
+
+#define _PR_OSF_ATOMIC_LOCK 1
+
+void 
+PR_StackPush(PRStack *stack, PRStackElem *stack_elem)
+{
+long locked;
+
+	do {
+		while ((long) stack->prstk_head.prstk_elem_next ==
+							_PR_OSF_ATOMIC_LOCK)
+			;
+		locked = __ATOMIC_EXCH_QUAD(&stack->prstk_head.prstk_elem_next,
+								_PR_OSF_ATOMIC_LOCK);	
+
+	} while (locked == _PR_OSF_ATOMIC_LOCK);
+	stack_elem->prstk_elem_next = (PRStackElem *) locked;
+	/*
+	 * memory-barrier instruction
+	 */
+	asm("mb");
+	stack->prstk_head.prstk_elem_next = stack_elem;
+}
+
+PRStackElem * 
+PR_StackPop(PRStack *stack)
+{
+PRStackElem *element;
+long locked;
+
+	do {
+		while ((long)stack->prstk_head.prstk_elem_next == _PR_OSF_ATOMIC_LOCK)
+			;
+		locked = __ATOMIC_EXCH_QUAD(&stack->prstk_head.prstk_elem_next,
+								_PR_OSF_ATOMIC_LOCK);	
+
+	} while (locked == _PR_OSF_ATOMIC_LOCK);
+
+	element = (PRStackElem *) locked;
+
+	if (element == NULL) {
+		stack->prstk_head.prstk_elem_next = NULL;
+	} else {
+		stack->prstk_head.prstk_elem_next =
+			element->prstk_elem_next;
+	}
+	/*
+	 * memory-barrier instruction
+	 */
+	asm("mb");
+	return element;
+}
+#endif /* _PR_HAVE_ATOMIC_CAS */
+
+
+/*
+** thread_suspend and thread_resume are used by the gc code
+** in nsprpub/pr/src/pthreads/ptthread.c
+**
+** These routines are never called for the current thread, and
+** there is no check for that - so beware!
+*/
+int thread_suspend(PRThread *thr_id) {
+
+    extern int pthread_suspend_np (
+			pthread_t                       thread,
+			__pthreadLongUint_t             *regs,
+			void                            *spare);
+
+    __pthreadLongUint_t regs[34];
+    int res;
+
+    /*
+    ** A return res < 0 indicates that the thread was suspended
+    ** but register information could not be obtained
+    */
+
+    res = pthread_suspend_np(thr_id->id,&regs[0],0);
+    if (res==0)
+	thr_id->sp = (void *) regs[30]; 
+
+    thr_id->suspend |= PT_THREAD_SUSPENDED;
+
+    /* Always succeeds */
+    return 0;
+}
+
+int thread_resume(PRThread *thr_id) {
+    extern int pthread_resume_np(pthread_t thread);
+    int res;
+
+    res = pthread_resume_np (thr_id->id);
+	
+    thr_id->suspend |= PT_THREAD_RESUMED;
+
+    return 0;
+}
+
+/*
+** Stubs for nspr_symvec.opt
+**
+** PR_ResumeSet, PR_ResumeTest, and PR_SuspendAllSuspended
+** (defined in ptthread.c) used to be exported by mistake
+** (because they look like public functions).  They have been
+** converted into static functions.
+**
+** There is an existing third-party binary that uses NSPR: the
+** Java plugin for Mozilla.  Because it is part of the Java
+** SDK, we have no control over its releases.  So we need these
+** stub functions to occupy the slots that used to be occupied
+** by PR_ResumeSet, PR_ResumeTest, and PR_SuspendAllSuspended
+** in the symbol vector so that LIBNSPR4 is backward compatible.
+**
+** The Java plugin was also using PR_CreateThread which we didn't
+** realise and hadn't "nailed down". So we now need to nail it down
+** to its Mozilla 1.1 position and have to insert 51 additional stubs
+** in order to achive this (stubs 4-54).
+**
+** Over time some of these stubs will get reused by new symbols.
+**   - Stub54 is replaced by LL_MaxUint
+*/
+
+void PR_VMS_Stub1(void) { }
+void PR_VMS_Stub2(void) { }
+void PR_VMS_Stub3(void) { }
+void PR_VMS_Stub4(void) { }
+void PR_VMS_Stub5(void) { }
+void PR_VMS_Stub6(void) { }
+void PR_VMS_Stub7(void) { }
+void PR_VMS_Stub8(void) { }
+void PR_VMS_Stub9(void) { }
+void PR_VMS_Stub10(void) { }
+void PR_VMS_Stub11(void) { }
+void PR_VMS_Stub12(void) { }
+void PR_VMS_Stub13(void) { }
+void PR_VMS_Stub14(void) { }
+void PR_VMS_Stub15(void) { }
+void PR_VMS_Stub16(void) { }
+void PR_VMS_Stub17(void) { }
+void PR_VMS_Stub18(void) { }
+void PR_VMS_Stub19(void) { }
+void PR_VMS_Stub20(void) { }
+void PR_VMS_Stub21(void) { }
+void PR_VMS_Stub22(void) { }
+void PR_VMS_Stub23(void) { }
+void PR_VMS_Stub24(void) { }
+void PR_VMS_Stub25(void) { }
+void PR_VMS_Stub26(void) { }
+void PR_VMS_Stub27(void) { }
+void PR_VMS_Stub28(void) { }
+void PR_VMS_Stub29(void) { }
+void PR_VMS_Stub30(void) { }
+void PR_VMS_Stub31(void) { }
+void PR_VMS_Stub32(void) { }
+void PR_VMS_Stub33(void) { }
+void PR_VMS_Stub34(void) { }
+void PR_VMS_Stub35(void) { }
+void PR_VMS_Stub36(void) { }
+void PR_VMS_Stub37(void) { }
+void PR_VMS_Stub38(void) { }
+void PR_VMS_Stub39(void) { }
+void PR_VMS_Stub40(void) { }
+void PR_VMS_Stub41(void) { }
+void PR_VMS_Stub42(void) { }
+void PR_VMS_Stub43(void) { }
+void PR_VMS_Stub44(void) { }
+void PR_VMS_Stub45(void) { }
+void PR_VMS_Stub46(void) { }
+void PR_VMS_Stub47(void) { }
+void PR_VMS_Stub48(void) { }
+void PR_VMS_Stub49(void) { }
+void PR_VMS_Stub50(void) { }
+void PR_VMS_Stub51(void) { }
+void PR_VMS_Stub52(void) { }
+void PR_VMS_Stub53(void) { }

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_AIX.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_AIX.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,119 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+# 
+# 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.
+# 
+
+.set r0,0; .set SP,1; .set RTOC,2; .set r3,3; .set r4,4
+.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9
+.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14
+.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19
+.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24
+.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29
+.set r30,30; .set r31,31
+
+
+        .rename H.10.NO_SYMBOL{PR},""
+        .rename H.18.longjmp{TC},"longjmp"
+
+        .lglobl H.10.NO_SYMBOL{PR}
+        .globl  .longjmp
+        .globl  longjmp{DS}
+        .extern .sigcleanup
+        .extern .jmprestfpr
+
+# .text section
+
+        .csect  H.10.NO_SYMBOL{PR}
+.longjmp:
+         mr   r13,r3
+         mr   r14,r4
+        stu   SP,-56(SP)
+         bl   .sigcleanup
+          l   RTOC,0x14(SP)
+        cal   SP,0x38(SP)
+         mr   r3,r13
+         mr   r4,r14
+          l   r5,0x8(r3)
+          l   SP,0xc(r3)
+          l   r7,0xf8(r3)
+         st   r7,0x0(SP)
+          l   RTOC,0x10(r3)
+         bl   .jmprestfpr
+# 1 == cr0 in disassembly
+       cmpi   1,r4,0x0  
+       mtlr   r5
+         lm   r13,0x14(r3)
+          l   r5,0x60(r3)
+      mtcrf   0x38,r5
+         mr   r3,r4
+        bne   __L1
+        lil   r3,0x1
+__L1:
+         br
+
+# traceback table
+        .long   0x00000000
+        .byte   0x00                    # VERSION=0
+        .byte   0x00                    # LANG=TB_C
+        .byte   0x20                    # IS_GL=0,IS_EPROL=0,HAS_TBOFF=1
+                                        # INT_PROC=0,HAS_CTL=0,TOCLESS=0
+                                        # FP_PRESENT=0,LOG_ABORT=0
+        .byte   0x40                    # INT_HNDL=0,NAME_PRESENT=1
+                                        # USES_ALLOCA=0,CL_DIS_INV=WALK_ONCOND
+                                        # SAVES_CR=0,SAVES_LR=0
+        .byte   0x80                    # STORES_BC=1,FPR_SAVED=0
+        .byte   0x00                    # GPR_SAVED=0
+        .byte   0x02                    # FIXEDPARMS=2
+        .byte   0x01                    # FLOATPARMS=0,PARMSONSTK=1
+        .long   0x00000000              #
+        .long   0x00000014              # TB_OFFSET
+        .short  7                       # NAME_LEN
+        .byte   "longjmp"
+        .byte   0                       # padding
+        .byte   0                       # padding
+        .byte   0                       # padding
+# End of traceback table
+        .long   0x00000000              # "\0\0\0\0"
+
+# .data section
+
+        .toc                            # 0x00000038
+T.18.longjmp:
+        .tc     H.18.longjmp{TC},longjmp{DS}
+
+        .csect  longjmp{DS}
+        .long   .longjmp                # "\0\0\0\0"
+        .long   TOC{TC0}                # "\0\0\0008"
+        .long   0x00000000              # "\0\0\0\0"
+# End   csect   longjmp{DS}
+
+# .bss section

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_BSD_386_2.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_BSD_386_2.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 
+* 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.
+*/
+
+/*
+ * os_BSD_386_2.s
+ * We need to define our own setjmp/longjmp on BSDI 2.x because libc's
+ * implementation does some sanity checking that defeats user level threads.
+ * This should no longer be necessary in BSDI 3.0.
+ */
+
+.globl _setjmp
+.align 2
+_setjmp:
+		movl	4(%esp),%eax
+		movl	0(%esp),%edx
+		movl	%edx, 0(%eax)           /* rta */
+		movl	%ebx, 4(%eax)
+		movl	%esp, 8(%eax)
+		movl	%ebp,12(%eax)
+		movl	%esi,16(%eax)
+		movl	%edi,20(%eax)
+		movl	$0,%eax
+		ret
+ 
+.globl _longjmp
+.align 2
+_longjmp:
+		movl	4(%esp),%edx
+		movl	8(%esp),%eax
+		movl	0(%edx),%ecx
+		movl	4(%edx),%ebx
+		movl	8(%edx),%esp
+		movl	12(%edx),%ebp
+		movl	16(%edx),%esi
+		movl	20(%edx),%edi
+		cmpl	$0,%eax
+		jne		1f
+		movl	$1,%eax
+1:		movl	%ecx,0(%esp)
+		ret

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Darwin_ppc.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Darwin_ppc.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,92 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+#
+# 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) 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.
+#
+
+#
+# Based on the programming examples in The PowerPC Architecture:
+# A Specification for A New Family of RISC Processors, 2nd Ed.,
+# Book I, Section E.1, "Synchronization," pp. 249-256, May 1994.
+#
+
+.text
+
+#
+# PRInt32 __PR_DarwinPPC_AtomicIncrement(PRInt32 *val);
+#
+        .align  2
+        .globl  __PR_DarwinPPC_AtomicIncrement
+__PR_DarwinPPC_AtomicIncrement:
+        lwarx   r4,0,r3
+        addi    r0,r4,1
+        stwcx.  r0,0,r3
+        bne-    __PR_DarwinPPC_AtomicIncrement
+        mr      r3,r0
+        blr
+
+#
+# PRInt32 __PR_DarwinPPC_AtomicDecrement(PRInt32 *val);
+#
+        .align  2
+        .globl  __PR_DarwinPPC_AtomicDecrement
+__PR_DarwinPPC_AtomicDecrement:
+        lwarx   r4,0,r3
+        addi    r0,r4,-1
+        stwcx.  r0,0,r3
+        bne-    __PR_DarwinPPC_AtomicDecrement
+        mr      r3,r0
+        blr
+
+#
+# PRInt32 __PR_DarwinPPC_AtomicSet(PRInt32 *val, PRInt32 newval);
+#
+        .align  2
+        .globl  __PR_DarwinPPC_AtomicSet
+__PR_DarwinPPC_AtomicSet:
+        lwarx   r5,0,r3
+        stwcx.  r4,0,r3
+        bne-    __PR_DarwinPPC_AtomicSet
+        mr      r3,r5
+        blr
+
+#
+# PRInt32 __PR_DarwinPPC_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#
+        .align  2
+        .globl  __PR_DarwinPPC_AtomicAdd
+__PR_DarwinPPC_AtomicAdd:
+        lwarx   r5,0,r3
+        add     r0,r4,r5
+        stwcx.  r0,0,r3
+        bne-    __PR_DarwinPPC_AtomicAdd
+        mr      r3,r0
+        blr

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Darwin_x86.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Darwin_x86.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,105 @@
+# -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+#
+# 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) 2003 Netscape Communications Corporation.  All
+# Rights Reserved.
+#
+# Contributor(s):
+#   Josh Aas <josh at mozilla.com>
+#
+# 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.
+#
+
+#
+# Based on os_Linux_x86.s
+#
+
+#
+# PRInt32 __PR_Darwin_x86_AtomicIncrement(PRInt32 *val);
+#
+# Atomically increment the integer pointed to by 'val' and return
+# the result of the increment.
+#
+    .text
+    .globl __PR_Darwin_x86_AtomicIncrement
+    .align 4
+__PR_Darwin_x86_AtomicIncrement:
+    movl 4(%esp), %ecx
+    movl $1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    incl %eax
+    ret
+
+#
+# PRInt32 __PR_Darwin_x86_AtomicDecrement(PRInt32 *val);
+#
+# Atomically decrement the integer pointed to by 'val' and return
+# the result of the decrement.
+#
+    .text
+    .globl __PR_Darwin_x86_AtomicDecrement
+    .align 4
+__PR_Darwin_x86_AtomicDecrement:
+    movl 4(%esp), %ecx
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    decl %eax
+    ret
+
+#
+# PRInt32 __PR_Darwin_x86_AtomicSet(PRInt32 *val, PRInt32 newval);
+#
+# Atomically set the integer pointed to by 'val' to the new
+# value 'newval' and return the old value.
+#
+    .text
+    .globl __PR_Darwin_x86_AtomicSet
+    .align 4
+__PR_Darwin_x86_AtomicSet:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    xchgl %eax, (%ecx)
+    ret
+
+#
+# PRInt32 __PR_Darwin_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val);
+#
+# Atomically add 'val' to the integer pointed to by 'ptr'
+# and return the result of the addition.
+#
+    .text
+    .globl __PR_Darwin_x86_AtomicAdd
+    .align 4
+__PR_Darwin_x86_AtomicAdd:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    movl %eax, %edx
+    lock
+    xaddl %eax, (%ecx)
+    addl %edx, %eax
+    ret

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_HPUX.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_HPUX.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,54 @@
+; 
+; 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.
+; 
+
+#ifdef __LP64__
+        .LEVEL   2.0W
+#else
+        .LEVEL   1.1
+#endif
+
+	.CODE	; equivalent to the following two lines
+;       .SPACE   $TEXT$,SORT=8
+;       .SUBSPA  $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24
+
+ret_cr16
+	.PROC
+	.CALLINFO 	FRAME=0, NO_CALLS
+	.EXPORT 	ret_cr16,ENTRY
+	.ENTER
+;	BV		%r0(%rp)
+	BV		0(%rp)
+	MFCTL		%cr16,%ret0
+        .LEAVE
+        .PROCEND
+        .END

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_HPUX_ia64.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_HPUX_ia64.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,108 @@
+// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// 
+// 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) 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.
+//
+
+.text
+
+// PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val)
+//
+// Atomically increment the integer pointed to by 'val' and return
+// the result of the increment.
+//
+        .align 16
+        .global _PR_ia64_AtomicIncrement#
+        .proc _PR_ia64_AtomicIncrement#
+_PR_ia64_AtomicIncrement:
+#ifndef _LP64
+        addp4 r32 = 0, r32  ;;
+#endif
+        fetchadd4.acq r8 = [r32], 1  ;;
+        adds r8 = 1, r8
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicIncrement#
+
+// PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val)
+//
+// Atomically decrement the integer pointed to by 'val' and return
+// the result of the decrement.
+//
+        .align 16
+        .global _PR_ia64_AtomicDecrement#
+        .proc _PR_ia64_AtomicDecrement#
+_PR_ia64_AtomicDecrement:
+#ifndef _LP64
+        addp4 r32 = 0, r32  ;;
+#endif
+        fetchadd4.rel r8 = [r32], -1  ;;
+        adds r8 = -1, r8
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicDecrement#
+
+// PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+//
+// Atomically add 'val' to the integer pointed to by 'ptr'
+// and return the result of the addition.
+//
+        .align 16
+        .global _PR_ia64_AtomicAdd#
+        .proc _PR_ia64_AtomicAdd#
+_PR_ia64_AtomicAdd:
+#ifndef _LP64
+        addp4 r32 = 0, r32  ;;
+#endif
+        ld4 r15 = [r32]  ;;
+.L3:
+        mov r14 = r15
+        mov ar.ccv = r15
+        add r8 = r15, r33  ;;
+        cmpxchg4.acq r15 = [r32], r8, ar.ccv  ;;
+        cmp4.ne p6, p7 =  r15, r14
+        (p6) br.cond.dptk .L3
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicAdd#
+
+// PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval)
+//
+// Atomically set the integer pointed to by 'val' to the new
+// value 'newval' and return the old value.
+//
+        .align 16
+        .global _PR_ia64_AtomicSet#
+        .proc _PR_ia64_AtomicSet#
+_PR_ia64_AtomicSet:
+#ifndef _LP64
+        addp4 r32 = 0, r32  ;;
+#endif
+        xchg4 r8 = [r32], r33
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicSet#

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Irix.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Irix.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 
+* 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.
+*/
+
+/* 
+ *  Atomically add a new element to the top of the stack
+ *
+ *  usage : PR_StackPush(listp, elementp);
+ *  -----------------------
+ */
+
+#include "md/_irix.h"
+#ifdef _PR_HAVE_ATOMIC_CAS
+
+#include <sys/asm.h>
+#include <sys/regdef.h>
+
+LEAF(PR_StackPush)
+
+retry_push:
+.set noreorder
+		lw		v0,0(a0)
+		li		t1,1
+		beq		v0,t1,retry_push
+		move	t0,a1
+
+        ll      v0,0(a0)
+		beq		v0,t1,retry_push
+		nop
+		sc		t1,0(a0)	
+		beq		t1,0,retry_push
+		nop
+		sw		v0,0(a1)
+		sync
+		sw		t0,0(a0)
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		jr		ra
+		nop
+
+END(PR_StackPush)
+
+/*
+ *
+ *  Atomically remove the element at the top of the stack
+ *
+ *  usage : elemep = PR_StackPop(listp);
+ *
+ */
+
+LEAF(PR_StackPop)
+retry_pop:
+.set noreorder
+
+
+		lw		v0,0(a0)
+		li		t1,1
+		beq		v0,0,done
+		nop	
+		beq		v0,t1,retry_pop
+		nop	
+
+        ll      v0,0(a0)
+		beq		v0,0,done
+		nop
+		beq		v0,t1,retry_pop
+		nop
+		sc		t1,0(a0)	
+		beq		t1,0,retry_pop
+		nop
+		lw		t0,0(v0)
+		sw		t0,0(a0)
+done:
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		nop
+		jr		ra
+		nop
+
+END(PR_StackPop)
+
+#endif /* _PR_HAVE_ATOMIC_CAS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Linux_ia64.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Linux_ia64.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,99 @@
+// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// 
+// 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) 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.
+//
+
+.text
+
+// PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val)
+//
+// Atomically increment the integer pointed to by 'val' and return
+// the result of the increment.
+//
+        .align 16
+        .global _PR_ia64_AtomicIncrement#
+        .proc _PR_ia64_AtomicIncrement#
+_PR_ia64_AtomicIncrement:
+        fetchadd4.acq r8 = [r32], 1  ;;
+        adds r8 = 1, r8
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicIncrement#
+
+// PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val)
+//
+// Atomically decrement the integer pointed to by 'val' and return
+// the result of the decrement.
+//
+        .align 16
+        .global _PR_ia64_AtomicDecrement#
+        .proc _PR_ia64_AtomicDecrement#
+_PR_ia64_AtomicDecrement:
+        fetchadd4.rel r8 = [r32], -1  ;;
+        adds r8 = -1, r8
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicDecrement#
+
+// PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+//
+// Atomically add 'val' to the integer pointed to by 'ptr'
+// and return the result of the addition.
+//
+        .align 16
+        .global _PR_ia64_AtomicAdd#
+        .proc _PR_ia64_AtomicAdd#
+_PR_ia64_AtomicAdd:
+        ld4 r15 = [r32]  ;;
+.L3:
+        mov r14 = r15
+        mov ar.ccv = r15
+        add r8 = r15, r33  ;;
+        cmpxchg4.acq r15 = [r32], r8, ar.ccv  ;;
+        cmp4.ne p6, p7 =  r15, r14
+        (p6) br.cond.dptk .L3
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicAdd#
+
+// PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval)
+//
+// Atomically set the integer pointed to by 'val' to the new
+// value 'newval' and return the old value.
+//
+        .align 16
+        .global _PR_ia64_AtomicSet#
+        .proc _PR_ia64_AtomicSet#
+_PR_ia64_AtomicSet:
+        xchg4 r8 = [r32], r33
+        br.ret.sptk.many b0
+        .endp _PR_ia64_AtomicSet#
+
+// Magic indicating no need for an executable stack
+.section .note.GNU-stack, "", @progbits ; .previous

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,113 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ 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) 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.
+/ 
+
+/ PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val)
+/
+/ Atomically increment the integer pointed to by 'val' and return
+/ the result of the increment.
+/
+    .text
+    .globl _PR_x86_AtomicIncrement
+    .align 4
+_PR_x86_AtomicIncrement:
+    movl 4(%esp), %ecx
+    movl $1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    incl %eax
+    ret
+
+/ PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val)
+/
+/ Atomically decrement the integer pointed to by 'val' and return
+/ the result of the decrement.
+/
+    .text
+    .globl _PR_x86_AtomicDecrement
+    .align 4
+_PR_x86_AtomicDecrement:
+    movl 4(%esp), %ecx
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    decl %eax
+    ret
+
+/ PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval)
+/
+/ Atomically set the integer pointed to by 'val' to the new
+/ value 'newval' and return the old value.
+/
+/ An alternative implementation:
+/   .text
+/   .globl _PR_x86_AtomicSet
+/   .align 4
+/_PR_x86_AtomicSet:
+/   movl 4(%esp), %ecx
+/   movl 8(%esp), %edx
+/   movl (%ecx), %eax
+/retry:
+/   lock
+/   cmpxchgl %edx, (%ecx)
+/   jne retry
+/   ret
+/
+    .text
+    .globl _PR_x86_AtomicSet
+    .align 4
+_PR_x86_AtomicSet:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    xchgl %eax, (%ecx)
+    ret
+
+/ PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+/
+/ Atomically add 'val' to the integer pointed to by 'ptr'
+/ and return the result of the addition.
+/
+    .text
+    .globl _PR_x86_AtomicAdd
+    .align 4
+_PR_x86_AtomicAdd:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    movl %eax, %edx
+    lock
+    xaddl %eax, (%ecx)
+    addl %edx, %eax
+    ret
+
+/ Magic indicating no need for an executable stack
+.section .note.GNU-stack, "", @progbits ; .previous

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86_64.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_Linux_x86_64.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,94 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ 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) 2004 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.
+/ 
+
+/ PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val)
+/
+/ Atomically increment the integer pointed to by 'val' and return
+/ the result of the increment.
+/
+    .text
+    .globl _PR_x86_64_AtomicIncrement
+    .align 4
+_PR_x86_64_AtomicIncrement:
+    movl $1, %eax
+    lock
+    xaddl %eax, (%rdi)
+    incl %eax
+    ret
+
+/ PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val)
+/
+/ Atomically decrement the integer pointed to by 'val' and return
+/ the result of the decrement.
+/
+    .text
+    .globl _PR_x86_64_AtomicDecrement
+    .align 4
+_PR_x86_64_AtomicDecrement:
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%rdi)
+    decl %eax
+    ret
+
+/ PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval)
+/
+/ Atomically set the integer pointed to by 'val' to the new
+/ value 'newval' and return the old value.
+/
+    .text
+    .globl _PR_x86_64_AtomicSet
+    .align 4
+_PR_x86_64_AtomicSet:
+    movl %esi, %eax
+    xchgl %eax, (%rdi)
+    ret
+
+/ PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+/
+/ Atomically add 'val' to the integer pointed to by 'ptr'
+/ and return the result of the addition.
+/
+    .text
+    .globl _PR_x86_64_AtomicAdd
+    .align 4
+_PR_x86_64_AtomicAdd:
+    movl %esi, %eax
+    lock
+    xaddl %eax, (%rdi)
+    addl %esi, %eax
+    ret
+
+/ Magic indicating no need for an executable stack
+.section .note.GNU-stack, "", @progbits ; .previous

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_ReliantUNIX.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_ReliantUNIX.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 
+* 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.
+*/
+
+/* We want position independent code */
+#define PIC
+
+#include <sys/asm.h>
+#include <sys/regdef.h>
+#include <sys/syscall.h>
+
+	.file 1 "os_ReliantUNIX.s"
+	.option pic2
+	.text
+
+	.align	2
+	.globl	getcxt
+	.ent	getcxt
+getcxt:
+	.frame	sp,0,$31		# vars= 0, regs= 0/0, args= 0, extra= 0
+	# saved integer regs
+	sw	ra,180(a0)	# gpregs[CXT_EPC]
+	sw	gp,152(a0)	# gpregs[CXT_GP]
+	sw	sp,156(a0)	# gpregs[CXT_SP]
+	sw	s8,160(a0)	# gpregs[CXT_S8]
+	sw	s0,104(a0)	# gpregs[CXT_S0]
+	sw	s1,108(a0)	# gpregs[CXT_S1]
+	sw	s2,112(a0)	# gpregs[CXT_S2]
+	sw	s3,116(a0)	# gpregs[CXT_S3]
+	sw	s4,120(a0)	# gpregs[CXT_S4]
+	sw	s5,124(a0)	# gpregs[CXT_S5]
+	sw	s6,128(a0)	# gpregs[CXT_S6]
+	sw	s7,132(a0)	# gpregs[CXT_S7]
+	# csr
+	cfc1	v0,$31
+	# saved float regs
+	s.d	$f20,264(a0)	# fpregs.fp_r.fp_dregs[10]
+	s.d	$f22,272(a0)	# fpregs.fp_r.fp_dregs[11]
+	s.d	$f24,280(a0)	# fpregs.fp_r.fp_dregs[12]
+	s.d	$f26,288(a0)	# fpregs.fp_r.fp_dregs[13]
+	s.d	$f28,296(a0)	# fpregs.fp_r.fp_dregs[14]
+	s.d	$f30,304(a0)	# fpregs.fp_r.fp_dregs[15]
+	sw	v0,312(a0)	# fpregs.fp_csr
+
+	# give no illusions about the contents
+	li	v0,0x0c		# UC_CPU | UC_MAU
+	sw	v0,0(a0)	# uc_flags
+
+	move	v0,zero
+	j	ra
+	.end	getcxt
+
+	.align	2
+	.globl	setcxt
+	.ent	setcxt
+setcxt:
+	.frame	sp,0,$31		# vars= 0, regs= 0/0, args= 0, extra= 0
+	lw	v0,312(a0)	# fpregs.fp_csr
+	li	v1,0xfffc0fff	# mask out exception cause bits
+	and	v0,v0,v1
+	# saved integer regs
+	lw	t9,180(a0)	# gpregs[CXT_EPC]
+	lw	ra,180(a0)	# gpregs[CXT_EPC]
+	lw	gp,152(a0)	# gpregs[CXT_GP]
+	lw	sp,156(a0)	# gpregs[CXT_SP]
+	ctc1	v0,$31		# fp_csr
+	lw	s8,160(a0)	# gpregs[CXT_S8]
+	lw	s0,104(a0)	# gpregs[CXT_S0]
+	lw	s1,108(a0)	# gpregs[CXT_S1]
+	lw	s2,112(a0)	# gpregs[CXT_S2]
+	lw	s3,116(a0)	# gpregs[CXT_S3]
+	lw	s4,120(a0)	# gpregs[CXT_S4]
+	lw	s5,124(a0)	# gpregs[CXT_S5]
+	lw	s6,128(a0)	# gpregs[CXT_S6]
+	lw	s7,132(a0)	# gpregs[CXT_S7]
+	# saved float regs
+	l.d	$f20,264(a0)	# fpregs.fp_r.fp_dregs[10]
+	l.d	$f22,272(a0)	# fpregs.fp_r.fp_dregs[11]
+	l.d	$f24,280(a0)	# fpregs.fp_r.fp_dregs[12]
+	l.d	$f26,288(a0)	# fpregs.fp_r.fp_dregs[13]
+	l.d	$f28,296(a0)	# fpregs.fp_r.fp_dregs[14]
+	l.d	$f30,304(a0)	# fpregs.fp_r.fp_dregs[15]
+
+	# load these, too
+	# they were not saved, but maybe the user modified them...
+	lw	v0,48(a0)
+	lw	v1,52(a0)
+	lw	a1,60(a0)
+	lw	a2,64(a0)
+	lw	a3,68(a0)
+	lw	a0,56(a0)	# there is no way back
+
+	j	ra
+
+	.end	setcxt

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 
+* 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.
+*/ 
+
+	.text
+
+/*
+ * sol_getsp()
+ *
+ * Return the current sp (for debugging)
+ */
+	.global sol_getsp
+sol_getsp:
+	retl
+   	mov     %sp, %o0
+
+
+/*
+ * sol_curthread()
+ *
+ * Return a unique identifier for the currently active thread.
+ */
+	.global sol_curthread
+sol_curthread:
+    retl
+    mov %g7, %o0
+                  
+
+	.global __MD_FlushRegisterWindows
+	.global _MD_FlushRegisterWindows
+
+__MD_FlushRegisterWindows:
+_MD_FlushRegisterWindows:
+
+	ta	3
+	ret
+	restore
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_sparcv9.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_sparcv9.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,201 @@
+! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+! 
+! 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.
+! 
+
+!
+!  atomic increment, decrement and swap routines for V8+ sparc (ultrasparc)
+!  using CAS (compare-and-swap) atomic instructions
+!
+!  this MUST be compiled with an ultrasparc-aware assembler
+!
+!  standard asm linkage macros; this module must be compiled
+!  with the -P option (use C preprocessor)
+
+#include <sys/asm_linkage.h>
+
+!  ======================================================================
+!
+!  Perform the sequence a = a + 1 atomically with respect to other
+!  fetch-and-adds to location a in a wait-free fashion.
+!
+!  usage : val = PR_AtomicIncrement(address)
+!  return: current value (you'd think this would be old val)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [local]   - work register
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(_MD_AtomicIncrement)      ! standard assembler/ELF prologue
+
+retryAI:
+        ld      [%o0], %o2              ! set o2 to the current value
+        add     %o2, 0x1, %o3           ! calc the new value
+        mov     %o3, %o1                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAI                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o1, %o0                ! set the return code to the new value
+
+        SET_SIZE(_MD_AtomicIncrement)   ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = a - 1 atomically with respect to other
+!  fetch-and-decs to location a in a wait-free fashion.
+!
+!  usage : val = PR_AtomicDecrement(address)
+!  return: current value (you'd think this would be old val)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [local]   - work register
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(_MD_AtomicDecrement)      ! standard assembler/ELF prologue
+
+retryAD:
+        ld      [%o0], %o2              ! set o2 to the current value
+        sub     %o2, 0x1, %o3           ! calc the new value
+        mov     %o3, %o1                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAD                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o1, %o0                ! set the return code to the new value
+
+        SET_SIZE(_MD_AtomicDecrement)   ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = b atomically with respect to other
+!  fetch-and-stores to location a in a wait-free fashion.
+!
+!  usage : old_val = PR_AtomicSet(address, newval)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [input]   - the new value to set for [%o0]
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(_MD_AtomicSet)            ! standard assembler/ELF prologue
+
+retryAS:
+        ld      [%o0], %o2              ! set o2 to the current value
+        mov     %o1, %o3                ! set up the new value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAS                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o3, %o0                ! set the return code to the prev value
+
+        SET_SIZE(_MD_AtomicSet)         ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = a + b atomically with respect to other
+!  fetch-and-adds to location a in a wait-free fashion.
+!
+!  usage : newval = PR_AtomicAdd(address, val)
+!  return: the value after addition
+!
+        ENTRY(_MD_AtomicAdd)      ! standard assembler/ELF prologue
+
+retryAA:
+        ld      [%o0], %o2              ! set o2 to the current value
+        add     %o2, %o1, %o3           ! calc the new value
+        mov     %o3, %o4                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAA                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o4, %o0                ! set the return code to the new value
+
+        SET_SIZE(_MD_AtomicAdd)    		! standard assembler/ELF epilogue
+
+!
+!  end
+!

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,201 @@
+! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+! 
+! 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.
+! 
+
+!
+!  atomic increment, decrement and swap routines for V8+ sparc (ultrasparc)
+!  using CAS (compare-and-swap) atomic instructions
+!
+!  this MUST be compiled with an ultrasparc-aware assembler
+!
+!  standard asm linkage macros; this module must be compiled
+!  with the -P option (use C preprocessor)
+
+#include <sys/asm_linkage.h>
+
+!  ======================================================================
+!
+!  Perform the sequence a = a + 1 atomically with respect to other
+!  fetch-and-adds to location a in a wait-free fashion.
+!
+!  usage : val = PR_AtomicIncrement(address)
+!  return: current value (you'd think this would be old val)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [local]   - work register
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(PR_AtomicIncrement)       ! standard assembler/ELF prologue
+
+retryAI:
+        ld      [%o0], %o2              ! set o2 to the current value
+        add     %o2, 0x1, %o3           ! calc the new value
+        mov     %o3, %o1                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAI                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o1, %o0                ! set the return code to the new value
+
+        SET_SIZE(PR_AtomicIncrement)    ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = a - 1 atomically with respect to other
+!  fetch-and-decs to location a in a wait-free fashion.
+!
+!  usage : val = PR_AtomicDecrement(address)
+!  return: current value (you'd think this would be old val)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [local]   - work register
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(PR_AtomicDecrement)       ! standard assembler/ELF prologue
+
+retryAD:
+        ld      [%o0], %o2              ! set o2 to the current value
+        sub     %o2, 0x1, %o3           ! calc the new value
+        mov     %o3, %o1                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAD                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o1, %o0                ! set the return code to the new value
+
+        SET_SIZE(PR_AtomicDecrement)    ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = b atomically with respect to other
+!  fetch-and-stores to location a in a wait-free fashion.
+!
+!  usage : old_val = PR_AtomicSet(address, newval)
+!
+!  -----------------------
+!  Note on REGISTER USAGE:
+!  as this is a LEAF procedure, a new stack frame is not created;
+!  we use the caller's stack frame so what would normally be %i (input)
+!  registers are actually %o (output registers).  Also, we must not
+!  overwrite the contents of %l (local) registers as they are not
+!  assumed to be volatile during calls.
+!
+!  So, the registers used are:
+!     %o0  [input]   - the address of the value to increment
+!     %o1  [input]   - the new value to set for [%o0]
+!     %o2  [local]   - work register
+!     %o3  [local]   - work register
+!  -----------------------
+
+        ENTRY(PR_AtomicSet)             ! standard assembler/ELF prologue
+
+retryAS:
+        ld      [%o0], %o2              ! set o2 to the current value
+        mov     %o1, %o3                ! set up the new value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAS                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o3, %o0                ! set the return code to the prev value
+
+        SET_SIZE(PR_AtomicSet)          ! standard assembler/ELF epilogue
+
+!
+!  end
+!
+!  ======================================================================
+!
+
+!  ======================================================================
+!
+!  Perform the sequence a = a + b atomically with respect to other
+!  fetch-and-adds to location a in a wait-free fashion.
+!
+!  usage : newval = PR_AtomicAdd(address, val)
+!  return: the value after addition
+!
+        ENTRY(PR_AtomicAdd)       ! standard assembler/ELF prologue
+
+retryAA:
+        ld      [%o0], %o2              ! set o2 to the current value
+        add     %o2, %o1, %o3           ! calc the new value
+        mov     %o3, %o4                ! save the return value
+        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
+        cmp     %o2, %o3                ! see if we set the value
+        bne     retryAA                 ! if not, try again
+        nop                             ! empty out the branch pipeline
+        retl                            ! return back to the caller
+        mov     %o4, %o0                ! set the return code to the new value
+
+        SET_SIZE(PR_AtomicAdd)    		! standard assembler/ELF epilogue
+
+!
+!  end
+!

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,154 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ 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.
+/ 
+
+	.text
+
+	.globl	getedi
+getedi:
+	movl	%edi,%eax
+	ret
+	.type	getedi, at function
+	.size	getedi,.-getedi
+ 
+	.globl	setedi
+setedi:
+	movl	4(%esp),%edi
+	ret
+	.type	setedi, at function
+	.size	setedi,.-setedi
+
+	.globl	__MD_FlushRegisterWindows
+	.globl _MD_FlushRegisterWindows
+
+__MD_FlushRegisterWindows:
+_MD_FlushRegisterWindows:
+
+	ret
+
+/
+/ sol_getsp()
+/
+/ Return the current sp (for debugging)
+/
+	.globl sol_getsp
+sol_getsp:
+	movl	%esp, %eax
+	ret
+
+/
+/ sol_curthread()
+/
+/ Return a unique identifier for the currently active thread.
+/
+	.globl sol_curthread
+sol_curthread:
+	movl	%ecx, %eax
+	ret
+
+/ PRInt32 _MD_AtomicIncrement(PRInt32 *val)
+/
+/ Atomically increment the integer pointed to by 'val' and return
+/ the result of the increment.
+/
+    .text
+    .globl _MD_AtomicIncrement
+    .align 4
+_MD_AtomicIncrement:
+    movl 4(%esp), %ecx
+    movl $1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    incl %eax
+    ret
+
+/ PRInt32 _MD_AtomicDecrement(PRInt32 *val)
+/
+/ Atomically decrement the integer pointed to by 'val' and return
+/ the result of the decrement.
+/
+    .text
+    .globl _MD_AtomicDecrement
+    .align 4
+_MD_AtomicDecrement:
+    movl 4(%esp), %ecx
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%ecx)
+    decl %eax
+    ret
+
+/ PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval)
+/
+/ Atomically set the integer pointed to by 'val' to the new
+/ value 'newval' and return the old value.
+/
+/ An alternative implementation:
+/   .text
+/   .globl _MD_AtomicSet
+/   .align 4
+/_MD_AtomicSet:
+/   movl 4(%esp), %ecx
+/   movl 8(%esp), %edx
+/   movl (%ecx), %eax
+/retry:
+/   lock
+/   cmpxchgl %edx, (%ecx)
+/   jne retry
+/   ret
+/
+    .text
+    .globl _MD_AtomicSet
+    .align 4
+_MD_AtomicSet:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    xchgl %eax, (%ecx)
+    ret
+
+/ PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+/
+/ Atomically add 'val' to the integer pointed to by 'ptr'
+/ and return the result of the addition.
+/
+    .text
+    .globl _MD_AtomicAdd
+    .align 4
+_MD_AtomicAdd:
+    movl 4(%esp), %ecx
+    movl 8(%esp), %eax
+    movl %eax, %edx
+    lock
+    xaddl %eax, (%ecx)
+    addl %edx, %eax
+    ret

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/os_SunOS_x86_64.s	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,91 @@
+/ -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/ 
+/ 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) 2004 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.
+/ 
+
+/ PRInt32 _MD_AtomicIncrement(PRInt32 *val)
+/
+/ Atomically increment the integer pointed to by 'val' and return
+/ the result of the increment.
+/
+    .text
+    .globl _MD_AtomicIncrement
+    .align 4
+_MD_AtomicIncrement:
+    movl $1, %eax
+    lock
+    xaddl %eax, (%rdi)
+    incl %eax
+    ret
+
+/ PRInt32 _MD_AtomicDecrement(PRInt32 *val)
+/
+/ Atomically decrement the integer pointed to by 'val' and return
+/ the result of the decrement.
+/
+    .text
+    .globl _MD_AtomicDecrement
+    .align 4
+_MD_AtomicDecrement:
+    movl $-1, %eax
+    lock
+    xaddl %eax, (%rdi)
+    decl %eax
+    ret
+
+/ PRInt32 _MD_AtomicSet(PRInt32 *val, PRInt32 newval)
+/
+/ Atomically set the integer pointed to by 'val' to the new
+/ value 'newval' and return the old value.
+/
+    .text
+    .globl _MD_AtomicSet
+    .align 4
+_MD_AtomicSet:
+    movl %esi, %eax
+    xchgl %eax, (%rdi)
+    ret
+
+/ PRInt32 _MD_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+/
+/ Atomically add 'val' to the integer pointed to by 'ptr'
+/ and return the result of the addition.
+/
+    .text
+    .globl _MD_AtomicAdd
+    .align 4
+_MD_AtomicAdd:
+    movl %esi, %eax
+    lock
+    xaddl %eax, (%rdi)
+    addl %esi, %eax
+    ret

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/osf1.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/osf1.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,107 @@
+/* -*- 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"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for OSF1 */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for OSF1.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OSF1.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/pthreads_user.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/pthreads_user.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,480 @@
+/* -*- 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 <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pthread.h>
+
+
+sigset_t ints_off;
+pthread_mutex_t	_pr_heapLock;
+pthread_key_t current_thread_key;
+pthread_key_t current_cpu_key;
+pthread_key_t last_thread_key;
+pthread_key_t intsoff_key;
+
+
+PRInt32 _pr_md_pthreads_created, _pr_md_pthreads_failed;
+PRInt32 _pr_md_pthreads = 1;
+
+void _MD_EarlyInit(void)
+{
+extern PRInt32 _nspr_noclock;
+
+	if (pthread_key_create(&current_thread_key, NULL) != 0) {
+		perror("pthread_key_create failed");
+		exit(1);
+	}
+	if (pthread_key_create(&current_cpu_key, NULL) != 0) {
+		perror("pthread_key_create failed");
+		exit(1);
+	}
+	if (pthread_key_create(&last_thread_key, NULL) != 0) {
+		perror("pthread_key_create failed");
+		exit(1);
+	}
+	if (pthread_key_create(&intsoff_key, NULL) != 0) {
+		perror("pthread_key_create failed");
+		exit(1);
+	}
+
+	sigemptyset(&ints_off);
+	sigaddset(&ints_off, SIGALRM);
+	sigaddset(&ints_off, SIGIO);
+	sigaddset(&ints_off, SIGCLD);
+
+	/*
+	 * disable clock interrupts
+	 */
+	_nspr_noclock = 1;
+
+}
+
+void _MD_InitLocks()
+{
+	if (pthread_mutex_init(&_pr_heapLock, NULL) != 0) {
+		perror("pthread_mutex_init failed");
+		exit(1);
+	}
+}
+
+PR_IMPLEMENT(void) _MD_FREE_LOCK(struct _MDLock *lockp)
+{
+	PRIntn _is;
+	PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(_is); 
+	pthread_mutex_destroy(&lockp->mutex);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(_is);
+}
+
+
+
+PR_IMPLEMENT(PRStatus) _MD_NEW_LOCK(struct _MDLock *lockp)
+{
+    PRStatus rv;
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();	
+
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(is);
+	rv = pthread_mutex_init(&lockp->mutex, NULL);
+	if (me && !_PR_IS_NATIVE_THREAD(me))
+		_PR_FAST_INTSON(is);
+	return (rv == 0) ? PR_SUCCESS : PR_FAILURE;
+}
+
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+PR_IMPLEMENT(void)
+_MD_SetPriority(_MDThread *thread, PRThreadPriority newPri)
+{
+	/*
+	 * XXX - to be implemented
+	 */
+    return;
+}
+
+PR_IMPLEMENT(PRStatus) _MD_InitThread(struct PRThread *thread)
+{
+    struct sigaction sigact;
+
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        thread->md.pthread = pthread_self();
+#if 0
+		/*
+		 * set up SIGUSR1 handler; this is used to save state
+		 * during PR_SuspendAll
+		 */
+		sigact.sa_handler = save_context_and_block;
+		sigact.sa_flags = SA_RESTART;
+		/*
+		 * Must mask clock interrupts
+		 */
+		sigact.sa_mask = timer_set;
+		sigaction(SIGUSR1, &sigact, 0);
+#endif
+    }
+
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(void) _MD_ExitThread(struct PRThread *thread)
+{
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        _MD_CLEAN_THREAD(thread);
+        _MD_SET_CURRENT_THREAD(NULL);
+    }
+}
+
+PR_IMPLEMENT(void) _MD_CleanThread(struct PRThread *thread)
+{
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+		pthread_mutex_destroy(&thread->md.pthread_mutex);
+		pthread_cond_destroy(&thread->md.pthread_cond);
+    }
+}
+
+PR_IMPLEMENT(void) _MD_SuspendThread(struct PRThread *thread)
+{
+    PRInt32 rv;
+
+    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&
+        _PR_IS_GCABLE_THREAD(thread));
+#if 0
+	thread->md.suspending_id = getpid();
+	rv = kill(thread->md.id, SIGUSR1);
+	PR_ASSERT(rv == 0);
+	/*
+	 * now, block the current thread/cpu until woken up by the suspended
+	 * thread from it's SIGUSR1 signal handler
+	 */
+	blockproc(getpid());
+#endif
+}
+
+PR_IMPLEMENT(void) _MD_ResumeThread(struct PRThread *thread)
+{
+    PRInt32 rv;
+
+    PR_ASSERT((thread->flags & _PR_GLOBAL_SCOPE) &&
+        _PR_IS_GCABLE_THREAD(thread));
+#if 0
+    rv = unblockproc(thread->md.id);
+#endif
+}
+
+PR_IMPLEMENT(void) _MD_SuspendCPU(struct _PRCPU *thread)
+{
+    PRInt32 rv;
+
+#if 0
+	cpu->md.suspending_id = getpid();
+	rv = kill(cpu->md.id, SIGUSR1);
+	PR_ASSERT(rv == 0);
+	/*
+	 * now, block the current thread/cpu until woken up by the suspended
+	 * thread from it's SIGUSR1 signal handler
+	 */
+	blockproc(getpid());
+#endif
+}
+
+PR_IMPLEMENT(void) _MD_ResumeCPU(struct _PRCPU *thread)
+{
+#if 0
+	unblockproc(cpu->md.id);
+#endif
+}
+
+
+#define PT_NANOPERMICRO 1000UL
+#define PT_BILLION 1000000000UL
+
+PR_IMPLEMENT(PRStatus)
+_pt_wait(PRThread *thread, PRIntervalTime timeout)
+{
+int rv;
+struct timeval now;
+struct timespec tmo;
+PRUint32 ticks = PR_TicksPerSecond();
+
+
+	if (timeout != PR_INTERVAL_NO_TIMEOUT) {
+		tmo.tv_sec = timeout / ticks;
+		tmo.tv_nsec = timeout - (tmo.tv_sec * ticks);
+		tmo.tv_nsec = PR_IntervalToMicroseconds(PT_NANOPERMICRO *
+											tmo.tv_nsec);
+
+		/* pthreads wants this in absolute time, off we go ... */
+		(void)GETTIMEOFDAY(&now);
+		/* that one's usecs, this one's nsecs - grrrr! */
+		tmo.tv_sec += now.tv_sec;
+		tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec);
+		tmo.tv_sec += tmo.tv_nsec / PT_BILLION;
+		tmo.tv_nsec %= PT_BILLION;
+	}
+
+	pthread_mutex_lock(&thread->md.pthread_mutex);
+	thread->md.wait--;
+	if (thread->md.wait < 0) {
+		if (timeout != PR_INTERVAL_NO_TIMEOUT) {
+			rv = pthread_cond_timedwait(&thread->md.pthread_cond,
+					&thread->md.pthread_mutex, &tmo);
+        }
+		else
+			rv = pthread_cond_wait(&thread->md.pthread_cond,
+					&thread->md.pthread_mutex);
+		if (rv != 0) {
+			thread->md.wait++;
+		}
+	} else
+		rv = 0;
+	pthread_mutex_unlock(&thread->md.pthread_mutex);
+
+	return (rv == 0) ? PR_SUCCESS : PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_wait(PRThread *thread, PRIntervalTime ticks)
+{
+    if ( thread->flags & _PR_GLOBAL_SCOPE ) {
+		_MD_CHECK_FOR_EXIT();
+        if (_pt_wait(thread, ticks) == PR_FAILURE) {
+	    	_MD_CHECK_FOR_EXIT();
+            /*
+             * wait timed out
+             */
+            _PR_THREAD_LOCK(thread);
+            if (thread->wait.cvar) {
+                /*
+                 * The thread will remove itself from the waitQ
+                 * of the cvar in _PR_WaitCondVar
+                 */
+                thread->wait.cvar = NULL;
+                thread->state =  _PR_RUNNING;
+                _PR_THREAD_UNLOCK(thread);
+            }  else {
+        		_pt_wait(thread, PR_INTERVAL_NO_TIMEOUT);
+                _PR_THREAD_UNLOCK(thread);
+            }
+        }
+    } else {
+		_PR_MD_SWITCH_CONTEXT(thread);
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_WakeupWaiter(PRThread *thread)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 pid, rv;
+    PRIntn is;
+
+	PR_ASSERT(_pr_md_idle_cpus >= 0);
+    if (thread == NULL) {
+		if (_pr_md_idle_cpus)
+        	_MD_Wakeup_CPUs();
+    } else if (!_PR_IS_NATIVE_THREAD(thread)) {
+		/*
+		 * If the thread is on my cpu's runq there is no need to
+		 * wakeup any cpus
+		 */
+		if (!_PR_IS_NATIVE_THREAD(me)) {
+			if (me->cpu != thread->cpu) {
+				if (_pr_md_idle_cpus)
+        			_MD_Wakeup_CPUs();
+			}
+		} else {
+			if (_pr_md_idle_cpus)
+        		_MD_Wakeup_CPUs();
+		}
+    } else {
+		PR_ASSERT(_PR_IS_NATIVE_THREAD(thread));
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_INTSOFF(is);
+
+		pthread_mutex_lock(&thread->md.pthread_mutex);
+		thread->md.wait++;
+		rv = pthread_cond_signal(&thread->md.pthread_cond);
+		PR_ASSERT(rv == 0);
+		pthread_mutex_unlock(&thread->md.pthread_mutex);
+
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+    } 
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for AIX */
+PR_IMPLEMENT(void)
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for AIX.");
+}
+
+PR_IMPLEMENT(PRStatus)
+_MD_CreateThread(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PRIntn is;
+    int rv;
+	PRThread *me = _PR_MD_CURRENT_THREAD();	
+	pthread_attr_t attr;
+
+	if (!_PR_IS_NATIVE_THREAD(me))
+		_PR_INTSOFF(is);
+
+	if (pthread_mutex_init(&thread->md.pthread_mutex, NULL) != 0) {
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return PR_FAILURE;
+	}
+
+	if (pthread_cond_init(&thread->md.pthread_cond, NULL) != 0) {
+		pthread_mutex_destroy(&thread->md.pthread_mutex);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return PR_FAILURE;
+	}
+    thread->flags |= _PR_GLOBAL_SCOPE;
+
+	pthread_attr_init(&attr); /* initialize attr with default attributes */
+	if (pthread_attr_setstacksize(&attr, (size_t) stackSize) != 0) {
+		pthread_mutex_destroy(&thread->md.pthread_mutex);
+		pthread_cond_destroy(&thread->md.pthread_cond);
+		pthread_attr_destroy(&attr);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return PR_FAILURE;
+	}
+
+	thread->md.wait = 0;
+    rv = pthread_create(&thread->md.pthread, &attr, start, (void *)thread);
+    if (0 == rv) {
+        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_created);
+        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        return PR_SUCCESS;
+    } else {
+		pthread_mutex_destroy(&thread->md.pthread_mutex);
+		pthread_cond_destroy(&thread->md.pthread_cond);
+		pthread_attr_destroy(&attr);
+        _MD_ATOMIC_INCREMENT(&_pr_md_pthreads_failed);
+		if (!_PR_IS_NATIVE_THREAD(me))
+			_PR_FAST_INTSON(is);
+        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, rv);
+        return PR_FAILURE;
+    }
+}
+
+PR_IMPLEMENT(void)
+_MD_InitRunningCPU(struct _PRCPU *cpu)
+{
+    extern int _pr_md_pipefd[2];
+
+    _MD_unix_init_running_cpu(cpu);
+    cpu->md.pthread = pthread_self();
+	if (_pr_md_pipefd[0] >= 0) {
+    	_PR_IOQ_MAX_OSFD(cpu) = _pr_md_pipefd[0];
+#ifndef _PR_USE_POLL
+    	FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(cpu));
+#endif
+	}
+}
+
+
+void
+_MD_CleanupBeforeExit(void)
+{
+#if 0
+    extern PRInt32    _pr_cpus_exit;
+
+	_pr_irix_exit_now = 1;
+    if (_pr_numCPU > 1) {
+        /*
+         * Set a global flag, and wakeup all cpus which will notice the flag
+         * and exit.
+         */
+        _pr_cpus_exit = getpid();
+        _MD_Wakeup_CPUs();
+        while(_pr_numCPU > 1) {
+            _PR_WAIT_SEM(_pr_irix_exit_sem);
+            _pr_numCPU--;
+        }
+    }
+    /*
+     * cause global threads on the recycle list to exit
+     */
+     _PR_DEADQ_LOCK;
+     if (_PR_NUM_DEADNATIVE != 0) {
+	PRThread *thread;
+    	PRCList *ptr;
+
+        ptr = _PR_DEADNATIVEQ.next;
+        while( ptr != &_PR_DEADNATIVEQ ) {
+        	thread = _PR_THREAD_PTR(ptr);
+		_MD_CVAR_POST_SEM(thread);
+                ptr = ptr->next;
+        } 
+     }
+     _PR_DEADQ_UNLOCK;
+     while(_PR_NUM_DEADNATIVE > 1) {
+	_PR_WAIT_SEM(_pr_irix_exit_sem);
+	_PR_DEC_DEADNATIVE;
+     }
+#endif
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/qnx.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/qnx.c	Mon Dec 18 10:53:47 2006
@@ -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) 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 <setjmp.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Unixware */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Unixware.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRUintn priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Unixware.");
+    return PR_FAILURE;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/reliantunix.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/reliantunix.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,133 @@
+/* -*- 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 ***** */
+
+/*
+ * SINIX (ReliantUNIX) 5.4 - copied from unixware.c by chrisk 040497
+ */
+#include "primpl.h"
+
+#include <ucontext.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) _GETCONTEXT(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+#ifdef ALARMS_BREAK_TCP /* I don't think they do */
+
+PRInt32 _MD_connect(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _connect(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+}
+
+PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _accept(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+    return(rv);
+}
+#endif
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for SINIX */
+/* Why? Just copied it from UNIXWARE... flying-by-night, chrisk 040497 */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for SINIX.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRUintn priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for SINIX.");
+#if defined(SNI) && !defined(__GNUC__)
+    /* make compiler happy */
+    return (PRStatus)NULL;
+#endif
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/rhapsody.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/rhapsody.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,137 @@
+/* -*- 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"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#if !defined(_PR_PTHREADS)
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#if !defined(_PR_PTHREADS)
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Rhapsody */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Rhapsody.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Rhapsody.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
+
+#if defined(_PR_PTHREADS)
+
+/*
+** Stubs for unimplemented functions
+*/
+
+int pthread_condattr_init(pthread_condattr_t *attr)
+{
+    return 0;
+}
+
+int pthread_kill(pthread_t thread, int sig)
+{
+    return ENOSYS;
+}
+
+typedef struct siginfo_t siginfo_t;
+
+int sigtimedwait(const sigset_t *set, siginfo_t *info,
+    const struct timespec *timeout)
+{
+    errno = ENOSYS;
+    return -1;
+}
+
+#endif /* _PR_PTHREADS */
+
+/* rhapsody.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/riscos.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/riscos.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,120 @@
+/* -*- 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): Peter Naulls <peter at chocky.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the 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"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifdef _PR_PTHREADS
+
+void _MD_CleanupBeforeExit(void)
+{
+}
+
+#else /* ! _PR_PTHREADS */
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	/*
+	 * set the pointers to the stack-pointer and frame-pointer words in the
+	 * context structure; this is for debugging use.
+	 */
+	thread->md.sp = _MD_GET_SP_PTR(thread);
+	thread->md.fp = _MD_GET_FP_PTR(thread);
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for RISC OS */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for RISC OS.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for RISC OS.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/scoos.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/scoos.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,181 @@
+/* -*- 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 ***** */
+
+/*
+ * SCO ODT 5.0 - originally created by mikep
+ */
+#include "primpl.h"
+
+#include <setjmp.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+#ifdef ALARMS_BREAK_TCP /* I don't think they do */
+
+PRInt32 _MD_connect(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _connect(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+}
+
+PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _accept(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+    return(rv);
+}
+#endif
+
+/*
+ * These are also implemented in pratom.c using NSPR locks.  Any reason
+ * this might be better or worse?  If you like this better, define
+ * _PR_HAVE_ATOMIC_OPS in include/md/unixware.h
+ */
+#ifdef _PR_HAVE_ATOMIC_OPS
+/* Atomic operations */
+#include  <stdio.h>
+static FILE *_uw_semf;
+
+void
+_MD_INIT_ATOMIC(void)
+{
+    /* Sigh.  Sure wish SYSV semaphores weren't such a pain to use */
+    if ((_uw_semf = tmpfile()) == NULL)
+        PR_ASSERT(0);
+
+    return;
+}
+
+void
+_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)++;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    flockfile(_uw_semf);
+    (*ptr) += val;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)--;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    flockfile(_uw_semf);
+    *val = newval;
+    unflockfile(_uw_semf);
+}
+#endif
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for SCO */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for SCO.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for SCO.");
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/solaris.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/solaris.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,889 @@
+/* -*- 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"
+
+
+extern PRBool suspendAllOn;
+extern PRThread *suspendAllThread;
+
+extern void _MD_SET_PRIORITY(_MDThread *md, PRThreadPriority newPri);
+
+PRIntervalTime _MD_Solaris_TicksPerSecond(void)
+{
+    /*
+     * Ticks have a 10-microsecond resolution.  So there are
+     * 100000 ticks per second.
+     */
+    return 100000UL;
+}
+
+/* Interval timers, implemented using gethrtime() */
+
+PRIntervalTime _MD_Solaris_GetInterval(void)
+{
+    union {
+	hrtime_t hrt;  /* hrtime_t is a 64-bit (long long) integer */
+	PRInt64 pr64;
+    } time;
+    PRInt64 resolution;
+    PRIntervalTime ticks;
+
+    time.hrt = gethrtime();  /* in nanoseconds */
+    /*
+     * Convert from nanoseconds to ticks.  A tick's resolution is
+     * 10 microseconds, or 10000 nanoseconds.
+     */
+    LL_I2L(resolution, 10000);
+    LL_DIV(time.pr64, time.pr64, resolution);
+    LL_L2UI(ticks, time.pr64);
+    return ticks;
+}
+
+#ifdef _PR_PTHREADS
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np)
+{
+	*np = 0;
+	return NULL;
+}
+#endif /* _PR_PTHREADS */
+
+#if !defined(i386) && !defined(IS_64)
+#if defined(_PR_HAVE_ATOMIC_OPS)
+/* NOTE:
+ * SPARC v9 (Ultras) do have an atomic test-and-set operation.  But
+ * SPARC v8 doesn't.  We should detect in the init if we are running on
+ * v8 or v9, and then use assembly where we can.
+ *
+ * This code uses the Solaris threads API.  It can be used in both the
+ * pthreads and Solaris threads versions of nspr20 because "POSIX threads
+ * and Solaris threads are fully compatible even within the same process",
+ * to quote from pthread_create(3T).
+ */
+
+#include <thread.h>
+#include <synch.h>
+
+static mutex_t _solaris_atomic = DEFAULTMUTEX;
+
+PRInt32
+_MD_AtomicIncrement(PRInt32 *val)
+{
+    PRInt32 rv;
+    if (mutex_lock(&_solaris_atomic) != 0)
+        PR_ASSERT(0);
+
+    rv = ++(*val);
+
+    if (mutex_unlock(&_solaris_atomic) != 0)\
+        PR_ASSERT(0);
+
+	return rv;
+}
+
+PRInt32
+_MD_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+{
+    PRInt32 rv;
+    if (mutex_lock(&_solaris_atomic) != 0)
+        PR_ASSERT(0);
+
+    rv = ((*ptr) += val);
+
+    if (mutex_unlock(&_solaris_atomic) != 0)\
+        PR_ASSERT(0);
+
+	return rv;
+}
+
+PRInt32
+_MD_AtomicDecrement(PRInt32 *val)
+{
+    PRInt32 rv;
+    if (mutex_lock(&_solaris_atomic) != 0)
+        PR_ASSERT(0);
+
+    rv = --(*val);
+
+    if (mutex_unlock(&_solaris_atomic) != 0)\
+        PR_ASSERT(0);
+
+	return rv;
+}
+
+PRInt32
+_MD_AtomicSet(PRInt32 *val, PRInt32 newval)
+{
+    PRInt32 rv;
+    if (mutex_lock(&_solaris_atomic) != 0)
+        PR_ASSERT(0);
+
+    rv = *val;
+    *val = newval;
+
+    if (mutex_unlock(&_solaris_atomic) != 0)\
+        PR_ASSERT(0);
+
+	return rv;
+}
+#endif  /* _PR_HAVE_ATOMIC_OPS */
+#endif  /* !defined(i386) */
+
+#if defined(_PR_GLOBAL_THREADS_ONLY)
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <thread.h>
+
+#include <sys/lwp.h>
+#include <sys/procfs.h>
+#include <sys/syscall.h>
+extern int syscall();  /* not declared in sys/syscall.h */
+
+static sigset_t old_mask;	/* store away original gc thread sigmask */
+static PRIntn gcprio;		/* store away original gc thread priority */
+
+THREAD_KEY_T threadid_key;
+THREAD_KEY_T cpuid_key;
+THREAD_KEY_T last_thread_key;
+static sigset_t set, oldset;
+
+static void
+threadid_key_destructor(void *value)
+{
+    PRThread *me = (PRThread *)value;
+    PR_ASSERT(me != NULL);
+    /* the thread could be PRIMORDIAL (thus not ATTACHED) */
+    if (me->flags & _PR_ATTACHED) {
+        /*
+         * The Solaris thread library sets the thread specific
+         * data (the current thread) to NULL before invoking
+         * the destructor.  We need to restore it to prevent the
+         * _PR_MD_CURRENT_THREAD() call in _PRI_DetachThread()
+         * from attaching the thread again.
+         */
+        _PR_MD_SET_CURRENT_THREAD(me);
+        _PRI_DetachThread();
+    }
+}
+
+void _MD_EarlyInit(void)
+{
+    THR_KEYCREATE(&threadid_key, threadid_key_destructor);
+    THR_KEYCREATE(&cpuid_key, NULL);
+    THR_KEYCREATE(&last_thread_key, NULL);
+    sigemptyset(&set);
+    sigaddset(&set, SIGALRM);
+}
+
+PRStatus _MD_CreateThread(PRThread *thread, 
+					void (*start)(void *), 
+					PRThreadPriority priority,
+					PRThreadScope scope, 
+					PRThreadState state, 
+					PRUint32 stackSize) 
+{
+	PRInt32 flags;
+	
+    /* mask out SIGALRM for native thread creation */
+    thr_sigsetmask(SIG_BLOCK, &set, &oldset); 
+
+    /*
+     * Note that we create joinable threads with the THR_DETACHED
+     * flag.  The reasons why we don't use thr_join to implement
+     * PR_JoinThread are:
+     * - We use a termination condition variable in the PRThread
+     *   structure to implement PR_JoinThread across all classic
+     *   nspr implementation strategies.
+     * - The native threads may be recycled by NSPR to run other
+     *   new NSPR threads, so the native threads may not terminate
+     *   when the corresponding NSPR threads terminate.  
+     */
+    flags = THR_SUSPENDED|THR_DETACHED;
+    if (_PR_IS_GCABLE_THREAD(thread) || (thread->flags & _PR_BOUND_THREAD) ||
+    							(scope == PR_GLOBAL_BOUND_THREAD))
+		flags |= THR_BOUND;
+
+    if (thr_create(NULL, thread->stack->stackSize,
+                  (void *(*)(void *)) start, (void *) thread, 
+				  flags,
+                  &thread->md.handle)) {
+        thr_sigsetmask(SIG_SETMASK, &oldset, NULL); 
+        return PR_FAILURE;
+    }
+
+    /* When the thread starts running, then the lwpid is set to the right
+     * value. Until then we want to mark this as 'uninit' so that
+     * its register state is initialized properly for GC */
+
+    thread->md.lwpid = -1;
+    thr_sigsetmask(SIG_SETMASK, &oldset, NULL); 
+    _MD_NEW_SEM(&thread->md.waiter_sem, 0);
+
+    if ((scope == PR_GLOBAL_THREAD) || (scope == PR_GLOBAL_BOUND_THREAD)) {
+		thread->flags |= _PR_GLOBAL_SCOPE;
+    }
+
+    _MD_SET_PRIORITY(&(thread->md), priority);
+
+    /* Activate the thread */
+    if (thr_continue( thread->md.handle ) ) {
+	return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+void _MD_cleanup_thread(PRThread *thread)
+{
+    thread_t hdl;
+
+    hdl = thread->md.handle;
+
+    /* 
+    ** First, suspend the thread (unless it's the active one)
+    ** Because we suspend it first, we don't have to use LOCK_SCHEDULER to
+    ** prevent both of us modifying the thread structure at the same time.
+    */
+    if ( thread != _PR_MD_CURRENT_THREAD() ) {
+        thr_suspend(hdl);
+    }
+    PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+            ("(0X%x)[DestroyThread]\n", thread));
+
+    _MD_DESTROY_SEM(&thread->md.waiter_sem);
+}
+
+void _MD_exit_thread(PRThread *thread)
+{
+    _MD_CLEAN_THREAD(thread);
+    _MD_SET_CURRENT_THREAD(NULL);
+}
+
+void _MD_SET_PRIORITY(_MDThread *md_thread,
+        PRThreadPriority newPri)
+{
+	PRIntn nativePri;
+
+	if (newPri < PR_PRIORITY_FIRST) {
+		newPri = PR_PRIORITY_FIRST;
+	} else if (newPri > PR_PRIORITY_LAST) {
+		newPri = PR_PRIORITY_LAST;
+	}
+	/* Solaris priorities are from 0 to 127 */
+	nativePri = newPri * 127 / PR_PRIORITY_LAST;
+	if(thr_setprio((thread_t)md_thread->handle, nativePri)) {
+		PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+		   ("_PR_SetThreadPriority: can't set thread priority\n"));
+	}
+}
+
+void _MD_WAIT_CV(
+    struct _MDCVar *md_cv, struct _MDLock *md_lock, PRIntervalTime timeout)
+{
+    struct timespec tt;
+    PRUint32 msec;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	PR_ASSERT((!suspendAllOn) || (suspendAllThread != me));
+
+    if (PR_INTERVAL_NO_TIMEOUT == timeout) {
+        COND_WAIT(&md_cv->cv, &md_lock->lock);
+    } else {
+        msec = PR_IntervalToMilliseconds(timeout);
+
+        GETTIME(&tt);
+        tt.tv_sec += msec / PR_MSEC_PER_SEC;
+        tt.tv_nsec += (msec % PR_MSEC_PER_SEC) * PR_NSEC_PER_MSEC;
+        /* Check for nsec overflow - otherwise we'll get an EINVAL */
+        if (tt.tv_nsec >= PR_NSEC_PER_SEC) {
+            tt.tv_sec++;
+            tt.tv_nsec -= PR_NSEC_PER_SEC;
+        }
+        COND_TIMEDWAIT(&md_cv->cv, &md_lock->lock, &tt);
+    }
+}
+
+void _MD_lock(struct _MDLock *md_lock)
+{
+#ifdef DEBUG
+    /* This code was used for GC testing to make sure that we didn't attempt
+     * to grab any locks while threads are suspended.
+     */
+    PRLock *lock;
+    
+    if ((suspendAllOn) && (suspendAllThread == _PR_MD_CURRENT_THREAD())) {
+        lock = ((PRLock *) ((char*) (md_lock) - offsetof(PRLock,ilock)));
+	PR_ASSERT(lock->owner == NULL);
+        return;
+    }
+#endif /* DEBUG */
+
+    mutex_lock(&md_lock->lock);
+}
+
+PRThread *_pr_attached_thread_tls()
+{
+    PRThread *ret;
+
+    thr_getspecific(threadid_key, (void **)&ret);
+    return ret;
+}
+
+PRThread *_pr_current_thread_tls()
+{
+    PRThread *thread;
+
+    thread = _MD_GET_ATTACHED_THREAD();
+
+    if (NULL == thread) {
+        thread = _PRI_AttachThread(
+            PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0);
+    }
+    PR_ASSERT(thread != NULL);
+
+    return thread;
+}
+
+PRStatus
+_MD_wait(PRThread *thread, PRIntervalTime ticks)
+{
+        _MD_WAIT_SEM(&thread->md.waiter_sem);
+        return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WakeupWaiter(PRThread *thread)
+{
+	if (thread == NULL) {
+		return PR_SUCCESS;
+	}
+	_MD_POST_SEM(&thread->md.waiter_sem);
+	return PR_SUCCESS;
+}
+
+_PRCPU *_pr_current_cpu_tls()
+{
+    _PRCPU *ret;
+
+    thr_getspecific(cpuid_key, (void **)&ret);
+    return ret;
+}
+
+PRThread *_pr_last_thread_tls()
+{
+    PRThread *ret;
+
+    thr_getspecific(last_thread_key, (void **)&ret);
+    return ret;
+}
+
+_MDLock _pr_ioq_lock;
+
+void
+_MD_InitIO(void)
+{
+    _MD_NEW_LOCK(&_pr_ioq_lock);
+}
+
+PRStatus _MD_InitializeThread(PRThread *thread)
+{
+    if (!_PR_IS_NATIVE_THREAD(thread))
+        return PR_SUCCESS;
+    /* sol_curthread is an asm routine which grabs GR7; GR7 stores an internal
+     * thread structure ptr used by solaris.  We'll use this ptr later
+     * with suspend/resume to find which threads are running on LWPs.
+     */
+    thread->md.threadID = sol_curthread();
+		/* prime the sp; substract 4 so we don't hit the assert that
+		 * curr sp > base_stack
+		 */
+    thread->md.sp = (uint_t) thread->stack->allocBase - sizeof(long);
+    thread->md.lwpid = _lwp_self();
+    thread->md.handle = THR_SELF();
+
+	/* all threads on Solaris are global threads from NSPR's perspective
+	 * since all of them are mapped to Solaris threads.
+	 */
+    thread->flags |= _PR_GLOBAL_SCOPE;
+ 
+ 	/* For primordial/attached thread, we don't create an underlying native thread.
+ 	 * So, _MD_CREATE_THREAD() does not get called.  We need to do initialization
+ 	 * like allocating thread's synchronization variables and set the underlying
+ 	 * native thread's priority.
+ 	 */
+	if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
+	    _MD_NEW_SEM(&thread->md.waiter_sem, 0);
+	    _MD_SET_PRIORITY(&(thread->md), thread->priority);
+	}
+	return PR_SUCCESS;
+}
+
+/* Sleep for n milliseconds, n < 1000   */
+void solaris_msec_sleep(int n)
+{
+    struct timespec ts;
+
+    ts.tv_sec = 0;
+    ts.tv_nsec = 1000000*n;
+    if (syscall(SYS_nanosleep, &ts, 0, 0) < 0) {
+        PR_ASSERT(0);
+    }
+}      
+
+#define VALID_SP(sp, bottom, top)   \
+	(((uint_t)(sp)) > ((uint_t)(bottom)) && ((uint_t)(sp)) < ((uint_t)(top)))
+
+void solaris_record_regs(PRThread *t, prstatus_t *lwpstatus)
+{
+#ifdef sparc
+	long *regs = (long *)&t->md.context.uc_mcontext.gregs[0];
+
+	PR_ASSERT(_PR_IS_GCABLE_THREAD(t));
+	PR_ASSERT(t->md.threadID == lwpstatus->pr_reg[REG_G7]);
+
+	t->md.sp = lwpstatus->pr_reg[REG_SP];
+	PR_ASSERT(VALID_SP(t->md.sp, t->stack->stackBottom, t->stack->stackTop));
+
+	regs[0] = lwpstatus->pr_reg[R_G1];
+	regs[1] = lwpstatus->pr_reg[R_G2];
+	regs[2] = lwpstatus->pr_reg[R_G3];
+	regs[3] = lwpstatus->pr_reg[R_G4];
+	regs[4] = lwpstatus->pr_reg[R_O0];
+	regs[5] = lwpstatus->pr_reg[R_O1];
+	regs[6] = lwpstatus->pr_reg[R_O2];
+	regs[7] = lwpstatus->pr_reg[R_O3];
+	regs[8] = lwpstatus->pr_reg[R_O4];
+	regs[9] = lwpstatus->pr_reg[R_O5];
+	regs[10] = lwpstatus->pr_reg[R_O6];
+	regs[11] = lwpstatus->pr_reg[R_O7];
+#elif defined(i386)
+	/*
+	 * To be implemented and tested
+	 */
+	PR_ASSERT(0);
+	PR_ASSERT(t->md.threadID == lwpstatus->pr_reg[GS]);
+	t->md.sp = lwpstatus->pr_reg[UESP];
+#endif
+}   
+
+void solaris_preempt_off()
+{
+    sigset_t set;
+ 
+    (void)sigfillset(&set);
+    syscall(SYS_sigprocmask, SIG_SETMASK, &set, &old_mask);
+}
+
+void solaris_preempt_on()
+{
+    syscall(SYS_sigprocmask, SIG_SETMASK, &old_mask, NULL);      
+}
+
+int solaris_open_main_proc_fd()
+{
+    char buf[30];
+    int fd;
+
+    /* Not locked, so must be created while threads coming up */
+    PR_snprintf(buf, sizeof(buf), "/proc/%ld", getpid());
+    if ( (fd = syscall(SYS_open, buf, O_RDONLY)) < 0) {
+        return -1;
+    }
+    return fd;
+}
+
+/* Return a file descriptor for the /proc entry corresponding to the
+ * given lwp. 
+ */
+int solaris_open_lwp(lwpid_t id, int lwp_main_proc_fd)
+{
+    int result;
+
+    if ( (result = syscall(SYS_ioctl, lwp_main_proc_fd, PIOCOPENLWP, &id)) <0)
+        return -1; /* exited??? */
+
+    return result;
+}
+void _MD_Begin_SuspendAll()
+{
+    solaris_preempt_off();
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin_SuspendAll\n"));
+    /* run at highest prio so I cannot be preempted */
+    thr_getprio(thr_self(), &gcprio);
+    thr_setprio(thr_self(), 0x7fffffff); 
+    suspendAllOn = PR_TRUE;
+    suspendAllThread = _PR_MD_CURRENT_THREAD();
+}
+
+void _MD_End_SuspendAll()
+{
+}
+
+void _MD_End_ResumeAll()
+{
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End_ResumeAll\n"));
+    thr_setprio(thr_self(), gcprio);
+    solaris_preempt_on();
+    suspendAllThread = NULL;
+    suspendAllOn = PR_FALSE;
+}
+
+void _MD_Suspend(PRThread *thr)
+{
+   int lwp_fd, result;
+   prstatus_t lwpstatus;
+   int lwp_main_proc_fd = 0;
+  
+   if (!_PR_IS_GCABLE_THREAD(thr) || !suspendAllOn){
+     /*XXX When the suspendAllOn is set, we will be trying to do lwp_suspend
+      * during that time we can't call any thread lib or libc calls. Hence
+      * make sure that no suspension is requested for Non gcable thread
+      * during suspendAllOn */
+      PR_ASSERT(!suspendAllOn);
+      thr_suspend(thr->md.handle);
+      return;
+   }
+
+    /* XXX Primordial thread can't be bound to an lwp, hence there is no
+     * way we can assume that we can get the lwp status for primordial
+     * thread reliably. Hence we skip this for primordial thread, hoping
+     * that the SP is saved during lock and cond. wait. 
+     * XXX - Again this is concern only for java interpreter, not for the
+     * server, 'cause primordial thread in the server does not do java work
+     */
+    if (thr->flags & _PR_PRIMORDIAL)
+      return;
+    
+    /* XXX Important Note: If the start function of a thread is not called,
+     * lwpid is -1. Then, skip this thread. This thread will get caught
+     * in PR_NativeRunThread before calling the start function, because
+     * we hold the pr_activeLock during suspend/resume */
+
+    /* if the thread is not started yet then don't do anything */
+    if (!suspendAllOn || thr->md.lwpid == -1)
+      return;
+
+    if (_lwp_suspend(thr->md.lwpid) < 0) { 
+       PR_ASSERT(0);
+       return;
+    }
+
+    if ( (lwp_main_proc_fd = solaris_open_main_proc_fd()) < 0) {
+        PR_ASSERT(0);
+        return;   /* XXXMB ARGH, we're hosed! */
+    }
+
+   if ( (lwp_fd = solaris_open_lwp(thr->md.lwpid, lwp_main_proc_fd)) < 0) {
+           PR_ASSERT(0);
+           close(lwp_main_proc_fd);
+	   return;
+   }
+   if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {
+            /* Hopefully the thread just died... */
+           close(lwp_fd);
+           close(lwp_main_proc_fd);
+	   return;
+   }
+            while ( !(lwpstatus.pr_flags & PR_STOPPED) ) {
+                if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {
+                    PR_ASSERT(0);  /* ARGH SOMETHING WRONG! */
+                    break;
+                }
+                solaris_msec_sleep(1);
+            }
+            solaris_record_regs(thr, &lwpstatus);
+            close(lwp_fd);
+   close(lwp_main_proc_fd);
+}
+
+#ifdef OLD_CODE
+
+void _MD_SuspendAll()
+{
+    /* On solaris there are threads, and there are LWPs. 
+     * Calling _PR_DoSingleThread would freeze all of the threads bound to LWPs
+     * but not necessarily stop all LWPs (for example if someone did
+     * an attachthread of a thread which was not bound to an LWP).
+     * So now go through all the LWPs for this process and freeze them.
+     *
+     * Note that if any thread which is capable of having the GC run on it must
+     * had better be a LWP with a single bound thread on it.  Otherwise, this 
+     * might not stop that thread from being run.
+     */
+    PRThread *current = _PR_MD_CURRENT_THREAD();
+    prstatus_t status, lwpstatus;
+    int result, index, lwp_fd;
+    lwpid_t me = _lwp_self();
+    int err;
+    int lwp_main_proc_fd;
+
+    solaris_preempt_off();
+
+    /* run at highest prio so I cannot be preempted */
+    thr_getprio(thr_self(), &gcprio);
+    thr_setprio(thr_self(), 0x7fffffff); 
+
+    current->md.sp = (uint_t)&me;	/* set my own stack pointer */
+
+    if ( (lwp_main_proc_fd = solaris_open_main_proc_fd()) < 0) {
+        PR_ASSERT(0);
+        solaris_preempt_on();
+        return;   /* XXXMB ARGH, we're hosed! */
+    }
+
+    if ( (result = syscall(SYS_ioctl, lwp_main_proc_fd, PIOCSTATUS, &status)) < 0) {
+        err = errno;
+        PR_ASSERT(0);
+        goto failure;   /* XXXMB ARGH, we're hosed! */
+    }
+
+    num_lwps = status.pr_nlwp;
+
+    if ( (all_lwps = (lwpid_t *)PR_MALLOC((num_lwps+1) * sizeof(lwpid_t)))==NULL) {
+        PR_ASSERT(0);
+        goto failure;   /* XXXMB ARGH, we're hosed! */
+    }
+           
+    if ( (result = syscall(SYS_ioctl, lwp_main_proc_fd, PIOCLWPIDS, all_lwps)) < 0) {
+        PR_ASSERT(0);
+        PR_DELETE(all_lwps);
+        goto failure;   /* XXXMB ARGH, we're hosed! */
+    }
+
+    for (index=0; index< num_lwps; index++) {
+        if (all_lwps[index] != me)  {
+            if (_lwp_suspend(all_lwps[index]) < 0) { 
+                /* could happen if lwp exited */
+                all_lwps[index] = me;	/* dummy it up */
+            }
+        }
+    }
+
+    /* Turns out that lwp_suspend is not a blocking call.
+     * Go through the list and make sure they are all stopped.
+     */
+    for (index=0; index< num_lwps; index++) {
+        if (all_lwps[index] != me)  {
+            if ( (lwp_fd = solaris_open_lwp(all_lwps[index], lwp_main_proc_fd)) < 0) {
+                PR_ASSERT(0);
+                PR_DELETE(all_lwps);
+                all_lwps = NULL;
+                goto failure;   /* XXXMB ARGH, we're hosed! */
+            }
+
+            if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {
+                /* Hopefully the thread just died... */
+                close(lwp_fd);
+                continue;
+            }
+            while ( !(lwpstatus.pr_flags & PR_STOPPED) ) {
+                if ( (result = syscall(SYS_ioctl, lwp_fd, PIOCSTATUS, &lwpstatus)) < 0) {
+                    PR_ASSERT(0);  /* ARGH SOMETHING WRONG! */
+                    break;
+                }
+                solaris_msec_sleep(1);
+            }
+            solaris_record_regs(&lwpstatus);
+            close(lwp_fd);
+        }
+    }
+
+    close(lwp_main_proc_fd);
+
+    return;
+failure:
+    solaris_preempt_on();
+    thr_setprio(thr_self(), gcprio);
+    close(lwp_main_proc_fd);
+    return;
+}
+
+void _MD_ResumeAll()
+{
+    int i;
+    lwpid_t me = _lwp_self();
+ 
+    for (i=0; i < num_lwps; i++) {
+        if (all_lwps[i] == me)
+            continue;
+        if ( _lwp_continue(all_lwps[i]) < 0) {
+            PR_ASSERT(0);  /* ARGH, we are hosed! */
+        }
+    }
+
+    /* restore priority and sigmask */
+    thr_setprio(thr_self(), gcprio);
+    solaris_preempt_on();
+    PR_DELETE(all_lwps);
+    all_lwps = NULL;
+}
+#endif /* OLD_CODE */
+
+#ifdef USE_SETJMP
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+		(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+#else
+PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np)
+{
+    if (isCurrent) {
+		(void) getcontext(CONTEXT(t));
+    }
+    *np = NGREG;
+    return (PRWord*) &t->md.context.uc_mcontext.gregs[0];
+}
+#endif  /* USE_SETJMP */
+
+#else /* _PR_GLOBAL_THREADS_ONLY */
+
+#if defined(_PR_LOCAL_THREADS_ONLY)
+
+void _MD_EarlyInit(void)
+{
+}
+
+void _MD_SolarisInit()
+{
+    _PR_UnixInit();
+}
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+	PR_ASSERT((thread == NULL) || (!(thread->flags & _PR_GLOBAL_SCOPE)));
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Solaris */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Solaris");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Solaris");
+	return(PR_FAILURE);
+}
+
+#ifdef USE_SETJMP
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+		(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+#else
+PRWord *_MD_HomeGCRegisters(PRThread *t, PRIntn isCurrent, PRIntn *np)
+{
+    if (isCurrent) {
+		(void) getcontext(CONTEXT(t));
+    }
+    *np = NGREG;
+    return (PRWord*) &t->md.context.uc_mcontext.gregs[0];
+}
+#endif  /* USE_SETJMP */
+
+#endif  /* _PR_LOCAL_THREADS_ONLY */
+
+#endif /* _PR_GLOBAL_THREADS_ONLY */
+
+#ifndef _PR_PTHREADS
+#if defined(i386) && defined(SOLARIS2_4)
+/* 
+ * Because clock_gettime() on Solaris/x86 2.4 always generates a
+ * segmentation fault, we use an emulated version _pr_solx86_clock_gettime(),
+ * which is implemented using gettimeofday().
+ */
+
+int
+_pr_solx86_clock_gettime(clockid_t clock_id, struct timespec *tp)
+{
+    struct timeval tv;
+
+    if (clock_id != CLOCK_REALTIME) {
+	errno = EINVAL;
+	return -1;
+    }
+
+    gettimeofday(&tv, NULL);
+    tp->tv_sec = tv.tv_sec;
+    tp->tv_nsec = tv.tv_usec * 1000;
+    return 0;
+}
+#endif  /* i386 && SOLARIS2_4 */
+#endif  /* _PR_PTHREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/sony.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/sony.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,109 @@
+/* -*- 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 <signal.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Sony */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for SONY.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for SONY.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/sunos4.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/sunos4.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,96 @@
+/* -*- 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 <setjmp.h>
+#include "primpl.h"
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRStatus _MD_CREATE_THREAD(PRThread *thread, 
+					void (*start)(void *), 
+					PRThreadPriority priority,
+					PRThreadScope scope, 
+					PRThreadState state, 
+					PRUint32 stackSize) 
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for SunOS 4.1.3.");
+    return PR_FAILURE;
+}
+
+void _MD_SET_PRIORITY(_MDThread *md_thread, PRUintn newPri)
+{
+    PR_NOT_REACHED("_MD_SET_PRIORITY should not be called for user-level threads.");
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus _MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for SunOS 4.1.3.");
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/unix.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/unix.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3731 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 
+ * 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.
+ */
+
+#include "primpl.h"
+
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+
+#ifdef _PR_POLL_AVAILABLE
+#include <poll.h>
+#endif
+
+/* To get FIONREAD */
+#if defined(NCR) || defined(UNIXWARE) || defined(NEC) || defined(SNI) \
+        || defined(SONY)
+#include <sys/filio.h>
+#endif
+
+#if defined(NTO)
+#include <sys/statvfs.h>
+#endif
+
+/*
+ * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or
+ * PRInt32* pointer to a _PRSockLen_t* pointer.
+ */
+#if defined(HAVE_SOCKLEN_T) \
+    || (defined(__GLIBC__) && __GLIBC__ >= 2)
+#define _PRSockLen_t socklen_t
+#elif defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \
+    || defined(AIX4_1) || defined(LINUX) || defined(SONY) \
+    || defined(BSDI) || defined(SCO) || defined(NEC) || defined(SNI) \
+    || defined(SUNOS4) || defined(NCR) || defined(DARWIN) \
+    || defined(NEXTSTEP) || defined(QNX)
+#define _PRSockLen_t int
+#elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \
+    || defined(NETBSD) || defined(OPENBSD) || defined(UNIXWARE) \
+    || defined(DGUX) || defined(VMS) || defined(NTO) || defined(RISCOS)
+#define _PRSockLen_t size_t
+#else
+#error "Cannot determine architecture"
+#endif
+
+/*
+** Global lock variable used to bracket calls into rusty libraries that
+** aren't thread safe (like libc, libX, etc).
+*/
+static PRLock *_pr_rename_lock = NULL;
+static PRMonitor *_pr_Xfe_mon = NULL;
+
+static PRInt64 minus_one;
+
+sigset_t timer_set;
+
+#if !defined(_PR_PTHREADS)
+
+static sigset_t empty_set;
+
+#ifdef SOLARIS
+#include <sys/file.h>
+#include <sys/filio.h>
+#endif
+
+#ifndef PIPE_BUF
+#define PIPE_BUF 512
+#endif
+
+/*
+ * _nspr_noclock - if set clock interrupts are disabled
+ */
+int _nspr_noclock = 1;
+
+#ifdef IRIX
+extern PRInt32 _nspr_terminate_on_error;
+#endif
+
+/*
+ * There is an assertion in this code that NSPR's definition of PRIOVec
+ * is bit compatible with UNIX' definition of a struct iovec. This is
+ * applicable to the 'writev()' operations where the types are casually
+ * cast to avoid warnings.
+ */
+
+int _pr_md_pipefd[2] = { -1, -1 };
+static char _pr_md_pipebuf[PIPE_BUF];
+static PRInt32 local_io_wait(PRInt32 osfd, PRInt32 wait_flag,
+							PRIntervalTime timeout);
+
+_PRInterruptTable _pr_interruptTable[] = {
+    { 
+        "clock", _PR_MISSED_CLOCK, _PR_ClockInterrupt,     },
+    { 
+        0     }
+};
+
+void _MD_unix_init_running_cpu(_PRCPU *cpu)
+{
+    PR_INIT_CLIST(&(cpu->md.md_unix.ioQ));
+    cpu->md.md_unix.ioq_max_osfd = -1;
+    cpu->md.md_unix.ioq_timeout = PR_INTERVAL_NO_TIMEOUT;
+}
+
+PRStatus _MD_open_dir(_MDDir *d, const char *name)
+{
+int err;
+
+    d->d = opendir(name);
+    if (!d->d) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_OPENDIR_ERROR(err);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PRInt32 _MD_close_dir(_MDDir *d)
+{
+int rv = 0, err;
+
+    if (d->d) {
+        rv = closedir(d->d);
+        if (rv == -1) {
+                err = _MD_ERRNO();
+                _PR_MD_MAP_CLOSEDIR_ERROR(err);
+        }
+    }
+    return rv;
+}
+
+char * _MD_read_dir(_MDDir *d, PRIntn flags)
+{
+struct dirent *de;
+int err;
+
+    for (;;) {
+        /*
+          * XXX: readdir() is not MT-safe. There is an MT-safe version
+          * readdir_r() on some systems.
+          */
+        _MD_ERRNO() = 0;
+        de = readdir(d->d);
+        if (!de) {
+            err = _MD_ERRNO();
+            _PR_MD_MAP_READDIR_ERROR(err);
+            return 0;
+        }        
+        if ((flags & PR_SKIP_DOT) &&
+            (de->d_name[0] == '.') && (de->d_name[1] == 0))
+            continue;
+        if ((flags & PR_SKIP_DOT_DOT) &&
+            (de->d_name[0] == '.') && (de->d_name[1] == '.') &&
+            (de->d_name[2] == 0))
+            continue;
+        if ((flags & PR_SKIP_HIDDEN) && (de->d_name[0] == '.'))
+            continue;
+        break;
+    }
+    return de->d_name;
+}
+
+PRInt32 _MD_delete(const char *name)
+{
+PRInt32 rv, err;
+#ifdef UNIXWARE
+    sigset_t set, oset;
+#endif
+
+#ifdef UNIXWARE
+    sigfillset(&set);
+    sigprocmask(SIG_SETMASK, &set, &oset);
+#endif
+    rv = unlink(name);
+#ifdef UNIXWARE
+    sigprocmask(SIG_SETMASK, &oset, NULL);
+#endif
+    if (rv == -1) {
+            err = _MD_ERRNO();
+            _PR_MD_MAP_UNLINK_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_rename(const char *from, const char *to)
+{
+    PRInt32 rv = -1, err;
+
+    /*
+    ** This is trying to enforce the semantics of WINDOZE' rename
+    ** operation. That means one is not allowed to rename over top
+    ** of an existing file. Holding a lock across these two function
+    ** and the open function is known to be a bad idea, but ....
+    */
+    if (NULL != _pr_rename_lock)
+        PR_Lock(_pr_rename_lock);
+    if (0 == access(to, F_OK))
+        PR_SetError(PR_FILE_EXISTS_ERROR, 0);
+    else
+    {
+        rv = rename(from, to);
+        if (rv < 0) {
+            err = _MD_ERRNO();
+            _PR_MD_MAP_RENAME_ERROR(err);
+        }
+    }
+    if (NULL != _pr_rename_lock)
+        PR_Unlock(_pr_rename_lock);
+    return rv;
+}
+
+PRInt32 _MD_access(const char *name, PRAccessHow how)
+{
+PRInt32 rv, err;
+int amode;
+
+    switch (how) {
+        case PR_ACCESS_WRITE_OK:
+            amode = W_OK;
+            break;
+        case PR_ACCESS_READ_OK:
+            amode = R_OK;
+            break;
+        case PR_ACCESS_EXISTS:
+            amode = F_OK;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            rv = -1;
+            goto done;
+    }
+    rv = access(name, amode);
+
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_ACCESS_ERROR(err);
+    }
+
+done:
+    return(rv);
+}
+
+PRInt32 _MD_mkdir(const char *name, PRIntn mode)
+{
+int rv, err;
+
+    /*
+    ** This lock is used to enforce rename semantics as described
+    ** in PR_Rename. Look there for more fun details.
+    */
+    if (NULL !=_pr_rename_lock)
+        PR_Lock(_pr_rename_lock);
+    rv = mkdir(name, mode);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_MKDIR_ERROR(err);
+    }
+    if (NULL !=_pr_rename_lock)
+        PR_Unlock(_pr_rename_lock);
+    return rv;
+}
+
+PRInt32 _MD_rmdir(const char *name)
+{
+int rv, err;
+
+    rv = rmdir(name);
+    if (rv == -1) {
+            err = _MD_ERRNO();
+            _PR_MD_MAP_RMDIR_ERROR(err);
+    }
+    return rv;
+}
+
+PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+PRThread *me = _PR_MD_CURRENT_THREAD();
+PRInt32 rv, err;
+#ifndef _PR_USE_POLL
+fd_set rd;
+#else
+struct pollfd pfd;
+#endif /* _PR_USE_POLL */
+PRInt32 osfd = fd->secret->md.osfd;
+
+#ifndef _PR_USE_POLL
+    FD_ZERO(&rd);
+    FD_SET(osfd, &rd);
+#else
+    pfd.fd = osfd;
+    pfd.events = POLLIN;
+#endif /* _PR_USE_POLL */
+    while ((rv = read(osfd,buf,amount)) == -1) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+                if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ,
+										PR_INTERVAL_NO_TIMEOUT)) < 0)
+					goto done;								
+            } else {
+#ifndef _PR_USE_POLL
+                while ((rv = _MD_SELECT(osfd + 1, &rd, NULL, NULL, NULL))
+                        == -1 && (err = _MD_ERRNO()) == EINTR) {
+                    /* retry _MD_SELECT() if it is interrupted */
+                }
+#else /* _PR_USE_POLL */
+                while ((rv = _MD_POLL(&pfd, 1, -1))
+                        == -1 && (err = _MD_ERRNO()) == EINTR) {
+                    /* retry _MD_POLL() if it is interrupted */
+                }
+#endif /* _PR_USE_POLL */
+                if (rv == -1) {
+                    break;
+                }
+            }
+            if (_PR_PENDING_INTERRUPT(me))
+                break;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            _PR_MD_MAP_READ_ERROR(err);
+        }
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+PRThread *me = _PR_MD_CURRENT_THREAD();
+PRInt32 rv, err;
+#ifndef _PR_USE_POLL
+fd_set wd;
+#else
+struct pollfd pfd;
+#endif /* _PR_USE_POLL */
+PRInt32 osfd = fd->secret->md.osfd;
+
+#ifndef _PR_USE_POLL
+    FD_ZERO(&wd);
+    FD_SET(osfd, &wd);
+#else
+    pfd.fd = osfd;
+    pfd.events = POLLOUT;
+#endif /* _PR_USE_POLL */
+    while ((rv = write(osfd,buf,amount)) == -1) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+                if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE,
+										PR_INTERVAL_NO_TIMEOUT)) < 0)
+                    goto done;
+            } else {
+#ifndef _PR_USE_POLL
+                while ((rv = _MD_SELECT(osfd + 1, NULL, &wd, NULL, NULL))
+                        == -1 && (err = _MD_ERRNO()) == EINTR) {
+                    /* retry _MD_SELECT() if it is interrupted */
+                }
+#else /* _PR_USE_POLL */
+                while ((rv = _MD_POLL(&pfd, 1, -1))
+                        == -1 && (err = _MD_ERRNO()) == EINTR) {
+                    /* retry _MD_POLL() if it is interrupted */
+                }
+#endif /* _PR_USE_POLL */
+                if (rv == -1) {
+                    break;
+                }
+            }
+            if (_PR_PENDING_INTERRUPT(me))
+                break;
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            _PR_MD_MAP_WRITE_ERROR(err);
+        }
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_fsync(PRFileDesc *fd)
+{
+PRInt32 rv, err;
+
+    rv = fsync(fd->secret->md.osfd);
+    if (rv == -1) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_FSYNC_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_close(PRInt32 osfd)
+{
+PRInt32 rv, err;
+
+    rv = close(osfd);
+    if (rv == -1) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_CLOSE_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
+{
+    PRInt32 osfd, err;
+
+    osfd = socket(domain, type, proto);
+
+    if (osfd == -1) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SOCKET_ERROR(err);
+        return(osfd);
+    }
+
+    return(osfd);
+}
+
+PRInt32 _MD_socketavailable(PRFileDesc *fd)
+{
+    PRInt32 result;
+
+    if (ioctl(fd->secret->md.osfd, FIONREAD, &result) < 0) {
+        _PR_MD_MAP_SOCKETAVAILABLE_ERROR(_MD_ERRNO());
+        return -1;
+    }
+    return result;
+}
+
+PRInt64 _MD_socketavailable64(PRFileDesc *fd)
+{
+    PRInt64 result;
+    LL_I2L(result, _MD_socketavailable(fd));
+    return result;
+}  /* _MD_socketavailable64 */
+
+#define READ_FD        1
+#define WRITE_FD    2
+
+/*
+ * socket_io_wait --
+ *
+ * wait for socket i/o, periodically checking for interrupt
+ *
+ * The first implementation uses select(), for platforms without
+ * poll().  The second (preferred) implementation uses poll().
+ */
+
+#ifndef _PR_USE_POLL
+
+static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
+    PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+    struct timeval tv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntervalTime epoch, now, elapsed, remaining;
+    PRBool wait_for_remaining;
+    PRInt32 syserror;
+    fd_set rd_wr;
+
+    switch (timeout) {
+        case PR_INTERVAL_NO_WAIT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+            break;
+        case PR_INTERVAL_NO_TIMEOUT:
+            /*
+             * This is a special case of the 'default' case below.
+             * Please see the comments there.
+             */
+            tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+            tv.tv_usec = 0;
+            FD_ZERO(&rd_wr);
+            do {
+                FD_SET(osfd, &rd_wr);
+                if (fd_type == READ_FD)
+                    rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
+                else
+                    rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
+                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+                    _PR_MD_MAP_SELECT_ERROR(syserror);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+        default:
+            now = epoch = PR_IntervalNow();
+            remaining = timeout;
+            FD_ZERO(&rd_wr);
+            do {
+                /*
+                 * We block in _MD_SELECT for at most
+                 * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
+                 * so that there is an upper limit on the delay
+                 * before the interrupt bit is checked.
+                 */
+                wait_for_remaining = PR_TRUE;
+                tv.tv_sec = PR_IntervalToSeconds(remaining);
+                if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
+                    wait_for_remaining = PR_FALSE;
+                    tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+                    tv.tv_usec = 0;
+                } else {
+                    tv.tv_usec = PR_IntervalToMicroseconds(
+                        remaining -
+                        PR_SecondsToInterval(tv.tv_sec));
+                }
+                FD_SET(osfd, &rd_wr);
+                if (fd_type == READ_FD)
+                    rv = _MD_SELECT(osfd + 1, &rd_wr, NULL, NULL, &tv);
+                else
+                    rv = _MD_SELECT(osfd + 1, NULL, &rd_wr, NULL, &tv);
+                /*
+                 * we don't consider EINTR a real error
+                 */
+                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+                    _PR_MD_MAP_SELECT_ERROR(syserror);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+                /*
+                 * We loop again if _MD_SELECT timed out or got interrupted
+                 * by a signal, and the timeout deadline has not passed yet.
+                 */
+                if (rv == 0 || (rv == -1 && syserror == EINTR)) {
+                    /*
+                     * If _MD_SELECT timed out, we know how much time
+                     * we spent in blocking, so we can avoid a
+                     * PR_IntervalNow() call.
+                     */
+                    if (rv == 0) {
+                        if (wait_for_remaining) {
+                            now += remaining;
+                        } else {
+                            now += PR_SecondsToInterval(tv.tv_sec)
+                                + PR_MicrosecondsToInterval(tv.tv_usec);
+                        }
+                    } else {
+                        now = PR_IntervalNow();
+                    }
+                    elapsed = (PRIntervalTime) (now - epoch);
+                    if (elapsed >= timeout) {
+                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                        rv = -1;
+                        break;
+                    } else {
+                        remaining = timeout - elapsed;
+                    }
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+    }
+    return(rv);
+}
+
+#else /* _PR_USE_POLL */
+
+static PRInt32 socket_io_wait(PRInt32 osfd, PRInt32 fd_type,
+    PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+    int msecs;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntervalTime epoch, now, elapsed, remaining;
+    PRBool wait_for_remaining;
+    PRInt32 syserror;
+    struct pollfd pfd;
+
+    switch (timeout) {
+        case PR_INTERVAL_NO_WAIT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+            break;
+        case PR_INTERVAL_NO_TIMEOUT:
+            /*
+             * This is a special case of the 'default' case below.
+             * Please see the comments there.
+             */
+            msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
+            pfd.fd = osfd;
+            if (fd_type == READ_FD) {
+                pfd.events = POLLIN;
+            } else {
+                pfd.events = POLLOUT;
+            }
+            do {
+                rv = _MD_POLL(&pfd, 1, msecs);
+                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+                    _PR_MD_MAP_POLL_ERROR(syserror);
+                    break;
+                }
+				/*
+				 * If POLLERR is set, don't process it; retry the operation
+				 */
+                if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) {
+					rv = -1;
+                    _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+        default:
+            now = epoch = PR_IntervalNow();
+            remaining = timeout;
+            pfd.fd = osfd;
+            if (fd_type == READ_FD) {
+                pfd.events = POLLIN;
+            } else {
+                pfd.events = POLLOUT;
+            }
+            do {
+                /*
+                 * We block in _MD_POLL for at most
+                 * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
+                 * so that there is an upper limit on the delay
+                 * before the interrupt bit is checked.
+                 */
+                wait_for_remaining = PR_TRUE;
+                msecs = PR_IntervalToMilliseconds(remaining);
+                if (msecs > _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000) {
+                    wait_for_remaining = PR_FALSE;
+                    msecs = _PR_INTERRUPT_CHECK_INTERVAL_SECS * 1000;
+                }
+                rv = _MD_POLL(&pfd, 1, msecs);
+                /*
+                 * we don't consider EINTR a real error
+                 */
+                if (rv == -1 && (syserror = _MD_ERRNO()) != EINTR) {
+                    _PR_MD_MAP_POLL_ERROR(syserror);
+                    break;
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+				/*
+				 * If POLLERR is set, don't process it; retry the operation
+				 */
+                if ((rv == 1) && (pfd.revents & (POLLHUP | POLLNVAL))) {
+					rv = -1;
+                    _PR_MD_MAP_POLL_REVENTS_ERROR(pfd.revents);
+                    break;
+                }
+                /*
+                 * We loop again if _MD_POLL timed out or got interrupted
+                 * by a signal, and the timeout deadline has not passed yet.
+                 */
+                if (rv == 0 || (rv == -1 && syserror == EINTR)) {
+                    /*
+                     * If _MD_POLL timed out, we know how much time
+                     * we spent in blocking, so we can avoid a
+                     * PR_IntervalNow() call.
+                     */
+                    if (rv == 0) {
+                        if (wait_for_remaining) {
+                            now += remaining;
+                        } else {
+                            now += PR_MillisecondsToInterval(msecs);
+                        }
+                    } else {
+                        now = PR_IntervalNow();
+                    }
+                    elapsed = (PRIntervalTime) (now - epoch);
+                    if (elapsed >= timeout) {
+                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                        rv = -1;
+                        break;
+                    } else {
+                        remaining = timeout - elapsed;
+                    }
+                }
+            } while (rv == 0 || (rv == -1 && syserror == EINTR));
+            break;
+    }
+    return(rv);
+}
+
+#endif /* _PR_USE_POLL */
+
+static PRInt32 local_io_wait(
+    PRInt32 osfd,
+    PRInt32 wait_flag,
+    PRIntervalTime timeout)
+{
+    _PRUnixPollDesc pd;
+    PRInt32 rv;
+
+    PR_LOG(_pr_io_lm, PR_LOG_MIN,
+       ("waiting to %s on osfd=%d",
+        (wait_flag == _PR_UNIX_POLL_READ) ? "read" : "write",
+        osfd));
+
+    if (timeout == PR_INTERVAL_NO_WAIT) return 0;
+
+    pd.osfd = osfd;
+    pd.in_flags = wait_flag;
+    pd.out_flags = 0;
+
+    rv = _PR_WaitForMultipleFDs(&pd, 1, timeout);
+
+    if (rv == 0) {
+        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        rv = -1;
+    }
+    return rv;
+}
+
+
+PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
+                                PRInt32 flags, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+/*
+ * Many OS's (Solaris, Unixware) have a broken recv which won't read
+ * from socketpairs.  As long as we don't use flags on socketpairs, this
+ * is a decent fix. - mikep
+ */
+#if defined(UNIXWARE) || defined(SOLARIS) || defined(NCR)
+    while ((rv = read(osfd,buf,amount)) == -1) {
+#else
+    while ((rv = recv(osfd,buf,amount,flags)) == -1) {
+#endif
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+				if ((rv = local_io_wait(osfd,_PR_UNIX_POLL_READ,timeout)) < 0)
+					goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_RECV_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
+                        PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((*addrlen = PR_NETADDR_SIZE(addr)),
+                ((rv = recvfrom(osfd, buf, amount, flags,
+                        (struct sockaddr *) addr, (_PRSockLen_t *)addrlen)) == -1)) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+                if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, timeout)) < 0)
+                    goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_RECVFROM_ERROR(err);
+    }
+done:
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv != -1) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    return(rv);
+}
+
+PRInt32 _MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+                            PRInt32 flags, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+#if defined(SOLARIS)
+	PRInt32 tmp_amount = amount;
+#endif
+
+    /*
+     * On pre-2.6 Solaris, send() is much slower than write().
+     * On 2.6 and beyond, with in-kernel sockets, send() and
+     * write() are fairly equivalent in performance.
+     */
+#if defined(SOLARIS)
+    PR_ASSERT(0 == flags);
+    while ((rv = write(osfd,buf,tmp_amount)) == -1) {
+#else
+    while ((rv = send(osfd,buf,amount,flags)) == -1) {
+#endif
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK))    {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+                if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
+                    goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+#if defined(SOLARIS)
+			/*
+			 * The write system call has been reported to return the ERANGE
+			 * error on occasion. Try to write in smaller chunks to workaround
+			 * this bug.
+			 */
+			if (err == ERANGE) {
+				if (tmp_amount > 1) {
+					tmp_amount = tmp_amount/2;	/* half the bytes */
+					continue;
+				}
+			}
+#endif
+            break;
+        }
+    }
+        /*
+         * optimization; if bytes sent is less than "amount" call
+         * select before returning. This is because it is likely that
+         * the next send() call will return EWOULDBLOCK.
+         */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+            && (timeout != PR_INTERVAL_NO_WAIT)) {
+        if (_PR_IS_NATIVE_THREAD(me)) {
+			if (socket_io_wait(osfd, WRITE_FD, timeout)< 0) {
+				rv = -1;
+				goto done;
+			}
+        } else {
+			if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) {
+				rv = -1;
+				goto done;
+			}
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_SEND_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_sendto(
+    PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+    const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+
+    while ((rv = sendto(osfd, buf, amount, flags,
+            (struct sockaddr *) &addrCopy, addrlen)) == -1) {
+#else
+    while ((rv = sendto(osfd, buf, amount, flags,
+            (struct sockaddr *) addr, addrlen)) == -1) {
+#endif
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK))    {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+				if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
+					goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))< 0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_SENDTO_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_writev(
+    PRFileDesc *fd, const PRIOVec *iov,
+    PRInt32 iov_size, PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 index, amount = 0;
+    PRInt32 osfd = fd->secret->md.osfd;
+
+    /*
+     * Calculate the total number of bytes to be sent; needed for
+     * optimization later.
+     * We could avoid this if this number was passed in; but it is
+     * probably not a big deal because iov_size is usually small (less than
+     * 3)
+     */
+    if (!fd->secret->nonblocking) {
+        for (index=0; index<iov_size; index++) {
+            amount += iov[index].iov_len;
+        }
+    }
+
+    while ((rv = writev(osfd, (const struct iovec*)iov, iov_size)) == -1) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK))    {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+				if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
+					goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, WRITE_FD, timeout))<0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    /*
+     * optimization; if bytes sent is less than "amount" call
+     * select before returning. This is because it is likely that
+     * the next writev() call will return EWOULDBLOCK.
+     */
+    if ((!fd->secret->nonblocking) && (rv > 0) && (rv < amount)
+            && (timeout != PR_INTERVAL_NO_WAIT)) {
+        if (_PR_IS_NATIVE_THREAD(me)) {
+            if (socket_io_wait(osfd, WRITE_FD, timeout) < 0) {
+				rv = -1;
+                goto done;
+			}
+        } else {
+			if (local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout) < 0) {
+				rv = -1;
+				goto done;
+			}
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_WRITEV_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr,
+                            PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    while ((rv = accept(osfd, (struct sockaddr *) addr,
+                                        (_PRSockLen_t *)addrlen)) == -1) {
+        err = _MD_ERRNO();
+        if ((err == EAGAIN) || (err == EWOULDBLOCK) || (err == ECONNABORTED)) {
+            if (fd->secret->nonblocking) {
+                break;
+            }
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+				if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_READ, timeout)) < 0)
+					goto done;
+            } else {
+                if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+                    goto done;
+            }
+        } else if ((err == EINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_ACCEPT_ERROR(err);
+    }
+done:
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv != -1) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    return(rv);
+}
+
+extern int _connect (int s, const struct sockaddr *name, int namelen);
+PRInt32 _MD_connect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 osfd = fd->secret->md.osfd;
+#ifdef IRIX
+extern PRInt32 _MD_irix_connect(
+        PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen, PRIntervalTime timeout);
+#endif
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+#endif
+
+    /*
+     * We initiate the connection setup by making a nonblocking connect()
+     * call.  If the connect() call fails, there are two cases we handle
+     * specially:
+     * 1. The connect() call was interrupted by a signal.  In this case
+     *    we simply retry connect().
+     * 2. The NSPR socket is nonblocking and connect() fails with
+     *    EINPROGRESS.  We first wait until the socket becomes writable.
+     *    Then we try to find out whether the connection setup succeeded
+     *    or failed.
+     */
+
+retry:
+#ifdef IRIX
+    if ((rv = _MD_irix_connect(osfd, addr, addrlen, timeout)) == -1) {
+#else
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if ((rv = connect(osfd, (struct sockaddr *)&addrCopy, addrlen)) == -1) {
+#else
+    if ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) {
+#endif
+#endif
+        err = _MD_ERRNO();
+
+        if (err == EINTR) {
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+            goto retry;
+        }
+
+        if (!fd->secret->nonblocking && (err == EINPROGRESS)) {
+            if (!_PR_IS_NATIVE_THREAD(me)) {
+
+				if ((rv = local_io_wait(osfd, _PR_UNIX_POLL_WRITE, timeout)) < 0)
+                    return -1;
+            } else {
+                /*
+                 * socket_io_wait() may return -1 or 1.
+                 */
+
+                rv = socket_io_wait(osfd, WRITE_FD, timeout);
+                if (rv == -1) {
+                    return -1;
+                }
+            }
+
+            PR_ASSERT(rv == 1);
+            if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                return -1;
+            }
+            err = _MD_unix_get_nonblocking_connect_error(osfd);
+            if (err != 0) {
+                _PR_MD_MAP_CONNECT_ERROR(err);
+                return -1;
+            }
+            return 0;
+        }
+
+        _PR_MD_MAP_CONNECT_ERROR(err);
+    }
+
+    return rv;
+}  /* _MD_connect */
+
+PRInt32 _MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
+{
+    PRInt32 rv, err;
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    PRNetAddr addrCopy;
+
+    addrCopy = *addr;
+    ((struct sockaddr *) &addrCopy)->sa_len = addrlen;
+    ((struct sockaddr *) &addrCopy)->sa_family = addr->raw.family;
+    rv = bind(fd->secret->md.osfd, (struct sockaddr *) &addrCopy, (int )addrlen);
+#else
+    rv = bind(fd->secret->md.osfd, (struct sockaddr *) addr, (int )addrlen);
+#endif
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_BIND_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog)
+{
+    PRInt32 rv, err;
+
+    rv = listen(fd->secret->md.osfd, backlog);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_LISTEN_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_shutdown(PRFileDesc *fd, PRIntn how)
+{
+    PRInt32 rv, err;
+
+    rv = shutdown(fd->secret->md.osfd, how);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SHUTDOWN_ERROR(err);
+    }
+    return(rv);
+}
+
+PRInt32 _MD_socketpair(int af, int type, int flags,
+                                                        PRInt32 *osfd)
+{
+    PRInt32 rv, err;
+
+    rv = socketpair(af, type, flags, osfd);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SOCKETPAIR_ERROR(err);
+    }
+    return rv;
+}
+
+PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr,
+                                                PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockname(fd->secret->md.osfd,
+            (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv == 0) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETSOCKNAME_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr,
+                                        PRUint32 *addrlen)
+{
+    PRInt32 rv, err;
+
+    rv = getpeername(fd->secret->md.osfd,
+            (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (rv == 0) {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr) {
+            addr->raw.family = ((struct sockaddr *) addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETPEERNAME_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level,
+                        PRInt32 optname, char* optval, PRInt32* optlen)
+{
+    PRInt32 rv, err;
+
+    rv = getsockopt(fd->secret->md.osfd, level, optname, optval, (_PRSockLen_t *)optlen);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_GETSOCKOPT_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level,   
+                    PRInt32 optname, const char* optval, PRInt32 optlen)
+{
+    PRInt32 rv, err;
+
+    rv = setsockopt(fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_SETSOCKOPT_ERROR(err);
+    }
+    return rv==0?PR_SUCCESS:PR_FAILURE;
+}
+
+PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable)
+{
+    int rv;
+
+    rv = fcntl(fd->secret->md.osfd, F_SETFD, inheritable ? 0 : FD_CLOEXEC);
+    if (-1 == rv) {
+        PR_SetError(PR_UNKNOWN_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+void _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported)
+{
+    if (imported) {
+        fd->secret->inheritable = _PR_TRI_UNKNOWN;
+    } else {
+        /* By default, a Unix fd is not closed on exec. */
+#ifdef DEBUG
+        {
+            int flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
+            PR_ASSERT(0 == flags);
+        }
+#endif
+        fd->secret->inheritable = _PR_TRI_TRUE;
+    }
+}
+
+/************************************************************************/
+#if !defined(_PR_USE_POLL)
+
+/*
+** Scan through io queue and find any bad fd's that triggered the error
+** from _MD_SELECT
+*/
+static void FindBadFDs(void)
+{
+    PRCList *q;
+    PRThread *me = _MD_CURRENT_THREAD();
+
+    PR_ASSERT(!_PR_IS_NATIVE_THREAD(me));
+    q = (_PR_IOQ(me->cpu)).next;
+    _PR_IOQ_MAX_OSFD(me->cpu) = -1;
+    _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT;
+    while (q != &_PR_IOQ(me->cpu)) {
+        PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+        PRBool notify = PR_FALSE;
+        _PRUnixPollDesc *pds = pq->pds;
+        _PRUnixPollDesc *epds = pds + pq->npds;
+        PRInt32 pq_max_osfd = -1;
+
+        q = q->next;
+        for (; pds < epds; pds++) {
+            PRInt32 osfd = pds->osfd;
+            pds->out_flags = 0;
+            PR_ASSERT(osfd >= 0 || pds->in_flags == 0);
+            if (pds->in_flags == 0) {
+                continue;  /* skip this fd */
+            }
+            if (fcntl(osfd, F_GETFL, 0) == -1) {
+                /* Found a bad descriptor, remove it from the fd_sets. */
+                PR_LOG(_pr_io_lm, PR_LOG_MAX,
+                    ("file descriptor %d is bad", osfd));
+                pds->out_flags = _PR_UNIX_POLL_NVAL;
+                notify = PR_TRUE;
+            }
+            if (osfd > pq_max_osfd) {
+                pq_max_osfd = osfd;
+            }
+        }
+
+        if (notify) {
+            PRIntn pri;
+            PR_REMOVE_LINK(&pq->links);
+            pq->on_ioq = PR_FALSE;
+
+            /*
+         * Decrement the count of descriptors for each desciptor/event
+         * because this I/O request is being removed from the
+         * ioq
+         */
+            pds = pq->pds;
+            for (; pds < epds; pds++) {
+                PRInt32 osfd = pds->osfd;
+                PRInt16 in_flags = pds->in_flags;
+                PR_ASSERT(osfd >= 0 || in_flags == 0);
+                if (in_flags & _PR_UNIX_POLL_READ) {
+                    if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
+                }
+                if (in_flags & _PR_UNIX_POLL_WRITE) {
+                    if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
+                }
+                if (in_flags & _PR_UNIX_POLL_EXCEPT) {
+                    if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+                }
+            }
+
+            _PR_THREAD_LOCK(pq->thr);
+            if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
+                _PRCPU *cpu = pq->thr->cpu;
+                _PR_SLEEPQ_LOCK(pq->thr->cpu);
+                _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);
+                _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
+
+				if (pq->thr->flags & _PR_SUSPENDING) {
+				    /*
+				     * set thread state to SUSPENDED;
+				     * a Resume operation on the thread
+				     * will move it to the runQ
+				     */
+				    pq->thr->state = _PR_SUSPENDED;
+				    _PR_MISCQ_LOCK(pq->thr->cpu);
+				    _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu);
+				    _PR_MISCQ_UNLOCK(pq->thr->cpu);
+				} else {
+				    pri = pq->thr->priority;
+				    pq->thr->state = _PR_RUNNABLE;
+
+				    _PR_RUNQ_LOCK(cpu);
+				    _PR_ADD_RUNQ(pq->thr, cpu, pri);
+				    _PR_RUNQ_UNLOCK(cpu);
+				}
+            }
+            _PR_THREAD_UNLOCK(pq->thr);
+        } else {
+            if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))
+                _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;
+            if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)
+                _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;
+        }
+    }
+    if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+        if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0])
+            _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
+    }
+}
+#endif  /* !defined(_PR_USE_POLL) */
+
+/************************************************************************/
+
+/*
+** Called by the scheduler when there is nothing to do. This means that
+** all threads are blocked on some monitor somewhere.
+**
+** Note: this code doesn't release the scheduler lock.
+*/
+/*
+** Pause the current CPU. longjmp to the cpu's pause stack
+**
+** This must be called with the scheduler locked
+*/
+void _MD_PauseCPU(PRIntervalTime ticks)
+{
+    PRThread *me = _MD_CURRENT_THREAD();
+#ifdef _PR_USE_POLL
+    int timeout;
+    struct pollfd *pollfds;    /* an array of pollfd structures */
+    struct pollfd *pollfdPtr;    /* a pointer that steps through the array */
+    unsigned long npollfds;     /* number of pollfd structures in array */
+    unsigned long pollfds_size;
+    int nfd;                    /* to hold the return value of poll() */
+#else
+    struct timeval timeout, *tvp;
+    fd_set r, w, e;
+    fd_set *rp, *wp, *ep;
+    PRInt32 max_osfd, nfd;
+#endif  /* _PR_USE_POLL */
+    PRInt32 rv;
+    PRCList *q;
+    PRUint32 min_timeout;
+    sigset_t oldset;
+#ifdef IRIX
+extern sigset_t ints_off;
+#endif
+
+    PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
+
+    _PR_MD_IOQ_LOCK();
+
+#ifdef _PR_USE_POLL
+    /* Build up the pollfd structure array to wait on */
+
+    /* Find out how many pollfd structures are needed */
+    npollfds = _PR_IOQ_OSFD_CNT(me->cpu);
+    PR_ASSERT(npollfds >= 0);
+
+    /*
+     * We use a pipe to wake up a native thread.  An fd is needed
+     * for the pipe and we poll it for reading.
+     */
+    if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+        npollfds++;
+#ifdef	IRIX
+		/*
+		 * On Irix, a second pipe is used to cause the primordial cpu to
+		 * wakeup and exit, when the process is exiting because of a call
+		 * to exit/PR_ProcessExit.
+		 */
+		if (me->cpu->id == 0) {
+        	npollfds++;
+		}
+#endif
+	}
+
+    /*
+     * if the cpu's pollfd array is not big enough, release it and allocate a new one
+     */
+    if (npollfds > _PR_IOQ_POLLFDS_SIZE(me->cpu)) {
+        if (_PR_IOQ_POLLFDS(me->cpu) != NULL)
+            PR_DELETE(_PR_IOQ_POLLFDS(me->cpu));
+        pollfds_size =  PR_MAX(_PR_IOQ_MIN_POLLFDS_SIZE(me->cpu), npollfds);
+        pollfds = (struct pollfd *) PR_MALLOC(pollfds_size * sizeof(struct pollfd));
+        _PR_IOQ_POLLFDS(me->cpu) = pollfds;
+        _PR_IOQ_POLLFDS_SIZE(me->cpu) = pollfds_size;
+    } else {
+        pollfds = _PR_IOQ_POLLFDS(me->cpu);
+    }
+    pollfdPtr = pollfds;
+
+    /*
+     * If we need to poll the pipe for waking up a native thread,
+     * the pipe's fd is the first element in the pollfds array.
+     */
+    if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+        pollfdPtr->fd = _pr_md_pipefd[0];
+        pollfdPtr->events = POLLIN;
+        pollfdPtr++;
+#ifdef	IRIX
+		/*
+		 * On Irix, the second element is the exit pipe
+		 */
+		if (me->cpu->id == 0) {
+			pollfdPtr->fd = _pr_irix_primoridal_cpu_fd[0];
+			pollfdPtr->events = POLLIN;
+			pollfdPtr++;
+		}
+#endif
+    }
+
+    min_timeout = PR_INTERVAL_NO_TIMEOUT;
+    for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) {
+        PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+        _PRUnixPollDesc *pds = pq->pds;
+        _PRUnixPollDesc *epds = pds + pq->npds;
+
+        if (pq->timeout < min_timeout) {
+            min_timeout = pq->timeout;
+        }
+        for (; pds < epds; pds++, pollfdPtr++) {
+            /*
+         * Assert that the pollfdPtr pointer does not go
+         * beyond the end of the pollfds array
+         */
+            PR_ASSERT(pollfdPtr < pollfds + npollfds);
+            pollfdPtr->fd = pds->osfd;
+            /* direct copy of poll flags */
+            pollfdPtr->events = pds->in_flags;
+        }
+    }
+    _PR_IOQ_TIMEOUT(me->cpu) = min_timeout;
+#else
+    /*
+     * assigment of fd_sets
+     */
+    r = _PR_FD_READ_SET(me->cpu);
+    w = _PR_FD_WRITE_SET(me->cpu);
+    e = _PR_FD_EXCEPTION_SET(me->cpu);
+
+    rp = &r;
+    wp = &w;
+    ep = &e;
+
+    max_osfd = _PR_IOQ_MAX_OSFD(me->cpu) + 1;
+    min_timeout = _PR_IOQ_TIMEOUT(me->cpu);
+#endif  /* _PR_USE_POLL */
+    /*
+    ** Compute the minimum timeout value: make it the smaller of the
+    ** timeouts specified by the i/o pollers or the timeout of the first
+    ** sleeping thread.
+    */
+    q = _PR_SLEEPQ(me->cpu).next;
+
+    if (q != &_PR_SLEEPQ(me->cpu)) {
+        PRThread *t = _PR_THREAD_PTR(q);
+
+        if (t->sleep < min_timeout) {
+            min_timeout = t->sleep;
+        }
+    }
+    if (min_timeout > ticks) {
+        min_timeout = ticks;
+    }
+
+#ifdef _PR_USE_POLL
+    if (min_timeout == PR_INTERVAL_NO_TIMEOUT)
+        timeout = -1;
+    else
+        timeout = PR_IntervalToMilliseconds(min_timeout);
+#else
+    if (min_timeout == PR_INTERVAL_NO_TIMEOUT) {
+        tvp = NULL;
+    } else {
+        timeout.tv_sec = PR_IntervalToSeconds(min_timeout);
+        timeout.tv_usec = PR_IntervalToMicroseconds(min_timeout)
+            % PR_USEC_PER_SEC;
+        tvp = &timeout;
+    }
+#endif  /* _PR_USE_POLL */
+
+    _PR_MD_IOQ_UNLOCK();
+    _MD_CHECK_FOR_EXIT();
+    /*
+     * check for i/o operations
+     */
+#ifndef _PR_NO_CLOCK_TIMER
+    /*
+     * Disable the clock interrupts while we are in select, if clock interrupts
+     * are enabled. Otherwise, when the select/poll calls are interrupted, the
+     * timer value starts ticking from zero again when the system call is restarted.
+     */
+#ifdef IRIX
+    /*
+     * SIGCHLD signal is used on Irix to detect he termination of an
+     * sproc by SIGSEGV, SIGBUS or SIGABRT signals when
+     * _nspr_terminate_on_error is set.
+     */
+    if ((!_nspr_noclock) || (_nspr_terminate_on_error))
+#else
+        if (!_nspr_noclock)
+#endif    /* IRIX */
+#ifdef IRIX
+    sigprocmask(SIG_BLOCK, &ints_off, &oldset);
+#else
+    PR_ASSERT(sigismember(&timer_set, SIGALRM));
+    sigprocmask(SIG_BLOCK, &timer_set, &oldset);
+#endif    /* IRIX */
+#endif  /* !_PR_NO_CLOCK_TIMER */
+
+#ifndef _PR_USE_POLL
+    PR_ASSERT(FD_ISSET(_pr_md_pipefd[0],rp));
+    nfd = _MD_SELECT(max_osfd, rp, wp, ep, tvp);
+#else
+    nfd = _MD_POLL(pollfds, npollfds, timeout);
+#endif  /* !_PR_USE_POLL */
+
+#ifndef _PR_NO_CLOCK_TIMER
+#ifdef IRIX
+    if ((!_nspr_noclock) || (_nspr_terminate_on_error))
+#else
+        if (!_nspr_noclock)
+#endif    /* IRIX */
+    sigprocmask(SIG_SETMASK, &oldset, 0);
+#endif  /* !_PR_NO_CLOCK_TIMER */
+
+    _MD_CHECK_FOR_EXIT();
+
+#ifdef IRIX
+	_PR_MD_primordial_cpu();
+#endif
+
+    _PR_MD_IOQ_LOCK();
+    /*
+    ** Notify monitors that are associated with the selected descriptors.
+    */
+#ifdef _PR_USE_POLL
+    if (nfd > 0) {
+        pollfdPtr = pollfds;
+        if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+            /*
+			 * Assert that the pipe is the first element in the
+			 * pollfds array.
+			 */
+            PR_ASSERT(pollfds[0].fd == _pr_md_pipefd[0]);
+            if ((pollfds[0].revents & POLLIN) && (nfd == 1)) {
+                /*
+				 * woken up by another thread; read all the data
+				 * in the pipe to empty the pipe
+				 */
+                while ((rv = read(_pr_md_pipefd[0], _pr_md_pipebuf,
+                    PIPE_BUF)) == PIPE_BUF){
+                }
+                PR_ASSERT((rv > 0) || ((rv == -1) && (errno == EAGAIN)));
+            }
+            pollfdPtr++;
+#ifdef	IRIX
+			/*
+			 * On Irix, check to see if the primordial cpu needs to exit
+			 * to cause the process to terminate
+			 */
+			if (me->cpu->id == 0) {
+            	PR_ASSERT(pollfds[1].fd == _pr_irix_primoridal_cpu_fd[0]);
+				if (pollfdPtr->revents & POLLIN) {
+					if (_pr_irix_process_exit) {
+						/*
+						 * process exit due to a call to PR_ProcessExit
+						 */
+						prctl(PR_SETEXITSIG, SIGKILL);
+						_exit(_pr_irix_process_exit_code);
+					} else {
+						while ((rv = read(_pr_irix_primoridal_cpu_fd[0],
+							_pr_md_pipebuf, PIPE_BUF)) == PIPE_BUF) {
+						}
+						PR_ASSERT(rv > 0);
+					}
+				}
+				pollfdPtr++;
+			}
+#endif
+        }
+        for (q = _PR_IOQ(me->cpu).next; q != &_PR_IOQ(me->cpu); q = q->next) {
+            PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+            PRBool notify = PR_FALSE;
+            _PRUnixPollDesc *pds = pq->pds;
+            _PRUnixPollDesc *epds = pds + pq->npds;
+
+            for (; pds < epds; pds++, pollfdPtr++) {
+                /*
+                  * Assert that the pollfdPtr pointer does not go beyond
+                  * the end of the pollfds array.
+                  */
+                PR_ASSERT(pollfdPtr < pollfds + npollfds);
+                /*
+                 * Assert that the fd's in the pollfds array (stepped
+                 * through by pollfdPtr) are in the same order as
+                 * the fd's in _PR_IOQ() (stepped through by q and pds).
+                 * This is how the pollfds array was created earlier.
+                 */
+                PR_ASSERT(pollfdPtr->fd == pds->osfd);
+                pds->out_flags = pollfdPtr->revents;
+                /* Negative fd's are ignored by poll() */
+                if (pds->osfd >= 0 && pds->out_flags) {
+                    notify = PR_TRUE;
+                }
+            }
+            if (notify) {
+                PRIntn pri;
+                PRThread *thred;
+
+                PR_REMOVE_LINK(&pq->links);
+                pq->on_ioq = PR_FALSE;
+
+                thred = pq->thr;
+                _PR_THREAD_LOCK(thred);
+                if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
+                    _PRCPU *cpu = pq->thr->cpu;
+                    _PR_SLEEPQ_LOCK(pq->thr->cpu);
+                    _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);
+                    _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
+
+					if (pq->thr->flags & _PR_SUSPENDING) {
+					    /*
+					     * set thread state to SUSPENDED;
+					     * a Resume operation on the thread
+					     * will move it to the runQ
+					     */
+					    pq->thr->state = _PR_SUSPENDED;
+					    _PR_MISCQ_LOCK(pq->thr->cpu);
+					    _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu);
+					    _PR_MISCQ_UNLOCK(pq->thr->cpu);
+					} else {
+						pri = pq->thr->priority;
+						pq->thr->state = _PR_RUNNABLE;
+
+						_PR_RUNQ_LOCK(cpu);
+						_PR_ADD_RUNQ(pq->thr, cpu, pri);
+						_PR_RUNQ_UNLOCK(cpu);
+						if (_pr_md_idle_cpus > 1)
+							_PR_MD_WAKEUP_WAITER(thred);
+					}
+                }
+                _PR_THREAD_UNLOCK(thred);
+                _PR_IOQ_OSFD_CNT(me->cpu) -= pq->npds;
+                PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0);
+            }
+        }
+    } else if (nfd == -1) {
+        PR_LOG(_pr_io_lm, PR_LOG_MAX, ("poll() failed with errno %d", errno));
+    }
+
+#else
+    if (nfd > 0) {
+        q = _PR_IOQ(me->cpu).next;
+        _PR_IOQ_MAX_OSFD(me->cpu) = -1;
+        _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT;
+        while (q != &_PR_IOQ(me->cpu)) {
+            PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+            PRBool notify = PR_FALSE;
+            _PRUnixPollDesc *pds = pq->pds;
+            _PRUnixPollDesc *epds = pds + pq->npds;
+            PRInt32 pq_max_osfd = -1;
+
+            q = q->next;
+            for (; pds < epds; pds++) {
+                PRInt32 osfd = pds->osfd;
+                PRInt16 in_flags = pds->in_flags;
+                PRInt16 out_flags = 0;
+                PR_ASSERT(osfd >= 0 || in_flags == 0);
+                if ((in_flags & _PR_UNIX_POLL_READ) && FD_ISSET(osfd, rp)) {
+                    out_flags |= _PR_UNIX_POLL_READ;
+                }
+                if ((in_flags & _PR_UNIX_POLL_WRITE) && FD_ISSET(osfd, wp)) {
+                    out_flags |= _PR_UNIX_POLL_WRITE;
+                }
+                if ((in_flags & _PR_UNIX_POLL_EXCEPT) && FD_ISSET(osfd, ep)) {
+                    out_flags |= _PR_UNIX_POLL_EXCEPT;
+                }
+                pds->out_flags = out_flags;
+                if (out_flags) {
+                    notify = PR_TRUE;
+                }
+                if (osfd > pq_max_osfd) {
+                    pq_max_osfd = osfd;
+                }
+            }
+            if (notify == PR_TRUE) {
+                PRIntn pri;
+                PRThread *thred;
+
+                PR_REMOVE_LINK(&pq->links);
+                pq->on_ioq = PR_FALSE;
+
+                /*
+                 * Decrement the count of descriptors for each desciptor/event
+                 * because this I/O request is being removed from the
+                 * ioq
+                 */
+                pds = pq->pds;
+                for (; pds < epds; pds++) {
+                    PRInt32 osfd = pds->osfd;
+                    PRInt16 in_flags = pds->in_flags;
+                    PR_ASSERT(osfd >= 0 || in_flags == 0);
+                    if (in_flags & _PR_UNIX_POLL_READ) {
+                        if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
+                            FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
+                    }
+                    if (in_flags & _PR_UNIX_POLL_WRITE) {
+                        if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
+                            FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
+                    }
+                    if (in_flags & _PR_UNIX_POLL_EXCEPT) {
+                        if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
+                            FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+                    }
+                }
+
+                /*
+                 * Because this thread can run on a different cpu right
+                 * after being added to the run queue, do not dereference
+                 * pq
+                 */
+                 thred = pq->thr;
+                _PR_THREAD_LOCK(thred);
+                if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
+                    _PRCPU *cpu = thred->cpu;
+                    _PR_SLEEPQ_LOCK(pq->thr->cpu);
+                    _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);
+                    _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
+
+					if (pq->thr->flags & _PR_SUSPENDING) {
+					    /*
+					     * set thread state to SUSPENDED;
+					     * a Resume operation on the thread
+					     * will move it to the runQ
+					     */
+					    pq->thr->state = _PR_SUSPENDED;
+					    _PR_MISCQ_LOCK(pq->thr->cpu);
+					    _PR_ADD_SUSPENDQ(pq->thr, pq->thr->cpu);
+					    _PR_MISCQ_UNLOCK(pq->thr->cpu);
+					} else {
+						pri = pq->thr->priority;
+						pq->thr->state = _PR_RUNNABLE;
+
+						pq->thr->cpu = cpu;
+						_PR_RUNQ_LOCK(cpu);
+						_PR_ADD_RUNQ(pq->thr, cpu, pri);
+						_PR_RUNQ_UNLOCK(cpu);
+						if (_pr_md_idle_cpus > 1)
+							_PR_MD_WAKEUP_WAITER(thred);
+					}
+                }
+                _PR_THREAD_UNLOCK(thred);
+            } else {
+                if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))
+                    _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;
+                if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)
+                    _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;
+            }
+        }
+        if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+            if ((FD_ISSET(_pr_md_pipefd[0], rp)) && (nfd == 1)) {
+                /*
+             * woken up by another thread; read all the data
+             * in the pipe to empty the pipe
+             */
+                while ((rv =
+                    read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF))
+                    == PIPE_BUF){
+                }
+                PR_ASSERT((rv > 0) ||
+                    ((rv == -1) && (errno == EAGAIN)));
+            }
+            if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0])
+                _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
+#ifdef	IRIX
+			if ((me->cpu->id == 0) && 
+						(FD_ISSET(_pr_irix_primoridal_cpu_fd[0], rp))) {
+				if (_pr_irix_process_exit) {
+					/*
+					 * process exit due to a call to PR_ProcessExit
+					 */
+					prctl(PR_SETEXITSIG, SIGKILL);
+					_exit(_pr_irix_process_exit_code);
+				} else {
+						while ((rv = read(_pr_irix_primoridal_cpu_fd[0],
+							_pr_md_pipebuf, PIPE_BUF)) == PIPE_BUF) {
+						}
+						PR_ASSERT(rv > 0);
+				}
+			}
+			if (me->cpu->id == 0) {
+				if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_irix_primoridal_cpu_fd[0])
+					_PR_IOQ_MAX_OSFD(me->cpu) = _pr_irix_primoridal_cpu_fd[0];
+			}
+#endif
+        }
+    } else if (nfd < 0) {
+        if (errno == EBADF) {
+            FindBadFDs();
+        } else {
+            PR_LOG(_pr_io_lm, PR_LOG_MAX, ("select() failed with errno %d",
+                errno));
+        }
+    } else {
+        PR_ASSERT(nfd == 0);
+        /*
+         * compute the new value of _PR_IOQ_TIMEOUT
+         */
+        q = _PR_IOQ(me->cpu).next;
+        _PR_IOQ_MAX_OSFD(me->cpu) = -1;
+        _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT;
+        while (q != &_PR_IOQ(me->cpu)) {
+            PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+            _PRUnixPollDesc *pds = pq->pds;
+            _PRUnixPollDesc *epds = pds + pq->npds;
+            PRInt32 pq_max_osfd = -1;
+
+            q = q->next;
+            for (; pds < epds; pds++) {
+                if (pds->osfd > pq_max_osfd) {
+                    pq_max_osfd = pds->osfd;
+                }
+            }
+            if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))
+                _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;
+            if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)
+                _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;
+        }
+        if (_PR_IS_NATIVE_THREAD_SUPPORTED()) {
+            if (_PR_IOQ_MAX_OSFD(me->cpu) < _pr_md_pipefd[0])
+                _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
+        }
+    }
+#endif  /* _PR_USE_POLL */
+    _PR_MD_IOQ_UNLOCK();
+}
+
+void _MD_Wakeup_CPUs()
+{
+    PRInt32 rv, data;
+
+    data = 0;
+    rv = write(_pr_md_pipefd[1], &data, 1);
+
+    while ((rv < 0) && (errno == EAGAIN)) {
+        /*
+         * pipe full, read all data in pipe to empty it
+         */
+        while ((rv =
+            read(_pr_md_pipefd[0], _pr_md_pipebuf, PIPE_BUF))
+            == PIPE_BUF) {
+        }
+        PR_ASSERT((rv > 0) ||
+            ((rv == -1) && (errno == EAGAIN)));
+        rv = write(_pr_md_pipefd[1], &data, 1);
+    }
+}
+
+
+void _MD_InitCPUS()
+{
+    PRInt32 rv, flags;
+    PRThread *me = _MD_CURRENT_THREAD();
+
+    rv = pipe(_pr_md_pipefd);
+    PR_ASSERT(rv == 0);
+    _PR_IOQ_MAX_OSFD(me->cpu) = _pr_md_pipefd[0];
+#ifndef _PR_USE_POLL
+    FD_SET(_pr_md_pipefd[0], &_PR_FD_READ_SET(me->cpu));
+#endif
+
+    flags = fcntl(_pr_md_pipefd[0], F_GETFL, 0);
+    fcntl(_pr_md_pipefd[0], F_SETFL, flags | O_NONBLOCK);
+    flags = fcntl(_pr_md_pipefd[1], F_GETFL, 0);
+    fcntl(_pr_md_pipefd[1], F_SETFL, flags | O_NONBLOCK);
+}
+
+/*
+** Unix SIGALRM (clock) signal handler
+*/
+static void ClockInterruptHandler()
+{
+    int olderrno;
+    PRUintn pri;
+    _PRCPU *cpu = _PR_MD_CURRENT_CPU();
+    PRThread *me = _MD_CURRENT_THREAD();
+
+#ifdef SOLARIS
+    if (!me || _PR_IS_NATIVE_THREAD(me)) {
+        _pr_primordialCPU->u.missed[_pr_primordialCPU->where] |= _PR_MISSED_CLOCK;
+        return;
+    }
+#endif
+
+    if (_PR_MD_GET_INTSOFF() != 0) {
+        cpu->u.missed[cpu->where] |= _PR_MISSED_CLOCK;
+        return;
+    }
+    _PR_MD_SET_INTSOFF(1);
+
+    olderrno = errno;
+    _PR_ClockInterrupt();
+    errno = olderrno;
+
+    /*
+    ** If the interrupt wants a resched or if some other thread at
+    ** the same priority needs the cpu, reschedule.
+    */
+    pri = me->priority;
+    if ((cpu->u.missed[3] || (_PR_RUNQREADYMASK(me->cpu) >> pri))) {
+#ifdef _PR_NO_PREEMPT
+        cpu->resched = PR_TRUE;
+        if (pr_interruptSwitchHook) {
+            (*pr_interruptSwitchHook)(pr_interruptSwitchHookArg);
+        }
+#else /* _PR_NO_PREEMPT */
+        /*
+    ** Re-enable unix interrupts (so that we can use
+    ** setjmp/longjmp for context switching without having to
+    ** worry about the signal state)
+    */
+        sigprocmask(SIG_SETMASK, &empty_set, 0);
+        PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock caused context switch"));
+
+        if(!(me->flags & _PR_IDLE_THREAD)) {
+            _PR_THREAD_LOCK(me);
+            me->state = _PR_RUNNABLE;
+            me->cpu = cpu;
+            _PR_RUNQ_LOCK(cpu);
+            _PR_ADD_RUNQ(me, cpu, pri);
+            _PR_RUNQ_UNLOCK(cpu);
+            _PR_THREAD_UNLOCK(me);
+        } else
+            me->state = _PR_RUNNABLE;
+        _MD_SWITCH_CONTEXT(me);
+        PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("clock back from context switch"));
+#endif /* _PR_NO_PREEMPT */
+    }
+    /*
+     * Because this thread could be running on a different cpu after
+     * a context switch the current cpu should be accessed and the
+     * value of the 'cpu' variable should not be used.
+     */
+    _PR_MD_SET_INTSOFF(0);
+}
+
+/*
+ * On HP-UX 9, we have to use the sigvector() interface to restart
+ * interrupted system calls, because sigaction() does not have the
+ * SA_RESTART flag.
+ */
+
+#ifdef HPUX9
+static void HPUX9_ClockInterruptHandler(
+    int sig,
+    int code,
+    struct sigcontext *scp)
+{
+    ClockInterruptHandler();
+    scp->sc_syscall_action = SIG_RESTART;
+}
+#endif /* HPUX9 */
+
+/* # of milliseconds per clock tick that we will use */
+#define MSEC_PER_TICK    50
+
+
+void _MD_StartInterrupts()
+{
+    char *eval;
+
+    if ((eval = getenv("NSPR_NOCLOCK")) != NULL) {
+        if (atoi(eval) == 0)
+            _nspr_noclock = 0;
+        else
+            _nspr_noclock = 1;
+    }
+
+#ifndef _PR_NO_CLOCK_TIMER
+    if (!_nspr_noclock) {
+        _MD_EnableClockInterrupts();
+    }
+#endif
+}
+
+void _MD_StopInterrupts()
+{
+    sigprocmask(SIG_BLOCK, &timer_set, 0);
+}
+
+void _MD_EnableClockInterrupts()
+{
+    struct itimerval itval;
+    extern PRUintn _pr_numCPU;
+#ifdef HPUX9
+    struct sigvec vec;
+
+    vec.sv_handler = (void (*)()) HPUX9_ClockInterruptHandler;
+    vec.sv_mask = 0;
+    vec.sv_flags = 0;
+    sigvector(SIGALRM, &vec, 0);
+#else
+    struct sigaction vtact;
+
+    vtact.sa_handler = (void (*)()) ClockInterruptHandler;
+    sigemptyset(&vtact.sa_mask);
+    vtact.sa_flags = SA_RESTART;
+    sigaction(SIGALRM, &vtact, 0);
+#endif /* HPUX9 */
+
+    PR_ASSERT(_pr_numCPU == 1);
+	itval.it_interval.tv_sec = 0;
+	itval.it_interval.tv_usec = MSEC_PER_TICK * PR_USEC_PER_MSEC;
+	itval.it_value = itval.it_interval;
+	setitimer(ITIMER_REAL, &itval, 0);
+}
+
+void _MD_DisableClockInterrupts()
+{
+    struct itimerval itval;
+    extern PRUintn _pr_numCPU;
+
+    PR_ASSERT(_pr_numCPU == 1);
+	itval.it_interval.tv_sec = 0;
+	itval.it_interval.tv_usec = 0;
+	itval.it_value = itval.it_interval;
+	setitimer(ITIMER_REAL, &itval, 0);
+}
+
+void _MD_BlockClockInterrupts()
+{
+    sigprocmask(SIG_BLOCK, &timer_set, 0);
+}
+
+void _MD_UnblockClockInterrupts()
+{
+    sigprocmask(SIG_UNBLOCK, &timer_set, 0);
+}
+
+void _MD_MakeNonblock(PRFileDesc *fd)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    int flags;
+
+    if (osfd <= 2) {
+        /* Don't mess around with stdin, stdout or stderr */
+        return;
+    }
+    flags = fcntl(osfd, F_GETFL, 0);
+
+    /*
+     * Use O_NONBLOCK (POSIX-style non-blocking I/O) whenever possible.
+     * On SunOS 4, we must use FNDELAY (BSD-style non-blocking I/O),
+     * otherwise connect() still blocks and can be interrupted by SIGALRM.
+     */
+
+#ifdef SUNOS4
+    fcntl(osfd, F_SETFL, flags | FNDELAY);
+#else
+    fcntl(osfd, F_SETFL, flags | O_NONBLOCK);
+#endif
+    }
+
+PRInt32 _MD_open(const char *name, PRIntn flags, PRIntn mode)
+{
+    PRInt32 osflags;
+    PRInt32 rv, err;
+
+    if (flags & PR_RDWR) {
+        osflags = O_RDWR;
+    } else if (flags & PR_WRONLY) {
+        osflags = O_WRONLY;
+    } else {
+        osflags = O_RDONLY;
+    }
+
+    if (flags & PR_EXCL)
+        osflags |= O_EXCL;
+    if (flags & PR_APPEND)
+        osflags |= O_APPEND;
+    if (flags & PR_TRUNCATE)
+        osflags |= O_TRUNC;
+    if (flags & PR_SYNC) {
+#if defined(O_SYNC)
+        osflags |= O_SYNC;
+#elif defined(O_FSYNC)
+        osflags |= O_FSYNC;
+#else
+#error "Neither O_SYNC nor O_FSYNC is defined on this platform"
+#endif
+    }
+
+    /*
+    ** On creations we hold the 'create' lock in order to enforce
+    ** the semantics of PR_Rename. (see the latter for more details)
+    */
+    if (flags & PR_CREATE_FILE)
+    {
+        osflags |= O_CREAT;
+        if (NULL !=_pr_rename_lock)
+            PR_Lock(_pr_rename_lock);
+    }
+
+    rv = _md_iovector._open64(name, osflags, mode);
+
+    if (rv < 0) {
+        err = _MD_ERRNO();
+        _PR_MD_MAP_OPEN_ERROR(err);
+    }
+
+    if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock))
+        PR_Unlock(_pr_rename_lock);
+    return rv;
+}
+
+PRIntervalTime intr_timeout_ticks;
+
+#if defined(SOLARIS) || defined(IRIX)
+static void sigsegvhandler() {
+    fprintf(stderr,"Received SIGSEGV\n");
+    fflush(stderr);
+    pause();
+}
+
+static void sigaborthandler() {
+    fprintf(stderr,"Received SIGABRT\n");
+    fflush(stderr);
+    pause();
+}
+
+static void sigbushandler() {
+    fprintf(stderr,"Received SIGBUS\n");
+    fflush(stderr);
+    pause();
+}
+#endif /* SOLARIS, IRIX */
+
+#endif  /* !defined(_PR_PTHREADS) */
+
+void _MD_query_fd_inheritable(PRFileDesc *fd)
+{
+    int flags;
+
+    PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
+    flags = fcntl(fd->secret->md.osfd, F_GETFD, 0);
+    PR_ASSERT(-1 != flags);
+    fd->secret->inheritable = (flags & FD_CLOEXEC) ?
+        _PR_TRI_FALSE : _PR_TRI_TRUE;
+}
+
+PROffset32 _MD_lseek(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
+{
+    PROffset32 rv, where;
+
+    switch (whence) {
+        case PR_SEEK_SET:
+            where = SEEK_SET;
+            break;
+        case PR_SEEK_CUR:
+            where = SEEK_CUR;
+            break;
+        case PR_SEEK_END:
+            where = SEEK_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            rv = -1;
+            goto done;
+    }
+    rv = lseek(fd->secret->md.osfd,offset,where);
+    if (rv == -1)
+    {
+        PRInt32 syserr = _MD_ERRNO();
+        _PR_MD_MAP_LSEEK_ERROR(syserr);
+    }
+done:
+    return(rv);
+}
+
+PROffset64 _MD_lseek64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence)
+{
+    PRInt32 where;
+    PROffset64 rv;
+
+    switch (whence)
+    {
+        case PR_SEEK_SET:
+            where = SEEK_SET;
+            break;
+        case PR_SEEK_CUR:
+            where = SEEK_CUR;
+            break;
+        case PR_SEEK_END:
+            where = SEEK_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            rv = minus_one;
+            goto done;
+    }
+    rv = _md_iovector._lseek64(fd->secret->md.osfd, offset, where);
+    if (LL_EQ(rv, minus_one))
+    {
+        PRInt32 syserr = _MD_ERRNO();
+        _PR_MD_MAP_LSEEK_ERROR(syserr);
+    }
+done:
+    return rv;
+}  /* _MD_lseek64 */
+
+/*
+** _MD_set_fileinfo_times --
+**     Set the modifyTime and creationTime of the PRFileInfo
+**     structure using the values in struct stat.
+**
+** _MD_set_fileinfo64_times --
+**     Set the modifyTime and creationTime of the PRFileInfo64
+**     structure using the values in _MDStat64.
+*/
+
+#if defined(_PR_STAT_HAS_ST_ATIM)
+/*
+** struct stat has st_atim, st_mtim, and st_ctim fields of
+** type timestruc_t.
+*/
+static void _MD_set_fileinfo_times(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtim.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtim.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctim.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctim.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+
+static void _MD_set_fileinfo64_times(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtim.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtim.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctim.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctim.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+#elif defined(_PR_STAT_HAS_ST_ATIM_UNION)
+/*
+** The st_atim, st_mtim, and st_ctim fields in struct stat are
+** unions with a st__tim union member of type timestruc_t.
+*/
+static void _MD_set_fileinfo_times(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtim.st__tim.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtim.st__tim.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctim.st__tim.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctim.st__tim.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+
+static void _MD_set_fileinfo64_times(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtim.st__tim.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtim.st__tim.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctim.st__tim.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctim.st__tim.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+#elif defined(_PR_STAT_HAS_ST_ATIMESPEC)
+/*
+** struct stat has st_atimespec, st_mtimespec, and st_ctimespec
+** fields of type struct timespec.
+*/
+#if defined(_PR_TIMESPEC_HAS_TS_SEC)
+static void _MD_set_fileinfo_times(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtimespec.ts_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtimespec.ts_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctimespec.ts_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctimespec.ts_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+
+static void _MD_set_fileinfo64_times(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtimespec.ts_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtimespec.ts_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctimespec.ts_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctimespec.ts_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+#else /* _PR_TIMESPEC_HAS_TS_SEC */
+/*
+** The POSIX timespec structure has tv_sec and tv_nsec.
+*/
+static void _MD_set_fileinfo_times(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtimespec.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtimespec.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctimespec.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctimespec.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+
+static void _MD_set_fileinfo64_times(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    PRInt64 us, s2us;
+
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(info->modifyTime, sb->st_mtimespec.tv_sec);
+    LL_MUL(info->modifyTime, info->modifyTime, s2us);
+    LL_I2L(us, sb->st_mtimespec.tv_nsec / 1000);
+    LL_ADD(info->modifyTime, info->modifyTime, us);
+    LL_I2L(info->creationTime, sb->st_ctimespec.tv_sec);
+    LL_MUL(info->creationTime, info->creationTime, s2us);
+    LL_I2L(us, sb->st_ctimespec.tv_nsec / 1000);
+    LL_ADD(info->creationTime, info->creationTime, us);
+}
+#endif /* _PR_TIMESPEC_HAS_TS_SEC */
+#elif defined(_PR_STAT_HAS_ONLY_ST_ATIME)
+/*
+** struct stat only has st_atime, st_mtime, and st_ctime fields
+** of type time_t.
+*/
+static void _MD_set_fileinfo_times(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    PRInt64 s, s2us;
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(s, sb->st_mtime);
+    LL_MUL(s, s, s2us);
+    info->modifyTime = s;
+    LL_I2L(s, sb->st_ctime);
+    LL_MUL(s, s, s2us);
+    info->creationTime = s;
+}
+
+static void _MD_set_fileinfo64_times(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    PRInt64 s, s2us;
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(s, sb->st_mtime);
+    LL_MUL(s, s, s2us);
+    info->modifyTime = s;
+    LL_I2L(s, sb->st_ctime);
+    LL_MUL(s, s, s2us);
+    info->creationTime = s;
+}
+#else
+#error "I don't know yet"
+#endif
+
+static int _MD_convert_stat_to_fileinfo(
+    const struct stat *sb,
+    PRFileInfo *info)
+{
+    if (S_IFREG & sb->st_mode)
+        info->type = PR_FILE_FILE;
+    else if (S_IFDIR & sb->st_mode)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_OTHER;
+
+#if defined(_PR_HAVE_LARGE_OFF_T)
+    if (0x7fffffffL < sb->st_size)
+    {
+        PR_SetError(PR_FILE_TOO_BIG_ERROR, 0);
+        return -1;
+    }
+#endif /* defined(_PR_HAVE_LARGE_OFF_T) */
+    info->size = sb->st_size;
+
+    _MD_set_fileinfo_times(sb, info);
+    return 0;
+}  /* _MD_convert_stat_to_fileinfo */
+
+static int _MD_convert_stat64_to_fileinfo64(
+    const _MDStat64 *sb,
+    PRFileInfo64 *info)
+{
+    if (S_IFREG & sb->st_mode)
+        info->type = PR_FILE_FILE;
+    else if (S_IFDIR & sb->st_mode)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_OTHER;
+
+    LL_I2L(info->size, sb->st_size);
+
+    _MD_set_fileinfo64_times(sb, info);
+    return 0;
+}  /* _MD_convert_stat64_to_fileinfo64 */
+
+PRInt32 _MD_getfileinfo(const char *fn, PRFileInfo *info)
+{
+    PRInt32 rv;
+    struct stat sb;
+
+    rv = stat(fn, &sb);
+    if (rv < 0)
+        _PR_MD_MAP_STAT_ERROR(_MD_ERRNO());
+    else if (NULL != info)
+        rv = _MD_convert_stat_to_fileinfo(&sb, info);
+    return rv;
+}
+
+PRInt32 _MD_getfileinfo64(const char *fn, PRFileInfo64 *info)
+{
+    _MDStat64 sb;
+    PRInt32 rv = _md_iovector._stat64(fn, &sb);
+    if (rv < 0)
+        _PR_MD_MAP_STAT_ERROR(_MD_ERRNO());
+    else if (NULL != info)
+        rv = _MD_convert_stat64_to_fileinfo64(&sb, info);
+    return rv;
+}
+
+PRInt32 _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info)
+{
+    struct stat sb;
+    PRInt32 rv = fstat(fd->secret->md.osfd, &sb);
+    if (rv < 0)
+        _PR_MD_MAP_FSTAT_ERROR(_MD_ERRNO());
+    else if (NULL != info)
+        rv = _MD_convert_stat_to_fileinfo(&sb, info);
+    return rv;
+}
+
+PRInt32 _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info)
+{
+    _MDStat64 sb;
+    PRInt32 rv = _md_iovector._fstat64(fd->secret->md.osfd, &sb);
+    if (rv < 0)
+        _PR_MD_MAP_FSTAT_ERROR(_MD_ERRNO());
+    else if (NULL != info)
+        rv = _MD_convert_stat64_to_fileinfo64(&sb, info);
+    return rv;
+}
+
+struct _MD_IOVector _md_iovector = { open };
+
+/*
+** These implementations are to emulate large file routines on systems that
+** don't have them. Their goal is to check in case overflow occurs. Otherwise
+** they will just operate as normal using 32-bit file routines.
+**
+** The checking might be pre- or post-op, depending on the semantics.
+*/
+
+#if defined(SOLARIS2_5)
+
+static PRIntn _MD_solaris25_fstat64(PRIntn osfd, _MDStat64 *buf)
+{
+    PRInt32 rv;
+    struct stat sb;
+
+    rv = fstat(osfd, &sb);
+    if (rv >= 0)
+    {
+        /*
+        ** I'm only copying the fields that are immediately needed.
+        ** If somebody else calls this function, some of the fields
+        ** may not be defined.
+        */
+        (void)memset(buf, 0, sizeof(_MDStat64));
+        buf->st_mode = sb.st_mode;
+        buf->st_ctim = sb.st_ctim;
+        buf->st_mtim = sb.st_mtim;
+        buf->st_size = sb.st_size;
+    }
+    return rv;
+}  /* _MD_solaris25_fstat64 */
+
+static PRIntn _MD_solaris25_stat64(const char *fn, _MDStat64 *buf)
+{
+    PRInt32 rv;
+    struct stat sb;
+
+    rv = stat(fn, &sb);
+    if (rv >= 0)
+    {
+        /*
+        ** I'm only copying the fields that are immediately needed.
+        ** If somebody else calls this function, some of the fields
+        ** may not be defined.
+        */
+        (void)memset(buf, 0, sizeof(_MDStat64));
+        buf->st_mode = sb.st_mode;
+        buf->st_ctim = sb.st_ctim;
+        buf->st_mtim = sb.st_mtim;
+        buf->st_size = sb.st_size;
+    }
+    return rv;
+}  /* _MD_solaris25_stat64 */
+#endif /* defined(SOLARIS2_5) */
+
+#if defined(_PR_NO_LARGE_FILES) || defined(SOLARIS2_5)
+
+static PROffset64 _MD_Unix_lseek64(PRIntn osfd, PROffset64 offset, PRIntn whence)
+{
+    PRUint64 maxoff;
+    PROffset64 rv = minus_one;
+    LL_I2L(maxoff, 0x7fffffff);
+    if (LL_CMP(offset, <=, maxoff))
+    {
+        off_t off;
+        LL_L2I(off, offset);
+        LL_I2L(rv, lseek(osfd, off, whence));
+    }
+    else errno = EFBIG;  /* we can't go there */
+    return rv;
+}  /* _MD_Unix_lseek64 */
+
+static void* _MD_Unix_mmap64(
+    void *addr, PRSize len, PRIntn prot, PRIntn flags,
+    PRIntn fildes, PRInt64 offset)
+{
+    PR_SetError(PR_FILE_TOO_BIG_ERROR, 0);
+    return NULL;
+}  /* _MD_Unix_mmap64 */
+#endif /* defined(_PR_NO_LARGE_FILES) || defined(SOLARIS2_5) */
+
+#if defined(OSF1) && defined(__GNUC__)
+
+/*
+ * On OSF1 V5.0A, <sys/stat.h> defines stat and fstat as
+ * macros when compiled under gcc, so it is rather tricky to
+ * take the addresses of the real functions the macros expend
+ * to.  A simple solution is to define forwarder functions
+ * and take the addresses of the forwarder functions instead.
+ */
+
+static int stat_forwarder(const char *path, struct stat *buffer)
+{
+    return stat(path, buffer);
+}
+
+static int fstat_forwarder(int filedes, struct stat *buffer)
+{
+    return fstat(filedes, buffer);
+}
+
+#endif
+
+static void _PR_InitIOV(void)
+{
+#if defined(SOLARIS2_5)
+    PRLibrary *lib;
+    void *open64_func;
+
+    open64_func = PR_FindSymbolAndLibrary("open64", &lib);
+    if (NULL != open64_func)
+    {
+        PR_ASSERT(NULL != lib);
+        _md_iovector._open64 = (_MD_Open64)open64_func;
+        _md_iovector._mmap64 = (_MD_Mmap64)PR_FindSymbol(lib, "mmap64");
+        _md_iovector._fstat64 = (_MD_Fstat64)PR_FindSymbol(lib, "fstat64");
+        _md_iovector._stat64 = (_MD_Stat64)PR_FindSymbol(lib, "stat64");
+        _md_iovector._lseek64 = (_MD_Lseek64)PR_FindSymbol(lib, "lseek64");
+        (void)PR_UnloadLibrary(lib);
+    }
+    else
+    {
+        _md_iovector._open64 = open;
+        _md_iovector._mmap64 = _MD_Unix_mmap64;
+        _md_iovector._fstat64 = _MD_solaris25_fstat64;
+        _md_iovector._stat64 = _MD_solaris25_stat64;
+        _md_iovector._lseek64 = _MD_Unix_lseek64;
+    }
+#elif defined(_PR_NO_LARGE_FILES)
+    _md_iovector._open64 = open;
+    _md_iovector._mmap64 = _MD_Unix_mmap64;
+    _md_iovector._fstat64 = fstat;
+    _md_iovector._stat64 = stat;
+    _md_iovector._lseek64 = _MD_Unix_lseek64;
+#elif defined(_PR_HAVE_OFF64_T)
+#if defined(IRIX5_3)
+    _md_iovector._open64 = open;
+#else
+    _md_iovector._open64 = open64;
+#endif
+    _md_iovector._mmap64 = mmap64;
+    _md_iovector._fstat64 = fstat64;
+    _md_iovector._stat64 = stat64;
+    _md_iovector._lseek64 = lseek64;
+#elif defined(_PR_HAVE_LARGE_OFF_T)
+    _md_iovector._open64 = open;
+    _md_iovector._mmap64 = mmap;
+#if defined(OSF1) && defined(__GNUC__)
+    _md_iovector._fstat64 = fstat_forwarder;
+    _md_iovector._stat64 = stat_forwarder;
+#else
+    _md_iovector._fstat64 = fstat;
+    _md_iovector._stat64 = stat;
+#endif
+    _md_iovector._lseek64 = lseek;
+#else
+#error "I don't know yet"
+#endif
+    LL_I2L(minus_one, -1);
+}  /* _PR_InitIOV */
+
+void _PR_UnixInit(void)
+{
+    struct sigaction sigact;
+    int rv;
+
+    sigemptyset(&timer_set);
+
+#if !defined(_PR_PTHREADS)
+
+    sigaddset(&timer_set, SIGALRM);
+    sigemptyset(&empty_set);
+    intr_timeout_ticks =
+            PR_SecondsToInterval(_PR_INTERRUPT_CHECK_INTERVAL_SECS);
+
+#if defined(SOLARIS) || defined(IRIX)
+
+    if (getenv("NSPR_SIGSEGV_HANDLE")) {
+        sigact.sa_handler = sigsegvhandler;
+        sigact.sa_flags = 0;
+        sigact.sa_mask = timer_set;
+        sigaction(SIGSEGV, &sigact, 0);
+    }
+
+    if (getenv("NSPR_SIGABRT_HANDLE")) {
+        sigact.sa_handler = sigaborthandler;
+        sigact.sa_flags = 0;
+        sigact.sa_mask = timer_set;
+        sigaction(SIGABRT, &sigact, 0);
+    }
+
+    if (getenv("NSPR_SIGBUS_HANDLE")) {
+        sigact.sa_handler = sigbushandler;
+        sigact.sa_flags = 0;
+        sigact.sa_mask = timer_set;
+        sigaction(SIGBUS, &sigact, 0);
+    }
+
+#endif
+#endif  /* !defined(_PR_PTHREADS) */
+
+    /*
+     * Under HP-UX DCE threads, sigaction() installs a per-thread
+     * handler, so we use sigvector() to install a process-wide
+     * handler.
+     */
+#if defined(HPUX) && defined(_PR_DCETHREADS)
+    {
+        struct sigvec vec;
+
+        vec.sv_handler = SIG_IGN;
+        vec.sv_mask = 0;
+        vec.sv_flags = 0;
+        rv = sigvector(SIGPIPE, &vec, NULL);
+        PR_ASSERT(0 == rv);
+    }
+#else
+    sigact.sa_handler = SIG_IGN;
+    sigemptyset(&sigact.sa_mask);
+    sigact.sa_flags = 0;
+    rv = sigaction(SIGPIPE, &sigact, 0);
+    PR_ASSERT(0 == rv);
+#endif /* HPUX && _PR_DCETHREADS */
+
+    _pr_rename_lock = PR_NewLock();
+    PR_ASSERT(NULL != _pr_rename_lock);
+    _pr_Xfe_mon = PR_NewMonitor();
+    PR_ASSERT(NULL != _pr_Xfe_mon);
+
+    _PR_InitIOV();  /* one last hack */
+}
+
+#if !defined(_PR_PTHREADS)
+
+/*
+ * Variables used by the GC code, initialized in _MD_InitSegs().
+ */
+static PRInt32 _pr_zero_fd = -1;
+static PRLock *_pr_md_lock = NULL;
+
+/*
+ * _MD_InitSegs --
+ *
+ * This is Unix's version of _PR_MD_INIT_SEGS(), which is
+ * called by _PR_InitSegs(), which in turn is called by
+ * PR_Init().
+ */
+void _MD_InitSegs(void)
+{
+#ifdef DEBUG
+    /*
+    ** Disable using mmap(2) if NSPR_NO_MMAP is set
+    */
+    if (getenv("NSPR_NO_MMAP")) {
+        _pr_zero_fd = -2;
+        return;
+    }
+#endif
+    _pr_zero_fd = open("/dev/zero",O_RDWR , 0);
+    /* Prevent the fd from being inherited by child processes */
+    fcntl(_pr_zero_fd, F_SETFD, FD_CLOEXEC);
+    _pr_md_lock = PR_NewLock();
+}
+
+PRStatus _MD_AllocSegment(PRSegment *seg, PRUint32 size, void *vaddr)
+{
+    static char *lastaddr = (char*) _PR_STACK_VMBASE;
+    PRStatus retval = PR_SUCCESS;
+    int prot;
+    void *rv;
+
+    PR_ASSERT(seg != 0);
+    PR_ASSERT(size != 0);
+
+    PR_Lock(_pr_md_lock);
+    if (_pr_zero_fd < 0) {
+from_heap:
+        seg->vaddr = PR_MALLOC(size);
+        if (!seg->vaddr) {
+            retval = PR_FAILURE;
+        }
+        else {
+            seg->size = size;
+        }
+        goto exit;
+    }
+
+    prot = PROT_READ|PROT_WRITE;
+    /*
+     * On Alpha Linux, the user-level thread stack needs
+     * to be made executable because longjmp/signal seem
+     * to put machine instructions on the stack.
+     */
+#if defined(LINUX) && defined(__alpha)
+    prot |= PROT_EXEC;
+#endif
+    rv = mmap((vaddr != 0) ? vaddr : lastaddr, size, prot,
+        _MD_MMAP_FLAGS,
+        _pr_zero_fd, 0);
+    if (rv == (void*)-1) {
+        goto from_heap;
+    }
+    lastaddr += size;
+    seg->vaddr = rv;
+    seg->size = size;
+    seg->flags = _PR_SEG_VM;
+
+exit:
+    PR_Unlock(_pr_md_lock);
+    return retval;
+}
+
+void _MD_FreeSegment(PRSegment *seg)
+{
+    if (seg->flags & _PR_SEG_VM)
+        (void) munmap(seg->vaddr, seg->size);
+    else
+        PR_DELETE(seg->vaddr);
+}
+
+#endif /* _PR_PTHREADS */
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_Now --
+ *
+ *     Returns the current time in microseconds since the epoch.
+ *     The epoch is midnight January 1, 1970 GMT.
+ *     The implementation is machine dependent.  This is the Unix
+ *     implementation.
+ *     Cf. time_t time(time_t *tp)
+ *
+ *-----------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRTime)
+PR_Now(void)
+{
+    struct timeval tv;
+    PRInt64 s, us, s2us;
+
+    GETTIMEOFDAY(&tv);
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(s, tv.tv_sec);
+    LL_I2L(us, tv.tv_usec);
+    LL_MUL(s, s, s2us);
+    LL_ADD(s, s, us);
+    return s;
+}
+
+PRIntervalTime _PR_UNIX_GetInterval()
+{
+    struct timeval time;
+    PRIntervalTime ticks;
+
+    (void)GETTIMEOFDAY(&time);  /* fallicy of course */
+    ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
+    ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC;  /* so's that */
+    return ticks;
+}  /* _PR_SUNOS_GetInterval */
+
+PRIntervalTime _PR_UNIX_TicksPerSecond()
+{
+    return 1000;  /* this needs some work :) */
+}
+
+#if !defined(_PR_PTHREADS)
+/*
+ * Wait for I/O on multiple descriptors.
+ *
+ * Return 0 if timed out, return -1 if interrupted,
+ * else return the number of ready descriptors.
+ */
+PRInt32 _PR_WaitForMultipleFDs(
+    _PRUnixPollDesc *unixpds,
+    PRInt32 pdcnt,
+    PRIntervalTime timeout)
+{
+    PRPollQueue pq;
+    PRIntn is;
+    PRInt32 rv;
+    _PRCPU *io_cpu;
+    _PRUnixPollDesc *unixpd, *eunixpd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD));
+
+    if (_PR_PENDING_INTERRUPT(me)) {
+        me->flags &= ~_PR_INTERRUPT;
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        return -1;
+    }
+
+    pq.pds = unixpds;
+    pq.npds = pdcnt;
+
+    _PR_INTSOFF(is);
+    _PR_MD_IOQ_LOCK();
+    _PR_THREAD_LOCK(me);
+
+    pq.thr = me;
+    io_cpu = me->cpu;
+    pq.on_ioq = PR_TRUE;
+    pq.timeout = timeout;
+    _PR_ADD_TO_IOQ(pq, me->cpu);
+
+#if !defined(_PR_USE_POLL)
+    eunixpd = unixpds + pdcnt;
+    for (unixpd = unixpds; unixpd < eunixpd; unixpd++) {
+        PRInt32 osfd = unixpd->osfd;
+        if (unixpd->in_flags & _PR_UNIX_POLL_READ) {
+            FD_SET(osfd, &_PR_FD_READ_SET(me->cpu));
+            _PR_FD_READ_CNT(me->cpu)[osfd]++;
+        }
+        if (unixpd->in_flags & _PR_UNIX_POLL_WRITE) {
+            FD_SET(osfd, &_PR_FD_WRITE_SET(me->cpu));
+            (_PR_FD_WRITE_CNT(me->cpu))[osfd]++;
+        }
+        if (unixpd->in_flags & _PR_UNIX_POLL_EXCEPT) {
+            FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+            (_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++;
+        }
+        if (osfd > _PR_IOQ_MAX_OSFD(me->cpu)) {
+            _PR_IOQ_MAX_OSFD(me->cpu) = osfd;
+        }
+    }
+#endif  /* !defined(_PR_USE_POLL) */
+
+    if (_PR_IOQ_TIMEOUT(me->cpu) > timeout) {
+        _PR_IOQ_TIMEOUT(me->cpu) = timeout;
+    }
+
+    _PR_IOQ_OSFD_CNT(me->cpu) += pdcnt;
+        
+    _PR_SLEEPQ_LOCK(me->cpu);
+    _PR_ADD_SLEEPQ(me, timeout);
+    me->state = _PR_IO_WAIT;
+    me->io_pending = PR_TRUE;
+    me->io_suspended = PR_FALSE;
+    _PR_SLEEPQ_UNLOCK(me->cpu);
+    _PR_THREAD_UNLOCK(me);
+    _PR_MD_IOQ_UNLOCK();
+
+    _PR_MD_WAIT(me, timeout);
+
+    me->io_pending = PR_FALSE;
+    me->io_suspended = PR_FALSE;
+
+    /*
+     * This thread should run on the same cpu on which it was blocked; when 
+     * the IO request times out the fd sets and fd counts for the
+     * cpu are updated below.
+     */
+    PR_ASSERT(me->cpu == io_cpu);
+
+    /*
+    ** If we timed out the pollq might still be on the ioq. Remove it
+    ** before continuing.
+    */
+    if (pq.on_ioq) {
+        _PR_MD_IOQ_LOCK();
+        /*
+         * Need to check pq.on_ioq again
+         */
+        if (pq.on_ioq) {
+            PR_REMOVE_LINK(&pq.links);
+#ifndef _PR_USE_POLL
+            eunixpd = unixpds + pdcnt;
+            for (unixpd = unixpds; unixpd < eunixpd; unixpd++) {
+                PRInt32 osfd = unixpd->osfd;
+                PRInt16 in_flags = unixpd->in_flags;
+
+                if (in_flags & _PR_UNIX_POLL_READ) {
+                    if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
+                }
+                if (in_flags & _PR_UNIX_POLL_WRITE) {
+                    if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
+                }
+                if (in_flags & _PR_UNIX_POLL_EXCEPT) {
+                    if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+                }
+            }
+#endif  /* _PR_USE_POLL */
+            PR_ASSERT(pq.npds == pdcnt);
+            _PR_IOQ_OSFD_CNT(me->cpu) -= pdcnt;
+            PR_ASSERT(_PR_IOQ_OSFD_CNT(me->cpu) >= 0);
+        }
+        _PR_MD_IOQ_UNLOCK();
+    }
+    /* XXX Should we use _PR_FAST_INTSON or _PR_INTSON? */
+    if (1 == pdcnt) {
+        _PR_FAST_INTSON(is);
+    } else {
+        _PR_INTSON(is);
+    }
+
+    if (_PR_PENDING_INTERRUPT(me)) {
+        me->flags &= ~_PR_INTERRUPT;
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        return -1;
+    }
+
+    rv = 0;
+    if (pq.on_ioq == PR_FALSE) {
+        /* Count the number of ready descriptors */
+        while (--pdcnt >= 0) {
+            if (unixpds->out_flags != 0) {
+                rv++;
+            }
+            unixpds++;
+        }
+    }
+
+    return rv;
+}
+
+/*
+ * Unblock threads waiting for I/O
+ *    used when interrupting threads
+ *
+ * NOTE: The thread lock should held when this function is called.
+ * On return, the thread lock is released.
+ */
+void _PR_Unblock_IO_Wait(PRThread *thr)
+{
+    int pri = thr->priority;
+    _PRCPU *cpu = thr->cpu;
+ 
+    /*
+     * GLOBAL threads wakeup periodically to check for interrupt
+     */
+    if (_PR_IS_NATIVE_THREAD(thr)) {
+        _PR_THREAD_UNLOCK(thr); 
+        return;
+    }
+
+    PR_ASSERT(thr->flags & (_PR_ON_SLEEPQ | _PR_ON_PAUSEQ));
+    _PR_SLEEPQ_LOCK(cpu);
+    _PR_DEL_SLEEPQ(thr, PR_TRUE);
+    _PR_SLEEPQ_UNLOCK(cpu);
+
+    PR_ASSERT(!(thr->flags & _PR_IDLE_THREAD));
+    thr->state = _PR_RUNNABLE;
+    _PR_RUNQ_LOCK(cpu);
+    _PR_ADD_RUNQ(thr, cpu, pri);
+    _PR_RUNQ_UNLOCK(cpu);
+    _PR_THREAD_UNLOCK(thr);
+    _PR_MD_WAKEUP_WAITER(thr);
+}
+#endif  /* !defined(_PR_PTHREADS) */
+
+/*
+ * When a nonblocking connect has completed, determine whether it
+ * succeeded or failed, and if it failed, what the error code is.
+ *
+ * The function returns the error code.  An error code of 0 means
+ * that the nonblocking connect succeeded.
+ */
+
+int _MD_unix_get_nonblocking_connect_error(int osfd)
+{
+#if defined(NTO)
+    /* Neutrino does not support the SO_ERROR socket option */
+    PRInt32      rv;
+    PRNetAddr    addr;
+    _PRSockLen_t addrlen = sizeof(addr);
+
+    /* Test to see if we are using the Tiny TCP/IP Stack or the Full one. */
+    struct statvfs superblock;
+    rv = fstatvfs(osfd, &superblock);
+    if (rv == 0) {
+        if (strcmp(superblock.f_basetype, "ttcpip") == 0) {
+            /* Using the Tiny Stack! */
+            rv = getpeername(osfd, (struct sockaddr *) &addr,
+                    (_PRSockLen_t *) &addrlen);
+            if (rv == -1) {
+                int errno_copy = errno;    /* make a copy so I don't
+                                            * accidentally reset */
+
+                if (errno_copy == ENOTCONN) {
+                    struct stat StatInfo;
+                    rv = fstat(osfd, &StatInfo);
+                    if (rv == 0) {
+                        time_t current_time = time(NULL);
+
+                        /*
+                         * this is a real hack, can't explain why it
+                         * works it just does
+                         */
+                        if (abs(current_time - StatInfo.st_atime) < 5) {
+                            return ECONNREFUSED;
+                        } else {
+                            return ETIMEDOUT;
+                        }
+                    } else {
+                        return ECONNREFUSED;
+                    }
+                } else {
+                    return errno_copy;
+                }
+            } else {
+                /* No Error */
+                return 0;
+            }
+        } else {
+            /* Have the FULL Stack which supports SO_ERROR */
+            /* Hasn't been written yet, never been tested! */
+            /* Jerry.Kirk at Nexwarecorp.com */
+
+            int err;
+            _PRSockLen_t optlen = sizeof(err);
+
+            if (getsockopt(osfd, SOL_SOCKET, SO_ERROR,
+                    (char *) &err, &optlen) == -1) {
+                return errno;
+            } else {
+                return err;
+            }		
+        }
+    } else {
+        return ECONNREFUSED;
+    }	
+#elif defined(NCR) || defined(UNIXWARE) || defined(SNI) || defined(NEC)
+    /*
+     * getsockopt() fails with EPIPE, so use getmsg() instead.
+     */
+
+    int rv;
+    int flags = 0;
+    rv = getmsg(osfd, NULL, NULL, &flags);
+    PR_ASSERT(-1 == rv || 0 == rv);
+    if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) {
+        return errno;
+    }
+    return 0;  /* no error */
+#else
+    int err;
+    _PRSockLen_t optlen = sizeof(err);
+    if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, (char *) &err, &optlen) == -1) {
+        return errno;
+    } else {
+        return err;
+    }
+#endif
+}
+
+/************************************************************************/
+
+/*
+** Special hacks for xlib. Xlib/Xt/Xm is not re-entrant nor is it thread
+** safe.  Unfortunately, neither is mozilla. To make these programs work
+** in a pre-emptive threaded environment, we need to use a lock.
+*/
+
+void PR_XLock(void)
+{
+    PR_EnterMonitor(_pr_Xfe_mon);
+}
+
+void PR_XUnlock(void)
+{
+    PR_ExitMonitor(_pr_Xfe_mon);
+}
+
+PRBool PR_XIsLocked(void)
+{
+    return (PR_InMonitor(_pr_Xfe_mon)) ? PR_TRUE : PR_FALSE;
+}
+
+void PR_XWait(int ms)
+{
+    PR_Wait(_pr_Xfe_mon, PR_MillisecondsToInterval(ms));
+}
+
+void PR_XNotify(void)
+{
+    PR_Notify(_pr_Xfe_mon);
+}
+
+void PR_XNotifyAll(void)
+{
+    PR_NotifyAll(_pr_Xfe_mon);
+}
+
+#if defined(HAVE_FCNTL_FILE_LOCKING)
+
+PRStatus
+_MD_LockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_WRLCK;
+    arg.l_whence = SEEK_SET;
+    arg.l_start = 0;
+    arg.l_len = 0;  /* until EOF */
+    rv = fcntl(f, F_SETLKW, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_TLockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_WRLCK;
+    arg.l_whence = SEEK_SET;
+    arg.l_start = 0;
+    arg.l_len = 0;  /* until EOF */
+    rv = fcntl(f, F_SETLK, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_UnlockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    struct flock arg;
+
+    arg.l_type = F_UNLCK;
+    arg.l_whence = SEEK_SET;
+    arg.l_start = 0;
+    arg.l_len = 0;  /* until EOF */
+    rv = fcntl(f, F_SETLK, &arg);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+#elif defined(HAVE_BSD_FLOCK)
+
+#include <sys/file.h>
+
+PRStatus
+_MD_LockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = flock(f, LOCK_EX);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_TLockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = flock(f, LOCK_EX|LOCK_NB);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_UnlockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = flock(f, LOCK_UN);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_FLOCK_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+#else
+
+PRStatus
+_MD_LockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = lockf(f, F_LOCK, 0);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_TLockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = lockf(f, F_TLOCK, 0);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus
+_MD_UnlockFile(PRInt32 f)
+{
+    PRInt32 rv;
+    rv = lockf(f, F_ULOCK, 0);
+    if (rv == 0)
+        return PR_SUCCESS;
+    _PR_MD_MAP_LOCKF_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+#endif
+
+PRStatus _MD_gethostname(char *name, PRUint32 namelen)
+{
+    PRIntn rv;
+
+    rv = gethostname(name, namelen);
+    if (0 == rv) {
+        return PR_SUCCESS;
+    }
+    _PR_MD_MAP_GETHOSTNAME_ERROR(_MD_ERRNO());
+    return PR_FAILURE;
+}
+
+PRStatus _MD_getsysinfo(PRSysInfo cmd, char *name, PRUint32 namelen)
+{
+	struct utsname info;
+
+	PR_ASSERT((cmd == PR_SI_SYSNAME) || (cmd == PR_SI_RELEASE));
+
+	if (uname(&info) == -1) {
+		_PR_MD_MAP_DEFAULT_ERROR(errno);
+    	return PR_FAILURE;
+	}
+	if (PR_SI_SYSNAME == cmd)
+		(void)PR_snprintf(name, namelen, info.sysname);
+	else if (PR_SI_RELEASE == cmd)
+		(void)PR_snprintf(name, namelen, info.release);
+	else
+		return PR_FAILURE;
+    return PR_SUCCESS;
+}
+
+/*
+ *******************************************************************
+ *
+ * Memory-mapped files
+ *
+ *******************************************************************
+ */
+
+PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size)
+{
+    PRFileInfo info;
+    PRUint32 sz;
+
+    LL_L2UI(sz, size);
+    if (sz) {
+        if (PR_GetOpenFileInfo(fmap->fd, &info) == PR_FAILURE) {
+            return PR_FAILURE;
+        }
+        if (sz > info.size) {
+            /*
+             * Need to extend the file
+             */
+            if (fmap->prot != PR_PROT_READWRITE) {
+                PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0);
+                return PR_FAILURE;
+            }
+            if (PR_Seek(fmap->fd, sz - 1, PR_SEEK_SET) == -1) {
+                return PR_FAILURE;
+            }
+            if (PR_Write(fmap->fd, "", 1) != 1) {
+                return PR_FAILURE;
+            }
+        }
+    }
+    if (fmap->prot == PR_PROT_READONLY) {
+        fmap->md.prot = PROT_READ;
+#ifdef OSF1V4_MAP_PRIVATE_BUG
+        /*
+         * Use MAP_SHARED to work around a bug in OSF1 V4.0D
+         * (QAR 70220 in the OSF_QAR database) that results in
+         * corrupted data in the memory-mapped region.  This
+         * bug is fixed in V5.0.
+         */
+        fmap->md.flags = MAP_SHARED;
+#else
+        fmap->md.flags = MAP_PRIVATE;
+#endif
+    } else if (fmap->prot == PR_PROT_READWRITE) {
+        fmap->md.prot = PROT_READ | PROT_WRITE;
+        fmap->md.flags = MAP_SHARED;
+    } else {
+        PR_ASSERT(fmap->prot == PR_PROT_WRITECOPY);
+        fmap->md.prot = PROT_READ | PROT_WRITE;
+        fmap->md.flags = MAP_PRIVATE;
+    }
+    return PR_SUCCESS;
+}
+
+void * _MD_MemMap(
+    PRFileMap *fmap,
+    PRInt64 offset,
+    PRUint32 len)
+{
+    PRInt32 off;
+    void *addr;
+
+    LL_L2I(off, offset);
+    if ((addr = mmap(0, len, fmap->md.prot, fmap->md.flags,
+        fmap->fd->secret->md.osfd, off)) == (void *) -1) {
+            _PR_MD_MAP_MMAP_ERROR(_MD_ERRNO());
+        addr = NULL;
+    }
+    return addr;
+}
+
+PRStatus _MD_MemUnmap(void *addr, PRUint32 len)
+{
+    if (munmap(addr, len) == 0) {
+        return PR_SUCCESS;
+    } else {
+    if (errno == EINVAL) {
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, errno);
+    } else {
+        PR_SetError(PR_UNKNOWN_ERROR, errno);
+    }
+        return PR_FAILURE;
+    }
+}
+
+PRStatus _MD_CloseFileMap(PRFileMap *fmap)
+{
+    if ( PR_TRUE == fmap->md.isAnonFM ) {
+        PRStatus rc = PR_Close( fmap->fd );
+        if ( PR_FAILURE == rc ) {
+            PR_LOG( _pr_io_lm, PR_LOG_DEBUG,
+                ("_MD_CloseFileMap(): error closing anonymnous file map osfd"));
+            return PR_FAILURE;
+        }
+    }
+    PR_DELETE(fmap);
+    return PR_SUCCESS;
+}
+
+#if defined(_PR_NEED_FAKE_POLL)
+
+/*
+ * Some platforms don't have poll().  For easier porting of code
+ * that calls poll(), we emulate poll() using select().
+ */
+
+int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
+{
+    int i;
+    int rv;
+    int maxfd;
+    fd_set rd, wr, ex;
+    struct timeval tv, *tvp;
+
+    if (timeout < 0 && timeout != -1) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    if (timeout == -1) {
+        tvp = NULL;
+    } else {
+        tv.tv_sec = timeout / 1000;
+        tv.tv_usec = (timeout % 1000) * 1000;
+        tvp = &tv;
+    }
+
+    maxfd = -1;
+    FD_ZERO(&rd);
+    FD_ZERO(&wr);
+    FD_ZERO(&ex);
+
+    for (i = 0; i < nfds; i++) {
+        int osfd = filedes[i].fd;
+        int events = filedes[i].events;
+        PRBool fdHasEvent = PR_FALSE;
+
+        if (osfd < 0) {
+            continue;  /* Skip this osfd. */
+        }
+
+        /*
+         * Map the poll events to the select fd_sets.
+         *     POLLIN, POLLRDNORM  ===> readable
+         *     POLLOUT, POLLWRNORM ===> writable
+         *     POLLPRI, POLLRDBAND ===> exception
+         *     POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
+         *     are ignored.
+         *
+         * The output events POLLERR and POLLHUP are never turned on.
+         * POLLNVAL may be turned on.
+         */
+
+        if (events & (POLLIN | POLLRDNORM)) {
+            FD_SET(osfd, &rd);
+            fdHasEvent = PR_TRUE;
+        }
+        if (events & (POLLOUT | POLLWRNORM)) {
+            FD_SET(osfd, &wr);
+            fdHasEvent = PR_TRUE;
+        }
+        if (events & (POLLPRI | POLLRDBAND)) {
+            FD_SET(osfd, &ex);
+            fdHasEvent = PR_TRUE;
+        }
+        if (fdHasEvent && osfd > maxfd) {
+            maxfd = osfd;
+        }
+    }
+
+    rv = select(maxfd + 1, &rd, &wr, &ex, tvp);
+
+    /* Compute poll results */
+    if (rv > 0) {
+        rv = 0;
+        for (i = 0; i < nfds; i++) {
+            PRBool fdHasEvent = PR_FALSE;
+
+            filedes[i].revents = 0;
+            if (filedes[i].fd < 0) {
+                continue;
+            }
+            if (FD_ISSET(filedes[i].fd, &rd)) {
+                if (filedes[i].events & POLLIN) {
+                    filedes[i].revents |= POLLIN;
+                }
+                if (filedes[i].events & POLLRDNORM) {
+                    filedes[i].revents |= POLLRDNORM;
+                }
+                fdHasEvent = PR_TRUE;
+            }
+            if (FD_ISSET(filedes[i].fd, &wr)) {
+                if (filedes[i].events & POLLOUT) {
+                    filedes[i].revents |= POLLOUT;
+                }
+                if (filedes[i].events & POLLWRNORM) {
+                    filedes[i].revents |= POLLWRNORM;
+                }
+                fdHasEvent = PR_TRUE;
+            }
+            if (FD_ISSET(filedes[i].fd, &ex)) {
+                if (filedes[i].events & POLLPRI) {
+                    filedes[i].revents |= POLLPRI;
+                }
+                if (filedes[i].events & POLLRDBAND) {
+                    filedes[i].revents |= POLLRDBAND;
+                }
+                fdHasEvent = PR_TRUE;
+            }
+            if (fdHasEvent) {
+                rv++;
+            }
+        }
+        PR_ASSERT(rv > 0);
+    } else if (rv == -1 && errno == EBADF) {
+        rv = 0;
+        for (i = 0; i < nfds; i++) {
+            filedes[i].revents = 0;
+            if (filedes[i].fd < 0) {
+                continue;
+            }
+            if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) {
+                filedes[i].revents = POLLNVAL;
+                rv++;
+            }
+        }
+        PR_ASSERT(rv > 0);
+    }
+    PR_ASSERT(-1 != timeout || rv != 0);
+
+    return rv;
+}
+#endif /* _PR_NEED_FAKE_POLL */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/unix_errors.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/unix_errors.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,863 @@
+/* -*- 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"
+#if defined(_PR_POLL_AVAILABLE)
+#include <poll.h>
+#endif
+#include <errno.h>
+
+void _MD_unix_map_default_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err ) {
+        case EACCES:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case EADDRINUSE:
+            prError = PR_ADDRESS_IN_USE_ERROR;
+            break;
+        case EADDRNOTAVAIL:
+            prError = PR_ADDRESS_NOT_AVAILABLE_ERROR;
+            break;
+        case EAFNOSUPPORT:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        case EAGAIN:
+            prError = PR_WOULD_BLOCK_ERROR;
+            break;
+        /*
+         * On QNX and Neutrino, EALREADY is defined as EBUSY.
+         */
+#if EALREADY != EBUSY
+        case EALREADY:
+            prError = PR_ALREADY_INITIATED_ERROR;
+            break;
+#endif
+        case EBADF:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+#ifdef EBADMSG
+        case EBADMSG:
+            prError = PR_IO_ERROR;
+            break;
+#endif
+        case EBUSY:
+            prError = PR_FILESYSTEM_MOUNTED_ERROR;
+            break;
+        case ECONNABORTED:
+            prError = PR_CONNECT_ABORTED_ERROR;
+            break;
+        case ECONNREFUSED:
+            prError = PR_CONNECT_REFUSED_ERROR;
+            break;
+        case ECONNRESET:
+            prError = PR_CONNECT_RESET_ERROR;
+            break;
+        case EDEADLK:
+            prError = PR_DEADLOCK_ERROR;
+            break;
+#ifdef EDIRCORRUPTED
+        case EDIRCORRUPTED:
+            prError = PR_DIRECTORY_CORRUPTED_ERROR;
+            break;
+#endif
+#ifdef EDQUOT
+        case EDQUOT:
+            prError = PR_NO_DEVICE_SPACE_ERROR;
+            break;
+#endif
+        case EEXIST:
+            prError = PR_FILE_EXISTS_ERROR;
+            break;
+        case EFAULT:
+            prError = PR_ACCESS_FAULT_ERROR;
+            break;
+        case EFBIG:
+            prError = PR_FILE_TOO_BIG_ERROR;
+            break;
+        case EHOSTUNREACH:
+            prError = PR_HOST_UNREACHABLE_ERROR;
+            break;
+        case EINPROGRESS:
+            prError = PR_IN_PROGRESS_ERROR;
+            break;
+        case EINTR:
+            prError = PR_PENDING_INTERRUPT_ERROR;
+            break;
+        case EINVAL:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case EIO:
+            prError = PR_IO_ERROR;
+            break;
+        case EISCONN:
+            prError = PR_IS_CONNECTED_ERROR;
+            break;
+        case EISDIR:
+            prError = PR_IS_DIRECTORY_ERROR;
+            break;
+        case ELOOP:
+            prError = PR_LOOP_ERROR;
+            break;
+        case EMFILE:
+            prError = PR_PROC_DESC_TABLE_FULL_ERROR;
+            break;
+        case EMLINK:
+            prError = PR_MAX_DIRECTORY_ENTRIES_ERROR;
+            break;
+        case EMSGSIZE:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+#ifdef EMULTIHOP
+        case EMULTIHOP:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+#endif
+        case ENAMETOOLONG:
+            prError = PR_NAME_TOO_LONG_ERROR;
+            break;
+        case ENETUNREACH:
+            prError = PR_NETWORK_UNREACHABLE_ERROR;
+            break;
+        case ENFILE:
+            prError = PR_SYS_DESC_TABLE_FULL_ERROR;
+            break;
+        /*
+         * On SCO OpenServer 5, ENOBUFS is defined as ENOSR.
+         */
+#if defined(ENOBUFS) && (ENOBUFS != ENOSR)
+        case ENOBUFS:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+#endif
+        case ENODEV:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        case ENOENT:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        case ENOLCK:
+            prError = PR_FILE_IS_LOCKED_ERROR;
+            break;
+#ifdef ENOLINK 
+        case ENOLINK:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+#endif
+        case ENOMEM:
+            prError = PR_OUT_OF_MEMORY_ERROR;
+            break;
+        case ENOPROTOOPT:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case ENOSPC:
+            prError = PR_NO_DEVICE_SPACE_ERROR;
+            break;
+#ifdef ENOSR
+        case ENOSR:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+#endif
+        case ENOTCONN:
+            prError = PR_NOT_CONNECTED_ERROR;
+            break;
+        case ENOTDIR:
+            prError = PR_NOT_DIRECTORY_ERROR;
+            break;
+        case ENOTSOCK:
+            prError = PR_NOT_SOCKET_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        case EOPNOTSUPP:
+            prError = PR_NOT_TCP_SOCKET_ERROR;
+            break;
+#ifdef EOVERFLOW
+        case EOVERFLOW:
+            prError = PR_BUFFER_OVERFLOW_ERROR;
+            break;
+#endif
+        case EPERM:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case EPIPE:
+            prError = PR_CONNECT_RESET_ERROR;
+            break;
+#ifdef EPROTO
+        case EPROTO:
+            prError = PR_IO_ERROR;
+            break;
+#endif
+        case EPROTONOSUPPORT:
+            prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR;
+            break;
+        case EPROTOTYPE:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        case ERANGE:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        case EROFS:
+            prError = PR_READ_ONLY_FILESYSTEM_ERROR;
+            break;
+        case ESPIPE:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        case ETIMEDOUT:
+            prError = PR_IO_TIMEOUT_ERROR;
+            break;
+#if EWOULDBLOCK != EAGAIN
+        case EWOULDBLOCK:
+            prError = PR_WOULD_BLOCK_ERROR;
+            break;
+#endif
+        case EXDEV:
+            prError = PR_NOT_SAME_DEVICE_ERROR;
+            break;
+        default:
+            prError = PR_UNKNOWN_ERROR;
+            break;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_opendir_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_closedir_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_readdir_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case 0:
+        case ENOENT:
+            prError = PR_NO_MORE_FILES_ERROR;
+            break;
+#ifdef EOVERFLOW
+        case EOVERFLOW:
+            prError = PR_IO_ERROR;
+            break;
+#endif
+        case EINVAL:
+            prError = PR_IO_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_IO_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_unlink_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EPERM:
+            prError = PR_IS_DIRECTORY_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_stat_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_fstat_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_rename_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EEXIST:
+            prError = PR_DIRECTORY_NOT_EMPTY_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_access_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_mkdir_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_rmdir_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        /*
+         * On AIX 4.3, ENOTEMPTY is defined as EEXIST.
+         */
+#if ENOTEMPTY != EEXIST
+        case ENOTEMPTY:
+            prError = PR_DIRECTORY_NOT_EMPTY_ERROR;
+            break;
+#endif
+        case EEXIST:
+            prError = PR_DIRECTORY_NOT_EMPTY_ERROR;
+            break;
+        case EINVAL:
+            prError = PR_DIRECTORY_NOT_EMPTY_ERROR;
+            break;
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_read_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_write_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_lseek_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_fsync_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        case EINVAL:
+            prError = PR_INVALID_METHOD_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_close_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_socket_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_socketavailable_error(int err)
+{
+    PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+}
+
+void _MD_unix_map_recv_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_recvfrom_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_send_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_sendto_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_writev_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_accept_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ENODEV:
+            prError = PR_NOT_TCP_SOCKET_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_connect_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EACCES:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+#if defined(UNIXWARE) || defined(SNI) || defined(NEC)
+        /*
+         * On some platforms, if we connect to a port on the local host 
+         * (the loopback address) that no process is listening on, we get 
+         * EIO instead of ECONNREFUSED.
+         */
+        case EIO:
+            prError = PR_CONNECT_REFUSED_ERROR;
+            break;
+#endif
+        case ELOOP:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        case ENOENT:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_IO_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_bind_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR;
+            break;
+        /*
+         * UNIX domain sockets are not supported in NSPR
+         */
+        case EIO:
+        case EISDIR:
+        case ELOOP:
+        case ENOENT:
+        case ENOTDIR:
+        case EROFS:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_listen_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_shutdown_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_socketpair_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_getsockname_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_getpeername_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_getsockopt_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_BUFFER_OVERFLOW_ERROR;
+            break;
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_setsockopt_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_BUFFER_OVERFLOW_ERROR;
+            break;
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_open_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EAGAIN:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case EBUSY:
+            prError = PR_IO_ERROR;
+            break;
+        case ENODEV:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        case ENOMEM:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+#ifdef EOVERFLOW
+        case EOVERFLOW:
+            prError = PR_FILE_TOO_BIG_ERROR;
+            break;
+#endif
+        case ETIMEDOUT:
+            prError = PR_REMOTE_FILE_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_mmap_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EAGAIN:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case EMFILE:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case ENODEV:
+            prError = PR_OPERATION_NOT_SUPPORTED_ERROR;
+            break;
+        case ENXIO:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_gethostname_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+void _MD_unix_map_select_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+
+#if defined(_PR_POLL_AVAILABLE) || defined(_PR_NEED_FAKE_POLL)
+void _MD_unix_map_poll_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EAGAIN:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_poll_revents_error(int err)
+{
+    if (err & POLLNVAL)
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
+    else if (err & POLLHUP)
+        PR_SetError(PR_CONNECT_RESET_ERROR, EPIPE);
+    else if (err & POLLERR)
+        PR_SetError(PR_IO_ERROR, EIO);
+    else
+        PR_SetError(PR_UNKNOWN_ERROR, err);
+}
+#endif /* _PR_POLL_AVAILABLE || _PR_NEED_FAKE_POLL */
+
+
+void _MD_unix_map_flock_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EINVAL:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        case EWOULDBLOCK:
+            prError = PR_FILE_IS_LOCKED_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_unix_map_lockf_error(int err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EACCES:
+            prError = PR_FILE_IS_LOCKED_ERROR;
+            break;
+        case EDEADLK:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        default:
+            _MD_unix_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+#ifdef AIX
+void _MD_aix_map_sendfile_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+#endif /* AIX */
+
+#ifdef HPUX11
+void _MD_hpux_map_sendfile_error(int err)
+{
+    _MD_unix_map_default_error(err);
+}
+#endif /* HPUX11 */
+
+#ifdef SOLARIS
+void _MD_solaris_map_sendfile_error(int err)
+{
+    _MD_unix_map_default_error(err) ;
+}
+#endif /* SOLARIS */
+
+#ifdef LINUX
+void _MD_linux_map_sendfile_error(int err)
+{
+    _MD_unix_map_default_error(err) ;
+}
+#endif /* LINUX */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/unixware.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/unixware.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,583 @@
+/* -*- 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"
+
+#if !defined (USE_SVR4_THREADS)
+
+/*
+         * using only NSPR threads here
+ */
+
+#include <setjmp.h>
+
+void _MD_EarlyInit(void)
+{
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) setjmp(CONTEXT(t));
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+}
+
+#ifdef ALARMS_BREAK_TCP /* I don't think they do */
+
+PRInt32 _MD_connect(PRInt32 osfd, const PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _connect(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+}
+
+PRInt32 _MD_accept(PRInt32 osfd, PRNetAddr *addr, PRInt32 addrlen,
+                        PRIntervalTime timeout)
+{
+    PRInt32 rv;
+
+    _MD_BLOCK_CLOCK_INTERRUPTS();
+    rv = _accept(osfd,addr,addrlen);
+    _MD_UNBLOCK_CLOCK_INTERRUPTS();
+    return(rv);
+}
+#endif
+
+/*
+ * These are also implemented in pratom.c using NSPR locks.  Any reason
+ * this might be better or worse?  If you like this better, define
+ * _PR_HAVE_ATOMIC_OPS in include/md/unixware.h
+ */
+#ifdef _PR_HAVE_ATOMIC_OPS
+/* Atomic operations */
+#include  <stdio.h>
+static FILE *_uw_semf;
+
+void
+_MD_INIT_ATOMIC(void)
+{
+    /* Sigh.  Sure wish SYSV semaphores weren't such a pain to use */
+    if ((_uw_semf = tmpfile()) == NULL)
+        PR_ASSERT(0);
+
+    return;
+}
+
+void
+_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)++;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    flockfile(_uw_semf);
+    (*ptr) += val;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    flockfile(_uw_semf);
+    (*val)--;
+    unflockfile(_uw_semf);
+}
+
+void
+_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    flockfile(_uw_semf);
+    *val = newval;
+    unflockfile(_uw_semf);
+}
+#endif
+
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for Unixware */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for Unixware.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for Unixware.");
+}
+
+#else  /* USE_SVR4_THREADS */
+
+/* NOTE:
+ * SPARC v9 (Ultras) do have an atomic test-and-set operation.  But
+ * SPARC v8 doesn't.  We should detect in the init if we are running on
+ * v8 or v9, and then use assembly where we can.
+ */
+
+#include <thread.h>
+#include <synch.h>
+
+static mutex_t _unixware_atomic = DEFAULTMUTEX;
+
+#define TEST_THEN_ADD(where, inc) \
+    if (mutex_lock(&_unixware_atomic) != 0)\
+        PR_ASSERT(0);\
+    *where += inc;\
+    if (mutex_unlock(&_unixware_atomic) != 0)\
+        PR_ASSERT(0);
+
+#define TEST_THEN_SET(where, val) \
+    if (mutex_lock(&_unixware_atomic) != 0)\
+        PR_ASSERT(0);\
+    *where = val;\
+    if (mutex_unlock(&_unixware_atomic) != 0)\
+        PR_ASSERT(0);
+
+void
+_MD_INIT_ATOMIC(void)
+{
+}
+
+void
+_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    TEST_THEN_ADD(val, 1);
+}
+
+void
+_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    TEST_THEN_ADD(ptr, val);
+}
+
+void
+_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    TEST_THEN_ADD(val, 0xffffffff);
+}
+
+void
+_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    TEST_THEN_SET(val, newval);
+}
+
+#include <signal.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/lwp.h>
+#include <sys/procfs.h>
+#include <sys/syscall.h>
+
+
+THREAD_KEY_T threadid_key;
+THREAD_KEY_T cpuid_key;
+THREAD_KEY_T last_thread_key;
+static sigset_t set, oldset;
+
+void _MD_EarlyInit(void)
+{
+    THR_KEYCREATE(&threadid_key, NULL);
+    THR_KEYCREATE(&cpuid_key, NULL);
+    THR_KEYCREATE(&last_thread_key, NULL);
+    sigemptyset(&set);
+    sigaddset(&set, SIGALRM);
+}
+
+PRStatus _MD_CREATE_THREAD(PRThread *thread, 
+					void (*start)(void *), 
+					PRThreadPriority priority,
+					PRThreadScope scope, 
+					PRThreadState state, 
+					PRUint32 stackSize) 
+{
+	long flags;
+	
+    /* mask out SIGALRM for native thread creation */
+    thr_sigsetmask(SIG_BLOCK, &set, &oldset); 
+
+    flags = (state == PR_JOINABLE_THREAD ? THR_SUSPENDED/*|THR_NEW_LWP*/ 
+			   : THR_SUSPENDED|THR_DETACHED/*|THR_NEW_LWP*/);
+	if (_PR_IS_GCABLE_THREAD(thread) ||
+							(scope == PR_GLOBAL_BOUND_THREAD))
+		flags |= THR_BOUND;
+
+    if (thr_create(NULL, thread->stack->stackSize,
+                  (void *(*)(void *)) start, (void *) thread, 
+				  flags,
+                  &thread->md.handle)) {
+        thr_sigsetmask(SIG_SETMASK, &oldset, NULL); 
+	return PR_FAILURE;
+    }
+
+
+    /* When the thread starts running, then the lwpid is set to the right
+     * value. Until then we want to mark this as 'uninit' so that
+     * its register state is initialized properly for GC */
+
+    thread->md.lwpid = -1;
+    thr_sigsetmask(SIG_SETMASK, &oldset, NULL); 
+    _MD_NEW_SEM(&thread->md.waiter_sem, 0);
+
+	if ((scope == PR_GLOBAL_THREAD) || (scope == PR_GLOBAL_BOUND_THREAD)) {
+		thread->flags |= _PR_GLOBAL_SCOPE;
+    }
+
+    /* 
+    ** Set the thread priority.  This will also place the thread on 
+    ** the runQ.
+    **
+    ** Force PR_SetThreadPriority to set the priority by
+    ** setting thread->priority to 100.
+    */
+    {
+    int pri;
+    pri = thread->priority;
+    thread->priority = 100;
+    PR_SetThreadPriority( thread, pri );
+
+    PR_LOG(_pr_thread_lm, PR_LOG_MIN, 
+            ("(0X%x)[Start]: on to runq at priority %d",
+            thread, thread->priority));
+    }
+
+    /* Activate the thread */
+    if (thr_continue( thread->md.handle ) ) {
+	return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+void _MD_cleanup_thread(PRThread *thread)
+{
+    thread_t hdl;
+    PRMonitor *mon;
+
+    hdl = thread->md.handle;
+
+    /* 
+    ** First, suspend the thread (unless it's the active one)
+    ** Because we suspend it first, we don't have to use LOCK_SCHEDULER to
+    ** prevent both of us modifying the thread structure at the same time.
+    */
+    if ( thread != _PR_MD_CURRENT_THREAD() ) {
+        thr_suspend(hdl);
+    }
+    PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+            ("(0X%x)[DestroyThread]\n", thread));
+
+    _MD_DESTROY_SEM(&thread->md.waiter_sem);
+}
+
+void _MD_SET_PRIORITY(_MDThread *md_thread, PRUintn newPri)
+{
+	if(thr_setprio((thread_t)md_thread->handle, newPri)) {
+		PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+		   ("_PR_SetThreadPriority: can't set thread priority\n"));
+	}
+}
+
+void _MD_WAIT_CV(
+    struct _MDCVar *md_cv, struct _MDLock *md_lock, PRIntervalTime timeout)
+{
+    struct timespec tt;
+    PRUint32 msec;
+    int rv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    msec = PR_IntervalToMilliseconds(timeout);
+
+    GETTIME (&tt);
+
+    tt.tv_sec += msec / PR_MSEC_PER_SEC;
+    tt.tv_nsec += (msec % PR_MSEC_PER_SEC) * PR_NSEC_PER_MSEC;
+    /* Check for nsec overflow - otherwise we'll get an EINVAL */
+    if (tt.tv_nsec >= PR_NSEC_PER_SEC) {
+        tt.tv_sec++;
+        tt.tv_nsec -= PR_NSEC_PER_SEC;
+    }
+    me->md.sp = unixware_getsp();
+
+
+    /* XXX Solaris 2.5.x gives back EINTR occasionally for no reason
+     * hence ignore EINTR for now */
+
+    COND_TIMEDWAIT(&md_cv->cv, &md_lock->lock, &tt);
+}
+
+void _MD_lock(struct _MDLock *md_lock)
+{
+    mutex_lock(&md_lock->lock);
+}
+
+void _MD_unlock(struct _MDLock *md_lock)
+{
+    mutex_unlock(&((md_lock)->lock));
+}
+
+
+PRThread *_pr_current_thread_tls()
+{
+    PRThread *ret;
+
+    thr_getspecific(threadid_key, (void **)&ret);
+    return ret;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+        _MD_WAIT_SEM(&thread->md.waiter_sem);
+        return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+	if (thread == NULL) {
+		return PR_SUCCESS;
+	}
+	_MD_POST_SEM(&thread->md.waiter_sem);
+	return PR_SUCCESS;
+}
+
+_PRCPU *_pr_current_cpu_tls()
+{
+    _PRCPU *ret;
+
+    thr_getspecific(cpuid_key, (void **)&ret);
+    return ret;
+}
+
+PRThread *_pr_last_thread_tls()
+{
+    PRThread *ret;
+
+    thr_getspecific(last_thread_key, (void **)&ret);
+    return ret;
+}
+
+_MDLock _pr_ioq_lock;
+
+void _MD_INIT_IO (void)
+{
+    _MD_NEW_LOCK(&_pr_ioq_lock);
+}
+
+PRStatus _MD_InitializeThread(PRThread *thread)
+{
+    if (!_PR_IS_NATIVE_THREAD(thread))
+        return;
+		/* prime the sp; substract 4 so we don't hit the assert that
+		 * curr sp > base_stack
+		 */
+    thread->md.sp = (uint_t) thread->stack->allocBase - sizeof(long);
+    thread->md.lwpid = _lwp_self();
+    thread->md.handle = THR_SELF();
+
+	/* all threads on Solaris are global threads from NSPR's perspective
+	 * since all of them are mapped to Solaris threads.
+	 */
+    thread->flags |= _PR_GLOBAL_SCOPE;
+
+ 	/* For primordial/attached thread, we don't create an underlying native thread.
+ 	 * So, _MD_CREATE_THREAD() does not get called.  We need to do initialization
+ 	 * like allocating thread's synchronization variables and set the underlying
+ 	 * native thread's priority.
+ 	 */
+	if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
+	    _MD_NEW_SEM(&thread->md.waiter_sem, 0);
+	    _MD_SET_PRIORITY(&(thread->md), thread->priority);
+	}
+	return PR_SUCCESS;
+}
+
+static sigset_t old_mask;	/* store away original gc thread sigmask */
+static int gcprio;		/* store away original gc thread priority */
+static lwpid_t *all_lwps=NULL;	/* list of lwps that we suspended */
+static int num_lwps ;
+static int suspendAllOn = 0;
+
+#define VALID_SP(sp, bottom, top)	\
+       (((uint_t)(sp)) > ((uint_t)(bottom)) && ((uint_t)(sp)) < ((uint_t)(top)))
+
+void unixware_preempt_off()
+{
+    sigset_t set;
+    (void)sigfillset(&set);
+    sigprocmask (SIG_SETMASK, &set, &old_mask);
+}
+
+void unixware_preempt_on()
+{
+    sigprocmask (SIG_SETMASK, &old_mask, NULL);      
+}
+
+void _MD_Begin_SuspendAll()
+{
+    unixware_preempt_off();
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin_SuspendAll\n"));
+    /* run at highest prio so I cannot be preempted */
+    thr_getprio(thr_self(), &gcprio);
+    thr_setprio(thr_self(), 0x7fffffff); 
+    suspendAllOn = 1;
+}
+
+void _MD_End_SuspendAll()
+{
+}
+
+void _MD_End_ResumeAll()
+{
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End_ResumeAll\n"));
+    thr_setprio(thr_self(), gcprio);
+    unixware_preempt_on();
+    suspendAllOn = 0;
+}
+
+void _MD_Suspend(PRThread *thr)
+{
+   int lwp_fd, result;
+   int lwp_main_proc_fd = 0;
+
+    thr_suspend(thr->md.handle);
+    if (!_PR_IS_GCABLE_THREAD(thr))
+      return;
+    /* XXX Primordial thread can't be bound to an lwp, hence there is no
+     * way we can assume that we can get the lwp status for primordial
+     * thread reliably. Hence we skip this for primordial thread, hoping
+     * that the SP is saved during lock and cond. wait. 
+     * XXX - Again this is concern only for java interpreter, not for the
+     * server, 'cause primordial thread in the server does not do java work
+     */
+    if (thr->flags & _PR_PRIMORDIAL)
+      return;
+
+    /* if the thread is not started yet then don't do anything */
+    if (!suspendAllOn || thr->md.lwpid == -1)
+      return;
+
+}
+void _MD_Resume(PRThread *thr)
+{
+   if (!_PR_IS_GCABLE_THREAD(thr) || !suspendAllOn){
+     /*XXX When the suspendAllOn is set, we will be trying to do lwp_suspend
+      * during that time we can't call any thread lib or libc calls. Hence
+      * make sure that no resume is requested for Non gcable thread
+      * during suspendAllOn */
+      PR_ASSERT(!suspendAllOn);
+      thr_continue(thr->md.handle);
+      return;
+   }
+   if (thr->md.lwpid == -1)
+     return;
+ 
+   if ( _lwp_continue(thr->md.lwpid) < 0) {
+      PR_ASSERT(0);  /* ARGH, we are hosed! */
+   }
+}
+
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    if (isCurrent) {
+	(void) getcontext(CONTEXT(t));	/* XXX tune me: set md_IRIX.c */
+    }
+    *np = NGREG;
+    if (t->md.lwpid == -1)
+      memset(&t->md.context.uc_mcontext.gregs[0], 0, NGREG * sizeof(PRWord));
+    return (PRWord*) &t->md.context.uc_mcontext.gregs[0];
+}
+
+int
+_pr_unixware_clock_gettime (struct timespec *tp)
+{
+    struct timeval tv;
+ 
+    gettimeofday(&tv, NULL);
+    tp->tv_sec = tv.tv_sec;
+    tp->tv_nsec = tv.tv_usec * 1000;
+    return 0;
+}
+
+
+#endif /* USE_SVR4_THREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxpoll.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxpoll.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,708 @@
+/* -*- 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(_PR_PTHREADS)
+
+#error "This file should not be compiled"
+
+#else  /* defined(_PR_PTHREADS) */
+
+#include "primpl.h"
+
+#include <sys/time.h>
+
+#include <fcntl.h>
+#ifdef _PR_USE_POLL
+#include <poll.h>
+#endif
+
+#if defined(_PR_USE_POLL)
+static PRInt32 NativeThreadPoll(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    /*
+     * This function is mostly duplicated from ptio.s's PR_Poll().
+     */
+    PRInt32 ready = 0;
+    /*
+     * For restarting poll() if it is interrupted by a signal.
+     * We use these variables to figure out how much time has
+     * elapsed and how much of the timeout still remains.
+     */
+    PRIntn index, msecs;
+    struct pollfd *syspoll = NULL;
+    PRIntervalTime start, elapsed, remaining;
+
+    syspoll = (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd));
+    if (NULL == syspoll)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+    for (index = 0; index < npds; ++index)
+    {
+        PRFileDesc *bottom;
+        PRInt16 in_flags_read = 0, in_flags_write = 0;
+        PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+        if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+        {
+            if (pds[index].in_flags & PR_POLL_READ)
+            {
+                in_flags_read = (pds[index].fd->methods->poll)(
+                    pds[index].fd,
+                    pds[index].in_flags & ~PR_POLL_WRITE,
+                    &out_flags_read);
+            }
+            if (pds[index].in_flags & PR_POLL_WRITE)
+            {
+                in_flags_write = (pds[index].fd->methods->poll)(
+                    pds[index].fd,
+                    pds[index].in_flags & ~PR_POLL_READ,
+                    &out_flags_write);
+            }
+            if ((0 != (in_flags_read & out_flags_read))
+            || (0 != (in_flags_write & out_flags_write)))
+            {
+                /* this one is ready right now */
+                if (0 == ready)
+                {
+                    /*
+                     * We will return without calling the system
+                     * poll function.  So zero the out_flags
+                     * fields of all the poll descriptors before
+                     * this one.
+                     */
+                    int i;
+                    for (i = 0; i < index; i++)
+                    {
+                        pds[i].out_flags = 0;
+                    }
+                }
+                ready += 1;
+                pds[index].out_flags = out_flags_read | out_flags_write;
+            }
+            else
+            {
+                pds[index].out_flags = 0;  /* pre-condition */
+                /* now locate the NSPR layer at the bottom of the stack */
+                bottom = PR_GetIdentitiesLayer(pds[index].fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                if ((NULL != bottom)
+                && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                {
+                    if (0 == ready)
+                    {
+                        syspoll[index].fd = bottom->secret->md.osfd;
+                        syspoll[index].events = 0;  /* pre-condition */
+                        if (in_flags_read & PR_POLL_READ)
+                        {
+                            pds[index].out_flags |=
+                                _PR_POLL_READ_SYS_READ;
+                            syspoll[index].events |= POLLIN;
+                        }
+                        if (in_flags_read & PR_POLL_WRITE)
+                        {
+                            pds[index].out_flags |=
+                                _PR_POLL_READ_SYS_WRITE;
+                            syspoll[index].events |= POLLOUT;
+                        }
+                        if (in_flags_write & PR_POLL_READ)
+                        {
+                            pds[index].out_flags |=
+                                _PR_POLL_WRITE_SYS_READ;
+                            syspoll[index].events |= POLLIN;
+                        }
+                        if (in_flags_write & PR_POLL_WRITE)
+                        {
+                            pds[index].out_flags |=
+                                _PR_POLL_WRITE_SYS_WRITE;
+                            syspoll[index].events |= POLLOUT;
+                        }
+                        if (pds[index].in_flags & PR_POLL_EXCEPT)
+                            syspoll[index].events |= POLLPRI;
+                    }
+                }
+                else
+                {
+                    if (0 == ready)
+                    {
+                        int i;
+                        for (i = 0; i < index; i++)
+                        {
+                            pds[i].out_flags = 0;
+                        }
+                    }
+                    ready += 1;  /* this will cause an abrupt return */
+                    pds[index].out_flags = PR_POLL_NVAL;  /* bogii */
+                }
+            }
+        }
+        else
+        {
+            /* make poll() ignore this entry */
+            syspoll[index].fd = -1;
+            syspoll[index].events = 0;
+            pds[index].out_flags = 0;
+        }
+    }
+
+    if (0 == ready)
+    {
+        switch (timeout)
+        {
+            case PR_INTERVAL_NO_WAIT: msecs = 0; break;
+            case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break;
+            default:
+                msecs = PR_IntervalToMilliseconds(timeout);
+                start = PR_IntervalNow();
+        }
+
+retry:
+        ready = _MD_POLL(syspoll, npds, msecs);
+        if (-1 == ready)
+        {
+            PRIntn oserror = errno;
+
+            if (EINTR == oserror)
+            {
+                if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
+                else if (timeout == PR_INTERVAL_NO_WAIT) ready = 0;
+                else
+                {
+                    elapsed = (PRIntervalTime)(PR_IntervalNow() - start);
+                    if (elapsed > timeout) ready = 0;  /* timed out */
+                    else
+                    {
+                        remaining = timeout - elapsed;
+                        msecs = PR_IntervalToMilliseconds(remaining);
+                        goto retry;
+                    }
+                }
+            }
+            else _PR_MD_MAP_POLL_ERROR(oserror);
+        }
+        else if (ready > 0)
+        {
+            for (index = 0; index < npds; ++index)
+            {
+                PRInt16 out_flags = 0;
+                if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+                {
+                    if (0 != syspoll[index].revents)
+                    {
+                        /*
+                        ** Set up the out_flags so that it contains the
+                        ** bits that the highest layer thinks are nice
+                        ** to have. Then the client of that layer will
+                        ** call the appropriate I/O function and maybe
+                        ** the protocol will make progress.
+                        */
+                        if (syspoll[index].revents & POLLIN)
+                        {
+                            if (pds[index].out_flags
+                            & _PR_POLL_READ_SYS_READ)
+                            {
+                                out_flags |= PR_POLL_READ;
+                            }
+                            if (pds[index].out_flags
+                            & _PR_POLL_WRITE_SYS_READ)
+                            {
+                                out_flags |= PR_POLL_WRITE;
+                            }
+                        }
+                        if (syspoll[index].revents & POLLOUT)
+                        {
+                            if (pds[index].out_flags
+                            & _PR_POLL_READ_SYS_WRITE)
+                            {
+                                out_flags |= PR_POLL_READ;
+                            }
+                            if (pds[index].out_flags
+                            & _PR_POLL_WRITE_SYS_WRITE)
+                            {
+                                out_flags |= PR_POLL_WRITE;
+                            }
+                        }
+                        if (syspoll[index].revents & POLLPRI)
+                            out_flags |= PR_POLL_EXCEPT;
+                        if (syspoll[index].revents & POLLERR)
+                            out_flags |= PR_POLL_ERR;
+                        if (syspoll[index].revents & POLLNVAL)
+                            out_flags |= PR_POLL_NVAL;
+                        if (syspoll[index].revents & POLLHUP)
+                            out_flags |= PR_POLL_HUP;
+                    }
+                }
+                pds[index].out_flags = out_flags;
+            }
+        }
+    }
+
+    PR_DELETE(syspoll);
+    return ready;
+
+}  /* NativeThreadPoll */
+#endif  /* defined(_PR_USE_POLL) */
+
+#if !defined(_PR_USE_POLL)
+static PRInt32 NativeThreadSelect(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    /*
+     * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL().
+     */
+    fd_set rd, wt, ex;
+    PRFileDesc *bottom;
+    PRPollDesc *pd, *epd;
+    PRInt32 maxfd = -1, ready, err;
+    PRIntervalTime remaining, elapsed, start;
+
+    struct timeval tv, *tvp = NULL;
+
+    FD_ZERO(&rd);
+    FD_ZERO(&wt);
+    FD_ZERO(&ex);
+
+    ready = 0;
+    for (pd = pds, epd = pd + npds; pd < epd; pd++)
+    {
+        PRInt16 in_flags_read = 0, in_flags_write = 0;
+        PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+        if ((NULL != pd->fd) && (0 != pd->in_flags))
+        {
+            if (pd->in_flags & PR_POLL_READ)
+            {
+                in_flags_read = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
+            }
+            if (pd->in_flags & PR_POLL_WRITE)
+            {
+                in_flags_write = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
+            }
+            if ((0 != (in_flags_read & out_flags_read))
+            || (0 != (in_flags_write & out_flags_write)))
+            {
+                /* this one's ready right now */
+                if (0 == ready)
+                {
+                    /*
+                     * We will have to return without calling the
+                     * system poll/select function.  So zero the
+                     * out_flags fields of all the poll descriptors
+                     * before this one.
+                     */
+                    PRPollDesc *prev;
+                    for (prev = pds; prev < pd; prev++)
+                    {
+                        prev->out_flags = 0;
+                    }
+                }
+                ready += 1;
+                pd->out_flags = out_flags_read | out_flags_write;
+            }
+            else
+            {
+                pd->out_flags = 0;  /* pre-condition */
+
+                /* make sure this is an NSPR supported stack */
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                if ((NULL != bottom)
+                && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                {
+                    if (0 == ready)
+                    {
+                        PRInt32 osfd = bottom->secret->md.osfd;
+                        if (osfd > maxfd) maxfd = osfd;
+                        if (in_flags_read & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
+                            FD_SET(osfd, &rd);
+                        }
+                        if (in_flags_read & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
+                            FD_SET(osfd, &wt);
+                        }
+                        if (in_flags_write & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
+                            FD_SET(osfd, &rd);
+                        }
+                        if (in_flags_write & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
+                            FD_SET(osfd, &wt);
+                        }
+                        if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);
+                    }
+                }
+                else
+                {
+                    if (0 == ready)
+                    {
+                        PRPollDesc *prev;
+                        for (prev = pds; prev < pd; prev++)
+                        {
+                            prev->out_flags = 0;
+                        }
+                    }
+                    ready += 1;  /* this will cause an abrupt return */
+                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
+                }
+            }
+        }
+        else
+        {
+            pd->out_flags = 0;
+        }
+    }
+
+    if (0 != ready) return ready;  /* no need to block */
+
+    remaining = timeout;
+    start = PR_IntervalNow();
+
+retry:
+    if (timeout != PR_INTERVAL_NO_TIMEOUT)
+    {
+        PRInt32 ticksPerSecond = PR_TicksPerSecond();
+        tv.tv_sec = remaining / ticksPerSecond;
+        tv.tv_usec = PR_IntervalToMicroseconds( remaining % ticksPerSecond );
+        tvp = &tv;
+    }
+
+    ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);
+
+    if (ready == -1 && errno == EINTR)
+    {
+        if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;
+        else
+        {
+            elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
+            if (elapsed > timeout) ready = 0;  /* timed out */
+            else
+            {
+                remaining = timeout - elapsed;
+                goto retry;
+            }
+        }
+    }
+
+    /*
+    ** Now to unravel the select sets back into the client's poll
+    ** descriptor list. Is this possibly an area for pissing away
+    ** a few cycles or what?
+    */
+    if (ready > 0)
+    {
+        ready = 0;
+        for (pd = pds, epd = pd + npds; pd < epd; pd++)
+        {
+            PRInt16 out_flags = 0;
+            if ((NULL != pd->fd) && (0 != pd->in_flags))
+            {
+                PRInt32 osfd;
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);
+
+                osfd = bottom->secret->md.osfd;
+
+                if (FD_ISSET(osfd, &rd))
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+                if (FD_ISSET(osfd, &wt))
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+                if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
+            }
+            pd->out_flags = out_flags;
+            if (out_flags) ready++;
+        }
+        PR_ASSERT(ready > 0);
+    }
+    else if (ready < 0)
+    {
+        err = _MD_ERRNO();
+        if (err == EBADF)
+        {
+            /* Find the bad fds */
+            ready = 0;
+            for (pd = pds, epd = pd + npds; pd < epd; pd++)
+            {
+                pd->out_flags = 0;
+                if ((NULL != pd->fd) && (0 != pd->in_flags))
+                {
+                    bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                    if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)
+                    {
+                        pd->out_flags = PR_POLL_NVAL;
+                        ready++;
+                    }
+                }
+            }
+            PR_ASSERT(ready > 0);
+        }
+        else _PR_MD_MAP_SELECT_ERROR(err);
+    }
+
+    return ready;
+}  /* NativeThreadSelect */
+#endif  /* !defined(_PR_USE_POLL) */
+
+static PRInt32 LocalThreads(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    PRPollDesc *pd, *epd;
+    PRInt32 ready, pdcnt;
+    _PRUnixPollDesc *unixpds, *unixpd;
+
+    /*
+     * XXX
+     *        PRPollDesc has a PRFileDesc field, fd, while the IOQ
+     *        is a list of PRPollQueue structures, each of which contains
+     *        a _PRUnixPollDesc. A _PRUnixPollDesc struct contains
+     *        the OS file descriptor, osfd, and not a PRFileDesc.
+     *        So, we have allocate memory for _PRUnixPollDesc structures,
+     *        copy the flags information from the pds list and have pq
+     *        point to this list of _PRUnixPollDesc structures.
+     *
+     *        It would be better if the memory allocation can be avoided.
+     */
+
+    unixpd = unixpds = (_PRUnixPollDesc*)
+        PR_MALLOC(npds * sizeof(_PRUnixPollDesc));
+    if (NULL == unixpds)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+
+    ready = 0;
+    for (pdcnt = 0, pd = pds, epd = pd + npds; pd < epd; pd++)
+    {
+        PRFileDesc *bottom;
+        PRInt16 in_flags_read = 0, in_flags_write = 0;
+        PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+        if ((NULL != pd->fd) && (0 != pd->in_flags))
+        {
+            if (pd->in_flags & PR_POLL_READ)
+            {
+                in_flags_read = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);
+            }
+            if (pd->in_flags & PR_POLL_WRITE)
+            {
+                in_flags_write = (pd->fd->methods->poll)(
+                    pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);
+            }
+            if ((0 != (in_flags_read & out_flags_read))
+            || (0 != (in_flags_write & out_flags_write)))
+            {
+                /* this one's ready right now */
+                if (0 == ready)
+                {
+                    /*
+                     * We will have to return without calling the
+                     * system poll/select function.  So zero the
+                     * out_flags fields of all the poll descriptors
+                     * before this one.
+                     */
+                    PRPollDesc *prev;
+                    for (prev = pds; prev < pd; prev++)
+                    {
+                        prev->out_flags = 0;
+                    }
+                }
+                ready += 1;
+                pd->out_flags = out_flags_read | out_flags_write;
+            }
+            else
+            {
+                pd->out_flags = 0;  /* pre-condition */
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                if ((NULL != bottom)
+                && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                {
+                    if (0 == ready)
+                    {
+                        unixpd->osfd = bottom->secret->md.osfd;
+                        unixpd->in_flags = 0;
+                        if (in_flags_read & PR_POLL_READ)
+                        {
+                            unixpd->in_flags |= _PR_UNIX_POLL_READ;
+                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
+                        }
+                        if (in_flags_read & PR_POLL_WRITE)
+                        {
+                            unixpd->in_flags |= _PR_UNIX_POLL_WRITE;
+                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
+                        }
+                        if (in_flags_write & PR_POLL_READ)
+                        {
+                            unixpd->in_flags |= _PR_UNIX_POLL_READ;
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
+                        }
+                        if (in_flags_write & PR_POLL_WRITE)
+                        {
+                            unixpd->in_flags |= _PR_UNIX_POLL_WRITE;
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
+                        }
+                        if ((in_flags_read | in_flags_write) & PR_POLL_EXCEPT)
+                        {
+                            unixpd->in_flags |= _PR_UNIX_POLL_EXCEPT;
+                        }
+                        unixpd++; pdcnt++;
+                    }
+                }
+                else
+                {
+                    if (0 == ready)
+                    {
+                        PRPollDesc *prev;
+                        for (prev = pds; prev < pd; prev++)
+                        {
+                            prev->out_flags = 0;
+                        }
+                    }
+                    ready += 1;  /* this will cause an abrupt return */
+                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
+                }
+            }
+        }
+    }
+
+    if (0 != ready)
+    {
+        /* no need to block */
+        PR_DELETE(unixpds);
+        return ready;
+    }
+
+    ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout);
+
+    /*
+     * Copy the out_flags from the _PRUnixPollDesc structures to the
+     * user's PRPollDesc structures and free the allocated memory
+     */
+    unixpd = unixpds;
+    for (pd = pds, epd = pd + npds; pd < epd; pd++)
+    {
+        PRInt16 out_flags = 0;
+        if ((NULL != pd->fd) && (0 != pd->in_flags))
+        {
+            /*
+             * take errors from the poll operation,
+             * the R/W bits from the request
+             */
+            if (0 != unixpd->out_flags)
+            {
+                if (unixpd->out_flags & _PR_UNIX_POLL_READ)
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
+                        out_flags |= PR_POLL_WRITE;
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_WRITE)
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
+                        out_flags |= PR_POLL_WRITE;
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT)
+                    out_flags |= PR_POLL_EXCEPT;
+                if (unixpd->out_flags & _PR_UNIX_POLL_ERR)
+                    out_flags |= PR_POLL_ERR;
+                if (unixpd->out_flags & _PR_UNIX_POLL_NVAL)
+                    out_flags |= PR_POLL_NVAL;
+                if (unixpd->out_flags & _PR_UNIX_POLL_HUP)
+                    out_flags |= PR_POLL_HUP;
+            }
+            unixpd++;
+        }
+        pd->out_flags = out_flags;
+    }
+
+    PR_DELETE(unixpds);
+
+    return ready;
+}  /* LocalThreads */
+
+#if defined(_PR_USE_POLL)
+#define NativeThreads NativeThreadPoll
+#else
+#define NativeThreads NativeThreadSelect
+#endif
+
+PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    PRInt32 rv = 0;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (_PR_PENDING_INTERRUPT(me))
+    {
+        me->flags &= ~_PR_INTERRUPT;
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        return -1;
+    }
+    if (0 == npds) PR_Sleep(timeout);
+    else if (_PR_IS_NATIVE_THREAD(me))
+        rv = NativeThreads(pds, npds, timeout);
+    else rv = LocalThreads(pds, npds, timeout);
+
+    return rv;
+}  /* _MD_pr_poll */
+
+#endif  /* defined(_PR_PTHREADS) */               
+
+/* uxpoll.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxproces.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxproces.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,991 @@
+/* -*- 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 <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/wait.h>
+#if defined(AIX)
+#include <dlfcn.h>  /* For dlopen, dlsym, dlclose */
+#endif
+
+#if defined(DARWIN)
+#include <crt_externs.h>
+#else
+PR_IMPORT_DATA(char **) environ;
+#endif
+
+/*
+ * HP-UX 9 doesn't have the SA_RESTART flag.
+ */
+#ifndef SA_RESTART
+#define SA_RESTART 0
+#endif
+
+#if defined(VMS)
+static PRLock *_pr_vms_fork_lock = NULL;
+#endif
+
+/*
+ **********************************************************************
+ *
+ * The Unix process routines
+ *
+ **********************************************************************
+ */
+
+#define _PR_SIGNALED_EXITSTATUS 256
+
+typedef enum pr_PidState {
+    _PR_PID_DETACHED,
+    _PR_PID_REAPED,
+    _PR_PID_WAITING
+} pr_PidState;
+
+typedef struct pr_PidRecord {
+    pid_t pid;
+    int exitStatus;
+    pr_PidState state;
+    PRCondVar *reapedCV;
+    struct pr_PidRecord *next;
+} pr_PidRecord;
+
+/*
+ * Irix sprocs and LinuxThreads are actually a kind of processes
+ * that can share the virtual address space and file descriptors.
+ */
+#if (defined(IRIX) && !defined(_PR_PTHREADS)) \
+        || ((defined(LINUX) || defined(__GNU__) || defined(__GLIBC__)) \
+        && defined(_PR_PTHREADS))
+#define _PR_SHARE_CLONES
+#endif
+
+/*
+ * The macro _PR_NATIVE_THREADS indicates that we are
+ * using native threads only, so waitpid() blocks just the
+ * calling thread, not the process.  In this case, the waitpid
+ * daemon thread can safely block in waitpid().  So we don't
+ * need to catch SIGCHLD, and the pipe to unblock PR_Poll() is
+ * also not necessary.
+ */
+
+#if defined(_PR_GLOBAL_THREADS_ONLY) \
+	|| (defined(_PR_PTHREADS) \
+	&& !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__))
+#define _PR_NATIVE_THREADS
+#endif
+
+/*
+ * All the static variables used by the Unix process routines are
+ * collected in this structure.
+ */
+
+static struct {
+    PRCallOnceType once;
+    PRThread *thread;
+    PRLock *ml;
+#if defined(_PR_NATIVE_THREADS)
+    PRInt32 numProcs;
+    PRCondVar *cv;
+#else
+    int pipefd[2];
+#endif
+    pr_PidRecord **pidTable;
+
+#ifdef _PR_SHARE_CLONES
+    struct pr_CreateProcOp *opHead, *opTail;
+#endif
+
+#ifdef AIX
+    pid_t (*forkptr)(void);  /* Newer versions of AIX (starting in 4.3.2)
+                              * have f_fork, which is faster than the
+                              * regular fork in a multithreaded process
+                              * because it skips calling the fork handlers.
+                              * So we look up the f_fork symbol to see if
+                              * it's available and fall back on fork.
+                              */
+#endif /* AIX */
+} pr_wp;
+
+#ifdef _PR_SHARE_CLONES
+static int pr_waitpid_daemon_exit;
+
+void
+_MD_unix_terminate_waitpid_daemon(void)
+{
+    if (pr_wp.thread) {
+        pr_waitpid_daemon_exit = 1;
+        write(pr_wp.pipefd[1], "", 1);
+        PR_JoinThread(pr_wp.thread);
+    }
+}
+#endif
+
+static PRStatus _MD_InitProcesses(void);
+#if !defined(_PR_NATIVE_THREADS)
+static void pr_InstallSigchldHandler(void);
+#endif
+
+static PRProcess *
+ForkAndExec(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    PRProcess *process;
+    int nEnv, idx;
+    char *const *childEnvp;
+    char **newEnvp = NULL;
+    int flags;
+#ifdef VMS
+    char VMScurdir[FILENAME_MAX+1] = { '\0' } ;
+#endif	
+
+    process = PR_NEW(PRProcess);
+    if (!process) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+
+    childEnvp = envp;
+    if (attr && attr->fdInheritBuffer) {
+        if (NULL == childEnvp) {
+#ifdef DARWIN
+            childEnvp = *(_NSGetEnviron());
+#else
+            childEnvp = environ;
+#endif
+        }
+        for (nEnv = 0; childEnvp[nEnv]; nEnv++) {
+        }
+        newEnvp = (char **) PR_MALLOC((nEnv + 2) * sizeof(char *));
+        if (NULL == newEnvp) {
+            PR_DELETE(process);
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return NULL;
+        }
+        for (idx = 0; idx < nEnv; idx++) {
+            newEnvp[idx] = childEnvp[idx];
+        }
+        newEnvp[idx++] = attr->fdInheritBuffer;
+        newEnvp[idx] = NULL;
+        childEnvp = newEnvp;
+    }
+
+#ifdef VMS
+/*
+** Since vfork/exec is implemented VERY differently on OpenVMS, we have to
+** handle the setting up of the standard streams very differently. And since
+** none of this code can ever execute in the context of the child, we have
+** to perform the chdir in the parent so the child is born into the correct
+** directory (and then switch the parent back again).
+*/
+{
+    int decc$set_child_standard_streams(int,int,int);
+    int n, fd_stdin=0, fd_stdout=1, fd_stderr=2;
+
+    /* Set up any standard streams we are given, assuming defaults */
+    if (attr) {
+       if (attr->stdinFd)
+           fd_stdin = attr->stdinFd->secret->md.osfd;
+       if (attr->stdoutFd)
+           fd_stdout = attr->stdoutFd->secret->md.osfd;
+       if (attr->stderrFd)
+           fd_stderr = attr->stderrFd->secret->md.osfd;
+    }
+
+    /*
+    ** Put a lock around anything that isn't going to be thread-safe.
+    */
+    PR_Lock(_pr_vms_fork_lock);
+
+    /*
+    ** Prepare the child's streams. We always do this in case a previous fork
+    ** has left the stream assignments in some non-standard way.
+    */
+    n = decc$set_child_standard_streams(fd_stdin,fd_stdout,fd_stderr);
+    if (n == -1) {
+       PR_SetError(PR_BAD_DESCRIPTOR_ERROR, errno);
+       PR_DELETE(process);
+       if (newEnvp) {
+           PR_DELETE(newEnvp);
+       }
+       PR_Unlock(_pr_vms_fork_lock);
+       return NULL;
+    }
+
+    /* Switch directory if we have to */
+    if (attr) {
+       if (attr->currentDirectory) {
+           if ( (getcwd(VMScurdir,sizeof(VMScurdir)) == NULL) ||
+                (chdir(attr->currentDirectory) < 0) ) {
+               PR_SetError(PR_DIRECTORY_OPEN_ERROR, errno);
+               PR_DELETE(process);
+               if (newEnvp) {
+                   PR_DELETE(newEnvp);
+               }
+               PR_Unlock(_pr_vms_fork_lock);
+               return NULL;
+           }
+       }
+    }
+}
+#endif /* VMS */
+
+#ifdef AIX
+    process->md.pid = (*pr_wp.forkptr)();
+#elif defined(NTO)
+    /*
+     * fork() & exec() does not work in a multithreaded process.
+     * Use spawn() instead.
+     */
+    {
+        int fd_map[3] = { 0, 1, 2 };
+
+        if (attr) {
+            if (attr->stdinFd && attr->stdinFd->secret->md.osfd != 0) {
+                fd_map[0] = dup(attr->stdinFd->secret->md.osfd);
+                flags = fcntl(fd_map[0], F_GETFL, 0);
+                if (flags & O_NONBLOCK)
+                    fcntl(fd_map[0], F_SETFL, flags & ~O_NONBLOCK);
+            }
+            if (attr->stdoutFd && attr->stdoutFd->secret->md.osfd != 1) {
+                fd_map[1] = dup(attr->stdoutFd->secret->md.osfd);
+                flags = fcntl(fd_map[1], F_GETFL, 0);
+                if (flags & O_NONBLOCK)
+                    fcntl(fd_map[1], F_SETFL, flags & ~O_NONBLOCK);
+            }
+            if (attr->stderrFd && attr->stderrFd->secret->md.osfd != 2) {
+                fd_map[2] = dup(attr->stderrFd->secret->md.osfd);
+                flags = fcntl(fd_map[2], F_GETFL, 0);
+                if (flags & O_NONBLOCK)
+                    fcntl(fd_map[2], F_SETFL, flags & ~O_NONBLOCK);
+            }
+
+            PR_ASSERT(attr->currentDirectory == NULL);  /* not implemented */
+        }
+
+        process->md.pid = spawn(path, 3, fd_map, NULL, argv, childEnvp);
+
+        if (fd_map[0] != 0)
+            close(fd_map[0]);
+        if (fd_map[1] != 1)
+            close(fd_map[1]);
+        if (fd_map[2] != 2)
+            close(fd_map[2]);
+    }
+#else
+    process->md.pid = fork();
+#endif
+    if ((pid_t) -1 == process->md.pid) {
+        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, errno);
+        PR_DELETE(process);
+        if (newEnvp) {
+            PR_DELETE(newEnvp);
+        }
+        return NULL;
+    } else if (0 == process->md.pid) {  /* the child process */
+        /*
+         * If the child process needs to exit, it must call _exit().
+         * Do not call exit(), because exit() will flush and close
+         * the standard I/O file descriptors, and hence corrupt
+         * the parent process's standard I/O data structures.
+         */
+
+#if !defined(NTO)
+#ifdef VMS
+       /* OpenVMS has already handled all this above */
+#else
+        if (attr) {
+            /* the osfd's to redirect stdin, stdout, and stderr to */
+            int in_osfd = -1, out_osfd = -1, err_osfd = -1;
+
+            if (attr->stdinFd
+                    && attr->stdinFd->secret->md.osfd != 0) {
+                in_osfd = attr->stdinFd->secret->md.osfd;
+                if (dup2(in_osfd, 0) != 0) {
+                    _exit(1);  /* failed */
+                }
+                flags = fcntl(0, F_GETFL, 0);
+                if (flags & O_NONBLOCK) {
+                    fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
+                }
+            }
+            if (attr->stdoutFd
+                    && attr->stdoutFd->secret->md.osfd != 1) {
+                out_osfd = attr->stdoutFd->secret->md.osfd;
+                if (dup2(out_osfd, 1) != 1) {
+                    _exit(1);  /* failed */
+                }
+                flags = fcntl(1, F_GETFL, 0);
+                if (flags & O_NONBLOCK) {
+                    fcntl(1, F_SETFL, flags & ~O_NONBLOCK);
+                }
+            }
+            if (attr->stderrFd
+                    && attr->stderrFd->secret->md.osfd != 2) {
+                err_osfd = attr->stderrFd->secret->md.osfd;
+                if (dup2(err_osfd, 2) != 2) {
+                    _exit(1);  /* failed */
+                }
+                flags = fcntl(2, F_GETFL, 0);
+                if (flags & O_NONBLOCK) {
+                    fcntl(2, F_SETFL, flags & ~O_NONBLOCK);
+                }
+            }
+            if (in_osfd != -1) {
+                close(in_osfd);
+            }
+            if (out_osfd != -1 && out_osfd != in_osfd) {
+                close(out_osfd);
+            }
+            if (err_osfd != -1 && err_osfd != in_osfd
+                    && err_osfd != out_osfd) {
+                close(err_osfd);
+            }
+            if (attr->currentDirectory) {
+                if (chdir(attr->currentDirectory) < 0) {
+                    _exit(1);  /* failed */
+                }
+            }
+        }
+#endif /* !VMS */
+
+        if (childEnvp) {
+            (void)execve(path, argv, childEnvp);
+        } else {
+            /* Inherit the environment of the parent. */
+            (void)execv(path, argv);
+        }
+        /* Whoops! It returned. That's a bad sign. */
+#ifdef VMS
+       /*
+       ** On OpenVMS we are still in the context of the parent, and so we
+       ** can (and should!) perform normal error handling.
+       */
+       PR_SetError(PR_UNKNOWN_ERROR, errno);
+       PR_DELETE(process);
+       if (newEnvp) {
+           PR_DELETE(newEnvp);
+       }
+       if (VMScurdir[0] != '\0')
+           chdir(VMScurdir);
+       PR_Unlock(_pr_vms_fork_lock);
+       return NULL;
+#else
+        _exit(1);
+#endif /* VMS */
+#endif /* !NTO */
+    }
+
+    if (newEnvp) {
+        PR_DELETE(newEnvp);
+    }
+#ifdef VMS
+    /* If we switched directories, then remember to switch back */
+    if (VMScurdir[0] != '\0') {
+       chdir(VMScurdir); /* can't do much if it fails */
+    }
+    PR_Unlock(_pr_vms_fork_lock);
+#endif /* VMS */
+
+#if defined(_PR_NATIVE_THREADS)
+    PR_Lock(pr_wp.ml);
+    if (0 == pr_wp.numProcs++) {
+        PR_NotifyCondVar(pr_wp.cv);
+    }
+    PR_Unlock(pr_wp.ml);
+#endif
+    return process;
+}
+
+#ifdef _PR_SHARE_CLONES
+
+struct pr_CreateProcOp {
+    const char *path;
+    char *const *argv;
+    char *const *envp;
+    const PRProcessAttr *attr;
+    PRProcess *process;
+    PRErrorCode prerror;
+    PRInt32 oserror;
+    PRBool done;
+    PRCondVar *doneCV;
+    struct pr_CreateProcOp *next;
+};
+
+PRProcess *
+_MD_CreateUnixProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    struct pr_CreateProcOp *op;
+    PRProcess *proc;
+    int rv;
+
+    if (PR_CallOnce(&pr_wp.once, _MD_InitProcesses) == PR_FAILURE) {
+	return NULL;
+    }
+
+    op = PR_NEW(struct pr_CreateProcOp);
+    if (NULL == op) {
+	PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	return NULL;
+    }
+    op->path = path;
+    op->argv = argv;
+    op->envp = envp;
+    op->attr = attr;
+    op->done = PR_FALSE;
+    op->doneCV = PR_NewCondVar(pr_wp.ml);
+    if (NULL == op->doneCV) {
+	PR_DELETE(op);
+	return NULL;
+    }
+    PR_Lock(pr_wp.ml);
+
+    /* add to the tail of op queue */
+    op->next = NULL;
+    if (pr_wp.opTail) {
+	pr_wp.opTail->next = op;
+	pr_wp.opTail = op;
+    } else {
+	PR_ASSERT(NULL == pr_wp.opHead);
+	pr_wp.opHead = pr_wp.opTail = op;
+    }
+
+    /* wake up the daemon thread */
+    do {
+        rv = write(pr_wp.pipefd[1], "", 1);
+    } while (-1 == rv && EINTR == errno);
+
+    while (op->done == PR_FALSE) {
+	PR_WaitCondVar(op->doneCV, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(pr_wp.ml);
+    PR_DestroyCondVar(op->doneCV);
+    proc = op->process;
+    if (!proc) {
+	PR_SetError(op->prerror, op->oserror);
+    }
+    PR_DELETE(op);
+    return proc;
+}
+
+#else  /* ! _PR_SHARE_CLONES */
+
+PRProcess *
+_MD_CreateUnixProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    if (PR_CallOnce(&pr_wp.once, _MD_InitProcesses) == PR_FAILURE) {
+	return NULL;
+    }
+    return ForkAndExec(path, argv, envp, attr);
+}  /* _MD_CreateUnixProcess */
+
+#endif  /* _PR_SHARE_CLONES */
+
+/*
+ * The pid table is a hashtable.
+ *
+ * The number of buckets in the hashtable (NBUCKETS) must be a power of 2.
+ */
+#define NBUCKETS_LOG2 6
+#define NBUCKETS (1 << NBUCKETS_LOG2)
+#define PID_HASH_MASK ((pid_t) (NBUCKETS - 1))
+
+static pr_PidRecord *
+FindPidTable(pid_t pid)
+{
+    pr_PidRecord *pRec;
+    int keyHash = (int) (pid & PID_HASH_MASK);
+
+    pRec =  pr_wp.pidTable[keyHash];
+    while (pRec) {
+	if (pRec->pid == pid) {
+	    break;
+	}
+	pRec = pRec->next;
+    }
+    return pRec;
+}
+
+static void
+InsertPidTable(pr_PidRecord *pRec)
+{
+    int keyHash = (int) (pRec->pid & PID_HASH_MASK);
+
+    pRec->next = pr_wp.pidTable[keyHash];
+    pr_wp.pidTable[keyHash] = pRec;
+}
+
+static void
+DeletePidTable(pr_PidRecord *pRec)
+{
+    int keyHash = (int) (pRec->pid & PID_HASH_MASK);
+
+    if (pr_wp.pidTable[keyHash] == pRec) {
+	pr_wp.pidTable[keyHash] = pRec->next;
+    } else {
+	pr_PidRecord *pred, *cur;  /* predecessor and current */
+
+	pred = pr_wp.pidTable[keyHash];
+	cur = pred->next;
+	while (cur) {
+	    if (cur == pRec) {
+		pred->next = cur->next;
+		break;
+            }
+	    pred = cur;
+	    cur = cur->next;
+        }
+	PR_ASSERT(cur != NULL);
+    }
+}
+
+static int
+ExtractExitStatus(int rawExitStatus)
+{
+    /*
+     * We did not specify the WCONTINUED and WUNTRACED options
+     * for waitpid, so these two events should not be reported.
+     */
+    PR_ASSERT(!WIFSTOPPED(rawExitStatus));
+#ifdef WIFCONTINUED
+    PR_ASSERT(!WIFCONTINUED(rawExitStatus));
+#endif
+    if (WIFEXITED(rawExitStatus)) {
+	return WEXITSTATUS(rawExitStatus);
+    } else {
+	PR_ASSERT(WIFSIGNALED(rawExitStatus));
+	return _PR_SIGNALED_EXITSTATUS;
+    }
+}
+
+static void
+ProcessReapedChildInternal(pid_t pid, int status)
+{
+    pr_PidRecord *pRec;
+
+    pRec = FindPidTable(pid);
+    if (NULL == pRec) {
+        pRec = PR_NEW(pr_PidRecord);
+        pRec->pid = pid;
+        pRec->state = _PR_PID_REAPED;
+        pRec->exitStatus = ExtractExitStatus(status);
+        pRec->reapedCV = NULL;
+        InsertPidTable(pRec);
+    } else {
+        PR_ASSERT(pRec->state != _PR_PID_REAPED);
+        if (_PR_PID_DETACHED == pRec->state) {
+            PR_ASSERT(NULL == pRec->reapedCV);
+            DeletePidTable(pRec);
+            PR_DELETE(pRec);
+        } else {
+            PR_ASSERT(_PR_PID_WAITING == pRec->state);
+            PR_ASSERT(NULL != pRec->reapedCV);
+            pRec->exitStatus = ExtractExitStatus(status);
+            pRec->state = _PR_PID_REAPED;
+            PR_NotifyCondVar(pRec->reapedCV);
+        }
+    }
+}
+
+#if defined(_PR_NATIVE_THREADS)
+
+/*
+ * If all the threads are native threads, the daemon thread is
+ * simpler.  We don't need to catch the SIGCHLD signal.  We can
+ * just have the daemon thread block in waitpid().
+ */
+
+static void WaitPidDaemonThread(void *unused)
+{
+    pid_t pid;
+    int status;
+
+    while (1) {
+        PR_Lock(pr_wp.ml);
+        while (0 == pr_wp.numProcs) {
+            PR_WaitCondVar(pr_wp.cv, PR_INTERVAL_NO_TIMEOUT);
+        }
+        PR_Unlock(pr_wp.ml);
+
+	while (1) {
+	    do {
+	        pid = waitpid((pid_t) -1, &status, 0);
+	    } while ((pid_t) -1 == pid && EINTR == errno);
+
+            /*
+             * waitpid() cannot return 0 because we did not invoke it
+             * with the WNOHANG option.
+             */ 
+	    PR_ASSERT(0 != pid);
+
+            /*
+             * The only possible error code is ECHILD.  But if we do
+             * our accounting correctly, we should only call waitpid()
+             * when there is a child process to wait for.
+             */
+            PR_ASSERT((pid_t) -1 != pid);
+	    if ((pid_t) -1 == pid) {
+                break;
+            }
+
+	    PR_Lock(pr_wp.ml);
+            ProcessReapedChildInternal(pid, status);
+            pr_wp.numProcs--;
+            while (0 == pr_wp.numProcs) {
+                PR_WaitCondVar(pr_wp.cv, PR_INTERVAL_NO_TIMEOUT);
+            }
+	    PR_Unlock(pr_wp.ml);
+	}
+    }
+}
+
+#else /* _PR_NATIVE_THREADS */
+
+static void WaitPidDaemonThread(void *unused)
+{
+    PRPollDesc pd;
+    PRFileDesc *fd;
+    int rv;
+    char buf[128];
+    pid_t pid;
+    int status;
+#ifdef _PR_SHARE_CLONES
+    struct pr_CreateProcOp *op;
+#endif
+
+#ifdef _PR_SHARE_CLONES
+    pr_InstallSigchldHandler();
+#endif
+
+    fd = PR_ImportFile(pr_wp.pipefd[0]);
+    PR_ASSERT(NULL != fd);
+    pd.fd = fd;
+    pd.in_flags = PR_POLL_READ;
+
+    while (1) {
+        rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+        PR_ASSERT(1 == rv);
+
+#ifdef _PR_SHARE_CLONES
+        if (pr_waitpid_daemon_exit) {
+            return;
+        }
+	PR_Lock(pr_wp.ml);
+#endif
+	    
+        do {
+            rv = read(pr_wp.pipefd[0], buf, sizeof(buf));
+        } while (sizeof(buf) == rv || (-1 == rv && EINTR == errno));
+
+#ifdef _PR_SHARE_CLONES
+	PR_Unlock(pr_wp.ml);
+	while ((op = pr_wp.opHead) != NULL) {
+	    op->process = ForkAndExec(op->path, op->argv,
+		    op->envp, op->attr);
+	    if (NULL == op->process) {
+		op->prerror = PR_GetError();
+		op->oserror = PR_GetOSError();
+	    }
+	    PR_Lock(pr_wp.ml);
+	    pr_wp.opHead = op->next;
+	    if (NULL == pr_wp.opHead) {
+		pr_wp.opTail = NULL;
+	    }
+	    op->done = PR_TRUE;
+	    PR_NotifyCondVar(op->doneCV);
+	    PR_Unlock(pr_wp.ml);
+	}
+#endif
+
+	while (1) {
+	    do {
+	        pid = waitpid((pid_t) -1, &status, WNOHANG);
+	    } while ((pid_t) -1 == pid && EINTR == errno);
+	    if (0 == pid) break;
+	    if ((pid_t) -1 == pid) {
+		/* must be because we have no child processes */
+		PR_ASSERT(ECHILD == errno);
+		break;
+            }
+
+	    PR_Lock(pr_wp.ml);
+            ProcessReapedChildInternal(pid, status);
+	    PR_Unlock(pr_wp.ml);
+	}
+    }
+}
+
+static void pr_SigchldHandler(int sig)
+{
+    int errnoCopy;
+    int rv;
+
+    errnoCopy = errno;
+
+    do {
+        rv = write(pr_wp.pipefd[1], "", 1);
+    } while (-1 == rv && EINTR == errno);
+
+#ifdef DEBUG
+    if (-1 == rv && EAGAIN != errno && EWOULDBLOCK != errno) {
+        char *msg = "cannot write to pipe\n";
+        write(2, msg, strlen(msg) + 1);
+        _exit(1);
+    }
+#endif
+
+    errno = errnoCopy;
+}
+
+static void pr_InstallSigchldHandler()
+{
+#if defined(HPUX) && defined(_PR_DCETHREADS)
+#error "HP-UX DCE threads have their own SIGCHLD handler"
+#endif
+
+    struct sigaction act, oact;
+    int rv;
+
+    act.sa_handler = pr_SigchldHandler;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_NOCLDSTOP | SA_RESTART;
+    rv = sigaction(SIGCHLD, &act, &oact);
+    PR_ASSERT(0 == rv);
+    /* Make sure we are not overriding someone else's SIGCHLD handler */
+#ifndef _PR_SHARE_CLONES
+    PR_ASSERT(oact.sa_handler == SIG_DFL);
+#endif
+}
+
+#endif  /* !defined(_PR_NATIVE_THREADS) */
+
+static PRStatus _MD_InitProcesses(void)
+{
+#if !defined(_PR_NATIVE_THREADS)
+    int rv;
+    int flags;
+#endif
+#ifdef SUNOS4
+#define _PR_NBIO_FLAG FNDELAY
+#else
+#define _PR_NBIO_FLAG O_NONBLOCK
+#endif
+
+#ifdef AIX
+    {
+        void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL);
+        pr_wp.forkptr = (pid_t (*)(void)) dlsym(handle, "f_fork");
+        if (!pr_wp.forkptr) {
+            pr_wp.forkptr = fork;
+        }
+        dlclose(handle);
+    }
+#endif /* AIX */
+
+    pr_wp.ml = PR_NewLock();
+    PR_ASSERT(NULL != pr_wp.ml);
+
+#if defined(VMS)
+    _pr_vms_fork_lock = PR_NewLock();
+    PR_ASSERT(NULL != _pr_vms_fork_lock);
+#endif
+
+#if defined(_PR_NATIVE_THREADS)
+    pr_wp.numProcs = 0;
+    pr_wp.cv = PR_NewCondVar(pr_wp.ml);
+    PR_ASSERT(NULL != pr_wp.cv);
+#else
+    rv = pipe(pr_wp.pipefd);
+    PR_ASSERT(0 == rv);
+    flags = fcntl(pr_wp.pipefd[0], F_GETFL, 0);
+    fcntl(pr_wp.pipefd[0], F_SETFL, flags | _PR_NBIO_FLAG);
+    flags = fcntl(pr_wp.pipefd[1], F_GETFL, 0);
+    fcntl(pr_wp.pipefd[1], F_SETFL, flags | _PR_NBIO_FLAG);
+
+#ifndef _PR_SHARE_CLONES
+    pr_InstallSigchldHandler();
+#endif
+#endif  /* !_PR_NATIVE_THREADS */
+
+    pr_wp.thread = PR_CreateThread(PR_SYSTEM_THREAD,
+	    WaitPidDaemonThread, NULL, PR_PRIORITY_NORMAL,
+#ifdef _PR_SHARE_CLONES
+            PR_GLOBAL_THREAD,
+#else
+	    PR_LOCAL_THREAD,
+#endif
+	    PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(NULL != pr_wp.thread);
+
+    pr_wp.pidTable = (pr_PidRecord**)PR_CALLOC(NBUCKETS * sizeof(pr_PidRecord *));
+    PR_ASSERT(NULL != pr_wp.pidTable);
+    return PR_SUCCESS;
+}
+
+PRStatus _MD_DetachUnixProcess(PRProcess *process)
+{
+    PRStatus retVal = PR_SUCCESS;
+    pr_PidRecord *pRec;
+
+    PR_Lock(pr_wp.ml);
+    pRec = FindPidTable(process->md.pid);
+    if (NULL == pRec) {
+	pRec = PR_NEW(pr_PidRecord);
+	if (NULL == pRec) {
+	    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	    retVal = PR_FAILURE;
+	    goto done;
+	}
+	pRec->pid = process->md.pid;
+	pRec->state = _PR_PID_DETACHED;
+	pRec->reapedCV = NULL;
+	InsertPidTable(pRec);
+    } else {
+	PR_ASSERT(_PR_PID_REAPED == pRec->state);
+	if (_PR_PID_REAPED != pRec->state) {
+	    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+	    retVal = PR_FAILURE;
+	} else {
+	    DeletePidTable(pRec);
+	    PR_ASSERT(NULL == pRec->reapedCV);
+	    PR_DELETE(pRec);
+	}
+    }
+    PR_DELETE(process);
+
+done:
+    PR_Unlock(pr_wp.ml);
+    return retVal;
+}
+
+PRStatus _MD_WaitUnixProcess(
+    PRProcess *process,
+    PRInt32 *exitCode)
+{
+    pr_PidRecord *pRec;
+    PRStatus retVal = PR_SUCCESS;
+    PRBool interrupted = PR_FALSE;
+
+    PR_Lock(pr_wp.ml);
+    pRec = FindPidTable(process->md.pid);
+    if (NULL == pRec) {
+	pRec = PR_NEW(pr_PidRecord);
+	if (NULL == pRec) {
+	    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	    retVal = PR_FAILURE;
+	    goto done;
+	}
+	pRec->pid = process->md.pid;
+	pRec->state = _PR_PID_WAITING;
+	pRec->reapedCV = PR_NewCondVar(pr_wp.ml);
+	if (NULL == pRec->reapedCV) {
+	    PR_DELETE(pRec);
+	    retVal = PR_FAILURE;
+	    goto done;
+	}
+	InsertPidTable(pRec);
+	while (!interrupted && _PR_PID_REAPED != pRec->state) {
+	    if (PR_WaitCondVar(pRec->reapedCV,
+		    PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE
+		    && PR_GetError() == PR_PENDING_INTERRUPT_ERROR) {
+		interrupted = PR_TRUE;
+            }
+	}
+	if (_PR_PID_REAPED == pRec->state) {
+            if (exitCode) {
+                *exitCode = pRec->exitStatus;
+            }
+	} else {
+	    PR_ASSERT(interrupted);
+	    retVal = PR_FAILURE;
+	}
+	DeletePidTable(pRec);
+	PR_DestroyCondVar(pRec->reapedCV);
+	PR_DELETE(pRec);
+    } else {
+	PR_ASSERT(_PR_PID_REAPED == pRec->state);
+	PR_ASSERT(NULL == pRec->reapedCV);
+	DeletePidTable(pRec);
+        if (exitCode) {
+            *exitCode = pRec->exitStatus;
+        }
+	PR_DELETE(pRec);
+    }
+    PR_DELETE(process);
+
+done:
+    PR_Unlock(pr_wp.ml);
+    return retVal;
+}  /* _MD_WaitUnixProcess */
+
+PRStatus _MD_KillUnixProcess(PRProcess *process)
+{
+    PRErrorCode prerror;
+    PRInt32 oserror;
+
+    if (kill(process->md.pid, SIGKILL) == 0) {
+	return PR_SUCCESS;
+    }
+    oserror = errno;
+    switch (oserror) {
+        case EPERM:
+	    prerror = PR_NO_ACCESS_RIGHTS_ERROR;
+	    break;
+        case ESRCH:
+	    prerror = PR_INVALID_ARGUMENT_ERROR;
+	    break;
+        default:
+	    prerror = PR_UNKNOWN_ERROR;
+	    break;
+    }
+    PR_SetError(prerror, oserror);
+    return PR_FAILURE;
+}  /* _MD_KillUnixProcess */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxrng.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxrng.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,341 @@
+/* -*- 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 "primpl.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/time.h>
+
+
+#if defined(SOLARIS)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    hrtime_t t;
+    t = gethrtime();
+    if (t) {
+	    return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
+    }
+    return 0;
+}
+
+#elif defined(SUNOS4)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    return 0;
+}
+
+#elif defined(HPUX)
+
+#ifdef __ia64
+#include <ia64/sys/inline.h>
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    PRUint64 t;
+
+    t = _Asm_mov_from_ar(_AREG44);
+    return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
+}
+#else
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    extern int ret_cr16();
+    int cr16val;
+
+    cr16val = ret_cr16();
+    return(_pr_CopyLowBits(buf, maxbytes, &cr16val, sizeof(cr16val)));
+}
+#endif
+
+#elif defined(OSF1)
+
+#include <c_asm.h>
+
+/*
+ * Use the "get the cycle counter" instruction on the alpha.
+ * The low 32 bits completely turn over in less than a minute.
+ * The high 32 bits are some non-counter gunk that changes sometimes.
+ */
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    unsigned long t;
+
+#ifdef __GNUC__
+    __asm__("rpcc %0" : "=r" (t));
+#else
+    t = asm("rpcc %v0");
+#endif
+    return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
+}
+
+#elif defined(VMS)
+
+#include <ints.h>
+
+/*
+ * Use the "get the cycle counter" instruction on the alpha.
+ * The low 32 bits completely turn over in less than a minute.
+ * The high 32 bits are some non-counter gunk that changes sometimes.
+ */
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    uint64 t;
+
+    t = __RPCC();
+    return _pr_CopyLowBits(buf, maxbytes, &t, sizeof(t));
+}
+
+#elif defined(AIX)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    return 0;
+}
+
+#elif (defined(LINUX) || defined(FREEBSD) || defined(__FreeBSD_kernel__) \
+    || defined(NETBSD) || defined(__NetBSD_kernel__) || defined(OPENBSD))
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+static int      fdDevRandom;
+static PRCallOnceType coOpenDevRandom;
+
+static PRStatus OpenDevRandom( void )
+{
+    fdDevRandom = open( "/dev/random", O_RDONLY );
+    return((-1 == fdDevRandom)? PR_FAILURE : PR_SUCCESS );
+} /* end OpenDevRandom() */
+
+static size_t GetDevRandom( void *buf, size_t size )
+{
+    int bytesIn;
+    int rc;
+
+    rc = PR_CallOnce( &coOpenDevRandom, OpenDevRandom );
+    if ( PR_FAILURE == rc ) {
+        _PR_MD_MAP_OPEN_ERROR( errno );
+        return(0);
+    }
+
+    bytesIn = read( fdDevRandom, buf, size );
+    if ( -1 == bytesIn ) {
+        _PR_MD_MAP_READ_ERROR( errno );
+        return(0);
+    }
+
+    return( bytesIn );
+} /* end GetDevRandom() */
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{             
+    return(GetDevRandom( buf, maxbytes ));
+}
+
+#elif defined(NCR)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    return 0;
+}
+
+#elif defined(IRIX)
+#include <fcntl.h>
+#undef PRIVATE
+#include <sys/mman.h>
+#include <sys/syssgi.h>
+#include <sys/immu.h>
+#include <sys/systeminfo.h>
+#include <sys/utsname.h>
+
+static size_t GetHighResClock(void *buf, size_t maxbuf)
+{
+    unsigned phys_addr, raddr, cycleval;
+    static volatile unsigned *iotimer_addr = NULL;
+    static int tries = 0;
+    static int cntr_size;
+    int mfd;
+    unsigned s0[2];
+
+#ifndef SGI_CYCLECNTR_SIZE
+#define SGI_CYCLECNTR_SIZE      165     /* Size user needs to use to read CC */
+#endif
+
+    if (iotimer_addr == NULL) {
+	    if (tries++ > 1) {
+	        /* Don't keep trying if it didn't work */
+	        return 0;
+	    }
+
+	    /*
+	    ** For SGI machines we can use the cycle counter, if it has one,
+	    ** to generate some truly random numbers
+	    */
+	    phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval);
+	    if (phys_addr) {
+	        int pgsz = getpagesize();
+	        int pgoffmask = pgsz - 1;
+
+	        raddr = phys_addr & ~pgoffmask;
+	        mfd = open("/dev/mmem", O_RDONLY);
+	        if (mfd < 0) {
+    		    return 0;
+	        }
+	        iotimer_addr = (unsigned *)
+		    mmap(0, pgoffmask, PROT_READ, MAP_PRIVATE, mfd, (int)raddr);
+	        if (iotimer_addr == (unsigned*)-1) {
+	    	    close(mfd);
+		        iotimer_addr = NULL;
+		        return 0;
+	        }
+	        iotimer_addr = (unsigned*)
+		    ((__psint_t)iotimer_addr | (phys_addr & pgoffmask));
+	        /*
+	         * The file 'mfd' is purposefully not closed.
+	         */
+	        cntr_size = syssgi(SGI_CYCLECNTR_SIZE);
+	        if (cntr_size < 0) {
+    		    struct utsname utsinfo;
+
+		        /* 
+		         * We must be executing on a 6.0 or earlier system, since the
+		         * SGI_CYCLECNTR_SIZE call is not supported.
+		         * 
+		         * The only pre-6.1 platforms with 64-bit counters are
+		         * IP19 and IP21 (Challenge, PowerChallenge, Onyx).
+		         */
+		        uname(&utsinfo);
+		        if (!strncmp(utsinfo.machine, "IP19", 4) ||
+		            !strncmp(utsinfo.machine, "IP21", 4))
+			        cntr_size = 64;
+		        else
+			        cntr_size = 32;
+	        }
+	        cntr_size /= 8;	/* Convert from bits to bytes */
+	    }
+    }
+
+    s0[0] = *iotimer_addr;
+    if (cntr_size > 4)
+	s0[1] = *(iotimer_addr + 1);
+    memcpy(buf, (char *)&s0[0], cntr_size);
+    return _pr_CopyLowBits(buf, maxbuf, &s0, cntr_size);
+}
+
+#elif defined(SONY)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    return 0;
+}
+
+#elif defined(SNI)
+#include <sys/times.h>
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    int ticks;
+    struct tms buffer;
+
+    ticks=times(&buffer);
+    return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
+}
+
+#elif defined(NEC)
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    return 0;
+}
+#elif defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(NTO) \
+    || defined(QNX) || defined(DARWIN) || defined(RISCOS)
+#include <sys/times.h>
+
+static size_t
+GetHighResClock(void *buf, size_t maxbytes)
+{
+    int ticks;
+    struct tms buffer;
+
+    ticks=times(&buffer);
+    return _pr_CopyLowBits(buf, maxbytes, &ticks, sizeof(ticks));
+}
+#else
+#error! Platform undefined
+#endif /* defined(SOLARIS) */
+
+extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size )
+{
+    struct timeval tv;
+    int n = 0;
+    int s;
+
+    n += GetHighResClock(buf, size);
+    size -= n;
+
+    GETTIMEOFDAY(&tv);
+
+    if ( size > 0 ) {
+        s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_usec, sizeof(tv.tv_usec));
+        size -= s;
+        n += s;
+    }
+    if ( size > 0 ) {
+        s = _pr_CopyLowBits((char*)buf+n, size, &tv.tv_sec, sizeof(tv.tv_usec));
+        size -= s;
+        n += s;
+    }
+
+    return n;
+} /* end _PR_MD_GetRandomNoise() */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxshm.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxshm.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,658 @@
+/* -*- 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 ***** */
+
+/*
+** uxshm.c -- Unix Implementations NSPR Named Shared Memory
+**
+**
+** lth. Jul-1999.
+**
+*/
+#include <string.h>
+#include <prshm.h>
+#include <prerr.h>
+#include <prmem.h>
+#include "primpl.h"       
+#include <fcntl.h>
+
+extern PRLogModuleInfo *_pr_shm_lm;
+
+
+#define NSPR_IPC_SHM_KEY 'b'
+/*
+** Implementation for System V
+*/
+#if defined PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
+#define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
+#define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
+#define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
+#define _MD_DELETE_SHARED_MEMORY  _MD_DeleteSharedMemory
+
+extern PRSharedMemory * _MD_OpenSharedMemory( 
+    const char *name,
+    PRSize      size,
+    PRIntn      flags,
+    PRIntn      mode
+)
+{
+    PRStatus rc = PR_SUCCESS;
+    key_t   key;
+    PRSharedMemory *shm;
+    char        ipcname[PR_IPC_NAME_SIZE];
+
+    rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
+    if ( PR_FAILURE == rc )
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
+        return( NULL );
+    }
+
+    shm = PR_NEWZAP( PRSharedMemory );
+    if ( NULL == shm ) 
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); 
+        return( NULL );
+    }
+
+    shm->ipcname = (char*)PR_MALLOC( strlen( ipcname ) + 1 );
+    if ( NULL == shm->ipcname )
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); 
+        return( NULL );
+    }
+
+    /* copy args to struct */
+    strcpy( shm->ipcname, ipcname );
+    shm->size = size; 
+    shm->mode = mode; 
+    shm->flags = flags;
+    shm->ident = _PR_SHM_IDENT;
+
+    /* create the file first */
+    if ( flags & PR_SHM_CREATE )  {
+        int osfd = open( shm->ipcname, (O_RDWR | O_CREAT), shm->mode );
+        if ( -1 == osfd ) {
+            _PR_MD_MAP_OPEN_ERROR( errno );
+            PR_FREEIF( shm->ipcname );
+            PR_DELETE( shm );
+            return( NULL );
+        } 
+        if ( close(osfd) == -1 ) {
+            _PR_MD_MAP_CLOSE_ERROR( errno );
+            PR_FREEIF( shm->ipcname );
+            PR_DELETE( shm );
+            return( NULL );
+        }
+    }
+
+    /* hash the shm.name to an ID */
+    key = ftok( shm->ipcname, NSPR_IPC_SHM_KEY );
+    if ( -1 == key )
+    {
+        rc = PR_FAILURE;
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): ftok() failed on name: %s", shm->ipcname));
+        PR_FREEIF( shm->ipcname );
+        PR_DELETE( shm );
+        return( NULL );
+    }
+
+    /* get the shared memory */
+    if ( flags & PR_SHM_CREATE )  {
+        shm->id = shmget( key, shm->size, ( shm->mode | IPC_CREAT|IPC_EXCL));
+        if ( shm->id >= 0 ) {
+            return( shm );
+        }
+        if ((errno == EEXIST) && (flags & PR_SHM_EXCL)) {
+            PR_SetError( PR_FILE_EXISTS_ERROR, errno );
+            PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+                ("_MD_OpenSharedMemory(): shmget() exclusive failed, errno: %d", errno));
+            PR_FREEIF(shm->ipcname);
+            PR_DELETE(shm);
+            return(NULL);
+        }
+    } 
+
+    shm->id = shmget( key, shm->size, shm->mode );
+    if ( -1 == shm->id ) {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): shmget() failed, errno: %d", errno));
+        PR_FREEIF(shm->ipcname);
+        PR_DELETE(shm);
+        return(NULL);
+    }
+
+    return( shm );
+} /* end _MD_OpenSharedMemory() */
+
+extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
+{
+    void        *addr;
+    PRUint32    aFlags = shm->mode;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    aFlags |= (flags & PR_SHM_READONLY )? SHM_RDONLY : 0;
+
+    addr = shmat( shm->id, NULL, aFlags );
+    if ( (void*)-1 == addr )
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_AttachSharedMemory(): shmat() failed on name: %s, OsError: %d", 
+                shm->ipcname, PR_GetOSError() ));
+        addr = NULL;
+    }
+
+    return addr;
+}    
+
+extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
+{
+    PRStatus rc = PR_SUCCESS;
+    PRIntn   urc;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    urc = shmdt( addr );
+    if ( -1 == urc )
+    {
+        rc = PR_FAILURE;
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DetachSharedMemory(): shmdt() failed on name: %s", shm->ipcname ));
+    }
+
+    return rc;
+}    
+
+extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
+{
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    PR_FREEIF(shm->ipcname);
+    PR_DELETE(shm);
+
+    return PR_SUCCESS;
+}    
+
+extern PRStatus _MD_DeleteSharedMemory( const char *name )
+{
+    PRStatus rc = PR_SUCCESS;
+    key_t   key;
+    int     id;
+    PRIntn  urc;
+    char        ipcname[PR_IPC_NAME_SIZE];
+
+    rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_SetError( PR_UNKNOWN_ERROR , errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
+        return(PR_FAILURE);
+    }
+
+    /* create the file first */ 
+    {
+        int osfd = open( ipcname, (O_RDWR | O_CREAT), 0666 );
+        if ( -1 == osfd ) {
+            _PR_MD_MAP_OPEN_ERROR( errno );
+            return( PR_FAILURE );
+        } 
+        if ( close(osfd) == -1 ) {
+            _PR_MD_MAP_CLOSE_ERROR( errno );
+            return( PR_FAILURE );
+        }
+    }
+
+    /* hash the shm.name to an ID */
+    key = ftok( ipcname, NSPR_IPC_SHM_KEY );
+    if ( -1 == key )
+    {
+        rc = PR_FAILURE;
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): ftok() failed on name: %s", ipcname));
+    }
+
+    id = shmget( key, 0, 0 );
+    if ( -1 == id ) {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): shmget() failed, errno: %d", errno));
+        return(PR_FAILURE);
+    }
+
+    urc = shmctl( id, IPC_RMID, NULL );
+    if ( -1 == urc )
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): shmctl() failed on name: %s", ipcname ));
+        return(PR_FAILURE);
+    }
+
+    urc = unlink( ipcname );
+    if ( -1 == urc ) {
+        _PR_MD_MAP_UNLINK_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): unlink() failed: %s", ipcname ));
+        return(PR_FAILURE);
+    }
+
+    return rc;
+}  /* end _MD_DeleteSharedMemory() */
+
+/*
+** Implementation for Posix
+*/
+#elif defined PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#include <sys/mman.h>
+
+#define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
+#define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
+#define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
+#define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
+#define _MD_DELETE_SHARED_MEMORY  _MD_DeleteSharedMemory
+
+struct _MDSharedMemory {
+    int     handle;
+};
+
+extern PRSharedMemory * _MD_OpenSharedMemory( 
+    const char *name,
+    PRSize      size,
+    PRIntn      flags,
+    PRIntn      mode
+)
+{
+    PRStatus    rc = PR_SUCCESS;
+    PRInt32     end;
+    PRSharedMemory *shm;
+    char        ipcname[PR_IPC_NAME_SIZE];
+
+    rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_SetError( PR_UNKNOWN_ERROR , errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
+        return( NULL );
+    }
+
+    shm = PR_NEWZAP( PRSharedMemory );
+    if ( NULL == shm ) 
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); 
+        return( NULL );
+    }
+
+    shm->ipcname = PR_MALLOC( strlen( ipcname ) + 1 );
+    if ( NULL == shm->ipcname )
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); 
+        return( NULL );
+    }
+
+    /* copy args to struct */
+    strcpy( shm->ipcname, ipcname );
+    shm->size = size; 
+    shm->mode = mode;
+    shm->flags = flags;
+    shm->ident = _PR_SHM_IDENT;
+
+    /*
+    ** Create the shared memory
+    */
+    if ( flags & PR_SHM_CREATE )  {
+        int oflag = (O_CREAT | O_RDWR);
+        
+        if ( flags & PR_SHM_EXCL )
+            oflag |= O_EXCL;
+        shm->id = shm_open( shm->ipcname, oflag, shm->mode );
+    } else {
+        shm->id = shm_open( shm->ipcname, O_RDWR, shm->mode );
+    }
+
+    if ( -1 == shm->id )  {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): shm_open failed: %s, OSError: %d",
+                shm->ipcname, PR_GetOSError())); 
+        PR_DELETE( shm->ipcname );
+        PR_DELETE( shm );
+        return(NULL);
+    }
+
+    end = ftruncate( shm->id, shm->size );
+    if ( -1 == end ) {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): ftruncate failed, OSError: %d",
+                PR_GetOSError()));
+        PR_DELETE( shm->ipcname );
+        PR_DELETE( shm );
+        return(NULL);
+    }
+
+    return(shm);
+} /* end _MD_OpenSharedMemory() */
+
+extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
+{
+    void        *addr;
+    PRIntn      prot = (PROT_READ | PROT_WRITE);
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    if ( PR_SHM_READONLY == flags)
+        prot ^= PROT_WRITE;
+
+    addr = mmap( (void*)0, shm->size, prot, MAP_SHARED, shm->id, 0 );
+    if ((void*)-1 == addr )
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_AttachSharedMemory(): mmap failed: %s, errno: %d",
+                shm->ipcname, PR_GetOSError()));
+        addr = NULL;
+    } else {
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_AttachSharedMemory(): name: %s, attached at: %p", shm->ipcname, addr));
+    }
+    
+    return addr;
+}    
+
+extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
+{
+    PRStatus    rc = PR_SUCCESS;
+    PRIntn      urc;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    urc = munmap( addr, shm->size );
+    if ( -1 == urc )
+    {
+        rc = PR_FAILURE;
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DetachSharedMemory(): munmap failed: %s, errno: %d", 
+                shm->ipcname, PR_GetOSError()));
+    }
+    return rc;
+}    
+
+extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
+{
+    int urc;
+    
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    urc = close( shm->id );
+    if ( -1 == urc ) {
+        _PR_MD_MAP_CLOSE_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_CloseSharedMemory(): close() failed, error: %d", PR_GetOSError()));
+        return(PR_FAILURE);
+    }
+    PR_DELETE( shm->ipcname );
+    PR_DELETE( shm );
+    return PR_SUCCESS;
+}    
+
+extern PRStatus _MD_DeleteSharedMemory( const char *name )
+{
+    PRStatus    rc = PR_SUCCESS;
+    PRUintn     urc;
+    char        ipcname[PR_IPC_NAME_SIZE];
+
+    rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_SetError( PR_UNKNOWN_ERROR , errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
+        return rc;
+    }
+
+    urc = shm_unlink( ipcname );
+    if ( -1 == urc ) {
+        rc = PR_FAILURE;
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): shm_unlink failed: %s, errno: %d", 
+                ipcname, PR_GetOSError()));
+    } else {
+        PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
+            ("_MD_DeleteSharedMemory(): %s, success", ipcname));
+    }
+
+    return rc;
+} /* end _MD_DeleteSharedMemory() */
+#endif
+
+
+
+/*
+** Unix implementation for anonymous memory (file) mapping
+*/
+extern PRLogModuleInfo *_pr_shma_lm;
+
+#include <unistd.h>
+
+extern PRFileMap* _md_OpenAnonFileMap( 
+    const char *dirName,
+    PRSize      size,
+    PRFileMapProtect prot
+)
+{
+    PRFileMap   *fm = NULL;
+    PRFileDesc  *fd;
+    int         osfd;
+    PRIntn      urc;
+    PRIntn      mode = 0600;
+    char        *genName;
+    pid_t       pid = getpid(); /* for generating filename */
+    PRThread    *tid = PR_GetCurrentThread(); /* for generating filename */
+    int         incr; /* for generating filename */
+    const int   maxTries = 20; /* maximum # attempts at a unique filename */
+    PRInt64     size64; /* 64-bit version of 'size' */
+
+    /*
+    ** generate a filename from input and runtime environment
+    ** open the file, unlink the file.
+    ** make maxTries number of attempts at uniqueness in the filename
+    */
+    for ( incr = 0; incr < maxTries ; incr++ ) {
+        genName = PR_smprintf( "%s/.NSPR-AFM-%d-%p.%d", 
+            dirName, (int) pid, tid, incr );
+        if ( NULL == genName ) {
+            PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+                ("_md_OpenAnonFileMap(): PR_snprintf(): failed, generating filename"));
+            goto Finished;
+        }
+        
+        /* create the file */
+        osfd = open( genName, (O_CREAT | O_EXCL | O_RDWR), mode );
+        if ( -1 == osfd ) {
+            if ( EEXIST == errno )  {
+                PR_smprintf_free( genName );
+                continue; /* name exists, try again */
+            } else {
+                _PR_MD_MAP_OPEN_ERROR( errno );
+                PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+                    ("_md_OpenAnonFileMap(): open(): failed, filename: %s, errno: %d", 
+                        genName, PR_GetOSError()));
+                PR_smprintf_free( genName );
+                goto Finished;
+            }
+        }
+        break; /* name generation and open successful, break; */
+    } /* end for() */
+
+    if ( incr == maxTries ) {
+        PR_ASSERT( -1 == osfd );
+        PR_ASSERT( EEXIST == errno );
+        _PR_MD_MAP_OPEN_ERROR( errno );
+        goto Finished;
+    }
+
+    urc = unlink( genName );
+    if ( -1 == urc ) {
+        _PR_MD_MAP_UNLINK_ERROR( errno );
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_OpenAnonFileMap(): failed on unlink(), errno: %d", errno));
+        PR_smprintf_free( genName );
+        close( osfd );
+        goto Finished;        
+    }
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_OpenAnonFileMap(): unlink(): %s", genName ));
+
+    PR_smprintf_free( genName );
+
+    fd = PR_ImportFile( osfd );
+    if ( NULL == fd ) {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_OpenAnonFileMap(): PR_ImportFile(): failed"));
+        goto Finished;        
+    }
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_OpenAnonFileMap(): fd: %p", fd ));
+
+    urc = ftruncate( fd->secret->md.osfd, size );
+    if ( -1 == urc ) {
+        _PR_MD_MAP_DEFAULT_ERROR( errno );
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_OpenAnonFileMap(): failed on ftruncate(), errno: %d", errno));
+        PR_Close( fd );
+        goto Finished;        
+    }
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_OpenAnonFileMap(): ftruncate(): size: %d", size ));
+
+    LL_UI2L(size64, size);  /* PRSize (size_t) is unsigned */
+    fm = PR_CreateFileMap( fd, size64, prot );
+    if ( NULL == fm )  {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("PR_OpenAnonFileMap(): failed"));
+        PR_Close( fd );
+        goto Finished;        
+    }
+    fm->md.isAnonFM = PR_TRUE; /* set fd close */
+
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_OpenAnonFileMap(): PR_CreateFileMap(): fm: %p", fm ));
+
+Finished:    
+    return(fm);
+} /* end md_OpenAnonFileMap() */
+
+/*
+** _md_ExportFileMapAsString()
+**
+**
+*/
+extern PRStatus _md_ExportFileMapAsString(
+    PRFileMap *fm,
+    PRSize    bufSize,
+    char      *buf
+)
+{
+    PRIntn  written;
+    PRIntn  prot = (PRIntn)fm->prot;
+    
+    written = PR_snprintf( buf, bufSize, "%ld:%d",
+        fm->fd->secret->md.osfd, prot );
+        
+    return((written == -1)? PR_FAILURE : PR_SUCCESS);
+} /* end _md_ExportFileMapAsString() */
+
+
+extern PRFileMap * _md_ImportFileMapFromString(
+    const char *fmstring
+)
+{
+    PRStatus    rc;
+    PRInt32     osfd;
+    PRIntn      prot; /* really: a PRFileMapProtect */
+    PRFileDesc  *fd;
+    PRFileMap   *fm = NULL; /* default return value */
+    PRFileInfo64 info;
+
+    PR_sscanf( fmstring, "%ld:%d", &osfd, &prot );
+
+    /* import the os file descriptor */
+    fd = PR_ImportFile( osfd );
+    if ( NULL == fd ) {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_ImportFileMapFromString(): PR_ImportFile() failed"));
+        goto Finished;
+    }
+
+    rc = PR_GetOpenFileInfo64( fd, &info );
+    if ( PR_FAILURE == rc )  {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_ImportFileMapFromString(): PR_GetOpenFileInfo64() failed"));    
+        goto Finished;
+    }
+
+    fm = PR_CreateFileMap( fd, info.size, (PRFileMapProtect)prot );
+    if ( NULL == fm ) {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_ImportFileMapFromString(): PR_CreateFileMap() failed"));    
+    }
+
+Finished:
+    return(fm);
+} /* end _md_ImportFileMapFromString() */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxwrap.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/unix/uxwrap.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,548 @@
+/* -*- 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: uxwrap.c
+ *
+ *     Our wrapped versions of the Unix select() and poll() system calls.
+ *
+ *------------------------------------------------------------------------
+ */
+
+#include "primpl.h"
+
+#if defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) || defined(QNX)
+/* Do not wrap select() and poll(). */
+#else  /* defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) */
+/* The include files for select() */
+#ifdef IRIX
+#include <unistd.h>
+#include <bstring.h>
+#endif
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#define ZAP_SET(_to, _width)				      \
+    PR_BEGIN_MACRO					      \
+	memset(_to, 0,					      \
+	       ((_width + 8*sizeof(int)-1) / (8*sizeof(int))) \
+		* sizeof(int)				      \
+	       );					      \
+    PR_END_MACRO
+
+/* see comments in ns/cmd/xfe/mozilla.c (look for "PR_XGetXtHackFD") */
+static int _pr_xt_hack_fd = -1;
+ 
+int PR_XGetXtHackFD(void)
+{
+    int fds[2];
+ 
+    if (_pr_xt_hack_fd == -1) {
+        if (!pipe(fds)) {
+            _pr_xt_hack_fd = fds[0];
+        }
+    }
+    return _pr_xt_hack_fd;
+}
+
+static int (*_pr_xt_hack_okayToReleaseXLock)(void) = 0;
+
+void PR_SetXtHackOkayToReleaseXLockFn(int (*fn)(void))
+{
+    _pr_xt_hack_okayToReleaseXLock = fn; 
+}
+
+
+/*
+ *-----------------------------------------------------------------------
+ *  select() --
+ *
+ *    Wrap up the select system call so that we can deschedule
+ *    a thread that tries to wait for i/o.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+#if defined(HPUX9)
+int select(size_t width, int *rl, int *wl, int *el, const struct timeval *tv)
+#elif defined(NEXTSTEP)
+int wrap_select(int width, fd_set *rd, fd_set *wr, fd_set *ex,
+        const struct timeval *tv)
+#elif defined(AIX_RENAME_SELECT)
+int wrap_select(unsigned long width, void *rl, void *wl, void *el,
+        struct timeval *tv)
+#elif defined(_PR_SELECT_CONST_TIMEVAL)
+int select(int width, fd_set *rd, fd_set *wr, fd_set *ex,
+        const struct timeval *tv)
+#else
+int select(int width, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *tv)
+#endif
+{
+    int osfd;
+    _PRUnixPollDesc *unixpds, *unixpd, *eunixpd;
+    PRInt32 pdcnt;
+    PRIntervalTime timeout;
+    int retVal;
+#if defined(HPUX9) || defined(AIX_RENAME_SELECT)
+    fd_set *rd = (fd_set*) rl;
+    fd_set *wr = (fd_set*) wl;
+    fd_set *ex = (fd_set*) el;
+#endif
+
+#if 0
+    /*
+     * Easy special case: zero timeout.  Simply call the native
+     * select() with no fear of blocking.
+     */
+    if (tv != NULL && tv->tv_sec == 0 && tv->tv_usec == 0) {
+#if defined(HPUX9) || defined(AIX_RENAME_SELECT)
+        return _MD_SELECT(width, rl, wl, el, tv);
+#else
+        return _MD_SELECT(width, rd, wr, ex, tv);
+#endif
+    }
+#endif
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+		
+#ifndef _PR_LOCAL_THREADS_ONLY
+    if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) {
+        return _MD_SELECT(width, rd, wr, ex, tv);	
+    }
+#endif
+
+    if (width < 0 || width > FD_SETSIZE) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    /* Compute timeout */
+    if (tv) {
+        /*
+         * These acceptable ranges for t_sec and t_usec are taken
+         * from the select() man pages.
+         */
+        if (tv->tv_sec < 0 || tv->tv_sec > 100000000
+                || tv->tv_usec < 0 || tv->tv_usec >= 1000000) {
+            errno = EINVAL;
+            return -1;
+        }
+
+        /* Convert microseconds to ticks */
+        timeout = PR_MicrosecondsToInterval(1000000*tv->tv_sec + tv->tv_usec);
+    } else {
+        /* tv being a NULL pointer means blocking indefinitely */
+        timeout = PR_INTERVAL_NO_TIMEOUT;
+    }
+
+    /* Check for no descriptors case (just doing a timeout) */
+    if ((!rd && !wr && !ex) || !width) {
+        PR_Sleep(timeout);
+        return 0;
+    }
+
+    /*
+     * Set up for PR_Poll().  The PRPollDesc array is allocated
+     * dynamically.  If this turns out to have high performance
+     * penalty, one can change to use a large PRPollDesc array
+     * on the stack, and allocate dynamically only when it turns
+     * out to be not large enough.
+     *
+     * I allocate an array of size 'width', which is the maximum
+     * number of fds we may need to poll.
+     */
+    unixpds = (_PRUnixPollDesc *) PR_CALLOC(width * sizeof(_PRUnixPollDesc));
+    if (!unixpds) {
+        errno = ENOMEM;
+        return -1;
+    }
+
+    pdcnt = 0;
+    unixpd = unixpds;
+    for (osfd = 0; osfd < width; osfd++) {
+        int in_flags = 0;
+        if (rd && FD_ISSET(osfd, rd)) {
+            in_flags |= _PR_UNIX_POLL_READ;
+        }
+        if (wr && FD_ISSET(osfd, wr)) {
+            in_flags |= _PR_UNIX_POLL_WRITE;
+        }
+        if (ex && FD_ISSET(osfd, ex)) {
+            in_flags |= _PR_UNIX_POLL_EXCEPT;
+        }
+        if (in_flags) {
+            unixpd->osfd = osfd;
+            unixpd->in_flags = in_flags;
+            unixpd->out_flags = 0;
+            unixpd++;
+            pdcnt++;
+        }
+    }
+
+    /*
+     * see comments in mozilla/cmd/xfe/mozilla.c (look for
+     * "PR_XGetXtHackFD")
+     */
+   {
+     int needToLockXAgain;
+ 
+     needToLockXAgain = 0;
+     if (rd && (_pr_xt_hack_fd != -1)
+             && FD_ISSET(_pr_xt_hack_fd, rd) && PR_XIsLocked()
+             && (!_pr_xt_hack_okayToReleaseXLock
+             || _pr_xt_hack_okayToReleaseXLock())) {
+         PR_XUnlock();
+         needToLockXAgain = 1;
+     }
+
+    /* This is the potentially blocking step */
+    retVal = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout);
+
+     if (needToLockXAgain) {
+         PR_XLock();
+     }
+   }
+
+    if (retVal > 0) {
+        /* Compute select results */
+        if (rd) ZAP_SET(rd, width);
+        if (wr) ZAP_SET(wr, width);
+        if (ex) ZAP_SET(ex, width);
+
+        /*
+         * The return value can be either the number of ready file
+         * descriptors or the number of set bits in the three fd_set's.
+         */
+        retVal = 0;  /* we're going to recompute */
+        eunixpd = unixpds + pdcnt;
+        for (unixpd = unixpds; unixpd < eunixpd; unixpd++) {
+            if (unixpd->out_flags) {
+                int nbits = 0;  /* The number of set bits on for this fd */
+
+                if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) {
+                    errno = EBADF;
+                    PR_LOG(_pr_io_lm, PR_LOG_ERROR,
+                            ("select returns EBADF for %d", unixpd->osfd));
+                    retVal = -1;
+                    break;
+                }
+                /*
+                 * If a socket has a pending error, it is considered
+                 * both readable and writable.  (See W. Richard Stevens,
+                 * Unix Network Programming, Vol. 1, 2nd Ed., Section 6.3,
+                 * pp. 153-154.)  We also consider a socket readable if
+                 * it has a hangup condition.
+                 */
+                if (rd && (unixpd->in_flags & _PR_UNIX_POLL_READ)
+                        && (unixpd->out_flags & (_PR_UNIX_POLL_READ
+                        | _PR_UNIX_POLL_ERR | _PR_UNIX_POLL_HUP))) {
+                    FD_SET(unixpd->osfd, rd);
+                    nbits++;
+                }
+                if (wr && (unixpd->in_flags & _PR_UNIX_POLL_WRITE)
+                        && (unixpd->out_flags & (_PR_UNIX_POLL_WRITE
+                        | _PR_UNIX_POLL_ERR))) {
+                    FD_SET(unixpd->osfd, wr);
+                    nbits++;
+                }
+                if (ex && (unixpd->in_flags & _PR_UNIX_POLL_WRITE)
+                        && (unixpd->out_flags & PR_POLL_EXCEPT)) {
+                    FD_SET(unixpd->osfd, ex);
+                    nbits++;
+                }
+                PR_ASSERT(nbits > 0);
+#if defined(HPUX) || defined(SOLARIS) || defined(SUNOS4) || defined(OSF1) || defined(AIX)
+                retVal += nbits;
+#else /* IRIX */
+                retVal += 1;
+#endif
+            }
+        }
+    }
+
+    PR_ASSERT(tv || retVal != 0);
+    PR_LOG(_pr_io_lm, PR_LOG_MIN, ("select returns %d", retVal));
+    PR_DELETE(unixpds);
+
+    return retVal;
+}
+
+/*
+ * Redefine poll, when supported on platforms, for local threads
+ */
+
+/*
+ * I am commenting out the poll() wrapper for Linux for now
+ * because it is difficult to define _MD_POLL that works on all
+ * Linux varieties.  People reported that glibc 2.0.7 on Debian
+ * 2.0 Linux machines doesn't have the __syscall_poll symbol
+ * defined.  (WTC 30 Nov. 1998)
+ */
+#if defined(_PR_POLL_AVAILABLE) && !defined(LINUX)
+
+/*
+ *-----------------------------------------------------------------------
+ * poll() --
+ *
+ * RETURN VALUES: 
+ *     -1:  fails, errno indicates the error.
+ *      0:  timed out, the revents bitmasks are not set.
+ *      positive value: the number of file descriptors for which poll()
+ *          has set the revents bitmask.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+#include <poll.h>
+
+#if defined(AIX_RENAME_SELECT)
+int wrap_poll(void *listptr, unsigned long nfds, long timeout)
+#elif (defined(AIX) && !defined(AIX_RENAME_SELECT))
+int poll(void *listptr, unsigned long nfds, long timeout)
+#elif defined(OSF1) || (defined(HPUX) && !defined(HPUX9))
+int poll(struct pollfd filedes[], unsigned int nfds, int timeout)
+#elif defined(HPUX9)
+int poll(struct pollfd filedes[], int nfds, int timeout)
+#elif defined(NETBSD)
+int poll(struct pollfd *filedes, nfds_t nfds, int timeout)
+#elif defined(OPENBSD)
+int poll(struct pollfd filedes[], nfds_t nfds, int timeout)
+#elif defined(FREEBSD)
+int poll(struct pollfd *filedes, unsigned nfds, int timeout)
+#else
+int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
+#endif
+{
+#ifdef AIX
+    struct pollfd *filedes = (struct pollfd *) listptr;
+#endif
+    struct pollfd *pfd, *epfd;
+    _PRUnixPollDesc *unixpds, *unixpd, *eunixpd;
+    PRIntervalTime ticks;
+    PRInt32 pdcnt;
+    int ready;
+
+    /*
+     * Easy special case: zero timeout.  Simply call the native
+     * poll() with no fear of blocking.
+     */
+    if (timeout == 0) {
+#if defined(AIX)
+        return _MD_POLL(listptr, nfds, timeout);
+#else
+        return _MD_POLL(filedes, nfds, timeout);
+#endif
+    }
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+
+#ifndef _PR_LOCAL_THREADS_ONLY
+    if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) {
+    	return _MD_POLL(filedes, nfds, timeout);
+    }
+#endif
+
+    /* We do not support the pollmsg structures on AIX */
+#ifdef AIX
+    PR_ASSERT((nfds & 0xff00) == 0);
+#endif
+
+    if (timeout < 0 && timeout != -1) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    /* Convert timeout from miliseconds to ticks */
+    if (timeout == -1) {
+        ticks = PR_INTERVAL_NO_TIMEOUT;
+    } else {
+        ticks = PR_MillisecondsToInterval(timeout);
+    }
+
+    /* Check for no descriptor case (just do a timeout) */
+    if (nfds == 0) {
+        PR_Sleep(ticks);
+        return 0;
+    }
+
+    unixpds = (_PRUnixPollDesc *)
+            PR_MALLOC(nfds * sizeof(_PRUnixPollDesc));
+    if (NULL == unixpds) {
+        errno = EAGAIN;
+        return -1;
+    }
+
+    pdcnt = 0;
+    epfd = filedes + nfds;
+    unixpd = unixpds;
+    for (pfd = filedes; pfd < epfd; pfd++) {
+        /*
+         * poll() ignores negative fd's.
+         */
+        if (pfd->fd >= 0) {
+            unixpd->osfd = pfd->fd;
+#ifdef _PR_USE_POLL
+            unixpd->in_flags = pfd->events;
+#else
+            /*
+             * Map the poll events to one of the three that can be
+             * represented by the select fd_sets:
+             *     POLLIN, POLLRDNORM  ===> readable
+             *     POLLOUT, POLLWRNORM ===> writable
+             *     POLLPRI, POLLRDBAND ===> exception
+             *     POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
+             *     are ignored.
+             *
+             * The output events POLLERR and POLLHUP are never turned on.
+             * POLLNVAL may be turned on.
+             */
+            unixpd->in_flags = 0;
+            if (pfd->events & (POLLIN
+#ifdef POLLRDNORM
+                    | POLLRDNORM
+#endif
+                    )) {
+                unixpd->in_flags |= _PR_UNIX_POLL_READ;
+            }
+            if (pfd->events & (POLLOUT
+#ifdef POLLWRNORM
+                    | POLLWRNORM
+#endif
+                    )) {
+                unixpd->in_flags |= _PR_UNIX_POLL_WRITE;
+            }
+            if (pfd->events & (POLLPRI
+#ifdef POLLRDBAND
+                    | POLLRDBAND
+#endif
+                    )) {
+                unixpd->in_flags |= PR_POLL_EXCEPT;
+            }
+#endif  /* _PR_USE_POLL */
+            unixpd->out_flags = 0;
+            unixpd++;
+            pdcnt++;
+        }
+    }
+
+    ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, ticks);
+    if (-1 == ready) {
+        if (PR_GetError() == PR_PENDING_INTERRUPT_ERROR) {
+            errno = EINTR;  /* XXX we aren't interrupted by a signal, but... */
+        } else {
+            errno = PR_GetOSError();
+        }
+    }
+    if (ready <= 0) {
+        goto done;
+    }
+
+    /*
+     * Copy the out_flags from the _PRUnixPollDesc structures to the
+     * user's pollfd structures and free the allocated memory
+     */
+    unixpd = unixpds;
+    for (pfd = filedes; pfd < epfd; pfd++) {
+        pfd->revents = 0;
+        if (pfd->fd >= 0) {
+#ifdef _PR_USE_POLL
+            pfd->revents = unixpd->out_flags;
+#else
+            if (0 != unixpd->out_flags) {
+                if (unixpd->out_flags & _PR_UNIX_POLL_READ) {
+                    if (pfd->events & POLLIN) {
+                        pfd->revents |= POLLIN;
+                    }
+#ifdef POLLRDNORM
+                    if (pfd->events & POLLRDNORM) {
+                        pfd->revents |= POLLRDNORM;
+                    }
+#endif
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_WRITE) {
+                    if (pfd->events & POLLOUT) {
+                        pfd->revents |= POLLOUT;
+                    }
+#ifdef POLLWRNORM
+                    if (pfd->events & POLLWRNORM) {
+                        pfd->revents |= POLLWRNORM;
+                    }
+#endif
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT) {
+                    if (pfd->events & POLLPRI) {
+                        pfd->revents |= POLLPRI;
+                    }
+#ifdef POLLRDBAND
+                    if (pfd->events & POLLRDBAND) {
+                        pfd->revents |= POLLRDBAND;
+                    }
+#endif
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_ERR) {
+                    pfd->revents |= POLLERR;
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) {
+                    pfd->revents |= POLLNVAL;
+                }
+                if (unixpd->out_flags & _PR_UNIX_POLL_HUP) {
+                    pfd->revents |= POLLHUP;
+                }
+            }
+#endif  /* _PR_USE_POLL */
+            unixpd++;
+        }
+    }
+
+done:
+    PR_DELETE(unixpds);
+    return ready;
+}
+
+#endif  /* !defined(LINUX) */
+
+#endif  /* defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY) */
+
+/* uxwrap.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,33 @@
+/.cvsignore/1.2/Sat May 12 04:42:04 2001//
+/Makefile.in/1.17/Sun Apr 25 15:01:00 2004//
+/ntdllmn.c/3.6/Sun Apr 25 15:01:00 2004//
+/ntgc.c/3.7/Fri Oct 21 18:21:42 2005//
+/ntinrval.c/3.13/Mon Feb 13 23:16:53 2006//
+/ntio.c/3.42/Fri Feb 17 23:16:24 2006//
+/ntmisc.c/3.21/Mon Jan  9 17:43:53 2006//
+/ntsec.c/3.7/Sun Apr 25 15:01:00 2004//
+/ntsem.c/3.5/Sun Apr 25 15:01:00 2004//
+/ntthread.c/3.18/Thu Apr 28 22:54:51 2005//
+/objs.mk/1.8/Sun Apr 25 15:01:00 2004//
+/w16callb.c/3.6/Sun Apr 25 15:01:00 2004//
+/w16error.c/3.5/Sun Apr 25 15:01:00 2004//
+/w16fmem.c/3.6/Sun Apr 25 15:01:00 2004//
+/w16gc.c/3.5/Sun Apr 25 15:01:00 2004//
+/w16io.c/3.5/Sun Apr 25 15:01:00 2004//
+/w16mem.c/3.6/Sun Apr 25 15:01:00 2004//
+/w16null.c/3.6/Sun Apr 25 15:01:00 2004//
+/w16proc.c/3.5/Sun Apr 25 15:01:00 2004//
+/w16sock.c/3.6/Sun Apr 25 15:01:00 2004//
+/w16stdio.c/3.5/Sun Apr 25 15:01:00 2004//
+/w16thred.c/3.5/Sun Apr 25 15:01:00 2004//
+/w32ipcsem.c/3.6/Sun Apr 25 15:01:00 2004//
+/w32poll.c/3.12/Sun Apr 25 15:01:00 2004//
+/w32rng.c/1.7/Fri Oct 21 18:21:42 2005//
+/w32shm.c/3.6/Fri Oct 21 18:21:42 2005//
+/w95cv.c/3.5/Sun Apr 25 15:01:00 2004//
+/w95dllmain.c/3.8/Sun Apr 25 15:01:00 2004//
+/w95io.c/3.29/Mon Feb 20 22:05:54 2006//
+/w95sock.c/3.11/Fri Oct 21 18:21:42 2005//
+/w95thred.c/3.16/Fri Oct 21 18:21:42 2005//
+/win32_errors.c/3.11/Mon Feb 20 22:05:54 2006//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/md/windows

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,121 @@
+# 
+# ***** 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)
+CSRCS = \
+	w16null.c \
+	w16thred.c \
+	w16proc.c \
+    w16fmem.c \
+    w16sock.c \
+    w16mem.c \
+    w16io.c  \
+    w16gc.c  \
+    w16error.c  \
+    w16stdio.c  \
+    w16callb.c \
+    ntinrval.c \
+    $(NULL)
+else
+ifeq ($(OS_TARGET), WIN95)
+CSRCS =          \
+    ntmisc.c \
+    ntsec.c   \
+    ntsem.c   \
+    ntinrval.c \
+    ntgc.c \
+	w95thred.c \
+	w95io.c \
+	w95cv.c \
+	w32rng.c \
+	w95sock.c \
+	win32_errors.c \
+    w32ipcsem.c \
+    w32poll.c \
+    w32shm.c \
+    w95dllmain.c \
+    $(NULL)
+else
+CSRCS =          \
+    ntdllmn.c \
+    ntmisc.c \
+    ntsec.c   \
+    ntsem.c   \
+    ntinrval.c \
+    ntgc.c \
+    ntthread.c \
+    ntio.c    \
+	win32_errors.c \
+    w32ipcsem.c \
+    w32poll.c \
+    w32rng.c \
+    w32shm.c \
+    $(NULL)
+endif
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES += -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
+# Bug 122433 workaround: disable global optimization (-Og-) on ntio.c.
+ifdef BUILD_OPT
+ifeq ($(OS_TARGET), WINNT)
+ifndef NS_USE_GCC
+$(OBJDIR)/ntio.$(OBJ_SUFFIX): ntio.c
+	@$(MAKE_OBJDIR)
+	$(CC) -Fo$@ -c $(CFLAGS) -Og- $<
+endif
+endif
+endif

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntdllmn.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntdllmn.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+ * The DLL entry point (DllMain) for NSPR.
+ *
+ * The only reason we use DLLMain() now is to find out whether
+ * the NSPR DLL is statically or dynamically loaded.  When
+ * dynamically loaded, we cannot use static thread-local storage.
+ * However, static TLS is faster than the TlsXXX() functions.
+ * So we want to use static TLS whenever we can.  A global
+ * variable _pr_use_static_tls is set in DllMain() during process
+ * attachment to indicate whether it is safe to use static TLS
+ * or not.
+ */
+
+#include <windows.h>
+#include <primpl.h>
+
+extern BOOL _pr_use_static_tls;  /* defined in ntthread.c */
+
+BOOL WINAPI DllMain(
+    HINSTANCE hinstDLL,
+    DWORD fdwReason,
+    LPVOID lpvReserved)
+{
+PRThread *me;
+
+    switch (fdwReason) {
+        case DLL_PROCESS_ATTACH:
+            /*
+             * If lpvReserved is NULL, we are dynamically loaded
+             * and therefore can't use static thread-local storage.
+             */
+            if (lpvReserved == NULL) {
+                _pr_use_static_tls = FALSE;
+            } else {
+                _pr_use_static_tls = TRUE;
+            }
+            break;
+        case DLL_THREAD_ATTACH:
+            break;
+        case DLL_THREAD_DETACH:
+            if (_pr_initialized) {
+                me = _MD_GET_ATTACHED_THREAD();
+                if ((me != NULL) && (me->flags & _PR_ATTACHED))
+                    _PRI_DetachThread();
+            }
+            break;
+        case DLL_PROCESS_DETACH:
+            break;
+    }
+    return TRUE;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntgc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntgc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,130 @@
+/* -*- 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 "primpl.h"
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) 
+{
+#if defined(_X86_)
+    CONTEXT context;
+    context.ContextFlags = CONTEXT_INTEGER;
+
+    if (_PR_IS_NATIVE_THREAD(t)) {
+        context.ContextFlags |= CONTEXT_CONTROL;
+        if (GetThreadContext(t->md.handle, &context)) {
+            t->md.gcContext[0] = context.Eax;
+            t->md.gcContext[1] = context.Ebx;
+            t->md.gcContext[2] = context.Ecx;
+            t->md.gcContext[3] = context.Edx;
+            t->md.gcContext[4] = context.Esi;
+            t->md.gcContext[5] = context.Edi;
+            t->md.gcContext[6] = context.Esp;
+            t->md.gcContext[7] = context.Ebp;
+            *np = PR_NUM_GCREGS;
+        } else {
+            PR_ASSERT(0);/* XXX */
+        }
+    } else {
+        /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+         *
+         * This code is extremely machine dependant and completely 
+         * undocumented by MS.  Its only known to work experimentally.  
+         * Ready for a walk on the wild * side?
+         *
+         * WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
+
+#if !defined WIN95 // Win95 does not have fibers
+        int *fiberData = t->md.fiber_id;
+
+        /* I found these offsets by disassembling SwitchToFiber().
+         * Are your palms sweating yet?
+         */
+
+        /* 
+        ** EAX is on the stack (ESP+0)
+        ** EDX is on the stack (ESP+4)
+        ** ECX is on the stack (ESP+8)
+        */
+        t->md.gcContext[0] = 0;                /* context.Eax */
+        t->md.gcContext[1] = fiberData[0x2e];  /* context.Ebx */
+        t->md.gcContext[2] = 0;                /* context.Ecx */
+        t->md.gcContext[2] = 0;                /* context.Edx */
+        t->md.gcContext[4] = fiberData[0x2d];  /* context.Esi */
+        t->md.gcContext[5] = fiberData[0x2c];  /* context.Edi */
+        t->md.gcContext[6] = fiberData[0x36];  /* context.Esp */
+        t->md.gcContext[7] = fiberData[0x32];  /* context.Ebp */
+        *np = PR_NUM_GCREGS;
+#endif
+    }
+    return (PRWord *)&t->md.gcContext;
+#else
+    PR_NOT_REACHED("not implemented");
+    return NULL;
+#endif /* defined(_X86_) */
+}
+
+/* This function is not used right now, but is left as a reference.
+ * If you ever need to get the fiberID from the currently running fiber, 
+ * this is it.
+ */
+void *
+GetMyFiberID()
+{
+#if defined(_X86_) && !defined(__MINGW32__)
+    void *fiberData;
+
+    /* A pointer to our tib entry is found at FS:[18]
+     * At offset 10h is the fiberData pointer.  The context of the 
+     * fiber is stored in there.  
+     */
+    __asm {
+        mov    EDX, FS:[18h]
+        mov    EAX, DWORD PTR [EDX+10h]
+        mov    [fiberData], EAX
+    }
+  
+    return fiberData;
+#else
+    PR_NOT_REACHED("not implemented");
+    return NULL;
+#endif /* defined(_X86_) */
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntinrval.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntinrval.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,60 @@
+/* -*- 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 ***** */
+
+/*
+ * NT interval timers
+ *
+ */
+
+#include "primpl.h"
+
+void
+_PR_MD_INTERVAL_INIT()
+{
+}
+
+PRIntervalTime 
+_PR_MD_GET_INTERVAL()
+{
+    return timeGetTime();  /* milliseconds since system start */
+}
+
+PRIntervalTime 
+_PR_MD_INTERVAL_PER_SEC()
+{
+    return 1000;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntio.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntio.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4698 @@
+/* -*- 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):
+ *   Masayuki Nakano <masayuki at d-toybox.com>
+ *
+ * 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 ***** */
+
+/* Windows NT IO module
+ *
+ * This module handles IO for LOCAL_SCOPE and GLOBAL_SCOPE threads.
+ * For LOCAL_SCOPE threads, we're using NT fibers.  For GLOBAL_SCOPE threads
+ * we're using NT-native threads.
+ *
+ * When doing IO, we want to use completion ports for optimal performance 
+ * with fibers.  But if we use completion ports for all IO, it is difficult
+ * to project a blocking model with GLOBAL_SCOPE threads.  To handle this
+ * we create an extra thread for completing IO for GLOBAL_SCOPE threads.
+ * We don't really want to complete IO on a separate thread for LOCAL_SCOPE
+ * threads because it means extra context switches, which are really slow
+ * on NT...  Since we're using a single completion port, some IO will
+ * be incorrectly completed on the GLOBAL_SCOPE IO thread; this will mean
+ * extra context switching; but I don't think there is anything I can do
+ * about it.
+ */
+
+#include "primpl.h"
+#include "pprmwait.h"
+#include <direct.h>
+#include <mbstring.h>
+
+static HANDLE                _pr_completion_port;
+static PRThread             *_pr_io_completion_thread;
+
+#define RECYCLE_SIZE 512
+static struct _MDLock        _pr_recycle_lock;
+static PRInt32               _pr_recycle_array[RECYCLE_SIZE];
+static PRInt32               _pr_recycle_tail = 0; 
+
+__declspec(thread) PRThread *_pr_io_restarted_io = NULL;
+DWORD _pr_io_restartedIOIndex;  /* The thread local storage slot for each
+                                 * thread is initialized to NULL. */
+
+PRBool                       _nt_version_gets_lockfile_completion;
+
+struct _MDLock               _pr_ioq_lock;
+extern _MDLock               _nt_idleLock;
+extern PRCList               _nt_idleList;
+extern PRUint32              _nt_idleCount;
+
+#define CLOSE_TIMEOUT   PR_SecondsToInterval(5)
+
+/*
+ * NSPR-to-NT access right mapping table for files.
+ */
+static DWORD fileAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
+ * NSPR-to-NT access right mapping table for directories.
+ */
+static DWORD dirAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE|FILE_DELETE_CHILD,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
+ * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
+ * We store the value in a PRTime variable for convenience.
+ * This constant is used by _PR_FileTimeToPRTime().
+ */
+#ifdef __GNUC__
+static const PRTime _pr_filetime_offset = 116444736000000000LL;
+#else
+static const PRTime _pr_filetime_offset = 116444736000000000i64;
+#endif
+
+static PRBool IsPrevCharSlash(const char *str, const char *current);
+
+#define _NEED_351_FILE_LOCKING_HACK
+#ifdef _NEED_351_FILE_LOCKING_HACK
+#define _PR_LOCAL_FILE 1
+#define _PR_REMOTE_FILE 2
+PRBool IsFileLocalInit();
+PRInt32 IsFileLocal(HANDLE hFile);
+#endif /* _NEED_351_FILE_LOCKING_HACK */
+
+static PRInt32 _md_MakeNonblock(HANDLE);
+
+static PROsfd _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr *addr, int *addrlen, PRIntervalTime);
+static PRInt32 _nt_nonblock_connect(PRFileDesc *fd, struct sockaddr *addr, int addrlen, PRIntervalTime);
+static PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, int flags, PRIntervalTime);
+static PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
+static PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime);
+static PRInt32 _nt_nonblock_sendto(PRFileDesc *, const char *, int, const struct sockaddr *, int, PRIntervalTime);
+static PRInt32 _nt_nonblock_recvfrom(PRFileDesc *, char *, int, struct sockaddr *, int *, PRIntervalTime);
+
+/*
+ * We cannot associate a fd (a socket) with an I/O completion port
+ * if the fd is nonblocking or inheritable.
+ *
+ * Nonblocking socket I/O won't work if the socket is associated with
+ * an I/O completion port.
+ *
+ * An inheritable fd cannot be associated with an I/O completion port
+ * because the completion notification of async I/O initiated by the
+ * child process is still posted to the I/O completion port in the
+ * parent process. 
+ */
+#define _NT_USE_NB_IO(fd) \
+    ((fd)->secret->nonblocking || (fd)->secret->inheritable == _PR_TRI_TRUE)
+
+/*
+ * UDP support
+ * 
+ * UDP is supported on NT by the continuation thread mechanism.
+ * The code is borrowed from ptio.c in pthreads nspr, hence the
+ * PT and pt prefixes.  This mechanism is in fact general and
+ * not limited to UDP.  For now, only UDP's recvfrom and sendto
+ * go through the continuation thread if they get WSAEWOULDBLOCK
+ * on first try.  Recv and send on a connected UDP socket still
+ * goes through asychronous io.
+ */
+
+#define PT_DEFAULT_SELECT_MSEC 100
+
+typedef struct pt_Continuation pt_Continuation;
+typedef PRBool (*ContinuationFn)(pt_Continuation *op, PRInt16 revent);
+
+typedef enum pr_ContuationStatus
+{
+    pt_continuation_sumbitted,
+    pt_continuation_inprogress,
+    pt_continuation_abort,
+    pt_continuation_done
+} pr_ContuationStatus;
+
+struct pt_Continuation
+{
+    /* These objects are linked in ascending timeout order */
+    pt_Continuation *next, *prev;           /* self linked list of these things */
+
+    /* The building of the continuation operation */
+    ContinuationFn function;                /* what function to continue */
+    union { SOCKET osfd; } arg1;            /* #1 - the op's fd */
+    union { void* buffer; } arg2;           /* #2 - primary transfer buffer */
+    union { PRIntn amount; } arg3;          /* #3 - size of 'buffer' */
+    union { PRIntn flags; } arg4;           /* #4 - read/write flags */
+    union { PRNetAddr *addr; } arg5;        /* #5 - send/recv address */
+    
+    PRIntervalTime timeout;                 /* representation of the timeout */
+
+    PRIntn event;                           /* flags for select()'s events */
+
+    /*
+    ** The representation and notification of the results of the operation.
+    ** These function can either return an int return code or a pointer to
+    ** some object.
+    */
+    union { PRIntn code; void *object; } result;
+
+    PRIntn syserrno;                        /* in case it failed, why (errno) */
+    pr_ContuationStatus status;             /* the status of the operation */
+    PRCondVar *complete;                    /* to notify the initiating thread */
+};
+
+static struct pt_TimedQueue
+{
+    PRLock *ml;                             /* a little protection */
+    PRThread *thread;                       /* internal thread's identification */
+    PRCondVar *new_op;                      /* new operation supplied */
+    PRCondVar *finish_op;                   /* an existing operation finished */
+    PRUintn op_count;                       /* number of operations in the list */
+    pt_Continuation *head, *tail;           /* head/tail of list of operations */
+
+    pt_Continuation *op;                    /* timed operation furthest in future */
+    PRIntervalTime epoch;                   /* the epoch of 'timed' */
+} pt_tq;
+
+#if defined(DEBUG)
+static struct pt_debug_s
+{
+    PRIntn predictionsFoiled;
+    PRIntn pollingListMax;
+    PRIntn continuationsServed;
+} pt_debug;
+#endif  /* DEBUG */
+
+static void ContinuationThread(void *arg);
+static PRInt32 pt_SendTo(
+    SOCKET osfd, const void *buf,
+    PRInt32 amount, PRInt32 flags, const PRNetAddr *addr,
+    PRIntn addrlen, PRIntervalTime timeout);
+static PRInt32 pt_RecvFrom(SOCKET osfd, void *buf, PRInt32 amount,
+    PRInt32 flags, PRNetAddr *addr, PRIntn *addr_len, PRIntervalTime timeout);
+
+
+/* The key returned from GetQueuedCompletionStatus() is used to determine what
+ * type of completion we have.  We differentiate between IO completions and
+ * CVAR completions.
+ */
+#define KEY_IO              0xaaaaaaaa
+#define KEY_CVAR            0xbbbbbbbb
+
+PRInt32
+_PR_MD_PAUSE_CPU(PRIntervalTime ticks)
+{
+    int awoken = 0;
+    unsigned long bytes, key;
+    int rv;
+    LPOVERLAPPED olp;
+    _MDOverlapped *mdOlp;
+    PRUint32 timeout;
+
+    if (_nt_idleCount > 0) {
+        PRThread *deadThread;
+
+        _MD_LOCK(&_nt_idleLock);
+        while( !PR_CLIST_IS_EMPTY(&_nt_idleList) ) {
+            deadThread = _PR_THREAD_PTR(PR_LIST_HEAD(&_nt_idleList));
+            PR_REMOVE_LINK(&deadThread->links);
+
+            PR_ASSERT(deadThread->state == _PR_DEAD_STATE);
+
+            /* XXXMB - cleanup to do here? */
+            if ( !_PR_IS_NATIVE_THREAD(deadThread) ){
+                /* Spinlock while user thread is still running.
+                 * There is no way to use a condition variable here. The thread
+                 * is dead, and we have to wait until we switch off the dead 
+                 * thread before we can kill the fiber completely.
+                 */
+                while ( deadThread->no_sched)
+                    ;
+
+                DeleteFiber(deadThread->md.fiber_id);
+            }
+            memset(deadThread, 0xa, sizeof(PRThread)); /* debugging */
+            if (!deadThread->threadAllocatedOnStack)
+                PR_DELETE(deadThread);
+            _nt_idleCount--;
+        }
+        _MD_UNLOCK(&_nt_idleLock);
+    }
+
+    if (ticks == PR_INTERVAL_NO_TIMEOUT)
+#if 0
+        timeout = INFINITE;
+#else
+    /*
+     * temporary hack to poll the runq every 5 seconds because of bug in
+     * native threads creating user threads and not poking the right cpu.
+     *
+     * A local thread that was interrupted is bound to its current
+     * cpu but there is no easy way for the interrupter to poke the
+     * right cpu.  This is a hack to poll the runq every 5 seconds.
+     */
+        timeout = 5000;
+#endif
+    else 
+        timeout = PR_IntervalToMilliseconds(ticks);
+
+    /*
+     * The idea of looping here is to complete as many IOs as possible before
+     * returning.  This should minimize trips to the idle thread.
+     */
+    while(1) {
+        rv = GetQueuedCompletionStatus(
+                _pr_completion_port,
+                &bytes,
+                &key,
+                &olp,
+                timeout); 
+        if (rv == 0 && olp == NULL) {
+            /* Error in GetQueuedCompetionStatus */
+            if (GetLastError() != WAIT_TIMEOUT) {
+                /* ARGH - what can we do here? Log an error? XXXMB */
+                return -1;
+            } else {
+                /* If awoken == 0, then we just had a timeout */
+                return awoken;
+            }
+        }
+
+        if (olp == NULL) 
+            return 0;
+
+        mdOlp = (_MDOverlapped *)olp;
+
+        if (mdOlp->ioModel == _MD_MultiWaitIO) {
+            PRRecvWait *desc;
+            PRWaitGroup *group;
+            PRThread *thred = NULL;
+            PRMWStatus mwstatus;
+
+            desc = mdOlp->data.mw.desc;
+            PR_ASSERT(desc != NULL);
+            mwstatus = rv ? PR_MW_SUCCESS : PR_MW_FAILURE;
+            if (InterlockedCompareExchange((PVOID *)&desc->outcome,
+                    (PVOID)mwstatus, (PVOID)PR_MW_PENDING)
+                    == (PVOID)PR_MW_PENDING) {
+                if (mwstatus == PR_MW_SUCCESS) {
+                    desc->bytesRecv = bytes;
+                } else {
+                    mdOlp->data.mw.error = GetLastError();
+                }
+            }
+            group = mdOlp->data.mw.group;
+            PR_ASSERT(group != NULL);
+
+            _PR_MD_LOCK(&group->mdlock);
+            PR_APPEND_LINK(&mdOlp->data.mw.links, &group->io_ready);
+            PR_ASSERT(desc->fd != NULL);
+            NT_HashRemoveInternal(group, desc->fd);
+            if (!PR_CLIST_IS_EMPTY(&group->wait_list)) {
+                thred = _PR_THREAD_CONDQ_PTR(PR_LIST_HEAD(&group->wait_list));
+                PR_REMOVE_LINK(&thred->waitQLinks);
+            }
+            _PR_MD_UNLOCK(&group->mdlock);
+
+            if (thred) {
+                if (!_PR_IS_NATIVE_THREAD(thred)) {
+                    int pri = thred->priority;
+                    _PRCPU *lockedCPU = _PR_MD_CURRENT_CPU();
+                    _PR_THREAD_LOCK(thred);
+                    if (thred->flags & _PR_ON_PAUSEQ) {
+                        _PR_SLEEPQ_LOCK(thred->cpu);
+                        _PR_DEL_SLEEPQ(thred, PR_TRUE);
+                        _PR_SLEEPQ_UNLOCK(thred->cpu);
+                        _PR_THREAD_UNLOCK(thred);
+                        thred->cpu = lockedCPU;
+                        thred->state = _PR_RUNNABLE;
+                        _PR_RUNQ_LOCK(lockedCPU);
+                        _PR_ADD_RUNQ(thred, lockedCPU, pri);
+                        _PR_RUNQ_UNLOCK(lockedCPU);
+                    } else {
+                        /*
+                         * The thread was just interrupted and moved
+                         * from the pause queue to the run queue.
+                         */
+                        _PR_THREAD_UNLOCK(thred);
+                    }
+                } else {
+                    _PR_THREAD_LOCK(thred);
+                    thred->state = _PR_RUNNABLE;
+                    _PR_THREAD_UNLOCK(thred);
+                    ReleaseSemaphore(thred->md.blocked_sema, 1, NULL);
+                }
+            }
+        } else {
+            PRThread *completed_io;
+
+            PR_ASSERT(mdOlp->ioModel == _MD_BlockingIO);
+            completed_io = _PR_THREAD_MD_TO_PTR(mdOlp->data.mdThread);
+            completed_io->md.blocked_io_status = rv;
+            if (rv == 0)
+                completed_io->md.blocked_io_error = GetLastError();
+            completed_io->md.blocked_io_bytes = bytes;
+
+            if ( !_PR_IS_NATIVE_THREAD(completed_io) ) {
+                int pri = completed_io->priority;
+                _PRCPU *lockedCPU = _PR_MD_CURRENT_CPU();
+
+                /* The KEY_CVAR notification only occurs when a native thread
+                 * is notifying a user thread.  For user-user notifications
+                 * the wakeup occurs by having the notifier place the thread 
+                 * on the runq directly; for native-native notifications the
+                 * wakeup occurs by calling ReleaseSemaphore.
+                 */
+                if ( key == KEY_CVAR ) {
+                    PR_ASSERT(completed_io->io_pending == PR_FALSE);
+                    PR_ASSERT(completed_io->io_suspended == PR_FALSE);
+                    PR_ASSERT(completed_io->md.thr_bound_cpu == NULL);
+
+                    /* Thread has already been deleted from sleepQ */
+
+                    /* Switch CPU and add to runQ */
+                    completed_io->cpu = lockedCPU;
+                    completed_io->state = _PR_RUNNABLE;
+                    _PR_RUNQ_LOCK(lockedCPU);
+                    _PR_ADD_RUNQ(completed_io, lockedCPU, pri);
+                    _PR_RUNQ_UNLOCK(lockedCPU);
+                } else {
+                    PR_ASSERT(key == KEY_IO);
+                    PR_ASSERT(completed_io->io_pending == PR_TRUE);
+
+                    _PR_THREAD_LOCK(completed_io);
+
+                    completed_io->io_pending = PR_FALSE;
+
+                    /* If io_suspended is true, then this IO has already resumed.
+                     * We don't need to do anything; because the thread is
+                     * already running.
+                     */
+                    if (completed_io->io_suspended == PR_FALSE) {
+                        if (completed_io->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ)) {
+                            _PR_SLEEPQ_LOCK(completed_io->cpu);
+                            _PR_DEL_SLEEPQ(completed_io, PR_TRUE);
+                            _PR_SLEEPQ_UNLOCK(completed_io->cpu);
+
+                            _PR_THREAD_UNLOCK(completed_io);
+
+						/*
+						 * If an I/O operation is suspended, the thread
+						 * must be running on the same cpu on which the
+						 * I/O operation was issued.
+						 */
+						PR_ASSERT(!completed_io->md.thr_bound_cpu ||
+					(completed_io->cpu == completed_io->md.thr_bound_cpu));
+
+							if (!completed_io->md.thr_bound_cpu)
+                            	completed_io->cpu = lockedCPU;
+                            completed_io->state = _PR_RUNNABLE;
+                            _PR_RUNQ_LOCK(completed_io->cpu);
+                            _PR_ADD_RUNQ(completed_io, completed_io->cpu, pri);
+                            _PR_RUNQ_UNLOCK(completed_io->cpu);
+                        } else {
+                            _PR_THREAD_UNLOCK(completed_io);
+                        }
+                    } else {
+                        _PR_THREAD_UNLOCK(completed_io);
+                    }
+                }
+            } else {
+                /* For native threads, they are only notified through this loop
+                 * when completing IO.  So, don't worry about this being a CVAR
+                 * notification, because that is not possible.
+                 */
+                _PR_THREAD_LOCK(completed_io);
+                completed_io->io_pending = PR_FALSE;
+                if (completed_io->io_suspended == PR_FALSE) {
+                    completed_io->state = _PR_RUNNABLE;
+                    _PR_THREAD_UNLOCK(completed_io);
+                    rv = ReleaseSemaphore(completed_io->md.blocked_sema,
+                            1, NULL);
+                    PR_ASSERT(0 != rv);
+                } else {
+                    _PR_THREAD_UNLOCK(completed_io);
+                }
+            }
+        }
+
+        awoken++;
+        timeout = 0;   /* Don't block on subsequent trips through the loop */
+    }
+
+    /* never reached */
+    return 0;
+}
+
+static PRStatus
+_native_thread_md_wait(PRThread *thread, PRIntervalTime ticks)
+{
+    DWORD rv;
+	PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
+		INFINITE : PR_IntervalToMilliseconds(ticks);
+
+	/*
+	 * thread waiting for a cvar or a joining thread
+	 */
+	rv = WaitForSingleObject(thread->md.blocked_sema, msecs);
+	switch(rv) {
+		case WAIT_OBJECT_0:
+			return PR_SUCCESS;
+			break;
+		case WAIT_TIMEOUT:
+			_PR_THREAD_LOCK(thread);
+			PR_ASSERT (thread->state != _PR_IO_WAIT);
+			if (thread->wait.cvar != NULL) {
+				PR_ASSERT(thread->state == _PR_COND_WAIT);
+				thread->wait.cvar = NULL;
+				thread->state = _PR_RUNNING;
+				_PR_THREAD_UNLOCK(thread);
+			} else {
+				/* The CVAR was notified just as the timeout
+				 * occurred.  This left the semaphore in the
+				 * signaled state.  Call WaitForSingleObject()
+				 * to clear the semaphore.
+				 */
+				_PR_THREAD_UNLOCK(thread);
+				rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE);
+				PR_ASSERT(rv == WAIT_OBJECT_0);
+			}
+			return PR_SUCCESS;
+			break;
+		default:
+			return PR_FAILURE;
+			break;
+	}
+
+    return PR_SUCCESS;
+}
+
+PRStatus
+_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    DWORD rv;
+
+	if (_native_threads_only) {
+		return(_native_thread_md_wait(thread, ticks));
+	}
+    if ( thread->flags & _PR_GLOBAL_SCOPE ) {
+        PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
+            INFINITE : PR_IntervalToMilliseconds(ticks);
+        rv = WaitForSingleObject(thread->md.blocked_sema, msecs);
+        switch(rv) {
+            case WAIT_OBJECT_0:
+                return PR_SUCCESS;
+                break;
+            case WAIT_TIMEOUT:
+                _PR_THREAD_LOCK(thread);
+                if (thread->state == _PR_IO_WAIT) {
+                    if (thread->io_pending == PR_TRUE) {
+                        thread->state = _PR_RUNNING;
+                        thread->io_suspended = PR_TRUE;
+                        _PR_THREAD_UNLOCK(thread);
+                    } else {
+                        /* The IO completed just at the same time the timeout
+                         * occurred.  This left the semaphore in the signaled
+                         * state.  Call WaitForSingleObject() to clear the
+                         * semaphore.
+                         */
+                        _PR_THREAD_UNLOCK(thread);
+                        rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE);
+                        PR_ASSERT(rv == WAIT_OBJECT_0);
+                    }
+                } else {
+                    if (thread->wait.cvar != NULL) {
+                        PR_ASSERT(thread->state == _PR_COND_WAIT);
+                        thread->wait.cvar = NULL;
+                        thread->state = _PR_RUNNING;
+                        _PR_THREAD_UNLOCK(thread);
+                    } else {
+                        /* The CVAR was notified just as the timeout
+                         * occurred.  This left the semaphore in the
+                         * signaled state.  Call WaitForSingleObject()
+                         * to clear the semaphore.
+                         */
+                        _PR_THREAD_UNLOCK(thread);
+                        rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE);
+                        PR_ASSERT(rv == WAIT_OBJECT_0);
+                    }
+                }
+                return PR_SUCCESS;
+                break;
+            default:
+                return PR_FAILURE;
+                break;
+        }
+    } else {
+        PRInt32 is;
+
+        _PR_INTSOFF(is);
+        _PR_MD_SWITCH_CONTEXT(thread);
+    }
+
+    return PR_SUCCESS;
+}
+
+static void
+_native_thread_io_nowait(
+    PRThread *thread,
+    int rv,
+    int bytes)
+{
+    int rc;
+
+    PR_ASSERT(rv != 0);
+    _PR_THREAD_LOCK(thread);
+    if (thread->state == _PR_IO_WAIT) {
+        PR_ASSERT(thread->io_suspended == PR_FALSE);
+        PR_ASSERT(thread->io_pending == PR_TRUE);
+        thread->state = _PR_RUNNING;
+        thread->io_pending = PR_FALSE;
+        _PR_THREAD_UNLOCK(thread);
+    } else {
+        /* The IO completed just at the same time the
+         * thread was interrupted. This left the semaphore
+         * in the signaled state. Call WaitForSingleObject()
+         * to clear the semaphore.
+         */
+        PR_ASSERT(thread->io_suspended == PR_TRUE);
+        PR_ASSERT(thread->io_pending == PR_TRUE);
+        thread->io_pending = PR_FALSE;
+        _PR_THREAD_UNLOCK(thread);
+        rc = WaitForSingleObject(thread->md.blocked_sema, INFINITE);
+        PR_ASSERT(rc == WAIT_OBJECT_0);
+    }
+
+    thread->md.blocked_io_status = rv;
+    thread->md.blocked_io_bytes = bytes;
+    rc = ResetEvent(thread->md.thr_event);
+    PR_ASSERT(rc != 0);
+    return;
+}
+
+static PRStatus
+_native_thread_io_wait(PRThread *thread, PRIntervalTime ticks)
+{
+    DWORD rv, bytes;
+#define _NATIVE_IO_WAIT_HANDLES		2
+#define _NATIVE_WAKEUP_EVENT_INDEX	0
+#define _NATIVE_IO_EVENT_INDEX		1
+
+	HANDLE wait_handles[_NATIVE_IO_WAIT_HANDLES];
+
+	PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
+		INFINITE : PR_IntervalToMilliseconds(ticks);
+
+    PR_ASSERT(thread->flags & _PR_GLOBAL_SCOPE);
+
+	wait_handles[0] = thread->md.blocked_sema;
+	wait_handles[1] = thread->md.thr_event;
+	rv = WaitForMultipleObjects(_NATIVE_IO_WAIT_HANDLES, wait_handles,
+										FALSE, msecs);
+
+	switch(rv) {
+		case WAIT_OBJECT_0 + _NATIVE_IO_EVENT_INDEX:
+			/*
+			 * I/O op completed
+			 */
+			_PR_THREAD_LOCK(thread);
+			if (thread->state == _PR_IO_WAIT) {
+
+				PR_ASSERT(thread->io_suspended == PR_FALSE);
+				PR_ASSERT(thread->io_pending == PR_TRUE);
+				thread->state = _PR_RUNNING;
+				thread->io_pending = PR_FALSE;
+				_PR_THREAD_UNLOCK(thread);
+			} else {
+				/* The IO completed just at the same time the
+				 * thread was interrupted. This led to us being
+				 * notified twice. Call WaitForSingleObject()
+				 * to clear the semaphore.
+				 */
+				PR_ASSERT(thread->io_suspended == PR_TRUE);
+				PR_ASSERT(thread->io_pending == PR_TRUE);
+				thread->io_pending = PR_FALSE;
+				_PR_THREAD_UNLOCK(thread);
+				rv = WaitForSingleObject(thread->md.blocked_sema,
+							INFINITE);
+				PR_ASSERT(rv == WAIT_OBJECT_0);
+			}
+
+			rv = GetOverlappedResult((HANDLE) thread->io_fd,
+				&thread->md.overlapped.overlapped, &bytes, FALSE);
+
+			thread->md.blocked_io_status = rv;
+			if (rv != 0) {
+				thread->md.blocked_io_bytes = bytes;
+			} else {
+				thread->md.blocked_io_error = GetLastError();
+				PR_ASSERT(ERROR_IO_PENDING != thread->md.blocked_io_error);
+			}
+			rv = ResetEvent(thread->md.thr_event);
+			PR_ASSERT(rv != 0);
+			break;
+		case WAIT_OBJECT_0 + _NATIVE_WAKEUP_EVENT_INDEX:
+			/*
+			 * I/O interrupted; 
+			 */
+#ifdef DEBUG
+			_PR_THREAD_LOCK(thread);
+			PR_ASSERT(thread->io_suspended == PR_TRUE);
+			_PR_THREAD_UNLOCK(thread);
+#endif
+			break;
+		case WAIT_TIMEOUT:
+			_PR_THREAD_LOCK(thread);
+			if (thread->state == _PR_IO_WAIT) {
+				thread->state = _PR_RUNNING;
+				thread->io_suspended = PR_TRUE;
+				_PR_THREAD_UNLOCK(thread);
+			} else {
+				/*
+				 * The thread was interrupted just as the timeout
+				 * occurred. This left the semaphore in the signaled
+				 * state. Call WaitForSingleObject() to clear the
+				 * semaphore.
+				 */
+				PR_ASSERT(thread->io_suspended == PR_TRUE);
+				_PR_THREAD_UNLOCK(thread);
+				rv = WaitForSingleObject(thread->md.blocked_sema, INFINITE);
+				PR_ASSERT(rv == WAIT_OBJECT_0);
+			}
+			break;
+		default:
+			return PR_FAILURE;
+			break;
+	}
+
+    return PR_SUCCESS;
+}
+
+
+static PRStatus
+_NT_IO_WAIT(PRThread *thread, PRIntervalTime timeout)
+{
+    PRBool fWait = PR_TRUE;
+
+	if (_native_threads_only) {
+		return(_native_thread_io_wait(thread, timeout));
+	}
+    if (!_PR_IS_NATIVE_THREAD(thread))  {
+
+        _PR_THREAD_LOCK(thread);
+
+        /* The IO may have already completed; if so, don't add to sleepQ, 
+         * since we are already on the runQ!
+         */
+        if (thread->io_pending == PR_TRUE) {
+            _PR_SLEEPQ_LOCK(thread->cpu);
+            _PR_ADD_SLEEPQ(thread, timeout);
+            _PR_SLEEPQ_UNLOCK(thread->cpu);
+        } else
+            fWait = PR_FALSE;
+        _PR_THREAD_UNLOCK(thread);
+    }
+    if (fWait)
+        return _PR_MD_WAIT(thread, timeout);
+    else
+        return PR_SUCCESS;
+}
+
+/*
+ * Unblock threads waiting for I/O
+ * used when interrupting threads
+ *
+ * NOTE: The thread lock should held when this function is called.
+ * On return, the thread lock is released.
+ */
+void _PR_Unblock_IO_Wait(PRThread *thr)
+{
+    PRStatus rv;
+    _PRCPU *cpu = thr->cpu;
+ 
+    PR_ASSERT(thr->state == _PR_IO_WAIT);
+	/*
+	 * A thread for which an I/O timed out or was interrupted cannot be
+	 * in an IO_WAIT state except as a result of calling PR_Close or
+	 * PR_NT_CancelIo for the FD. For these two cases, _PR_IO_WAIT state
+	 * is not interruptible
+	 */
+	if (thr->md.interrupt_disabled == PR_TRUE) {
+    	_PR_THREAD_UNLOCK(thr);
+		return;
+	}
+    thr->io_suspended = PR_TRUE;
+    thr->state = _PR_RUNNABLE;
+
+    if (!_PR_IS_NATIVE_THREAD(thr)) {
+        PRThread *me = _PR_MD_CURRENT_THREAD();
+        PR_ASSERT(thr->flags & (_PR_ON_SLEEPQ | _PR_ON_PAUSEQ));
+        _PR_SLEEPQ_LOCK(cpu);
+        _PR_DEL_SLEEPQ(thr, PR_TRUE);
+        _PR_SLEEPQ_UNLOCK(cpu);
+		/*
+		 * this thread will continue to run on the same cpu until the
+		 * I/O is aborted by closing the FD or calling CancelIO
+		 */
+		thr->md.thr_bound_cpu = cpu;
+
+        PR_ASSERT(!(thr->flags & _PR_IDLE_THREAD));
+        _PR_AddThreadToRunQ(me, thr);
+    }
+    _PR_THREAD_UNLOCK(thr);
+    rv = _PR_MD_WAKEUP_WAITER(thr);
+    PR_ASSERT(PR_SUCCESS == rv);
+}
+
+/* Resume an outstanding IO; requires that after the switch, we disable */
+static PRStatus
+_NT_ResumeIO(PRThread *thread, PRIntervalTime ticks)
+{
+    PRBool fWait = PR_TRUE;
+
+    if (!_PR_IS_NATIVE_THREAD(thread)) {
+        if (_pr_use_static_tls) {
+            _pr_io_restarted_io = thread;
+        } else {
+            TlsSetValue(_pr_io_restartedIOIndex, thread);
+        }
+    } else {
+        _PR_THREAD_LOCK(thread);
+        if (!thread->io_pending)
+            fWait = PR_FALSE;
+        thread->io_suspended = PR_FALSE;
+            
+        _PR_THREAD_UNLOCK(thread);
+    }
+    /* We don't put ourselves back on the sleepQ yet; until we 
+     * set the suspended bit to false, we can't do that.  Just save
+     * the sleep time here, and then continue.  The restarted_io handler
+     * will add us to the sleepQ if needed.
+     */
+    thread->sleep = ticks;
+
+    if (fWait) {
+        if (!_PR_IS_NATIVE_THREAD(thread))
+            return _PR_MD_WAIT(thread, ticks);
+        else
+            return _NT_IO_WAIT(thread, ticks);
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus
+_PR_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread == NULL) {
+        /* If thread is NULL, we aren't waking a thread, we're just poking
+         * idle thread 
+         */
+        if ( PostQueuedCompletionStatus(_pr_completion_port, 0, 
+            KEY_CVAR, NULL) == FALSE) 
+            return PR_FAILURE;
+        return PR_SUCCESS;
+    }
+
+    if ( _PR_IS_NATIVE_THREAD(thread) ) {
+        if (ReleaseSemaphore(thread->md.blocked_sema, 1, NULL) == FALSE)
+            return PR_FAILURE;
+        else
+            return PR_SUCCESS;
+    } else {
+        PRThread *me = _PR_MD_CURRENT_THREAD();
+
+        /* When a Native thread has to awaken a user thread, it has to poke
+         * the completion port because all user threads might be idle, and
+         * thus the CPUs are just waiting for a completion.  
+         *
+         * XXXMB - can we know when we are truely idle (and not checking 
+         *         the runq)?
+         */
+        if ((_PR_IS_NATIVE_THREAD(me) || (thread->cpu != me->cpu)) &&
+                (!thread->md.thr_bound_cpu)) {
+            /* The thread should not be in any queue */
+            PR_ASSERT(thread->queueCount == 0);
+            if ( PostQueuedCompletionStatus(_pr_completion_port, 0, 
+                KEY_CVAR, &(thread->md.overlapped.overlapped)) == FALSE) 
+                return PR_FAILURE;
+        }
+        return PR_SUCCESS;
+    }
+}
+
+void
+_PR_MD_INIT_IO()
+{
+    WORD WSAVersion = 0x0101;
+    WSADATA WSAData;
+    int err;
+    OSVERSIONINFO OSversion;
+
+    err = WSAStartup( WSAVersion, &WSAData );
+    PR_ASSERT(0 == err);
+                                                      
+    _pr_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 
+                                                 NULL, 
+                                                 0, 
+                                                 0);
+ 
+    _MD_NEW_LOCK(&_pr_recycle_lock);
+    _MD_NEW_LOCK(&_pr_ioq_lock);
+
+    OSversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    if (GetVersionEx(&OSversion)) {
+        _nt_version_gets_lockfile_completion = PR_FALSE;
+        if (OSversion.dwMajorVersion >= 4) {
+            _nt_version_gets_lockfile_completion = PR_TRUE;
+        }
+    } else 
+        PR_ASSERT(0);
+
+    IsFileLocalInit();
+
+    /*
+     * UDP support: start up the continuation thread
+     */
+
+    pt_tq.op_count = 0;
+    pt_tq.head = pt_tq.tail = NULL;
+    pt_tq.ml = PR_NewLock();
+    PR_ASSERT(NULL != pt_tq.ml);
+    pt_tq.new_op = PR_NewCondVar(pt_tq.ml);
+    PR_ASSERT(NULL != pt_tq.new_op);
+#if defined(DEBUG)
+    memset(&pt_debug, 0, sizeof(struct pt_debug_s));
+#endif
+
+    pt_tq.thread = PR_CreateThread(
+        PR_SYSTEM_THREAD, ContinuationThread, NULL,
+        PR_PRIORITY_URGENT, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    PR_ASSERT(NULL != pt_tq.thread);
+
+#ifdef DEBUG
+    /* Doublecheck _pr_filetime_offset's hard-coded value is correct. */
+    {
+        SYSTEMTIME systime;
+        union {
+           PRTime prt;
+           FILETIME ft;
+        } filetime;
+        BOOL rv;
+
+        systime.wYear = 1970;
+        systime.wMonth = 1;
+        /* wDayOfWeek is ignored */
+        systime.wDay = 1;
+        systime.wHour = 0;
+        systime.wMinute = 0;
+        systime.wSecond = 0;
+        systime.wMilliseconds = 0;
+
+        rv = SystemTimeToFileTime(&systime, &filetime.ft);
+        PR_ASSERT(0 != rv);
+        PR_ASSERT(filetime.prt == _pr_filetime_offset);
+    }
+#endif /* DEBUG */
+
+    _PR_NT_InitSids();
+}
+
+/* --- SOCKET IO --------------------------------------------------------- */
+
+/* _md_get_recycled_socket()
+ * Get a socket from the recycle bin; if no sockets are in the bin,
+ * create one.  The socket will be passed to AcceptEx() as the
+ * second argument.
+ */
+static SOCKET
+_md_get_recycled_socket()
+{
+    SOCKET rv;
+    int af = AF_INET;
+
+    _MD_LOCK(&_pr_recycle_lock);
+    if (_pr_recycle_tail) {
+        _pr_recycle_tail--;
+        rv = _pr_recycle_array[_pr_recycle_tail];
+        _MD_UNLOCK(&_pr_recycle_lock);
+        return rv;
+    }
+    _MD_UNLOCK(&_pr_recycle_lock);
+
+    rv = _PR_MD_SOCKET(af, SOCK_STREAM, 0);
+    if (rv != INVALID_SOCKET && _md_Associate((HANDLE)rv) == 0) {
+        closesocket(rv);
+        return INVALID_SOCKET;
+    }
+    return rv;
+}
+
+/* _md_put_recycled_socket()
+ * Add a socket to the recycle bin.
+ */
+static void
+_md_put_recycled_socket(SOCKET newsock)
+{
+    PR_ASSERT(_pr_recycle_tail >= 0);
+
+    _MD_LOCK(&_pr_recycle_lock);
+    if (_pr_recycle_tail < RECYCLE_SIZE) {
+        _pr_recycle_array[_pr_recycle_tail] = newsock;
+        _pr_recycle_tail++;
+        _MD_UNLOCK(&_pr_recycle_lock);
+    } else {
+        _MD_UNLOCK(&_pr_recycle_lock);
+        closesocket(newsock);
+    }
+ 
+    return;
+}
+
+/* _md_Associate()
+ * Associates a file with the completion port.
+ * Returns 0 on failure, 1 on success.
+ */
+PRInt32
+_md_Associate(HANDLE file)
+{
+    HANDLE port;
+
+	if (!_native_threads_only) {
+		port = CreateIoCompletionPort((HANDLE)file, 
+										_pr_completion_port, 
+										KEY_IO,
+										0);
+
+		/* XXX should map error codes on failures */
+		return (port == _pr_completion_port);
+	} else {
+		return 1;
+	}
+}
+
+/*
+ * _md_MakeNonblock()
+ * Make a socket nonblocking.
+ * Returns 0 on failure, 1 on success.
+ */
+static PRInt32
+_md_MakeNonblock(HANDLE file)
+{
+    int rv;
+    u_long one = 1;
+
+    rv = ioctlsocket((SOCKET)file, FIONBIO, &one);
+    /* XXX should map error codes on failures */
+    return (rv == 0);
+}
+
+static int missing_completions = 0;
+static int max_wait_loops = 0;
+
+static PRInt32
+_NT_IO_ABORT(PROsfd sock)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRBool fWait;
+    PRInt32 rv;
+    int loop_count;
+
+    /* This is a clumsy way to abort the IO, but it is all we can do.
+     * It looks a bit racy, but we handle all the cases. 
+     * case 1:  IO completes before calling closesocket
+     *     case 1a:  fWait is set to PR_FALSE
+     *           This should e the most likely case.  We'll properly
+     *           not wait call _NT_IO_WAIT, since the closesocket()
+     *           won't be forcing a completion.
+     *     case 1b: fWait is set to PR_TRUE
+     *           This hopefully won't happen much.  When it does, this
+     *           thread will timeout in _NT_IO_WAIT for CLOSE_INTERVAL
+     *           before cleaning up.
+     * case 2:  IO does not complete before calling closesocket
+     *     case 2a: IO never completes
+     *           This is the likely case.  We'll close it and wait
+     *           for the completion forced by the close.  Return should
+     *           be immediate.
+     *     case 2b: IO completes just after calling closesocket
+     *           Since the closesocket is issued, we'll either get a
+     *           completion back for the real IO or for the close.  We
+     *           don't really care.  It may not even be possible to get
+     *           a real completion here.  In any event, we'll awaken
+     *           from NT_IO_WAIT immediately.
+     */
+
+    _PR_THREAD_LOCK(me);
+    fWait = me->io_pending;
+    if (fWait) {
+        /*
+         * If there's still I/O pending, it should have already timed
+         * out once before this function is called.
+         */
+        PR_ASSERT(me->io_suspended == PR_TRUE);
+
+        /* Set up to wait for I/O completion again */
+        me->state = _PR_IO_WAIT;
+        me->io_suspended = PR_FALSE;
+        me->md.interrupt_disabled = PR_TRUE;
+    }
+    _PR_THREAD_UNLOCK(me);
+
+    /* Close the socket if there is one */
+    if (sock != INVALID_SOCKET) {
+        rv = closesocket((SOCKET)sock);
+    }
+
+    /* If there was I/O pending before the close, wait for it to complete */
+    if (fWait) {
+
+        /* Wait and wait for the I/O to complete */
+        for (loop_count = 0; fWait; ++loop_count) {
+
+            _NT_IO_WAIT(me, CLOSE_TIMEOUT);
+
+            _PR_THREAD_LOCK(me);
+            fWait = me->io_pending;
+            if (fWait) {
+                PR_ASSERT(me->io_suspended == PR_TRUE);
+                me->state = _PR_IO_WAIT;
+                me->io_suspended = PR_FALSE;
+            }
+            _PR_THREAD_UNLOCK(me);
+
+            if (loop_count > max_wait_loops) {
+                max_wait_loops = loop_count;
+            }
+        }
+
+        if (loop_count > 1) {
+            ++missing_completions;
+        }
+
+        me->md.interrupt_disabled = PR_FALSE;
+        me->io_pending = PR_FALSE;
+        me->state = _PR_RUNNING;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+    me->md.thr_bound_cpu = NULL;
+    me->io_suspended = PR_FALSE;
+
+    return rv;
+}
+
+
+PROsfd
+_PR_MD_SOCKET(int af, int type, int flags)
+{
+    SOCKET sock;
+
+    sock = socket(af, type, flags);
+
+    if (sock == INVALID_SOCKET) {
+        _PR_MD_MAP_SOCKET_ERROR(WSAGetLastError());
+    }
+
+    return (PROsfd)sock;
+}
+
+struct connect_data_s {
+    PRInt32 status;
+    PRInt32 error;
+    PROsfd  osfd;
+    struct sockaddr *addr;
+    PRUint32 addrlen;
+    PRIntervalTime timeout;
+};
+
+void
+_PR_MD_connect_thread(void *cdata)
+{
+    struct connect_data_s *cd = (struct connect_data_s *)cdata;
+
+    cd->status = connect(cd->osfd, cd->addr, cd->addrlen);
+
+    if (cd->status == SOCKET_ERROR)
+        cd->error = WSAGetLastError();
+
+    return;
+}
+
+
+PRInt32
+_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, 
+               PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    u_long nbio;
+    PRInt32 rc;
+
+    if (fd->secret->nonblocking) {
+        if (!fd->secret->md.io_model_committed) {
+            rv = _md_MakeNonblock((HANDLE)osfd);
+            PR_ASSERT(0 != rv);
+            fd->secret->md.io_model_committed = PR_TRUE;
+        }
+
+        if ((rv = connect(osfd, (struct sockaddr *) addr, addrlen)) == -1) {
+            err = WSAGetLastError();
+            _PR_MD_MAP_CONNECT_ERROR(err);
+        }
+        return rv;
+    }
+
+    /*
+     * Temporarily make the socket non-blocking so that we can
+     * initiate a non-blocking connect and wait for its completion
+     * (with a timeout) in select.
+     */
+    PR_ASSERT(!fd->secret->md.io_model_committed);
+    nbio = 1;
+    rv = ioctlsocket((SOCKET)osfd, FIONBIO, &nbio);
+    PR_ASSERT(0 == rv);
+
+    rc = _nt_nonblock_connect(fd, (struct sockaddr *) addr, addrlen, timeout);
+
+    /* Set the socket back to blocking. */
+    nbio = 0;
+    rv = ioctlsocket((SOCKET)osfd, FIONBIO, &nbio);
+    PR_ASSERT(0 == rv);
+
+    return rc;
+}
+
+PRInt32
+_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
+{
+    PRInt32 rv;
+#if 0
+    int one = 1;
+#endif
+
+    rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen);
+
+    if (rv == SOCKET_ERROR) {
+        _PR_MD_MAP_BIND_ERROR(WSAGetLastError());
+        return -1;
+    }
+
+#if 0
+    /* Disable nagle- so far unknown if this is good or not...
+     */
+    rv = setsockopt(fd->secret->md.osfd, 
+                    SOL_SOCKET,
+                    TCP_NODELAY,
+                    (const char *)&one,
+                    sizeof(one));
+    PR_ASSERT(rv == 0);
+#endif
+
+    return 0;
+}
+
+void _PR_MD_UPDATE_ACCEPT_CONTEXT(PROsfd accept_sock, PROsfd listen_sock)
+{
+    /* Sockets accept()'d with AcceptEx need to call this setsockopt before
+     * calling anything other than ReadFile(), WriteFile(), send(), recv(), 
+     * Transmitfile(), and closesocket().  In order to call any other 
+     * winsock functions, we have to make this setsockopt call.
+     *
+     * XXXMB - For the server, we *NEVER* need this in
+     * the "normal" code path.  But now we have to call it.  This is a waste
+     * of a system call.  We'd like to only call it before calling the 
+     * obscure socket calls, but since we don't know at that point what the
+     * original socket was (or even if it is still alive) we can't do it
+     * at that point... 
+     */
+    setsockopt((SOCKET)accept_sock, 
+               SOL_SOCKET, 
+               SO_UPDATE_ACCEPT_CONTEXT,
+               (char *)&listen_sock,
+               sizeof(listen_sock));
+
+}
+
+#define INET_ADDR_PADDED (sizeof(PRNetAddr) + 16)
+PROsfd
+_PR_MD_FAST_ACCEPT(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
+              PRIntervalTime timeout, PRBool fast, 
+              _PR_AcceptTimeoutCallback callback, void *callbackArg)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    SOCKET accept_sock;
+    int bytes;
+    PRNetAddr *Laddr;
+    PRNetAddr *Raddr;
+    PRUint32 llen, err;
+    int rv;
+
+    if (_NT_USE_NB_IO(fd)) {
+        if (!fd->secret->md.io_model_committed) {
+            rv = _md_MakeNonblock((HANDLE)osfd);
+            PR_ASSERT(0 != rv);
+            fd->secret->md.io_model_committed = PR_TRUE;
+        }
+        /*
+         * The accepted socket inherits the nonblocking and
+         * inheritable (HANDLE_FLAG_INHERIT) attributes of
+         * the listening socket.
+         */
+        accept_sock = _nt_nonblock_accept(fd, (struct sockaddr *)raddr, rlen, timeout);
+        if (!fd->secret->nonblocking) {
+            u_long zero = 0;
+
+            rv = ioctlsocket(accept_sock, FIONBIO, &zero);
+            PR_ASSERT(0 == rv);
+        }
+        return accept_sock;
+    }
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return -1;
+    }
+
+    if (!fd->secret->md.io_model_committed) {
+        rv = _md_Associate((HANDLE)osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+
+    if (!me->md.acceptex_buf) {
+        me->md.acceptex_buf = PR_MALLOC(2*INET_ADDR_PADDED);
+        if (!me->md.acceptex_buf) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return -1;
+        }
+    }
+
+    accept_sock = _md_get_recycled_socket();
+    if (accept_sock == INVALID_SOCKET)
+        return -1;
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+	if (_native_threads_only)
+		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		closesocket(accept_sock);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+    me->io_fd = osfd;
+
+    rv = AcceptEx((SOCKET)osfd,
+                  accept_sock,
+                  me->md.acceptex_buf,
+                  0,
+                  INET_ADDR_PADDED,
+                  INET_ADDR_PADDED,
+                  &bytes,
+                  &(me->md.overlapped.overlapped));
+
+    if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING))  {
+        /* Argh! The IO failed */
+		closesocket(accept_sock);
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return -1;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+		_PR_MD_MAP_ACCEPTEX_ERROR(err);
+        return -1;
+    }
+
+    if (_native_threads_only && rv) {
+        _native_thread_io_nowait(me, rv, bytes);
+    } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) {
+        PR_ASSERT(0);
+        closesocket(accept_sock);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+    if (me->io_suspended) {
+        closesocket(accept_sock);
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        }
+        return -1;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+		closesocket(accept_sock);
+		_PR_MD_MAP_ACCEPTEX_ERROR(me->md.blocked_io_error);
+        return -1;
+    }
+
+    if (!fast)
+        _PR_MD_UPDATE_ACCEPT_CONTEXT((SOCKET)accept_sock, (SOCKET)osfd);
+
+    /* IO is done */
+    GetAcceptExSockaddrs(
+            me->md.acceptex_buf,
+            0,
+            INET_ADDR_PADDED,
+            INET_ADDR_PADDED,
+            (LPSOCKADDR *)&(Laddr),
+            &llen,
+            (LPSOCKADDR *)&(Raddr),
+            (unsigned int *)rlen);
+
+    if (raddr != NULL)
+        memcpy((char *)raddr, (char *)&Raddr->inet, *rlen);
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+
+    return accept_sock;
+}
+
+PRInt32
+_PR_MD_FAST_ACCEPT_READ(PRFileDesc *sd, PROsfd *newSock, PRNetAddr **raddr, 
+                   void *buf, PRInt32 amount, PRIntervalTime timeout, 
+                   PRBool fast, _PR_AcceptTimeoutCallback callback, 
+                   void *callbackArg)
+{
+    PROsfd sock = sd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    int bytes;
+    PRNetAddr *Laddr;
+    PRUint32 llen, rlen, err;
+    int rv;
+    PRBool isConnected;
+    PRBool madeCallback = PR_FALSE;
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return -1;
+    }
+
+    if (!sd->secret->md.io_model_committed) {
+        rv = _md_Associate((HANDLE)sock);
+        PR_ASSERT(0 != rv);
+        sd->secret->md.io_model_committed = PR_TRUE;
+    }
+
+    *newSock = _md_get_recycled_socket();
+    if (*newSock == INVALID_SOCKET)
+        return -1;
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+	if (_native_threads_only)
+		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		closesocket(*newSock);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+    me->io_fd = sock;
+
+    rv = AcceptEx((SOCKET)sock,
+                  *newSock,
+                  buf,
+                  amount,
+                  INET_ADDR_PADDED,
+                  INET_ADDR_PADDED,
+                  &bytes,
+                  &(me->md.overlapped.overlapped));
+
+    if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING)) {
+		closesocket(*newSock);
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return -1;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+		_PR_MD_MAP_ACCEPTEX_ERROR(err);
+        return -1;
+    }
+
+    if (_native_threads_only && rv) {
+        _native_thread_io_nowait(me, rv, bytes);
+    } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) {
+        PR_ASSERT(0);
+        closesocket(*newSock);
+        return -1;
+    }
+
+retry:
+    if (me->io_suspended) {
+        PRInt32 err;
+        INT seconds;
+        INT bytes = sizeof(seconds);
+
+        PR_ASSERT(timeout != PR_INTERVAL_NO_TIMEOUT);
+
+        err = getsockopt(*newSock, 
+                         SOL_SOCKET,
+                         SO_CONNECT_TIME,
+                         (char *)&seconds,
+                         (PINT)&bytes);
+        if ( err == NO_ERROR ) {
+            PRIntervalTime elapsed = PR_SecondsToInterval(seconds);
+
+            if (seconds == 0xffffffff) 
+                isConnected = PR_FALSE;
+            else 
+                isConnected = PR_TRUE;
+
+            if (!isConnected) {
+                if (madeCallback == PR_FALSE && callback)
+                    callback(callbackArg);
+                madeCallback = PR_TRUE;
+                me->state = _PR_IO_WAIT;
+                if (_NT_ResumeIO(me, timeout) == PR_FAILURE) {
+                    closesocket(*newSock);
+                    return -1;
+                }
+                goto retry;
+            }
+
+            if (elapsed < timeout) {
+                /* Socket is connected but time not elapsed, RESUME IO */
+                timeout -= elapsed;
+                me->state = _PR_IO_WAIT;
+                if (_NT_ResumeIO(me, timeout) == PR_FAILURE) {
+                    closesocket(*newSock);
+                    return -1;
+                }
+                goto retry;
+            }
+        } else {
+            /*  What to do here? Assume socket not open?*/
+            PR_ASSERT(0);
+            isConnected = PR_FALSE;
+        }
+
+        rv = _NT_IO_ABORT(*newSock);
+
+        PR_ASSERT(me->io_pending ==  PR_FALSE);
+        PR_ASSERT(me->io_suspended ==  PR_FALSE);
+        PR_ASSERT(me->md.thr_bound_cpu ==  NULL);
+        /* If the IO is still suspended, it means we didn't get any 
+         * completion from NT_IO_WAIT.  This is not disasterous, I hope,
+         * but it may mean we still have an IO outstanding...  Try to 
+         * recover by just allowing ourselves to continue.
+         */
+        me->io_suspended = PR_FALSE;
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        }
+        me->state = _PR_RUNNING;
+        closesocket(*newSock);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+    PR_ASSERT(me->io_suspended == PR_FALSE);
+    PR_ASSERT(me->md.thr_bound_cpu == NULL);
+
+    if (me->md.blocked_io_status == 0) {
+		_PR_MD_MAP_ACCEPTEX_ERROR(me->md.blocked_io_error);
+        closesocket(*newSock);
+        return -1;
+    }
+
+    if (!fast) 
+        _PR_MD_UPDATE_ACCEPT_CONTEXT((SOCKET)*newSock, (SOCKET)sock);
+
+    /* IO is done */
+    GetAcceptExSockaddrs(
+            buf,
+            amount,
+            INET_ADDR_PADDED,
+            INET_ADDR_PADDED,
+            (LPSOCKADDR *)&(Laddr),
+            &llen,
+            (LPSOCKADDR *)(raddr),
+            (unsigned int *)&rlen);
+
+    return me->md.blocked_io_bytes;
+}
+
+PRInt32
+_PR_MD_SENDFILE(PRFileDesc *sock, PRSendFileData *sfd,
+					PRInt32 flags, PRIntervalTime timeout)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 tflags;
+    int rv, err;
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return -1;
+    }
+
+    if (!sock->secret->md.io_model_committed) {
+        rv = _md_Associate((HANDLE)sock->secret->md.osfd);
+        PR_ASSERT(0 != rv);
+        sock->secret->md.io_model_committed = PR_TRUE;
+    }
+    if (!me->md.xmit_bufs) {
+        me->md.xmit_bufs = PR_NEW(TRANSMIT_FILE_BUFFERS);
+        if (!me->md.xmit_bufs) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return -1;
+        }
+    }
+    me->md.xmit_bufs->Head       = (void *)sfd->header;
+    me->md.xmit_bufs->HeadLength = sfd->hlen;
+    me->md.xmit_bufs->Tail       = (void *)sfd->trailer;
+    me->md.xmit_bufs->TailLength = sfd->tlen;
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+    me->md.overlapped.overlapped.Offset = sfd->file_offset;
+	if (_native_threads_only)
+		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+    tflags = 0;
+    if (flags & PR_TRANSMITFILE_CLOSE_SOCKET)
+        tflags = TF_DISCONNECT | TF_REUSE_SOCKET;
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+    me->io_fd = sock->secret->md.osfd;
+
+    rv = TransmitFile((SOCKET)sock->secret->md.osfd,
+                      (HANDLE)sfd->fd->secret->md.osfd,
+                      (DWORD)sfd->file_nbytes,
+                      (DWORD)0,
+                      (LPOVERLAPPED)&(me->md.overlapped.overlapped),
+                      (TRANSMIT_FILE_BUFFERS *)me->md.xmit_bufs,
+                      (DWORD)tflags);
+    if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return -1;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+		_PR_MD_MAP_TRANSMITFILE_ERROR(err);
+        return -1;
+    }
+
+    if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) {
+        PR_ASSERT(0);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+    if (me->io_suspended) {
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        }
+        return -1;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+		_PR_MD_MAP_TRANSMITFILE_ERROR(me->md.blocked_io_error);
+        return -1;
+    }
+
+    if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
+        _md_put_recycled_socket(sock->secret->md.osfd);
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+
+    return me->md.blocked_io_bytes;
+}
+
+PRInt32
+_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 
+            PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    int bytes;
+    int rv, err;
+
+    if (_NT_USE_NB_IO(fd)) {
+        if (!fd->secret->md.io_model_committed) {
+            rv = _md_MakeNonblock((HANDLE)osfd);
+            PR_ASSERT(0 != rv);
+            fd->secret->md.io_model_committed = PR_TRUE;
+        }
+        return _nt_nonblock_recv(fd, buf, amount, flags, timeout);
+    }
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return -1;
+    }
+
+    if (!fd->secret->md.io_model_committed) {
+        rv = _md_Associate((HANDLE)osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+	if (_native_threads_only)
+		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+    me->io_fd = osfd;
+
+    rv = ReadFile((HANDLE)osfd,
+                  buf, 
+                  amount,
+                  &bytes,
+                  &(me->md.overlapped.overlapped));
+    if ( (rv == 0) && (GetLastError() != ERROR_IO_PENDING) ) {
+    	_PR_THREAD_LOCK(me);
+        me->io_pending = PR_FALSE;
+        me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return -1;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+        if ((err = GetLastError()) == ERROR_HANDLE_EOF)
+            return 0;
+		_PR_MD_MAP_READ_ERROR(err);
+        return -1;
+    }
+
+    if (_native_threads_only && rv) {
+        _native_thread_io_nowait(me, rv, bytes);
+    } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) {
+        PR_ASSERT(0);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+    if (me->io_suspended) {
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        }
+        return -1;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+        if (me->md.blocked_io_error == ERROR_HANDLE_EOF)
+            return 0;
+		_PR_MD_MAP_READ_ERROR(me->md.blocked_io_error);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+
+    return me->md.blocked_io_bytes;
+}
+
+PRInt32
+_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+            PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    int bytes;
+    int rv, err;
+
+    if (_NT_USE_NB_IO(fd)) {
+        if (!fd->secret->md.io_model_committed) {
+            rv = _md_MakeNonblock((HANDLE)osfd);
+            PR_ASSERT(0 != rv);
+            fd->secret->md.io_model_committed = PR_TRUE;
+        }
+        return _nt_nonblock_send(fd, (char *)buf, amount, timeout);
+    }
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return -1;
+    }
+
+    if (!fd->secret->md.io_model_committed) {
+        rv = _md_Associate((HANDLE)osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+	if (_native_threads_only)
+		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+    me->io_fd = osfd;
+
+    rv = WriteFile((HANDLE)osfd,
+                   buf, 
+                   amount,
+                   &bytes,
+                   &(me->md.overlapped.overlapped));
+    if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) {
+    	_PR_THREAD_LOCK(me);
+        me->io_pending = PR_FALSE;
+        me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return -1;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+		_PR_MD_MAP_WRITE_ERROR(err);
+        return -1;
+    }
+
+    if (_native_threads_only && rv) {
+        _native_thread_io_nowait(me, rv, bytes);
+    } else if (_NT_IO_WAIT(me, timeout) == PR_FAILURE) {
+        PR_ASSERT(0);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+    if (me->io_suspended) {
+        if (_PR_PENDING_INTERRUPT(me)) {
+            me->flags &= ~_PR_INTERRUPT;
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        } else {
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        }
+        return -1;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+		_PR_MD_MAP_WRITE_ERROR(me->md.blocked_io_error);
+        return -1;
+    }
+
+    PR_ASSERT(me->io_pending == PR_FALSE);
+
+    return me->md.blocked_io_bytes;
+}
+
+PRInt32
+_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+              const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv;
+
+    if (!fd->secret->md.io_model_committed) {
+        rv = _md_MakeNonblock((HANDLE)osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+    if (_NT_USE_NB_IO(fd))
+        return _nt_nonblock_sendto(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
+    else
+        return pt_SendTo(osfd, buf, amount, flags, addr, addrlen, timeout);
+}
+
+PRInt32
+_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+                PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv;
+
+    if (!fd->secret->md.io_model_committed) {
+        rv = _md_MakeNonblock((HANDLE)osfd);
+        PR_ASSERT(0 != rv);
+        fd->secret->md.io_model_committed = PR_TRUE;
+    }
+    if (_NT_USE_NB_IO(fd))
+        return _nt_nonblock_recvfrom(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
+    else
+        return pt_RecvFrom(osfd, buf, amount, flags, addr, addrlen, timeout);
+}
+
+/* XXXMB - for now this is a sockets call only */
+PRInt32
+_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    int index;
+    int sent = 0;
+    int rv;
+
+    if (_NT_USE_NB_IO(fd)) {
+        if (!fd->secret->md.io_model_committed) {
+            rv = _md_MakeNonblock((HANDLE)osfd);
+            PR_ASSERT(0 != rv);
+            fd->secret->md.io_model_committed = PR_TRUE;
+        }
+        return _nt_nonblock_writev(fd, iov, iov_size, timeout);
+    }
+
+    for (index=0; index<iov_size; index++) {
+        rv = _PR_MD_SEND(fd, iov[index].iov_base, iov[index].iov_len, 0,
+						timeout);
+        if (rv > 0) 
+            sent += rv;
+        if ( rv != iov[index].iov_len ) {
+            if (sent <= 0)
+                return -1;
+            return -1;
+        }
+    }
+
+    return sent;
+}
+
+PRInt32
+_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog)
+{
+    PRInt32 rv;
+
+    rv = listen(fd->secret->md.osfd, backlog);
+	if (rv < 0)
+		_PR_MD_MAP_LISTEN_ERROR(WSAGetLastError());
+	return(rv);
+}
+
+PRInt32
+_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how)
+{
+    PRInt32 rv;
+
+    rv = shutdown(fd->secret->md.osfd, how);
+	if (rv < 0)
+		_PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError());
+	return(rv);
+}
+
+PRStatus
+_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
+{
+    PRInt32 rv;
+
+    rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len);
+    if (rv==0)
+		return PR_SUCCESS;
+	else {
+		_PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError());
+		return PR_FAILURE;
+	}
+}
+
+PRStatus
+_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
+{
+    PRInt32 rv;
+
+    /*
+     * NT has a bug that, when invoked on a socket accepted by
+     * AcceptEx(), getpeername() returns an all-zero peer address.
+     * To work around this bug, we store the peer's address (returned
+     * by AcceptEx()) with the socket fd and use the cached peer
+     * address if the socket is an accepted socket.
+     */
+
+    if (fd->secret->md.accepted_socket) {
+        INT seconds;
+        INT bytes = sizeof(seconds);
+
+        /*
+         * Determine if the socket is connected.
+         */
+
+        rv = getsockopt(fd->secret->md.osfd, 
+                        SOL_SOCKET,
+                        SO_CONNECT_TIME,
+                        (char *) &seconds,
+                        (PINT) &bytes);
+        if (rv == NO_ERROR) {
+            if (seconds == 0xffffffff) {
+                PR_SetError(PR_NOT_CONNECTED_ERROR, 0);
+                return PR_FAILURE;
+            }
+            *len = PR_NETADDR_SIZE(&fd->secret->md.peer_addr);
+            memcpy(addr, &fd->secret->md.peer_addr, *len);
+            return PR_SUCCESS;
+        } else {
+            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+            return PR_FAILURE;
+        }
+    } else { 
+        rv = getpeername((SOCKET)fd->secret->md.osfd,
+                         (struct sockaddr *) addr, len);
+        if (rv == 0) {
+            return PR_SUCCESS;
+        } else {
+            _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError());
+            return PR_FAILURE;
+        }
+    }
+}
+
+PRStatus
+_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen)
+{
+    PRInt32 rv;
+
+    rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv==0)
+		return PR_SUCCESS;
+	else {
+		_PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+		return PR_FAILURE;
+	}
+}
+
+PRStatus
+_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen)
+{
+    PRInt32 rv;
+
+    rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv==0)
+		return PR_SUCCESS;
+	else {
+		_PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError());
+		return PR_FAILURE;
+	}
+}
+
+/* --- FILE IO ----------------------------------------------------------- */
+
+PROsfd
+_PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode)
+{
+    HANDLE file;
+    PRInt32 access = 0;
+    PRInt32 flags = 0;
+    PRInt32 flag6 = 0;
+    
+    if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
+ 
+    if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE)
+        flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
+    else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
+    else flags = OPEN_EXISTING;
+
+
+    flag6 |= FILE_FLAG_OVERLAPPED;
+
+    file = CreateFile(name, 
+                      access, 
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      NULL,
+                      flags, 
+                      flag6,
+                      NULL);
+    if (file == INVALID_HANDLE_VALUE) {
+        _PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1;
+    }
+
+    if (osflags & PR_APPEND) {
+        if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
+            _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+            CloseHandle(file);
+            return -1;
+        }
+    }
+
+    return (PROsfd)file;
+}
+
+PROsfd
+_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode)
+{
+    HANDLE file;
+    PRInt32 access = 0;
+    PRInt32 flags = 0;
+    PRInt32 flag6 = 0;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
+ 
+    if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE)
+        flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
+    else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
+    else flags = OPEN_EXISTING;
+
+
+    flag6 |= FILE_FLAG_OVERLAPPED;
+
+    if (osflags & PR_CREATE_FILE) {
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
+    }
+    file = CreateFile(name, 
+                      access, 
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      lpSA,
+                      flags, 
+                      flag6,
+                      NULL);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (file == INVALID_HANDLE_VALUE) {
+        _PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1;
+    }
+
+    if (osflags & PR_APPEND) {
+        if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
+            _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+            CloseHandle(file);
+            return -1;
+        }
+    }
+
+    return (PROsfd)file;
+}
+
+PRInt32 
+_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
+{
+    PROsfd f = fd->secret->md.osfd;
+    PRUint32 bytes;
+    int rv, err;
+    LONG hiOffset = 0;
+    LONG loOffset;
+
+    if (!fd->secret->md.sync_file_io) {
+        PRThread *me = _PR_MD_CURRENT_THREAD();
+
+        if (me->io_suspended) {
+            PR_SetError(PR_INVALID_STATE_ERROR, 0);
+            return -1;
+        }
+
+        memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+
+        me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT);
+        PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR));
+
+        if (fd->secret->inheritable == _PR_TRI_TRUE) {
+            rv = ReadFile((HANDLE)f, 
+                          (LPVOID)buf, 
+                          len, 
+                          &bytes, 
+                          &me->md.overlapped.overlapped);
+            if (rv != 0) {
+                loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
+                return bytes;
+            }
+            err = GetLastError();
+            if (err == ERROR_IO_PENDING) {
+                rv = GetOverlappedResult((HANDLE)f,
+                        &me->md.overlapped.overlapped, &bytes, TRUE);
+                if (rv != 0) {
+                    loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                    PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
+                    return bytes;
+                }
+                err = GetLastError();
+            }
+            if (err == ERROR_HANDLE_EOF) {
+                return 0;
+            } else {
+                _PR_MD_MAP_READ_ERROR(err);
+                return -1;
+            }
+        } else {
+            if (!fd->secret->md.io_model_committed) {
+                rv = _md_Associate((HANDLE)f);
+                PR_ASSERT(rv != 0);
+                fd->secret->md.io_model_committed = PR_TRUE;
+            }
+
+			if (_native_threads_only)
+        		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+			_PR_THREAD_LOCK(me);
+			if (_PR_PENDING_INTERRUPT(me)) {
+				me->flags &= ~_PR_INTERRUPT;
+				PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+				_PR_THREAD_UNLOCK(me);
+				return -1;
+			}
+			me->io_pending = PR_TRUE;
+			me->state = _PR_IO_WAIT;
+			_PR_THREAD_UNLOCK(me);
+			me->io_fd = f;
+
+            rv = ReadFile((HANDLE)f, 
+                          (LPVOID)buf, 
+                          len, 
+                          &bytes, 
+                          &me->md.overlapped.overlapped);
+            if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) {
+				_PR_THREAD_LOCK(me);
+				me->io_pending = PR_FALSE;
+				me->state = _PR_RUNNING;
+				if (_PR_PENDING_INTERRUPT(me)) {
+					me->flags &= ~_PR_INTERRUPT;
+					PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+					_PR_THREAD_UNLOCK(me);
+					return -1;
+				}
+				_PR_THREAD_UNLOCK(me);
+
+                if (err == ERROR_HANDLE_EOF) {
+                    return 0;
+                }
+                _PR_MD_MAP_READ_ERROR(err);
+                return -1;
+            }
+
+            if (_native_threads_only && rv) {
+                _native_thread_io_nowait(me, rv, bytes);
+            } else if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+                PR_ASSERT(0);
+                return -1;
+            }
+
+            PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+            if (me->io_suspended) {
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                } else {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                }
+                return -1;
+            }
+
+            if (me->md.blocked_io_status == 0) {
+                if (me->md.blocked_io_error == ERROR_HANDLE_EOF) {
+                    return 0;
+                }
+                _PR_MD_MAP_READ_ERROR(me->md.blocked_io_error);
+                return -1;
+            }
+
+            SetFilePointer((HANDLE)f, me->md.blocked_io_bytes, 0, FILE_CURRENT);
+    
+            PR_ASSERT(me->io_pending == PR_FALSE);
+
+            return me->md.blocked_io_bytes;
+        }
+    } else {
+
+        rv = ReadFile((HANDLE)f,
+                      (LPVOID)buf,
+                      len,
+                      &bytes,
+                      NULL);
+        if (rv == 0) {
+            err = GetLastError();
+            /* ERROR_HANDLE_EOF can only be returned by async io */
+            PR_ASSERT(err != ERROR_HANDLE_EOF);
+            if (err == ERROR_BROKEN_PIPE) {
+                /* The write end of the pipe has been closed. */ 
+                return 0;
+            }
+            _PR_MD_MAP_READ_ERROR(err);
+            return -1;
+        }
+        return bytes;
+    }
+}
+
+PRInt32
+_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
+{
+    PROsfd f = fd->secret->md.osfd;
+    PRInt32 bytes;
+    int rv, err;
+    LONG hiOffset = 0;
+    LONG loOffset;
+    LARGE_INTEGER offset; /* use for the calculation of the new offset */
+
+    if (!fd->secret->md.sync_file_io) {
+        PRThread *me = _PR_MD_CURRENT_THREAD();
+
+        if (me->io_suspended) {
+            PR_SetError(PR_INVALID_STATE_ERROR, 0);
+            return -1;
+        }
+
+        memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+
+        me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT);
+        PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR));
+
+        if (fd->secret->inheritable == _PR_TRI_TRUE) {
+            rv = WriteFile((HANDLE)f, 
+                          (LPVOID)buf, 
+                          len, 
+                          &bytes, 
+                          &me->md.overlapped.overlapped);
+            if (rv != 0) {
+                loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
+                return bytes;
+            }
+            err = GetLastError();
+            if (err == ERROR_IO_PENDING) {
+                rv = GetOverlappedResult((HANDLE)f,
+                        &me->md.overlapped.overlapped, &bytes, TRUE);
+                if (rv != 0) {
+                    loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                    PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
+                    return bytes;
+                }
+                err = GetLastError();
+            }
+            _PR_MD_MAP_READ_ERROR(err);
+            return -1;
+        } else {
+            if (!fd->secret->md.io_model_committed) {
+                rv = _md_Associate((HANDLE)f);
+                PR_ASSERT(rv != 0);
+                fd->secret->md.io_model_committed = PR_TRUE;
+            }
+			if (_native_threads_only)
+        		me->md.overlapped.overlapped.hEvent = me->md.thr_event;
+
+			_PR_THREAD_LOCK(me);
+			if (_PR_PENDING_INTERRUPT(me)) {
+				me->flags &= ~_PR_INTERRUPT;
+				PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+				_PR_THREAD_UNLOCK(me);
+				return -1;
+			}
+			me->io_pending = PR_TRUE;
+			me->state = _PR_IO_WAIT;
+			_PR_THREAD_UNLOCK(me);
+			me->io_fd = f;
+
+            rv = WriteFile((HANDLE)f, 
+                           buf, 
+                           len, 
+                           &bytes, 
+                           &(me->md.overlapped.overlapped));
+            if ( (rv == 0) && ((err = GetLastError()) != ERROR_IO_PENDING) ) {
+				_PR_THREAD_LOCK(me);
+				me->io_pending = PR_FALSE;
+				me->state = _PR_RUNNING;
+				if (_PR_PENDING_INTERRUPT(me)) {
+					me->flags &= ~_PR_INTERRUPT;
+					PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+					_PR_THREAD_UNLOCK(me);
+					return -1;
+				}
+				_PR_THREAD_UNLOCK(me);
+
+                _PR_MD_MAP_WRITE_ERROR(err);
+                return -1;
+            }
+
+            if (_native_threads_only && rv) {
+                _native_thread_io_nowait(me, rv, bytes);
+            } else if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+                PR_ASSERT(0);
+                return -1;
+            }
+
+            PR_ASSERT(me->io_pending == PR_FALSE || me->io_suspended == PR_TRUE);
+
+            if (me->io_suspended) {
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                } else {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                }
+                return -1;
+            }
+
+            if (me->md.blocked_io_status == 0) {
+                _PR_MD_MAP_WRITE_ERROR(me->md.blocked_io_error);
+                return -1;
+            }
+
+            /*
+             * Moving the file pointer by a relative offset (FILE_CURRENT)
+             * does not work with a file on a network drive exported by a
+             * Win2K system.  We still don't know why.  A workaround is to
+             * move the file pointer by an absolute offset (FILE_BEGIN).
+             * (Bugzilla bug 70765)
+             */
+            offset.LowPart = me->md.overlapped.overlapped.Offset;
+            offset.HighPart = me->md.overlapped.overlapped.OffsetHigh;
+            offset.QuadPart += me->md.blocked_io_bytes;
+
+            SetFilePointer((HANDLE)f, offset.LowPart, &offset.HighPart, FILE_BEGIN);
+    
+            PR_ASSERT(me->io_pending == PR_FALSE);
+
+            return me->md.blocked_io_bytes;
+        }
+    } else {
+        rv = WriteFile((HANDLE)f,
+                       buf,
+                       len,
+                       &bytes,
+                       NULL);
+        if (rv == 0) {
+            _PR_MD_MAP_WRITE_ERROR(GetLastError());
+            return -1;
+        }
+        return bytes;
+    }
+}
+
+PRInt32
+_PR_MD_SOCKETAVAILABLE(PRFileDesc *fd)
+{
+    PRInt32 result;
+
+    if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) {
+		PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError());
+        return -1;
+    }
+    return result;
+}
+
+PRInt32
+_PR_MD_PIPEAVAILABLE(PRFileDesc *fd)
+{
+    if (NULL == fd)
+		PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+	else
+		PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return -1;
+}
+
+PROffset32
+_PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
+{
+    DWORD moveMethod;
+    PROffset32 rv;
+
+    switch (whence) {
+        case PR_SEEK_SET:
+            moveMethod = FILE_BEGIN;
+            break;
+        case PR_SEEK_CUR:
+            moveMethod = FILE_CURRENT;
+            break;
+        case PR_SEEK_END:
+            moveMethod = FILE_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return -1;
+    }
+
+    rv = SetFilePointer((HANDLE)fd->secret->md.osfd, offset, NULL, moveMethod);
+
+    /*
+     * If the lpDistanceToMoveHigh argument (third argument) is
+     * NULL, SetFilePointer returns 0xffffffff on failure.
+     */
+    if (-1 == rv) {
+        _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+    }
+    return rv;
+}
+
+PROffset64
+_PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence)
+{
+    DWORD moveMethod;
+    LARGE_INTEGER li;
+    DWORD err;
+
+    switch (whence) {
+        case PR_SEEK_SET:
+            moveMethod = FILE_BEGIN;
+            break;
+        case PR_SEEK_CUR:
+            moveMethod = FILE_CURRENT;
+            break;
+        case PR_SEEK_END:
+            moveMethod = FILE_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return -1;
+    }
+
+    li.QuadPart = offset;
+    li.LowPart = SetFilePointer((HANDLE)fd->secret->md.osfd,
+            li.LowPart, &li.HighPart, moveMethod);
+
+    if (0xffffffff == li.LowPart && (err = GetLastError()) != NO_ERROR) {
+        _PR_MD_MAP_LSEEK_ERROR(err);
+        li.QuadPart = -1;
+    }
+    return li.QuadPart;
+}
+
+/*
+ * This is documented to succeed on read-only files, but Win32's
+ * FlushFileBuffers functions fails with "access denied" in such a
+ * case.  So we only signal an error if the error is *not* "access
+ * denied".
+ */
+PRInt32
+_PR_MD_FSYNC(PRFileDesc *fd)
+{
+    /*
+     * From the documentation:
+     *
+     *	   On Windows NT, the function FlushFileBuffers fails if hFile
+     *	   is a handle to console output. That is because console
+     *	   output is not buffered. The function returns FALSE, and
+     *	   GetLastError returns ERROR_INVALID_HANDLE.
+     *
+     * On the other hand, on Win95, it returns without error.  I cannot
+     * assume that 0, 1, and 2 are console, because if someone closes
+     * System.out and then opens a file, they might get file descriptor
+     * 1.  An error on *that* version of 1 should be reported, whereas
+     * an error on System.out (which was the original 1) should be
+     * ignored.  So I use isatty() to ensure that such an error was
+     * because of this, and if it was, I ignore the error.
+     */
+
+    BOOL ok = FlushFileBuffers((HANDLE)fd->secret->md.osfd);
+
+    if (!ok) {
+	DWORD err = GetLastError();
+
+	if (err != ERROR_ACCESS_DENIED) {	/* from winerror.h */
+			_PR_MD_MAP_FSYNC_ERROR(err);
+	    return -1;
+	}
+    }
+    return 0;
+}
+
+PRInt32
+_PR_MD_CLOSE(PROsfd osfd, PRBool socket)
+{
+    PRInt32 rv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (socket)  {
+        rv = closesocket((SOCKET)osfd);
+        if (rv < 0)
+            _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
+    } else {
+        rv = CloseHandle((HANDLE)osfd)?0:-1;
+        if (rv < 0)
+            _PR_MD_MAP_CLOSE_ERROR(GetLastError());
+    }
+
+    if (rv == 0 && me->io_suspended) {
+        if (me->io_fd == osfd) {
+            PRBool fWait;
+
+            _PR_THREAD_LOCK(me);
+            me->state = _PR_IO_WAIT;
+            /* The IO could have completed on another thread just after
+             * calling closesocket while the io_suspended flag was true.  
+             * So we now grab the lock to do a safe check on io_pending to
+             * see if we need to wait or not.
+             */
+            fWait = me->io_pending;
+            me->io_suspended = PR_FALSE;
+            me->md.interrupt_disabled = PR_TRUE;
+            _PR_THREAD_UNLOCK(me);
+
+            if (fWait)
+                _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+            PR_ASSERT(me->io_suspended ==  PR_FALSE);
+            PR_ASSERT(me->io_pending ==  PR_FALSE);
+            /*
+             * I/O operation is no longer pending; the thread can now
+             * run on any cpu
+             */
+            _PR_THREAD_LOCK(me);
+            me->md.interrupt_disabled = PR_FALSE;
+            me->md.thr_bound_cpu = NULL;
+            me->io_suspended = PR_FALSE;
+            me->io_pending = PR_FALSE;
+            me->state = _PR_RUNNING;
+            _PR_THREAD_UNLOCK(me);
+        }
+    }
+    return rv;
+}
+
+PRStatus
+_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
+{
+    BOOL rv;
+
+    if (fd->secret->md.io_model_committed) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    rv = SetHandleInformation(
+            (HANDLE)fd->secret->md.osfd,
+            HANDLE_FLAG_INHERIT,
+            inheritable ? HANDLE_FLAG_INHERIT : 0);
+    if (0 == rv) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+} 
+
+void
+_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported)
+{
+    if (imported) {
+        fd->secret->inheritable = _PR_TRI_UNKNOWN;
+    } else {
+        fd->secret->inheritable = _PR_TRI_FALSE;
+    }
+}
+
+void
+_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd)
+{
+    DWORD flags;
+
+    PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
+    if (fd->secret->md.io_model_committed) {
+        return;
+    }
+    if (GetHandleInformation((HANDLE)fd->secret->md.osfd, &flags)) {
+        if (flags & HANDLE_FLAG_INHERIT) {
+            fd->secret->inheritable = _PR_TRI_TRUE;
+        } else {
+            fd->secret->inheritable = _PR_TRI_FALSE;
+        }
+    }
+}
+
+
+/* --- DIR IO ------------------------------------------------------------ */
+#define GetFileFromDIR(d)       (d)->d_entry.cFileName
+#define FileIsHidden(d)       ((d)->d_entry.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+
+void FlipSlashes(char *cp, int len)
+{
+    while (--len >= 0) {
+        if (cp[0] == '/') {
+            cp[0] = PR_DIRECTORY_SEPARATOR;
+        }
+        cp = _mbsinc(cp);
+    }
+} /* end FlipSlashes() */
+
+/*
+**
+** Local implementations of standard Unix RTL functions which are not provided
+** by the VC RTL.
+**
+*/
+
+PRStatus
+_PR_MD_CLOSE_DIR(_MDDir *d)
+{
+    if ( d ) {
+        if (FindClose( d->d_hdl )) {
+            d->magic = (PRUint32)-1;
+            return PR_SUCCESS;
+        } else {
+            _PR_MD_MAP_CLOSEDIR_ERROR(GetLastError());
+            return PR_FAILURE;
+        }
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return PR_FAILURE;
+}
+
+
+PRStatus
+_PR_MD_OPEN_DIR(_MDDir *d, const char *name)
+{
+    char filename[ MAX_PATH ];
+    int len;
+
+    len = strlen(name);
+    /* Need 5 bytes for \*.* and the trailing null byte. */
+    if (len + 5 > MAX_PATH) {
+        PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
+        return PR_FAILURE;
+    }
+    strcpy(filename, name);
+
+    /*
+     * If 'name' ends in a slash or backslash, do not append
+     * another backslash.
+     */
+    if (IsPrevCharSlash(filename, filename + len)) {
+        len--;
+    }
+    strcpy(&filename[len], "\\*.*");
+    FlipSlashes( filename, strlen(filename) );
+
+    d->d_hdl = FindFirstFile( filename, &(d->d_entry) );
+    if ( d->d_hdl == INVALID_HANDLE_VALUE ) {
+		_PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    d->firstEntry = PR_TRUE;
+    d->magic = _MD_MAGIC_DIR;
+    return PR_SUCCESS;
+}
+
+char *
+_PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
+{
+    PRInt32 err;
+    BOOL rv;
+    char *fileName;
+
+    if ( d ) {
+        while (1) {
+            if (d->firstEntry) {
+                d->firstEntry = PR_FALSE;
+                rv = 1;
+            } else {
+                rv = FindNextFile(d->d_hdl, &(d->d_entry));
+            }
+            if (rv == 0) {
+                break;
+            }
+            fileName = GetFileFromDIR(d);
+            if ( (flags & PR_SKIP_DOT) &&
+                 (fileName[0] == '.') && (fileName[1] == '\0'))
+                 continue;
+            if ( (flags & PR_SKIP_DOT_DOT) &&
+                 (fileName[0] == '.') && (fileName[1] == '.') &&
+                 (fileName[2] == '\0'))
+                 continue;
+            if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d))
+                 continue;
+            return fileName;
+        }
+	err = GetLastError();
+	PR_ASSERT(NO_ERROR != err);
+			_PR_MD_MAP_READDIR_ERROR(err);
+	return NULL;
+		}
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return NULL;
+}
+
+PRInt32
+_PR_MD_DELETE(const char *name)
+{
+    if (DeleteFile(name)) {
+		return 0;
+	} else {
+		_PR_MD_MAP_DELETE_ERROR(GetLastError());
+		return -1;
+	}
+}
+
+void
+_PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm)
+{
+    PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime));
+    CopyMemory(prtm, filetime, sizeof(PRTime));
+#ifdef __GNUC__
+    *prtm = (*prtm - _pr_filetime_offset) / 10LL;
+#else
+    *prtm = (*prtm - _pr_filetime_offset) / 10i64;
+#endif
+
+#ifdef DEBUG
+    /* Doublecheck our calculation. */
+    {
+        SYSTEMTIME systime;
+        PRExplodedTime etm;
+        PRTime cmp; /* for comparison */
+        BOOL rv;
+
+        rv = FileTimeToSystemTime(filetime, &systime);
+        PR_ASSERT(0 != rv);
+
+        /*
+         * PR_ImplodeTime ignores wday and yday.
+         */
+        etm.tm_usec = systime.wMilliseconds * PR_USEC_PER_MSEC;
+        etm.tm_sec = systime.wSecond;
+        etm.tm_min = systime.wMinute;
+        etm.tm_hour = systime.wHour;
+        etm.tm_mday = systime.wDay;
+        etm.tm_month = systime.wMonth - 1;
+        etm.tm_year = systime.wYear;
+        /*
+         * It is not well-documented what time zone the FILETIME's
+         * are in.  WIN32_FIND_DATA is documented to be in UTC (GMT).
+         * But BY_HANDLE_FILE_INFORMATION is unclear about this.
+         * By our best judgement, we assume that FILETIME is in UTC.
+         */
+        etm.tm_params.tp_gmt_offset = 0;
+        etm.tm_params.tp_dst_offset = 0;
+        cmp = PR_ImplodeTime(&etm);
+
+        /*
+         * SYSTEMTIME is in milliseconds precision, so we convert PRTime's
+         * microseconds to milliseconds before doing the comparison.
+         */
+        PR_ASSERT((cmp / PR_USEC_PER_MSEC) == (*prtm / PR_USEC_PER_MSEC));
+    }
+#endif /* DEBUG */
+}
+
+PRInt32
+_PR_MD_STAT(const char *fn, struct stat *info)
+{
+    PRInt32 rv;
+
+    rv = _stat(fn, (struct _stat *)info);
+    if (-1 == rv) {
+        /*
+         * Check for MSVC runtime library _stat() bug.
+         * (It's really a bug in FindFirstFile().)
+         * If a pathname ends in a backslash or slash,
+         * e.g., c:\temp\ or c:/temp/, _stat() will fail.
+         * Note: a pathname ending in a slash (e.g., c:/temp/)
+         * can be handled by _stat() on NT but not on Win95.
+         *
+         * We remove the backslash or slash at the end and
+         * try again.
+         */
+
+        int len = strlen(fn);
+        if (len > 0 && len <= _MAX_PATH
+                && IsPrevCharSlash(fn, fn + len)) {
+            char newfn[_MAX_PATH + 1];
+
+            strcpy(newfn, fn);
+            newfn[len - 1] = '\0';
+            rv = _stat(newfn, (struct _stat *)info);
+        }
+    }
+
+    if (-1 == rv) {
+        _PR_MD_MAP_STAT_ERROR(errno);
+    }
+    return rv;
+}
+
+#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\')
+
+static PRBool
+IsPrevCharSlash(const char *str, const char *current)
+{
+    const char *prev;
+
+    if (str >= current)
+        return PR_FALSE;
+    prev = _mbsdec(str, current);
+    return (prev == current - 1) && _PR_IS_SLASH(*prev);
+}
+
+/*
+ * IsRootDirectory --
+ *
+ * Return PR_TRUE if the pathname 'fn' is a valid root directory,
+ * else return PR_FALSE.  The char buffer pointed to by 'fn' must
+ * be writable.  During the execution of this function, the contents
+ * of the buffer pointed to by 'fn' may be modified, but on return
+ * the original contents will be restored.  'buflen' is the size of
+ * the buffer pointed to by 'fn'.
+ *
+ * Root directories come in three formats:
+ * 1. / or \, meaning the root directory of the current drive.
+ * 2. C:/ or C:\, where C is a drive letter.
+ * 3. \\<server name>\<share point name>\ or
+ *    \\<server name>\<share point name>, meaning the root directory
+ *    of a UNC (Universal Naming Convention) name.
+ */
+
+static PRBool
+IsRootDirectory(char *fn, size_t buflen)
+{
+    char *p;
+    PRBool slashAdded = PR_FALSE;
+    PRBool rv = PR_FALSE;
+
+    if (_PR_IS_SLASH(fn[0]) && fn[1] == '\0') {
+        return PR_TRUE;
+    }
+
+    if (isalpha(fn[0]) && fn[1] == ':' && _PR_IS_SLASH(fn[2])
+            && fn[3] == '\0') {
+        rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE;
+        return rv;
+    }
+
+    /* The UNC root directory */
+
+    if (_PR_IS_SLASH(fn[0]) && _PR_IS_SLASH(fn[1])) {
+        /* The 'server' part should have at least one character. */
+        p = &fn[2];
+        if (*p == '\0' || _PR_IS_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the next slash */
+        do {
+            p = _mbsinc(p);
+        } while (*p != '\0' && !_PR_IS_SLASH(*p));
+        if (*p == '\0') {
+            return PR_FALSE;
+        }
+
+        /* The 'share' part should have at least one character. */
+        p++;
+        if (*p == '\0' || _PR_IS_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the final slash */
+        do {
+            p = _mbsinc(p);
+        } while (*p != '\0' && !_PR_IS_SLASH(*p));
+        if (_PR_IS_SLASH(*p) && p[1] != '\0') {
+            return PR_FALSE;
+        }
+        if (*p == '\0') {
+            /*
+             * GetDriveType() doesn't work correctly if the
+             * path is of the form \\server\share, so we add
+             * a final slash temporarily.
+             */
+            if ((p + 1) < (fn + buflen)) {
+                *p++ = '\\';
+                *p = '\0';
+                slashAdded = PR_TRUE;
+            } else {
+                return PR_FALSE; /* name too long */
+            }
+        }
+        rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE;
+        /* restore the 'fn' buffer */
+        if (slashAdded) {
+            *--p = '\0';
+        }
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
+{
+    HANDLE hFindFile;
+    WIN32_FIND_DATA findFileData;
+    char pathbuf[MAX_PATH + 1];
+    
+    if (NULL == fn || '\0' == *fn) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+
+    /*
+     * FindFirstFile() expands wildcard characters.  So
+     * we make sure the pathname contains no wildcard.
+     */
+    if (NULL != _mbspbrk(fn, "?*")) {
+        PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0);
+        return -1;
+    }
+
+    hFindFile = FindFirstFile(fn, &findFileData);
+    if (INVALID_HANDLE_VALUE == hFindFile) {
+        DWORD len;
+        char *filePart;
+
+        /*
+         * FindFirstFile() does not work correctly on root directories.
+         * It also doesn't work correctly on a pathname that ends in a
+         * slash.  So we first check to see if the pathname specifies a
+         * root directory.  If not, and if the pathname ends in a slash,
+         * we remove the final slash and try again.
+         */
+
+        /*
+         * If the pathname does not contain ., \, and /, it cannot be
+         * a root directory or a pathname that ends in a slash.
+         */
+        if (NULL == _mbspbrk(fn, ".\\/")) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        } 
+        len = GetFullPathName(fn, sizeof(pathbuf), pathbuf,
+                &filePart);
+        if (0 == len) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        }
+        if (len > sizeof(pathbuf)) {
+            PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
+            return -1;
+        }
+        if (IsRootDirectory(pathbuf, sizeof(pathbuf))) {
+            info->type = PR_FILE_DIRECTORY;
+            info->size = 0;
+            /*
+             * These timestamps don't make sense for root directories.
+             */
+            info->modifyTime = 0;
+            info->creationTime = 0;
+            return 0;
+        }
+        if (!IsPrevCharSlash(pathbuf, pathbuf + len)) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        } else {
+            pathbuf[len - 1] = '\0';
+            hFindFile = FindFirstFile(pathbuf, &findFileData);
+            if (INVALID_HANDLE_VALUE == hFindFile) {
+                _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+                return -1;
+            }
+        }
+    }
+
+    FindClose(hFindFile);
+
+    if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        info->type = PR_FILE_DIRECTORY;
+    } else {
+        info->type = PR_FILE_FILE;
+    }
+
+    info->size = findFileData.nFileSizeHigh;
+    info->size = (info->size << 32) + findFileData.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime);
+
+    if (0 == findFileData.ftCreationTime.dwLowDateTime &&
+            0 == findFileData.ftCreationTime.dwHighDateTime) {
+        info->creationTime = info->modifyTime;
+    } else {
+        _PR_FileTimeToPRTime(&findFileData.ftCreationTime,
+                &info->creationTime);
+    }
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info)
+{
+    PRFileInfo64 info64;
+    PRInt32 rv = _PR_MD_GETFILEINFO64(fn, &info64);
+    if (0 == rv)
+    {
+        info->type = info64.type;
+        info->size = (PRUint32) info64.size;
+        info->modifyTime = info64.modifyTime;
+        info->creationTime = info64.creationTime;
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
+{
+    int rv;
+
+    BY_HANDLE_FILE_INFORMATION hinfo;
+
+    rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo);
+    if (rv == FALSE) {
+		_PR_MD_MAP_FSTAT_ERROR(GetLastError());
+        return -1;
+	}
+
+    if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_FILE;
+
+    info->size = hinfo.nFileSizeHigh;
+    info->size = (info->size << 32) + hinfo.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) );
+    _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) );
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
+{
+    int rv;
+
+    BY_HANDLE_FILE_INFORMATION hinfo;
+
+    rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo);
+    if (rv == FALSE) {
+		_PR_MD_MAP_FSTAT_ERROR(GetLastError());
+        return -1;
+	}
+
+    if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_FILE;
+
+    info->size = hinfo.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) );
+    _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) );
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_RENAME(const char *from, const char *to)
+{
+    /* Does this work with dot-relative pathnames? */
+    if (MoveFile(from, to)) {
+		return 0;
+	} else {
+		_PR_MD_MAP_RENAME_ERROR(GetLastError());
+		return -1;
+	}
+}
+
+PRInt32
+_PR_MD_ACCESS(const char *name, PRAccessHow how)
+{
+    PRInt32 rv;
+
+    switch (how) {
+      case PR_ACCESS_WRITE_OK:
+        rv = _access(name, 02);
+		break;
+      case PR_ACCESS_READ_OK:
+        rv = _access(name, 04);
+		break;
+      case PR_ACCESS_EXISTS:
+        rv = _access(name, 00);
+		break;
+      default:
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+    }
+	if (rv < 0) {
+		_PR_MD_MAP_ACCESS_ERROR(errno);
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_MKDIR(const char *name, PRIntn mode)
+{
+    /* XXXMB - how to translate the "mode"??? */
+    if (CreateDirectory(name, NULL)) {
+        return 0;
+    } else {
+        _PR_MD_MAP_MKDIR_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_MAKE_DIR(const char *name, PRIntn mode)
+{
+    BOOL rv;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (_PR_NT_MakeSecurityDescriptorACL(mode, dirAccessTable,
+            &pSD, &pACL) == PR_SUCCESS) {
+        sa.nLength = sizeof(sa);
+        sa.lpSecurityDescriptor = pSD;
+        sa.bInheritHandle = FALSE;
+        lpSA = &sa;
+    }
+    rv = CreateDirectory(name, lpSA);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (rv) {
+        return 0;
+    } else {
+        _PR_MD_MAP_MKDIR_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_RMDIR(const char *name)
+{
+    if (RemoveDirectory(name)) {
+        return 0;
+    } else {
+        _PR_MD_MAP_RMDIR_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRStatus
+_PR_MD_LOCKFILE(PROsfd f)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+
+    rv = LockFileEx((HANDLE)f, 
+                    LOCKFILE_EXCLUSIVE_LOCK,
+                    0,
+                    0x7fffffff,
+                    0,
+                    &me->md.overlapped.overlapped);
+
+    if (_native_threads_only) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return PR_FAILURE;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+        if (rv == FALSE) {
+            err = GetLastError();
+            PR_ASSERT(err != ERROR_IO_PENDING);
+            _PR_MD_MAP_LOCKF_ERROR(err);
+            return PR_FAILURE;
+        }
+        return PR_SUCCESS;
+    }
+
+    /* HACK AROUND NT BUG
+     * NT 3.51 has a bug.  In NT 3.51, if LockFileEx returns true, you
+     * don't get any completion on the completion port.  This is a bug.
+     *
+     * They fixed it on NT4.0 so that you do get a completion.
+     *
+     * If we pretend we won't get a completion, NSPR gets confused later
+     * when the unexpected completion arrives.  If we assume we do get
+     * a completion, we hang on 3.51.  Worse, Microsoft informs me that the 
+     * behavior varies on 3.51 depending on if you are using a network
+     * file system or a local disk!
+     *
+     * Solution:  For now, _nt_version_gets_lockfile_completion is set
+     * depending on whether or not this system is EITHER
+     *      - running NT 4.0
+     *      - running NT 3.51 with a service pack greater than 5.
+     * 
+     * In the meantime, this code may not work on network file systems.
+     *
+     */
+
+    if ( rv == FALSE && ((err = GetLastError()) != ERROR_IO_PENDING)) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return PR_FAILURE;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+		_PR_MD_MAP_LOCKF_ERROR(err);
+        return PR_FAILURE;
+    }
+#ifdef _NEED_351_FILE_LOCKING_HACK
+    else if (rv)  {
+        /* If this is NT 3.51 and the file is local, then we won't get a 
+         * completion back from LockFile when it succeeded.
+         */
+        if (_nt_version_gets_lockfile_completion == PR_FALSE) {
+            if ( IsFileLocal((HANDLE)f) == _PR_LOCAL_FILE) {
+                me->io_pending = PR_FALSE;
+                me->state = _PR_RUNNING;
+                return PR_SUCCESS; 
+            }
+        }
+    }
+#endif /* _NEED_351_FILE_LOCKING_HACK */
+
+    if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+		_PR_THREAD_LOCK(me);
+        me->io_pending = PR_FALSE;
+        me->state = _PR_RUNNING;
+		_PR_THREAD_UNLOCK(me);
+        return PR_FAILURE;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+		_PR_MD_MAP_LOCKF_ERROR(me->md.blocked_io_error);
+        return PR_FAILURE;
+    }
+
+    return PR_SUCCESS;
+}
+
+PRStatus
+_PR_MD_TLOCKFILE(PROsfd f)
+{
+    PRInt32 rv, err;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+
+    _PR_THREAD_LOCK(me);
+	if (_PR_PENDING_INTERRUPT(me)) {
+		me->flags &= ~_PR_INTERRUPT;
+		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    	_PR_THREAD_UNLOCK(me);
+		return -1;
+	}
+    me->io_pending = PR_TRUE;
+    me->state = _PR_IO_WAIT;
+    _PR_THREAD_UNLOCK(me);
+
+    rv = LockFileEx((HANDLE)f, 
+                    LOCKFILE_FAIL_IMMEDIATELY|LOCKFILE_EXCLUSIVE_LOCK,
+                    0,
+                    0x7fffffff,
+                    0,
+                    &me->md.overlapped.overlapped);
+    if (_native_threads_only) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return PR_FAILURE;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+        if (rv == FALSE) {
+            err = GetLastError();
+            PR_ASSERT(err != ERROR_IO_PENDING);
+            _PR_MD_MAP_LOCKF_ERROR(err);
+            return PR_FAILURE;
+        }
+        return PR_SUCCESS;
+    }
+    if ( rv == FALSE && ((err = GetLastError()) != ERROR_IO_PENDING)) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return PR_FAILURE;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+        _PR_MD_MAP_LOCKF_ERROR(err);
+        return PR_FAILURE;
+    }
+#ifdef _NEED_351_FILE_LOCKING_HACK
+    else if (rv)  {
+        /* If this is NT 3.51 and the file is local, then we won't get a 
+         * completion back from LockFile when it succeeded.
+         */
+        if (_nt_version_gets_lockfile_completion == PR_FALSE) {
+            if ( IsFileLocal((HANDLE)f) == _PR_LOCAL_FILE) {
+				_PR_THREAD_LOCK(me);
+				me->io_pending = PR_FALSE;
+				me->state = _PR_RUNNING;
+				if (_PR_PENDING_INTERRUPT(me)) {
+					me->flags &= ~_PR_INTERRUPT;
+					PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+					_PR_THREAD_UNLOCK(me);
+					return PR_FAILURE;
+				}
+				_PR_THREAD_UNLOCK(me);
+
+                return PR_SUCCESS; 
+            }
+        }
+    }
+#endif /* _NEED_351_FILE_LOCKING_HACK */
+
+    if (_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+		_PR_THREAD_LOCK(me);
+		me->io_pending = PR_FALSE;
+		me->state = _PR_RUNNING;
+		if (_PR_PENDING_INTERRUPT(me)) {
+			me->flags &= ~_PR_INTERRUPT;
+			PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+			_PR_THREAD_UNLOCK(me);
+			return PR_FAILURE;
+		}
+		_PR_THREAD_UNLOCK(me);
+
+        return PR_FAILURE;
+    }
+
+    if (me->md.blocked_io_status == 0) {
+		_PR_MD_MAP_LOCKF_ERROR(me->md.blocked_io_error);
+        return PR_FAILURE;
+    }
+
+    return PR_SUCCESS;
+}
+
+
+PRStatus
+_PR_MD_UNLOCKFILE(PROsfd f)
+{
+    PRInt32 rv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (me->io_suspended) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
+
+    rv = UnlockFileEx((HANDLE)f,
+                      0,
+                      0x7fffffff,
+                      0,
+                      &me->md.overlapped.overlapped);
+
+    if (rv)
+        return PR_SUCCESS;
+    else {
+        int err = GetLastError();
+		_PR_MD_MAP_LOCKF_ERROR(err);
+        return PR_FAILURE;
+    }
+}
+
+void
+_PR_MD_MAKE_NONBLOCK(PRFileDesc *f)
+{
+    /*
+     * On NT, we either call _md_Associate() or _md_MakeNonblock(),
+     * depending on whether the socket is blocking or not.
+     *
+     * Once we associate a socket with the io completion port,
+     * there is no way to disassociate it from the io completion
+     * port.  So we have to call _md_Associate/_md_MakeNonblock
+     * lazily.
+     */
+}
+
+#ifdef _NEED_351_FILE_LOCKING_HACK
+/***************
+** 
+** Lockfile hacks
+**
+** The following code is a hack to work around a microsoft bug with lockfile.
+** The problem is that on NT 3.51, if LockFileEx() succeeds, you never
+** get a completion back for files that are on local disks.  So, we need to
+** know if a file is local or remote so we can tell if we should expect 
+** a completion.
+**
+** The only way to check if a file is local or remote based on the handle is
+** to get the serial number for the volume it is mounted on and then to 
+** compare that with mounted drives.  This code caches the volume numbers of
+** fixed disks and does a relatively quick check.
+**
+** Locking:  Since the only thing we ever do when multithreaded is a 32bit
+**           assignment, we probably don't need locking.  It is included just
+**           case anyway.
+**
+** Limitations:  Does not work on floppies because they are too slow
+**               Unknown if it will work on wierdo 3rd party file systems
+**
+****************
+*/
+
+/* There can only be 26 drive letters on NT */
+#define _PR_MAX_DRIVES 26
+
+_MDLock cachedVolumeLock;
+DWORD dwCachedVolumeSerialNumbers[_PR_MAX_DRIVES] = {0};
+DWORD dwLastCachedDrive = 0;
+DWORD dwRemoveableDrivesToCheck = 0; /* bitmask for removeable drives */
+
+PRBool IsFileLocalInit()
+{
+   TCHAR lpBuffer[_PR_MAX_DRIVES*5];
+   DWORD nBufferLength = _PR_MAX_DRIVES*5;
+   DWORD nBufferNeeded = GetLogicalDriveStrings(0, NULL);
+   DWORD dwIndex = 0;
+   DWORD dwDriveType;
+   DWORD dwVolumeSerialNumber;
+   DWORD dwDriveIndex = 0;
+   DWORD oldmode = (DWORD) -1;
+
+   _MD_NEW_LOCK(&cachedVolumeLock);
+
+   nBufferNeeded = GetLogicalDriveStrings(nBufferLength, lpBuffer);
+   if (nBufferNeeded == 0 || nBufferNeeded > nBufferLength)
+      return PR_FALSE;
+
+   // Calling GetVolumeInformation on a removeable drive where the
+   // disk is currently removed will cause a dialog box to the
+   // console.  This is not good.
+   // Temporarily disable the SEM_FAILCRITICALERRORS to avoid the
+   // damn dialog.
+
+   dwCachedVolumeSerialNumbers[dwDriveIndex] = 0;
+   oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
+
+   // now loop through the logical drives
+   while(lpBuffer[dwIndex] != TEXT('\0'))
+   {
+      // skip the floppy drives.  This is *SLOW*
+      if ((lpBuffer[dwIndex] == TEXT('A')) || (lpBuffer[dwIndex] == TEXT('B')))
+         /* Skip over floppies */;
+      else
+      {
+         dwDriveIndex = (lpBuffer[dwIndex] - TEXT('A'));
+
+         dwDriveType = GetDriveType(&lpBuffer[dwIndex]);
+
+         switch(dwDriveType)
+         {
+               // Ignore these drive types
+            case 0:
+            case 1:
+            case DRIVE_REMOTE:
+            default: // If the drive type is unknown, ignore it.
+               break;
+
+               // Removable media drives can have different serial numbers
+               // at different times, so cache the current serial number
+               // but keep track of them so they can be rechecked if necessary.
+            case DRIVE_REMOVABLE:
+
+               // CDROM is a removable media
+            case DRIVE_CDROM: 
+
+               // no idea if ramdisks can change serial numbers or not
+               // but it doesn't hurt to treat them as removable.
+              
+            case DRIVE_RAMDISK: 
+
+
+               // Here is where we keep track of removable drives.
+               dwRemoveableDrivesToCheck |= 1 << dwDriveIndex;
+
+               // removable drives fall through to fixed drives and get cached.
+
+            case DRIVE_FIXED:
+
+               // cache volume serial numbers. 
+               if (GetVolumeInformation(
+                   &lpBuffer[dwIndex],
+                   NULL, 0,
+                   &dwVolumeSerialNumber,
+                   NULL, NULL, NULL, 0)
+                  )
+                  {
+                     if (dwLastCachedDrive < dwDriveIndex)
+                        dwLastCachedDrive = dwDriveIndex;
+                     dwCachedVolumeSerialNumbers[dwDriveIndex] = dwVolumeSerialNumber;
+                  }
+ 
+               break;
+         }
+      }
+
+      dwIndex += lstrlen(&lpBuffer[dwIndex]) +1;
+   }
+
+   if (oldmode != (DWORD) -1) {
+       SetErrorMode(oldmode);
+       oldmode = (DWORD) -1;
+   }
+
+   return PR_TRUE;
+}
+
+PRInt32 IsFileLocal(HANDLE hFile)
+{
+   DWORD dwIndex = 0, dwMask;
+   BY_HANDLE_FILE_INFORMATION Info;
+   TCHAR szDrive[4] = TEXT("C:\\");
+   DWORD dwVolumeSerialNumber;
+   DWORD oldmode = (DWORD) -1;
+   int rv = _PR_REMOTE_FILE;
+
+   if (!GetFileInformationByHandle(hFile, &Info))
+      return -1;
+
+   // look to see if the volume serial number has been cached.
+   _MD_LOCK(&cachedVolumeLock);
+   while(dwIndex <= dwLastCachedDrive)
+      if (dwCachedVolumeSerialNumbers[dwIndex++] == Info.dwVolumeSerialNumber)
+         return _PR_LOCAL_FILE;
+   _MD_UNLOCK(&cachedVolumeLock);
+
+   // volume serial number not found in the cache.  Check removable files.
+   // removable drives are noted as a bitmask.  If the bit associated with 
+   // a specific drive is set, then we should query its volume serial number
+   // as its possible it has changed.
+   dwMask = dwRemoveableDrivesToCheck;
+   dwIndex = 0;
+
+   while(dwMask)
+   {
+      while(!(dwMask & 1))
+      {
+         dwIndex++;
+         dwMask = dwMask >> 1;
+      }
+
+      szDrive[0] = TEXT('A')+ (TCHAR) dwIndex;
+
+      // Calling GetVolumeInformation on a removeable drive where the
+      // disk is currently removed will cause a dialog box to the
+      // console.  This is not good.
+      // Temporarily disable the SEM_FAILCRITICALERRORS to avoid the
+      // dialog.
+
+      oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
+
+      if (GetVolumeInformation(
+                  szDrive,
+                  NULL, 0,
+                  &dwVolumeSerialNumber,
+                  NULL, NULL, NULL, 0)
+         )
+      {
+         if (dwVolumeSerialNumber == Info.dwVolumeSerialNumber)
+         {
+            _MD_LOCK(&cachedVolumeLock);
+            if (dwLastCachedDrive < dwIndex)
+               dwLastCachedDrive = dwIndex;
+            dwCachedVolumeSerialNumbers[dwIndex] = dwVolumeSerialNumber;
+            _MD_UNLOCK(&cachedVolumeLock);
+            rv = _PR_LOCAL_FILE;
+         }
+      }
+      if (oldmode != (DWORD) -1) {
+          SetErrorMode(oldmode);
+          oldmode = (DWORD) -1;
+      }
+
+      if (rv == _PR_LOCAL_FILE)
+          return _PR_LOCAL_FILE;
+
+      dwIndex++;
+      dwMask = dwMask >> 1;
+   }
+
+   return _PR_REMOTE_FILE;
+}
+#endif /* _NEED_351_FILE_LOCKING_HACK */
+
+PR_IMPLEMENT(PRStatus) PR_NT_CancelIo(PRFileDesc *fd)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+	PRBool fWait;
+	PRFileDesc *bottom;
+
+	bottom = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER);
+    if (!me->io_suspended || (NULL == bottom) ||
+					(me->io_fd != bottom->secret->md.osfd)) {
+        PR_SetError(PR_INVALID_STATE_ERROR, 0);
+        return PR_FAILURE;
+    }
+	/*
+	 * The CancelIO operation has to be issued by the same NT thread that
+	 * issued the I/O operation
+	 */
+	PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || (me->cpu == me->md.thr_bound_cpu));
+	if (me->io_pending) {
+		if (!CancelIo((HANDLE)bottom->secret->md.osfd)) {
+			PR_SetError(PR_INVALID_STATE_ERROR, GetLastError());
+			return PR_FAILURE;
+		}
+	}
+	_PR_THREAD_LOCK(me);
+	fWait = me->io_pending;
+	me->io_suspended = PR_FALSE;
+	me->state = _PR_IO_WAIT;
+	me->md.interrupt_disabled = PR_TRUE;
+	_PR_THREAD_UNLOCK(me);
+	if (fWait)
+		_NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(me->io_suspended ==  PR_FALSE);
+	PR_ASSERT(me->io_pending ==  PR_FALSE);
+
+	_PR_THREAD_LOCK(me);
+	me->md.interrupt_disabled = PR_FALSE;
+	me->md.thr_bound_cpu = NULL;
+    me->io_suspended = PR_FALSE;
+    me->io_pending = PR_FALSE;
+	me->state = _PR_RUNNING;
+	_PR_THREAD_UNLOCK(me);
+	return PR_SUCCESS;
+}
+
+static PROsfd _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr *addr, int *addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    SOCKET sock;
+    PRInt32 rv, err;
+    fd_set rd;
+    struct timeval tv, *tvp;
+
+    FD_ZERO(&rd);
+    FD_SET((SOCKET)osfd, &rd);
+    if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+        while ((sock = accept(osfd, addr, addrlen)) == -1) {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                    && (!fd->secret->nonblocking)) {
+                if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL,
+                        NULL)) == -1) {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                    break;
+                }
+            } else {
+                _PR_MD_MAP_ACCEPT_ERROR(err);
+                break;
+            }
+        }
+    } else if (timeout == PR_INTERVAL_NO_WAIT) {
+        if ((sock = accept(osfd, addr, addrlen)) == -1) {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                    && (!fd->secret->nonblocking)) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+            } else {
+                _PR_MD_MAP_ACCEPT_ERROR(err);
+            }
+        }
+    } else {
+retry:
+        if ((sock = accept(osfd, addr, addrlen)) == -1) {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                    && (!fd->secret->nonblocking)) {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                    timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+
+                rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL, tvp);
+                if (rv > 0) {
+                    goto retry;
+                } else if (rv == 0) {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                } else {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                }
+            } else {
+                _PR_MD_MAP_ACCEPT_ERROR(err);
+            }
+        }
+    }
+    return (PROsfd)sock;
+}
+
+static PRInt32 _nt_nonblock_connect(PRFileDesc *fd, struct sockaddr *addr, int addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv;
+    int err;
+    fd_set wr, ex;
+    struct timeval tv, *tvp;
+    int len;
+
+    if ((rv = connect(osfd, addr, addrlen)) == -1) {
+        if ((err = WSAGetLastError()) == WSAEWOULDBLOCK) {
+            if ( timeout == PR_INTERVAL_NO_TIMEOUT ) {
+                tvp = NULL;
+            } else {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                    timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+            }
+            FD_ZERO(&wr);
+            FD_ZERO(&ex);
+            FD_SET((SOCKET)osfd, &wr);
+            FD_SET((SOCKET)osfd, &ex);
+            if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wr, &ex,
+                    tvp)) == -1) {
+                _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                return rv;
+            }
+            if (rv == 0) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                return -1;
+            }
+            /* Call Sleep(0) to work around a Winsock timeing bug. */
+            Sleep(0);
+            if (FD_ISSET((SOCKET)osfd, &ex)) {
+                len = sizeof(err);
+                if (getsockopt(osfd, SOL_SOCKET, SO_ERROR,
+                        (char *) &err, &len) == SOCKET_ERROR) {
+                    _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+                    return -1;
+                }
+                _PR_MD_MAP_CONNECT_ERROR(err);
+                return -1;
+            } 
+            PR_ASSERT(FD_ISSET((SOCKET)osfd, &wr));
+            rv = 0;
+        } else {
+            _PR_MD_MAP_CONNECT_ERROR(err);
+        }
+    }
+    return rv;
+}
+
+static PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, int flags, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    struct timeval tv, *tvp;
+    fd_set rd;
+    int osflags;
+
+    if (0 == flags) {
+        osflags = 0;
+    } else {
+        PR_ASSERT(PR_MSG_PEEK == flags);
+        osflags = MSG_PEEK;
+    }
+    while ((rv = recv(osfd,buf,len,osflags)) == -1) {
+        if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                && (!fd->secret->nonblocking)) {
+            FD_ZERO(&rd);
+            FD_SET((SOCKET)osfd, &rd);
+            if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+                tvp = NULL;
+            } else {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+            }
+            if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL,
+                    tvp)) == -1) {
+                _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                break;
+            } else if (rv == 0) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                rv = -1;
+                break;
+            }
+        } else {
+            _PR_MD_MAP_RECV_ERROR(err);
+            break;
+        }
+    }
+    return(rv);
+}
+
+static PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    struct timeval tv, *tvp;
+    fd_set wd;
+    PRInt32 bytesSent = 0;
+
+    while(bytesSent < len) {
+        while ((rv = send(osfd,buf,len,0)) == -1) {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                    && (!fd->secret->nonblocking)) {
+                if ( timeout == PR_INTERVAL_NO_TIMEOUT ) {
+                    tvp = NULL;
+                } else {
+                    tv.tv_sec = PR_IntervalToSeconds(timeout);
+                    tv.tv_usec = PR_IntervalToMicroseconds(
+                        timeout - PR_SecondsToInterval(tv.tv_sec));
+                    tvp = &tv;
+                }
+                FD_ZERO(&wd);
+                FD_SET((SOCKET)osfd, &wd);
+                if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL,
+                        tvp)) == -1) {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                    return -1;
+                }
+                if (rv == 0) {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                    return -1;
+                }
+            } else {
+                _PR_MD_MAP_SEND_ERROR(err);
+                return -1;
+            }
+        }
+        bytesSent += rv;
+        if (fd->secret->nonblocking) {
+            break;
+        }
+        if (bytesSent < len) {
+            if ( timeout == PR_INTERVAL_NO_TIMEOUT ) {
+                tvp = NULL;
+            } else {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                    timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+            }
+            FD_ZERO(&wd);
+            FD_SET((SOCKET)osfd, &wd);
+            if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL,
+                    tvp)) == -1) {
+                _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                return -1;
+            }
+            if (rv == 0) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                return -1;
+            }
+        }
+    }
+    return bytesSent;
+}
+
+static PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime timeout)
+{
+    int index;
+    int sent = 0;
+    int rv;
+
+    for (index=0; index<size; index++) {
+        rv = _nt_nonblock_send(fd, iov[index].iov_base, iov[index].iov_len, timeout);
+        if (rv > 0) 
+            sent += rv;
+        if ( rv != iov[index].iov_len ) {
+            if (rv < 0) {
+                if (fd->secret->nonblocking
+                        && (PR_GetError() == PR_WOULD_BLOCK_ERROR)
+                        && (sent > 0)) {
+                    return sent;
+                } else {
+                    return -1;
+                }
+            }
+            /* Only a nonblocking socket can have partial sends */
+            PR_ASSERT(fd->secret->nonblocking);
+            return sent;
+        }
+    }
+
+    return sent;
+}
+
+static PRInt32 _nt_nonblock_sendto(
+    PRFileDesc *fd, const char *buf, int len,
+    const struct sockaddr *addr, int addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    struct timeval tv, *tvp;
+    fd_set wd;
+    PRInt32 bytesSent = 0;
+
+    while(bytesSent < len) {
+        while ((rv = sendto(osfd,buf,len,0, addr, addrlen)) == -1) {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                    && (!fd->secret->nonblocking)) {
+                if ( timeout == PR_INTERVAL_NO_TIMEOUT ) {
+                    tvp = NULL;
+                } else {
+                    tv.tv_sec = PR_IntervalToSeconds(timeout);
+                    tv.tv_usec = PR_IntervalToMicroseconds(
+                        timeout - PR_SecondsToInterval(tv.tv_sec));
+                    tvp = &tv;
+                }
+                FD_ZERO(&wd);
+                FD_SET((SOCKET)osfd, &wd);
+                if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL,
+                        tvp)) == -1) {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                    return -1;
+                }
+                if (rv == 0) {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                    return -1;
+                }
+            } else {
+                _PR_MD_MAP_SENDTO_ERROR(err);
+                return -1;
+            }
+        }
+        bytesSent += rv;
+        if (fd->secret->nonblocking) {
+            break;
+        }
+        if (bytesSent < len) {
+            if ( timeout == PR_INTERVAL_NO_TIMEOUT ) {
+                tvp = NULL;
+            } else {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                    timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+            }
+            FD_ZERO(&wd);
+            FD_SET((SOCKET)osfd, &wd);
+            if ((rv = _PR_NTFiberSafeSelect(0, NULL, &wd, NULL,
+                    tvp)) == -1) {
+                _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                return -1;
+            }
+            if (rv == 0) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                return -1;
+            }
+        }
+    }
+    return bytesSent;
+}
+
+static PRInt32 _nt_nonblock_recvfrom(PRFileDesc *fd, char *buf, int len, struct sockaddr *addr, int *addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    struct timeval tv, *tvp;
+    fd_set rd;
+
+    while ((rv = recvfrom(osfd,buf,len,0,addr, addrlen)) == -1) {
+        if (((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+                && (!fd->secret->nonblocking)) {
+            if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+                tvp = NULL;
+            } else {
+                tv.tv_sec = PR_IntervalToSeconds(timeout);
+                tv.tv_usec = PR_IntervalToMicroseconds(
+                timeout - PR_SecondsToInterval(tv.tv_sec));
+                tvp = &tv;
+            }
+            FD_ZERO(&rd);
+            FD_SET((SOCKET)osfd, &rd);
+            if ((rv = _PR_NTFiberSafeSelect(0, &rd, NULL, NULL,
+                    tvp)) == -1) {
+                _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                break;
+            } else if (rv == 0) {
+                PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                rv = -1;
+                break;
+            }
+        } else {
+            _PR_MD_MAP_RECVFROM_ERROR(err);
+            break;
+        }
+    }
+    return(rv);
+}
+
+/*
+ * UDP support: the continuation thread functions and recvfrom and sendto.
+ */
+
+static void pt_InsertTimedInternal(pt_Continuation *op)
+{
+    PRInt32 delta = 0;
+    pt_Continuation *t_op = NULL;
+    PRIntervalTime now = PR_IntervalNow(), op_tmo, qd_tmo;
+
+    /*
+     * If this element operation isn't timed, it gets queued at the
+     * end of the list (just after pt_tq.tail) and we're
+     * finishd early.
+     */
+    if (PR_INTERVAL_NO_TIMEOUT == op->timeout)
+    {
+        t_op = pt_tq.tail;  /* put it at the end */
+        goto done;
+    }
+
+    /*
+     * The rest of this routine actaully deals with timed ops.
+     */
+
+    if (NULL != pt_tq.op)
+    {
+        /*
+         * To find where in the list to put the new operation, form
+         * the absolute time the operations in question will expire.
+         *
+         * The new operation ('op') will expire at now() + op->timeout.
+         *
+         * The operation that will time out furthest in the future will
+         * do so at pt_tq.epoch + pt_tq.op->timeout.
+         *
+         * Subsequently earlier timeouts are computed based on the latter
+         * knowledge by subracting the timeout deltas that are stored in
+         * the operation list. There are operation[n]->timeout ticks
+         * between the expiration of operation[n-1] and operation[n].e e 
+         *
+         * Therefore, the operation[n-1] will expire operation[n]->timeout
+         * ticks prior to operation[n].
+         *
+         * This should be easy!
+         */
+        t_op = pt_tq.op;  /* running pointer to queued op */
+        op_tmo = now + op->timeout;  /* that's in absolute ticks */
+        qd_tmo = pt_tq.epoch + t_op->timeout;  /* likewise */
+
+        do
+        {
+            /*
+             * If 'op' expires later than t_op, then insert 'op' just
+             * ahead of t_op. Otherwise, compute when operation[n-1]
+             * expires and try again.
+             *
+             * The actual different between the expiriation of 'op'
+             * and the current operation what becomes the new operaton's
+             * timeout interval. That interval is also subtracted from
+             * the interval of the operation immediately following where
+             * we stick 'op' (unless the next one isn't timed). The new
+             * timeout assigned to 'op' takes into account the values of
+             * now() and when the previous intervals were compured.
+             */
+            delta = op_tmo - qd_tmo;
+            if (delta >= 0)
+            {
+                op->timeout += (now - pt_tq.epoch);
+                goto done;
+            }
+
+            qd_tmo -= t_op->timeout;  /* previous operaton expiration */
+            t_op = t_op->prev;  /* point to previous operation */
+            if (NULL != t_op) qd_tmo += t_op->timeout;
+        } while (NULL != t_op);
+
+        /*
+         * If we got here we backed off the head of the list. That means that
+         * this timed entry has to go at the head of the list. This is just
+         * about like having an empty timer list.
+         */
+        delta = op->timeout;  /* $$$ is this right? */
+    }
+
+done:
+
+    /*
+     * Insert 'op' into the queue just after t_op or if t_op is null,
+     * at the head of the list.
+     *
+     * If t_op is NULL, the list is currently empty and this is pretty
+     * easy.
+     */
+    if (NULL == t_op)
+    {
+        op->prev = NULL;
+        op->next = pt_tq.head;
+        pt_tq.head = op;
+        if (NULL == pt_tq.tail) pt_tq.tail = op;
+        else op->next->prev = op;
+    }
+    else
+    {
+        op->prev = t_op;
+        op->next = t_op->next;
+        if (NULL != op->prev)
+            op->prev->next = op;
+        if (NULL != op->next)
+            op->next->prev = op;
+        if (t_op == pt_tq.tail)
+            pt_tq.tail = op;
+    }
+
+    /*
+     * Are we adjusting our epoch, etc? Are we replacing
+     * what was previously the element due to expire furthest
+     * out in the future? Is this even a timed operation?
+     */
+    if (PR_INTERVAL_NO_TIMEOUT != op->timeout)
+    {
+        if ((NULL == pt_tq.op)  /* we're the one and only */
+        || (t_op == pt_tq.op))  /* we're replacing */
+        {
+            pt_tq.op = op;
+            pt_tq.epoch = now;
+        }
+    }
+
+    pt_tq.op_count += 1;
+
+}  /* pt_InsertTimedInternal */
+
+/*
+ * function: pt_FinishTimed
+ *
+ * Takes the finished operation out of the timed queue. It
+ * notifies the initiating thread that the opertions is
+ * complete and returns to the caller the value of the next
+ * operation in the list (or NULL).
+ */
+static pt_Continuation *pt_FinishTimedInternal(pt_Continuation *op)
+{
+    pt_Continuation *next;
+
+    /* remove this one from the list */
+    if (NULL == op->prev) pt_tq.head = op->next;
+    else op->prev->next = op->next;
+    if (NULL == op->next) pt_tq.tail = op->prev;
+    else op->next->prev = op->prev;
+
+    /* did we happen to hit the timed op? */
+    if (op == pt_tq.op) pt_tq.op = op->prev;
+
+    next = op->next;
+    op->next = op->prev = NULL;
+    op->status = pt_continuation_done;
+
+    pt_tq.op_count -= 1;
+#if defined(DEBUG)
+    pt_debug.continuationsServed += 1;
+#endif
+    PR_NotifyCondVar(op->complete);
+
+    return next;
+}  /* pt_FinishTimedInternal */
+
+static void ContinuationThread(void *arg)
+{
+    /* initialization */
+    fd_set readSet, writeSet, exceptSet;
+    struct timeval tv;
+    SOCKET *pollingList = 0;                /* list built for polling */
+    PRIntn pollingListUsed;                 /* # entries used in the list */
+    PRIntn pollingListNeeded;               /* # entries needed this time */
+    PRIntn pollingSlotsAllocated = 0;       /* # entries available in list */
+    PRIntervalTime mx_select_ticks = PR_MillisecondsToInterval(PT_DEFAULT_SELECT_MSEC);
+
+    /* do some real work */
+    while (1)
+    {
+        PRIntn rv;
+        PRStatus status;
+        PRIntn pollIndex;
+        pt_Continuation *op;
+        PRIntervalTime now = PR_IntervalNow();
+        PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
+
+        PR_Lock(pt_tq.ml);
+        while (NULL == pt_tq.head)
+        {
+            status = PR_WaitCondVar(pt_tq.new_op, PR_INTERVAL_NO_TIMEOUT);
+            if ((PR_FAILURE == status)
+                && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break;
+        }
+        pollingListNeeded = pt_tq.op_count;
+        PR_Unlock(pt_tq.ml);
+
+        /* Okay. We're history */
+        if ((PR_FAILURE == status)
+            && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break;
+
+	/*
+	 * We are not holding the pt_tq.ml lock now, so more items may
+	 * get added to pt_tq during this window of time.  We hope
+	 * that 10 more spaces in the polling list should be enough.
+	 */
+
+        FD_ZERO(&readSet);
+        FD_ZERO(&writeSet);
+        FD_ZERO(&exceptSet);
+        pollingListNeeded += 10;
+        if (pollingListNeeded > pollingSlotsAllocated)
+        {
+            if (NULL != pollingList) PR_DELETE(pollingList);
+            pollingList = PR_MALLOC(pollingListNeeded * sizeof(PRPollDesc));
+            PR_ASSERT(NULL != pollingList);
+            pollingSlotsAllocated = pollingListNeeded;
+        }
+
+#if defined(DEBUG)
+        if (pollingListNeeded > pt_debug.pollingListMax)
+            pt_debug.pollingListMax = pollingListUsed;
+#endif
+
+        /*
+         * Build up a polling list.
+         * This list is sorted on time. Operations that have been
+         * interrupted are completed and not included in the list.
+         * There is an assertion that the operation is in progress.
+         */
+        pollingListUsed = 0;
+        PR_Lock(pt_tq.ml);
+
+        for (op = pt_tq.head; NULL != op;)
+        {
+            if (pt_continuation_abort == op->status)
+            {
+                op->result.code = -1;
+                op->syserrno = WSAEINTR;
+                op = pt_FinishTimedInternal(op);
+            }
+            else
+            {
+                PR_ASSERT(pt_continuation_done != op->status);
+                op->status = pt_continuation_inprogress;
+                if (op->event & PR_POLL_READ) {
+                    FD_SET(op->arg1.osfd, &readSet);
+                }
+                if (op->event & PR_POLL_WRITE) {
+                    FD_SET(op->arg1.osfd, &writeSet);
+                }
+                if (op->event & PR_POLL_EXCEPT) {
+                    FD_SET(op->arg1.osfd, &exceptSet);
+                }
+                pollingList[pollingListUsed] = op->arg1.osfd;
+                pollingListUsed += 1;
+                if (pollingListUsed == pollingSlotsAllocated) break;
+                op = op->next;
+            }
+        }
+
+        PR_Unlock(pt_tq.ml);
+
+        /*
+         * If 'op' isn't NULL at this point, then we didn't get to
+         * the end of the list. That means that more items got added
+         * to the list than we anticipated. So, forget this iteration,
+         * go around the horn again.
+         * One would hope this doesn't happen all that often.
+         */
+        if (NULL != op)
+        {
+#if defined(DEBUG)
+            pt_debug.predictionsFoiled += 1;  /* keep track */
+#endif
+            continue;  /* make it rethink things */
+        }
+
+        /* there's a chance that all ops got blown away */
+        if (NULL == pt_tq.head) continue;
+        /* if not, we know this is the shortest timeout */
+        timeout = pt_tq.head->timeout;
+
+        /*
+         * We don't want to wait forever on this poll. So keep
+         * the interval down. The operations, if they are timed,
+         * still have to timeout, while those that are not timed
+         * should persist forever. But they may be aborted. That's
+         * what this anxiety is all about.
+         */
+        if (timeout > mx_select_ticks) timeout = mx_select_ticks;
+
+        if (PR_INTERVAL_NO_TIMEOUT != pt_tq.head->timeout)
+            pt_tq.head->timeout -= timeout;
+        tv.tv_sec = PR_IntervalToSeconds(timeout);
+        tv.tv_usec = PR_IntervalToMicroseconds(timeout) % PR_USEC_PER_SEC;
+
+        rv = select(0, &readSet, &writeSet, &exceptSet, &tv);
+
+        if (0 == rv)  /* poll timed out - what about leading op? */
+        {
+            if (0 == pt_tq.head->timeout)
+            {
+                /* 
+                 * The leading element of the timed queue has timed
+                 * out. Get rid of it. In any case go around the
+                 * loop again, computing the polling list, checking
+                 * for interrupted operations.
+                 */
+                PR_Lock(pt_tq.ml);
+                do
+                {
+                    pt_tq.head->result.code = -1;
+                    pt_tq.head->syserrno = WSAETIMEDOUT;
+                    op = pt_FinishTimedInternal(pt_tq.head);
+                } while ((NULL != op) && (0 == op->timeout));
+                PR_Unlock(pt_tq.ml);
+            }
+            continue;
+        }
+
+        if (-1 == rv && (WSAGetLastError() == WSAEINTR
+                || WSAGetLastError() == WSAEINPROGRESS))
+        {
+            continue;               /* go around the loop again */
+        }
+
+        /*
+         * select() says that something in our list is ready for some more
+         * action or is an invalid fd. Find it, load up the operation and
+         * see what happens.
+         */
+
+        PR_ASSERT(rv > 0 || WSAGetLastError() == WSAENOTSOCK);
+
+
+        /*
+         * $$$ There's a problem here. I'm running the operations list
+         * and I'm not holding any locks. I don't want to hold the lock
+         * and do the operation, so this is really messed up..
+         *
+         * This may work out okay. The rule is that only this thread,
+         * the continuation thread, can remove elements from the list.
+         * Therefore, the list is at worst, longer than when we built
+         * the polling list.
+         */
+        op = pt_tq.head;
+        for (pollIndex = 0; pollIndex < pollingListUsed; ++pollIndex)
+        {
+            PRInt16 revents = 0;
+
+            PR_ASSERT(NULL != op);
+
+            /*
+             * This one wants attention. Redo the operation.
+             * We know that there can only be more elements
+             * in the op list than we knew about when we created
+             * the poll list. Therefore, we might have to skip
+             * a few ops to find the right one to operation on.
+             */
+            while (pollingList[pollIndex] != op->arg1.osfd )
+            {
+                op = op->next;
+                PR_ASSERT(NULL != op);
+            }
+
+            if (FD_ISSET(op->arg1.osfd, &readSet)) {
+                revents |= PR_POLL_READ;
+            }
+            if (FD_ISSET(op->arg1.osfd, &writeSet)) {
+                revents |= PR_POLL_WRITE;
+            }
+            if (FD_ISSET(op->arg1.osfd, &exceptSet)) {
+                revents |= PR_POLL_EXCEPT;
+            }
+
+            /*
+             * Sip over all those not in progress. They'll be
+             * pruned next time we build a polling list. Call
+             * the continuation function. If it reports completion,
+             * finish off the operation.
+             */
+            if (revents && (pt_continuation_inprogress == op->status)
+                && (op->function(op, revents)))
+            {
+                PR_Lock(pt_tq.ml);
+                op = pt_FinishTimedInternal(op);
+                PR_Unlock(pt_tq.ml);
+            }
+        }
+    }
+    if (NULL != pollingList) PR_DELETE(pollingList);
+}  /* ContinuationThread */
+
+static int pt_Continue(pt_Continuation *op)
+{
+    PRStatus rv;
+    /* Finish filling in the blank slots */
+    op->status = pt_continuation_sumbitted;
+    op->complete = PR_NewCondVar(pt_tq.ml);
+
+    PR_Lock(pt_tq.ml);  /* we provide the locking */
+
+    pt_InsertTimedInternal(op);  /* insert in the structure */
+
+    PR_NotifyCondVar(pt_tq.new_op);  /* notify the continuation thread */
+
+    while (pt_continuation_done != op->status)  /* wait for completion */
+    {
+        rv = PR_WaitCondVar(op->complete, PR_INTERVAL_NO_TIMEOUT);
+        /*
+         * If we get interrupted, we set state the continuation thread will
+         * see and allow it to finish the I/O operation w/ error. That way
+         * the rule that only the continuation thread is removing elements
+         * from the list is still valid.
+         *
+         * Don't call interrupt on the continuation thread. That'll just
+         * piss him off. He's cycling around at least every mx_select_ticks
+         * anyhow and should notice the request in there.
+         */
+        if ((PR_FAILURE == rv)
+            && (PR_PENDING_INTERRUPT_ERROR == PR_GetError()))
+            op->status = pt_continuation_abort;  /* our status */
+    }
+
+    PR_Unlock(pt_tq.ml);  /* we provide the locking */
+
+    PR_DestroyCondVar(op->complete);
+
+    return op->result.code;  /* and the primary answer */
+}  /* pt_Continue */
+
+static PRBool pt_sendto_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn bytes = sendto(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags,
+        (struct sockaddr*)op->arg5.addr, sizeof(*(op->arg5.addr)));
+    op->syserrno = WSAGetLastError();
+    if (bytes > 0)  /* this is progress */
+    {
+        char *bp = op->arg2.buffer;
+        bp += bytes;  /* adjust the buffer pointer */
+        op->arg2.buffer = bp;
+        op->result.code += bytes;  /* accumulate the number sent */
+        op->arg3.amount -= bytes;  /* and reduce the required count */
+        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
+    }
+    else return ((-1 == bytes) && (WSAEWOULDBLOCK == op->syserrno)) ?
+	PR_FALSE : PR_TRUE;
+}  /* pt_sendto_cont */
+
+static PRBool pt_recvfrom_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn addr_len = sizeof(*(op->arg5.addr));
+    op->result.code = recvfrom(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount,
+        op->arg4.flags, (struct sockaddr*)op->arg5.addr, &addr_len);
+    op->syserrno = WSAGetLastError();
+    return ((-1 == op->result.code) && (WSAEWOULDBLOCK == op->syserrno)) ?
+        PR_FALSE : PR_TRUE;
+}  /* pt_recvfrom_cont */
+
+static PRInt32 pt_SendTo(
+    SOCKET osfd, const void *buf,
+    PRInt32 amount, PRInt32 flags, const PRNetAddr *addr,
+    PRIntn addrlen, PRIntervalTime timeout)
+{
+    PRInt32 bytes = -1, err;
+    PRBool fNeedContinue = PR_FALSE;
+
+    bytes = sendto(
+            osfd, buf, amount, flags,
+            (struct sockaddr*)addr, PR_NETADDR_SIZE(addr));
+    if (bytes == -1) {
+		if ((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+        fNeedContinue = PR_TRUE;
+		else
+			_PR_MD_MAP_SENDTO_ERROR(err);
+    }
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = osfd;
+        op.arg2.buffer = (void*)buf;
+        op.arg3.amount = amount;
+        op.arg4.flags = flags;
+        op.arg5.addr = (PRNetAddr*)addr;
+        op.timeout = timeout;
+        op.result.code = 0;  /* initialize the number sent */
+        op.function = pt_sendto_cont;
+        op.event = PR_POLL_WRITE | PR_POLL_EXCEPT;
+        bytes = pt_Continue(&op);
+        if (bytes < 0) {
+            WSASetLastError(op.syserrno);
+			_PR_MD_MAP_SENDTO_ERROR(op.syserrno);
+        }
+    }
+    return bytes;
+}  /* pt_SendTo */
+
+static PRInt32 pt_RecvFrom(SOCKET osfd, void *buf, PRInt32 amount,
+    PRInt32 flags, PRNetAddr *addr, PRIntn *addr_len, PRIntervalTime timeout)
+{
+    PRInt32 bytes = -1, err;
+    PRBool fNeedContinue = PR_FALSE;
+
+    bytes = recvfrom(
+            osfd, buf, amount, flags,
+            (struct sockaddr*)addr, addr_len);
+    if (bytes == -1) {
+		if ((err = WSAGetLastError()) == WSAEWOULDBLOCK)
+        fNeedContinue = PR_TRUE;
+		else
+			_PR_MD_MAP_RECVFROM_ERROR(err);
+    }
+
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = osfd;
+        op.arg2.buffer = buf;
+        op.arg3.amount = amount;
+        op.arg4.flags = flags;
+        op.arg5.addr = addr;
+        op.timeout = timeout;
+        op.function = pt_recvfrom_cont;
+        op.event = PR_POLL_READ | PR_POLL_EXCEPT;
+        bytes = pt_Continue(&op);
+        if (bytes < 0) {
+            WSASetLastError(op.syserrno);
+			_PR_MD_MAP_RECVFROM_ERROR(op.syserrno);
+        }
+    }
+    return bytes;
+}  /* pt_RecvFrom */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntmisc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntmisc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,862 @@
+/* -*- 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 ***** */
+
+/*
+ * ntmisc.c
+ *
+ */
+
+#include "primpl.h"
+
+char *_PR_MD_GET_ENV(const char *name)
+{
+    return getenv(name);
+}
+
+/*
+** _PR_MD_PUT_ENV() -- add or change environment variable
+**
+**
+*/
+PRIntn _PR_MD_PUT_ENV(const char *name)
+{
+    return(putenv(name));
+}
+
+
+/*
+ **************************************************************************
+ **************************************************************************
+ **
+ **     Date and time routines
+ **
+ **************************************************************************
+ **************************************************************************
+ */
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_Now --
+ *
+ *     Returns the current time in microseconds since the epoch.
+ *     The epoch is midnight January 1, 1970 GMT.
+ *     The implementation is machine dependent.  This is the
+ *     implementation for Windows.
+ *     Cf. time_t time(time_t *tp)
+ *
+ *-----------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRTime)
+PR_Now(void)
+{
+    PRTime prt;
+    FILETIME ft;
+
+    GetSystemTimeAsFileTime(&ft);
+    _PR_FileTimeToPRTime(&ft, &prt);
+    return prt;       
+}
+
+/*
+ ***********************************************************************
+ ***********************************************************************
+ *
+ * Process creation routines
+ *
+ ***********************************************************************
+ ***********************************************************************
+ */
+
+/*
+ * Assemble the command line by concatenating the argv array.
+ * On success, this function returns 0 and the resulting command
+ * line is returned in *cmdLine.  On failure, it returns -1.
+ */
+static int assembleCmdLine(char *const *argv, char **cmdLine)
+{
+    char *const *arg;
+    char *p, *q;
+    size_t cmdLineSize;
+    int numBackslashes;
+    int i;
+    int argNeedQuotes;
+
+    /*
+     * Find out how large the command line buffer should be.
+     */
+    cmdLineSize = 0;
+    for (arg = argv; *arg; arg++) {
+        /*
+         * \ and " need to be escaped by a \.  In the worst case,
+         * every character is a \ or ", so the string of length
+         * may double.  If we quote an argument, that needs two ".
+         * Finally, we need a space between arguments, and
+         * a null byte at the end of command line.
+         */
+        cmdLineSize += 2 * strlen(*arg)  /* \ and " need to be escaped */
+                + 2                      /* we quote every argument */
+                + 1;                     /* space in between, or final null */
+    }
+    p = *cmdLine = PR_MALLOC((PRUint32) cmdLineSize);
+    if (p == NULL) {
+        return -1;
+    }
+
+    for (arg = argv; *arg; arg++) {
+        /* Add a space to separates the arguments */
+        if (arg != argv) {
+            *p++ = ' '; 
+        }
+        q = *arg;
+        numBackslashes = 0;
+        argNeedQuotes = 0;
+
+        /* If the argument contains white space, it needs to be quoted. */
+        if (strpbrk(*arg, " \f\n\r\t\v")) {
+            argNeedQuotes = 1;
+        }
+
+        if (argNeedQuotes) {
+            *p++ = '"';
+        }
+        while (*q) {
+            if (*q == '\\') {
+                numBackslashes++;
+                q++;
+            } else if (*q == '"') {
+                if (numBackslashes) {
+                    /*
+                     * Double the backslashes since they are followed
+                     * by a quote
+                     */
+                    for (i = 0; i < 2 * numBackslashes; i++) {
+                        *p++ = '\\';
+                    }
+                    numBackslashes = 0;
+                }
+                /* To escape the quote */
+                *p++ = '\\';
+                *p++ = *q++;
+            } else {
+                if (numBackslashes) {
+                    /*
+                     * Backslashes are not followed by a quote, so
+                     * don't need to double the backslashes.
+                     */
+                    for (i = 0; i < numBackslashes; i++) {
+                        *p++ = '\\';
+                    }
+                    numBackslashes = 0;
+                }
+                *p++ = *q++;
+            }
+        }
+
+        /* Now we are at the end of this argument */
+        if (numBackslashes) {
+            /*
+             * Double the backslashes if we have a quote string
+             * delimiter at the end.
+             */
+            if (argNeedQuotes) {
+                numBackslashes *= 2;
+            }
+            for (i = 0; i < numBackslashes; i++) {
+                *p++ = '\\';
+            }
+        }
+        if (argNeedQuotes) {
+            *p++ = '"';
+        }
+    } 
+
+    *p = '\0';
+    return 0;
+}
+
+/*
+ * Assemble the environment block by concatenating the envp array
+ * (preserving the terminating null byte in each array element)
+ * and adding a null byte at the end.
+ *
+ * Returns 0 on success.  The resulting environment block is returned
+ * in *envBlock.  Note that if envp is NULL, a NULL pointer is returned
+ * in *envBlock.  Returns -1 on failure.
+ */
+static int assembleEnvBlock(char **envp, char **envBlock)
+{
+    char *p;
+    char *q;
+    char **env;
+    char *curEnv;
+    char *cwdStart, *cwdEnd;
+    size_t envBlockSize;
+
+    if (envp == NULL) {
+        *envBlock = NULL;
+        return 0;
+    }
+
+    curEnv = GetEnvironmentStrings();
+
+    cwdStart = curEnv;
+    while (*cwdStart) {
+        if (cwdStart[0] == '=' && cwdStart[1] != '\0'
+                && cwdStart[2] == ':' && cwdStart[3] == '=') {
+            break;
+        }
+        cwdStart += strlen(cwdStart) + 1;
+    }
+    cwdEnd = cwdStart;
+    if (*cwdEnd) {
+        cwdEnd += strlen(cwdEnd) + 1;
+        while (*cwdEnd) {
+            if (cwdEnd[0] != '=' || cwdEnd[1] == '\0'
+                    || cwdEnd[2] != ':' || cwdEnd[3] != '=') {
+                break;
+            }
+            cwdEnd += strlen(cwdEnd) + 1;
+        }
+    }
+    envBlockSize = cwdEnd - cwdStart;
+
+    for (env = envp; *env; env++) {
+        envBlockSize += strlen(*env) + 1;
+    }
+    envBlockSize++;
+
+    p = *envBlock = PR_MALLOC((PRUint32) envBlockSize);
+    if (p == NULL) {
+        FreeEnvironmentStrings(curEnv);
+        return -1;
+    }
+
+    q = cwdStart;
+    while (q < cwdEnd) {
+        *p++ = *q++;
+    }
+    FreeEnvironmentStrings(curEnv);
+
+    for (env = envp; *env; env++) {
+        q = *env;
+        while (*q) {
+            *p++ = *q++;
+        }
+        *p++ = '\0';
+    }
+    *p = '\0';
+    return 0;
+}
+
+/*
+ * For qsort.  We sort (case-insensitive) the environment strings
+ * before generating the environment block.
+ */
+static int compare(const void *arg1, const void *arg2)
+{
+    return _stricmp(* (char**)arg1, * (char**)arg2);
+}
+
+PRProcess * _PR_CreateWindowsProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    STARTUPINFO startupInfo;
+    PROCESS_INFORMATION procInfo;
+    BOOL retVal;
+    char *cmdLine = NULL;
+    char *envBlock = NULL;
+    char **newEnvp = NULL;
+    const char *cwd = NULL; /* current working directory */
+    PRProcess *proc = NULL;
+
+    proc = PR_NEW(PRProcess);
+    if (!proc) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+
+    if (assembleCmdLine(argv, &cmdLine) == -1) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+
+    /*
+     * If attr->fdInheritBuffer is not NULL, we need to insert
+     * it into the envp array, so envp cannot be NULL.
+     */
+    if ((envp == NULL) && attr && attr->fdInheritBuffer) {
+        envp = environ;
+    }
+
+    if (envp != NULL) {
+        int idx;
+        int numEnv;
+        int newEnvpSize;
+
+        numEnv = 0;
+        while (envp[numEnv]) {
+            numEnv++;
+        }
+        newEnvpSize = numEnv + 1;  /* terminating null pointer */
+        if (attr && attr->fdInheritBuffer) {
+            newEnvpSize++;
+        }
+        newEnvp = (char **) PR_MALLOC(newEnvpSize * sizeof(char *));
+        for (idx = 0; idx < numEnv; idx++) {
+            newEnvp[idx] = envp[idx];
+        }
+        if (attr && attr->fdInheritBuffer) {
+            newEnvp[idx++] = attr->fdInheritBuffer;
+        }
+        newEnvp[idx] = NULL;
+        qsort((void *) newEnvp, (size_t) (newEnvpSize - 1),
+                sizeof(char *), compare);
+    }
+    if (assembleEnvBlock(newEnvp, &envBlock) == -1) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        goto errorExit;
+    }
+
+    ZeroMemory(&startupInfo, sizeof(startupInfo));
+    startupInfo.cb = sizeof(startupInfo);
+
+    if (attr) {
+        PRBool redirected = PR_FALSE;
+
+        /*
+         * XXX the default value for stdin, stdout, and stderr
+         * should probably be the console input and output, not
+         * those of the parent process.
+         */
+        startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+        startupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+        startupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+        if (attr->stdinFd) {
+            startupInfo.hStdInput = (HANDLE) attr->stdinFd->secret->md.osfd;
+            redirected = PR_TRUE;
+        }
+        if (attr->stdoutFd) {
+            startupInfo.hStdOutput = (HANDLE) attr->stdoutFd->secret->md.osfd;
+            redirected = PR_TRUE;
+        }
+        if (attr->stderrFd) {
+            startupInfo.hStdError = (HANDLE) attr->stderrFd->secret->md.osfd;
+            redirected = PR_TRUE;
+        }
+        if (redirected) {
+            startupInfo.dwFlags |= STARTF_USESTDHANDLES;
+        }
+        cwd = attr->currentDirectory;
+    }
+
+    retVal = CreateProcess(NULL,
+                           cmdLine,
+                           NULL,  /* security attributes for the new
+                                   * process */
+                           NULL,  /* security attributes for the primary
+                                   * thread in the new process */
+                           TRUE,  /* inherit handles */
+                           0,     /* creation flags */
+                           envBlock,  /* an environment block, consisting
+                                       * of a null-terminated block of
+                                       * null-terminated strings.  Each
+                                       * string is in the form:
+                                       *     name=value
+                                       * XXX: usually NULL */
+                           cwd,  /* current drive and directory */
+                           &startupInfo,
+                           &procInfo
+                          );
+    if (retVal == FALSE) {
+        /* XXX what error code? */
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        goto errorExit;
+    }
+
+    CloseHandle(procInfo.hThread);
+    proc->md.handle = procInfo.hProcess;
+    proc->md.id = procInfo.dwProcessId;
+
+    PR_DELETE(cmdLine);
+    if (newEnvp) {
+        PR_DELETE(newEnvp);
+    }
+    if (envBlock) {
+        PR_DELETE(envBlock);
+    }
+    return proc;
+
+errorExit:
+    if (cmdLine) {
+        PR_DELETE(cmdLine);
+    }
+    if (newEnvp) {
+        PR_DELETE(newEnvp);
+    }
+    if (envBlock) {
+        PR_DELETE(envBlock);
+    }
+    if (proc) {
+        PR_DELETE(proc);
+    }
+    return NULL;
+}  /* _PR_CreateWindowsProcess */
+
+PRStatus _PR_DetachWindowsProcess(PRProcess *process)
+{
+    CloseHandle(process->md.handle);
+    PR_DELETE(process);
+    return PR_SUCCESS;
+}
+
+/*
+ * XXX: This implementation is a temporary quick solution.
+ * It can be called by native threads only (not by fibers).
+ */
+PRStatus _PR_WaitWindowsProcess(PRProcess *process,
+    PRInt32 *exitCode)
+{
+    DWORD dwRetVal;
+
+    dwRetVal = WaitForSingleObject(process->md.handle, INFINITE);
+    if (dwRetVal == WAIT_FAILED) {
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        return PR_FAILURE;
+    }
+    PR_ASSERT(dwRetVal == WAIT_OBJECT_0);
+    if (exitCode != NULL &&
+            GetExitCodeProcess(process->md.handle, exitCode) == FALSE) {
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        return PR_FAILURE;
+    }
+    CloseHandle(process->md.handle);
+    PR_DELETE(process);
+    return PR_SUCCESS;
+}
+
+PRStatus _PR_KillWindowsProcess(PRProcess *process)
+{
+    /*
+     * On Unix, if a process terminates normally, its exit code is
+     * between 0 and 255.  So here on Windows, we use the exit code
+     * 256 to indicate that the process is killed.
+     */
+    if (TerminateProcess(process->md.handle, 256)) {
+	return PR_SUCCESS;
+    }
+    PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+    return PR_FAILURE;
+}
+
+PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen)
+{
+    PRIntn rv;
+    PRInt32 syserror;
+
+    rv = gethostname(name, (PRInt32) namelen);
+    if (0 == rv) {
+        return PR_SUCCESS;
+    }
+    syserror = WSAGetLastError();
+    PR_ASSERT(WSANOTINITIALISED != syserror);
+	_PR_MD_MAP_GETHOSTNAME_ERROR(syserror);
+    return PR_FAILURE;
+}
+
+PRStatus _MD_WindowsGetSysInfo(PRSysInfo cmd, char *name, PRUint32 namelen)
+{
+	OSVERSIONINFO osvi;
+
+	PR_ASSERT((cmd == PR_SI_SYSNAME) || (cmd == PR_SI_RELEASE));
+
+	ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+	if (! GetVersionEx (&osvi) ) {
+		_PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+    	return PR_FAILURE;
+	}
+
+	switch (osvi.dwPlatformId) {
+		case VER_PLATFORM_WIN32_NT:
+			if (PR_SI_SYSNAME == cmd)
+				(void)PR_snprintf(name, namelen, "Windows_NT");
+			else if (PR_SI_RELEASE == cmd)
+				(void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, 
+            							osvi.dwMinorVersion);
+			break;
+		case VER_PLATFORM_WIN32_WINDOWS:
+			if (PR_SI_SYSNAME == cmd) {
+				if ((osvi.dwMajorVersion > 4) || 
+					((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0)))
+					(void)PR_snprintf(name, namelen, "Windows_98");
+				else
+					(void)PR_snprintf(name, namelen, "Windows_95");
+			} else if (PR_SI_RELEASE == cmd) {
+				(void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, 
+            							osvi.dwMinorVersion);
+			}
+			break;
+   		default:
+			if (PR_SI_SYSNAME == cmd)
+				(void)PR_snprintf(name, namelen, "Windows_Unknown");
+			else if (PR_SI_RELEASE == cmd)
+				(void)PR_snprintf(name, namelen, "%d.%d",0,0);
+			break;
+	}
+	return PR_SUCCESS;
+}
+
+PRStatus _MD_WindowsGetReleaseName(char *name, PRUint32 namelen)
+{
+	OSVERSIONINFO osvi;
+
+	ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+	if (! GetVersionEx (&osvi) ) {
+		_PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+    	return PR_FAILURE;
+	}
+
+	switch (osvi.dwPlatformId) {
+		case VER_PLATFORM_WIN32_NT:
+		case VER_PLATFORM_WIN32_WINDOWS:
+			(void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, 
+            							osvi.dwMinorVersion);
+			break;
+   		default:
+			(void)PR_snprintf(name, namelen, "%d.%d",0,0);
+			break;
+	}
+	return PR_SUCCESS;
+}
+
+/*
+ **********************************************************************
+ *
+ * Memory-mapped files
+ *
+ **********************************************************************
+ */
+
+PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size)
+{
+    DWORD dwHi, dwLo;
+    DWORD flProtect;
+    PROsfd osfd;
+
+    osfd = ( fmap->fd == (PRFileDesc*)-1 )?  -1 : fmap->fd->secret->md.osfd;
+
+    dwLo = (DWORD) (size & 0xffffffff);
+    dwHi = (DWORD) (((PRUint64) size >> 32) & 0xffffffff);
+
+    if (fmap->prot == PR_PROT_READONLY) {
+        flProtect = PAGE_READONLY;
+        fmap->md.dwAccess = FILE_MAP_READ;
+    } else if (fmap->prot == PR_PROT_READWRITE) {
+        flProtect = PAGE_READWRITE;
+        fmap->md.dwAccess = FILE_MAP_WRITE;
+    } else {
+        PR_ASSERT(fmap->prot == PR_PROT_WRITECOPY);
+        flProtect = PAGE_WRITECOPY;
+        fmap->md.dwAccess = FILE_MAP_COPY;
+    }
+
+    fmap->md.hFileMap = CreateFileMapping(
+        (HANDLE) osfd,
+        NULL,
+        flProtect,
+        dwHi,
+        dwLo,
+        NULL);
+
+    if (fmap->md.hFileMap == NULL) {
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PRInt32 _MD_GetMemMapAlignment(void)
+{
+    SYSTEM_INFO info;
+    GetSystemInfo(&info);
+    return info.dwAllocationGranularity;
+}
+
+extern PRLogModuleInfo *_pr_shma_lm;
+
+void * _MD_MemMap(
+    PRFileMap *fmap,
+    PROffset64 offset,
+    PRUint32 len)
+{
+    DWORD dwHi, dwLo;
+    void *addr;
+
+    dwLo = (DWORD) (offset & 0xffffffff);
+    dwHi = (DWORD) (((PRUint64) offset >> 32) & 0xffffffff);
+    if ((addr = MapViewOfFile(fmap->md.hFileMap, fmap->md.dwAccess,
+            dwHi, dwLo, len)) == NULL) {
+        {
+            LPVOID lpMsgBuf; 
+            
+            FormatMessage( 
+                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+                NULL,
+                GetLastError(),
+                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+                (LPTSTR) &lpMsgBuf,
+                0,
+                NULL 
+            );
+            PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, ("md_memmap(): %s", lpMsgBuf ));
+        }
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+    }
+    return addr;
+}
+
+PRStatus _MD_MemUnmap(void *addr, PRUint32 len)
+{
+    if (UnmapViewOfFile(addr)) {
+        return PR_SUCCESS;
+    } else {
+        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        return PR_FAILURE;
+    }
+}
+
+PRStatus _MD_CloseFileMap(PRFileMap *fmap)
+{
+    CloseHandle(fmap->md.hFileMap);
+    PR_DELETE(fmap);
+    return PR_SUCCESS;
+}
+
+/*
+ ***********************************************************************
+ *
+ * Atomic increment and decrement operations for x86 processors
+ *
+ * We don't use InterlockedIncrement and InterlockedDecrement
+ * because on NT 3.51 and Win95, they return a number with
+ * the same sign as the incremented/decremented result, rather
+ * than the result itself.  On NT 4.0 these functions do return
+ * the incremented/decremented result.
+ *
+ * The result is returned in the eax register by the inline
+ * assembly code.  We disable the harmless "no return value"
+ * warning (4035) for these two functions.
+ *
+ ***********************************************************************
+ */
+
+#if defined(_M_IX86) || defined(_X86_)
+
+#pragma warning(disable: 4035)
+PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{    
+#if defined(__GNUC__)
+  PRInt32 result;
+  asm volatile ("lock ; xadd %0, %1" 
+                : "=r"(result), "=m"(*val)
+                : "0"(1), "m"(*val));
+  return result + 1;
+#else
+    __asm
+    {
+        mov ecx, val
+        mov eax, 1
+        lock xadd dword ptr [ecx], eax
+        inc eax
+    }
+#endif /* __GNUC__ */
+}
+#pragma warning(default: 4035)
+
+#pragma warning(disable: 4035)
+PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+#if defined(__GNUC__)
+  PRInt32 result;
+  asm volatile ("lock ; xadd %0, %1" 
+                : "=r"(result), "=m"(*val)
+                : "0"(-1), "m"(*val));
+  //asm volatile("lock ; xadd %0, %1" : "=m" (val), "=a" (result) : "-1" (1));
+  return result - 1;
+#else
+    __asm
+    {
+        mov ecx, val
+        mov eax, 0ffffffffh
+        lock xadd dword ptr [ecx], eax
+        dec eax
+    }
+#endif /* __GNUC__ */
+}
+#pragma warning(default: 4035)
+
+#pragma warning(disable: 4035)
+PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *intp, PRInt32 val)
+{
+#if defined(__GNUC__)
+  PRInt32 result;
+  //asm volatile("lock ; xadd %1, %0" : "=m" (intp), "=a" (result) : "1" (val));
+  asm volatile ("lock ; xadd %0, %1" 
+                : "=r"(result), "=m"(*intp)
+                : "0"(val), "m"(*intp));
+  return result + val;
+#else
+    __asm
+    {
+        mov ecx, intp
+        mov eax, val
+        mov edx, eax
+        lock xadd dword ptr [ecx], eax
+        add eax, edx
+    }
+#endif /* __GNUC__ */
+}
+#pragma warning(default: 4035)
+
+#ifdef _PR_HAVE_ATOMIC_CAS
+
+#pragma warning(disable: 4035)
+void 
+PR_StackPush(PRStack *stack, PRStackElem *stack_elem)
+{
+#if defined(__GNUC__)
+  void **tos = (void **) stack;
+  void *tmp;
+  
+ retry:
+  if (*tos == (void *) -1)
+    goto retry;
+  
+  __asm__("xchg %0,%1"
+          : "=r" (tmp), "=m"(*tos)
+          : "0" (-1), "m"(*tos));
+  
+  if (tmp == (void *) -1)
+    goto retry;
+  
+  *(void **)stack_elem = tmp;
+  __asm__("" : : : "memory");
+  *tos = stack_elem;
+#else
+    __asm
+    {
+	mov ebx, stack
+	mov ecx, stack_elem
+retry:	mov eax,[ebx]
+	cmp eax,-1
+	je retry
+	mov eax,-1
+	xchg dword ptr [ebx], eax
+	cmp eax,-1
+	je  retry
+	mov [ecx],eax
+	mov [ebx],ecx
+    }
+#endif /* __GNUC__ */
+}
+#pragma warning(default: 4035)
+
+#pragma warning(disable: 4035)
+PRStackElem * 
+PR_StackPop(PRStack *stack)
+{
+#if defined(__GNUC__)
+  void **tos = (void **) stack;
+  void *tmp;
+  
+ retry:
+  if (*tos == (void *) -1)
+    goto retry;
+  
+  __asm__("xchg %0,%1"
+          : "=r" (tmp), "=m"(*tos)
+          : "0" (-1), "m"(*tos));
+
+  if (tmp == (void *) -1)
+    goto retry;
+  
+  if (tmp != (void *) 0)
+    {
+      void *next = *(void **)tmp;
+      *tos = next;
+      *(void **)tmp = 0;
+    }
+  else
+    *tos = tmp;
+  
+  return tmp;
+#else
+    __asm
+    {
+	mov ebx, stack
+retry:	mov eax,[ebx]
+	cmp eax,-1
+	je retry
+	mov eax,-1
+	xchg dword ptr [ebx], eax
+	cmp eax,-1
+	je  retry
+	cmp eax,0
+	je  empty
+	mov ecx,[eax]
+	mov [ebx],ecx
+	mov [eax],0
+	jmp done
+empty:
+	mov [ebx],eax
+done:	
+	}
+#endif /* __GNUC__ */
+}
+#pragma warning(default: 4035)
+
+#endif /* _PR_HAVE_ATOMIC_CAS */
+
+#endif /* x86 processors */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntsec.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntsec.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,279 @@
+/* -*- 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) 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"
+
+/*
+ * ntsec.c
+ *
+ * Implement the POSIX-style mode bits (access permissions) for
+ * files and other securable objects in Windows NT using Windows
+ * NT's security descriptors with appropriate discretionary
+ * access-control lists.
+ */
+
+/*
+ * The security identifiers (SIDs) for owner, primary group,
+ * and the Everyone (World) group.
+ *
+ * These SIDs are looked up during NSPR initialization and
+ * saved in this global structure (see _PR_NT_InitSids) so
+ * that _PR_NT_MakeSecurityDescriptorACL doesn't need to
+ * look them up every time.
+ */
+static struct {
+    PSID owner;
+    PSID group;
+    PSID everyone;
+} _pr_nt_sids;
+
+/*
+ * Initialize the SIDs for owner, primary group, and the Everyone
+ * group in the _pr_nt_sids structure.
+ *
+ * This function needs to be called by NSPR initialization.
+ */
+void _PR_NT_InitSids(void)
+{
+    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
+    HANDLE hToken = NULL; /* initialized to an arbitrary value to
+                           * silence a Purify UMR warning */
+    UCHAR infoBuffer[1024];
+    PTOKEN_OWNER pTokenOwner = (PTOKEN_OWNER) infoBuffer;
+    PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup
+            = (PTOKEN_PRIMARY_GROUP) infoBuffer;
+    DWORD dwLength;
+    BOOL rv;
+
+    /*
+     * Look up and make a copy of the owner and primary group
+     * SIDs in the access token of the calling process.
+     */
+    rv = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
+    if (rv == 0) {
+        /*
+         * On non-NT systems, this function is not implemented
+         * (error code ERROR_CALL_NOT_IMPLEMENTED), and neither are
+         * the other security functions.  There is no point in
+         * going further.
+         *
+         * A process with insufficient access permissions may fail
+         * with the error code ERROR_ACCESS_DENIED.
+         */
+        PR_LOG(_pr_io_lm, PR_LOG_DEBUG,
+                ("_PR_NT_InitSids: OpenProcessToken() failed. Error: %d",
+                GetLastError()));
+        return;
+    }
+
+    rv = GetTokenInformation(hToken, TokenOwner, infoBuffer,
+            sizeof(infoBuffer), &dwLength);
+    PR_ASSERT(rv != 0);
+    dwLength = GetLengthSid(pTokenOwner->Owner);
+    _pr_nt_sids.owner = (PSID) PR_Malloc(dwLength);
+    PR_ASSERT(_pr_nt_sids.owner != NULL);
+    rv = CopySid(dwLength, _pr_nt_sids.owner, pTokenOwner->Owner);
+    PR_ASSERT(rv != 0);
+
+    rv = GetTokenInformation(hToken, TokenPrimaryGroup, infoBuffer,
+            sizeof(infoBuffer), &dwLength);
+    PR_ASSERT(rv != 0);
+    dwLength = GetLengthSid(pTokenPrimaryGroup->PrimaryGroup);
+    _pr_nt_sids.group = (PSID) PR_Malloc(dwLength);
+    PR_ASSERT(_pr_nt_sids.group != NULL);
+    rv = CopySid(dwLength, _pr_nt_sids.group,
+            pTokenPrimaryGroup->PrimaryGroup);
+    PR_ASSERT(rv != 0);
+
+    rv = CloseHandle(hToken);
+    PR_ASSERT(rv != 0);
+
+    /* Create a well-known SID for the Everyone group. */
+    rv = AllocateAndInitializeSid(&SIDAuthWorld, 1,
+            SECURITY_WORLD_RID,
+            0, 0, 0, 0, 0, 0, 0,
+            &_pr_nt_sids.everyone);
+    PR_ASSERT(rv != 0);
+}
+
+/*
+ * Free the SIDs for owner, primary group, and the Everyone group
+ * in the _pr_nt_sids structure.
+ *
+ * This function needs to be called by NSPR cleanup.
+ */
+void
+_PR_NT_FreeSids(void)
+{
+    if (_pr_nt_sids.owner) {
+        PR_Free(_pr_nt_sids.owner);
+    }
+    if (_pr_nt_sids.group) {
+        PR_Free(_pr_nt_sids.group);
+    }
+    if (_pr_nt_sids.everyone) {
+        FreeSid(_pr_nt_sids.everyone);
+    }
+}
+
+/*
+ * Construct a security descriptor whose discretionary access-control
+ * list implements the specified mode bits.  The SIDs for owner, group,
+ * and everyone are obtained from the global _pr_nt_sids structure.
+ * Both the security descriptor and access-control list are returned
+ * and should be freed by a _PR_NT_FreeSecurityDescriptorACL call.
+ *
+ * The accessTable array maps NSPR's read, write, and execute access
+ * rights to the corresponding NT access rights for the securable
+ * object.
+ */
+PRStatus
+_PR_NT_MakeSecurityDescriptorACL(
+    PRIntn mode,
+    DWORD accessTable[],
+    PSECURITY_DESCRIPTOR *resultSD,
+    PACL *resultACL)
+{
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+    DWORD cbACL;  /* size of ACL */
+    DWORD accessMask;
+
+    if (_pr_nt_sids.owner == NULL) {
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    pSD = (PSECURITY_DESCRIPTOR) PR_Malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
+    if (pSD == NULL) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!SetSecurityDescriptorOwner(pSD, _pr_nt_sids.owner, FALSE)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!SetSecurityDescriptorGroup(pSD, _pr_nt_sids.group, FALSE)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+
+    /*
+     * Construct a discretionary access-control list with three
+     * access-control entries, one each for owner, primary group,
+     * and Everyone.
+     */
+
+    cbACL = sizeof(ACL)
+          + 3 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))
+          + GetLengthSid(_pr_nt_sids.owner)
+          + GetLengthSid(_pr_nt_sids.group)
+          + GetLengthSid(_pr_nt_sids.everyone);
+    pACL = (PACL) PR_Malloc(cbACL);
+    if (pACL == NULL) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    accessMask = 0;
+    if (mode & 00400) accessMask |= accessTable[0];
+    if (mode & 00200) accessMask |= accessTable[1];
+    if (mode & 00100) accessMask |= accessTable[2];
+    if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+            _pr_nt_sids.owner)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    accessMask = 0;
+    if (mode & 00040) accessMask |= accessTable[0];
+    if (mode & 00020) accessMask |= accessTable[1];
+    if (mode & 00010) accessMask |= accessTable[2];
+    if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+            _pr_nt_sids.group)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    accessMask = 0;
+    if (mode & 00004) accessMask |= accessTable[0];
+    if (mode & 00002) accessMask |= accessTable[1];
+    if (mode & 00001) accessMask |= accessTable[2];
+    if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+            _pr_nt_sids.everyone)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+
+    if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+
+    *resultSD = pSD;
+    *resultACL = pACL;
+    return PR_SUCCESS;
+
+failed:
+    if (pSD) {
+        PR_Free(pSD);
+    }
+    if (pACL) {
+        PR_Free(pACL);
+    }
+    return PR_FAILURE;
+}
+
+/*
+ * Free the specified security descriptor and access-control list
+ * previously created by _PR_NT_MakeSecurityDescriptorACL.
+ */
+void
+_PR_NT_FreeSecurityDescriptorACL(PSECURITY_DESCRIPTOR pSD, PACL pACL)
+{
+    if (pSD) {
+        PR_Free(pSD);
+    }
+    if (pACL) {
+        PR_Free(pACL);
+    }
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntsem.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntsem.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+ * NT-specific semaphore handling code.
+ *
+ */
+
+
+#include "primpl.h"
+
+
+void 
+_PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value)
+{
+    md->sem = CreateSemaphore(NULL, value, 0x7fffffff, NULL);
+}
+
+void 
+_PR_MD_DESTROY_SEM(_MDSemaphore *md)
+{
+    CloseHandle(md->sem);
+}
+
+PRStatus 
+_PR_MD_TIMED_WAIT_SEM(_MDSemaphore *md, PRIntervalTime ticks)
+{
+    int rv;
+
+    rv = WaitForSingleObject(md->sem, PR_IntervalToMilliseconds(ticks));
+
+    if (rv == WAIT_OBJECT_0)
+        return PR_SUCCESS;
+    else
+        return PR_FAILURE;
+}
+
+PRStatus 
+_PR_MD_WAIT_SEM(_MDSemaphore *md)
+{
+    return _PR_MD_TIMED_WAIT_SEM(md, PR_INTERVAL_NO_TIMEOUT);
+}
+
+void 
+_PR_MD_POST_SEM(_MDSemaphore *md)
+{
+    int old_count;
+
+    ReleaseSemaphore(md->sem, 1, &old_count);
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntthread.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/ntthread.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,560 @@
+/* -*- 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 <process.h>  /* for _beginthreadex() */
+
+/* --- globals ------------------------------------------------ */
+PRLock                       *_pr_schedLock = NULL;
+_PRInterruptTable             _pr_interruptTable[] = { { 0 } };
+
+BOOL _pr_use_static_tls = TRUE;
+__declspec(thread) PRThread  *_pr_current_fiber;
+__declspec(thread) PRThread  *_pr_fiber_last_run;
+__declspec(thread) _PRCPU    *_pr_current_cpu;
+__declspec(thread) PRUintn    _pr_ints_off;
+DWORD _pr_currentFiberIndex;
+DWORD _pr_lastFiberIndex;
+DWORD _pr_currentCPUIndex;
+DWORD _pr_intsOffIndex;
+
+_MDLock                       _nt_idleLock;
+PRCList                       _nt_idleList;
+PRUint32                        _nt_idleCount;
+
+extern __declspec(thread) PRThread *_pr_io_restarted_io;
+extern DWORD _pr_io_restartedIOIndex;
+
+/* Must check the restarted_io *before* decrementing no_sched to 0 */
+#define POST_SWITCH_WORK() \
+    PR_BEGIN_MACRO \
+        PRThread *restarted_io = \
+            (_pr_use_static_tls ? _pr_io_restarted_io \
+            : (PRThread *) TlsGetValue(_pr_io_restartedIOIndex)); \
+        if (restarted_io) { \
+            _nt_handle_restarted_io(restarted_io); \
+        } \
+        _PR_MD_LAST_THREAD()->no_sched = 0; \
+    PR_END_MACRO
+
+void
+_nt_handle_restarted_io(PRThread *restarted_io)
+{
+    /* After the switch we can resume an IO if needed.
+     * XXXMB - this needs to be done in create thread, since that could
+     * be the result for a context switch too..
+     */
+    PR_ASSERT(restarted_io->io_suspended == PR_TRUE);
+    PR_ASSERT(restarted_io->md.thr_bound_cpu == restarted_io->cpu);
+
+    _PR_THREAD_LOCK(restarted_io);
+    if (restarted_io->io_pending == PR_FALSE) {
+
+        /* The IO already completed, put us back on the runq. */
+        int pri = restarted_io->priority;
+
+        restarted_io->state = _PR_RUNNABLE;
+        _PR_RUNQ_LOCK(restarted_io->cpu);
+        _PR_ADD_RUNQ(restarted_io, restarted_io->cpu, pri);
+        _PR_RUNQ_UNLOCK(restarted_io->cpu);
+    } else {
+        _PR_SLEEPQ_LOCK(restarted_io->cpu);
+        _PR_ADD_SLEEPQ(restarted_io, restarted_io->sleep);
+        _PR_SLEEPQ_UNLOCK(restarted_io->cpu);
+    }
+    restarted_io->io_suspended = PR_FALSE;
+    restarted_io->md.thr_bound_cpu = NULL;
+
+    _PR_THREAD_UNLOCK(restarted_io);
+
+    if (_pr_use_static_tls) {
+        _pr_io_restarted_io = NULL;
+    } else {
+        TlsSetValue(_pr_io_restartedIOIndex, NULL);
+    }
+}
+
+void
+_PR_MD_EARLY_INIT()
+{
+    _MD_NEW_LOCK( &_nt_idleLock );
+    _nt_idleCount = 0;
+    PR_INIT_CLIST(&_nt_idleList);
+
+#if 0
+    /* Make the clock tick at least once per millisecond */
+    if ( timeBeginPeriod(1) == TIMERR_NOCANDO) {
+        /* deep yoghurt; clock doesn't tick fast enough! */
+        PR_ASSERT(0);
+    }
+#endif
+
+    if (!_pr_use_static_tls) {
+        _pr_currentFiberIndex = TlsAlloc();
+        _pr_lastFiberIndex = TlsAlloc();
+        _pr_currentCPUIndex = TlsAlloc();
+        _pr_intsOffIndex = TlsAlloc();
+        _pr_io_restartedIOIndex = TlsAlloc();
+    }
+}
+
+void _PR_MD_CLEANUP_BEFORE_EXIT(void)
+{
+    _PR_NT_FreeSids();
+
+    WSACleanup();
+
+    if (!_pr_use_static_tls) {
+        TlsFree(_pr_currentFiberIndex);
+        TlsFree(_pr_lastFiberIndex);
+        TlsFree(_pr_currentCPUIndex);
+        TlsFree(_pr_intsOffIndex);
+        TlsFree(_pr_io_restartedIOIndex);
+    }
+}
+
+PRStatus
+_PR_MD_INIT_THREAD(PRThread *thread)
+{
+    thread->md.overlapped.ioModel = _MD_BlockingIO;
+    thread->md.overlapped.data.mdThread = &thread->md;
+
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
+            /*
+            ** Warning:
+            ** --------
+            ** NSPR requires a real handle to every thread.
+            ** GetCurrentThread() returns a pseudo-handle which
+            ** is not suitable for some thread operations (e.g.,
+            ** suspending).  Therefore, get a real handle from
+            ** the pseudo handle via DuplicateHandle(...)
+            */
+            DuplicateHandle(
+                    GetCurrentProcess(),     /* Process of source handle */
+                    GetCurrentThread(),      /* Pseudo Handle to dup */
+                    GetCurrentProcess(),     /* Process of handle */
+                    &(thread->md.handle),    /* resulting handle */
+                    0L,                      /* access flags */
+                    FALSE,                   /* Inheritable */
+                    DUPLICATE_SAME_ACCESS);  /* Options */
+        }
+
+        /* Create the blocking IO semaphore */
+        thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL);
+        if (thread->md.blocked_sema == NULL) {
+            return PR_FAILURE;
+        }
+		if (_native_threads_only) {
+			/* Create the blocking IO semaphore */
+			thread->md.thr_event = CreateEvent(NULL, TRUE, FALSE, NULL);
+			if (thread->md.thr_event == NULL) {
+				return PR_FAILURE;
+			}
+		}
+    }
+
+    return PR_SUCCESS;
+}
+
+static unsigned __stdcall
+pr_root(void *arg)
+{
+    PRThread *thread = (PRThread *)arg;
+    thread->md.start(thread);
+    return 0;
+}
+
+PRStatus 
+_PR_MD_CREATE_THREAD(PRThread *thread, 
+                  void (*start)(void *), 
+                  PRThreadPriority priority, 
+                  PRThreadScope scope, 
+                  PRThreadState state, 
+                  PRUint32 stackSize)
+{
+
+    thread->md.start = start;
+    thread->md.handle = (HANDLE) _beginthreadex(
+                    NULL,
+                    thread->stack->stackSize,
+                    pr_root,
+                    (void *)thread,
+                    CREATE_SUSPENDED,
+                    &(thread->id));
+    if(!thread->md.handle) {
+        PRErrorCode prerror;
+        thread->md.fiber_last_error = GetLastError();
+        switch (errno) {
+            case ENOMEM:
+                prerror = PR_OUT_OF_MEMORY_ERROR;
+                break;
+            case EAGAIN:
+                prerror = PR_INSUFFICIENT_RESOURCES_ERROR;
+                break;
+            case EINVAL:
+                prerror = PR_INVALID_ARGUMENT_ERROR;
+                break;
+            default:
+                prerror = PR_UNKNOWN_ERROR;
+        }
+        PR_SetError(prerror, errno);
+        return PR_FAILURE;
+    }
+
+    thread->md.id = thread->id;
+    /*
+     * On windows, a thread is created with a thread priority of
+     * THREAD_PRIORITY_NORMAL.
+     */
+    if (priority != PR_PRIORITY_NORMAL) {
+        _PR_MD_SET_PRIORITY(&(thread->md), priority);
+    }
+
+    /* Activate the thread */
+    if ( ResumeThread( thread->md.handle ) != -1)
+        return PR_SUCCESS;
+
+    PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+    return PR_FAILURE;
+}
+
+void
+_PR_MD_JOIN_THREAD(_MDThread *md)
+{
+    DWORD rv;
+
+    rv = WaitForSingleObject(md->handle, INFINITE);
+    PR_ASSERT(WAIT_OBJECT_0 == rv);
+}
+
+void
+_PR_MD_END_THREAD(void)
+{
+    _endthreadex(0);
+}
+
+void    
+_PR_MD_YIELD(void)
+{
+    /* Can NT really yield at all? */
+    Sleep(0);
+}
+
+void     
+_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
+{
+    int nativePri;
+    BOOL rv;
+
+    if (newPri < PR_PRIORITY_FIRST) {
+        newPri = PR_PRIORITY_FIRST;
+    } else if (newPri > PR_PRIORITY_LAST) {
+        newPri = PR_PRIORITY_LAST;
+    }
+    switch (newPri) {
+        case PR_PRIORITY_LOW:
+            nativePri = THREAD_PRIORITY_BELOW_NORMAL;
+            break;
+        case PR_PRIORITY_NORMAL:
+            nativePri = THREAD_PRIORITY_NORMAL;
+            break;
+        case PR_PRIORITY_HIGH:
+            nativePri = THREAD_PRIORITY_ABOVE_NORMAL;
+            break;
+        case PR_PRIORITY_URGENT:
+            nativePri = THREAD_PRIORITY_HIGHEST;
+    }
+    rv = SetThreadPriority(thread->handle, nativePri);
+    PR_ASSERT(rv);
+    if (!rv) {
+	PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+                ("PR_SetThreadPriority: can't set thread priority\n"));
+    }
+    return;
+}
+
+void
+_PR_MD_CLEAN_THREAD(PRThread *thread)
+{
+    BOOL rv;
+
+    if (thread->md.acceptex_buf) {
+        PR_DELETE(thread->md.acceptex_buf);
+    }
+
+    if (thread->md.xmit_bufs) {
+        PR_DELETE(thread->md.xmit_bufs);
+    }
+
+    if (thread->md.blocked_sema) {
+        rv = CloseHandle(thread->md.blocked_sema);
+        PR_ASSERT(rv);
+        thread->md.blocked_sema = 0;
+    }
+	if (_native_threads_only) {
+		if (thread->md.thr_event) {
+			rv = CloseHandle(thread->md.thr_event);
+			PR_ASSERT(rv);
+			thread->md.thr_event = 0;
+		}
+	}
+
+    if (thread->md.handle) {
+        rv = CloseHandle(thread->md.handle);
+        PR_ASSERT(rv);
+        thread->md.handle = 0;
+    }
+
+    /* Don't call DeleteFiber on current fiber or we'll kill the whole thread.
+     * Don't call free(thread) until we've switched off the thread.
+     * So put this fiber (or thread) on a list to be deleted by the idle
+     * fiber next time we have a chance.
+     */
+    if (!(thread->flags & (_PR_ATTACHED|_PR_GLOBAL_SCOPE))) {
+        _MD_LOCK(&_nt_idleLock);
+        _nt_idleCount++;
+        PR_APPEND_LINK(&thread->links, &_nt_idleList);
+        _MD_UNLOCK(&_nt_idleLock);
+    }
+}
+
+void
+_PR_MD_EXIT_THREAD(PRThread *thread)
+{
+    BOOL rv;
+
+    if (thread->md.acceptex_buf) {
+        PR_DELETE(thread->md.acceptex_buf);
+    }
+
+    if (thread->md.xmit_bufs) {
+        PR_DELETE(thread->md.xmit_bufs);
+    }
+
+    if (thread->md.blocked_sema) {
+        rv = CloseHandle(thread->md.blocked_sema);
+        PR_ASSERT(rv);
+        thread->md.blocked_sema = 0;
+    }
+
+	if (_native_threads_only) {
+		if (thread->md.thr_event) {
+			rv = CloseHandle(thread->md.thr_event);
+			PR_ASSERT(rv);
+			thread->md.thr_event = 0;
+		}
+	}
+
+    if (thread->md.handle) {
+        rv = CloseHandle(thread->md.handle);
+        PR_ASSERT(rv);
+        thread->md.handle = 0;
+    }
+
+    if (thread->flags & _PR_GLOBAL_SCOPE) {
+        _MD_SET_CURRENT_THREAD(NULL);
+    }
+}
+
+
+void
+_PR_MD_EXIT(PRIntn status)
+{
+    _exit(status);
+}
+
+#ifdef HAVE_FIBERS
+
+void
+_pr_fiber_mainline(void *unused) 
+{
+    PRThread *fiber = _PR_MD_CURRENT_THREAD();
+
+    POST_SWITCH_WORK();
+
+    fiber->md.fiber_fn(fiber->md.fiber_arg);
+}
+
+PRThread *_PR_MD_CREATE_USER_THREAD(
+    PRUint32 stacksize, void (*start)(void *), void *arg)
+{
+    PRThread *thread;
+
+    if ( (thread = PR_NEW(PRThread)) == NULL ) {
+        return NULL;
+    }
+    
+    memset(thread, 0, sizeof(PRThread));
+    thread->md.fiber_fn = start;
+    thread->md.fiber_arg = arg;
+    thread->md.fiber_stacksize = stacksize;
+    return thread;
+}
+
+void
+_PR_MD_CREATE_PRIMORDIAL_USER_THREAD(PRThread *thread)
+{
+    thread->md.fiber_id = ConvertThreadToFiber(NULL);
+    PR_ASSERT(thread->md.fiber_id);
+    _MD_SET_CURRENT_THREAD(thread);
+    _MD_SET_LAST_THREAD(thread);
+    thread->no_sched = 1;
+    return;
+}
+
+void
+_PR_MD_INIT_CONTEXT(PRThread *thread, char *top, void (*start) (void), PRBool *status)
+{
+    thread->md.fiber_fn = (void (*)(void *))start;
+    thread->md.fiber_id = CreateFiber(thread->md.fiber_stacksize, 
+        (LPFIBER_START_ROUTINE)_pr_fiber_mainline, NULL);
+    if (thread->md.fiber_id != 0)
+        *status = PR_TRUE;
+    else {
+        DWORD oserror = GetLastError();
+        PRErrorCode prerror;
+        if (oserror == ERROR_NOT_ENOUGH_MEMORY) {
+            prerror = PR_OUT_OF_MEMORY_ERROR;
+        } else {
+            prerror = PR_UNKNOWN_ERROR;
+        }
+        PR_SetError(prerror, oserror);
+        *status = PR_FALSE;
+    }
+}
+
+void
+_PR_MD_SWITCH_CONTEXT(PRThread *thread)
+{
+    PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) );
+
+    thread->md.fiber_last_error = GetLastError();
+    _PR_Schedule();
+}
+
+void
+_PR_MD_RESTORE_CONTEXT(PRThread *thread)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) );
+
+    /* The user-level code for yielding will happily add ourselves to the runq
+     * and then switch to ourselves; the NT fibers can't handle switching to 
+     * ourselves.
+     */
+    if (thread != me) {
+        SetLastError(thread->md.fiber_last_error);
+        _MD_SET_CURRENT_THREAD(thread);
+        _PR_MD_SET_LAST_THREAD(me);
+        thread->no_sched = 1;
+        SwitchToFiber(thread->md.fiber_id);
+        POST_SWITCH_WORK();
+    }
+}
+
+
+#endif /* HAVE_FIBERS */
+
+PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask )
+{
+    int rv;
+
+    rv = SetThreadAffinityMask(thread->md.handle, mask);
+
+    return rv?0:-1;
+}
+
+PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask)
+{
+    PRInt32 rv, system_mask;
+
+    rv = GetProcessAffinityMask(GetCurrentProcess(), mask, &system_mask);
+    
+    return rv?0:-1;
+}
+
+void 
+_PR_MD_SUSPEND_CPU(_PRCPU *cpu) 
+{
+    _PR_MD_SUSPEND_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_RESUME_CPU(_PRCPU *cpu)
+{
+    _PR_MD_RESUME_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_SUSPEND_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        /*
+        ** There seems to be some doubt about whether or not SuspendThread
+        ** is a synchronous function. The test afterwards is to help veriry
+        ** that it is, which is what Microsoft says it is.
+        */
+        PRUintn rv = SuspendThread(thread->md.handle);
+        PR_ASSERT(0xffffffffUL != rv);
+    }
+}
+
+void
+_PR_MD_RESUME_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        ResumeThread(thread->md.handle);
+    }
+}
+
+PRThread*
+_MD_CURRENT_THREAD(void)
+{
+PRThread *thread;
+
+	thread = _MD_GET_ATTACHED_THREAD();
+
+   	if (NULL == thread) {
+		thread = _PRI_AttachThread(
+            PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0);
+	}
+	PR_ASSERT(thread != NULL);
+	return thread;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/objs.mk
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/objs.mk	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,94 @@
+# 
+# ***** 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 *****
+
+
+ifeq ($(OS_TARGET),WINNT)
+CSRCS = ntmisc.c \
+	ntsec.c \
+	ntsem.c \
+	ntinrval.c \
+	ntgc.c \
+	ntio.c \
+	ntthread.c \
+	ntdllmn.c \
+	win32_errors.c \
+	w32ipcsem.c \
+	w32poll.c \
+	w32rng.c \
+	w32shm.c
+else
+ifeq ($(OS_TARGET),WIN95)
+CSRCS =	ntmisc.c \
+	ntsec.c \
+	ntsem.c \
+	ntinrval.c \
+	ntgc.c \
+	w95thred.c \
+	w95io.c \
+	w95cv.c \
+	w95sock.c \
+	win32_errors.c \
+	w32ipcsem.c \
+	w32poll.c \
+	w32rng.c \
+	w32shm.c \
+	w95dllmain.c
+else
+ifeq ($(OS_TARGET),WIN16)
+CSRCS =	w16null.c \
+	w16thred.c \
+	w16proc.c \
+	w16fmem.c \
+	w16sock.c \
+	w16mem.c \
+	w16io.c \
+	w16gc.c \
+	w16error.c \
+	w16stdio.c \
+	w16callb.c \
+	ntinrval.c
+endif # win16
+endif # win95
+endif # winnt
+
+CSRCS	+= $(PR_MD_CSRCS)
+ASFILES += $(PR_MD_ASFILES)
+
+OBJS += $(addprefix md/windows/$(OBJDIR)/,$(CSRCS:.c=.$(OBJ_SUFFIX)))  \
+	$(addprefix md/windows/$(OBJDIR)/,$(ASFILES:.s=.$(OBJ_SUFFIX)))
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16callb.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16callb.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,262 @@
+/* -*- 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 ***** */
+
+/*
+** w16callb.c -- Implement Win16 Callback functions
+**
+** Functions here are to replace functions normally in
+** LIBC which are not implemented in MSVC's LIBC.
+** Some clients of NSPR expect to statically link
+** to NSPR and get these functions.
+**
+** Some are implemented as callbacks to the .EXE
+** some are implemented directly in this module.
+**
+*/
+
+#include "primpl.h"
+#include "windowsx.h"
+
+/*
+** _pr_callback_funcs -- This is where clients register the 
+** callback function structure.
+*/
+struct PRMethodCallbackStr * _pr_callback_funcs;
+
+/*
+** PR_MDInitWin16() -- Register the PRMethodCallback table pointer
+** 
+*/
+void PR_MDRegisterCallbacks(struct PRMethodCallbackStr *f)
+{
+    _pr_callback_funcs = f;
+}
+
+/*
+** NSPR re-implenentations of various C runtime functions:
+*/
+
+/*
+** PR_MD_printf() -- exported as printf()
+**
+*/
+int  PR_MD_printf(const char *fmt, ...)
+{
+    char buffer[1024];
+    int ret = 0;
+    va_list args;
+
+    va_start(args, fmt);
+
+#ifdef DEBUG
+    PR_vsnprintf(buffer, sizeof(buffer), fmt, args);
+    {   
+        if (_pr_callback_funcs != NULL && _pr_callback_funcs->auxOutput != NULL) {
+            (* _pr_callback_funcs->auxOutput)(buffer);
+        } else {
+            OutputDebugString(buffer);
+        }
+    }
+#endif
+
+    va_end(args);
+    return ret;
+}
+
+/*
+** PR_MD_sscanf() -- exported as sscanf()
+**
+*/
+int  PR_MD_sscanf(const char *buf, const char *fmt, ...)
+{
+	int		retval;
+	va_list	arglist;
+
+	va_start(arglist, fmt);
+	retval = vsscanf((const unsigned char *)buf, (const unsigned char *)fmt, arglist);
+	va_end(arglist);
+	return retval;
+}
+
+/*
+** PR_MD_strftime() -- exported as strftime
+**
+*/
+size_t PR_MD_strftime(char *s, size_t len, const char *fmt, const struct tm *p) 
+{
+    if( _pr_callback_funcs ) {
+        return (*_pr_callback_funcs->strftime)(s, len, fmt, p);
+    } else {
+        PR_ASSERT(0);
+        return 0;
+    }
+}
+
+
+/*
+** PR_MD_malloc() -- exported as malloc()
+**
+*/
+void *PR_MD_malloc( size_t size )
+{
+    if( _pr_callback_funcs ) {
+        return (*_pr_callback_funcs->malloc)( size );
+    } else {
+        return GlobalAllocPtr(GPTR, (DWORD)size);
+    }
+} /* end malloc() */
+
+/*
+** PR_MD_calloc() -- exported as calloc()
+**
+*/
+void *PR_MD_calloc( size_t n, size_t size )
+{
+    void *p;
+    size_t sz;
+    
+    if( _pr_callback_funcs ) {
+        return (*_pr_callback_funcs->calloc)( n, size );
+    } else {
+        sz = n * size;
+        p = GlobalAllocPtr(GPTR, (DWORD)sz );
+        memset( p, 0x00, sz );
+        return p;
+    }
+} /* end calloc() */
+
+/*
+** PR_MD_realloc() -- exported as realloc()
+**
+*/
+void *PR_MD_realloc( void* old_blk, size_t size )
+{
+    if( _pr_callback_funcs ) {
+        return (*_pr_callback_funcs->realloc)( old_blk, size );
+    } else {
+        return GlobalReAllocPtr( old_blk, (DWORD)size, GPTR);
+    }
+} /* end realloc */
+
+/*
+** PR_MD_free() -- exported as free()
+**
+*/
+void PR_MD_free( void *ptr )
+{
+    if( _pr_callback_funcs ) {
+        (*_pr_callback_funcs->free)( ptr );
+        return;
+    } else {
+        GlobalFreePtr( ptr );
+        return;
+    }
+} /* end free() */
+
+/*
+** PR_MD_getenv() -- exported as getenv()
+**
+*/
+char *PR_MD_getenv( const char *name )
+{
+    if( _pr_callback_funcs ) {
+        return (*_pr_callback_funcs->getenv)( name );
+    } else {
+        return 0;
+    }
+} /* end getenv() */
+
+
+/*
+** PR_MD_perror() -- exported as perror()
+**
+** well, not really (lth. 12/5/97).
+** XXX hold this thought.
+**
+*/
+void PR_MD_perror( const char *prefix )
+{
+    return;
+} /* end perror() */
+
+/*
+** PR_MD_putenv() -- exported as putenv()
+**
+*/
+int  PR_MD_putenv(const char *assoc)
+{
+    if( _pr_callback_funcs ) {
+        return (*_pr_callback_funcs->putenv)(assoc);
+    } else {
+        PR_ASSERT(0);
+        return NULL;
+    }
+}
+
+/*
+** PR_MD_fprintf() -- exported as fprintf()
+**
+*/
+int  PR_MD_fprintf(FILE *fPtr, const char *fmt, ...)
+{
+    char buffer[1024];
+    va_list args;
+
+    va_start(args, fmt);
+    PR_vsnprintf(buffer, sizeof(buffer), fmt, args);
+
+    if (fPtr == NULL) 
+    {
+        if (_pr_callback_funcs != NULL && _pr_callback_funcs->auxOutput != NULL) 
+        {
+            (* _pr_callback_funcs->auxOutput)(buffer);
+        } 
+        else 
+        {
+            OutputDebugString(buffer);
+        }
+    } 
+    else 
+    {
+        fwrite(buffer, 1, strlen(buffer), fPtr); /* XXX Is this a sec. hole? */
+    }
+
+    va_end(args);
+    return 0;
+}
+
+/* end w16callb.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16error.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16error.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,252 @@
+/* -*- 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 ***** */
+
+/*
+** Note: A single error mapping function is provided.
+**
+*/ 
+#include "prerror.h"
+#include <errno.h>
+#include <winsock.h>
+
+
+void _PR_MD_map_error( int err )
+{
+
+    switch ( err )
+    {
+        case  ENOENT:   /* No such file or directory */
+			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+            break;
+        case  E2BIG:    /* Argument list too big */
+            PR_SetError( PR_INVALID_ARGUMENT_ERROR, err );
+            break;
+        case  ENOEXEC:  /* Exec format error */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EBADF:    /* Bad file number */
+            PR_SetError( PR_BAD_DESCRIPTOR_ERROR, err );
+            break;
+        case  ENOMEM:   /* Not enough Memory */
+            PR_SetError( PR_OUT_OF_MEMORY_ERROR, err );
+            break;
+        case  EACCES:   /* Permission denied */
+            PR_SetError( PR_NO_ACCESS_RIGHTS_ERROR, err );
+            break;
+        case  EEXIST:   /* File exists */
+        
+ /* RESTART here */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EXDEV:    /* Cross device link */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EINVAL:   /* Invalid argument */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ENFILE:   /* File table overflow */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EMFILE:   /* Too many open files */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ENOSPC:   /* No space left on device */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        /* math errors */
+        case  EDOM:     /* Argument too large */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ERANGE:   /* Result too large */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        /* file locking error */
+        case  EDEADLK:      /* Resource deadlock would occur */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EINTR:    /* Interrupt */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ECHILD:   /* Child does not exist */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        /* POSIX errors */
+        case  EAGAIN:   /* Resource unavailable, try again */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EBUSY:    /* Device or Resource is busy */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EFBIG:    /* File too large */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EIO:      /* I/O error */
+            PR_SetError( PR_IO_ERROR, err );
+            break;
+        case  EISDIR:   /* Is a directory */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ENOTDIR:  /* Not a directory */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EMLINK:   /* Too many links */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ENOTBLK:  /* Block device required */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ENOTTY:   /* Not a character device */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ENXIO:    /* No such device or address */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EPERM:    /* Not owner */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EPIPE:    /* Broken pipe */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EROFS:    /* Read only file system */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ESPIPE:   /* Illegal seek */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ESRCH:    /* No such process */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ETXTBSY:  /* Text file busy */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  EFAULT:   /* Bad address */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ENAMETOOLONG: /* Name too long */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ENODEV:   /* No such device */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ENOLCK:   /* No locks available on system */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ENOSYS:   /* Unknown system call */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+        case  ENOTEMPTY:    /* Directory not empty */
+        /* Normative Addendum error */
+        case  EILSEQ:   /* Multibyte/widw character encoding error */
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+            
+        /* WinSock errors */
+        case WSAEACCES:
+            PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
+            break;
+        case WSAEADDRINUSE:
+            PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
+            break;
+        case WSAEADDRNOTAVAIL:
+            PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err);
+            break;
+        case WSAEAFNOSUPPORT:
+            PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, err);
+            break;
+        case WSAEBADF:
+            PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
+            break;
+        case WSAECONNREFUSED:
+            PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
+            break;
+        case WSAEFAULT:
+            PR_SetError(PR_ACCESS_FAULT_ERROR, err);
+            break;
+        case WSAEINVAL:
+            PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
+            break;
+        case WSAEISCONN:
+            PR_SetError(PR_IS_CONNECTED_ERROR, err);
+            break;
+        case WSAEMFILE:
+            PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
+            break;
+        case WSAENETDOWN:
+        case WSAENETUNREACH:
+            PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err);
+            break;
+        case WSAENOBUFS:
+            PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
+            break;
+        case WSAENOPROTOOPT:
+        case WSAEMSGSIZE:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
+            break;
+        case WSAENOTCONN:
+            PR_SetError(PR_NOT_CONNECTED_ERROR, err);
+            break;
+        case WSAENOTSOCK:
+            PR_SetError(PR_NOT_SOCKET_ERROR, err);
+            break;
+        case WSAEOPNOTSUPP:
+            PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err);
+            break;
+        case WSAEPROTONOSUPPORT:
+            PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err);
+            break;
+        case WSAETIMEDOUT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, err);
+            break;
+        case WSAEINTR:
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, err );
+            break;
+        case WSASYSNOTREADY:
+        case WSAVERNOTSUPPORTED:
+            PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, err);
+            break;
+		case WSAEWOULDBLOCK:
+			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
+			break;
+            
+        default:
+            PR_SetError( PR_UNKNOWN_ERROR, err );
+            break;
+    }
+    return;
+} /* end _MD_map_win16_error() */
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16fmem.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16fmem.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,85 @@
+/* -*- 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"
+
+/*
+ **********************************************************************
+ *
+ * Memory-mapped files are not implemented on Win16.
+ *
+ **********************************************************************
+ */
+
+PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size)
+{
+    PR_ASSERT(!"Not implemented");
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRInt32 _MD_GetMemMapAlignment(void)
+{
+    PR_ASSERT(!"Not implemented");
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return -1;
+}
+
+void * _MD_MemMap(
+    PRFileMap *fmap,
+    PRInt64 offset,
+    PRUint32 len)
+{
+    PR_ASSERT(!"Not implemented");
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PRStatus _MD_MemUnmap(void *addr, PRUint32 len)
+{
+    PR_ASSERT(!"Not implemented");
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRStatus _MD_CloseFileMap(PRFileMap *fmap)
+{
+    PR_ASSERT(!"Not implemented");
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16gc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16gc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,86 @@
+/* -*- 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 <sys/timeb.h>
+
+PRWord *
+_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) 
+{
+    if (isCurrent) 
+    {
+        _MD_SAVE_CONTEXT(t);
+    }
+    /*
+    ** In Win16 because the premption is "cooperative" it can never be the 
+    ** case that a register holds the sole reference to an object.  It
+    ** will always have been pushed onto the stack before the thread
+    ** switch...  So don't bother to scan the registers...
+    */
+    *np = 0;
+
+    return (PRWord *) CONTEXT(t);
+}
+
+#if 0
+#ifndef SPORT_MODEL
+
+#define MAX_SEGMENT_SIZE (65536l - 4096l)
+
+/************************************************************************/
+/*
+** Machine dependent GC Heap management routines:
+**    _MD_GrowGCHeap
+*/
+/************************************************************************/
+
+extern void *
+_MD_GrowGCHeap(uint32 *sizep)
+{
+    void *addr;
+
+    if( *sizep > MAX_SEGMENT_SIZE ) {
+        *sizep = MAX_SEGMENT_SIZE;
+    }
+
+    addr = malloc((size_t)*sizep);
+    return addr;
+}
+
+#endif /* SPORT_MODEL */
+#endif /* 0 */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16io.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16io.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,855 @@
+/* -*- 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 <sys/types.h>
+#include <sys/stat.h>
+#include <share.h>
+#include <sys/locking.h>
+
+
+/*
+** Sleep this many milliseconds on each I/O operation
+** to cause an intentional thread switch. 
+*/
+#define _PR_MD_WIN16_DELAY 1
+
+
+/*
+** PR_MD_RegisterW16StdioCallbacks() -- Register Win16 stdio callback functions
+**
+** This public function call is unique to Win16. 
+** ... Sigh ... So much for platform independence.
+** 
+** To get stdio to work from a command line executable, the stdio stream
+** calls must be issued from the .EXE file; calling them from the .DLL
+** sends the output to the bit-bucket. Therefore, the .EXE wanting to
+** do stdio to the console window (must be built as a "quickwin" application)
+** must have the wrapper functions defined in this module statically linked
+** into the .EXE.
+**
+** There appears to be nothing you can do to get stdio to work from a
+** Win16 GUI application. Oh Well!
+**
+*/
+PRStdinRead   _pr_md_read_stdin = 0;
+PRStdoutWrite _pr_md_write_stdout = 0;
+PRStderrWrite _pr_md_write_stderr = 0;
+
+PRStatus
+PR_MD_RegisterW16StdioCallbacks( PRStdinRead inReadf, PRStdoutWrite outWritef, PRStderrWrite errWritef )
+{
+    _pr_md_write_stdout = outWritef;
+    _pr_md_write_stderr = errWritef;
+    _pr_md_read_stdin   = inReadf;
+    
+    return(PR_SUCCESS);
+} /* end PR_MD_RegisterW16StdioCallbacks() */
+
+
+/*
+** _PR_MD_OPEN() -- Open a file
+**
+** Returns: a fileHandle or -1
+**
+**
+*/
+PRInt32
+_PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
+{
+    PRInt32 file;
+    int     access = O_BINARY;
+    int     rights = 0;
+    
+    
+    /*
+    ** Map NSPR open flags to os open flags
+    */
+    if (osflags & PR_RDONLY )
+        access |= O_RDONLY;
+    if (osflags & PR_WRONLY )
+        access |= O_WRONLY;
+    if (osflags & PR_RDWR )
+        access |= O_RDWR;
+    if (osflags & PR_CREATE_FILE )
+    {
+        access |= O_CREAT;
+        rights |= S_IRWXU;
+    }
+    if (osflags & PR_TRUNCATE)
+        access |= O_TRUNC;
+    if (osflags & PR_APPEND)
+        access |= O_APPEND;
+    else
+        access |= O_RDONLY;
+        
+    /*
+    ** Open the file
+    */        
+    file = (PRInt32) sopen( name, access, SH_DENYNO, rights );
+    if ( -1 == (PRInt32)file )
+    {
+        _PR_MD_MAP_OPEN_ERROR( errno );
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return file;
+}
+
+/*
+** _PR_MD_READ() - Read something
+**
+** Returns: bytes read or -1
+**
+*/
+PRInt32
+_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
+{
+    PRInt32     rv;
+    
+    if ( (PR_GetDescType(fd) == PR_DESC_FILE) &&
+         ( fd->secret->md.osfd == PR_StandardInput ) &&
+         ( _pr_md_write_stdout ))
+    {
+        rv = (*_pr_md_read_stdin)( buf, len);    
+    }
+    else
+    {
+        rv = read( fd->secret->md.osfd, buf, len );
+    }
+    
+    if ( rv == -1)
+    {
+        _PR_MD_MAP_READ_ERROR( errno );
+    }
+    
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return rv;
+}
+
+/*
+** _PR_MD_WRITE() - Write something
+**
+** Returns:  bytes written or -1
+**
+** Note: for file handles 1 and 2 (stdout and stderr)
+** call the Win16 NSPR stdio callback functions, if they are 
+** registered.
+**
+*/
+PRInt32
+_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
+{
+    PRInt32     rv;
+
+    if ( (PR_GetDescType(fd) == PR_DESC_FILE))
+    {
+        switch ( fd->secret->md.osfd )
+        {
+            case  PR_StandardOutput :
+                if ( _pr_md_write_stdout )
+                    rv = (*_pr_md_write_stdout)( (void *)buf, len);
+                else
+                    rv = len; /* fake success */
+                break;
+                
+            case  PR_StandardError  :
+                if ( _pr_md_write_stderr )
+                    rv = (*_pr_md_write_stderr)( (void *)buf, len);    
+                else
+                    rv = len; /* fake success */
+                break;
+                
+            default:
+                rv = write( fd->secret->md.osfd, buf, len );
+                if ( rv == -1 )
+                {
+                    _PR_MD_MAP_WRITE_ERROR( errno );
+                }
+                break;
+        }
+    }
+    else
+    {
+        rv = write( fd->secret->md.osfd, buf, len );
+        if ( rv == -1 )
+        {
+            _PR_MD_MAP_WRITE_ERROR( errno );
+        }
+    }
+    
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return rv;
+} /* --- end _PR_MD_WRITE() --- */
+
+/*
+** _PR_MD_LSEEK() - Seek to position in a file
+**
+** Note: 'whence' maps directly to PR_...
+**
+** Returns:
+**
+*/
+PRInt32
+_PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, int whence)
+{
+    PRInt32     rv;
+    
+    rv = lseek( fd->secret->md.osfd, offset, whence );
+    if ( rv == -1 )
+    {
+        _PR_MD_MAP_LSEEK_ERROR( errno );
+        
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return( rv );
+}
+
+/*
+** _PR_MD_LSEEK64() -- Seek to position in file, 64bit offset.
+**
+*/
+PRInt64
+_PR_MD_LSEEK64( PRFileDesc *fd, PRInt64 offset, int whence )
+{
+    PRInt64 test;
+    PRInt32 rv, off;
+    LL_SHR(test, offset, 32);
+    if (!LL_IS_ZERO(test))
+    {
+        PR_SetError(PR_FILE_TOO_BIG_ERROR, 0);
+        LL_I2L(test, -1);
+        return test;
+    }
+    LL_L2I(off, offset);
+    rv = _PR_MD_LSEEK(fd, off, whence);
+    LL_I2L(test, rv);
+    return test;
+} /* end _PR_MD_LSEEK64() */
+
+/*
+** _PR_MD_FSYNC() - Flush file buffers.
+**
+** Returns:
+**
+**
+*/
+PRInt32
+_PR_MD_FSYNC(PRFileDesc *fd)
+{
+    PRInt32     rv;
+    
+    rv = (PRInt32) fsync( fd->secret->md.osfd );
+    if ( rv == -1 )
+    {
+        _PR_MD_MAP_FSYNC_ERROR( errno );
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return(rv);
+}
+
+/*
+** _PR_MD_CLOSE() - Close an open file handle
+**
+** Returns:
+**
+**
+*/
+PRInt32
+_PR_MD_CLOSE_FILE(PRInt32 osfd)
+{
+    PRInt32     rv;
+    
+    rv = (PRInt32) close( osfd );
+    if ( rv == -1 )
+    {
+        _PR_MD_MAP_CLOSE_ERROR( errno );
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return(rv);
+} /* --- end _MD_CloseFile() --- */
+
+
+/* --- DIR IO ------------------------------------------------------------ */
+#define GetFileFromDIR(d)       (d)->d_entry.cFileName
+
+/*
+** FlipSlashes() - Make forward slashes ('/') into backslashes
+**
+** Returns: void
+**
+**
+*/
+void FlipSlashes(char *cp, int len)
+{
+    while (--len >= 0) {
+    if (cp[0] == '/') {
+        cp[0] = PR_DIRECTORY_SEPARATOR;
+    }
+    cp++;
+    }
+}
+
+
+/*
+** _PR_MD_OPEN_DIR() - Open a Directory.
+**
+** Returns:
+**
+**
+*/
+PRStatus
+_PR_MD_OPEN_DIR(_MDDir *d, const char *name)
+{
+    d->dir = opendir( name );
+    
+    if ( d->dir == NULL )
+    {
+        _PR_MD_MAP_OPENDIR_ERROR( errno );
+        return( PR_FAILURE );
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return( PR_SUCCESS );
+}
+
+
+/*
+** _PR_MD_READ_DIR() - read next directory entry
+**
+**
+*/
+char *
+_PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
+{
+    struct dirent *de;
+    int err;
+
+	for (;;) 
+    {
+		de = readdir( d->dir );
+		if ( de == NULL ) {
+			_PR_MD_MAP_READDIR_ERROR( errno);
+			return 0;
+		}		
+		if ((flags & PR_SKIP_DOT) &&
+		    (de->d_name[0] == '.') && (de->d_name[1] == 0))
+			continue;
+		if ((flags & PR_SKIP_DOT_DOT) &&
+		    (de->d_name[0] == '.') && (de->d_name[1] == '.') &&
+		    (de->d_name[2] == 0))
+			continue;
+		break;
+	}
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+	return de->d_name;
+}
+
+/*
+** _PR_MD_CLOSE_DIR() - Close a directory.
+**
+**
+*/
+PRInt32
+_PR_MD_CLOSE_DIR(_MDDir *d)
+{
+    PRInt32     rv;
+    
+    if ( d->dir ) 
+    {
+        rv = closedir( d->dir );
+        if (rv != 0) 
+        {
+            _PR_MD_MAP_CLOSEDIR_ERROR( errno );
+        }
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return rv;
+}
+
+
+/*
+** _PR_MD_DELETE() - Delete a file.
+**
+** Returns:
+**
+**
+*/
+PRInt32
+_PR_MD_DELETE(const char *name)
+{
+    PRInt32     rv;
+    
+    rv = (PRInt32) remove( name );
+    if ( rv != 0 )
+    {
+        _PR_MD_MAP_DELETE_ERROR( errno );
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return(rv);
+}
+
+
+/*
+** _PR_MD_STAT() - Get file attributes by filename
+**
+** Returns:
+**
+**
+*/
+PRInt32
+_PR_MD_STAT(const char *fn, struct stat *info)
+{
+    PRInt32     rv;
+    
+    rv = _stat(fn, (struct _stat *)info);
+    if ( rv == -1 )
+    {
+        _PR_MD_MAP_STAT_ERROR( errno );
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return( rv );
+}
+
+/*
+** _PR_MD_GETFILEINFO() - Get file attributes by filename
+**
+** Returns:
+**
+**
+*/
+PRInt32
+_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info)
+{
+    struct _stat sb;
+    PRInt32 rv;
+ 
+    if ( (rv = _stat(fn, &sb)) == 0 ) {
+        if (info) {
+            if (S_IFREG & sb.st_mode)
+                info->type = PR_FILE_FILE ;
+            else if (S_IFDIR & sb.st_mode)
+                info->type = PR_FILE_DIRECTORY;
+            else
+                info->type = PR_FILE_OTHER;
+            info->size = sb.st_size;
+            LL_I2L(info->modifyTime, sb.st_mtime);
+            LL_I2L(info->creationTime, sb.st_ctime);
+        }
+    }
+    else
+    {
+        _PR_MD_MAP_STAT_ERROR( errno );
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
+{
+    PRFileInfo info32;
+    
+    PRInt32 rv = _PR_MD_GETFILEINFO(fn, &info32);
+    if (0 == rv)
+    {
+        info->type = info32.type;
+        info->modifyTime = info32.modifyTime;
+        info->creationTime = info32.creationTime;
+        LL_I2L(info->size, info32.size);
+    }
+    return(rv);
+}
+
+/*
+** _PR_MD_GETOPENFILEINFO() - Get file attributes from an open file handle
+**
+** Returns:
+**
+**
+*/
+PRInt32
+_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
+{
+    struct stat statBuf;
+    PRInt32 rv = PR_SUCCESS;
+    
+    rv = fstat( fd->secret->md.osfd, &statBuf );
+    if ( rv == 0)
+    {
+        if (statBuf.st_mode & S_IFREG )
+            info->type = PR_FILE_FILE;
+        else if ( statBuf.st_mode & S_IFDIR )
+            info->type = PR_FILE_DIRECTORY;
+        else
+            info->type = PR_FILE_OTHER;
+        info->size = statBuf.st_size;
+        LL_I2L(info->modifyTime, statBuf.st_mtime);
+        LL_I2L(info->creationTime, statBuf.st_ctime);
+        
+    }
+    else
+    {
+        _PR_MD_MAP_FSTAT_ERROR( errno );
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return(rv);
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
+{
+    PRFileInfo info32;
+    
+    PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, &info32);
+    if (0 == rv)
+    {
+        info->type = info32.type;
+        info->modifyTime = info32.modifyTime;
+        info->creationTime = info32.creationTime;
+        LL_I2L(info->size, info32.size);
+    }
+    return(rv);
+}
+
+/*
+** _PR_MD_RENAME() - Rename a file
+**
+** Returns:
+**
+**
+*/
+PRInt32
+_PR_MD_RENAME(const char *from, const char *to)
+{
+    PRInt32 rv;
+    
+    rv = rename( from, to );
+    if ( rv == -1 )
+    {
+        _PR_MD_MAP_RENAME_ERROR( errno );
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return( rv );
+}
+
+/*
+** _PR_MD_ACCESS() - Return file acesss attribute.
+**
+** Returns:
+**
+**
+*/
+PRInt32
+_PR_MD_ACCESS(const char *name, PRIntn how)
+{
+    PRInt32     rv;
+    int         mode = 0;
+    
+    if ( how & PR_ACCESS_WRITE_OK )
+        mode |= W_OK;
+    if ( how & PR_ACCESS_READ_OK )
+        mode |= R_OK;
+        
+    rv = (PRInt32) access( name, mode );        
+    if ( rv == -1 )
+    {
+        _PR_MD_MAP_ACCESS_ERROR( errno );
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return(rv);
+}
+
+/*
+** _PR_MD_MKDIR() - Make a directory
+**
+** Returns:
+**
+**
+*/
+PRInt32
+_PR_MD_MKDIR(const char *name, PRIntn mode)
+{
+    PRInt32 rv;
+        
+    rv = mkdir( name );
+    if ( rv == 0 )
+    {
+        PR_Sleep( _PR_MD_WIN16_DELAY );    
+        return PR_SUCCESS;
+    }
+    else
+    {
+        _PR_MD_MAP_MKDIR_ERROR( errno );
+        PR_Sleep( _PR_MD_WIN16_DELAY );    
+        return PR_FAILURE;
+    }
+}
+
+/*
+** _PR_MD_RMDIR() - Delete a directory
+**
+** Returns:
+**
+**
+*/
+PRInt32
+_PR_MD_RMDIR(const char *name)
+{
+    PRInt32 rv;
+    
+    rv = (PRInt32) rmdir( name );
+    if ( rv == -1 )
+    {
+        _PR_MD_MAP_RMDIR_ERROR( errno );
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return(rv);
+}
+
+/*
+** _PR_MD_LOCKFILE() - Lock a file.
+**
+** The _locking() call locks relative to the current file pointer.
+** This function is required to lock all of the file, so,
+** 1. Seek to the beginning of the file, preserving the original position.
+** 2. Lock the file, pausing if it is locked by someone else, and
+**    try again.
+** 3. Re-position to the original position in the file.
+**
+** For unlocking, a similar protocol of positioning is required.
+**
+*/
+PRStatus
+_PR_MD_LOCKFILE(PRInt32 f)
+{
+    PRInt32 rv = PR_SUCCESS;    /* What we return to our caller */
+    long    seekOrigin;         /* original position in file */
+    PRInt32 rc;                 /* what the system call returns to us */
+
+    /*
+    ** Seek to beginning of file, saving original position.
+    */    
+    seekOrigin = lseek( f, 0l, SEEK_SET );
+    if ( rc == -1 )
+    {
+        _PR_MD_MAP_LSEEK_ERROR( errno );
+        return( PR_FAILURE );
+    }
+    
+    /*
+    ** Attempt to lock the file.
+    ** If someone else has it, Sleep-a-while and try again.
+    */
+    for( rc = -1; rc != 0; )
+    {
+        rc = _locking( f, _LK_NBLCK , 0x7fffffff );
+        if ( rc == -1 )
+        {
+            if ( errno == EACCES )
+            {
+                PR_Sleep( 100 );
+                continue;
+            }
+            else
+            {
+                _PR_MD_MAP_LOCKF_ERROR( errno );
+                rv = PR_FAILURE;
+                break;
+            }
+        }
+    } /* end for() */
+    
+    /*
+    ** Now that the file is locked, re-position to
+    ** the original file position.
+    **
+    */
+    rc = lseek( f, seekOrigin, SEEK_SET );
+    if ( rc == -1 )
+    {
+        _PR_MD_MAP_LSEEK_ERROR( errno );
+        rv = PR_FAILURE;
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return PR_SUCCESS;
+} /* end _PR_MD_LOCKFILE() */
+
+/*
+** _PR_MD_TLOCKFILE() - Test and Lock file.
+**
+** The _locking() call locks relative to the current file pointer.
+** This function is required to lock all of the file, so,
+** 1. Seek to the beginning of the file, preserving the original position.
+** 2. Attempt to Lock the file.
+**    If the file is locked by someone else, try NO MORE.
+** 3. Re-position to the original position in the file.
+**
+** See the discussion of _PR_MD_LOCKFILE
+**
+**
+*/
+PRStatus
+_PR_MD_TLOCKFILE(PRInt32 f)
+{
+    PRInt32 rv = PR_SUCCESS;    /* What we return */
+    long    seekOrigin;         /* original position in file */
+    PRInt32 rc;                 /* return value from system call */
+
+    /*
+    ** Seek to beginning of file, saving original position.
+    */    
+    seekOrigin = lseek( f, 0l, SEEK_SET );
+    if ( rc == -1 )
+    {
+        _PR_MD_MAP_LSEEK_ERROR( errno );
+        return( PR_FAILURE );
+    }
+    
+    /*
+    ** Attempt to lock the file. One ping; one ping only, Vasily.
+    ** If someone else has it, Reposition and return failure.
+    */
+    rc = _locking( f, _LK_NBLCK , 0x7fffffff );
+    if ( rc == -1 )
+    {
+        if ( errno != EACCES )
+            _PR_MD_MAP_LOCKF_ERROR( errno );
+        rv = PR_FAILURE;
+    }
+    
+    /*
+    ** Now that the file is locked, maybe, re-position to
+    ** the original file position.
+    */
+    rc = lseek( f, seekOrigin, SEEK_SET );
+    if ( rc == -1 )
+    {
+        _PR_MD_MAP_LSEEK_ERROR( errno );
+        rv = PR_FAILURE;
+    }
+    
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return rv;
+} /* end _PR_MD_TLOCKFILE() */
+
+
+/*
+** _PR_MD_UNLOCKFILE() - Unlock a file.
+**
+** See the discussion of _PR_MD_LOCKFILE
+**
+*/
+PRStatus
+_PR_MD_UNLOCKFILE(PRInt32 f)
+{
+    PRInt32 rv = PR_SUCCESS;    /* What we return */
+    long    seekOrigin;         /* original position in file */
+    PRInt32 rc;                 /* return value from system call */
+
+    /*
+    ** Seek to beginning of file, saving original position.
+    */    
+    seekOrigin = lseek( f, 0l, SEEK_SET );
+    if ( rc == -1 )
+    {
+        _PR_MD_MAP_LSEEK_ERROR( errno );
+        return( PR_FAILURE );
+    }
+    
+    /*
+    ** Unlock the file.
+    */
+    rc = _locking( f, _LK_UNLCK , 0x7fffffff );
+    if ( rc == -1 )
+    {
+        _PR_MD_MAP_LOCKF_ERROR( errno );
+        rv = PR_FAILURE;
+    }
+    
+    /*
+    ** Now that the file is unlocked, re-position to
+    ** the original file position.
+    */
+    rc = lseek( f, seekOrigin, SEEK_SET );
+    if ( rc == -1 )
+    {
+        _PR_MD_MAP_LSEEK_ERROR( errno );
+        rv = PR_FAILURE;
+    }
+    PR_Sleep( _PR_MD_WIN16_DELAY );    
+    return rv;
+} /* end _PR_MD_UNLOCKFILE() */
+
+/*
+** PR_Stat() -- Return status on a file
+**
+** This is a hack! ... See BugSplat: 98516 
+** Basically, this hack takes a name and stat buffer as input.
+** The input stat buffer is presumed to be a Microsoft stat buffer.
+** The functions does a Watcom stat() then maps the result to
+** the MS stat buffer. ...
+**
+*/
+PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf)
+{
+    PRInt32     rv;
+    _MDMSStat   *mssb = (_MDMSStat*) buf; /* this is Microsoft's stat buffer */
+    struct stat statBuf;   /* this is Watcom's stat buffer */
+
+    /* First, get Watcom's idea of stat
+    ** then reformat it into a Microsoft idea of stat
+    */
+    rv = (PRInt32) _stat( name, &statBuf);
+    if (rv == 0l )
+    {
+        mssb->st_dev = statBuf.st_dev;
+        mssb->st_ino = statBuf.st_ino; /* not used, really */
+        mssb->st_mode = statBuf.st_mode;
+        mssb->st_nlink = 1; /* always 1, says MS */
+        mssb->st_uid = statBuf.st_uid;
+        mssb->st_gid = statBuf.st_gid;
+        mssb->st_rdev = statBuf.st_rdev; /* please Gh0d! Let these be the same */
+        mssb->st_size = statBuf.st_size;
+        mssb->st_atime = statBuf.st_atime;
+        mssb->st_mtime = statBuf.st_mtime;
+        mssb->st_ctime = statBuf.st_ctime;
+    }
+    return rv;
+} /* end PR_Stat() */
+
+
+
+/* $$ end W16io.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16mem.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16mem.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*******************************************************************
+** w16mem.c -- Implement memory segment functions.
+**
+** 
+********************************************************************
+*/
+#include "primpl.h"
+
+
+/*
+**	Allocate a new memory segment.
+**	
+**	Return the segment's access rights and size.  
+*/
+PRStatus _MD_AllocSegment(PRSegment *seg, PRUint32 size, void *vaddr)
+{
+	PR_ASSERT(seg != 0);
+	PR_ASSERT(size != 0);
+	PR_ASSERT(vaddr == 0);
+
+	/*	
+	** Take the actual memory for the segment out of our Figment heap.
+	*/
+
+	seg->vaddr = (char *)malloc(size);
+
+	if (seg->vaddr == NULL) {
+		return PR_FAILURE;
+	}
+
+	seg->size = size;	
+
+	return PR_SUCCESS;
+} /* --- end _MD_AllocSegment() --- */
+
+
+/*
+**	Free previously allocated memory segment.
+*/
+void _MD_FreeSegment(PRSegment *seg)
+{
+	PR_ASSERT((seg->flags & _PR_SEG_VM) == 0);
+
+	if (seg->vaddr != NULL)
+		free( seg->vaddr );
+    return;
+} /* --- end _MD_FreeSegment() --- */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16null.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16null.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,116 @@
+/* -*- 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 <sys/timeb.h>
+
+
+struct _MDLock          _pr_ioq_lock;
+HINSTANCE               _pr_hInstance = NULL;
+char *                  _pr_top_of_task_stack;
+_PRInterruptTable       _pr_interruptTable[] = { { 0 } };
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_Now --
+ *
+ *     Returns the current time in microseconds since the epoch.
+ *     The epoch is midnight January 1, 1970 GMT.
+ *     The implementation is machine dependent.  This is the
+ *     implementation for Windows.
+ *     Cf. time_t time(time_t *tp)
+ *
+ *-----------------------------------------------------------------------
+ */
+
+#if defined(HAVE_WATCOM_BUG_2)
+PRTime __pascal __export __loadds
+#else
+PR_IMPLEMENT(PRTime)
+#endif
+PR_Now(void)
+{
+    PRInt64 s, ms, ms2us, s2us;
+    struct timeb b;
+
+    ftime(&b);
+    LL_I2L(ms2us, PR_USEC_PER_MSEC);
+    LL_I2L(s2us, PR_USEC_PER_SEC);
+    LL_I2L(s, b.time);
+    LL_I2L(ms, (PRInt32)b.millitm);
+    LL_MUL(ms, ms, ms2us);
+    LL_MUL(s, s, s2us);
+    LL_ADD(s, s, ms);
+    return s;       
+}
+
+
+
+char *_PR_MD_GET_ENV(const char *name)
+{
+    return NULL;
+}
+
+PRIntn
+_PR_MD_PUT_ENV(const char *name)
+{
+    return NULL;
+}
+
+int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg, 
+                      WORD cbHeapSize, LPSTR lpszCmdLine )
+{
+    _pr_hInstance = hInst;
+    return TRUE;
+}
+
+
+
+void
+_PR_MD_EARLY_INIT()
+{
+    _tzset();
+    return;
+}
+
+void
+_PR_MD_WAKEUP_CPUS( void )
+{
+    return;
+}    
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16proc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16proc.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+#include "primpl.h"
+#include <sys/timeb.h>
+
+
+/* 
+** Create Process.
+*/
+PRProcess * _PR_CreateWindowsProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    PR_ASSERT(!"Not implemented");
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PRStatus _PR_DetachWindowsProcess(PRProcess *process)
+{
+    PR_ASSERT(!"Not implemented");
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRStatus _PR_WaitWindowsProcess(PRProcess *process,
+    PRInt32 *exitCode)
+{
+    PR_ASSERT(!"Not implemented");
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRStatus _PR_KillWindowsProcess(PRProcess *process)
+{
+    PR_ASSERT(!"Not implemented");
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16sock.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16sock.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1170 @@
+/* -*- 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"
+
+static  int winsockNotPresent = 0;
+
+void
+_PR_MD_INIT_IO()
+{
+    int rv;
+    
+    WORD WSAVersion = 0x0101;
+    WSADATA WSAData;
+
+    rv = WSAStartup( WSAVersion, &WSAData );
+    if ( rv != 0 )
+    {
+        _PR_MD_MAP_WSASTARTUP_ERROR(WSAGetLastError());
+        winsockNotPresent = 1;
+    }
+    return;
+}
+
+void
+_PR_MD_CLEANUP_BEFORE_EXIT(void)
+{
+    int rv;
+    int err;
+    
+    rv = WSACleanup();
+    if ( rv == SOCKET_ERROR )
+    {
+        err = WSAGetLastError();
+        PR_ASSERT(0);
+    }
+    return;
+} /* end _PR_MD_CLEANUP_BEFORE_EXIT() */
+
+/* --- SOCKET IO --------------------------------------------------------- */
+
+PRStatus 
+_MD_WindowsGetHostName(char *name, PRUint32 namelen)
+{
+    PRIntn  rv;
+    PRInt32 syserror;
+    
+    rv = gethostname(name, (PRInt32) namelen);
+    if (0 == rv) {
+        return PR_SUCCESS;
+    }
+    syserror = WSAGetLastError();
+    PR_ASSERT(WSANOTINITIALISED != syserror);
+    _PR_MD_MAP_GETHOSTNAME_ERROR(syserror);
+    return PR_FAILURE;
+}
+
+
+PRInt32
+_PR_MD_SOCKET(int af, int type, int flags)
+{
+    SOCKET      sock;
+    PRUint32    one = 1;
+    PRInt32     rv;
+    PRInt32     err;
+
+    if ( winsockNotPresent )
+        return( (PRInt32)INVALID_SOCKET );
+
+    sock = socket(af, type, flags);
+
+    if (sock == INVALID_SOCKET ) 
+    {
+        int rv = GetLastError();
+        closesocket(sock);
+        _PR_MD_MAP_SOCKET_ERROR(rv);
+        return (PRInt32)INVALID_SOCKET;
+    }
+
+    /*
+    ** Make the socket Non-Blocking
+    */
+    rv = ioctlsocket( sock, FIONBIO, &one);
+    if ( rv != 0 )
+    {
+        err = WSAGetLastError();
+        return -1;
+    }
+
+    return (PRInt32)sock;
+}
+
+
+PRInt32
+_PR_MD_SOCKETAVAILABLE(PRFileDesc *fd)
+{
+    PRUint32 result;
+
+    if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError());
+        return -1;
+    }
+    return result;
+}
+
+
+/*
+** _MD_CloseSocket() -- Close a socket
+**
+*/
+PRInt32
+_PR_MD_CLOSE_SOCKET(PRInt32 osfd)
+{
+    PRInt32 rv;
+
+    rv = closesocket((SOCKET) osfd );
+    if (rv < 0)
+        _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
+
+    return rv;
+}
+
+PRInt32 _PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog)
+{
+    int rv, err;
+
+	rv = listen(fd->secret->md.osfd, backlog);
+	if ( rv == SOCKET_ERROR ) {
+		_PR_MD_MAP_LISTEN_ERROR(WSAGetLastError());
+        return(-1);
+	}
+	return(rv);
+}
+
+PRInt32
+_PR_MD_ACCEPT(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen,
+       PRIntervalTime timeout )
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRThread    *me = _PR_MD_CURRENT_THREAD();
+    PRInt32     err;
+    PRIntn      rv;
+
+    MD_ASSERTINT( *addrlen );    
+
+    while ((rv = (SOCKET)accept(osfd, (struct sockaddr *) addr,
+                                        (int *)addrlen)) == INVALID_SOCKET ) {
+        err = WSAGetLastError();
+		if ( err == WSAEWOULDBLOCK ) {
+			if (fd->secret->nonblocking) {
+				break;
+			}
+            if (_PR_WaitForFD(osfd, PR_POLL_READ, timeout) == 0) {
+                if ( _PR_PENDING_INTERRUPT(me))
+                {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                } else
+                {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                }
+                rv = -1;
+                goto done;
+            } else if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                rv = -1;
+                goto done;
+            }
+        } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_ACCEPT_ERROR(err);
+    }
+done:
+    if ( rv == INVALID_SOCKET )
+        return(-1 );
+    else
+        return(rv);
+} /* end _MD_Accept() */
+
+
+PRInt32
+_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, 
+               PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 rv, err;
+
+    while ((rv = connect(osfd, (struct sockaddr *)addr, addrlen)) == -1) {
+        err = WSAGetLastError();
+        if (err == WSAEISCONN) {
+            rv = 0;
+            break;
+        }
+        /* for winsock1.1, it reports EALREADY as EINVAL */
+		if ((err == WSAEWOULDBLOCK)
+            ||(err == WSAEALREADY) 
+            || (err = WSAEINVAL)) {
+			if (fd->secret->nonblocking) {
+				break;
+			}
+            if (_PR_WaitForFD(osfd, PR_POLL_WRITE, timeout) == 0) {
+                if ( _PR_PENDING_INTERRUPT(me))
+                {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                } else
+                {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                }
+                rv = -1;
+                goto done;
+            } else if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                rv = -1;
+                goto done;
+            }
+        } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+
+    if (rv < 0) {
+        _PR_MD_MAP_CONNECT_ERROR(err);
+    }
+done:
+    return rv;
+}
+
+PRInt32
+_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
+{
+    PRInt32 rv;
+    int one = 1;
+
+    rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen);
+
+    if (rv == SOCKET_ERROR)  {
+        _PR_MD_MAP_BIND_ERROR(WSAGetLastError());
+        return -1;
+    }
+
+    return 0;
+}
+
+
+PRInt32
+_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 
+            PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 rv, err;
+
+    while ((rv = recv(osfd,buf,amount,flags)) == -1) {
+        err = WSAGetLastError();
+		if ( err == WSAEWOULDBLOCK ) {
+			if (fd->secret->nonblocking) {
+				break;
+			}
+            if (_PR_WaitForFD(osfd, PR_POLL_READ, timeout) == 0) {
+                if ( _PR_PENDING_INTERRUPT(me))
+                {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                } else
+                {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                }
+                rv = -1;
+                goto done;
+            } else if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                rv = -1;
+                goto done;
+            }
+        } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_RECV_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+            PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 rv, err;
+
+    while ((rv = send(osfd,buf,amount,flags)) == -1) {
+        err = WSAGetLastError();
+		if ( err == WSAEWOULDBLOCK ) {
+			if (fd->secret->nonblocking) {
+				break;
+			}
+            if (_PR_WaitForFD(osfd, PR_POLL_WRITE, timeout) == 0) {
+                if ( _PR_PENDING_INTERRUPT(me))
+                {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                } else
+                {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                }
+                rv = -1;
+                goto done;
+            } else if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                rv = -1;
+                goto done;
+            }
+        } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_SEND_ERROR(err);
+    }
+done:
+    return rv;
+}
+
+PRInt32
+_PR_MD_SENDTO(PRFileDesc*fd, const void *buf, PRInt32 amount, PRIntn flags,
+              const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 rv, err;
+
+    while ((rv = sendto(osfd, buf, amount, flags,
+            (struct sockaddr *) addr, addrlen)) == -1) {
+        err = WSAGetLastError();
+		if ( err == WSAEWOULDBLOCK ) {
+			if (fd->secret->nonblocking) {
+				break;
+			}
+            if (_PR_WaitForFD(osfd, PR_POLL_WRITE, timeout) == 0) {
+                if ( _PR_PENDING_INTERRUPT(me))
+                {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                } else
+                {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                }
+                rv = -1;
+                goto done;
+            } else if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                rv = -1;
+                goto done;
+            }
+        } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_SENDTO_ERROR(err);
+    }
+done:
+    return rv;
+}
+
+PRInt32
+_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+                PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PRInt32 osfd = fd->secret->md.osfd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRInt32 rv, err;
+
+    while ((*addrlen = PR_NETADDR_SIZE(addr)),
+                ((rv = recvfrom(osfd, buf, amount, flags,
+                (struct sockaddr FAR *) addr,(int FAR *)addrlen)) == -1)) {
+        err = WSAGetLastError();
+		if ( err == WSAEWOULDBLOCK ) {
+			if (fd->secret->nonblocking) {
+				break;
+			}
+            if (_PR_WaitForFD(osfd, PR_POLL_READ, timeout) == 0) {
+                if ( _PR_PENDING_INTERRUPT(me))
+                {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                } else
+                {
+                    PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                }
+                rv = -1;
+                goto done;
+            } else if (_PR_PENDING_INTERRUPT(me)) {
+                me->flags &= ~_PR_INTERRUPT;
+                PR_SetError( PR_PENDING_INTERRUPT_ERROR, 0);
+                rv = -1;
+                goto done;
+            }
+        } else if ((err == WSAEINTR) && (!_PR_PENDING_INTERRUPT(me))){
+            continue;
+        } else {
+            break;
+        }
+    }
+    if (rv < 0) {
+        _PR_MD_MAP_RECVFROM_ERROR(err);
+    }
+done:
+    return(rv);
+}
+
+PRInt32
+_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout)
+{
+    int index;
+    int sent = 0;
+    int rv;
+
+    for (index=0; index < iov_size; index++) 
+    {
+
+/*
+ * XXX To be fixed
+ * should call PR_Send
+ */
+
+        rv = _PR_MD_SEND(fd, iov[index].iov_base, iov[index].iov_len, 0, timeout);
+        if (rv > 0) 
+            sent += rv;
+        if ( rv != iov[index].iov_len ) 
+        {
+            if (sent <= 0)
+                return -1;
+            return -1;
+        }
+    }
+    return sent;
+}
+
+PRInt32
+_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how)
+{
+PRInt32 rv;
+
+    rv = shutdown(fd->secret->md.osfd, how);
+    if (rv < 0)
+        _PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError());
+    return rv;
+}
+
+PRStatus
+_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
+{
+    PRInt32 rv;
+
+    rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, (int *)len);
+    if (rv==0)
+        return PR_SUCCESS;
+    else {
+        _PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+PRStatus
+_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
+{
+    PRInt32 rv;
+
+    rv = getpeername((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, (int*)len);
+    if (rv==0)
+        return PR_SUCCESS;
+    else {
+        _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+PRStatus
+_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen)
+{
+    PRInt32 rv;
+
+    rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, (int*)optlen);
+    if (rv==0)
+        return PR_SUCCESS;
+    else {
+        _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+PRStatus
+_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen)
+{
+    PRInt32 rv;
+
+    rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv==0)
+        return PR_SUCCESS;
+    else {
+        _PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+void
+_PR_MD_MAKE_NONBLOCK(PRFileDesc *f)
+{
+    return; // do nothing!
+}
+
+/*
+** Wait for I/O on a single descriptor.
+ *
+ * return 0, if timed-out, else return 1
+*/
+PRInt32
+_PR_WaitForFD(PRInt32 osfd, PRUintn how, PRIntervalTime timeout)
+{
+    _PRWin16PollDesc *pd;
+    PRPollQueue      *pq;
+    PRIntn is;
+    PRInt32 rv = 1;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD));
+
+    pd = &me->md.thr_pd;
+    pq = &me->md.thr_pq;
+    if (timeout == PR_INTERVAL_NO_WAIT) return 0;
+
+    pd->osfd = osfd;
+    pd->in_flags = how;
+    pd->out_flags = 0;
+
+    pq->pds = pd;
+    pq->npds = 1;
+
+    _PR_INTSOFF(is);
+    _PR_MD_IOQ_LOCK();
+    _PR_THREAD_LOCK(me);
+
+	if (_PR_PENDING_INTERRUPT(me)) {
+    	_PR_THREAD_UNLOCK(me);
+    	_PR_MD_IOQ_UNLOCK();
+		return 0;
+	}
+
+    pq->thr = me;
+    pq->on_ioq = PR_TRUE;
+    pq->timeout = timeout;
+    _PR_ADD_TO_IOQ((*pq), me->cpu);
+    if (how == PR_POLL_READ) {
+        FD_SET(osfd, &_PR_FD_READ_SET(me->cpu));
+        (_PR_FD_READ_CNT(me->cpu))[osfd]++;
+    } else if (how == PR_POLL_WRITE) {
+        FD_SET(osfd, &_PR_FD_WRITE_SET(me->cpu));
+        (_PR_FD_WRITE_CNT(me->cpu))[osfd]++;
+    } else {
+        FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+        (_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++;
+    }
+    if (_PR_IOQ_MAX_OSFD(me->cpu) < osfd)
+        _PR_IOQ_MAX_OSFD(me->cpu) = osfd;
+    if (_PR_IOQ_TIMEOUT(me->cpu) > timeout)
+        _PR_IOQ_TIMEOUT(me->cpu) = timeout;
+        
+    _PR_THREAD_LOCK(me);
+
+    _PR_SLEEPQ_LOCK(me->cpu);
+    _PR_ADD_SLEEPQ(me, timeout);
+    me->state = _PR_IO_WAIT;
+    me->io_pending = PR_TRUE;
+    me->io_suspended = PR_FALSE;
+    _PR_SLEEPQ_UNLOCK(me->cpu);
+    _PR_THREAD_UNLOCK(me);
+    _PR_MD_IOQ_UNLOCK();
+
+    _PR_MD_WAIT(me, timeout);
+    me->io_pending = PR_FALSE;
+    me->io_suspended = PR_FALSE;
+
+    /*
+    ** If we timed out the pollq might still be on the ioq. Remove it
+    ** before continuing.
+    */
+    if (pq->on_ioq) {
+        _PR_INTSOFF(is);
+        _PR_MD_IOQ_LOCK();
+    /*
+     * Need to check pq.on_ioq again
+     */
+        if (pq->on_ioq) {
+            PR_REMOVE_LINK(&pq->links);
+            if (how == PR_POLL_READ) {
+                if ((--(_PR_FD_READ_CNT(me->cpu))[osfd]) == 0)
+                    FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
+            
+            } else if (how == PR_POLL_WRITE) {
+                if ((--(_PR_FD_WRITE_CNT(me->cpu))[osfd]) == 0)
+                    FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
+            } else {
+                if ((--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]) == 0)
+                    FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+            }
+        }
+        _PR_MD_IOQ_UNLOCK();
+        rv = 0;
+    }
+    _PR_FAST_INTSON(is);
+   return(rv);
+}
+
+/*
+ * Unblock threads waiting for I/O
+ *    used when interrupting threads
+ *
+ * NOTE: The thread lock should held when this function is called.
+ * On return, the thread lock is released.
+ */
+void _PR_Unblock_IO_Wait(PRThread *thr)
+{
+    int pri = thr->priority;
+    _PRCPU *cpu = thr->cpu;
+ 
+    PR_ASSERT(thr->flags & (_PR_ON_SLEEPQ | _PR_ON_PAUSEQ));
+    _PR_SLEEPQ_LOCK(cpu);
+    _PR_DEL_SLEEPQ(thr, PR_TRUE);
+    _PR_SLEEPQ_UNLOCK(cpu);
+
+    PR_ASSERT(!(thr->flags & _PR_IDLE_THREAD));
+    thr->state = _PR_RUNNABLE;
+    _PR_RUNQ_LOCK(cpu);
+    _PR_ADD_RUNQ(thr, cpu, pri);
+    _PR_RUNQ_UNLOCK(cpu);
+    _PR_THREAD_UNLOCK(thr);
+    _PR_MD_WAKEUP_WAITER(thr);
+}
+
+/*
+** Scan through io queue and find any bad fd's that triggered the error
+** from _MD_SELECT
+*/
+static void FindBadFDs(void)
+{
+    PRCList *q;
+    PRThread *me = _MD_CURRENT_THREAD();
+    int sockOpt;
+    int sockOptLen = sizeof(sockOpt);
+
+    PR_ASSERT(!_PR_IS_NATIVE_THREAD(me));
+    q = (_PR_IOQ(me->cpu)).next;
+    _PR_IOQ_MAX_OSFD(me->cpu) = -1;
+    _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT;
+    while (q != &_PR_IOQ(me->cpu)) {
+        PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+        PRBool notify = PR_FALSE;
+        _PRWin16PollDesc *pds = pq->pds;
+        _PRWin16PollDesc *epds = pds + pq->npds;
+        PRInt32 pq_max_osfd = -1;
+
+        q = q->next;
+        for (; pds < epds; pds++) {
+            PRInt32 osfd = pds->osfd;
+            pds->out_flags = 0;
+            PR_ASSERT(osfd >= 0 || pds->in_flags == 0);
+            if (pds->in_flags == 0) {
+                continue;  /* skip this fd */
+            }
+            if ( getsockopt(osfd, 
+                    (int)SOL_SOCKET, 
+                    SO_TYPE, 
+                    (char*)&sockOpt, 
+                    &sockOptLen) == SOCKET_ERROR ) 
+            {
+                if ( WSAGetLastError() == WSAENOTSOCK )
+                {
+                    PR_LOG(_pr_io_lm, PR_LOG_MAX,
+                        ("file descriptor %d is bad", osfd));
+                    pds->out_flags = PR_POLL_NVAL;
+                    notify = PR_TRUE;
+                }
+            }
+            if (osfd > pq_max_osfd) {
+                pq_max_osfd = osfd;
+            }
+        }
+
+        if (notify) {
+            PRIntn pri;
+            PR_REMOVE_LINK(&pq->links);
+            pq->on_ioq = PR_FALSE;
+
+            /*
+         * Decrement the count of descriptors for each desciptor/event
+         * because this I/O request is being removed from the
+         * ioq
+         */
+            pds = pq->pds;
+            for (; pds < epds; pds++) {
+                PRInt32 osfd = pds->osfd;
+                PRInt16 in_flags = pds->in_flags;
+                PR_ASSERT(osfd >= 0 || in_flags == 0);
+                if (in_flags & PR_POLL_READ) {
+                    if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
+                }
+                if (in_flags & PR_POLL_WRITE) {
+                    if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
+                }
+                if (in_flags & PR_POLL_EXCEPT) {
+                    if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+                }
+            }
+
+            _PR_THREAD_LOCK(pq->thr);
+            if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
+                _PRCPU *cpu = pq->thr->cpu;
+                
+                _PR_SLEEPQ_LOCK(pq->thr->cpu);
+                _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);
+                _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
+
+                pri = pq->thr->priority;
+                pq->thr->state = _PR_RUNNABLE;
+
+                _PR_RUNQ_LOCK(cpu);
+                _PR_ADD_RUNQ(pq->thr, cpu, pri);
+                _PR_RUNQ_UNLOCK(cpu);
+            }
+            _PR_THREAD_UNLOCK(pq->thr);
+        } else {
+            if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))
+                _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;
+            if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)
+                _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;
+        }
+    }
+} /* end FindBadFDs() */
+
+/*
+** Called by the scheduler when there is nothing to do. This means that
+** all threads are blocked on some monitor somewhere.
+**
+** Pause the current CPU. longjmp to the cpu's pause stack
+*/
+PRInt32 _PR_MD_PAUSE_CPU( PRIntervalTime ticks)
+{
+    PRThread *me = _MD_CURRENT_THREAD();
+    struct timeval timeout, *tvp;
+    fd_set r, w, e;
+    fd_set *rp, *wp, *ep;
+    PRInt32 max_osfd, nfd;
+    PRInt32 rv;
+    PRCList *q;
+    PRUint32 min_timeout;
+
+    PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
+
+    /*
+     * assigment of fd_sets
+     */
+    r = _PR_FD_READ_SET(me->cpu);
+    w = _PR_FD_WRITE_SET(me->cpu);
+    e = _PR_FD_EXCEPTION_SET(me->cpu);
+
+    rp = &r;
+    wp = &w;
+    ep = &e;
+
+    max_osfd = _PR_IOQ_MAX_OSFD(me->cpu) + 1;
+    min_timeout = _PR_IOQ_TIMEOUT(me->cpu);
+    /*
+    ** Compute the minimum timeout value: make it the smaller of the
+    ** timeouts specified by the i/o pollers or the timeout of the first
+    ** sleeping thread.
+    */
+    q = _PR_SLEEPQ(me->cpu).next;
+
+    if (q != &_PR_SLEEPQ(me->cpu)) {
+        PRThread *t = _PR_THREAD_PTR(q);
+
+        if (t->sleep < min_timeout) {
+            min_timeout = t->sleep;
+        }
+    }
+    if (min_timeout > ticks) {
+        min_timeout = ticks;
+    }
+
+    if (min_timeout == PR_INTERVAL_NO_TIMEOUT) {
+        tvp = NULL;
+    } else {
+        timeout.tv_sec = PR_IntervalToSeconds(min_timeout);
+        timeout.tv_usec = PR_IntervalToMicroseconds(min_timeout)
+            % PR_USEC_PER_SEC;
+        tvp = &timeout;
+    }
+
+    _PR_MD_IOQ_UNLOCK();
+    _MD_CHECK_FOR_EXIT();
+    /*
+     * check for i/o operations
+     */
+
+    nfd = _MD_SELECT(max_osfd, rp, wp, ep, tvp);
+
+    _MD_CHECK_FOR_EXIT();
+    _PR_MD_IOQ_LOCK();
+    /*
+    ** Notify monitors that are associated with the selected descriptors.
+    */
+    if (nfd > 0) {
+        q = _PR_IOQ(me->cpu).next;
+        _PR_IOQ_MAX_OSFD(me->cpu) = -1;
+        _PR_IOQ_TIMEOUT(me->cpu) = PR_INTERVAL_NO_TIMEOUT;
+        while (q != &_PR_IOQ(me->cpu)) {
+            PRPollQueue *pq = _PR_POLLQUEUE_PTR(q);
+            PRBool notify = PR_FALSE;
+            _PRWin16PollDesc *pds = pq->pds;
+            _PRWin16PollDesc *epds = pds + pq->npds;
+            PRInt32 pq_max_osfd = -1;
+
+            q = q->next;
+            for (; pds < epds; pds++) {
+                PRInt32 osfd = pds->osfd;
+                PRInt16 in_flags = pds->in_flags;
+                PRInt16 out_flags = 0;
+                PR_ASSERT(osfd >= 0 || in_flags == 0);
+                if ((in_flags & PR_POLL_READ) && FD_ISSET(osfd, rp)) {
+                    out_flags |= PR_POLL_READ;
+                }
+                if ((in_flags & PR_POLL_WRITE) && FD_ISSET(osfd, wp)) {
+                    out_flags |= PR_POLL_WRITE;
+                }
+                if ((in_flags & PR_POLL_EXCEPT) && FD_ISSET(osfd, ep)) {
+                    out_flags |= PR_POLL_EXCEPT;
+                }
+                pds->out_flags = out_flags;
+                if (out_flags) {
+                    notify = PR_TRUE;
+                }
+                if (osfd > pq_max_osfd) {
+                    pq_max_osfd = osfd;
+                }
+            }
+            if (notify == PR_TRUE) {
+                PRIntn pri;
+                PRThread *thred;
+
+                PR_REMOVE_LINK(&pq->links);
+                pq->on_ioq = PR_FALSE;
+
+                /*
+                 * Decrement the count of descriptors for each desciptor/event
+                 * because this I/O request is being removed from the
+                 * ioq
+                 */
+                pds = pq->pds;
+                for (; pds < epds; pds++) {
+                    PRInt32 osfd = pds->osfd;
+                    PRInt16 in_flags = pds->in_flags;
+                    PR_ASSERT(osfd >= 0 || in_flags == 0);
+                    if (in_flags & PR_POLL_READ) {
+                        if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
+                            FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
+                    }
+                    if (in_flags & PR_POLL_WRITE) {
+                        if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
+                            FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
+                    }
+                    if (in_flags & PR_POLL_EXCEPT) {
+                        if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
+                            FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+                    }
+                }
+                 thred = pq->thr;
+                _PR_THREAD_LOCK(thred);
+                if (pq->thr->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
+                    _PRCPU *cpu = thred->cpu;
+                    _PR_SLEEPQ_LOCK(pq->thr->cpu);
+                    _PR_DEL_SLEEPQ(pq->thr, PR_TRUE);
+                    _PR_SLEEPQ_UNLOCK(pq->thr->cpu);
+
+                    pri = pq->thr->priority;
+                    pq->thr->state = _PR_RUNNABLE;
+
+                    pq->thr->cpu = cpu;
+                    _PR_RUNQ_LOCK(cpu);
+                    _PR_ADD_RUNQ(pq->thr, cpu, pri);
+                    _PR_RUNQ_UNLOCK(cpu);
+                    if (_pr_md_idle_cpus > 1)
+                        _PR_MD_WAKEUP_WAITER(thred);
+                }
+                _PR_THREAD_UNLOCK(thred);
+            } else {
+                if (pq->timeout < _PR_IOQ_TIMEOUT(me->cpu))
+                    _PR_IOQ_TIMEOUT(me->cpu) = pq->timeout;
+                if (_PR_IOQ_MAX_OSFD(me->cpu) < pq_max_osfd)
+                    _PR_IOQ_MAX_OSFD(me->cpu) = pq_max_osfd;
+            }
+        }
+    } else if (nfd < 0) {
+        if ( WSAGetLastError() == WSAENOTSOCK )
+        {
+            FindBadFDs();
+        } else {
+            PR_LOG(_pr_io_lm, PR_LOG_MAX, ("select() failed with errno %d",
+                errno));
+        }
+    }
+    _PR_MD_IOQ_UNLOCK();
+    return(0);
+    
+} /* end _PR_MD_PAUSE_CPU() */
+
+
+/*
+** _MD_pr_poll() -- Implement MD polling
+**
+** The function was snatched (re-used) from the unix implementation.
+** 
+** The native thread stuff was deleted.
+** The pollqueue is instantiated on the mdthread structure
+** to keep the stack frame from being corrupted when this
+** thread is waiting on the poll.
+**
+*/
+extern PRInt32 
+_MD_PR_POLL(PRPollDesc *pds, PRIntn npds,
+                        PRIntervalTime timeout)
+{
+    PRPollDesc *pd, *epd;
+    PRInt32 n, err, pdcnt;
+    PRIntn is;
+    _PRWin16PollDesc *spds, *spd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRPollQueue *pq;
+
+    pq = &me->md.thr_pq;
+    
+    /*
+     * XXX
+     *   PRPollDesc has a PRFileDesc field, fd, while the IOQ
+     *   is a list of PRPollQueue structures, each of which contains
+     *   a _PRWin16PollDesc. A _PRWin16PollDesc struct contains
+     *   the OS file descriptor, osfd, and not a PRFileDesc.
+     *   So, we have allocate memory for _PRWin16PollDesc structures,
+     *   copy the flags information from the pds list and have pq
+     *   point to this list of _PRWin16PollDesc structures.
+     *
+     *   It would be better if the memory allocation can be avoided.
+     */
+
+    spds = (_PRWin16PollDesc*) PR_MALLOC(npds * sizeof(_PRWin16PollDesc));
+    if (!spds) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+           return -1;
+    }
+    spd = spds;
+
+    _PR_INTSOFF(is);
+    _PR_MD_IOQ_LOCK();
+       _PR_THREAD_LOCK(me);
+
+    if (_PR_PENDING_INTERRUPT(me)) {
+        me->flags &= ~_PR_INTERRUPT;
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        _PR_THREAD_UNLOCK(me);
+        _PR_MD_IOQ_UNLOCK();
+        PR_DELETE(spds);
+           return -1;
+    }
+
+    pdcnt = 0;
+    for (pd = pds, epd = pd + npds; pd < epd; pd++) {
+        PRInt32 osfd;
+        PRInt16 in_flags = pd->in_flags;
+        PRFileDesc *bottom = pd->fd;
+
+        if ((NULL == bottom) || (in_flags == 0)) {
+            continue;
+        }
+        while (bottom->lower != NULL) {
+            bottom = bottom->lower;
+        }
+        osfd = bottom->secret->md.osfd;
+
+        PR_ASSERT(osfd >= 0 || in_flags == 0);
+
+        spd->osfd = osfd;
+        spd->in_flags = pd->in_flags;
+        spd++;
+        pdcnt++;
+
+        if (in_flags & PR_POLL_READ)  {
+            FD_SET(osfd, &_PR_FD_READ_SET(me->cpu));
+            _PR_FD_READ_CNT(me->cpu)[osfd]++;
+        }
+        if (in_flags & PR_POLL_WRITE) {
+            FD_SET(osfd, &_PR_FD_WRITE_SET(me->cpu));
+            (_PR_FD_WRITE_CNT(me->cpu))[osfd]++;
+        }
+        if (in_flags & PR_POLL_EXCEPT) {
+            FD_SET(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+            (_PR_FD_EXCEPTION_CNT(me->cpu))[osfd]++;
+        }
+        if (osfd > _PR_IOQ_MAX_OSFD(me->cpu))
+            _PR_IOQ_MAX_OSFD(me->cpu) = osfd;
+    }
+    if (timeout < _PR_IOQ_TIMEOUT(me->cpu))
+        _PR_IOQ_TIMEOUT(me->cpu) = timeout;
+
+
+    pq->pds = spds;
+    pq->npds = pdcnt;
+
+    pq->thr = me;
+    pq->on_ioq = PR_TRUE;
+    pq->timeout = timeout;
+    _PR_ADD_TO_IOQ((*pq), me->cpu);
+    _PR_SLEEPQ_LOCK(me->cpu);
+    _PR_ADD_SLEEPQ(me, timeout);
+    me->state = _PR_IO_WAIT;
+    me->io_pending = PR_TRUE;
+    me->io_suspended = PR_FALSE;
+    _PR_SLEEPQ_UNLOCK(me->cpu);
+    _PR_THREAD_UNLOCK(me);
+    _PR_MD_IOQ_UNLOCK();
+
+    _PR_MD_WAIT(me, timeout);
+
+    me->io_pending = PR_FALSE;
+    me->io_suspended = PR_FALSE;
+
+    /*
+     * Copy the out_flags from the _PRWin16PollDesc structures to the
+     * user's PRPollDesc structures and free the allocated memory
+     */
+    spd = spds;
+    for (pd = pds, epd = pd + npds; pd < epd; pd++) {
+        if ((NULL == pd->fd) || (pd->in_flags == 0)) {
+            pd->out_flags = 0;
+            continue;
+        }
+        pd->out_flags = spd->out_flags;
+        spd++;
+    }
+    PR_DELETE(spds);
+
+    /*
+    ** If we timed out the pollq might still be on the ioq. Remove it
+    ** before continuing.
+    */
+    if (pq->on_ioq) {
+        _PR_INTSOFF(is);
+        _PR_MD_IOQ_LOCK();
+        /*
+         * Need to check pq.on_ioq again
+         */
+        if (pq->on_ioq == PR_TRUE) {
+            PR_REMOVE_LINK(&pq->links);
+            for (pd = pds, epd = pd + npds; pd < epd; pd++) {
+                PRInt32 osfd;
+                PRInt16 in_flags = pd->in_flags;
+                PRFileDesc *bottom = pd->fd;
+
+                if ((NULL == bottom) || (in_flags == 0)) {
+                    continue;
+                }
+                while (bottom->lower != NULL) {
+                    bottom = bottom->lower;
+                }
+                osfd = bottom->secret->md.osfd;
+                PR_ASSERT(osfd >= 0 || in_flags == 0);
+                if (in_flags & PR_POLL_READ)  {
+                    if (--(_PR_FD_READ_CNT(me->cpu))[osfd] == 0)
+                        FD_CLR(osfd, &_PR_FD_READ_SET(me->cpu));
+                }
+                if (in_flags & PR_POLL_WRITE) {
+                    if (--(_PR_FD_WRITE_CNT(me->cpu))[osfd] == 0)
+                            FD_CLR(osfd, &_PR_FD_WRITE_SET(me->cpu));
+                }
+                if (in_flags & PR_POLL_EXCEPT) {
+                    if (--(_PR_FD_EXCEPTION_CNT(me->cpu))[osfd] == 0)
+                            FD_CLR(osfd, &_PR_FD_EXCEPTION_SET(me->cpu));
+                }
+            }
+        }
+        _PR_MD_IOQ_UNLOCK();
+        _PR_INTSON(is);
+    }
+    if (_PR_PENDING_INTERRUPT(me)) {
+        me->flags &= ~_PR_INTERRUPT;
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+           return -1;
+    } else {
+        n = 0;
+        if (pq->on_ioq == PR_FALSE) {
+            /* Count the number of ready descriptors */
+            while (--npds >= 0) {
+            if (pds->out_flags) {
+                n++;
+            }
+                pds++;
+            }
+        }
+        return n;
+    }
+} /* end _MD_pr_poll() */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16stdio.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16stdio.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,169 @@
+/* -*- 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 ***** */
+ 
+/*
+** w16stdio.c -- Callback functions for Win16 stdio read/write.
+**
+**
+*/
+#include "primpl.h"
+
+/*
+** _PL_MDStdioWrite() -- Win16 hackery to get console output
+**
+** Returns: number of bytes written.
+**
+*/
+PRInt32
+_PL_W16StdioWrite( void *buf, PRInt32 amount )
+{
+    int   rc;
+    
+    rc = fputs( buf, stdout );
+    if ( rc == EOF )
+    {
+        // something about errno
+        return(PR_FAILURE);
+    }
+    return( strlen(buf));
+} /* end _PL_fputs() */
+
+/*
+** _PL_W16StdioRead() -- Win16 hackery to get console input
+**
+*/
+PRInt32
+_PL_W16StdioRead( void *buf, PRInt32 amount )
+{
+    char *bp;
+
+    bp = fgets( buf, (int) amount, stdin );
+    if ( bp == NULL )
+    {
+        // something about errno
+        return(PR_FAILURE);
+    }
+    
+    return( strlen(buf));
+} /* end _PL_fgets() */
+/* --- end w16stdio.c --- */
+
+/*
+** Wrappers, linked into the client, that call
+** functions in LibC
+**
+*/
+
+/*
+** _PL_W16CallBackPuts() -- Wrapper for puts()
+**
+*/
+int PR_CALLBACK _PL_W16CallBackPuts( const char *outputString )
+{
+    return( puts( outputString ));
+} /* end _PL_W16CallBackPuts()  */    
+
+/*
+** _PL_W16CallBackStrftime() -- Wrapper for strftime()
+**
+*/
+size_t PR_CALLBACK _PL_W16CallBackStrftime( 
+    char *s, 
+    size_t len, 
+    const char *fmt,
+    const struct tm *p )
+{
+    return( strftime( s, len, fmt, p ));
+} /* end _PL_W16CallBackStrftime()  */    
+
+/*
+** _PL_W16CallBackMalloc() -- Wrapper for malloc()
+**
+*/
+void * PR_CALLBACK _PL_W16CallBackMalloc( size_t size )
+{
+    return( malloc( size ));
+} /* end _PL_W16CallBackMalloc()  */    
+
+/*
+** _PL_W16CallBackCalloc() -- Wrapper for calloc()
+**
+*/
+void * PR_CALLBACK _PL_W16CallBackCalloc( size_t n, size_t size )
+{
+    return( calloc( n, size ));
+} /* end _PL_W16CallBackCalloc()  */    
+
+/*
+** _PL_W16CallBackRealloc() -- Wrapper for realloc()
+**
+*/
+void * PR_CALLBACK _PL_W16CallBackRealloc( 
+    void *old_blk, 
+    size_t size )
+{
+    return( realloc( old_blk, size ));
+} /* end _PL_W16CallBackRealloc()  */
+
+/*
+** _PL_W16CallBackFree() -- Wrapper for free()
+**
+*/
+void PR_CALLBACK _PL_W16CallBackFree( void *ptr )
+{
+    free( ptr );
+    return;
+} /* end _PL_W16CallBackFree()  */
+
+/*
+** _PL_W16CallBackGetenv() -- Wrapper for getenv()
+**
+*/
+void * PR_CALLBACK _PL_W16CallBackGetenv( const char *name )
+{
+    return( getenv( name ));
+} /* end _PL_W16CallBackGetenv  */
+
+
+/*
+** _PL_W16CallBackPutenv() -- Wrapper for putenv()
+**
+*/
+int PR_CALLBACK _PL_W16CallBackPutenv( const char *assoc )
+{
+    return( putenv( assoc ));
+} /* end _PL_W16CallBackGetenv  */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16thred.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w16thred.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,426 @@
+/* -*- 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 <sys/timeb.h>
+#include <stdio.h>
+
+/*
+** DispatchTrace -- define a thread dispatch trace entry
+**
+** The DispatchTrace oject(s) are instantiated in a single
+** array. Think of the array as a push-down stack; entry
+** zero is the most recent, entry one the next most recent, etc.
+** For each time PR_MD_RESTORE_CONTEXT() is called, the array
+** is Pushed down and entry zero is overwritten with data
+** for the newly dispatched thread.
+**
+** Function TraceDispatch() manages the DispatchTrace array.
+**
+*/
+typedef struct DispatchTrace
+{
+    PRThread *          thread;
+    PRUint32            state;
+    PRInt16             mdThreadNumber;
+    PRInt16             unused;
+    PRThreadPriority    priority;
+    
+} DispatchTrace, *DispatchTracePtr ;
+
+static void TraceDispatch( PRThread *thread );
+
+
+PRThread                *_pr_primordialThread;
+
+/*
+** Note: the static variables must be on the data-segment because
+** the stack is destroyed during shadow-stack copy operations.
+**
+*/
+static char * pSource;          /* ptr to sourc of a "shadow-stack" copy */
+static char * pTarget;          /* ptr to target of a "shadow-stack" copy */
+static int   cxByteCount;       /* number of bytes for "shadow-stack" copy */
+static int   bytesMoved;        /* instrumentation: WRT "shadow-stack" copy */
+static FILE *    file1 = 0;     /* instrumentation: WRT debug */
+
+#define NUM_DISPATCHTRACE_OBJECTS  24
+static DispatchTrace dt[NUM_DISPATCHTRACE_OBJECTS] = {0}; /* instrumentation: WRT dispatch */
+static PRUint32 dispatchCount = 0;  /* instrumentation: number of thread dispatches */
+
+static int OldPriorityOfPrimaryThread   = -1;
+static int TimeSlicesOnNonPrimaryThread =  0;
+static PRUint32 threadNumber = 1;   /* Instrumentation: monotonically increasing number */
+
+
+
+/*
+** _PR_MD_FINAL_INIT() -- Final MD Initialization
+**
+** Poultry Problems! ... The stack, as allocated by PR_NewStack()
+** is called from here, late in initialization, because PR_NewStack()
+** requires lots of things working. When some elements of the
+** primordial thread are created, early in initialization, the
+** shadow stack is not one of these things. The "shadow stack" is
+** created here, late in initiailization using PR_NewStack(), to
+** ensure consistency in creation of the related objects.
+** 
+** A new ThreadStack, and all its affiliated structures, is allocated
+** via the call to PR_NewStack(). The PRThread structure in the
+** new stack is ignored; the old PRThread structure is used (why?).
+** The old PRThreadStack structure is abandoned.
+**
+*/
+void
+_PR_MD_FINAL_INIT()
+{
+    PRThreadStack *     stack = 0;
+    PRInt32             stacksize = 0;
+    PRThread *          me = _PR_MD_CURRENT_THREAD();
+    
+    _PR_ADJUST_STACKSIZE( stacksize );
+    stack = _PR_NewStack( stacksize );
+    
+    me->stack = stack;
+    stack->thr = me;
+    
+    return;
+} /* --- end _PR_MD_FINAL_INIT() --- */
+
+
+void
+_MD_INIT_RUNNING_CPU( struct _PRCPU *cpu )
+{
+	PR_INIT_CLIST(&(cpu->md.ioQ));
+	cpu->md.ioq_max_osfd = -1;
+	cpu->md.ioq_timeout = PR_INTERVAL_NO_TIMEOUT;
+}    
+
+
+void
+_PR_MD_YIELD( void )
+{
+    PR_ASSERT(0);
+}
+
+/*
+** _PR_MD_INIT_STACK() -- Win16 specific Stack initialization.
+**
+**
+*/
+
+void
+_PR_MD_INIT_STACK( PRThreadStack *ts, PRIntn redzone )
+{
+    ts->md.stackTop = ts->stackTop - sizeof(PRThread);
+    ts->md.cxByteCount = 0;
+    
+    return;
+} /* --- end _PR_MD_INIT_STACK() --- */
+
+/*
+**  _PR_MD_INIT_THREAD() -- Win16 specific Thread initialization.
+**
+*/
+PRStatus
+_PR_MD_INIT_THREAD(PRThread *thread)
+{
+    if ( thread->flags & _PR_PRIMORDIAL)
+    {
+        _pr_primordialThread = thread;
+        thread->md.threadNumber = 1;
+    }
+    else
+    {
+        thread->md.threadNumber = ++threadNumber;
+    }
+
+    thread->md.magic = _MD_MAGIC_THREAD;
+    strcpy( thread->md.guardBand, "GuardBand" );
+    
+    return PR_SUCCESS;
+}
+
+
+PRStatus
+_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    _MD_SWITCH_CONTEXT( thread );
+    
+    return( PR_SUCCESS );
+}
+
+void *PR_W16GetExceptionContext(void)
+{
+    return _MD_CURRENT_THREAD()->md.exceptionContext;
+}
+
+void
+PR_W16SetExceptionContext(void *context)
+{
+    _MD_CURRENT_THREAD()->md.exceptionContext = context;
+}
+
+
+
+
+/*
+** _MD_RESTORE_CONTEXT() -- Resume execution of thread 't'.
+**
+** Win16 threading is based on the NSPR 2.0 general model of
+** user threads. It differs from the general model in that a 
+** single "real" stack segment is used for execution of all 
+** threads. The context of the suspended threads is preserved
+** in the md.context [and related members] of the PRThread 
+** structure. The stack context of the suspended thread is
+** preserved in a "shadow stack" object.
+**
+** _MD_RESTORE_CONTEXT() implements most of the thread switching
+** for NSPR's implementation of Win16 theads.
+**
+** Operations Notes:
+**
+** Function PR_NewStack() in prustack.c allocates a new
+** PRThreadStack, PRStack, PRSegment, and a "shadow" stack
+** for a thread. These structures are wired together to
+** form the basis of Win16 threads. The thread and shadow
+** stack structures are created as part of PR_CreateThread().
+** 
+** Note! Some special "magic" is applied to the "primordial"
+** thread. The physical layout of the PRThread, PRThreadStack,
+** shadow stack, ... is somewhat different. Watch yourself when
+** mucking around with it. ... See _PR_MD_FINAL_INIT() for most
+** of the special treatment of the primordial thread.
+**
+** Function _PR_MD_INIT_STACK() initializes the value of
+** PRThreadStack member md.cxByteCount to zero; there
+** is no context to be restored for a thread's initial
+** dispatch. The value of member md.stackTop is set to
+** point to the highest usable address on the shadow stack.
+** This point corresponds to _pr_top_of_task_stack on the
+** system's operating stack.
+**
+** _pr_top_of_task_stack points to a place on the system stack
+** considered to be "close to the top". Stack context is preserved
+** relative to this point.
+**
+** Reminder: In x86 architecture, the stack grows "down".
+** That is: the stack pointer (SP register) is decremented
+** to push objects onto the stack or when a call is made.
+** 
+** Function _PR_MD_WAIT() invokes macro _MD_SWITCH_CONTEXT();
+** this causes the hardware registers to be preserved in a
+** CATCHBUF structure using function Catch() [see _win16.h], 
+** then calls PR_Schedule() to select a new thread for dispatch. 
+** PR_Schedule() calls _MD_RESTORE_CONTEXT() to cause the thread 
+** being suspended's stack to be preserved, to restore the 
+** stack of the to-be-dispactched thread, and to restore the 
+** to-be-dispactched thread's hardware registers.
+**
+** At the moment _PR_MD_RESTORE_CONTEXT() is called, the stack
+** pointer (SP) is less than the reference pointer
+** _pr_top_of_task_stack. The distance difference between the SP and
+** _pr_top_of_task_stack is the amount of stack that must be preserved.
+** This value, cxByteCount, is calculated then preserved in the
+** PRThreadStack.md.cxByteCount for later use (size of stack
+** context to restore) when this thread is dispatched again.
+** 
+** A C language for() loop is used to copy, byte-by-byte, the
+** stack data being preserved starting at the "address of t"
+** [Note: 't' is the argument passed to _PR_MD_RESTORE_CONTEXT()]
+** for the length of cxByteCount.
+**
+** variables pSource and pTarget are the calculated source and
+** destination pointers for the stack copy operation. These
+** variables are static scope because they cannot be instantiated
+** on the stack itself, since the stack is clobbered by restoring
+** the to-be-dispatched thread's stack context.
+**
+** After preserving the suspended thread's stack and architectural
+** context, the to-be-dispatched thread's stack context is copied
+** from its shadow stack to the system operational stack. The copy
+** is done in a small fragment of in-line assembly language. Note:
+** In NSPR 1.0, a while() loop was used to do the copy; when compiled
+** with the MS C 1.52c compiler, the short while loop used no
+** stack variables. The Watcom compiler, specified for use on NSPR 2.0,
+** uses stack variables to implement the same while loop. This is
+** a no-no! The copy operation clobbers these variables making the
+** results of the copy ... unpredictable ... So, a short piece of
+** inline assembly language is used to effect the copy.
+**
+** Following the restoration of the to-be-dispatched thread's
+** stack context, another short inline piece of assemble language
+** is used to set the SP register to correspond to what it was
+** when the to-be-dispatched thread was suspended. This value
+** uses the thread's stack->md.cxByteCount as a negative offset 
+** from _pr_top_of_task_stack as the new value of SP.
+**
+** Finally, Function Throw() is called to restore the architectural
+** context of the to-be-dispatched thread.
+**
+** At this point, the newly dispatched thread appears to resume
+** execution following the _PR_MD_SWITCH_CONTEXT() macro.
+**
+** OK, this ain't rocket-science, but it can confuse you easily.
+** If you have to work on this stuff, please take the time to
+** draw, on paper, the structures (PRThread, PRThreadStack,
+** PRSegment, the "shadow stack", the system stack and the related
+** global variables). Hand step it thru the debugger to make sure
+** you understand it very well before making any changes. ...
+** YMMV.
+** 
+*/
+void _MD_RESTORE_CONTEXT(PRThread *t)
+{
+    dispatchCount++;
+    TraceDispatch( t );
+    /*	
+    **	This is a good opportunity to make sure that the main
+    **	mozilla thread actually gets some time.  If interrupts
+    **	are on, then we know it is safe to check if the main
+    **	thread is being starved.  If moz has not been scheduled
+    **	for a long time, then then temporarily bump the fe priority 
+    **	up so that it gets to run at least one. 
+    */	
+// #if 0 // lth. condition off for debug.
+    if (_pr_primordialThread == t) {
+        if (OldPriorityOfPrimaryThread != -1) {
+            PR_SetThreadPriority(_pr_primordialThread, OldPriorityOfPrimaryThread);
+            OldPriorityOfPrimaryThread = -1;
+        }
+        TimeSlicesOnNonPrimaryThread = 0;
+    } else {
+        TimeSlicesOnNonPrimaryThread++;
+    }
+
+    if ((TimeSlicesOnNonPrimaryThread >= 20) && (OldPriorityOfPrimaryThread == -1)) {
+        OldPriorityOfPrimaryThread = PR_GetThreadPriority(_pr_primordialThread);
+        PR_SetThreadPriority(_pr_primordialThread, 31);
+        TimeSlicesOnNonPrimaryThread = 0;
+    }
+// #endif
+    /*
+    ** Save the Task Stack into the "shadow stack" of the current thread
+    */
+    cxByteCount  = (int) ((PRUint32) _pr_top_of_task_stack - (PRUint32) &t );
+    pSource      = (char *) &t;
+    pTarget      = (char *)((PRUint32)_pr_currentThread->stack->md.stackTop 
+                            - (PRUint32)cxByteCount );
+    _pr_currentThread->stack->md.cxByteCount = cxByteCount;
+    
+    for( bytesMoved = 0; bytesMoved < cxByteCount; bytesMoved++ )
+        *(pTarget + bytesMoved ) = *(pSource + bytesMoved );
+    
+    /* Mark the new thread as the current thread */
+    _pr_currentThread = t;
+
+    /*
+    ** Now copy the "shadow stack" of the new thread into the Task Stack
+    **
+    ** REMEMBER:
+    **    After the stack has been copied, ALL local variables in this function
+    **    are invalid !!
+    */
+    cxByteCount  = t->stack->md.cxByteCount;
+    pSource      = t->stack->md.stackTop - cxByteCount;
+    pTarget      = _pr_top_of_task_stack - cxByteCount;
+    
+    errno = (_pr_currentThread)->md.errcode;
+    
+    __asm 
+    {
+        mov cx, cxByteCount
+        mov si, WORD PTR [pSource]
+        mov di, WORD PTR [pTarget]
+        mov ax, WORD PTR [pTarget + 2]
+        mov es, ax
+        mov ax, WORD PTR [pSource + 2]
+        mov bx, ds
+        mov ds, ax
+        rep movsb
+        mov ds, bx
+    }
+
+    /* 
+    ** IMPORTANT:
+    ** ----------
+    ** SS:SP is now invalid :-( This means that all local variables and
+    ** function arguments are invalid and NO function calls can be
+    ** made !!! We must fix up SS:SP so that function calls can safely
+    ** be made...
+    */
+
+    __asm {
+        mov     ax, WORD PTR [_pr_top_of_task_stack]
+        sub     ax, cxByteCount
+        mov     sp, ax
+    };
+
+    /*
+    ** Resume execution of thread: t by restoring the thread's context.
+    **
+    */
+    Throw((_pr_currentThread)->md.context, 1);
+} /* --- end MD_RESTORE_CONTEXT() --- */
+
+
+static void TraceDispatch( PRThread *thread )
+{
+    int i;
+    
+    /*
+    ** push all DispatchTrace objects to down one slot.
+    ** Note: the last entry is lost; last-1 becomes last, etc.
+    */
+    for( i = NUM_DISPATCHTRACE_OBJECTS -2; i >= 0; i-- )
+    {
+        dt[i +1] = dt[i];
+    }
+    
+    /*
+    ** Build dt[0] from t
+    */
+    dt->thread = thread;
+    dt->state = thread->state;
+    dt->mdThreadNumber = thread->md.threadNumber;
+    dt->priority = thread->priority;
+    
+    return;
+} /* --- end TraceDispatch() --- */
+
+
+/* $$ end W16thred.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32ipcsem.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32ipcsem.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,227 @@
+/* -*- 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 ***** */
+
+/*
+ * File: w32ipcsem.c
+ * Description: implements named semaphores for NT and WIN95.
+ */
+
+#include "primpl.h"
+
+/*
+ * NSPR-to-NT access right mapping table for semaphore objects.
+ *
+ * The SYNCHRONIZE access is required by WaitForSingleObject.
+ * The SEMAPHORE_MODIFY_STATE access is required by ReleaseSemaphore.
+ * The OR of these three access masks must equal SEMAPHORE_ALL_ACCESS.
+ * This is because if a semaphore object with the specified name
+ * exists, CreateSemaphore requests SEMAPHORE_ALL_ACCESS access to
+ * the existing object.
+ */
+static DWORD semAccessTable[] = {
+    STANDARD_RIGHTS_REQUIRED|0x1, /* read (0x1 is "query state") */
+    STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, /* write */
+    0 /* execute */
+};
+
+#ifndef _PR_GLOBAL_THREADS_ONLY
+
+/*
+ * A fiber cannot call WaitForSingleObject because that
+ * will block the other fibers running on the same thread.
+ * If a fiber needs to wait on a (semaphore) handle, we
+ * create a native thread to call WaitForSingleObject and
+ * have the fiber join the native thread.
+ */
+
+/*
+ * Arguments, return value, and error code for WaitForSingleObject
+ */
+struct WaitSingleArg {
+    HANDLE handle;
+    DWORD timeout;
+    DWORD rv;
+    DWORD error;
+};
+
+static void WaitSingleThread(void *arg)
+{
+    struct WaitSingleArg *warg = (struct WaitSingleArg *) arg;
+
+    warg->rv = WaitForSingleObject(warg->handle, warg->timeout);
+    if (warg->rv == WAIT_FAILED) {
+        warg->error = GetLastError();
+    }
+}
+
+static DWORD FiberSafeWaitForSingleObject(
+    HANDLE hHandle,
+    DWORD dwMilliseconds
+)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (_PR_IS_NATIVE_THREAD(me)) {
+        return WaitForSingleObject(hHandle, dwMilliseconds);
+    } else {
+        PRThread *waitThread;
+        struct WaitSingleArg warg;
+        PRStatus rv;
+
+        warg.handle = hHandle;
+        warg.timeout = dwMilliseconds;
+        waitThread = PR_CreateThread(
+            PR_USER_THREAD, WaitSingleThread, &warg,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (waitThread == NULL) {
+            return WAIT_FAILED;
+        }
+
+        rv = PR_JoinThread(waitThread);
+        PR_ASSERT(rv == PR_SUCCESS);
+        if (rv == PR_FAILURE) {
+            return WAIT_FAILED;
+        }
+        if (warg.rv == WAIT_FAILED) {
+            SetLastError(warg.error);
+        }
+        return warg.rv;
+    }
+}
+
+#endif /* !_PR_GLOBAL_THREADS_ONLY */
+
+PRSem *_PR_MD_OPEN_SEMAPHORE(
+    const char *osname, PRIntn flags, PRIntn mode, PRUintn value)
+{
+    PRSem *sem;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    sem = PR_NEW(PRSem);
+    if (sem == NULL) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    if (flags & PR_SEM_CREATE) {
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, semAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
+        sem->sem = CreateSemaphore(lpSA, value, 0x7fffffff, osname);
+        if (lpSA != NULL) {
+            _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+        }
+        if (sem->sem == NULL) {
+            _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+            PR_DELETE(sem);
+            return NULL;
+        }
+        if ((flags & PR_SEM_EXCL) && (GetLastError() == ERROR_ALREADY_EXISTS)) {
+            PR_SetError(PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS);
+            CloseHandle(sem->sem);
+            PR_DELETE(sem);
+            return NULL;
+        }
+    } else {
+        sem->sem = OpenSemaphore(
+                SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, FALSE, osname);
+        if (sem->sem == NULL) {
+            DWORD err = GetLastError();
+
+            /*
+             * If we open a nonexistent named semaphore, NT
+             * returns ERROR_FILE_NOT_FOUND, while Win95
+             * returns ERROR_INVALID_NAME
+             */
+            if (err == ERROR_INVALID_NAME) {
+                PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
+            } else {
+                _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+            }
+            PR_DELETE(sem);
+            return NULL;
+        }
+    }
+    return sem;
+}
+
+PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem)
+{
+    DWORD rv;
+
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    rv = WaitForSingleObject(sem->sem, INFINITE);
+#else
+    rv = FiberSafeWaitForSingleObject(sem->sem, INFINITE);
+#endif
+    PR_ASSERT(rv == WAIT_FAILED || rv == WAIT_OBJECT_0);
+    if (rv == WAIT_FAILED) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    if (rv != WAIT_OBJECT_0) {
+        /* Should not happen */
+        PR_SetError(PR_UNKNOWN_ERROR, 0);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem)
+{
+    if (ReleaseSemaphore(sem->sem, 1, NULL) == FALSE) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem)
+{
+    if (CloseHandle(sem->sem) == FALSE) {
+        _PR_MD_MAP_CLOSE_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    PR_DELETE(sem);
+    return PR_SUCCESS;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32poll.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32poll.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+ * This file implements _PR_MD_PR_POLL for Win32.
+ */
+
+/* The default value of FD_SETSIZE is 64. */
+#define FD_SETSIZE 1024
+
+#include "primpl.h"
+
+#if !defined(_PR_GLOBAL_THREADS_ONLY)
+
+struct select_data_s {
+    PRInt32 status;
+    PRInt32 error;
+    fd_set *rd, *wt, *ex;
+    const struct timeval *tv;
+};
+
+static void
+_PR_MD_select_thread(void *cdata)
+{
+    struct select_data_s *cd = (struct select_data_s *)cdata;
+
+    cd->status = select(0, cd->rd, cd->wt, cd->ex, cd->tv);
+
+    if (cd->status == SOCKET_ERROR) {
+        cd->error = WSAGetLastError();
+    }
+}
+
+int _PR_NTFiberSafeSelect(
+    int nfds,
+    fd_set *readfds,
+    fd_set *writefds,
+    fd_set *exceptfds,
+    const struct timeval *timeout)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    int ready;
+
+    if (_PR_IS_NATIVE_THREAD(me)) {
+        ready = _MD_SELECT(nfds, readfds, writefds, exceptfds, timeout);
+    }
+    else
+    {
+        /*
+        ** Creating a new thread on each call!!
+        ** I guess web server doesn't use non-block I/O.
+        */
+        PRThread *selectThread;
+        struct select_data_s data;
+        data.status = 0;
+        data.error = 0;
+        data.rd = readfds;
+        data.wt = writefds;
+        data.ex = exceptfds;
+        data.tv = timeout;
+
+        selectThread = PR_CreateThread(
+            PR_USER_THREAD, _PR_MD_select_thread, &data,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (selectThread == NULL) return -1;
+
+        PR_JoinThread(selectThread);
+        ready = data.status;
+        if (ready == SOCKET_ERROR) WSASetLastError(data.error);
+    }
+    return ready;
+}
+
+#endif /* !defined(_PR_GLOBAL_THREADS_ONLY) */
+
+PRInt32 _PR_MD_PR_POLL(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    int ready, err;
+    fd_set rd, wt, ex;
+    fd_set *rdp, *wtp, *exp;
+    int nrd, nwt, nex;
+    PRFileDesc *bottom;
+    PRPollDesc *pd, *epd;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    struct timeval tv, *tvp = NULL;
+
+    if (_PR_PENDING_INTERRUPT(me))
+    {
+        me->flags &= ~_PR_INTERRUPT;
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        return -1;
+    }
+
+    /*
+    ** Is it an empty set? If so, just sleep for the timeout and return
+    */
+    if (0 == npds)
+    {
+        PR_Sleep(timeout);
+        return 0;
+    }
+
+    nrd = nwt = nex = 0;
+    FD_ZERO(&rd);
+    FD_ZERO(&wt);
+    FD_ZERO(&ex);
+
+    ready = 0;
+    for (pd = pds, epd = pd + npds; pd < epd; pd++)
+    {
+        SOCKET osfd;
+        PRInt16 in_flags_read = 0, in_flags_write = 0;
+        PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+        if ((NULL != pd->fd) && (0 != pd->in_flags))
+        {
+            if (pd->in_flags & PR_POLL_READ)
+            {
+                in_flags_read = (pd->fd->methods->poll)(
+                    pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_WRITE),
+                    &out_flags_read);
+            }
+            if (pd->in_flags & PR_POLL_WRITE)
+            {
+                in_flags_write = (pd->fd->methods->poll)(
+                    pd->fd, (PRInt16)(pd->in_flags & ~PR_POLL_READ),
+                    &out_flags_write);
+            }
+            if ((0 != (in_flags_read & out_flags_read))
+            || (0 != (in_flags_write & out_flags_write)))
+            {
+                /* this one's ready right now (buffered input) */
+                if (0 == ready)
+                {
+                    /*
+                     * We will have to return without calling the
+                     * system poll/select function.  So zero the
+                     * out_flags fields of all the poll descriptors
+                     * before this one.
+                     */
+                    PRPollDesc *prev;
+                    for (prev = pds; prev < pd; prev++)
+                    {
+                        prev->out_flags = 0;
+                    }
+                }
+                ready += 1;
+                pd->out_flags = out_flags_read | out_flags_write;
+            }
+            else
+            {
+                pd->out_flags = 0;  /* pre-condition */
+                /* make sure this is an NSPR supported stack */
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                if ((NULL != bottom)
+                && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                {
+                    if (0 == ready)
+                    {
+                        osfd = (SOCKET) bottom->secret->md.osfd;
+                        if (in_flags_read & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_READ;
+                            FD_SET(osfd, &rd);
+                            nrd++;
+                        }
+                        if (in_flags_read & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;
+                            FD_SET(osfd, &wt);
+                            nwt++;
+                        }
+                        if (in_flags_write & PR_POLL_READ)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;
+                            FD_SET(osfd, &rd);
+                            nrd++;
+                        }
+                        if (in_flags_write & PR_POLL_WRITE)
+                        {
+                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;
+                            FD_SET(osfd, &wt);
+                            nwt++;
+                        }
+                        if (pd->in_flags & PR_POLL_EXCEPT) {
+                            FD_SET(osfd, &ex);
+                            nex++;
+                        }
+                    }
+                }
+                else
+                {
+                    if (0 == ready)
+                    {
+                        PRPollDesc *prev;
+                        for (prev = pds; prev < pd; prev++)
+                        {
+                            prev->out_flags = 0;
+                        }
+                    }
+                    ready += 1;  /* this will cause an abrupt return */
+                    pd->out_flags = PR_POLL_NVAL;  /* bogii */
+                }
+            }
+        }
+        else
+        {
+            pd->out_flags = 0;
+        }
+    }
+
+    if (0 != ready) return ready;  /* no need to block */
+
+    if ((nrd > FD_SETSIZE) || (nwt > FD_SETSIZE) || (nex > FD_SETSIZE)) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+
+    rdp = (0 == nrd) ? NULL : &rd;
+    wtp = (0 == nwt) ? NULL : &wt;
+    exp = (0 == nex) ? NULL : &ex;
+
+    if ((NULL == rdp) && (NULL == wtp) && (NULL == exp)) {
+        PR_Sleep(timeout);
+        return 0;
+    }
+
+    if (timeout != PR_INTERVAL_NO_TIMEOUT)
+    {
+        PRInt32 ticksPerSecond = PR_TicksPerSecond();
+        tv.tv_sec = timeout / ticksPerSecond;
+        tv.tv_usec = PR_IntervalToMicroseconds( timeout % ticksPerSecond );
+        tvp = &tv;
+    }
+
+#if defined(_PR_GLOBAL_THREADS_ONLY)
+    ready = _MD_SELECT(0, rdp, wtp, exp, tvp);
+#else
+    ready = _PR_NTFiberSafeSelect(0, rdp, wtp, exp, tvp);
+#endif
+
+    /*
+    ** Now to unravel the select sets back into the client's poll
+    ** descriptor list. Is this possibly an area for pissing away
+    ** a few cycles or what?
+    */
+    if (ready > 0)
+    {
+        ready = 0;
+        for (pd = pds, epd = pd + npds; pd < epd; pd++)
+        {
+            PRInt16 out_flags = 0;
+            if ((NULL != pd->fd) && (0 != pd->in_flags))
+            {
+                SOCKET osfd;
+                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                PR_ASSERT(NULL != bottom);
+
+                osfd = (SOCKET) bottom->secret->md.osfd;
+
+                if (FD_ISSET(osfd, &rd))
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+                if (FD_ISSET(osfd, &wt))
+                {
+                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)
+                        out_flags |= PR_POLL_READ;
+                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)
+                        out_flags |= PR_POLL_WRITE;
+                } 
+                if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;
+            }
+            pd->out_flags = out_flags;
+            if (out_flags) ready++;
+        }
+        PR_ASSERT(ready > 0);
+    }
+    else if (ready == SOCKET_ERROR)
+    {
+        err = WSAGetLastError();
+        if (err == WSAENOTSOCK)
+        {
+            /* Find the bad fds */
+            int optval;
+            int optlen = sizeof(optval);
+            ready = 0;
+            for (pd = pds, epd = pd + npds; pd < epd; pd++)
+            {
+                pd->out_flags = 0;
+                if ((NULL != pd->fd) && (0 != pd->in_flags))
+                {
+                    bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+                    if (getsockopt(bottom->secret->md.osfd, SOL_SOCKET,
+                        SO_TYPE, (char *) &optval, &optlen) == -1)
+                    {
+                        PR_ASSERT(WSAGetLastError() == WSAENOTSOCK);
+                        if (WSAGetLastError() == WSAENOTSOCK)
+                        {
+                            pd->out_flags = PR_POLL_NVAL;
+                            ready++;
+                        }
+                    }
+                }
+            }
+            PR_ASSERT(ready > 0);
+        }
+        else _PR_MD_MAP_SELECT_ERROR(err);
+    }
+
+    return ready;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32rng.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32rng.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,107 @@
+/* -*- 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 <windows.h>
+#include <time.h>
+#include <io.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <primpl.h>
+
+static BOOL
+CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow)
+{
+    LARGE_INTEGER   liCount;
+
+    if (!QueryPerformanceCounter(&liCount))
+        return FALSE;
+
+    *lpdwHigh = liCount.u.HighPart;
+    *lpdwLow = liCount.u.LowPart;
+    return TRUE;
+}
+
+extern PRSize _PR_MD_GetRandomNoise( void *buf, PRSize size )
+{
+    DWORD   dwHigh, dwLow, dwVal;
+    size_t  n = 0;
+    size_t  nBytes;
+    time_t  sTime;
+
+    if (size <= 0)
+        return 0;
+
+    CurrentClockTickTime(&dwHigh, &dwLow);
+
+    // get the maximally changing bits first
+    nBytes = sizeof(dwLow) > size ? size : sizeof(dwLow);
+    memcpy((char *)buf, &dwLow, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+        return n;
+
+    nBytes = sizeof(dwHigh) > size ? size : sizeof(dwHigh);
+    memcpy(((char *)buf) + n, &dwHigh, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+        return n;
+
+    // get the number of milliseconds that have elapsed since Windows started
+    dwVal = GetTickCount();
+
+    nBytes = sizeof(dwVal) > size ? size : sizeof(dwVal);
+    memcpy(((char *)buf) + n, &dwVal, nBytes);
+    n += nBytes;
+    size -= nBytes;
+
+    if (size <= 0)
+        return n;
+
+    // get the time in seconds since midnight Jan 1, 1970
+    time(&sTime);
+    nBytes = sizeof(sTime) > size ? size : sizeof(sTime);
+    memcpy(((char *)buf) + n, &sTime, nBytes);
+    n += nBytes;
+
+    return n;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32shm.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w32shm.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,355 @@
+/* -*- 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 <private/primpl.h>       
+#include <string.h>
+#include <prshm.h>
+#include <prerr.h>
+#include <prmem.h>
+
+#if defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY)
+
+extern PRLogModuleInfo *_pr_shm_lm;
+
+/*
+ * NSPR-to-NT access right mapping table for file-mapping objects.
+ *
+ * The OR of these three access masks must equal FILE_MAP_ALL_ACCESS.
+ * This is because if a file-mapping object with the specified name
+ * exists, CreateFileMapping requests full access to the existing
+ * object.
+ */
+static DWORD filemapAccessTable[] = {
+    FILE_MAP_ALL_ACCESS & ~FILE_MAP_WRITE, /* read */
+    FILE_MAP_ALL_ACCESS & ~FILE_MAP_READ, /* write */ 
+    0  /* execute */
+};
+
+extern PRSharedMemory * _MD_OpenSharedMemory( 
+        const char *name,
+        PRSize      size,
+        PRIntn      flags,
+        PRIntn      mode
+)
+{
+    char        ipcname[PR_IPC_NAME_SIZE];
+    PRStatus    rc = PR_SUCCESS;
+    DWORD dwHi, dwLo;
+    PRSharedMemory *shm;
+    DWORD flProtect = ( PAGE_READWRITE );
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_SetError(PR_UNKNOWN_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: name is invalid")); 
+        return(NULL);
+    }
+
+    shm = PR_NEWZAP( PRSharedMemory );
+    if ( NULL == shm ) 
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); 
+        return(NULL);
+    }
+
+    shm->ipcname = PR_MALLOC( (PRUint32) (strlen( ipcname ) + 1) );
+    if ( NULL == shm->ipcname )
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
+        PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); 
+        PR_DELETE(shm);
+        return(NULL);
+    }
+
+    /* copy args to struct */
+    strcpy( shm->ipcname, ipcname );
+    shm->size = size; 
+    shm->mode = mode;
+    shm->flags = flags;
+    shm->ident = _PR_SHM_IDENT;
+
+    if (flags & PR_SHM_CREATE ) {
+        dwHi = (DWORD) (((PRUint64) shm->size >> 32) & 0xffffffff);
+        dwLo = (DWORD) (shm->size & 0xffffffff);
+
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, filemapAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
+        shm->handle = CreateFileMapping(
+            (HANDLE)-1 ,
+            lpSA,
+            flProtect,
+            dwHi,
+            dwLo,
+            shm->ipcname);
+        if (lpSA != NULL) {
+            _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+        }
+
+        if ( NULL == shm->handle ) {
+            PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
+                ( "PR_OpenSharedMemory: CreateFileMapping() failed: %s",
+                    shm->ipcname )); 
+            _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
+            PR_FREEIF( shm->ipcname )
+            PR_DELETE( shm );
+            return(NULL);
+        } else {
+            if (( flags & PR_SHM_EXCL) && ( GetLastError() == ERROR_ALREADY_EXISTS ))  {
+                PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
+                    ( "PR_OpenSharedMemory: Request exclusive & already exists",
+                        shm->ipcname )); 
+                PR_SetError( PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS );
+                CloseHandle( shm->handle );
+                PR_FREEIF( shm->ipcname )
+                PR_DELETE( shm );
+                return(NULL);
+            } else {
+                PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
+                    ( "PR_OpenSharedMemory: CreateFileMapping() success: %s, handle: %d",
+                        shm->ipcname, shm->handle ));
+                return(shm);
+            }
+        }
+    } else {
+        shm->handle = OpenFileMapping( FILE_MAP_WRITE, TRUE, shm->ipcname );
+        if ( NULL == shm->handle ) {
+            _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
+            PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
+                ( "PR_OpenSharedMemory: OpenFileMapping() failed: %s, error: %d",
+                    shm->ipcname, PR_GetOSError())); 
+            PR_FREEIF( shm->ipcname );
+            PR_DELETE( shm );
+            return(NULL);
+        } else {
+            PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
+                ( "PR_OpenSharedMemory: OpenFileMapping() success: %s, handle: %d",
+                    shm->ipcname, shm->handle )); 
+                return(shm);
+        }
+    }
+    /* returns from separate paths */
+}
+
+extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
+{
+    PRUint32    access = FILE_MAP_WRITE;
+    void        *addr;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    if ( PR_SHM_READONLY & flags )
+        access = FILE_MAP_READ;
+
+    addr = MapViewOfFile( shm->handle,
+        access,
+        0, 0,
+        shm->size );
+
+    if ( NULL == addr ) {
+        _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
+        PR_LOG( _pr_shm_lm, PR_LOG_ERROR, 
+            ("_MD_AttachSharedMemory: MapViewOfFile() failed. OSerror: %d", PR_GetOSError()));
+    }
+
+    return( addr );
+} /* end _MD_ATTACH_SHARED_MEMORY() */
+
+
+extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
+{
+    PRStatus rc = PR_SUCCESS;
+    BOOL        wrc;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    wrc = UnmapViewOfFile( addr );
+    if ( FALSE == wrc ) 
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
+        PR_LOG( _pr_shm_lm, PR_LOG_ERROR, 
+            ("_MD_DetachSharedMemory: UnmapViewOfFile() failed. OSerror: %d", PR_GetOSError()));
+        rc = PR_FAILURE;
+    }
+
+    return( rc );
+}
+
+
+extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
+{
+    PRStatus rc = PR_SUCCESS;
+    BOOL wrc;
+
+    PR_ASSERT( shm->ident == _PR_SHM_IDENT );
+
+    wrc = CloseHandle( shm->handle );
+    if ( FALSE == wrc )
+    {
+        _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
+        PR_LOG( _pr_shm_lm, PR_LOG_ERROR, 
+            ("_MD_CloseSharedMemory: CloseHandle() failed. OSerror: %d", PR_GetOSError()));
+        rc = PR_FAILURE;
+    }
+    PR_FREEIF( shm->ipcname );
+    PR_DELETE( shm );
+
+    return( rc );
+} /* end _MD_CLOSE_SHARED_MEMORY() */
+
+extern PRStatus _MD_DeleteSharedMemory( const char *name )
+{
+    return( PR_SUCCESS );
+}    
+
+
+/*
+** Windows implementation of anonymous memory (file) map
+*/
+extern PRLogModuleInfo *_pr_shma_lm;
+
+extern PRFileMap* _md_OpenAnonFileMap( 
+    const char *dirName,
+    PRSize      size,
+    PRFileMapProtect prot
+)
+{
+    PRFileMap   *fm;
+    HANDLE      hFileMap;
+
+    fm = PR_CreateFileMap( (PRFileDesc*)-1, size, prot );
+    if ( NULL == fm )  {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_OpenAnonFileMap(): PR_CreateFileMap(): failed"));
+        goto Finished;
+    }
+
+    /*
+    ** Make fm->md.hFileMap inheritable. We can't use
+    ** GetHandleInformation and SetHandleInformation
+    ** because these two functions fail with
+    ** ERROR_CALL_NOT_IMPLEMENTED on Win95.
+    */
+    if (DuplicateHandle(GetCurrentProcess(), fm->md.hFileMap,
+            GetCurrentProcess(), &hFileMap,
+            0, TRUE /* inheritable */,
+            DUPLICATE_SAME_ACCESS) == FALSE) {
+        PR_SetError( PR_UNKNOWN_ERROR, GetLastError() );
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_OpenAnonFileMap(): DuplicateHandle(): failed"));
+        PR_CloseFileMap( fm );
+        fm = NULL;
+        goto Finished;
+    }
+    CloseHandle(fm->md.hFileMap);
+    fm->md.hFileMap = hFileMap;
+
+Finished:    
+    return(fm);
+} /* end md_OpenAnonFileMap() */
+
+/*
+** _md_ExportFileMapAsString()
+**
+*/
+extern PRStatus _md_ExportFileMapAsString(
+    PRFileMap *fm,
+    PRSize    bufSize,
+    char      *buf
+)
+{
+    PRIntn  written;
+
+    written = PR_snprintf( buf, (PRUint32) bufSize, "%d:%" PR_PRIdOSFD ":%ld",
+        (PRIntn)fm->prot, (PROsfd)fm->md.hFileMap, (PRInt32)fm->md.dwAccess );
+
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_ExportFileMapAsString(): prot: %x, hFileMap: %x, dwAccess: %x",
+            fm->prot, fm->md.hFileMap, fm->md.dwAccess ));
+        
+    return((written == -1)? PR_FAILURE : PR_SUCCESS);
+} /* end _md_ExportFileMapAsString() */
+
+
+/*
+** _md_ImportFileMapFromString()
+**
+*/
+extern PRFileMap * _md_ImportFileMapFromString(
+    const char *fmstring
+)
+{
+    PRIntn  prot;
+    PROsfd hFileMap;
+    PRInt32 dwAccess;
+    PRFileMap *fm = NULL;
+
+    PR_sscanf( fmstring, "%d:%" PR_SCNdOSFD ":%ld",
+        &prot, &hFileMap, &dwAccess );
+
+    fm = PR_NEWZAP(PRFileMap);
+    if ( NULL == fm ) {
+        PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+            ("_md_ImportFileMapFromString(): PR_NEWZAP(): Failed"));
+        return(fm);
+    }
+
+    fm->prot = (PRFileMapProtect)prot;
+    fm->md.hFileMap = (HANDLE)hFileMap;
+    fm->md.dwAccess = (DWORD)dwAccess;
+    fm->fd = (PRFileDesc*)-1;
+
+    PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
+        ("_md_ImportFileMapFromString(): fm: %p, prot: %d, hFileMap: %8.8x, dwAccess: %8.8x, fd: %x",
+            fm, prot, fm->md.hFileMap, fm->md.dwAccess, fm->fd));
+    return(fm);
+} /* end _md_ImportFileMapFromString() */
+
+#else
+Error! Why is PR_HAVE_WIN32_NAMED_SHARED_MEMORY not defined? 
+#endif /* PR_HAVE_WIN32_NAMED_SHARED_MEMORY */
+/* --- end w32shm.c --- */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95cv.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95cv.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,347 @@
+/* -*- 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 ***** */
+
+/*
+ *  w95cv.c -- Windows 95 Machine-Dependent Code for Condition Variables
+ *
+ *  We implement our own condition variable wait queue.  Each thread
+ *  has a semaphore object (thread->md.blocked_sema) to block on while
+ *  waiting on a condition variable.
+ *
+ *  We use a deferred condition notify algorithm.  When PR_NotifyCondVar
+ *  or PR_NotifyAllCondVar is called, the condition notifies are simply
+ *  recorded in the _MDLock structure.  We defer the condition notifies
+ *  until right after we unlock the lock.  This way the awakened threads
+ *  have a better chance to reaquire the lock.
+ */
+ 
+#include "primpl.h"
+
+/*
+ * AddThreadToCVWaitQueueInternal --
+ *
+ * Add the thread to the end of the condition variable's wait queue.
+ * The CV's lock must be locked when this function is called.
+ */
+
+static void
+AddThreadToCVWaitQueueInternal(PRThread *thred, struct _MDCVar *cv)
+{
+    PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL)
+            || (cv->waitTail == NULL && cv->waitHead == NULL));
+    cv->nwait += 1;
+    thred->md.inCVWaitQueue = PR_TRUE;
+    thred->md.next = NULL;
+    thred->md.prev = cv->waitTail;
+    if (cv->waitHead == NULL) {
+        cv->waitHead = thred;
+    } else {
+        cv->waitTail->md.next = thred;
+    }
+    cv->waitTail = thred;
+}
+
+/*
+ * md_UnlockAndPostNotifies --
+ *
+ * Unlock the lock, and then do the deferred condition notifies.
+ * If waitThred and waitCV are not NULL, waitThred is added to
+ * the wait queue of waitCV before the lock is unlocked.
+ *
+ * This function is called by _PR_MD_WAIT_CV and _PR_MD_UNLOCK,
+ * the two places where a lock is unlocked.
+ */
+static void
+md_UnlockAndPostNotifies(
+    _MDLock *lock,
+    PRThread *waitThred,
+    _MDCVar *waitCV)
+{
+    PRIntn index;
+    _MDNotified post;
+    _MDNotified *notified, *prev = NULL;
+
+    /*
+     * Time to actually notify any conditions that were affected
+     * while the lock was held.  Get a copy of the list that's in
+     * the lock structure and then zero the original.  If it's
+     * linked to other such structures, we own that storage.
+     */
+    post = lock->notified;  /* a safe copy; we own the lock */
+
+#if defined(DEBUG)
+    ZeroMemory(&lock->notified, sizeof(_MDNotified));  /* reset */
+#else
+    lock->notified.length = 0;  /* these are really sufficient */
+    lock->notified.link = NULL;
+#endif
+
+    /* 
+     * Figure out how many threads we need to wake up.
+     */
+    notified = &post;  /* this is where we start */
+    do {
+        for (index = 0; index < notified->length; ++index) {
+            _MDCVar *cv = notified->cv[index].cv;
+            PRThread *thred;
+            int i;
+            
+            /* Fast special case: no waiting threads */
+            if (cv->waitHead == NULL) {
+                notified->cv[index].notifyHead = NULL;
+                continue;
+            }
+
+            /* General case */
+            if (-1 == notified->cv[index].times) {
+                /* broadcast */
+                thred = cv->waitHead;
+                while (thred != NULL) {
+                    thred->md.inCVWaitQueue = PR_FALSE;
+                    thred = thred->md.next;
+                }
+                notified->cv[index].notifyHead = cv->waitHead;
+                cv->waitHead = cv->waitTail = NULL;
+                cv->nwait = 0;
+            } else {
+                thred = cv->waitHead;
+                i = notified->cv[index].times;
+                while (thred != NULL && i > 0) {
+                    thred->md.inCVWaitQueue = PR_FALSE;
+                    thred = thred->md.next;
+                    i--;
+                }
+                notified->cv[index].notifyHead = cv->waitHead;
+                cv->waitHead = thred;
+                if (cv->waitHead == NULL) {
+                    cv->waitTail = NULL;
+                } else {
+                    if (cv->waitHead->md.prev != NULL) {
+                        cv->waitHead->md.prev->md.next = NULL;
+                        cv->waitHead->md.prev = NULL;
+                    }
+                }
+                cv->nwait -= notified->cv[index].times - i;
+            }
+        }
+        notified = notified->link;
+    } while (NULL != notified);
+
+    if (waitThred) {
+        AddThreadToCVWaitQueueInternal(waitThred, waitCV);
+    }
+
+    /* Release the lock before notifying */
+        LeaveCriticalSection(&lock->mutex);
+
+    notified = &post;  /* this is where we start */
+    do {
+        for (index = 0; index < notified->length; ++index) {
+            PRThread *thred;
+            PRThread *next;
+
+            thred = notified->cv[index].notifyHead;
+            while (thred != NULL) {
+                BOOL rv;
+
+                next = thred->md.next;
+                thred->md.prev = thred->md.next = NULL;
+
+                rv = ReleaseSemaphore(thred->md.blocked_sema, 1, NULL);
+                PR_ASSERT(rv != 0);
+                thred = next;
+            }
+        }
+        prev = notified;
+        notified = notified->link;
+        if (&post != prev) PR_DELETE(prev);
+    } while (NULL != notified);
+}
+
+/*
+ * Notifies just get posted to the protecting mutex.  The
+ * actual notification is done when the lock is released so that
+ * MP systems don't contend for a lock that they can't have.
+ */
+static void md_PostNotifyToCvar(_MDCVar *cvar, _MDLock *lock,
+        PRBool broadcast)
+{
+    PRIntn index = 0;
+    _MDNotified *notified = &lock->notified;
+
+    while (1) {
+        for (index = 0; index < notified->length; ++index) {
+            if (notified->cv[index].cv == cvar) {
+                if (broadcast) {
+                    notified->cv[index].times = -1;
+                } else if (-1 != notified->cv[index].times) {
+                    notified->cv[index].times += 1;
+                }
+                return;
+            }
+        }
+        /* if not full, enter new CV in this array */
+        if (notified->length < _MD_CV_NOTIFIED_LENGTH) break;
+
+        /* if there's no link, create an empty array and link it */
+        if (NULL == notified->link) {
+            notified->link = PR_NEWZAP(_MDNotified);
+        }
+
+        notified = notified->link;
+    }
+
+    /* A brand new entry in the array */
+    notified->cv[index].times = (broadcast) ? -1 : 1;
+    notified->cv[index].cv = cvar;
+    notified->length += 1;
+}
+
+/*
+ * _PR_MD_NEW_CV() -- Creating new condition variable
+ * ... Solaris uses cond_init() in similar function.
+ *
+ * returns: -1 on failure
+ *          0 when it succeeds.
+ *
+ */
+PRInt32 
+_PR_MD_NEW_CV(_MDCVar *cv)
+{
+    cv->magic = _MD_MAGIC_CV;
+    /*
+     * The waitHead, waitTail, and nwait fields are zeroed
+     * when the PRCondVar structure is created.
+     */
+    return 0;
+} 
+
+void _PR_MD_FREE_CV(_MDCVar *cv)
+{
+    cv->magic = (PRUint32)-1;
+    return;
+}
+
+/*
+ *  _PR_MD_WAIT_CV() -- Wait on condition variable
+ */
+void _PR_MD_WAIT_CV(_MDCVar *cv, _MDLock *lock, PRIntervalTime timeout )
+{
+    PRThread *thred = _PR_MD_CURRENT_THREAD();
+    DWORD rv;
+    DWORD msecs = (timeout == PR_INTERVAL_NO_TIMEOUT) ?
+            INFINITE : PR_IntervalToMilliseconds(timeout);
+
+    /*
+     * If we have pending notifies, post them now.
+     */
+    if (0 != lock->notified.length) {
+        md_UnlockAndPostNotifies(lock, thred, cv);
+    } else {
+        AddThreadToCVWaitQueueInternal(thred, cv);
+        LeaveCriticalSection(&lock->mutex);
+    }
+
+    /* Wait for notification or timeout; don't really care which */
+    rv = WaitForSingleObject(thred->md.blocked_sema, msecs);
+
+    EnterCriticalSection(&(lock->mutex));
+
+    PR_ASSERT(rv != WAIT_ABANDONED);
+    PR_ASSERT(rv != WAIT_FAILED);
+    PR_ASSERT(rv != WAIT_OBJECT_0 || thred->md.inCVWaitQueue == PR_FALSE);
+
+    if (rv == WAIT_TIMEOUT) {
+        if (thred->md.inCVWaitQueue) {
+            PR_ASSERT((cv->waitTail != NULL && cv->waitHead != NULL)
+                    || (cv->waitTail == NULL && cv->waitHead == NULL));
+            cv->nwait -= 1;
+            thred->md.inCVWaitQueue = PR_FALSE;
+            if (cv->waitHead == thred) {
+                cv->waitHead = thred->md.next;
+                if (cv->waitHead == NULL) {
+                    cv->waitTail = NULL;
+                } else {
+                    cv->waitHead->md.prev = NULL;
+                }
+            } else {
+                PR_ASSERT(thred->md.prev != NULL);
+                thred->md.prev->md.next = thred->md.next;
+                if (thred->md.next != NULL) {
+                    thred->md.next->md.prev = thred->md.prev;
+                } else {
+                    PR_ASSERT(cv->waitTail == thred);
+                    cv->waitTail = thred->md.prev;
+                }
+            }
+            thred->md.next = thred->md.prev = NULL;
+        } else {
+            /*
+             * This thread must have been notified, but the
+             * ReleaseSemaphore call happens after WaitForSingleObject
+             * times out.  Wait on the semaphore again to make it
+             * non-signaled.  We assume this wait won't take long.
+             */
+            rv = WaitForSingleObject(thred->md.blocked_sema, INFINITE);
+            PR_ASSERT(rv == WAIT_OBJECT_0);
+        }
+    }
+    PR_ASSERT(thred->md.inCVWaitQueue == PR_FALSE);
+    return;
+} /* --- end _PR_MD_WAIT_CV() --- */
+
+void _PR_MD_NOTIFY_CV(_MDCVar *cv, _MDLock *lock)
+{
+    md_PostNotifyToCvar(cv, lock, PR_FALSE);
+    return;
+}
+
+void _PR_MD_NOTIFYALL_CV(_MDCVar *cv, _MDLock *lock)
+{
+    md_PostNotifyToCvar(cv, lock, PR_TRUE);
+    return;
+}
+
+void _PR_MD_UNLOCK(_MDLock *lock)
+{
+    if (0 != lock->notified.length) {
+        md_UnlockAndPostNotifies(lock, NULL, NULL);
+    } else {
+        LeaveCriticalSection(&lock->mutex);
+    }
+    return;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95dllmain.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95dllmain.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+ * The DLL entry point (DllMain) for NSPR.
+ *
+ * This is used to detach threads that were automatically attached by
+ * nspr.
+ */
+
+#include <windows.h>
+#include <primpl.h>
+
+BOOL WINAPI DllMain(
+    HINSTANCE hinstDLL,
+    DWORD fdwReason,
+    LPVOID lpvReserved)
+{
+PRThread *me;
+
+    switch (fdwReason) {
+        case DLL_PROCESS_ATTACH:
+            break;
+        case DLL_THREAD_ATTACH:
+            break;
+        case DLL_THREAD_DETACH:
+            if (_pr_initialized) {
+                me = _MD_GET_ATTACHED_THREAD();
+                if ((me != NULL) && (me->flags & _PR_ATTACHED))
+                    _PRI_DetachThread();
+            }
+            break;
+        case DLL_PROCESS_DETACH:
+            break;
+    }
+    return TRUE;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95io.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95io.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1492 @@
+/* -*- 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):
+ *   Masayuki Nakano <masayuki at d-toybox.com>
+ *
+ * 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 ***** */
+
+/* Windows 95 IO module
+ *
+ * Assumes synchronous I/O.
+ *
+ */
+
+#include "primpl.h"
+#include <direct.h>
+#include <mbstring.h>
+#ifdef MOZ_UNICODE
+#include <wchar.h>
+#endif /* MOZ_UNICODE */
+
+
+struct _MDLock               _pr_ioq_lock;
+
+/*
+ * NSPR-to-NT access right mapping table for files.
+ */
+static DWORD fileAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
+ * NSPR-to-NT access right mapping table for directories.
+ */
+static DWORD dirAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE|FILE_DELETE_CHILD,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
+ * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
+ * We store the value in a PRTime variable for convenience.
+ * This constant is used by _PR_FileTimeToPRTime().
+ */
+#if defined(__MINGW32__)
+static const PRTime _pr_filetime_offset = 116444736000000000LL;
+#else
+static const PRTime _pr_filetime_offset = 116444736000000000i64;
+#endif
+
+#ifdef MOZ_UNICODE
+static void InitUnicodeSupport(void);
+#endif
+
+static PRBool IsPrevCharSlash(const char *str, const char *current);
+
+void
+_PR_MD_INIT_IO()
+{
+    WORD WSAVersion = 0x0101;
+    WSADATA WSAData;
+    int err;
+
+    err = WSAStartup( WSAVersion, &WSAData );
+    PR_ASSERT(0 == err);
+
+#ifdef DEBUG
+    /* Doublecheck _pr_filetime_offset's hard-coded value is correct. */
+    {
+        SYSTEMTIME systime;
+        union {
+           PRTime prt;
+           FILETIME ft;
+        } filetime;
+        BOOL rv;
+
+        systime.wYear = 1970;
+        systime.wMonth = 1;
+        /* wDayOfWeek is ignored */
+        systime.wDay = 1;
+        systime.wHour = 0;
+        systime.wMinute = 0;
+        systime.wSecond = 0;
+        systime.wMilliseconds = 0;
+
+        rv = SystemTimeToFileTime(&systime, &filetime.ft);
+        PR_ASSERT(0 != rv);
+        PR_ASSERT(filetime.prt == _pr_filetime_offset);
+    }
+#endif /* DEBUG */
+
+    _PR_NT_InitSids();
+
+#ifdef MOZ_UNICODE
+    InitUnicodeSupport();
+#endif
+}
+
+PRStatus
+_PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    DWORD rv;
+
+    PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
+        INFINITE : PR_IntervalToMilliseconds(ticks);
+    rv = WaitForSingleObject(thread->md.blocked_sema, msecs);
+    switch(rv) 
+    {
+        case WAIT_OBJECT_0:
+            return PR_SUCCESS;
+            break;
+        case WAIT_TIMEOUT:
+            _PR_THREAD_LOCK(thread);
+            if (thread->state == _PR_IO_WAIT) {
+			  ;
+            } else {
+                if (thread->wait.cvar != NULL) {
+                    thread->wait.cvar = NULL;
+                    _PR_THREAD_UNLOCK(thread);
+                } else {
+                    /* The CVAR was notified just as the timeout
+                     * occurred.  This led to us being notified twice.
+                     * call WaitForSingleObject() to clear the semaphore.
+                     */
+                    _PR_THREAD_UNLOCK(thread);
+                    rv = WaitForSingleObject(thread->md.blocked_sema, 0);
+                    PR_ASSERT(rv == WAIT_OBJECT_0);
+                }
+            }
+            return PR_SUCCESS;
+            break;
+        default:
+            return PR_FAILURE;
+            break;
+    }
+}
+PRStatus
+_PR_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if ( _PR_IS_NATIVE_THREAD(thread) ) 
+    {
+        if (ReleaseSemaphore(thread->md.blocked_sema, 1, NULL) == FALSE)
+            return PR_FAILURE;
+        else
+			return PR_SUCCESS;
+	}
+}
+
+
+/* --- FILE IO ----------------------------------------------------------- */
+/*
+ *  _PR_MD_OPEN() -- Open a file
+ *
+ *  returns: a fileHandle
+ *
+ *  The NSPR open flags (osflags) are translated into flags for Win95
+ *
+ *  Mode seems to be passed in as a unix style file permissions argument
+ *  as in 0666, in the case of opening the logFile. 
+ *
+ */
+PROsfd
+_PR_MD_OPEN(const char *name, PRIntn osflags, int mode)
+{
+    HANDLE file;
+    PRInt32 access = 0;
+    PRInt32 flags = 0;
+    PRInt32 flag6 = 0;
+    
+    if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
+ 
+    if (osflags & PR_RDONLY || osflags & PR_RDWR)
+        access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR)
+        access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE) {
+        if (osflags & PR_TRUNCATE)
+            flags = CREATE_ALWAYS;
+        else
+            flags = OPEN_ALWAYS;
+    } else {
+        if (osflags & PR_TRUNCATE)
+            flags = TRUNCATE_EXISTING;
+        else
+            flags = OPEN_EXISTING;
+    }
+
+    file = CreateFile(name,
+                      access,
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      NULL,
+                      flags,
+                      flag6,
+                      NULL);
+    if (file == INVALID_HANDLE_VALUE) {
+		_PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1; 
+	}
+
+    return (PROsfd)file;
+}
+
+PROsfd
+_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, int mode)
+{
+    HANDLE file;
+    PRInt32 access = 0;
+    PRInt32 flags = 0;
+    PRInt32 flag6 = 0;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (osflags & PR_CREATE_FILE) {
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
+    }
+    
+    if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
+ 
+    if (osflags & PR_RDONLY || osflags & PR_RDWR)
+        access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR)
+        access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE) {
+        if (osflags & PR_TRUNCATE)
+            flags = CREATE_ALWAYS;
+        else
+            flags = OPEN_ALWAYS;
+    } else {
+        if (osflags & PR_TRUNCATE)
+            flags = TRUNCATE_EXISTING;
+        else
+            flags = OPEN_EXISTING;
+    }
+
+    file = CreateFile(name,
+                      access,
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      lpSA,
+                      flags,
+                      flag6,
+                      NULL);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (file == INVALID_HANDLE_VALUE) {
+		_PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1; 
+	}
+
+    return (PROsfd)file;
+}
+
+PRInt32
+_PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
+{
+    PRUint32 bytes;
+    int rv, err;
+
+    rv = ReadFile((HANDLE)fd->secret->md.osfd,
+            (LPVOID)buf,
+            len,
+            &bytes,
+            NULL);
+    
+    if (rv == 0) 
+    {
+        err = GetLastError();
+        /* ERROR_HANDLE_EOF can only be returned by async io */
+        PR_ASSERT(err != ERROR_HANDLE_EOF);
+        if (err == ERROR_BROKEN_PIPE)
+            return 0;
+		else {
+			_PR_MD_MAP_READ_ERROR(err);
+        return -1;
+    }
+    }
+    return bytes;
+}
+
+PRInt32
+_PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 len)
+{
+    PROsfd f = fd->secret->md.osfd;
+    PRInt32 bytes;
+    int rv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    
+    rv = WriteFile((HANDLE)f,
+            buf,
+            len,
+            &bytes,
+            NULL );
+            
+    if (rv == 0) 
+    {
+		_PR_MD_MAP_WRITE_ERROR(GetLastError());
+        return -1;
+    }
+    return bytes;
+} /* --- end _PR_MD_WRITE() --- */
+
+PROffset32
+_PR_MD_LSEEK(PRFileDesc *fd, PROffset32 offset, PRSeekWhence whence)
+{
+    DWORD moveMethod;
+    PROffset32 rv;
+
+    switch (whence) {
+        case PR_SEEK_SET:
+            moveMethod = FILE_BEGIN;
+            break;
+        case PR_SEEK_CUR:
+            moveMethod = FILE_CURRENT;
+            break;
+        case PR_SEEK_END:
+            moveMethod = FILE_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return -1;
+    }
+
+    rv = SetFilePointer((HANDLE)fd->secret->md.osfd, offset, NULL, moveMethod);
+
+    /*
+     * If the lpDistanceToMoveHigh argument (third argument) is
+     * NULL, SetFilePointer returns 0xffffffff on failure.
+     */
+    if (-1 == rv) {
+        _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+    }
+    return rv;
+}
+
+PROffset64
+_PR_MD_LSEEK64(PRFileDesc *fd, PROffset64 offset, PRSeekWhence whence)
+{
+    DWORD moveMethod;
+    LARGE_INTEGER li;
+    DWORD err;
+
+    switch (whence) {
+        case PR_SEEK_SET:
+            moveMethod = FILE_BEGIN;
+            break;
+        case PR_SEEK_CUR:
+            moveMethod = FILE_CURRENT;
+            break;
+        case PR_SEEK_END:
+            moveMethod = FILE_END;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return -1;
+    }
+
+    li.QuadPart = offset;
+    li.LowPart = SetFilePointer((HANDLE)fd->secret->md.osfd,
+            li.LowPart, &li.HighPart, moveMethod);
+
+    if (0xffffffff == li.LowPart && (err = GetLastError()) != NO_ERROR) {
+        _PR_MD_MAP_LSEEK_ERROR(err);
+        li.QuadPart = -1;
+    }
+    return li.QuadPart;
+}
+
+/*
+ * This is documented to succeed on read-only files, but Win32's
+ * FlushFileBuffers functions fails with "access denied" in such a
+ * case.  So we only signal an error if the error is *not* "access
+ * denied".
+ */
+PRInt32
+_PR_MD_FSYNC(PRFileDesc *fd)
+{
+    /*
+     * From the documentation:
+     *
+     *	   On Windows NT, the function FlushFileBuffers fails if hFile
+     *	   is a handle to console output. That is because console
+     *	   output is not buffered. The function returns FALSE, and
+     *	   GetLastError returns ERROR_INVALID_HANDLE.
+     *
+     * On the other hand, on Win95, it returns without error.  I cannot
+     * assume that 0, 1, and 2 are console, because if someone closes
+     * System.out and then opens a file, they might get file descriptor
+     * 1.  An error on *that* version of 1 should be reported, whereas
+     * an error on System.out (which was the original 1) should be
+     * ignored.  So I use isatty() to ensure that such an error was due
+     * to this bogosity, and if it was, I ignore the error.
+     */
+
+    BOOL ok = FlushFileBuffers((HANDLE)fd->secret->md.osfd);
+
+    if (!ok) {
+	DWORD err = GetLastError();
+	if (err != ERROR_ACCESS_DENIED) {	// from winerror.h
+			_PR_MD_MAP_FSYNC_ERROR(err);
+	    return -1;
+	}
+    }
+    return 0;
+}
+
+PRInt32
+_MD_CloseFile(PROsfd osfd)
+{
+    PRInt32 rv;
+    
+    rv = (CloseHandle((HANDLE)osfd))?0:-1;
+	if (rv == -1)
+		_PR_MD_MAP_CLOSE_ERROR(GetLastError());
+    return rv;
+}
+
+
+/* --- DIR IO ------------------------------------------------------------ */
+#define GetFileFromDIR(d)       (d)->d_entry.cFileName
+#define FileIsHidden(d)	((d)->d_entry.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+
+void FlipSlashes(char *cp, size_t len)
+{
+    while (len-- > 0) {
+        if (cp[0] == '/') {
+            cp[0] = PR_DIRECTORY_SEPARATOR;
+        }
+        cp = _mbsinc(cp);
+    }
+} /* end FlipSlashes() */
+
+
+/*
+**
+** Local implementations of standard Unix RTL functions which are not provided
+** by the VC RTL.
+**
+*/
+
+PRStatus
+_PR_MD_CLOSE_DIR(_MDDir *d)
+{
+    if ( d ) {
+        if (FindClose(d->d_hdl)) {
+        d->magic = (PRUint32)-1;
+        return PR_SUCCESS;
+		} else {
+			_PR_MD_MAP_CLOSEDIR_ERROR(GetLastError());
+        	return PR_FAILURE;
+		}
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return PR_FAILURE;
+}
+
+
+PRStatus
+_PR_MD_OPEN_DIR(_MDDir *d, const char *name)
+{
+    char filename[ MAX_PATH ];
+    size_t len;
+
+    len = strlen(name);
+    /* Need 5 bytes for \*.* and the trailing null byte. */
+    if (len + 5 > MAX_PATH) {
+        PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
+        return PR_FAILURE;
+    }
+    strcpy(filename, name);
+
+    /*
+     * If 'name' ends in a slash or backslash, do not append
+     * another backslash.
+     */
+    if (IsPrevCharSlash(filename, filename + len)) {
+        len--;
+    }
+    strcpy(&filename[len], "\\*.*");
+    FlipSlashes( filename, strlen(filename) );
+
+    d->d_hdl = FindFirstFile( filename, &(d->d_entry) );
+    if ( d->d_hdl == INVALID_HANDLE_VALUE ) {
+		_PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    d->firstEntry = PR_TRUE;
+    d->magic = _MD_MAGIC_DIR;
+    return PR_SUCCESS;
+}
+
+char *
+_PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
+{
+    PRInt32 err;
+    BOOL rv;
+    char *fileName;
+
+    if ( d ) {
+        while (1) {
+            if (d->firstEntry) {
+                d->firstEntry = PR_FALSE;
+                rv = 1;
+            } else {
+                rv = FindNextFile(d->d_hdl, &(d->d_entry));
+            }
+            if (rv == 0) {
+                break;
+            }
+            fileName = GetFileFromDIR(d);
+            if ( (flags & PR_SKIP_DOT) &&
+                 (fileName[0] == '.') && (fileName[1] == '\0'))
+                 continue;
+            if ( (flags & PR_SKIP_DOT_DOT) &&
+                 (fileName[0] == '.') && (fileName[1] == '.') &&
+                 (fileName[2] == '\0'))
+                 continue;
+            if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d))
+                 continue;
+            return fileName;
+        }
+        err = GetLastError();
+        PR_ASSERT(NO_ERROR != err);
+			_PR_MD_MAP_READDIR_ERROR(err);
+        return NULL;
+		}
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return NULL;
+}
+
+PRInt32
+_PR_MD_DELETE(const char *name)
+{
+    if (DeleteFile(name)) {
+        return 0;
+    } else {
+		_PR_MD_MAP_DELETE_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+void
+_PR_FileTimeToPRTime(const FILETIME *filetime, PRTime *prtm)
+{
+    PR_ASSERT(sizeof(FILETIME) == sizeof(PRTime));
+    CopyMemory(prtm, filetime, sizeof(PRTime));
+#if defined(__MINGW32__)
+    *prtm = (*prtm - _pr_filetime_offset) / 10LL;
+#else
+    *prtm = (*prtm - _pr_filetime_offset) / 10i64;
+#endif
+
+#ifdef DEBUG
+    /* Doublecheck our calculation. */
+    {
+        SYSTEMTIME systime;
+        PRExplodedTime etm;
+        PRTime cmp; /* for comparison */
+        BOOL rv;
+
+        rv = FileTimeToSystemTime(filetime, &systime);
+        PR_ASSERT(0 != rv);
+
+        /*
+         * PR_ImplodeTime ignores wday and yday.
+         */
+        etm.tm_usec = systime.wMilliseconds * PR_USEC_PER_MSEC;
+        etm.tm_sec = systime.wSecond;
+        etm.tm_min = systime.wMinute;
+        etm.tm_hour = systime.wHour;
+        etm.tm_mday = systime.wDay;
+        etm.tm_month = systime.wMonth - 1;
+        etm.tm_year = systime.wYear;
+        /*
+         * It is not well-documented what time zone the FILETIME's
+         * are in.  WIN32_FIND_DATA is documented to be in UTC (GMT).
+         * But BY_HANDLE_FILE_INFORMATION is unclear about this.
+         * By our best judgement, we assume that FILETIME is in UTC.
+         */
+        etm.tm_params.tp_gmt_offset = 0;
+        etm.tm_params.tp_dst_offset = 0;
+        cmp = PR_ImplodeTime(&etm);
+
+        /*
+         * SYSTEMTIME is in milliseconds precision, so we convert PRTime's
+         * microseconds to milliseconds before doing the comparison.
+         */
+        PR_ASSERT((cmp / PR_USEC_PER_MSEC) == (*prtm / PR_USEC_PER_MSEC));
+    }
+#endif /* DEBUG */
+}
+
+PRInt32
+_PR_MD_STAT(const char *fn, struct stat *info)
+{
+    PRInt32 rv;
+
+    rv = _stat(fn, (struct _stat *)info);
+    if (-1 == rv) {
+        /*
+         * Check for MSVC runtime library _stat() bug.
+         * (It's really a bug in FindFirstFile().)
+         * If a pathname ends in a backslash or slash,
+         * e.g., c:\temp\ or c:/temp/, _stat() will fail.
+         * Note: a pathname ending in a slash (e.g., c:/temp/)
+         * can be handled by _stat() on NT but not on Win95.
+         *
+         * We remove the backslash or slash at the end and
+         * try again.
+         */
+
+        size_t len = strlen(fn);
+        if (len > 0 && len <= _MAX_PATH
+                && IsPrevCharSlash(fn, fn + len)) {
+            char newfn[_MAX_PATH + 1];
+
+            strcpy(newfn, fn);
+            newfn[len - 1] = '\0';
+            rv = _stat(newfn, (struct _stat *)info);
+        }
+    }
+
+    if (-1 == rv) {
+        _PR_MD_MAP_STAT_ERROR(errno);
+    }
+    return rv;
+}
+
+#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\')
+
+static PRBool
+IsPrevCharSlash(const char *str, const char *current)
+{
+    const char *prev;
+
+    if (str >= current)
+        return PR_FALSE;
+    prev = _mbsdec(str, current);
+    return (prev == current - 1) && _PR_IS_SLASH(*prev);
+}
+
+/*
+ * IsRootDirectory --
+ *
+ * Return PR_TRUE if the pathname 'fn' is a valid root directory,
+ * else return PR_FALSE.  The char buffer pointed to by 'fn' must
+ * be writable.  During the execution of this function, the contents
+ * of the buffer pointed to by 'fn' may be modified, but on return
+ * the original contents will be restored.  'buflen' is the size of
+ * the buffer pointed to by 'fn'.
+ *
+ * Root directories come in three formats:
+ * 1. / or \, meaning the root directory of the current drive.
+ * 2. C:/ or C:\, where C is a drive letter.
+ * 3. \\<server name>\<share point name>\ or
+ *    \\<server name>\<share point name>, meaning the root directory
+ *    of a UNC (Universal Naming Convention) name.
+ */
+
+static PRBool
+IsRootDirectory(char *fn, size_t buflen)
+{
+    char *p;
+    PRBool slashAdded = PR_FALSE;
+    PRBool rv = PR_FALSE;
+
+    if (_PR_IS_SLASH(fn[0]) && fn[1] == '\0') {
+        return PR_TRUE;
+    }
+
+    if (isalpha(fn[0]) && fn[1] == ':' && _PR_IS_SLASH(fn[2])
+            && fn[3] == '\0') {
+        rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE;
+        return rv;
+    }
+
+    /* The UNC root directory */
+
+    if (_PR_IS_SLASH(fn[0]) && _PR_IS_SLASH(fn[1])) {
+        /* The 'server' part should have at least one character. */
+        p = &fn[2];
+        if (*p == '\0' || _PR_IS_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the next slash */
+        do {
+            p = _mbsinc(p);
+        } while (*p != '\0' && !_PR_IS_SLASH(*p));
+        if (*p == '\0') {
+            return PR_FALSE;
+        }
+
+        /* The 'share' part should have at least one character. */
+        p++;
+        if (*p == '\0' || _PR_IS_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the final slash */
+        do {
+            p = _mbsinc(p);
+        } while (*p != '\0' && !_PR_IS_SLASH(*p));
+        if (_PR_IS_SLASH(*p) && p[1] != '\0') {
+            return PR_FALSE;
+        }
+        if (*p == '\0') {
+            /*
+             * GetDriveType() doesn't work correctly if the
+             * path is of the form \\server\share, so we add
+             * a final slash temporarily.
+             */
+            if ((p + 1) < (fn + buflen)) {
+                *p++ = '\\';
+                *p = '\0';
+                slashAdded = PR_TRUE;
+            } else {
+                return PR_FALSE; /* name too long */
+            }
+        }
+        rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE;
+        /* restore the 'fn' buffer */
+        if (slashAdded) {
+            *--p = '\0';
+        }
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO64(const char *fn, PRFileInfo64 *info)
+{
+    HANDLE hFindFile;
+    WIN32_FIND_DATA findFileData;
+    char pathbuf[MAX_PATH + 1];
+    
+    if (NULL == fn || '\0' == *fn) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+
+    /*
+     * FindFirstFile() expands wildcard characters.  So
+     * we make sure the pathname contains no wildcard.
+     */
+    if (NULL != _mbspbrk(fn, "?*")) {
+        PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0);
+        return -1;
+    }
+
+    hFindFile = FindFirstFile(fn, &findFileData);
+    if (INVALID_HANDLE_VALUE == hFindFile) {
+        DWORD len;
+        char *filePart;
+
+        /*
+         * FindFirstFile() does not work correctly on root directories.
+         * It also doesn't work correctly on a pathname that ends in a
+         * slash.  So we first check to see if the pathname specifies a
+         * root directory.  If not, and if the pathname ends in a slash,
+         * we remove the final slash and try again.
+         */
+
+        /*
+         * If the pathname does not contain ., \, and /, it cannot be
+         * a root directory or a pathname that ends in a slash.
+         */
+        if (NULL == _mbspbrk(fn, ".\\/")) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        } 
+        len = GetFullPathName(fn, sizeof(pathbuf), pathbuf,
+                &filePart);
+        if (0 == len) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        }
+        if (len > sizeof(pathbuf)) {
+            PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
+            return -1;
+        }
+        if (IsRootDirectory(pathbuf, sizeof(pathbuf))) {
+            info->type = PR_FILE_DIRECTORY;
+            info->size = 0;
+            /*
+             * These timestamps don't make sense for root directories.
+             */
+            info->modifyTime = 0;
+            info->creationTime = 0;
+            return 0;
+        }
+        if (!IsPrevCharSlash(pathbuf, pathbuf + len)) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        } else {
+            pathbuf[len - 1] = '\0';
+            hFindFile = FindFirstFile(pathbuf, &findFileData);
+            if (INVALID_HANDLE_VALUE == hFindFile) {
+                _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+                return -1;
+            }
+        }
+    }
+
+    FindClose(hFindFile);
+
+    if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        info->type = PR_FILE_DIRECTORY;
+    } else {
+        info->type = PR_FILE_FILE;
+    }
+
+    info->size = findFileData.nFileSizeHigh;
+    info->size = (info->size << 32) + findFileData.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime);
+
+    if (0 == findFileData.ftCreationTime.dwLowDateTime &&
+            0 == findFileData.ftCreationTime.dwHighDateTime) {
+        info->creationTime = info->modifyTime;
+    } else {
+        _PR_FileTimeToPRTime(&findFileData.ftCreationTime,
+                &info->creationTime);
+    }
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO(const char *fn, PRFileInfo *info)
+{
+    PRFileInfo64 info64;
+    PRInt32 rv = _PR_MD_GETFILEINFO64(fn, &info64);
+    if (0 == rv)
+    {
+        info->type = info64.type;
+        info->size = (PRUint32) info64.size;
+        info->modifyTime = info64.modifyTime;
+        info->creationTime = info64.creationTime;
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO64(const PRFileDesc *fd, PRFileInfo64 *info)
+{
+    int rv;
+
+    BY_HANDLE_FILE_INFORMATION hinfo;
+
+    rv = GetFileInformationByHandle((HANDLE)fd->secret->md.osfd, &hinfo);
+    if (rv == FALSE) {
+		_PR_MD_MAP_FSTAT_ERROR(GetLastError());
+        return -1;
+	}
+
+    if (hinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        info->type = PR_FILE_DIRECTORY;
+    else
+        info->type = PR_FILE_FILE;
+
+    info->size = hinfo.nFileSizeHigh;
+    info->size = (info->size << 32) + hinfo.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&hinfo.ftLastWriteTime, &(info->modifyTime) );
+    _PR_FileTimeToPRTime(&hinfo.ftCreationTime, &(info->creationTime) );
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_GETOPENFILEINFO(const PRFileDesc *fd, PRFileInfo *info)
+{
+    PRFileInfo64 info64;
+    int rv = _PR_MD_GETOPENFILEINFO64(fd, &info64);
+    if (0 == rv)
+    {
+        info->type = info64.type;
+        info->modifyTime = info64.modifyTime;
+        info->creationTime = info64.creationTime;
+        LL_L2I(info->size, info64.size);
+    }
+    return rv;
+}
+
+PRStatus
+_PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
+{
+    BOOL rv;
+
+    /*
+     * The SetHandleInformation function fails with the
+     * ERROR_CALL_NOT_IMPLEMENTED error on Win95.
+     */
+    rv = SetHandleInformation(
+            (HANDLE)fd->secret->md.osfd,
+            HANDLE_FLAG_INHERIT,
+            inheritable ? HANDLE_FLAG_INHERIT : 0);
+    if (0 == rv) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+} 
+
+void
+_PR_MD_INIT_FD_INHERITABLE(PRFileDesc *fd, PRBool imported)
+{
+    if (imported) {
+        fd->secret->inheritable = _PR_TRI_UNKNOWN;
+    } else {
+        fd->secret->inheritable = _PR_TRI_FALSE;
+    }
+}
+
+void
+_PR_MD_QUERY_FD_INHERITABLE(PRFileDesc *fd)
+{
+    DWORD flags;
+
+    PR_ASSERT(_PR_TRI_UNKNOWN == fd->secret->inheritable);
+    if (GetHandleInformation((HANDLE)fd->secret->md.osfd, &flags)) {
+        if (flags & HANDLE_FLAG_INHERIT) {
+            fd->secret->inheritable = _PR_TRI_TRUE;
+        } else {
+            fd->secret->inheritable = _PR_TRI_FALSE;
+        }
+    }
+}
+
+PRInt32
+_PR_MD_RENAME(const char *from, const char *to)
+{
+    /* Does this work with dot-relative pathnames? */
+    if (MoveFile(from, to)) {
+        return 0;
+    } else {
+		_PR_MD_MAP_RENAME_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_ACCESS(const char *name, PRAccessHow how)
+{
+PRInt32 rv;
+    switch (how) {
+      case PR_ACCESS_WRITE_OK:
+        rv = _access(name, 02);
+		break;
+      case PR_ACCESS_READ_OK:
+        rv = _access(name, 04);
+		break;
+      case PR_ACCESS_EXISTS:
+        return _access(name, 00);
+	  	break;
+      default:
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return -1;
+    }
+	if (rv < 0)
+		_PR_MD_MAP_ACCESS_ERROR(errno);
+    return rv;
+}
+
+PRInt32
+_PR_MD_MKDIR(const char *name, PRIntn mode)
+{
+    /* XXXMB - how to translate the "mode"??? */
+    if (CreateDirectory(name, NULL)) {
+        return 0;
+    } else {
+		_PR_MD_MAP_MKDIR_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_MAKE_DIR(const char *name, PRIntn mode)
+{
+    BOOL rv;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (_PR_NT_MakeSecurityDescriptorACL(mode, dirAccessTable,
+            &pSD, &pACL) == PR_SUCCESS) {
+        sa.nLength = sizeof(sa);
+        sa.lpSecurityDescriptor = pSD;
+        sa.bInheritHandle = FALSE;
+        lpSA = &sa;
+    }
+    rv = CreateDirectory(name, lpSA);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (rv) {
+        return 0;
+    } else {
+        _PR_MD_MAP_MKDIR_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRInt32
+_PR_MD_RMDIR(const char *name)
+{
+    if (RemoveDirectory(name)) {
+        return 0;
+    } else {
+		_PR_MD_MAP_RMDIR_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRStatus
+_PR_MD_LOCKFILE(PROsfd f)
+{
+    PRStatus  rc = PR_SUCCESS;
+	DWORD     rv;
+
+	rv = LockFile( (HANDLE)f,
+		0l, 0l,
+		0x0l, 0xffffffffl ); 
+	if ( rv == 0 ) {
+        DWORD rc = GetLastError();
+        PR_LOG( _pr_io_lm, PR_LOG_ERROR,
+            ("_PR_MD_LOCKFILE() failed. Error: %d", rc ));
+        rc = PR_FAILURE;
+    }
+
+    return rc;
+} /* end _PR_MD_LOCKFILE() */
+
+PRStatus
+_PR_MD_TLOCKFILE(PROsfd f)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return PR_FAILURE;
+} /* end _PR_MD_TLOCKFILE() */
+
+
+PRStatus
+_PR_MD_UNLOCKFILE(PROsfd f)
+{
+	PRInt32   rv;
+    
+    rv = UnlockFile( (HANDLE) f,
+    		0l, 0l,
+            0x0l, 0xffffffffl ); 
+            
+    if ( rv )
+    {
+    	return PR_SUCCESS;
+    }
+    else
+    {
+		_PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+		return PR_FAILURE;
+    }
+} /* end _PR_MD_UNLOCKFILE() */
+
+PRInt32
+_PR_MD_PIPEAVAILABLE(PRFileDesc *fd)
+{
+    if (NULL == fd)
+		PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+	else
+		PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return -1;
+}
+
+#ifdef MOZ_UNICODE
+
+typedef HANDLE (WINAPI *CreateFileWFn) (LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
+static CreateFileWFn createFileW = CreateFileW;
+typedef HANDLE (WINAPI *FindFirstFileWFn) (LPCWSTR, LPWIN32_FIND_DATAW);
+static FindFirstFileWFn findFirstFileW = FindFirstFileW;
+typedef BOOL (WINAPI *FindNextFileWFn) (HANDLE, LPWIN32_FIND_DATAW);
+static FindNextFileWFn findNextFileW = FindNextFileW;
+typedef DWORD (WINAPI *GetFullPathNameWFn) (LPCWSTR, DWORD, LPWSTR, LPWSTR *);
+static GetFullPathNameWFn getFullPathNameW = GetFullPathNameW;
+typedef UINT (WINAPI *GetDriveTypeWFn) (LPCWSTR);
+static GetDriveTypeWFn getDriveTypeW = GetDriveTypeW;
+
+static void InitUnicodeSupport(void)
+{
+    /*
+     * The W functions exist on Win9x as stubs that fail with the
+     * ERROR_CALL_NOT_IMPLEMENTED error.  We plan to emulate the
+     * MSLU W functions on Win9x in the future.
+     */
+}
+
+/* ================ UTF16 Interfaces ================================ */
+void FlipSlashesW(PRUnichar *cp, size_t len)
+{
+    while (len-- > 0) {
+        if (cp[0] == L'/') {
+            cp[0] = L'\\';
+        }
+        cp++;
+    }
+} /* end FlipSlashesW() */
+
+PROsfd
+_PR_MD_OPEN_FILE_UTF16(const PRUnichar *name, PRIntn osflags, int mode)
+{
+    HANDLE file;
+    PRInt32 access = 0;
+    PRInt32 flags = 0;
+    PRInt32 flag6 = 0;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (osflags & PR_CREATE_FILE) {
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
+    }
+
+    if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
+
+    if (osflags & PR_RDONLY || osflags & PR_RDWR)
+        access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR)
+        access |= GENERIC_WRITE;
+ 
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE) {
+        if (osflags & PR_TRUNCATE)
+            flags = CREATE_ALWAYS;
+        else
+            flags = OPEN_ALWAYS;
+    } else {
+        if (osflags & PR_TRUNCATE)
+            flags = TRUNCATE_EXISTING;
+        else
+            flags = OPEN_EXISTING;
+    }
+
+    file = createFileW(name,
+                       access,
+                       FILE_SHARE_READ|FILE_SHARE_WRITE,
+                       lpSA,
+                       flags,
+                       flag6,
+                       NULL);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (file == INVALID_HANDLE_VALUE) {
+        _PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1;
+    }
+ 
+    return (PROsfd)file;
+}
+ 
+PRStatus
+_PR_MD_OPEN_DIR_UTF16(_MDDirUTF16 *d, const PRUnichar *name)
+{
+    PRUnichar filename[ MAX_PATH ];
+    int len;
+
+    len = wcslen(name);
+    /* Need 5 bytes for \*.* and the trailing null byte. */
+    if (len + 5 > MAX_PATH) {
+        PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
+        return PR_FAILURE;
+    }
+    wcscpy(filename, name);
+
+    /*
+     * If 'name' ends in a slash or backslash, do not append
+     * another backslash.
+     */
+    if (filename[len - 1] == L'/' || filename[len - 1] == L'\\') {
+        len--;
+    }
+    wcscpy(&filename[len], L"\\*.*");
+    FlipSlashesW( filename, wcslen(filename) );
+
+    d->d_hdl = findFirstFileW( filename, &(d->d_entry) );
+    if ( d->d_hdl == INVALID_HANDLE_VALUE ) {
+        _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+        return PR_FAILURE;
+    }
+    d->firstEntry = PR_TRUE;
+    d->magic = _MD_MAGIC_DIR;
+    return PR_SUCCESS;
+}
+
+PRUnichar *
+_PR_MD_READ_DIR_UTF16(_MDDirUTF16 *d, PRIntn flags)
+{
+    PRInt32 err;
+    BOOL rv;
+    PRUnichar *fileName;
+
+    if ( d ) {
+        while (1) {
+            if (d->firstEntry) {
+                d->firstEntry = PR_FALSE;
+                rv = 1;
+            } else {
+                rv = findNextFileW(d->d_hdl, &(d->d_entry));
+            }
+            if (rv == 0) {
+                break;
+            }
+            fileName = GetFileFromDIR(d);
+            if ( (flags & PR_SKIP_DOT) &&
+                 (fileName[0] == L'.') && (fileName[1] == L'\0'))
+                continue;
+            if ( (flags & PR_SKIP_DOT_DOT) &&
+                 (fileName[0] == L'.') && (fileName[1] == L'.') &&
+                 (fileName[2] == L'\0'))
+                continue;
+            if ( (flags & PR_SKIP_HIDDEN) && FileIsHidden(d))
+                continue;
+            return fileName;
+        }
+        err = GetLastError();
+        PR_ASSERT(NO_ERROR != err);
+        _PR_MD_MAP_READDIR_ERROR(err);
+        return NULL;
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return NULL;
+}
+ 
+PRStatus
+_PR_MD_CLOSE_DIR_UTF16(_MDDirUTF16 *d)
+{
+    if ( d ) {
+        if (FindClose(d->d_hdl)) {
+            d->magic = (PRUint32)-1;
+            return PR_SUCCESS;
+        } else {
+            _PR_MD_MAP_CLOSEDIR_ERROR(GetLastError());
+            return PR_FAILURE;
+        }
+    }
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return PR_FAILURE;
+}
+
+#define _PR_IS_W_SLASH(ch) ((ch) == L'/' || (ch) == L'\\')
+
+/*
+ * IsRootDirectoryW --
+ *
+ * Return PR_TRUE if the pathname 'fn' is a valid root directory,
+ * else return PR_FALSE.  The PRUnichar buffer pointed to by 'fn' must
+ * be writable.  During the execution of this function, the contents
+ * of the buffer pointed to by 'fn' may be modified, but on return
+ * the original contents will be restored.  'buflen' is the size of
+ * the buffer pointed to by 'fn', in PRUnichars.
+ *
+ * Root directories come in three formats:
+ * 1. / or \, meaning the root directory of the current drive.
+ * 2. C:/ or C:\, where C is a drive letter.
+ * 3. \\<server name>\<share point name>\ or
+ *    \\<server name>\<share point name>, meaning the root directory
+ *    of a UNC (Universal Naming Convention) name.
+ */
+
+static PRBool
+IsRootDirectoryW(PRUnichar *fn, size_t buflen)
+{
+    PRUnichar *p;
+    PRBool slashAdded = PR_FALSE;
+    PRBool rv = PR_FALSE;
+
+    if (_PR_IS_W_SLASH(fn[0]) && fn[1] == L'\0') {
+        return PR_TRUE;
+    }
+
+    if (iswalpha(fn[0]) && fn[1] == L':' && _PR_IS_W_SLASH(fn[2])
+            && fn[3] == L'\0') {
+        rv = getDriveTypeW(fn) > 1 ? PR_TRUE : PR_FALSE;
+        return rv;
+    }
+
+    /* The UNC root directory */
+
+    if (_PR_IS_W_SLASH(fn[0]) && _PR_IS_W_SLASH(fn[1])) {
+        /* The 'server' part should have at least one character. */
+        p = &fn[2];
+        if (*p == L'\0' || _PR_IS_W_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the next slash */
+        do {
+            p++;
+        } while (*p != L'\0' && !_PR_IS_W_SLASH(*p));
+        if (*p == L'\0') {
+            return PR_FALSE;
+        }
+
+        /* The 'share' part should have at least one character. */
+        p++;
+        if (*p == L'\0' || _PR_IS_W_SLASH(*p)) {
+            return PR_FALSE;
+        }
+
+        /* look for the final slash */
+        do {
+            p++;
+        } while (*p != L'\0' && !_PR_IS_W_SLASH(*p));
+        if (_PR_IS_W_SLASH(*p) && p[1] != L'\0') {
+            return PR_FALSE;
+        }
+        if (*p == L'\0') {
+            /*
+             * GetDriveType() doesn't work correctly if the
+             * path is of the form \\server\share, so we add
+             * a final slash temporarily.
+             */
+            if ((p + 1) < (fn + buflen)) {
+                *p++ = L'\\';
+                *p = L'\0';
+                slashAdded = PR_TRUE;
+            } else {
+                return PR_FALSE; /* name too long */
+            }
+        }
+        rv = getDriveTypeW(fn) > 1 ? PR_TRUE : PR_FALSE;
+        /* restore the 'fn' buffer */
+        if (slashAdded) {
+            *--p = L'\0';
+        }
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_GETFILEINFO64_UTF16(const PRUnichar *fn, PRFileInfo64 *info)
+{
+    HANDLE hFindFile;
+    WIN32_FIND_DATAW findFileData;
+    PRUnichar pathbuf[MAX_PATH + 1];
+
+    if (NULL == fn || L'\0' == *fn) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+
+    /*
+     * FindFirstFile() expands wildcard characters.  So
+     * we make sure the pathname contains no wildcard.
+     */
+    if (NULL != wcspbrk(fn, L"?*")) {
+        PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0);
+        return -1;
+    }
+
+    hFindFile = findFirstFileW(fn, &findFileData);
+    if (INVALID_HANDLE_VALUE == hFindFile) {
+        DWORD len;
+        PRUnichar *filePart;
+
+        /*
+         * FindFirstFile() does not work correctly on root directories.
+         * It also doesn't work correctly on a pathname that ends in a
+         * slash.  So we first check to see if the pathname specifies a
+         * root directory.  If not, and if the pathname ends in a slash,
+         * we remove the final slash and try again.
+         */
+
+        /*
+         * If the pathname does not contain ., \, and /, it cannot be
+         * a root directory or a pathname that ends in a slash.
+         */
+        if (NULL == wcspbrk(fn, L".\\/")) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        } 
+        len = getFullPathNameW(fn, sizeof(pathbuf)/sizeof(pathbuf[0]), pathbuf,
+                &filePart);
+        if (0 == len) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        }
+        if (len > sizeof(pathbuf)/sizeof(pathbuf[0])) {
+            PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
+            return -1;
+        }
+        if (IsRootDirectoryW(pathbuf, sizeof(pathbuf)/sizeof(pathbuf[0]))) {
+            info->type = PR_FILE_DIRECTORY;
+            info->size = 0;
+            /*
+             * These timestamps don't make sense for root directories.
+             */
+            info->modifyTime = 0;
+            info->creationTime = 0;
+            return 0;
+        }
+        if (!_PR_IS_W_SLASH(pathbuf[len - 1])) {
+            _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+            return -1;
+        } else {
+            pathbuf[len - 1] = L'\0';
+            hFindFile = findFirstFileW(pathbuf, &findFileData);
+            if (INVALID_HANDLE_VALUE == hFindFile) {
+                _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
+                return -1;
+            }
+        }
+    }
+
+    FindClose(hFindFile);
+
+    if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        info->type = PR_FILE_DIRECTORY;
+    } else {
+        info->type = PR_FILE_FILE;
+    }
+
+    info->size = findFileData.nFileSizeHigh;
+    info->size = (info->size << 32) + findFileData.nFileSizeLow;
+
+    _PR_FileTimeToPRTime(&findFileData.ftLastWriteTime, &info->modifyTime);
+
+    if (0 == findFileData.ftCreationTime.dwLowDateTime &&
+            0 == findFileData.ftCreationTime.dwHighDateTime) {
+        info->creationTime = info->modifyTime;
+    } else {
+        _PR_FileTimeToPRTime(&findFileData.ftCreationTime,
+                &info->creationTime);
+    }
+
+    return 0;
+}
+/* ================ end of UTF16 Interfaces ================================ */
+#endif /* MOZ_UNICODE */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95sock.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95sock.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,659 @@
+/* -*- 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 ***** */
+
+/* Win95 Sockets module
+ *
+ */
+
+#include "primpl.h"
+
+#define READ_FD     1
+#define WRITE_FD    2
+#define CONNECT_FD  3
+
+static PRInt32 socket_io_wait(
+    PROsfd osfd, 
+    PRInt32 fd_type,
+    PRIntervalTime timeout);
+
+
+/* --- SOCKET IO --------------------------------------------------------- */
+
+
+PROsfd
+_PR_MD_SOCKET(int af, int type, int flags)
+{
+    SOCKET sock;
+    u_long one = 1;
+
+    sock = socket(af, type, flags);
+
+    if (sock == INVALID_SOCKET ) 
+    {
+        _PR_MD_MAP_SOCKET_ERROR(WSAGetLastError());
+        return (PROsfd)sock;
+    }
+
+    /*
+    ** Make the socket Non-Blocking
+    */
+    if (ioctlsocket( sock, FIONBIO, &one) != 0)
+    {
+        PR_SetError(PR_UNKNOWN_ERROR, WSAGetLastError());
+        closesocket(sock);
+        return -1;
+    }
+
+    return (PROsfd)sock;
+}
+
+/*
+** _MD_CloseSocket() -- Close a socket
+**
+*/
+PRInt32
+_MD_CloseSocket(PROsfd osfd)
+{
+    PRInt32 rv;
+
+    rv = closesocket((SOCKET) osfd );
+    if (rv < 0)
+        _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
+
+    return rv;
+}
+
+PRInt32
+_MD_SocketAvailable(PRFileDesc *fd)
+{
+    PRInt32 result;
+
+    if (ioctlsocket(fd->secret->md.osfd, FIONREAD, &result) < 0) {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, WSAGetLastError());
+        return -1;
+    }
+    return result;
+}
+
+PROsfd _MD_Accept(
+    PRFileDesc *fd, 
+    PRNetAddr *raddr, 
+    PRUint32 *rlen,
+    PRIntervalTime timeout )
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    SOCKET sock;
+    PRInt32 rv, err;
+
+    while ((sock = accept(osfd, (struct sockaddr *) raddr, rlen)) == -1) 
+    {
+        err = WSAGetLastError();
+        if ((err == WSAEWOULDBLOCK) && (!fd->secret->nonblocking))
+        {
+            if ((rv = socket_io_wait(osfd, READ_FD, timeout)) < 0)
+            {
+                break;
+            }
+        }
+        else
+        {
+            _PR_MD_MAP_ACCEPT_ERROR(err);
+            break;
+        }
+    }
+    return(sock);
+} /* end _MD_accept() */
+
+PRInt32
+_PR_MD_CONNECT(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen, 
+               PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv;
+    int     err;
+
+    if ((rv = connect(osfd, (struct sockaddr *) addr, addrlen)) == -1) 
+    {
+        err = WSAGetLastError();
+        if ((!fd->secret->nonblocking) && (err == WSAEWOULDBLOCK))
+        {
+            rv = socket_io_wait(osfd, CONNECT_FD, timeout);
+            if ( rv < 0 )
+            {
+                return(-1);
+            }
+            else
+            {
+                PR_ASSERT(rv > 0);
+                /* it's connected */
+                return(0);
+            } 
+        }
+        _PR_MD_MAP_CONNECT_ERROR(err);
+    }
+    return rv;
+}
+
+PRInt32
+_PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
+{
+    PRInt32 rv;
+
+    rv = bind(fd->secret->md.osfd, (const struct sockaddr *)&(addr->inet), addrlen);
+
+    if (rv == SOCKET_ERROR)  {
+        _PR_MD_MAP_BIND_ERROR(WSAGetLastError());
+        return -1;
+    }
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_LISTEN(PRFileDesc *fd, PRIntn backlog)
+{
+    PRInt32 rv;
+
+    rv = listen(fd->secret->md.osfd, backlog);
+
+    if (rv == SOCKET_ERROR)  {
+        _PR_MD_MAP_DEFAULT_ERROR(WSAGetLastError());
+        return -1;
+    }
+
+    return 0;
+}
+
+PRInt32
+_PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 
+            PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    int osflags;
+
+    if (0 == flags) {
+        osflags = 0;
+    } else {
+        PR_ASSERT(PR_MSG_PEEK == flags);
+        osflags = MSG_PEEK;
+    }
+    while ((rv = recv( osfd, buf, amount, osflags)) == -1) 
+    {
+        if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
+            && (!fd->secret->nonblocking))
+        {
+            rv = socket_io_wait(osfd, READ_FD, timeout);
+            if ( rv < 0 )
+            {
+                return -1;
+            } 
+        } 
+        else 
+        {
+            _PR_MD_MAP_RECV_ERROR(err);
+            break;
+        }
+    } /* end while() */
+    return(rv);
+}
+
+PRInt32
+_PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+            PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRInt32 bytesSent = 0;
+
+    while(bytesSent < amount ) 
+    {
+        while ((rv = send( osfd, buf, amount, 0 )) == -1) 
+        {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
+                && (!fd->secret->nonblocking))
+            {
+                rv = socket_io_wait(osfd, WRITE_FD, timeout);
+                if ( rv < 0 )
+                {
+                    return -1;
+                }
+            } 
+            else 
+            {
+                _PR_MD_MAP_SEND_ERROR(err);
+                return -1;
+            }
+        }
+        bytesSent += rv;
+        if (fd->secret->nonblocking)
+        {
+            break;
+        }
+        if (bytesSent < amount) 
+        {
+            rv = socket_io_wait(osfd, WRITE_FD, timeout);
+            if ( rv < 0 )
+            {
+                return -1;
+            }
+        }
+    }
+    return bytesSent;
+}
+
+PRInt32
+_PR_MD_SENDTO(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
+              const PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+    PRInt32 bytesSent = 0;
+
+    while(bytesSent < amount) 
+    {
+        while ((rv = sendto( osfd, buf, amount, 0, (struct sockaddr *) addr,
+                addrlen)) == -1) 
+        {
+            if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
+                && (!fd->secret->nonblocking))
+            {
+                rv = socket_io_wait(osfd, WRITE_FD, timeout);
+                if ( rv < 0 )
+                {
+                    return -1;
+                }
+            } 
+            else 
+            {
+                _PR_MD_MAP_SENDTO_ERROR(err);
+                return -1;
+            }
+        }
+        bytesSent += rv;
+        if (fd->secret->nonblocking)
+        {
+            break;
+        }
+        if (bytesSent < amount) 
+        {
+            rv = socket_io_wait(osfd, WRITE_FD, timeout);
+            if (rv < 0) 
+            {
+                return -1;
+            }
+        }
+    }
+    return bytesSent;
+}
+
+PRInt32
+_PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
+                PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
+{
+    PROsfd osfd = fd->secret->md.osfd;
+    PRInt32 rv, err;
+
+    while ((rv = recvfrom( osfd, buf, amount, 0, (struct sockaddr *) addr,
+            addrlen)) == -1) 
+    {
+        if (((err = WSAGetLastError()) == WSAEWOULDBLOCK) 
+            && (!fd->secret->nonblocking))
+        {
+            rv = socket_io_wait(osfd, READ_FD, timeout);
+            if ( rv < 0)
+            {
+                return -1;
+            } 
+        } 
+        else 
+        {
+            _PR_MD_MAP_RECVFROM_ERROR(err);
+            break;
+        }
+    }
+    return(rv);
+}
+
+PRInt32
+_PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout)
+{
+    int index;
+    int sent = 0;
+    int rv;
+
+    for (index=0; index < iov_size; index++) 
+    {
+        rv = _PR_MD_SEND(fd, iov[index].iov_base, iov[index].iov_len, 0, timeout);
+        if (rv > 0) 
+            sent += rv;
+        if ( rv != iov[index].iov_len ) 
+        {
+            if (rv < 0)
+            {
+                if (fd->secret->nonblocking
+                    && (PR_GetError() == PR_WOULD_BLOCK_ERROR)
+                    && (sent > 0))
+                {
+                    return sent;
+                }
+                else
+                {
+                    return -1;
+                }
+            }
+            /* Only a nonblocking socket can have partial sends */
+            PR_ASSERT(fd->secret->nonblocking);
+            return sent;
+        }
+    }
+    return sent;
+}
+
+PRInt32
+_PR_MD_SHUTDOWN(PRFileDesc *fd, PRIntn how)
+{
+PRInt32 rv;
+
+    rv = shutdown(fd->secret->md.osfd, how);
+    if (rv < 0)
+        _PR_MD_MAP_SHUTDOWN_ERROR(WSAGetLastError());
+    return rv;
+}
+
+PRStatus
+_PR_MD_GETSOCKNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
+{
+    PRInt32 rv;
+
+    rv = getsockname((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len);
+    if (rv==0) {
+        return PR_SUCCESS;
+    } else {
+        _PR_MD_MAP_GETSOCKNAME_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+PRStatus
+_PR_MD_GETPEERNAME(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *len)
+{
+    PRInt32 rv;
+
+    rv = getpeername((SOCKET)fd->secret->md.osfd, (struct sockaddr *)addr, len);
+    if (rv==0) {
+        return PR_SUCCESS;
+    } else {
+        _PR_MD_MAP_GETPEERNAME_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+PRStatus
+_PR_MD_GETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen)
+{
+    PRInt32 rv;
+
+    rv = getsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv==0) {
+        return PR_SUCCESS;
+    } else {
+        _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+PRStatus
+_PR_MD_SETSOCKOPT(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen)
+{
+    PRInt32 rv;
+
+    rv = setsockopt((SOCKET)fd->secret->md.osfd, level, optname, optval, optlen);
+    if (rv==0) {
+        return PR_SUCCESS;
+    } else {
+        _PR_MD_MAP_SETSOCKOPT_ERROR(WSAGetLastError());
+        return PR_FAILURE;
+    }
+}
+
+void
+_MD_MakeNonblock(PRFileDesc *f)
+{
+    return; /* do nothing */
+}
+
+
+
+/*
+ * socket_io_wait --
+ *
+ * Wait for socket i/o, periodically checking for interrupt.
+ *
+ * This function returns 1 on success.  On failure, it returns
+ * -1 and sets the error codes.  It never returns 0.
+ */
+#define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5
+
+static PRInt32 socket_io_wait(
+    PROsfd osfd, 
+    PRInt32 fd_type,
+    PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+    struct timeval tv;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntervalTime elapsed, remaining;
+    PRBool wait_for_remaining;
+    fd_set rd_wr, ex;
+    int err, len;
+
+    switch (timeout) {
+        case PR_INTERVAL_NO_WAIT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+            break;
+        case PR_INTERVAL_NO_TIMEOUT:
+            /*
+             * This is a special case of the 'default' case below.
+             * Please see the comments there.
+             */
+            tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+            tv.tv_usec = 0;
+            FD_ZERO(&rd_wr);
+            FD_ZERO(&ex);
+            do {
+                FD_SET(osfd, &rd_wr);
+                FD_SET(osfd, &ex);
+                switch( fd_type )
+                {
+                    case READ_FD:
+                        rv = _MD_SELECT(0, &rd_wr, NULL, NULL, &tv);
+                        break;
+                    case WRITE_FD:
+                        rv = _MD_SELECT(0, NULL, &rd_wr, NULL, &tv);
+                        break;
+                    case CONNECT_FD:
+                        rv = _MD_SELECT(0, NULL, &rd_wr, &ex, &tv);
+                        break;
+                    default:
+                        PR_ASSERT(0);
+                        break;
+                } /* end switch() */
+                if (rv == -1 )
+                {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                    break;
+                }
+                if ( rv > 0 && fd_type == CONNECT_FD )
+                {
+                    /*
+                     * Call Sleep(0) to work around a Winsock timing bug.
+                     */
+                    Sleep(0);
+                    if (FD_ISSET((SOCKET)osfd, &ex))
+                    {
+                        len = sizeof(err);
+                        if (getsockopt(osfd, SOL_SOCKET, SO_ERROR,
+                                (char *) &err, &len) == SOCKET_ERROR)
+                        {  
+                            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+                            return -1;
+                        }
+                        if (err != 0)
+                            _PR_MD_MAP_CONNECT_ERROR(err);
+                        else
+                            PR_SetError(PR_UNKNOWN_ERROR, 0);
+                        return -1;
+                    }
+                    if (FD_ISSET((SOCKET)osfd, &rd_wr))
+                    {
+                        /* it's connected */
+                        return 1;
+                    }
+                    PR_ASSERT(0);
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+            } while (rv == 0);
+            break;
+        default:
+            remaining = timeout;
+            FD_ZERO(&rd_wr);
+            FD_ZERO(&ex);
+            do {
+                /*
+                 * We block in _MD_SELECT for at most
+                 * _PR_INTERRUPT_CHECK_INTERVAL_SECS seconds,
+                 * so that there is an upper limit on the delay
+                 * before the interrupt bit is checked.
+                 */
+                wait_for_remaining = PR_TRUE;
+                tv.tv_sec = PR_IntervalToSeconds(remaining);
+                if (tv.tv_sec > _PR_INTERRUPT_CHECK_INTERVAL_SECS) {
+                    wait_for_remaining = PR_FALSE;
+                    tv.tv_sec = _PR_INTERRUPT_CHECK_INTERVAL_SECS;
+                    tv.tv_usec = 0;
+                } else {
+                    tv.tv_usec = PR_IntervalToMicroseconds(
+                        remaining -
+                        PR_SecondsToInterval(tv.tv_sec));
+                }
+                FD_SET(osfd, &rd_wr);
+                FD_SET(osfd, &ex);
+                switch( fd_type )
+                {
+                    case READ_FD:
+                        rv = _MD_SELECT(0, &rd_wr, NULL, NULL, &tv);
+                        break;
+                    case WRITE_FD:
+                        rv = _MD_SELECT(0, NULL, &rd_wr, NULL, &tv);
+                        break;
+                    case CONNECT_FD:
+                        rv = _MD_SELECT(0, NULL, &rd_wr, &ex, &tv);
+                        break;
+                    default:
+                        PR_ASSERT(0);
+                        break;
+                } /* end switch() */
+                if (rv == -1)
+                {
+                    _PR_MD_MAP_SELECT_ERROR(WSAGetLastError());
+                    break;
+                }
+                if ( rv > 0 && fd_type == CONNECT_FD )
+                {
+                    /*
+                     * Call Sleep(0) to work around a Winsock timing bug.
+                     */
+                    Sleep(0);
+                    if (FD_ISSET((SOCKET)osfd, &ex))
+                    {
+                        len = sizeof(err);
+                        if (getsockopt(osfd, SOL_SOCKET, SO_ERROR,
+                                (char *) &err, &len) == SOCKET_ERROR)
+                        {  
+                            _PR_MD_MAP_GETSOCKOPT_ERROR(WSAGetLastError());
+                            return -1;
+                        }
+                        if (err != 0)
+                            _PR_MD_MAP_CONNECT_ERROR(err);
+                        else
+                            PR_SetError(PR_UNKNOWN_ERROR, 0);
+                        return -1;
+                    }
+                    if (FD_ISSET((SOCKET)osfd, &rd_wr))
+                    {
+                        /* it's connected */
+                        return 1;
+                    }
+                    PR_ASSERT(0);
+                }
+                if (_PR_PENDING_INTERRUPT(me)) {
+                    me->flags &= ~_PR_INTERRUPT;
+                    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+                    rv = -1;
+                    break;
+                }
+                /*
+                 * We loop again if _MD_SELECT timed out and the
+                 * timeout deadline has not passed yet.
+                 */
+                if (rv == 0 )
+                {
+                    if (wait_for_remaining) {
+                        elapsed = remaining;
+                    } else {
+                        elapsed = PR_SecondsToInterval(tv.tv_sec) 
+                                    + PR_MicrosecondsToInterval(tv.tv_usec);
+                    }
+                    if (elapsed >= remaining) {
+                        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+                        rv = -1;
+                        break;
+                    } else {
+                        remaining = remaining - elapsed;
+                    }
+                }
+            } while (rv == 0 );
+            break;
+    }
+    return(rv);
+} /* end socket_io_wait() */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95thred.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/w95thred.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,304 @@
+/* -*- 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 <process.h>  /* for _beginthreadex() */
+
+#if _MSC_VER <= 1200
+/*
+ * VC++ 6.0 doesn't have DWORD_PTR.
+ */
+
+typedef DWORD DWORD_PTR;
+#endif /* _MSC_VER <= 1200 */
+
+/* --- globals ------------------------------------------------ */
+#ifdef _PR_USE_STATIC_TLS
+__declspec(thread) struct PRThread  *_pr_thread_last_run;
+__declspec(thread) struct PRThread  *_pr_currentThread;
+__declspec(thread) struct _PRCPU    *_pr_currentCPU;
+#else
+DWORD _pr_currentThreadIndex;
+DWORD _pr_lastThreadIndex;
+DWORD _pr_currentCPUIndex;
+#endif
+int                           _pr_intsOff = 0; 
+_PRInterruptTable             _pr_interruptTable[] = { { 0 } };
+
+void
+_PR_MD_EARLY_INIT()
+{
+#ifndef _PR_USE_STATIC_TLS
+    _pr_currentThreadIndex = TlsAlloc();
+    _pr_lastThreadIndex = TlsAlloc();
+    _pr_currentCPUIndex = TlsAlloc();
+#endif
+}
+
+void _PR_MD_CLEANUP_BEFORE_EXIT(void)
+{
+    _PR_NT_FreeSids();
+
+    WSACleanup();
+
+#ifndef _PR_USE_STATIC_TLS
+    TlsFree(_pr_currentThreadIndex);
+    TlsFree(_pr_lastThreadIndex);
+    TlsFree(_pr_currentCPUIndex);
+#endif
+}
+
+PRStatus
+_PR_MD_INIT_THREAD(PRThread *thread)
+{
+    if (thread->flags & (_PR_PRIMORDIAL | _PR_ATTACHED)) {
+        /*
+        ** Warning:
+        ** --------
+        ** NSPR requires a real handle to every thread.
+        ** GetCurrentThread() returns a pseudo-handle which
+        ** is not suitable for some thread operations (e.g.,
+        ** suspending).  Therefore, get a real handle from
+        ** the pseudo handle via DuplicateHandle(...)
+        */
+        DuplicateHandle(
+                GetCurrentProcess(),     /* Process of source handle */
+                GetCurrentThread(),      /* Pseudo Handle to dup */
+                GetCurrentProcess(),     /* Process of handle */
+                &(thread->md.handle),    /* resulting handle */
+                0L,                      /* access flags */
+                FALSE,                   /* Inheritable */
+                DUPLICATE_SAME_ACCESS);  /* Options */
+    }
+
+    /* Create the blocking IO semaphore */
+    thread->md.blocked_sema = CreateSemaphore(NULL, 0, 1, NULL);
+    if (thread->md.blocked_sema == NULL)
+        return PR_FAILURE;
+	else
+		return PR_SUCCESS;
+}
+
+static unsigned __stdcall
+pr_root(void *arg)
+{
+    PRThread *thread = (PRThread *)arg;
+    thread->md.start(thread);
+    return 0;
+}
+
+PRStatus 
+_PR_MD_CREATE_THREAD(PRThread *thread, 
+                  void (*start)(void *), 
+                  PRThreadPriority priority, 
+                  PRThreadScope scope, 
+                  PRThreadState state, 
+                  PRUint32 stackSize)
+{
+
+    thread->md.start = start;
+    thread->md.handle = (HANDLE) _beginthreadex(
+                    NULL,
+                    thread->stack->stackSize,
+                    pr_root,
+                    (void *)thread,
+                    CREATE_SUSPENDED,
+                    &(thread->id));
+    if(!thread->md.handle) {
+        return PR_FAILURE;
+    }
+
+    thread->md.id = thread->id;
+    /*
+     * On windows, a thread is created with a thread priority of
+     * THREAD_PRIORITY_NORMAL.
+     */
+    if (priority != PR_PRIORITY_NORMAL) {
+        _PR_MD_SET_PRIORITY(&(thread->md), priority);
+    }
+
+    /* Activate the thread */
+    if ( ResumeThread( thread->md.handle ) != -1)
+        return PR_SUCCESS;
+
+    return PR_FAILURE;
+}
+
+void    
+_PR_MD_YIELD(void)
+{
+    /* Can NT really yield at all? */
+    Sleep(0);
+}
+
+void     
+_PR_MD_SET_PRIORITY(_MDThread *thread, PRThreadPriority newPri)
+{
+    int nativePri;
+    BOOL rv;
+
+    if (newPri < PR_PRIORITY_FIRST) {
+        newPri = PR_PRIORITY_FIRST;
+    } else if (newPri > PR_PRIORITY_LAST) {
+        newPri = PR_PRIORITY_LAST;
+    }
+    switch (newPri) {
+        case PR_PRIORITY_LOW:
+            nativePri = THREAD_PRIORITY_BELOW_NORMAL;
+            break;
+        case PR_PRIORITY_NORMAL:
+            nativePri = THREAD_PRIORITY_NORMAL;
+            break;
+        case PR_PRIORITY_HIGH:
+            nativePri = THREAD_PRIORITY_ABOVE_NORMAL;
+            break;
+        case PR_PRIORITY_URGENT:
+            nativePri = THREAD_PRIORITY_HIGHEST;
+    }
+    rv = SetThreadPriority(thread->handle, nativePri);
+    PR_ASSERT(rv);
+    if (!rv) {
+	PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+                ("PR_SetThreadPriority: can't set thread priority\n"));
+    }
+    return;
+}
+
+void
+_PR_MD_CLEAN_THREAD(PRThread *thread)
+{
+    BOOL rv;
+
+    if (thread->md.blocked_sema) {
+        rv = CloseHandle(thread->md.blocked_sema);
+        PR_ASSERT(rv);
+        thread->md.blocked_sema = 0;
+    }
+
+    if (thread->md.handle) {
+        rv = CloseHandle(thread->md.handle);
+        PR_ASSERT(rv);
+        thread->md.handle = 0;
+    }
+}
+
+void
+_PR_MD_EXIT_THREAD(PRThread *thread)
+{
+    _PR_MD_CLEAN_THREAD(thread);
+    _PR_MD_SET_CURRENT_THREAD(NULL);
+}
+
+
+void
+_PR_MD_EXIT(PRIntn status)
+{
+    _exit(status);
+}
+
+PRInt32 _PR_MD_SETTHREADAFFINITYMASK(PRThread *thread, PRUint32 mask )
+{
+    DWORD_PTR rv;
+
+    rv = SetThreadAffinityMask(thread->md.handle, mask);
+
+    return rv?0:-1;
+}
+
+PRInt32 _PR_MD_GETTHREADAFFINITYMASK(PRThread *thread, PRUint32 *mask)
+{
+    BOOL rv;
+    DWORD_PTR process_mask;
+    DWORD_PTR system_mask;
+
+    rv = GetProcessAffinityMask(GetCurrentProcess(),
+            &process_mask, &system_mask);
+    if (rv)
+        *mask = (PRUint32)process_mask;
+
+    return rv?0:-1;
+}
+
+void 
+_PR_MD_SUSPEND_CPU(_PRCPU *cpu) 
+{
+    _PR_MD_SUSPEND_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_RESUME_CPU(_PRCPU *cpu)
+{
+    _PR_MD_RESUME_THREAD(cpu->thread);
+}
+
+void
+_PR_MD_SUSPEND_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        DWORD previousSuspendCount;
+        /* XXXMB - SuspendThread() is not a blocking call; how do we
+         * know when the thread is *REALLY* suspended?
+         */
+        previousSuspendCount = SuspendThread(thread->md.handle);
+        PR_ASSERT(previousSuspendCount == 0);
+    }
+}
+
+void
+_PR_MD_RESUME_THREAD(PRThread *thread)
+{
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        DWORD previousSuspendCount;
+        previousSuspendCount = ResumeThread(thread->md.handle);
+        PR_ASSERT(previousSuspendCount == 1);
+    }
+}
+
+PRThread*
+_MD_CURRENT_THREAD(void)
+{
+PRThread *thread;
+
+	thread = _MD_GET_ATTACHED_THREAD();
+
+   	if (NULL == thread) {
+		thread = _PRI_AttachThread(
+            PR_USER_THREAD, PR_PRIORITY_NORMAL, NULL, 0);
+	}
+	PR_ASSERT(thread != NULL);
+	return thread;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/win32_errors.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/md/windows/win32_errors.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,565 @@
+/* -*- 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 "prerror.h"
+#include "prlog.h"
+#include <errno.h>
+#include <windows.h>
+
+/*
+ * On Win32, we map three kinds of error codes:
+ * - GetLastError(): for Win32 functions
+ * - WSAGetLastError(): for Winsock functions
+ * - errno: for standard C library functions
+ * 
+ * GetLastError() and WSAGetLastError() return error codes in
+ * non-overlapping ranges, so their error codes (ERROR_* and
+ * WSAE*) can be mapped by the same function.  On the other hand,
+ * errno and GetLastError() have overlapping ranges, so we need
+ * to use a separate function to map errno.
+ *
+ * We do not check for WSAEINPROGRESS and WSAEINTR because we do not
+ * use blocking Winsock 1.1 calls.
+ *
+ * Except for the 'socket' call, we do not check for WSAEINITIALISED.
+ * It is assumed that if Winsock is not initialized, that fact will
+ * be detected at the time we create new sockets.
+ */
+
+static void _MD_win32_map_default_errno(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case EACCES:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case ENOENT:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        default:
+            prError = PR_UNKNOWN_ERROR;
+            break;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_default_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case ERROR_ACCESS_DENIED:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case ERROR_ALREADY_EXISTS:
+            prError = PR_FILE_EXISTS_ERROR;
+            break;
+        case ERROR_CALL_NOT_IMPLEMENTED:
+            prError = PR_NOT_IMPLEMENTED_ERROR;
+            break;
+        case ERROR_DISK_CORRUPT:
+            prError = PR_IO_ERROR; 
+            break;
+        case ERROR_DISK_FULL:
+            prError = PR_NO_DEVICE_SPACE_ERROR;
+            break;
+        case ERROR_DISK_OPERATION_FAILED:
+            prError = PR_IO_ERROR;
+            break;
+        case ERROR_DRIVE_LOCKED:
+            prError = PR_FILE_IS_LOCKED_ERROR;
+            break;
+        case ERROR_FILENAME_EXCED_RANGE:
+            prError = PR_NAME_TOO_LONG_ERROR;
+            break;
+        case ERROR_FILE_CORRUPT:
+            prError = PR_IO_ERROR;
+            break;
+        case ERROR_FILE_EXISTS:
+            prError = PR_FILE_EXISTS_ERROR;
+            break;
+        case ERROR_FILE_INVALID:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        case ERROR_FILE_NOT_FOUND:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        case ERROR_HANDLE_DISK_FULL:
+            prError = PR_NO_DEVICE_SPACE_ERROR;
+            break;
+        case ERROR_INVALID_ADDRESS:
+            prError = PR_ACCESS_FAULT_ERROR;
+            break;
+        case ERROR_INVALID_HANDLE:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        case ERROR_INVALID_NAME:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case ERROR_INVALID_PARAMETER:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case ERROR_INVALID_USER_BUFFER:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case ERROR_LOCKED:
+            prError = PR_FILE_IS_LOCKED_ERROR;
+            break;
+        case ERROR_NETNAME_DELETED:
+            prError = PR_CONNECT_RESET_ERROR;
+            break;
+        case ERROR_NOACCESS:
+            prError = PR_ACCESS_FAULT_ERROR;
+            break;
+        case ERROR_NOT_ENOUGH_MEMORY:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case ERROR_NOT_ENOUGH_QUOTA:
+            prError = PR_OUT_OF_MEMORY_ERROR;
+            break;
+        case ERROR_NOT_READY:
+            prError = PR_IO_ERROR;
+            break;
+        case ERROR_NO_MORE_FILES:
+            prError = PR_NO_MORE_FILES_ERROR;
+            break;
+        case ERROR_OPEN_FAILED:
+            prError = PR_IO_ERROR;
+            break;
+        case ERROR_OPEN_FILES:
+            prError = PR_IO_ERROR;
+            break;
+        case ERROR_OPERATION_ABORTED:
+            prError = PR_OPERATION_ABORTED_ERROR;
+            break;
+        case ERROR_OUTOFMEMORY:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case ERROR_PATH_BUSY:
+            prError = PR_IO_ERROR;
+            break;
+        case ERROR_PATH_NOT_FOUND:
+            prError = PR_FILE_NOT_FOUND_ERROR;
+            break;
+        case ERROR_SEEK_ON_DEVICE:
+            prError = PR_IO_ERROR;
+            break;
+        case ERROR_SHARING_VIOLATION:
+            prError = PR_FILE_IS_BUSY_ERROR;
+            break;
+        case ERROR_STACK_OVERFLOW:
+            prError = PR_ACCESS_FAULT_ERROR;
+            break;
+        case ERROR_TOO_MANY_OPEN_FILES:
+            prError = PR_SYS_DESC_TABLE_FULL_ERROR;
+            break;
+        case ERROR_WRITE_PROTECT:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case WSAEACCES:
+            prError = PR_NO_ACCESS_RIGHTS_ERROR;
+            break;
+        case WSAEADDRINUSE:
+            prError = PR_ADDRESS_IN_USE_ERROR;
+            break;
+        case WSAEADDRNOTAVAIL:
+            prError = PR_ADDRESS_NOT_AVAILABLE_ERROR;
+            break;
+        case WSAEAFNOSUPPORT:
+            prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
+            break;
+        case WSAEALREADY:
+            prError = PR_ALREADY_INITIATED_ERROR;
+            break;
+        case WSAEBADF:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        case WSAECONNABORTED:
+            prError = PR_CONNECT_ABORTED_ERROR;
+            break;
+        case WSAECONNREFUSED:
+            prError = PR_CONNECT_REFUSED_ERROR;
+            break;
+        case WSAECONNRESET:
+            prError = PR_CONNECT_RESET_ERROR;
+            break;
+        case WSAEDESTADDRREQ:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case WSAEFAULT:
+            prError = PR_ACCESS_FAULT_ERROR;
+            break;
+        case WSAEHOSTUNREACH:
+            prError = PR_HOST_UNREACHABLE_ERROR;
+            break;
+        case WSAEINVAL:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case WSAEISCONN:
+            prError = PR_IS_CONNECTED_ERROR;
+            break;
+        case WSAEMFILE:
+            prError = PR_PROC_DESC_TABLE_FULL_ERROR;
+            break;
+        case WSAEMSGSIZE:
+            prError = PR_BUFFER_OVERFLOW_ERROR;
+            break;
+        case WSAENETDOWN:
+            prError = PR_NETWORK_DOWN_ERROR;
+            break;
+        case WSAENETRESET:
+            prError = PR_CONNECT_ABORTED_ERROR;
+            break;
+        case WSAENETUNREACH:
+            prError = PR_NETWORK_UNREACHABLE_ERROR;
+            break;
+        case WSAENOBUFS:
+            prError = PR_INSUFFICIENT_RESOURCES_ERROR;
+            break;
+        case WSAENOPROTOOPT:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case WSAENOTCONN:
+            prError = PR_NOT_CONNECTED_ERROR;
+            break;
+        case WSAENOTSOCK:
+            prError = PR_NOT_SOCKET_ERROR;
+            break;
+        case WSAEOPNOTSUPP:
+            prError = PR_OPERATION_NOT_SUPPORTED_ERROR;
+            break;
+        case WSAEPROTONOSUPPORT:
+            prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR;
+            break;
+        case WSAEPROTOTYPE:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case WSAESHUTDOWN:
+            prError = PR_SOCKET_SHUTDOWN_ERROR;
+            break;
+        case WSAESOCKTNOSUPPORT:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        case WSAETIMEDOUT:
+            prError = PR_CONNECT_ABORTED_ERROR;
+            break;
+        case WSAEWOULDBLOCK:
+            prError = PR_WOULD_BLOCK_ERROR;
+            break;
+        default:
+            prError = PR_UNKNOWN_ERROR;
+            break;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_opendir_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_closedir_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_unix_readdir_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_delete_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+/* The error code for stat() is in errno. */
+void _MD_win32_map_stat_error(PRInt32 err)
+{
+    _MD_win32_map_default_errno(err);
+}
+
+void _MD_win32_map_fstat_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_rename_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+/* The error code for access() is in errno. */
+void _MD_win32_map_access_error(PRInt32 err)
+{
+    _MD_win32_map_default_errno(err);
+}
+
+void _MD_win32_map_mkdir_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_rmdir_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_read_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_transmitfile_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_write_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_lseek_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_fsync_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+/*
+ * For both CloseHandle() and closesocket().
+ */
+void _MD_win32_map_close_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_socket_error(PRInt32 err)
+{
+    PR_ASSERT(err != WSANOTINITIALISED);
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_recv_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_recvfrom_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_send_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEMSGSIZE:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_sendto_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEMSGSIZE:
+            prError = PR_INVALID_ARGUMENT_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_accept_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEOPNOTSUPP:
+            prError = PR_NOT_TCP_SOCKET_ERROR;
+            break;
+        case WSAEINVAL:
+            prError = PR_INVALID_STATE_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_acceptex_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_connect_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEWOULDBLOCK:
+            prError = PR_IN_PROGRESS_ERROR;
+            break;
+        case WSAEINVAL:
+            prError = PR_ALREADY_INITIATED_ERROR;
+            break;
+        case WSAETIMEDOUT:
+            prError = PR_IO_TIMEOUT_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_bind_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEINVAL:
+            prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_listen_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEOPNOTSUPP:
+            prError = PR_NOT_TCP_SOCKET_ERROR;
+            break;
+        case WSAEINVAL:
+            prError = PR_INVALID_STATE_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_shutdown_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_getsockname_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAEINVAL:
+            prError = PR_INVALID_STATE_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_getpeername_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_getsockopt_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_setsockopt_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_open_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+void _MD_win32_map_gethostname_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}
+
+/* Win32 select() only works on sockets.  So in this
+** context, WSAENOTSOCK is equivalent to EBADF on Unix.  
+*/
+void _MD_win32_map_select_error(PRInt32 err)
+{
+    PRErrorCode prError;
+
+    switch (err) {
+        case WSAENOTSOCK:
+            prError = PR_BAD_DESCRIPTOR_ERROR;
+            break;
+        default:
+            _MD_win32_map_default_error(err);
+            return;
+    }
+    PR_SetError(prError, err);
+}
+
+void _MD_win32_map_lockf_error(PRInt32 err)
+{
+    _MD_win32_map_default_error(err);
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/memory/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/memory/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/memory/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/memory/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,7 @@
+/.cvsignore/1.2/Sat May 12 04:47:04 2001//
+/Makefile.in/1.15/Sun Apr 25 15:01:01 2004//
+/prgcleak.c/1.2/Sun Apr 25 15:01:01 2004//
+/prseg.c/3.8/Sun Apr 25 15:01:01 2004//
+/prshm.c/3.4/Sun Apr 25 15:01:01 2004//
+/prshma.c/3.4/Sun Apr 25 15:01:01 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/memory/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/memory/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/memory

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/memory/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/memory/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/memory/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/memory/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,69 @@
+# 
+# ***** 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
+
+CSRCS = prseg.c prshm.c prshma.c
+
+ifdef GC_LEAK_DETECTOR
+CSRCS += prgcleak.c
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+ifdef GC_LEAK_DETECTOR
+INCLUDES += -I$(dist_includedir)/.. -I$(dist_includedir)/../boehm
+endif
+
+DEFINES += -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prgcleak.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prgcleak.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,122 @@
+/* -*- 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):
+ *   Patrick Beard <beard at netscape.com>
+ *
+ * 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 ***** */
+
+/*
+ * prgcleak.c
+ */
+
+#ifdef GC_LEAK_DETECTOR
+
+/* for FILE */
+#include <stdio.h>
+
+/* NSPR stuff */
+#include "generic_threads.h"
+#include "primpl.h"
+
+extern FILE *GC_stdout, *GC_stderr;
+
+extern void GC_gcollect(void);
+extern void GC_clear_roots(void);
+
+static PRStatus PR_CALLBACK scanner(PRThread* t, void** baseAddr,
+                                    PRUword count, void* closure)
+{
+    if (count) {
+        char* begin = (char*)baseAddr;
+        char* end = (char*)(baseAddr + count);
+        GC_mark_range_proc marker = (GC_mark_range_proc) closure;
+        marker(begin, end);
+    }
+    return PR_SUCCESS;
+}
+
+static void mark_all_stacks(GC_mark_range_proc marker)
+{
+    PR_ScanStackPointers(&scanner, (void *)marker);
+}
+
+#if defined(_PR_PTHREADS)
+#define _PR_MD_CURRENT_CPU() 1
+#endif
+
+static void locker(void* mutex)
+{
+    if (_PR_MD_CURRENT_CPU())
+        PR_EnterMonitor(mutex);
+}
+
+static void unlocker(void* mutex)
+{
+    if (_PR_MD_CURRENT_CPU())
+        PR_ExitMonitor(mutex);
+}
+
+static void stopper(void* unused)
+{
+    if (_PR_MD_CURRENT_CPU())
+        PR_SuspendAll();
+}
+
+static void starter(void* unused)
+{
+    if (_PR_MD_CURRENT_CPU())
+        PR_ResumeAll();
+}
+
+void _PR_InitGarbageCollector()
+{
+    void* mutex;
+
+    /* redirect GC's stderr to catch startup leaks. */
+    GC_stderr = fopen("StartupLeaks", "w");
+
+    mutex = PR_NewMonitor();
+    PR_ASSERT(mutex != NULL);
+
+    GC_generic_init_threads(&mark_all_stacks, mutex,
+            &locker, &unlocker,
+            &stopper, &starter);
+}
+
+void _PR_ShutdownGarbageCollector()
+{
+    /* do anything you need to shut down the collector. */
+}
+
+#endif /* GC_LEAK_DETECTOR */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prseg.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prseg.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,93 @@
+/* -*- 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"
+
+#if defined(_PR_PTHREADS)
+
+/*
+** The pthreads version doesn't use these functions.
+*/
+void _PR_InitSegs(void)
+{
+}
+
+#else /* _PR_PTHREADS */
+
+void _PR_InitSegs(void)
+{
+	_PR_MD_INIT_SEGS();
+}
+
+/*
+** Allocate a memory segment. The size value is rounded up to the native
+** system page size and a page aligned portion of memory is returned.
+** This memory is not part of the malloc heap. If "vaddr" is not NULL
+** then PR tries to allocate the segment at the desired virtual address.
+*/
+PRSegment* _PR_NewSegment(PRUint32 size, void *vaddr)
+{
+    PRSegment *seg;
+
+	/* calloc the data structure for the segment */
+    seg = PR_NEWZAP(PRSegment);
+
+    if (seg) {
+	    size = ((size + _pr_pageSize - 1) >> _pr_pageShift) << _pr_pageShift;
+		/*
+		**	Now, allocate the actual segment memory (or map under some OS)
+		**	The OS specific code decides from where or how to allocate memory.
+		*/
+	    if (_PR_MD_ALLOC_SEGMENT(seg, size, vaddr) != PR_SUCCESS) {
+			PR_DELETE(seg);
+			return NULL;
+    	}
+	}
+
+    return seg;
+}
+
+/*
+** Free a memory segment.
+*/
+void _PR_DestroySegment(PRSegment *seg)
+{
+	_PR_MD_FREE_SEGMENT(seg);
+    PR_DELETE(seg);
+}
+
+#endif /* _PR_PTHREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prshm.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prshm.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,156 @@
+/* -*- 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 ***** */
+
+/*
+** prshm.c -- NSPR Named Shared Memory
+**
+** lth. Jul-1999.
+*/
+#include <string.h>
+#include "primpl.h"
+
+extern PRLogModuleInfo *_pr_shm_lm;
+
+
+#if defined PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+/* SysV implementation is in pr/src/md/unix/uxshm.c */
+#elif defined PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+/* Posix implementation is in pr/src/md/unix/uxshm.c */
+#elif defined PR_HAVE_WIN32_NAMED_SHARED_MEMORY
+/* Win32 implementation is in pr/src/md/windows/w32shm.c */
+#else 
+/* 
+**  there is no named_shared_memory 
+*/
+extern PRSharedMemory*  _MD_OpenSharedMemory( const char *name, PRSize size, PRIntn flags, PRIntn mode )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}    
+
+extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}    
+
+extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}    
+
+extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}    
+
+extern PRStatus _MD_DeleteSharedMemory( const char *name )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}    
+#endif /* HAVE_SYSV_NAMED_SHARED_MEMORY */
+
+/*
+** FUNCTION: PR_OpenSharedMemory()
+**
+*/
+PR_IMPLEMENT( PRSharedMemory * )
+    PR_OpenSharedMemory(
+        const char *name,
+        PRSize      size,
+        PRIntn      flags,
+        PRIntn      mode
+)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    return( _PR_MD_OPEN_SHARED_MEMORY( name, size, flags, mode ));
+} /* end PR_OpenSharedMemory() */
+
+/*
+** FUNCTION: PR_AttachSharedMemory()
+**
+*/
+PR_IMPLEMENT( void * )
+    PR_AttachSharedMemory(
+        PRSharedMemory *shm,
+        PRIntn          flags
+)
+{
+    return( _PR_MD_ATTACH_SHARED_MEMORY( shm, flags ));
+} /* end PR_AttachSharedMemory() */
+
+/*
+** FUNCTION: PR_DetachSharedMemory()
+**
+*/
+PR_IMPLEMENT( PRStatus )
+    PR_DetachSharedMemory(
+        PRSharedMemory *shm,
+        void *addr
+)
+{
+    return( _PR_MD_DETACH_SHARED_MEMORY( shm, addr ));
+} /* end PR_DetachSharedMemory() */
+
+/*
+** FUNCTION: PR_CloseSharedMemory()
+**
+*/
+PR_IMPLEMENT( PRStatus )
+    PR_CloseSharedMemory(
+        PRSharedMemory *shm
+)
+{
+    return( _PR_MD_CLOSE_SHARED_MEMORY( shm ));
+} /* end PR_CloseSharedMemory() */
+
+/*
+** FUNCTION: PR_DeleteSharedMemory()
+**
+*/
+PR_EXTERN( PRStatus )
+    PR_DeleteSharedMemory(
+        const char *name
+)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    return(_PR_MD_DELETE_SHARED_MEMORY( name ));
+} /* end PR_DestroySharedMemory() */
+/* end prshm.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prshma.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/memory/prshma.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,142 @@
+/* -*- 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 ***** */
+
+/*
+** prshma.h -- NSPR Anonymous Shared Memory
+**
+** 
+*/
+
+#include "primpl.h"
+
+extern PRLogModuleInfo *_pr_shma_lm;
+
+#if defined(XP_UNIX)
+/* defined in pr/src/md/unix/uxshm.c */
+#elif defined(WIN32)
+/* defined in pr/src/md/windows/w32shm.c */
+#else
+extern PRFileMap * _PR_MD_OPEN_ANON_FILE_MAP( const char *dirName, PRSize size, PRFileMapProtect prot )
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+extern PRStatus _PR_MD_EXPORT_FILE_MAP_AS_STRING(PRFileMap *fm, PRSize bufSize, char *buf)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+extern PRFileMap * _PR_MD_IMPORT_FILE_MAP_FROM_STRING(const char *fmstring)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+#endif
+
+/*
+** PR_OpenAnonFileMap() -- Creates an anonymous file-mapped shared memory
+**
+*/
+PR_IMPLEMENT(PRFileMap*)
+PR_OpenAnonFileMap(
+    const char *dirName,
+    PRSize      size, 
+    PRFileMapProtect prot
+)
+{
+    return(_PR_MD_OPEN_ANON_FILE_MAP( dirName, size, prot ));
+} /* end PR_OpenAnonFileMap() */
+
+/*
+** PR_ProcessAttrSetInheritableFileMap() -- Prepare FileMap for export  
+**   to my children processes via PR_CreateProcess()
+**
+**
+*/
+PR_IMPLEMENT( PRStatus) 
+PR_ProcessAttrSetInheritableFileMap( 
+    PRProcessAttr   *attr,
+    PRFileMap       *fm, 
+    const char      *shmname
+)
+{
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return( PR_FAILURE);
+} /* end PR_ProcessAttrSetInheritableFileMap() */ 
+
+/*
+** PR_GetInheritedFileMap() -- Import a PRFileMap previously exported
+**   by my parent process via PR_CreateProcess()
+**
+*/
+PR_IMPLEMENT( PRFileMap *)
+PR_GetInheritedFileMap( 
+    const char *shmname 
+)
+{
+    PRFileMap   *fm = NULL;
+    PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+    return( fm );
+} /* end PR_GetInhteritedFileMap() */
+
+/*
+** PR_ExportFileMapAsString() -- Creates a string identifying a PRFileMap
+**
+*/
+PR_IMPLEMENT( PRStatus )
+PR_ExportFileMapAsString( 
+    PRFileMap *fm,
+    PRSize    bufSize,
+    char      *buf
+)
+{
+    return( _PR_MD_EXPORT_FILE_MAP_AS_STRING( fm, bufSize, buf ));
+} /* end PR_ExportFileMapAsString() */
+
+/*
+** PR_ImportFileMapFromString() -- Creates a PRFileMap from the identifying string
+**
+**
+*/
+PR_IMPLEMENT( PRFileMap * )
+PR_ImportFileMapFromString( 
+    const char *fmstring
+)
+{
+    return( _PR_MD_IMPORT_FILE_MAP_FROM_STRING(fmstring));
+} /* end PR_ImportFileMapFromString() */
+/* end prshma.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,28 @@
+/.cvsignore/1.2/Sat May 12 04:52:36 2001//
+/Makefile.in/1.19/Mon Nov  8 02:52:56 2004//
+/compile-et.pl/3.9/Sun Apr 25 15:01:01 2004//
+/pralarm.c/3.8/Sun Apr 25 15:01:01 2004//
+/pratom.c/3.18/Sun Apr 25 15:01:01 2004//
+/prcountr.c/3.8/Sun Apr 25 15:01:01 2004//
+/prdtoa.c/4.3/Fri Jul  1 01:19:30 2005//
+/prenv.c/3.11/Sun Apr 25 15:01:01 2004//
+/prerr.c/3.10/Sun Apr 25 15:01:01 2004//
+/prerr.et/3.7/Wed Feb  2 22:27:58 2005//
+/prerr.properties/3.7/Sun Apr 25 15:01:01 2004//
+/prerror.c/3.10/Sun Apr 25 15:01:01 2004//
+/prerrortable.c/3.8/Sun Apr 25 15:01:01 2004//
+/prinit.c/3.44/Fri Oct 21 18:21:43 2005//
+/prinrval.c/3.9/Sun Apr 25 15:01:01 2004//
+/pripc.c/3.5/Sun Apr 25 15:01:01 2004//
+/pripcsem.c/3.5/Sun Apr 25 15:01:01 2004//
+/prlog2.c/3.5/Sun Apr 25 15:01:01 2004//
+/prlong.c/3.6/Sun Apr 25 15:01:01 2004//
+/prnetdb.c/3.48/Sat Dec 24 08:25:30 2005//
+/prolock.c/3.8/Sun Apr 25 15:01:01 2004//
+/prrng.c/1.7/Sun Apr 25 15:01:01 2004//
+/prsystem.c/3.28/Thu Jan 19 22:11:59 2006//
+/prthinfo.c/3.10/Mon Nov  7 22:39:01 2005//
+/prtime.c/3.23/Mon Jan  9 22:48:25 2006//
+/prtpool.c/3.9/Thu Apr 28 22:37:25 2005//
+/prtrace.c/3.8/Sun Apr 25 15:01:01 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/misc

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,111 @@
+# 
+# ***** 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
+
+CSRCS = \
+	pralarm.c  \
+	pratom.c   \
+	prcountr.c \
+	prdtoa.c   \
+	prenv.c    \
+	prerr.c  \
+	prerror.c  \
+	prerrortable.c  \
+	prinit.c   \
+	prinrval.c \
+	pripc.c \
+	prlog2.c   \
+	prlong.c   \
+	prnetdb.c  \
+	prolock.c  \
+	prrng.c    \
+	prsystem.c \
+	prtime.c   \
+	prthinfo.c \
+	prtpool.c \
+	prtrace.c  \
+	$(NULL)
+
+ifndef USE_PTHREADS
+CSRCS += \
+	pripcsem.c \
+	$(NULL)
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+RELEASE_BINS = $(srcdir)/compile-et.pl $(srcdir)/prerr.properties
+
+include $(topsrcdir)/config/rules.mk
+
+# Prevent floating point errors caused by MSVC 6.0 Processor Pack
+# optimizations (bug 207421).  This disables optimizations that
+# could change the precision of floating-point calculations for
+# this single compilation unit.
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+$(OBJDIR)/prdtoa.$(OBJ_SUFFIX): prdtoa.c
+	@$(MAKE_OBJDIR)
+ifeq (,$(filter-out 1100 1200 1300 1310,$(MSC_VER)))
+	$(CC) -Fo$@ -c $(CFLAGS) -Op $(call abspath,$<)
+else
+	$(CC) -Fo$@ -c $(CFLAGS) -fp:precise $(call abspath,$<)
+endif
+endif
+
+#
+# Generate prerr.h, prerr.c, and prerr.properties from prerr.et.
+#
+build_prerr:
+	cd $(srcdir); $(PERL) compile-et.pl prerr.et
+
+export:: $(TARGETS)
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/compile-et.pl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/compile-et.pl	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,140 @@
+#!/usr/bin/perl
+
+# usage: compile-et input.et
+
+# 
+# ***** 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 *****
+
+sub header
+{
+    local($filename, $comment) = @_;
+
+<<EOF
+$comment
+$comment $filename
+$comment This file is automatically generated; please do not edit it.
+EOF
+}
+
+sub table_base
+{
+    local($name) = @_;
+    local($base) = 0;
+
+    for ($i = 0; $i < length($name); $i++) {
+	$base *= 64;
+	$base += index("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_", substr($name, $i, 1)) + 1;
+    }
+    $base -= 0x1000000 if ($base > 0x7fffff);
+    $base*256;
+}
+
+sub code {
+    local($macro, $text) = @_;
+    $code = $table_base + $table_item_count;
+
+    print H "\n";
+    print H "/* ", $text, " */\n";
+    printf H "#define %-40s (%dL)\n", $macro, $code;
+
+    print C "\t{\"", $macro, "\",    \"", $text, "\"},\n";
+
+    print PROPERTIES $macro, "=", $text, "\n";
+
+    $table_item_count++;
+}
+
+
+$filename = $ARGV[0];
+open(INPUT, "< $filename") || die "Can't read $filename: $!\n";
+
+$base = "$filename";
+$base =~ s/\.et$//;
+$base =~ s#.*/##;
+
+open(H, "> ${base}.h") || die "Can't write ${base}.h\n";
+open(C, "> ${base}.c") || die "Can't write ${base}.c\n";
+open(PROPERTIES, "> ${base}.properties") || die "Can't write ${base}.properties\n";
+
+print H "/*\n", &header("${base}.h", " *"), " */\n";
+print C "/*\n", &header("${base}.c", " *"), " */\n";
+print PROPERTIES &header("${base}.properties", "#");
+
+$skipone = 0;
+
+while ($_ = <INPUT>) {
+    next if /^#/;
+
+    if (/^[ \t]*(error_table|et)[ \t]+([a-zA-Z][a-zA-Z0-9_]+) *(-?[0-9]*)/) {
+	$table_name = $2;
+	if ($3) {
+	    $table_base = $3;
+	}
+	else {
+	    $table_base = &table_base($table_name);
+	}
+	$table_item_count = 0;
+
+	print C "#include \"prerror.h\"\n";
+	print C "static const struct PRErrorMessage text[] = {\n";
+    }
+    elsif (/^[ \t]*(error_code|ec)[ \t]+([A-Z_0-9]+),[ \t]*$/) {
+	$skipone = 1;
+	$macro = $2;
+    }
+    elsif (/^[ \t]*(error_code|ec)[ \t]+([A-Z_0-9]+),[ \t]*"(.*)"[ \t]*$/) {
+	&code($2, $3);
+    }
+    elsif ($skipone && /^[ \t]*"(.*)"[ \t]*$/) {
+	&code($macro, $1);
+    }
+}
+
+print H "\n";
+print H "extern void ", $table_name, "_InitializePRErrorTable","(void);\n";
+printf H "#define ERROR_TABLE_BASE_%s (%dL)\n", $table_name, $table_base;
+
+print C "\t{0, 0}\n";
+print C "};\n\n";
+printf C "static const struct PRErrorTable et = { text, \"%s\", %dL, %d };\n",
+    $base, $table_base, $table_item_count;
+print C "\n";
+print C "void ", $table_name, "_InitializePRErrorTable", "(void) {\n";
+print C "    PR_ErrorInstallTable(&et);\n";
+print C "}\n";
+
+0;

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pralarm.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pralarm.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,282 @@
+/* -*- 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"
+
+/**********************************************************************/
+/******************************* PRALARM ******************************/
+/**********************************************************************/
+
+#ifdef XP_MAC
+#include "pralarm.h"
+#else
+#include "obsolete/pralarm.h"
+#endif
+
+struct PRAlarmID {                       /* typedef'd in pralarm.h       */
+    PRCList list;                        /* circular list linkage        */
+    PRAlarm *alarm;                      /* back pointer to owning alarm */
+    PRPeriodicAlarmFn function;          /* function to call for notify  */
+    void *clientData;                    /* opaque client context        */
+    PRIntervalTime period;               /* the client defined period    */
+    PRUint32 rate;                       /* rate of notification         */
+
+    PRUint32 accumulator;                /* keeps track of # notifies    */
+    PRIntervalTime epoch;                /* when timer was started       */
+    PRIntervalTime nextNotify;           /* when we'll next do our thing */
+    PRIntervalTime lastNotify;           /* when we last did our thing   */
+};
+
+typedef enum {alarm_active, alarm_inactive} _AlarmState;
+
+struct PRAlarm {                         /* typedef'd in pralarm.h       */
+    PRCList timers;                      /* base of alarm ids list       */
+    PRLock *lock;                        /* lock used to protect data    */
+    PRCondVar *cond;                     /* condition that used to wait  */
+    PRThread *notifier;                  /* thread to deliver notifies   */
+    PRAlarmID *current;                  /* current alarm being served   */
+    _AlarmState state;                   /* used to delete the alarm     */
+};
+
+static PRAlarmID *pr_getNextAlarm(PRAlarm *alarm, PRAlarmID *id)
+{
+/*
+ * Puts 'id' back into the sorted list iff it's not NULL.
+ * Removes the first element from the list and returns it (or NULL).
+ * List is "assumed" to be short.
+ *
+ * NB: Caller is providing locking
+ */
+    PRCList *timer;
+    PRAlarmID *result = id;
+    PRIntervalTime now = PR_IntervalNow();
+
+    if (!PR_CLIST_IS_EMPTY(&alarm->timers))
+    {    
+        if (id != NULL)  /* have to put this id back in */
+        {        
+            PRIntervalTime idDelta = now - id->nextNotify;
+            timer = alarm->timers.next;
+            do
+            {
+                result = (PRAlarmID*)timer;
+                if ((PRIntervalTime)(now - result->nextNotify) > idDelta)
+                {
+                    PR_INSERT_BEFORE(&id->list, &alarm->timers);
+                    break;
+                }
+                timer = timer->next;
+            } while (timer != &alarm->timers);
+        }
+        result = (PRAlarmID*)(timer = PR_LIST_HEAD(&alarm->timers));
+        PR_REMOVE_LINK(timer);  /* remove it from the list */
+    }
+
+    return result;
+}  /* pr_getNextAlarm */
+
+static PRIntervalTime pr_PredictNextNotifyTime(PRAlarmID *id)
+{
+    PRIntervalTime delta;
+    PRFloat64 baseRate = (PRFloat64)id->period / (PRFloat64)id->rate;
+    PRFloat64 offsetFromEpoch = (PRFloat64)id->accumulator * baseRate;
+
+    id->accumulator += 1;  /* every call advances to next period */
+    id->lastNotify = id->nextNotify;  /* just keeping track of things */
+    id->nextNotify = (PRIntervalTime)(offsetFromEpoch + 0.5);
+
+    delta = id->nextNotify - id->lastNotify;
+    return delta;
+}  /* pr_PredictNextNotifyTime */
+
+static void PR_CALLBACK pr_alarmNotifier(void *arg)
+{
+    /*
+     * This is the root of the notifier thread. There is one such thread
+     * for each PRAlarm. It may service an arbitrary (though assumed to be
+     * small) number of alarms using the same thread and structure. It
+     * continues to run until the alarm is destroyed.
+     */
+    PRAlarmID *id = NULL;
+    PRAlarm *alarm = (PRAlarm*)arg;
+    enum {notify, abort, scan} why = scan;
+
+    while (why != abort)
+    {
+        PRIntervalTime pause;
+
+        PR_Lock(alarm->lock);
+        while (why == scan)
+        {
+            alarm->current = NULL;  /* reset current id */
+            if (alarm->state == alarm_inactive) why = abort;  /* we're toast */
+            else if (why == scan)  /* the dominant case */
+            {
+                id = pr_getNextAlarm(alarm, id);  /* even if it's the same */
+                if (id == NULL)  /* there are no alarms set */
+                    (void)PR_WaitCondVar(alarm->cond, PR_INTERVAL_NO_TIMEOUT);
+                else
+                {
+                    pause = id->nextNotify - (PR_IntervalNow() - id->epoch);
+                    if ((PRInt32)pause <= 0)  /* is this one's time up? */
+                    {
+                        why = notify;  /* set up to do our thing */
+                        alarm->current = id;  /* id we're about to schedule */
+                    }
+                    else
+                        (void)PR_WaitCondVar(alarm->cond, pause);  /* dally */
+                }
+            }
+        }
+        PR_Unlock(alarm->lock);
+
+        if (why == notify)
+        {
+            (void)pr_PredictNextNotifyTime(id);
+            if (!id->function(id, id->clientData, ~pause))
+            {
+                /*
+                 * Notified function decided not to continue. Free
+                 * the alarm id to make sure it doesn't get back on
+                 * the list.
+                 */
+                PR_DELETE(id);  /* free notifier object */
+                id = NULL;  /* so it doesn't get back into the list */
+            }
+            why = scan;  /* so we can cycle through the loop again */
+        }
+    }
+
+}  /* pr_alarm_notifier */
+
+PR_IMPLEMENT(PRAlarm*) PR_CreateAlarm(void)
+{
+    PRAlarm *alarm = PR_NEWZAP(PRAlarm);
+    if (alarm != NULL)
+    {
+        if ((alarm->lock = PR_NewLock()) == NULL) goto done;
+        if ((alarm->cond = PR_NewCondVar(alarm->lock)) == NULL) goto done;
+        alarm->state = alarm_active;
+        PR_INIT_CLIST(&alarm->timers);
+        alarm->notifier = PR_CreateThread(
+            PR_USER_THREAD, pr_alarmNotifier, alarm,
+            PR_GetThreadPriority(PR_GetCurrentThread()),
+            PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (alarm->notifier == NULL) goto done;
+    }
+    return alarm;
+
+done:
+    if (alarm->cond != NULL) PR_DestroyCondVar(alarm->cond);
+    if (alarm->lock != NULL) PR_DestroyLock(alarm->lock);
+    PR_DELETE(alarm);
+    return NULL;
+}  /* CreateAlarm */
+
+PR_IMPLEMENT(PRStatus) PR_DestroyAlarm(PRAlarm *alarm)
+{
+    PRStatus rv;
+
+    PR_Lock(alarm->lock);
+    alarm->state = alarm_inactive;
+    rv = PR_NotifyCondVar(alarm->cond);
+    PR_Unlock(alarm->lock);
+
+    if (rv == PR_SUCCESS)
+        rv = PR_JoinThread(alarm->notifier);
+    if (rv == PR_SUCCESS)
+    {
+        PR_DestroyCondVar(alarm->cond);
+        PR_DestroyLock(alarm->lock);
+        PR_DELETE(alarm);
+    }
+    return rv;
+}  /* PR_DestroyAlarm */
+
+PR_IMPLEMENT(PRAlarmID*) PR_SetAlarm(
+    PRAlarm *alarm, PRIntervalTime period, PRUint32 rate,
+    PRPeriodicAlarmFn function, void *clientData)
+{
+    /*
+     * Create a new periodic alarm an existing current structure.
+     * Set up the context and compute the first notify time (immediate).
+     * Link the new ID into the head of the list (since it's notifying
+     * immediately).
+     */
+
+    PRAlarmID *id = PR_NEWZAP(PRAlarmID);
+
+    if (!id)
+        return NULL;
+
+    id->alarm = alarm;
+    PR_INIT_CLIST(&id->list);
+    id->function = function;
+    id->clientData = clientData;
+    id->period = period;
+    id->rate = rate;
+    id->epoch = id->nextNotify = PR_IntervalNow();
+    (void)pr_PredictNextNotifyTime(id);
+
+    PR_Lock(alarm->lock);
+    PR_INSERT_BEFORE(&id->list, &alarm->timers);
+    PR_NotifyCondVar(alarm->cond);
+    PR_Unlock(alarm->lock);
+
+    return id;
+}  /* PR_SetAlarm */
+
+PR_IMPLEMENT(PRStatus) PR_ResetAlarm(
+    PRAlarmID *id, PRIntervalTime period, PRUint32 rate)
+{
+    /*
+     * Can only be called from within the notify routine. Doesn't
+     * need locking because it can only be called from within the
+     * notify routine.
+     */
+    if (id != id->alarm->current)
+        return PR_FAILURE;
+    id->period = period;
+    id->rate = rate;
+    id->accumulator = 1;
+    id->epoch = PR_IntervalNow();
+    (void)pr_PredictNextNotifyTime(id);
+    return PR_SUCCESS;
+}  /* PR_ResetAlarm */
+
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pratom.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pratom.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,409 @@
+/* -*- 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 ***** */
+
+/*
+**     PR Atomic operations
+*/
+
+
+#include "pratom.h"
+#include "primpl.h"
+
+#include <string.h>
+
+/*
+ * The following is a fallback implementation that emulates
+ * atomic operations for platforms without atomic operations.
+ * If a platform has atomic operations, it should define the
+ * macro _PR_HAVE_ATOMIC_OPS, and the following will not be
+ * compiled in.
+ */
+
+#if !defined(_PR_HAVE_ATOMIC_OPS)
+
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+/*
+ * PR_AtomicDecrement() is used in NSPR's thread-specific data
+ * destructor.  Because thread-specific data destructors may be
+ * invoked after a PR_Cleanup() call, we need an implementation
+ * of the atomic routines that doesn't need NSPR to be initialized.
+ */
+
+/*
+ * We use a set of locks for all the emulated atomic operations.
+ * By hashing on the address of the integer to be locked the
+ * contention between multiple threads should be lessened.
+ *
+ * The number of atomic locks can be set by the environment variable
+ * NSPR_ATOMIC_HASH_LOCKS
+ */
+
+/*
+ * lock counts should be a power of 2
+ */
+#define DEFAULT_ATOMIC_LOCKS	16	/* should be in sync with the number of initializers
+										below */
+#define MAX_ATOMIC_LOCKS		(4 * 1024)
+
+static pthread_mutex_t static_atomic_locks[DEFAULT_ATOMIC_LOCKS] = {
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER,
+        PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER };
+
+#ifdef DEBUG
+static PRInt32 static_hash_lock_counts[DEFAULT_ATOMIC_LOCKS];
+static PRInt32 *hash_lock_counts = static_hash_lock_counts;
+#endif
+
+static PRUint32	num_atomic_locks = DEFAULT_ATOMIC_LOCKS;
+static pthread_mutex_t *atomic_locks = static_atomic_locks;
+static PRUint32 atomic_hash_mask = DEFAULT_ATOMIC_LOCKS - 1;
+
+#define _PR_HASH_FOR_LOCK(ptr) 							\
+			((PRUint32) (((PRUptrdiff) (ptr) >> 2)	^	\
+						((PRUptrdiff) (ptr) >> 8)) &	\
+						atomic_hash_mask)
+
+void _PR_MD_INIT_ATOMIC()
+{
+char *eval;
+int index;
+
+
+	PR_ASSERT(PR_FloorLog2(MAX_ATOMIC_LOCKS) ==
+						PR_CeilingLog2(MAX_ATOMIC_LOCKS));
+
+	PR_ASSERT(PR_FloorLog2(DEFAULT_ATOMIC_LOCKS) ==
+							PR_CeilingLog2(DEFAULT_ATOMIC_LOCKS));
+
+	if (((eval = getenv("NSPR_ATOMIC_HASH_LOCKS")) != NULL)  &&
+		((num_atomic_locks = atoi(eval)) != DEFAULT_ATOMIC_LOCKS)) {
+
+		if (num_atomic_locks > MAX_ATOMIC_LOCKS)
+			num_atomic_locks = MAX_ATOMIC_LOCKS;
+		else {
+			num_atomic_locks = PR_FloorLog2(num_atomic_locks);
+			num_atomic_locks = 1L << num_atomic_locks;
+		}
+		atomic_locks = (pthread_mutex_t *) PR_Malloc(sizeof(pthread_mutex_t) *
+						num_atomic_locks);
+		if (atomic_locks) {
+			for (index = 0; index < num_atomic_locks; index++) {
+				if (pthread_mutex_init(&atomic_locks[index], NULL)) {
+						PR_DELETE(atomic_locks);
+						atomic_locks = NULL;
+						break; 
+				}
+			}
+		}
+#ifdef DEBUG
+		if (atomic_locks) {
+			hash_lock_counts = PR_CALLOC(num_atomic_locks * sizeof(PRInt32));
+			if (hash_lock_counts == NULL) {
+				PR_DELETE(atomic_locks);
+				atomic_locks = NULL;
+			}
+		}
+#endif
+		if (atomic_locks == NULL) {
+			/*
+			 *	Use statically allocated locks
+			 */
+			atomic_locks = static_atomic_locks;
+			num_atomic_locks = DEFAULT_ATOMIC_LOCKS;
+	#ifdef DEBUG
+			hash_lock_counts = static_hash_lock_counts;
+	#endif
+		}
+		atomic_hash_mask = num_atomic_locks - 1;
+	}
+	PR_ASSERT(PR_FloorLog2(num_atomic_locks) ==
+								PR_CeilingLog2(num_atomic_locks));
+}
+
+PRInt32
+_PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    PRInt32 rv;
+    PRInt32 idx = _PR_HASH_FOR_LOCK(val);
+
+    pthread_mutex_lock(&atomic_locks[idx]);
+    rv = ++(*val);
+#ifdef DEBUG
+    hash_lock_counts[idx]++;
+#endif
+    pthread_mutex_unlock(&atomic_locks[idx]);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    PRInt32 rv;
+    PRInt32 idx = _PR_HASH_FOR_LOCK(ptr);
+
+    pthread_mutex_lock(&atomic_locks[idx]);
+    rv = ((*ptr) += val);
+#ifdef DEBUG
+    hash_lock_counts[idx]++;
+#endif
+    pthread_mutex_unlock(&atomic_locks[idx]);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    PRInt32 rv;
+    PRInt32 idx = _PR_HASH_FOR_LOCK(val);
+
+    pthread_mutex_lock(&atomic_locks[idx]);
+    rv = --(*val);
+#ifdef DEBUG
+    hash_lock_counts[idx]++;
+#endif
+    pthread_mutex_unlock(&atomic_locks[idx]);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    PRInt32 rv;
+    PRInt32 idx = _PR_HASH_FOR_LOCK(val);
+
+    pthread_mutex_lock(&atomic_locks[idx]);
+    rv = *val;
+    *val = newval;
+#ifdef DEBUG
+    hash_lock_counts[idx]++;
+#endif
+    pthread_mutex_unlock(&atomic_locks[idx]);
+    return rv;
+}
+#else  /* _PR_PTHREADS && !_PR_DCETHREADS */
+/*
+ * We use a single lock for all the emulated atomic operations.
+ * The lock contention should be acceptable.
+ */
+static PRLock *atomic_lock = NULL;
+void _PR_MD_INIT_ATOMIC(void)
+{
+    if (atomic_lock == NULL) {
+        atomic_lock = PR_NewLock();
+    }
+}
+
+PRInt32
+_PR_MD_ATOMIC_INCREMENT(PRInt32 *val)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+    PR_Lock(atomic_lock);
+    rv = ++(*val);
+    PR_Unlock(atomic_lock);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 val)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+    PR_Lock(atomic_lock);
+    rv = ((*ptr) += val);
+    PR_Unlock(atomic_lock);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_DECREMENT(PRInt32 *val)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+    PR_Lock(atomic_lock);
+    rv = --(*val);
+    PR_Unlock(atomic_lock);
+    return rv;
+}
+
+PRInt32
+_PR_MD_ATOMIC_SET(PRInt32 *val, PRInt32 newval)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+    PR_Lock(atomic_lock);
+    rv = *val;
+    *val = newval;
+    PR_Unlock(atomic_lock);
+    return rv;
+}
+#endif  /* _PR_PTHREADS && !_PR_DCETHREADS */
+
+#endif  /* !_PR_HAVE_ATOMIC_OPS */
+
+void _PR_InitAtomic(void)
+{
+    _PR_MD_INIT_ATOMIC();
+}
+
+PR_IMPLEMENT(PRInt32)
+PR_AtomicIncrement(PRInt32 *val)
+{
+    return _PR_MD_ATOMIC_INCREMENT(val);
+}
+
+PR_IMPLEMENT(PRInt32)
+PR_AtomicDecrement(PRInt32 *val)
+{
+    return _PR_MD_ATOMIC_DECREMENT(val);
+}
+
+PR_IMPLEMENT(PRInt32)
+PR_AtomicSet(PRInt32 *val, PRInt32 newval)
+{
+    return _PR_MD_ATOMIC_SET(val, newval);
+}
+
+PR_IMPLEMENT(PRInt32)
+PR_AtomicAdd(PRInt32 *ptr, PRInt32 val)
+{
+    return _PR_MD_ATOMIC_ADD(ptr, val);
+}
+/*
+ * For platforms, which don't support the CAS (compare-and-swap) instruction
+ * (or an equivalent), the stack operations are implemented by use of PRLock
+ */
+
+PR_IMPLEMENT(PRStack *)
+PR_CreateStack(const char *stack_name)
+{
+PRStack *stack;
+
+    if (!_pr_initialized) {
+        _PR_ImplicitInitialization();
+    }
+
+    if ((stack = PR_NEW(PRStack)) == NULL) {
+		return NULL;
+	}
+	if (stack_name) {
+		stack->prstk_name = (char *) PR_Malloc(strlen(stack_name) + 1);
+		if (stack->prstk_name == NULL) {
+			PR_DELETE(stack);
+			return NULL;
+		}
+		strcpy(stack->prstk_name, stack_name);
+	} else
+		stack->prstk_name = NULL;
+
+#ifndef _PR_HAVE_ATOMIC_CAS
+    stack->prstk_lock = PR_NewLock();
+	if (stack->prstk_lock == NULL) {
+		PR_Free(stack->prstk_name);
+		PR_DELETE(stack);
+		return NULL;
+	}
+#endif /* !_PR_HAVE_ATOMIC_CAS */
+
+	stack->prstk_head.prstk_elem_next = NULL;
+	
+    return stack;
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_DestroyStack(PRStack *stack)
+{
+	if (stack->prstk_head.prstk_elem_next != NULL) {
+		PR_SetError(PR_INVALID_STATE_ERROR, 0);
+		return PR_FAILURE;
+	}
+
+	if (stack->prstk_name)
+		PR_Free(stack->prstk_name);
+#ifndef _PR_HAVE_ATOMIC_CAS
+	PR_DestroyLock(stack->prstk_lock);
+#endif /* !_PR_HAVE_ATOMIC_CAS */
+	PR_DELETE(stack);
+
+	return PR_SUCCESS;
+}
+
+#ifndef _PR_HAVE_ATOMIC_CAS
+
+PR_IMPLEMENT(void)
+PR_StackPush(PRStack *stack, PRStackElem *stack_elem)
+{
+    PR_Lock(stack->prstk_lock);
+	stack_elem->prstk_elem_next = stack->prstk_head.prstk_elem_next;
+	stack->prstk_head.prstk_elem_next = stack_elem;
+    PR_Unlock(stack->prstk_lock);
+    return;
+}
+
+PR_IMPLEMENT(PRStackElem *)
+PR_StackPop(PRStack *stack)
+{
+PRStackElem *element;
+
+    PR_Lock(stack->prstk_lock);
+	element = stack->prstk_head.prstk_elem_next;
+	if (element != NULL) {
+		stack->prstk_head.prstk_elem_next = element->prstk_elem_next;
+		element->prstk_elem_next = NULL;	/* debugging aid */
+	}
+    PR_Unlock(stack->prstk_lock);
+    return element;
+}
+#endif /* !_PR_HAVE_ATOMIC_CAS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prcountr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prcountr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,506 @@
+/* -*- 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 ***** */
+
+/*
+** prcountr.c -- NSPR Instrumentation Counters
+**
+** Implement the interface defined in prcountr.h
+**
+** Design Notes:
+**
+** The Counter Facility (CF) has a single anchor: qNameList.      
+** The anchor is a PRCList. qNameList is a list of links in QName
+** structures. From qNameList any QName structure and its
+** associated RName structure can be located. 
+** 
+** For each QName, a list of RName structures is anchored at
+** rnLink in the QName structure.
+** 
+** The counter itself is embedded in the RName structure.
+** 
+** For manipulating the counter database, single lock is used to
+** protect the entire list: counterLock.
+**
+** A PRCounterHandle, defined in prcountr.h, is really a pointer
+** to a RName structure. References by PRCounterHandle are
+** dead-reconed to the RName structure. The PRCounterHandle is
+** "overloaded" for traversing the QName structures; only the
+** function PR_FindNextQnameHandle() uses this overloading.
+**
+** 
+** ToDo (lth): decide on how to lock or atomically update
+** individual counters. Candidates are: the global lock; a lock
+** per RName structure; Atomic operations (Note that there are
+** not adaquate atomic operations (yet) to achieve this goal). At
+** this writing (6/19/98) , the update of the counter variable in
+** a QName structure is unprotected.
+**
+*/
+
+#include "prcountr.h"
+#include "prclist.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmem.h"
+#include <string.h>
+
+/*
+**
+*/
+typedef struct QName
+{
+    PRCList link;
+    PRCList rNameList;
+    char    name[PRCOUNTER_NAME_MAX+1];
+} QName;
+
+/*
+**
+*/
+typedef struct RName
+{
+    PRCList link;
+    QName   *qName;
+    PRLock  *lock;
+    volatile PRUint32   counter;    
+    char    name[PRCOUNTER_NAME_MAX+1]; 
+    char    desc[PRCOUNTER_DESC_MAX+1]; 
+} RName;
+
+
+/*
+** Define the Counter Facility database
+*/
+static PRLock  *counterLock;
+static PRCList qNameList;
+static PRLogModuleInfo *lm;
+
+/*
+** _PR_CounterInitialize() -- Initialize the Counter Facility
+**
+*/
+static void _PR_CounterInitialize( void )
+{
+    /*
+    ** This function should be called only once
+    */
+    PR_ASSERT( counterLock == NULL );
+    
+    counterLock = PR_NewLock();
+    PR_INIT_CLIST( &qNameList );
+    lm = PR_NewLogModule("counters");
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Initialization complete"));
+
+    return;
+} /* end _PR_CounterInitialize() */
+
+/*
+** PR_CreateCounter() -- Create a counter
+**
+**  ValidateArguments
+**  Lock
+**  if (qName not already in database)
+**      NewQname
+**  if (rName already in database )
+**      Assert
+**  else NewRname
+**  NewCounter
+**  link 'em up
+**  Unlock
+**
+*/
+PR_IMPLEMENT(PRCounterHandle) 
+	PR_CreateCounter( 
+		const char *qName, 
+    	const char *rName, 
+        const char *description 
+) 
+{
+    QName   *qnp;
+    RName   *rnp;
+    PRBool  matchQname = PR_FALSE;
+
+    /* Self initialize, if necessary */
+    if ( counterLock == NULL )
+        _PR_CounterInitialize();
+
+    /* Validate input arguments */
+    PR_ASSERT( strlen(qName) <= PRCOUNTER_NAME_MAX );
+    PR_ASSERT( strlen(rName) <= PRCOUNTER_NAME_MAX );
+    PR_ASSERT( strlen(description) <= PRCOUNTER_DESC_MAX );
+
+    /* Lock the Facility */
+    PR_Lock( counterLock );
+
+    /* Do we already have a matching QName? */
+    if (!PR_CLIST_IS_EMPTY( &qNameList ))
+    {
+        qnp = (QName *) PR_LIST_HEAD( &qNameList );
+        do {
+            if ( strcmp(qnp->name, qName) == 0)
+            {
+                matchQname = PR_TRUE;
+                break;
+            }
+            qnp = (QName *)PR_NEXT_LINK( &qnp->link );
+        } while( qnp != (QName *)PR_LIST_HEAD( &qNameList ));
+    }
+    /*
+    ** If we did not find a matching QName,
+    **    allocate one and initialize it.
+    **    link it onto the qNameList.
+    **
+    */
+    if ( matchQname != PR_TRUE )
+    {
+        qnp = PR_NEWZAP( QName );
+        PR_ASSERT( qnp != NULL );
+        PR_INIT_CLIST( &qnp->link ); 
+        PR_INIT_CLIST( &qnp->rNameList ); 
+        strcpy( qnp->name, qName );
+        PR_APPEND_LINK( &qnp->link, &qNameList ); 
+    }
+
+    /* Do we already have a matching RName? */
+    if (!PR_CLIST_IS_EMPTY( &qnp->rNameList ))
+    {
+        rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList );
+        do {
+            /*
+            ** No duplicate RNames are allowed within a QName
+            **
+            */
+            PR_ASSERT( strcmp(rnp->name, rName));
+            rnp = (RName *)PR_NEXT_LINK( &rnp->link );
+        } while( rnp != (RName *)PR_LIST_HEAD( &qnp->rNameList ));
+    }
+
+    /* Get a new RName structure; initialize its members */
+    rnp = PR_NEWZAP( RName );
+    PR_ASSERT( rnp != NULL );
+    PR_INIT_CLIST( &rnp->link );
+    strcpy( rnp->name, rName );
+    strcpy( rnp->desc, description );
+    rnp->lock = PR_NewLock();
+    if ( rnp->lock == NULL )
+    {
+        PR_ASSERT(0);
+    }
+
+    PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */    
+    rnp->qName = qnp;                       /* point the RName to the QName */
+
+    /* Unlock the Facility */
+    PR_Unlock( counterLock );
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Create: QName: %s %p, RName: %s %p\n\t",
+        qName, qnp, rName, rnp ));
+
+    return((PRCounterHandle)rnp);
+} /*  end PR_CreateCounter() */
+  
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_DestroyCounter( 
+		PRCounterHandle handle 
+)
+{
+    RName   *rnp = (RName *)handle;
+    QName   *qnp = rnp->qName;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting: QName: %s, RName: %s", 
+        qnp->name, rnp->name));
+
+    /* Lock the Facility */
+    PR_Lock( counterLock );
+
+    /*
+    ** Remove RName from the list of RNames in QName
+    ** and free RName
+    */
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting RName: %s, %p", 
+        rnp->name, rnp));
+    PR_REMOVE_LINK( &rnp->link );
+    PR_Free( rnp->lock );
+    PR_DELETE( rnp );
+
+    /*
+    ** If this is the last RName within QName
+    **   remove QName from the qNameList and free it
+    */
+    if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) )
+    {
+        PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting unused QName: %s, %p", 
+            qnp->name, qnp));
+        PR_REMOVE_LINK( &qnp->link );
+        PR_DELETE( qnp );
+    } 
+
+    /* Unlock the Facility */
+    PR_Unlock( counterLock );
+    return;
+} /*  end PR_DestroyCounter() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRCounterHandle) 
+	PR_GetCounterHandleFromName( 
+    	const char *qName, 
+    	const char *rName 
+)
+{
+    const char    *qn, *rn, *desc;
+    PRCounterHandle     qh, rh = NULL;
+    RName   *rnp = NULL;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounterHandleFromName:\n\t"
+        "QName: %s, RName: %s", qName, rName ));
+
+    qh = PR_FindNextCounterQname( NULL );
+    while (qh != NULL)
+    {
+        rh = PR_FindNextCounterRname( NULL, qh );
+        while ( rh != NULL )
+        {
+            PR_GetCounterNameFromHandle( rh, &qn, &rn, &desc );
+            if ( (strcmp( qName, qn ) == 0)
+                && (strcmp( rName, rn ) == 0 ))
+            {
+                rnp = (RName *)rh;
+                goto foundIt;
+            }
+            rh = PR_FindNextCounterRname( rh, qh );
+        }
+        qh = PR_FindNextCounterQname( NULL );
+    }
+
+foundIt:
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp ));
+    return(rh);
+} /*  end PR_GetCounterHandleFromName() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_GetCounterNameFromHandle( 
+    	PRCounterHandle handle,  
+	    const char **qName, 
+	    const char **rName, 
+		const char **description 
+)
+{
+    RName   *rnp = (RName *)handle;
+    QName   *qnp = rnp->qName;
+
+    *qName = qnp->name;
+    *rName = rnp->name;
+    *description = rnp->desc;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterNameFromHandle: "
+        "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", 
+        qnp, rnp, qnp->name, rnp->name, rnp->desc ));
+
+    return;
+} /*  end PR_GetCounterNameFromHandle() */
+
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_IncrementCounter( 
+		PRCounterHandle handle
+)
+{
+    PR_Lock(((RName *)handle)->lock);
+    ((RName *)handle)->counter++;
+    PR_Unlock(((RName *)handle)->lock);
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Increment: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return;
+} /*  end PR_IncrementCounter() */
+
+
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_DecrementCounter( 
+		PRCounterHandle handle
+)
+{
+    PR_Lock(((RName *)handle)->lock);
+    ((RName *)handle)->counter--;
+    PR_Unlock(((RName *)handle)->lock);
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Decrement: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return;
+} /*  end PR_DecrementCounter()  */
+
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_AddToCounter( 
+    	PRCounterHandle handle, 
+	    PRUint32 value 
+)
+{
+    PR_Lock(((RName *)handle)->lock);
+    ((RName *)handle)->counter += value;
+    PR_Unlock(((RName *)handle)->lock);
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: AddToCounter: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return;
+} /*  end PR_AddToCounter() */
+
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_SubtractFromCounter( 
+    	PRCounterHandle handle, 
+	    PRUint32 value 
+)
+{
+    PR_Lock(((RName *)handle)->lock);
+    ((RName *)handle)->counter -= value;
+    PR_Unlock(((RName *)handle)->lock);
+    
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SubtractFromCounter: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return;
+} /*  end  PR_SubtractFromCounter() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRUint32) 
+	PR_GetCounter( 
+		PRCounterHandle handle 
+)
+{
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounter: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return(((RName *)handle)->counter);
+} /*  end  PR_GetCounter() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_SetCounter( 
+		PRCounterHandle handle, 
+		PRUint32 value 
+)
+{
+    ((RName *)handle)->counter = value;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SetCounter: %p, %ld", 
+        handle, ((RName *)handle)->counter ));
+
+    return;
+} /*  end  PR_SetCounter() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRCounterHandle) 
+	PR_FindNextCounterQname( 
+        PRCounterHandle handle
+)
+{
+    QName *qnp = (QName *)handle;
+
+    if ( PR_CLIST_IS_EMPTY( &qNameList ))
+            qnp = NULL;
+    else if ( qnp == NULL )
+        qnp = (QName *)PR_LIST_HEAD( &qNameList );
+    else if ( PR_NEXT_LINK( &qnp->link ) ==  &qNameList )
+        qnp = NULL;
+    else  
+        qnp = (QName *)PR_NEXT_LINK( &qnp->link );
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextQname: Handle: %p, Returns: %p", 
+        handle, qnp ));
+
+    return((PRCounterHandle)qnp);
+} /*  end  PR_FindNextCounterQname() */
+
+
+/*
+**
+*/
+PR_IMPLEMENT(PRCounterHandle) 
+	PR_FindNextCounterRname( 
+        PRCounterHandle rhandle, 
+        PRCounterHandle qhandle 
+)
+{
+    RName *rnp = (RName *)rhandle;
+    QName *qnp = (QName *)qhandle;
+
+
+    if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ))
+        rnp = NULL;
+    else if ( rnp == NULL )
+        rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList );
+    else if ( PR_NEXT_LINK( &rnp->link ) ==  &qnp->rNameList )
+        rnp = NULL;
+    else
+        rnp = (RName *)PR_NEXT_LINK( &rnp->link );
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", 
+        rhandle, qhandle, rnp ));
+
+    return((PRCounterHandle)rnp);
+} /*  end PR_FindNextCounterRname() */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prdtoa.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prdtoa.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3515 @@
+/* -*- 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"
+
+#define MULTIPLE_THREADS
+#define ACQUIRE_DTOA_LOCK(n)	PR_Lock(dtoa_lock[n])
+#define FREE_DTOA_LOCK(n)	PR_Unlock(dtoa_lock[n])
+
+static PRLock *dtoa_lock[2];
+
+void _PR_InitDtoa(void)
+{
+    dtoa_lock[0] = PR_NewLock();
+    dtoa_lock[1] = PR_NewLock();
+}
+
+void _PR_CleanupDtoa(void)
+{
+    PR_DestroyLock(dtoa_lock[0]);
+    dtoa_lock[0] = NULL;
+    PR_DestroyLock(dtoa_lock[1]);
+    dtoa_lock[1] = NULL;
+
+    /* FIXME: deal with freelist and p5s. */
+}
+
+#if defined(__arm) || defined(__arm__) || defined(__arm26__) \
+    || defined(__arm32__)
+#define IEEE_ARM
+#elif defined(IS_LITTLE_ENDIAN)
+#define IEEE_8087
+#else
+#define IEEE_MC68k
+#endif
+
+#define Long PRInt32
+#define ULong PRUint32
+#define NO_LONG_LONG
+
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to David M. Gay (dmg at acm dot org,
+ * with " at " changed at "@" and " dot " changed to ".").	*/
+
+/* On a machine with IEEE extended-precision registers, it is
+ * necessary to specify double-precision (53-bit) rounding precision
+ * before invoking strtod or dtoa.  If the machine uses (the equivalent
+ * of) Intel 80x87 arithmetic, the call
+ *	_control87(PC_53, MCW_PC);
+ * does this with many compilers.  Whether this or another call is
+ * appropriate depends on the compiler; for this to work, it may be
+ * necessary to #include "float.h" or another system-dependent header
+ * file.
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE).  With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule.  Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ *	1. We only require IEEE, IBM, or VAX double-precision
+ *		arithmetic (not IEEE double-extended).
+ *	2. We get by with floating-point arithmetic in a case that
+ *		Clinger missed -- when we're computing d * 10^n
+ *		for a small integer d and the integer n is not too
+ *		much larger than 22 (the maximum integer k for which
+ *		we can represent 10^k exactly), we may be able to
+ *		compute (d*10^k) * 10^(e-k) with just one roundoff.
+ *	3. Rather than a bit-at-a-time adjustment of the binary
+ *		result in the hard case, we use floating-point
+ *		arithmetic to determine the adjustment to within
+ *		one bit; only in really hard cases do we need to
+ *		compute a second residual.
+ *	4. Because of 3., we don't need a large table of powers of 10
+ *		for ten-to-e (just some small tables, e.g. of 10^k
+ *		for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
+ *	significant byte has the lowest address.
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
+ *	significant byte has the lowest address.
+ * #define IEEE_ARM for IEEE-arithmetic machines where the two words
+ *	in a double are stored in big endian order but the two shorts
+ *	in a word are still stored in little endian order.
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic (D_floating).
+ * #define No_leftright to omit left-right logic in fast floating-point
+ *	computation of dtoa.
+ * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ *	and strtod and dtoa should round accordingly.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3
+ *	and Honor_FLT_ROUNDS is not #defined.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ *	that use extended-precision instructions to compute rounded
+ *	products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ *	products but inaccurate quotients, e.g., for Intel i860.
+ * #define NO_LONG_LONG on machines that do not have a "long long"
+ *	integer type (of >= 64 bits).  On such machines, you can
+ *	#define Just_16 to store 16 bits per 32-bit Long when doing
+ *	high-precision integer arithmetic.  Whether this speeds things
+ *	up or slows things down depends on the machine and the number
+ *	being converted.  If long long is available and the name is
+ *	something other than "long long", #define Llong to be the name,
+ *	and if "unsigned Llong" does not work as an unsigned version of
+ *	Llong, #define #ULLong to be the corresponding unsigned type.
+ * #define KR_headers for old-style C function headers.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ *	define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ *	FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ *	if memory is available and otherwise does something you deem
+ *	appropriate.  If MALLOC is undefined, malloc will be invoked
+ *	directly -- and assumed always to succeed.
+ * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
+ *	memory allocations from a private pool of memory when possible.
+ *	When used, the private pool is PRIVATE_MEM bytes long:  2304 bytes,
+ *	unless #defined to be a different length.  This default length
+ *	suffices to get rid of MALLOC calls except for unusual cases,
+ *	such as decimal-to-binary conversion of a very long string of
+ *	digits.  The longest string dtoa can return is about 751 bytes
+ *	long.  For conversions by strtod of strings of 800 digits and
+ *	all dtoa conversions in single-threaded executions with 8-byte
+ *	pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte
+ *	pointers, PRIVATE_MEM >= 7112 appears adequate.
+ * #define INFNAN_CHECK on IEEE systems to cause strtod to check for
+ *	Infinity and NaN (case insensitively).  On some systems (e.g.,
+ *	some HP systems), it may be necessary to #define NAN_WORD0
+ *	appropriately -- to the most significant word of a quiet NaN.
+ *	(On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
+ *	When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined,
+ *	strtod also accepts (case insensitively) strings of the form
+ *	NaN(x), where x is a string of hexadecimal digits and spaces;
+ *	if there is only one string of hexadecimal digits, it is taken
+ *	for the 52 fraction bits of the resulting NaN; if there are two
+ *	or more strings of hex digits, the first is for the high 20 bits,
+ *	the second and subsequent for the low 32 bits, with intervening
+ *	white space ignored; but if this results in none of the 52
+ *	fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0
+ *	and NAN_WORD1 are used instead.
+ * #define MULTIPLE_THREADS if the system offers preemptively scheduled
+ *	multiple threads.  In this case, you must provide (or suitably
+ *	#define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed
+ *	by FREE_DTOA_LOCK(n) for n = 0 or 1.  (The second lock, accessed
+ *	in pow5mult, ensures lazy evaluation of only one copy of high
+ *	powers of 5; omitting this lock would introduce a small
+ *	probability of wasting memory, but would otherwise be harmless.)
+ *	You must also invoke freedtoa(s) to free the value s returned by
+ *	dtoa.  You may do so whether or not MULTIPLE_THREADS is #defined.
+ * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that
+ *	avoids underflows on inputs whose result does not underflow.
+ *	If you #define NO_IEEE_Scale on a machine that uses IEEE-format
+ *	floating-point numbers and flushes underflows to zero rather
+ *	than implementing gradual underflow, then you must also #define
+ *	Sudden_Underflow.
+ * #define YES_ALIAS to permit aliasing certain double values with
+ *	arrays of ULongs.  This leads to slightly better code with
+ *	some compilers and was always used prior to 19990916, but it
+ *	is not strictly legal and can cause trouble with aggressively
+ *	optimizing compilers (e.g., gcc 2.95.1 under -O2).
+ * #define USE_LOCALE to use the current locale's decimal_point value.
+ * #define SET_INEXACT if IEEE arithmetic is being used and extra
+ *	computation should be done to set the inexact flag when the
+ *	result is inexact and avoid setting inexact when the result
+ *	is exact.  In this case, dtoa.c must be compiled in
+ *	an environment, perhaps provided by #include "dtoa.c" in a
+ *	suitable wrapper, that defines two functions,
+ *		int get_inexact(void);
+ *		void clear_inexact(void);
+ *	such that get_inexact() returns a nonzero value if the
+ *	inexact bit is already set, and clear_inexact() sets the
+ *	inexact bit to 0.  When SET_INEXACT is #defined, strtod
+ *	also does extra computations to set the underflow and overflow
+ *	flags when appropriate (i.e., when the result is tiny and
+ *	inexact or when it is a numeric value rounded to +-infinity).
+ * #define NO_ERRNO if strtod should not assign errno = ERANGE when
+ *	the result overflows to +-Infinity or underflows to 0.
+ */
+
+#ifndef Long
+#define Long long
+#endif
+#ifndef ULong
+typedef unsigned Long ULong;
+#endif
+
+#ifdef DEBUG
+#include "stdio.h"
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+#include "stdlib.h"
+#include "string.h"
+
+#ifdef USE_LOCALE
+#include "locale.h"
+#endif
+
+#ifdef MALLOC
+#ifdef KR_headers
+extern char *MALLOC();
+#else
+extern void *MALLOC(size_t);
+#endif
+#else
+#define MALLOC malloc
+#endif
+
+#ifndef Omit_Private_Memory
+#ifndef PRIVATE_MEM
+#define PRIVATE_MEM 2304
+#endif
+#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
+static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
+#endif
+
+#undef IEEE_Arith
+#undef Avoid_Underflow
+#ifdef IEEE_MC68k
+#define IEEE_Arith
+#endif
+#ifdef IEEE_8087
+#define IEEE_Arith
+#endif
+#ifdef IEEE_ARM
+#define IEEE_Arith
+#endif
+
+#include "errno.h"
+
+#ifdef Bad_float_h
+
+#ifdef IEEE_Arith
+#define DBL_DIG 15
+#define DBL_MAX_10_EXP 308
+#define DBL_MAX_EXP 1024
+#define FLT_RADIX 2
+#endif /*IEEE_Arith*/
+
+#ifdef IBM
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 75
+#define DBL_MAX_EXP 63
+#define FLT_RADIX 16
+#define DBL_MAX 7.2370055773322621e+75
+#endif
+
+#ifdef VAX
+#define DBL_DIG 16
+#define DBL_MAX_10_EXP 38
+#define DBL_MAX_EXP 127
+#define FLT_RADIX 2
+#define DBL_MAX 1.7014118346046923e+38
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647
+#endif
+
+#else /* ifndef Bad_float_h */
+#include "float.h"
+/*
+ * MacOS 10.2 defines the macro FLT_ROUNDS to an internal function
+ * which does not exist on 10.1.  We can safely #define it to 1 here
+ * to allow 10.2 builds to run on 10.1, since we can't use fesetround()
+ * (which does not exist on 10.1 either).
+ */
+#if defined(XP_MACOSX) && (!defined(MAC_OS_X_VERSION_10_2) || \
+    MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_2)
+#undef FLT_ROUNDS
+#define FLT_ROUNDS 1
+#endif /* DT < 10.2 */
+#endif /* Bad_float_h */
+
+#ifndef __MATH_H__
+#include "math.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef CONST
+#ifdef KR_headers
+#define CONST /* blank */
+#else
+#define CONST const
+#endif
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_ARM) + defined(VAX) + defined(IBM) != 1
+Exactly one of IEEE_8087, IEEE_MC68k, IEEE_ARM, VAX, or IBM should be defined.
+#endif
+
+typedef union { double d; ULong L[2]; } U;
+
+#ifdef YES_ALIAS
+#define dval(x) x
+#ifdef IEEE_8087
+#define word0(x) ((ULong *)&x)[1]
+#define word1(x) ((ULong *)&x)[0]
+#else
+#define word0(x) ((ULong *)&x)[0]
+#define word1(x) ((ULong *)&x)[1]
+#endif
+#else
+#ifdef IEEE_8087
+#define word0(x) ((U*)&x)->L[1]
+#define word1(x) ((U*)&x)->L[0]
+#else
+#define word0(x) ((U*)&x)->L[0]
+#define word1(x) ((U*)&x)->L[1]
+#endif
+#define dval(x) ((U*)&x)->d
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_8087) + defined(IEEE_ARM) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#ifdef IEEE_Arith
+#define Exp_shift  20
+#define Exp_shift1 20
+#define Exp_msk1    0x100000
+#define Exp_msk11   0x100000
+#define Exp_mask  0x7ff00000
+#define P 53
+#define Bias 1023
+#define Emin (-1022)
+#define Exp_1  0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask  0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask  0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#ifndef NO_IEEE_Scale
+#define Avoid_Underflow
+#ifdef Flush_Denorm	/* debugging option */
+#undef Sudden_Underflow
+#endif
+#endif
+
+#ifndef Flt_Rounds
+#ifdef FLT_ROUNDS
+#define Flt_Rounds FLT_ROUNDS
+#else
+#define Flt_Rounds 1
+#endif
+#endif /*Flt_Rounds*/
+
+#ifdef Honor_FLT_ROUNDS
+#define Rounding rounding
+#undef Check_FLT_ROUNDS
+#define Check_FLT_ROUNDS
+#else
+#define Rounding Flt_Rounds
+#endif
+
+#else /* ifndef IEEE_Arith */
+#undef Check_FLT_ROUNDS
+#undef Honor_FLT_ROUNDS
+#undef SET_INEXACT
+#undef  Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#undef Flt_Rounds
+#define Flt_Rounds 0
+#define Exp_shift  24
+#define Exp_shift1 24
+#define Exp_msk1   0x1000000
+#define Exp_msk11  0x1000000
+#define Exp_mask  0x7f000000
+#define P 14
+#define Bias 65
+#define Exp_1  0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8	/* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask  0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask  0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#undef Flt_Rounds
+#define Flt_Rounds 1
+#define Exp_shift  23
+#define Exp_shift1 7
+#define Exp_msk1    0x80
+#define Exp_msk11   0x800000
+#define Exp_mask  0x7f80
+#define P 56
+#define Bias 129
+#define Exp_1  0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask  0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask  0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif /* IBM, VAX */
+#endif /* IEEE_Arith */
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+#ifdef KR_headers
+extern double rnd_prod(), rnd_quot();
+#else
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#endif
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#ifndef Pack_32
+#define Pack_32
+#endif
+
+#ifdef KR_headers
+#define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff)
+#else
+#define FFFFFFFF 0xffffffffUL
+#endif
+
+#ifdef NO_LONG_LONG
+#undef ULLong
+#ifdef Just_16
+#undef Pack_32
+/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower.  Hence the default is now to store 32 bits per Long.
+ */
+#endif
+#else	/* long long available */
+#ifndef Llong
+#define Llong long long
+#endif
+#ifndef ULLong
+#define ULLong unsigned Llong
+#endif
+#endif /* NO_LONG_LONG */
+
+#ifndef MULTIPLE_THREADS
+#define ACQUIRE_DTOA_LOCK(n)	/*nothing*/
+#define FREE_DTOA_LOCK(n)	/*nothing*/
+#endif
+
+#define Kmax 15
+
+ struct
+Bigint {
+	struct Bigint *next;
+	int k, maxwds, sign, wds;
+	ULong x[1];
+	};
+
+ typedef struct Bigint Bigint;
+
+ static Bigint *freelist[Kmax+1];
+
+ static Bigint *
+Balloc
+#ifdef KR_headers
+	(k) int k;
+#else
+	(int k)
+#endif
+{
+	int x;
+	Bigint *rv;
+#ifndef Omit_Private_Memory
+	unsigned int len;
+#endif
+
+	ACQUIRE_DTOA_LOCK(0);
+	if (rv = freelist[k]) {
+		freelist[k] = rv->next;
+		}
+	else {
+		x = 1 << k;
+#ifdef Omit_Private_Memory
+		rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
+#else
+		len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
+			/sizeof(double);
+		if (pmem_next - private_mem + len <= PRIVATE_mem) {
+			rv = (Bigint*)pmem_next;
+			pmem_next += len;
+			}
+		else
+			rv = (Bigint*)MALLOC(len*sizeof(double));
+#endif
+		rv->k = k;
+		rv->maxwds = x;
+		}
+	FREE_DTOA_LOCK(0);
+	rv->sign = rv->wds = 0;
+	return rv;
+	}
+
+ static void
+Bfree
+#ifdef KR_headers
+	(v) Bigint *v;
+#else
+	(Bigint *v)
+#endif
+{
+	if (v) {
+		ACQUIRE_DTOA_LOCK(0);
+		v->next = freelist[v->k];
+		freelist[v->k] = v;
+		FREE_DTOA_LOCK(0);
+		}
+	}
+
+#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
+y->wds*sizeof(Long) + 2*sizeof(int))
+
+ static Bigint *
+multadd
+#ifdef KR_headers
+	(b, m, a) Bigint *b; int m, a;
+#else
+	(Bigint *b, int m, int a)	/* multiply by m and add a */
+#endif
+{
+	int i, wds;
+#ifdef ULLong
+	ULong *x;
+	ULLong carry, y;
+#else
+	ULong carry, *x, y;
+#ifdef Pack_32
+	ULong xi, z;
+#endif
+#endif
+	Bigint *b1;
+
+	wds = b->wds;
+	x = b->x;
+	i = 0;
+	carry = a;
+	do {
+#ifdef ULLong
+		y = *x * (ULLong)m + carry;
+		carry = y >> 32;
+		*x++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+		xi = *x;
+		y = (xi & 0xffff) * m + carry;
+		z = (xi >> 16) * m + (y >> 16);
+		carry = z >> 16;
+		*x++ = (z << 16) + (y & 0xffff);
+#else
+		y = *x * m + carry;
+		carry = y >> 16;
+		*x++ = y & 0xffff;
+#endif
+#endif
+		}
+		while(++i < wds);
+	if (carry) {
+		if (wds >= b->maxwds) {
+			b1 = Balloc(b->k+1);
+			Bcopy(b1, b);
+			Bfree(b);
+			b = b1;
+			}
+		b->x[wds++] = carry;
+		b->wds = wds;
+		}
+	return b;
+	}
+
+ static Bigint *
+s2b
+#ifdef KR_headers
+	(s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
+#else
+	(CONST char *s, int nd0, int nd, ULong y9)
+#endif
+{
+	Bigint *b;
+	int i, k;
+	Long x, y;
+
+	x = (nd + 8) / 9;
+	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+	b = Balloc(k);
+	b->x[0] = y9;
+	b->wds = 1;
+#else
+	b = Balloc(k+1);
+	b->x[0] = y9 & 0xffff;
+	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+	i = 9;
+	if (9 < nd0) {
+		s += 9;
+		do b = multadd(b, 10, *s++ - '0');
+			while(++i < nd0);
+		s++;
+		}
+	else
+		s += 10;
+	for(; i < nd; i++)
+		b = multadd(b, 10, *s++ - '0');
+	return b;
+	}
+
+ static int
+hi0bits
+#ifdef KR_headers
+	(x) register ULong x;
+#else
+	(register ULong x)
+#endif
+{
+	register int k = 0;
+
+	if (!(x & 0xffff0000)) {
+		k = 16;
+		x <<= 16;
+		}
+	if (!(x & 0xff000000)) {
+		k += 8;
+		x <<= 8;
+		}
+	if (!(x & 0xf0000000)) {
+		k += 4;
+		x <<= 4;
+		}
+	if (!(x & 0xc0000000)) {
+		k += 2;
+		x <<= 2;
+		}
+	if (!(x & 0x80000000)) {
+		k++;
+		if (!(x & 0x40000000))
+			return 32;
+		}
+	return k;
+	}
+
+ static int
+lo0bits
+#ifdef KR_headers
+	(y) ULong *y;
+#else
+	(ULong *y)
+#endif
+{
+	register int k;
+	register ULong x = *y;
+
+	if (x & 7) {
+		if (x & 1)
+			return 0;
+		if (x & 2) {
+			*y = x >> 1;
+			return 1;
+			}
+		*y = x >> 2;
+		return 2;
+		}
+	k = 0;
+	if (!(x & 0xffff)) {
+		k = 16;
+		x >>= 16;
+		}
+	if (!(x & 0xff)) {
+		k += 8;
+		x >>= 8;
+		}
+	if (!(x & 0xf)) {
+		k += 4;
+		x >>= 4;
+		}
+	if (!(x & 0x3)) {
+		k += 2;
+		x >>= 2;
+		}
+	if (!(x & 1)) {
+		k++;
+		x >>= 1;
+		if (!x)
+			return 32;
+		}
+	*y = x;
+	return k;
+	}
+
+ static Bigint *
+i2b
+#ifdef KR_headers
+	(i) int i;
+#else
+	(int i)
+#endif
+{
+	Bigint *b;
+
+	b = Balloc(1);
+	b->x[0] = i;
+	b->wds = 1;
+	return b;
+	}
+
+ static Bigint *
+mult
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	Bigint *c;
+	int k, wa, wb, wc;
+	ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+	ULong y;
+#ifdef ULLong
+	ULLong carry, z;
+#else
+	ULong carry, z;
+#ifdef Pack_32
+	ULong z2;
+#endif
+#endif
+
+	if (a->wds < b->wds) {
+		c = a;
+		a = b;
+		b = c;
+		}
+	k = a->k;
+	wa = a->wds;
+	wb = b->wds;
+	wc = wa + wb;
+	if (wc > a->maxwds)
+		k++;
+	c = Balloc(k);
+	for(x = c->x, xa = x + wc; x < xa; x++)
+		*x = 0;
+	xa = a->x;
+	xae = xa + wa;
+	xb = b->x;
+	xbe = xb + wb;
+	xc0 = c->x;
+#ifdef ULLong
+	for(; xb < xbe; xc0++) {
+		if (y = *xb++) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			do {
+				z = *x++ * (ULLong)y + *xc + carry;
+				carry = z >> 32;
+				*xc++ = z & FFFFFFFF;
+				}
+				while(x < xae);
+			*xc = carry;
+			}
+		}
+#else
+#ifdef Pack_32
+	for(; xb < xbe; xb++, xc0++) {
+		if (y = *xb & 0xffff) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			do {
+				z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+				carry = z >> 16;
+				z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+				carry = z2 >> 16;
+				Storeinc(xc, z2, z);
+				}
+				while(x < xae);
+			*xc = carry;
+			}
+		if (y = *xb >> 16) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			z2 = *xc;
+			do {
+				z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+				carry = z >> 16;
+				Storeinc(xc, z, z2);
+				z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+				carry = z2 >> 16;
+				}
+				while(x < xae);
+			*xc = z2;
+			}
+		}
+#else
+	for(; xb < xbe; xc0++) {
+		if (y = *xb++) {
+			x = xa;
+			xc = xc0;
+			carry = 0;
+			do {
+				z = *x++ * y + *xc + carry;
+				carry = z >> 16;
+				*xc++ = z & 0xffff;
+				}
+				while(x < xae);
+			*xc = carry;
+			}
+		}
+#endif
+#endif
+	for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+	c->wds = wc;
+	return c;
+	}
+
+ static Bigint *p5s;
+
+ static Bigint *
+pow5mult
+#ifdef KR_headers
+	(b, k) Bigint *b; int k;
+#else
+	(Bigint *b, int k)
+#endif
+{
+	Bigint *b1, *p5, *p51;
+	int i;
+	static int p05[3] = { 5, 25, 125 };
+
+	if (i = k & 3)
+		b = multadd(b, p05[i-1], 0);
+
+	if (!(k >>= 2))
+		return b;
+	if (!(p5 = p5s)) {
+		/* first time */
+#ifdef MULTIPLE_THREADS
+		ACQUIRE_DTOA_LOCK(1);
+		if (!(p5 = p5s)) {
+			p5 = p5s = i2b(625);
+			p5->next = 0;
+			}
+		FREE_DTOA_LOCK(1);
+#else
+		p5 = p5s = i2b(625);
+		p5->next = 0;
+#endif
+		}
+	for(;;) {
+		if (k & 1) {
+			b1 = mult(b, p5);
+			Bfree(b);
+			b = b1;
+			}
+		if (!(k >>= 1))
+			break;
+		if (!(p51 = p5->next)) {
+#ifdef MULTIPLE_THREADS
+			ACQUIRE_DTOA_LOCK(1);
+			if (!(p51 = p5->next)) {
+				p51 = p5->next = mult(p5,p5);
+				p51->next = 0;
+				}
+			FREE_DTOA_LOCK(1);
+#else
+			p51 = p5->next = mult(p5,p5);
+			p51->next = 0;
+#endif
+			}
+		p5 = p51;
+		}
+	return b;
+	}
+
+ static Bigint *
+lshift
+#ifdef KR_headers
+	(b, k) Bigint *b; int k;
+#else
+	(Bigint *b, int k)
+#endif
+{
+	int i, k1, n, n1;
+	Bigint *b1;
+	ULong *x, *x1, *xe, z;
+
+#ifdef Pack_32
+	n = k >> 5;
+#else
+	n = k >> 4;
+#endif
+	k1 = b->k;
+	n1 = n + b->wds + 1;
+	for(i = b->maxwds; n1 > i; i <<= 1)
+		k1++;
+	b1 = Balloc(k1);
+	x1 = b1->x;
+	for(i = 0; i < n; i++)
+		*x1++ = 0;
+	x = b->x;
+	xe = x + b->wds;
+#ifdef Pack_32
+	if (k &= 0x1f) {
+		k1 = 32 - k;
+		z = 0;
+		do {
+			*x1++ = *x << k | z;
+			z = *x++ >> k1;
+			}
+			while(x < xe);
+		if (*x1 = z)
+			++n1;
+		}
+#else
+	if (k &= 0xf) {
+		k1 = 16 - k;
+		z = 0;
+		do {
+			*x1++ = *x << k  & 0xffff | z;
+			z = *x++ >> k1;
+			}
+			while(x < xe);
+		if (*x1 = z)
+			++n1;
+		}
+#endif
+	else do
+		*x1++ = *x++;
+		while(x < xe);
+	b1->wds = n1 - 1;
+	Bfree(b);
+	return b1;
+	}
+
+ static int
+cmp
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	ULong *xa, *xa0, *xb, *xb0;
+	int i, j;
+
+	i = a->wds;
+	j = b->wds;
+#ifdef DEBUG
+	if (i > 1 && !a->x[i-1])
+		Bug("cmp called with a->x[a->wds-1] == 0");
+	if (j > 1 && !b->x[j-1])
+		Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+	if (i -= j)
+		return i;
+	xa0 = a->x;
+	xa = xa0 + j;
+	xb0 = b->x;
+	xb = xb0 + j;
+	for(;;) {
+		if (*--xa != *--xb)
+			return *xa < *xb ? -1 : 1;
+		if (xa <= xa0)
+			break;
+		}
+	return 0;
+	}
+
+ static Bigint *
+diff
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	Bigint *c;
+	int i, wa, wb;
+	ULong *xa, *xae, *xb, *xbe, *xc;
+#ifdef ULLong
+	ULLong borrow, y;
+#else
+	ULong borrow, y;
+#ifdef Pack_32
+	ULong z;
+#endif
+#endif
+
+	i = cmp(a,b);
+	if (!i) {
+		c = Balloc(0);
+		c->wds = 1;
+		c->x[0] = 0;
+		return c;
+		}
+	if (i < 0) {
+		c = a;
+		a = b;
+		b = c;
+		i = 1;
+		}
+	else
+		i = 0;
+	c = Balloc(a->k);
+	c->sign = i;
+	wa = a->wds;
+	xa = a->x;
+	xae = xa + wa;
+	wb = b->wds;
+	xb = b->x;
+	xbe = xb + wb;
+	xc = c->x;
+	borrow = 0;
+#ifdef ULLong
+	do {
+		y = (ULLong)*xa++ - *xb++ - borrow;
+		borrow = y >> 32 & (ULong)1;
+		*xc++ = y & FFFFFFFF;
+		}
+		while(xb < xbe);
+	while(xa < xae) {
+		y = *xa++ - borrow;
+		borrow = y >> 32 & (ULong)1;
+		*xc++ = y & FFFFFFFF;
+		}
+#else
+#ifdef Pack_32
+	do {
+		y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
+		borrow = (y & 0x10000) >> 16;
+		z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
+		borrow = (z & 0x10000) >> 16;
+		Storeinc(xc, z, y);
+		}
+		while(xb < xbe);
+	while(xa < xae) {
+		y = (*xa & 0xffff) - borrow;
+		borrow = (y & 0x10000) >> 16;
+		z = (*xa++ >> 16) - borrow;
+		borrow = (z & 0x10000) >> 16;
+		Storeinc(xc, z, y);
+		}
+#else
+	do {
+		y = *xa++ - *xb++ - borrow;
+		borrow = (y & 0x10000) >> 16;
+		*xc++ = y & 0xffff;
+		}
+		while(xb < xbe);
+	while(xa < xae) {
+		y = *xa++ - borrow;
+		borrow = (y & 0x10000) >> 16;
+		*xc++ = y & 0xffff;
+		}
+#endif
+#endif
+	while(!*--xc)
+		wa--;
+	c->wds = wa;
+	return c;
+	}
+
+ static double
+ulp
+#ifdef KR_headers
+	(x) double x;
+#else
+	(double x)
+#endif
+{
+	register Long L;
+	double a;
+
+	L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Avoid_Underflow
+#ifndef Sudden_Underflow
+	if (L > 0) {
+#endif
+#endif
+#ifdef IBM
+		L |= Exp_msk1 >> 4;
+#endif
+		word0(a) = L;
+		word1(a) = 0;
+#ifndef Avoid_Underflow
+#ifndef Sudden_Underflow
+		}
+	else {
+		L = -L >> Exp_shift;
+		if (L < Exp_shift) {
+			word0(a) = 0x80000 >> L;
+			word1(a) = 0;
+			}
+		else {
+			word0(a) = 0;
+			L -= Exp_shift;
+			word1(a) = L >= 31 ? 1 : 1 << 31 - L;
+			}
+		}
+#endif
+#endif
+	return dval(a);
+	}
+
+ static double
+b2d
+#ifdef KR_headers
+	(a, e) Bigint *a; int *e;
+#else
+	(Bigint *a, int *e)
+#endif
+{
+	ULong *xa, *xa0, w, y, z;
+	int k;
+	double d;
+#ifdef VAX
+	ULong d0, d1;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+	xa0 = a->x;
+	xa = xa0 + a->wds;
+	y = *--xa;
+#ifdef DEBUG
+	if (!y) Bug("zero y in b2d");
+#endif
+	k = hi0bits(y);
+	*e = 32 - k;
+#ifdef Pack_32
+	if (k < Ebits) {
+		d0 = Exp_1 | y >> Ebits - k;
+		w = xa > xa0 ? *--xa : 0;
+		d1 = y << (32-Ebits) + k | w >> Ebits - k;
+		goto ret_d;
+		}
+	z = xa > xa0 ? *--xa : 0;
+	if (k -= Ebits) {
+		d0 = Exp_1 | y << k | z >> 32 - k;
+		y = xa > xa0 ? *--xa : 0;
+		d1 = z << k | y >> 32 - k;
+		}
+	else {
+		d0 = Exp_1 | y;
+		d1 = z;
+		}
+#else
+	if (k < Ebits + 16) {
+		z = xa > xa0 ? *--xa : 0;
+		d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
+		w = xa > xa0 ? *--xa : 0;
+		y = xa > xa0 ? *--xa : 0;
+		d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
+		goto ret_d;
+		}
+	z = xa > xa0 ? *--xa : 0;
+	w = xa > xa0 ? *--xa : 0;
+	k -= Ebits + 16;
+	d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
+	y = xa > xa0 ? *--xa : 0;
+	d1 = w << k + 16 | y << k;
+#endif
+ ret_d:
+#ifdef VAX
+	word0(d) = d0 >> 16 | d0 << 16;
+	word1(d) = d1 >> 16 | d1 << 16;
+#else
+#undef d0
+#undef d1
+#endif
+	return dval(d);
+	}
+
+ static Bigint *
+d2b
+#ifdef KR_headers
+	(d, e, bits) double d; int *e, *bits;
+#else
+	(double d, int *e, int *bits)
+#endif
+{
+	Bigint *b;
+	int de, k;
+	ULong *x, y, z;
+#ifndef Sudden_Underflow
+	int i;
+#endif
+#ifdef VAX
+	ULong d0, d1;
+	d0 = word0(d) >> 16 | word0(d) << 16;
+	d1 = word1(d) >> 16 | word1(d) << 16;
+#else
+#define d0 word0(d)
+#define d1 word1(d)
+#endif
+
+#ifdef Pack_32
+	b = Balloc(1);
+#else
+	b = Balloc(2);
+#endif
+	x = b->x;
+
+	z = d0 & Frac_mask;
+	d0 &= 0x7fffffff;	/* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+	de = (int)(d0 >> Exp_shift);
+#ifndef IBM
+	z |= Exp_msk11;
+#endif
+#else
+	if (de = (int)(d0 >> Exp_shift))
+		z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+	if (y = d1) {
+		if (k = lo0bits(&y)) {
+			x[0] = y | z << 32 - k;
+			z >>= k;
+			}
+		else
+			x[0] = y;
+#ifndef Sudden_Underflow
+		i =
+#endif
+		    b->wds = (x[1] = z) ? 2 : 1;
+		}
+	else {
+#ifdef DEBUG
+		if (!z)
+			Bug("Zero passed to d2b");
+#endif
+		k = lo0bits(&z);
+		x[0] = z;
+#ifndef Sudden_Underflow
+		i =
+#endif
+		    b->wds = 1;
+		k += 32;
+		}
+#else
+	if (y = d1) {
+		if (k = lo0bits(&y))
+			if (k >= 16) {
+				x[0] = y | z << 32 - k & 0xffff;
+				x[1] = z >> k - 16 & 0xffff;
+				x[2] = z >> k;
+				i = 2;
+				}
+			else {
+				x[0] = y & 0xffff;
+				x[1] = y >> 16 | z << 16 - k & 0xffff;
+				x[2] = z >> k & 0xffff;
+				x[3] = z >> k+16;
+				i = 3;
+				}
+		else {
+			x[0] = y & 0xffff;
+			x[1] = y >> 16;
+			x[2] = z & 0xffff;
+			x[3] = z >> 16;
+			i = 3;
+			}
+		}
+	else {
+#ifdef DEBUG
+		if (!z)
+			Bug("Zero passed to d2b");
+#endif
+		k = lo0bits(&z);
+		if (k >= 16) {
+			x[0] = z;
+			i = 0;
+			}
+		else {
+			x[0] = z & 0xffff;
+			x[1] = z >> 16;
+			i = 1;
+			}
+		k += 32;
+		}
+	while(!x[i])
+		--i;
+	b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+	if (de) {
+#endif
+#ifdef IBM
+		*e = (de - Bias - (P-1) << 2) + k;
+		*bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+#else
+		*e = de - Bias - (P-1) + k;
+		*bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+		}
+	else {
+		*e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+		*bits = 32*i - hi0bits(x[i-1]);
+#else
+		*bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+		}
+#endif
+	return b;
+	}
+#undef d0
+#undef d1
+
+ static double
+ratio
+#ifdef KR_headers
+	(a, b) Bigint *a, *b;
+#else
+	(Bigint *a, Bigint *b)
+#endif
+{
+	double da, db;
+	int k, ka, kb;
+
+	dval(da) = b2d(a, &ka);
+	dval(db) = b2d(b, &kb);
+#ifdef Pack_32
+	k = ka - kb + 32*(a->wds - b->wds);
+#else
+	k = ka - kb + 16*(a->wds - b->wds);
+#endif
+#ifdef IBM
+	if (k > 0) {
+		word0(da) += (k >> 2)*Exp_msk1;
+		if (k &= 3)
+			dval(da) *= 1 << k;
+		}
+	else {
+		k = -k;
+		word0(db) += (k >> 2)*Exp_msk1;
+		if (k &= 3)
+			dval(db) *= 1 << k;
+		}
+#else
+	if (k > 0)
+		word0(da) += k*Exp_msk1;
+	else {
+		k = -k;
+		word0(db) += k*Exp_msk1;
+		}
+#endif
+	return dval(da) / dval(db);
+	}
+
+ static CONST double
+tens[] = {
+		1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+		1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+		1e20, 1e21, 1e22
+#ifdef VAX
+		, 1e23, 1e24
+#endif
+		};
+
+ static CONST double
+#ifdef IEEE_Arith
+bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
+#ifdef Avoid_Underflow
+		9007199254740992.*9007199254740992.e-256
+		/* = 2^106 * 1e-53 */
+#else
+		1e-256
+#endif
+		};
+/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
+/* flag unnecessarily.  It leads to a song and dance at the end of strtod. */
+#define Scale_Bit 0x10
+#define n_bigtens 5
+#else
+#ifdef IBM
+bigtens[] = { 1e16, 1e32, 1e64 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+bigtens[] = { 1e16, 1e32 };
+static CONST double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#undef INFNAN_CHECK
+#endif
+
+#ifdef INFNAN_CHECK
+
+#ifndef NAN_WORD0
+#define NAN_WORD0 0x7ff80000
+#endif
+
+#ifndef NAN_WORD1
+#define NAN_WORD1 0
+#endif
+
+ static int
+match
+#ifdef KR_headers
+	(sp, t) char **sp, *t;
+#else
+	(CONST char **sp, char *t)
+#endif
+{
+	int c, d;
+	CONST char *s = *sp;
+
+	while(d = *t++) {
+		if ((c = *++s) >= 'A' && c <= 'Z')
+			c += 'a' - 'A';
+		if (c != d)
+			return 0;
+		}
+	*sp = s + 1;
+	return 1;
+	}
+
+#ifndef No_Hex_NaN
+ static void
+hexnan
+#ifdef KR_headers
+	(rvp, sp) double *rvp; CONST char **sp;
+#else
+	(double *rvp, CONST char **sp)
+#endif
+{
+	ULong c, x[2];
+	CONST char *s;
+	int havedig, udx0, xshift;
+
+	x[0] = x[1] = 0;
+	havedig = xshift = 0;
+	udx0 = 1;
+	s = *sp;
+	while(c = *(CONST unsigned char*)++s) {
+		if (c >= '0' && c <= '9')
+			c -= '0';
+		else if (c >= 'a' && c <= 'f')
+			c += 10 - 'a';
+		else if (c >= 'A' && c <= 'F')
+			c += 10 - 'A';
+		else if (c <= ' ') {
+			if (udx0 && havedig) {
+				udx0 = 0;
+				xshift = 1;
+				}
+			continue;
+			}
+		else if (/*(*/ c == ')' && havedig) {
+			*sp = s + 1;
+			break;
+			}
+		else
+			return;	/* invalid form: don't change *sp */
+		havedig = 1;
+		if (xshift) {
+			xshift = 0;
+			x[0] = x[1];
+			x[1] = 0;
+			}
+		if (udx0)
+			x[0] = (x[0] << 4) | (x[1] >> 28);
+		x[1] = (x[1] << 4) | c;
+		}
+	if ((x[0] &= 0xfffff) || x[1]) {
+		word0(*rvp) = Exp_mask | x[0];
+		word1(*rvp) = x[1];
+		}
+	}
+#endif /*No_Hex_NaN*/
+#endif /* INFNAN_CHECK */
+
+ PR_IMPLEMENT(double)
+PR_strtod
+#ifdef KR_headers
+	(s00, se) CONST char *s00; char **se;
+#else
+	(CONST char *s00, char **se)
+#endif
+{
+#ifdef Avoid_Underflow
+	int scale;
+#endif
+	int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
+		 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+	CONST char *s, *s0, *s1;
+	double aadj, aadj1, adj, rv, rv0;
+	Long L;
+	ULong y, z;
+	Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+#ifdef SET_INEXACT
+	int inexact, oldinexact;
+#endif
+#ifdef Honor_FLT_ROUNDS
+	int rounding;
+#endif
+#ifdef USE_LOCALE
+	CONST char *s2;
+#endif
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	sign = nz0 = nz = 0;
+	dval(rv) = 0.;
+	for(s = s00;;s++) switch(*s) {
+		case '-':
+			sign = 1;
+			/* no break */
+		case '+':
+			if (*++s)
+				goto break2;
+			/* no break */
+		case 0:
+			goto ret0;
+		case '\t':
+		case '\n':
+		case '\v':
+		case '\f':
+		case '\r':
+		case ' ':
+			continue;
+		default:
+			goto break2;
+		}
+ break2:
+	if (*s == '0') {
+		nz0 = 1;
+		while(*++s == '0') ;
+		if (!*s)
+			goto ret;
+		}
+	s0 = s;
+	y = z = 0;
+	for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+		if (nd < 9)
+			y = 10*y + c - '0';
+		else if (nd < 16)
+			z = 10*z + c - '0';
+	nd0 = nd;
+#ifdef USE_LOCALE
+	s1 = localeconv()->decimal_point;
+	if (c == *s1) {
+		c = '.';
+		if (*++s1) {
+			s2 = s;
+			for(;;) {
+				if (*++s2 != *s1) {
+					c = 0;
+					break;
+					}
+				if (!*++s1) {
+					s = s2;
+					break;
+					}
+				}
+			}
+		}
+#endif
+	if (c == '.') {
+		c = *++s;
+		if (!nd) {
+			for(; c == '0'; c = *++s)
+				nz++;
+			if (c > '0' && c <= '9') {
+				s0 = s;
+				nf += nz;
+				nz = 0;
+				goto have_dig;
+				}
+			goto dig_done;
+			}
+		for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+			nz++;
+			if (c -= '0') {
+				nf += nz;
+				for(i = 1; i < nz; i++)
+					if (nd++ < 9)
+						y *= 10;
+					else if (nd <= DBL_DIG + 1)
+						z *= 10;
+				if (nd++ < 9)
+					y = 10*y + c;
+				else if (nd <= DBL_DIG + 1)
+					z = 10*z + c;
+				nz = 0;
+				}
+			}
+		}
+ dig_done:
+	e = 0;
+	if (c == 'e' || c == 'E') {
+		if (!nd && !nz && !nz0) {
+			goto ret0;
+			}
+		s00 = s;
+		esign = 0;
+		switch(c = *++s) {
+			case '-':
+				esign = 1;
+			case '+':
+				c = *++s;
+			}
+		if (c >= '0' && c <= '9') {
+			while(c == '0')
+				c = *++s;
+			if (c > '0' && c <= '9') {
+				L = c - '0';
+				s1 = s;
+				while((c = *++s) >= '0' && c <= '9')
+					L = 10*L + c - '0';
+				if (s - s1 > 8 || L > 19999)
+					/* Avoid confusion from exponents
+					 * so large that e might overflow.
+					 */
+					e = 19999; /* safe for 16 bit ints */
+				else
+					e = (int)L;
+				if (esign)
+					e = -e;
+				}
+			else
+				e = 0;
+			}
+		else
+			s = s00;
+		}
+	if (!nd) {
+		if (!nz && !nz0) {
+#ifdef INFNAN_CHECK
+			/* Check for Nan and Infinity */
+			switch(c) {
+			  case 'i':
+			  case 'I':
+				if (match(&s,"nf")) {
+					--s;
+					if (!match(&s,"inity"))
+						++s;
+					word0(rv) = 0x7ff00000;
+					word1(rv) = 0;
+					goto ret;
+					}
+				break;
+			  case 'n':
+			  case 'N':
+				if (match(&s, "an")) {
+					word0(rv) = NAN_WORD0;
+					word1(rv) = NAN_WORD1;
+#ifndef No_Hex_NaN
+					if (*s == '(') /*)*/
+						hexnan(&rv, &s);
+#endif
+					goto ret;
+					}
+			  }
+#endif /* INFNAN_CHECK */
+ ret0:
+			s = s00;
+			sign = 0;
+			}
+		goto ret;
+		}
+	e1 = e -= nf;
+
+	/* Now we have nd0 digits, starting at s0, followed by a
+	 * decimal point, followed by nd-nd0 digits.  The number we're
+	 * after is the integer represented by those digits times
+	 * 10**e */
+
+	if (!nd0)
+		nd0 = nd;
+	k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+	dval(rv) = y;
+	if (k > 9) {
+#ifdef SET_INEXACT
+		if (k > DBL_DIG)
+			oldinexact = get_inexact();
+#endif
+		dval(rv) = tens[k - 9] * dval(rv) + z;
+		}
+	bd0 = 0;
+	if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+#ifndef Honor_FLT_ROUNDS
+		&& Flt_Rounds == 1
+#endif
+#endif
+			) {
+		if (!e)
+			goto ret;
+		if (e > 0) {
+			if (e <= Ten_pmax) {
+#ifdef VAX
+				goto vax_ovfl_check;
+#else
+#ifdef Honor_FLT_ROUNDS
+				/* round correctly FLT_ROUNDS = 2 or 3 */
+				if (sign) {
+					rv = -rv;
+					sign = 0;
+					}
+#endif
+				/* rv = */ rounded_product(dval(rv), tens[e]);
+				goto ret;
+#endif
+				}
+			i = DBL_DIG - nd;
+			if (e <= Ten_pmax + i) {
+				/* A fancier test would sometimes let us do
+				 * this for larger i values.
+				 */
+#ifdef Honor_FLT_ROUNDS
+				/* round correctly FLT_ROUNDS = 2 or 3 */
+				if (sign) {
+					rv = -rv;
+					sign = 0;
+					}
+#endif
+				e -= i;
+				dval(rv) *= tens[i];
+#ifdef VAX
+				/* VAX exponent range is so narrow we must
+				 * worry about overflow here...
+				 */
+ vax_ovfl_check:
+				word0(rv) -= P*Exp_msk1;
+				/* rv = */ rounded_product(dval(rv), tens[e]);
+				if ((word0(rv) & Exp_mask)
+				 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+					goto ovfl;
+				word0(rv) += P*Exp_msk1;
+#else
+				/* rv = */ rounded_product(dval(rv), tens[e]);
+#endif
+				goto ret;
+				}
+			}
+#ifndef Inaccurate_Divide
+		else if (e >= -Ten_pmax) {
+#ifdef Honor_FLT_ROUNDS
+			/* round correctly FLT_ROUNDS = 2 or 3 */
+			if (sign) {
+				rv = -rv;
+				sign = 0;
+				}
+#endif
+			/* rv = */ rounded_quotient(dval(rv), tens[-e]);
+			goto ret;
+			}
+#endif
+		}
+	e1 += nd - k;
+
+#ifdef IEEE_Arith
+#ifdef SET_INEXACT
+	inexact = 1;
+	if (k <= DBL_DIG)
+		oldinexact = get_inexact();
+#endif
+#ifdef Avoid_Underflow
+	scale = 0;
+#endif
+#ifdef Honor_FLT_ROUNDS
+	if ((rounding = Flt_Rounds) >= 2) {
+		if (sign)
+			rounding = rounding == 2 ? 0 : 2;
+		else
+			if (rounding != 2)
+				rounding = 0;
+		}
+#endif
+#endif /*IEEE_Arith*/
+
+	/* Get starting approximation = rv * 10**e1 */
+
+	if (e1 > 0) {
+		if (i = e1 & 15)
+			dval(rv) *= tens[i];
+		if (e1 &= ~15) {
+			if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+#ifndef NO_ERRNO
+				PR_SetError(PR_RANGE_ERROR, 0);
+#endif
+				/* Can't trust HUGE_VAL */
+#ifdef IEEE_Arith
+#ifdef Honor_FLT_ROUNDS
+				switch(rounding) {
+				  case 0: /* toward 0 */
+				  case 3: /* toward -infinity */
+					word0(rv) = Big0;
+					word1(rv) = Big1;
+					break;
+				  default:
+					word0(rv) = Exp_mask;
+					word1(rv) = 0;
+				  }
+#else /*Honor_FLT_ROUNDS*/
+				word0(rv) = Exp_mask;
+				word1(rv) = 0;
+#endif /*Honor_FLT_ROUNDS*/
+#ifdef SET_INEXACT
+				/* set overflow bit */
+				dval(rv0) = 1e300;
+				dval(rv0) *= dval(rv0);
+#endif
+#else /*IEEE_Arith*/
+				word0(rv) = Big0;
+				word1(rv) = Big1;
+#endif /*IEEE_Arith*/
+				if (bd0)
+					goto retfree;
+				goto ret;
+				}
+			e1 >>= 4;
+			for(j = 0; e1 > 1; j++, e1 >>= 1)
+				if (e1 & 1)
+					dval(rv) *= bigtens[j];
+		/* The last multiplication could overflow. */
+			word0(rv) -= P*Exp_msk1;
+			dval(rv) *= bigtens[j];
+			if ((z = word0(rv) & Exp_mask)
+			 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+				goto ovfl;
+			if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+				/* set to largest number */
+				/* (Can't trust DBL_MAX) */
+				word0(rv) = Big0;
+				word1(rv) = Big1;
+				}
+			else
+				word0(rv) += P*Exp_msk1;
+			}
+		}
+	else if (e1 < 0) {
+		e1 = -e1;
+		if (i = e1 & 15)
+			dval(rv) /= tens[i];
+		if (e1 >>= 4) {
+			if (e1 >= 1 << n_bigtens)
+				goto undfl;
+#ifdef Avoid_Underflow
+			if (e1 & Scale_Bit)
+				scale = 2*P;
+			for(j = 0; e1 > 0; j++, e1 >>= 1)
+				if (e1 & 1)
+					dval(rv) *= tinytens[j];
+			if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
+						>> Exp_shift)) > 0) {
+				/* scaled rv is denormal; zap j low bits */
+				if (j >= 32) {
+					word1(rv) = 0;
+					if (j >= 53)
+					 word0(rv) = (P+2)*Exp_msk1;
+					else
+					 word0(rv) &= 0xffffffff << j-32;
+					}
+				else
+					word1(rv) &= 0xffffffff << j;
+				}
+#else
+			for(j = 0; e1 > 1; j++, e1 >>= 1)
+				if (e1 & 1)
+					dval(rv) *= tinytens[j];
+			/* The last multiplication could underflow. */
+			dval(rv0) = dval(rv);
+			dval(rv) *= tinytens[j];
+			if (!dval(rv)) {
+				dval(rv) = 2.*dval(rv0);
+				dval(rv) *= tinytens[j];
+#endif
+				if (!dval(rv)) {
+ undfl:
+					dval(rv) = 0.;
+#ifndef NO_ERRNO
+					PR_SetError(PR_RANGE_ERROR, 0);
+#endif
+					if (bd0)
+						goto retfree;
+					goto ret;
+					}
+#ifndef Avoid_Underflow
+				word0(rv) = Tiny0;
+				word1(rv) = Tiny1;
+				/* The refinement below will clean
+				 * this approximation up.
+				 */
+				}
+#endif
+			}
+		}
+
+	/* Now the hard part -- adjusting rv to the correct value.*/
+
+	/* Put digits into bd: true value = bd * 10^e */
+
+	bd0 = s2b(s0, nd0, nd, y);
+
+	for(;;) {
+		bd = Balloc(bd0->k);
+		Bcopy(bd, bd0);
+		bb = d2b(dval(rv), &bbe, &bbbits);	/* rv = bb * 2^bbe */
+		bs = i2b(1);
+
+		if (e >= 0) {
+			bb2 = bb5 = 0;
+			bd2 = bd5 = e;
+			}
+		else {
+			bb2 = bb5 = -e;
+			bd2 = bd5 = 0;
+			}
+		if (bbe >= 0)
+			bb2 += bbe;
+		else
+			bd2 -= bbe;
+		bs2 = bb2;
+#ifdef Honor_FLT_ROUNDS
+		if (rounding != 1)
+			bs2++;
+#endif
+#ifdef Avoid_Underflow
+		j = bbe - scale;
+		i = j + bbbits - 1;	/* logb(rv) */
+		if (i < Emin)	/* denormal */
+			j += P - Emin;
+		else
+			j = P + 1 - bbbits;
+#else /*Avoid_Underflow*/
+#ifdef Sudden_Underflow
+#ifdef IBM
+		j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+		j = P + 1 - bbbits;
+#endif
+#else /*Sudden_Underflow*/
+		j = bbe;
+		i = j + bbbits - 1;	/* logb(rv) */
+		if (i < Emin)	/* denormal */
+			j += P - Emin;
+		else
+			j = P + 1 - bbbits;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+		bb2 += j;
+		bd2 += j;
+#ifdef Avoid_Underflow
+		bd2 += scale;
+#endif
+		i = bb2 < bd2 ? bb2 : bd2;
+		if (i > bs2)
+			i = bs2;
+		if (i > 0) {
+			bb2 -= i;
+			bd2 -= i;
+			bs2 -= i;
+			}
+		if (bb5 > 0) {
+			bs = pow5mult(bs, bb5);
+			bb1 = mult(bs, bb);
+			Bfree(bb);
+			bb = bb1;
+			}
+		if (bb2 > 0)
+			bb = lshift(bb, bb2);
+		if (bd5 > 0)
+			bd = pow5mult(bd, bd5);
+		if (bd2 > 0)
+			bd = lshift(bd, bd2);
+		if (bs2 > 0)
+			bs = lshift(bs, bs2);
+		delta = diff(bb, bd);
+		dsign = delta->sign;
+		delta->sign = 0;
+		i = cmp(delta, bs);
+#ifdef Honor_FLT_ROUNDS
+		if (rounding != 1) {
+			if (i < 0) {
+				/* Error is less than an ulp */
+				if (!delta->x[0] && delta->wds <= 1) {
+					/* exact */
+#ifdef SET_INEXACT
+					inexact = 0;
+#endif
+					break;
+					}
+				if (rounding) {
+					if (dsign) {
+						adj = 1.;
+						goto apply_adj;
+						}
+					}
+				else if (!dsign) {
+					adj = -1.;
+					if (!word1(rv)
+					 && !(word0(rv) & Frac_mask)) {
+						y = word0(rv) & Exp_mask;
+#ifdef Avoid_Underflow
+						if (!scale || y > 2*P*Exp_msk1)
+#else
+						if (y)
+#endif
+						  {
+						  delta = lshift(delta,Log2P);
+						  if (cmp(delta, bs) <= 0)
+							adj = -0.5;
+						  }
+						}
+ apply_adj:
+#ifdef Avoid_Underflow
+					if (scale && (y = word0(rv) & Exp_mask)
+						<= 2*P*Exp_msk1)
+					  word0(adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+					if ((word0(rv) & Exp_mask) <=
+							P*Exp_msk1) {
+						word0(rv) += P*Exp_msk1;
+						dval(rv) += adj*ulp(dval(rv));
+						word0(rv) -= P*Exp_msk1;
+						}
+					else
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+					dval(rv) += adj*ulp(dval(rv));
+					}
+				break;
+				}
+			adj = ratio(delta, bs);
+			if (adj < 1.)
+				adj = 1.;
+			if (adj <= 0x7ffffffe) {
+				/* adj = rounding ? ceil(adj) : floor(adj); */
+				y = adj;
+				if (y != adj) {
+					if (!((rounding>>1) ^ dsign))
+						y++;
+					adj = y;
+					}
+				}
+#ifdef Avoid_Underflow
+			if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
+				word0(adj) += (2*P+1)*Exp_msk1 - y;
+#else
+#ifdef Sudden_Underflow
+			if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+				word0(rv) += P*Exp_msk1;
+				adj *= ulp(dval(rv));
+				if (dsign)
+					dval(rv) += adj;
+				else
+					dval(rv) -= adj;
+				word0(rv) -= P*Exp_msk1;
+				goto cont;
+				}
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+			adj *= ulp(dval(rv));
+			if (dsign)
+				dval(rv) += adj;
+			else
+				dval(rv) -= adj;
+			goto cont;
+			}
+#endif /*Honor_FLT_ROUNDS*/
+
+		if (i < 0) {
+			/* Error is less than half an ulp -- check for
+			 * special case of mantissa a power of two.
+			 */
+			if (dsign || word1(rv) || word0(rv) & Bndry_mask
+#ifdef IEEE_Arith
+#ifdef Avoid_Underflow
+			 || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
+#else
+			 || (word0(rv) & Exp_mask) <= Exp_msk1
+#endif
+#endif
+				) {
+#ifdef SET_INEXACT
+				if (!delta->x[0] && delta->wds <= 1)
+					inexact = 0;
+#endif
+				break;
+				}
+			if (!delta->x[0] && delta->wds <= 1) {
+				/* exact result */
+#ifdef SET_INEXACT
+				inexact = 0;
+#endif
+				break;
+				}
+			delta = lshift(delta,Log2P);
+			if (cmp(delta, bs) > 0)
+				goto drop_down;
+			break;
+			}
+		if (i == 0) {
+			/* exactly half-way between */
+			if (dsign) {
+				if ((word0(rv) & Bndry_mask1) == Bndry_mask1
+				 &&  word1(rv) == (
+#ifdef Avoid_Underflow
+			(scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
+		? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
+#endif
+						   0xffffffff)) {
+					/*boundary case -- increment exponent*/
+					word0(rv) = (word0(rv) & Exp_mask)
+						+ Exp_msk1
+#ifdef IBM
+						| Exp_msk1 >> 4
+#endif
+						;
+					word1(rv) = 0;
+#ifdef Avoid_Underflow
+					dsign = 0;
+#endif
+					break;
+					}
+				}
+			else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+ drop_down:
+				/* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow /*{{*/
+				L = word0(rv) & Exp_mask;
+#ifdef IBM
+				if (L <  Exp_msk1)
+#else
+#ifdef Avoid_Underflow
+				if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
+#else
+				if (L <= Exp_msk1)
+#endif /*Avoid_Underflow*/
+#endif /*IBM*/
+					goto undfl;
+				L -= Exp_msk1;
+#else /*Sudden_Underflow}{*/
+#ifdef Avoid_Underflow
+				if (scale) {
+					L = word0(rv) & Exp_mask;
+					if (L <= (2*P+1)*Exp_msk1) {
+						if (L > (P+2)*Exp_msk1)
+							/* round even ==> */
+							/* accept rv */
+							break;
+						/* rv = smallest denormal */
+						goto undfl;
+						}
+					}
+#endif /*Avoid_Underflow*/
+				L = (word0(rv) & Exp_mask) - Exp_msk1;
+#endif /*Sudden_Underflow}}*/
+				word0(rv) = L | Bndry_mask1;
+				word1(rv) = 0xffffffff;
+#ifdef IBM
+				goto cont;
+#else
+				break;
+#endif
+				}
+#ifndef ROUND_BIASED
+			if (!(word1(rv) & LSB))
+				break;
+#endif
+			if (dsign)
+				dval(rv) += ulp(dval(rv));
+#ifndef ROUND_BIASED
+			else {
+				dval(rv) -= ulp(dval(rv));
+#ifndef Sudden_Underflow
+				if (!dval(rv))
+					goto undfl;
+#endif
+				}
+#ifdef Avoid_Underflow
+			dsign = 1 - dsign;
+#endif
+#endif
+			break;
+			}
+		if ((aadj = ratio(delta, bs)) <= 2.) {
+			if (dsign)
+				aadj = aadj1 = 1.;
+			else if (word1(rv) || word0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+				if (word1(rv) == Tiny1 && !word0(rv))
+					goto undfl;
+#endif
+				aadj = 1.;
+				aadj1 = -1.;
+				}
+			else {
+				/* special case -- power of FLT_RADIX to be */
+				/* rounded down... */
+
+				if (aadj < 2./FLT_RADIX)
+					aadj = 1./FLT_RADIX;
+				else
+					aadj *= 0.5;
+				aadj1 = -aadj;
+				}
+			}
+		else {
+			aadj *= 0.5;
+			aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+			switch(Rounding) {
+				case 2: /* towards +infinity */
+					aadj1 -= 0.5;
+					break;
+				case 0: /* towards 0 */
+				case 3: /* towards -infinity */
+					aadj1 += 0.5;
+				}
+#else
+			if (Flt_Rounds == 0)
+				aadj1 += 0.5;
+#endif /*Check_FLT_ROUNDS*/
+			}
+		y = word0(rv) & Exp_mask;
+
+		/* Check for overflow */
+
+		if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+			dval(rv0) = dval(rv);
+			word0(rv) -= P*Exp_msk1;
+			adj = aadj1 * ulp(dval(rv));
+			dval(rv) += adj;
+			if ((word0(rv) & Exp_mask) >=
+					Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+				if (word0(rv0) == Big0 && word1(rv0) == Big1)
+					goto ovfl;
+				word0(rv) = Big0;
+				word1(rv) = Big1;
+				goto cont;
+				}
+			else
+				word0(rv) += P*Exp_msk1;
+			}
+		else {
+#ifdef Avoid_Underflow
+			if (scale && y <= 2*P*Exp_msk1) {
+				if (aadj <= 0x7fffffff) {
+					if ((z = aadj) <= 0)
+						z = 1;
+					aadj = z;
+					aadj1 = dsign ? aadj : -aadj;
+					}
+				word0(aadj1) += (2*P+1)*Exp_msk1 - y;
+				}
+			adj = aadj1 * ulp(dval(rv));
+			dval(rv) += adj;
+#else
+#ifdef Sudden_Underflow
+			if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+				dval(rv0) = dval(rv);
+				word0(rv) += P*Exp_msk1;
+				adj = aadj1 * ulp(dval(rv));
+				dval(rv) += adj;
+#ifdef IBM
+				if ((word0(rv) & Exp_mask) <  P*Exp_msk1)
+#else
+				if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+					{
+					if (word0(rv0) == Tiny0
+					 && word1(rv0) == Tiny1)
+						goto undfl;
+					word0(rv) = Tiny0;
+					word1(rv) = Tiny1;
+					goto cont;
+					}
+				else
+					word0(rv) -= P*Exp_msk1;
+				}
+			else {
+				adj = aadj1 * ulp(dval(rv));
+				dval(rv) += adj;
+				}
+#else /*Sudden_Underflow*/
+			/* Compute adj so that the IEEE rounding rules will
+			 * correctly round rv + adj in some half-way cases.
+			 * If rv * ulp(rv) is denormalized (i.e.,
+			 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+			 * trouble from bits lost to denormalization;
+			 * example: 1.2e-307 .
+			 */
+			if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
+				aadj1 = (double)(int)(aadj + 0.5);
+				if (!dsign)
+					aadj1 = -aadj1;
+				}
+			adj = aadj1 * ulp(dval(rv));
+			dval(rv) += adj;
+#endif /*Sudden_Underflow*/
+#endif /*Avoid_Underflow*/
+			}
+		z = word0(rv) & Exp_mask;
+#ifndef SET_INEXACT
+#ifdef Avoid_Underflow
+		if (!scale)
+#endif
+		if (y == z) {
+			/* Can we stop now? */
+			L = (Long)aadj;
+			aadj -= L;
+			/* The tolerances below are conservative. */
+			if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+				if (aadj < .4999999 || aadj > .5000001)
+					break;
+				}
+			else if (aadj < .4999999/FLT_RADIX)
+				break;
+			}
+#endif
+ cont:
+		Bfree(bb);
+		Bfree(bd);
+		Bfree(bs);
+		Bfree(delta);
+		}
+#ifdef SET_INEXACT
+	if (inexact) {
+		if (!oldinexact) {
+			word0(rv0) = Exp_1 + (70 << Exp_shift);
+			word1(rv0) = 0;
+			dval(rv0) += 1.;
+			}
+		}
+	else if (!oldinexact)
+		clear_inexact();
+#endif
+#ifdef Avoid_Underflow
+	if (scale) {
+		word0(rv0) = Exp_1 - 2*P*Exp_msk1;
+		word1(rv0) = 0;
+		dval(rv) *= dval(rv0);
+#ifndef NO_ERRNO
+		/* try to avoid the bug of testing an 8087 register value */
+		if (word0(rv) == 0 && word1(rv) == 0)
+			PR_SetError(PR_RANGE_ERROR, 0);
+#endif
+		}
+#endif /* Avoid_Underflow */
+#ifdef SET_INEXACT
+	if (inexact && !(word0(rv) & Exp_mask)) {
+		/* set underflow bit */
+		dval(rv0) = 1e-300;
+		dval(rv0) *= dval(rv0);
+		}
+#endif
+ retfree:
+	Bfree(bb);
+	Bfree(bd);
+	Bfree(bs);
+	Bfree(bd0);
+	Bfree(delta);
+ ret:
+	if (se)
+		*se = (char *)s;
+	return sign ? -dval(rv) : dval(rv);
+	}
+
+ static int
+quorem
+#ifdef KR_headers
+	(b, S) Bigint *b, *S;
+#else
+	(Bigint *b, Bigint *S)
+#endif
+{
+	int n;
+	ULong *bx, *bxe, q, *sx, *sxe;
+#ifdef ULLong
+	ULLong borrow, carry, y, ys;
+#else
+	ULong borrow, carry, y, ys;
+#ifdef Pack_32
+	ULong si, z, zs;
+#endif
+#endif
+
+	n = S->wds;
+#ifdef DEBUG
+	/*debug*/ if (b->wds > n)
+	/*debug*/	Bug("oversize b in quorem");
+#endif
+	if (b->wds < n)
+		return 0;
+	sx = S->x;
+	sxe = sx + --n;
+	bx = b->x;
+	bxe = bx + n;
+	q = *bxe / (*sxe + 1);	/* ensure q <= true quotient */
+#ifdef DEBUG
+	/*debug*/ if (q > 9)
+	/*debug*/	Bug("oversized quotient in quorem");
+#endif
+	if (q) {
+		borrow = 0;
+		carry = 0;
+		do {
+#ifdef ULLong
+			ys = *sx++ * (ULLong)q + carry;
+			carry = ys >> 32;
+			y = *bx - (ys & FFFFFFFF) - borrow;
+			borrow = y >> 32 & (ULong)1;
+			*bx++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+			si = *sx++;
+			ys = (si & 0xffff) * q + carry;
+			zs = (si >> 16) * q + (ys >> 16);
+			carry = zs >> 16;
+			y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			z = (*bx >> 16) - (zs & 0xffff) - borrow;
+			borrow = (z & 0x10000) >> 16;
+			Storeinc(bx, z, y);
+#else
+			ys = *sx++ * q + carry;
+			carry = ys >> 16;
+			y = *bx - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			*bx++ = y & 0xffff;
+#endif
+#endif
+			}
+			while(sx <= sxe);
+		if (!*bxe) {
+			bx = b->x;
+			while(--bxe > bx && !*bxe)
+				--n;
+			b->wds = n;
+			}
+		}
+	if (cmp(b, S) >= 0) {
+		q++;
+		borrow = 0;
+		carry = 0;
+		bx = b->x;
+		sx = S->x;
+		do {
+#ifdef ULLong
+			ys = *sx++ + carry;
+			carry = ys >> 32;
+			y = *bx - (ys & FFFFFFFF) - borrow;
+			borrow = y >> 32 & (ULong)1;
+			*bx++ = y & FFFFFFFF;
+#else
+#ifdef Pack_32
+			si = *sx++;
+			ys = (si & 0xffff) + carry;
+			zs = (si >> 16) + (ys >> 16);
+			carry = zs >> 16;
+			y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			z = (*bx >> 16) - (zs & 0xffff) - borrow;
+			borrow = (z & 0x10000) >> 16;
+			Storeinc(bx, z, y);
+#else
+			ys = *sx++ + carry;
+			carry = ys >> 16;
+			y = *bx - (ys & 0xffff) - borrow;
+			borrow = (y & 0x10000) >> 16;
+			*bx++ = y & 0xffff;
+#endif
+#endif
+			}
+			while(sx <= sxe);
+		bx = b->x;
+		bxe = bx + n;
+		if (!*bxe) {
+			while(--bxe > bx && !*bxe)
+				--n;
+			b->wds = n;
+			}
+		}
+	return q;
+	}
+
+#ifndef MULTIPLE_THREADS
+ static char *dtoa_result;
+#endif
+
+ static char *
+#ifdef KR_headers
+rv_alloc(i) int i;
+#else
+rv_alloc(int i)
+#endif
+{
+	int j, k, *r;
+
+	j = sizeof(ULong);
+	for(k = 0;
+		sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
+		j <<= 1)
+			k++;
+	r = (int*)Balloc(k);
+	*r = k;
+	return
+#ifndef MULTIPLE_THREADS
+	dtoa_result =
+#endif
+		(char *)(r+1);
+	}
+
+ static char *
+#ifdef KR_headers
+nrv_alloc(s, rve, n) char *s, **rve; int n;
+#else
+nrv_alloc(char *s, char **rve, int n)
+#endif
+{
+	char *rv, *t;
+
+	t = rv = rv_alloc(n);
+	while(*t = *s++) t++;
+	if (rve)
+		*rve = t;
+	return rv;
+	}
+
+/* freedtoa(s) must be used to free values s returned by dtoa
+ * when MULTIPLE_THREADS is #defined.  It should be used in all cases,
+ * but for consistency with earlier versions of dtoa, it is optional
+ * when MULTIPLE_THREADS is not defined.
+ */
+
+ void
+#ifdef KR_headers
+freedtoa(s) char *s;
+#else
+freedtoa(char *s)
+#endif
+{
+	Bigint *b = (Bigint *)((int *)s - 1);
+	b->maxwds = 1 << (b->k = *(int*)b);
+	Bfree(b);
+#ifndef MULTIPLE_THREADS
+	if (s == dtoa_result)
+		dtoa_result = 0;
+#endif
+	}
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
+ *
+ * Modifications:
+ *	1. Rather than iterating, we use a simple numeric overestimate
+ *	   to determine k = floor(log10(d)).  We scale relevant
+ *	   quantities using O(log2(k)) rather than O(k) multiplications.
+ *	2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ *	   try to generate digits strictly left to right.  Instead, we
+ *	   compute with fewer bits and propagate the carry if necessary
+ *	   when rounding the final digit up.  This is often faster.
+ *	3. Under the assumption that input will be rounded nearest,
+ *	   mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ *	   That is, we allow equality in stopping tests when the
+ *	   round-nearest rule will give the same floating-point value
+ *	   as would satisfaction of the stopping test with strict
+ *	   inequality.
+ *	4. We remove common factors of powers of 2 from relevant
+ *	   quantities.
+ *	5. When converting floating-point integers less than 1e16,
+ *	   we use floating-point arithmetic rather than resorting
+ *	   to multiple-precision integers.
+ *	6. When asked to produce fewer than 15 digits, we first try
+ *	   to get by with floating-point arithmetic; we resort to
+ *	   multiple-precision integer arithmetic only if we cannot
+ *	   guarantee that the floating-point calculation has given
+ *	   the correctly rounded result.  For k requested digits and
+ *	   "uniformly" distributed input, the probability is
+ *	   something like 10^(k-15) that we must resort to the Long
+ *	   calculation.
+ */
+
+ static char *
+dtoa
+#ifdef KR_headers
+	(d, mode, ndigits, decpt, sign, rve)
+	double d; int mode, ndigits, *decpt, *sign; char **rve;
+#else
+	(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+#endif
+{
+ /*	Arguments ndigits, decpt, sign are similar to those
+	of ecvt and fcvt; trailing zeros are suppressed from
+	the returned string.  If not null, *rve is set to point
+	to the end of the return value.  If d is +-Infinity or NaN,
+	then *decpt is set to 9999.
+
+	mode:
+		0 ==> shortest string that yields d when read in
+			and rounded to nearest.
+		1 ==> like 0, but with Steele & White stopping rule;
+			e.g. with IEEE P754 arithmetic , mode 0 gives
+			1e23 whereas mode 1 gives 9.999999999999999e22.
+		2 ==> max(1,ndigits) significant digits.  This gives a
+			return value similar to that of ecvt, except
+			that trailing zeros are suppressed.
+		3 ==> through ndigits past the decimal point.  This
+			gives a return value similar to that from fcvt,
+			except that trailing zeros are suppressed, and
+			ndigits can be negative.
+		4,5 ==> similar to 2 and 3, respectively, but (in
+			round-nearest mode) with the tests of mode 0 to
+			possibly return a shorter string that rounds to d.
+			With IEEE arithmetic and compilation with
+			-DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
+			as modes 2 and 3 when FLT_ROUNDS != 1.
+		6-9 ==> Debugging modes similar to mode - 4:  don't try
+			fast floating-point estimate (if applicable).
+
+		Values of mode other than 0-9 are treated as mode 0.
+
+		Sufficient space is allocated to the return value
+		to hold the suppressed trailing zeros.
+	*/
+
+	int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
+		j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+		spec_case, try_quick;
+	Long L;
+#ifndef Sudden_Underflow
+	int denorm;
+	ULong x;
+#endif
+	Bigint *b, *b1, *delta, *mlo, *mhi, *S;
+	double d2, ds, eps;
+	char *s, *s0;
+#ifdef Honor_FLT_ROUNDS
+	int rounding;
+#endif
+#ifdef SET_INEXACT
+	int inexact, oldinexact;
+#endif
+
+#ifndef MULTIPLE_THREADS
+	if (dtoa_result) {
+		freedtoa(dtoa_result);
+		dtoa_result = 0;
+		}
+#endif
+
+	if (word0(d) & Sign_bit) {
+		/* set sign for everything, including 0's and NaNs */
+		*sign = 1;
+		word0(d) &= ~Sign_bit;	/* clear sign bit */
+		}
+	else
+		*sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+	if ((word0(d) & Exp_mask) == Exp_mask)
+#else
+	if (word0(d)  == 0x8000)
+#endif
+		{
+		/* Infinity or NaN */
+		*decpt = 9999;
+#ifdef IEEE_Arith
+		if (!word1(d) && !(word0(d) & 0xfffff))
+			return nrv_alloc("Infinity", rve, 8);
+#endif
+		return nrv_alloc("NaN", rve, 3);
+		}
+#endif
+#ifdef IBM
+	dval(d) += 0; /* normalize */
+#endif
+	if (!dval(d)) {
+		*decpt = 1;
+		return nrv_alloc("0", rve, 1);
+		}
+
+#ifdef SET_INEXACT
+	try_quick = oldinexact = get_inexact();
+	inexact = 1;
+#endif
+#ifdef Honor_FLT_ROUNDS
+	if ((rounding = Flt_Rounds) >= 2) {
+		if (*sign)
+			rounding = rounding == 2 ? 0 : 2;
+		else
+			if (rounding != 2)
+				rounding = 0;
+		}
+#endif
+
+	b = d2b(dval(d), &be, &bbits);
+#ifdef Sudden_Underflow
+	i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+	if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) {
+#endif
+		dval(d2) = dval(d);
+		word0(d2) &= Frac_mask1;
+		word0(d2) |= Exp_11;
+#ifdef IBM
+		if (j = 11 - hi0bits(word0(d2) & Frac_mask))
+			dval(d2) /= 1 << j;
+#endif
+
+		/* log(x)	~=~ log(1.5) + (x-1.5)/1.5
+		 * log10(x)	 =  log(x) / log(10)
+		 *		~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+		 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+		 *
+		 * This suggests computing an approximation k to log10(d) by
+		 *
+		 * k = (i - Bias)*0.301029995663981
+		 *	+ ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+		 *
+		 * We want k to be too large rather than too small.
+		 * The error in the first-order Taylor series approximation
+		 * is in our favor, so we just round up the constant enough
+		 * to compensate for any error in the multiplication of
+		 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+		 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+		 * adding 1e-13 to the constant term more than suffices.
+		 * Hence we adjust the constant term to 0.1760912590558.
+		 * (We could get a more accurate k by invoking log10,
+		 *  but this is probably not worthwhile.)
+		 */
+
+		i -= Bias;
+#ifdef IBM
+		i <<= 2;
+		i += j;
+#endif
+#ifndef Sudden_Underflow
+		denorm = 0;
+		}
+	else {
+		/* d is denormalized */
+
+		i = bbits + be + (Bias + (P-1) - 1);
+		x = i > 32  ? word0(d) << 64 - i | word1(d) >> i - 32
+			    : word1(d) << 32 - i;
+		dval(d2) = x;
+		word0(d2) -= 31*Exp_msk1; /* adjust exponent */
+		i -= (Bias + (P-1) - 1) + 1;
+		denorm = 1;
+		}
+#endif
+	ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+	k = (int)ds;
+	if (ds < 0. && ds != k)
+		k--;	/* want k = floor(ds) */
+	k_check = 1;
+	if (k >= 0 && k <= Ten_pmax) {
+		if (dval(d) < tens[k])
+			k--;
+		k_check = 0;
+		}
+	j = bbits - i - 1;
+	if (j >= 0) {
+		b2 = 0;
+		s2 = j;
+		}
+	else {
+		b2 = -j;
+		s2 = 0;
+		}
+	if (k >= 0) {
+		b5 = 0;
+		s5 = k;
+		s2 += k;
+		}
+	else {
+		b2 -= k;
+		b5 = -k;
+		s5 = 0;
+		}
+	if (mode < 0 || mode > 9)
+		mode = 0;
+
+#ifndef SET_INEXACT
+#ifdef Check_FLT_ROUNDS
+	try_quick = Rounding == 1;
+#else
+	try_quick = 1;
+#endif
+#endif /*SET_INEXACT*/
+
+	if (mode > 5) {
+		mode -= 4;
+		try_quick = 0;
+		}
+	leftright = 1;
+	switch(mode) {
+		case 0:
+		case 1:
+			ilim = ilim1 = -1;
+			i = 18;
+			ndigits = 0;
+			break;
+		case 2:
+			leftright = 0;
+			/* no break */
+		case 4:
+			if (ndigits <= 0)
+				ndigits = 1;
+			ilim = ilim1 = i = ndigits;
+			break;
+		case 3:
+			leftright = 0;
+			/* no break */
+		case 5:
+			i = ndigits + k + 1;
+			ilim = i;
+			ilim1 = i - 1;
+			if (i <= 0)
+				i = 1;
+		}
+	s = s0 = rv_alloc(i);
+
+#ifdef Honor_FLT_ROUNDS
+	if (mode > 1 && rounding != 1)
+		leftright = 0;
+#endif
+
+	if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+		/* Try to get by with floating-point arithmetic. */
+
+		i = 0;
+		dval(d2) = dval(d);
+		k0 = k;
+		ilim0 = ilim;
+		ieps = 2; /* conservative */
+		if (k > 0) {
+			ds = tens[k&0xf];
+			j = k >> 4;
+			if (j & Bletch) {
+				/* prevent overflows */
+				j &= Bletch - 1;
+				dval(d) /= bigtens[n_bigtens-1];
+				ieps++;
+				}
+			for(; j; j >>= 1, i++)
+				if (j & 1) {
+					ieps++;
+					ds *= bigtens[i];
+					}
+			dval(d) /= ds;
+			}
+		else if (j1 = -k) {
+			dval(d) *= tens[j1 & 0xf];
+			for(j = j1 >> 4; j; j >>= 1, i++)
+				if (j & 1) {
+					ieps++;
+					dval(d) *= bigtens[i];
+					}
+			}
+		if (k_check && dval(d) < 1. && ilim > 0) {
+			if (ilim1 <= 0)
+				goto fast_failed;
+			ilim = ilim1;
+			k--;
+			dval(d) *= 10.;
+			ieps++;
+			}
+		dval(eps) = ieps*dval(d) + 7.;
+		word0(eps) -= (P-1)*Exp_msk1;
+		if (ilim == 0) {
+			S = mhi = 0;
+			dval(d) -= 5.;
+			if (dval(d) > dval(eps))
+				goto one_digit;
+			if (dval(d) < -dval(eps))
+				goto no_digits;
+			goto fast_failed;
+			}
+#ifndef No_leftright
+		if (leftright) {
+			/* Use Steele & White method of only
+			 * generating digits needed.
+			 */
+			dval(eps) = 0.5/tens[ilim-1] - dval(eps);
+			for(i = 0;;) {
+				L = dval(d);
+				dval(d) -= L;
+				*s++ = '0' + (int)L;
+				if (dval(d) < dval(eps))
+					goto ret1;
+				if (1. - dval(d) < dval(eps))
+					goto bump_up;
+				if (++i >= ilim)
+					break;
+				dval(eps) *= 10.;
+				dval(d) *= 10.;
+				}
+			}
+		else {
+#endif
+			/* Generate ilim digits, then fix them up. */
+			dval(eps) *= tens[ilim-1];
+			for(i = 1;; i++, dval(d) *= 10.) {
+				L = (Long)(dval(d));
+				if (!(dval(d) -= L))
+					ilim = i;
+				*s++ = '0' + (int)L;
+				if (i == ilim) {
+					if (dval(d) > 0.5 + dval(eps))
+						goto bump_up;
+					else if (dval(d) < 0.5 - dval(eps)) {
+						while(*--s == '0');
+						s++;
+						goto ret1;
+						}
+					break;
+					}
+				}
+#ifndef No_leftright
+			}
+#endif
+ fast_failed:
+		s = s0;
+		dval(d) = dval(d2);
+		k = k0;
+		ilim = ilim0;
+		}
+
+	/* Do we have a "small" integer? */
+
+	if (be >= 0 && k <= Int_max) {
+		/* Yes. */
+		ds = tens[k];
+		if (ndigits < 0 && ilim <= 0) {
+			S = mhi = 0;
+			if (ilim < 0 || dval(d) <= 5*ds)
+				goto no_digits;
+			goto one_digit;
+			}
+		for(i = 1;; i++, dval(d) *= 10.) {
+			L = (Long)(dval(d) / ds);
+			dval(d) -= L*ds;
+#ifdef Check_FLT_ROUNDS
+			/* If FLT_ROUNDS == 2, L will usually be high by 1 */
+			if (dval(d) < 0) {
+				L--;
+				dval(d) += ds;
+				}
+#endif
+			*s++ = '0' + (int)L;
+			if (!dval(d)) {
+#ifdef SET_INEXACT
+				inexact = 0;
+#endif
+				break;
+				}
+			if (i == ilim) {
+#ifdef Honor_FLT_ROUNDS
+				if (mode > 1)
+				switch(rounding) {
+				  case 0: goto ret1;
+				  case 2: goto bump_up;
+				  }
+#endif
+				dval(d) += dval(d);
+				if (dval(d) > ds || dval(d) == ds && L & 1) {
+ bump_up:
+					while(*--s == '9')
+						if (s == s0) {
+							k++;
+							*s = '0';
+							break;
+							}
+					++*s++;
+					}
+				break;
+				}
+			}
+		goto ret1;
+		}
+
+	m2 = b2;
+	m5 = b5;
+	mhi = mlo = 0;
+	if (leftright) {
+		i =
+#ifndef Sudden_Underflow
+			denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+			1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+			1 + P - bbits;
+#endif
+		b2 += i;
+		s2 += i;
+		mhi = i2b(1);
+		}
+	if (m2 > 0 && s2 > 0) {
+		i = m2 < s2 ? m2 : s2;
+		b2 -= i;
+		m2 -= i;
+		s2 -= i;
+		}
+	if (b5 > 0) {
+		if (leftright) {
+			if (m5 > 0) {
+				mhi = pow5mult(mhi, m5);
+				b1 = mult(mhi, b);
+				Bfree(b);
+				b = b1;
+				}
+			if (j = b5 - m5)
+				b = pow5mult(b, j);
+			}
+		else
+			b = pow5mult(b, b5);
+		}
+	S = i2b(1);
+	if (s5 > 0)
+		S = pow5mult(S, s5);
+
+	/* Check for special case that d is a normalized power of 2. */
+
+	spec_case = 0;
+	if ((mode < 2 || leftright)
+#ifdef Honor_FLT_ROUNDS
+			&& rounding == 1
+#endif
+				) {
+		if (!word1(d) && !(word0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+		 && word0(d) & (Exp_mask & ~Exp_msk1)
+#endif
+				) {
+			/* The special case */
+			b2 += Log2P;
+			s2 += Log2P;
+			spec_case = 1;
+			}
+		}
+
+	/* Arrange for convenient computation of quotients:
+	 * shift left if necessary so divisor has 4 leading 0 bits.
+	 *
+	 * Perhaps we should just compute leading 28 bits of S once
+	 * and for all and pass them and a shift to quorem, so it
+	 * can do shifts and ors to compute the numerator for q.
+	 */
+#ifdef Pack_32
+	if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f)
+		i = 32 - i;
+#else
+	if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
+		i = 16 - i;
+#endif
+	if (i > 4) {
+		i -= 4;
+		b2 += i;
+		m2 += i;
+		s2 += i;
+		}
+	else if (i < 4) {
+		i += 28;
+		b2 += i;
+		m2 += i;
+		s2 += i;
+		}
+	if (b2 > 0)
+		b = lshift(b, b2);
+	if (s2 > 0)
+		S = lshift(S, s2);
+	if (k_check) {
+		if (cmp(b,S) < 0) {
+			k--;
+			b = multadd(b, 10, 0);	/* we botched the k estimate */
+			if (leftright)
+				mhi = multadd(mhi, 10, 0);
+			ilim = ilim1;
+			}
+		}
+	if (ilim <= 0 && (mode == 3 || mode == 5)) {
+		if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+			/* no digits, fcvt style */
+ no_digits:
+			k = -1 - ndigits;
+			goto ret;
+			}
+ one_digit:
+		*s++ = '1';
+		k++;
+		goto ret;
+		}
+	if (leftright) {
+		if (m2 > 0)
+			mhi = lshift(mhi, m2);
+
+		/* Compute mlo -- check for special case
+		 * that d is a normalized power of 2.
+		 */
+
+		mlo = mhi;
+		if (spec_case) {
+			mhi = Balloc(mhi->k);
+			Bcopy(mhi, mlo);
+			mhi = lshift(mhi, Log2P);
+			}
+
+		for(i = 1;;i++) {
+			dig = quorem(b,S) + '0';
+			/* Do we yet have the shortest decimal string
+			 * that will round to d?
+			 */
+			j = cmp(b, mlo);
+			delta = diff(S, mhi);
+			j1 = delta->sign ? 1 : cmp(b, delta);
+			Bfree(delta);
+#ifndef ROUND_BIASED
+			if (j1 == 0 && mode != 1 && !(word1(d) & 1)
+#ifdef Honor_FLT_ROUNDS
+				&& rounding >= 1
+#endif
+								   ) {
+				if (dig == '9')
+					goto round_9_up;
+				if (j > 0)
+					dig++;
+#ifdef SET_INEXACT
+				else if (!b->x[0] && b->wds <= 1)
+					inexact = 0;
+#endif
+				*s++ = dig;
+				goto ret;
+				}
+#endif
+			if (j < 0 || j == 0 && mode != 1
+#ifndef ROUND_BIASED
+							&& !(word1(d) & 1)
+#endif
+					) {
+				if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+					inexact = 0;
+#endif
+					goto accept_dig;
+					}
+#ifdef Honor_FLT_ROUNDS
+				if (mode > 1)
+				 switch(rounding) {
+				  case 0: goto accept_dig;
+				  case 2: goto keep_dig;
+				  }
+#endif /*Honor_FLT_ROUNDS*/
+				if (j1 > 0) {
+					b = lshift(b, 1);
+					j1 = cmp(b, S);
+					if ((j1 > 0 || j1 == 0 && dig & 1)
+					&& dig++ == '9')
+						goto round_9_up;
+					}
+ accept_dig:
+				*s++ = dig;
+				goto ret;
+				}
+			if (j1 > 0) {
+#ifdef Honor_FLT_ROUNDS
+				if (!rounding)
+					goto accept_dig;
+#endif
+				if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+					*s++ = '9';
+					goto roundoff;
+					}
+				*s++ = dig + 1;
+				goto ret;
+				}
+#ifdef Honor_FLT_ROUNDS
+ keep_dig:
+#endif
+			*s++ = dig;
+			if (i == ilim)
+				break;
+			b = multadd(b, 10, 0);
+			if (mlo == mhi)
+				mlo = mhi = multadd(mhi, 10, 0);
+			else {
+				mlo = multadd(mlo, 10, 0);
+				mhi = multadd(mhi, 10, 0);
+				}
+			}
+		}
+	else
+		for(i = 1;; i++) {
+			*s++ = dig = quorem(b,S) + '0';
+			if (!b->x[0] && b->wds <= 1) {
+#ifdef SET_INEXACT
+				inexact = 0;
+#endif
+				goto ret;
+				}
+			if (i >= ilim)
+				break;
+			b = multadd(b, 10, 0);
+			}
+
+	/* Round off last digit */
+
+#ifdef Honor_FLT_ROUNDS
+	switch(rounding) {
+	  case 0: goto trimzeros;
+	  case 2: goto roundoff;
+	  }
+#endif
+	b = lshift(b, 1);
+	j = cmp(b, S);
+	if (j > 0 || j == 0 && dig & 1) {
+ roundoff:
+		while(*--s == '9')
+			if (s == s0) {
+				k++;
+				*s++ = '1';
+				goto ret;
+				}
+		++*s++;
+		}
+	else {
+ trimzeros:
+		while(*--s == '0');
+		s++;
+		}
+ ret:
+	Bfree(S);
+	if (mhi) {
+		if (mlo && mlo != mhi)
+			Bfree(mlo);
+		Bfree(mhi);
+		}
+ ret1:
+#ifdef SET_INEXACT
+	if (inexact) {
+		if (!oldinexact) {
+			word0(d) = Exp_1 + (70 << Exp_shift);
+			word1(d) = 0;
+			dval(d) += 1.;
+			}
+		}
+	else if (!oldinexact)
+		clear_inexact();
+#endif
+	Bfree(b);
+	*s = 0;
+	*decpt = k + 1;
+	if (rve)
+		*rve = s;
+	return s0;
+	}
+#ifdef __cplusplus
+}
+#endif
+
+PR_IMPLEMENT(PRStatus)
+PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits,
+	PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize)
+{
+    char *result;
+    PRSize resultlen;
+    PRStatus rv = PR_FAILURE;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (mode < 0 || mode > 3) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return rv;
+    }
+    result = dtoa(d, mode, ndigits, decpt, sign, rve);
+    if (!result) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return rv;
+    }
+    resultlen = strlen(result)+1;
+    if (bufsize < resultlen) {
+        PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
+    } else {
+        memcpy(buf, result, resultlen);
+        if (rve) {
+            *rve = buf + (*rve - result);
+        }
+        rv = PR_SUCCESS;
+    }
+    freedtoa(result);
+    return rv;  
+}
+
+/*
+** conversion routines for floating point
+** prcsn - number of digits of precision to generate floating
+** point value.
+** This should be reparameterized so that you can send in a
+**   prcn for the positive and negative ranges.  For now, 
+**   conform to the ECMA JavaScript spec which says numbers
+**   less than 1e-6 are in scientific notation.
+** Also, the ECMA spec says that there should always be a
+**   '+' or '-' after the 'e' in scientific notation
+*/
+PR_IMPLEMENT(void)
+PR_cnvtf(char *buf,int bufsz, int prcsn,double fval)
+{
+    PRIntn decpt, sign, numdigits;
+    char *num, *nump;
+    char *bufp = buf;
+    char *endnum;
+
+    /* If anything fails, we store an empty string in 'buf' */
+    num = (char*)PR_MALLOC(bufsz);
+    if (num == NULL) {
+        buf[0] = '\0';
+        return;
+    }
+    /* XXX Why use mode 1? */
+    if (PR_dtoa(dval(fval),1,prcsn,&decpt,&sign,&endnum,num,bufsz)
+            == PR_FAILURE) {
+        buf[0] = '\0';
+        goto done;
+    }
+    numdigits = endnum - num;
+    nump = num;
+
+    if (sign &&
+        !(word0(fval) == Sign_bit && word1(fval) == 0) &&
+        !((word0(fval) & Exp_mask) == Exp_mask &&
+          (word1(fval) || (word0(fval) & 0xfffff)))) {
+        *bufp++ = '-';
+    }
+
+    if (decpt == 9999) {
+        while ((*bufp++ = *nump++) != 0) {} /* nothing to execute */
+        goto done;
+    }
+
+    if (decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5) {
+        *bufp++ = *nump++;
+        if (numdigits != 1) {
+            *bufp++ = '.';
+        }
+
+        while (*nump != '\0') {
+            *bufp++ = *nump++;
+        }
+        *bufp++ = 'e';
+        PR_snprintf(bufp, bufsz - (bufp - buf), "%+d", decpt-1);
+    } else if (decpt >= 0) {
+        if (decpt == 0) {
+            *bufp++ = '0';
+        } else {
+            while (decpt--) {
+                if (*nump != '\0') {
+                    *bufp++ = *nump++;
+                } else {
+                    *bufp++ = '0';
+                }
+            }
+        }
+        if (*nump != '\0') {
+            *bufp++ = '.';
+            while (*nump != '\0') {
+                *bufp++ = *nump++;
+            }
+        }
+        *bufp++ = '\0';
+    } else if (decpt < 0) {
+        *bufp++ = '0';
+        *bufp++ = '.';
+        while (decpt++) {
+            *bufp++ = '0';
+        }
+
+        while (*nump != '\0') {
+            *bufp++ = *nump++;
+        }
+        *bufp++ = '\0';
+    }
+done:
+    PR_DELETE(num);
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prenv.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prenv.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,109 @@
+/* -*- 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 "primpl.h"
+
+/* Lock used to lock the environment */
+#if defined(_PR_NO_PREEMPT)
+#define _PR_NEW_LOCK_ENV()
+#define _PR_DELETE_LOCK_ENV()
+#define _PR_LOCK_ENV()
+#define _PR_UNLOCK_ENV()
+#elif defined(_PR_LOCAL_THREADS_ONLY)
+extern _PRCPU * _pr_primordialCPU;
+static PRIntn _is;
+#define _PR_NEW_LOCK_ENV()
+#define _PR_DELETE_LOCK_ENV()
+#define _PR_LOCK_ENV() if (_pr_primordialCPU) _PR_INTSOFF(_is);
+#define _PR_UNLOCK_ENV() if (_pr_primordialCPU) _PR_INTSON(_is);
+#else
+static PRLock *_pr_envLock = NULL;
+#define _PR_NEW_LOCK_ENV() {_pr_envLock = PR_NewLock();}
+#define _PR_DELETE_LOCK_ENV() \
+    { if (_pr_envLock) { PR_DestroyLock(_pr_envLock); _pr_envLock = NULL; } }
+#define _PR_LOCK_ENV() { if (_pr_envLock) PR_Lock(_pr_envLock); }
+#define _PR_UNLOCK_ENV() { if (_pr_envLock) PR_Unlock(_pr_envLock); }
+#endif
+
+/************************************************************************/
+
+void _PR_InitEnv(void)
+{
+	_PR_NEW_LOCK_ENV();
+}
+
+void _PR_CleanupEnv(void)
+{
+    _PR_DELETE_LOCK_ENV();
+}
+
+PR_IMPLEMENT(char*) PR_GetEnv(const char *var)
+{
+    char *ev;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    _PR_LOCK_ENV();
+    ev = _PR_MD_GET_ENV(var);
+    _PR_UNLOCK_ENV();
+    return ev;
+}
+
+PR_IMPLEMENT(PRStatus) PR_SetEnv(const char *string)
+{
+    PRIntn result;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if ( !strchr(string, '=')) return(PR_FAILURE);
+
+    _PR_LOCK_ENV();
+    result = _PR_MD_PUT_ENV(string);
+    _PR_UNLOCK_ENV();
+    return (result)? PR_FAILURE : PR_SUCCESS;
+}
+
+/*
+** DEPRECATED.  Use PR_SetEnv() instead.
+*/
+#ifdef XP_MAC
+PR_IMPLEMENT(PRIntn) PR_PutEnv(const char *string)
+{
+    return (PR_SetEnv(string) == PR_SUCCESS) ? PR_TRUE : PR_FALSE;
+}
+#endif

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,128 @@
+/* -*- 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 ***** */
+
+/*
+ *
+ * prerr.c
+ * This file is automatically generated; please do not edit it.
+ */
+#include "prerror.h"
+static const struct PRErrorMessage text[] = {
+	{"PR_OUT_OF_MEMORY_ERROR",    "Memory allocation attempt failed"},
+	{"PR_BAD_DESCRIPTOR_ERROR",    "Invalid file descriptor"},
+	{"PR_WOULD_BLOCK_ERROR",    "The operation would have blocked"},
+	{"PR_ACCESS_FAULT_ERROR",    "Invalid memory address argument"},
+	{"PR_INVALID_METHOD_ERROR",    "Invalid function for file type"},
+	{"PR_ILLEGAL_ACCESS_ERROR",    "Invalid memory address argument"},
+	{"PR_UNKNOWN_ERROR",    "Some unknown error has occurred"},
+	{"PR_PENDING_INTERRUPT_ERROR",    "Operation interrupted by another thread"},
+	{"PR_NOT_IMPLEMENTED_ERROR",    "function not implemented"},
+	{"PR_IO_ERROR",    "I/O function error"},
+	{"PR_IO_TIMEOUT_ERROR",    "I/O operation timed out"},
+	{"PR_IO_PENDING_ERROR",    "I/O operation on busy file descriptor"},
+	{"PR_DIRECTORY_OPEN_ERROR",    "The directory could not be opened"},
+	{"PR_INVALID_ARGUMENT_ERROR",    "Invalid function argument"},
+	{"PR_ADDRESS_NOT_AVAILABLE_ERROR",    "Network address not available (in use?)"},
+	{"PR_ADDRESS_NOT_SUPPORTED_ERROR",    "Network address type not supported"},
+	{"PR_IS_CONNECTED_ERROR",    "Already connected"},
+	{"PR_BAD_ADDRESS_ERROR",    "Network address is invalid"},
+	{"PR_ADDRESS_IN_USE_ERROR",    "Local Network address is in use"},
+	{"PR_CONNECT_REFUSED_ERROR",    "Connection refused by peer"},
+	{"PR_NETWORK_UNREACHABLE_ERROR",    "Network address is presently unreachable"},
+	{"PR_CONNECT_TIMEOUT_ERROR",    "Connection attempt timed out"},
+	{"PR_NOT_CONNECTED_ERROR",    "Network file descriptor is not connected"},
+	{"PR_LOAD_LIBRARY_ERROR",    "Failure to load dynamic library"},
+	{"PR_UNLOAD_LIBRARY_ERROR",    "Failure to unload dynamic library"},
+	{"PR_FIND_SYMBOL_ERROR",    "Symbol not found in any of the loaded dynamic libraries"},
+	{"PR_INSUFFICIENT_RESOURCES_ERROR",    "Insufficient system resources"},
+	{"PR_DIRECTORY_LOOKUP_ERROR",    "A directory lookup on a network address has failed"},
+	{"PR_TPD_RANGE_ERROR",    "Attempt to access a TPD key that is out of range"},
+	{"PR_PROC_DESC_TABLE_FULL_ERROR",    "Process open FD table is full"},
+	{"PR_SYS_DESC_TABLE_FULL_ERROR",    "System open FD table is full"},
+	{"PR_NOT_SOCKET_ERROR",    "Network operation attempted on non-network file descriptor"},
+	{"PR_NOT_TCP_SOCKET_ERROR",    "TCP-specific function attempted on a non-TCP file descriptor"},
+	{"PR_SOCKET_ADDRESS_IS_BOUND_ERROR",    "TCP file descriptor is already bound"},
+	{"PR_NO_ACCESS_RIGHTS_ERROR",    "Access Denied"},
+	{"PR_OPERATION_NOT_SUPPORTED_ERROR",    "The requested operation is not supported by the platform"},
+	{"PR_PROTOCOL_NOT_SUPPORTED_ERROR",    "The host operating system does not support the protocol requested"},
+	{"PR_REMOTE_FILE_ERROR",    "Access to the remote file has been severed"},
+	{"PR_BUFFER_OVERFLOW_ERROR",    "The value requested is too large to be stored in the data buffer provided"},
+	{"PR_CONNECT_RESET_ERROR",    "TCP connection reset by peer"},
+	{"PR_RANGE_ERROR",    "Unused"},
+	{"PR_DEADLOCK_ERROR",    "The operation would have deadlocked"},
+	{"PR_FILE_IS_LOCKED_ERROR",    "The file is already locked"},
+	{"PR_FILE_TOO_BIG_ERROR",    "Write would result in file larger than the system allows"},
+	{"PR_NO_DEVICE_SPACE_ERROR",    "The device for storing the file is full"},
+	{"PR_PIPE_ERROR",    "Unused"},
+	{"PR_NO_SEEK_DEVICE_ERROR",    "Unused"},
+	{"PR_IS_DIRECTORY_ERROR",    "Cannot perform a normal file operation on a directory"},
+	{"PR_LOOP_ERROR",    "Symbolic link loop"},
+	{"PR_NAME_TOO_LONG_ERROR",    "File name is too long"},
+	{"PR_FILE_NOT_FOUND_ERROR",    "File not found"},
+	{"PR_NOT_DIRECTORY_ERROR",    "Cannot perform directory operation on a normal file"},
+	{"PR_READ_ONLY_FILESYSTEM_ERROR",    "Cannot write to a read-only file system"},
+	{"PR_DIRECTORY_NOT_EMPTY_ERROR",    "Cannot delete a directory that is not empty"},
+	{"PR_FILESYSTEM_MOUNTED_ERROR",    "Cannot delete or rename a file object while the file system is busy"},
+	{"PR_NOT_SAME_DEVICE_ERROR",    "Cannot rename a file to a file system on another device"},
+	{"PR_DIRECTORY_CORRUPTED_ERROR",    "The directory object in the file system is corrupted"},
+	{"PR_FILE_EXISTS_ERROR",    "Cannot create or rename a filename that already exists"},
+	{"PR_MAX_DIRECTORY_ENTRIES_ERROR",    "Directory is full.  No additional filenames may be added"},
+	{"PR_INVALID_DEVICE_STATE_ERROR",    "The required device was in an invalid state"},
+	{"PR_DEVICE_IS_LOCKED_ERROR",    "The device is locked"},
+	{"PR_NO_MORE_FILES_ERROR",    "No more entries in the directory"},
+	{"PR_END_OF_FILE_ERROR",    "Encountered end of file"},
+	{"PR_FILE_SEEK_ERROR",    "Seek error"},
+	{"PR_FILE_IS_BUSY_ERROR",    "The file is busy"},
+	{"PR_OPERATION_ABORTED_ERROR",    "The I/O operation was aborted"},
+	{"PR_IN_PROGRESS_ERROR",    "Operation is still in progress (probably a non-blocking connect)"},
+	{"PR_ALREADY_INITIATED_ERROR",    "Operation has already been initiated (probably a non-blocking connect)"},
+	{"PR_GROUP_EMPTY_ERROR",    "The wait group is empty"},
+	{"PR_INVALID_STATE_ERROR",    "Object state improper for request"},
+	{"PR_NETWORK_DOWN_ERROR",    "Network is down"},
+	{"PR_SOCKET_SHUTDOWN_ERROR",    "Socket shutdown"},
+	{"PR_CONNECT_ABORTED_ERROR",    "Connection aborted"},
+	{"PR_HOST_UNREACHABLE_ERROR",    "Host is unreachable"},
+	{"PR_LIBRARY_NOT_LOADED_ERROR",    "The library is not loaded"},
+	{"PR_MAX_ERROR",    "Placeholder for the end of the list"},
+	{0, 0}
+};
+
+static const struct PRErrorTable et = { text, "prerr", -6000L, 76 };
+
+void nspr_InitializePRErrorTable(void) {
+    PR_ErrorInstallTable(&et);
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerr.et
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerr.et	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,139 @@
+# 
+# ***** 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 *****
+
+et nspr -6000
+
+ec PR_OUT_OF_MEMORY_ERROR,      "Memory allocation attempt failed"
+ec PR_BAD_DESCRIPTOR_ERROR,     "Invalid file descriptor"
+ec PR_WOULD_BLOCK_ERROR,        "The operation would have blocked"
+ec PR_ACCESS_FAULT_ERROR,       "Invalid memory address argument"
+ec PR_INVALID_METHOD_ERROR,     "Invalid function for file type"
+ec PR_ILLEGAL_ACCESS_ERROR,     "Invalid memory address argument"
+ec PR_UNKNOWN_ERROR,            "Some unknown error has occurred"
+ec PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread"
+ec PR_NOT_IMPLEMENTED_ERROR,    "function not implemented"
+ec PR_IO_ERROR,                 "I/O function error"
+ec PR_IO_TIMEOUT_ERROR,         "I/O operation timed out"
+ec PR_IO_PENDING_ERROR,         "I/O operation on busy file descriptor"
+ec PR_DIRECTORY_OPEN_ERROR,     "The directory could not be opened"
+ec PR_INVALID_ARGUMENT_ERROR, "Invalid function argument"
+ec PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)"
+ec PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported"
+ec PR_IS_CONNECTED_ERROR,       "Already connected"
+ec PR_BAD_ADDRESS_ERROR,        "Network address is invalid"
+ec PR_ADDRESS_IN_USE_ERROR,     "Local Network address is in use"
+ec PR_CONNECT_REFUSED_ERROR,    "Connection refused by peer"
+ec PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable"
+ec PR_CONNECT_TIMEOUT_ERROR,    "Connection attempt timed out"
+ec PR_NOT_CONNECTED_ERROR,      "Network file descriptor is not connected"
+ec PR_LOAD_LIBRARY_ERROR,       "Failure to load dynamic library"
+ec PR_UNLOAD_LIBRARY_ERROR,     "Failure to unload dynamic library"
+ec PR_FIND_SYMBOL_ERROR,
+"Symbol not found in any of the loaded dynamic libraries"
+ec PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources"
+ec PR_DIRECTORY_LOOKUP_ERROR,
+"A directory lookup on a network address has failed"
+ec PR_TPD_RANGE_ERROR,
+"Attempt to access a TPD key that is out of range"
+ec PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full"
+ec PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full"
+ec PR_NOT_SOCKET_ERROR,
+"Network operation attempted on non-network file descriptor"
+ec PR_NOT_TCP_SOCKET_ERROR,
+"TCP-specific function attempted on a non-TCP file descriptor"
+ec PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound"
+ec PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied"
+ec PR_OPERATION_NOT_SUPPORTED_ERROR,
+"The requested operation is not supported by the platform"
+ec PR_PROTOCOL_NOT_SUPPORTED_ERROR,
+"The host operating system does not support the protocol requested"
+ec PR_REMOTE_FILE_ERROR,        "Access to the remote file has been severed"
+ec PR_BUFFER_OVERFLOW_ERROR,
+"The value requested is too large to be stored in the data buffer provided"
+ec PR_CONNECT_RESET_ERROR,      "TCP connection reset by peer"
+ec PR_RANGE_ERROR,              "Unused"
+ec PR_DEADLOCK_ERROR,   "The operation would have deadlocked"
+ec PR_FILE_IS_LOCKED_ERROR,     "The file is already locked"
+ec PR_FILE_TOO_BIG_ERROR,
+"Write would result in file larger than the system allows"
+ec PR_NO_DEVICE_SPACE_ERROR,    "The device for storing the file is full"
+ec PR_PIPE_ERROR,               "Unused"
+ec PR_NO_SEEK_DEVICE_ERROR,     "Unused"
+ec PR_IS_DIRECTORY_ERROR,
+"Cannot perform a normal file operation on a directory"
+ec PR_LOOP_ERROR,               "Symbolic link loop"
+ec PR_NAME_TOO_LONG_ERROR,      "File name is too long"
+ec PR_FILE_NOT_FOUND_ERROR,     "File not found"
+ec PR_NOT_DIRECTORY_ERROR,
+"Cannot perform directory operation on a normal file"
+ec PR_READ_ONLY_FILESYSTEM_ERROR,
+"Cannot write to a read-only file system"
+ec PR_DIRECTORY_NOT_EMPTY_ERROR,
+"Cannot delete a directory that is not empty"
+ec PR_FILESYSTEM_MOUNTED_ERROR,
+"Cannot delete or rename a file object while the file system is busy"
+ec PR_NOT_SAME_DEVICE_ERROR,
+"Cannot rename a file to a file system on another device"
+ec PR_DIRECTORY_CORRUPTED_ERROR,
+"The directory object in the file system is corrupted"
+ec PR_FILE_EXISTS_ERROR,
+"Cannot create or rename a filename that already exists"
+ec PR_MAX_DIRECTORY_ENTRIES_ERROR,
+"Directory is full.  No additional filenames may be added"
+ec PR_INVALID_DEVICE_STATE_ERROR,
+"The required device was in an invalid state"
+ec PR_DEVICE_IS_LOCKED_ERROR, "The device is locked"
+ec PR_NO_MORE_FILES_ERROR,      "No more entries in the directory"
+ec PR_END_OF_FILE_ERROR,        "Encountered end of file"
+ec PR_FILE_SEEK_ERROR,  "Seek error"
+ec PR_FILE_IS_BUSY_ERROR,       "The file is busy"
+ec PR_OPERATION_ABORTED_ERROR,  "The I/O operation was aborted"
+ec PR_IN_PROGRESS_ERROR,
+"Operation is still in progress (probably a non-blocking connect)"
+ec PR_ALREADY_INITIATED_ERROR,
+"Operation has already been initiated (probably a non-blocking connect)"
+ec PR_GROUP_EMPTY_ERROR,        "The wait group is empty"
+ec PR_INVALID_STATE_ERROR,      "Object state improper for request"
+ec PR_NETWORK_DOWN_ERROR,       "Network is down"
+ec PR_SOCKET_SHUTDOWN_ERROR,    "Socket shutdown"
+ec PR_CONNECT_ABORTED_ERROR,    "Connection aborted"
+ec PR_HOST_UNREACHABLE_ERROR,   "Host is unreachable"
+ec PR_LIBRARY_NOT_LOADED_ERROR, "The library is not loaded"
+
+ec PR_MAX_ERROR,                "Placeholder for the end of the list"
+
+end

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerr.properties
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerr.properties	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,116 @@
+# 
+# ***** 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 *****
+
+#
+# prerr.properties
+# This file is automatically generated; please do not edit it.
+PR_OUT_OF_MEMORY_ERROR=Memory allocation attempt failed
+PR_BAD_DESCRIPTOR_ERROR=Invalid file descriptor
+PR_WOULD_BLOCK_ERROR=The operation would have blocked
+PR_ACCESS_FAULT_ERROR=Invalid memory address argument
+PR_INVALID_METHOD_ERROR=Invalid function for file type
+PR_ILLEGAL_ACCESS_ERROR=Invalid memory address argument
+PR_UNKNOWN_ERROR=Some unknown error has occurred
+PR_PENDING_INTERRUPT_ERROR=Operation interrupted by another thread
+PR_NOT_IMPLEMENTED_ERROR=function not implemented
+PR_IO_ERROR=I/O function error
+PR_IO_TIMEOUT_ERROR=I/O operation timed out
+PR_IO_PENDING_ERROR=I/O operation on busy file descriptor
+PR_DIRECTORY_OPEN_ERROR=The directory could not be opened
+PR_INVALID_ARGUMENT_ERROR=Invalid function argument
+PR_ADDRESS_NOT_AVAILABLE_ERROR=Network address not available (in use?)
+PR_ADDRESS_NOT_SUPPORTED_ERROR=Network address type not supported
+PR_IS_CONNECTED_ERROR=Already connected
+PR_BAD_ADDRESS_ERROR=Network address is invalid
+PR_ADDRESS_IN_USE_ERROR=Local Network address is in use
+PR_CONNECT_REFUSED_ERROR=Connection refused by peer
+PR_NETWORK_UNREACHABLE_ERROR=Network address is presently unreachable
+PR_CONNECT_TIMEOUT_ERROR=Connection attempt timed out
+PR_NOT_CONNECTED_ERROR=Network file descriptor is not connected
+PR_LOAD_LIBRARY_ERROR=Failure to load dynamic library
+PR_UNLOAD_LIBRARY_ERROR=Failure to unload dynamic library
+PR_FIND_SYMBOL_ERROR=Symbol not found in any of the loaded dynamic libraries
+PR_INSUFFICIENT_RESOURCES_ERROR=Insufficient system resources
+PR_DIRECTORY_LOOKUP_ERROR=A directory lookup on a network address has failed
+PR_TPD_RANGE_ERROR=Attempt to access a TPD key that is out of range
+PR_PROC_DESC_TABLE_FULL_ERROR=Process open FD table is full
+PR_SYS_DESC_TABLE_FULL_ERROR=System open FD table is full
+PR_NOT_SOCKET_ERROR=Network operation attempted on non-network file descriptor
+PR_NOT_TCP_SOCKET_ERROR=TCP-specific function attempted on a non-TCP file descriptor
+PR_SOCKET_ADDRESS_IS_BOUND_ERROR=TCP file descriptor is already bound
+PR_NO_ACCESS_RIGHTS_ERROR=Access Denied
+PR_OPERATION_NOT_SUPPORTED_ERROR=The requested operation is not supported by the platform
+PR_PROTOCOL_NOT_SUPPORTED_ERROR=The host operating system does not support the protocol requested
+PR_REMOTE_FILE_ERROR=Access to the remote file has been severed
+PR_BUFFER_OVERFLOW_ERROR=The value requested is too large to be stored in the data buffer provided
+PR_CONNECT_RESET_ERROR=TCP connection reset by peer
+PR_RANGE_ERROR=Unused
+PR_DEADLOCK_ERROR=The operation would have deadlocked
+PR_FILE_IS_LOCKED_ERROR=The file is already locked
+PR_FILE_TOO_BIG_ERROR=Write would result in file larger than the system allows
+PR_NO_DEVICE_SPACE_ERROR=The device for storing the file is full
+PR_PIPE_ERROR=Unused
+PR_NO_SEEK_DEVICE_ERROR=Unused
+PR_IS_DIRECTORY_ERROR=Cannot perform a normal file operation on a directory
+PR_LOOP_ERROR=Symbolic link loop
+PR_NAME_TOO_LONG_ERROR=File name is too long
+PR_FILE_NOT_FOUND_ERROR=File not found
+PR_NOT_DIRECTORY_ERROR=Cannot perform directory operation on a normal file
+PR_READ_ONLY_FILESYSTEM_ERROR=Cannot write to a read-only file system
+PR_DIRECTORY_NOT_EMPTY_ERROR=Cannot delete a directory that is not empty
+PR_FILESYSTEM_MOUNTED_ERROR=Cannot delete or rename a file object while the file system is busy
+PR_NOT_SAME_DEVICE_ERROR=Cannot rename a file to a file system on another device
+PR_DIRECTORY_CORRUPTED_ERROR=The directory object in the file system is corrupted
+PR_FILE_EXISTS_ERROR=Cannot create or rename a filename that already exists
+PR_MAX_DIRECTORY_ENTRIES_ERROR=Directory is full.  No additional filenames may be added
+PR_INVALID_DEVICE_STATE_ERROR=The required device was in an invalid state
+PR_DEVICE_IS_LOCKED_ERROR=The device is locked
+PR_NO_MORE_FILES_ERROR=No more entries in the directory
+PR_END_OF_FILE_ERROR=Encountered end of file
+PR_FILE_SEEK_ERROR=Seek error
+PR_FILE_IS_BUSY_ERROR=The file is busy
+PR_OPERATION_ABORTED_ERROR=The I/O operation was aborted
+PR_IN_PROGRESS_ERROR=Operation is still in progress (probably a non-blocking connect)
+PR_ALREADY_INITIATED_ERROR=Operation has already been initiated (probably a non-blocking connect)
+PR_GROUP_EMPTY_ERROR=The wait group is empty
+PR_INVALID_STATE_ERROR=Object state improper for request
+PR_NETWORK_DOWN_ERROR=Network is down
+PR_SOCKET_SHUTDOWN_ERROR=Socket shutdown
+PR_CONNECT_ABORTED_ERROR=Connection aborted
+PR_HOST_UNREACHABLE_ERROR=Host is unreachable
+PR_LIBRARY_NOT_LOADED_ERROR=The library is not loaded
+PR_MAX_ERROR=Placeholder for the end of the list

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerror.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerror.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,107 @@
+/* -*- 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 <string.h>
+#include <stdlib.h>
+
+PR_IMPLEMENT(PRErrorCode) PR_GetError(void)
+{
+    PRThread *thread = PR_GetCurrentThread();
+    return thread->errorCode;
+}
+
+PR_IMPLEMENT(PRInt32) PR_GetOSError(void)
+{
+    PRThread *thread = PR_GetCurrentThread();
+    return thread->osErrorCode;
+}
+
+PR_IMPLEMENT(void) PR_SetError(PRErrorCode code, PRInt32 osErr)
+{
+    PRThread *thread = PR_GetCurrentThread();
+    thread->errorCode = code;
+    thread->osErrorCode = osErr;
+    thread->errorStringLength = 0;
+}
+
+PR_IMPLEMENT(void) PR_SetErrorText(PRIntn textLength, const char *text)
+{
+    PRThread *thread = PR_GetCurrentThread();
+
+    if (0 == textLength)
+    {
+	    if (NULL != thread->errorString)
+	        PR_DELETE(thread->errorString);
+	    thread->errorStringSize = 0;
+    }
+    else
+    {
+	    PRIntn size = textLength + 31;  /* actual length to allocate. Plus a little extra */
+        if (thread->errorStringSize < textLength+1)  /* do we have room? */
+        {
+	        if (NULL != thread->errorString)
+	            PR_DELETE(thread->errorString);
+		    thread->errorString = (char*)PR_MALLOC(size);
+            if ( NULL == thread->errorString ) {
+                thread->errorStringSize = 0;
+                thread->errorStringLength = 0;
+                return;
+            }
+            thread->errorStringSize = size;
+	    }
+        memcpy(thread->errorString, text, textLength+1 );
+    }
+    thread->errorStringLength = textLength;
+}
+
+PR_IMPLEMENT(PRInt32) PR_GetErrorTextLength(void)
+{
+    PRThread *thread = PR_GetCurrentThread();
+    return thread->errorStringLength;
+}  /* PR_GetErrorTextLength */
+
+PR_IMPLEMENT(PRInt32) PR_GetErrorText(char *text)
+{
+    PRThread *thread = PR_GetCurrentThread();
+    if (0 != thread->errorStringLength)
+        memcpy(text, thread->errorString, thread->errorStringLength+1);
+    return thread->errorStringLength;
+}  /* PR_GetErrorText */
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerrortable.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prerrortable.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,240 @@
+/* ***** 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 ***** */
+
+
+
+
+/*
+
+Copyright 1987, 1988 by the Student Information Processing Board
+	of the Massachusetts Institute of Technology
+
+Permission to use, copy, modify, and distribute this software
+and its documentation for any purpose and without fee is
+hereby granted, provided that the above copyright notice
+appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation,
+and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+M.I.T. and the M.I.T. S.I.P.B. make no representations about
+the suitability of this software for any purpose.  It is
+provided "as is" without express or implied warranty.
+
+*/
+
+#include <string.h>
+#ifdef SUNOS4
+#include "md/sunos4.h"  /* for strerror */
+#endif
+#include <assert.h>
+#include <errno.h>
+#include "prmem.h"
+#include "prerror.h"
+
+#define	ERRCODE_RANGE	8	/* # of bits to shift table number */
+#define	BITS_PER_CHAR	6	/* # bits to shift per character in name */
+
+#ifdef NEED_SYS_ERRLIST
+extern char const * const sys_errlist[];
+extern const int sys_nerr;
+#endif
+
+/* List of error tables */
+struct PRErrorTableList {
+    struct PRErrorTableList *next;
+    const struct PRErrorTable *table;
+    struct PRErrorCallbackTablePrivate *table_private;
+};
+static struct PRErrorTableList * Table_List = (struct PRErrorTableList *) NULL;
+
+/* Supported languages */
+static const char * default_languages[] = { "i-default", "en", 0 };
+static const char * const * callback_languages = default_languages;
+
+/* Callback info */
+static struct PRErrorCallbackPrivate *callback_private = 0;
+static PRErrorCallbackLookupFn *callback_lookup = 0;
+static PRErrorCallbackNewTableFn *callback_newtable = 0;
+
+
+static const char char_set[] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
+
+static const char *
+error_table_name (PRErrorCode num)
+{
+    static char buf[6];	/* only used if internal code problems exist */
+
+    long ch;
+    int i;
+    char *p;
+
+    /* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
+    p = buf;
+    num >>= ERRCODE_RANGE;
+    /* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
+    num &= 077777777;
+    /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
+    for (i = 4; i >= 0; i--) {
+	ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
+	if (ch != 0)
+	    *p++ = char_set[ch-1];
+    }
+    *p = '\0';
+    return(buf);
+}
+
+PR_IMPLEMENT(const char *)
+PR_ErrorToString(PRErrorCode code, PRLanguageCode language)
+{
+    /* static buffer only used if code is using inconsistent error message
+     * numbers, so just ignore the possible thread contention
+     */
+    static char buffer[25];
+
+    const char *msg;
+    int offset;
+    PRErrorCode table_num;
+    struct PRErrorTableList *et;
+    int started = 0;
+    char *cp;
+
+    for (et = Table_List; et; et = et->next) {
+	if (et->table->base <= code &&
+	    et->table->base + et->table->n_msgs > code) {
+	    /* This is the right table */
+	    if (callback_lookup) {
+		msg = callback_lookup(code, language, et->table,
+		    callback_private, et->table_private);
+		if (msg) return msg;
+	    }
+    
+	    return(et->table->msgs[code - et->table->base].en_text);
+	}
+    }
+
+    if (code >= 0 && code < 256) {
+	return strerror(code);
+    }
+
+    offset = (int) (code & ((1<<ERRCODE_RANGE)-1));
+    table_num = code - offset;
+    strcpy (buffer, "Unknown code ");
+    if (table_num) {
+	strcat(buffer, error_table_name (table_num));
+	strcat(buffer, " ");
+    }
+    for (cp = buffer; *cp; cp++)
+	;
+    if (offset >= 100) {
+	*cp++ = (char)('0' + offset / 100);
+	offset %= 100;
+	started++;
+    }
+    if (started || offset >= 10) {
+	*cp++ = (char)('0' + offset / 10);
+	offset %= 10;
+    }
+    *cp++ = (char)('0' + offset);
+    *cp = '\0';
+    return(buffer);
+}
+
+PR_IMPLEMENT(const char *)
+PR_ErrorToName(PRErrorCode code)
+{
+    struct PRErrorTableList *et;
+
+    for (et = Table_List; et; et = et->next) {
+	if (et->table->base <= code &&
+	    et->table->base + et->table->n_msgs > code) {
+	    /* This is the right table */
+	    return(et->table->msgs[code - et->table->base].name);
+	}
+    }
+
+    return 0;
+}
+
+PR_IMPLEMENT(const char * const *)
+PR_ErrorLanguages(void)
+{
+    return callback_languages;
+}
+
+PR_IMPLEMENT(PRErrorCode)
+PR_ErrorInstallTable(const struct PRErrorTable *table)
+{
+    struct PRErrorTableList * new_et;
+
+    new_et = (struct PRErrorTableList *)
+					PR_Malloc(sizeof(struct PRErrorTableList));
+    if (!new_et)
+	return errno;	/* oops */
+    new_et->table = table;
+    if (callback_newtable) {
+	new_et->table_private = callback_newtable(table, callback_private);
+    } else {
+	new_et->table_private = 0;
+    }
+    new_et->next = Table_List;
+    Table_List = new_et;
+    return 0;
+}
+
+PR_IMPLEMENT(void)
+PR_ErrorInstallCallback(const char * const * languages,
+		       PRErrorCallbackLookupFn *lookup, 
+		       PRErrorCallbackNewTableFn *newtable,
+		       struct PRErrorCallbackPrivate *cb_private)
+{
+    struct PRErrorTableList *et;
+
+    assert(strcmp(languages[0], "i-default") == 0);
+    assert(strcmp(languages[1], "en") == 0);
+    
+    callback_languages = languages;
+    callback_lookup = lookup;
+    callback_newtable = newtable;
+    callback_private = cb_private;
+
+    if (callback_newtable) {
+	for (et = Table_List; et; et = et->next) {
+	    et->table_private = callback_newtable(et->table, callback_private);
+	}
+    }
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prinit.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prinit.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,870 @@
+/* -*- 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 <ctype.h>
+#include <string.h>
+
+PRLogModuleInfo *_pr_clock_lm;
+PRLogModuleInfo *_pr_cmon_lm;
+PRLogModuleInfo *_pr_io_lm;
+PRLogModuleInfo *_pr_cvar_lm;
+PRLogModuleInfo *_pr_mon_lm;
+PRLogModuleInfo *_pr_linker_lm;
+PRLogModuleInfo *_pr_sched_lm;
+PRLogModuleInfo *_pr_thread_lm;
+PRLogModuleInfo *_pr_gc_lm;
+PRLogModuleInfo *_pr_shm_lm;
+PRLogModuleInfo *_pr_shma_lm;
+
+PRFileDesc *_pr_stdin;
+PRFileDesc *_pr_stdout;
+PRFileDesc *_pr_stderr;
+
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
+
+PRCList _pr_active_local_threadQ =
+			PR_INIT_STATIC_CLIST(&_pr_active_local_threadQ);
+PRCList _pr_active_global_threadQ =
+			PR_INIT_STATIC_CLIST(&_pr_active_global_threadQ);
+
+_MDLock  _pr_cpuLock;           /* lock for the CPU Q */
+PRCList _pr_cpuQ = PR_INIT_STATIC_CLIST(&_pr_cpuQ);
+
+PRUint32 _pr_utid;
+
+PRInt32 _pr_userActive;
+PRInt32 _pr_systemActive;
+PRUintn _pr_maxPTDs;
+
+#ifdef _PR_LOCAL_THREADS_ONLY
+
+struct _PRCPU 	*_pr_currentCPU;
+PRThread 	*_pr_currentThread;
+PRThread 	*_pr_lastThread;
+PRInt32 	_pr_intsOff;
+
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+/* Lock protecting all "termination" condition variables of all threads */
+PRLock *_pr_terminationCVLock;
+
+#endif /* !defined(_PR_PTHREADS) */
+
+PRLock *_pr_sleeplock;  /* used in PR_Sleep(), classic and pthreads */
+
+static void _PR_InitCallOnce(void);
+
+PRBool _pr_initialized = PR_FALSE;
+
+
+PR_IMPLEMENT(PRBool) PR_VersionCheck(const char *importedVersion)
+{
+    /*
+    ** This is the secret handshake algorithm.
+    **
+    ** This release has a simple version compatibility
+    ** check algorithm.  This release is not backward
+    ** compatible with previous major releases.  It is
+    ** not compatible with future major, minor, or
+    ** patch releases.
+    */
+    int vmajor = 0, vminor = 0, vpatch = 0;
+    const char *ptr = importedVersion;
+
+    while (isdigit(*ptr)) {
+        vmajor = 10 * vmajor + *ptr - '0';
+        ptr++;
+    }
+    if (*ptr == '.') {
+        ptr++;
+        while (isdigit(*ptr)) {
+            vminor = 10 * vminor + *ptr - '0';
+            ptr++;
+        }
+        if (*ptr == '.') {
+            ptr++;
+            while (isdigit(*ptr)) {
+                vpatch = 10 * vpatch + *ptr - '0';
+                ptr++;
+            }
+        }
+    }
+
+    if (vmajor != PR_VMAJOR) {
+        return PR_FALSE;
+    }
+    if (vmajor == PR_VMAJOR && vminor > PR_VMINOR) {
+        return PR_FALSE;
+    }
+    if (vmajor == PR_VMAJOR && vminor == PR_VMINOR && vpatch > PR_VPATCH) {
+        return PR_FALSE;
+    }
+    return PR_TRUE;
+}  /* PR_VersionCheck */
+
+
+PR_IMPLEMENT(PRBool) PR_Initialized(void)
+{
+    return _pr_initialized;
+}
+
+PRInt32 _native_threads_only = 0;
+
+#ifdef WINNT
+static void _pr_SetNativeThreadsOnlyMode(void)
+{
+    HMODULE mainExe;
+    PRBool *globalp;
+    char *envp;
+
+    mainExe = GetModuleHandle(NULL);
+    PR_ASSERT(NULL != mainExe);
+    globalp = (PRBool *) GetProcAddress(mainExe, "nspr_native_threads_only");
+    if (globalp) {
+        _native_threads_only = (*globalp != PR_FALSE);
+    } else if (envp = getenv("NSPR_NATIVE_THREADS_ONLY")) {
+        _native_threads_only = (atoi(envp) == 1);
+    }
+}
+#endif
+
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+extern PRStatus _pr_init_ipv6(void);
+#endif
+
+static void _PR_InitStuff(void)
+{
+
+    if (_pr_initialized) return;
+    _pr_initialized = PR_TRUE;
+#ifdef _PR_ZONE_ALLOCATOR
+    _PR_InitZones();
+#endif
+#ifdef WINNT
+    _pr_SetNativeThreadsOnlyMode();
+#endif
+
+
+    (void) PR_GetPageSize();
+
+	_pr_clock_lm = PR_NewLogModule("clock");
+	_pr_cmon_lm = PR_NewLogModule("cmon");
+	_pr_io_lm = PR_NewLogModule("io");
+	_pr_mon_lm = PR_NewLogModule("mon");
+	_pr_linker_lm = PR_NewLogModule("linker");
+	_pr_cvar_lm = PR_NewLogModule("cvar");
+	_pr_sched_lm = PR_NewLogModule("sched");
+	_pr_thread_lm = PR_NewLogModule("thread");
+	_pr_gc_lm = PR_NewLogModule("gc");
+	_pr_shm_lm = PR_NewLogModule("shm");
+	_pr_shma_lm = PR_NewLogModule("shma");
+      
+    /* NOTE: These init's cannot depend on _PR_MD_CURRENT_THREAD() */ 
+    _PR_MD_EARLY_INIT();
+
+    _PR_InitLocks();
+    _PR_InitAtomic();
+    _PR_InitSegs();
+    _PR_InitStacks();
+	_PR_InitTPD();
+    _PR_InitEnv();
+    _PR_InitLayerCache();
+    _PR_InitClock();
+
+    _pr_sleeplock = PR_NewLock();
+    PR_ASSERT(NULL != _pr_sleeplock);
+
+#ifdef GC_LEAK_DETECTOR
+    _PR_InitGarbageCollector();
+#endif
+
+    _PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    
+#ifdef WIN16
+	{
+	PRInt32 top;   /* artificial top of stack, win16 */
+    _pr_top_of_task_stack = (char *) &top;
+	}
+#endif    
+
+#ifndef _PR_GLOBAL_THREADS_ONLY
+	_PR_InitCPUs();
+#endif
+
+/*
+ * XXX: call _PR_InitMem only on those platforms for which nspr implements
+ *	malloc, for now.
+ */
+#ifdef _PR_OVERRIDE_MALLOC
+    _PR_InitMem();
+#endif
+
+    _PR_InitCMon();
+    _PR_InitIO();
+    _PR_InitNet();
+    _PR_InitLog();
+    _PR_InitLinker();
+    _PR_InitCallOnce();
+    _PR_InitDtoa();
+    _PR_InitMW();
+    _PR_InitRWLocks();
+
+    nspr_InitializePRErrorTable();
+
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+	_pr_init_ipv6();
+#endif
+	
+    _PR_MD_FINAL_INIT();
+}
+
+void _PR_ImplicitInitialization(void)
+{
+	_PR_InitStuff();
+
+    /* Enable interrupts */
+#if !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY)
+    _PR_MD_START_INTERRUPTS();
+#endif
+
+}
+
+PR_IMPLEMENT(void) PR_DisableClockInterrupts(void)
+{
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
+	if (!_pr_initialized) {
+		_PR_InitStuff();
+	} else {
+    	_PR_MD_DISABLE_CLOCK_INTERRUPTS();
+	}
+#endif
+}
+
+PR_IMPLEMENT(void) PR_EnableClockInterrupts(void)
+{
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
+	if (!_pr_initialized) {
+		_PR_InitStuff();
+	}
+    _PR_MD_ENABLE_CLOCK_INTERRUPTS();
+#endif
+}
+
+PR_IMPLEMENT(void) PR_BlockClockInterrupts(void)
+{
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
+    	_PR_MD_BLOCK_CLOCK_INTERRUPTS();
+#endif
+}
+
+PR_IMPLEMENT(void) PR_UnblockClockInterrupts(void)
+{
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
+    	_PR_MD_UNBLOCK_CLOCK_INTERRUPTS();
+#endif
+}
+
+PR_IMPLEMENT(void) PR_Init(
+    PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs)
+{
+#if defined(XP_MAC)
+#pragma unused (type, priority, maxPTDs)
+#endif
+
+    _PR_ImplicitInitialization();
+}
+
+PR_IMPLEMENT(PRIntn) PR_Initialize(
+    PRPrimordialFn prmain, PRIntn argc, char **argv, PRUintn maxPTDs)
+{
+#if defined(XP_MAC)
+#pragma unused (maxPTDs)
+#endif
+
+    PRIntn rv;
+    _PR_ImplicitInitialization();
+    rv = prmain(argc, argv);
+	PR_Cleanup();
+    return rv;
+}  /* PR_Initialize */
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * _PR_CleanupBeforeExit --
+ *
+ *   Perform the cleanup work before exiting the process. 
+ *   We first do the cleanup generic to all platforms.  Then
+ *   we call _PR_MD_CLEANUP_BEFORE_EXIT(), where platform-dependent
+ *   cleanup is done.  This function is used by PR_Cleanup().
+ *
+ * See also: PR_Cleanup().
+ *
+ *-----------------------------------------------------------------------
+ */
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
+    /* see ptthread.c */
+#else
+static void
+_PR_CleanupBeforeExit(void)
+{
+/* 
+Do not make any calls here other than to destroy resources.  For example,
+do not make any calls that eventually may end up in PR_Lock.  Because the
+thread is destroyed, can not access current thread any more.
+*/
+    _PR_CleanupTPD();
+    if (_pr_terminationCVLock)
+    /*
+     * In light of the comment above, this looks real suspicious.
+     * I'd go so far as to say it's just a problem waiting to happen.
+     */
+        PR_DestroyLock(_pr_terminationCVLock);
+
+    _PR_MD_CLEANUP_BEFORE_EXIT();
+}
+#endif /* defined(_PR_PTHREADS) */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PR_Cleanup --
+ *
+ *   Perform a graceful shutdown of the NSPR runtime.  PR_Cleanup() may
+ *   only be called from the primordial thread, typically at the
+ *   end of the main() function.  It returns when it has completed
+ *   its platform-dependent duty and the process must not make any other
+ *   NSPR library calls prior to exiting from main().
+ *
+ *   PR_Cleanup() first blocks the primordial thread until all the
+ *   other user (non-system) threads, if any, have terminated.
+ *   Then it performs cleanup in preparation for exiting the process.
+ *   PR_Cleanup() does not exit the primordial thread (which would
+ *   in turn exit the process).
+ *   
+ *   PR_Cleanup() only responds when it is called by the primordial
+ *   thread. Calls by any other thread are silently ignored.
+ *
+ * See also: PR_ExitProcess()
+ *
+ *----------------------------------------------------------------------
+ */
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
+    /* see ptthread.c */
+#else
+
+PR_IMPLEMENT(PRStatus) PR_Cleanup()
+{
+    PRThread *me = PR_GetCurrentThread();
+    PR_ASSERT((NULL != me) && (me->flags & _PR_PRIMORDIAL));
+    if ((NULL != me) && (me->flags & _PR_PRIMORDIAL))
+    {
+        PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR"));
+
+        /*
+         * No more recycling of threads
+         */
+        _pr_recycleThreads = 0;
+
+        /*
+         * Wait for all other user (non-system/daemon) threads
+         * to terminate.
+         */
+        PR_Lock(_pr_activeLock);
+        while (_pr_userActive > _pr_primordialExitCount) {
+            PR_WaitCondVar(_pr_primordialExitCVar, PR_INTERVAL_NO_TIMEOUT);
+        }
+        PR_Unlock(_pr_activeLock);
+
+#ifdef IRIX
+		_PR_MD_PRE_CLEANUP(me);
+		/*
+		 * The primordial thread must now be running on the primordial cpu
+		 */
+    	PR_ASSERT((_PR_IS_NATIVE_THREAD(me)) || (me->cpu->id == 0));
+#endif
+
+        _PR_CleanupMW();
+        _PR_CleanupDtoa();
+        _PR_CleanupCallOnce();
+		_PR_ShutdownLinker();
+        /* Release the primordial thread's private data, etc. */
+        _PR_CleanupThread(me);
+
+        _PR_MD_STOP_INTERRUPTS();
+
+	    PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+	            ("PR_Cleanup: clean up before destroying thread"));
+	    _PR_LogCleanup();
+
+        /*
+         * This part should look like the end of _PR_NativeRunThread
+         * and _PR_UserRunThread.
+         */
+        if (_PR_IS_NATIVE_THREAD(me)) {
+            _PR_MD_EXIT_THREAD(me);
+            _PR_NativeDestroyThread(me);
+        } else {
+            _PR_UserDestroyThread(me);
+            PR_DELETE(me->stack);
+            PR_DELETE(me);
+        }
+
+        /*
+         * XXX: We are freeing the heap memory here so that Purify won't
+         * complain, but we should also free other kinds of resources
+         * that are allocated by the _PR_InitXXX() functions.
+         * Ideally, for each _PR_InitXXX(), there should be a corresponding
+         * _PR_XXXCleanup() that we can call here.
+         */
+        _PR_CleanupNet();
+        _PR_CleanupIO();
+#ifdef WINNT
+        _PR_CleanupCPUs();
+#endif
+        _PR_CleanupThreads();
+        PR_DestroyLock(_pr_sleeplock);
+        _pr_sleeplock = NULL;
+        _PR_CleanupLayerCache();
+        _PR_CleanupEnv();
+        _PR_CleanupStacks();
+        _PR_CleanupBeforeExit();
+        _pr_initialized = PR_FALSE;
+        return PR_SUCCESS;
+    }
+    return PR_FAILURE;
+}
+#endif /* defined(_PR_PTHREADS) */
+
+/*
+ *------------------------------------------------------------------------
+ * PR_ProcessExit --
+ * 
+ *   Cause an immediate, nongraceful, forced termination of the process.
+ *   It takes a PRIntn argument, which is the exit status code of the
+ *   process.
+ *   
+ * See also: PR_Cleanup()
+ *
+ *------------------------------------------------------------------------
+ */
+
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
+    /* see ptthread.c */
+#else
+PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status)
+{
+    _PR_MD_EXIT(status);
+}
+
+#endif /* defined(_PR_PTHREADS) */
+
+PR_IMPLEMENT(PRProcessAttr *)
+PR_NewProcessAttr(void)
+{
+    PRProcessAttr *attr;
+
+    attr = PR_NEWZAP(PRProcessAttr);
+    if (!attr) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return attr;
+}
+
+PR_IMPLEMENT(void)
+PR_ResetProcessAttr(PRProcessAttr *attr)
+{
+    PR_FREEIF(attr->currentDirectory);
+    PR_FREEIF(attr->fdInheritBuffer);
+    memset(attr, 0, sizeof(*attr));
+}
+
+PR_IMPLEMENT(void)
+PR_DestroyProcessAttr(PRProcessAttr *attr)
+{
+    PR_FREEIF(attr->currentDirectory);
+    PR_FREEIF(attr->fdInheritBuffer);
+    PR_DELETE(attr);
+}
+
+PR_IMPLEMENT(void)
+PR_ProcessAttrSetStdioRedirect(
+    PRProcessAttr *attr,
+    PRSpecialFD stdioFd,
+    PRFileDesc *redirectFd)
+{
+    switch (stdioFd) {
+        case PR_StandardInput:
+            attr->stdinFd = redirectFd;
+            break;
+        case PR_StandardOutput:
+            attr->stdoutFd = redirectFd;
+            break;
+        case PR_StandardError:
+            attr->stderrFd = redirectFd;
+            break;
+        default:
+            PR_ASSERT(0);
+    }
+}
+
+/*
+ * OBSOLETE
+ */
+PR_IMPLEMENT(void)
+PR_SetStdioRedirect(
+    PRProcessAttr *attr,
+    PRSpecialFD stdioFd,
+    PRFileDesc *redirectFd)
+{
+#if defined(DEBUG)
+    static PRBool warn = PR_TRUE;
+    if (warn) {
+        warn = _PR_Obsolete("PR_SetStdioRedirect()",
+                "PR_ProcessAttrSetStdioRedirect()");
+    }
+#endif
+    PR_ProcessAttrSetStdioRedirect(attr, stdioFd, redirectFd);
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_ProcessAttrSetCurrentDirectory(
+    PRProcessAttr *attr,
+    const char *dir)
+{
+    PR_FREEIF(attr->currentDirectory);
+    attr->currentDirectory = (char *) PR_MALLOC(strlen(dir) + 1);
+    if (!attr->currentDirectory) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return PR_FAILURE;
+    }
+    strcpy(attr->currentDirectory, dir);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_ProcessAttrSetInheritableFD(
+    PRProcessAttr *attr,
+    PRFileDesc *fd,
+    const char *name)
+{
+    /* We malloc the fd inherit buffer in multiples of this number. */
+#define FD_INHERIT_BUFFER_INCR 128
+    /* The length of "NSPR_INHERIT_FDS=" */
+#define NSPR_INHERIT_FDS_STRLEN 17
+    /* The length of osfd (PROsfd) printed in hexadecimal with 0x prefix */
+#ifdef _WIN64
+#define OSFD_STRLEN 18
+#else
+#define OSFD_STRLEN 10
+#endif
+    /* The length of fd type (PRDescType) printed in decimal */
+#define FD_TYPE_STRLEN 1
+    PRSize newSize;
+    int remainder;
+    char *newBuffer;
+    int nwritten;
+    char *cur;
+    int freeSize;
+
+    if (fd->identity != PR_NSPR_IO_LAYER) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if (fd->secret->inheritable == _PR_TRI_UNKNOWN) {
+        _PR_MD_QUERY_FD_INHERITABLE(fd);
+    }
+    if (fd->secret->inheritable != _PR_TRI_TRUE) {
+        PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    /*
+     * We also need to account for the : separators and the
+     * terminating null byte.
+     */
+    if (NULL == attr->fdInheritBuffer) {
+        /* The first time, we print "NSPR_INHERIT_FDS=<name>:<type>:<val>" */
+        newSize = NSPR_INHERIT_FDS_STRLEN + strlen(name)
+                + FD_TYPE_STRLEN + OSFD_STRLEN + 2 + 1;
+    } else {
+        /* At other times, we print ":<name>:<type>:<val>" */
+        newSize = attr->fdInheritBufferUsed + strlen(name)
+                + FD_TYPE_STRLEN + OSFD_STRLEN + 3 + 1;
+    }
+    if (newSize > attr->fdInheritBufferSize) {
+        /* Make newSize a multiple of FD_INHERIT_BUFFER_INCR */
+        remainder = newSize % FD_INHERIT_BUFFER_INCR;
+        if (remainder != 0) {
+            newSize += (FD_INHERIT_BUFFER_INCR - remainder);
+        }
+        if (NULL == attr->fdInheritBuffer) {
+            newBuffer = (char *) PR_MALLOC(newSize);
+        } else {
+            newBuffer = (char *) PR_REALLOC(attr->fdInheritBuffer, newSize);
+        }
+        if (NULL == newBuffer) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return PR_FAILURE;
+        }
+        attr->fdInheritBuffer = newBuffer;
+        attr->fdInheritBufferSize = newSize;
+    }
+    cur = attr->fdInheritBuffer + attr->fdInheritBufferUsed;
+    freeSize = attr->fdInheritBufferSize - attr->fdInheritBufferUsed;
+    if (0 == attr->fdInheritBufferUsed) {
+        nwritten = PR_snprintf(cur, freeSize,
+                "NSPR_INHERIT_FDS=%s:%d:0x%" PR_PRIxOSFD,
+                name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd);
+    } else {
+        nwritten = PR_snprintf(cur, freeSize, ":%s:%d:0x%" PR_PRIxOSFD,
+                name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd);
+    }
+    attr->fdInheritBufferUsed += nwritten; 
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRFileDesc *) PR_GetInheritedFD(
+    const char *name)
+{
+    PRFileDesc *fd;
+    const char *envVar;
+    const char *ptr;
+    int len = strlen(name);
+    PROsfd osfd;
+    int nColons;
+    PRIntn fileType;
+
+    envVar = PR_GetEnv("NSPR_INHERIT_FDS");
+    if (NULL == envVar || '\0' == envVar[0]) {
+        PR_SetError(PR_UNKNOWN_ERROR, 0);
+        return NULL;
+    }
+
+    ptr = envVar;
+    while (1) {
+        if ((ptr[len] == ':') && (strncmp(ptr, name, len) == 0)) {
+            ptr += len + 1;
+            PR_sscanf(ptr, "%d:0x%" PR_SCNxOSFD, &fileType, &osfd);
+            switch ((PRDescType)fileType) {
+                case PR_DESC_FILE:
+                    fd = PR_ImportFile(osfd);
+                    break;
+                case PR_DESC_PIPE:
+                    fd = PR_ImportPipe(osfd);
+                    break;
+                case PR_DESC_SOCKET_TCP:
+                    fd = PR_ImportTCPSocket(osfd);
+                    break;
+                case PR_DESC_SOCKET_UDP:
+                    fd = PR_ImportUDPSocket(osfd);
+                    break;
+                default:
+                    PR_ASSERT(0);
+                    PR_SetError(PR_UNKNOWN_ERROR, 0);
+                    fd = NULL;
+                    break;
+            }
+            if (fd) {
+                /*
+                 * An inherited FD is inheritable by default.
+                 * The child process needs to call PR_SetFDInheritable
+                 * to make it non-inheritable if so desired.
+                 */
+                fd->secret->inheritable = _PR_TRI_TRUE;
+            }
+            return fd;
+        }
+        /* Skip three colons */
+        nColons = 0;
+        while (*ptr) {
+            if (*ptr == ':') {
+                if (++nColons == 3) {
+                    break;
+                }
+            }
+            ptr++;
+        }
+        if (*ptr == '\0') {
+            PR_SetError(PR_UNKNOWN_ERROR, 0);
+            return NULL;
+        }
+        ptr++;
+    }
+}
+
+PR_IMPLEMENT(PRProcess*) PR_CreateProcess(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    return _PR_MD_CREATE_PROCESS(path, argv, envp, attr);
+}  /* PR_CreateProcess */
+
+PR_IMPLEMENT(PRStatus) PR_CreateProcessDetached(
+    const char *path,
+    char *const *argv,
+    char *const *envp,
+    const PRProcessAttr *attr)
+{
+    PRProcess *process;
+    PRStatus rv;
+
+    process = PR_CreateProcess(path, argv, envp, attr);
+    if (NULL == process) {
+	return PR_FAILURE;
+    }
+    rv = PR_DetachProcess(process);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if (rv == PR_FAILURE) {
+	PR_DELETE(process);
+	return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DetachProcess(PRProcess *process)
+{
+    return _PR_MD_DETACH_PROCESS(process);
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitProcess(PRProcess *process, PRInt32 *exitCode)
+{
+    return _PR_MD_WAIT_PROCESS(process, exitCode);
+}  /* PR_WaitProcess */
+
+PR_IMPLEMENT(PRStatus) PR_KillProcess(PRProcess *process)
+{
+    return _PR_MD_KILL_PROCESS(process);
+}
+
+/*
+ ********************************************************************
+ *
+ * Module initialization
+ *
+ ********************************************************************
+ */
+
+static struct {
+    PRLock *ml;
+    PRCondVar *cv;
+} mod_init;
+
+static void _PR_InitCallOnce(void) {
+    mod_init.ml = PR_NewLock();
+    PR_ASSERT(NULL != mod_init.ml);
+    mod_init.cv = PR_NewCondVar(mod_init.ml);
+    PR_ASSERT(NULL != mod_init.cv);
+}
+
+void _PR_CleanupCallOnce()
+{
+    PR_DestroyLock(mod_init.ml);
+    mod_init.ml = NULL;
+    PR_DestroyCondVar(mod_init.cv);
+    mod_init.cv = NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CallOnce(
+    PRCallOnceType *once,
+    PRCallOnceFN    func)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (!once->initialized) {
+	if (PR_AtomicSet(&once->inProgress, 1) == 0) {
+	    once->status = (*func)();
+	    PR_Lock(mod_init.ml);
+	    once->initialized = 1;
+	    PR_NotifyAllCondVar(mod_init.cv);
+	    PR_Unlock(mod_init.ml);
+	} else {
+	    PR_Lock(mod_init.ml);
+	    while (!once->initialized) {
+		PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
+            }
+	    PR_Unlock(mod_init.ml);
+	}
+    }
+    return once->status;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg(
+    PRCallOnceType      *once,
+    PRCallOnceWithArgFN  func,
+    void                *arg)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (!once->initialized) {
+	if (PR_AtomicSet(&once->inProgress, 1) == 0) {
+	    once->status = (*func)(arg);
+	    PR_Lock(mod_init.ml);
+	    once->initialized = 1;
+	    PR_NotifyAllCondVar(mod_init.cv);
+	    PR_Unlock(mod_init.ml);
+	} else {
+	    PR_Lock(mod_init.ml);
+	    while (!once->initialized) {
+		PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT);
+            }
+	    PR_Unlock(mod_init.ml);
+	}
+    }
+    return once->status;
+}
+
+PRBool _PR_Obsolete(const char *obsolete, const char *preferred)
+{
+#if defined(DEBUG)
+#ifndef XP_MAC
+    PR_fprintf(
+        PR_STDERR, "'%s' is obsolete. Use '%s' instead.\n",
+        obsolete, (NULL == preferred) ? "something else" : preferred);
+#else
+#pragma unused (obsolete, preferred)
+#endif
+#endif
+    return PR_FALSE;
+}  /* _PR_Obsolete */
+
+/* prinit.c */
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prinrval.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prinrval.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,157 @@
+/* -*- 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:			prinrval.c
+ * description:		implementation for the kernel interval timing functions
+ */
+
+#include "primpl.h"
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * _PR_InitClock --
+ *
+ *
+ *-----------------------------------------------------------------------
+ */
+
+void _PR_InitClock(void)
+{
+    _PR_MD_INTERVAL_INIT();
+#ifdef DEBUG
+    {
+        PRIntervalTime ticksPerSec = PR_TicksPerSecond();
+
+        PR_ASSERT(ticksPerSec >= PR_INTERVAL_MIN);
+        PR_ASSERT(ticksPerSec <= PR_INTERVAL_MAX);
+    }
+#endif /* DEBUG */
+}
+
+/*
+ * This version of interval times is based on the time of day
+ * capability offered by system. This isn't valid for two reasons:
+ * 1) The time of day is neither linear nor montonically increasing
+ * 2) The units here are milliseconds. That's not appropriate for our use.
+ */
+
+PR_IMPLEMENT(PRIntervalTime) PR_IntervalNow(void)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    return _PR_MD_GET_INTERVAL();
+}  /* PR_IntervalNow */
+
+PR_EXTERN(PRUint32) PR_TicksPerSecond(void)
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    return _PR_MD_INTERVAL_PER_SEC();
+}  /* PR_TicksPerSecond */
+
+PR_IMPLEMENT(PRIntervalTime) PR_SecondsToInterval(PRUint32 seconds)
+{
+    return seconds * PR_TicksPerSecond();
+}  /* PR_SecondsToInterval */
+
+PR_IMPLEMENT(PRIntervalTime) PR_MillisecondsToInterval(PRUint32 milli)
+{
+    PRIntervalTime ticks;
+    PRUint64 tock, tps, msecPerSec, rounding;
+    LL_UI2L(tock, milli);
+    LL_I2L(msecPerSec, PR_MSEC_PER_SEC);
+    LL_I2L(rounding, (PR_MSEC_PER_SEC >> 1));
+    LL_I2L(tps, PR_TicksPerSecond());
+    LL_MUL(tock, tock, tps);
+    LL_ADD(tock, tock, rounding);
+    LL_DIV(tock, tock, msecPerSec);
+    LL_L2UI(ticks, tock);
+    return ticks;
+}  /* PR_MillisecondsToInterval */
+
+PR_IMPLEMENT(PRIntervalTime) PR_MicrosecondsToInterval(PRUint32 micro)
+{
+    PRIntervalTime ticks;
+    PRUint64 tock, tps, usecPerSec, rounding;
+    LL_UI2L(tock, micro);
+    LL_I2L(usecPerSec, PR_USEC_PER_SEC);
+    LL_I2L(rounding, (PR_USEC_PER_SEC >> 1));
+    LL_I2L(tps, PR_TicksPerSecond());
+    LL_MUL(tock, tock, tps);
+    LL_ADD(tock, tock, rounding);
+    LL_DIV(tock, tock, usecPerSec);
+    LL_L2UI(ticks, tock);
+    return ticks;
+}  /* PR_MicrosecondsToInterval */
+
+PR_IMPLEMENT(PRUint32) PR_IntervalToSeconds(PRIntervalTime ticks)
+{
+    return ticks / PR_TicksPerSecond();
+}  /* PR_IntervalToSeconds */
+
+PR_IMPLEMENT(PRUint32) PR_IntervalToMilliseconds(PRIntervalTime ticks)
+{
+    PRUint32 milli;
+    PRUint64 tock, tps, msecPerSec, rounding;
+    LL_UI2L(tock, ticks);
+    LL_I2L(msecPerSec, PR_MSEC_PER_SEC);
+    LL_I2L(tps, PR_TicksPerSecond());
+    LL_USHR(rounding, tps, 1);
+    LL_MUL(tock, tock, msecPerSec);
+    LL_ADD(tock, tock, rounding);
+    LL_DIV(tock, tock, tps);
+    LL_L2UI(milli, tock);
+    return milli;
+}  /* PR_IntervalToMilliseconds */
+
+PR_IMPLEMENT(PRUint32) PR_IntervalToMicroseconds(PRIntervalTime ticks)
+{
+    PRUint32 micro;
+    PRUint64 tock, tps, usecPerSec, rounding;
+    LL_UI2L(tock, ticks);
+    LL_I2L(usecPerSec, PR_USEC_PER_SEC);
+    LL_I2L(tps, PR_TicksPerSecond());
+    LL_USHR(rounding, tps, 1);
+    LL_MUL(tock, tock, usecPerSec);
+    LL_ADD(tock, tock, rounding);
+    LL_DIV(tock, tock, tps);
+    LL_L2UI(micro, tock);
+    return micro;
+}  /* PR_IntervalToMicroseconds */
+
+/* prinrval.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pripc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pripc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,132 @@
+/* -*- 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 ***** */
+
+/*
+ * File: pripc.c
+ *
+ * Description: functions for IPC support
+ */
+
+#include "primpl.h"
+
+#include <string.h>
+
+/*
+ * A POSIX IPC name must begin with a '/'.
+ * A POSIX IPC name on Solaris cannot contain any '/' except
+ * the required leading '/'.
+ * A POSIX IPC name on HP-UX and OSF1 must be a valid pathname
+ * in the file system.
+ *
+ * The ftok() function for System V IPC requires a valid pathname
+ * in the file system.
+ *
+ * A Win32 IPC name cannot contain '\'.
+ */
+
+static void _pr_ConvertSemName(char *result)
+{
+#ifdef _PR_HAVE_POSIX_SEMAPHORES
+#if defined(SOLARIS)
+    char *p;
+
+    /* Convert '/' to '_' except for the leading '/' */
+    for (p = result+1; *p; p++) {
+        if (*p == '/') {
+            *p = '_';
+        }
+    }
+    return;
+#else
+    return;
+#endif
+#elif defined(_PR_HAVE_SYSV_SEMAPHORES)
+    return;
+#elif defined(WIN32)
+    return;
+#endif
+}
+
+static void _pr_ConvertShmName(char *result)
+{
+#if defined(PR_HAVE_POSIX_NAMED_SHARED_MEMORY)
+#if defined(SOLARIS)
+    char *p;
+
+    /* Convert '/' to '_' except for the leading '/' */
+    for (p = result+1; *p; p++) {
+        if (*p == '/') {
+            *p = '_';
+        }
+    }
+    return;
+#else
+    return;
+#endif
+#elif defined(PR_HAVE_SYSV_NAMED_SHARED_MEMORY)
+    return;
+#elif defined(WIN32)
+    return;
+#else
+    return;
+#endif
+}
+
+PRStatus _PR_MakeNativeIPCName(
+    const char *name,
+    char *result,
+    PRIntn size,
+    _PRIPCType type)
+{
+    if (strlen(name) >= (PRSize)size) {
+        PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
+        return PR_FAILURE;
+    }
+    strcpy(result, name);
+    switch (type) {
+        case _PRIPCSem:
+            _pr_ConvertSemName(result);
+            break;
+        case _PRIPCShm:
+            _pr_ConvertShmName(result);
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pripcsem.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/pripcsem.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,130 @@
+/* -*- 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 ***** */
+
+/*
+ * File: pripcsem.c
+ *
+ * Description: implements the named semaphores API in prsemipc.h
+ * for classic NSPR.  If _PR_HAVE_NAMED_SEMAPHORES is not defined,
+ * the named semaphore functions all fail with the error code
+ * PR_NOT_IMPLEMENTED_ERROR.
+ */
+
+#include "primpl.h"
+
+#ifdef _PR_PTHREADS
+
+#error "This file should not be compiled for the pthreads version"
+
+#else
+
+#ifndef _PR_HAVE_NAMED_SEMAPHORES
+
+PRSem * _PR_MD_OPEN_SEMAPHORE(
+    const char *osname, PRIntn flags, PRIntn mode, PRUintn value)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PRStatus _PR_MD_WAIT_SEMAPHORE(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRStatus _PR_MD_POST_SEMAPHORE(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRStatus _PR_MD_CLOSE_SEMAPHORE(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PRStatus _PR_MD_DELETE_SEMAPHORE(const char *osname)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+#endif /* !_PR_HAVE_NAMED_SEMAPHORES */
+
+PR_IMPLEMENT(PRSem *) PR_OpenSemaphore(
+    const char *name, PRIntn flags, PRIntn mode, PRUintn value)
+{
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+            == PR_FAILURE) {
+        return NULL;
+    }
+    return _PR_MD_OPEN_SEMAPHORE(osname, flags, mode, value);
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem)
+{
+    return _PR_MD_WAIT_SEMAPHORE(sem);
+}
+
+PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem)
+{
+    return _PR_MD_POST_SEMAPHORE(sem);
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem)
+{
+    return _PR_MD_CLOSE_SEMAPHORE(sem);
+}
+
+PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name)
+{
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+            == PR_FAILURE) {
+        return PR_FAILURE;
+    }
+    return _PR_MD_DELETE_SEMAPHORE(osname);
+}
+
+#endif /* _PR_PTHREADS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prlog2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prlog2.c	Mon Dec 18 10:53:47 2006
@@ -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 "prbit.h"
+
+/*
+** Compute the log of the least power of 2 greater than or equal to n
+*/
+PR_IMPLEMENT(PRIntn) PR_CeilingLog2(PRUint32 n)
+{
+    PRIntn log2 = 0;
+
+    if (n & (n-1))
+	log2++;
+    if (n >> 16)
+	log2 += 16, n >>= 16;
+    if (n >> 8)
+	log2 += 8, n >>= 8;
+    if (n >> 4)
+	log2 += 4, n >>= 4;
+    if (n >> 2)
+	log2 += 2, n >>= 2;
+    if (n >> 1)
+	log2++;
+    return log2;
+}
+
+/*
+** Compute the log of the greatest power of 2 less than or equal to n.
+** This really just finds the highest set bit in the word.
+*/
+PR_IMPLEMENT(PRIntn) PR_FloorLog2(PRUint32 n)
+{
+    PRIntn log2 = 0;
+
+    if (n >> 16)
+	log2 += 16, n >>= 16;
+    if (n >> 8)
+	log2 += 8, n >>= 8;
+    if (n >> 4)
+	log2 += 4, n >>= 4;
+    if (n >> 2)
+	log2 += 2, n >>= 2;
+    if (n >> 1)
+	log2++;
+    return log2;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prlong.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prlong.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,282 @@
+/* -*- 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"
+
+static PRInt64 ll_zero = LL_INIT( 0x00000000,0x00000000 );
+static PRInt64 ll_maxint = LL_INIT( 0x7fffffff, 0xffffffff );
+static PRInt64 ll_minint = LL_INIT( 0x80000000, 0x00000000 );
+static PRUint64 ll_maxuint = LL_INIT( 0xffffffff, 0xffffffff );
+
+#if defined(HAVE_WATCOM_BUG_2)
+PRInt64 __pascal __loadds __export
+    LL_Zero(void) { return ll_zero; }
+PRInt64 __pascal __loadds __export
+    LL_MaxInt(void) { return ll_maxint; }
+PRInt64 __pascal __loadds __export
+    LL_MinInt(void) { return ll_minint; }
+PRUint64 __pascal __loadds __export
+    LL_MaxUint(void) { return ll_maxuint; }
+#else
+PR_IMPLEMENT(PRInt64) LL_Zero(void) { return ll_zero; }
+PR_IMPLEMENT(PRInt64) LL_MaxInt(void) { return ll_maxint; }
+PR_IMPLEMENT(PRInt64) LL_MinInt(void) { return ll_minint; }
+PR_IMPLEMENT(PRUint64) LL_MaxUint(void) { return ll_maxuint; }
+#endif
+
+#ifndef HAVE_LONG_LONG
+/*
+** Divide 64-bit a by 32-bit b, which must be normalized so its high bit is 1.
+*/
+static void norm_udivmod32(PRUint32 *qp, PRUint32 *rp, PRUint64 a, PRUint32 b)
+{
+    PRUint32 d1, d0, q1, q0;
+    PRUint32 r1, r0, m;
+
+    d1 = _hi16(b);
+    d0 = _lo16(b);
+    r1 = a.hi % d1;
+    q1 = a.hi / d1;
+    m = q1 * d0;
+    r1 = (r1 << 16) | _hi16(a.lo);
+    if (r1 < m) {
+        q1--, r1 += b;
+        if (r1 >= b	/* i.e., we didn't get a carry when adding to r1 */
+	    && r1 < m) {
+	    q1--, r1 += b;
+	}
+    }
+    r1 -= m;
+    r0 = r1 % d1;
+    q0 = r1 / d1;
+    m = q0 * d0;
+    r0 = (r0 << 16) | _lo16(a.lo);
+    if (r0 < m) {
+        q0--, r0 += b;
+        if (r0 >= b
+	    && r0 < m) {
+	    q0--, r0 += b;
+	}
+    }
+    *qp = (q1 << 16) | q0;
+    *rp = r0 - m;
+}
+
+static PRUint32 CountLeadingZeros(PRUint32 a)
+{
+    PRUint32 t;
+    PRUint32 r = 32;
+
+    if ((t = a >> 16) != 0)
+	r -= 16, a = t;
+    if ((t = a >> 8) != 0)
+	r -= 8, a = t;
+    if ((t = a >> 4) != 0)
+	r -= 4, a = t;
+    if ((t = a >> 2) != 0)
+	r -= 2, a = t;
+    if ((t = a >> 1) != 0)
+	r -= 1, a = t;
+    if (a & 1)
+	r--;
+    return r;
+}
+
+PR_IMPLEMENT(void) ll_udivmod(PRUint64 *qp, PRUint64 *rp, PRUint64 a, PRUint64 b)
+{
+    PRUint32 n0, n1, n2;
+    PRUint32 q0, q1;
+    PRUint32 rsh, lsh;
+
+    n0 = a.lo;
+    n1 = a.hi;
+
+    if (b.hi == 0) {
+	if (b.lo > n1) {
+	    /* (0 q0) = (n1 n0) / (0 D0) */
+
+	    lsh = CountLeadingZeros(b.lo);
+
+	    if (lsh) {
+		/*
+		 * Normalize, i.e. make the most significant bit of the
+		 * denominator be set.
+		 */
+		b.lo = b.lo << lsh;
+		n1 = (n1 << lsh) | (n0 >> (32 - lsh));
+		n0 = n0 << lsh;
+	    }
+
+	    a.lo = n0, a.hi = n1;
+	    norm_udivmod32(&q0, &n0, a, b.lo);
+	    q1 = 0;
+
+	    /* remainder is in n0 >> lsh */
+	} else {
+	    /* (q1 q0) = (n1 n0) / (0 d0) */
+
+	    if (b.lo == 0)		/* user wants to divide by zero! */
+		b.lo = 1 / b.lo;	/* so go ahead and crash */
+
+	    lsh = CountLeadingZeros(b.lo);
+
+	    if (lsh == 0) {
+		/*
+		 * From (n1 >= b.lo)
+		 *   && (the most significant bit of b.lo is set),
+		 * conclude that
+		 *	(the most significant bit of n1 is set)
+		 *   && (the leading quotient digit q1 = 1).
+		 *
+		 * This special case is necessary, not an optimization
+		 * (Shifts counts of 32 are undefined).
+		 */
+		n1 -= b.lo;
+		q1 = 1;
+	    } else {
+		/*
+		 * Normalize.
+		 */
+		rsh = 32 - lsh;
+
+		b.lo = b.lo << lsh;
+		n2 = n1 >> rsh;
+		n1 = (n1 << lsh) | (n0 >> rsh);
+		n0 = n0 << lsh;
+
+		a.lo = n1, a.hi = n2;
+		norm_udivmod32(&q1, &n1, a, b.lo);
+	    }
+
+	    /* n1 != b.lo... */
+
+	    a.lo = n0, a.hi = n1;
+	    norm_udivmod32(&q0, &n0, a, b.lo);
+
+	    /* remainder in n0 >> lsh */
+	}
+
+	if (rp) {
+	    rp->lo = n0 >> lsh;
+	    rp->hi = 0;
+	}
+    } else {
+	if (b.hi > n1) {
+	    /* (0 0) = (n1 n0) / (D1 d0) */
+
+	    q0 = 0;
+	    q1 = 0;
+
+	    /* remainder in (n1 n0) */
+	    if (rp) {
+		rp->lo = n0;
+		rp->hi = n1;
+	    }
+	} else {
+	    /* (0 q0) = (n1 n0) / (d1 d0) */
+
+	    lsh = CountLeadingZeros(b.hi);
+	    if (lsh == 0) {
+		/*
+		 * From (n1 >= b.hi)
+		 *   && (the most significant bit of b.hi is set),
+		 * conclude that
+		 *      (the most significant bit of n1 is set)
+		 *   && (the quotient digit q0 = 0 or 1).
+		 *
+		 * This special case is necessary, not an optimization.
+		 */
+
+		/*
+		 * The condition on the next line takes advantage of that
+		 * n1 >= b.hi (true due to control flow).
+		 */
+		if (n1 > b.hi || n0 >= b.lo) {
+		    q0 = 1;
+		    a.lo = n0, a.hi = n1;
+		    LL_SUB(a, a, b);
+		} else {
+		    q0 = 0;
+		}
+		q1 = 0;
+
+		if (rp) {
+		    rp->lo = n0;
+		    rp->hi = n1;
+		}
+	    } else {
+		PRInt64 m;
+
+		/*
+		 * Normalize.
+		 */
+		rsh = 32 - lsh;
+
+		b.hi = (b.hi << lsh) | (b.lo >> rsh);
+		b.lo = b.lo << lsh;
+		n2 = n1 >> rsh;
+		n1 = (n1 << lsh) | (n0 >> rsh);
+		n0 = n0 << lsh;
+
+		a.lo = n1, a.hi = n2;
+		norm_udivmod32(&q0, &n1, a, b.hi);
+		LL_MUL32(m, q0, b.lo);
+
+		if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) {
+		    q0--;
+		    LL_SUB(m, m, b);
+		}
+
+		q1 = 0;
+
+		/* Remainder is ((n1 n0) - (m1 m0)) >> lsh */
+		if (rp) {
+		    a.lo = n0, a.hi = n1;
+		    LL_SUB(a, a, m);
+		    rp->lo = (a.hi << rsh) | (a.lo >> lsh);
+		    rp->hi = a.hi >> lsh;
+		}
+	    }
+	}
+    }
+
+    if (qp) {
+	qp->lo = q0;
+	qp->hi = q1;
+    }
+}
+#endif /* !HAVE_LONG_LONG */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prnetdb.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prnetdb.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2198 @@
+/* -*- 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 <string.h>
+
+/*
+ * On Unix, the error code for gethostbyname() and gethostbyaddr()
+ * is returned in the global variable h_errno, instead of the usual
+ * errno.
+ */
+#if defined(XP_UNIX)
+#if defined(_PR_NEED_H_ERRNO)
+extern int h_errno;
+#endif
+#define _MD_GETHOST_ERRNO() h_errno
+#else
+#define _MD_GETHOST_ERRNO() _MD_ERRNO()
+#endif
+
+/*
+ * The meaning of the macros related to gethostbyname, gethostbyaddr,
+ * and gethostbyname2 is defined below.
+ * - _PR_HAVE_THREADSAFE_GETHOST: the gethostbyXXX functions return
+ *   the result in thread specific storage.  For example, AIX, HP-UX,
+ *   and OSF1.
+ * -  _PR_HAVE_GETHOST_R: have the gethostbyXXX_r functions. See next
+ *   two macros.
+ * - _PR_HAVE_GETHOST_R_INT: the gethostbyXXX_r functions return an
+ *   int.  For example, Linux glibc.
+ * - _PR_HAVE_GETHOST_R_POINTER: the gethostbyXXX_r functions return
+ *   a struct hostent* pointer.  For example, Solaris and IRIX.
+ */
+#if defined(_PR_NO_PREEMPT) || defined(_PR_HAVE_GETHOST_R) \
+    || defined(_PR_HAVE_THREADSAFE_GETHOST)
+#define _PR_NO_DNS_LOCK
+#endif
+
+#if defined(_PR_NO_DNS_LOCK)
+#define LOCK_DNS()
+#define UNLOCK_DNS()
+#else
+PRLock *_pr_dnsLock = NULL;
+#define LOCK_DNS() PR_Lock(_pr_dnsLock)
+#define UNLOCK_DNS() PR_Unlock(_pr_dnsLock)
+#endif  /* defined(_PR_NO_DNS_LOCK) */
+
+/*
+ * Some platforms have the reentrant getprotobyname_r() and
+ * getprotobynumber_r().  However, they come in two flavors.
+ * Some return a pointer to struct protoent, others return
+ * an int.
+ */
+#if defined(XP_BEOS) && defined(BONE_VERSION)
+#include <arpa/inet.h>  /* pick up define for inet_addr */
+#include <sys/socket.h>
+#define _PR_HAVE_GETPROTO_R
+#define _PR_HAVE_GETPROTO_R_POINTER
+#endif
+
+#if defined(SOLARIS) || (defined(BSDI) && defined(_REENTRANT)) \
+	|| (defined(LINUX) && defined(_REENTRANT) \
+        && !(defined(__GLIBC__) && __GLIBC__ >= 2))
+#define _PR_HAVE_GETPROTO_R
+#define _PR_HAVE_GETPROTO_R_POINTER
+#endif
+
+#if defined(OSF1) \
+        || defined(AIX4_3_PLUS) || (defined(AIX) && defined(_THREAD_SAFE)) \
+	|| (defined(HPUX10_10) && defined(_REENTRANT)) \
+        || (defined(HPUX10_20) && defined(_REENTRANT))
+#define _PR_HAVE_GETPROTO_R
+#define _PR_HAVE_GETPROTO_R_INT
+#endif
+
+#if (defined(__GLIBC__) && __GLIBC__ >= 2)
+#define _PR_HAVE_GETPROTO_R
+#define _PR_HAVE_5_ARG_GETPROTO_R
+#endif
+
+#if !defined(_PR_HAVE_GETPROTO_R)
+PRLock* _getproto_lock = NULL;
+#endif
+
+#if defined(_PR_INET6_PROBE)
+PR_EXTERN(PRBool) _pr_ipv6_is_present;
+#endif
+
+#define _PR_IN6_IS_ADDR_UNSPECIFIED(a)				\
+				(((a)->pr_s6_addr32[0] == 0) &&	\
+				((a)->pr_s6_addr32[1] == 0) &&		\
+				((a)->pr_s6_addr32[2] == 0) &&		\
+				((a)->pr_s6_addr32[3] == 0))
+ 
+#define _PR_IN6_IS_ADDR_LOOPBACK(a)					\
+               (((a)->pr_s6_addr32[0] == 0)	&&	\
+               ((a)->pr_s6_addr32[1] == 0)		&&	\
+               ((a)->pr_s6_addr32[2] == 0)		&&	\
+               ((a)->pr_s6_addr[12] == 0)		&&	\
+               ((a)->pr_s6_addr[13] == 0)		&&	\
+               ((a)->pr_s6_addr[14] == 0)		&&	\
+               ((a)->pr_s6_addr[15] == 0x1U))
+ 
+const PRIPv6Addr _pr_in6addr_any =	{{{ 0, 0, 0, 0,
+										0, 0, 0, 0,
+										0, 0, 0, 0,
+										0, 0, 0, 0 }}};
+
+const PRIPv6Addr _pr_in6addr_loopback = {{{ 0, 0, 0, 0,
+											0, 0, 0, 0,
+											0, 0, 0, 0,
+											0, 0, 0, 0x1U }}};
+/*
+ * The values at bytes 10 and 11 are compared using pointers to
+ * 8-bit fields, and not 32-bit fields, to make the comparison work on
+ * both big-endian and little-endian systems
+ */
+
+#define _PR_IN6_IS_ADDR_V4MAPPED(a)			\
+		(((a)->pr_s6_addr32[0] == 0) 	&&	\
+		((a)->pr_s6_addr32[1] == 0)	&&	\
+		((a)->pr_s6_addr[8] == 0)		&&	\
+		((a)->pr_s6_addr[9] == 0)		&&	\
+		((a)->pr_s6_addr[10] == 0xff)	&&	\
+		((a)->pr_s6_addr[11] == 0xff))
+
+#define _PR_IN6_IS_ADDR_V4COMPAT(a)			\
+		(((a)->pr_s6_addr32[0] == 0) &&	\
+		((a)->pr_s6_addr32[1] == 0) &&		\
+		((a)->pr_s6_addr32[2] == 0))
+
+#define _PR_IN6_V4MAPPED_TO_IPADDR(a) ((a)->pr_s6_addr32[3])
+
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+
+/*
+ * The _pr_QueryNetIfs() function finds out if the system has
+ * IPv4 or IPv6 source addresses configured and sets _pr_have_inet_if
+ * and _pr_have_inet6_if accordingly.
+ *
+ * We have an implementation using SIOCGIFCONF ioctl and a
+ * default implementation that simply sets _pr_have_inet_if
+ * and _pr_have_inet6_if to true.  A better implementation
+ * would be to use the routing sockets (see Chapter 17 of
+ * W. Richard Stevens' Unix Network Programming, Vol. 1, 2nd. Ed.)
+ */
+
+static PRLock *_pr_query_ifs_lock = NULL;
+static PRBool _pr_have_inet_if = PR_FALSE;
+static PRBool _pr_have_inet6_if = PR_FALSE;
+
+#undef DEBUG_QUERY_IFS
+
+#if defined(AIX) \
+    || (defined(DARWIN) && (!defined(HAVE_GETIFADDRS) \
+        || (defined(XP_MACOSX) && (!defined(MAC_OS_X_VERSION_10_2) || \
+        MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_2))))
+
+/*
+ * Use SIOCGIFCONF ioctl on platforms that don't have routing
+ * sockets.  Warning: whether SIOCGIFCONF ioctl returns AF_INET6
+ * network interfaces is not portable.
+ *
+ * The _pr_QueryNetIfs() function is derived from the code in
+ * src/lib/libc/net/getifaddrs.c in BSD Unix and the code in
+ * Section 16.6 of W. Richard Stevens' Unix Network Programming,
+ * Vol. 1, 2nd. Ed.
+ */
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h>
+
+#ifdef DEBUG_QUERY_IFS
+static void
+_pr_PrintIfreq(struct ifreq *ifr)
+{
+    PRNetAddr addr;
+    struct sockaddr *sa;
+    const char* family;
+    char addrstr[64];
+
+    sa = &ifr->ifr_addr;
+    if (sa->sa_family == AF_INET) {
+        struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+        family = "inet";
+        memcpy(&addr.inet.ip, &sin->sin_addr, sizeof(sin->sin_addr));
+    } else if (sa->sa_family == AF_INET6) {
+        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+        family = "inet6";
+        memcpy(&addr.ipv6.ip, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
+    } else {
+        return;  /* skip if not AF_INET or AF_INET6 */
+    }
+    addr.raw.family = sa->sa_family;
+    PR_NetAddrToString(&addr, addrstr, sizeof(addrstr));
+    printf("%s: %s %s\n", ifr->ifr_name, family, addrstr);
+}
+#endif
+
+static void
+_pr_QueryNetIfs(void)
+{
+    int sock;
+    int rv;
+    struct ifconf ifc;
+    struct ifreq *ifr;
+    struct ifreq *lifr;
+    PRUint32 len, lastlen;
+    char *buf;
+
+    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+        return;
+    }
+
+    /* Issue SIOCGIFCONF request in a loop. */
+    lastlen = 0;
+    len = 100 * sizeof(struct ifreq);  /* initial buffer size guess */
+    for (;;) {
+        buf = (char *)PR_Malloc(len);
+        if (NULL == buf) {
+            close(sock);
+            return;
+        }
+        ifc.ifc_buf = buf;
+        ifc.ifc_len = len;
+        rv = ioctl(sock, SIOCGIFCONF, &ifc);
+        if (rv < 0) {
+            if (errno != EINVAL || lastlen != 0) {
+                close(sock);
+                PR_Free(buf);
+                return;
+            }
+        } else {
+            if (ifc.ifc_len == lastlen)
+                break;  /* success, len has not changed */
+            lastlen = ifc.ifc_len;
+        }
+        len += 10 * sizeof(struct ifreq);  /* increment */
+        PR_Free(buf);
+    }
+    close(sock);
+
+    ifr = ifc.ifc_req;
+    lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
+
+    while (ifr < lifr) {
+        struct sockaddr *sa;
+        int sa_len;
+
+#ifdef DEBUG_QUERY_IFS
+        _pr_PrintIfreq(ifr);
+#endif
+        sa = &ifr->ifr_addr;
+        if (sa->sa_family == AF_INET) {
+            struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+            if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
+                _pr_have_inet_if = PR_TRUE;
+            } 
+        } else if (sa->sa_family == AF_INET6) {
+            struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+            if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)
+                    && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+                _pr_have_inet6_if = PR_TRUE;
+            } 
+        }
+
+#ifdef _PR_HAVE_SOCKADDR_LEN
+        sa_len = PR_MAX(sa->sa_len, sizeof(struct sockaddr));
+#else
+        switch (sa->sa_family) {
+#ifdef AF_LINK
+        case AF_LINK:
+            sa_len = sizeof(struct sockaddr_dl);
+            break;
+#endif
+        case AF_INET6:
+            sa_len = sizeof(struct sockaddr_in6);
+            break;
+        default:
+            sa_len = sizeof(struct sockaddr);
+            break;
+        }
+#endif
+        ifr = (struct ifreq *)(((char *)sa) + sa_len);
+    }
+    PR_Free(buf);
+}
+
+#elif (defined(DARWIN) && defined(HAVE_GETIFADDRS)) || defined(FREEBSD) \
+    || defined(NETBSD) || defined(OPENBSD)
+
+/*
+ * Use the BSD getifaddrs function.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <ifaddrs.h>
+#include <netinet/in.h>
+
+#ifdef DEBUG_QUERY_IFS
+static void
+_pr_PrintIfaddrs(struct ifaddrs *ifa)
+{
+    struct sockaddr *sa;
+    const char* family;
+    void *addrp;
+    char addrstr[64];
+
+    sa = ifa->ifa_addr;
+    if (sa->sa_family == AF_INET) {
+        struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+        family = "inet";
+        addrp = &sin->sin_addr;
+    } else if (sa->sa_family == AF_INET6) {
+        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+        family = "inet6";
+        addrp = &sin6->sin6_addr;
+    } else {
+        return;  /* skip if not AF_INET or AF_INET6 */
+    }
+    inet_ntop(sa->sa_family, addrp, addrstr, sizeof(addrstr));
+    printf("%s: %s %s\n", ifa->ifa_name, family, addrstr);
+}
+#endif
+
+static void
+_pr_QueryNetIfs(void)
+{
+    struct ifaddrs *ifp;
+    struct ifaddrs *ifa;
+
+    if (getifaddrs(&ifp) == -1) {
+        return;
+    }
+    for (ifa = ifp; ifa; ifa = ifa->ifa_next) {
+        struct sockaddr *sa;
+
+#ifdef DEBUG_QUERY_IFS
+        _pr_PrintIfaddrs(ifa);
+#endif
+        sa = ifa->ifa_addr;
+        if (sa->sa_family == AF_INET) {
+            struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+            if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
+                _pr_have_inet_if = 1;
+            } 
+        } else if (sa->sa_family == AF_INET6) {
+            struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+            if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)
+                    && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
+                _pr_have_inet6_if = 1;
+            } 
+        }
+    } 
+    freeifaddrs(ifp);
+}
+
+#else  /* default */
+
+/*
+ * Emulate the code in NSPR 4.2 or older.  PR_GetIPNodeByName behaves
+ * as if the system had both IPv4 and IPv6 source addresses configured.
+ */
+static void
+_pr_QueryNetIfs(void)
+{
+    _pr_have_inet_if = PR_TRUE;
+    _pr_have_inet6_if = PR_TRUE;
+}
+
+#endif
+
+#endif  /* _PR_INET6 && _PR_HAVE_GETHOSTBYNAME2 */
+
+void _PR_InitNet(void)
+{
+#if defined(XP_UNIX)
+#ifdef HAVE_NETCONFIG
+	/*
+	 * This one-liner prevents the endless re-open's and re-read's of
+	 * /etc/netconfig on EACH and EVERY call to accept(), connect(), etc.
+	 */
+	 (void)setnetconfig();
+#endif
+#endif
+#if !defined(_PR_NO_DNS_LOCK)
+	_pr_dnsLock = PR_NewLock();
+#endif
+#if !defined(_PR_HAVE_GETPROTO_R)
+	_getproto_lock = PR_NewLock();
+#endif
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+	_pr_query_ifs_lock = PR_NewLock();
+#endif
+}
+
+void _PR_CleanupNet(void)
+{
+#if !defined(_PR_NO_DNS_LOCK)
+    if (_pr_dnsLock) {
+        PR_DestroyLock(_pr_dnsLock);
+        _pr_dnsLock = NULL;
+    }
+#endif
+#if !defined(_PR_HAVE_GETPROTO_R)
+    if (_getproto_lock) {
+        PR_DestroyLock(_getproto_lock);
+        _getproto_lock = NULL;
+    }
+#endif
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+    if (_pr_query_ifs_lock) {
+        PR_DestroyLock(_pr_query_ifs_lock);
+        _pr_query_ifs_lock = NULL;
+    }
+#endif
+}
+
+/*
+** Allocate space from the buffer, aligning it to "align" before doing
+** the allocation. "align" must be a power of 2.
+*/
+static char *Alloc(PRIntn amount, char **bufp, PRIntn *buflenp, PRIntn align)
+{
+	char *buf = *bufp;
+	PRIntn buflen = *buflenp;
+
+	if (align && ((long)buf & (align - 1))) {
+		PRIntn skip = align - ((ptrdiff_t)buf & (align - 1));
+		if (buflen < skip) {
+			return 0;
+		}
+		buf += skip;
+		buflen -= skip;
+	}
+	if (buflen < amount) {
+		return 0;
+	}
+	*bufp = buf + amount;
+	*buflenp = buflen - amount;
+	return buf;
+}
+
+typedef enum _PRIPAddrConversion {
+    _PRIPAddrNoConversion,
+    _PRIPAddrIPv4Mapped,
+    _PRIPAddrIPv4Compat
+} _PRIPAddrConversion;
+
+/*
+** Convert an IPv4 address (v4) to an IPv4-mapped IPv6 address (v6).
+*/
+static void MakeIPv4MappedAddr(const char *v4, char *v6)
+{
+    memset(v6, 0, 10);
+    memset(v6 + 10, 0xff, 2);
+    memcpy(v6 + 12, v4, 4);
+}
+
+/*
+** Convert an IPv4 address (v4) to an IPv4-compatible IPv6 address (v6).
+*/
+static void MakeIPv4CompatAddr(const char *v4, char *v6)
+{
+    memset(v6, 0, 12);
+    memcpy(v6 + 12, v4, 4);
+}
+
+/*
+** Copy a hostent, and all of the memory that it refers to into
+** (hopefully) stacked buffers.
+*/
+static PRStatus CopyHostent(
+    struct hostent *from,
+    char **buf,
+    PRIntn *bufsize,
+    _PRIPAddrConversion conversion,
+    PRHostEnt *to)
+{
+	PRIntn len, na;
+	char **ap;
+
+	if (conversion != _PRIPAddrNoConversion
+			&& from->h_addrtype == AF_INET) {
+		PR_ASSERT(from->h_length == 4);
+		to->h_addrtype = PR_AF_INET6;
+		to->h_length = 16;
+	} else {
+#if defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+		if (AF_INET6 == from->h_addrtype)
+			to->h_addrtype = PR_AF_INET6;
+		else
+#endif
+			to->h_addrtype = from->h_addrtype;
+		to->h_length = from->h_length;
+	}
+
+	/* Copy the official name */
+	if (!from->h_name) return PR_FAILURE;
+	len = strlen(from->h_name) + 1;
+	to->h_name = Alloc(len, buf, bufsize, 0);
+	if (!to->h_name) return PR_FAILURE;
+	memcpy(to->h_name, from->h_name, len);
+
+	/* Count the aliases, then allocate storage for the pointers */
+	if (!from->h_aliases) {
+		na = 1;
+	} else {
+		for (na = 1, ap = from->h_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */
+	}
+	to->h_aliases = (char**)Alloc(
+	    na * sizeof(char*), buf, bufsize, sizeof(char**));
+	if (!to->h_aliases) return PR_FAILURE;
+
+	/* Copy the aliases, one at a time */
+	if (!from->h_aliases) {
+		to->h_aliases[0] = 0;
+	} else {
+		for (na = 0, ap = from->h_aliases; *ap != 0; na++, ap++) {
+			len = strlen(*ap) + 1;
+			to->h_aliases[na] = Alloc(len, buf, bufsize, 0);
+			if (!to->h_aliases[na]) return PR_FAILURE;
+			memcpy(to->h_aliases[na], *ap, len);
+		}
+		to->h_aliases[na] = 0;
+	}
+
+	/* Count the addresses, then allocate storage for the pointers */
+	for (na = 1, ap = from->h_addr_list; *ap != 0; na++, ap++){;} /* nothing to execute */
+	to->h_addr_list = (char**)Alloc(
+	    na * sizeof(char*), buf, bufsize, sizeof(char**));
+	if (!to->h_addr_list) return PR_FAILURE;
+
+	/* Copy the addresses, one at a time */
+	for (na = 0, ap = from->h_addr_list; *ap != 0; na++, ap++) {
+		to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0);
+		if (!to->h_addr_list[na]) return PR_FAILURE;
+		if (conversion != _PRIPAddrNoConversion
+				&& from->h_addrtype == AF_INET) {
+			if (conversion == _PRIPAddrIPv4Mapped) {
+				MakeIPv4MappedAddr(*ap, to->h_addr_list[na]);
+			} else {
+				PR_ASSERT(conversion == _PRIPAddrIPv4Compat);
+				MakeIPv4CompatAddr(*ap, to->h_addr_list[na]);
+			}
+		} else {
+			memcpy(to->h_addr_list[na], *ap, to->h_length);
+		}
+	}
+	to->h_addr_list[na] = 0;
+	return PR_SUCCESS;
+}
+
+#if !defined(_PR_HAVE_GETPROTO_R)
+/*
+** Copy a protoent, and all of the memory that it refers to into
+** (hopefully) stacked buffers.
+*/
+static PRStatus CopyProtoent(
+    struct protoent *from, char *buf, PRIntn bufsize, PRProtoEnt *to)
+{
+	PRIntn len, na;
+	char **ap;
+
+	/* Do the easy stuff */
+	to->p_num = from->p_proto;
+
+	/* Copy the official name */
+	if (!from->p_name) return PR_FAILURE;
+	len = strlen(from->p_name) + 1;
+	to->p_name = Alloc(len, &buf, &bufsize, 0);
+	if (!to->p_name) return PR_FAILURE;
+	memcpy(to->p_name, from->p_name, len);
+
+	/* Count the aliases, then allocate storage for the pointers */
+	for (na = 1, ap = from->p_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */
+	to->p_aliases = (char**)Alloc(
+	    na * sizeof(char*), &buf, &bufsize, sizeof(char**));
+	if (!to->p_aliases) return PR_FAILURE;
+
+	/* Copy the aliases, one at a time */
+	for (na = 0, ap = from->p_aliases; *ap != 0; na++, ap++) {
+		len = strlen(*ap) + 1;
+		to->p_aliases[na] = Alloc(len, &buf, &bufsize, 0);
+		if (!to->p_aliases[na]) return PR_FAILURE;
+		memcpy(to->p_aliases[na], *ap, len);
+	}
+	to->p_aliases[na] = 0;
+
+	return PR_SUCCESS;
+}
+#endif /* !defined(_PR_HAVE_GETPROTO_R) */
+
+/*
+ * #################################################################
+ * NOTE: tmphe, tmpbuf, bufsize, h, and h_err are local variables
+ * or arguments of PR_GetHostByName, PR_GetIPNodeByName, and
+ * PR_GetHostByAddr.  DO NOT CHANGE THE NAMES OF THESE LOCAL 
+ * VARIABLES OR ARGUMENTS.
+ * #################################################################
+ */
+#if defined(_PR_HAVE_GETHOST_R_INT)
+
+#define GETHOSTBYNAME(name) \
+    (gethostbyname_r(name, &tmphe, tmpbuf, bufsize, &h, &h_err), h)
+#define GETHOSTBYNAME2(name, af) \
+    (gethostbyname2_r(name, af, &tmphe, tmpbuf, bufsize, &h, &h_err), h)
+#define GETHOSTBYADDR(addr, addrlen, af) \
+    (gethostbyaddr_r(addr, addrlen, af, \
+    &tmphe, tmpbuf, bufsize, &h, &h_err), h)
+
+#elif defined(_PR_HAVE_GETHOST_R_POINTER)
+
+#define GETHOSTBYNAME(name) \
+    gethostbyname_r(name, &tmphe, tmpbuf, bufsize, &h_err)
+#define GETHOSTBYNAME2(name, af) \
+    gethostbyname2_r(name, af, &tmphe, tmpbuf, bufsize, &h_err)
+#define GETHOSTBYADDR(addr, addrlen, af) \
+    gethostbyaddr_r(addr, addrlen, af, &tmphe, tmpbuf, bufsize, &h_err)
+
+#else
+
+#define GETHOSTBYNAME(name) gethostbyname(name)
+#define GETHOSTBYNAME2(name, af) gethostbyname2(name, af)
+#define GETHOSTBYADDR(addr, addrlen, af) gethostbyaddr(addr, addrlen, af)
+
+#endif  /* definition of GETHOSTBYXXX */
+
+PR_IMPLEMENT(PRStatus) PR_GetHostByName(
+    const char *name, char *buf, PRIntn bufsize, PRHostEnt *hp)
+{
+	struct hostent *h;
+	PRStatus rv = PR_FAILURE;
+#if defined(_PR_HAVE_GETHOST_R)
+    char localbuf[PR_NETDB_BUF_SIZE];
+    char *tmpbuf;
+    struct hostent tmphe;
+    int h_err;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if defined(_PR_HAVE_GETHOST_R)
+    tmpbuf = localbuf;
+    if (bufsize > sizeof(localbuf))
+    {
+        tmpbuf = (char *)PR_Malloc(bufsize);
+        if (NULL == tmpbuf)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return rv;
+        }
+    }
+#endif
+
+	LOCK_DNS();
+
+#ifdef XP_OS2_VACPP
+	h = GETHOSTBYNAME((char *)name);
+#else
+	h = GETHOSTBYNAME(name);
+#endif
+    
+	if (NULL == h)
+	{
+	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
+	}
+	else
+	{
+		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
+		rv = CopyHostent(h, &buf, &bufsize, conversion, hp);
+		if (PR_SUCCESS != rv)
+		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+	}
+	UNLOCK_DNS();
+#if defined(_PR_HAVE_GETHOST_R)
+    if (tmpbuf != localbuf)
+        PR_Free(tmpbuf);
+#endif
+	return rv;
+}
+
+#if !defined(_PR_INET6) && \
+        defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+typedef struct hostent  * (*_pr_getipnodebyname_t)(const char *, int,
+										int, int *);
+typedef struct hostent  * (*_pr_getipnodebyaddr_t)(const void *, size_t,
+													int, int *);
+typedef void (*_pr_freehostent_t)(struct hostent *);
+static void * _pr_getipnodebyname_fp;
+static void * _pr_getipnodebyaddr_fp;
+static void * _pr_freehostent_fp;
+
+/*
+ * Look up the addresses of getipnodebyname, getipnodebyaddr,
+ * and freehostent.
+ */
+PRStatus
+_pr_find_getipnodebyname(void)
+{
+    PRLibrary *lib;	
+    PRStatus rv;
+#if defined(VMS)
+#define GETIPNODEBYNAME getenv("GETIPNODEBYNAME")
+#define GETIPNODEBYADDR getenv("GETIPNODEBYADDR")
+#define FREEHOSTENT     getenv("FREEHOSTENT")
+#else
+#define GETIPNODEBYNAME "getipnodebyname"
+#define GETIPNODEBYADDR "getipnodebyaddr"
+#define FREEHOSTENT     "freehostent"
+#endif
+    _pr_getipnodebyname_fp = PR_FindSymbolAndLibrary(GETIPNODEBYNAME, &lib);
+    if (NULL != _pr_getipnodebyname_fp) {
+        _pr_freehostent_fp = PR_FindSymbol(lib, FREEHOSTENT);
+        if (NULL != _pr_freehostent_fp) {
+            _pr_getipnodebyaddr_fp = PR_FindSymbol(lib, GETIPNODEBYADDR);
+            if (NULL != _pr_getipnodebyaddr_fp)
+                rv = PR_SUCCESS;
+            else
+                rv = PR_FAILURE;
+        } else
+            rv = PR_FAILURE;
+        (void)PR_UnloadLibrary(lib);
+    } else
+        rv = PR_FAILURE;
+    return rv;
+}
+#endif
+
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+/*
+** Append the V4 addresses to the end of the list
+*/
+static PRStatus AppendV4AddrsToHostent(
+    struct hostent *from,
+    char **buf,
+    PRIntn *bufsize,
+    PRHostEnt *to)
+{
+    PRIntn na, na_old;
+    char **ap;
+    char **new_addr_list;
+			
+    /* Count the addresses, then grow storage for the pointers */
+    for (na_old = 0, ap = to->h_addr_list; *ap != 0; na_old++, ap++)
+        {;} /* nothing to execute */
+    for (na = na_old + 1, ap = from->h_addr_list; *ap != 0; na++, ap++)
+        {;} /* nothing to execute */
+    new_addr_list = (char**)Alloc(
+        na * sizeof(char*), buf, bufsize, sizeof(char**));
+    if (!new_addr_list) return PR_FAILURE;
+
+    /* Copy the V6 addresses, one at a time */
+    for (na = 0, ap = to->h_addr_list; *ap != 0; na++, ap++) {
+        new_addr_list[na] = to->h_addr_list[na];
+    }
+    to->h_addr_list = new_addr_list;
+
+    /* Copy the V4 addresses, one at a time */
+    for (ap = from->h_addr_list; *ap != 0; na++, ap++) {
+        to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0);
+        if (!to->h_addr_list[na]) return PR_FAILURE;
+        MakeIPv4MappedAddr(*ap, to->h_addr_list[na]);
+    }
+    to->h_addr_list[na] = 0;
+    return PR_SUCCESS;
+}
+#endif
+
+PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
+    const char *name, PRUint16 af, PRIntn flags,
+    char *buf, PRIntn bufsize, PRHostEnt *hp)
+{
+	struct hostent *h = 0;
+	PRStatus rv = PR_FAILURE;
+#if defined(_PR_HAVE_GETHOST_R)
+    char localbuf[PR_NETDB_BUF_SIZE];
+    char *tmpbuf;
+    struct hostent tmphe;
+    int h_err;
+#endif
+#if defined(_PR_HAVE_GETIPNODEBYNAME)
+	PRUint16 md_af = af;
+	int error_num;
+	int tmp_flags = 0;
+#endif
+#if defined(_PR_HAVE_GETHOSTBYNAME2)
+    PRBool did_af_inet = PR_FALSE;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (af != PR_AF_INET && af != PR_AF_INET6) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+    PR_Lock(_pr_query_ifs_lock);
+    /*
+     * Keep querying the presence of IPv4 and IPv6 interfaces until
+     * at least one is up.  This allows us to detect the local
+     * machine going from offline to online.
+     */
+    if (!_pr_have_inet_if && !_pr_have_inet6_if) {
+	_pr_QueryNetIfs();
+#ifdef DEBUG_QUERY_IFS
+	if (_pr_have_inet_if)
+		printf("Have IPv4 source address\n");
+	if (_pr_have_inet6_if)
+		printf("Have IPv6 source address\n");
+#endif
+    }
+    PR_Unlock(_pr_query_ifs_lock);
+#endif
+
+#if defined(_PR_HAVE_GETIPNODEBYNAME)
+	if (flags & PR_AI_V4MAPPED)
+		tmp_flags |= AI_V4MAPPED;
+	if (flags & PR_AI_ADDRCONFIG)
+		tmp_flags |= AI_ADDRCONFIG;
+	if (flags & PR_AI_ALL)
+		tmp_flags |= AI_ALL;
+    if (af == PR_AF_INET6)
+    	md_af = AF_INET6;
+	else
+    	md_af = af;
+#endif
+
+#if defined(_PR_HAVE_GETHOST_R)
+    tmpbuf = localbuf;
+    if (bufsize > sizeof(localbuf))
+    {
+        tmpbuf = (char *)PR_Malloc(bufsize);
+        if (NULL == tmpbuf)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return rv;
+        }
+    }
+#endif
+
+    /* Do not need to lock the DNS lock if getipnodebyname() is called */
+#ifdef _PR_INET6
+#ifdef _PR_HAVE_GETHOSTBYNAME2
+    LOCK_DNS();
+    if (af == PR_AF_INET6)
+    {
+        if ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet6_if)
+        {
+#ifdef _PR_INET6_PROBE
+          if (_pr_ipv6_is_present == PR_TRUE)
+#endif
+            h = GETHOSTBYNAME2(name, AF_INET6); 
+        }
+        if ((NULL == h) && (flags & PR_AI_V4MAPPED)
+        && ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet_if))
+        {
+            did_af_inet = PR_TRUE;
+            h = GETHOSTBYNAME2(name, AF_INET);
+        }
+    }
+    else
+    {
+        if ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet_if)
+        {
+            did_af_inet = PR_TRUE;
+            h = GETHOSTBYNAME2(name, af);
+        }
+    }
+#elif defined(_PR_HAVE_GETIPNODEBYNAME)
+    h = getipnodebyname(name, md_af, tmp_flags, &error_num);
+#else
+#error "Unknown name-to-address translation function"
+#endif	/* _PR_HAVE_GETHOSTBYNAME2 */
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    if (_pr_ipv6_is_present == PR_TRUE)
+    {
+#ifdef PR_GETIPNODE_NOT_THREADSAFE
+        LOCK_DNS();
+#endif
+    	h = (*((_pr_getipnodebyname_t)_pr_getipnodebyname_fp))(name, md_af, tmp_flags, &error_num);
+    }
+    else
+    {
+        LOCK_DNS();
+    	h = GETHOSTBYNAME(name);
+    }
+#else /* _PR_INET6 */
+    LOCK_DNS();
+#ifdef XP_OS2_VACPP
+    h = GETHOSTBYNAME((char *)name);
+#else
+    h = GETHOSTBYNAME(name);
+#endif
+#endif /* _PR_INET6 */
+    
+	if (NULL == h)
+	{
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+		else
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
+#else
+	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
+#endif
+	}
+	else
+	{
+		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
+
+		if (af == PR_AF_INET6) conversion = _PRIPAddrIPv4Mapped;
+		rv = CopyHostent(h, &buf, &bufsize, conversion, hp);
+		if (PR_SUCCESS != rv)
+		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+		freehostent(h);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+			(*((_pr_freehostent_t)_pr_freehostent_fp))(h);
+#endif
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+		if ((PR_SUCCESS == rv) && (flags & PR_AI_V4MAPPED)
+				&& ((flags & PR_AI_ALL)
+				|| ((flags & PR_AI_ADDRCONFIG) && _pr_have_inet_if))
+				&& !did_af_inet && (h = GETHOSTBYNAME2(name, AF_INET)) != 0) {
+			rv = AppendV4AddrsToHostent(h, &buf, &bufsize, hp);
+			if (PR_SUCCESS != rv)
+				PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+		}
+#endif
+	}
+
+    /* Must match the convoluted logic above for LOCK_DNS() */
+#ifdef _PR_INET6
+#ifdef _PR_HAVE_GETHOSTBYNAME2
+    UNLOCK_DNS();
+#endif	/* _PR_HAVE_GETHOSTBYNAME2 */
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+#ifdef PR_GETIPNODE_NOT_THREADSAFE
+    UNLOCK_DNS();
+#else
+    if (_pr_ipv6_is_present == PR_FALSE)
+        UNLOCK_DNS();
+#endif
+#else /* _PR_INET6 */
+    UNLOCK_DNS();
+#endif /* _PR_INET6 */
+
+#if defined(_PR_HAVE_GETHOST_R)
+    if (tmpbuf != localbuf)
+        PR_Free(tmpbuf);
+#endif
+
+	return rv;
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
+    const PRNetAddr *hostaddr, char *buf, PRIntn bufsize, PRHostEnt *hostentry)
+{
+	struct hostent *h;
+	PRStatus rv = PR_FAILURE;
+	const void *addr;
+	PRUint32 tmp_ip;
+	int addrlen;
+	PRInt32 af;
+#if defined(_PR_HAVE_GETHOST_R)
+    char localbuf[PR_NETDB_BUF_SIZE];
+    char *tmpbuf;
+    struct hostent tmphe;
+    int h_err;
+#endif
+#if defined(_PR_HAVE_GETIPNODEBYADDR)
+	int error_num;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	if (hostaddr->raw.family == PR_AF_INET6)
+	{
+#if defined(_PR_INET6_PROBE)
+		if (_pr_ipv6_is_present == PR_TRUE)
+			af = AF_INET6;
+		else
+			af = AF_INET;
+#elif defined(_PR_INET6)
+		af = AF_INET6;
+#else
+		af = AF_INET;
+#endif
+#if defined(_PR_GHBA_DISALLOW_V4MAPPED)
+		if (_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip))
+			af = AF_INET;
+#endif
+	}
+	else
+	{
+		PR_ASSERT(hostaddr->raw.family == AF_INET);
+		af = AF_INET;
+	}
+	if (hostaddr->raw.family == PR_AF_INET6) {
+#if defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+		if (af == AF_INET6) {
+			addr = &hostaddr->ipv6.ip;
+			addrlen = sizeof(hostaddr->ipv6.ip);
+		}
+		else
+#endif
+		{
+			PR_ASSERT(af == AF_INET);
+			if (!_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) {
+				PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+				return rv;
+			}
+			tmp_ip = _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)
+												&hostaddr->ipv6.ip);
+			addr = &tmp_ip;
+			addrlen = sizeof(tmp_ip);
+		}
+	} else {
+		PR_ASSERT(hostaddr->raw.family == AF_INET);
+		PR_ASSERT(af == AF_INET);
+		addr = &hostaddr->inet.ip;
+		addrlen = sizeof(hostaddr->inet.ip);
+	}
+
+#if defined(_PR_HAVE_GETHOST_R)
+    tmpbuf = localbuf;
+    if (bufsize > sizeof(localbuf))
+    {
+        tmpbuf = (char *)PR_Malloc(bufsize);
+        if (NULL == tmpbuf)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return rv;
+        }
+    }
+#endif
+
+    /* Do not need to lock the DNS lock if getipnodebyaddr() is called */
+#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6)
+	h = getipnodebyaddr(addr, addrlen, af, &error_num);
+#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE)
+    if (_pr_ipv6_is_present == PR_TRUE)
+    {
+#ifdef PR_GETIPNODE_NOT_THREADSAFE
+        LOCK_DNS();
+#endif
+    	h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen,
+				af, &error_num);
+    }
+	else
+    {
+        LOCK_DNS();
+		h = GETHOSTBYADDR(addr, addrlen, af);
+    }
+#else	/* _PR_HAVE_GETIPNODEBYADDR */
+    LOCK_DNS();
+#ifdef XP_OS2_VACPP
+	h = GETHOSTBYADDR((char *)addr, addrlen, af);
+#else
+	h = GETHOSTBYADDR(addr, addrlen, af);
+#endif
+#endif /* _PR_HAVE_GETIPNODEBYADDR */
+	if (NULL == h)
+	{
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
+		PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+		else
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
+#else
+		PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
+#endif
+	}
+	else
+	{
+		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
+		if (hostaddr->raw.family == PR_AF_INET6) {
+			if (af == AF_INET) {
+				if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr*)
+												&hostaddr->ipv6.ip)) {
+					conversion = _PRIPAddrIPv4Mapped;
+				} else if (_PR_IN6_IS_ADDR_V4COMPAT((PRIPv6Addr *)
+													&hostaddr->ipv6.ip)) {
+					conversion = _PRIPAddrIPv4Compat;
+				}
+			}
+		}
+		rv = CopyHostent(h, &buf, &bufsize, conversion, hostentry);
+		if (PR_SUCCESS != rv) {
+		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+		}
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
+		freehostent(h);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+			(*((_pr_freehostent_t)_pr_freehostent_fp))(h);
+#endif
+	}
+
+    /* Must match the convoluted logic above for LOCK_DNS() */
+#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6)
+#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE)
+#ifdef PR_GETIPNODE_NOT_THREADSAFE
+    UNLOCK_DNS();
+#else
+    if (_pr_ipv6_is_present == PR_FALSE)
+        UNLOCK_DNS();
+#endif
+#else	/* _PR_HAVE_GETIPNODEBYADDR */
+    UNLOCK_DNS();
+#endif /* _PR_HAVE_GETIPNODEBYADDR */
+
+#if defined(_PR_HAVE_GETHOST_R)
+    if (tmpbuf != localbuf)
+        PR_Free(tmpbuf);
+#endif
+
+	return rv;
+}
+
+/******************************************************************************/
+/*
+ * Some systems define a reentrant version of getprotobyname(). Too bad
+ * the signature isn't always the same. But hey, they tried. If there
+ * is such a definition, use it. Otherwise, grab a lock and do it here.
+ */
+/******************************************************************************/
+
+#if !defined(_PR_HAVE_GETPROTO_R)
+/*
+ * This may seem like a silly thing to do, but the compiler SHOULD
+ * complain if getprotobyname_r() is implemented on some system and
+ * we're not using it. For sure these signatures are different than
+ * any usable implementation.
+ */
+
+static struct protoent *getprotobyname_r(const char* name)
+{
+#ifdef XP_OS2_VACPP
+	return getprotobyname((char *)name);
+#else
+	return getprotobyname(name);
+#endif
+} /* getprotobyname_r */
+
+static struct protoent *getprotobynumber_r(PRInt32 number)
+{
+	return getprotobynumber(number);
+} /* getprotobynumber_r */
+
+#endif /* !defined(_PR_HAVE_GETPROTO_R) */
+
+PR_IMPLEMENT(PRStatus) PR_GetProtoByName(
+    const char* name, char* buffer, PRInt32 buflen, PRProtoEnt* result)
+{
+	PRStatus rv = PR_SUCCESS;
+#if defined(_PR_HAVE_GETPROTO_R)
+	struct protoent* res = (struct protoent*)result;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if defined(_PR_HAVE_GETPROTO_R_INT)
+    {
+        /*
+        ** The protoent_data has a pointer as the first field.
+        ** That implies the buffer better be aligned, and char*
+        ** doesn't promise much.
+        */
+        PRUptrdiff aligned = (PRUptrdiff)buffer;
+        if (0 != (aligned & (sizeof(struct protoent_data*) - 1)))
+        {
+            aligned += sizeof(struct protoent_data*) - 1;
+            aligned &= ~(sizeof(struct protoent_data*) - 1);
+            buflen -= (aligned - (PRUptrdiff)buffer);
+            buffer = (char*)aligned;
+        }
+    }
+#endif  /* defined(_PR_HAVE_GETPROTO_R_INT) */
+
+    if (PR_NETDB_BUF_SIZE > buflen)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+#if defined(_PR_HAVE_GETPROTO_R_POINTER)
+    if (NULL == getprotobyname_r(name, res, buffer, buflen))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+#elif defined(_PR_HAVE_GETPROTO_R_INT)
+    /*
+    ** The buffer needs to be zero'd, and it should be
+    ** at least the size of a struct protoent_data.
+    */
+    memset(buffer, 0, buflen);
+	if (-1 == getprotobyname_r(name, res, (struct protoent_data*)buffer))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+#elif defined(_PR_HAVE_5_ARG_GETPROTO_R)
+    /* The 5th argument for getprotobyname_r() cannot be NULL */
+    if (-1 == getprotobyname_r(name, res, buffer, buflen, &res))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+#else  /* do it the hard way */
+	{
+		struct protoent *staticBuf;
+		PR_Lock(_getproto_lock);
+		staticBuf = getprotobyname_r(name);
+		if (NULL == staticBuf)
+		{
+		    rv = PR_FAILURE;
+		    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        }
+		else
+		{
+			rv = CopyProtoent(staticBuf, buffer, buflen, result);
+			if (PR_FAILURE == rv)
+			    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+        }
+		PR_Unlock(_getproto_lock);
+	}
+#endif  /* all that */
+    return rv;
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetProtoByNumber(
+    PRInt32 number, char* buffer, PRInt32 buflen, PRProtoEnt* result)
+{
+	PRStatus rv = PR_SUCCESS;
+#if defined(_PR_HAVE_GETPROTO_R)
+	struct protoent* res = (struct protoent*)result;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if defined(_PR_HAVE_GETPROTO_R_INT)
+    {
+        /*
+        ** The protoent_data has a pointer as the first field.
+        ** That implies the buffer better be aligned, and char*
+        ** doesn't promise much.
+        */
+        PRUptrdiff aligned = (PRUptrdiff)buffer;
+        if (0 != (aligned & (sizeof(struct protoent_data*) - 1)))
+        {
+            aligned += sizeof(struct protoent_data*) - 1;
+            aligned &= ~(sizeof(struct protoent_data*) - 1);
+            buflen -= (aligned - (PRUptrdiff)buffer);
+            buffer = (char*)aligned;
+        }
+    }
+#endif /* defined(_PR_HAVE_GETPROTO_R_INT) */
+
+    if (PR_NETDB_BUF_SIZE > buflen)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+#if defined(_PR_HAVE_GETPROTO_R_POINTER)
+    if (NULL == getprotobynumber_r(number, res, buffer, buflen))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+
+#elif defined(_PR_HAVE_GETPROTO_R_INT)
+    /*
+    ** The buffer needs to be zero'd for these OS's.
+    */
+    memset(buffer, 0, buflen);
+	if (-1 == getprotobynumber_r(number, res, (struct protoent_data*)buffer))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+#elif defined(_PR_HAVE_5_ARG_GETPROTO_R)
+    /* The 5th argument for getprotobynumber_r() cannot be NULL */
+    if (-1 == getprotobynumber_r(number, res, buffer, buflen, &res))
+    {
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        return PR_FAILURE;
+    }
+#else  /* do it the hard way */
+	{
+		struct protoent *staticBuf;
+		PR_Lock(_getproto_lock);
+		staticBuf = getprotobynumber_r(number);
+		if (NULL == staticBuf)
+		{
+		    rv = PR_FAILURE;
+		    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());
+        }
+		else
+		{
+			rv = CopyProtoent(staticBuf, buffer, buflen, result);
+			if (PR_FAILURE == rv)
+			    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+        }
+		PR_Unlock(_getproto_lock);
+	}
+#endif  /* all that crap */
+    return rv;
+
+}
+
+PRUintn _PR_NetAddrSize(const PRNetAddr* addr)
+{
+    PRUintn addrsize;
+
+    /*
+     * RFC 2553 added a new field (sin6_scope_id) to
+     * struct sockaddr_in6.  PRNetAddr's ipv6 member has a
+     * scope_id field to match the new field.  In order to
+     * work with older implementations supporting RFC 2133,
+     * we take the size of struct sockaddr_in6 instead of
+     * addr->ipv6.
+     */
+    if (AF_INET == addr->raw.family)
+        addrsize = sizeof(addr->inet);
+    else if (PR_AF_INET6 == addr->raw.family)
+#if defined(_PR_INET6)
+        addrsize = sizeof(struct sockaddr_in6);
+#else
+        addrsize = sizeof(addr->ipv6);
+#endif
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+    else if (AF_UNIX == addr->raw.family)
+        addrsize = sizeof(addr->local);
+#endif
+    else addrsize = 0;
+
+    return addrsize;
+}  /* _PR_NetAddrSize */
+
+PR_IMPLEMENT(PRIntn) PR_EnumerateHostEnt(
+    PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address)
+{
+    void *addr = hostEnt->h_addr_list[enumIndex++];
+    memset(address, 0, sizeof(PRNetAddr));
+    if (NULL == addr) enumIndex = 0;
+    else
+    {
+        address->raw.family = hostEnt->h_addrtype;
+        if (PR_AF_INET6 == hostEnt->h_addrtype)
+        {
+            address->ipv6.port = htons(port);
+        	address->ipv6.flowinfo = 0;
+        	address->ipv6.scope_id = 0;
+            memcpy(&address->ipv6.ip, addr, hostEnt->h_length);
+        }
+        else
+        {
+            PR_ASSERT(AF_INET == hostEnt->h_addrtype);
+            address->inet.port = htons(port);
+            memcpy(&address->inet.ip, addr, hostEnt->h_length);
+        }
+    }
+    return enumIndex;
+}  /* PR_EnumerateHostEnt */
+
+PR_IMPLEMENT(PRStatus) PR_InitializeNetAddr(
+    PRNetAddrValue val, PRUint16 port, PRNetAddr *addr)
+{
+    PRStatus rv = PR_SUCCESS;
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet));
+	addr->inet.family = AF_INET;
+	addr->inet.port = htons(port);
+	switch (val)
+	{
+	case PR_IpAddrNull:
+		break;  /* don't overwrite the address */
+	case PR_IpAddrAny:
+		addr->inet.ip = htonl(INADDR_ANY);
+		break;
+	case PR_IpAddrLoopback:
+		addr->inet.ip = htonl(INADDR_LOOPBACK);
+		break;
+	default:
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		rv = PR_FAILURE;
+	}
+    return rv;
+}  /* PR_InitializeNetAddr */
+
+PR_IMPLEMENT(PRStatus) PR_SetNetAddr(
+    PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr)
+{
+    PRStatus rv = PR_SUCCESS;
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (af == PR_AF_INET6)
+    {
+        if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->ipv6));
+        addr->ipv6.family = af;
+        addr->ipv6.port = htons(port);
+        addr->ipv6.flowinfo = 0;
+        addr->ipv6.scope_id = 0;
+        switch (val)
+        {
+        case PR_IpAddrNull:
+            break;  /* don't overwrite the address */
+        case PR_IpAddrAny:
+            addr->ipv6.ip = _pr_in6addr_any;
+            break;
+        case PR_IpAddrLoopback:
+            addr->ipv6.ip = _pr_in6addr_loopback;
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            rv = PR_FAILURE;
+        }
+    }
+    else
+    {
+        if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet));
+        addr->inet.family = af;
+        addr->inet.port = htons(port);
+        switch (val)
+        {
+        case PR_IpAddrNull:
+            break;  /* don't overwrite the address */
+        case PR_IpAddrAny:
+            addr->inet.ip = htonl(INADDR_ANY);
+            break;
+        case PR_IpAddrLoopback:
+            addr->inet.ip = htonl(INADDR_LOOPBACK);
+            break;
+        default:
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            rv = PR_FAILURE;
+        }
+    }
+    return rv;
+}  /* PR_SetNetAddr */
+
+PR_IMPLEMENT(PRBool)
+PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val)
+{
+    if (addr->raw.family == PR_AF_INET6) {
+        if (val == PR_IpAddrAny) {
+			if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) {
+            	return PR_TRUE;
+			} else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
+					&& _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
+							== htonl(INADDR_ANY)) {
+            	return PR_TRUE;
+			}
+        } else if (val == PR_IpAddrLoopback) {
+            if (_PR_IN6_IS_ADDR_LOOPBACK((PRIPv6Addr *)&addr->ipv6.ip)) {
+            	return PR_TRUE;
+			} else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
+					&& _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
+							== htonl(INADDR_LOOPBACK)) {
+            	return PR_TRUE;
+			}
+        } else if (val == PR_IpAddrV4Mapped
+                && _PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)) {
+            return PR_TRUE;
+        }
+    } else {
+        if (addr->raw.family == AF_INET) {
+            if (val == PR_IpAddrAny && addr->inet.ip == htonl(INADDR_ANY)) {
+                return PR_TRUE;
+            } else if (val == PR_IpAddrLoopback
+                    && addr->inet.ip == htonl(INADDR_LOOPBACK)) {
+                return PR_TRUE;
+            }
+        }
+    }
+    return PR_FALSE;
+}
+
+#ifndef _PR_HAVE_INET_NTOP
+#define XX 127
+static const unsigned char index_hex[256] = {
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+     0, 1, 2, 3,  4, 5, 6, 7,  8, 9,XX,XX, XX,XX,XX,XX,
+    XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+};
+
+/*
+ * StringToV6Addr() returns 1 if the conversion succeeds,
+ * or 0 if the input is not a valid IPv6 address string.
+ * (Same as inet_pton(AF_INET6, string, addr).)
+ */
+static int StringToV6Addr(const char *string, PRIPv6Addr *addr)
+{
+    const unsigned char *s = (const unsigned char *)string;
+    int section = 0;        /* index of the current section (a 16-bit
+                             * piece of the address */
+    int double_colon = -1;  /* index of the section after the first
+                             * 16-bit group of zeros represented by
+                             * the double colon */
+    unsigned int val;
+    int len;
+
+    /* Handle initial (double) colon */
+    if (*s == ':') {
+        if (s[1] != ':') return 0;
+        s += 2;
+        addr->pr_s6_addr16[0] = 0;
+        section = double_colon = 1;
+    }
+
+    while (*s) {
+        if (section == 8) return 0; /* too long */
+        if (*s == ':') {
+            if (double_colon != -1) return 0; /* two double colons */
+            addr->pr_s6_addr16[section++] = 0;
+            double_colon = section;
+            s++;
+            continue;
+        }
+        for (len = val = 0; len < 4 && index_hex[*s] != XX; len++) {
+            val = (val << 4) + index_hex[*s++];
+        }
+        if (*s == '.') {
+            if (len == 0) return 0; /* nothing between : and . */
+            break;
+        }
+        if (*s == ':') {
+            s++;
+            if (!*s) return 0; /* cannot end with single colon */
+        } else if (*s) {
+            return 0; /* bad character */
+        }
+        addr->pr_s6_addr16[section++] = htons((unsigned short)val);
+    }
+    
+    if (*s == '.') {
+        /* Have a trailing v4 format address */
+        if (section > 6) return 0; /* not enough room */
+
+        /*
+         * The number before the '.' is decimal, but we parsed it
+         * as hex.  That means it is in BCD.  Check it for validity
+         * and convert it to binary.
+         */
+        if (val > 0x0255 || (val & 0xf0) > 0x90 || (val & 0xf) > 9) return 0;
+        val = (val >> 8) * 100 + ((val >> 4) & 0xf) * 10 + (val & 0xf);
+        addr->pr_s6_addr[2 * section] = val;
+
+        s++;
+        val = index_hex[*s++];
+        if (val > 9) return 0;
+        while (*s >= '0' && *s <= '9') {
+            val = val * 10 + *s++ - '0';
+            if (val > 255) return 0;
+        }
+        if (*s != '.') return 0; /* must have exactly 4 decimal numbers */
+        addr->pr_s6_addr[2 * section + 1] = val;
+        section++;
+
+        s++;
+        val = index_hex[*s++];
+        if (val > 9) return 0;
+        while (*s >= '0' && *s <= '9') {
+            val = val * 10 + *s++ - '0';
+            if (val > 255) return 0;
+        }
+        if (*s != '.') return 0; /* must have exactly 4 decimal numbers */
+        addr->pr_s6_addr[2 * section] = val;
+
+        s++;
+        val = index_hex[*s++];
+        if (val > 9) return 0;
+        while (*s >= '0' && *s <= '9') {
+            val = val * 10 + *s++ - '0';
+            if (val > 255) return 0;
+        }
+        if (*s) return 0; /* must have exactly 4 decimal numbers */
+        addr->pr_s6_addr[2 * section + 1] = val;
+        section++;
+    }
+    
+    if (double_colon != -1) {
+        /* Stretch the double colon */
+        int tosection;
+        int ncopy = section - double_colon;
+        for (tosection = 7; ncopy--; tosection--) {
+            addr->pr_s6_addr16[tosection] = 
+                addr->pr_s6_addr16[double_colon + ncopy];
+        }
+        while (tosection >= double_colon) {
+            addr->pr_s6_addr16[tosection--] = 0;
+        }
+    } else if (section != 8) {
+        return 0; /* too short */
+    }
+    return 1;
+}
+#undef XX
+            
+static const char *basis_hex = "0123456789abcdef";
+
+/*
+ * V6AddrToString() returns a pointer to the buffer containing
+ * the text string if the conversion succeeds, and NULL otherwise.
+ * (Same as inet_ntop(AF_INET6, addr, buf, size), except that errno
+ * is not set on failure.)
+ */
+static const char *V6AddrToString(
+    const PRIPv6Addr *addr, char *buf, PRUint32 size)
+{
+#define STUFF(c) do { \
+    if (!size--) return NULL; \
+    *buf++ = (c); \
+} while (0)
+
+    int double_colon = -1;          /* index of the first 16-bit
+                                     * group of zeros represented
+                                     * by the double colon */
+    int double_colon_length = 1;    /* use double colon only if
+                                     * there are two or more 16-bit
+                                     * groups of zeros */
+    int zero_length;
+    int section;
+    unsigned int val;
+    const char *bufcopy = buf;
+
+    /* Scan to find the placement of the double colon */
+    for (section = 0; section < 8; section++) {
+        if (addr->pr_s6_addr16[section] == 0) {
+            zero_length = 1;
+            section++;
+            while (section < 8 && addr->pr_s6_addr16[section] == 0) {
+                zero_length++;
+                section++;
+            }
+            /* Select the longest sequence of zeros */
+            if (zero_length > double_colon_length) {
+                double_colon = section - zero_length;
+                double_colon_length = zero_length;
+            }
+        }
+    }
+
+    /* Now start converting to a string */
+    section = 0;
+
+    if (double_colon == 0) {
+        if (double_colon_length == 6 ||
+            (double_colon_length == 5 && addr->pr_s6_addr16[5] == 0xffff)) {
+            /* ipv4 format address */
+            STUFF(':');
+            STUFF(':');
+            if (double_colon_length == 5) {
+                STUFF('f');
+                STUFF('f');
+                STUFF('f');
+                STUFF('f');
+                STUFF(':');
+            }
+            if (addr->pr_s6_addr[12] > 99) STUFF(addr->pr_s6_addr[12]/100 + '0');
+            if (addr->pr_s6_addr[12] > 9) STUFF((addr->pr_s6_addr[12]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[12]%10 + '0');
+            STUFF('.');
+            if (addr->pr_s6_addr[13] > 99) STUFF(addr->pr_s6_addr[13]/100 + '0');
+            if (addr->pr_s6_addr[13] > 9) STUFF((addr->pr_s6_addr[13]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[13]%10 + '0');
+            STUFF('.');
+            if (addr->pr_s6_addr[14] > 99) STUFF(addr->pr_s6_addr[14]/100 + '0');
+            if (addr->pr_s6_addr[14] > 9) STUFF((addr->pr_s6_addr[14]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[14]%10 + '0');
+            STUFF('.');
+            if (addr->pr_s6_addr[15] > 99) STUFF(addr->pr_s6_addr[15]/100 + '0');
+            if (addr->pr_s6_addr[15] > 9) STUFF((addr->pr_s6_addr[15]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[15]%10 + '0');
+            STUFF('\0');
+            return bufcopy;
+        }
+    }
+
+    while (section < 8) {
+        if (section == double_colon) {
+            STUFF(':');
+            STUFF(':');
+            section += double_colon_length;
+            continue;
+        }
+        val = ntohs(addr->pr_s6_addr16[section]);
+        if (val > 0xfff) {
+            STUFF(basis_hex[val >> 12]);
+        }
+        if (val > 0xff) {
+            STUFF(basis_hex[(val >> 8) & 0xf]);
+        }
+        if (val > 0xf) {
+            STUFF(basis_hex[(val >> 4) & 0xf]);
+        }
+        STUFF(basis_hex[val & 0xf]);
+        section++;
+        if (section < 8 && section != double_colon) STUFF(':');
+    }
+    STUFF('\0');
+    return bufcopy;
+#undef STUFF    
+}
+
+#endif /* !_PR_HAVE_INET_NTOP */
+
+PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
+{
+    PRStatus status = PR_SUCCESS;
+    PRIntn rv;
+
+#if defined(_PR_HAVE_INET_NTOP)
+    rv = inet_pton(AF_INET6, string, &addr->ipv6.ip);
+    if (1 == rv)
+    {
+        addr->raw.family = PR_AF_INET6;
+    }
+    else
+    {
+        PR_ASSERT(0 == rv);
+        /* clean up after the failed inet_pton() call */
+        memset(&addr->ipv6.ip, 0, sizeof(addr->ipv6.ip));
+        rv = inet_pton(AF_INET, string, &addr->inet.ip);
+        if (1 == rv)
+        {
+            addr->raw.family = AF_INET;
+        }
+        else
+        {
+            PR_ASSERT(0 == rv);
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            status = PR_FAILURE;
+        }
+    }
+#else /* _PR_HAVE_INET_NTOP */
+    rv = StringToV6Addr(string, &addr->ipv6.ip);
+    if (1 == rv) {
+        addr->raw.family = PR_AF_INET6;
+        return PR_SUCCESS;
+    }
+    PR_ASSERT(0 == rv);
+    /* clean up after the failed StringToV6Addr() call */
+    memset(&addr->ipv6.ip, 0, sizeof(addr->ipv6.ip));
+
+    addr->inet.family = AF_INET;
+#ifdef XP_OS2_VACPP
+    addr->inet.ip = inet_addr((char *)string);
+#else
+    addr->inet.ip = inet_addr(string);
+#endif
+    if ((PRUint32) -1 == addr->inet.ip)
+    {
+        /*
+         * The string argument is a malformed address string.
+         */
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        status = PR_FAILURE;
+    }
+#endif /* _PR_HAVE_INET_NTOP */
+
+    return status;
+}
+
+PR_IMPLEMENT(PRStatus) PR_NetAddrToString(
+    const PRNetAddr *addr, char *string, PRUint32 size)
+{
+    if (PR_AF_INET6 == addr->raw.family)
+    {
+#if defined(_PR_HAVE_INET_NTOP)
+        if (NULL == inet_ntop(AF_INET6, &addr->ipv6.ip, string, size))
+#else
+        if (NULL == V6AddrToString(&addr->ipv6.ip, string, size))
+#endif
+        {
+            /* the size of the result buffer is inadequate */
+            PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
+            return PR_FAILURE;
+        }
+    }
+    else
+    {
+        if (size < 16) goto failed;
+        if (AF_INET != addr->raw.family) goto failed;
+        else
+        {
+            unsigned char *byte = (unsigned char*)&addr->inet.ip;
+            PR_snprintf(string, size, "%u.%u.%u.%u",
+                byte[0], byte[1], byte[2], byte[3]);
+        }
+    }
+
+    return PR_SUCCESS;
+
+failed:
+    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    return PR_FAILURE;
+
+}  /* PR_NetAddrToString */
+
+/*
+ * Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr
+ */
+PR_IMPLEMENT(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr)
+{
+    PRUint8 *dstp;
+    dstp = v6addr->pr_s6_addr;
+    memset(dstp, 0, 10);
+    memset(dstp + 10, 0xff, 2);
+    memcpy(dstp + 12,(char *) &v4addr, 4);
+}
+
+PR_IMPLEMENT(PRUint16) PR_ntohs(PRUint16 n) { return ntohs(n); }
+PR_IMPLEMENT(PRUint32) PR_ntohl(PRUint32 n) { return ntohl(n); }
+PR_IMPLEMENT(PRUint16) PR_htons(PRUint16 n) { return htons(n); }
+PR_IMPLEMENT(PRUint32) PR_htonl(PRUint32 n) { return htonl(n); }
+PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n)
+{
+#ifdef IS_BIG_ENDIAN
+    return n;
+#else
+    PRUint64 tmp;
+    PRUint32 hi, lo;
+    LL_L2UI(lo, n);
+    LL_SHR(tmp, n, 32);
+    LL_L2UI(hi, tmp);
+    hi = PR_ntohl(hi);
+    lo = PR_ntohl(lo);
+    LL_UI2L(n, lo);
+    LL_SHL(n, n, 32);
+    LL_UI2L(tmp, hi);
+    LL_ADD(n, n, tmp);
+    return n;
+#endif
+}  /* ntohll */
+
+PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n)
+{
+#ifdef IS_BIG_ENDIAN
+    return n;
+#else
+    PRUint64 tmp;
+    PRUint32 hi, lo;
+    LL_L2UI(lo, n);
+    LL_SHR(tmp, n, 32);
+    LL_L2UI(hi, tmp);
+    hi = htonl(hi);
+    lo = htonl(lo);
+    LL_UI2L(n, lo);
+    LL_SHL(n, n, 32);
+    LL_UI2L(tmp, hi);
+    LL_ADD(n, n, tmp);
+    return n;
+#endif
+}  /* htonll */
+
+
+/*
+ * Implementation of PR_GetAddrInfoByName and friends
+ *
+ * Compile-time options:
+ *
+ *  _PR_HAVE_GETADDRINFO  Define this macro if the target system provides
+ *                        getaddrinfo. With this defined, NSPR will require
+ *                        getaddrinfo at run time. If this if not defined,
+ *                        then NSPR will attempt to dynamically resolve
+ *                        getaddrinfo, falling back to PR_GetHostByName if
+ *                        getaddrinfo does not exist on the target system.
+ *
+ * Since getaddrinfo is a relatively new system call on many systems,
+ * we are forced to dynamically resolve it at run time in most cases.
+ * The exception includes any system (such as Mac OS X) that is known to
+ * provide getaddrinfo in all versions that NSPR cares to support.
+ */
+
+#if defined(_PR_HAVE_GETADDRINFO)
+
+#if defined(_PR_INET6)
+
+typedef struct addrinfo PRADDRINFO;
+#define GETADDRINFO getaddrinfo
+#define FREEADDRINFO freeaddrinfo
+
+#elif defined(_PR_INET6_PROBE)
+
+typedef struct addrinfo PRADDRINFO;
+
+/* getaddrinfo/freeaddrinfo prototypes */ 
+#if defined(WIN32)
+#define FUNC_MODIFIER __stdcall
+#else
+#define FUNC_MODIFIER
+#endif
+typedef int (FUNC_MODIFIER * FN_GETADDRINFO)
+    (const char *nodename,
+     const char *servname,
+     const PRADDRINFO *hints,
+     PRADDRINFO **res);
+typedef int (FUNC_MODIFIER * FN_FREEADDRINFO)
+    (PRADDRINFO *ai);
+
+/* global state */
+static FN_GETADDRINFO   _pr_getaddrinfo   = NULL;
+static FN_FREEADDRINFO  _pr_freeaddrinfo  = NULL;
+
+#if defined(VMS)
+#define GETADDRINFO_SYMBOL getenv("GETADDRINFO")
+#define FREEADDRINFO_SYMBOL getenv("FREEADDRINFO")
+#else
+#define GETADDRINFO_SYMBOL "getaddrinfo"
+#define FREEADDRINFO_SYMBOL "freeaddrinfo"
+#endif
+
+PRStatus
+_pr_find_getaddrinfo(void)
+{
+    PRLibrary *lib;
+#ifdef WIN32
+    /*
+     * On windows, we need to search ws2_32.dll or wship6.dll
+     * (Microsoft IPv6 Technology Preview for Windows 2000) for
+     * getaddrinfo and freeaddrinfo.  These libraries might not
+     * be loaded yet.
+     */
+    const char *libname[] = { "ws2_32.dll", "wship6.dll" };
+    int i;
+
+    for (i = 0; i < sizeof(libname)/sizeof(libname[0]); i++) {
+        lib = PR_LoadLibrary(libname[i]);
+        if (!lib) {
+            continue;
+        }
+        _pr_getaddrinfo = (FN_GETADDRINFO)
+            PR_FindFunctionSymbol(lib, GETADDRINFO_SYMBOL);
+        if (!_pr_getaddrinfo) {
+            PR_UnloadLibrary(lib);
+            continue;
+        }
+        _pr_freeaddrinfo = (FN_FREEADDRINFO)
+            PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL);
+        PR_ASSERT(_pr_freeaddrinfo);
+        /* Keep the library loaded. */
+        return PR_SUCCESS;
+    }
+    return PR_FAILURE;
+#else
+    /*
+     * Resolve getaddrinfo by searching all loaded libraries.  Then
+     * search library containing getaddrinfo for freeaddrinfo.
+     */
+    _pr_getaddrinfo = (FN_GETADDRINFO)
+        PR_FindFunctionSymbolAndLibrary(GETADDRINFO_SYMBOL, &lib);
+    if (!_pr_getaddrinfo) {
+        return PR_FAILURE;
+    }
+    _pr_freeaddrinfo = (FN_FREEADDRINFO)
+        PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL);
+    PR_UnloadLibrary(lib);
+    if (!_pr_freeaddrinfo) {
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+#endif
+}
+
+#define GETADDRINFO (*_pr_getaddrinfo)
+#define FREEADDRINFO (*_pr_freeaddrinfo)
+
+#endif /* _PR_INET6 */
+
+#endif /* _PR_HAVE_GETADDRINFO */
+
+/*
+ * If getaddrinfo does not exist, then we will fall back on
+ * PR_GetHostByName, which requires that we allocate a buffer for the 
+ * PRHostEnt data structure and its members.
+ */
+typedef struct PRAddrInfoFB {
+    char      buf[PR_NETDB_BUF_SIZE];
+    PRHostEnt hostent;
+    PRBool    has_cname;
+} PRAddrInfoFB;
+
+static PRAddrInfo *
+pr_GetAddrInfoByNameFB(const char  *hostname,
+                       PRUint16     af,
+                       PRIntn       flags)
+{
+    PRStatus rv;
+    PRAddrInfoFB *ai;
+    /* fallback on PR_GetHostByName */
+    ai = PR_NEW(PRAddrInfoFB);
+    if (!ai) {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    rv = PR_GetHostByName(hostname, ai->buf, sizeof ai->buf, &ai->hostent);
+    if (rv == PR_FAILURE) {
+        PR_Free(ai);
+        return NULL;
+    }
+    ai->has_cname = !(flags & PR_AI_NOCANONNAME);
+
+    return (PRAddrInfo *) ai;
+}
+
+PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char  *hostname,
+                                                PRUint16     af,
+                                                PRIntn       flags)
+{
+    /* restrict input to supported values */
+    if ((af != PR_AF_INET && af != PR_AF_UNSPEC) ||
+        (flags & ~ PR_AI_NOCANONNAME) != PR_AI_ADDRCONFIG) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return NULL;
+    }
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+#if !defined(_PR_HAVE_GETADDRINFO)
+    return pr_GetAddrInfoByNameFB(hostname, af, flags);
+#else
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present) {
+        return pr_GetAddrInfoByNameFB(hostname, af, flags);
+    }
+#endif
+    {
+        PRADDRINFO *res, hints;
+        PRStatus rv;
+
+        /*
+         * we assume a RFC 2553 compliant getaddrinfo.  this may at some
+         * point need to be customized as platforms begin to adopt the
+         * RFC 3493.
+         */
+
+        memset(&hints, 0, sizeof(hints));
+        hints.ai_flags = (flags & PR_AI_NOCANONNAME) ? 0: AI_CANONNAME;
+        hints.ai_family = (af == PR_AF_INET) ? AF_INET : AF_UNSPEC;
+
+        /*
+         * it is important to select a socket type in the hints, otherwise we
+         * will get back repetitive entries: one for each socket type.  since
+         * we do not expose ai_socktype through our API, it is okay to do this
+         * here.  the application may still choose to create a socket of some
+         * other type.
+         */
+        hints.ai_socktype = SOCK_STREAM;
+
+        rv = GETADDRINFO(hostname, NULL, &hints, &res);
+        if (rv == 0)
+            return (PRAddrInfo *) res;
+
+        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, rv);
+    }
+    return NULL;
+#endif
+}
+
+PR_IMPLEMENT(void) PR_FreeAddrInfo(PRAddrInfo *ai)
+{
+#if defined(_PR_HAVE_GETADDRINFO)
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present)
+        PR_Free((PRAddrInfoFB *) ai);
+    else
+#endif
+        FREEADDRINFO((PRADDRINFO *) ai);
+#else
+    PR_Free((PRAddrInfoFB *) ai);
+#endif
+}
+
+PR_IMPLEMENT(void *) PR_EnumerateAddrInfo(void             *iterPtr,
+                                          const PRAddrInfo *base,
+                                          PRUint16          port,
+                                          PRNetAddr        *result)
+{
+#if defined(_PR_HAVE_GETADDRINFO)
+    PRADDRINFO *ai;
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present) {
+        /* using PRAddrInfoFB */
+        PRIntn iter = (PRIntn)(PRPtrdiff) iterPtr;
+        iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result);
+        if (iter < 0)
+            iter = 0;
+        return (void *)(PRPtrdiff) iter;
+    }
+#endif
+
+    if (iterPtr)
+        ai = ((PRADDRINFO *) iterPtr)->ai_next;
+    else
+        ai = (PRADDRINFO *) base;
+
+    if (ai) {
+        /* copy sockaddr to PRNetAddr */
+        memcpy(result, ai->ai_addr, ai->ai_addrlen);
+        result->raw.family = ai->ai_addr->sa_family;
+        if (ai->ai_addrlen < sizeof(PRNetAddr))
+            memset(((char*)result)+ai->ai_addrlen, 0, sizeof(PRNetAddr) - ai->ai_addrlen);
+
+        if (result->raw.family == PR_AF_INET)
+            result->inet.port = htons(port);
+        else
+            result->ipv6.port = htons(port);
+    }
+
+    return ai;
+#else
+    /* using PRAddrInfoFB */
+    PRIntn iter = (PRIntn) iterPtr;
+    iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result);
+    if (iter < 0)
+        iter = 0;
+    return (void *) iter;
+#endif
+}
+
+PR_IMPLEMENT(const char *) PR_GetCanonNameFromAddrInfo(const PRAddrInfo *ai)
+{
+#if defined(_PR_HAVE_GETADDRINFO)
+#if defined(_PR_INET6_PROBE)
+    if (!_pr_ipv6_is_present) {
+        const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai;
+        return fb->has_cname ? fb->hostent.h_name : NULL;
+    } 
+#endif
+    return ((const PRADDRINFO *) ai)->ai_canonname;
+#else
+    const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai;
+    return fb->has_cname ? fb->hostent.h_name : NULL;
+#endif
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prolock.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prolock.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+**  prolock.c -- NSPR Ordered Lock
+** 
+**  Implement the API defined in prolock.h
+** 
+*/
+#include "prolock.h"
+#include "prlog.h"
+#include "prerror.h"
+
+PR_IMPLEMENT(PROrderedLock *) 
+    PR_CreateOrderedLock( 
+        PRInt32 order,
+        const char *name
+)
+{
+#ifdef XP_MAC
+#pragma unused( order, name )
+#endif
+    PR_ASSERT(!"Not implemented"); /* Not implemented yet */
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+} /*  end PR_CreateOrderedLock() */
+
+
+PR_IMPLEMENT(void) 
+    PR_DestroyOrderedLock( 
+        PROrderedLock *lock 
+)
+{
+#ifdef XP_MAC
+#pragma unused( lock )
+#endif
+    PR_ASSERT(!"Not implemented"); /* Not implemented yet */
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+} /*  end PR_DestroyOrderedLock() */
+
+
+PR_IMPLEMENT(void) 
+    PR_LockOrderedLock( 
+        PROrderedLock *lock 
+)
+{
+#ifdef XP_MAC
+#pragma unused( lock )
+#endif
+    PR_ASSERT(!"Not implemented"); /* Not implemented yet */
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+} /*  end PR_LockOrderedLock() */
+
+
+PR_IMPLEMENT(PRStatus) 
+    PR_UnlockOrderedLock( 
+        PROrderedLock *lock 
+)
+{
+#ifdef XP_MAC
+#pragma unused( lock )
+#endif
+    PR_ASSERT(!"Not implemented"); /* Not implemented yet */
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+} /*  end PR_UnlockOrderedLock() */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prrng.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prrng.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,76 @@
+/* -*- 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"
+
+/*
+ * We were not including <string.h> in optimized builds.  On AIX this
+ * caused libnspr4.so to export memcpy and some binaries linked with
+ * libnspr4.so resolved their memcpy references with libnspr4.so.  To
+ * be backward compatible with old libnspr4.so binaries, we do not
+ * include <string.h> in optimized builds for AIX.  (bug 200561)
+ */
+#if !(defined(AIX) && !defined(DEBUG))
+#include <string.h>
+#endif
+
+PRSize _pr_CopyLowBits( 
+    void *dst, 
+    PRSize dstlen, 
+    void *src, 
+    PRSize srclen )
+{
+    if (srclen <= dstlen) {
+    	memcpy(dst, src, srclen);
+	    return srclen;
+    }
+#if defined IS_BIG_ENDIAN
+    memcpy(dst, (char*)src + (srclen - dstlen), dstlen);
+#else
+    memcpy(dst, src, dstlen);
+#endif
+    return dstlen;
+}    
+
+PR_IMPLEMENT(PRSize) PR_GetRandomNoise( 
+    void    *buf,
+    PRSize  size
+)
+{
+    return( _PR_MD_GET_RANDOM_NOISE( buf, size ));
+} /* end PR_GetRandomNoise() */
+/* end prrng.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prsystem.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prsystem.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,366 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 "prsystem.h"
+#include "prprf.h"
+#include "prlong.h"
+
+#if defined(BEOS)
+#include <kernel/OS.h>
+#endif
+
+#if defined(OS2)
+#define INCL_DOS
+#define INCL_DOSMISC
+#include <os2.h>
+/* define the required constant if it is not already defined in the headers */
+#ifndef QSV_NUMPROCESSORS
+#define QSV_NUMPROCESSORS 26
+#endif
+#endif
+
+/* BSD-derived systems use sysctl() to get the number of processors */
+#if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) \
+    || defined(OPENBSD) || defined(DARWIN)
+#define _PR_HAVE_SYSCTL
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#endif
+
+#if defined(DARWIN)
+#include <mach/mach_init.h>
+#include <mach/mach_host.h>
+#endif
+
+#if defined(HPUX)
+#include <sys/mpctl.h>
+#include <sys/pstat.h>
+#endif
+
+#if defined(XP_UNIX)
+#include <unistd.h>
+#include <sys/utsname.h>
+#endif
+
+#if defined(AIX)
+#include <cf.h>
+#include <sys/cfgodm.h>
+#endif
+
+#if defined(WIN32)
+/* This struct is not present in VC6 headers, so declare it here */
+typedef struct {
+    DWORD dwLength;
+    DWORD dwMemoryLoad;
+    DWORDLONG ullTotalPhys;
+    DWORDLONG ullAvailPhys;
+    DWORDLONG ullToalPageFile;
+    DWORDLONG ullAvailPageFile;
+    DWORDLONG ullTotalVirtual;
+    DWORDLONG ullAvailVirtual;
+    DWORDLONG ullAvailExtendedVirtual;
+} PR_MEMORYSTATUSEX;
+
+/* Typedef for dynamic lookup of GlobalMemoryStatusEx(). */
+typedef BOOL (WINAPI *GlobalMemoryStatusExFn)(PR_MEMORYSTATUSEX *);
+#endif
+
+PR_IMPLEMENT(char) PR_GetDirectorySeparator(void)
+{
+    return PR_DIRECTORY_SEPARATOR;
+}  /* PR_GetDirectorySeparator */
+
+/*
+** OBSOLETE -- the function name is misspelled.
+*/
+PR_IMPLEMENT(char) PR_GetDirectorySepartor(void)
+{
+#if defined(DEBUG)
+    static PRBool warn = PR_TRUE;
+    if (warn) {
+        warn = _PR_Obsolete("PR_GetDirectorySepartor()",
+                "PR_GetDirectorySeparator()");
+    }
+#endif
+    return PR_GetDirectorySeparator();
+}  /* PR_GetDirectorySepartor */
+
+PR_IMPLEMENT(char) PR_GetPathSeparator(void)
+{
+    return PR_PATH_SEPARATOR;
+}  /* PR_GetPathSeparator */
+
+PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 buflen)
+{
+    PRUintn len = 0;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    switch(cmd)
+    {
+      case PR_SI_HOSTNAME:
+      case PR_SI_HOSTNAME_UNTRUNCATED:
+        if (PR_FAILURE == _PR_MD_GETHOSTNAME(buf, (PRUintn)buflen))
+            return PR_FAILURE;
+
+        if (cmd == PR_SI_HOSTNAME_UNTRUNCATED)
+            break;
+        /*
+         * On some platforms a system does not have a hostname and
+         * its IP address is returned instead.   The following code
+         * should be skipped on those platforms.
+         */
+#ifndef _PR_GET_HOST_ADDR_AS_NAME
+        /* Return the unqualified hostname */
+            while (buf[len] && (len < buflen)) {
+                if (buf[len] == '.') {
+                    buf[len] = '\0';
+                    break;
+                }
+                len += 1;
+            }    
+#endif
+         break;
+
+      case PR_SI_SYSNAME:
+        /* Return the operating system name */
+#if defined(XP_UNIX) || defined(WIN32)
+        if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen))
+            return PR_FAILURE;
+#else
+        (void)PR_snprintf(buf, buflen, _PR_SI_SYSNAME);
+#endif
+        break;
+
+      case PR_SI_RELEASE:
+        /* Return the version of the operating system */
+#if defined(XP_UNIX) || defined(WIN32)
+        if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen))
+            return PR_FAILURE;
+#endif
+#if defined(XP_OS2)
+        {
+            ULONG os2ver[2] = {0};
+            DosQuerySysInfo(QSV_VERSION_MINOR, QSV_VERSION_REVISION,
+                            &os2ver, sizeof(os2ver));
+            /* Formatting for normal usage (2.11, 3.0, 4.0, 4.5); officially,
+               Warp 4 is version 2.40.00, WSeB 2.45.00 */
+            if (os2ver[0] < 30)
+              (void)PR_snprintf(buf, buflen, "%s%lu",
+                                "2.", os2ver[0]);
+            else if (os2ver[0] < 45)
+              (void)PR_snprintf(buf, buflen, "%lu%s%lu",
+                                os2ver[0]/10, ".", os2ver[1]);
+            else
+              (void)PR_snprintf(buf, buflen, "%.1f",
+                                os2ver[0]/10.0);
+        }
+#endif /* OS2 */
+        break;
+
+      case PR_SI_ARCHITECTURE:
+        /* Return the architecture of the machine (ie. x86, mips, alpha, ...)*/
+        (void)PR_snprintf(buf, buflen, _PR_SI_ARCHITECTURE);
+        break;
+	  default:
+			PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+			return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+/*
+** PR_GetNumberOfProcessors()
+** 
+** Implementation notes:
+**   Every platform does it a bit different.
+**     numCpus is the returned value.
+**   for each platform's "if defined" section
+**     declare your local variable
+**     do your thing, assign to numCpus
+**   order of the if defined()s may be important,
+**     especially for unix variants. Do platform
+**     specific implementations before XP_UNIX.
+** 
+*/
+PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void )
+{
+    PRInt32     numCpus;
+#if defined(WIN32)
+    SYSTEM_INFO     info;
+
+    GetSystemInfo( &info );
+    numCpus = info.dwNumberOfProcessors;
+#elif defined(XP_MAC)
+/* Hard-code the number of processors to 1 on the Mac
+** MacOS/9 will always be 1. The MPProcessors() call is for
+** MacOS/X, when issued. Leave it commented out for now. */
+/*  numCpus = MPProcessors(); */
+    numCpus = 1;
+#elif defined(BEOS)
+    system_info sysInfo;
+
+    get_system_info(&sysInfo);
+    numCpus = sysInfo.cpu_count;
+#elif defined(OS2)
+    DosQuerySysInfo( QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numCpus, sizeof(numCpus));
+#elif defined(_PR_HAVE_SYSCTL)
+    int mib[2];
+    int rc;
+    size_t len = sizeof(numCpus);
+
+    mib[0] = CTL_HW;
+    mib[1] = HW_NCPU;
+    rc = sysctl( mib, 2, &numCpus, &len, NULL, 0 );
+    if ( -1 == rc )  {
+        numCpus = -1; /* set to -1 for return value on error */
+        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
+    }
+#elif defined(HPUX)
+    numCpus = mpctl( MPC_GETNUMSPUS, 0, 0 );
+    if ( numCpus < 1 )  {
+        numCpus = -1; /* set to -1 for return value on error */
+        _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() );
+    }
+#elif defined(IRIX)
+    numCpus = sysconf( _SC_NPROC_ONLN );
+#elif defined(RISCOS)
+    numCpus = 1;
+#elif defined(XP_UNIX)
+    numCpus = sysconf( _SC_NPROCESSORS_ONLN );
+#else
+#error "An implementation is required"
+#endif
+    return(numCpus);
+} /* end PR_GetNumberOfProcessors() */
+
+/*
+** PR_GetPhysicalMemorySize()
+** 
+** Implementation notes:
+**   Every platform does it a bit different.
+**     bytes is the returned value.
+**   for each platform's "if defined" section
+**     declare your local variable
+**     do your thing, assign to bytes.
+** 
+*/
+PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void)
+{
+    PRUint64 bytes = 0;
+
+#if defined(LINUX) || defined(SOLARIS)
+
+    long pageSize = sysconf(_SC_PAGESIZE);
+    long pageCount = sysconf(_SC_PHYS_PAGES);
+    bytes = (PRUint64) pageSize * pageCount;
+
+#elif defined(HPUX)
+
+    struct pst_static info;
+    int result = pstat_getstatic(&info, sizeof(info), 1, 0);
+    if (result == 1)
+        bytes = (PRUint64) info.physical_memory * info.page_size;
+
+#elif defined(DARWIN)
+
+    struct host_basic_info hInfo;
+    mach_msg_type_number_t count;
+
+    int result = host_info(mach_host_self(),
+                           HOST_BASIC_INFO,
+                           (host_info_t) &hInfo,
+                           &count);
+    if (result == KERN_SUCCESS)
+        bytes = hInfo.memory_size;
+
+#elif defined(WIN32)
+
+    /* Try to use the newer GlobalMemoryStatusEx API for Windows 2000+. */
+    GlobalMemoryStatusExFn globalMemory = (GlobalMemoryStatusExFn) NULL;
+    HMODULE module = GetModuleHandle("kernel32.dll");
+
+    if (module) {
+        globalMemory = (GlobalMemoryStatusExFn)GetProcAddress(module, "GlobalMemoryStatusEx");
+
+        if (globalMemory) {
+            PR_MEMORYSTATUSEX memStat;
+            memStat.dwLength = sizeof(memStat);
+
+            if (globalMemory(&memStat))
+                bytes = memStat.ullTotalPhys;
+        }
+    }
+
+    if (!bytes) {
+        /* Fall back to the older API. */
+        MEMORYSTATUS memStat;
+        memset(&memStat, 0, sizeof(memStat));
+        GlobalMemoryStatus(&memStat);
+        bytes = memStat.dwTotalPhys;
+    }
+
+#elif defined(OS2)
+
+    ULONG ulPhysMem;
+    DosQuerySysInfo(QSV_TOTPHYSMEM,
+                    QSV_TOTPHYSMEM,
+                    &ulPhysMem,
+                    sizeof(ulPhysMem));
+    bytes = ulPhysMem;
+
+#elif defined(AIX)
+
+    if (odm_initialize() == 0) {
+        int how_many;
+        struct CuAt *obj = getattr("sys0", "realmem", 0, &how_many);
+        if (obj != NULL) {
+            bytes = (PRUint64) atoi(obj->value) * 1024;
+            free(obj);
+        }
+        odm_terminate();
+    }
+
+#else
+
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+
+#endif
+
+    return bytes;
+} /* end PR_GetPhysicalMemorySize() */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prthinfo.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prthinfo.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,247 @@
+/* -*- 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 "prlog.h"
+#include "prthread.h"
+#ifdef XP_MAC
+#include "pprthred.h"
+#else
+#include "private/pprthred.h"
+#endif
+#include "primpl.h"
+
+PR_IMPLEMENT(PRWord *)
+PR_GetGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+    return _MD_HomeGCRegisters(t, isCurrent, np);
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_ThreadScanStackPointers(PRThread* t,
+                           PRScanStackFun scanFun, void* scanClosure)
+{
+    PRThread* current = PR_GetCurrentThread();
+    PRWord *sp, *esp, *p0;
+    int n;
+    void **ptd;
+    PRStatus status;
+    PRUint32 index;
+    int stack_end;
+
+    /*
+    ** Store the thread's registers in the thread structure so the GC
+    ** can scan them. Then scan them.
+    */
+    p0 = _MD_HomeGCRegisters(t, t == current, &n);
+    status = scanFun(t, (void**)p0, n, scanClosure);
+    if (status != PR_SUCCESS)
+        return status;
+
+    /* Scan the C stack for pointers into the GC heap */
+#if defined(XP_PC) && defined(WIN16)
+    /*
+    ** Under WIN16, the stack of the current thread is always mapped into
+    ** the "task stack" (at SS:xxxx).  So, if t is the current thread, scan
+    ** the "task stack".  Otherwise, scan the "cached stack" of the inactive
+    ** thread...
+    */
+    if (t == current) {
+        sp  = (PRWord*) &stack_end;
+        esp = (PRWord*) _pr_top_of_task_stack;
+
+        PR_ASSERT(sp <= esp);
+    } else {
+        sp  = (PRWord*) PR_GetSP(t);
+        esp = (PRWord*) t->stack->stackTop;
+
+        PR_ASSERT((t->stack->stackSize == 0) ||
+                  ((sp >  (PRWord*)t->stack->stackBottom) &&
+                   (sp <= (PRWord*)t->stack->stackTop)));
+    }
+#else   /* ! WIN16 */
+#ifdef HAVE_STACK_GROWING_UP
+    if (t == current) {
+        esp = (PRWord*) &stack_end;
+    } else {
+        esp = (PRWord*) PR_GetSP(t);
+    }
+    sp = (PRWord*) t->stack->stackTop;
+    if (t->stack->stackSize) {
+        PR_ASSERT((esp > (PRWord*)t->stack->stackTop) &&
+                  (esp < (PRWord*)t->stack->stackBottom));
+    }
+#else   /* ! HAVE_STACK_GROWING_UP */
+    if (t == current) {
+        sp = (PRWord*) &stack_end;
+    } else {
+        sp = (PRWord*) PR_GetSP(t);
+    }
+    esp = (PRWord*) t->stack->stackTop;
+    if (t->stack->stackSize) {
+        PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) &&
+                  (sp < (PRWord*)t->stack->stackTop));
+    }
+#endif  /* ! HAVE_STACK_GROWING_UP */
+#endif  /* ! WIN16 */
+
+#if defined(WIN16)
+    {
+        prword_t scan;
+        prword_t limit;
+        
+        scan = (prword_t) sp;
+        limit = (prword_t) esp;
+        while (scan < limit) {
+            prword_t *test;
+
+            test = *((prword_t **)scan);
+            status = scanFun(t, (void**)&test, 1, scanClosure);
+            if (status != PR_SUCCESS)
+                return status;
+            scan += sizeof(char);
+        }
+    }
+#else
+    if (sp < esp) {
+        status = scanFun(t, (void**)sp, esp - sp, scanClosure);
+        if (status != PR_SUCCESS)
+            return status;
+    }
+#endif
+
+    /*
+    ** Mark all of the per-thread-data items attached to this thread
+    **
+    ** The execution environment better be accounted for otherwise it
+    ** will be collected
+    */
+    status = scanFun(t, (void**)&t->environment, 1, scanClosure);
+    if (status != PR_SUCCESS)
+        return status;
+
+#ifndef GC_LEAK_DETECTOR
+    /* if thread is not allocated on stack, this is redundant. */
+    ptd = t->privateData;
+    for (index = 0; index < t->tpdLength; index++, ptd++) {
+        status = scanFun(t, (void**)ptd, 1, scanClosure);
+        if (status != PR_SUCCESS)
+            return status;
+    }
+#endif
+    
+    return PR_SUCCESS;
+}
+
+/* transducer for PR_EnumerateThreads */
+typedef struct PRScanStackData {
+    PRScanStackFun      scanFun;
+    void*               scanClosure;
+} PRScanStackData;
+
+static PRStatus PR_CALLBACK
+pr_ScanStack(PRThread* t, int i, void* arg)
+{
+#if defined(XP_MAC)
+#pragma unused (i)
+#endif
+    PRScanStackData* data = (PRScanStackData*)arg;
+    return PR_ThreadScanStackPointers(t, data->scanFun, data->scanClosure);
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_ScanStackPointers(PRScanStackFun scanFun, void* scanClosure)
+{
+    PRScanStackData data;
+    data.scanFun = scanFun;
+    data.scanClosure = scanClosure;
+    return PR_EnumerateThreads(pr_ScanStack, &data);
+}
+
+PR_IMPLEMENT(PRUword)
+PR_GetStackSpaceLeft(PRThread* t)
+{
+    PRThread *current = PR_GetCurrentThread();
+    PRWord *sp, *esp;
+    int stack_end;
+
+#if defined(WIN16)
+    /*
+    ** Under WIN16, the stack of the current thread is always mapped into
+    ** the "task stack" (at SS:xxxx).  So, if t is the current thread, scan
+    ** the "task stack".  Otherwise, scan the "cached stack" of the inactive
+    ** thread...
+    */
+    if (t == current) {
+        sp  = (PRWord*) &stack_end;
+        esp = (PRWord*) _pr_top_of_task_stack;
+
+        PR_ASSERT(sp <= esp);
+    } else {
+        sp  = (PRWord*) PR_GetSP(t);
+        esp = (PRWord*) t->stack->stackTop;
+
+	PR_ASSERT((t->stack->stackSize == 0) ||
+                 ((sp >  (PRWord*)t->stack->stackBottom) &&
+		  (sp <= (PRWord*)t->stack->stackTop)));
+    }
+#else   /* ! WIN16 */
+#ifdef HAVE_STACK_GROWING_UP
+    if (t == current) {
+        esp = (PRWord*) &stack_end;
+    } else {
+        esp = (PRWord*) PR_GetSP(t);
+    }
+    sp = (PRWord*) t->stack->stackTop;
+    if (t->stack->stackSize) {
+        PR_ASSERT((esp > (PRWord*)t->stack->stackTop) &&
+                  (esp < (PRWord*)t->stack->stackBottom));
+    }
+#else   /* ! HAVE_STACK_GROWING_UP */
+    if (t == current) {
+        sp = (PRWord*) &stack_end;
+    } else {
+        sp = (PRWord*) PR_GetSP(t);
+    }
+    esp = (PRWord*) t->stack->stackTop;
+    if (t->stack->stackSize) {
+	PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) &&
+		  (sp < (PRWord*)t->stack->stackTop));
+    }
+#endif  /* ! HAVE_STACK_GROWING_UP */
+#endif  /* ! WIN16 */
+    return (PRUword)t->stack->stackSize - ((PRWord)esp - (PRWord)sp);
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prtime.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prtime.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1961 @@
+/* -*- 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 ***** */
+
+/*
+ * prtime.c --
+ *
+ *     NSPR date and time functions
+ *
+ */
+
+#include "prinit.h"
+#include "prtime.h"
+#include "prlock.h"
+#include "prprf.h"
+#include "prlog.h"
+
+#include <string.h>
+#include <ctype.h>
+
+#ifdef XP_MAC
+#include <time.h>
+#endif
+
+/* 
+ * The COUNT_LEAPS macro counts the number of leap years passed by
+ * till the start of the given year Y.  At the start of the year 4
+ * A.D. the number of leap years passed by is 0, while at the start of
+ * the year 5 A.D. this count is 1. The number of years divisible by
+ * 100 but not divisible by 400 (the non-leap years) is deducted from
+ * the count to get the correct number of leap years.
+ *
+ * The COUNT_DAYS macro counts the number of days since 01/01/01 till the
+ * start of the given year Y. The number of days at the start of the year
+ * 1 is 0 while the number of days at the start of the year 2 is 365
+ * (which is ((2)-1) * 365) and so on. The reference point is 01/01/01
+ * midnight 00:00:00.
+ */
+
+#define COUNT_LEAPS(Y)   ( ((Y)-1)/4 - ((Y)-1)/100 + ((Y)-1)/400 )
+#define COUNT_DAYS(Y)  ( ((Y)-1)*365 + COUNT_LEAPS(Y) )
+#define DAYS_BETWEEN_YEARS(A, B)  (COUNT_DAYS(B) - COUNT_DAYS(A))
+
+
+
+
+/*
+ * Static variables used by functions in this file
+ */
+
+/*
+ * The following array contains the day of year for the last day of
+ * each month, where index 1 is January, and day 0 is January 1.
+ */
+
+static const int lastDayOfMonth[2][13] = {
+    {-1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364},
+    {-1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}
+};
+
+/*
+ * The number of days in a month
+ */
+
+static const PRInt8 nDays[2][12] = {
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
+};
+
+/*
+ * Declarations for internal functions defined later in this file.
+ */
+
+static void        ComputeGMT(PRTime time, PRExplodedTime *gmt);
+static int        IsLeapYear(PRInt16 year);
+static void        ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset);
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ComputeGMT --
+ *
+ *     Caveats:
+ *     - we ignore leap seconds
+ *     - our leap-year calculation is only correct for years 1901-2099
+ *
+ *------------------------------------------------------------------------
+ */
+
+static void
+ComputeGMT(PRTime time, PRExplodedTime *gmt)
+{
+    PRInt32 tmp, rem;
+    PRInt32 numDays;
+    PRInt64 numDays64, rem64;
+    int isLeap;
+    PRInt64 sec;
+    PRInt64 usec;
+    PRInt64 usecPerSec;
+    PRInt64 secPerDay;
+
+    /*
+     * We first do the usec, sec, min, hour thing so that we do not
+     * have to do LL arithmetic.
+     */
+
+    LL_I2L(usecPerSec, 1000000L);
+    LL_DIV(sec, time, usecPerSec);
+    LL_MOD(usec, time, usecPerSec);
+    LL_L2I(gmt->tm_usec, usec);
+    /* Correct for weird mod semantics so the remainder is always positive */
+    if (gmt->tm_usec < 0) {
+        PRInt64 one;
+
+        LL_I2L(one, 1L);
+        LL_SUB(sec, sec, one);
+        gmt->tm_usec += 1000000L;
+    }
+
+    LL_I2L(secPerDay, 86400L);
+    LL_DIV(numDays64, sec, secPerDay);
+    LL_MOD(rem64, sec, secPerDay);
+    /* We are sure both of these numbers can fit into PRInt32 */
+    LL_L2I(numDays, numDays64);
+    LL_L2I(rem, rem64);
+    if (rem < 0) {
+        numDays--;
+        rem += 86400L;
+    }
+
+    /* Compute day of week.  Epoch started on a Thursday. */
+
+    gmt->tm_wday = (numDays + 4) % 7;
+    if (gmt->tm_wday < 0) {
+        gmt->tm_wday += 7;
+    }
+
+    /* Compute the time of day. */
+    
+    gmt->tm_hour = rem / 3600;
+    rem %= 3600;
+    gmt->tm_min = rem / 60;
+    gmt->tm_sec = rem % 60;
+
+    /* Compute the four-year span containing the specified time */
+
+    tmp = numDays / (4 * 365 + 1);
+    rem = numDays % (4 * 365 + 1);
+
+    if (rem < 0) {
+        tmp--;
+        rem += (4 * 365 + 1);
+    }
+
+    /*
+     * Compute the year after 1900 by taking the four-year span and
+     * adjusting for the remainder.  This works because 2000 is a 
+     * leap year, and 1900 and 2100 are out of the range.
+     */
+    
+    tmp = (tmp * 4) + 1970;
+    isLeap = 0;
+
+    /*
+     * 1970 has 365 days
+     * 1971 has 365 days
+     * 1972 has 366 days (leap year)
+     * 1973 has 365 days
+     */
+
+    if (rem >= 365) {                                /* 1971, etc. */
+        tmp++;
+        rem -= 365;
+        if (rem >= 365) {                        /* 1972, etc. */
+            tmp++;
+            rem -= 365;
+            if (rem >= 366) {                        /* 1973, etc. */
+                tmp++;
+                rem -= 366;
+            } else {
+                isLeap = 1;
+            }
+        }
+    }
+
+    gmt->tm_year = tmp;
+    gmt->tm_yday = rem;
+
+    /* Compute the month and day of month. */
+
+    for (tmp = 1; lastDayOfMonth[isLeap][tmp] < gmt->tm_yday; tmp++) {
+    }
+    gmt->tm_month = --tmp;
+    gmt->tm_mday = gmt->tm_yday - lastDayOfMonth[isLeap][tmp];
+
+    gmt->tm_params.tp_gmt_offset = 0;
+    gmt->tm_params.tp_dst_offset = 0;
+}
+
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * PR_ExplodeTime --
+ *
+ *     Cf. struct tm *gmtime(const time_t *tp) and
+ *         struct tm *localtime(const time_t *tp)
+ *
+ *------------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(void)
+PR_ExplodeTime(
+        PRTime usecs,
+        PRTimeParamFn params,
+        PRExplodedTime *exploded)
+{
+    ComputeGMT(usecs, exploded);
+    exploded->tm_params = params(exploded);
+    ApplySecOffset(exploded, exploded->tm_params.tp_gmt_offset
+            + exploded->tm_params.tp_dst_offset);
+}
+
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * PR_ImplodeTime --
+ *
+ *     Cf. time_t mktime(struct tm *tp)
+ *     Note that 1 year has < 2^25 seconds.  So an PRInt32 is large enough.
+ *
+ *------------------------------------------------------------------------
+ */
+#if defined(HAVE_WATCOM_BUG_2)
+PRTime __pascal __export __loadds
+#else
+PR_IMPLEMENT(PRTime)
+#endif
+PR_ImplodeTime(const PRExplodedTime *exploded)
+{
+    PRExplodedTime copy;
+    PRTime retVal;
+    PRInt64 secPerDay, usecPerSec;
+    PRInt64 temp;
+    PRInt64 numSecs64;
+    PRInt32 numDays;
+    PRInt32 numSecs;
+
+    /* Normalize first.  Do this on our copy */
+    copy = *exploded;
+    PR_NormalizeTime(&copy, PR_GMTParameters);
+
+    numDays = DAYS_BETWEEN_YEARS(1970, copy.tm_year);
+    
+    numSecs = copy.tm_yday * 86400 + copy.tm_hour * 3600
+            + copy.tm_min * 60 + copy.tm_sec;
+
+    LL_I2L(temp, numDays);
+    LL_I2L(secPerDay, 86400);
+    LL_MUL(temp, temp, secPerDay);
+    LL_I2L(numSecs64, numSecs);
+    LL_ADD(numSecs64, numSecs64, temp);
+
+    /* apply the GMT and DST offsets */
+    LL_I2L(temp,  copy.tm_params.tp_gmt_offset);
+    LL_SUB(numSecs64, numSecs64, temp);
+    LL_I2L(temp,  copy.tm_params.tp_dst_offset);
+    LL_SUB(numSecs64, numSecs64, temp);
+
+    LL_I2L(usecPerSec, 1000000L);
+    LL_MUL(temp, numSecs64, usecPerSec);
+    LL_I2L(retVal, copy.tm_usec);
+    LL_ADD(retVal, retVal, temp);
+
+    return retVal;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * IsLeapYear --
+ *
+ *     Returns 1 if the year is a leap year, 0 otherwise.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int IsLeapYear(PRInt16 year)
+{
+    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
+        return 1;
+    else
+        return 0;
+}
+
+/*
+ * 'secOffset' should be less than 86400 (i.e., a day).
+ * 'time' should point to a normalized PRExplodedTime.
+ */
+
+static void
+ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset)
+{
+    time->tm_sec += secOffset;
+
+    /* Note that in this implementation we do not count leap seconds */
+    if (time->tm_sec < 0 || time->tm_sec >= 60) {
+        time->tm_min += time->tm_sec / 60;
+        time->tm_sec %= 60;
+        if (time->tm_sec < 0) {
+            time->tm_sec += 60;
+            time->tm_min--;
+        }
+    }
+
+    if (time->tm_min < 0 || time->tm_min >= 60) {
+        time->tm_hour += time->tm_min / 60;
+        time->tm_min %= 60;
+        if (time->tm_min < 0) {
+            time->tm_min += 60;
+            time->tm_hour--;
+        }
+    }
+
+    if (time->tm_hour < 0) {
+        /* Decrement mday, yday, and wday */
+        time->tm_hour += 24;
+        time->tm_mday--;
+        time->tm_yday--;
+        if (time->tm_mday < 1) {
+            time->tm_month--;
+            if (time->tm_month < 0) {
+                time->tm_month = 11;
+                time->tm_year--;
+                if (IsLeapYear(time->tm_year))
+                    time->tm_yday = 365;
+                else
+                    time->tm_yday = 364;
+            }
+            time->tm_mday = nDays[IsLeapYear(time->tm_year)][time->tm_month];
+        }
+        time->tm_wday--;
+        if (time->tm_wday < 0)
+            time->tm_wday = 6;
+    } else if (time->tm_hour > 23) {
+        /* Increment mday, yday, and wday */
+        time->tm_hour -= 24;
+        time->tm_mday++;
+        time->tm_yday++;
+        if (time->tm_mday >
+                nDays[IsLeapYear(time->tm_year)][time->tm_month]) {
+            time->tm_mday = 1;
+            time->tm_month++;
+            if (time->tm_month > 11) {
+                time->tm_month = 0;
+                time->tm_year++;
+                time->tm_yday = 0;
+            }
+        }
+        time->tm_wday++;
+        if (time->tm_wday > 6)
+            time->tm_wday = 0;
+    }
+}
+
+PR_IMPLEMENT(void)
+PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params)
+{
+    int daysInMonth;
+    PRInt32 numDays;
+
+    /* Get back to GMT */
+    time->tm_sec -= time->tm_params.tp_gmt_offset
+            + time->tm_params.tp_dst_offset;
+    time->tm_params.tp_gmt_offset = 0;
+    time->tm_params.tp_dst_offset = 0;
+
+    /* Now normalize GMT */
+
+    if (time->tm_usec < 0 || time->tm_usec >= 1000000) {
+        time->tm_sec +=  time->tm_usec / 1000000;
+        time->tm_usec %= 1000000;
+        if (time->tm_usec < 0) {
+            time->tm_usec += 1000000;
+            time->tm_sec--;
+        }
+    }
+
+    /* Note that we do not count leap seconds in this implementation */
+    if (time->tm_sec < 0 || time->tm_sec >= 60) {
+        time->tm_min += time->tm_sec / 60;
+        time->tm_sec %= 60;
+        if (time->tm_sec < 0) {
+            time->tm_sec += 60;
+            time->tm_min--;
+        }
+    }
+
+    if (time->tm_min < 0 || time->tm_min >= 60) {
+        time->tm_hour += time->tm_min / 60;
+        time->tm_min %= 60;
+        if (time->tm_min < 0) {
+            time->tm_min += 60;
+            time->tm_hour--;
+        }
+    }
+
+    if (time->tm_hour < 0 || time->tm_hour >= 24) {
+        time->tm_mday += time->tm_hour / 24;
+        time->tm_hour %= 24;
+        if (time->tm_hour < 0) {
+            time->tm_hour += 24;
+            time->tm_mday--;
+        }
+    }
+
+    /* Normalize month and year before mday */
+    if (time->tm_month < 0 || time->tm_month >= 12) {
+        time->tm_year += time->tm_month / 12;
+        time->tm_month %= 12;
+        if (time->tm_month < 0) {
+            time->tm_month += 12;
+            time->tm_year--;
+        }
+    }
+
+    /* Now that month and year are in proper range, normalize mday */
+
+    if (time->tm_mday < 1) {
+        /* mday too small */
+        do {
+            /* the previous month */
+            time->tm_month--;
+            if (time->tm_month < 0) {
+                time->tm_month = 11;
+                time->tm_year--;
+            }
+            time->tm_mday += nDays[IsLeapYear(time->tm_year)][time->tm_month];
+        } while (time->tm_mday < 1);
+    } else {
+        daysInMonth = nDays[IsLeapYear(time->tm_year)][time->tm_month];
+        while (time->tm_mday > daysInMonth) {
+            /* mday too large */
+            time->tm_mday -= daysInMonth;
+            time->tm_month++;
+            if (time->tm_month > 11) {
+                time->tm_month = 0;
+                time->tm_year++;
+            }
+            daysInMonth = nDays[IsLeapYear(time->tm_year)][time->tm_month];
+        }
+    }
+
+    /* Recompute yday and wday */
+    time->tm_yday = time->tm_mday +
+            lastDayOfMonth[IsLeapYear(time->tm_year)][time->tm_month];
+	    
+    numDays = DAYS_BETWEEN_YEARS(1970, time->tm_year) + time->tm_yday;
+    time->tm_wday = (numDays + 4) % 7;
+    if (time->tm_wday < 0) {
+        time->tm_wday += 7;
+    }
+
+    /* Recompute time parameters */
+
+    time->tm_params = params(time);
+
+    ApplySecOffset(time, time->tm_params.tp_gmt_offset
+            + time->tm_params.tp_dst_offset);
+}
+
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * PR_LocalTimeParameters --
+ * 
+ *     returns the time parameters for the local time zone
+ *
+ *     The following uses localtime() from the standard C library.
+ *     (time.h)  This is our fallback implementation.  Unix and PC
+ *     use this version.  Mac has its own machine-dependent
+ *     implementation of this function.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include <time.h>
+
+#if defined(HAVE_INT_LOCALTIME_R)
+
+/*
+ * In this case we could define the macro as
+ *     #define MT_safe_localtime(timer, result) \
+ *             (localtime_r(timer, result) == 0 ? result : NULL)
+ * I chose to compare the return value of localtime_r with -1 so 
+ * that I can catch the cases where localtime_r returns a pointer
+ * to struct tm.  The macro definition above would not be able to
+ * detect such mistakes because it is legal to compare a pointer
+ * with 0.
+ */
+
+#define MT_safe_localtime(timer, result) \
+        (localtime_r(timer, result) == -1 ? NULL: result)
+
+#elif defined(HAVE_POINTER_LOCALTIME_R)
+
+#define MT_safe_localtime localtime_r
+
+#else
+
+#if defined(XP_MAC)
+extern struct tm *Maclocaltime(const time_t * t);
+#endif
+
+static PRLock *monitor = NULL;
+
+static struct tm *MT_safe_localtime(const time_t *clock, struct tm *result)
+{
+    struct tm *tmPtr;
+    int needLock = PR_Initialized();  /* We need to use a lock to protect
+                                       * against NSPR threads only when the
+                                       * NSPR thread system is activated. */
+
+    if (needLock) {
+        if (monitor == NULL) {
+            monitor = PR_NewLock();
+        }
+        PR_Lock(monitor);
+    }
+
+    /*
+     * Microsoft (all flavors) localtime() returns a NULL pointer if 'clock'
+     * represents a time before midnight January 1, 1970.  In
+     * that case, we also return a NULL pointer and the struct tm
+     * object pointed to by 'result' is not modified.
+     *
+     * Watcom C/C++ 11.0 localtime() treats time_t as unsigned long
+     * hence, does not recognize negative values of clock as pre-1/1/70.
+     * We have to manually check (WIN16 only) for negative value of
+     * clock and return NULL.
+     *
+     * With negative values of clock, emx returns the struct tm for
+     * clock plus ULONG_MAX. So we also have to check for the invalid
+     * structs returned for timezones west of Greenwich when clock == 0.
+     */
+    
+#if defined(XP_MAC)
+    tmPtr = Maclocaltime(clock);
+#else
+    tmPtr = localtime(clock);
+#endif
+
+#if defined(WIN16) || defined(XP_OS2_EMX)
+    if ( (PRInt32) *clock < 0 ||
+         ( (PRInt32) *clock == 0 && tmPtr->tm_year != 70))
+        result = NULL;
+    else
+        *result = *tmPtr;
+#else
+    if (tmPtr) {
+        *result = *tmPtr;
+    } else {
+        result = NULL;
+    }
+#endif /* WIN16 */
+
+    if (needLock) PR_Unlock(monitor);
+
+    return result;
+}
+
+#endif  /* definition of MT_safe_localtime() */
+
+#if defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS)
+
+PR_IMPLEMENT(PRTimeParameters)
+PR_LocalTimeParameters(const PRExplodedTime *gmt)
+{
+
+    PRTimeParameters retVal;
+    struct tm localTime;
+    time_t secs;
+    PRTime secs64;
+    PRInt64 usecPerSec;
+    PRInt64 usecPerSec_1;
+    PRInt64 maxInt32;
+    PRInt64 minInt32;
+    PRInt32 dayOffset;
+    PRInt32 offset2Jan1970;
+    PRInt32 offsetNew;
+    int isdst2Jan1970;
+
+    /*
+     * Calculate the GMT offset.  First, figure out what is
+     * 00:00:00 Jan. 2, 1970 GMT (which is exactly a day, or 86400
+     * seconds, since the epoch) in local time.  Then we calculate
+     * the difference between local time and GMT in seconds:
+     *     gmt_offset = local_time - GMT
+     *
+     * Caveat: the validity of this calculation depends on two
+     * assumptions:
+     * 1. Daylight saving time was not in effect on Jan. 2, 1970.
+     * 2. The time zone of the geographic location has not changed
+     *    since Jan. 2, 1970.
+     */
+
+    secs = 86400L;
+    (void) MT_safe_localtime(&secs, &localTime);
+
+    /* GMT is 00:00:00, 2nd of Jan. */
+
+    offset2Jan1970 = (PRInt32)localTime.tm_sec 
+            + 60L * (PRInt32)localTime.tm_min
+            + 3600L * (PRInt32)localTime.tm_hour
+            + 86400L * (PRInt32)((PRInt32)localTime.tm_mday - 2L);
+
+    isdst2Jan1970 = localTime.tm_isdst;
+
+    /*
+     * Now compute DST offset.  We calculate the overall offset
+     * of local time from GMT, similar to above.  The overall
+     * offset has two components: gmt offset and dst offset.
+     * We subtract gmt offset from the overall offset to get
+     * the dst offset.
+     *     overall_offset = local_time - GMT
+     *     overall_offset = gmt_offset + dst_offset
+     * ==> dst_offset = local_time - GMT - gmt_offset
+     */
+
+    secs64 = PR_ImplodeTime(gmt);    /* This is still in microseconds */
+    LL_I2L(usecPerSec, PR_USEC_PER_SEC);
+    LL_I2L(usecPerSec_1, PR_USEC_PER_SEC - 1);
+    /* Convert to seconds, truncating down (3.1 -> 3 and -3.1 -> -4) */
+    if (LL_GE_ZERO(secs64)) {
+        LL_DIV(secs64, secs64, usecPerSec);
+    } else {
+        LL_NEG(secs64, secs64);
+        LL_ADD(secs64, secs64, usecPerSec_1);
+        LL_DIV(secs64, secs64, usecPerSec);
+        LL_NEG(secs64, secs64);
+    }
+    LL_I2L(maxInt32, PR_INT32_MAX);
+    LL_I2L(minInt32, PR_INT32_MIN);
+    if (LL_CMP(secs64, >, maxInt32) || LL_CMP(secs64, <, minInt32)) {
+        /* secs64 is too large or too small for time_t (32-bit integer) */
+        retVal.tp_gmt_offset = offset2Jan1970;
+        retVal.tp_dst_offset = 0;
+        return retVal;
+    }
+    LL_L2I(secs, secs64);
+
+    /*
+     * On Windows, localtime() (and our MT_safe_localtime() too)
+     * returns a NULL pointer for time before midnight January 1,
+     * 1970 GMT.  In that case, we just use the GMT offset for
+     * Jan 2, 1970 and assume that DST was not in effect.
+     */
+
+    if (MT_safe_localtime(&secs, &localTime) == NULL) {
+        retVal.tp_gmt_offset = offset2Jan1970;
+        retVal.tp_dst_offset = 0;
+        return retVal;
+    }
+
+    /*
+     * dayOffset is the offset between local time and GMT in 
+     * the day component, which can only be -1, 0, or 1.  We
+     * use the day of the week to compute dayOffset.
+     */
+
+    dayOffset = (PRInt32) localTime.tm_wday - gmt->tm_wday;
+
+    /*
+     * Need to adjust for wrapping around of day of the week from
+     * 6 back to 0.
+     */
+
+    if (dayOffset == -6) {
+        /* Local time is Sunday (0) and GMT is Saturday (6) */
+        dayOffset = 1;
+    } else if (dayOffset == 6) {
+        /* Local time is Saturday (6) and GMT is Sunday (0) */
+        dayOffset = -1;
+    }
+
+    offsetNew = (PRInt32)localTime.tm_sec - gmt->tm_sec
+            + 60L * ((PRInt32)localTime.tm_min - gmt->tm_min)
+            + 3600L * ((PRInt32)localTime.tm_hour - gmt->tm_hour)
+            + 86400L * (PRInt32)dayOffset;
+
+    if (localTime.tm_isdst <= 0) {
+        /* DST is not in effect */
+        retVal.tp_gmt_offset = offsetNew;
+        retVal.tp_dst_offset = 0;
+    } else {
+        /* DST is in effect */
+        if (isdst2Jan1970 <=0) {
+            /*
+             * DST was not in effect back in 2 Jan. 1970.
+             * Use the offset back then as the GMT offset,
+             * assuming the time zone has not changed since then.
+             */
+            retVal.tp_gmt_offset = offset2Jan1970;
+            retVal.tp_dst_offset = offsetNew - offset2Jan1970;
+        } else {
+            /*
+             * DST was also in effect back in 2 Jan. 1970.
+             * Then our clever trick (or rather, ugly hack) fails.
+             * We will just assume DST offset is an hour.
+             */
+            retVal.tp_gmt_offset = offsetNew - 3600;
+            retVal.tp_dst_offset = 3600;
+        }
+    }
+    
+    return retVal;
+}
+
+#endif    /* defined(XP_UNIX) !! defined(XP_PC) */
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * PR_USPacificTimeParameters --
+ *
+ *     The time parameters function for the US Pacific Time Zone.
+ *
+ *------------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRTimeParameters)
+PR_USPacificTimeParameters(const PRExplodedTime *gmt)
+{
+    PRTimeParameters retVal;
+    PRExplodedTime st;
+
+    /*
+     * Based on geographic location and GMT, figure out offset of
+     * standard time from GMT.  In this example implementation, we
+     * assume the local time zone is US Pacific Time.
+     */
+
+    retVal.tp_gmt_offset = -8L * 3600L;
+
+    /*
+     * Make a copy of GMT.  Note that the tm_params field of this copy
+     * is ignored.
+     */
+
+    st.tm_usec = gmt->tm_usec;
+    st.tm_sec = gmt->tm_sec;
+    st.tm_min = gmt->tm_min;
+    st.tm_hour = gmt->tm_hour;
+    st.tm_mday = gmt->tm_mday;
+    st.tm_month = gmt->tm_month;
+    st.tm_year = gmt->tm_year;
+    st.tm_wday = gmt->tm_wday;
+    st.tm_yday = gmt->tm_yday;
+
+    /* Apply the offset to GMT to obtain the local standard time */
+    ApplySecOffset(&st, retVal.tp_gmt_offset);
+
+    /*
+     * Apply the rules on standard time or GMT to obtain daylight saving
+     * time offset.  In this implementation, we use the US DST rule.
+     */
+    if (st.tm_month < 3) {
+        retVal.tp_dst_offset = 0L;
+    } else if (st.tm_month == 3) {
+        if (st.tm_wday == 0) {
+            /* A Sunday */
+            if (st.tm_mday <= 7) {
+                /* First Sunday */
+                /* 01:59:59 PST -> 03:00:00 PDT */
+                if (st.tm_hour < 2) {
+                    retVal.tp_dst_offset = 0L;
+                } else {
+                    retVal.tp_dst_offset = 3600L;
+                }
+            } else {
+                /* Not first Sunday */
+                retVal.tp_dst_offset = 3600L;
+            }
+        } else {
+            /* Not a Sunday.  See if before first Sunday or after */
+            if (st.tm_wday + 1 <= st.tm_mday) {
+                /* After first Sunday */
+                retVal.tp_dst_offset = 3600L;
+            } else {
+                /* Before first Sunday */
+                retVal.tp_dst_offset = 0L;
+            } 
+        }
+    } else if (st.tm_month < 9) {
+        retVal.tp_dst_offset = 3600L;
+    } else if (st.tm_month == 9) {
+        if (st.tm_wday == 0) {
+            if (31 - st.tm_mday < 7) {
+                /* Last Sunday */
+                /* 01:59:59 PDT -> 01:00:00 PST */
+                if (st.tm_hour < 1) {
+                    retVal.tp_dst_offset = 3600L;
+                } else {
+                    retVal.tp_dst_offset = 0L;
+                }
+            } else {
+                /* Not last Sunday */
+                retVal.tp_dst_offset = 3600L;
+            }
+        } else {
+            /* See if before or after last Sunday */
+            if (7 - st.tm_wday <= 31 - st.tm_mday) {
+                /* before last Sunday */
+                retVal.tp_dst_offset = 3600L;
+            } else {
+                retVal.tp_dst_offset = 0L;
+            }
+        }
+    } else {
+        retVal.tp_dst_offset = 0L;
+    }
+    return retVal;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * PR_GMTParameters --
+ *
+ *     Returns the PRTimeParameters for Greenwich Mean Time.
+ *     Trivially, both the tp_gmt_offset and tp_dst_offset fields are 0.
+ *
+ *------------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRTimeParameters)
+PR_GMTParameters(const PRExplodedTime *gmt)
+{
+#if defined(XP_MAC)
+#pragma unused (gmt)
+#endif
+
+    PRTimeParameters retVal = { 0, 0 };
+    return retVal;
+}
+
+/*
+ * The following code implements PR_ParseTimeString().  It is based on
+ * ns/lib/xp/xp_time.c, revision 1.25, by Jamie Zawinski <jwz at netscape.com>.
+ */
+
+/*
+ * We only recognize the abbreviations of a small subset of time zones
+ * in North America, Europe, and Japan.
+ *
+ * PST/PDT: Pacific Standard/Daylight Time
+ * MST/MDT: Mountain Standard/Daylight Time
+ * CST/CDT: Central Standard/Daylight Time
+ * EST/EDT: Eastern Standard/Daylight Time
+ * AST: Atlantic Standard Time
+ * NST: Newfoundland Standard Time
+ * GMT: Greenwich Mean Time
+ * BST: British Summer Time
+ * MET: Middle Europe Time
+ * EET: Eastern Europe Time
+ * JST: Japan Standard Time
+ */
+
+typedef enum
+{
+  TT_UNKNOWN,
+
+  TT_SUN, TT_MON, TT_TUE, TT_WED, TT_THU, TT_FRI, TT_SAT,
+
+  TT_JAN, TT_FEB, TT_MAR, TT_APR, TT_MAY, TT_JUN,
+  TT_JUL, TT_AUG, TT_SEP, TT_OCT, TT_NOV, TT_DEC,
+
+  TT_PST, TT_PDT, TT_MST, TT_MDT, TT_CST, TT_CDT, TT_EST, TT_EDT,
+  TT_AST, TT_NST, TT_GMT, TT_BST, TT_MET, TT_EET, TT_JST
+} TIME_TOKEN;
+
+/*
+ * This parses a time/date string into a PRTime
+ * (microseconds after "1-Jan-1970 00:00:00 GMT").
+ * It returns PR_SUCCESS on success, and PR_FAILURE
+ * if the time/date string can't be parsed.
+ *
+ * Many formats are handled, including:
+ *
+ *   14 Apr 89 03:20:12
+ *   14 Apr 89 03:20 GMT
+ *   Fri, 17 Mar 89 4:01:33
+ *   Fri, 17 Mar 89 4:01 GMT
+ *   Mon Jan 16 16:12 PDT 1989
+ *   Mon Jan 16 16:12 +0130 1989
+ *   6 May 1992 16:41-JST (Wednesday)
+ *   22-AUG-1993 10:59:12.82
+ *   22-AUG-1993 10:59pm
+ *   22-AUG-1993 12:59am
+ *   22-AUG-1993 12:59 PM
+ *   Friday, August 04, 1995 3:54 PM
+ *   06/21/95 04:24:34 PM
+ *   20/06/95 21:07
+ *   95-06-08 19:32:48 EDT
+ *
+ * If the input string doesn't contain a description of the timezone,
+ * we consult the `default_to_gmt' to decide whether the string should
+ * be interpreted relative to the local time zone (PR_FALSE) or GMT (PR_TRUE).
+ * The correct value for this argument depends on what standard specified
+ * the time string which you are parsing.
+ */
+
+PR_IMPLEMENT(PRStatus)
+PR_ParseTimeString(
+        const char *string,
+        PRBool default_to_gmt,
+        PRTime *result)
+{
+  PRExplodedTime tm;
+  TIME_TOKEN dotw = TT_UNKNOWN;
+  TIME_TOKEN month = TT_UNKNOWN;
+  TIME_TOKEN zone = TT_UNKNOWN;
+  int zone_offset = -1;
+  int date = -1;
+  PRInt32 year = -1;
+  int hour = -1;
+  int min = -1;
+  int sec = -1;
+
+  const char *rest = string;
+
+#ifdef DEBUG
+  int iterations = 0;
+#endif
+
+  PR_ASSERT(string && result);
+  if (!string || !result) return PR_FAILURE;
+
+  while (*rest)
+        {
+
+#ifdef DEBUG
+          if (iterations++ > 1000)
+                {
+                  PR_ASSERT(0);
+                  return PR_FAILURE;
+                }
+#endif
+
+          switch (*rest)
+                {
+                case 'a': case 'A':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'p' || rest[1] == 'P') &&
+                          (rest[2] == 'r' || rest[2] == 'R'))
+                        month = TT_APR;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 's') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_AST;
+                  else if (month == TT_UNKNOWN &&
+                                   (rest[1] == 'u' || rest[1] == 'U') &&
+                                   (rest[2] == 'g' || rest[2] == 'G'))
+                        month = TT_AUG;
+                  break;
+                case 'b': case 'B':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 's' || rest[1] == 'S') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_BST;
+                  break;
+                case 'c': case 'C':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 'd' || rest[1] == 'D') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_CDT;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_CST;
+                  break;
+                case 'd': case 'D':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'e' || rest[1] == 'E') &&
+                          (rest[2] == 'c' || rest[2] == 'C'))
+                        month = TT_DEC;
+                  break;
+                case 'e': case 'E':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 'd' || rest[1] == 'D') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_EDT;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 'e' || rest[1] == 'E') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_EET;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_EST;
+                  break;
+                case 'f': case 'F':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'e' || rest[1] == 'E') &&
+                          (rest[2] == 'b' || rest[2] == 'B'))
+                        month = TT_FEB;
+                  else if (dotw == TT_UNKNOWN &&
+                                   (rest[1] == 'r' || rest[1] == 'R') &&
+                                   (rest[2] == 'i' || rest[2] == 'I'))
+                        dotw = TT_FRI;
+                  break;
+                case 'g': case 'G':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 'm' || rest[1] == 'M') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_GMT;
+                  break;
+                case 'j': case 'J':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'a' || rest[1] == 'A') &&
+                          (rest[2] == 'n' || rest[2] == 'N'))
+                        month = TT_JAN;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_JST;
+                  else if (month == TT_UNKNOWN &&
+                                   (rest[1] == 'u' || rest[1] == 'U') &&
+                                   (rest[2] == 'l' || rest[2] == 'L'))
+                        month = TT_JUL;
+                  else if (month == TT_UNKNOWN &&
+                                   (rest[1] == 'u' || rest[1] == 'U') &&
+                                   (rest[2] == 'n' || rest[2] == 'N'))
+                        month = TT_JUN;
+                  break;
+                case 'm': case 'M':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'a' || rest[1] == 'A') &&
+                          (rest[2] == 'r' || rest[2] == 'R'))
+                        month = TT_MAR;
+                  else if (month == TT_UNKNOWN &&
+                                   (rest[1] == 'a' || rest[1] == 'A') &&
+                                   (rest[2] == 'y' || rest[2] == 'Y'))
+                        month = TT_MAY;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 'd' || rest[1] == 'D') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_MDT;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 'e' || rest[1] == 'E') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_MET;
+                  else if (dotw == TT_UNKNOWN &&
+                                   (rest[1] == 'o' || rest[1] == 'O') &&
+                                   (rest[2] == 'n' || rest[2] == 'N'))
+                        dotw = TT_MON;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_MST;
+                  break;
+                case 'n': case 'N':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'o' || rest[1] == 'O') &&
+                          (rest[2] == 'v' || rest[2] == 'V'))
+                        month = TT_NOV;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_NST;
+                  break;
+                case 'o': case 'O':
+                  if (month == TT_UNKNOWN &&
+                          (rest[1] == 'c' || rest[1] == 'C') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        month = TT_OCT;
+                  break;
+                case 'p': case 'P':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 'd' || rest[1] == 'D') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_PDT;
+                  else if (zone == TT_UNKNOWN &&
+                                   (rest[1] == 's' || rest[1] == 'S') &&
+                                   (rest[2] == 't' || rest[2] == 'T'))
+                        zone = TT_PST;
+                  break;
+                case 's': case 'S':
+                  if (dotw == TT_UNKNOWN &&
+                          (rest[1] == 'a' || rest[1] == 'A') &&
+                          (rest[2] == 't' || rest[2] == 'T'))
+                        dotw = TT_SAT;
+                  else if (month == TT_UNKNOWN &&
+                                   (rest[1] == 'e' || rest[1] == 'E') &&
+                                   (rest[2] == 'p' || rest[2] == 'P'))
+                        month = TT_SEP;
+                  else if (dotw == TT_UNKNOWN &&
+                                   (rest[1] == 'u' || rest[1] == 'U') &&
+                                   (rest[2] == 'n' || rest[2] == 'N'))
+                        dotw = TT_SUN;
+                  break;
+                case 't': case 'T':
+                  if (dotw == TT_UNKNOWN &&
+                          (rest[1] == 'h' || rest[1] == 'H') &&
+                          (rest[2] == 'u' || rest[2] == 'U'))
+                        dotw = TT_THU;
+                  else if (dotw == TT_UNKNOWN &&
+                                   (rest[1] == 'u' || rest[1] == 'U') &&
+                                   (rest[2] == 'e' || rest[2] == 'E'))
+                        dotw = TT_TUE;
+                  break;
+                case 'u': case 'U':
+                  if (zone == TT_UNKNOWN &&
+                          (rest[1] == 't' || rest[1] == 'T') &&
+                          !(rest[2] >= 'A' && rest[2] <= 'Z') &&
+                          !(rest[2] >= 'a' && rest[2] <= 'z'))
+                        /* UT is the same as GMT but UTx is not. */
+                        zone = TT_GMT;
+                  break;
+                case 'w': case 'W':
+                  if (dotw == TT_UNKNOWN &&
+                          (rest[1] == 'e' || rest[1] == 'E') &&
+                          (rest[2] == 'd' || rest[2] == 'D'))
+                        dotw = TT_WED;
+                  break;
+
+                case '+': case '-':
+                  {
+                        const char *end;
+                        int sign;
+                        if (zone_offset != -1)
+                          {
+                                /* already got one... */
+                                rest++;
+                                break;
+                          }
+                        if (zone != TT_UNKNOWN && zone != TT_GMT)
+                          {
+                                /* GMT+0300 is legal, but PST+0300 is not. */
+                                rest++;
+                                break;
+                          }
+
+                        sign = ((*rest == '+') ? 1 : -1);
+                        rest++; /* move over sign */
+                        end = rest;
+                        while (*end >= '0' && *end <= '9')
+                          end++;
+                        if (rest == end) /* no digits here */
+                          break;
+
+                        if ((end - rest) == 4)
+                          /* offset in HHMM */
+                          zone_offset = (((((rest[0]-'0')*10) + (rest[1]-'0')) * 60) +
+                                                         (((rest[2]-'0')*10) + (rest[3]-'0')));
+                        else if ((end - rest) == 2)
+                          /* offset in hours */
+                          zone_offset = (((rest[0]-'0')*10) + (rest[1]-'0')) * 60;
+                        else if ((end - rest) == 1)
+                          /* offset in hours */
+                          zone_offset = (rest[0]-'0') * 60;
+                        else
+                          /* 3 or >4 */
+                          break;
+
+                        zone_offset *= sign;
+                        zone = TT_GMT;
+                        break;
+                  }
+
+                case '0': case '1': case '2': case '3': case '4':
+                case '5': case '6': case '7': case '8': case '9':
+                  {
+                        int tmp_hour = -1;
+                        int tmp_min = -1;
+                        int tmp_sec = -1;
+                        const char *end = rest + 1;
+                        while (*end >= '0' && *end <= '9')
+                          end++;
+
+                        /* end is now the first character after a range of digits. */
+
+                        if (*end == ':')
+                          {
+                                if (hour >= 0 && min >= 0) /* already got it */
+                                  break;
+
+                                /* We have seen "[0-9]+:", so this is probably HH:MM[:SS] */
+                                if ((end - rest) > 2)
+                                  /* it is [0-9][0-9][0-9]+: */
+                                  break;
+                                else if ((end - rest) == 2)
+                                  tmp_hour = ((rest[0]-'0')*10 +
+                                                          (rest[1]-'0'));
+                                else
+                                  tmp_hour = (rest[0]-'0');
+
+                                while (*rest && *rest != ':')
+                                  rest++;
+                                rest++;
+
+                                /* move over the colon, and parse minutes */
+
+                                end = rest + 1;
+                                while (*end >= '0' && *end <= '9')
+                                  end++;
+
+                                if (end == rest)
+                                  /* no digits after first colon? */
+                                  break;
+                                else if ((end - rest) > 2)
+                                  /* it is [0-9][0-9][0-9]+: */
+                                  break;
+                                else if ((end - rest) == 2)
+                                  tmp_min = ((rest[0]-'0')*10 +
+                                                         (rest[1]-'0'));
+                                else
+                                  tmp_min = (rest[0]-'0');
+
+                                /* now go for seconds */
+                                rest = end;
+                                if (*rest == ':')
+                                  rest++;
+                                end = rest;
+                                while (*end >= '0' && *end <= '9')
+                                  end++;
+
+                                if (end == rest)
+                                  /* no digits after second colon - that's ok. */
+                                  ;
+                                else if ((end - rest) > 2)
+                                  /* it is [0-9][0-9][0-9]+: */
+                                  break;
+                                else if ((end - rest) == 2)
+                                  tmp_sec = ((rest[0]-'0')*10 +
+                                                         (rest[1]-'0'));
+                                else
+                                  tmp_sec = (rest[0]-'0');
+
+                                /* If we made it here, we've parsed hour and min,
+                                   and possibly sec, so it worked as a unit. */
+
+                                /* skip over whitespace and see if there's an AM or PM
+                                   directly following the time.
+                                 */
+                                if (tmp_hour <= 12)
+                                  {
+                                        const char *s = end;
+                                        while (*s && (*s == ' ' || *s == '\t'))
+                                          s++;
+                                        if ((s[0] == 'p' || s[0] == 'P') &&
+                                                (s[1] == 'm' || s[1] == 'M'))
+                                          /* 10:05pm == 22:05, and 12:05pm == 12:05 */
+                                          tmp_hour = (tmp_hour == 12 ? 12 : tmp_hour + 12);
+                                        else if (tmp_hour == 12 &&
+                                                         (s[0] == 'a' || s[0] == 'A') &&
+                                                         (s[1] == 'm' || s[1] == 'M'))
+                                          /* 12:05am == 00:05 */
+                                          tmp_hour = 0;
+                                  }
+
+                                hour = tmp_hour;
+                                min = tmp_min;
+                                sec = tmp_sec;
+                                rest = end;
+                                break;
+                          }
+                        else if ((*end == '/' || *end == '-') &&
+                                         end[1] >= '0' && end[1] <= '9')
+                          {
+                                /* Perhaps this is 6/16/95, 16/6/95, 6-16-95, or 16-6-95
+                                   or even 95-06-05...
+                                   #### But it doesn't handle 1995-06-22.
+                                 */
+                                int n1, n2, n3;
+                                const char *s;
+
+                                if (month != TT_UNKNOWN)
+                                  /* if we saw a month name, this can't be. */
+                                  break;
+
+                                s = rest;
+
+                                n1 = (*s++ - '0');                                /* first 1 or 2 digits */
+                                if (*s >= '0' && *s <= '9')
+                                  n1 = n1*10 + (*s++ - '0');
+
+                                if (*s != '/' && *s != '-')                /* slash */
+                                  break;
+                                s++;
+
+                                if (*s < '0' || *s > '9')                /* second 1 or 2 digits */
+                                  break;
+                                n2 = (*s++ - '0');
+                                if (*s >= '0' && *s <= '9')
+                                  n2 = n2*10 + (*s++ - '0');
+
+                                if (*s != '/' && *s != '-')                /* slash */
+                                  break;
+                                s++;
+
+                                if (*s < '0' || *s > '9')                /* third 1, 2, or 4 digits */
+                                  break;
+                                n3 = (*s++ - '0');
+                                if (*s >= '0' && *s <= '9')
+                                  n3 = n3*10 + (*s++ - '0');
+
+                                if (*s >= '0' && *s <= '9')                /* optional digits 3 and 4 */
+                                  {
+                                        n3 = n3*10 + (*s++ - '0');
+                                        if (*s < '0' || *s > '9')
+                                          break;
+                                        n3 = n3*10 + (*s++ - '0');
+                                  }
+
+                                if ((*s >= '0' && *s <= '9') ||        /* followed by non-alphanum */
+                                        (*s >= 'A' && *s <= 'Z') ||
+                                        (*s >= 'a' && *s <= 'z'))
+                                  break;
+
+                                /* Ok, we parsed three 1-2 digit numbers, with / or -
+                                   between them.  Now decide what the hell they are
+                                   (DD/MM/YY or MM/DD/YY or YY/MM/DD.)
+                                 */
+
+                                if (n1 > 31 || n1 == 0)  /* must be YY/MM/DD */
+                                  {
+                                        if (n2 > 12) break;
+                                        if (n3 > 31) break;
+                                        year = n1;
+                                        if (year < 70)
+                                            year += 2000;
+                                        else if (year < 100)
+                                            year += 1900;
+                                        month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1);
+                                        date = n3;
+                                        rest = s;
+                                        break;
+                                  }
+
+                                if (n1 > 12 && n2 > 12)  /* illegal */
+                                  {
+                                        rest = s;
+                                        break;
+                                  }
+
+                                if (n3 < 70)
+                                    n3 += 2000;
+                                else if (n3 < 100)
+                                    n3 += 1900;
+
+                                if (n1 > 12)  /* must be DD/MM/YY */
+                                  {
+                                        date = n1;
+                                        month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1);
+                                        year = n3;
+                                  }
+                                else                  /* assume MM/DD/YY */
+                                  {
+                                        /* #### In the ambiguous case, should we consult the
+                                           locale to find out the local default? */
+                                        month = (TIME_TOKEN)(n1 + ((int)TT_JAN) - 1);
+                                        date = n2;
+                                        year = n3;
+                                  }
+                                rest = s;
+                          }
+                        else if ((*end >= 'A' && *end <= 'Z') ||
+                                         (*end >= 'a' && *end <= 'z'))
+                          /* Digits followed by non-punctuation - what's that? */
+                          ;
+                        else if ((end - rest) == 4)                /* four digits is a year */
+                          year = (year < 0
+                                          ? ((rest[0]-'0')*1000L +
+                                                 (rest[1]-'0')*100L +
+                                                 (rest[2]-'0')*10L +
+                                                 (rest[3]-'0'))
+                                          : year);
+                        else if ((end - rest) == 2)                /* two digits - date or year */
+                          {
+                                int n = ((rest[0]-'0')*10 +
+                                                 (rest[1]-'0'));
+                                /* If we don't have a date (day of the month) and we see a number
+                                     less than 32, then assume that is the date.
+
+                                         Otherwise, if we have a date and not a year, assume this is the
+                                         year.  If it is less than 70, then assume it refers to the 21st
+                                         century.  If it is two digits (>= 70), assume it refers to this
+                                         century.  Otherwise, assume it refers to an unambiguous year.
+
+                                         The world will surely end soon.
+                                   */
+                                if (date < 0 && n < 32)
+                                  date = n;
+                                else if (year < 0)
+                                  {
+                                        if (n < 70)
+                                          year = 2000 + n;
+                                        else if (n < 100)
+                                          year = 1900 + n;
+                                        else
+                                          year = n;
+                                  }
+                                /* else what the hell is this. */
+                          }
+                        else if ((end - rest) == 1)                /* one digit - date */
+                          date = (date < 0 ? (rest[0]-'0') : date);
+                        /* else, three or more than four digits - what's that? */
+
+                        break;
+                  }
+                }
+
+          /* Skip to the end of this token, whether we parsed it or not.
+                 Tokens are delimited by whitespace, or ,;-/
+                 But explicitly not :+-.
+           */
+          while (*rest &&
+                         *rest != ' ' && *rest != '\t' &&
+                         *rest != ',' && *rest != ';' &&
+                         *rest != '-' && *rest != '+' &&
+                         *rest != '/' &&
+                         *rest != '(' && *rest != ')' && *rest != '[' && *rest != ']')
+                rest++;
+          /* skip over uninteresting chars. */
+        SKIP_MORE:
+          while (*rest &&
+                         (*rest == ' ' || *rest == '\t' ||
+                          *rest == ',' || *rest == ';' || *rest == '/' ||
+                          *rest == '(' || *rest == ')' || *rest == '[' || *rest == ']'))
+                rest++;
+
+          /* "-" is ignored at the beginning of a token if we have not yet
+                 parsed a year (e.g., the second "-" in "30-AUG-1966"), or if
+                 the character after the dash is not a digit. */         
+          if (*rest == '-' && ((rest > string && isalpha(rest[-1]) && year < 0)
+              || rest[1] < '0' || rest[1] > '9'))
+                {
+                  rest++;
+                  goto SKIP_MORE;
+                }
+
+        }
+
+  if (zone != TT_UNKNOWN && zone_offset == -1)
+        {
+          switch (zone)
+                {
+                case TT_PST: zone_offset = -8 * 60; break;
+                case TT_PDT: zone_offset = -7 * 60; break;
+                case TT_MST: zone_offset = -7 * 60; break;
+                case TT_MDT: zone_offset = -6 * 60; break;
+                case TT_CST: zone_offset = -6 * 60; break;
+                case TT_CDT: zone_offset = -5 * 60; break;
+                case TT_EST: zone_offset = -5 * 60; break;
+                case TT_EDT: zone_offset = -4 * 60; break;
+                case TT_AST: zone_offset = -4 * 60; break;
+                case TT_NST: zone_offset = -3 * 60 - 30; break;
+                case TT_GMT: zone_offset =  0 * 60; break;
+                case TT_BST: zone_offset =  1 * 60; break;
+                case TT_MET: zone_offset =  1 * 60; break;
+                case TT_EET: zone_offset =  2 * 60; break;
+                case TT_JST: zone_offset =  9 * 60; break;
+                default:
+                  PR_ASSERT (0);
+                  break;
+                }
+        }
+
+  /* If we didn't find a year, month, or day-of-the-month, we can't
+         possibly parse this, and in fact, mktime() will do something random
+         (I'm seeing it return "Tue Feb  5 06:28:16 2036", which is no doubt
+         a numerologically significant date... */
+  if (month == TT_UNKNOWN || date == -1 || year == -1)
+      return PR_FAILURE;
+
+  memset(&tm, 0, sizeof(tm));
+  if (sec != -1)
+        tm.tm_sec = sec;
+  if (min != -1)
+  tm.tm_min = min;
+  if (hour != -1)
+        tm.tm_hour = hour;
+  if (date != -1)
+        tm.tm_mday = date;
+  if (month != TT_UNKNOWN)
+        tm.tm_month = (((int)month) - ((int)TT_JAN));
+  if (year != -1)
+        tm.tm_year = year;
+  if (dotw != TT_UNKNOWN)
+        tm.tm_wday = (((int)dotw) - ((int)TT_SUN));
+
+  if (zone == TT_UNKNOWN && default_to_gmt)
+        {
+          /* No zone was specified, so pretend the zone was GMT. */
+          zone = TT_GMT;
+          zone_offset = 0;
+        }
+
+  if (zone_offset == -1)
+         {
+           /* no zone was specified, and we're to assume that everything
+             is local. */
+          struct tm localTime;
+          time_t secs;
+
+          PR_ASSERT(tm.tm_month > -1 
+                                   && tm.tm_mday > 0 
+                                   && tm.tm_hour > -1
+                                   && tm.tm_min > -1
+                                   && tm.tm_sec > -1);
+
+            /*
+             * To obtain time_t from a tm structure representing the local
+             * time, we call mktime().  However, we need to see if we are
+             * on 1-Jan-1970 or before.  If we are, we can't call mktime()
+             * because mktime() will crash on win16. In that case, we
+             * calculate zone_offset based on the zone offset at 
+             * 00:00:00, 2 Jan 1970 GMT, and subtract zone_offset from the
+             * date we are parsing to transform the date to GMT.  We also
+             * do so if mktime() returns (time_t) -1 (time out of range).
+           */
+
+          /* month, day, hours, mins and secs are always non-negative
+             so we dont need to worry about them. */  
+            if(tm.tm_year >= 1970)
+                {
+                  PRInt64 usec_per_sec;
+
+                  localTime.tm_sec = tm.tm_sec;
+                  localTime.tm_min = tm.tm_min;
+                  localTime.tm_hour = tm.tm_hour;
+                  localTime.tm_mday = tm.tm_mday;
+                  localTime.tm_mon = tm.tm_month;
+                  localTime.tm_year = tm.tm_year - 1900;
+                  /* Set this to -1 to tell mktime "I don't care".  If you set
+                     it to 0 or 1, you are making assertions about whether the
+                     date you are handing it is in daylight savings mode or not;
+                     and if you're wrong, it will "fix" it for you. */
+                  localTime.tm_isdst = -1;
+                  secs = mktime(&localTime);
+                  if (secs != (time_t) -1)
+                    {
+#if defined(XP_MAC) && (__MSL__ < 0x6000)
+                      /*
+                       * The mktime() routine in MetroWerks MSL C
+                       * Runtime library returns seconds since midnight,
+                       * 1 Jan. 1900, not 1970 - in versions of MSL (Metrowerks Standard
+                       * Library) prior to version 6.  Only for older versions of
+                       * MSL do we adjust the value of secs to the NSPR epoch
+                       */
+                      secs -= ((365 * 70UL) + 17) * 24 * 60 * 60;
+#endif
+                      LL_I2L(*result, secs);
+                      LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
+                      LL_MUL(*result, *result, usec_per_sec);
+                      return PR_SUCCESS;
+                    }
+                }
+                
+                /* So mktime() can't handle this case.  We assume the
+                   zone_offset for the date we are parsing is the same as
+                   the zone offset on 00:00:00 2 Jan 1970 GMT. */
+                secs = 86400;
+                (void) MT_safe_localtime(&secs, &localTime);
+                zone_offset = localTime.tm_min
+                              + 60 * localTime.tm_hour
+                              + 1440 * (localTime.tm_mday - 2);
+        }
+
+        /* Adjust the hours and minutes before handing them to
+           PR_ImplodeTime(). Note that it's ok for them to be <0 or >24/60 
+
+           We adjust the time to GMT before going into PR_ImplodeTime().
+           The zone_offset represents the difference between the time
+           zone parsed and GMT
+         */
+        tm.tm_hour -= (zone_offset / 60);
+        tm.tm_min  -= (zone_offset % 60);
+
+  *result = PR_ImplodeTime(&tm);
+
+  return PR_SUCCESS;
+}
+
+/*
+ *******************************************************************
+ *******************************************************************
+ **
+ **    OLD COMPATIBILITY FUNCTIONS
+ **
+ *******************************************************************
+ *******************************************************************
+ */
+
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * PR_FormatTime --
+ *
+ *     Format a time value into a buffer. Same semantics as strftime().
+ *
+ *-----------------------------------------------------------------------
+ */
+
+PR_IMPLEMENT(PRUint32)
+PR_FormatTime(char *buf, int buflen, const char *fmt, const PRExplodedTime *tm)
+{
+    struct tm a;
+    a.tm_sec = tm->tm_sec;
+    a.tm_min = tm->tm_min;
+    a.tm_hour = tm->tm_hour;
+    a.tm_mday = tm->tm_mday;
+    a.tm_mon = tm->tm_month;
+    a.tm_wday = tm->tm_wday;
+    a.tm_year = tm->tm_year - 1900;
+    a.tm_yday = tm->tm_yday;
+    a.tm_isdst = tm->tm_params.tp_dst_offset ? 1 : 0;
+
+/*
+ * On some platforms, for example SunOS 4, struct tm has two additional
+ * fields: tm_zone and tm_gmtoff.
+ */
+
+#if defined(SUNOS4) || (__GLIBC__ >= 2) || defined(XP_BEOS) \
+        || defined(NETBSD) || defined(OPENBSD) || defined(FREEBSD) \
+        || defined(DARWIN)
+    a.tm_zone = NULL;
+    a.tm_gmtoff = tm->tm_params.tp_gmt_offset + tm->tm_params.tp_dst_offset;
+#endif
+
+    return strftime(buf, buflen, fmt, &a);
+}
+
+
+/*
+ * The following string arrays and macros are used by PR_FormatTimeUSEnglish().
+ */
+
+static const char* abbrevDays[] =
+{
+   "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
+};
+
+static const char* days[] =
+{
+   "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
+};
+
+static const char* abbrevMonths[] =
+{
+   "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static const char* months[] =
+{ 
+    "January", "February", "March", "April", "May", "June",
+    "July", "August", "September", "October", "November", "December"
+};
+
+
+/*
+ * Add a single character to the given buffer, incrementing the buffer pointer
+ * and decrementing the buffer size. Return 0 on error.
+ */
+#define ADDCHAR( buf, bufSize, ch )             \
+do                                              \
+{                                               \
+   if( bufSize < 1 )                            \
+   {                                            \
+      *(--buf) = '\0';                          \
+      return 0;                                 \
+   }                                            \
+   *buf++ = ch;                                 \
+   bufSize--;                                   \
+}                                               \
+while(0)
+
+
+/*
+ * Add a string to the given buffer, incrementing the buffer pointer
+ * and decrementing the buffer size appropriately.  Return 0 on error.
+ */
+#define ADDSTR( buf, bufSize, str )             \
+do                                              \
+{                                               \
+   PRUint32 strSize = strlen( str );              \
+   if( strSize > bufSize )                      \
+   {                                            \
+      if( bufSize==0 )                          \
+         *(--buf) = '\0';                       \
+      else                                      \
+         *buf = '\0';                           \
+      return 0;                                 \
+   }                                            \
+   memcpy(buf, str, strSize);                   \
+   buf += strSize;                              \
+   bufSize -= strSize;                          \
+}                                               \
+while(0)
+
+/* Needed by PR_FormatTimeUSEnglish() */
+static unsigned int  pr_WeekOfYear(const PRExplodedTime* time,
+        unsigned int firstDayOfWeek);
+
+
+/***********************************************************************************
+ *
+ * Description:
+ *  This is a dumbed down version of strftime that will format the date in US
+ *  English regardless of the setting of the global locale.  This functionality is
+ *  needed to write things like MIME headers which must always be in US English.
+ *
+ **********************************************************************************/
+             
+PR_IMPLEMENT(PRUint32)
+PR_FormatTimeUSEnglish( char* buf, PRUint32 bufSize,
+                        const char* format, const PRExplodedTime* time )
+{
+   char*         bufPtr = buf;
+   const char*   fmtPtr;
+   char          tmpBuf[ 40 ];        
+   const int     tmpBufSize = sizeof( tmpBuf );
+
+   
+   for( fmtPtr=format; *fmtPtr != '\0'; fmtPtr++ )
+   {
+      if( *fmtPtr != '%' )
+      {
+         ADDCHAR( bufPtr, bufSize, *fmtPtr );
+      }
+      else
+      {
+         switch( *(++fmtPtr) )
+         {
+         case '%':
+            /* escaped '%' character */
+            ADDCHAR( bufPtr, bufSize, '%' );
+            break;
+            
+         case 'a':
+            /* abbreviated weekday name */
+            ADDSTR( bufPtr, bufSize, abbrevDays[ time->tm_wday ] );
+            break;
+               
+         case 'A':
+            /* full weekday name */
+            ADDSTR( bufPtr, bufSize, days[ time->tm_wday ] );
+            break;
+        
+         case 'b':
+            /* abbreviated month name */
+            ADDSTR( bufPtr, bufSize, abbrevMonths[ time->tm_month ] );
+            break;
+        
+         case 'B':
+            /* full month name */
+            ADDSTR(bufPtr, bufSize,  months[ time->tm_month ] );
+            break;
+        
+         case 'c':
+            /* Date and time. */
+            PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%a %b %d %H:%M:%S %Y", time );
+            ADDSTR( bufPtr, bufSize, tmpBuf );
+            break;
+        
+         case 'd':
+            /* day of month ( 01 - 31 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_mday );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+
+         case 'H':
+            /* hour ( 00 - 23 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_hour );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'I':
+            /* hour ( 01 - 12 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",
+                        (time->tm_hour%12) ? time->tm_hour%12 : (PRInt32) 12 );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'j':
+            /* day number of year ( 001 - 366 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.3d",time->tm_yday + 1);
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'm':
+            /* month number ( 01 - 12 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_month+1);
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'M':
+            /* minute ( 00 - 59 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_min );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+       
+         case 'p':
+            /* locale's equivalent of either AM or PM */
+            ADDSTR( bufPtr, bufSize, (time->tm_hour<12)?"AM":"PM" ); 
+            break;
+        
+         case 'S':
+            /* seconds ( 00 - 61 ), allows for leap seconds */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_sec );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+     
+         case 'U':
+            /* week number of year ( 00 - 53  ),  Sunday  is  the first day of week 1 */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 0 ) );
+            ADDSTR( bufPtr, bufSize, tmpBuf );
+            break;
+        
+         case 'w':
+            /* weekday number ( 0 - 6 ), Sunday = 0 */
+            PR_snprintf(tmpBuf,tmpBufSize,"%d",time->tm_wday );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'W':
+            /* Week number of year ( 00 - 53  ),  Monday  is  the first day of week 1 */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 1 ) );
+            ADDSTR( bufPtr, bufSize, tmpBuf );
+            break;
+        
+         case 'x':
+            /* Date representation */
+            PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%m/%d/%y", time );
+            ADDSTR( bufPtr, bufSize, tmpBuf );
+            break;
+        
+         case 'X':
+            /* Time representation. */
+            PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%H:%M:%S", time );
+            ADDSTR( bufPtr, bufSize, tmpBuf );
+            break;
+        
+         case 'y':
+            /* year within century ( 00 - 99 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.2d",time->tm_year % 100 );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'Y':
+            /* year as ccyy ( for example 1986 ) */
+            PR_snprintf(tmpBuf,tmpBufSize,"%.4d",time->tm_year );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+        
+         case 'Z':
+            /* Time zone name or no characters if  no  time  zone exists.
+             * Since time zone name is supposed to be independant of locale, we
+             * defer to PR_FormatTime() for this option.
+             */
+            PR_FormatTime( tmpBuf, tmpBufSize, "%Z", time );
+            ADDSTR( bufPtr, bufSize, tmpBuf ); 
+            break;
+
+         default:
+            /* Unknown format.  Simply copy format into output buffer. */
+            ADDCHAR( bufPtr, bufSize, '%' );
+            ADDCHAR( bufPtr, bufSize, *fmtPtr );
+            break;
+            
+         }
+      }
+   }
+
+   ADDCHAR( bufPtr, bufSize, '\0' );
+   return (PRUint32)(bufPtr - buf - 1);
+}
+
+
+
+/***********************************************************************************
+ *
+ * Description:
+ *  Returns the week number of the year (0-53) for the given time.  firstDayOfWeek
+ *  is the day on which the week is considered to start (0=Sun, 1=Mon, ...).
+ *  Week 1 starts the first time firstDayOfWeek occurs in the year.  In other words,
+ *  a partial week at the start of the year is considered week 0.  
+ *
+ **********************************************************************************/
+
+static unsigned int
+pr_WeekOfYear(const PRExplodedTime* time, unsigned int firstDayOfWeek)
+{
+   int dayOfWeek;
+   int dayOfYear;
+
+  /* Get the day of the year for the given time then adjust it to represent the
+   * first day of the week containing the given time.
+   */
+  dayOfWeek = time->tm_wday - firstDayOfWeek;
+  if (dayOfWeek < 0)
+    dayOfWeek += 7;
+  
+  dayOfYear = time->tm_yday - dayOfWeek;
+
+
+  if( dayOfYear <= 0 )
+  {
+     /* If dayOfYear is <= 0, it is in the first partial week of the year. */
+     return 0;
+  }
+  else
+  {
+     /* Count the number of full weeks ( dayOfYear / 7 ) then add a week if there
+      * are any days left over ( dayOfYear % 7 ).  Because we are only counting to
+      * the first day of the week containing the given time, rather than to the
+      * actual day representing the given time, any days in week 0 will be "absorbed"
+      * as extra days in the given week.
+      */
+     return (dayOfYear / 7) + ( (dayOfYear % 7) == 0 ? 0 : 1 );
+  }
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prtpool.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prtpool.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1219 @@
+/* -*- 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 "nspr.h"
+
+/*
+ * Thread pools
+ *	Thread pools create and manage threads to provide support for
+ *	scheduling jobs onto one or more threads.
+ *
+ */
+#ifdef OPT_WINNT
+#include <windows.h>
+#endif
+
+/*
+ * worker thread
+ */
+typedef struct wthread {
+	PRCList		links;
+	PRThread	*thread;
+} wthread;
+
+/*
+ * queue of timer jobs
+ */
+typedef struct timer_jobq {
+	PRCList		list;
+	PRLock		*lock;
+	PRCondVar	*cv;
+	PRInt32		cnt;
+	PRCList 	wthreads;
+} timer_jobq;
+
+/*
+ * queue of jobs
+ */
+typedef struct tp_jobq {
+	PRCList		list;
+	PRInt32		cnt;
+	PRLock		*lock;
+	PRCondVar	*cv;
+	PRCList 	wthreads;
+#ifdef OPT_WINNT
+	HANDLE		nt_completion_port;
+#endif
+} tp_jobq;
+
+/*
+ * queue of IO jobs
+ */
+typedef struct io_jobq {
+	PRCList		list;
+	PRPollDesc  *pollfds;
+	PRInt32  	npollfds;
+	PRJob		**polljobs;
+	PRLock		*lock;
+	PRInt32		cnt;
+	PRFileDesc	*notify_fd;
+	PRCList 	wthreads;
+} io_jobq;
+
+/*
+ * Threadpool
+ */
+struct PRThreadPool {
+	PRInt32		init_threads;
+	PRInt32		max_threads;
+	PRInt32		current_threads;
+	PRInt32		idle_threads;
+	PRUint32	stacksize;
+	tp_jobq		jobq;
+	io_jobq		ioq;
+	timer_jobq	timerq;
+	PRLock		*join_lock;		/* used with jobp->join_cv */
+	PRCondVar	*shutdown_cv;
+	PRBool		shutdown;
+};
+
+typedef enum io_op_type
+	{ JOB_IO_READ, JOB_IO_WRITE, JOB_IO_CONNECT, JOB_IO_ACCEPT } io_op_type;
+
+#ifdef OPT_WINNT
+typedef struct NT_notifier {
+	OVERLAPPED overlapped;		/* must be first */
+	PRJob	*jobp;
+} NT_notifier;
+#endif
+
+struct PRJob {
+	PRCList			links;		/* 	for linking jobs */
+	PRBool			on_ioq;		/* job on ioq */
+	PRBool			on_timerq;	/* job on timerq */
+	PRJobFn			job_func;
+	void 			*job_arg;
+	PRCondVar		*join_cv;
+	PRBool			join_wait;	/* == PR_TRUE, when waiting to join */
+	PRCondVar		*cancel_cv;	/* for cancelling IO jobs */
+	PRBool			cancel_io;	/* for cancelling IO jobs */
+	PRThreadPool	*tpool;		/* back pointer to thread pool */
+	PRJobIoDesc		*iod;
+	io_op_type		io_op;
+	PRInt16			io_poll_flags;
+	PRNetAddr		*netaddr;
+	PRIntervalTime	timeout;	/* relative value */
+	PRIntervalTime	absolute;
+#ifdef OPT_WINNT
+	NT_notifier		nt_notifier;	
+#endif
+};
+
+#define JOB_LINKS_PTR(_qp) \
+    ((PRJob *) ((char *) (_qp) - offsetof(PRJob, links)))
+
+#define WTHREAD_LINKS_PTR(_qp) \
+    ((wthread *) ((char *) (_qp) - offsetof(wthread, links)))
+
+#define JOINABLE_JOB(_jobp) (NULL != (_jobp)->join_cv)
+
+#define JOIN_NOTIFY(_jobp)								\
+				PR_BEGIN_MACRO							\
+				PR_Lock(_jobp->tpool->join_lock);		\
+				_jobp->join_wait = PR_FALSE;			\
+				PR_NotifyCondVar(_jobp->join_cv);		\
+				PR_Unlock(_jobp->tpool->join_lock);		\
+				PR_END_MACRO
+
+#define CANCEL_IO_JOB(jobp)								\
+				PR_BEGIN_MACRO							\
+				jobp->cancel_io = PR_FALSE;				\
+				jobp->on_ioq = PR_FALSE;				\
+				PR_REMOVE_AND_INIT_LINK(&jobp->links);	\
+				tp->ioq.cnt--;							\
+				PR_NotifyCondVar(jobp->cancel_cv);		\
+				PR_END_MACRO
+
+static void delete_job(PRJob *jobp);
+static PRThreadPool * alloc_threadpool(void);
+static PRJob * alloc_job(PRBool joinable, PRThreadPool *tp);
+static void notify_ioq(PRThreadPool *tp);
+static void notify_timerq(PRThreadPool *tp);
+
+/*
+ * locks are acquired in the following order
+ *
+ *	tp->ioq.lock,tp->timerq.lock
+ *			|
+ *			V
+ *		tp->jobq->lock		
+ */
+
+/*
+ * worker thread function
+ */
+static void wstart(void *arg)
+{
+PRThreadPool *tp = (PRThreadPool *) arg;
+PRCList *head;
+
+	/*
+	 * execute jobs until shutdown
+	 */
+	while (!tp->shutdown) {
+		PRJob *jobp;
+#ifdef OPT_WINNT
+		BOOL rv;
+		DWORD unused, shutdown;
+		LPOVERLAPPED olp;
+
+		PR_Lock(tp->jobq.lock);
+		tp->idle_threads++;
+		PR_Unlock(tp->jobq.lock);
+		rv = GetQueuedCompletionStatus(tp->jobq.nt_completion_port,
+					&unused, &shutdown, &olp, INFINITE);
+		
+		PR_ASSERT(rv);
+		if (shutdown)
+			break;
+		jobp = ((NT_notifier *) olp)->jobp;
+		PR_Lock(tp->jobq.lock);
+		tp->idle_threads--;
+		tp->jobq.cnt--;
+		PR_Unlock(tp->jobq.lock);
+#else
+
+		PR_Lock(tp->jobq.lock);
+		while (PR_CLIST_IS_EMPTY(&tp->jobq.list) && (!tp->shutdown)) {
+			tp->idle_threads++;
+			PR_WaitCondVar(tp->jobq.cv, PR_INTERVAL_NO_TIMEOUT);
+			tp->idle_threads--;
+		}	
+		if (tp->shutdown) {
+			PR_Unlock(tp->jobq.lock);
+			break;
+		}
+		head = PR_LIST_HEAD(&tp->jobq.list);
+		/*
+		 * remove job from queue
+		 */
+		PR_REMOVE_AND_INIT_LINK(head);
+		tp->jobq.cnt--;
+		jobp = JOB_LINKS_PTR(head);
+		PR_Unlock(tp->jobq.lock);
+#endif
+
+		jobp->job_func(jobp->job_arg);
+		if (!JOINABLE_JOB(jobp)) {
+			delete_job(jobp);
+		} else {
+			JOIN_NOTIFY(jobp);
+		}
+	}
+	PR_Lock(tp->jobq.lock);
+	tp->current_threads--;
+	PR_Unlock(tp->jobq.lock);
+}
+
+/*
+ * add a job to the work queue
+ */
+static void
+add_to_jobq(PRThreadPool *tp, PRJob *jobp)
+{
+	/*
+	 * add to jobq
+	 */
+#ifdef OPT_WINNT
+	PR_Lock(tp->jobq.lock);
+	tp->jobq.cnt++;
+	PR_Unlock(tp->jobq.lock);
+	/*
+	 * notify worker thread(s)
+	 */
+	PostQueuedCompletionStatus(tp->jobq.nt_completion_port, 0,
+            FALSE, &jobp->nt_notifier.overlapped);
+#else
+	PR_Lock(tp->jobq.lock);
+	PR_APPEND_LINK(&jobp->links,&tp->jobq.list);
+	tp->jobq.cnt++;
+	if ((tp->idle_threads < tp->jobq.cnt) &&
+					(tp->current_threads < tp->max_threads)) {
+		wthread *wthrp;
+		/*
+		 * increment thread count and unlock the jobq lock
+		 */
+		tp->current_threads++;
+		PR_Unlock(tp->jobq.lock);
+		/* create new worker thread */
+		wthrp = PR_NEWZAP(wthread);
+		if (wthrp) {
+			wthrp->thread = PR_CreateThread(PR_USER_THREAD, wstart,
+						tp, PR_PRIORITY_NORMAL,
+						PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,tp->stacksize);
+			if (NULL == wthrp->thread) {
+				PR_DELETE(wthrp);  /* this sets wthrp to NULL */
+			}
+		}
+		PR_Lock(tp->jobq.lock);
+		if (NULL == wthrp) {
+			tp->current_threads--;
+		} else {
+			PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads);
+		}
+	}
+	/*
+	 * wakeup a worker thread
+	 */
+	PR_NotifyCondVar(tp->jobq.cv);
+	PR_Unlock(tp->jobq.lock);
+#endif
+}
+
+/*
+ * io worker thread function
+ */
+static void io_wstart(void *arg)
+{
+PRThreadPool *tp = (PRThreadPool *) arg;
+int pollfd_cnt, pollfds_used;
+int rv;
+PRCList *qp, *nextqp;
+PRPollDesc *pollfds;
+PRJob **polljobs;
+int poll_timeout;
+PRIntervalTime now;
+
+	/*
+	 * scan io_jobq
+	 * construct poll list
+	 * call PR_Poll
+	 * for all fds, for which poll returns true, move the job to
+	 * jobq and wakeup worker thread.
+	 */
+	while (!tp->shutdown) {
+		PRJob *jobp;
+
+		pollfd_cnt = tp->ioq.cnt + 10;
+		if (pollfd_cnt > tp->ioq.npollfds) {
+
+			/*
+			 * re-allocate pollfd array if the current one is not large
+			 * enough
+			 */
+			if (NULL != tp->ioq.pollfds)
+				PR_Free(tp->ioq.pollfds);
+			tp->ioq.pollfds = (PRPollDesc *) PR_Malloc(pollfd_cnt *
+						(sizeof(PRPollDesc) + sizeof(PRJob *)));
+			PR_ASSERT(NULL != tp->ioq.pollfds);
+			/*
+			 * array of pollfds
+			 */
+			pollfds = tp->ioq.pollfds;
+			tp->ioq.polljobs = (PRJob **) (&tp->ioq.pollfds[pollfd_cnt]);
+			/*
+			 * parallel array of jobs
+			 */
+			polljobs = tp->ioq.polljobs;
+			tp->ioq.npollfds = pollfd_cnt;
+		}
+
+		pollfds_used = 0;
+		/*
+		 * add the notify fd; used for unblocking io thread(s)
+		 */
+		pollfds[pollfds_used].fd = tp->ioq.notify_fd;
+		pollfds[pollfds_used].in_flags = PR_POLL_READ;
+		pollfds[pollfds_used].out_flags = 0;
+		polljobs[pollfds_used] = NULL;
+		pollfds_used++;
+		/*
+		 * fill in the pollfd array
+		 */
+		PR_Lock(tp->ioq.lock);
+		for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = nextqp) {
+			nextqp = qp->next;
+			jobp = JOB_LINKS_PTR(qp);
+			if (jobp->cancel_io) {
+				CANCEL_IO_JOB(jobp);
+				continue;
+			}
+			if (pollfds_used == (pollfd_cnt))
+				break;
+			pollfds[pollfds_used].fd = jobp->iod->socket;
+			pollfds[pollfds_used].in_flags = jobp->io_poll_flags;
+			pollfds[pollfds_used].out_flags = 0;
+			polljobs[pollfds_used] = jobp;
+
+			pollfds_used++;
+		}
+		if (!PR_CLIST_IS_EMPTY(&tp->ioq.list)) {
+			qp = tp->ioq.list.next;
+			jobp = JOB_LINKS_PTR(qp);
+			if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout)
+				poll_timeout = PR_INTERVAL_NO_TIMEOUT;
+			else if (PR_INTERVAL_NO_WAIT == jobp->timeout)
+				poll_timeout = PR_INTERVAL_NO_WAIT;
+			else {
+				poll_timeout = jobp->absolute - PR_IntervalNow();
+				if (poll_timeout <= 0) /* already timed out */
+					poll_timeout = PR_INTERVAL_NO_WAIT;
+			}
+		} else {
+			poll_timeout = PR_INTERVAL_NO_TIMEOUT;
+		}
+		PR_Unlock(tp->ioq.lock);
+
+		/*
+		 * XXXX
+		 * should retry if more jobs have been added to the queue?
+		 *
+		 */
+		PR_ASSERT(pollfds_used <= pollfd_cnt);
+		rv = PR_Poll(tp->ioq.pollfds, pollfds_used, poll_timeout);
+
+		if (tp->shutdown) {
+			break;
+		}
+
+		if (rv > 0) {
+			/*
+			 * at least one io event is set
+			 */
+			PRStatus rval_status;
+			PRInt32 index;
+
+			PR_ASSERT(pollfds[0].fd == tp->ioq.notify_fd);
+			/*
+			 * reset the pollable event, if notified
+			 */
+			if (pollfds[0].out_flags & PR_POLL_READ) {
+				rval_status = PR_WaitForPollableEvent(tp->ioq.notify_fd);
+				PR_ASSERT(PR_SUCCESS == rval_status);
+			}
+
+			for(index = 1; index < (pollfds_used); index++) {
+                PRInt16 events = pollfds[index].in_flags;
+                PRInt16 revents = pollfds[index].out_flags;	
+				jobp = polljobs[index];	
+
+                if ((revents & PR_POLL_NVAL) ||  /* busted in all cases */
+                	(revents & PR_POLL_ERR) ||
+                			((events & PR_POLL_WRITE) &&
+							(revents & PR_POLL_HUP))) { /* write op & hup */
+					PR_Lock(tp->ioq.lock);
+					if (jobp->cancel_io) {
+						CANCEL_IO_JOB(jobp);
+						PR_Unlock(tp->ioq.lock);
+						continue;
+					}
+					PR_REMOVE_AND_INIT_LINK(&jobp->links);
+					tp->ioq.cnt--;
+					jobp->on_ioq = PR_FALSE;
+					PR_Unlock(tp->ioq.lock);
+
+					/* set error */
+                    if (PR_POLL_NVAL & revents)
+						jobp->iod->error = PR_BAD_DESCRIPTOR_ERROR;
+                    else if (PR_POLL_HUP & revents)
+						jobp->iod->error = PR_CONNECT_RESET_ERROR;
+                    else 
+						jobp->iod->error = PR_IO_ERROR;
+
+					/*
+					 * add to jobq
+					 */
+					add_to_jobq(tp, jobp);
+				} else if (revents) {
+					/*
+					 * add to jobq
+					 */
+					PR_Lock(tp->ioq.lock);
+					if (jobp->cancel_io) {
+						CANCEL_IO_JOB(jobp);
+						PR_Unlock(tp->ioq.lock);
+						continue;
+					}
+					PR_REMOVE_AND_INIT_LINK(&jobp->links);
+					tp->ioq.cnt--;
+					jobp->on_ioq = PR_FALSE;
+					PR_Unlock(tp->ioq.lock);
+
+					if (jobp->io_op == JOB_IO_CONNECT) {
+						if (PR_GetConnectStatus(&pollfds[index]) == PR_SUCCESS)
+							jobp->iod->error = 0;
+						else
+							jobp->iod->error = PR_GetError();
+					} else
+						jobp->iod->error = 0;
+
+					add_to_jobq(tp, jobp);
+				}
+			}
+		}
+		/*
+		 * timeout processing
+		 */
+		now = PR_IntervalNow();
+		PR_Lock(tp->ioq.lock);
+		for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = nextqp) {
+			nextqp = qp->next;
+			jobp = JOB_LINKS_PTR(qp);
+			if (jobp->cancel_io) {
+				CANCEL_IO_JOB(jobp);
+				continue;
+			}
+			if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout)
+				break;
+			if ((PR_INTERVAL_NO_WAIT != jobp->timeout) &&
+								((PRInt32)(jobp->absolute - now) > 0))
+				break;
+			PR_REMOVE_AND_INIT_LINK(&jobp->links);
+			tp->ioq.cnt--;
+			jobp->on_ioq = PR_FALSE;
+			jobp->iod->error = PR_IO_TIMEOUT_ERROR;
+			add_to_jobq(tp, jobp);
+		}
+		PR_Unlock(tp->ioq.lock);
+	}
+}
+
+/*
+ * timer worker thread function
+ */
+static void timer_wstart(void *arg)
+{
+PRThreadPool *tp = (PRThreadPool *) arg;
+PRCList *qp;
+PRIntervalTime timeout;
+PRIntervalTime now;
+
+	/*
+	 * call PR_WaitCondVar with minimum value of all timeouts
+	 */
+	while (!tp->shutdown) {
+		PRJob *jobp;
+
+		PR_Lock(tp->timerq.lock);
+		if (PR_CLIST_IS_EMPTY(&tp->timerq.list)) {
+			timeout = PR_INTERVAL_NO_TIMEOUT;
+		} else {
+			PRCList *qp;
+
+			qp = tp->timerq.list.next;
+			jobp = JOB_LINKS_PTR(qp);
+
+			timeout = jobp->absolute - PR_IntervalNow();
+            if (timeout <= 0)
+				timeout = PR_INTERVAL_NO_WAIT;  /* already timed out */
+		}
+		if (PR_INTERVAL_NO_WAIT != timeout)
+			PR_WaitCondVar(tp->timerq.cv, timeout);
+		if (tp->shutdown) {
+			PR_Unlock(tp->timerq.lock);
+			break;
+		}
+		/*
+		 * move expired-timer jobs to jobq
+		 */
+		now = PR_IntervalNow();	
+		while (!PR_CLIST_IS_EMPTY(&tp->timerq.list)) {
+			qp = tp->timerq.list.next;
+			jobp = JOB_LINKS_PTR(qp);
+
+			if ((PRInt32)(jobp->absolute - now) > 0) {
+				break;
+			}
+			/*
+			 * job timed out
+			 */
+			PR_REMOVE_AND_INIT_LINK(&jobp->links);
+			tp->timerq.cnt--;
+			jobp->on_timerq = PR_FALSE;
+			add_to_jobq(tp, jobp);
+		}
+		PR_Unlock(tp->timerq.lock);
+	}
+}
+
+static void
+delete_threadpool(PRThreadPool *tp)
+{
+	if (NULL != tp) {
+		if (NULL != tp->shutdown_cv)
+			PR_DestroyCondVar(tp->shutdown_cv);
+		if (NULL != tp->jobq.cv)
+			PR_DestroyCondVar(tp->jobq.cv);
+		if (NULL != tp->jobq.lock)
+			PR_DestroyLock(tp->jobq.lock);
+		if (NULL != tp->join_lock)
+			PR_DestroyLock(tp->join_lock);
+#ifdef OPT_WINNT
+		if (NULL != tp->jobq.nt_completion_port)
+			CloseHandle(tp->jobq.nt_completion_port);
+#endif
+		/* Timer queue */
+		if (NULL != tp->timerq.cv)
+			PR_DestroyCondVar(tp->timerq.cv);
+		if (NULL != tp->timerq.lock)
+			PR_DestroyLock(tp->timerq.lock);
+
+		if (NULL != tp->ioq.lock)
+			PR_DestroyLock(tp->ioq.lock);
+		if (NULL != tp->ioq.pollfds)
+			PR_Free(tp->ioq.pollfds);
+		if (NULL != tp->ioq.notify_fd)
+			PR_DestroyPollableEvent(tp->ioq.notify_fd);
+		PR_Free(tp);
+	}
+	return;
+}
+
+static PRThreadPool *
+alloc_threadpool(void)
+{
+PRThreadPool *tp;
+
+	tp = (PRThreadPool *) PR_CALLOC(sizeof(*tp));
+	if (NULL == tp)
+		goto failed;
+	tp->jobq.lock = PR_NewLock();
+	if (NULL == tp->jobq.lock)
+		goto failed;
+	tp->jobq.cv = PR_NewCondVar(tp->jobq.lock);
+	if (NULL == tp->jobq.cv)
+		goto failed;
+	tp->join_lock = PR_NewLock();
+	if (NULL == tp->join_lock)
+		goto failed;
+#ifdef OPT_WINNT
+	tp->jobq.nt_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
+									NULL, 0, 0);
+	if (NULL == tp->jobq.nt_completion_port)
+		goto failed;
+#endif
+
+	tp->ioq.lock = PR_NewLock();
+	if (NULL == tp->ioq.lock)
+		goto failed;
+
+	/* Timer queue */
+
+	tp->timerq.lock = PR_NewLock();
+	if (NULL == tp->timerq.lock)
+		goto failed;
+	tp->timerq.cv = PR_NewCondVar(tp->timerq.lock);
+	if (NULL == tp->timerq.cv)
+		goto failed;
+
+	tp->shutdown_cv = PR_NewCondVar(tp->jobq.lock);
+	if (NULL == tp->shutdown_cv)
+		goto failed;
+	tp->ioq.notify_fd = PR_NewPollableEvent();
+	if (NULL == tp->ioq.notify_fd)
+		goto failed;
+	return tp;
+failed:
+	delete_threadpool(tp);
+	PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	return NULL;
+}
+
+/* Create thread pool */
+PR_IMPLEMENT(PRThreadPool *)
+PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads,
+                                PRUint32 stacksize)
+{
+PRThreadPool *tp;
+PRThread *thr;
+int i;
+wthread *wthrp;
+
+	tp = alloc_threadpool();
+	if (NULL == tp)
+		return NULL;
+
+	tp->init_threads = initial_threads;
+	tp->max_threads = max_threads;
+	tp->stacksize = stacksize;
+	PR_INIT_CLIST(&tp->jobq.list);
+	PR_INIT_CLIST(&tp->ioq.list);
+	PR_INIT_CLIST(&tp->timerq.list);
+	PR_INIT_CLIST(&tp->jobq.wthreads);
+	PR_INIT_CLIST(&tp->ioq.wthreads);
+	PR_INIT_CLIST(&tp->timerq.wthreads);
+	tp->shutdown = PR_FALSE;
+
+	PR_Lock(tp->jobq.lock);
+	for(i=0; i < initial_threads; ++i) {
+
+		thr = PR_CreateThread(PR_USER_THREAD, wstart,
+						tp, PR_PRIORITY_NORMAL,
+						PR_GLOBAL_THREAD, PR_JOINABLE_THREAD,stacksize);
+		PR_ASSERT(thr);
+		wthrp = PR_NEWZAP(wthread);
+		PR_ASSERT(wthrp);
+		wthrp->thread = thr;
+		PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads);
+	}
+	tp->current_threads = initial_threads;
+
+	thr = PR_CreateThread(PR_USER_THREAD, io_wstart,
+					tp, PR_PRIORITY_NORMAL,
+					PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize);
+	PR_ASSERT(thr);
+	wthrp = PR_NEWZAP(wthread);
+	PR_ASSERT(wthrp);
+	wthrp->thread = thr;
+	PR_APPEND_LINK(&wthrp->links, &tp->ioq.wthreads);
+
+	thr = PR_CreateThread(PR_USER_THREAD, timer_wstart,
+					tp, PR_PRIORITY_NORMAL,
+					PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize);
+	PR_ASSERT(thr);
+	wthrp = PR_NEWZAP(wthread);
+	PR_ASSERT(wthrp);
+	wthrp->thread = thr;
+	PR_APPEND_LINK(&wthrp->links, &tp->timerq.wthreads);
+
+	PR_Unlock(tp->jobq.lock);
+	return tp;
+}
+
+static void
+delete_job(PRJob *jobp)
+{
+	if (NULL != jobp) {
+		if (NULL != jobp->join_cv) {
+			PR_DestroyCondVar(jobp->join_cv);
+			jobp->join_cv = NULL;
+		}
+		if (NULL != jobp->cancel_cv) {
+			PR_DestroyCondVar(jobp->cancel_cv);
+			jobp->cancel_cv = NULL;
+		}
+		PR_DELETE(jobp);
+	}
+}
+
+static PRJob *
+alloc_job(PRBool joinable, PRThreadPool *tp)
+{
+	PRJob *jobp;
+
+	jobp = PR_NEWZAP(PRJob);
+	if (NULL == jobp) 
+		goto failed;
+	if (joinable) {
+		jobp->join_cv = PR_NewCondVar(tp->join_lock);
+		jobp->join_wait = PR_TRUE;
+		if (NULL == jobp->join_cv)
+			goto failed;
+	} else {
+		jobp->join_cv = NULL;
+	}
+#ifdef OPT_WINNT
+	jobp->nt_notifier.jobp = jobp;
+#endif
+	return jobp;
+failed:
+	delete_job(jobp);
+	PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+	return NULL;
+}
+
+/* queue a job */
+PR_IMPLEMENT(PRJob *)
+PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable)
+{
+	PRJob *jobp;
+
+	jobp = alloc_job(joinable, tpool);
+	if (NULL == jobp)
+		return NULL;
+
+	jobp->job_func = fn;
+	jobp->job_arg = arg;
+	jobp->tpool = tpool;
+
+	add_to_jobq(tpool, jobp);
+	return jobp;
+}
+
+/* queue a job, when a socket is readable or writeable */
+static PRJob *
+queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg,
+				PRBool joinable, io_op_type op)
+{
+	PRJob *jobp;
+	PRIntervalTime now;
+
+	jobp = alloc_job(joinable, tpool);
+	if (NULL == jobp) {
+		return NULL;
+	}
+
+	/*
+	 * Add a new job to io_jobq
+	 * wakeup io worker thread
+	 */
+
+	jobp->job_func = fn;
+	jobp->job_arg = arg;
+	jobp->tpool = tpool;
+	jobp->iod = iod;
+	if (JOB_IO_READ == op) {
+		jobp->io_op = JOB_IO_READ;
+		jobp->io_poll_flags = PR_POLL_READ;
+	} else if (JOB_IO_WRITE == op) {
+		jobp->io_op = JOB_IO_WRITE;
+		jobp->io_poll_flags = PR_POLL_WRITE;
+	} else if (JOB_IO_ACCEPT == op) {
+		jobp->io_op = JOB_IO_ACCEPT;
+		jobp->io_poll_flags = PR_POLL_READ;
+	} else if (JOB_IO_CONNECT == op) {
+		jobp->io_op = JOB_IO_CONNECT;
+		jobp->io_poll_flags = PR_POLL_WRITE|PR_POLL_EXCEPT;
+	} else {
+		delete_job(jobp);
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return NULL;
+	}
+
+	jobp->timeout = iod->timeout;
+	if ((PR_INTERVAL_NO_TIMEOUT == iod->timeout) ||
+			(PR_INTERVAL_NO_WAIT == iod->timeout)) {
+		jobp->absolute = iod->timeout;
+	} else {
+		now = PR_IntervalNow();
+		jobp->absolute = now + iod->timeout;
+	}
+
+
+	PR_Lock(tpool->ioq.lock);
+
+	if (PR_CLIST_IS_EMPTY(&tpool->ioq.list) ||
+			(PR_INTERVAL_NO_TIMEOUT == iod->timeout)) {
+		PR_APPEND_LINK(&jobp->links,&tpool->ioq.list);
+	} else if (PR_INTERVAL_NO_WAIT == iod->timeout) {
+		PR_INSERT_LINK(&jobp->links,&tpool->ioq.list);
+	} else {
+		PRCList *qp;
+		PRJob *tmp_jobp;
+		/*
+		 * insert into the timeout-sorted ioq
+		 */
+		for (qp = tpool->ioq.list.prev; qp != &tpool->ioq.list;
+							qp = qp->prev) {
+			tmp_jobp = JOB_LINKS_PTR(qp);
+			if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) {
+				break;
+			}
+		}
+		PR_INSERT_AFTER(&jobp->links,qp);
+	}
+
+	jobp->on_ioq = PR_TRUE;
+	tpool->ioq.cnt++;
+	/*
+	 * notify io worker thread(s)
+	 */
+	PR_Unlock(tpool->ioq.lock);
+	notify_ioq(tpool);
+	return jobp;
+}
+
+/* queue a job, when a socket is readable */
+PR_IMPLEMENT(PRJob *)
+PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg,
+											PRBool joinable)
+{
+	return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_READ));
+}
+
+/* queue a job, when a socket is writeable */
+PR_IMPLEMENT(PRJob *)
+PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn,void * arg,
+										PRBool joinable)
+{
+	return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_WRITE));
+}
+
+
+/* queue a job, when a socket has a pending connection */
+PR_IMPLEMENT(PRJob *)
+PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn,
+								void * arg, PRBool joinable)
+{
+	return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_ACCEPT));
+}
+
+/* queue a job, when a socket can be connected */
+PR_IMPLEMENT(PRJob *)
+PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod,
+			const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable)
+{
+	PRStatus rv;
+	PRErrorCode err;
+
+	rv = PR_Connect(iod->socket, addr, PR_INTERVAL_NO_WAIT);
+	if ((rv == PR_FAILURE) && ((err = PR_GetError()) == PR_IN_PROGRESS_ERROR)){
+		/* connection pending */
+		return(queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_CONNECT));
+	} else {
+		/*
+		 * connection succeeded or failed; add to jobq right away
+		 */
+		if (rv == PR_FAILURE)
+			iod->error = err;
+		else
+			iod->error = 0;
+		return(PR_QueueJob(tpool, fn, arg, joinable));
+	}
+}
+
+/* queue a job, when a timer expires */
+PR_IMPLEMENT(PRJob *)
+PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout,
+							PRJobFn fn, void * arg, PRBool joinable)
+{
+	PRIntervalTime now;
+	PRJob *jobp;
+
+	if (PR_INTERVAL_NO_TIMEOUT == timeout) {
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return NULL;
+	}
+	if (PR_INTERVAL_NO_WAIT == timeout) {
+		/*
+		 * no waiting; add to jobq right away
+		 */
+		return(PR_QueueJob(tpool, fn, arg, joinable));
+	}
+	jobp = alloc_job(joinable, tpool);
+	if (NULL == jobp) {
+		return NULL;
+	}
+
+	/*
+	 * Add a new job to timer_jobq
+	 * wakeup timer worker thread
+	 */
+
+	jobp->job_func = fn;
+	jobp->job_arg = arg;
+	jobp->tpool = tpool;
+	jobp->timeout = timeout;
+
+	now = PR_IntervalNow();
+	jobp->absolute = now + timeout;
+
+
+	PR_Lock(tpool->timerq.lock);
+	jobp->on_timerq = PR_TRUE;
+	if (PR_CLIST_IS_EMPTY(&tpool->timerq.list))
+		PR_APPEND_LINK(&jobp->links,&tpool->timerq.list);
+	else {
+		PRCList *qp;
+		PRJob *tmp_jobp;
+		/*
+		 * insert into the sorted timer jobq
+		 */
+		for (qp = tpool->timerq.list.prev; qp != &tpool->timerq.list;
+							qp = qp->prev) {
+			tmp_jobp = JOB_LINKS_PTR(qp);
+			if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) {
+				break;
+			}
+		}
+		PR_INSERT_AFTER(&jobp->links,qp);
+	}
+	tpool->timerq.cnt++;
+	/*
+	 * notify timer worker thread(s)
+	 */
+	notify_timerq(tpool);
+	PR_Unlock(tpool->timerq.lock);
+	return jobp;
+}
+
+static void
+notify_timerq(PRThreadPool *tp)
+{
+	/*
+	 * wakeup the timer thread(s)
+	 */
+	PR_NotifyCondVar(tp->timerq.cv);
+}
+
+static void
+notify_ioq(PRThreadPool *tp)
+{
+PRStatus rval_status;
+
+	/*
+	 * wakeup the io thread(s)
+	 */
+	rval_status = PR_SetPollableEvent(tp->ioq.notify_fd);
+	PR_ASSERT(PR_SUCCESS == rval_status);
+}
+
+/*
+ * cancel a job
+ *
+ *	XXXX: is this needed? likely to be removed
+ */
+PR_IMPLEMENT(PRStatus)
+PR_CancelJob(PRJob *jobp) {
+
+	PRStatus rval = PR_FAILURE;
+	PRThreadPool *tp;
+
+	if (jobp->on_timerq) {
+		/*
+		 * now, check again while holding the timerq lock
+		 */
+		tp = jobp->tpool;
+		PR_Lock(tp->timerq.lock);
+		if (jobp->on_timerq) {
+			jobp->on_timerq = PR_FALSE;
+			PR_REMOVE_AND_INIT_LINK(&jobp->links);
+			tp->timerq.cnt--;
+			PR_Unlock(tp->timerq.lock);
+			if (!JOINABLE_JOB(jobp)) {
+				delete_job(jobp);
+			} else {
+				JOIN_NOTIFY(jobp);
+			}
+			rval = PR_SUCCESS;
+		} else
+			PR_Unlock(tp->timerq.lock);
+	} else if (jobp->on_ioq) {
+		/*
+		 * now, check again while holding the ioq lock
+		 */
+		tp = jobp->tpool;
+		PR_Lock(tp->ioq.lock);
+		if (jobp->on_ioq) {
+			jobp->cancel_cv = PR_NewCondVar(tp->ioq.lock);
+			if (NULL == jobp->cancel_cv) {
+				PR_Unlock(tp->ioq.lock);
+				PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+				return PR_FAILURE;
+			}
+			/*
+			 * mark job 'cancelled' and notify io thread(s)
+			 * XXXX:
+			 *		this assumes there is only one io thread; when there
+			 * 		are multiple threads, the io thread processing this job
+			 * 		must be notified.
+			 */
+			jobp->cancel_io = PR_TRUE;
+			PR_Unlock(tp->ioq.lock);	/* release, reacquire ioq lock */
+			notify_ioq(tp);
+			PR_Lock(tp->ioq.lock);
+			while (jobp->cancel_io)
+				PR_WaitCondVar(jobp->cancel_cv, PR_INTERVAL_NO_TIMEOUT);
+			PR_Unlock(tp->ioq.lock);
+			PR_ASSERT(!jobp->on_ioq);
+			if (!JOINABLE_JOB(jobp)) {
+				delete_job(jobp);
+			} else {
+				JOIN_NOTIFY(jobp);
+			}
+			rval = PR_SUCCESS;
+		} else
+			PR_Unlock(tp->ioq.lock);
+	}
+	if (PR_FAILURE == rval)
+		PR_SetError(PR_INVALID_STATE_ERROR, 0);
+	return rval;
+}
+
+/* join a job, wait until completion */
+PR_IMPLEMENT(PRStatus)
+PR_JoinJob(PRJob *jobp)
+{
+	if (!JOINABLE_JOB(jobp)) {
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		return PR_FAILURE;
+	}
+	PR_Lock(jobp->tpool->join_lock);
+	while(jobp->join_wait)
+		PR_WaitCondVar(jobp->join_cv, PR_INTERVAL_NO_TIMEOUT);
+	PR_Unlock(jobp->tpool->join_lock);
+	delete_job(jobp);
+	return PR_SUCCESS;
+}
+
+/* shutdown threadpool */
+PR_IMPLEMENT(PRStatus)
+PR_ShutdownThreadPool(PRThreadPool *tpool)
+{
+PRStatus rval = PR_SUCCESS;
+
+	PR_Lock(tpool->jobq.lock);
+	tpool->shutdown = PR_TRUE;
+	PR_NotifyAllCondVar(tpool->shutdown_cv);
+	PR_Unlock(tpool->jobq.lock);
+
+	return rval;
+}
+
+/*
+ * join thread pool
+ * 	wait for termination of worker threads
+ *	reclaim threadpool resources
+ */
+PR_IMPLEMENT(PRStatus)
+PR_JoinThreadPool(PRThreadPool *tpool)
+{
+PRStatus rval = PR_SUCCESS;
+PRCList *head;
+PRStatus rval_status;
+
+	PR_Lock(tpool->jobq.lock);
+	while (!tpool->shutdown)
+		PR_WaitCondVar(tpool->shutdown_cv, PR_INTERVAL_NO_TIMEOUT);
+
+	/*
+	 * wakeup worker threads
+	 */
+#ifdef OPT_WINNT
+	/*
+	 * post shutdown notification for all threads
+	 */
+	{
+		int i;
+		for(i=0; i < tpool->current_threads; i++) {
+			PostQueuedCompletionStatus(tpool->jobq.nt_completion_port, 0,
+												TRUE, NULL);
+		}
+	}
+#else
+	PR_NotifyAllCondVar(tpool->jobq.cv);
+#endif
+
+	/*
+	 * wakeup io thread(s)
+	 */
+	notify_ioq(tpool);
+
+	/*
+	 * wakeup timer thread(s)
+	 */
+	PR_Lock(tpool->timerq.lock);
+	notify_timerq(tpool);
+	PR_Unlock(tpool->timerq.lock);
+
+	while (!PR_CLIST_IS_EMPTY(&tpool->jobq.wthreads)) {
+		wthread *wthrp;
+
+		head = PR_LIST_HEAD(&tpool->jobq.wthreads);
+		PR_REMOVE_AND_INIT_LINK(head);
+		PR_Unlock(tpool->jobq.lock);
+		wthrp = WTHREAD_LINKS_PTR(head);
+		rval_status = PR_JoinThread(wthrp->thread);
+		PR_ASSERT(PR_SUCCESS == rval_status);
+		PR_DELETE(wthrp);
+		PR_Lock(tpool->jobq.lock);
+	}
+	PR_Unlock(tpool->jobq.lock);
+	while (!PR_CLIST_IS_EMPTY(&tpool->ioq.wthreads)) {
+		wthread *wthrp;
+
+		head = PR_LIST_HEAD(&tpool->ioq.wthreads);
+		PR_REMOVE_AND_INIT_LINK(head);
+		wthrp = WTHREAD_LINKS_PTR(head);
+		rval_status = PR_JoinThread(wthrp->thread);
+		PR_ASSERT(PR_SUCCESS == rval_status);
+		PR_DELETE(wthrp);
+	}
+
+	while (!PR_CLIST_IS_EMPTY(&tpool->timerq.wthreads)) {
+		wthread *wthrp;
+
+		head = PR_LIST_HEAD(&tpool->timerq.wthreads);
+		PR_REMOVE_AND_INIT_LINK(head);
+		wthrp = WTHREAD_LINKS_PTR(head);
+		rval_status = PR_JoinThread(wthrp->thread);
+		PR_ASSERT(PR_SUCCESS == rval_status);
+		PR_DELETE(wthrp);
+	}
+
+	/*
+	 * Delete queued jobs
+	 */
+	while (!PR_CLIST_IS_EMPTY(&tpool->jobq.list)) {
+		PRJob *jobp;
+
+		head = PR_LIST_HEAD(&tpool->jobq.list);
+		PR_REMOVE_AND_INIT_LINK(head);
+		jobp = JOB_LINKS_PTR(head);
+		tpool->jobq.cnt--;
+		delete_job(jobp);
+	}
+
+	/* delete io jobs */
+	while (!PR_CLIST_IS_EMPTY(&tpool->ioq.list)) {
+		PRJob *jobp;
+
+		head = PR_LIST_HEAD(&tpool->ioq.list);
+		PR_REMOVE_AND_INIT_LINK(head);
+		tpool->ioq.cnt--;
+		jobp = JOB_LINKS_PTR(head);
+		delete_job(jobp);
+	}
+
+	/* delete timer jobs */
+	while (!PR_CLIST_IS_EMPTY(&tpool->timerq.list)) {
+		PRJob *jobp;
+
+		head = PR_LIST_HEAD(&tpool->timerq.list);
+		PR_REMOVE_AND_INIT_LINK(head);
+		tpool->timerq.cnt--;
+		jobp = JOB_LINKS_PTR(head);
+		delete_job(jobp);
+	}
+
+	PR_ASSERT(0 == tpool->jobq.cnt);
+	PR_ASSERT(0 == tpool->ioq.cnt);
+	PR_ASSERT(0 == tpool->timerq.cnt);
+
+	delete_threadpool(tpool);
+	return rval;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prtrace.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/misc/prtrace.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,922 @@
+/* -*- 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 ***** */
+
+/*
+** prtrace.c -- NSPR Trace Instrumentation
+**
+** Implement the API defined in prtrace.h
+**
+**
+**
+*/
+
+#include <string.h>
+#include "prtrace.h"
+#include "prclist.h"
+#include "prlock.h"
+#include "prcvar.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prenv.h"
+#include "prmem.h"
+#include "prerror.h"
+
+
+#define DEFAULT_TRACE_BUFSIZE ( 1024 * 1024 )
+#define DEFAULT_BUFFER_SEGMENTS    2
+
+/*
+** Enumerate states in a RName structure
+*/
+typedef enum TraceState
+{
+    Running = 1,
+    Suspended = 2
+} TraceState;
+
+/*
+** Define QName structure
+*/
+typedef struct QName
+{
+    PRCList link;
+    PRCList rNameList;
+    char    name[PRTRACE_NAME_MAX+1];
+} QName;
+
+/*
+** Define RName structure
+*/
+typedef struct RName
+{
+    PRCList link;
+    PRLock  *lock;
+    QName   *qName;
+    TraceState state;
+    char    name[PRTRACE_NAME_MAX+1];
+    char    desc[PRTRACE_DESC_MAX+1];
+} RName;
+
+
+/*
+** The Trace Facility database
+**
+*/
+static PRLogModuleInfo *lm;
+
+static PRLock      *traceLock;      /* Facility Lock */
+static PRCList     qNameList;       /* anchor to all QName structures */
+static TraceState traceState = Running;
+
+/*
+** in-memory trace buffer controls
+*/
+static  PRTraceEntry    *tBuf;      /* pointer to buffer */
+static  PRInt32         bufSize;    /* size of buffer, in bytes, rounded up to sizeof(PRTraceEntry) */
+static  volatile PRInt32  next;     /* index to next PRTraceEntry */
+static  PRInt32         last;       /* index of highest numbered trace entry */
+
+/*
+** Real-time buffer capture controls
+*/
+static PRInt32 fetchLastSeen = 0;
+static PRBool  fetchLostData = PR_FALSE;
+
+/*
+** Buffer write-to-file controls
+*/
+static  PRLock      *logLock;               /* Sync lock */
+static  PRCondVar   *logCVar;               /* Sync Condidtion Variable */
+/*
+** Inter-thread state communication.
+** Controling thread writes to logOrder under protection of logCVar
+** the logging thread reads logOrder and sets logState on Notify.
+** 
+** logSegments, logCount, logLostData must be read and written under
+** protection of logLock, logCVar.
+** 
+*/
+static  enum LogState
+{
+    LogNotRunning,  /* Initial state */
+    LogReset,       /* Causes logger to re-calc controls */
+    LogActive,      /* Logging in progress, set only by log thread */
+    LogSuspend,     /* Suspend Logging */ 
+    LogResume,      /* Resume Logging => LogActive */ 
+    LogStop         /* Stop the log thread */
+}   logOrder, logState, localState;         /* controlling state variables */
+static  PRInt32     logSegments;            /* Number of buffer segments */
+static  PRInt32     logEntries;             /* number of Trace Entries in the buffer */
+static  PRInt32     logEntriesPerSegment;   /* number of PRTraceEntries per buffer segment */
+static  PRInt32     logSegSize;             /* size of buffer segment */
+static  PRInt32     logCount;               /* number of segments pending output */
+static  PRInt32     logLostData;            /* number of lost log buffer segments */
+
+/*
+** end Trace Database
+**
+*/
+
+/*
+** _PR_InitializeTrace() -- Initialize the trace facility
+*/
+static void NewTraceBuffer( PRInt32 size )
+{
+    /*
+    ** calculate the size of the buffer
+    ** round down so that each segment has the same number of
+    ** trace entries
+    */
+    logSegments = DEFAULT_BUFFER_SEGMENTS;
+    logEntries = size / sizeof(PRTraceEntry);
+    logEntriesPerSegment = logEntries / logSegments;
+    logEntries = logSegments * logEntriesPerSegment;
+    bufSize = logEntries * sizeof(PRTraceEntry);
+    logSegSize = logEntriesPerSegment * sizeof(PRTraceEntry);
+    PR_ASSERT( bufSize != 0);
+    PR_LOG( lm, PR_LOG_ERROR,
+        ("NewTraceBuffer: logSegments: %ld, logEntries: %ld, logEntriesPerSegment: %ld, logSegSize: %ld",
+            logSegments, logEntries, logEntriesPerSegment, logSegSize ));
+
+
+    tBuf = PR_Malloc( bufSize );
+    if ( tBuf == NULL )
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("PRTrace: Failed to get trace buffer"));
+        PR_ASSERT( 0 );
+    } 
+    else
+    {
+        PR_LOG( lm, PR_LOG_NOTICE,
+            ("PRTrace: Got trace buffer of size: %ld, at %p", bufSize, tBuf));
+    }
+
+    next = 0;
+    last = logEntries -1;
+    logCount = 0;
+    logLostData = PR_TRUE; /* not really on first call */
+    logOrder = LogReset;
+
+} /* end NewTraceBuffer() */
+
+/*
+** _PR_InitializeTrace() -- Initialize the trace facility
+*/
+static void _PR_InitializeTrace( void )
+{
+    /* The lock pointer better be null on this call */
+    PR_ASSERT( traceLock == NULL );
+
+    traceLock = PR_NewLock();
+    PR_ASSERT( traceLock != NULL );
+
+    PR_Lock( traceLock );
+    
+    PR_INIT_CLIST( &qNameList );
+
+    lm = PR_NewLogModule("trace");
+
+    bufSize = DEFAULT_TRACE_BUFSIZE;
+    NewTraceBuffer( bufSize );
+
+    /* Initialize logging controls */
+    logLock = PR_NewLock();
+    logCVar = PR_NewCondVar( logLock );
+
+    PR_Unlock( traceLock );
+    return;    
+} /* end _PR_InitializeTrace() */
+
+/*
+** Create a Trace Handle
+*/
+PR_IMPLEMENT(PRTraceHandle)
+	PR_CreateTrace( 
+    	const char *qName,          /* QName for this trace handle */
+	    const char *rName,          /* RName for this trace handle */
+	    const char *description     /* description for this trace handle */
+)
+{
+    QName   *qnp;
+    RName   *rnp;
+    PRBool  matchQname = PR_FALSE;
+
+    /* Self initialize, if necessary */
+    if ( traceLock == NULL )
+        _PR_InitializeTrace();
+
+    /* Validate input arguments */
+    PR_ASSERT( strlen(qName) <= PRTRACE_NAME_MAX );
+    PR_ASSERT( strlen(rName) <= PRTRACE_NAME_MAX );
+    PR_ASSERT( strlen(description) <= PRTRACE_DESC_MAX );
+
+    PR_LOG( lm, PR_LOG_DEBUG,
+            ("PRTRACE: CreateTrace: Qname: %s, RName: %s", qName, rName));
+
+    /* Lock the Facility */
+    PR_Lock( traceLock );
+
+    /* Do we already have a matching QName? */
+    if (!PR_CLIST_IS_EMPTY( &qNameList ))
+    {
+        qnp = (QName *) PR_LIST_HEAD( &qNameList );
+        do {
+            if ( strcmp(qnp->name, qName) == 0)
+            {
+                matchQname = PR_TRUE;
+                break;
+            }
+            qnp = (QName *)PR_NEXT_LINK( &qnp->link );
+        } while( qnp != (QName *)PR_LIST_HEAD( &qNameList ));
+    }
+    /*
+    ** If we did not find a matching QName,
+    **    allocate one and initialize it.
+    **    link it onto the qNameList.
+    **
+    */
+    if ( matchQname != PR_TRUE )
+    {
+        qnp = PR_NEWZAP( QName );
+        PR_ASSERT( qnp != NULL );
+        PR_INIT_CLIST( &qnp->link ); 
+        PR_INIT_CLIST( &qnp->rNameList ); 
+        strcpy( qnp->name, qName );
+        PR_APPEND_LINK( &qnp->link, &qNameList ); 
+    }
+
+    /* Do we already have a matching RName? */
+    if (!PR_CLIST_IS_EMPTY( &qnp->rNameList ))
+    {
+        rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList );
+        do {
+            /*
+            ** No duplicate RNames are allowed within a QName
+            **
+            */
+            PR_ASSERT( strcmp(rnp->name, rName));
+            rnp = (RName *)PR_NEXT_LINK( &rnp->link );
+        } while( rnp != (RName *)PR_LIST_HEAD( &qnp->rNameList ));
+    }
+
+    /* Get a new RName structure; initialize its members */
+    rnp = PR_NEWZAP( RName );
+    PR_ASSERT( rnp != NULL );
+    PR_INIT_CLIST( &rnp->link );
+    strcpy( rnp->name, rName );
+    strcpy( rnp->desc, description );
+    rnp->lock = PR_NewLock();
+    rnp->state = Running;
+    if ( rnp->lock == NULL )
+    {
+        PR_ASSERT(0);
+    }
+
+    PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */    
+    rnp->qName = qnp;                       /* point the RName to the QName */
+
+    /* Unlock the Facility */
+    PR_Unlock( traceLock );
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Create: QName: %s %p, RName: %s %p\n\t",
+        qName, qnp, rName, rnp ));
+
+    return((PRTraceHandle)rnp);
+} /* end  PR_CreateTrace() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_DestroyTrace( 
+		PRTraceHandle handle    /* Handle to be destroyed */
+)
+{
+    RName   *rnp = (RName *)handle;
+    QName   *qnp = rnp->qName;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting: QName: %s, RName: %s", 
+        qnp->name, rnp->name));
+
+    /* Lock the Facility */
+    PR_Lock( traceLock );
+
+    /*
+    ** Remove RName from the list of RNames in QName
+    ** and free RName
+    */
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting RName: %s, %p", 
+        rnp->name, rnp));
+    PR_REMOVE_LINK( &rnp->link );
+    PR_Free( rnp->lock );
+    PR_DELETE( rnp );
+
+    /*
+    ** If this is the last RName within QName
+    **   remove QName from the qNameList and free it
+    */
+    if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) )
+    {
+        PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting unused QName: %s, %p", 
+            qnp->name, qnp));
+        PR_REMOVE_LINK( &qnp->link );
+        PR_DELETE( qnp );
+    } 
+
+    /* Unlock the Facility */
+    PR_Unlock( traceLock );
+    return;
+} /* end PR_DestroyTrace()  */
+
+/*
+** Create a TraceEntry in the trace buffer
+*/
+PR_IMPLEMENT(void) 
+	PR_Trace( 
+    	PRTraceHandle handle,       /* use this trace handle */
+	    PRUint32    userData0,      /* User supplied data word 0 */
+	    PRUint32    userData1,      /* User supplied data word 1 */
+	    PRUint32    userData2,      /* User supplied data word 2 */
+	    PRUint32    userData3,      /* User supplied data word 3 */
+	    PRUint32    userData4,      /* User supplied data word 4 */
+	    PRUint32    userData5,      /* User supplied data word 5 */
+	    PRUint32    userData6,      /* User supplied data word 6 */
+	    PRUint32    userData7       /* User supplied data word 7 */
+)
+{
+    PRTraceEntry   *tep;
+    PRInt32         mark;
+
+    if ( (traceState == Suspended ) 
+        || ( ((RName *)handle)->state == Suspended )) 
+        return;
+
+    /*
+    ** Get the next trace entry slot w/ minimum delay
+    */
+    PR_Lock( traceLock );
+
+    tep = &tBuf[next++]; 
+    if ( next > last )
+        next = 0;
+    if ( fetchLostData == PR_FALSE && next == fetchLastSeen )
+        fetchLostData = PR_TRUE;
+    
+    mark = next;
+        
+    PR_Unlock( traceLock );
+
+    /*
+    ** We have a trace entry. Fill it in.
+    */
+    tep->thread = PR_GetCurrentThread();
+    tep->handle = handle;
+    tep->time   = PR_Now();
+    tep->userData[0] = userData0;
+    tep->userData[1] = userData1;
+    tep->userData[2] = userData2;
+    tep->userData[3] = userData3;
+    tep->userData[4] = userData4;
+    tep->userData[5] = userData5;
+    tep->userData[6] = userData6;
+    tep->userData[7] = userData7;
+
+    /* When buffer segment is full, signal trace log thread to run */
+    if (( mark % logEntriesPerSegment) == 0 )
+    {
+        PR_Lock( logLock );
+        logCount++;
+        PR_NotifyCondVar( logCVar );
+        PR_Unlock( logLock );
+        /*
+        ** Gh0D! This is awful!
+        ** Anyway, to minimize lost trace data segments,
+        ** I inserted the PR_Sleep(0) to cause a context switch
+        ** so that the log thread could run.
+        ** I know, it perturbs the universe and may cause
+        ** funny things to happen in the optimized builds.
+        ** Take it out, loose data; leave it in risk Heisenberg.
+        */
+        /* PR_Sleep(0); */
+    }
+
+    return;
+} /* end PR_Trace() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_SetTraceOption( 
+	    PRTraceOption command,  /* One of the enumerated values */
+	    void *value             /* command value or NULL */
+)
+{
+    RName * rnp;
+
+    switch ( command )
+    {
+        case PRTraceBufSize :
+            PR_Lock( traceLock );
+            PR_Free( tBuf );
+            bufSize = *(PRInt32 *)value;
+            NewTraceBuffer( bufSize );
+            PR_Unlock( traceLock );
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceBufSize: %ld", bufSize));
+            break;
+        
+        case PRTraceEnable :
+            rnp = *(RName **)value;
+            rnp->state = Running;
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceEnable: %p", rnp));
+            break;
+        
+        case PRTraceDisable :
+            rnp = *(RName **)value;
+            rnp->state = Suspended;
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceDisable: %p", rnp));
+            break;
+        
+        case PRTraceSuspend :
+            traceState = Suspended;
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceSuspend"));
+            break;
+        
+        case PRTraceResume :
+            traceState = Running;
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceResume"));
+            break;
+        
+        case PRTraceSuspendRecording :
+            PR_Lock( logLock );
+            logOrder = LogSuspend;
+            PR_NotifyCondVar( logCVar );
+            PR_Unlock( logLock );
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceSuspendRecording"));
+            break;
+        
+        case PRTraceResumeRecording :
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceResumeRecording"));
+            if ( logState != LogSuspend )
+                break;
+            PR_Lock( logLock );
+            logOrder = LogResume;
+            PR_NotifyCondVar( logCVar );
+            PR_Unlock( logLock );
+            break;
+        
+        case PRTraceStopRecording :
+            PR_Lock( logLock );
+            logOrder = LogStop;
+            PR_NotifyCondVar( logCVar );
+            PR_Unlock( logLock );
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceStopRecording"));
+            break;
+
+        case PRTraceLockHandles :
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceLockTraceHandles"));
+            PR_Lock( traceLock );
+            break;
+        
+        case PRTraceUnLockHandles :
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRSetTraceOption: PRTraceUnLockHandles"));
+            PR_Lock( traceLock );
+            break;
+
+        default:
+            PR_LOG( lm, PR_LOG_ERROR,
+                ("PRSetTraceOption: Invalid command %ld", command ));
+            PR_ASSERT( 0 );
+            break;
+    } /* end switch() */
+    return;
+} /* end  PR_SetTraceOption() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_GetTraceOption( 
+    	PRTraceOption command,  /* One of the enumerated values */
+	    void *value             /* command value or NULL */
+)
+{
+    switch ( command )
+    {
+        case PRTraceBufSize :
+            *((PRInt32 *)value) = bufSize;
+            PR_LOG( lm, PR_LOG_DEBUG,
+                ("PRGetTraceOption: PRTraceBufSize: %ld", bufSize ));
+            break;
+        
+        default:
+            PR_LOG( lm, PR_LOG_ERROR,
+                ("PRGetTraceOption: Invalid command %ld", command ));
+            PR_ASSERT( 0 );
+            break;
+    } /* end switch() */
+    return;
+} /* end PR_GetTraceOption() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRTraceHandle) 
+	PR_GetTraceHandleFromName( 
+    	const char *qName,      /* QName search argument */
+        const char *rName       /* RName search argument */
+)
+{
+    const char    *qn, *rn, *desc;
+    PRTraceHandle     qh, rh = NULL;
+    RName   *rnp = NULL;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetTraceHandleFromName:\n\t"
+        "QName: %s, RName: %s", qName, rName ));
+
+    qh = PR_FindNextTraceQname( NULL );
+    while (qh != NULL)
+    {
+        rh = PR_FindNextTraceRname( NULL, qh );
+        while ( rh != NULL )
+        {
+            PR_GetTraceNameFromHandle( rh, &qn, &rn, &desc );
+            if ( (strcmp( qName, qn ) == 0)
+                && (strcmp( rName, rn ) == 0 ))
+            {
+                rnp = (RName *)rh;
+                goto foundIt;
+            }
+            rh = PR_FindNextTraceRname( rh, qh );
+        }
+        qh = PR_FindNextTraceQname( NULL );
+    }
+
+foundIt:
+    PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp ));
+    return(rh);
+} /* end PR_GetTraceHandleFromName() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void) 
+	PR_GetTraceNameFromHandle( 
+    	PRTraceHandle handle,       /* handle as search argument */
+	    const char **qName,         /* pointer to associated QName */
+	    const char **rName,         /* pointer to associated RName */
+    	const char **description    /* pointer to associated description */
+)
+{
+    RName   *rnp = (RName *)handle;
+    QName   *qnp = rnp->qName;
+
+    *qName = qnp->name;
+    *rName = rnp->name;
+    *description = rnp->desc;
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetConterNameFromHandle: "
+        "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", 
+        qnp, rnp, qnp->name, rnp->name, rnp->desc ));
+
+    return;
+} /* end PR_GetTraceNameFromHandle() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRTraceHandle) 
+	PR_FindNextTraceQname( 
+        PRTraceHandle handle
+)
+{
+    QName *qnp = (QName *)handle;
+
+    if ( PR_CLIST_IS_EMPTY( &qNameList ))
+            qnp = NULL;
+    else if ( qnp == NULL )
+        qnp = (QName *)PR_LIST_HEAD( &qNameList );
+    else if ( PR_NEXT_LINK( &qnp->link ) ==  &qNameList )
+        qnp = NULL;
+    else  
+        qnp = (QName *)PR_NEXT_LINK( &qnp->link );
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextQname: Handle: %p, Returns: %p", 
+        handle, qnp ));
+
+    return((PRTraceHandle)qnp);
+} /* end PR_FindNextTraceQname() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRTraceHandle) 
+	PR_FindNextTraceRname( 
+        PRTraceHandle rhandle,
+        PRTraceHandle qhandle
+)
+{
+    RName *rnp = (RName *)rhandle;
+    QName *qnp = (QName *)qhandle;
+
+
+    if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ))
+        rnp = NULL;
+    else if ( rnp == NULL )
+        rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList );
+    else if ( PR_NEXT_LINK( &rnp->link ) ==  &qnp->rNameList )
+        rnp = NULL;
+    else
+        rnp = (RName *)PR_NEXT_LINK( &rnp->link );
+
+    PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", 
+        rhandle, qhandle, rnp ));
+
+    return((PRTraceHandle)rnp);
+} /* end PR_FindNextTraceRname() */
+    
+/*
+**
+*/
+static PRFileDesc * InitializeRecording( void )
+{
+    char    *logFileName;
+    PRFileDesc  *logFile;
+
+    /* Self initialize, if necessary */
+    if ( traceLock == NULL )
+        _PR_InitializeTrace();
+
+    PR_LOG( lm, PR_LOG_DEBUG,
+        ("PR_RecordTraceEntries: begins"));
+
+    logLostData = 0; /* reset at entry */
+    logState = LogReset;
+
+    /* Get the filename for the logfile from the environment */
+    logFileName = PR_GetEnv( "NSPR_TRACE_LOG" );
+    if ( logFileName == NULL )
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("RecordTraceEntries: Environment variable not defined. Exiting"));
+        return NULL;
+    }
+    
+    /* Open the logfile */
+    logFile = PR_Open( logFileName, PR_WRONLY | PR_CREATE_FILE, 0666 );
+    if ( logFile == NULL )
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("RecordTraceEntries: Cannot open %s as trace log file. OS error: %ld", 
+		logFileName, PR_GetOSError()));
+        return NULL;
+    }
+    return logFile;
+} /* end InitializeRecording() */
+
+/*
+**
+*/
+static void ProcessOrders( void )
+{
+    switch ( logOrder )
+    {
+    case LogReset :
+        logOrder = logState = localState;
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("RecordTraceEntries: LogReset"));
+        break;
+
+    case LogSuspend :
+        localState = logOrder = logState = LogSuspend;
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("RecordTraceEntries: LogSuspend"));
+        break;
+
+    case LogResume :
+        localState = logOrder = logState = LogActive;
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("RecordTraceEntries: LogResume"));
+        break;
+
+    case LogStop :
+        logOrder = logState = LogStop;
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("RecordTraceEntries: LogStop"));
+        break;
+
+    default :
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("RecordTraceEntries: Invalid logOrder: %ld", logOrder ));
+        PR_ASSERT( 0 );
+        break;
+    } /* end switch() */
+    return ;
+} /* end ProcessOrders() */
+
+/*
+**
+*/
+static void WriteTraceSegment( PRFileDesc *logFile, void *buf, PRInt32 amount )
+{
+    PRInt32 rc;
+
+
+    PR_LOG( lm, PR_LOG_ERROR,
+        ("WriteTraceSegment: Buffer: %p, Amount: %ld", buf, amount));
+    rc = PR_Write( logFile, buf , amount );
+    if ( rc == -1 )
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("RecordTraceEntries: PR_Write() failed. Error: %ld", PR_GetError() ));
+    else if ( rc != amount )
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("RecordTraceEntries: PR_Write() Tried to write: %ld, Wrote: %ld", amount, rc));
+    else 
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("RecordTraceEntries: PR_Write(): Buffer: %p, bytes: %ld", buf, amount));
+
+    return;
+} /* end WriteTraceSegment() */
+
+/*
+**
+*/
+PR_IMPLEMENT(void)
+	PR_RecordTraceEntries(
+        void 
+)
+{
+    PRFileDesc  *logFile;
+    PRInt32     lostSegments;
+    PRInt32     currentSegment = 0;
+    void        *buf;
+    PRBool      doWrite;
+
+    logFile = InitializeRecording();
+    if ( logFile == NULL )
+    {
+        PR_LOG( lm, PR_LOG_DEBUG,
+            ("PR_RecordTraceEntries: Failed to initialize"));
+        return;
+    }
+
+    /* Do this until told to stop */
+    while ( logState != LogStop )
+    {
+
+        PR_Lock( logLock );
+
+        while ( (logCount == 0) && ( logOrder == logState ) )
+            PR_WaitCondVar( logCVar, PR_INTERVAL_NO_TIMEOUT );
+
+        /* Handle state transitions */
+        if ( logOrder != logState )
+            ProcessOrders();
+
+        /* recalculate local controls */
+        if ( logCount )
+        {
+            lostSegments = logCount - logSegments;
+            if ( lostSegments > 0 )
+            {
+                logLostData += ( logCount - logSegments );
+                logCount = (logCount % logSegments);
+                currentSegment = logCount;
+                PR_LOG( lm, PR_LOG_DEBUG,
+                    ("PR_RecordTraceEntries: LostData segments: %ld", logLostData));
+            }
+            else
+            {
+                logCount--;
+            }
+
+            buf = tBuf + ( logEntriesPerSegment * currentSegment );
+            if (++currentSegment >= logSegments )
+                currentSegment = 0;
+            doWrite = PR_TRUE;
+        }
+        else
+            doWrite = PR_FALSE;
+
+        PR_Unlock( logLock );
+
+        if ( doWrite == PR_TRUE )
+        {
+            if ( localState != LogSuspend )
+                WriteTraceSegment( logFile, buf, logSegSize );
+            else
+                PR_LOG( lm, PR_LOG_DEBUG,
+                    ("RecordTraceEntries: PR_Write(): is suspended" ));
+        }
+
+    } /* end while(logState...) */
+
+    PR_Close( logFile );
+    PR_LOG( lm, PR_LOG_DEBUG,
+        ("RecordTraceEntries: exiting"));
+    return;
+} /* end  PR_RecordTraceEntries() */
+
+/*
+**
+*/
+PR_IMPLEMENT(PRIntn)
+    PR_GetTraceEntries(
+        PRTraceEntry    *buffer,    /* where to write output */
+        PRInt32         count,      /* number to get */
+        PRInt32         *found      /* number you got */
+)
+{
+    PRInt32 rc; 
+    PRInt32 copied = 0;
+    
+    PR_Lock( traceLock );
+    
+    /*
+    ** Depending on where the LastSeen and Next indices are,
+    ** copy the trace buffer in one or two pieces. 
+    */
+    PR_LOG( lm, PR_LOG_ERROR,
+        ("PR_GetTraceEntries: Next: %ld, LastSeen: %ld", next, fetchLastSeen));
+
+    if ( fetchLastSeen <= next )
+    {
+        while (( count-- > 0 ) && (fetchLastSeen < next ))
+        {
+            *(buffer + copied++) = *(tBuf + fetchLastSeen++);
+        }
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen));
+    }
+    else /* copy in 2 parts */
+    {
+        while ( count-- > 0  && fetchLastSeen <= last )
+        {
+            *(buffer + copied++) = *(tBuf + fetchLastSeen++);
+        }
+        fetchLastSeen = 0;
+
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen));
+
+        while ( count-- > 0  && fetchLastSeen < next )
+        {
+            *(buffer + copied++) = *(tBuf + fetchLastSeen++);
+        }
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen));
+    }
+
+    *found = copied;
+    rc = ( fetchLostData == PR_TRUE )? 1 : 0;
+    fetchLostData = PR_FALSE;
+
+    PR_Unlock( traceLock );
+    return rc;
+} /* end PR_GetTraceEntries() */
+
+/* end prtrace.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/nspr.def
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/nspr.def	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,467 @@
+;+#
+;+# ***** 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) 2002-2003
+;+# 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 *****
+;+#
+;+# 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 nspr4 ;-
+EXPORTS ;-
+		LL_MaxInt;
+		LL_MinInt;
+		LL_Zero;
+		PR_Abort;
+		PR_AddToCounter;
+		PR_Accept;
+		PR_AcceptRead;
+		PR_Access;
+		PR_AddWaitFileDesc;
+		PR_AllocFileDesc;
+		PR_Assert;
+		PR_AtomicAdd;
+		PR_AtomicDecrement;
+		PR_AtomicIncrement;
+		PR_AtomicSet;
+		PR_AttachSharedMemory;
+		PR_AttachThread;
+		PR_Available;
+		PR_Available64;
+		PR_Bind;
+		PR_BlockClockInterrupts;
+		PR_BlockInterrupt;
+		PR_CEnterMonitor;
+		PR_CExitMonitor;
+		PR_CNotify;
+		PR_CNotifyAll;
+		PR_CSetOnMonitorRecycle;
+		PR_CWait;
+		PR_CallOnce;
+		PR_Calloc;
+		PR_CancelJob;
+		PR_CancelWaitFileDesc;
+		PR_CancelWaitGroup;
+		PR_CeilingLog2;
+		PR_ChangeFileDescNativeHandle;
+		PR_Cleanup;
+		PR_ClearInterrupt;
+		PR_ClearThreadGCAble;
+		PR_Close;
+		PR_CloseDir;
+		PR_CloseFileMap;
+		PR_CloseSemaphore;
+		PR_CloseSharedMemory;
+		PR_Connect;
+		PR_CreateCounter;
+		PR_ConvertIPv4AddrToIPv6;
+		PR_CreateAlarm;
+		PR_CreateFileMap;
+		PR_CreateIOLayerStub;
+		PR_CreateOrderedLock;
+		PR_CreateMWaitEnumerator;
+		PR_CreatePipe;
+		PR_CreateProcess;
+		PR_CreateProcessDetached;
+		PR_CreateSocketPollFd;
+		PR_CreateStack;
+		PR_CreateThread;
+		PR_CreateThreadGCAble;
+		PR_CreateTrace;
+		PR_CreateThreadPool;
+		PR_DecrementCounter;
+		PR_CreateWaitGroup;
+		PR_Delete;
+		PR_DeleteSemaphore;
+		PR_DeleteSharedMemory;
+		PR_DestroyAlarm;
+		PR_DestroyCounter;
+		PR_DestroyCondVar;
+		PR_DestroyLock;
+		PR_DestroyMWaitEnumerator;
+		PR_DestroyOrderedLock;
+		PR_DestroyMonitor;
+		PR_DestroyPollableEvent;
+		PR_DestroyProcessAttr;
+		PR_DestroyRWLock;
+		PR_DestroySem;
+		PR_DestroySocketPollFd;
+		PR_DestroyTrace;
+		PR_DestroyStack;
+		PR_DestroyWaitGroup;
+		PR_DetachProcess;
+		PR_DetachSharedMemory;
+		PR_DetachThread;
+		PR_DisableClockInterrupts;
+		PR_EnableClockInterrupts;
+		PR_EnterMonitor;
+		PR_EnumerateHostEnt;
+		PR_EnumerateThreads;
+		PR_EnumerateWaitGroup;
+		PR_ErrorInstallCallback;
+		PR_ErrorInstallTable;
+		PR_ErrorLanguages;
+		PR_ErrorToName;
+		PR_ErrorToString;
+		PR_ExitMonitor;
+		PR_ExplodeTime;
+		PR_ExportFileMapAsString;
+		PR_FD_CLR;
+		PR_FD_ISSET;
+		PR_FD_NCLR;
+		PR_FD_NISSET;
+		PR_FD_NSET;
+		PR_FD_SET;
+		PR_FD_ZERO;
+		PR_FileDesc2NativeHandle;
+		PR_FindSymbol;
+		PR_FindSymbolAndLibrary;
+		PR_FloorLog2;
+		PR_FormatTime;
+		PR_FindNextCounterQname;
+		PR_FindNextCounterRname;
+		PR_FindNextTraceQname;
+		PR_FindNextTraceRname;
+		PR_FormatTimeUSEnglish;
+		PR_Free;
+		PR_FreeLibraryName;
+		PR_GMTParameters;
+		PR_GetConnectStatus;
+		PR_GetCurrentThread;
+		PR_GetDefaultIOMethods;
+		PR_GetDescType;
+		PR_GetDirectorySeparator;
+		PR_GetCounter;
+		PR_GetCounterHandleFromName;
+		PR_GetCounterNameFromHandle;
+		PR_GetDirectorySepartor;
+		PR_GetEnv;
+		PR_GetError;
+		PR_GetErrorText;
+		PR_GetErrorTextLength;
+		PR_GetFileInfo;
+		PR_GetFileInfo64;
+		PR_GetFileMethods;
+		PR_GetGCRegisters;
+		PR_GetHostByAddr;
+		PR_GetHostByName;
+		PR_GetIPNodeByName;
+		PR_GetIdentitiesLayer;
+		PR_GetInheritedFD;
+		PR_GetInheritedFileMap;
+		PR_GetLayersIdentity;
+		PR_GetLibraryName;
+		PR_GetLibraryPath;
+		PR_GetMonitorEntryCount;
+		PR_GetNameForIdentity;
+		PR_GetOSError;
+		PR_GetOpenFileInfo;
+		PR_GetOpenFileInfo64;
+		PR_GetPageShift;
+		PR_GetPageSize;
+		PR_GetPeerName;
+		PR_GetPipeMethods;
+		PR_GetProtoByName;
+		PR_GetProtoByNumber;
+		PR_GetRandomNoise;
+		PR_GetSP;
+		PR_GetSockName;
+		PR_GetSocketOption;
+		PR_GetSpecialFD;
+		PR_GetStackSpaceLeft;
+		PR_GetSysfdTableMax;
+		PR_GetSystemInfo;
+		PR_GetTCPMethods;
+		PR_GetThreadAffinityMask;
+		PR_GetThreadID;
+		PR_GetThreadPriority;
+		PR_GetThreadPrivate;
+		PR_GetThreadScope;
+		PR_GetThreadState;
+		PR_GetThreadType;
+		PR_GetUDPMethods;
+		PR_GetUniqueIdentity;
+		PR_ImplodeTime;
+		PR_ImportFile;
+		PR_ImportFileMapFromString;
+		PR_ImportTCPSocket;
+		PR_ImportUDPSocket;
+		PR_GetTraceEntries;
+		PR_GetTraceHandleFromName;
+		PR_GetTraceNameFromHandle;
+		PR_GetTraceOption;
+		PR_Init;
+		PR_Initialize;
+		PR_InitializeNetAddr;
+		PR_Initialized;
+		PR_Interrupt;
+		PR_IntervalNow;
+		PR_IntervalToMicroseconds;
+		PR_IntervalToMilliseconds;
+		PR_IncrementCounter;
+		PR_IntervalToSeconds;
+		PR_IsNetAddrType;
+		PR_JoinJob;
+		PR_JoinThread;
+		PR_JoinThreadPool;
+		PR_KillProcess;
+		PR_Listen;
+		PR_LoadLibrary;
+		PR_LoadLibraryWithFlags;
+		PR_LoadStaticLibrary;
+		PR_LocalTimeParameters;
+		PR_Lock;
+		PR_LockFile;
+		PR_LogFlush;
+		PR_LogPrint;
+		PR_MakeDir;
+		PR_Malloc;
+		PR_MemMap;
+		PR_MemUnmap;
+		PR_MicrosecondsToInterval;
+		PR_MillisecondsToInterval;
+		PR_LockOrderedLock;
+		PR_MkDir;
+		PR_NetAddrToString;
+		PR_NewCondVar;
+		PR_NewLock;
+		PR_NewLogModule;
+		PR_NewMonitor;
+		PR_NewNamedMonitor;
+		PR_NewPollableEvent;
+		PR_NewProcessAttr;
+		PR_NewRWLock;
+		PR_NewSem;
+		PR_NewTCPSocket;
+		PR_NewTCPSocketPair;
+		PR_NewThreadPrivateIndex;
+		PR_NewUDPSocket;
+		PR_NormalizeTime;
+		PR_Notify;
+		PR_NotifyAll;
+		PR_NotifyAllCondVar;
+		PR_NotifyCondVar;
+		PR_Now;
+		PR_Open;
+		PR_OpenAnonFileMap;
+		PR_OpenDir;
+		PR_OpenFile;
+		PR_OpenSemaphore;
+		PR_OpenSharedMemory;
+		PR_OpenTCPSocket;
+		PR_OpenUDPSocket;
+		PR_ParseTimeString;
+		PR_Poll;
+		PR_PopIOLayer;
+		PR_PostSem;
+		PR_PostSemaphore;
+		PR_ProcessAttrSetCurrentDirectory;
+		PR_ProcessAttrSetInheritableFD;
+		PR_ProcessAttrSetInheritableFileMap;
+		PR_ProcessAttrSetStdioRedirect;
+		PR_ProcessExit;
+		PR_PushIOLayer;
+		PR_QueueJob;
+		PR_QueueJob_Accept;
+		PR_QueueJob_Connect;
+		PR_QueueJob_Read;
+		PR_QueueJob_Timer;
+		PR_QueueJob_Write;
+		PR_RWLock_Rlock;
+		PR_RWLock_Unlock;
+		PR_RWLock_Wlock;
+		PR_Read;
+		PR_ReadDir;
+		PR_Realloc;
+		PR_Recv;
+		PR_RecvFrom;
+		PR_Rename;
+		PR_ResetAlarm;
+		PR_ResetProcessAttr;
+		PR_ResumeAll;
+		PR_RmDir;
+		PR_ScanStackPointers;
+		PR_RecordTraceEntries;
+		PR_SecondsToInterval;
+		PR_Seek;
+		PR_Seek64;
+		PR_Select;
+		PR_Send;
+		PR_SendFile;
+		PR_SendTo;
+		PR_SetAlarm;
+		PR_SetConcurrency;
+		PR_SetError;
+		PR_SetErrorText;
+		PR_SetFDCacheSize;
+		PR_SetFDInheritable;
+		PR_SetLibraryPath;
+		PR_SetLogBuffering;
+		PR_SetLogFile;
+		PR_SetNetAddr;
+		PR_SetPollableEvent;
+		PR_SetSocketOption;
+		PR_SetCounter;
+		PR_SetStdioRedirect;
+		PR_SetSysfdTableSize;
+		PR_SetThreadAffinityMask;
+		PR_SetThreadDumpProc;
+		PR_SetThreadGCAble;
+		PR_SetThreadPriority;
+		PR_SetThreadPrivate;
+		PR_SetThreadRecycleMode;
+		PR_Shutdown;
+		PR_ShutdownThreadPool;
+		PR_Sleep;
+		PR_Socket;
+		PR_StackPop;
+		PR_StackPush;
+		PR_Stat;
+		PR_StringToNetAddr;
+		PR_SuspendAll;
+		PR_Sync;
+		PR_TLockFile;
+		PR_ThreadScanStackPointers;
+		PR_SetTraceOption;
+		PR_TicksPerSecond;
+		PR_TransmitFile;
+		PR_USPacificTimeParameters;
+		PR_UnblockClockInterrupts;
+		PR_UnblockInterrupt;
+		PR_UnloadLibrary;
+		PR_SubtractFromCounter;
+		PR_Unlock;
+		PR_UnlockFile;
+		PR_VersionCheck;
+		PR_Wait;
+		PR_WaitCondVar;
+		PR_WaitForPollableEvent;
+		PR_Trace;
+		PR_WaitProcess;
+		PR_WaitRecvReady;
+		PR_WaitSem;
+		PR_WaitSemaphore;
+		PR_Write;
+		PR_Writev;
+		PR_Yield;
+		PR_UnlockOrderedLock;
+		PR_cnvtf;
+		PR_dtoa;
+		PR_fprintf;
+		PR_htonl;
+		PR_htonll;
+		PR_htons;
+		PR_ntohl;
+		PR_ntohll;
+		PR_ntohs;
+		PR_smprintf;
+		PR_smprintf_free;
+		PR_snprintf;
+		PR_sprintf_append;
+		PR_sscanf;
+		PR_strtod;
+		PR_sxprintf;
+		PR_vfprintf;
+		PR_vsmprintf;
+		PR_vsnprintf;
+		PR_vsprintf_append;
+		PR_vsxprintf;
+		PRP_DestroyNakedCondVar;
+		PRP_NakedBroadcast;
+		PRP_NakedNotify;
+		PRP_NakedWait;
+		PRP_NewNakedCondVar;
+		PRP_TryLock;
+		libVersionPoint;
+;+	local: *;
+;+};
+;+
+;+NSPRprivate {
+;+	global:
+		GetExecutionEnvironment;
+		PT_FPrintStats;
+		SetExecutionEnvironment;
+;+	local: *;
+;+};
+;+
+;+NSPR_4.1 {
+;+	global:
+		PR_ConnectContinue;
+		PR_CreateIOLayer;
+		PR_EmulateAcceptRead;
+		PR_EmulateSendFile;
+		PR_FindFunctionSymbol;
+		PR_FindFunctionSymbolAndLibrary;
+		PR_GetMemMapAlignment;
+		PR_GetNumberOfProcessors;
+		PR_ImportPipe;
+		PR_SetEnv;
+;+} NSPR_4.0;
+;+
+;+NSPR_4.3 {
+;+	global:
+		LL_MaxUint;
+		PR_CallOnceWithArg;
+		PR_GetLibraryFilePathname;
+;+} NSPR_4.1;
+;+
+;+NSPR_4.4 {
+;+	global:
+		PR_GetPathSeparator;
+;+} NSPR_4.3;
+;+
+;+NSPR_4.5 {
+;+	global:
+		PR_EnumerateAddrInfo;
+		PR_FreeAddrInfo;
+		PR_GetAddrInfoByName;
+		PR_GetCanonNameFromAddrInfo;
+;+} NSPR_4.4;
+;+
+;+NSPR_4.6 {
+;+	global:
+		PR_GetPhysicalMemorySize;
+;+} NSPR_4.5;

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/nspr.rc
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/nspr.rc	Mon Dec 18 10:53:47 2006
@@ -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) 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 <winver.h>
+
+#define MY_LIBNAME "nspr"
+#define MY_FILEDESCRIPTION "NSPR 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

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/nspr_symvec.opt
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/nspr_symvec.opt	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,503 @@
+! Fixed section of symbol vector for LIBNSPR4 (non-debug)
+!
+GSMATCH=LEQUAL,2,8
+case_sensitive=YES
+!
+! --------------------------------------------------------------------------
+! Ident 2,1 introduced for Mozilla 0.9.4
+! Based on NSPR 4.1.2
+! --------------------------------------------------------------------------
+! Ident 2,2 introduced for Mozilla 1.2
+! Based on NSPR 4.2.2?
+! PR_ResumeSet, PR_ResumeTest, and PR_SuspendAllSuspended has been "removed".
+! Only we can't remove the entry points because OJI is linked against NSPR so
+! we have to make an upwardly compatible change:
+!   PR_ResumeSet is now PR_VMS_Stub1
+!   PR_ResumeTest is now PR_VMS_Stub2
+!   PR_SuspendAllSuspended is PR_VMS_Stub3
+! These are stub functions (defined in openvms.c) solely for the purpose of
+! occupying the slots in our fixed section of the symbol table. 
+! --------------------------------------------------------------------------
+! Ident 2,3 introduced for Mozilla 1.3
+! Previously we were missing some symbols from NSPR 4.0 and 4.1, so now we
+! include everything that's specified in nspr.def.
+! --------------------------------------------------------------------------
+! Ident 2,4 introduced for Mozilla 1.3 final.
+! 2,3 was still missing some symbols, in particular PR_CreateThread, which
+! is used by OJI. So insert stubs to force the PR_CreateThread entry down
+! to its Mozilla 1.1 (and Java 1.4-0) location so that everyone can play
+! together and be happy.
+! --------------------------------------------------------------------------
+! Ident 2,5 introduced for post Mozilla 1.3.
+! LL_MaxUint introduced. Replaces Stub54.
+! --------------------------------------------------------------------------
+! Ident 2,6 introduced for post Mozilla 1.4.
+! PR_GetPathSeparator introduced in NSPR 4.4.
+! This replaces stub 53
+! --------------------------------------------------------------------------
+! Ident 2,7 introduced for post Mozilla 1.4.
+! PR_GetAddrInfoByName, PR_FreeAddrInfo, PR_EnumerateAddrInfo and
+! PR_GetCanonNameFromAddrInfo introduced in NSPR 4.5.
+! These replace stubs 49-52
+! --------------------------------------------------------------------------
+! Ident 2,8 introduced for NSPR 4.6.
+! PR_FindLibrary removed. Replaced by PR_GetPhysicalMemorySize.
+! --------------------------------------------------------------------------
+!
+SYMBOL_VECTOR=(PR_Accept=PROCEDURE)
+SYMBOL_VECTOR=(PR_AcceptRead=PROCEDURE)
+SYMBOL_VECTOR=(PR_Access=PROCEDURE)
+SYMBOL_VECTOR=(PR_AllocFileDesc=PROCEDURE)
+SYMBOL_VECTOR=(PR_Assert=PROCEDURE)
+SYMBOL_VECTOR=(PR_AtomicAdd=PROCEDURE)
+SYMBOL_VECTOR=(PR_AtomicDecrement=PROCEDURE)
+SYMBOL_VECTOR=(PR_AtomicSet=PROCEDURE)
+SYMBOL_VECTOR=(PR_AttachSharedMemory=PROCEDURE)
+SYMBOL_VECTOR=(PR_AttachThread=PROCEDURE)
+SYMBOL_VECTOR=(PR_Available64=PROCEDURE)
+SYMBOL_VECTOR=(PR_Available=PROCEDURE)
+SYMBOL_VECTOR=(PR_Bind=PROCEDURE)
+SYMBOL_VECTOR=(PR_BlockClockInterrupts=PROCEDURE)
+SYMBOL_VECTOR=(PR_BlockInterrupt=PROCEDURE)
+SYMBOL_VECTOR=(PR_CExitMonitor=PROCEDURE)
+SYMBOL_VECTOR=(PR_CNotify=PROCEDURE)
+SYMBOL_VECTOR=(PR_CNotifyAll=PROCEDURE)
+SYMBOL_VECTOR=(PR_CSetOnMonitorRecycle=PROCEDURE)
+SYMBOL_VECTOR=(PR_CWait=PROCEDURE)
+SYMBOL_VECTOR=(PR_CallOnce=PROCEDURE)
+SYMBOL_VECTOR=(PR_Calloc=PROCEDURE)
+SYMBOL_VECTOR=(PR_CancelJob=PROCEDURE)
+SYMBOL_VECTOR=(PR_CancelWaitFileDesc=PROCEDURE)
+SYMBOL_VECTOR=(PR_CancelWaitGroup=PROCEDURE)
+SYMBOL_VECTOR=(PR_ChangeFileDescNativeHandle=PROCEDURE)
+SYMBOL_VECTOR=(PR_Cleanup=PROCEDURE)
+SYMBOL_VECTOR=(PR_ClearInterrupt=PROCEDURE)
+SYMBOL_VECTOR=(PR_ClearThreadGCAble=PROCEDURE)
+SYMBOL_VECTOR=(PR_Close=PROCEDURE)
+SYMBOL_VECTOR=(PR_CloseDir=PROCEDURE)
+SYMBOL_VECTOR=(PR_CloseFileMap=PROCEDURE)
+SYMBOL_VECTOR=(PR_CloseSemaphore=PROCEDURE)
+SYMBOL_VECTOR=(PR_CloseSharedMemory=PROCEDURE)
+SYMBOL_VECTOR=(PR_Connect=PROCEDURE)
+SYMBOL_VECTOR=(PR_ConnectContinue=PROCEDURE)
+SYMBOL_VECTOR=(PR_ConvertIPv4AddrToIPv6=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateIOLayer=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateIOLayerStub=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateMWaitEnumerator=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreatePipe=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateProcess=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateProcessDetached=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateSocketPollFd=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateStack=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateThreadGCAble=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateWaitGroup=PROCEDURE)
+SYMBOL_VECTOR=(PR_Delete=PROCEDURE)
+SYMBOL_VECTOR=(PR_DeleteSemaphore=PROCEDURE)
+SYMBOL_VECTOR=(PR_DeleteSharedMemory=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyAlarm=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyCondVar=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyLock=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyMWaitEnumerator=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyMonitor=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyPollableEvent=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyProcessAttr=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyRWLock=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroySem=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroySocketPollFd=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyStack=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyWaitGroup=PROCEDURE)
+SYMBOL_VECTOR=(PR_DetachProcess=PROCEDURE)
+SYMBOL_VECTOR=(PR_DetachSharedMemory=PROCEDURE)
+SYMBOL_VECTOR=(PR_DetachThread=PROCEDURE)
+SYMBOL_VECTOR=(PR_DisableClockInterrupts=PROCEDURE)
+SYMBOL_VECTOR=(PR_EmulateAcceptRead=PROCEDURE)
+SYMBOL_VECTOR=(PR_EmulateSendFile=PROCEDURE)
+SYMBOL_VECTOR=(PR_EnableClockInterrupts=PROCEDURE)
+SYMBOL_VECTOR=(PR_EnterMonitor=PROCEDURE)
+SYMBOL_VECTOR=(PR_EnumerateHostEnt=PROCEDURE)
+SYMBOL_VECTOR=(PR_EnumerateThreads=PROCEDURE)
+SYMBOL_VECTOR=(PR_EnumerateWaitGroup=PROCEDURE)
+SYMBOL_VECTOR=(PR_ErrorInstallCallback=PROCEDURE)
+SYMBOL_VECTOR=(PR_ErrorInstallTable=PROCEDURE)
+SYMBOL_VECTOR=(PR_ErrorLanguages=PROCEDURE)
+SYMBOL_VECTOR=(PR_ErrorToName=PROCEDURE)
+SYMBOL_VECTOR=(PR_ExitMonitor=PROCEDURE)
+SYMBOL_VECTOR=(PR_ExportFileMapAsString=PROCEDURE)
+SYMBOL_VECTOR=(PR_FD_CLR=PROCEDURE)
+SYMBOL_VECTOR=(PR_FD_ISSET=PROCEDURE)
+SYMBOL_VECTOR=(PR_FD_NCLR=PROCEDURE)
+SYMBOL_VECTOR=(PR_FD_NISSET=PROCEDURE)
+SYMBOL_VECTOR=(PR_FD_NSET=PROCEDURE)
+SYMBOL_VECTOR=(PR_FD_SET=PROCEDURE)
+SYMBOL_VECTOR=(PR_FD_ZERO=PROCEDURE)
+SYMBOL_VECTOR=(PR_FileDesc2NativeHandle=PROCEDURE)
+SYMBOL_VECTOR=(PR_FindFunctionSymbol=PROCEDURE)
+SYMBOL_VECTOR=(PR_FindFunctionSymbolAndLibrary=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetPhysicalMemorySize=PROCEDURE)
+SYMBOL_VECTOR=(PR_FindSymbol=PROCEDURE)
+SYMBOL_VECTOR=(PR_FindSymbolAndLibrary=PROCEDURE)
+SYMBOL_VECTOR=(PR_FloorLog2=PROCEDURE)
+SYMBOL_VECTOR=(PR_FormatTime=PROCEDURE)
+SYMBOL_VECTOR=(PR_FormatTimeUSEnglish=PROCEDURE)
+SYMBOL_VECTOR=(PR_Free=PROCEDURE)
+SYMBOL_VECTOR=(PR_FreeLibraryName=PROCEDURE)
+SYMBOL_VECTOR=(PR_GMTParameters=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetConnectStatus=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetCurrentThread=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetDefaultIOMethods=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetDirectorySepartor=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetError=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetErrorText=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetErrorTextLength=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetFileInfo64=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetFileInfo=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetFileMethods=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetHostByAddr=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetHostByName=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetIPNodeByName=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetIdentitiesLayer=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetInheritedFD=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetInheritedFileMap=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetLayersIdentity=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetLibraryName=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetLibraryPath=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetMemMapAlignment=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetMonitorEntryCount=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetNameForIdentity=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetNumberOfProcessors=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetOSError=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetOpenFileInfo64=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetOpenFileInfo=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetPageShift=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetPeerName=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetPipeMethods=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetProtoByName=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetProtoByNumber=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetSP=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetSockName=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetSocketOption=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetStackSpaceLeft=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetSysfdTableMax=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetSystemInfo=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetTCPMethods=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetThreadAffinityMask=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetThreadID=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetThreadPriority=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetThreadPrivate=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetThreadScope=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetThreadState=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetThreadType=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetUDPMethods=PROCEDURE)
+SYMBOL_VECTOR=(PR_ImplodeTime=PROCEDURE)
+SYMBOL_VECTOR=(PR_ImportFile=PROCEDURE)
+SYMBOL_VECTOR=(PR_ImportFileMapFromString=PROCEDURE)
+SYMBOL_VECTOR=(PR_ImportPipe=PROCEDURE)
+SYMBOL_VECTOR=(PR_ImportTCPSocket=PROCEDURE)
+SYMBOL_VECTOR=(PR_ImportUDPSocket=PROCEDURE)
+SYMBOL_VECTOR=(PR_Init=PROCEDURE)
+SYMBOL_VECTOR=(PR_Initialize=PROCEDURE)
+SYMBOL_VECTOR=(PR_InitializeNetAddr=PROCEDURE)
+SYMBOL_VECTOR=(PR_Initialized=PROCEDURE)
+SYMBOL_VECTOR=(PR_Interrupt=PROCEDURE)
+SYMBOL_VECTOR=(PR_IntervalToMicroseconds=PROCEDURE)
+SYMBOL_VECTOR=(PR_IntervalToMilliseconds=PROCEDURE)
+SYMBOL_VECTOR=(PR_IntervalToSeconds=PROCEDURE)
+SYMBOL_VECTOR=(PR_IsNetAddrType=PROCEDURE)
+SYMBOL_VECTOR=(PR_JoinJob=PROCEDURE)
+SYMBOL_VECTOR=(PR_JoinThread=PROCEDURE)
+SYMBOL_VECTOR=(PR_JoinThreadPool=PROCEDURE)
+SYMBOL_VECTOR=(PR_KillProcess=PROCEDURE)
+SYMBOL_VECTOR=(PR_Listen=PROCEDURE)
+SYMBOL_VECTOR=(PR_LoadLibrary=PROCEDURE)
+SYMBOL_VECTOR=(PR_LoadLibraryWithFlags=PROCEDURE)
+SYMBOL_VECTOR=(PR_LoadStaticLibrary=PROCEDURE)
+SYMBOL_VECTOR=(PR_LocalTimeParameters=PROCEDURE)
+SYMBOL_VECTOR=(PR_Lock=PROCEDURE)
+SYMBOL_VECTOR=(PR_LockFile=PROCEDURE)
+SYMBOL_VECTOR=(PR_LogFlush=PROCEDURE)
+SYMBOL_VECTOR=(PR_LogPrint=PROCEDURE)
+SYMBOL_VECTOR=(PR_MakeDir=PROCEDURE)
+SYMBOL_VECTOR=(PR_MemMap=PROCEDURE)
+SYMBOL_VECTOR=(PR_MemUnmap=PROCEDURE)
+SYMBOL_VECTOR=(PR_MicrosecondsToInterval=PROCEDURE)
+SYMBOL_VECTOR=(PR_MillisecondsToInterval=PROCEDURE)
+SYMBOL_VECTOR=(PR_MkDir=PROCEDURE)
+SYMBOL_VECTOR=(PR_NetAddrToString=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewCondVar=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewLogModule=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewMonitor=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewNamedMonitor=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewProcessAttr=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewSem=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewTCPSocket=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewTCPSocketPair=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewUDPSocket=PROCEDURE)
+SYMBOL_VECTOR=(PR_NormalizeTime=PROCEDURE)
+SYMBOL_VECTOR=(PR_Notify=PROCEDURE)
+SYMBOL_VECTOR=(PR_NotifyAll=PROCEDURE)
+SYMBOL_VECTOR=(PR_NotifyAllCondVar=PROCEDURE)
+SYMBOL_VECTOR=(PR_NotifyCondVar=PROCEDURE)
+SYMBOL_VECTOR=(PR_Open=PROCEDURE)
+SYMBOL_VECTOR=(PR_OpenDir=PROCEDURE)
+SYMBOL_VECTOR=(PR_OpenFile=PROCEDURE)
+SYMBOL_VECTOR=(PR_OpenSemaphore=PROCEDURE)
+SYMBOL_VECTOR=(PR_OpenTCPSocket=PROCEDURE)
+SYMBOL_VECTOR=(PR_OpenUDPSocket=PROCEDURE)
+SYMBOL_VECTOR=(PR_ParseTimeString=PROCEDURE)
+SYMBOL_VECTOR=(PR_Poll=PROCEDURE)
+SYMBOL_VECTOR=(PR_PopIOLayer=PROCEDURE)
+SYMBOL_VECTOR=(PR_PostSem=PROCEDURE)
+SYMBOL_VECTOR=(PR_PostSemaphore=PROCEDURE)
+SYMBOL_VECTOR=(PR_ProcessAttrSetCurren1sb1r7b$=PROCEDURE) ! PR_ProcessAttrSetCurrentDirectory
+SYMBOL_VECTOR=(PR_ProcessAttrSetInheri3dpg1d0$=PROCEDURE) ! PR_ProcessAttrSetInheritableFileMap
+SYMBOL_VECTOR=(PR_ProcessAttrSetInheritableFD=PROCEDURE)
+SYMBOL_VECTOR=(PR_ProcessAttrSetStdioRedirect=PROCEDURE)
+SYMBOL_VECTOR=(PR_ProcessExit=PROCEDURE)
+SYMBOL_VECTOR=(PR_PushIOLayer=PROCEDURE)
+SYMBOL_VECTOR=(PR_QueueJob=PROCEDURE)
+SYMBOL_VECTOR=(PR_QueueJob_Accept=PROCEDURE)
+SYMBOL_VECTOR=(PR_QueueJob_Connect=PROCEDURE)
+SYMBOL_VECTOR=(PR_QueueJob_Read=PROCEDURE)
+SYMBOL_VECTOR=(PR_QueueJob_Timer=PROCEDURE)
+SYMBOL_VECTOR=(PR_QueueJob_Write=PROCEDURE)
+SYMBOL_VECTOR=(PR_RWLock_Rlock=PROCEDURE)
+SYMBOL_VECTOR=(PR_RWLock_Unlock=PROCEDURE)
+SYMBOL_VECTOR=(PR_RWLock_Wlock=PROCEDURE)
+SYMBOL_VECTOR=(PR_Read=PROCEDURE)
+SYMBOL_VECTOR=(PR_ReadDir=PROCEDURE)
+SYMBOL_VECTOR=(PR_Realloc=PROCEDURE)
+SYMBOL_VECTOR=(PR_Recv=PROCEDURE)
+SYMBOL_VECTOR=(PR_RecvFrom=PROCEDURE)
+SYMBOL_VECTOR=(PR_Rename=PROCEDURE)
+SYMBOL_VECTOR=(PR_ResetAlarm=PROCEDURE)
+SYMBOL_VECTOR=(PR_ResetProcessAttr=PROCEDURE)
+SYMBOL_VECTOR=(PR_ResumeAll=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub1=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub2=PROCEDURE)
+SYMBOL_VECTOR=(PR_RmDir=PROCEDURE)
+SYMBOL_VECTOR=(PR_ScanStackPointers=PROCEDURE)
+SYMBOL_VECTOR=(PR_SecondsToInterval=PROCEDURE)
+SYMBOL_VECTOR=(PR_Seek64=PROCEDURE)
+SYMBOL_VECTOR=(PR_Seek=PROCEDURE)
+SYMBOL_VECTOR=(PR_Select=PROCEDURE)
+SYMBOL_VECTOR=(PR_Send=PROCEDURE)
+SYMBOL_VECTOR=(PR_SendFile=PROCEDURE)
+SYMBOL_VECTOR=(PR_SendTo=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetAlarm=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetEnv=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetErrorText=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetFDInheritable=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetLogBuffering=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetLogFile=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetNetAddr=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetPollableEvent=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetSocketOption=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetStdioRedirect=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetSysfdTableSize=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetThreadAffinityMask=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetThreadDumpProc=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetThreadGCAble=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetThreadPriority=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetThreadPrivate=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetThreadRecycleMode=PROCEDURE)
+SYMBOL_VECTOR=(PR_Shutdown=PROCEDURE)
+SYMBOL_VECTOR=(PR_ShutdownThreadPool=PROCEDURE)
+SYMBOL_VECTOR=(PR_Sleep=PROCEDURE)
+SYMBOL_VECTOR=(PR_Socket=PROCEDURE)
+SYMBOL_VECTOR=(PR_StackPop=PROCEDURE)
+SYMBOL_VECTOR=(PR_StackPush=PROCEDURE)
+SYMBOL_VECTOR=(PR_Stat=PROCEDURE)
+SYMBOL_VECTOR=(PR_SuspendAll=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub3=PROCEDURE)
+SYMBOL_VECTOR=(PR_Sync=PROCEDURE)
+SYMBOL_VECTOR=(PR_TLockFile=PROCEDURE)
+SYMBOL_VECTOR=(PR_ThreadScanStackPointers=PROCEDURE)
+SYMBOL_VECTOR=(PR_TicksPerSecond=PROCEDURE)
+SYMBOL_VECTOR=(PR_TransmitFile=PROCEDURE)
+SYMBOL_VECTOR=(PR_USPacificTimeParameters=PROCEDURE)
+SYMBOL_VECTOR=(PR_UnblockClockInterrupts=PROCEDURE)
+SYMBOL_VECTOR=(PR_UnblockInterrupt=PROCEDURE)
+SYMBOL_VECTOR=(PR_UnloadLibrary=PROCEDURE)
+SYMBOL_VECTOR=(PR_Unlock=PROCEDURE)
+SYMBOL_VECTOR=(PR_UnlockFile=PROCEDURE)
+SYMBOL_VECTOR=(PR_Wait=PROCEDURE)
+SYMBOL_VECTOR=(PR_WaitCondVar=PROCEDURE)
+SYMBOL_VECTOR=(PR_WaitForPollableEvent=PROCEDURE)
+SYMBOL_VECTOR=(PR_WaitProcess=PROCEDURE)
+SYMBOL_VECTOR=(PR_WaitRecvReady=PROCEDURE)
+SYMBOL_VECTOR=(PR_WaitSem=PROCEDURE)
+SYMBOL_VECTOR=(PR_WaitSemaphore=PROCEDURE)
+SYMBOL_VECTOR=(PR_Write=PROCEDURE)
+SYMBOL_VECTOR=(PR_Writev=PROCEDURE)
+SYMBOL_VECTOR=(PR_XIsLocked=PROCEDURE)
+SYMBOL_VECTOR=(PR_XLock=PROCEDURE)
+SYMBOL_VECTOR=(PR_XNotify=PROCEDURE)
+SYMBOL_VECTOR=(PR_XNotifyAll=PROCEDURE)
+SYMBOL_VECTOR=(PR_XUnlock=PROCEDURE)
+SYMBOL_VECTOR=(PR_XWait=PROCEDURE)
+SYMBOL_VECTOR=(PR_Yield=PROCEDURE)
+SYMBOL_VECTOR=(PR_cnvtf=PROCEDURE)
+SYMBOL_VECTOR=(PR_dtoa=PROCEDURE)
+SYMBOL_VECTOR=(PR_htonl=PROCEDURE)
+SYMBOL_VECTOR=(PR_htonll=PROCEDURE)
+SYMBOL_VECTOR=(PR_htons=PROCEDURE)
+SYMBOL_VECTOR=(PR_ntohl=PROCEDURE)
+SYMBOL_VECTOR=(PR_ntohll=PROCEDURE)
+SYMBOL_VECTOR=(PR_ntohs=PROCEDURE)
+SYMBOL_VECTOR=(PR_smprintf=PROCEDURE)
+SYMBOL_VECTOR=(PR_smprintf_free=PROCEDURE)
+SYMBOL_VECTOR=(PR_sprintf_append=PROCEDURE)
+SYMBOL_VECTOR=(PR_sxprintf=PROCEDURE)
+SYMBOL_VECTOR=(PR_vfprintf=PROCEDURE)
+SYMBOL_VECTOR=(PR_vsmprintf=PROCEDURE)
+SYMBOL_VECTOR=(PR_vsnprintf=PROCEDURE)
+SYMBOL_VECTOR=(PR_vsprintf_append=PROCEDURE)
+SYMBOL_VECTOR=(PR_vsxprintf=PROCEDURE)
+!
+! Start of 2,3 additions
+!
+SYMBOL_VECTOR=(LL_MaxInt=PROCEDURE)
+SYMBOL_VECTOR=(LL_MinInt=PROCEDURE)
+SYMBOL_VECTOR=(LL_Zero=PROCEDURE)
+SYMBOL_VECTOR=(PR_Abort=PROCEDURE)
+SYMBOL_VECTOR=(PR_AddToCounter=PROCEDURE)
+SYMBOL_VECTOR=(PR_AddWaitFileDesc=PROCEDURE)
+SYMBOL_VECTOR=(PR_AtomicIncrement=PROCEDURE)
+SYMBOL_VECTOR=(PR_CEnterMonitor=PROCEDURE)
+SYMBOL_VECTOR=(PR_CeilingLog2=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateCounter=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateAlarm=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateFileMap=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateOrderedLock=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateTrace=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateThreadPool=PROCEDURE)
+SYMBOL_VECTOR=(PR_DecrementCounter=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyCounter=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyOrderedLock=PROCEDURE)
+SYMBOL_VECTOR=(PR_DestroyTrace=PROCEDURE)
+SYMBOL_VECTOR=(PR_ErrorToString=PROCEDURE)
+SYMBOL_VECTOR=(PR_ExplodeTime=PROCEDURE)
+SYMBOL_VECTOR=(PR_FindNextCounterQname=PROCEDURE)
+SYMBOL_VECTOR=(PR_FindNextCounterRname=PROCEDURE)
+SYMBOL_VECTOR=(PR_FindNextTraceQname=PROCEDURE)
+SYMBOL_VECTOR=(PR_FindNextTraceRname=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetDescType=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetDirectorySeparator=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetCounter=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetCounterHandleFromName=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetCounterNameFromHandle=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetEnv=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetGCRegisters=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetPageSize=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetRandomNoise=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetSpecialFD=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetUniqueIdentity=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetTraceEntries=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetTraceHandleFromName=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetTraceNameFromHandle=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetTraceOption=PROCEDURE)
+SYMBOL_VECTOR=(PR_IntervalNow=PROCEDURE)
+SYMBOL_VECTOR=(PR_IncrementCounter=PROCEDURE)
+SYMBOL_VECTOR=(PR_Malloc=PROCEDURE)
+SYMBOL_VECTOR=(PR_LockOrderedLock=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewLock=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewPollableEvent=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewRWLock=PROCEDURE)
+SYMBOL_VECTOR=(PR_NewThreadPrivateIndex=PROCEDURE)
+SYMBOL_VECTOR=(PR_Now=PROCEDURE)
+SYMBOL_VECTOR=(PR_OpenAnonFileMap=PROCEDURE)
+SYMBOL_VECTOR=(PR_OpenSharedMemory=PROCEDURE)
+SYMBOL_VECTOR=(PR_RecordTraceEntries=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetConcurrency=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetFDCacheSize=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetLibraryPath=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetCounter=PROCEDURE)
+SYMBOL_VECTOR=(PR_StringToNetAddr=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetTraceOption=PROCEDURE)
+SYMBOL_VECTOR=(PR_SubtractFromCounter=PROCEDURE)
+SYMBOL_VECTOR=(PR_VersionCheck=PROCEDURE)
+SYMBOL_VECTOR=(PR_Trace=PROCEDURE)
+SYMBOL_VECTOR=(PR_UnlockOrderedLock=PROCEDURE)
+SYMBOL_VECTOR=(PR_fprintf=PROCEDURE)
+SYMBOL_VECTOR=(PR_snprintf=PROCEDURE)
+SYMBOL_VECTOR=(PR_sscanf=PROCEDURE)
+SYMBOL_VECTOR=(PR_strtod=PROCEDURE)
+SYMBOL_VECTOR=(PRP_DestroyNakedCondVar=PROCEDURE)
+SYMBOL_VECTOR=(PRP_NakedBroadcast=PROCEDURE)
+SYMBOL_VECTOR=(PRP_NakedNotify=PROCEDURE)
+SYMBOL_VECTOR=(PRP_NakedWait=PROCEDURE)
+SYMBOL_VECTOR=(PRP_NewNakedCondVar=PROCEDURE)
+SYMBOL_VECTOR=(PRP_TryLock=PROCEDURE)
+SYMBOL_VECTOR=(libVersionPoint=PROCEDURE)
+!
+! NSPR private
+!
+SYMBOL_VECTOR=(GetExecutionEnvironment=PROCEDURE)
+SYMBOL_VECTOR=(PT_FPrintStats=PROCEDURE)
+SYMBOL_VECTOR=(SetExecutionEnvironment=PROCEDURE)
+!
+! Start of 2,4 additions
+! 51 stubs (4 thru 54) so that PR_CreateThread ends up at 1B70.
+! Over time some of these stubs will get replaced by new symbols.
+!
+SYMBOL_VECTOR=(PR_VMS_Stub4=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub5=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub6=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub7=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub8=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub9=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub10=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub11=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub12=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub13=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub14=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub15=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub16=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub17=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub18=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub19=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub20=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub21=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub22=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub23=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub24=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub25=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub26=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub27=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub28=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub29=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub30=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub31=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub32=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub33=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub34=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub35=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub36=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub37=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub38=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub39=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub40=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub41=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub42=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub43=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub44=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub45=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub46=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub47=PROCEDURE)
+SYMBOL_VECTOR=(PR_VMS_Stub48=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetAddrInfoByName=PROCEDURE)		! was Stub49
+SYMBOL_VECTOR=(PR_FreeAddrInfo=PROCEDURE)		! was Stub50
+SYMBOL_VECTOR=(PR_EnumerateAddrInfo=PROCEDURE)		! was Stub51
+SYMBOL_VECTOR=(PR_GetCanonNameFromAddrInfo=PROCEDURE)	! was Stub52
+SYMBOL_VECTOR=(PR_GetPathSeparator=PROCEDURE)		! was Stub53
+SYMBOL_VECTOR=(LL_MaxUint=PROCEDURE)			! was Stub54
+!
+SYMBOL_VECTOR=(PR_CallOnceWithArg=PROCEDURE)
+SYMBOL_VECTOR=(PR_GetLibraryFilePathname=PROCEDURE)
+SYMBOL_VECTOR=(PR_SetError=PROCEDURE)
+SYMBOL_VECTOR=(PR_CreateThread=PROCEDURE)
+!
+! --------------------------------------------------------------------------
+! End of fixed section
+! --------------------------------------------------------------------------
+!

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/os2extra.def
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/os2extra.def	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,16 @@
+    ;
+    ; Support plugins that were explicitly linked to the Visual Age
+    ;   version of nspr4.dll.
+    ;
+    PR_NewMonitor
+    PR_EnterMonitor
+    PR_ExitMonitor
+    PR_GetCurrentThread
+    PR_AttachThread
+    PR_DetachThread
+    ;
+    ; Exception handler functions that are used by nsAppRunner.cpp
+    ;
+    _PR_OS2_SetFloatExcpHandler
+    _PR_OS2_UnsetFloatExcpHandler
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/prvrsion.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/prvrsion.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,127 @@
+/* -*- 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***********************/
+/************************************************************************/
+#ifndef XP_MAC
+#include "_pr_bld.h"
+#endif
+#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_libnspr, 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          */  "License information: 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(void)
+{
+#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 */
+
+/* prvrsion.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,7 @@
+/.cvsignore/1.2/Sat May 12 04:53:48 2001//
+/Makefile.in/1.14/Sat Jan  7 00:51:39 2006//
+/ptio.c/3.104/Tue Feb  7 01:21:00 2006//
+/ptmisc.c/3.8/Sun Apr 25 15:01:01 2004//
+/ptsynch.c/3.29/Mon Nov  7 22:39:01 2005//
+/ptthread.c/3.67/Mon Nov  7 22:39:01 2005//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/pthreads

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,74 @@
+# 
+# ***** 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 =
+endif
+endif
+
+CSRCS = \
+	ptio.c \
+	ptsynch.c \
+	ptthread.c \
+	ptmisc.c \
+	$(NULL)
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptio.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptio.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4889 @@
+/* -*- 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:   ptio.c
+** Descritpion:  Implemenation of I/O methods for pthreads
+*/
+
+#if defined(_PR_PTHREADS)
+
+#if defined(_PR_POLL_WITH_SELECT)
+#if !(defined(HPUX) && defined(_USE_BIG_FDS))
+/* set fd limit for select(), before including system header files */
+#define FD_SETSIZE (16 * 1024)
+#endif
+#endif
+
+#include <pthread.h>
+#include <string.h>  /* for memset() */
+#include <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#if defined(DARWIN)
+#include <sys/utsname.h> /* for uname */
+#endif
+#if defined(SOLARIS) || defined(UNIXWARE)
+#include <sys/filio.h>  /* to pick up FIONREAD */
+#endif
+#ifdef _PR_POLL_AVAILABLE
+#include <poll.h>
+#endif
+#ifdef AIX
+/* To pick up sysconf() */
+#include <unistd.h>
+#include <dlfcn.h>  /* for dlopen */
+#else
+/* To pick up getrlimit() etc. */
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
+
+#ifdef SOLARIS
+/*
+ * Define HAVE_SENDFILEV if the system has the sendfilev() system call.
+ * Code built this way won't run on a system without sendfilev().
+ * We can define HAVE_SENDFILEV by default when the minimum release
+ * of Solaris that NSPR supports has sendfilev().
+ */
+#ifdef HAVE_SENDFILEV
+
+#include <sys/sendfile.h>
+
+#define SOLARIS_SENDFILEV(a, b, c, d) sendfilev((a), (b), (c), (d))
+
+#else
+
+#include <dlfcn.h>  /* for dlopen */
+
+/*
+ * Match the definitions in <sys/sendfile.h>.
+ */
+typedef struct sendfilevec {
+    int sfv_fd;       /* input fd */
+    uint_t sfv_flag;  /* flags */
+    off_t sfv_off;    /* offset to start reading from */
+    size_t sfv_len;   /* amount of data */
+} sendfilevec_t;
+
+#define SFV_FD_SELF (-2)
+
+/*
+ * extern ssize_t sendfilev(int, const struct sendfilevec *, int, size_t *);
+ */
+static ssize_t (*pt_solaris_sendfilev_fptr)() = NULL;
+
+#define SOLARIS_SENDFILEV(a, b, c, d) \
+        (*pt_solaris_sendfilev_fptr)((a), (b), (c), (d))
+
+#endif /* HAVE_SENDFILEV */
+#endif /* SOLARIS */
+
+/*
+ * The send_file() system call is available in AIX 4.3.2 or later.
+ * If this file is compiled on an older AIX system, it attempts to
+ * look up the send_file symbol at run time to determine whether
+ * we can use the faster PR_SendFile/PR_TransmitFile implementation based on
+ * send_file().  On AIX 4.3.2 or later, we can safely skip this
+ * runtime function dispatching and just use the send_file based
+ * implementation.
+ */
+#ifdef AIX
+#ifdef SF_CLOSE
+#define HAVE_SEND_FILE
+#endif
+
+#ifdef HAVE_SEND_FILE
+
+#define AIX_SEND_FILE(a, b, c) send_file(a, b, c)
+
+#else /* HAVE_SEND_FILE */
+
+/*
+ * The following definitions match those in <sys/socket.h>
+ * on AIX 4.3.2.
+ */
+
+/*
+ * Structure for the send_file() system call
+ */
+struct sf_parms {
+    /* --------- header parms ---------- */
+    void      *header_data;         /* Input/Output. Points to header buf */
+    uint_t    header_length;        /* Input/Output. Length of the header */
+    /* --------- file parms ------------ */
+    int       file_descriptor;      /* Input. File descriptor of the file */
+    unsigned long long file_size;   /* Output. Size of the file */
+    unsigned long long file_offset; /* Input/Output. Starting offset */
+    long long file_bytes;           /* Input/Output. no. of bytes to send */
+    /* --------- trailer parms --------- */
+    void      *trailer_data;        /* Input/Output. Points to trailer buf */
+    uint_t    trailer_length;       /* Input/Output. Length of the trailer */
+    /* --------- return info ----------- */
+    unsigned long long bytes_sent;  /* Output. no. of bytes sent */
+};
+
+/*
+ * Flags for the send_file() system call
+ */
+#define SF_CLOSE        0x00000001      /* close the socket after completion */
+#define SF_REUSE        0x00000002      /* reuse socket. not supported */
+#define SF_DONT_CACHE   0x00000004      /* don't apply network buffer cache */
+#define SF_SYNC_CACHE   0x00000008      /* sync/update network buffer cache */
+
+/*
+ * prototype: size_t send_file(int *, struct sf_parms *, uint_t);
+ */
+static ssize_t (*pt_aix_sendfile_fptr)() = NULL;
+
+#define AIX_SEND_FILE(a, b, c) (*pt_aix_sendfile_fptr)(a, b, c)
+
+#endif /* HAVE_SEND_FILE */
+#endif /* AIX */
+
+#ifdef LINUX
+#include <sys/sendfile.h>
+#endif
+
+#include "primpl.h"
+
+#include <netinet/tcp.h>  /* TCP_NODELAY, TCP_MAXSEG */
+#ifdef LINUX
+/* TCP_CORK is not defined in <netinet/tcp.h> on Red Hat Linux 6.0 */
+#ifndef TCP_CORK
+#define TCP_CORK 3
+#endif
+#endif
+
+#ifdef _PR_IPV6_V6ONLY_PROBE
+static PRBool _pr_ipv6_v6only_on_by_default;
+#endif
+
+#if (defined(HPUX) && !defined(HPUX10_30) && !defined(HPUX11))
+#define _PRSelectFdSetArg_t int *
+#elif defined(AIX4_1)
+#define _PRSelectFdSetArg_t void *
+#elif defined(IRIX) || (defined(AIX) && !defined(AIX4_1)) \
+    || defined(OSF1) || defined(SOLARIS) \
+    || defined(HPUX10_30) || defined(HPUX11) \
+    || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
+    || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
+    || defined(BSDI) || defined(VMS) || defined(NTO) || defined(DARWIN) \
+    || defined(UNIXWARE) || defined(RISCOS)
+#define _PRSelectFdSetArg_t fd_set *
+#else
+#error "Cannot determine architecture"
+#endif
+
+static PRFileDesc *pt_SetMethods(
+    PRIntn osfd, PRDescType type, PRBool isAcceptedSocket, PRBool imported);
+
+static PRLock *_pr_flock_lock;  /* For PR_LockFile() etc. */
+static PRCondVar *_pr_flock_cv;  /* For PR_LockFile() etc. */
+static PRLock *_pr_rename_lock;  /* For PR_Rename() */
+
+/**************************************************************************/
+
+/* These two functions are only used in assertions. */
+#if defined(DEBUG)
+
+PRBool IsValidNetAddr(const PRNetAddr *addr)
+{
+    if ((addr != NULL)
+            && (addr->raw.family != AF_UNIX)
+            && (addr->raw.family != PR_AF_INET6)
+            && (addr->raw.family != AF_INET)) {
+        return PR_FALSE;
+    }
+    return PR_TRUE;
+}
+
+static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
+{
+    /*
+     * The definition of the length of a Unix domain socket address
+     * is not uniform, so we don't check it.
+     */
+    if ((addr != NULL)
+            && (addr->raw.family != AF_UNIX)
+            && (PR_NETADDR_SIZE(addr) != addr_len)) {
+#if defined(LINUX) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 1
+        /*
+         * In glibc 2.1, struct sockaddr_in6 is 24 bytes.  In glibc 2.2
+         * and in the 2.4 kernel, struct sockaddr_in6 has the scope_id
+         * field and is 28 bytes.  It is possible for socket functions
+         * to return an addr_len greater than sizeof(struct sockaddr_in6).
+         * We need to allow that.  (Bugzilla bug #77264)
+         */
+        if ((PR_AF_INET6 == addr->raw.family)
+                && (sizeof(addr->ipv6) == addr_len)) {
+            return PR_TRUE;
+        }
+#endif
+        return PR_FALSE;
+    }
+    return PR_TRUE;
+}
+
+#endif /* DEBUG */
+
+/*****************************************************************************/
+/************************* I/O Continuation machinery ************************/
+/*****************************************************************************/
+
+/*
+ * The polling interval defines the maximum amount of time that a thread
+ * might hang up before an interrupt is noticed.
+ */
+#define PT_DEFAULT_POLL_MSEC 5000
+#if defined(_PR_POLL_WITH_SELECT)
+#define PT_DEFAULT_SELECT_SEC (PT_DEFAULT_POLL_MSEC/PR_MSEC_PER_SEC)
+#define PT_DEFAULT_SELECT_USEC							\
+		((PT_DEFAULT_POLL_MSEC % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC)
+#endif
+
+/*
+ * pt_SockLen is the type for the length of a socket address
+ * structure, used in the address length argument to bind,
+ * connect, accept, getsockname, getpeername, etc.  Posix.1g
+ * defines this type as socklen_t.  It is size_t or int on
+ * most current systems.
+ */
+#if defined(HAVE_SOCKLEN_T) \
+    || (defined(__GLIBC__) && __GLIBC__ >= 2)
+typedef socklen_t pt_SockLen;
+#elif (defined(AIX) && !defined(AIX4_1)) \
+    || defined(VMS)
+typedef PRSize pt_SockLen;
+#else
+typedef PRIntn pt_SockLen;
+#endif
+
+typedef struct pt_Continuation pt_Continuation;
+typedef PRBool (*ContinuationFn)(pt_Continuation *op, PRInt16 revents);
+
+typedef enum pr_ContuationStatus
+{
+    pt_continuation_pending,
+    pt_continuation_done
+} pr_ContuationStatus;
+
+struct pt_Continuation
+{
+    /* The building of the continuation operation */
+    ContinuationFn function;                /* what function to continue */
+    union { PRIntn osfd; } arg1;            /* #1 - the op's fd */
+    union { void* buffer; } arg2;           /* #2 - primary transfer buffer */
+    union {
+        PRSize amount;                      /* #3 - size of 'buffer', or */
+        pt_SockLen *addr_len;                  /*    - length of address */
+#ifdef HPUX11
+        /*
+         * For sendfile()
+         */
+		struct file_spec {		
+        	off_t offset;                       /* offset in file to send */
+        	size_t nbytes;                      /* length of file data to send */
+        	size_t st_size;                     /* file size */
+		} file_spec;
+#endif
+    } arg3;
+    union { PRIntn flags; } arg4;           /* #4 - read/write flags */
+    union { PRNetAddr *addr; } arg5;        /* #5 - send/recv address */
+
+#ifdef HPUX11
+    /*
+     * For sendfile()
+     */
+    int filedesc;                           /* descriptor of file to send */
+    int nbytes_to_send;                     /* size of header and file */
+#endif  /* HPUX11 */
+    
+#ifdef SOLARIS
+    /*
+     * For sendfilev()
+     */
+    int nbytes_to_send;                     /* size of header and file */
+#endif  /* SOLARIS */
+
+#ifdef LINUX
+    /*
+     * For sendfile()
+     */
+    int in_fd;                              /* descriptor of file to send */
+    off_t offset;
+    size_t count;
+#endif  /* LINUX */
+ 
+    PRIntervalTime timeout;                 /* client (relative) timeout */
+
+    PRInt16 event;                           /* flags for poll()'s events */
+
+    /*
+    ** The representation and notification of the results of the operation.
+    ** These function can either return an int return code or a pointer to
+    ** some object.
+    */
+    union { PRSize code; void *object; } result;
+
+    PRIntn syserrno;                        /* in case it failed, why (errno) */
+    pr_ContuationStatus status;             /* the status of the operation */
+};
+
+#if defined(DEBUG)
+
+PTDebug pt_debug;  /* this is shared between several modules */
+
+PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg)
+{
+    PTDebug stats;
+    char buffer[100];
+    PRExplodedTime tod;
+    PRInt64 elapsed, aMil;
+    stats = pt_debug;  /* a copy */
+    PR_ExplodeTime(stats.timeStarted, PR_LocalTimeParameters, &tod);
+    (void)PR_FormatTime(buffer, sizeof(buffer), "%T", &tod);
+
+    LL_SUB(elapsed, PR_Now(), stats.timeStarted);
+    LL_I2L(aMil, 1000000);
+    LL_DIV(elapsed, elapsed, aMil);
+    
+    if (NULL != msg) PR_fprintf(debug_out, "%s", msg);
+    PR_fprintf(
+        debug_out, "\tstarted: %s[%lld]\n", buffer, elapsed);
+    PR_fprintf(
+        debug_out, "\tlocks [created: %u, destroyed: %u]\n",
+        stats.locks_created, stats.locks_destroyed);
+    PR_fprintf(
+        debug_out, "\tlocks [acquired: %u, released: %u]\n",
+        stats.locks_acquired, stats.locks_released);
+    PR_fprintf(
+        debug_out, "\tcvars [created: %u, destroyed: %u]\n",
+        stats.cvars_created, stats.cvars_destroyed);
+    PR_fprintf(
+        debug_out, "\tcvars [notified: %u, delayed_delete: %u]\n",
+        stats.cvars_notified, stats.delayed_cv_deletes);
+}  /* PT_FPrintStats */
+
+#else
+
+PR_IMPLEMENT(void) PT_FPrintStats(PRFileDesc *debug_out, const char *msg)
+{
+    /* do nothing */
+}  /* PT_FPrintStats */
+
+#endif  /* DEBUG */
+
+#if defined(_PR_POLL_WITH_SELECT)
+/*
+ * OSF1 and HPUX report the POLLHUP event for a socket when the
+ * shutdown(SHUT_WR) operation is called for the remote end, even though
+ * the socket is still writeable. Use select(), instead of poll(), to
+ * workaround this problem.
+ */
+static void pt_poll_now_with_select(pt_Continuation *op)
+{
+    PRInt32 msecs;
+	fd_set rd, wr, *rdp, *wrp;
+	struct timeval tv;
+	PRIntervalTime epoch, now, elapsed, remaining;
+	PRBool wait_for_remaining;
+    PRThread *self = PR_GetCurrentThread();
+    
+	PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout);
+	PR_ASSERT(op->arg1.osfd < FD_SETSIZE);
+
+    switch (op->timeout) {
+        case PR_INTERVAL_NO_TIMEOUT:
+			tv.tv_sec = PT_DEFAULT_SELECT_SEC;
+			tv.tv_usec = PT_DEFAULT_SELECT_USEC;
+			do
+			{
+				PRIntn rv;
+
+				if (op->event & POLLIN) {
+					FD_ZERO(&rd);
+					FD_SET(op->arg1.osfd, &rd);
+					rdp = &rd;
+				} else
+					rdp = NULL;
+				if (op->event & POLLOUT) {
+					FD_ZERO(&wr);
+					FD_SET(op->arg1.osfd, &wr);
+					wrp = &wr;
+				} else
+					wrp = NULL;
+
+				rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv);
+
+				if (self->state & PT_THREAD_ABORTED)
+				{
+					self->state &= ~PT_THREAD_ABORTED;
+					op->result.code = -1;
+					op->syserrno = EINTR;
+					op->status = pt_continuation_done;
+					return;
+				}
+
+				if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN)))
+					continue; /* go around the loop again */
+
+				if (rv > 0)
+				{
+					PRInt16 revents = 0;
+
+					if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd))
+						revents |= POLLIN;
+					if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr))
+						revents |= POLLOUT;
+						
+					if (op->function(op, revents))
+						op->status = pt_continuation_done;
+				} else if (rv == -1) {
+					op->result.code = -1;
+					op->syserrno = errno;
+					op->status = pt_continuation_done;
+				}
+				/* else, select timed out */
+			} while (pt_continuation_done != op->status);
+			break;
+        default:
+            now = epoch = PR_IntervalNow();
+            remaining = op->timeout;
+			do
+			{
+				PRIntn rv;
+
+				if (op->event & POLLIN) {
+					FD_ZERO(&rd);
+					FD_SET(op->arg1.osfd, &rd);
+					rdp = &rd;
+				} else
+					rdp = NULL;
+				if (op->event & POLLOUT) {
+					FD_ZERO(&wr);
+					FD_SET(op->arg1.osfd, &wr);
+					wrp = &wr;
+				} else
+					wrp = NULL;
+
+    			wait_for_remaining = PR_TRUE;
+    			msecs = (PRInt32)PR_IntervalToMilliseconds(remaining);
+				if (msecs > PT_DEFAULT_POLL_MSEC) {
+					wait_for_remaining = PR_FALSE;
+					msecs = PT_DEFAULT_POLL_MSEC;
+				}
+				tv.tv_sec = msecs/PR_MSEC_PER_SEC;
+				tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC;
+				rv = select(op->arg1.osfd + 1, rdp, wrp, NULL, &tv);
+
+				if (self->state & PT_THREAD_ABORTED)
+				{
+					self->state &= ~PT_THREAD_ABORTED;
+					op->result.code = -1;
+					op->syserrno = EINTR;
+					op->status = pt_continuation_done;
+					return;
+				}
+
+				if (rv > 0) {
+					PRInt16 revents = 0;
+
+					if ((op->event & POLLIN) && FD_ISSET(op->arg1.osfd, &rd))
+						revents |= POLLIN;
+					if ((op->event & POLLOUT) && FD_ISSET(op->arg1.osfd, &wr))
+						revents |= POLLOUT;
+						
+					if (op->function(op, revents))
+						op->status = pt_continuation_done;
+
+				} else if ((rv == 0) ||
+						((errno == EINTR) || (errno == EAGAIN))) {
+					if (rv == 0) {	/* select timed out */
+						if (wait_for_remaining)
+							now += remaining;
+						else
+							now += PR_MillisecondsToInterval(msecs);
+					} else
+						now = PR_IntervalNow();
+					elapsed = (PRIntervalTime) (now - epoch);
+					if (elapsed >= op->timeout) {
+						op->result.code = -1;
+						op->syserrno = ETIMEDOUT;
+						op->status = pt_continuation_done;
+					} else
+						remaining = op->timeout - elapsed;
+				} else {
+					op->result.code = -1;
+					op->syserrno = errno;
+					op->status = pt_continuation_done;
+				}
+			} while (pt_continuation_done != op->status);
+            break;
+    }
+
+}  /* pt_poll_now_with_select */
+
+#endif	/* _PR_POLL_WITH_SELECT */
+
+static void pt_poll_now(pt_Continuation *op)
+{
+    PRInt32 msecs;
+	PRIntervalTime epoch, now, elapsed, remaining;
+	PRBool wait_for_remaining;
+    PRThread *self = PR_GetCurrentThread();
+    
+	PR_ASSERT(PR_INTERVAL_NO_WAIT != op->timeout);
+#if defined (_PR_POLL_WITH_SELECT)
+	/*
+ 	 * If the fd is small enough call the select-based poll operation
+	 */
+	if (op->arg1.osfd < FD_SETSIZE) {
+		pt_poll_now_with_select(op);
+		return;
+	}
+#endif
+
+    switch (op->timeout) {
+        case PR_INTERVAL_NO_TIMEOUT:
+			msecs = PT_DEFAULT_POLL_MSEC;
+			do
+			{
+				PRIntn rv;
+				struct pollfd tmp_pfd;
+
+				tmp_pfd.revents = 0;
+				tmp_pfd.fd = op->arg1.osfd;
+				tmp_pfd.events = op->event;
+
+				rv = poll(&tmp_pfd, 1, msecs);
+				
+				if (self->state & PT_THREAD_ABORTED)
+				{
+					self->state &= ~PT_THREAD_ABORTED;
+					op->result.code = -1;
+					op->syserrno = EINTR;
+					op->status = pt_continuation_done;
+					return;
+				}
+
+				if ((-1 == rv) && ((errno == EINTR) || (errno == EAGAIN)))
+					continue; /* go around the loop again */
+
+				if (rv > 0)
+				{
+					PRInt16 events = tmp_pfd.events;
+					PRInt16 revents = tmp_pfd.revents;
+
+					if ((revents & POLLNVAL)  /* busted in all cases */
+					|| ((events & POLLOUT) && (revents & POLLHUP)))
+						/* write op & hup */
+					{
+						op->result.code = -1;
+						if (POLLNVAL & revents) op->syserrno = EBADF;
+						else if (POLLHUP & revents) op->syserrno = EPIPE;
+						op->status = pt_continuation_done;
+					} else {
+						if (op->function(op, revents))
+							op->status = pt_continuation_done;
+					}
+				} else if (rv == -1) {
+					op->result.code = -1;
+					op->syserrno = errno;
+					op->status = pt_continuation_done;
+				}
+				/* else, poll timed out */
+			} while (pt_continuation_done != op->status);
+			break;
+        default:
+            now = epoch = PR_IntervalNow();
+            remaining = op->timeout;
+			do
+			{
+				PRIntn rv;
+				struct pollfd tmp_pfd;
+
+				tmp_pfd.revents = 0;
+				tmp_pfd.fd = op->arg1.osfd;
+				tmp_pfd.events = op->event;
+
+    			wait_for_remaining = PR_TRUE;
+    			msecs = (PRInt32)PR_IntervalToMilliseconds(remaining);
+				if (msecs > PT_DEFAULT_POLL_MSEC)
+				{
+					wait_for_remaining = PR_FALSE;
+					msecs = PT_DEFAULT_POLL_MSEC;
+				}
+				rv = poll(&tmp_pfd, 1, msecs);
+				
+				if (self->state & PT_THREAD_ABORTED)
+				{
+					self->state &= ~PT_THREAD_ABORTED;
+					op->result.code = -1;
+					op->syserrno = EINTR;
+					op->status = pt_continuation_done;
+					return;
+				}
+
+				if (rv > 0)
+				{
+					PRInt16 events = tmp_pfd.events;
+					PRInt16 revents = tmp_pfd.revents;
+
+					if ((revents & POLLNVAL)  /* busted in all cases */
+						|| ((events & POLLOUT) && (revents & POLLHUP))) 
+											/* write op & hup */
+					{
+						op->result.code = -1;
+						if (POLLNVAL & revents) op->syserrno = EBADF;
+						else if (POLLHUP & revents) op->syserrno = EPIPE;
+						op->status = pt_continuation_done;
+					} else {
+						if (op->function(op, revents))
+						{
+							op->status = pt_continuation_done;
+						}
+					}
+				} else if ((rv == 0) ||
+						((errno == EINTR) || (errno == EAGAIN))) {
+					if (rv == 0)	/* poll timed out */
+					{
+						if (wait_for_remaining)
+							now += remaining;
+						else
+							now += PR_MillisecondsToInterval(msecs);
+					}
+					else
+						now = PR_IntervalNow();
+					elapsed = (PRIntervalTime) (now - epoch);
+					if (elapsed >= op->timeout) {
+						op->result.code = -1;
+						op->syserrno = ETIMEDOUT;
+						op->status = pt_continuation_done;
+					} else
+						remaining = op->timeout - elapsed;
+				} else {
+					op->result.code = -1;
+					op->syserrno = errno;
+					op->status = pt_continuation_done;
+				}
+			} while (pt_continuation_done != op->status);
+            break;
+    }
+
+}  /* pt_poll_now */
+
+static PRIntn pt_Continue(pt_Continuation *op)
+{
+    op->status = pt_continuation_pending;  /* set default value */
+	/*
+	 * let each thread call poll directly
+	 */
+	pt_poll_now(op);
+	PR_ASSERT(pt_continuation_done == op->status);
+    return op->result.code;
+}  /* pt_Continue */
+
+/*****************************************************************************/
+/*********************** specific continuation functions *********************/
+/*****************************************************************************/
+static PRBool pt_connect_cont(pt_Continuation *op, PRInt16 revents)
+{
+    op->syserrno = _MD_unix_get_nonblocking_connect_error(op->arg1.osfd);
+    if (op->syserrno != 0) {
+        op->result.code = -1;
+    } else {
+        op->result.code = 0;
+    }
+    return PR_TRUE; /* this one is cooked */
+}  /* pt_connect_cont */
+
+static PRBool pt_accept_cont(pt_Continuation *op, PRInt16 revents)
+{
+    op->syserrno = 0;
+    op->result.code = accept(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.addr_len);
+    if (-1 == op->result.code)
+    {
+        op->syserrno = errno;
+        if (EWOULDBLOCK == errno || EAGAIN == errno || ECONNABORTED == errno)
+            return PR_FALSE;  /* do nothing - this one ain't finished */
+    }
+    return PR_TRUE;
+}  /* pt_accept_cont */
+
+static PRBool pt_read_cont(pt_Continuation *op, PRInt16 revents)
+{
+    /*
+     * Any number of bytes will complete the operation. It need
+     * not (and probably will not) satisfy the request. The only
+     * error we continue is EWOULDBLOCK|EAGAIN.
+     */
+    op->result.code = read(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount);
+    op->syserrno = errno;
+    return ((-1 == op->result.code) && 
+            (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ?
+        PR_FALSE : PR_TRUE;
+}  /* pt_read_cont */
+
+static PRBool pt_recv_cont(pt_Continuation *op, PRInt16 revents)
+{
+    /*
+     * Any number of bytes will complete the operation. It need
+     * not (and probably will not) satisfy the request. The only
+     * error we continue is EWOULDBLOCK|EAGAIN.
+     */
+#if defined(SOLARIS)
+    if (0 == op->arg4.flags)
+        op->result.code = read(
+            op->arg1.osfd, op->arg2.buffer, op->arg3.amount);
+    else
+        op->result.code = recv(
+            op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags);
+#else
+    op->result.code = recv(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags);
+#endif
+    op->syserrno = errno;
+    return ((-1 == op->result.code) && 
+            (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ?
+        PR_FALSE : PR_TRUE;
+}  /* pt_recv_cont */
+
+static PRBool pt_send_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn bytes;
+#if defined(SOLARIS)
+    PRInt32 tmp_amount = op->arg3.amount;
+#endif
+    /*
+     * We want to write the entire amount out, no matter how many
+     * tries it takes. Keep advancing the buffer and the decrementing
+     * the amount until the amount goes away. Return the total bytes
+     * (which should be the original amount) when finished (or an
+     * error).
+     */
+#if defined(SOLARIS)
+retry:
+    bytes = write(op->arg1.osfd, op->arg2.buffer, tmp_amount);
+#else
+    bytes = send(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags);
+#endif
+    op->syserrno = errno;
+
+#if defined(SOLARIS)
+    /*
+     * The write system call has been reported to return the ERANGE error
+     * on occasion. Try to write in smaller chunks to workaround this bug.
+     */
+    if ((bytes == -1) && (op->syserrno == ERANGE))
+    {
+        if (tmp_amount > 1)
+        {
+            tmp_amount = tmp_amount/2;  /* half the bytes */
+            goto retry;
+        }
+    }
+#endif
+
+    if (bytes >= 0)  /* this is progress */
+    {
+        char *bp = (char*)op->arg2.buffer;
+        bp += bytes;  /* adjust the buffer pointer */
+        op->arg2.buffer = bp;
+        op->result.code += bytes;  /* accumulate the number sent */
+        op->arg3.amount -= bytes;  /* and reduce the required count */
+        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
+    }
+    else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+    {
+        op->result.code = -1;
+        return PR_TRUE;
+    }
+    else return PR_FALSE;
+}  /* pt_send_cont */
+
+static PRBool pt_write_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn bytes;
+    /*
+     * We want to write the entire amount out, no matter how many
+     * tries it takes. Keep advancing the buffer and the decrementing
+     * the amount until the amount goes away. Return the total bytes
+     * (which should be the original amount) when finished (or an
+     * error).
+     */
+    bytes = write(op->arg1.osfd, op->arg2.buffer, op->arg3.amount);
+    op->syserrno = errno;
+    if (bytes >= 0)  /* this is progress */
+    {
+        char *bp = (char*)op->arg2.buffer;
+        bp += bytes;  /* adjust the buffer pointer */
+        op->arg2.buffer = bp;
+        op->result.code += bytes;  /* accumulate the number sent */
+        op->arg3.amount -= bytes;  /* and reduce the required count */
+        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
+    }
+    else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+    {
+        op->result.code = -1;
+        return PR_TRUE;
+    }
+    else return PR_FALSE;
+}  /* pt_write_cont */
+
+static PRBool pt_writev_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn bytes;
+    struct iovec *iov = (struct iovec*)op->arg2.buffer;
+    /*
+     * Same rules as write, but continuing seems to be a bit more
+     * complicated. As the number of bytes sent grows, we have to
+     * redefine the vector we're pointing at. We might have to
+     * modify an individual vector parms or we might have to eliminate
+     * a pair altogether.
+     */
+    bytes = writev(op->arg1.osfd, iov, op->arg3.amount);
+    op->syserrno = errno;
+    if (bytes >= 0)  /* this is progress */
+    {
+        PRIntn iov_index;
+        op->result.code += bytes;  /* accumulate the number sent */
+        for (iov_index = 0; iov_index < op->arg3.amount; ++iov_index)
+        {
+            /* how much progress did we make in the i/o vector? */
+            if (bytes < iov[iov_index].iov_len)
+            {
+                /* this element's not done yet */
+                char **bp = (char**)&(iov[iov_index].iov_base);
+                iov[iov_index].iov_len -= bytes;  /* there's that much left */
+                *bp += bytes;  /* starting there */
+                break;  /* go off and do that */
+            }
+            bytes -= iov[iov_index].iov_len;  /* that element's consumed */
+        }
+        op->arg2.buffer = &iov[iov_index];  /* new start of array */
+        op->arg3.amount -= iov_index;  /* and array length */
+        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
+    }
+    else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+    {
+        op->result.code = -1;
+        return PR_TRUE;
+    }
+    else return PR_FALSE;
+}  /* pt_writev_cont */
+
+static PRBool pt_sendto_cont(pt_Continuation *op, PRInt16 revents)
+{
+    PRIntn bytes = sendto(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount, op->arg4.flags,
+        (struct sockaddr*)op->arg5.addr, PR_NETADDR_SIZE(op->arg5.addr));
+    op->syserrno = errno;
+    if (bytes >= 0)  /* this is progress */
+    {
+        char *bp = (char*)op->arg2.buffer;
+        bp += bytes;  /* adjust the buffer pointer */
+        op->arg2.buffer = bp;
+        op->result.code += bytes;  /* accumulate the number sent */
+        op->arg3.amount -= bytes;  /* and reduce the required count */
+        return (0 == op->arg3.amount) ? PR_TRUE : PR_FALSE;
+    }
+    else if ((EWOULDBLOCK != op->syserrno) && (EAGAIN != op->syserrno))
+    {
+        op->result.code = -1;
+        return PR_TRUE;
+    }
+    else return PR_FALSE;
+}  /* pt_sendto_cont */
+
+static PRBool pt_recvfrom_cont(pt_Continuation *op, PRInt16 revents)
+{
+    pt_SockLen addr_len = sizeof(PRNetAddr);
+    op->result.code = recvfrom(
+        op->arg1.osfd, op->arg2.buffer, op->arg3.amount,
+        op->arg4.flags, (struct sockaddr*)op->arg5.addr, &addr_len);
+    op->syserrno = errno;
+    return ((-1 == op->result.code) && 
+            (EWOULDBLOCK == op->syserrno || EAGAIN == op->syserrno)) ?
+        PR_FALSE : PR_TRUE;
+}  /* pt_recvfrom_cont */
+
+#ifdef AIX
+static PRBool pt_aix_sendfile_cont(pt_Continuation *op, PRInt16 revents)
+{
+    struct sf_parms *sf_struct = (struct sf_parms *) op->arg2.buffer;
+    ssize_t rv;
+	unsigned long long saved_file_offset;
+	long long saved_file_bytes;
+
+	saved_file_offset = sf_struct->file_offset;
+	saved_file_bytes = sf_struct->file_bytes;
+	sf_struct->bytes_sent = 0;
+
+	if ((sf_struct->file_bytes > 0) && (sf_struct->file_size > 0))
+	PR_ASSERT((sf_struct->file_bytes + sf_struct->file_offset) <=
+									sf_struct->file_size);
+    rv = AIX_SEND_FILE(&op->arg1.osfd, sf_struct, op->arg4.flags);
+    op->syserrno = errno;
+
+    if (rv != -1) {
+        op->result.code += sf_struct->bytes_sent;
+		/*
+		 * A bug in AIX 4.3.2 prevents the 'file_bytes' field from
+		 * being updated. So, 'file_bytes' is maintained by NSPR to
+		 * avoid conflict when this bug is fixed in AIX, in the future.
+		 */
+		if (saved_file_bytes != -1)
+			saved_file_bytes -= (sf_struct->file_offset - saved_file_offset);
+		sf_struct->file_bytes = saved_file_bytes;
+    } else if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) {
+        op->result.code = -1;
+    } else {
+        return PR_FALSE;
+    }
+
+    if (rv == 1) {    /* more data to send */
+        return PR_FALSE;
+    }
+
+    return PR_TRUE;
+}
+#endif  /* AIX */
+
+#ifdef HPUX11
+static PRBool pt_hpux_sendfile_cont(pt_Continuation *op, PRInt16 revents)
+{
+    struct iovec *hdtrl = (struct iovec *) op->arg2.buffer;
+    int count;
+
+    count = sendfile(op->arg1.osfd, op->filedesc, op->arg3.file_spec.offset,
+			op->arg3.file_spec.nbytes, hdtrl, op->arg4.flags);
+    PR_ASSERT(count <= op->nbytes_to_send);
+    op->syserrno = errno;
+
+    if (count != -1) {
+        op->result.code += count;
+    } else if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) {
+        op->result.code = -1;
+    } else {
+        return PR_FALSE;
+    }
+    if (count != -1 && count < op->nbytes_to_send) {
+        if (count < hdtrl[0].iov_len) {
+			/* header not sent */
+
+            hdtrl[0].iov_base = ((char *) hdtrl[0].iov_len) + count;
+            hdtrl[0].iov_len -= count;
+
+        } else if (count < (hdtrl[0].iov_len + op->arg3.file_spec.nbytes)) {
+			/* header sent, file not sent */
+            PRUint32 file_nbytes_sent = count - hdtrl[0].iov_len;
+
+            hdtrl[0].iov_base = NULL;
+            hdtrl[0].iov_len = 0;
+
+            op->arg3.file_spec.offset += file_nbytes_sent;
+            op->arg3.file_spec.nbytes -= file_nbytes_sent;
+        } else if (count < (hdtrl[0].iov_len + op->arg3.file_spec.nbytes +
+											hdtrl[1].iov_len)) {
+            PRUint32 trailer_nbytes_sent = count - (hdtrl[0].iov_len +
+                                         op->arg3.file_spec.nbytes);
+
+			/* header sent, file sent, trailer not sent */
+
+            hdtrl[0].iov_base = NULL;
+            hdtrl[0].iov_len = 0;
+			/*
+			 * set file offset and len so that no more file data is
+			 * sent
+			 */
+            op->arg3.file_spec.offset = op->arg3.file_spec.st_size;
+            op->arg3.file_spec.nbytes = 0;
+
+            hdtrl[1].iov_base =((char *) hdtrl[1].iov_base)+ trailer_nbytes_sent;
+            hdtrl[1].iov_len -= trailer_nbytes_sent;
+		}
+        op->nbytes_to_send -= count;
+        return PR_FALSE;
+    }
+
+    return PR_TRUE;
+}
+#endif  /* HPUX11 */
+
+#ifdef SOLARIS  
+static PRBool pt_solaris_sendfile_cont(pt_Continuation *op, PRInt16 revents)
+{
+    struct sendfilevec *vec = (struct sendfilevec *) op->arg2.buffer;
+    size_t xferred;
+    ssize_t count;
+
+    count = SOLARIS_SENDFILEV(op->arg1.osfd, vec, op->arg3.amount, &xferred);
+    op->syserrno = errno;
+    PR_ASSERT((count == -1) || (count == xferred));
+
+    if (count == -1) {
+        if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN
+                && op->syserrno != EINTR) {
+            op->result.code = -1;
+            return PR_TRUE;
+        }
+        count = xferred;
+    }
+    PR_ASSERT(count <= op->nbytes_to_send);
+    
+    op->result.code += count;
+    if (count < op->nbytes_to_send) {
+        op->nbytes_to_send -= count;
+
+        while (count >= vec->sfv_len) {
+            count -= vec->sfv_len;
+            vec++;
+            op->arg3.amount--;
+        }
+        PR_ASSERT(op->arg3.amount > 0);
+
+        vec->sfv_off += count;
+        vec->sfv_len -= count;
+        PR_ASSERT(vec->sfv_len > 0);
+        op->arg2.buffer = vec;
+
+        return PR_FALSE;
+    }
+
+    return PR_TRUE;
+}
+#endif  /* SOLARIS */
+
+#ifdef LINUX 
+static PRBool pt_linux_sendfile_cont(pt_Continuation *op, PRInt16 revents)
+{
+    ssize_t rv;
+    off_t oldoffset;
+
+    oldoffset = op->offset;
+    rv = sendfile(op->arg1.osfd, op->in_fd, &op->offset, op->count);
+    op->syserrno = errno;
+
+    if (rv == -1) {
+        if (op->syserrno != EWOULDBLOCK && op->syserrno != EAGAIN) {
+            op->result.code = -1;
+            return PR_TRUE;
+        }
+        rv = 0;
+    }
+    PR_ASSERT(rv == op->offset - oldoffset);
+    op->result.code += rv;
+    if (rv < op->count) {
+        op->count -= rv;
+        return PR_FALSE;
+    }
+    return PR_TRUE;
+}
+#endif  /* LINUX */
+
+void _PR_InitIO(void)
+{
+#if defined(DEBUG)
+    memset(&pt_debug, 0, sizeof(PTDebug));
+    pt_debug.timeStarted = PR_Now();
+#endif
+
+    _pr_flock_lock = PR_NewLock();
+    PR_ASSERT(NULL != _pr_flock_lock);
+    _pr_flock_cv = PR_NewCondVar(_pr_flock_lock);
+    PR_ASSERT(NULL != _pr_flock_cv);
+    _pr_rename_lock = PR_NewLock();
+    PR_ASSERT(NULL != _pr_rename_lock); 
+
+    _PR_InitFdCache();  /* do that */   
+
+    _pr_stdin = pt_SetMethods(0, PR_DESC_FILE, PR_FALSE, PR_TRUE);
+    _pr_stdout = pt_SetMethods(1, PR_DESC_FILE, PR_FALSE, PR_TRUE);
+    _pr_stderr = pt_SetMethods(2, PR_DESC_FILE, PR_FALSE, PR_TRUE);
+    PR_ASSERT(_pr_stdin && _pr_stdout && _pr_stderr);
+
+#ifdef _PR_IPV6_V6ONLY_PROBE
+    /* In Mac OS X v10.3 Panther Beta the IPV6_V6ONLY socket option
+     * is turned on by default, contrary to what RFC 3493, Section
+     * 5.3 says.  So we have to turn it off.  Find out whether we
+     * are running on such a system.
+     */
+    {
+        int osfd;
+        osfd = socket(AF_INET6, SOCK_STREAM, 0);
+        if (osfd != -1) {
+            int on;
+            int optlen = sizeof(on);
+            if (getsockopt(osfd, IPPROTO_IPV6, IPV6_V6ONLY,
+                    &on, &optlen) == 0) {
+                _pr_ipv6_v6only_on_by_default = on;
+            }
+            close(osfd);
+        }
+    }
+#endif
+}  /* _PR_InitIO */
+
+void _PR_CleanupIO(void)
+{
+    _PR_Putfd(_pr_stdin);
+    _pr_stdin = NULL;
+    _PR_Putfd(_pr_stdout);
+    _pr_stdout = NULL;
+    _PR_Putfd(_pr_stderr); 
+    _pr_stderr = NULL;
+
+    _PR_CleanupFdCache();
+    
+    if (_pr_flock_cv)
+    {
+        PR_DestroyCondVar(_pr_flock_cv);
+        _pr_flock_cv = NULL;
+    }
+    if (_pr_flock_lock)
+    {
+        PR_DestroyLock(_pr_flock_lock);
+        _pr_flock_lock = NULL;
+    }
+    if (_pr_rename_lock)
+    {
+        PR_DestroyLock(_pr_rename_lock);
+        _pr_rename_lock = NULL;
+    }
+}  /* _PR_CleanupIO */
+
+PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd)
+{
+    PRFileDesc *result = NULL;
+    PR_ASSERT(osfd >= PR_StandardInput && osfd <= PR_StandardError);
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    
+    switch (osfd)
+    {
+        case PR_StandardInput: result = _pr_stdin; break;
+        case PR_StandardOutput: result = _pr_stdout; break;
+        case PR_StandardError: result = _pr_stderr; break;
+        default:
+            (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    }
+    return result;
+}  /* PR_GetSpecialFD */
+
+/*****************************************************************************/
+/***************************** I/O private methods ***************************/
+/*****************************************************************************/
+
+static PRBool pt_TestAbort(void)
+{
+    PRThread *me = PR_GetCurrentThread();
+    if(_PT_THREAD_INTERRUPTED(me))
+    {
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        me->state &= ~PT_THREAD_ABORTED;
+        return PR_TRUE;
+    }
+    return PR_FALSE;
+}  /* pt_TestAbort */
+
+static void pt_MapError(void (*mapper)(PRIntn), PRIntn syserrno)
+{
+    switch (syserrno)
+    {
+        case EINTR:
+            PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0); break;
+        case ETIMEDOUT:
+            PR_SetError(PR_IO_TIMEOUT_ERROR, 0); break;
+        default:
+            mapper(syserrno);
+    }
+}  /* pt_MapError */
+
+static PRStatus pt_Close(PRFileDesc *fd)
+{
+    if ((NULL == fd) || (NULL == fd->secret)
+        || ((_PR_FILEDESC_OPEN != fd->secret->state)
+        && (_PR_FILEDESC_CLOSED != fd->secret->state)))
+    {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    if (_PR_FILEDESC_OPEN == fd->secret->state)
+    {
+        if (-1 == close(fd->secret->md.osfd))
+        {
+#ifdef OSF1
+            /*
+             * Bug 86941: On Tru64 UNIX V5.0A and V5.1, the close()
+             * system call, when called to close a TCP socket, may
+             * return -1 with errno set to EINVAL but the system call
+             * does close the socket successfully.  An application
+             * may safely ignore the EINVAL error.  This bug is fixed
+             * on Tru64 UNIX V5.1A and later.  The defect tracking
+             * number is QAR 81431.
+             */
+            if (PR_DESC_SOCKET_TCP != fd->methods->file_type
+            || EINVAL != errno)
+            {
+                pt_MapError(_PR_MD_MAP_CLOSE_ERROR, errno);
+                return PR_FAILURE;
+            }
+#else
+            pt_MapError(_PR_MD_MAP_CLOSE_ERROR, errno);
+            return PR_FAILURE;
+#endif
+        }
+        fd->secret->state = _PR_FILEDESC_CLOSED;
+    }
+    _PR_Putfd(fd);
+    return PR_SUCCESS;
+}  /* pt_Close */
+
+static PRInt32 pt_Read(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+    PRInt32 syserrno, bytes = -1;
+
+    if (pt_TestAbort()) return bytes;
+
+    bytes = read(fd->secret->md.osfd, buf, amount);
+    syserrno = errno;
+
+    if ((bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking))
+    {
+        pt_Continuation op;
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = buf;
+        op.arg3.amount = amount;
+        op.timeout = PR_INTERVAL_NO_TIMEOUT;
+        op.function = pt_read_cont;
+        op.event = POLLIN | POLLPRI;
+        bytes = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+    if (bytes < 0)
+        pt_MapError(_PR_MD_MAP_READ_ERROR, syserrno);
+    return bytes;
+}  /* pt_Read */
+
+static PRInt32 pt_Write(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+    PRInt32 syserrno, bytes = -1;
+    PRBool fNeedContinue = PR_FALSE;
+
+    if (pt_TestAbort()) return bytes;
+
+    bytes = write(fd->secret->md.osfd, buf, amount);
+    syserrno = errno;
+
+    if ( (bytes >= 0) && (bytes < amount) && (!fd->secret->nonblocking) )
+    {
+        buf = (char *) buf + bytes;
+        amount -= bytes;
+        fNeedContinue = PR_TRUE;
+    }
+    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking) )
+    {
+        bytes = 0;
+        fNeedContinue = PR_TRUE;
+    }
+
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = (void*)buf;
+        op.arg3.amount = amount;
+        op.timeout = PR_INTERVAL_NO_TIMEOUT;
+        op.result.code = bytes;  /* initialize the number sent */
+        op.function = pt_write_cont;
+        op.event = POLLOUT | POLLPRI;
+        bytes = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+    if (bytes == -1)
+        pt_MapError(_PR_MD_MAP_WRITE_ERROR, syserrno);
+    return bytes;
+}  /* pt_Write */
+
+static PRInt32 pt_Writev(
+    PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_len, PRIntervalTime timeout)
+{
+    PRIntn iov_index;
+    PRBool fNeedContinue = PR_FALSE;
+    PRInt32 syserrno, bytes, rv = -1;
+    struct iovec osiov_local[PR_MAX_IOVECTOR_SIZE], *osiov;
+    int osiov_len;
+
+    if (pt_TestAbort()) return rv;
+
+    /* Ensured by PR_Writev */
+    PR_ASSERT(iov_len <= PR_MAX_IOVECTOR_SIZE);
+
+    /*
+     * We can't pass iov to writev because PRIOVec and struct iovec
+     * may not be binary compatible.  Make osiov a copy of iov and
+     * pass osiov to writev.  We can modify osiov if we need to
+     * continue the operation.
+     */
+    osiov = osiov_local;
+    osiov_len = iov_len;
+    for (iov_index = 0; iov_index < osiov_len; iov_index++)
+    {
+        osiov[iov_index].iov_base = iov[iov_index].iov_base;
+        osiov[iov_index].iov_len = iov[iov_index].iov_len;
+    }
+
+    rv = bytes = writev(fd->secret->md.osfd, osiov, osiov_len);
+    syserrno = errno;
+
+    if (!fd->secret->nonblocking)
+    {
+        if (bytes >= 0)
+        {
+            /*
+             * If we moved some bytes, how does that implicate the
+             * i/o vector list?  In other words, exactly where are
+             * we within that array?  What are the parameters for
+             * resumption?  Maybe we're done!
+             */
+            for ( ;osiov_len > 0; osiov++, osiov_len--)
+            {
+                if (bytes < osiov->iov_len)
+                {
+                    /* this one's not done yet */
+                    osiov->iov_base = (char*)osiov->iov_base + bytes;
+                    osiov->iov_len -= bytes;
+                    break;  /* go off and do that */
+                }
+                bytes -= osiov->iov_len;  /* this one's done cooked */
+            }
+            PR_ASSERT(osiov_len > 0 || bytes == 0);
+            if (osiov_len > 0)
+            {
+                if (PR_INTERVAL_NO_WAIT == timeout)
+                {
+                    rv = -1;
+                    syserrno = ETIMEDOUT;
+                }
+                else fNeedContinue = PR_TRUE;
+            }
+        }
+        else if (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        {
+            if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+            else
+            {
+                rv = 0;
+                fNeedContinue = PR_TRUE;
+            }
+        }
+    }
+
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = (void*)osiov;
+        op.arg3.amount = osiov_len;
+        op.timeout = timeout;
+        op.result.code = rv;
+        op.function = pt_writev_cont;
+        op.event = POLLOUT | POLLPRI;
+        rv = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+    if (rv == -1) pt_MapError(_PR_MD_MAP_WRITEV_ERROR, syserrno);
+    return rv;
+}  /* pt_Writev */
+
+static PRInt32 pt_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
+{
+    return _PR_MD_LSEEK(fd, offset, whence);
+}  /* pt_Seek */
+
+static PRInt64 pt_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
+{
+    return _PR_MD_LSEEK64(fd, offset, whence);
+}  /* pt_Seek64 */
+
+static PRInt32 pt_Available_f(PRFileDesc *fd)
+{
+    PRInt32 result, cur, end;
+
+    cur = _PR_MD_LSEEK(fd, 0, PR_SEEK_CUR);
+
+    if (cur >= 0)
+        end = _PR_MD_LSEEK(fd, 0, PR_SEEK_END);
+
+    if ((cur < 0) || (end < 0)) {
+        return -1;
+    }
+
+    result = end - cur;
+    _PR_MD_LSEEK(fd, cur, PR_SEEK_SET);
+
+    return result;
+}  /* pt_Available_f */
+
+static PRInt64 pt_Available64_f(PRFileDesc *fd)
+{
+    PRInt64 result, cur, end;
+    PRInt64 minus_one;
+
+    LL_I2L(minus_one, -1);
+    cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR);
+
+    if (LL_GE_ZERO(cur))
+        end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END);
+
+    if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one;
+
+    LL_SUB(result, end, cur);
+    (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET);
+
+    return result;
+}  /* pt_Available64_f */
+
+static PRInt32 pt_Available_s(PRFileDesc *fd)
+{
+    PRInt32 rv, bytes = -1;
+    if (pt_TestAbort()) return bytes;
+
+    rv = ioctl(fd->secret->md.osfd, FIONREAD, &bytes);
+
+    if (rv == -1)
+        pt_MapError(_PR_MD_MAP_SOCKETAVAILABLE_ERROR, errno);
+    return bytes;
+}  /* pt_Available_s */
+
+static PRInt64 pt_Available64_s(PRFileDesc *fd)
+{
+    PRInt64 rv;
+    LL_I2L(rv, pt_Available_s(fd));
+    return rv;
+}  /* pt_Available64_s */
+
+static PRStatus pt_FileInfo(PRFileDesc *fd, PRFileInfo *info)
+{
+    PRInt32 rv = _PR_MD_GETOPENFILEINFO(fd, info);
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* pt_FileInfo */
+
+static PRStatus pt_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
+{
+    PRInt32 rv = _PR_MD_GETOPENFILEINFO64(fd, info);
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* pt_FileInfo64 */
+
+static PRStatus pt_Synch(PRFileDesc *fd)
+{
+    return (NULL == fd) ? PR_FAILURE : PR_SUCCESS;
+} /* pt_Synch */
+
+static PRStatus pt_Fsync(PRFileDesc *fd)
+{
+    PRIntn rv = -1;
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = fsync(fd->secret->md.osfd);
+    if (rv < 0) {
+        pt_MapError(_PR_MD_MAP_FSYNC_ERROR, errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_Fsync */
+
+static PRStatus pt_Connect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRIntn rv = -1, syserrno;
+    pt_SockLen addr_len;
+	const PRNetAddr *addrp = addr;
+#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
+	PRUint16 md_af = addr->raw.family;
+    PRNetAddr addrCopy;
+#endif
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+    addr_len = PR_NETADDR_SIZE(addr);
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		md_af = AF_INET6;
+#ifndef _PR_HAVE_SOCKADDR_LEN
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+#endif
+	}
+#endif
+
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    addrCopy = *addr;
+    ((struct sockaddr*)&addrCopy)->sa_len = addr_len;
+    ((struct sockaddr*)&addrCopy)->sa_family = md_af;
+    addrp = &addrCopy;
+#endif
+    rv = connect(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len);
+    syserrno = errno;
+    if ((-1 == rv) && (EINPROGRESS == syserrno) && (!fd->secret->nonblocking))
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+        else
+        {
+            pt_Continuation op;
+            op.arg1.osfd = fd->secret->md.osfd;
+            op.arg2.buffer = (void*)addrp;
+            op.arg3.amount = addr_len;
+            op.timeout = timeout;
+            op.function = pt_connect_cont;
+            op.event = POLLOUT | POLLPRI;
+            rv = pt_Continue(&op);
+            syserrno = op.syserrno;
+        }
+    }
+    if (-1 == rv) {
+        pt_MapError(_PR_MD_MAP_CONNECT_ERROR, syserrno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_Connect */
+
+static PRStatus pt_ConnectContinue(
+    PRFileDesc *fd, PRInt16 out_flags)
+{
+    int err;
+    PRInt32 osfd;
+
+    if (out_flags & PR_POLL_NVAL)
+    {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if ((out_flags & (PR_POLL_WRITE | PR_POLL_EXCEPT | PR_POLL_ERR)) == 0)
+    {
+        PR_ASSERT(out_flags == 0);
+        PR_SetError(PR_IN_PROGRESS_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    osfd = fd->secret->md.osfd;
+
+    err = _MD_unix_get_nonblocking_connect_error(osfd);
+    if (err != 0)
+    {
+        _PR_MD_MAP_CONNECT_ERROR(err);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_ConnectContinue */
+
+PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
+{
+    /* Find the NSPR layer and invoke its connectcontinue method */
+    PRFileDesc *bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);
+
+    if (NULL == bottom)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    return pt_ConnectContinue(bottom, pd->out_flags);
+}  /* PR_GetConnectStatus */
+
+static PRFileDesc* pt_Accept(
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRFileDesc *newfd = NULL;
+    PRIntn syserrno, osfd = -1;
+    pt_SockLen addr_len = sizeof(PRNetAddr);
+
+    if (pt_TestAbort()) return newfd;
+
+#ifdef _PR_STRICT_ADDR_LEN
+    if (addr)
+    {
+        /*
+         * Set addr->raw.family just so that we can use the
+         * PR_NETADDR_SIZE macro.
+         */
+        addr->raw.family = fd->secret->af;
+        addr_len = PR_NETADDR_SIZE(addr);
+    }
+#endif
+
+    osfd = accept(fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len);
+    syserrno = errno;
+
+    if (osfd == -1)
+    {
+        if (fd->secret->nonblocking) goto failed;
+
+        if (EWOULDBLOCK != syserrno && EAGAIN != syserrno
+        && ECONNABORTED != syserrno)
+            goto failed;
+        else
+        {
+            if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+            else
+            {
+                pt_Continuation op;
+                op.arg1.osfd = fd->secret->md.osfd;
+                op.arg2.buffer = addr;
+                op.arg3.addr_len = &addr_len;
+                op.timeout = timeout;
+                op.function = pt_accept_cont;
+                op.event = POLLIN | POLLPRI;
+                osfd = pt_Continue(&op);
+                syserrno = op.syserrno;
+            }
+            if (osfd < 0) goto failed;
+        }
+    }
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    /* ignore the sa_len field of struct sockaddr */
+    if (addr)
+    {
+        addr->raw.family = ((struct sockaddr*)addr)->sa_family;
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+#ifdef _PR_INET6
+	if (addr && (AF_INET6 == addr->raw.family))
+        addr->raw.family = PR_AF_INET6;
+#endif
+    newfd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_TRUE, PR_FALSE);
+    if (newfd == NULL) close(osfd);  /* $$$ whoops! this doesn't work $$$ */
+    else
+    {
+        PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+        PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
+#ifdef LINUX
+        /*
+         * On Linux, experiments showed that the accepted sockets
+         * inherit the TCP_NODELAY socket option of the listening
+         * socket.
+         */
+        newfd->secret->md.tcp_nodelay = fd->secret->md.tcp_nodelay;
+#endif
+    }
+    return newfd;
+
+failed:
+    pt_MapError(_PR_MD_MAP_ACCEPT_ERROR, syserrno);
+    return NULL;
+}  /* pt_Accept */
+
+static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr)
+{
+    PRIntn rv;
+    pt_SockLen addr_len;
+	const PRNetAddr *addrp = addr;
+#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
+	PRUint16 md_af = addr->raw.family;
+    PRNetAddr addrCopy;
+#endif
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+    if (addr->raw.family == AF_UNIX)
+    {
+        /* Disallow relative pathnames */
+        if (addr->local.path[0] != '/')
+        {
+            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+            return PR_FAILURE;
+        }
+    }
+
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		md_af = AF_INET6;
+#ifndef _PR_HAVE_SOCKADDR_LEN
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+#endif
+	}
+#endif
+
+    addr_len = PR_NETADDR_SIZE(addr);
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    addrCopy = *addr;
+    ((struct sockaddr*)&addrCopy)->sa_len = addr_len;
+    ((struct sockaddr*)&addrCopy)->sa_family = md_af;
+    addrp = &addrCopy;
+#endif
+    rv = bind(fd->secret->md.osfd, (struct sockaddr*)addrp, addr_len);
+
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_BIND_ERROR, errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_Bind */
+
+static PRStatus pt_Listen(PRFileDesc *fd, PRIntn backlog)
+{
+    PRIntn rv;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = listen(fd->secret->md.osfd, backlog);
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_LISTEN_ERROR, errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_Listen */
+
+static PRStatus pt_Shutdown(PRFileDesc *fd, PRIntn how)
+{
+    PRIntn rv = -1;
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = shutdown(fd->secret->md.osfd, how);
+
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_SHUTDOWN_ERROR, errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* pt_Shutdown */
+
+static PRInt16 pt_Poll(PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    *out_flags = 0;
+    return in_flags;
+}  /* pt_Poll */
+
+static PRInt32 pt_Recv(
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    PRInt32 syserrno, bytes = -1;
+    PRIntn osflags;
+
+    if (0 == flags)
+        osflags = 0;
+    else if (PR_MSG_PEEK == flags)
+        osflags = MSG_PEEK;
+    else
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return bytes;
+    }
+
+    if (pt_TestAbort()) return bytes;
+
+    /* recv() is a much slower call on pre-2.6 Solaris than read(). */
+#if defined(SOLARIS)
+    if (0 == osflags)
+        bytes = read(fd->secret->md.osfd, buf, amount);
+    else
+        bytes = recv(fd->secret->md.osfd, buf, amount, osflags);
+#else
+    bytes = recv(fd->secret->md.osfd, buf, amount, osflags);
+#endif
+    syserrno = errno;
+
+    if ((bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking))
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+        else
+        {
+            pt_Continuation op;
+            op.arg1.osfd = fd->secret->md.osfd;
+            op.arg2.buffer = buf;
+            op.arg3.amount = amount;
+            op.arg4.flags = osflags;
+            op.timeout = timeout;
+            op.function = pt_recv_cont;
+            op.event = POLLIN | POLLPRI;
+            bytes = pt_Continue(&op);
+            syserrno = op.syserrno;
+        }
+    }
+    if (bytes < 0)
+        pt_MapError(_PR_MD_MAP_RECV_ERROR, syserrno);
+    return bytes;
+}  /* pt_Recv */
+
+static PRInt32 pt_SocketRead(PRFileDesc *fd, void *buf, PRInt32 amount)
+{
+    return pt_Recv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
+}  /* pt_SocketRead */
+
+static PRInt32 pt_Send(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    PRInt32 syserrno, bytes = -1;
+    PRBool fNeedContinue = PR_FALSE;
+#if defined(SOLARIS)
+	PRInt32 tmp_amount = amount;
+#endif
+
+    /*
+     * Under HP-UX DCE threads, pthread.h includes dce/cma_ux.h,
+     * which has the following:
+     *     #  define send        cma_send
+     *     extern int  cma_send (int , void *, int, int );
+     * So we need to cast away the 'const' of argument #2 for send().
+     */
+#if defined (HPUX) && defined(_PR_DCETHREADS)
+#define PT_SENDBUF_CAST (void *)
+#else
+#define PT_SENDBUF_CAST
+#endif
+
+    if (pt_TestAbort()) return bytes;
+
+    /*
+     * On pre-2.6 Solaris, send() is much slower than write().
+     * On 2.6 and beyond, with in-kernel sockets, send() and
+     * write() are fairly equivalent in performance.
+     */
+#if defined(SOLARIS)
+    PR_ASSERT(0 == flags);
+retry:
+    bytes = write(fd->secret->md.osfd, PT_SENDBUF_CAST buf, tmp_amount);
+#else
+    bytes = send(fd->secret->md.osfd, PT_SENDBUF_CAST buf, amount, flags);
+#endif
+    syserrno = errno;
+
+#if defined(SOLARIS)
+    /*
+     * The write system call has been reported to return the ERANGE error
+     * on occasion. Try to write in smaller chunks to workaround this bug.
+     */
+    if ((bytes == -1) && (syserrno == ERANGE))
+    {
+        if (tmp_amount > 1)
+        {
+            tmp_amount = tmp_amount/2;  /* half the bytes */
+            goto retry;
+        }
+    }
+#endif
+
+    if ( (bytes >= 0) && (bytes < amount) && (!fd->secret->nonblocking) )
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout)
+        {
+            bytes = -1;
+            syserrno = ETIMEDOUT;
+        }
+        else
+        {
+            buf = (char *) buf + bytes;
+            amount -= bytes;
+            fNeedContinue = PR_TRUE;
+        }
+    }
+    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking) )
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+        else
+        {
+            bytes = 0;
+            fNeedContinue = PR_TRUE;
+        }
+    }
+
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = (void*)buf;
+        op.arg3.amount = amount;
+        op.arg4.flags = flags;
+        op.timeout = timeout;
+        op.result.code = bytes;  /* initialize the number sent */
+        op.function = pt_send_cont;
+        op.event = POLLOUT | POLLPRI;
+        bytes = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+    if (bytes == -1)
+        pt_MapError(_PR_MD_MAP_SEND_ERROR, syserrno);
+    return bytes;
+}  /* pt_Send */
+
+static PRInt32 pt_SocketWrite(PRFileDesc *fd, const void *buf, PRInt32 amount)
+{
+    return pt_Send(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
+}  /* pt_SocketWrite */
+
+static PRInt32 pt_SendTo(
+    PRFileDesc *fd, const void *buf,
+    PRInt32 amount, PRIntn flags, const PRNetAddr *addr,
+    PRIntervalTime timeout)
+{
+    PRInt32 syserrno, bytes = -1;
+    PRBool fNeedContinue = PR_FALSE;
+    pt_SockLen addr_len;
+	const PRNetAddr *addrp = addr;
+#if defined(_PR_HAVE_SOCKADDR_LEN) || defined(_PR_INET6)
+	PRUint16 md_af = addr->raw.family;
+    PRNetAddr addrCopy;
+#endif
+
+    if (pt_TestAbort()) return bytes;
+
+    PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		md_af = AF_INET6;
+#ifndef _PR_HAVE_SOCKADDR_LEN
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+#endif
+	}
+#endif
+
+    addr_len = PR_NETADDR_SIZE(addr);
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    addrCopy = *addr;
+    ((struct sockaddr*)&addrCopy)->sa_len = addr_len;
+    ((struct sockaddr*)&addrCopy)->sa_family = md_af;
+    addrp = &addrCopy;
+#endif
+    bytes = sendto(
+        fd->secret->md.osfd, buf, amount, flags,
+        (struct sockaddr*)addrp, addr_len);
+    syserrno = errno;
+    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking) )
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+        else fNeedContinue = PR_TRUE;
+    }
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = (void*)buf;
+        op.arg3.amount = amount;
+        op.arg4.flags = flags;
+        op.arg5.addr = (PRNetAddr*)addrp;
+        op.timeout = timeout;
+        op.result.code = 0;  /* initialize the number sent */
+        op.function = pt_sendto_cont;
+        op.event = POLLOUT | POLLPRI;
+        bytes = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+    if (bytes < 0)
+        pt_MapError(_PR_MD_MAP_SENDTO_ERROR, syserrno);
+    return bytes;
+}  /* pt_SendTo */
+
+static PRInt32 pt_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRBool fNeedContinue = PR_FALSE;
+    PRInt32 syserrno, bytes = -1;
+    pt_SockLen addr_len = sizeof(PRNetAddr);
+
+    if (pt_TestAbort()) return bytes;
+
+    bytes = recvfrom(
+        fd->secret->md.osfd, buf, amount, flags,
+        (struct sockaddr*)addr, &addr_len);
+    syserrno = errno;
+
+    if ( (bytes == -1) && (syserrno == EWOULDBLOCK || syserrno == EAGAIN)
+        && (!fd->secret->nonblocking) )
+    {
+        if (PR_INTERVAL_NO_WAIT == timeout) syserrno = ETIMEDOUT;
+        else fNeedContinue = PR_TRUE;
+    }
+
+    if (fNeedContinue == PR_TRUE)
+    {
+        pt_Continuation op;
+        op.arg1.osfd = fd->secret->md.osfd;
+        op.arg2.buffer = buf;
+        op.arg3.amount = amount;
+        op.arg4.flags = flags;
+        op.arg5.addr = addr;
+        op.timeout = timeout;
+        op.function = pt_recvfrom_cont;
+        op.event = POLLIN | POLLPRI;
+        bytes = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+#ifdef _PR_HAVE_SOCKADDR_LEN
+    if (bytes >= 0)
+    {
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr)
+        {
+            addr->raw.family = ((struct sockaddr*)addr)->sa_family;
+        }
+    }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+#ifdef _PR_INET6
+	if (addr && (AF_INET6 == addr->raw.family))
+        addr->raw.family = PR_AF_INET6;
+#endif
+    if (bytes < 0)
+        pt_MapError(_PR_MD_MAP_RECVFROM_ERROR, syserrno);
+    return bytes;
+}  /* pt_RecvFrom */
+
+#ifdef AIX
+#ifndef HAVE_SEND_FILE
+static pthread_once_t pt_aix_sendfile_once_block = PTHREAD_ONCE_INIT;
+
+static void pt_aix_sendfile_init_routine(void)
+{
+    void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL);
+    pt_aix_sendfile_fptr = (ssize_t (*)()) dlsym(handle, "send_file");
+    dlclose(handle);
+}
+
+/* 
+ * pt_AIXDispatchSendFile
+ */
+static PRInt32 pt_AIXDispatchSendFile(PRFileDesc *sd, PRSendFileData *sfd,
+	  PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    int rv;
+
+    rv = pthread_once(&pt_aix_sendfile_once_block,
+            pt_aix_sendfile_init_routine);
+    PR_ASSERT(0 == rv);
+    if (pt_aix_sendfile_fptr) {
+        return pt_AIXSendFile(sd, sfd, flags, timeout);
+    } else {
+        return PR_EmulateSendFile(sd, sfd, flags, timeout);
+    }
+}
+#endif /* !HAVE_SEND_FILE */
+
+
+/*
+ * pt_AIXSendFile
+ *
+ *    Send file sfd->fd across socket sd. If specified, header and trailer
+ *    buffers are sent before and after the file, respectively. 
+ *
+ *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
+ *    
+ *    return number of bytes sent or -1 on error
+ *
+ *      This implementation takes advantage of the send_file() system
+ *      call available in AIX 4.3.2.
+ */
+
+static PRInt32 pt_AIXSendFile(PRFileDesc *sd, PRSendFileData *sfd, 
+		PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    struct sf_parms sf_struct;
+    uint_t send_flags;
+    ssize_t rv;
+    int syserrno;
+    PRInt32 count;
+	unsigned long long saved_file_offset;
+	long long saved_file_bytes;
+
+    sf_struct.header_data = (void *) sfd->header;  /* cast away the 'const' */
+    sf_struct.header_length = sfd->hlen;
+    sf_struct.file_descriptor = sfd->fd->secret->md.osfd;
+    sf_struct.file_size = 0;
+    sf_struct.file_offset = sfd->file_offset;
+    if (sfd->file_nbytes == 0)
+    	sf_struct.file_bytes = -1;
+	else
+    	sf_struct.file_bytes = sfd->file_nbytes;
+    sf_struct.trailer_data = (void *) sfd->trailer;
+    sf_struct.trailer_length = sfd->tlen;
+    sf_struct.bytes_sent = 0;
+
+	saved_file_offset = sf_struct.file_offset;
+    saved_file_bytes = sf_struct.file_bytes;
+
+    send_flags = 0;			/* flags processed at the end */
+
+    /* The first argument to send_file() is int*. */
+    PR_ASSERT(sizeof(int) == sizeof(sd->secret->md.osfd));
+    do {
+        rv = AIX_SEND_FILE(&sd->secret->md.osfd, &sf_struct, send_flags);
+    } while (rv == -1 && (syserrno = errno) == EINTR);
+
+    if (rv == -1) {
+        if (syserrno == EAGAIN || syserrno == EWOULDBLOCK) {
+            count = 0; /* Not a real error.  Need to continue. */
+        } else {
+            count = -1;
+        }
+    } else {
+        count = sf_struct.bytes_sent;
+		/*
+		 * A bug in AIX 4.3.2 prevents the 'file_bytes' field from
+		 * being updated. So, 'file_bytes' is maintained by NSPR to
+		 * avoid conflict when this bug is fixed in AIX, in the future.
+		 */
+		if (saved_file_bytes != -1)
+			saved_file_bytes -= (sf_struct.file_offset - saved_file_offset);
+		sf_struct.file_bytes = saved_file_bytes;
+    }
+
+    if ((rv == 1) || ((rv == -1) && (count == 0))) {
+        pt_Continuation op;
+
+        op.arg1.osfd = sd->secret->md.osfd;
+        op.arg2.buffer = &sf_struct;
+        op.arg4.flags = send_flags;
+        op.result.code = count;
+        op.timeout = timeout;
+        op.function = pt_aix_sendfile_cont;
+        op.event = POLLOUT | POLLPRI;
+        count = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+
+    if (count == -1) {
+        pt_MapError(_MD_aix_map_sendfile_error, syserrno);
+        return -1;
+    }
+    if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
+        PR_Close(sd);
+    }
+	PR_ASSERT(count == (sfd->hlen + sfd->tlen +
+						((sfd->file_nbytes ==  0) ?
+						sf_struct.file_size - sfd->file_offset :
+						sfd->file_nbytes)));
+    return count;
+}
+#endif /* AIX */
+
+#ifdef HPUX11
+/*
+ * pt_HPUXSendFile
+ *
+ *    Send file sfd->fd across socket sd. If specified, header and trailer
+ *    buffers are sent before and after the file, respectively.
+ *
+ *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
+ *    
+ *    return number of bytes sent or -1 on error
+ *
+ *      This implementation takes advantage of the sendfile() system
+ *      call available in HP-UX B.11.00.
+ */
+
+static PRInt32 pt_HPUXSendFile(PRFileDesc *sd, PRSendFileData *sfd, 
+		PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    struct stat statbuf;
+    size_t nbytes_to_send, file_nbytes_to_send;
+    struct iovec hdtrl[2];  /* optional header and trailer buffers */
+    int send_flags;
+    PRInt32 count;
+    int syserrno;
+
+    if (sfd->file_nbytes == 0) {
+        /* Get file size */
+        if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) {
+            _PR_MD_MAP_FSTAT_ERROR(errno);
+            return -1;
+        } 		
+        file_nbytes_to_send = statbuf.st_size - sfd->file_offset;
+    } else {
+        file_nbytes_to_send = sfd->file_nbytes;
+    }
+    nbytes_to_send = sfd->hlen + sfd->tlen + file_nbytes_to_send;
+
+    hdtrl[0].iov_base = (void *) sfd->header;  /* cast away the 'const' */
+    hdtrl[0].iov_len = sfd->hlen;
+    hdtrl[1].iov_base = (void *) sfd->trailer;
+    hdtrl[1].iov_len = sfd->tlen;
+    /*
+     * SF_DISCONNECT seems to close the socket even if sendfile()
+     * only does a partial send on a nonblocking socket.  This
+     * would prevent the subsequent sendfile() calls on that socket
+     * from working.  So we don't use the SD_DISCONNECT flag.
+     */
+    send_flags = 0;
+
+    do {
+        count = sendfile(sd->secret->md.osfd, sfd->fd->secret->md.osfd,
+                sfd->file_offset, file_nbytes_to_send, hdtrl, send_flags);
+    } while (count == -1 && (syserrno = errno) == EINTR);
+
+    if (count == -1 && (syserrno == EAGAIN || syserrno == EWOULDBLOCK)) {
+        count = 0;
+    }
+    if (count != -1 && count < nbytes_to_send) {
+        pt_Continuation op;
+
+        if (count < sfd->hlen) {
+			/* header not sent */
+
+            hdtrl[0].iov_base = ((char *) sfd->header) + count;
+            hdtrl[0].iov_len = sfd->hlen - count;
+            op.arg3.file_spec.offset = sfd->file_offset;
+            op.arg3.file_spec.nbytes = file_nbytes_to_send;
+        } else if (count < (sfd->hlen + file_nbytes_to_send)) {
+			/* header sent, file not sent */
+
+            hdtrl[0].iov_base = NULL;
+            hdtrl[0].iov_len = 0;
+
+            op.arg3.file_spec.offset = sfd->file_offset + count - sfd->hlen;
+            op.arg3.file_spec.nbytes = file_nbytes_to_send - (count - sfd->hlen);
+        } else if (count < (sfd->hlen + file_nbytes_to_send + sfd->tlen)) {
+			PRUint32 trailer_nbytes_sent;
+
+			/* header sent, file sent, trailer not sent */
+
+            hdtrl[0].iov_base = NULL;
+            hdtrl[0].iov_len = 0;
+			/*
+			 * set file offset and len so that no more file data is
+			 * sent
+			 */
+            op.arg3.file_spec.offset = statbuf.st_size;
+            op.arg3.file_spec.nbytes = 0;
+
+			trailer_nbytes_sent = count - sfd->hlen - file_nbytes_to_send;
+            hdtrl[1].iov_base = ((char *) sfd->trailer) + trailer_nbytes_sent;
+            hdtrl[1].iov_len = sfd->tlen - trailer_nbytes_sent;
+		}
+
+        op.arg1.osfd = sd->secret->md.osfd;
+        op.filedesc = sfd->fd->secret->md.osfd;
+        op.arg2.buffer = hdtrl;
+        op.arg3.file_spec.st_size = statbuf.st_size;
+        op.arg4.flags = send_flags;
+        op.nbytes_to_send = nbytes_to_send - count;
+        op.result.code = count;
+        op.timeout = timeout;
+        op.function = pt_hpux_sendfile_cont;
+        op.event = POLLOUT | POLLPRI;
+        count = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+
+    if (count == -1) {
+        pt_MapError(_MD_hpux_map_sendfile_error, syserrno);
+        return -1;
+    }
+    if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
+        PR_Close(sd);
+    }
+    PR_ASSERT(count == nbytes_to_send);
+    return count;
+}
+
+#endif  /* HPUX11 */
+
+#ifdef SOLARIS 
+
+/*
+ *    pt_SolarisSendFile
+ *
+ *    Send file sfd->fd across socket sd. If specified, header and trailer
+ *    buffers are sent before and after the file, respectively.
+ *
+ *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
+ *
+ *    return number of bytes sent or -1 on error
+ *
+ *    This implementation takes advantage of the sendfilev() system
+ *    call available in Solaris 8.
+ */
+
+static PRInt32 pt_SolarisSendFile(PRFileDesc *sd, PRSendFileData *sfd,
+                PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    struct stat statbuf;
+    size_t nbytes_to_send, file_nbytes_to_send;	
+    struct sendfilevec sfv_struct[3];  
+    int sfvcnt = 0;	
+    size_t xferred;
+    PRInt32 count;
+    int syserrno;
+
+    if (sfd->file_nbytes == 0) {
+        /* Get file size */
+        if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) {
+            _PR_MD_MAP_FSTAT_ERROR(errno);
+            return -1;
+        } 		
+        file_nbytes_to_send = statbuf.st_size - sfd->file_offset;
+    } else {
+        file_nbytes_to_send = sfd->file_nbytes;
+    }
+
+    nbytes_to_send = sfd->hlen + sfd->tlen + file_nbytes_to_send;
+
+    if (sfd->hlen != 0) {
+        sfv_struct[sfvcnt].sfv_fd = SFV_FD_SELF;
+        sfv_struct[sfvcnt].sfv_flag = 0;
+        sfv_struct[sfvcnt].sfv_off = (off_t) sfd->header; 
+        sfv_struct[sfvcnt].sfv_len = sfd->hlen;
+        sfvcnt++;
+    }
+
+    if (file_nbytes_to_send != 0) {
+        sfv_struct[sfvcnt].sfv_fd = sfd->fd->secret->md.osfd;
+        sfv_struct[sfvcnt].sfv_flag = 0;
+        sfv_struct[sfvcnt].sfv_off = sfd->file_offset;
+        sfv_struct[sfvcnt].sfv_len = file_nbytes_to_send;
+        sfvcnt++;
+    }
+
+    if (sfd->tlen != 0) {
+        sfv_struct[sfvcnt].sfv_fd = SFV_FD_SELF;
+        sfv_struct[sfvcnt].sfv_flag = 0;
+        sfv_struct[sfvcnt].sfv_off = (off_t) sfd->trailer; 
+        sfv_struct[sfvcnt].sfv_len = sfd->tlen;
+        sfvcnt++;
+    }
+
+    if (0 == sfvcnt) {
+        count = 0;
+        goto done;
+    }
+   	   
+    /*
+     * Strictly speaking, we may have sent some bytes when the
+     * sendfilev() is interrupted and we should retry it from an
+     * updated offset.  We are not doing that here.
+     */
+    count = SOLARIS_SENDFILEV(sd->secret->md.osfd, sfv_struct,
+            sfvcnt, &xferred);
+
+    PR_ASSERT((count == -1) || (count == xferred));
+
+    if (count == -1) {
+        syserrno = errno;
+        if (syserrno == EINTR
+                || syserrno == EAGAIN || syserrno == EWOULDBLOCK) {
+            count = xferred;
+        }
+    }
+
+    if (count != -1 && count < nbytes_to_send) {
+        pt_Continuation op;
+        struct sendfilevec *vec = sfv_struct;
+        PRInt32 rem = count;
+
+        while (rem >= vec->sfv_len) {
+            rem -= vec->sfv_len;
+            vec++;
+            sfvcnt--;
+        }
+        PR_ASSERT(sfvcnt > 0);
+
+        vec->sfv_off += rem;
+        vec->sfv_len -= rem;
+        PR_ASSERT(vec->sfv_len > 0);
+
+        op.arg1.osfd = sd->secret->md.osfd;
+        op.arg2.buffer = vec;
+        op.arg3.amount = sfvcnt;
+        op.arg4.flags = 0;
+        op.nbytes_to_send = nbytes_to_send - count;
+        op.result.code = count;
+        op.timeout = timeout;
+        op.function = pt_solaris_sendfile_cont;
+        op.event = POLLOUT | POLLPRI;
+        count = pt_Continue(&op);
+        syserrno = op.syserrno;
+    }
+
+done:
+    if (count == -1) {
+        pt_MapError(_MD_solaris_map_sendfile_error, syserrno);
+        return -1;
+    }
+    if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
+        PR_Close(sd);
+    }
+    PR_ASSERT(count == nbytes_to_send);
+    return count;
+}
+
+#ifndef HAVE_SENDFILEV
+static pthread_once_t pt_solaris_sendfilev_once_block = PTHREAD_ONCE_INIT;
+
+static void pt_solaris_sendfilev_init_routine(void)
+{
+    void *handle;
+    PRBool close_it = PR_FALSE;
+ 
+    /*
+     * We do not want to unload libsendfile.so.  This handle is leaked
+     * intentionally.
+     */
+    handle = dlopen("libsendfile.so", RTLD_LAZY | RTLD_GLOBAL);
+    PR_LOG(_pr_io_lm, PR_LOG_DEBUG,
+        ("dlopen(libsendfile.so) returns %p", handle));
+
+    if (NULL == handle) {
+        /*
+         * The dlopen(0, mode) call is to allow for the possibility that
+         * sendfilev() may become part of a standard system library in a
+         * future Solaris release.
+         */
+        handle = dlopen(0, RTLD_LAZY | RTLD_GLOBAL);
+        PR_LOG(_pr_io_lm, PR_LOG_DEBUG,
+            ("dlopen(0) returns %p", handle));
+        close_it = PR_TRUE;
+    }
+    pt_solaris_sendfilev_fptr = (ssize_t (*)()) dlsym(handle, "sendfilev");
+    PR_LOG(_pr_io_lm, PR_LOG_DEBUG,
+        ("dlsym(sendfilev) returns %p", pt_solaris_sendfilev_fptr));
+    
+    if (close_it) {
+        dlclose(handle);
+    }
+}
+
+/* 
+ * pt_SolarisDispatchSendFile
+ */
+static PRInt32 pt_SolarisDispatchSendFile(PRFileDesc *sd, PRSendFileData *sfd,
+	  PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    int rv;
+
+    rv = pthread_once(&pt_solaris_sendfilev_once_block,
+            pt_solaris_sendfilev_init_routine);
+    PR_ASSERT(0 == rv);
+    if (pt_solaris_sendfilev_fptr) {
+        return pt_SolarisSendFile(sd, sfd, flags, timeout);
+    } else {
+        return PR_EmulateSendFile(sd, sfd, flags, timeout);
+    }
+}
+#endif /* !HAVE_SENDFILEV */
+
+#endif  /* SOLARIS */
+
+#ifdef LINUX
+/*
+ * pt_LinuxSendFile
+ *
+ *    Send file sfd->fd across socket sd. If specified, header and trailer
+ *    buffers are sent before and after the file, respectively.
+ *
+ *    PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file
+ *    
+ *    return number of bytes sent or -1 on error
+ *
+ *      This implementation takes advantage of the sendfile() system
+ *      call available in Linux kernel 2.2 or higher.
+ */
+
+static PRInt32 pt_LinuxSendFile(PRFileDesc *sd, PRSendFileData *sfd,
+                PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    struct stat statbuf;
+    size_t file_nbytes_to_send;	
+    PRInt32 count = 0;
+    ssize_t rv;
+    int syserrno;
+    off_t offset;
+    PRBool tcp_cork_enabled = PR_FALSE;
+    int tcp_cork;
+
+    if (sfd->file_nbytes == 0) {
+        /* Get file size */
+        if (fstat(sfd->fd->secret->md.osfd, &statbuf) == -1) {
+            _PR_MD_MAP_FSTAT_ERROR(errno);
+            return -1;
+        } 		
+        file_nbytes_to_send = statbuf.st_size - sfd->file_offset;
+    } else {
+        file_nbytes_to_send = sfd->file_nbytes;
+    }
+
+    if ((sfd->hlen != 0 || sfd->tlen != 0)
+            && sd->secret->md.tcp_nodelay == 0) {
+        tcp_cork = 1;
+        if (setsockopt(sd->secret->md.osfd, SOL_TCP, TCP_CORK,
+                &tcp_cork, sizeof tcp_cork) == 0) {
+            tcp_cork_enabled = PR_TRUE;
+        } else {
+            syserrno = errno;
+            if (syserrno != EINVAL) {
+                _PR_MD_MAP_SETSOCKOPT_ERROR(syserrno);
+                return -1;
+            }
+            /*
+             * The most likely reason for the EINVAL error is that
+             * TCP_NODELAY is set (with a function other than
+             * PR_SetSocketOption).  This is not fatal, so we keep
+             * on going.
+             */
+            PR_LOG(_pr_io_lm, PR_LOG_WARNING,
+                ("pt_LinuxSendFile: "
+                "setsockopt(TCP_CORK) failed with EINVAL\n"));
+        }
+    }
+
+    if (sfd->hlen != 0) {
+        count = PR_Send(sd, sfd->header, sfd->hlen, 0, timeout);
+        if (count == -1) {
+            goto failed;
+        }
+    }
+
+    if (file_nbytes_to_send != 0) {
+        offset = sfd->file_offset;
+        do {
+            rv = sendfile(sd->secret->md.osfd, sfd->fd->secret->md.osfd,
+                &offset, file_nbytes_to_send);
+        } while (rv == -1 && (syserrno = errno) == EINTR);
+        if (rv == -1) {
+            if (syserrno != EAGAIN && syserrno != EWOULDBLOCK) {
+                _MD_linux_map_sendfile_error(syserrno);
+                count = -1;
+                goto failed;
+            }
+            rv = 0;
+        }
+        PR_ASSERT(rv == offset - sfd->file_offset);
+        count += rv;
+
+        if (rv < file_nbytes_to_send) {
+            pt_Continuation op;
+
+            op.arg1.osfd = sd->secret->md.osfd;
+            op.in_fd = sfd->fd->secret->md.osfd;
+            op.offset = offset;
+            op.count = file_nbytes_to_send - rv;
+            op.result.code = count;
+            op.timeout = timeout;
+            op.function = pt_linux_sendfile_cont;
+            op.event = POLLOUT | POLLPRI;
+            count = pt_Continue(&op);
+            syserrno = op.syserrno;
+            if (count == -1) {
+                pt_MapError(_MD_linux_map_sendfile_error, syserrno);
+                goto failed;
+            }
+        }
+    }
+
+    if (sfd->tlen != 0) {
+        rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout);
+        if (rv == -1) {
+            count = -1;
+            goto failed;
+        }
+        count += rv;
+    }
+
+failed:
+    if (tcp_cork_enabled) {
+        tcp_cork = 0;
+        if (setsockopt(sd->secret->md.osfd, SOL_TCP, TCP_CORK,
+                &tcp_cork, sizeof tcp_cork) == -1 && count != -1) {
+            _PR_MD_MAP_SETSOCKOPT_ERROR(errno);
+            count = -1;
+        }
+    }
+    if (count != -1) {
+        if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) {
+            PR_Close(sd);
+        }
+        PR_ASSERT(count == sfd->hlen + sfd->tlen + file_nbytes_to_send);
+    }
+    return count;
+}
+#endif  /* LINUX */
+
+#ifdef AIX
+extern	int _pr_aix_send_file_use_disabled;
+#endif
+
+static PRInt32 pt_SendFile(
+    PRFileDesc *sd, PRSendFileData *sfd,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    if (pt_TestAbort()) return -1;
+    /* The socket must be in blocking mode. */
+    if (sd->secret->nonblocking)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return -1;
+    }
+#ifdef HPUX11
+    return(pt_HPUXSendFile(sd, sfd, flags, timeout));
+#elif defined(AIX)
+#ifdef HAVE_SEND_FILE
+	/*
+	 * A bug in AIX 4.3.2 results in corruption of data transferred by
+	 * send_file(); AIX patch PTF U463956 contains the fix.  A user can
+	 * disable the use of send_file function in NSPR, when this patch is
+	 * not installed on the system, by setting the envionment variable
+	 * NSPR_AIX_SEND_FILE_USE_DISABLED to 1.
+	 */
+	if (_pr_aix_send_file_use_disabled)
+		return(PR_EmulateSendFile(sd, sfd, flags, timeout));
+	else
+    	return(pt_AIXSendFile(sd, sfd, flags, timeout));
+#else
+	return(PR_EmulateSendFile(sd, sfd, flags, timeout));
+    /* return(pt_AIXDispatchSendFile(sd, sfd, flags, timeout));*/
+#endif /* HAVE_SEND_FILE */
+#elif defined(SOLARIS)
+#ifdef HAVE_SENDFILEV
+    	return(pt_SolarisSendFile(sd, sfd, flags, timeout));
+#else
+	return(pt_SolarisDispatchSendFile(sd, sfd, flags, timeout));
+#endif /* HAVE_SENDFILEV */
+#elif defined(LINUX)
+    	return(pt_LinuxSendFile(sd, sfd, flags, timeout));
+#else
+	return(PR_EmulateSendFile(sd, sfd, flags, timeout));
+#endif
+}
+
+static PRInt32 pt_TransmitFile(
+    PRFileDesc *sd, PRFileDesc *fd, const void *headers,
+    PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+	PRSendFileData sfd;
+
+	sfd.fd = fd;
+	sfd.file_offset = 0;
+	sfd.file_nbytes = 0;
+	sfd.header = headers;
+	sfd.hlen = hlen;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+
+	return(pt_SendFile(sd, &sfd, flags, timeout));
+}  /* pt_TransmitFile */
+
+static PRInt32 pt_AcceptRead(
+    PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
+    void *buf, PRInt32 amount, PRIntervalTime timeout)
+{
+    PRInt32 rv = -1;
+
+    if (pt_TestAbort()) return rv;
+    /* The socket must be in blocking mode. */
+    if (sd->secret->nonblocking)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return rv;
+    }
+
+    rv = PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout);
+    return rv;
+}  /* pt_AcceptRead */
+
+static PRStatus pt_GetSockName(PRFileDesc *fd, PRNetAddr *addr)
+{
+    PRIntn rv = -1;
+    pt_SockLen addr_len = sizeof(PRNetAddr);
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = getsockname(
+        fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len);
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_GETSOCKNAME_ERROR, errno);
+        return PR_FAILURE;
+    } else {
+#ifdef _PR_HAVE_SOCKADDR_LEN
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr)
+        {
+            addr->raw.family = ((struct sockaddr*)addr)->sa_family;
+        }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+#ifdef _PR_INET6
+		if (AF_INET6 == addr->raw.family)
+			addr->raw.family = PR_AF_INET6;
+#endif
+        PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+        PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
+        return PR_SUCCESS;
+    }
+}  /* pt_GetSockName */
+
+static PRStatus pt_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
+{
+    PRIntn rv = -1;
+    pt_SockLen addr_len = sizeof(PRNetAddr);
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = getpeername(
+        fd->secret->md.osfd, (struct sockaddr*)addr, &addr_len);
+
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_GETPEERNAME_ERROR, errno);
+        return PR_FAILURE;
+    } else {
+#ifdef _PR_HAVE_SOCKADDR_LEN
+        /* ignore the sa_len field of struct sockaddr */
+        if (addr)
+        {
+            addr->raw.family = ((struct sockaddr*)addr)->sa_family;
+        }
+#endif /* _PR_HAVE_SOCKADDR_LEN */
+#ifdef _PR_INET6
+		if (AF_INET6 == addr->raw.family)
+        	addr->raw.family = PR_AF_INET6;
+#endif
+        PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+        PR_ASSERT(IsValidNetAddrLen(addr, addr_len) == PR_TRUE);
+        return PR_SUCCESS;
+    }
+}  /* pt_GetPeerName */
+
+static PRStatus pt_GetSocketOption(PRFileDesc *fd, PRSocketOptionData *data)
+{
+    PRIntn rv;
+    pt_SockLen length;
+    PRInt32 level, name;
+
+    /*
+     * PR_SockOpt_Nonblocking is a special case that does not
+     * translate to a getsockopt() call
+     */
+    if (PR_SockOpt_Nonblocking == data->option)
+    {
+        data->value.non_blocking = fd->secret->nonblocking;
+        return PR_SUCCESS;
+    }
+
+    rv = _PR_MapOptionName(data->option, &level, &name);
+    if (PR_SUCCESS == rv)
+    {
+        switch (data->option)
+        {
+            case PR_SockOpt_Linger:
+            {
+                struct linger linger;
+                length = sizeof(linger);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name, (char *) &linger, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(linger) == length));
+                data->value.linger.polarity =
+                    (linger.l_onoff) ? PR_TRUE : PR_FALSE;
+                data->value.linger.linger =
+                    PR_SecondsToInterval(linger.l_linger);
+                break;
+            }
+            case PR_SockOpt_Reuseaddr:
+            case PR_SockOpt_Keepalive:
+            case PR_SockOpt_NoDelay:
+            case PR_SockOpt_Broadcast:
+            {
+                PRIntn value;
+                length = sizeof(PRIntn);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name, (char*)&value, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length));
+                data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE;
+                break;
+            }
+            case PR_SockOpt_McastLoopback:
+            {
+                PRUint8 xbool;
+                length = sizeof(xbool);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&xbool, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(xbool) == length));
+                data->value.mcast_loopback = (0 == xbool) ? PR_FALSE : PR_TRUE;
+                break;
+            }
+            case PR_SockOpt_RecvBufferSize:
+            case PR_SockOpt_SendBufferSize:
+            case PR_SockOpt_MaxSegment:
+            {
+                PRIntn value;
+                length = sizeof(PRIntn);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name, (char*)&value, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length));
+                data->value.recv_buffer_size = value;
+                break;
+            }
+            case PR_SockOpt_IpTimeToLive:
+            case PR_SockOpt_IpTypeOfService:
+            {
+                length = sizeof(PRUintn);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&data->value.ip_ttl, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(PRIntn) == length));
+                break;
+            }
+            case PR_SockOpt_McastTimeToLive:
+            {
+                PRUint8 ttl;
+                length = sizeof(ttl);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&ttl, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(ttl) == length));
+                data->value.mcast_ttl = ttl;
+                break;
+            }
+            case PR_SockOpt_AddMember:
+            case PR_SockOpt_DropMember:
+            {
+                struct ip_mreq mreq;
+                length = sizeof(mreq);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name, (char*)&mreq, &length);
+                PR_ASSERT((-1 == rv) || (sizeof(mreq) == length));
+                data->value.add_member.mcaddr.inet.ip =
+                    mreq.imr_multiaddr.s_addr;
+                data->value.add_member.ifaddr.inet.ip =
+                    mreq.imr_interface.s_addr;
+                break;
+            }
+            case PR_SockOpt_McastInterface:
+            {
+                length = sizeof(data->value.mcast_if.inet.ip);
+                rv = getsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&data->value.mcast_if.inet.ip, &length);
+                PR_ASSERT((-1 == rv)
+                    || (sizeof(data->value.mcast_if.inet.ip) == length));
+                break;
+            }
+            default:
+                PR_NOT_REACHED("Unknown socket option");
+                break;
+        }
+        if (-1 == rv) _PR_MD_MAP_GETSOCKOPT_ERROR(errno);
+    }
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* pt_GetSocketOption */
+
+static PRStatus pt_SetSocketOption(PRFileDesc *fd, const PRSocketOptionData *data)
+{
+    PRIntn rv;
+    PRInt32 level, name;
+
+    /*
+     * PR_SockOpt_Nonblocking is a special case that does not
+     * translate to a setsockopt call.
+     */
+    if (PR_SockOpt_Nonblocking == data->option)
+    {
+        fd->secret->nonblocking = data->value.non_blocking;
+        return PR_SUCCESS;
+    }
+
+    rv = _PR_MapOptionName(data->option, &level, &name);
+    if (PR_SUCCESS == rv)
+    {
+        switch (data->option)
+        {
+            case PR_SockOpt_Linger:
+            {
+                struct linger linger;
+                linger.l_onoff = data->value.linger.polarity;
+                linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger);
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name, (char*)&linger, sizeof(linger));
+                break;
+            }
+            case PR_SockOpt_Reuseaddr:
+            case PR_SockOpt_Keepalive:
+            case PR_SockOpt_NoDelay:
+            case PR_SockOpt_Broadcast:
+            {
+                PRIntn value = (data->value.reuse_addr) ? 1 : 0;
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&value, sizeof(PRIntn));
+#ifdef LINUX
+                /* for pt_LinuxSendFile */
+                if (name == TCP_NODELAY && rv == 0) {
+                    fd->secret->md.tcp_nodelay = value;
+                }
+#endif
+                break;
+            }
+            case PR_SockOpt_McastLoopback:
+            {
+                PRUint8 xbool = data->value.mcast_loopback ? 1 : 0;
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&xbool, sizeof(xbool));
+                break;
+            }
+            case PR_SockOpt_RecvBufferSize:
+            case PR_SockOpt_SendBufferSize:
+            case PR_SockOpt_MaxSegment:
+            {
+                PRIntn value = data->value.recv_buffer_size;
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&value, sizeof(PRIntn));
+                break;
+            }
+            case PR_SockOpt_IpTimeToLive:
+            case PR_SockOpt_IpTypeOfService:
+            {
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&data->value.ip_ttl, sizeof(PRUintn));
+                break;
+            }
+            case PR_SockOpt_McastTimeToLive:
+            {
+                PRUint8 ttl = data->value.mcast_ttl;
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&ttl, sizeof(ttl));
+                break;
+            }
+            case PR_SockOpt_AddMember:
+            case PR_SockOpt_DropMember:
+            {
+                struct ip_mreq mreq;
+                mreq.imr_multiaddr.s_addr =
+                    data->value.add_member.mcaddr.inet.ip;
+                mreq.imr_interface.s_addr =
+                    data->value.add_member.ifaddr.inet.ip;
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&mreq, sizeof(mreq));
+                break;
+            }
+            case PR_SockOpt_McastInterface:
+            {
+                rv = setsockopt(
+                    fd->secret->md.osfd, level, name,
+                    (char*)&data->value.mcast_if.inet.ip,
+                    sizeof(data->value.mcast_if.inet.ip));
+                break;
+            }
+            default:
+                PR_NOT_REACHED("Unknown socket option");
+                break;
+        }
+        if (-1 == rv) _PR_MD_MAP_SETSOCKOPT_ERROR(errno);
+    }
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* pt_SetSocketOption */
+
+/*****************************************************************************/
+/****************************** I/O method objects ***************************/
+/*****************************************************************************/
+
+static PRIOMethods _pr_file_methods = {
+    PR_DESC_FILE,
+    pt_Close,
+    pt_Read,
+    pt_Write,
+    pt_Available_f,
+    pt_Available64_f,
+    pt_Fsync,
+    pt_Seek,
+    pt_Seek64,
+    pt_FileInfo,
+    pt_FileInfo64,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+    pt_Poll,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRIOMethods _pr_pipe_methods = {
+    PR_DESC_PIPE,
+    pt_Close,
+    pt_Read,
+    pt_Write,
+    pt_Available_s,
+    pt_Available64_s,
+    pt_Synch,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+    pt_Poll,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRIOMethods _pr_tcp_methods = {
+    PR_DESC_SOCKET_TCP,
+    pt_Close,
+    pt_SocketRead,
+    pt_SocketWrite,
+    pt_Available_s,
+    pt_Available64_s,
+    pt_Synch,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    pt_Writev,
+    pt_Connect,
+    pt_Accept,
+    pt_Bind,
+    pt_Listen,
+    pt_Shutdown,
+    pt_Recv,
+    pt_Send,
+    (PRRecvfromFN)_PR_InvalidInt,
+    (PRSendtoFN)_PR_InvalidInt,
+    pt_Poll,
+    pt_AcceptRead,
+    pt_TransmitFile,
+    pt_GetSockName,
+    pt_GetPeerName,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    pt_GetSocketOption,
+    pt_SetSocketOption,
+    pt_SendFile, 
+    pt_ConnectContinue,
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRIOMethods _pr_udp_methods = {
+    PR_DESC_SOCKET_UDP,
+    pt_Close,
+    pt_SocketRead,
+    pt_SocketWrite,
+    pt_Available_s,
+    pt_Available64_s,
+    pt_Synch,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    pt_Writev,
+    pt_Connect,
+    (PRAcceptFN)_PR_InvalidDesc,
+    pt_Bind,
+    pt_Listen,
+    pt_Shutdown,
+    pt_Recv,
+    pt_Send,
+    pt_RecvFrom,
+    pt_SendTo,
+    pt_Poll,
+    (PRAcceptreadFN)_PR_InvalidInt,
+    (PRTransmitfileFN)_PR_InvalidInt,
+    pt_GetSockName,
+    pt_GetPeerName,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
+    pt_GetSocketOption,
+    pt_SetSocketOption,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+static PRIOMethods _pr_socketpollfd_methods = {
+    (PRDescType) 0,
+    (PRCloseFN)_PR_InvalidStatus,
+    (PRReadFN)_PR_InvalidInt,
+    (PRWriteFN)_PR_InvalidInt,
+    (PRAvailableFN)_PR_InvalidInt,
+    (PRAvailable64FN)_PR_InvalidInt64,
+    (PRFsyncFN)_PR_InvalidStatus,
+    (PRSeekFN)_PR_InvalidInt,
+    (PRSeek64FN)_PR_InvalidInt64,
+    (PRFileInfoFN)_PR_InvalidStatus,
+    (PRFileInfo64FN)_PR_InvalidStatus,
+    (PRWritevFN)_PR_InvalidInt,        
+    (PRConnectFN)_PR_InvalidStatus,        
+    (PRAcceptFN)_PR_InvalidDesc,        
+    (PRBindFN)_PR_InvalidStatus,        
+    (PRListenFN)_PR_InvalidStatus,        
+    (PRShutdownFN)_PR_InvalidStatus,    
+    (PRRecvFN)_PR_InvalidInt,        
+    (PRSendFN)_PR_InvalidInt,        
+    (PRRecvfromFN)_PR_InvalidInt,    
+    (PRSendtoFN)_PR_InvalidInt,        
+	pt_Poll,
+    (PRAcceptreadFN)_PR_InvalidInt,   
+    (PRTransmitfileFN)_PR_InvalidInt, 
+    (PRGetsocknameFN)_PR_InvalidStatus,    
+    (PRGetpeernameFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRGetsocketoptionFN)_PR_InvalidStatus,
+    (PRSetsocketoptionFN)_PR_InvalidStatus,
+    (PRSendfileFN)_PR_InvalidInt, 
+    (PRConnectcontinueFN)_PR_InvalidStatus, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt, 
+    (PRReservedFN)_PR_InvalidInt
+};
+
+#if defined(HPUX) || defined(OSF1) || defined(SOLARIS) || defined (IRIX) \
+    || defined(LINUX) || defined(__GNU__) || defined(__GLIBC__) \
+    || defined(AIX) || defined(FREEBSD) || defined(NETBSD) \
+    || defined(OPENBSD) || defined(BSDI) || defined(VMS) || defined(NTO) \
+    || defined(DARWIN) || defined(UNIXWARE) || defined(RISCOS)
+#define _PR_FCNTL_FLAGS O_NONBLOCK
+#else
+#error "Can't determine architecture"
+#endif
+
+/*
+ * Put a Unix file descriptor in non-blocking mode.
+ */
+static void pt_MakeFdNonblock(PRIntn osfd)
+{
+    PRIntn flags;
+    flags = fcntl(osfd, F_GETFL, 0);
+    flags |= _PR_FCNTL_FLAGS;
+    (void)fcntl(osfd, F_SETFL, flags);
+}
+
+/*
+ * Put a Unix socket fd in non-blocking mode that can
+ * ideally be inherited by an accepted socket.
+ *
+ * Why doesn't pt_MakeFdNonblock do?  This is to deal with
+ * the special case of HP-UX.  HP-UX has three kinds of
+ * non-blocking modes for sockets: the fcntl() O_NONBLOCK
+ * and O_NDELAY flags and ioctl() FIOSNBIO request.  Only
+ * the ioctl() FIOSNBIO form of non-blocking mode is
+ * inherited by an accepted socket.
+ *
+ * Other platforms just use the generic pt_MakeFdNonblock
+ * to put a socket in non-blocking mode.
+ */
+#ifdef HPUX
+static void pt_MakeSocketNonblock(PRIntn osfd)
+{
+    PRIntn one = 1;
+    (void)ioctl(osfd, FIOSNBIO, &one);
+}
+#else
+#define pt_MakeSocketNonblock pt_MakeFdNonblock
+#endif
+
+static PRFileDesc *pt_SetMethods(
+    PRIntn osfd, PRDescType type, PRBool isAcceptedSocket, PRBool imported)
+{
+    PRFileDesc *fd = _PR_Getfd();
+    
+    if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    else
+    {
+        fd->secret->md.osfd = osfd;
+        fd->secret->state = _PR_FILEDESC_OPEN;
+        if (imported) fd->secret->inheritable = _PR_TRI_UNKNOWN;
+        else
+        {
+            /* By default, a Unix fd is not closed on exec. */
+#ifdef DEBUG
+            PRIntn flags;
+            flags = fcntl(osfd, F_GETFD, 0);
+            PR_ASSERT(0 == flags);
+#endif
+            fd->secret->inheritable = _PR_TRI_TRUE;
+        }
+        switch (type)
+        {
+            case PR_DESC_FILE:
+                fd->methods = PR_GetFileMethods();
+                break;
+            case PR_DESC_SOCKET_TCP:
+                fd->methods = PR_GetTCPMethods();
+#ifdef _PR_ACCEPT_INHERIT_NONBLOCK
+                if (!isAcceptedSocket) pt_MakeSocketNonblock(osfd);
+#else
+                pt_MakeSocketNonblock(osfd);
+#endif
+                break;
+            case PR_DESC_SOCKET_UDP:
+                fd->methods = PR_GetUDPMethods();
+                pt_MakeFdNonblock(osfd);
+                break;
+            case PR_DESC_PIPE:
+                fd->methods = PR_GetPipeMethods();
+                pt_MakeFdNonblock(osfd);
+                break;
+            default:
+                break;
+        }
+    }
+    return fd;
+}  /* pt_SetMethods */
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetFileMethods(void)
+{
+    return &_pr_file_methods;
+}  /* PR_GetFileMethods */
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetPipeMethods(void)
+{
+    return &_pr_pipe_methods;
+}  /* PR_GetPipeMethods */
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetTCPMethods(void)
+{
+    return &_pr_tcp_methods;
+}  /* PR_GetTCPMethods */
+
+PR_IMPLEMENT(const PRIOMethods*) PR_GetUDPMethods(void)
+{
+    return &_pr_udp_methods;
+}  /* PR_GetUDPMethods */
+
+static const PRIOMethods* PR_GetSocketPollFdMethods(void)
+{
+    return &_pr_socketpollfd_methods;
+}  /* PR_GetSocketPollFdMethods */
+
+PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(
+    PRInt32 osfd, const PRIOMethods *methods)
+{
+    PRFileDesc *fd = _PR_Getfd();
+
+    if (NULL == fd) goto failed;
+
+    fd->methods = methods;
+    fd->secret->md.osfd = osfd;
+    /* Make fd non-blocking */
+    if (osfd > 2)
+    {
+        /* Don't mess around with stdin, stdout or stderr */
+        if (&_pr_tcp_methods == methods) pt_MakeSocketNonblock(osfd);
+        else pt_MakeFdNonblock(osfd);
+    }
+    fd->secret->state = _PR_FILEDESC_OPEN;
+    fd->secret->inheritable = _PR_TRI_UNKNOWN;
+    return fd;
+    
+failed:
+    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    return fd;
+}  /* PR_AllocFileDesc */
+
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+PR_EXTERN(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd);
+#if defined(_PR_INET6_PROBE)
+PR_EXTERN(PRBool) _pr_ipv6_is_present;
+PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket()
+{
+PRInt32 osfd;
+
+#if defined(DARWIN)
+    /*
+     * Disable IPv6 if Darwin version is less than 7.0.0 (OS X 10.3).  IPv6 on
+     * lesser versions is not ready for general use (see bug 222031).
+     */
+    {
+        struct utsname u;
+        if (uname(&u) != 0 || atoi(u.release) < 7)
+            return PR_FALSE;
+    }
+#endif
+
+    /*
+     * HP-UX only: HP-UX IPv6 Porting Guide (dated February 2001)
+     * suggests that we call open("/dev/ip6", O_RDWR) to determine
+     * whether IPv6 APIs and the IPv6 stack are on the system.
+     * Our portable test below seems to work fine, so I am using it.
+     */
+    osfd = socket(AF_INET6, SOCK_STREAM, 0);
+    if (osfd != -1) {
+        close(osfd);
+        return PR_TRUE;
+    }
+    return PR_FALSE;
+}
+#endif	/* _PR_INET6_PROBE */
+#endif
+
+PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
+{
+    PRIntn osfd;
+    PRDescType ftype;
+    PRFileDesc *fd = NULL;
+	PRInt32 tmp_domain = domain;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (pt_TestAbort()) return NULL;
+
+    if (PF_INET != domain
+        && PR_AF_INET6 != domain
+        && PF_UNIX != domain)
+    {
+        PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+        return fd;
+    }
+	if (type == SOCK_STREAM) ftype = PR_DESC_SOCKET_TCP;
+	else if (type == SOCK_DGRAM) ftype = PR_DESC_SOCKET_UDP;
+	else
+	{
+		(void)PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return fd;
+	}
+#if defined(_PR_INET6_PROBE)
+	if (PR_AF_INET6 == domain) {
+		if (_pr_ipv6_is_present == PR_FALSE) 
+			domain = AF_INET;
+		else
+			domain = AF_INET6;
+	}
+#elif defined(_PR_INET6) 
+	if (PR_AF_INET6 == domain)
+		domain = AF_INET6;
+#else
+	if (PR_AF_INET6 == domain)
+		domain = AF_INET;
+#endif
+
+    osfd = socket(domain, type, proto);
+    if (osfd == -1) pt_MapError(_PR_MD_MAP_SOCKET_ERROR, errno);
+    else
+    {
+#ifdef _PR_IPV6_V6ONLY_PROBE
+        if ((domain == AF_INET6) && _pr_ipv6_v6only_on_by_default)
+        {
+            int on = 0;
+            (void)setsockopt(osfd, IPPROTO_IPV6, IPV6_V6ONLY,
+                    &on, sizeof(on));
+        }
+#endif
+        fd = pt_SetMethods(osfd, ftype, PR_FALSE, PR_FALSE);
+        if (fd == NULL) close(osfd);
+    }
+#ifdef _PR_STRICT_ADDR_LEN
+    if (fd != NULL) fd->secret->af = domain;
+#endif
+#if defined(_PR_INET6_PROBE) || !defined(_PR_INET6)
+	if (fd != NULL) {
+		/*
+		 * For platforms with no support for IPv6 
+		 * create layered socket for IPv4-mapped IPv6 addresses
+		 */
+		if (PR_AF_INET6 == tmp_domain && PR_AF_INET == domain) {
+			if (PR_FAILURE == _pr_push_ipv6toipv4_layer(fd)) {
+				PR_Close(fd);
+				fd = NULL;
+			}
+		}
+	}
+#endif
+    return fd;
+}  /* PR_Socket */
+
+/*****************************************************************************/
+/****************************** I/O public methods ***************************/
+/*****************************************************************************/
+
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFile(
+    const char *name, PRIntn flags, PRIntn mode)
+{
+    PRFileDesc *fd = NULL;
+    PRIntn syserrno, osfd = -1, osflags = 0;;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (pt_TestAbort()) return NULL;
+
+    if (flags & PR_RDONLY) osflags |= O_RDONLY;
+    if (flags & PR_WRONLY) osflags |= O_WRONLY;
+    if (flags & PR_RDWR) osflags |= O_RDWR;
+    if (flags & PR_APPEND) osflags |= O_APPEND;
+    if (flags & PR_TRUNCATE) osflags |= O_TRUNC;
+    if (flags & PR_EXCL) osflags |= O_EXCL;
+    if (flags & PR_SYNC)
+    {
+#if defined(O_SYNC)
+        osflags |= O_SYNC;
+#elif defined(O_FSYNC)
+        osflags |= O_FSYNC;
+#else
+#error "Neither O_SYNC nor O_FSYNC is defined on this platform"
+#endif
+    }
+
+    /*
+    ** We have to hold the lock across the creation in order to
+    ** enforce the sematics of PR_Rename(). (see the latter for
+    ** more details)
+    */
+    if (flags & PR_CREATE_FILE)
+    {
+        osflags |= O_CREAT;
+        if (NULL !=_pr_rename_lock)
+            PR_Lock(_pr_rename_lock);
+    }
+
+    osfd = _md_iovector._open64(name, osflags, mode);
+    syserrno = errno;
+
+    if ((flags & PR_CREATE_FILE) && (NULL !=_pr_rename_lock))
+        PR_Unlock(_pr_rename_lock);
+
+    if (osfd == -1)
+        pt_MapError(_PR_MD_MAP_OPEN_ERROR, syserrno);
+    else
+    {
+        fd = pt_SetMethods(osfd, PR_DESC_FILE, PR_FALSE, PR_FALSE);
+        if (fd == NULL) close(osfd);  /* $$$ whoops! this is bad $$$ */
+    }
+    return fd;
+}  /* PR_OpenFile */
+
+PR_IMPLEMENT(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode)
+{
+    return PR_OpenFile(name, flags, mode);
+}  /* PR_Open */
+
+PR_IMPLEMENT(PRStatus) PR_Delete(const char *name)
+{
+    PRIntn rv = -1;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = unlink(name);
+
+    if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_UNLINK_ERROR, errno);
+        return PR_FAILURE;
+    } else
+        return PR_SUCCESS;
+}  /* PR_Delete */
+
+PR_IMPLEMENT(PRStatus) PR_Access(const char *name, PRAccessHow how)
+{
+    PRIntn rv;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    switch (how)
+    {
+    case PR_ACCESS_READ_OK:
+        rv =  access(name, R_OK);
+        break;
+    case PR_ACCESS_WRITE_OK:
+        rv = access(name, W_OK);
+        break;
+    case PR_ACCESS_EXISTS:
+    default:
+        rv = access(name, F_OK);
+    }
+    if (0 == rv) return PR_SUCCESS;
+    pt_MapError(_PR_MD_MAP_ACCESS_ERROR, errno);
+    return PR_FAILURE;
+    
+}  /* PR_Access */
+
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo(const char *fn, PRFileInfo *info)
+{
+    PRInt32 rv = _PR_MD_GETFILEINFO(fn, info);
+    return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+}  /* PR_GetFileInfo */
+
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo64(const char *fn, PRFileInfo64 *info)
+{
+    PRInt32 rv;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    rv = _PR_MD_GETFILEINFO64(fn, info);
+    return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+}  /* PR_GetFileInfo64 */
+
+PR_IMPLEMENT(PRStatus) PR_Rename(const char *from, const char *to)
+{
+    PRIntn rv = -1;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    /*
+    ** We have to acquire a lock here to stiffle anybody trying to create
+    ** a new file at the same time. And we have to hold that lock while we
+    ** test to see if the file exists and do the rename. The other place
+    ** where the lock is held is in PR_Open() when possibly creating a 
+    ** new file.
+    */
+
+    PR_Lock(_pr_rename_lock);
+    rv = access(to, F_OK);
+    if (0 == rv)
+    {
+        PR_SetError(PR_FILE_EXISTS_ERROR, 0);
+        rv = -1;
+    }
+    else
+    {
+        rv = rename(from, to);
+        if (rv == -1)
+            pt_MapError(_PR_MD_MAP_RENAME_ERROR, errno);
+    }
+    PR_Unlock(_pr_rename_lock);
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* PR_Rename */
+
+PR_IMPLEMENT(PRStatus) PR_CloseDir(PRDir *dir)
+{
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    if (NULL != dir->md.d)
+    {
+        if (closedir(dir->md.d) == -1)
+        {
+            _PR_MD_MAP_CLOSEDIR_ERROR(errno);
+            return PR_FAILURE;
+        }
+        dir->md.d = NULL;
+        PR_DELETE(dir);
+    }
+    return PR_SUCCESS;
+}  /* PR_CloseDir */
+
+PR_IMPLEMENT(PRStatus) PR_MakeDir(const char *name, PRIntn mode)
+{
+    PRInt32 rv = -1;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    /*
+    ** This lock is used to enforce rename semantics as described
+    ** in PR_Rename.
+    */
+    if (NULL !=_pr_rename_lock)
+        PR_Lock(_pr_rename_lock);
+    rv = mkdir(name, mode);
+    if (-1 == rv)
+        pt_MapError(_PR_MD_MAP_MKDIR_ERROR, errno);
+    if (NULL !=_pr_rename_lock)
+        PR_Unlock(_pr_rename_lock);
+
+    return (-1 == rv) ? PR_FAILURE : PR_SUCCESS;
+}  /* PR_Makedir */
+
+PR_IMPLEMENT(PRStatus) PR_MkDir(const char *name, PRIntn mode)
+{
+    return PR_MakeDir(name, mode);
+}  /* PR_Mkdir */
+
+PR_IMPLEMENT(PRStatus) PR_RmDir(const char *name)
+{
+    PRInt32 rv;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    rv = rmdir(name);
+    if (0 == rv) {
+    return PR_SUCCESS;
+    } else {
+    pt_MapError(_PR_MD_MAP_RMDIR_ERROR, errno);
+    return PR_FAILURE;
+    }
+}  /* PR_Rmdir */
+
+
+PR_IMPLEMENT(PRDir*) PR_OpenDir(const char *name)
+{
+    DIR *osdir;
+    PRDir *dir = NULL;
+
+    if (pt_TestAbort()) return dir;
+
+    osdir = opendir(name);
+    if (osdir == NULL)
+        pt_MapError(_PR_MD_MAP_OPENDIR_ERROR, errno);
+    else
+    {
+        dir = PR_NEWZAP(PRDir);
+        dir->md.d = osdir;
+    }
+    return dir;
+}  /* PR_OpenDir */
+
+static PRInt32 _pr_poll_with_poll(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    PRInt32 ready = 0;
+    /*
+     * For restarting poll() if it is interrupted by a signal.
+     * We use these variables to figure out how much time has
+     * elapsed and how much of the timeout still remains.
+     */
+    PRIntervalTime start, elapsed, remaining;
+
+    if (pt_TestAbort()) return -1;
+
+    if (0 == npds) PR_Sleep(timeout);
+    else
+    {
+#define STACK_POLL_DESC_COUNT 64
+        struct pollfd stack_syspoll[STACK_POLL_DESC_COUNT];
+        struct pollfd *syspoll;
+        PRIntn index, msecs;
+
+        if (npds <= STACK_POLL_DESC_COUNT)
+        {
+            syspoll = stack_syspoll;
+        }
+        else
+        {
+            PRThread *me = PR_GetCurrentThread();
+            if (npds > me->syspoll_count)
+            {
+                PR_Free(me->syspoll_list);
+                me->syspoll_list =
+                    (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd));
+                if (NULL == me->syspoll_list)
+                {
+                    me->syspoll_count = 0;
+                    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                    return -1;
+                }
+                me->syspoll_count = npds;
+            }
+            syspoll = me->syspoll_list;
+        }
+
+        for (index = 0; index < npds; ++index)
+        {
+            PRInt16 in_flags_read = 0, in_flags_write = 0;
+            PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+            if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+            {
+                if (pds[index].in_flags & PR_POLL_READ)
+                {
+                    in_flags_read = (pds[index].fd->methods->poll)(
+                        pds[index].fd,
+                        pds[index].in_flags & ~PR_POLL_WRITE,
+                        &out_flags_read);
+                }
+                if (pds[index].in_flags & PR_POLL_WRITE)
+                {
+                    in_flags_write = (pds[index].fd->methods->poll)(
+                        pds[index].fd,
+                        pds[index].in_flags & ~PR_POLL_READ,
+                        &out_flags_write);
+                }
+                if ((0 != (in_flags_read & out_flags_read))
+                || (0 != (in_flags_write & out_flags_write)))
+                {
+                    /* this one is ready right now */
+                    if (0 == ready)
+                    {
+                        /*
+                         * We will return without calling the system
+                         * poll function.  So zero the out_flags
+                         * fields of all the poll descriptors before
+                         * this one.
+                         */
+                        int i;
+                        for (i = 0; i < index; i++)
+                        {
+                            pds[i].out_flags = 0;
+                        }
+                    }
+                    ready += 1;
+                    pds[index].out_flags = out_flags_read | out_flags_write;
+                }
+                else
+                {
+                    /* now locate the NSPR layer at the bottom of the stack */
+                    PRFileDesc *bottom = PR_GetIdentitiesLayer(
+                        pds[index].fd, PR_NSPR_IO_LAYER);
+                    PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                    pds[index].out_flags = 0;  /* pre-condition */
+                    if ((NULL != bottom)
+                    && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                    {
+                        if (0 == ready)
+                        {
+                            syspoll[index].fd = bottom->secret->md.osfd;
+                            syspoll[index].events = 0;
+                            if (in_flags_read & PR_POLL_READ)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_READ_SYS_READ;
+                                syspoll[index].events |= POLLIN;
+                            }
+                            if (in_flags_read & PR_POLL_WRITE)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_READ_SYS_WRITE;
+                                syspoll[index].events |= POLLOUT;
+                            }
+                            if (in_flags_write & PR_POLL_READ)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_WRITE_SYS_READ;
+                                syspoll[index].events |= POLLIN;
+                            }
+                            if (in_flags_write & PR_POLL_WRITE)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_WRITE_SYS_WRITE;
+                                syspoll[index].events |= POLLOUT;
+                            }
+                            if (pds[index].in_flags & PR_POLL_EXCEPT)
+                                syspoll[index].events |= POLLPRI;
+                        }
+                    }
+                    else
+                    {
+                        if (0 == ready)
+                        {
+                            int i;
+                            for (i = 0; i < index; i++)
+                            {
+                                pds[i].out_flags = 0;
+                            }
+                        }
+                        ready += 1;  /* this will cause an abrupt return */
+                        pds[index].out_flags = PR_POLL_NVAL;  /* bogii */
+                    }
+                }
+            }
+            else
+            {
+                /* make poll() ignore this entry */
+                syspoll[index].fd = -1;
+                syspoll[index].events = 0;
+                pds[index].out_flags = 0;
+            }
+        }
+        if (0 == ready)
+        {
+            switch (timeout)
+            {
+            case PR_INTERVAL_NO_WAIT: msecs = 0; break;
+            case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break;
+            default:
+                msecs = PR_IntervalToMilliseconds(timeout);
+                start = PR_IntervalNow();
+            }
+
+retry:
+            ready = poll(syspoll, npds, msecs);
+            if (-1 == ready)
+            {
+                PRIntn oserror = errno;
+
+                if (EINTR == oserror)
+                {
+                    if (timeout == PR_INTERVAL_NO_TIMEOUT)
+                        goto retry;
+                    else if (timeout == PR_INTERVAL_NO_WAIT)
+                        ready = 0;  /* don't retry, just time out */
+                    else
+                    {
+                        elapsed = (PRIntervalTime) (PR_IntervalNow()
+                                - start);
+                        if (elapsed > timeout)
+                            ready = 0;  /* timed out */
+                        else
+                        {
+                            remaining = timeout - elapsed;
+                            msecs = PR_IntervalToMilliseconds(remaining);
+                            goto retry;
+                        }
+                    }
+                }
+                else
+                {
+                    _PR_MD_MAP_POLL_ERROR(oserror);
+                }
+            }
+            else if (ready > 0)
+            {
+                for (index = 0; index < npds; ++index)
+                {
+                    PRInt16 out_flags = 0;
+                    if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+                    {
+                        if (0 != syspoll[index].revents)
+                        {
+                            if (syspoll[index].revents & POLLIN)
+                            {
+                                if (pds[index].out_flags
+                                & _PR_POLL_READ_SYS_READ)
+                                {
+                                    out_flags |= PR_POLL_READ;
+                                }
+                                if (pds[index].out_flags
+                                & _PR_POLL_WRITE_SYS_READ)
+                                {
+                                    out_flags |= PR_POLL_WRITE;
+                                }
+                            }
+                            if (syspoll[index].revents & POLLOUT)
+                            {
+                                if (pds[index].out_flags
+                                & _PR_POLL_READ_SYS_WRITE)
+                                {
+                                    out_flags |= PR_POLL_READ;
+                                }
+                                if (pds[index].out_flags
+                                & _PR_POLL_WRITE_SYS_WRITE)
+                                {
+                                    out_flags |= PR_POLL_WRITE;
+                                }
+                            }
+                            if (syspoll[index].revents & POLLPRI)
+                                out_flags |= PR_POLL_EXCEPT;
+                            if (syspoll[index].revents & POLLERR)
+                                out_flags |= PR_POLL_ERR;
+                            if (syspoll[index].revents & POLLNVAL)
+                                out_flags |= PR_POLL_NVAL;
+                            if (syspoll[index].revents & POLLHUP)
+                                out_flags |= PR_POLL_HUP;
+                        }
+                    }
+                    pds[index].out_flags = out_flags;
+                }
+            }
+        }
+    }
+    return ready;
+
+} /* _pr_poll_with_poll */
+
+#if defined(_PR_POLL_WITH_SELECT)
+/*
+ * OSF1 and HPUX report the POLLHUP event for a socket when the
+ * shutdown(SHUT_WR) operation is called for the remote end, even though
+ * the socket is still writeable. Use select(), instead of poll(), to
+ * workaround this problem.
+ */
+static PRInt32 _pr_poll_with_select(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+    PRInt32 ready = 0;
+    /*
+     * For restarting select() if it is interrupted by a signal.
+     * We use these variables to figure out how much time has
+     * elapsed and how much of the timeout still remains.
+     */
+    PRIntervalTime start, elapsed, remaining;
+
+    if (pt_TestAbort()) return -1;
+
+    if (0 == npds) PR_Sleep(timeout);
+    else
+    {
+#define STACK_POLL_DESC_COUNT 64
+        int stack_selectfd[STACK_POLL_DESC_COUNT];
+        int *selectfd;
+		fd_set rd, wr, ex, *rdp = NULL, *wrp = NULL, *exp = NULL;
+		struct timeval tv, *tvp;
+        PRIntn index, msecs, maxfd = 0;
+
+        if (npds <= STACK_POLL_DESC_COUNT)
+        {
+            selectfd = stack_selectfd;
+        }
+        else
+        {
+            PRThread *me = PR_GetCurrentThread();
+            if (npds > me->selectfd_count)
+            {
+                PR_Free(me->selectfd_list);
+                me->selectfd_list = (int *)PR_MALLOC(npds * sizeof(int));
+                if (NULL == me->selectfd_list)
+                {
+                    me->selectfd_count = 0;
+                    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                    return -1;
+                }
+                me->selectfd_count = npds;
+            }
+            selectfd = me->selectfd_list;
+        }
+		FD_ZERO(&rd);
+		FD_ZERO(&wr);
+		FD_ZERO(&ex);
+
+        for (index = 0; index < npds; ++index)
+        {
+            PRInt16 in_flags_read = 0, in_flags_write = 0;
+            PRInt16 out_flags_read = 0, out_flags_write = 0;
+
+            if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+            {
+                if (pds[index].in_flags & PR_POLL_READ)
+                {
+                    in_flags_read = (pds[index].fd->methods->poll)(
+                        pds[index].fd,
+                        pds[index].in_flags & ~PR_POLL_WRITE,
+                        &out_flags_read);
+                }
+                if (pds[index].in_flags & PR_POLL_WRITE)
+                {
+                    in_flags_write = (pds[index].fd->methods->poll)(
+                        pds[index].fd,
+                        pds[index].in_flags & ~PR_POLL_READ,
+                        &out_flags_write);
+                }
+                if ((0 != (in_flags_read & out_flags_read))
+                || (0 != (in_flags_write & out_flags_write)))
+                {
+                    /* this one is ready right now */
+                    if (0 == ready)
+                    {
+                        /*
+                         * We will return without calling the system
+                         * poll function.  So zero the out_flags
+                         * fields of all the poll descriptors before
+                         * this one.
+                         */
+                        int i;
+                        for (i = 0; i < index; i++)
+                        {
+                            pds[i].out_flags = 0;
+                        }
+                    }
+                    ready += 1;
+                    pds[index].out_flags = out_flags_read | out_flags_write;
+                }
+                else
+                {
+                    /* now locate the NSPR layer at the bottom of the stack */
+                    PRFileDesc *bottom = PR_GetIdentitiesLayer(
+                        pds[index].fd, PR_NSPR_IO_LAYER);
+                    PR_ASSERT(NULL != bottom);  /* what to do about that? */
+                    pds[index].out_flags = 0;  /* pre-condition */
+                    if ((NULL != bottom)
+                    && (_PR_FILEDESC_OPEN == bottom->secret->state))
+                    {
+                        if (0 == ready)
+                        {
+                            PRBool add_to_rd = PR_FALSE;
+                            PRBool add_to_wr = PR_FALSE;
+                            PRBool add_to_ex = PR_FALSE;
+
+                            selectfd[index] = bottom->secret->md.osfd;
+                            if (in_flags_read & PR_POLL_READ)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_READ_SYS_READ;
+                                add_to_rd = PR_TRUE;
+                            }
+                            if (in_flags_read & PR_POLL_WRITE)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_READ_SYS_WRITE;
+                                add_to_wr = PR_TRUE;
+                            }
+                            if (in_flags_write & PR_POLL_READ)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_WRITE_SYS_READ;
+                                add_to_rd = PR_TRUE;
+                            }
+                            if (in_flags_write & PR_POLL_WRITE)
+                            {
+                                pds[index].out_flags |=
+                                    _PR_POLL_WRITE_SYS_WRITE;
+                                add_to_wr = PR_TRUE;
+                            }
+                            if (pds[index].in_flags & PR_POLL_EXCEPT)
+                            {
+                                add_to_ex = PR_TRUE;
+                            }
+                            if ((selectfd[index] > maxfd) &&
+                                    (add_to_rd || add_to_wr || add_to_ex))
+                            {
+                                maxfd = selectfd[index];
+                                /*
+                                 * If maxfd is too large to be used with
+                                 * select, fall back to calling poll.
+                                 */
+                                if (maxfd >= FD_SETSIZE)
+                                    break;
+                            }
+                            if (add_to_rd)
+                            {
+                                FD_SET(bottom->secret->md.osfd, &rd);
+                                rdp = &rd;
+                            }
+                            if (add_to_wr)
+                            {
+                                FD_SET(bottom->secret->md.osfd, &wr);
+                                wrp = &wr;
+                            }
+                            if (add_to_ex)
+                            {
+                                FD_SET(bottom->secret->md.osfd, &ex);
+                                exp = &ex;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        if (0 == ready)
+                        {
+                            int i;
+                            for (i = 0; i < index; i++)
+                            {
+                                pds[i].out_flags = 0;
+                            }
+                        }
+                        ready += 1;  /* this will cause an abrupt return */
+                        pds[index].out_flags = PR_POLL_NVAL;  /* bogii */
+                    }
+                }
+            }
+            else
+            {
+                pds[index].out_flags = 0;
+            }
+        }
+        if (0 == ready)
+        {
+			if (maxfd >= FD_SETSIZE)
+			{
+				/*
+				 * maxfd too large to be used with select, fall back to
+				 * calling poll
+				 */
+				return(_pr_poll_with_poll(pds, npds, timeout));
+			}
+            switch (timeout)
+            {
+            case PR_INTERVAL_NO_WAIT:
+				tv.tv_sec = 0;
+				tv.tv_usec = 0;
+				tvp = &tv;
+				break;
+            case PR_INTERVAL_NO_TIMEOUT:
+				tvp = NULL;
+				break;
+            default:
+                msecs = PR_IntervalToMilliseconds(timeout);
+				tv.tv_sec = msecs/PR_MSEC_PER_SEC;
+				tv.tv_usec = (msecs % PR_MSEC_PER_SEC) * PR_USEC_PER_MSEC;
+				tvp = &tv;
+                start = PR_IntervalNow();
+            }
+
+retry:
+            ready = select(maxfd + 1, rdp, wrp, exp, tvp);
+            if (-1 == ready)
+            {
+                PRIntn oserror = errno;
+
+                if ((EINTR == oserror) || (EAGAIN == oserror))
+                {
+                    if (timeout == PR_INTERVAL_NO_TIMEOUT)
+                        goto retry;
+                    else if (timeout == PR_INTERVAL_NO_WAIT)
+                        ready = 0;  /* don't retry, just time out */
+                    else
+                    {
+                        elapsed = (PRIntervalTime) (PR_IntervalNow()
+                                - start);
+                        if (elapsed > timeout)
+                            ready = 0;  /* timed out */
+                        else
+                        {
+                            remaining = timeout - elapsed;
+                            msecs = PR_IntervalToMilliseconds(remaining);
+							tv.tv_sec = msecs/PR_MSEC_PER_SEC;
+							tv.tv_usec = (msecs % PR_MSEC_PER_SEC) *
+													PR_USEC_PER_MSEC;
+                            goto retry;
+                        }
+                    }
+                } else if (EBADF == oserror)
+                {
+					/* find all the bad fds */
+					ready = 0;
+                	for (index = 0; index < npds; ++index)
+					{
+                    	pds[index].out_flags = 0;
+            			if ((NULL != pds[index].fd) &&
+											(0 != pds[index].in_flags))
+						{
+							if (fcntl(selectfd[index], F_GETFL, 0) == -1)
+							{
+                    			pds[index].out_flags = PR_POLL_NVAL;
+								ready++;
+							}
+						}
+					}
+                } else 
+                    _PR_MD_MAP_SELECT_ERROR(oserror);
+            }
+            else if (ready > 0)
+            {
+                for (index = 0; index < npds; ++index)
+                {
+                    PRInt16 out_flags = 0;
+                    if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))
+                    {
+						if (FD_ISSET(selectfd[index], &rd))
+						{
+							if (pds[index].out_flags
+							& _PR_POLL_READ_SYS_READ)
+							{
+								out_flags |= PR_POLL_READ;
+							}
+							if (pds[index].out_flags
+							& _PR_POLL_WRITE_SYS_READ)
+							{
+								out_flags |= PR_POLL_WRITE;
+							}
+						}
+						if (FD_ISSET(selectfd[index], &wr))
+						{
+							if (pds[index].out_flags
+							& _PR_POLL_READ_SYS_WRITE)
+							{
+								out_flags |= PR_POLL_READ;
+							}
+							if (pds[index].out_flags
+							& _PR_POLL_WRITE_SYS_WRITE)
+							{
+								out_flags |= PR_POLL_WRITE;
+							}
+						}
+						if (FD_ISSET(selectfd[index], &ex))
+							out_flags |= PR_POLL_EXCEPT;
+                    }
+                    pds[index].out_flags = out_flags;
+                }
+            }
+        }
+    }
+    return ready;
+
+} /* _pr_poll_with_select */
+#endif	/* _PR_POLL_WITH_SELECT */
+
+PR_IMPLEMENT(PRInt32) PR_Poll(
+    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
+{
+#if defined(_PR_POLL_WITH_SELECT)
+	return(_pr_poll_with_select(pds, npds, timeout));
+#else
+	return(_pr_poll_with_poll(pds, npds, timeout));
+#endif
+}
+
+PR_IMPLEMENT(PRDirEntry*) PR_ReadDir(PRDir *dir, PRDirFlags flags)
+{
+    struct dirent *dp;
+
+    if (pt_TestAbort()) return NULL;
+
+    for (;;)
+    {
+        errno = 0;
+        dp = readdir(dir->md.d);
+        if (NULL == dp)
+        {
+            pt_MapError(_PR_MD_MAP_READDIR_ERROR, errno);
+            return NULL;
+        }
+        if ((flags & PR_SKIP_DOT)
+            && ('.' == dp->d_name[0])
+            && (0 == dp->d_name[1])) continue;
+        if ((flags & PR_SKIP_DOT_DOT)
+            && ('.' == dp->d_name[0])
+            && ('.' == dp->d_name[1])
+            && (0 == dp->d_name[2])) continue;
+        if ((flags & PR_SKIP_HIDDEN) && ('.' == dp->d_name[0]))
+            continue;
+        break;
+    }
+    dir->d.name = dp->d_name;
+    return &dir->d;
+}  /* PR_ReadDir */
+
+PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void)
+{
+    PRIntn domain = PF_INET;
+
+    return PR_Socket(domain, SOCK_DGRAM, 0);
+}  /* PR_NewUDPSocket */
+
+PR_IMPLEMENT(PRFileDesc*) PR_NewTCPSocket(void)
+{
+    PRIntn domain = PF_INET;
+
+    return PR_Socket(domain, SOCK_STREAM, 0);
+}  /* PR_NewTCPSocket */
+
+PR_IMPLEMENT(PRFileDesc*) PR_OpenUDPSocket(PRIntn af)
+{
+    return PR_Socket(af, SOCK_DGRAM, 0);
+}  /* PR_NewUDPSocket */
+
+PR_IMPLEMENT(PRFileDesc*) PR_OpenTCPSocket(PRIntn af)
+{
+    return PR_Socket(af, SOCK_STREAM, 0);
+}  /* PR_NewTCPSocket */
+
+PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *fds[2])
+{
+    PRInt32 osfd[2];
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    if (socketpair(AF_UNIX, SOCK_STREAM, 0, osfd) == -1) {
+        pt_MapError(_PR_MD_MAP_SOCKETPAIR_ERROR, errno);
+        return PR_FAILURE;
+    }
+
+    fds[0] = pt_SetMethods(osfd[0], PR_DESC_SOCKET_TCP, PR_FALSE, PR_FALSE);
+    if (fds[0] == NULL) {
+        close(osfd[0]);
+        close(osfd[1]);
+        return PR_FAILURE;
+    }
+    fds[1] = pt_SetMethods(osfd[1], PR_DESC_SOCKET_TCP, PR_FALSE, PR_FALSE);
+    if (fds[1] == NULL) {
+        PR_Close(fds[0]);
+        close(osfd[1]);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* PR_NewTCPSocketPair */
+
+PR_IMPLEMENT(PRStatus) PR_CreatePipe(
+    PRFileDesc **readPipe,
+    PRFileDesc **writePipe
+)
+{
+    int pipefd[2];
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    if (pipe(pipefd) == -1)
+    {
+    /* XXX map pipe error */
+        PR_SetError(PR_UNKNOWN_ERROR, errno);
+        return PR_FAILURE;
+    }
+    *readPipe = pt_SetMethods(pipefd[0], PR_DESC_PIPE, PR_FALSE, PR_FALSE);
+    if (NULL == *readPipe)
+    {
+        close(pipefd[0]);
+        close(pipefd[1]);
+        return PR_FAILURE;
+    }
+    *writePipe = pt_SetMethods(pipefd[1], PR_DESC_PIPE, PR_FALSE, PR_FALSE);
+    if (NULL == *writePipe)
+    {
+        PR_Close(*readPipe);
+        close(pipefd[1]);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+/*
+** Set the inheritance attribute of a file descriptor.
+*/
+PR_IMPLEMENT(PRStatus) PR_SetFDInheritable(
+    PRFileDesc *fd,
+    PRBool inheritable)
+{
+    /*
+     * Only a non-layered, NSPR file descriptor can be inherited
+     * by a child process.
+     */
+    if (fd->identity != PR_NSPR_IO_LAYER)
+    {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        return PR_FAILURE;
+    }
+    if (fd->secret->inheritable != inheritable)
+    {
+        if (fcntl(fd->secret->md.osfd, F_SETFD,
+        inheritable ? 0 : FD_CLOEXEC) == -1)
+        {
+            return PR_FAILURE;
+        }
+        fd->secret->inheritable = (_PRTriStateBool) inheritable;
+    }
+    return PR_SUCCESS;
+}
+
+/*****************************************************************************/
+/***************************** I/O friends methods ***************************/
+/*****************************************************************************/
+
+PR_IMPLEMENT(PRFileDesc*) PR_ImportFile(PRInt32 osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    fd = pt_SetMethods(osfd, PR_DESC_FILE, PR_FALSE, PR_TRUE);
+    if (NULL == fd) close(osfd);
+    return fd;
+}  /* PR_ImportFile */
+
+PR_IMPLEMENT(PRFileDesc*) PR_ImportPipe(PRInt32 osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    fd = pt_SetMethods(osfd, PR_DESC_PIPE, PR_FALSE, PR_TRUE);
+    if (NULL == fd) close(osfd);
+    return fd;
+}  /* PR_ImportPipe */
+
+PR_IMPLEMENT(PRFileDesc*) PR_ImportTCPSocket(PRInt32 osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    fd = pt_SetMethods(osfd, PR_DESC_SOCKET_TCP, PR_FALSE, PR_TRUE);
+    if (NULL == fd) close(osfd);
+#ifdef _PR_STRICT_ADDR_LEN
+    if (NULL != fd) fd->secret->af = PF_INET;
+#endif
+    return fd;
+}  /* PR_ImportTCPSocket */
+
+PR_IMPLEMENT(PRFileDesc*) PR_ImportUDPSocket(PRInt32 osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    fd = pt_SetMethods(osfd, PR_DESC_SOCKET_UDP, PR_FALSE, PR_TRUE);
+    if (NULL != fd) close(osfd);
+    return fd;
+}  /* PR_ImportUDPSocket */
+
+PR_IMPLEMENT(PRFileDesc*) PR_CreateSocketPollFd(PRInt32 osfd)
+{
+    PRFileDesc *fd;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    fd = _PR_Getfd();
+
+    if (fd == NULL) PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    else
+    {
+        fd->secret->md.osfd = osfd;
+        fd->secret->inheritable = _PR_TRI_FALSE;
+    	fd->secret->state = _PR_FILEDESC_OPEN;
+        fd->methods = PR_GetSocketPollFdMethods();
+    }
+
+    return fd;
+}  /* PR_CreateSocketPollFD */
+
+PR_IMPLEMENT(PRStatus) PR_DestroySocketPollFd(PRFileDesc *fd)
+{
+    if (NULL == fd)
+    {
+        PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+        return PR_FAILURE;
+    }
+    fd->secret->state = _PR_FILEDESC_CLOSED;
+    _PR_Putfd(fd);
+    return PR_SUCCESS;
+}  /* PR_DestroySocketPollFd */
+
+PR_IMPLEMENT(PRInt32) PR_FileDesc2NativeHandle(PRFileDesc *bottom)
+{
+    PRInt32 osfd = -1;
+    bottom = (NULL == bottom) ?
+        NULL : PR_GetIdentitiesLayer(bottom, PR_NSPR_IO_LAYER);
+    if (NULL == bottom) PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+    else osfd = bottom->secret->md.osfd;
+    return osfd;
+}  /* PR_FileDesc2NativeHandle */
+
+PR_IMPLEMENT(void) PR_ChangeFileDescNativeHandle(PRFileDesc *fd,
+    PRInt32 handle)
+{
+    if (fd) fd->secret->md.osfd = handle;
+}  /*  PR_ChangeFileDescNativeHandle*/
+
+PR_IMPLEMENT(PRStatus) PR_LockFile(PRFileDesc *fd)
+{
+    PRStatus status = PR_SUCCESS;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    PR_Lock(_pr_flock_lock);
+    while (-1 == fd->secret->lockCount)
+        PR_WaitCondVar(_pr_flock_cv, PR_INTERVAL_NO_TIMEOUT);
+    if (0 == fd->secret->lockCount)
+    {
+        fd->secret->lockCount = -1;
+        PR_Unlock(_pr_flock_lock);
+        status = _PR_MD_LOCKFILE(fd->secret->md.osfd);
+        PR_Lock(_pr_flock_lock);
+        fd->secret->lockCount = (PR_SUCCESS == status) ? 1 : 0;
+        PR_NotifyAllCondVar(_pr_flock_cv);
+    }
+    else
+    {
+        fd->secret->lockCount += 1;
+    }
+    PR_Unlock(_pr_flock_lock);
+ 
+    return status;
+}  /* PR_LockFile */
+
+PR_IMPLEMENT(PRStatus) PR_TLockFile(PRFileDesc *fd)
+{
+    PRStatus status = PR_SUCCESS;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    PR_Lock(_pr_flock_lock);
+    if (0 == fd->secret->lockCount)
+    {
+        status = _PR_MD_TLOCKFILE(fd->secret->md.osfd);
+        if (PR_SUCCESS == status) fd->secret->lockCount = 1;
+    }
+    else fd->secret->lockCount += 1;
+    PR_Unlock(_pr_flock_lock);
+ 
+    return status;
+}  /* PR_TLockFile */
+
+PR_IMPLEMENT(PRStatus) PR_UnlockFile(PRFileDesc *fd)
+{
+    PRStatus status = PR_SUCCESS;
+
+    if (pt_TestAbort()) return PR_FAILURE;
+
+    PR_Lock(_pr_flock_lock);
+    if (fd->secret->lockCount == 1)
+    {
+        status = _PR_MD_UNLOCKFILE(fd->secret->md.osfd);
+        if (PR_SUCCESS == status) fd->secret->lockCount = 0;
+    }
+    else fd->secret->lockCount -= 1;
+    PR_Unlock(_pr_flock_lock);
+
+    return status;
+}
+
+/*
+ * The next two entry points should not be in the API, but they are
+ * defined here for historical (or hysterical) reasons.
+ */
+
+PR_IMPLEMENT(PRInt32) PR_GetSysfdTableMax(void)
+{
+#if defined(XP_UNIX) && !defined(AIX) && !defined(VMS)
+    struct rlimit rlim;
+
+    if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) 
+       return -1;
+
+    return rlim.rlim_max;
+#elif defined(AIX) || defined(VMS)
+    return sysconf(_SC_OPEN_MAX);
+#endif
+}
+
+PR_IMPLEMENT(PRInt32) PR_SetSysfdTableSize(PRIntn table_size)
+{
+#if defined(XP_UNIX) && !defined(AIX) && !defined(VMS)
+    struct rlimit rlim;
+    PRInt32 tableMax = PR_GetSysfdTableMax();
+
+    if (tableMax < 0) return -1;
+    rlim.rlim_max = tableMax;
+
+    /* Grow as much as we can; even if too big */
+    if ( rlim.rlim_max < table_size )
+        rlim.rlim_cur = rlim.rlim_max;
+    else
+        rlim.rlim_cur = table_size;
+
+    if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) 
+        return -1;
+
+    return rlim.rlim_cur;
+#elif defined(AIX) || defined(VMS)
+    return -1;
+#endif
+}
+
+/*
+ * PR_Stat is supported for backward compatibility; some existing Java
+ * code uses it.  New code should use PR_GetFileInfo.
+ */
+
+#ifndef NO_NSPR_10_SUPPORT
+PR_IMPLEMENT(PRInt32) PR_Stat(const char *name, struct stat *buf)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_Stat", "PR_GetFileInfo");
+
+    if (pt_TestAbort()) return -1;
+
+    if (-1 == stat(name, buf)) {
+        pt_MapError(_PR_MD_MAP_STAT_ERROR, errno);
+        return -1;
+    } else {
+        return 0;
+    }
+}
+#endif /* ! NO_NSPR_10_SUPPORT */
+
+
+PR_IMPLEMENT(void) PR_FD_ZERO(PR_fd_set *set)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_ZERO (PR_Select)", "PR_Poll");
+    memset(set, 0, sizeof(PR_fd_set));
+}
+
+PR_IMPLEMENT(void) PR_FD_SET(PRFileDesc *fh, PR_fd_set *set)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_SET (PR_Select)", "PR_Poll");
+    PR_ASSERT( set->hsize < PR_MAX_SELECT_DESC );
+
+    set->harray[set->hsize++] = fh;
+}
+
+PR_IMPLEMENT(void) PR_FD_CLR(PRFileDesc *fh, PR_fd_set *set)
+{
+    PRUint32 index, index2;
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_CLR (PR_Select)", "PR_Poll");
+
+    for (index = 0; index<set->hsize; index++)
+       if (set->harray[index] == fh) {
+           for (index2=index; index2 < (set->hsize-1); index2++) {
+               set->harray[index2] = set->harray[index2+1];
+           }
+           set->hsize--;
+           break;
+       }
+}
+
+PR_IMPLEMENT(PRInt32) PR_FD_ISSET(PRFileDesc *fh, PR_fd_set *set)
+{
+    PRUint32 index;
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_ISSET (PR_Select)", "PR_Poll");
+    for (index = 0; index<set->hsize; index++)
+       if (set->harray[index] == fh) {
+           return 1;
+       }
+    return 0;
+}
+
+PR_IMPLEMENT(void) PR_FD_NSET(PRInt32 fd, PR_fd_set *set)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_NSET (PR_Select)", "PR_Poll");
+    PR_ASSERT( set->nsize < PR_MAX_SELECT_DESC );
+
+    set->narray[set->nsize++] = fd;
+}
+
+PR_IMPLEMENT(void) PR_FD_NCLR(PRInt32 fd, PR_fd_set *set)
+{
+    PRUint32 index, index2;
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_NCLR (PR_Select)", "PR_Poll");
+
+    for (index = 0; index<set->nsize; index++)
+       if (set->narray[index] == fd) {
+           for (index2=index; index2 < (set->nsize-1); index2++) {
+               set->narray[index2] = set->narray[index2+1];
+           }
+           set->nsize--;
+           break;
+       }
+}
+
+PR_IMPLEMENT(PRInt32) PR_FD_NISSET(PRInt32 fd, PR_fd_set *set)
+{
+    PRUint32 index;
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete("PR_FD_NISSET (PR_Select)", "PR_Poll");
+    for (index = 0; index<set->nsize; index++)
+       if (set->narray[index] == fd) {
+           return 1;
+       }
+    return 0;
+}
+
+#include <sys/types.h>
+#include <sys/time.h>
+#if !defined(SUNOS4) && !defined(HPUX) \
+    && !defined(LINUX) && !defined(__GNU__) && !defined(__GLIBC__)
+#include <sys/select.h>
+#endif
+
+static PRInt32
+_PR_getset(PR_fd_set *pr_set, fd_set *set)
+{
+    PRUint32 index;
+    PRInt32 max = 0;
+
+    if (!pr_set)
+        return 0;
+   
+    FD_ZERO(set);
+
+    /* First set the pr file handle osfds */
+    for (index=0; index<pr_set->hsize; index++) {
+        FD_SET(pr_set->harray[index]->secret->md.osfd, set);
+        if (pr_set->harray[index]->secret->md.osfd > max)
+            max = pr_set->harray[index]->secret->md.osfd;
+    }
+    /* Second set the native osfds */
+    for (index=0; index<pr_set->nsize; index++) {
+        FD_SET(pr_set->narray[index], set);
+        if (pr_set->narray[index] > max)
+            max = pr_set->narray[index];
+    }
+    return max;
+}
+
+static void
+_PR_setset(PR_fd_set *pr_set, fd_set *set)
+{
+    PRUint32 index, last_used;
+
+    if (!pr_set)
+        return;
+
+    for (last_used=0, index=0; index<pr_set->hsize; index++) {
+        if ( FD_ISSET(pr_set->harray[index]->secret->md.osfd, set) ) {
+            pr_set->harray[last_used++] = pr_set->harray[index];
+        }
+    }
+    pr_set->hsize = last_used;
+
+    for (last_used=0, index=0; index<pr_set->nsize; index++) {
+        if ( FD_ISSET(pr_set->narray[index], set) ) {
+            pr_set->narray[last_used++] = pr_set->narray[index];
+        }
+    }
+    pr_set->nsize = last_used;
+}
+
+PR_IMPLEMENT(PRInt32) PR_Select(
+    PRInt32 unused, PR_fd_set *pr_rd, PR_fd_set *pr_wr, 
+    PR_fd_set *pr_ex, PRIntervalTime timeout)
+{
+    fd_set rd, wr, ex;
+    struct timeval tv, *tvp;
+    PRInt32 max, max_fd;
+    PRInt32 rv;
+    /*
+     * For restarting select() if it is interrupted by a Unix signal.
+     * We use these variables to figure out how much time has elapsed
+     * and how much of the timeout still remains.
+     */
+    PRIntervalTime start, elapsed, remaining;
+
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete( "PR_Select", "PR_Poll");
+
+    FD_ZERO(&rd);
+    FD_ZERO(&wr);
+    FD_ZERO(&ex);
+
+    max_fd = _PR_getset(pr_rd, &rd);
+    max_fd = (max = _PR_getset(pr_wr, &wr))>max_fd?max:max_fd;
+    max_fd = (max = _PR_getset(pr_ex, &ex))>max_fd?max:max_fd;
+
+    if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+        tvp = NULL;
+    } else {
+        tv.tv_sec = (PRInt32)PR_IntervalToSeconds(timeout);
+        tv.tv_usec = (PRInt32)PR_IntervalToMicroseconds(
+                timeout - PR_SecondsToInterval(tv.tv_sec));
+        tvp = &tv;
+        start = PR_IntervalNow();
+    }
+
+retry:
+    rv = select(max_fd + 1, (_PRSelectFdSetArg_t) &rd,
+        (_PRSelectFdSetArg_t) &wr, (_PRSelectFdSetArg_t) &ex, tvp);
+
+    if (rv == -1 && errno == EINTR) {
+        if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+            goto retry;
+        } else {
+            elapsed = (PRIntervalTime) (PR_IntervalNow() - start);
+            if (elapsed > timeout) {
+                rv = 0;  /* timed out */
+            } else {
+                remaining = timeout - elapsed;
+                tv.tv_sec = (PRInt32)PR_IntervalToSeconds(remaining);
+                tv.tv_usec = (PRInt32)PR_IntervalToMicroseconds(
+                        remaining - PR_SecondsToInterval(tv.tv_sec));
+                goto retry;
+            }
+        }
+    }
+
+    if (rv > 0) {
+        _PR_setset(pr_rd, &rd);
+        _PR_setset(pr_wr, &wr);
+        _PR_setset(pr_ex, &ex);
+    } else if (rv == -1) {
+        pt_MapError(_PR_MD_MAP_SELECT_ERROR, errno);
+    }
+    return rv;
+}
+#endif /* defined(_PR_PTHREADS) */
+
+#ifdef MOZ_UNICODE 
+/* ================ UTF16 Interfaces ================================ */
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFileUTF16(
+    const PRUnichar *name, PRIntn flags, PRIntn mode)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseDirUTF16(PRDir *dir)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRDirUTF16*) PR_OpenDirUTF16(const PRUnichar *name)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PR_IMPLEMENT(PRDirEntryUTF16*) PR_ReadDirUTF16(PRDirUTF16 *dir, PRDirFlags flags)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_GetFileInfo64UTF16(const PRUnichar *fn, PRFileInfo64 *info)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+/* ================ UTF16 Interfaces ================================ */
+#endif /* MOZ_UNICODE */
+
+/* ptio.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptmisc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptmisc.c	Mon Dec 18 10:53:47 2006
@@ -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:   ptmisc.c
+** Descritpion:  Implemenation of miscellaneous methods for pthreads
+*/
+
+#if defined(_PR_PTHREADS)
+
+#include "primpl.h"
+
+#include <stdio.h>
+#ifdef SOLARIS
+#include <thread.h>
+#endif
+
+#define PT_LOG(f)
+
+void _PR_InitCPUs(void) {PT_LOG("_PR_InitCPUs")}
+void _PR_InitStacks(void) {PT_LOG("_PR_InitStacks")}
+
+PR_IMPLEMENT(void) PR_SetConcurrency(PRUintn numCPUs) 
+{
+#ifdef SOLARIS
+	thr_setconcurrency(numCPUs);	
+#else
+	PT_LOG("PR_SetConcurrency");
+#endif
+}
+
+PR_IMPLEMENT(void) PR_SetThreadRecycleMode(PRUint32 flag)
+    {PT_LOG("PR_SetThreadRecycleMode")}
+
+#endif /* defined(_PR_PTHREADS) */
+
+/* ptmisc.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptsynch.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptsynch.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1139 @@
+/* -*- 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:            ptsynch.c
+** Descritpion:        Implemenation for thread synchronization using pthreads
+** Exports:            prlock.h, prcvar.h, prmon.h, prcmon.h
+*/
+
+#if defined(_PR_PTHREADS)
+
+#include "primpl.h"
+#include "obsolete/prsem.h"
+
+#include <string.h>
+#include <pthread.h>
+#include <sys/time.h>
+
+static pthread_mutexattr_t _pt_mattr;
+static pthread_condattr_t _pt_cvar_attr;
+
+#if defined(DEBUG)
+extern PTDebug pt_debug;  /* this is shared between several modules */
+
+#if defined(_PR_DCETHREADS)
+static pthread_t pt_zero_tid;  /* a null pthread_t (pthread_t is a struct
+                                * in DCE threads) to compare with */
+#endif  /* defined(_PR_DCETHREADS) */
+#endif  /* defined(DEBUG) */
+
+#if defined(FREEBSD)
+/*
+ * On older versions of FreeBSD, pthread_mutex_trylock returns EDEADLK.
+ * Newer versions return EBUSY.  We still need to support both.
+ */
+static int
+pt_pthread_mutex_is_locked(pthread_mutex_t *m)
+{
+    int rv = pthread_mutex_trylock(m);
+    return (EBUSY == rv || EDEADLK == rv);
+}
+#endif
+
+/**************************************************************/
+/**************************************************************/
+/*****************************LOCKS****************************/
+/**************************************************************/
+/**************************************************************/
+
+void _PR_InitLocks(void)
+{
+    int rv;
+    rv = _PT_PTHREAD_MUTEXATTR_INIT(&_pt_mattr); 
+    PR_ASSERT(0 == rv);
+
+#ifdef LINUX
+#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
+    rv = pthread_mutexattr_settype(&_pt_mattr, PTHREAD_MUTEX_ADAPTIVE_NP);
+    PR_ASSERT(0 == rv);
+#endif
+#endif
+
+    rv = _PT_PTHREAD_CONDATTR_INIT(&_pt_cvar_attr);
+    PR_ASSERT(0 == rv);
+}
+
+static void pt_PostNotifies(PRLock *lock, PRBool unlock)
+{
+    PRIntn index, rv;
+    _PT_Notified post;
+    _PT_Notified *notified, *prev = NULL;
+    /*
+     * Time to actually notify any conditions that were affected
+     * while the lock was held. Get a copy of the list that's in
+     * the lock structure and then zero the original. If it's
+     * linked to other such structures, we own that storage.
+     */
+    post = lock->notified;  /* a safe copy; we own the lock */
+
+#if defined(DEBUG)
+    memset(&lock->notified, 0, sizeof(_PT_Notified));  /* reset */
+#else
+    lock->notified.length = 0;  /* these are really sufficient */
+    lock->notified.link = NULL;
+#endif
+
+    /* should (may) we release lock before notifying? */
+    if (unlock)
+    {
+        rv = pthread_mutex_unlock(&lock->mutex);
+        PR_ASSERT(0 == rv);
+    }
+
+    notified = &post;  /* this is where we start */
+    do
+    {
+        for (index = 0; index < notified->length; ++index)
+        {
+            PRCondVar *cv = notified->cv[index].cv;
+            PR_ASSERT(NULL != cv);
+            PR_ASSERT(0 != notified->cv[index].times);
+            if (-1 == notified->cv[index].times)
+            {
+                rv = pthread_cond_broadcast(&cv->cv);
+                PR_ASSERT(0 == rv);
+            }
+            else
+            {
+                while (notified->cv[index].times-- > 0)
+                {
+                    rv = pthread_cond_signal(&cv->cv);
+                    PR_ASSERT(0 == rv);
+                }
+            }
+#if defined(DEBUG)
+            pt_debug.cvars_notified += 1;
+            if (0 > PR_AtomicDecrement(&cv->notify_pending))
+            {
+                pt_debug.delayed_cv_deletes += 1;
+                PR_DestroyCondVar(cv);
+            }
+#else  /* defined(DEBUG) */
+            if (0 > PR_AtomicDecrement(&cv->notify_pending))
+                PR_DestroyCondVar(cv);
+#endif  /* defined(DEBUG) */
+        }
+        prev = notified;
+        notified = notified->link;
+        if (&post != prev) PR_DELETE(prev);
+    } while (NULL != notified);
+}  /* pt_PostNotifies */
+
+PR_IMPLEMENT(PRLock*) PR_NewLock(void)
+{
+    PRIntn rv;
+    PRLock *lock;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    lock = PR_NEWZAP(PRLock);
+    if (lock != NULL)
+    {
+        rv = _PT_PTHREAD_MUTEX_INIT(lock->mutex, _pt_mattr); 
+        PR_ASSERT(0 == rv);
+    }
+#if defined(DEBUG)
+    pt_debug.locks_created += 1;
+#endif
+    return lock;
+}  /* PR_NewLock */
+
+PR_IMPLEMENT(void) PR_DestroyLock(PRLock *lock)
+{
+    PRIntn rv;
+    PR_ASSERT(NULL != lock);
+    PR_ASSERT(PR_FALSE == lock->locked);
+    PR_ASSERT(0 == lock->notified.length);
+    PR_ASSERT(NULL == lock->notified.link);
+    rv = pthread_mutex_destroy(&lock->mutex);
+    PR_ASSERT(0 == rv);
+#if defined(DEBUG)
+    memset(lock, 0xaf, sizeof(PRLock));
+    pt_debug.locks_destroyed += 1;
+#endif
+    PR_DELETE(lock);
+}  /* PR_DestroyLock */
+
+PR_IMPLEMENT(void) PR_Lock(PRLock *lock)
+{
+    PRIntn rv;
+    PR_ASSERT(lock != NULL);
+    rv = pthread_mutex_lock(&lock->mutex);
+    PR_ASSERT(0 == rv);
+    PR_ASSERT(0 == lock->notified.length);
+    PR_ASSERT(NULL == lock->notified.link);
+    PR_ASSERT(PR_FALSE == lock->locked);
+    lock->locked = PR_TRUE;
+    lock->owner = pthread_self();
+#if defined(DEBUG)
+    pt_debug.locks_acquired += 1;
+#endif
+}  /* PR_Lock */
+
+PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *lock)
+{
+    PRIntn rv;
+
+    PR_ASSERT(lock != NULL);
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(lock->mutex));
+    PR_ASSERT(PR_TRUE == lock->locked);
+    PR_ASSERT(pthread_equal(lock->owner, pthread_self()));
+
+    if (!lock->locked || !pthread_equal(lock->owner, pthread_self()))
+        return PR_FAILURE;
+
+    lock->locked = PR_FALSE;
+    if (0 == lock->notified.length)  /* shortcut */
+    {
+        rv = pthread_mutex_unlock(&lock->mutex);
+        PR_ASSERT(0 == rv);
+    }
+    else pt_PostNotifies(lock, PR_TRUE);
+
+#if defined(DEBUG)
+    pt_debug.locks_released += 1;
+#endif
+    return PR_SUCCESS;
+}  /* PR_Unlock */
+
+
+/**************************************************************/
+/**************************************************************/
+/***************************CONDITIONS*************************/
+/**************************************************************/
+/**************************************************************/
+
+
+/*
+ * This code is used to compute the absolute time for the wakeup.
+ * It's moderately ugly, so it's defined here and called in a
+ * couple of places.
+ */
+#define PT_NANOPERMICRO 1000UL
+#define PT_BILLION 1000000000UL
+
+static PRIntn pt_TimedWait(
+    pthread_cond_t *cv, pthread_mutex_t *ml, PRIntervalTime timeout)
+{
+    int rv;
+    struct timeval now;
+    struct timespec tmo;
+    PRUint32 ticks = PR_TicksPerSecond();
+
+    tmo.tv_sec = (PRInt32)(timeout / ticks);
+    tmo.tv_nsec = (PRInt32)(timeout - (tmo.tv_sec * ticks));
+    tmo.tv_nsec = (PRInt32)PR_IntervalToMicroseconds(PT_NANOPERMICRO * tmo.tv_nsec);
+
+    /* pthreads wants this in absolute time, off we go ... */
+    (void)GETTIMEOFDAY(&now);
+    /* that one's usecs, this one's nsecs - grrrr! */
+    tmo.tv_sec += now.tv_sec;
+    tmo.tv_nsec += (PT_NANOPERMICRO * now.tv_usec);
+    tmo.tv_sec += tmo.tv_nsec / PT_BILLION;
+    tmo.tv_nsec %= PT_BILLION;
+
+    rv = pthread_cond_timedwait(cv, ml, &tmo);
+
+    /* NSPR doesn't report timeouts */
+#ifdef _PR_DCETHREADS
+    if (rv == -1) return (errno == EAGAIN) ? 0 : errno;
+    else return rv;
+#else
+    return (rv == ETIMEDOUT) ? 0 : rv;
+#endif
+}  /* pt_TimedWait */
+
+
+/*
+ * Notifies just get posted to the protecting mutex. The
+ * actual notification is done when the lock is released so that
+ * MP systems don't contend for a lock that they can't have.
+ */
+static void pt_PostNotifyToCvar(PRCondVar *cvar, PRBool broadcast)
+{
+    PRIntn index = 0;
+    _PT_Notified *notified = &cvar->lock->notified;
+
+    PR_ASSERT(PR_TRUE == cvar->lock->locked);
+    PR_ASSERT(pthread_equal(cvar->lock->owner, pthread_self()));
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(cvar->lock->mutex));
+
+    while (1)
+    {
+        for (index = 0; index < notified->length; ++index)
+        {
+            if (notified->cv[index].cv == cvar)
+            {
+                if (broadcast)
+                    notified->cv[index].times = -1;
+                else if (-1 != notified->cv[index].times)
+                    notified->cv[index].times += 1;
+                goto finished;  /* we're finished */
+            }
+        }
+        /* if not full, enter new CV in this array */
+        if (notified->length < PT_CV_NOTIFIED_LENGTH) break;
+
+        /* if there's no link, create an empty array and link it */
+        if (NULL == notified->link)
+            notified->link = PR_NEWZAP(_PT_Notified);
+        notified = notified->link;
+    }
+
+    /* A brand new entry in the array */
+    (void)PR_AtomicIncrement(&cvar->notify_pending);
+    notified->cv[index].times = (broadcast) ? -1 : 1;
+    notified->cv[index].cv = cvar;
+    notified->length += 1;
+
+finished:
+    PR_ASSERT(PR_TRUE == cvar->lock->locked);
+    PR_ASSERT(pthread_equal(cvar->lock->owner, pthread_self()));
+}  /* pt_PostNotifyToCvar */
+
+PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock)
+{
+    PRCondVar *cv = PR_NEW(PRCondVar);
+    PR_ASSERT(lock != NULL);
+    if (cv != NULL)
+    {
+        int rv = _PT_PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr); 
+        PR_ASSERT(0 == rv);
+        cv->lock = lock;
+        cv->notify_pending = 0;
+#if defined(DEBUG)
+        pt_debug.cvars_created += 1;
+#endif
+    }
+    return cv;
+}  /* PR_NewCondVar */
+
+PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar)
+{
+    if (0 > PR_AtomicDecrement(&cvar->notify_pending))
+    {
+        PRIntn rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv);
+#if defined(DEBUG)
+        memset(cvar, 0xaf, sizeof(PRCondVar));
+        pt_debug.cvars_destroyed += 1;
+#endif
+        PR_DELETE(cvar);
+    }
+}  /* PR_DestroyCondVar */
+
+PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout)
+{
+    PRIntn rv;
+    PRThread *thred = PR_GetCurrentThread();
+
+    PR_ASSERT(cvar != NULL);
+    /* We'd better be locked */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(cvar->lock->mutex));
+    PR_ASSERT(PR_TRUE == cvar->lock->locked);
+    /* and it better be by us */
+    PR_ASSERT(pthread_equal(cvar->lock->owner, pthread_self()));
+
+    if (_PT_THREAD_INTERRUPTED(thred)) goto aborted;
+
+    /*
+     * The thread waiting is used for PR_Interrupt
+     */
+    thred->waiting = cvar;  /* this is where we're waiting */
+
+    /*
+     * If we have pending notifies, post them now.
+     *
+     * This is not optimal. We're going to post these notifies
+     * while we're holding the lock. That means on MP systems
+     * that they are going to collide for the lock that we will
+     * hold until we actually wait.
+     */
+    if (0 != cvar->lock->notified.length)
+        pt_PostNotifies(cvar->lock, PR_FALSE);
+
+    /*
+     * We're surrendering the lock, so clear out the locked field.
+     */
+    cvar->lock->locked = PR_FALSE;
+
+    if (timeout == PR_INTERVAL_NO_TIMEOUT)
+        rv = pthread_cond_wait(&cvar->cv, &cvar->lock->mutex);
+    else
+        rv = pt_TimedWait(&cvar->cv, &cvar->lock->mutex, timeout);
+
+    /* We just got the lock back - this better be empty */
+    PR_ASSERT(PR_FALSE == cvar->lock->locked);
+    cvar->lock->locked = PR_TRUE;
+    cvar->lock->owner = pthread_self();
+
+    PR_ASSERT(0 == cvar->lock->notified.length);
+    thred->waiting = NULL;  /* and now we're not */
+    if (_PT_THREAD_INTERRUPTED(thred)) goto aborted;
+    if (rv != 0)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(rv);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+
+aborted:
+    PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+    thred->state &= ~PT_THREAD_ABORTED;
+    return PR_FAILURE;
+}  /* PR_WaitCondVar */
+
+PR_IMPLEMENT(PRStatus) PR_NotifyCondVar(PRCondVar *cvar)
+{
+    PR_ASSERT(cvar != NULL);   
+    pt_PostNotifyToCvar(cvar, PR_FALSE);
+    return PR_SUCCESS;
+}  /* PR_NotifyCondVar */
+
+PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar)
+{
+    PR_ASSERT(cvar != NULL);
+    pt_PostNotifyToCvar(cvar, PR_TRUE);
+    return PR_SUCCESS;
+}  /* PR_NotifyAllCondVar */
+
+/**************************************************************/
+/**************************************************************/
+/***************************MONITORS***************************/
+/**************************************************************/
+/**************************************************************/
+
+PR_IMPLEMENT(PRMonitor*) PR_NewMonitor(void)
+{
+    PRMonitor *mon;
+    PRCondVar *cvar;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    cvar = PR_NEWZAP(PRCondVar);
+    if (NULL == cvar)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    mon = PR_NEWZAP(PRMonitor);
+    if (mon != NULL)
+    {
+        int rv;
+        rv = _PT_PTHREAD_MUTEX_INIT(mon->lock.mutex, _pt_mattr); 
+        PR_ASSERT(0 == rv);
+
+        _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner);
+
+        mon->cvar = cvar;
+        rv = _PT_PTHREAD_COND_INIT(mon->cvar->cv, _pt_cvar_attr); 
+        PR_ASSERT(0 == rv);
+        mon->entryCount = 0;
+        mon->cvar->lock = &mon->lock;
+        if (0 != rv)
+        {
+            PR_DELETE(mon);
+            PR_DELETE(cvar);
+            mon = NULL;
+        }
+    }
+    return mon;
+}  /* PR_NewMonitor */
+
+PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name)
+{
+    PRMonitor* mon = PR_NewMonitor();
+    if (mon)
+        mon->name = name;
+    return mon;
+}
+
+PR_IMPLEMENT(void) PR_DestroyMonitor(PRMonitor *mon)
+{
+    int rv;
+    PR_ASSERT(mon != NULL);
+    PR_DestroyCondVar(mon->cvar);
+    rv = pthread_mutex_destroy(&mon->lock.mutex); PR_ASSERT(0 == rv);
+#if defined(DEBUG)
+        memset(mon, 0xaf, sizeof(PRMonitor));
+#endif
+    PR_DELETE(mon);    
+}  /* PR_DestroyMonitor */
+
+
+/* The GC uses this; it is quite arguably a bad interface.  I'm just 
+ * duplicating it for now - XXXMB
+ */
+PR_IMPLEMENT(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon)
+{
+    pthread_t self = pthread_self();
+    if (pthread_equal(mon->owner, self))
+        return mon->entryCount;
+    return 0;
+}
+
+PR_IMPLEMENT(void) PR_EnterMonitor(PRMonitor *mon)
+{
+    pthread_t self = pthread_self();
+
+    PR_ASSERT(mon != NULL);
+    /*
+     * This is safe only if mon->owner (a pthread_t) can be
+     * read in one instruction.  Perhaps mon->owner should be
+     * a "PRThread *"?
+     */
+    if (!pthread_equal(mon->owner, self))
+    {
+        PR_Lock(&mon->lock);
+        /* and now I have the lock */
+        PR_ASSERT(0 == mon->entryCount);
+        PR_ASSERT(_PT_PTHREAD_THR_HANDLE_IS_INVALID(mon->owner));
+        _PT_PTHREAD_COPY_THR_HANDLE(self, mon->owner);
+    }
+    mon->entryCount += 1;
+}  /* PR_EnterMonitor */
+
+PR_IMPLEMENT(PRStatus) PR_ExitMonitor(PRMonitor *mon)
+{
+    pthread_t self = pthread_self();
+
+    PR_ASSERT(mon != NULL);
+    /* The lock better be that - locked */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));
+    /* we'd better be the owner */
+    PR_ASSERT(pthread_equal(mon->owner, self));
+    if (!pthread_equal(mon->owner, self))
+        return PR_FAILURE;
+
+    /* if it's locked and we have it, then the entries should be > 0 */
+    PR_ASSERT(mon->entryCount > 0);
+    mon->entryCount -= 1;  /* reduce by one */
+    if (mon->entryCount == 0)
+    {
+        /* and if it transitioned to zero - unlock */
+        _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner);  /* make the owner unknown */
+        PR_Unlock(&mon->lock);
+    }
+    return PR_SUCCESS;
+}  /* PR_ExitMonitor */
+
+PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime timeout)
+{
+    PRStatus rv;
+    PRInt16 saved_entries;
+    pthread_t saved_owner;
+
+    PR_ASSERT(mon != NULL);
+    /* we'd better be locked */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));
+    /* and the entries better be positive */
+    PR_ASSERT(mon->entryCount > 0);
+    /* and it better be by us */
+    PR_ASSERT(pthread_equal(mon->owner, pthread_self()));
+
+    /* tuck these away 'till later */
+    saved_entries = mon->entryCount; 
+    mon->entryCount = 0;
+    _PT_PTHREAD_COPY_THR_HANDLE(mon->owner, saved_owner);
+    _PT_PTHREAD_INVALIDATE_THR_HANDLE(mon->owner);
+    
+    rv = PR_WaitCondVar(mon->cvar, timeout);
+
+    /* reinstate the intresting information */
+    mon->entryCount = saved_entries;
+    _PT_PTHREAD_COPY_THR_HANDLE(saved_owner, mon->owner);
+
+    return rv;
+}  /* PR_Wait */
+
+PR_IMPLEMENT(PRStatus) PR_Notify(PRMonitor *mon)
+{
+    PR_ASSERT(NULL != mon);
+    /* we'd better be locked */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));
+    /* and the entries better be positive */
+    PR_ASSERT(mon->entryCount > 0);
+    /* and it better be by us */
+    PR_ASSERT(pthread_equal(mon->owner, pthread_self()));
+
+    pt_PostNotifyToCvar(mon->cvar, PR_FALSE);
+
+    return PR_SUCCESS;
+}  /* PR_Notify */
+
+PR_IMPLEMENT(PRStatus) PR_NotifyAll(PRMonitor *mon)
+{
+    PR_ASSERT(mon != NULL);
+    /* we'd better be locked */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(mon->lock.mutex));
+    /* and the entries better be positive */
+    PR_ASSERT(mon->entryCount > 0);
+    /* and it better be by us */
+    PR_ASSERT(pthread_equal(mon->owner, pthread_self()));
+
+    pt_PostNotifyToCvar(mon->cvar, PR_TRUE);
+
+    return PR_SUCCESS;
+}  /* PR_NotifyAll */
+
+/**************************************************************/
+/**************************************************************/
+/**************************SEMAPHORES**************************/
+/**************************************************************/
+/**************************************************************/
+PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *semaphore)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete(
+        "PR_PostSem", "locks & condition variables");
+	PR_Lock(semaphore->cvar->lock);
+	PR_NotifyCondVar(semaphore->cvar);
+	semaphore->count += 1;
+	PR_Unlock(semaphore->cvar->lock);
+}  /* PR_PostSem */
+
+PR_IMPLEMENT(PRStatus) PR_WaitSem(PRSemaphore *semaphore)
+{
+	PRStatus status = PR_SUCCESS;
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete(
+        "PR_WaitSem", "locks & condition variables");
+	PR_Lock(semaphore->cvar->lock);
+	while ((semaphore->count == 0) && (PR_SUCCESS == status))
+		status = PR_WaitCondVar(semaphore->cvar, PR_INTERVAL_NO_TIMEOUT);
+	if (PR_SUCCESS == status) semaphore->count -= 1;
+	PR_Unlock(semaphore->cvar->lock);
+	return status;
+}  /* PR_WaitSem */
+
+PR_IMPLEMENT(void) PR_DestroySem(PRSemaphore *semaphore)
+{
+    static PRBool unwarned = PR_TRUE;
+    if (unwarned) unwarned = _PR_Obsolete(
+        "PR_DestroySem", "locks & condition variables");
+    PR_DestroyLock(semaphore->cvar->lock);
+    PR_DestroyCondVar(semaphore->cvar);
+    PR_DELETE(semaphore);
+}  /* PR_DestroySem */
+
+PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value)
+{
+    PRSemaphore *semaphore;
+    static PRBool unwarned = PR_TRUE;
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (unwarned) unwarned = _PR_Obsolete(
+        "PR_NewSem", "locks & condition variables");
+
+    semaphore = PR_NEWZAP(PRSemaphore);
+    if (NULL != semaphore)
+    {
+        PRLock *lock = PR_NewLock();
+        if (NULL != lock)
+        {
+            semaphore->cvar = PR_NewCondVar(lock);
+            if (NULL != semaphore->cvar)
+            {
+                semaphore->count = value;
+                return semaphore;
+            }
+            PR_DestroyLock(lock);
+        }
+        PR_DELETE(semaphore);
+    }
+    return NULL;
+}
+
+/*
+ * Define the interprocess named semaphore functions.
+ * There are three implementations:
+ * 1. POSIX semaphore based;
+ * 2. System V semaphore based;
+ * 3. unsupported (fails with PR_NOT_IMPLEMENTED_ERROR).
+ */
+
+#ifdef _PR_HAVE_POSIX_SEMAPHORES
+#include <fcntl.h>
+
+PR_IMPLEMENT(PRSem *) PR_OpenSemaphore(
+    const char *name,
+    PRIntn flags,
+    PRIntn mode,
+    PRUintn value)
+{
+    PRSem *sem;
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+        == PR_FAILURE)
+    {
+        return NULL;
+    }
+
+    sem = PR_NEW(PRSem);
+    if (NULL == sem)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+
+    if (flags & PR_SEM_CREATE)
+    {
+        int oflag = O_CREAT;
+
+        if (flags & PR_SEM_EXCL) oflag |= O_EXCL;
+        sem->sem = sem_open(osname, oflag, mode, value);
+    }
+    else
+    {
+#ifdef HPUX
+        /* Pass 0 as the mode and value arguments to work around a bug. */
+        sem->sem = sem_open(osname, 0, 0, 0);
+#else
+        sem->sem = sem_open(osname, 0);
+#endif
+    }
+    if ((sem_t *) -1 == sem->sem)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        PR_DELETE(sem);
+        return NULL;
+    }
+    return sem;
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem)
+{
+    int rv;
+    rv = sem_wait(sem->sem);
+    if (0 != rv)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem)
+{
+    int rv;
+    rv = sem_post(sem->sem);
+    if (0 != rv)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem)
+{
+    int rv;
+    rv = sem_close(sem->sem);
+    if (0 != rv)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    PR_DELETE(sem);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name)
+{
+    int rv;
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+        == PR_FAILURE)
+    {
+        return PR_FAILURE;
+    }
+    rv = sem_unlink(osname);
+    if (0 != rv)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+    
+#elif defined(_PR_HAVE_SYSV_SEMAPHORES)
+
+#include <fcntl.h>
+#include <sys/sem.h>
+
+/*
+ * From the semctl(2) man page in glibc 2.0
+ */
+#if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) \
+    || defined(FREEBSD) || defined(OPENBSD) || defined(BSDI)
+/* union semun is defined by including <sys/sem.h> */
+#else
+/* according to X/OPEN we have to define it ourselves */
+union semun {
+    int val;
+    struct semid_ds *buf;
+    unsigned short  *array;
+};
+#endif
+
+/*
+ * 'a' (97) is the final closing price of NSCP stock.
+ */
+#define NSPR_IPC_KEY_ID 'a'  /* the id argument for ftok() */
+
+#define NSPR_SEM_MODE 0666
+
+PR_IMPLEMENT(PRSem *) PR_OpenSemaphore(
+    const char *name,
+    PRIntn flags,
+    PRIntn mode,
+    PRUintn value)
+{
+    PRSem *sem;
+    key_t key;
+    union semun arg;
+    struct sembuf sop;
+    struct semid_ds seminfo;
+#define MAX_TRIES 60
+    PRIntn i;
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+        == PR_FAILURE)
+    {
+        return NULL;
+    }
+
+    /* Make sure the file exists before calling ftok. */
+    if (flags & PR_SEM_CREATE)
+    {
+        int osfd = open(osname, O_RDWR|O_CREAT, mode);
+        if (-1 == osfd)
+        {
+            _PR_MD_MAP_OPEN_ERROR(errno);
+            return NULL;
+        }
+        if (close(osfd) == -1)
+        {
+            _PR_MD_MAP_CLOSE_ERROR(errno);
+            return NULL;
+        }
+    }
+    key = ftok(osname, NSPR_IPC_KEY_ID);
+    if ((key_t)-1 == key)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return NULL;
+    }
+
+    sem = PR_NEW(PRSem);
+    if (NULL == sem)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+
+    if (flags & PR_SEM_CREATE)
+    {
+        sem->semid = semget(key, 1, mode|IPC_CREAT|IPC_EXCL);
+        if (sem->semid >= 0)
+        {
+            /* creator of a semaphore is responsible for initializing it */
+            arg.val = 0;
+            if (semctl(sem->semid, 0, SETVAL, arg) == -1)
+            {
+                _PR_MD_MAP_DEFAULT_ERROR(errno);
+                PR_DELETE(sem);
+                return NULL;
+            }
+            /* call semop to set sem_otime to nonzero */
+            sop.sem_num = 0;
+            sop.sem_op = value;
+            sop.sem_flg = 0;
+            if (semop(sem->semid, &sop, 1) == -1)
+            {
+                _PR_MD_MAP_DEFAULT_ERROR(errno);
+                PR_DELETE(sem);
+                return NULL;
+            }
+            return sem;
+        }
+
+        if (errno != EEXIST || flags & PR_SEM_EXCL)
+        {
+            _PR_MD_MAP_DEFAULT_ERROR(errno);
+            PR_DELETE(sem);
+            return NULL;
+        }
+    }
+
+    sem->semid = semget(key, 1, NSPR_SEM_MODE);
+    if (sem->semid == -1)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        PR_DELETE(sem);
+        return NULL;
+    }
+    for (i = 0; i < MAX_TRIES; i++)
+    {
+        arg.buf = &seminfo;
+        semctl(sem->semid, 0, IPC_STAT, arg);
+        if (seminfo.sem_otime != 0) break;
+        sleep(1);
+    }
+    if (i == MAX_TRIES)
+    {
+        PR_SetError(PR_IO_TIMEOUT_ERROR, 0);
+        PR_DELETE(sem);
+        return NULL;
+    }
+    return sem;
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem)
+{
+    struct sembuf sop;
+
+    sop.sem_num = 0;
+    sop.sem_op = -1;
+    sop.sem_flg = 0;
+    if (semop(sem->semid, &sop, 1) == -1)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem)
+{
+    struct sembuf sop;
+
+    sop.sem_num = 0;
+    sop.sem_op = 1;
+    sop.sem_flg = 0;
+    if (semop(sem->semid, &sop, 1) == -1)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem)
+{
+    PR_DELETE(sem);
+    return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name)
+{
+    key_t key;
+    int semid;
+    /* On some systems (e.g., glibc 2.0) semctl requires a fourth argument */
+    union semun unused;
+    char osname[PR_IPC_NAME_SIZE];
+
+    if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem)
+        == PR_FAILURE)
+    {
+        return PR_FAILURE;
+    }
+    key = ftok(osname, NSPR_IPC_KEY_ID);
+    if ((key_t) -1 == key)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    if (unlink(osname) == -1)
+    {
+        _PR_MD_MAP_UNLINK_ERROR(errno);
+        return PR_FAILURE;
+    }
+    semid = semget(key, 1, NSPR_SEM_MODE);
+    if (-1 == semid)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    unused.val = 0;
+    if (semctl(semid, 0, IPC_RMID, unused) == -1)
+    { 
+        _PR_MD_MAP_DEFAULT_ERROR(errno);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+#else /* neither POSIX nor System V semaphores are available */
+
+PR_IMPLEMENT(PRSem *) PR_OpenSemaphore(
+    const char *name,
+    PRIntn flags,
+    PRIntn mode,
+    PRUintn value)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_WaitSemaphore(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus) PR_PostSemaphore(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CloseSemaphore(PRSem *sem)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name)
+{
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return PR_FAILURE;
+}
+
+#endif /* end of interprocess named semaphore functions */
+
+/**************************************************************/
+/**************************************************************/
+/******************ROUTINES FOR DCE EMULATION******************/
+/**************************************************************/
+/**************************************************************/
+
+#include "prpdce.h"
+
+PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock)
+{
+    PRIntn rv = pthread_mutex_trylock(&lock->mutex);
+    if (rv == PT_TRYLOCK_SUCCESS)
+    {
+        PR_ASSERT(PR_FALSE == lock->locked);
+        lock->locked = PR_TRUE;
+        lock->owner = pthread_self();
+    }
+    /* XXX set error code? */
+    return (PT_TRYLOCK_SUCCESS == rv) ? PR_SUCCESS : PR_FAILURE;
+}  /* PRP_TryLock */
+
+PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void)
+{
+    PRCondVar *cv;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    cv = PR_NEW(PRCondVar);
+    if (cv != NULL)
+    {
+        int rv;
+        rv = _PT_PTHREAD_COND_INIT(cv->cv, _pt_cvar_attr); 
+        PR_ASSERT(0 == rv);
+        cv->lock = _PR_NAKED_CV_LOCK;
+    }
+    return cv;
+}  /* PRP_NewNakedCondVar */
+
+PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar)
+{
+    int rv;
+    rv = pthread_cond_destroy(&cvar->cv); PR_ASSERT(0 == rv);
+#if defined(DEBUG)
+        memset(cvar, 0xaf, sizeof(PRCondVar));
+#endif
+    PR_DELETE(cvar);
+}  /* PRP_DestroyNakedCondVar */
+
+PR_IMPLEMENT(PRStatus) PRP_NakedWait(
+    PRCondVar *cvar, PRLock *ml, PRIntervalTime timeout)
+{
+    PRIntn rv;
+    PR_ASSERT(cvar != NULL);
+    /* XXX do we really want to assert this in a naked wait? */
+    PR_ASSERT(_PT_PTHREAD_MUTEX_IS_LOCKED(ml->mutex));
+    if (timeout == PR_INTERVAL_NO_TIMEOUT)
+        rv = pthread_cond_wait(&cvar->cv, &ml->mutex);
+    else
+        rv = pt_TimedWait(&cvar->cv, &ml->mutex, timeout);
+    if (rv != 0)
+    {
+        _PR_MD_MAP_DEFAULT_ERROR(rv);
+        return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}  /* PRP_NakedWait */
+
+PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar)
+{
+    int rv;
+    PR_ASSERT(cvar != NULL);
+    rv = pthread_cond_signal(&cvar->cv);
+    PR_ASSERT(0 == rv);
+    return PR_SUCCESS;
+}  /* PRP_NakedNotify */
+
+PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar)
+{
+    int rv;
+    PR_ASSERT(cvar != NULL);
+    rv = pthread_cond_broadcast(&cvar->cv);
+    PR_ASSERT(0 == rv);
+    return PR_SUCCESS;
+}  /* PRP_NakedBroadcast */
+
+#endif  /* defined(_PR_PTHREADS) */
+
+/* ptsynch.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptthread.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/pthreads/ptthread.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1548 @@
+/* -*- 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:            ptthread.c
+** Descritpion:        Implemenation for threds using pthreds
+** Exports:            ptthread.h
+*/
+
+#if defined(_PR_PTHREADS) || defined(_PR_DCETHREADS)
+
+#include "prlog.h"
+#include "primpl.h"
+#include "prpdce.h"
+
+#include <pthread.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+
+/*
+ * Record whether or not we have the privilege to set the scheduling
+ * policy and priority of threads.  0 means that privilege is available.
+ * EPERM means that privilege is not available.
+ */
+
+static PRIntn pt_schedpriv = 0;
+extern PRLock *_pr_sleeplock;
+
+static struct _PT_Bookeeping
+{
+    PRLock *ml;                 /* a lock to protect ourselves */
+    PRCondVar *cv;              /* used to signal global things */
+    PRInt32 system, user;       /* a count of the two different types */
+    PRUintn this_many;          /* number of threads allowed for exit */
+    pthread_key_t key;          /* private private data key */
+    PRThread *first, *last;     /* list of threads we know about */
+#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+    PRInt32 minPrio, maxPrio;   /* range of scheduling priorities */
+#endif
+} pt_book = {0};
+
+static void _pt_thread_death(void *arg);
+static void init_pthread_gc_support(void);
+
+#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+static PRIntn pt_PriorityMap(PRThreadPriority pri)
+{
+#ifdef NTO
+    /* This priority algorithm causes lots of problems on Neutrino
+     * for now I have just hard coded everything to run at priority 10
+     * until I can come up with a new algorithm.
+     *     Jerry.Kirk at Nexwarecorp.com
+     */
+    return 10;
+#else
+    return pt_book.minPrio +
+	    pri * (pt_book.maxPrio - pt_book.minPrio) / PR_PRIORITY_LAST;
+#endif
+}
+#endif
+
+#if defined(GC_LEAK_DETECTOR) && (__GLIBC__ >= 2) && defined(__i386__) 
+
+#include <setjmp.h>
+
+typedef struct stack_frame stack_frame;
+
+struct stack_frame {
+    stack_frame* next;
+    void* pc;
+};
+
+static stack_frame* GetStackFrame()
+{
+    jmp_buf jb;
+    stack_frame* currentFrame;
+    setjmp(jb);
+    currentFrame = (stack_frame*)(jb[0].__jmpbuf[JB_BP]);
+    currentFrame = currentFrame->next;
+    return currentFrame;
+}
+
+static void* GetStackTop()
+{
+    stack_frame* frame;
+    frame = GetStackFrame();
+    while (frame != NULL)
+    {
+        ptrdiff_t pc = (ptrdiff_t)frame->pc;
+        if ((pc < 0x08000000) || (pc > 0x7fffffff) || (frame->next < frame))
+            return frame;
+        frame = frame->next;
+    }
+    return NULL;
+}
+#endif /* GC_LEAK_DETECTOR && (__GLIBC__ >= 2) && __i386__ */
+
+/*
+** Initialize a stack for a native pthread thread
+*/
+static void _PR_InitializeStack(PRThreadStack *ts)
+{
+    if( ts && (ts->stackTop == 0) ) {
+        ts->allocBase = (char *) &ts;
+        ts->allocSize = ts->stackSize;
+
+        /*
+        ** Setup stackTop and stackBottom values.
+        */
+#ifdef HAVE_STACK_GROWING_UP
+        ts->stackBottom = ts->allocBase + ts->stackSize;
+        ts->stackTop = ts->allocBase;
+#else
+#ifdef GC_LEAK_DETECTOR
+        ts->stackTop    = GetStackTop();
+        ts->stackBottom = ts->stackTop - ts->stackSize;
+#else
+        ts->stackTop    = ts->allocBase;
+        ts->stackBottom = ts->allocBase - ts->stackSize;
+#endif
+#endif
+    }
+}
+
+static void *_pt_root(void *arg)
+{
+    PRIntn rv;
+    PRThread *thred = (PRThread*)arg;
+    PRBool detached = (thred->state & PT_THREAD_DETACHED) ? PR_TRUE : PR_FALSE;
+
+    /*
+     * Both the parent thread and this new thread set thred->id.
+     * The new thread must ensure that thred->id is set before
+     * it executes its startFunc.  The parent thread must ensure
+     * that thred->id is set before PR_CreateThread() returns.
+     * Both threads set thred->id without holding a lock.  Since
+     * they are writing the same value, this unprotected double
+     * write should be safe.
+     */
+    thred->id = pthread_self();
+
+    /*
+    ** DCE Threads can't detach during creation, so do it late.
+    ** I would like to do it only here, but that doesn't seem
+    ** to work.
+    */
+#if defined(_PR_DCETHREADS)
+    if (detached)
+    {
+        /* pthread_detach() modifies its argument, so we must pass a copy */
+        pthread_t self = thred->id;
+        rv = pthread_detach(&self);
+        PR_ASSERT(0 == rv);
+    }
+#endif /* defined(_PR_DCETHREADS) */
+
+    /* Set up the thread stack information */
+    _PR_InitializeStack(thred->stack);
+
+    /*
+     * Set within the current thread the pointer to our object.
+     * This object will be deleted when the thread termintates,
+     * whether in a join or detached (see _PR_InitThreads()).
+     */
+    rv = pthread_setspecific(pt_book.key, thred);
+    PR_ASSERT(0 == rv);
+
+    /* make the thread visible to the rest of the runtime */
+    PR_Lock(pt_book.ml);
+
+    /* If this is a GCABLE thread, set its state appropriately */
+    if (thred->suspend & PT_THREAD_SETGCABLE)
+	    thred->state |= PT_THREAD_GCABLE;
+    thred->suspend = 0;
+
+    thred->prev = pt_book.last;
+    if (pt_book.last)
+        pt_book.last->next = thred;
+    else
+        pt_book.first = thred;
+    thred->next = NULL;
+    pt_book.last = thred;
+    PR_Unlock(pt_book.ml);
+
+    thred->startFunc(thred->arg);  /* make visible to the client */
+
+    /* unhook the thread from the runtime */
+    PR_Lock(pt_book.ml);
+    /*
+     * At this moment, PR_CreateThread() may not have set thred->id yet.
+     * It is safe for a detached thread to free thred only after
+     * PR_CreateThread() has set thred->id.
+     */
+    if (detached)
+    {
+        while (!thred->okToDelete)
+            PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+    if (thred->state & PT_THREAD_SYSTEM)
+        pt_book.system -= 1;
+    else if (--pt_book.user == pt_book.this_many)
+        PR_NotifyAllCondVar(pt_book.cv);
+    if (NULL == thred->prev)
+        pt_book.first = thred->next;
+    else
+        thred->prev->next = thred->next;
+    if (NULL == thred->next)
+        pt_book.last = thred->prev;
+    else
+        thred->next->prev = thred->prev;
+    PR_Unlock(pt_book.ml);
+
+    /*
+    * Here we set the pthread's backpointer to the PRThread to NULL.
+    * Otherwise the destructor would get called eagerly as the thread
+    * returns to the pthread runtime. The joining thread would them be
+    * the proud possessor of a dangling reference. However, this is the
+    * last chance to delete the object if the thread is detached, so
+    * just let the destructor do the work.
+    */
+    if (PR_FALSE == detached)
+    {
+        rv = pthread_setspecific(pt_book.key, NULL);
+        PR_ASSERT(0 == rv);
+    }
+
+    return NULL;
+}  /* _pt_root */
+
+static PRThread* pt_AttachThread(void)
+{
+    PRThread *thred = NULL;
+
+    /*
+     * NSPR must have been initialized when PR_AttachThread is called.
+     * We cannot have PR_AttachThread call implicit initialization
+     * because if multiple threads call PR_AttachThread simultaneously,
+     * NSPR may be initialized more than once.
+     * We can't call any function that calls PR_GetCurrentThread()
+     * either (e.g., PR_SetError()) as that will result in infinite
+     * recursion.
+     */
+    if (!_pr_initialized) return NULL;
+
+    /* PR_NEWZAP must not call PR_GetCurrentThread() */
+    thred = PR_NEWZAP(PRThread);
+    if (NULL != thred)
+    {
+        int rv;
+
+        thred->priority = PR_PRIORITY_NORMAL;
+        thred->id = pthread_self();
+        rv = pthread_setspecific(pt_book.key, thred);
+        PR_ASSERT(0 == rv);
+
+        thred->state = PT_THREAD_GLOBAL | PT_THREAD_FOREIGN;
+        PR_Lock(pt_book.ml);
+
+        /* then put it into the list */
+        thred->prev = pt_book.last;
+        if (pt_book.last)
+            pt_book.last->next = thred;
+        else
+            pt_book.first = thred;
+        thred->next = NULL;
+        pt_book.last = thred;
+        PR_Unlock(pt_book.ml);
+
+    }
+    return thred;  /* may be NULL */
+}  /* pt_AttachThread */
+
+static PRThread* _PR_CreateThread(
+    PRThreadType type, void (*start)(void *arg),
+    void *arg, PRThreadPriority priority, PRThreadScope scope,
+    PRThreadState state, PRUint32 stackSize, PRBool isGCAble)
+{
+    int rv;
+    PRThread *thred;
+    pthread_attr_t tattr;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if ((PRIntn)PR_PRIORITY_FIRST > (PRIntn)priority)
+        priority = PR_PRIORITY_FIRST;
+    else if ((PRIntn)PR_PRIORITY_LAST < (PRIntn)priority)
+        priority = PR_PRIORITY_LAST;
+
+    rv = _PT_PTHREAD_ATTR_INIT(&tattr);
+    PR_ASSERT(0 == rv);
+
+    if (EPERM != pt_schedpriv)
+    {
+#if !defined(_PR_DCETHREADS) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+        struct sched_param schedule;
+#endif
+
+#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+        rv = pthread_attr_setinheritsched(&tattr, PTHREAD_EXPLICIT_SCHED);
+        PR_ASSERT(0 == rv);
+#endif
+
+        /* Use the default scheduling policy */
+
+#if defined(_PR_DCETHREADS)
+        rv = pthread_attr_setprio(&tattr, pt_PriorityMap(priority));
+        PR_ASSERT(0 == rv);
+#elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+        rv = pthread_attr_getschedparam(&tattr, &schedule);
+        PR_ASSERT(0 == rv);
+        schedule.sched_priority = pt_PriorityMap(priority);
+        rv = pthread_attr_setschedparam(&tattr, &schedule);
+        PR_ASSERT(0 == rv);
+#ifdef NTO
+        rv = pthread_attr_setschedpolicy(&tattr, SCHED_RR); /* Round Robin */
+        PR_ASSERT(0 == rv);
+#endif
+#endif /* !defined(_PR_DCETHREADS) */
+    }
+
+    /*
+     * DCE threads can't set detach state before creating the thread.
+     * AIX can't set detach late. Why can't we all just get along?
+     */
+#if !defined(_PR_DCETHREADS)
+    rv = pthread_attr_setdetachstate(&tattr,
+        ((PR_JOINABLE_THREAD == state) ?
+            PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
+    PR_ASSERT(0 == rv);
+#endif /* !defined(_PR_DCETHREADS) */
+
+    /*
+     * If stackSize is 0, we use the default pthread stack size.
+     */
+    if (stackSize)
+    {
+#ifdef _MD_MINIMUM_STACK_SIZE
+        if (stackSize < _MD_MINIMUM_STACK_SIZE)
+            stackSize = _MD_MINIMUM_STACK_SIZE;
+#endif
+        rv = pthread_attr_setstacksize(&tattr, stackSize);
+        PR_ASSERT(0 == rv);
+    }
+
+    thred = PR_NEWZAP(PRThread);
+    if (NULL == thred)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, errno);
+        goto done;
+    }
+    else
+    {
+        pthread_t id;
+
+        thred->arg = arg;
+        thred->startFunc = start;
+        thred->priority = priority;
+        if (PR_UNJOINABLE_THREAD == state)
+            thred->state |= PT_THREAD_DETACHED;
+
+        if (PR_LOCAL_THREAD == scope)
+        	scope = PR_GLOBAL_THREAD;
+			
+        if (PR_GLOBAL_BOUND_THREAD == scope) {
+#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+    		rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);
+			if (rv) {
+				/*
+				 * system scope not supported
+				 */
+        		scope = PR_GLOBAL_THREAD;
+				/*
+				 * reset scope
+				 */
+    			rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_PROCESS);
+    			PR_ASSERT(0 == rv);
+			}
+#endif
+		}
+        if (PR_GLOBAL_THREAD == scope)
+            thred->state |= PT_THREAD_GLOBAL;
+        else if (PR_GLOBAL_BOUND_THREAD == scope)
+            thred->state |= (PT_THREAD_GLOBAL | PT_THREAD_BOUND);
+		else	/* force it global */
+            thred->state |= PT_THREAD_GLOBAL;
+        if (PR_SYSTEM_THREAD == type)
+            thred->state |= PT_THREAD_SYSTEM;
+
+        thred->suspend =(isGCAble) ? PT_THREAD_SETGCABLE : 0;
+
+        thred->stack = PR_NEWZAP(PRThreadStack);
+        if (thred->stack == NULL) {
+            PRIntn oserr = errno;
+            PR_Free(thred);  /* all that work ... poof! */
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, oserr);
+            thred = NULL;  /* and for what? */
+            goto done;
+        }
+        thred->stack->stackSize = stackSize;
+        thred->stack->thr = thred;
+
+#ifdef PT_NO_SIGTIMEDWAIT
+        pthread_mutex_init(&thred->suspendResumeMutex,NULL);
+        pthread_cond_init(&thred->suspendResumeCV,NULL);
+#endif
+
+        /* make the thread counted to the rest of the runtime */
+        PR_Lock(pt_book.ml);
+        if (PR_SYSTEM_THREAD == type)
+            pt_book.system += 1;
+        else pt_book.user += 1;
+        PR_Unlock(pt_book.ml);
+
+        /*
+         * We pass a pointer to a local copy (instead of thred->id)
+         * to pthread_create() because who knows what wacky things
+         * pthread_create() may be doing to its argument.
+         */
+        rv = _PT_PTHREAD_CREATE(&id, tattr, _pt_root, thred);
+
+#if !defined(_PR_DCETHREADS)
+        if (EPERM == rv)
+        {
+#if defined(IRIX)
+        	if (PR_GLOBAL_BOUND_THREAD == scope) {
+				/*
+				 * SCOPE_SYSTEM requires appropriate privilege
+				 * reset to process scope and try again
+				 */
+    			rv = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_PROCESS);
+    			PR_ASSERT(0 == rv);
+            	thred->state &= ~PT_THREAD_BOUND;
+			}
+#else
+            /* Remember that we don't have thread scheduling privilege. */
+            pt_schedpriv = EPERM;
+            PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+                ("_PR_CreateThread: no thread scheduling privilege"));
+            /* Try creating the thread again without setting priority. */
+#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+            rv = pthread_attr_setinheritsched(&tattr, PTHREAD_INHERIT_SCHED);
+            PR_ASSERT(0 == rv);
+#endif
+#endif	/* IRIX */
+            rv = _PT_PTHREAD_CREATE(&id, tattr, _pt_root, thred);
+        }
+#endif
+
+        if (0 != rv)
+        {
+#if defined(_PR_DCETHREADS)
+            PRIntn oserr = errno;
+#else
+            PRIntn oserr = rv;
+#endif
+            PR_Lock(pt_book.ml);
+            if (thred->state & PT_THREAD_SYSTEM)
+                pt_book.system -= 1;
+            else if (--pt_book.user == pt_book.this_many)
+                PR_NotifyAllCondVar(pt_book.cv);
+            PR_Unlock(pt_book.ml);
+
+            PR_Free(thred->stack);
+            PR_Free(thred);  /* all that work ... poof! */
+            PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, oserr);
+            thred = NULL;  /* and for what? */
+            goto done;
+        }
+
+        /*
+         * Both the parent thread and this new thread set thred->id.
+         * The parent thread must ensure that thred->id is set before
+         * PR_CreateThread() returns.  (See comments in _pt_root().)
+         */
+        thred->id = id;
+
+        /*
+         * If the new thread is detached, tell it that PR_CreateThread()
+         * has set thred->id so it's ok to delete thred.
+         */
+        if (PR_UNJOINABLE_THREAD == state)
+        {
+            PR_Lock(pt_book.ml);
+            thred->okToDelete = PR_TRUE;
+            PR_NotifyAllCondVar(pt_book.cv);
+            PR_Unlock(pt_book.ml);
+        }
+    }
+
+done:
+    rv = _PT_PTHREAD_ATTR_DESTROY(&tattr);
+    PR_ASSERT(0 == rv);
+
+    return thred;
+}  /* _PR_CreateThread */
+
+PR_IMPLEMENT(PRThread*) PR_CreateThread(
+    PRThreadType type, void (*start)(void *arg), void *arg,
+    PRThreadPriority priority, PRThreadScope scope,
+    PRThreadState state, PRUint32 stackSize)
+{
+    return _PR_CreateThread(
+        type, start, arg, priority, scope, state, stackSize, PR_FALSE);
+} /* PR_CreateThread */
+
+PR_IMPLEMENT(PRThread*) PR_CreateThreadGCAble(
+    PRThreadType type, void (*start)(void *arg), void *arg, 
+    PRThreadPriority priority, PRThreadScope scope,
+    PRThreadState state, PRUint32 stackSize)
+{
+    return _PR_CreateThread(
+        type, start, arg, priority, scope, state, stackSize, PR_TRUE);
+}  /* PR_CreateThreadGCAble */
+
+PR_IMPLEMENT(void*) GetExecutionEnvironment(PRThread *thred)
+{
+    return thred->environment;
+}  /* GetExecutionEnvironment */
+ 
+PR_IMPLEMENT(void) SetExecutionEnvironment(PRThread *thred, void *env)
+{
+    thred->environment = env;
+}  /* SetExecutionEnvironment */
+
+PR_IMPLEMENT(PRThread*) PR_AttachThread(
+    PRThreadType type, PRThreadPriority priority, PRThreadStack *stack)
+{
+    return PR_GetCurrentThread();
+}  /* PR_AttachThread */
+
+
+PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thred)
+{
+    int rv = -1;
+    void *result = NULL;
+    PR_ASSERT(thred != NULL);
+
+    if ((0xafafafaf == thred->state)
+    || (PT_THREAD_DETACHED == (PT_THREAD_DETACHED & thred->state))
+    || (PT_THREAD_FOREIGN == (PT_THREAD_FOREIGN & thred->state)))
+    {
+        /*
+         * This might be a bad address, but if it isn't, the state should
+         * either be an unjoinable thread or it's already had the object
+         * deleted. However, the client that called join on a detached
+         * thread deserves all the rath I can muster....
+         */
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        PR_LogPrint(
+            "PR_JoinThread: %p not joinable | already smashed\n", thred);
+    }
+    else
+    {
+        pthread_t id = thred->id;
+        rv = pthread_join(id, &result);
+        PR_ASSERT(rv == 0 && result == NULL);
+        if (0 == rv)
+        {
+#ifdef _PR_DCETHREADS
+            rv = pthread_detach(&id);
+            PR_ASSERT(0 == rv);
+#endif
+            _pt_thread_death(thred);
+        }
+        else
+        {
+            PRErrorCode prerror;
+            switch (rv)
+            {
+                case EINVAL:  /* not a joinable thread */
+                case ESRCH:   /* no thread with given ID */
+                    prerror = PR_INVALID_ARGUMENT_ERROR;
+                    break;
+                case EDEADLK: /* a thread joining with itself */
+                    prerror = PR_DEADLOCK_ERROR;
+                    break;
+                default:
+                    prerror = PR_UNKNOWN_ERROR;
+                    break;
+            }
+            PR_SetError(prerror, rv);
+        }
+    }
+    return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+}  /* PR_JoinThread */
+
+PR_IMPLEMENT(void) PR_DetachThread(void) { }  /* PR_DetachThread */
+
+PR_IMPLEMENT(PRThread*) PR_GetCurrentThread(void)
+{
+    void *thred;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred);
+    if (NULL == thred) thred = pt_AttachThread();
+    PR_ASSERT(NULL != thred);
+    return (PRThread*)thred;
+}  /* PR_GetCurrentThread */
+
+PR_IMPLEMENT(PRThreadScope) PR_GetThreadScope(const PRThread *thred)
+{
+    return (thred->state & PT_THREAD_BOUND) ?
+        PR_GLOBAL_BOUND_THREAD : PR_GLOBAL_THREAD;
+}  /* PR_GetThreadScope() */
+
+PR_IMPLEMENT(PRThreadType) PR_GetThreadType(const PRThread *thred)
+{
+    return (thred->state & PT_THREAD_SYSTEM) ?
+        PR_SYSTEM_THREAD : PR_USER_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadState) PR_GetThreadState(const PRThread *thred)
+{
+    return (thred->state & PT_THREAD_DETACHED) ?
+        PR_UNJOINABLE_THREAD : PR_JOINABLE_THREAD;
+}  /* PR_GetThreadState */
+
+PR_IMPLEMENT(PRThreadPriority) PR_GetThreadPriority(const PRThread *thred)
+{
+    PR_ASSERT(thred != NULL);
+    return thred->priority;
+}  /* PR_GetThreadPriority */
+
+PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred, PRThreadPriority newPri)
+{
+    PRIntn rv = -1;
+
+    PR_ASSERT(NULL != thred);
+
+    if ((PRIntn)PR_PRIORITY_FIRST > (PRIntn)newPri)
+        newPri = PR_PRIORITY_FIRST;
+    else if ((PRIntn)PR_PRIORITY_LAST < (PRIntn)newPri)
+        newPri = PR_PRIORITY_LAST;
+
+#if defined(_PR_DCETHREADS)
+    rv = pthread_setprio(thred->id, pt_PriorityMap(newPri));
+    /* pthread_setprio returns the old priority */
+#elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+    if (EPERM != pt_schedpriv)
+    {
+        int policy;
+        struct sched_param schedule;
+
+        rv = pthread_getschedparam(thred->id, &policy, &schedule);
+        if(0 == rv) {
+			schedule.sched_priority = pt_PriorityMap(newPri);
+			rv = pthread_setschedparam(thred->id, policy, &schedule);
+			if (EPERM == rv)
+			{
+				pt_schedpriv = EPERM;
+				PR_LOG(_pr_thread_lm, PR_LOG_MIN,
+					("PR_SetThreadPriority: no thread scheduling privilege"));
+			}
+		}
+		if (rv != 0)
+			rv = -1;
+    }
+#endif
+
+    thred->priority = newPri;
+}  /* PR_SetThreadPriority */
+
+PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thred)
+{
+    /*
+    ** If the target thread indicates that it's waiting,
+    ** find the condition and broadcast to it. Broadcast
+    ** since we don't know which thread (if there are more
+    ** than one). This sounds risky, but clients must
+    ** test their invariants when resumed from a wait and
+    ** I don't expect very many threads to be waiting on
+    ** a single condition and I don't expect interrupt to
+    ** be used very often.
+    **
+    ** I don't know why I thought this would work. Must have
+    ** been one of those weaker momements after I'd been
+    ** smelling the vapors.
+    **
+    ** Even with the followng changes it is possible that
+    ** the pointer to the condition variable is pointing
+    ** at a bogus value. Will the unerlying code detect
+    ** that?
+    */
+    PRCondVar *cv;
+    PR_ASSERT(NULL != thred);
+    if (NULL == thred) return PR_FAILURE;
+
+    thred->state |= PT_THREAD_ABORTED;
+
+    cv = thred->waiting;
+    if ((NULL != cv) && !thred->interrupt_blocked)
+    {
+        PRIntn rv;
+        (void)PR_AtomicIncrement(&cv->notify_pending);
+        rv = pthread_cond_broadcast(&cv->cv);
+        PR_ASSERT(0 == rv);
+        if (0 > PR_AtomicDecrement(&cv->notify_pending))
+            PR_DestroyCondVar(cv);
+    }
+    return PR_SUCCESS;
+}  /* PR_Interrupt */
+
+PR_IMPLEMENT(void) PR_ClearInterrupt(void)
+{
+    PRThread *me = PR_GetCurrentThread();
+    me->state &= ~PT_THREAD_ABORTED;
+}  /* PR_ClearInterrupt */
+
+PR_IMPLEMENT(void) PR_BlockInterrupt(void)
+{
+    PRThread *me = PR_GetCurrentThread();
+    _PT_THREAD_BLOCK_INTERRUPT(me);
+}  /* PR_BlockInterrupt */
+
+PR_IMPLEMENT(void) PR_UnblockInterrupt(void)
+{
+    PRThread *me = PR_GetCurrentThread();
+    _PT_THREAD_UNBLOCK_INTERRUPT(me);
+}  /* PR_UnblockInterrupt */
+
+PR_IMPLEMENT(PRStatus) PR_Yield(void)
+{
+    static PRBool warning = PR_TRUE;
+    if (warning) warning = _PR_Obsolete(
+        "PR_Yield()", "PR_Sleep(PR_INTERVAL_NO_WAIT)");
+    return PR_Sleep(PR_INTERVAL_NO_WAIT);
+}
+
+PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks)
+{
+    PRStatus rv = PR_SUCCESS;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (PR_INTERVAL_NO_WAIT == ticks)
+    {
+        _PT_PTHREAD_YIELD();
+    }
+    else
+    {
+        PRCondVar *cv;
+        PRIntervalTime timein;
+
+        timein = PR_IntervalNow();
+        cv = PR_NewCondVar(_pr_sleeplock);
+        PR_ASSERT(cv != NULL);
+        PR_Lock(_pr_sleeplock);
+        do
+        {
+            PRIntervalTime now = PR_IntervalNow();
+            PRIntervalTime delta = now - timein;
+            if (delta > ticks) break;
+            rv = PR_WaitCondVar(cv, ticks - delta);
+        } while (PR_SUCCESS == rv);
+        PR_Unlock(_pr_sleeplock);
+        PR_DestroyCondVar(cv);
+    }
+    return rv;
+}  /* PR_Sleep */
+
+static void _pt_thread_death(void *arg)
+{
+    PRThread *thred = (PRThread*)arg;
+
+    if (thred->state & (PT_THREAD_FOREIGN|PT_THREAD_PRIMORD))
+    {
+        PR_Lock(pt_book.ml);
+        if (NULL == thred->prev)
+            pt_book.first = thred->next;
+        else
+            thred->prev->next = thred->next;
+        if (NULL == thred->next)
+            pt_book.last = thred->prev;
+        else
+            thred->next->prev = thred->prev;
+        PR_Unlock(pt_book.ml);
+    }
+    _PR_DestroyThreadPrivate(thred);
+    PR_Free(thred->privateData);
+    if (NULL != thred->errorString)
+        PR_Free(thred->errorString);
+    PR_Free(thred->stack);
+    if (NULL != thred->syspoll_list)
+        PR_Free(thred->syspoll_list);
+#if defined(_PR_POLL_WITH_SELECT)
+    if (NULL != thred->selectfd_list)
+        PR_Free(thred->selectfd_list);
+#endif
+#if defined(DEBUG)
+    memset(thred, 0xaf, sizeof(PRThread));
+#endif /* defined(DEBUG) */
+    PR_Free(thred);
+}  /* _pt_thread_death */
+
+void _PR_InitThreads(
+    PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs)
+{
+    int rv;
+    PRThread *thred;
+
+#ifdef _PR_NEED_PTHREAD_INIT
+    /*
+     * On BSD/OS (3.1 and 4.0), the pthread subsystem is lazily
+     * initialized, but pthread_self() fails to initialize
+     * pthreads and hence returns a null thread ID if invoked
+     * by the primordial thread before any other pthread call.
+     * So we explicitly initialize pthreads here.
+     */
+    pthread_init();
+#endif
+
+#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
+#if defined(FREEBSD)
+    {
+    pthread_attr_t attr;
+    int policy;
+    /* get the min and max priorities of the default policy */
+    pthread_attr_init(&attr);
+    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+    pthread_attr_getschedpolicy(&attr, &policy);
+    pt_book.minPrio = sched_get_priority_min(policy);
+    PR_ASSERT(-1 != pt_book.minPrio);
+    pt_book.maxPrio = sched_get_priority_max(policy);
+    PR_ASSERT(-1 != pt_book.maxPrio);
+    pthread_attr_destroy(&attr);
+    }
+#else
+    /*
+    ** These might be function evaluations
+    */
+    pt_book.minPrio = PT_PRIO_MIN;
+    pt_book.maxPrio = PT_PRIO_MAX;
+#endif
+#endif
+    
+    PR_ASSERT(NULL == pt_book.ml);
+    pt_book.ml = PR_NewLock();
+    PR_ASSERT(NULL != pt_book.ml);
+    pt_book.cv = PR_NewCondVar(pt_book.ml);
+    PR_ASSERT(NULL != pt_book.cv);
+    thred = PR_NEWZAP(PRThread);
+    PR_ASSERT(NULL != thred);
+    thred->arg = NULL;
+    thred->startFunc = NULL;
+    thred->priority = priority;
+    thred->id = pthread_self();
+
+    thred->state = (PT_THREAD_DETACHED | PT_THREAD_PRIMORD);
+    if (PR_SYSTEM_THREAD == type)
+    {
+        thred->state |= PT_THREAD_SYSTEM;
+        pt_book.system += 1;
+	    pt_book.this_many = 0;
+    }
+    else
+    {
+	    pt_book.user += 1;
+	    pt_book.this_many = 1;
+    }
+    thred->next = thred->prev = NULL;
+    pt_book.first = pt_book.last = thred;
+
+    thred->stack = PR_NEWZAP(PRThreadStack);
+    PR_ASSERT(thred->stack != NULL);
+    thred->stack->stackSize = 0;
+    thred->stack->thr = thred;
+	_PR_InitializeStack(thred->stack);
+
+    /*
+     * Create a key for our use to store a backpointer in the pthread
+     * to our PRThread object. This object gets deleted when the thread
+     * returns from its root in the case of a detached thread. Other
+     * threads delete the objects in Join.
+     *
+     * NB: The destructor logic seems to have a bug so it isn't used.
+     * NBB: Oh really? I'm going to give it a spin - AOF 19 June 1998.
+     * More info - the problem is that pthreads calls the destructor
+     * eagerly as the thread returns from its root, rather than lazily
+     * after the thread is joined. Therefore, threads that are joining
+     * and holding PRThread references are actually holding pointers to
+     * nothing.
+     */
+    rv = _PT_PTHREAD_KEY_CREATE(&pt_book.key, _pt_thread_death);
+    PR_ASSERT(0 == rv);
+    rv = pthread_setspecific(pt_book.key, thred);
+    PR_ASSERT(0 == rv);    
+    PR_SetThreadPriority(thred, priority);
+}  /* _PR_InitThreads */
+
+PR_IMPLEMENT(PRStatus) PR_Cleanup(void)
+{
+    PRThread *me = PR_GetCurrentThread();
+    int rv;
+    PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("PR_Cleanup: shutting down NSPR"));
+    PR_ASSERT(me->state & PT_THREAD_PRIMORD);
+    if (me->state & PT_THREAD_PRIMORD)
+    {
+        PR_Lock(pt_book.ml);
+        while (pt_book.user > pt_book.this_many)
+            PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT);
+        PR_Unlock(pt_book.ml);
+
+        _PR_CleanupMW();
+        _PR_CleanupDtoa();
+        _PR_CleanupCallOnce();
+        _PR_ShutdownLinker();
+        _PR_LogCleanup();
+        _PR_CleanupNet();
+        /* Close all the fd's before calling _PR_CleanupIO */
+        _PR_CleanupIO();
+
+        _pt_thread_death(me);
+        rv = pthread_setspecific(pt_book.key, NULL);
+        PR_ASSERT(0 == rv);
+        /*
+         * I am not sure if it's safe to delete the cv and lock here,
+         * since there may still be "system" threads around. If this
+         * call isn't immediately prior to exiting, then there's a
+         * problem.
+         */
+        if (0 == pt_book.system)
+        {
+            PR_DestroyCondVar(pt_book.cv); pt_book.cv = NULL;
+            PR_DestroyLock(pt_book.ml); pt_book.ml = NULL;
+        }
+        PR_DestroyLock(_pr_sleeplock);
+        _pr_sleeplock = NULL;
+        _PR_CleanupLayerCache();
+        _PR_CleanupEnv();
+#ifdef _PR_ZONE_ALLOCATOR
+        _PR_DestroyZones();
+#endif
+        _pr_initialized = PR_FALSE;
+        return PR_SUCCESS;
+    }
+    return PR_FAILURE;
+}  /* PR_Cleanup */
+
+PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status)
+{
+    _exit(status);
+}
+
+PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thred)
+{
+#if defined(_PR_DCETHREADS)
+    return (PRUint32)&thred->id;  /* this is really a sham! */
+#else
+    return (PRUint32)thred->id;  /* and I don't know what they will do with it */
+#endif
+}
+
+/*
+ * $$$
+ * The following two thread-to-processor affinity functions are not
+ * yet implemented for pthreads.  By the way, these functions should return
+ * PRStatus rather than PRInt32 to indicate the success/failure status.
+ * $$$
+ */
+
+PR_IMPLEMENT(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask)
+{
+    return 0;  /* not implemented */
+}
+
+PR_IMPLEMENT(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask )
+{
+    return 0;  /* not implemented */
+}
+
+PR_IMPLEMENT(void)
+PR_SetThreadDumpProc(PRThread* thread, PRThreadDumpProc dump, void *arg)
+{
+    thread->dump = dump;
+    thread->dumpArg = arg;
+}
+
+/* 
+ * Garbage collection support follows.
+ */
+
+#if defined(_PR_DCETHREADS)
+
+/*
+ * statics for Garbage Collection support.  We don't need to protect these
+ * signal masks since the garbage collector itself is protected by a lock
+ * and multiple threads will not be garbage collecting at the same time.
+ */
+static sigset_t javagc_vtalarm_sigmask;
+static sigset_t javagc_intsoff_sigmask;
+
+#else /* defined(_PR_DCETHREADS) */
+
+/* a bogus signal mask for forcing a timed wait */
+/* Not so bogus in AIX as we really do a sigwait */
+static sigset_t sigwait_set;
+
+static struct timespec onemillisec = {0, 1000000L};
+#ifndef PT_NO_SIGTIMEDWAIT
+static struct timespec hundredmillisec = {0, 100000000L};
+#endif
+
+static void suspend_signal_handler(PRIntn sig);
+
+#ifdef PT_NO_SIGTIMEDWAIT
+static void null_signal_handler(PRIntn sig);
+#endif
+
+#endif /* defined(_PR_DCETHREADS) */
+
+/*
+ * Linux pthreads use SIGUSR1 and SIGUSR2 internally, which
+ * conflict with the use of these two signals in our GC support.
+ * So we don't know how to support GC on Linux pthreads.
+ */
+static void init_pthread_gc_support(void)
+{
+    PRIntn rv;
+
+#if defined(_PR_DCETHREADS)
+	rv = sigemptyset(&javagc_vtalarm_sigmask);
+    PR_ASSERT(0 == rv);
+	rv = sigaddset(&javagc_vtalarm_sigmask, SIGVTALRM);
+    PR_ASSERT(0 == rv);
+#else  /* defined(_PR_DCETHREADS) */
+	{
+	    struct sigaction sigact_usr2;
+
+	    sigact_usr2.sa_handler = suspend_signal_handler;
+	    sigact_usr2.sa_flags = SA_RESTART;
+	    sigemptyset (&sigact_usr2.sa_mask);
+
+        rv = sigaction (SIGUSR2, &sigact_usr2, NULL);
+        PR_ASSERT(0 == rv);
+
+        sigemptyset (&sigwait_set);
+#if defined(PT_NO_SIGTIMEDWAIT)
+        sigaddset (&sigwait_set, SIGUSR1);
+#else
+        sigaddset (&sigwait_set, SIGUSR2);
+#endif  /* defined(PT_NO_SIGTIMEDWAIT) */
+	}
+#if defined(PT_NO_SIGTIMEDWAIT)
+	{
+	    struct sigaction sigact_null;
+	    sigact_null.sa_handler = null_signal_handler;
+	    sigact_null.sa_flags = SA_RESTART;
+	    sigemptyset (&sigact_null.sa_mask);
+        rv = sigaction (SIGUSR1, &sigact_null, NULL);
+	    PR_ASSERT(0 ==rv); 
+    }
+#endif  /* defined(PT_NO_SIGTIMEDWAIT) */
+#endif /* defined(_PR_DCETHREADS) */
+}
+
+PR_IMPLEMENT(void) PR_SetThreadGCAble(void)
+{
+    PR_Lock(pt_book.ml);
+	PR_GetCurrentThread()->state |= PT_THREAD_GCABLE;
+    PR_Unlock(pt_book.ml);
+}
+
+PR_IMPLEMENT(void) PR_ClearThreadGCAble(void)
+{
+    PR_Lock(pt_book.ml);
+	PR_GetCurrentThread()->state &= (~PT_THREAD_GCABLE);
+    PR_Unlock(pt_book.ml);
+}
+
+#if defined(DEBUG)
+static PRBool suspendAllOn = PR_FALSE;
+#endif
+
+static PRBool suspendAllSuspended = PR_FALSE;
+
+PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg)
+{
+    PRIntn count = 0;
+    PRStatus rv = PR_SUCCESS;
+    PRThread* thred = pt_book.first;
+    PRThread *me = PR_GetCurrentThread();
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_EnumerateThreads\n"));
+    /*
+     * $$$
+     * Need to suspend all threads other than me before doing this.
+     * This is really a gross and disgusting thing to do. The only
+     * good thing is that since all other threads are suspended, holding
+     * the lock during a callback seems like child's play.
+     * $$$
+     */
+    PR_ASSERT(suspendAllOn);
+
+    while (thred != NULL)
+    {
+        /* Steve Morse, 4-23-97: Note that we can't walk a queue by taking
+         * qp->next after applying the function "func".  In particular, "func"
+         * might remove the thread from the queue and put it into another one in
+         * which case qp->next no longer points to the next entry in the original
+         * queue.
+         *
+         * To get around this problem, we save qp->next in qp_next before applying
+         * "func" and use that saved value as the next value after applying "func".
+         */
+        PRThread* next = thred->next;
+
+        if (_PT_IS_GCABLE_THREAD(thred))
+        {
+#if !defined(_PR_DCETHREADS)
+            PR_ASSERT((thred == me) || (thred->suspend & PT_THREAD_SUSPENDED));
+#endif
+            PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+                   ("In PR_EnumerateThreads callback thread %p thid = %X\n", 
+                    thred, thred->id));
+
+            rv = func(thred, count++, arg);
+            if (rv != PR_SUCCESS)
+                return rv;
+        }
+        thred = next;
+    }
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("End PR_EnumerateThreads count = %d \n", count));
+    return rv;
+}  /* PR_EnumerateThreads */
+
+/*
+ * PR_SuspendAll and PR_ResumeAll are called during garbage collection.  The strategy 
+ * we use is to send a SIGUSR2 signal to every gc able thread that we intend to suspend.
+ * The signal handler will record the stack pointer and will block until resumed by
+ * the resume call.  Since the signal handler is the last routine called for the
+ * suspended thread, the stack pointer will also serve as a place where all the
+ * registers have been saved on the stack for the previously executing routines.
+ *
+ * Through global variables, we also make sure that PR_Suspend and PR_Resume does not
+ * proceed until the thread is suspended or resumed.
+ */
+
+#if !defined(_PR_DCETHREADS)
+
+/*
+ * In the signal handler, we can not use condition variable notify or wait.
+ * This does not work consistently across all pthread platforms.  We also can not 
+ * use locking since that does not seem to work reliably across platforms.
+ * Only thing we can do is yielding while testing for a global condition
+ * to change.  This does work on pthread supported platforms.  We may have
+ * to play with priortities if there are any problems detected.
+ */
+
+ /* 
+  * In AIX, you cannot use ANY pthread calls in the signal handler except perhaps
+  * pthread_yield. But that is horribly inefficient. Hence we use only sigwait, no
+  * sigtimedwait is available. We need to use another user signal, SIGUSR1. Actually
+  * SIGUSR1 is also used by exec in Java. So our usage here breaks the exec in Java,
+  * for AIX. You cannot use pthread_cond_wait or pthread_delay_np in the signal
+  * handler as all synchronization mechanisms just break down. 
+  */
+
+#if defined(PT_NO_SIGTIMEDWAIT)
+static void null_signal_handler(PRIntn sig)
+{
+	return;
+}
+#endif
+
+static void suspend_signal_handler(PRIntn sig)
+{
+	PRThread *me = PR_GetCurrentThread();
+
+	PR_ASSERT(me != NULL);
+	PR_ASSERT(_PT_IS_GCABLE_THREAD(me));
+	PR_ASSERT((me->suspend & PT_THREAD_SUSPENDED) == 0);
+
+	PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+        ("Begin suspend_signal_handler thred %p thread id = %X\n", 
+		me, me->id));
+
+	/*
+	 * save stack pointer
+	 */
+	me->sp = &me;
+
+	/* 
+	   At this point, the thread's stack pointer has been saved,
+	   And it is going to enter a wait loop until it is resumed.
+	   So it is _really_ suspended 
+	*/
+
+	me->suspend |= PT_THREAD_SUSPENDED;
+
+	/*
+	 * now, block current thread
+	 */
+#if defined(PT_NO_SIGTIMEDWAIT)
+	pthread_cond_signal(&me->suspendResumeCV);
+	while (me->suspend & PT_THREAD_SUSPENDED)
+	{
+#if !defined(FREEBSD) && !defined(NETBSD) && !defined(OPENBSD) \
+    && !defined(BSDI) && !defined(VMS) && !defined(UNIXWARE) \
+    && !defined(DARWIN) && !defined(RISCOS) /*XXX*/
+        PRIntn rv;
+	    sigwait(&sigwait_set, &rv);
+#endif
+	}
+	me->suspend |= PT_THREAD_RESUMED;
+	pthread_cond_signal(&me->suspendResumeCV);
+#else /* defined(PT_NO_SIGTIMEDWAIT) */
+	while (me->suspend & PT_THREAD_SUSPENDED)
+	{
+		PRIntn rv = sigtimedwait(&sigwait_set, NULL, &hundredmillisec);
+    	PR_ASSERT(-1 == rv);
+	}
+	me->suspend |= PT_THREAD_RESUMED;
+#endif
+
+    /*
+     * At this point, thread has been resumed, so set a global condition.
+     * The ResumeAll needs to know that this has really been resumed. 
+     * So the signal handler sets a flag which PR_ResumeAll will reset. 
+     * The PR_ResumeAll must reset this flag ...
+     */
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+        ("End suspend_signal_handler thred = %p tid = %X\n", me, me->id));
+}  /* suspend_signal_handler */
+
+static void pt_SuspendSet(PRThread *thred)
+{
+    PRIntn rv;
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("pt_SuspendSet thred %p thread id = %X\n", thred, thred->id));
+
+
+    /*
+     * Check the thread state and signal the thread to suspend
+     */
+
+    PR_ASSERT((thred->suspend & PT_THREAD_SUSPENDED) == 0);
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("doing pthread_kill in pt_SuspendSet thred %p tid = %X\n",
+	   thred, thred->id));
+#if defined(VMS)
+    rv = thread_suspend(thred);
+#else
+    rv = pthread_kill (thred->id, SIGUSR2);
+#endif
+    PR_ASSERT(0 == rv);
+}
+
+static void pt_SuspendTest(PRThread *thred)
+{
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("Begin pt_SuspendTest thred %p thread id = %X\n", thred, thred->id));
+
+
+    /*
+     * Wait for the thread to be really suspended. This happens when the
+     * suspend signal handler stores the stack pointer and sets the state
+     * to suspended. 
+     */
+
+#if defined(PT_NO_SIGTIMEDWAIT)
+    pthread_mutex_lock(&thred->suspendResumeMutex);
+    while ((thred->suspend & PT_THREAD_SUSPENDED) == 0)
+    {
+	    pthread_cond_timedwait(
+	        &thred->suspendResumeCV, &thred->suspendResumeMutex, &onemillisec);
+	}
+	pthread_mutex_unlock(&thred->suspendResumeMutex);
+#else
+    while ((thred->suspend & PT_THREAD_SUSPENDED) == 0)
+    {
+		PRIntn rv = sigtimedwait(&sigwait_set, NULL, &onemillisec);
+    	PR_ASSERT(-1 == rv);
+	}
+#endif
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS,
+        ("End pt_SuspendTest thred %p tid %X\n", thred, thred->id));
+}  /* pt_SuspendTest */
+
+static void pt_ResumeSet(PRThread *thred)
+{
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("pt_ResumeSet thred %p thread id = %X\n", thred, thred->id));
+
+    /*
+     * Clear the global state and set the thread state so that it will
+     * continue past yield loop in the suspend signal handler
+     */
+
+    PR_ASSERT(thred->suspend & PT_THREAD_SUSPENDED);
+
+
+    thred->suspend &= ~PT_THREAD_SUSPENDED;
+
+#if defined(PT_NO_SIGTIMEDWAIT)
+#if defined(VMS)
+	thread_resume(thred);
+#else
+	pthread_kill(thred->id, SIGUSR1);
+#endif
+#endif
+
+}  /* pt_ResumeSet */
+
+static void pt_ResumeTest(PRThread *thred)
+{
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	   ("Begin pt_ResumeTest thred %p thread id = %X\n", thred, thred->id));
+
+    /*
+     * Wait for the threads resume state to change
+     * to indicate it is really resumed 
+     */
+#if defined(PT_NO_SIGTIMEDWAIT)
+    pthread_mutex_lock(&thred->suspendResumeMutex);
+    while ((thred->suspend & PT_THREAD_RESUMED) == 0)
+    {
+	    pthread_cond_timedwait(
+	        &thred->suspendResumeCV, &thred->suspendResumeMutex, &onemillisec);
+    }
+    pthread_mutex_unlock(&thred->suspendResumeMutex);
+#else
+    while ((thred->suspend & PT_THREAD_RESUMED) == 0) {
+		PRIntn rv = sigtimedwait(&sigwait_set, NULL, &onemillisec);
+    	PR_ASSERT(-1 == rv);
+	}
+#endif
+
+    thred->suspend &= ~PT_THREAD_RESUMED;
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, (
+        "End pt_ResumeTest thred %p tid %X\n", thred, thred->id));
+}  /* pt_ResumeTest */
+
+static pthread_once_t pt_gc_support_control = PTHREAD_ONCE_INIT;
+
+PR_IMPLEMENT(void) PR_SuspendAll(void)
+{
+#ifdef DEBUG
+    PRIntervalTime stime, etime;
+#endif
+    PRThread* thred = pt_book.first;
+    PRThread *me = PR_GetCurrentThread();
+    int rv;
+
+    rv = pthread_once(&pt_gc_support_control, init_pthread_gc_support);
+    PR_ASSERT(0 == rv);
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_SuspendAll\n"));
+    /*
+     * Stop all threads which are marked GC able.
+     */
+    PR_Lock(pt_book.ml);
+#ifdef DEBUG
+    suspendAllOn = PR_TRUE;
+    stime = PR_IntervalNow();
+#endif
+    while (thred != NULL)
+    {
+	    if ((thred != me) && _PT_IS_GCABLE_THREAD(thred))
+    		pt_SuspendSet(thred);
+        thred = thred->next;
+    }
+
+    /* Wait till they are really suspended */
+    thred = pt_book.first;
+    while (thred != NULL)
+    {
+	    if ((thred != me) && _PT_IS_GCABLE_THREAD(thred))
+            pt_SuspendTest(thred);
+        thred = thred->next;
+    }
+
+    suspendAllSuspended = PR_TRUE;
+
+#ifdef DEBUG
+    etime = PR_IntervalNow();
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS,\
+        ("End PR_SuspendAll (time %dms)\n",
+        PR_IntervalToMilliseconds(etime - stime)));
+#endif
+}  /* PR_SuspendAll */
+
+PR_IMPLEMENT(void) PR_ResumeAll(void)
+{
+#ifdef DEBUG
+    PRIntervalTime stime, etime;
+#endif
+    PRThread* thred = pt_book.first;
+    PRThread *me = PR_GetCurrentThread();
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_ResumeAll\n"));
+    /*
+     * Resume all previously suspended GC able threads.
+     */
+    suspendAllSuspended = PR_FALSE;
+#ifdef DEBUG
+    stime = PR_IntervalNow();
+#endif
+
+    while (thred != NULL)
+    {
+	    if ((thred != me) && _PT_IS_GCABLE_THREAD(thred))
+    	    pt_ResumeSet(thred);
+        thred = thred->next;
+    }
+
+    thred = pt_book.first;
+    while (thred != NULL)
+    {
+	    if ((thred != me) && _PT_IS_GCABLE_THREAD(thred))
+    	    pt_ResumeTest(thred);
+        thred = thred->next;
+    }
+
+    PR_Unlock(pt_book.ml);
+#ifdef DEBUG
+    suspendAllOn = PR_FALSE;
+    etime = PR_IntervalNow();
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS,
+        ("End PR_ResumeAll (time %dms)\n",
+        PR_IntervalToMilliseconds(etime - stime)));
+#endif
+}  /* PR_ResumeAll */
+
+/* Return the stack pointer for the given thread- used by the GC */
+PR_IMPLEMENT(void *)PR_GetSP(PRThread *thred)
+{
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, 
+	    ("in PR_GetSP thred %p thid = %X, sp = %p\n", 
+	    thred, thred->id, thred->sp));
+    return thred->sp;
+}  /* PR_GetSP */
+
+#else /* !defined(_PR_DCETHREADS) */
+
+static pthread_once_t pt_gc_support_control = pthread_once_init;
+
+/*
+ * For DCE threads, there is no pthread_kill or a way of suspending or resuming a
+ * particular thread.  We will just disable the preemption (virtual timer alarm) and
+ * let the executing thread finish the garbage collection.  This stops all other threads
+ * (GC able or not) and is very inefficient but there is no other choice.
+ */
+PR_IMPLEMENT(void) PR_SuspendAll()
+{
+    PRIntn rv;
+
+    rv = pthread_once(&pt_gc_support_control, init_pthread_gc_support);
+    PR_ASSERT(0 == rv);  /* returns -1 on failure */
+#ifdef DEBUG
+    suspendAllOn = PR_TRUE;
+#endif
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_SuspendAll\n"));
+    /* 
+     * turn off preemption - i.e add virtual alarm signal to the set of 
+     * blocking signals 
+     */
+    rv = sigprocmask(
+        SIG_BLOCK, &javagc_vtalarm_sigmask, &javagc_intsoff_sigmask);
+    PR_ASSERT(0 == rv);
+    suspendAllSuspended = PR_TRUE;
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_SuspendAll\n"));
+}  /* PR_SuspendAll */
+
+PR_IMPLEMENT(void) PR_ResumeAll()
+{
+    PRIntn rv;
+    
+    suspendAllSuspended = PR_FALSE;
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_ResumeAll\n"));
+    /* turn on preemption - i.e re-enable virtual alarm signal */
+
+    rv = sigprocmask(SIG_SETMASK, &javagc_intsoff_sigmask, (sigset_t *)NULL);
+    PR_ASSERT(0 == rv);
+#ifdef DEBUG
+    suspendAllOn = PR_FALSE;
+#endif
+
+    PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_ResumeAll\n"));
+}  /* PR_ResumeAll */
+
+/* Return the stack pointer for the given thread- used by the GC */
+PR_IMPLEMENT(void*)PR_GetSP(PRThread *thred)
+{
+	pthread_t tid = thred->id;
+	char *thread_tcb, *top_sp;
+
+	/*
+	 * For HPUX DCE threads, pthread_t is a struct with the
+	 * following three fields (see pthread.h, dce/cma.h):
+	 *     cma_t_address       field1;
+	 *     short int           field2;
+	 *     short int           field3;
+	 * where cma_t_address is typedef'd to be either void*
+	 * or char*.
+	 */
+	PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("Begin PR_GetSP\n"));
+	thread_tcb = (char*)tid.field1;
+	top_sp = *(char**)(thread_tcb + 128);
+	PR_LOG(_pr_gc_lm, PR_LOG_ALWAYS, ("End PR_GetSP %p \n", top_sp));
+	return top_sp;
+}  /* PR_GetSP */
+
+#endif /* !defined(_PR_DCETHREADS) */
+
+#endif  /* defined(_PR_PTHREADS) || defined(_PR_DCETHREADS) */
+
+/* ptthread.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,10 @@
+/.cvsignore/1.2/Sat May 12 04:55:26 2001//
+/Makefile.in/1.11/Sun Apr 25 15:01:02 2004//
+/prcmon.c/3.7/Sun Apr 25 15:01:02 2004//
+/prcthr.c/3.19/Sun Apr 25 15:01:02 2004//
+/prdump.c/3.7/Sun Apr 25 15:01:02 2004//
+/prmon.c/3.6/Sun Apr 25 15:01:02 2004//
+/prrwlock.c/1.9/Sun Apr 25 15:01:02 2004//
+/prsem.c/3.5/Sun Apr 25 15:01:02 2004//
+/prtpd.c/3.12/Sun Apr 25 15:01:02 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+A D/combined////

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/threads

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,94 @@
+# 
+# ***** 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
+
+ifdef USE_PTHREADS
+    DIRS =
+else
+ifdef USE_BTHREADS
+    DIRS =
+else
+    DIRS = combined
+endif
+endif
+
+ifdef USE_PTHREADS
+CSRCS = \
+	prcmon.c \
+	prrwlock.c   \
+	prtpd.c \
+	$(NULL)
+else
+ifdef USE_BTHREADS
+CSRCS = \
+	prcmon.c \
+	prrwlock.c   \
+	prtpd.c \
+	$(NULL)
+else
+CSRCS =	\
+	prcmon.c  \
+	prdump.c  \
+	prmon.c   \
+	prsem.c   \
+	prrwlock.c   \
+	prcthr.c \
+	prtpd.c \
+	$(NULL)
+endif
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,9 @@
+/.cvsignore/1.2/Sat May 12 04:56:56 2001//
+/Makefile.in/1.12/Sun Apr 25 15:01:02 2004//
+/README/3.1/Sat Mar 28 03:37:59 1998//
+/prucpu.c/3.14/Sun Apr 25 15:01:02 2004//
+/prucv.c/3.8/Sun Apr 25 15:01:02 2004//
+/prulock.c/3.12/Sun Apr 25 15:01:02 2004//
+/prustack.c/3.8/Sun Apr 25 15:01:02 2004//
+/pruthr.c/3.36/Sun Apr 25 15:01:02 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/src/threads/combined

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,79 @@
+# 
+# ***** 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 =
+endif
+endif
+
+ifdef USE_PTHREADS
+CSRCS =         \
+	$(NULL)
+else
+CSRCS =         \
+    prucpu.c      \
+	prucv.c      \
+	prulock.c    \
+	pruthr.c     \
+    prustack.c    \
+	$(NULL)
+endif
+
+TARGETS	= $(OBJS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+DEFINES	+= -D_NSPR_BUILD_
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/README
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/README	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,62 @@
+NSPR 2.0 evolution
+------------------
+
+
+Phase 1- today
+
+Currently (Oct 10, 1996) NSPR 2.0 has two modes.  Either _PR_NTHREAD 
+is defined, in which case the PR_CreateThread() call always creates a 
+native kernel thread, or _PR_NTHREAD is not defined and PR_CreateThread() 
+always creates user level threads within the single, original process.  This 
+source code is reflected in two directories, nspr20/pr/src/threads/native, and 
+nspr20/pr/src/threads/user.  Although the PR_CreateThread() function has
+a paramter to specify the "scope" of a thread, this parameter is not yet 
+used- except on solaris where it uses it to specify bound vs unbound threads.
+
+Phase 2 - next week
+
+The next step is to provide a combination of user and native threads.  The
+idea, of course, is to have some small number of native threads and each of 
+those threads be able to run user level threads.  The number of native
+threads created will most likely be proportional to the number of CPUs in
+the system.  For this reason, the specific set of native threads which are
+used to run the user-level threads will be called "CPU" threads.  
+
+The user level threads which will be run on the CPU threads are able to
+run on any of the CPU threads available, and over the course of a user-level
+thread's lifetime, it may drift from one CPU thread to another.  All 
+user-level threads will compete for processing time via a single run queue.
+
+Creation of a CPU thread will be primarily controlled by NSPR itself or by
+the user running a function PR_Concurrency().  The details of PR_Concurrency()
+have not yet been worked out; but the idea is that the user can specify to 
+NSPR how many CPU threads are desired.
+
+In this system, user-level threads are created by using PR_CreateThread() and
+specifying the PR_LOCAL_SCOPE option.  LOCAL_SCOPE indicates that the thread
+will be under the control of the "local" scheduler.  Creating threads with
+GLOBAL_SCOPE, on the other hand will create a thread which is under the 
+control of the system's scheduler.  In otherwords, this creates a native thread
+which is not a CPU thread; it runs a single thread task and never has more 
+than one task to run.  LOCAL_SCOPE is much like creating a Solaris unbound 
+thread, while GLOBAL_SCOPE is similar to creating a Solaris bound thread.
+
+To implement this architecture, the source code will still maintain the "user"
+and "native" directories which is has today.  However a third directory 
+"combined" will also exist.  To compile a version of NSPR which only creates
+native threads, the user can define _PR_NTHREAD.  For exclusive user-level
+threads, do not define _PR_NTHREAD.  To get the combined threads, define
+_PR_NTHREAD and _PR_USE_CPUS.
+
+
+Phase 3 - later than next week
+
+The goal is to eliminate the 3 directories.  Once these three models are in
+place, the remaining work will be to eliminate the native and user thread
+directories for all platforms, so that the entire thread model is contained
+within what is today called the "combined" model.  This new and glorious
+source code will attempt to make the "combined" model on any platforms which
+provide the necessary underlying native threading, but will also be 
+capable of using exclusive user-level threads on systems which don't have
+native threads.
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prucpu.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prucpu.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,440 @@
+/* -*- 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"
+
+_PRCPU *_pr_primordialCPU = NULL;
+
+PRInt32 _pr_md_idle_cpus;       /* number of idle cpus */
+/*
+ * The idle threads in MxN models increment/decrement _pr_md_idle_cpus.
+ * If _PR_HAVE_ATOMIC_OPS is not defined, they can't use the atomic
+ * increment/decrement routines (which are based on PR_Lock/PR_Unlock),
+ * because PR_Lock asserts that the calling thread is not an idle thread.
+ * So we use a _MDLock to protect _pr_md_idle_cpus.
+ */
+#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
+#ifndef _PR_HAVE_ATOMIC_OPS
+static _MDLock _pr_md_idle_cpus_lock;
+#endif
+#endif
+PRUintn _pr_numCPU;
+PRInt32 _pr_cpus_exit;
+PRInt32 _pr_cpu_affinity_mask = 0;
+
+#if !defined (_PR_GLOBAL_THREADS_ONLY)
+
+static PRUintn _pr_cpuID;
+
+static void PR_CALLBACK _PR_CPU_Idle(void *);
+
+static _PRCPU *_PR_CreateCPU(void);
+static PRStatus _PR_StartCPU(_PRCPU *cpu, PRThread *thread);
+
+#if !defined(_PR_LOCAL_THREADS_ONLY)
+static void _PR_RunCPU(void *arg);
+#endif
+
+void  _PR_InitCPUs()
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (_native_threads_only)
+        return;
+
+    _pr_cpuID = 0;
+    _MD_NEW_LOCK( &_pr_cpuLock);
+#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
+#ifndef _PR_HAVE_ATOMIC_OPS
+    _MD_NEW_LOCK(&_pr_md_idle_cpus_lock);
+#endif
+#endif
+
+#ifdef _PR_LOCAL_THREADS_ONLY
+
+#ifdef HAVE_CUSTOM_USER_THREADS
+    _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(me);
+#endif
+
+    /* Now start the first CPU. */
+    _pr_primordialCPU = _PR_CreateCPU();
+    _pr_numCPU = 1;
+    _PR_StartCPU(_pr_primordialCPU, me);
+
+    _PR_MD_SET_CURRENT_CPU(_pr_primordialCPU);
+
+    /* Initialize cpu for current thread (could be different from me) */
+    _PR_MD_CURRENT_THREAD()->cpu = _pr_primordialCPU;
+
+    _PR_MD_SET_LAST_THREAD(me);
+
+#else /* Combined MxN model */
+
+    _pr_primordialCPU = _PR_CreateCPU();
+    _pr_numCPU = 1;
+    _PR_CreateThread(PR_SYSTEM_THREAD,
+                     _PR_RunCPU,
+                     _pr_primordialCPU,
+                     PR_PRIORITY_NORMAL,
+                     PR_GLOBAL_THREAD,
+                     PR_UNJOINABLE_THREAD,
+                     0,
+                     _PR_IDLE_THREAD);
+
+#endif /* _PR_LOCAL_THREADS_ONLY */
+
+    _PR_MD_INIT_CPUS();
+}
+
+#ifdef WINNT
+/*
+ * Right now this function merely stops the CPUs and does
+ * not do any other cleanup.
+ *
+ * It is only implemented for WINNT because bug 161998 only
+ * affects the WINNT version of NSPR, but it would be nice
+ * to implement this function for other platforms too.
+ */
+void _PR_CleanupCPUs(void)
+{
+    PRUintn i;
+    PRCList *qp;
+    _PRCPU *cpu;
+
+    _pr_cpus_exit = 1;
+    for (i = 0; i < _pr_numCPU; i++) {
+        _PR_MD_WAKEUP_WAITER(NULL);
+    }
+    for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {
+        cpu = _PR_CPU_PTR(qp);
+        _PR_MD_JOIN_THREAD(&cpu->thread->md);
+    }
+}
+#endif
+
+static _PRCPUQueue *_PR_CreateCPUQueue(void)
+{
+    PRInt32 index;
+    _PRCPUQueue *cpuQueue;
+    cpuQueue = PR_NEWZAP(_PRCPUQueue);
+ 
+    _MD_NEW_LOCK( &cpuQueue->runQLock );
+    _MD_NEW_LOCK( &cpuQueue->sleepQLock );
+    _MD_NEW_LOCK( &cpuQueue->miscQLock );
+
+    for (index = 0; index < PR_PRIORITY_LAST + 1; index++)
+        PR_INIT_CLIST( &(cpuQueue->runQ[index]) );
+    PR_INIT_CLIST( &(cpuQueue->sleepQ) );
+    PR_INIT_CLIST( &(cpuQueue->pauseQ) );
+    PR_INIT_CLIST( &(cpuQueue->suspendQ) );
+    PR_INIT_CLIST( &(cpuQueue->waitingToJoinQ) );
+
+    cpuQueue->numCPUs = 1;
+
+    return cpuQueue;
+}
+
+/*
+ * Create a new CPU.
+ *
+ * This function initializes enough of the _PRCPU structure so
+ * that it can be accessed safely by a global thread or another
+ * CPU.  This function does not create the native thread that
+ * will run the CPU nor does it initialize the parts of _PRCPU
+ * that must be initialized by that native thread.
+ *
+ * The reason we cannot simply have the native thread create
+ * and fully initialize a new CPU is that we need to be able to
+ * create a usable _pr_primordialCPU in _PR_InitCPUs without
+ * assuming that the primordial CPU thread we created can run
+ * during NSPR initialization.  For example, on Windows while
+ * new threads can be created by DllMain, they won't be able
+ * to run during DLL initialization.  If NSPR is initialized
+ * by DllMain, the primordial CPU thread won't run until DLL
+ * initialization is finished.
+ */
+static _PRCPU *_PR_CreateCPU(void)
+{
+    _PRCPU *cpu;
+
+    cpu = PR_NEWZAP(_PRCPU);
+    if (cpu) {
+        cpu->queue = _PR_CreateCPUQueue();
+        if (!cpu->queue) {
+            PR_DELETE(cpu);
+            return NULL;
+        }
+    }
+    return cpu;
+}
+
+/*
+ * Start a new CPU.
+ *
+ * 'cpu' is a _PRCPU structure created by _PR_CreateCPU().
+ * 'thread' is the native thread that will run the CPU.
+ *
+ * If this function fails, 'cpu' is destroyed.
+ */
+static PRStatus _PR_StartCPU(_PRCPU *cpu, PRThread *thread)
+{
+    /*
+    ** Start a new cpu. The assumption this code makes is that the
+    ** underlying operating system creates a stack to go with the new
+    ** native thread. That stack will be used by the cpu when pausing.
+    */
+
+    PR_ASSERT(!_native_threads_only);
+
+    cpu->last_clock = PR_IntervalNow();
+
+    /* Before we create any threads on this CPU we have to
+     * set the current CPU 
+     */
+    _PR_MD_SET_CURRENT_CPU(cpu);
+    _PR_MD_INIT_RUNNING_CPU(cpu);
+    thread->cpu = cpu;
+
+    cpu->idle_thread = _PR_CreateThread(PR_SYSTEM_THREAD,
+                                        _PR_CPU_Idle,
+                                        (void *)cpu,
+                                        PR_PRIORITY_NORMAL,
+                                        PR_LOCAL_THREAD,
+                                        PR_UNJOINABLE_THREAD,
+                                        0,
+                                        _PR_IDLE_THREAD);
+
+    if (!cpu->idle_thread) {
+        /* didn't clean up CPU queue XXXMB */
+        PR_DELETE(cpu);
+        return PR_FAILURE;
+    } 
+    PR_ASSERT(cpu->idle_thread->cpu == cpu);
+
+    cpu->idle_thread->no_sched = 0;
+
+    cpu->thread = thread;
+
+    if (_pr_cpu_affinity_mask)
+        PR_SetThreadAffinityMask(thread, _pr_cpu_affinity_mask);
+
+    /* Created and started a new CPU */
+    _PR_CPU_LIST_LOCK();
+    cpu->id = _pr_cpuID++;
+    PR_APPEND_LINK(&cpu->links, &_PR_CPUQ());
+    _PR_CPU_LIST_UNLOCK();
+
+    return PR_SUCCESS;
+}
+
+#if !defined(_PR_GLOBAL_THREADS_ONLY) && !defined(_PR_LOCAL_THREADS_ONLY)
+/*
+** This code is used during a cpu's initial creation.
+*/
+static void _PR_RunCPU(void *arg)
+{
+    _PRCPU *cpu = (_PRCPU *)arg;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(NULL != me);
+
+    /*
+     * _PR_StartCPU calls _PR_CreateThread to create the
+     * idle thread.  Because _PR_CreateThread calls PR_Lock,
+     * the current thread has to remain a global thread
+     * during the _PR_StartCPU call so that it can wait for
+     * the lock if the lock is held by another thread.  If
+     * we clear the _PR_GLOBAL_SCOPE flag in
+     * _PR_MD_CREATE_PRIMORDIAL_THREAD, the current thread
+     * will be treated as a local thread and have trouble
+     * waiting for the lock because the CPU is not fully
+     * constructed yet.
+     *
+     * After the CPU is started, it is safe to mark the
+     * current thread as a local thread.
+     */
+
+#ifdef HAVE_CUSTOM_USER_THREADS
+    _PR_MD_CREATE_PRIMORDIAL_USER_THREAD(me);
+#endif
+
+    me->no_sched = 1;
+    _PR_StartCPU(cpu, me);
+
+#ifdef HAVE_CUSTOM_USER_THREADS
+    me->flags &= (~_PR_GLOBAL_SCOPE);
+#endif
+
+    _PR_MD_SET_CURRENT_CPU(cpu);
+    _PR_MD_SET_CURRENT_THREAD(cpu->thread);
+    me->cpu = cpu;
+
+    while(1) {
+        PRInt32 is;
+        if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+	    _PR_MD_START_INTERRUPTS();
+        _PR_MD_SWITCH_CONTEXT(me);
+    }
+}
+#endif
+
+static void PR_CALLBACK _PR_CPU_Idle(void *_cpu)
+{
+    _PRCPU *cpu = (_PRCPU *)_cpu;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(NULL != me);
+
+    me->cpu = cpu;
+    cpu->idle_thread = me;
+    if (_MD_LAST_THREAD())
+        _MD_LAST_THREAD()->no_sched = 0;
+    if (!_PR_IS_NATIVE_THREAD(me)) _PR_MD_SET_INTSOFF(0);
+    while(1) {
+        PRInt32 is;
+        PRIntervalTime timeout;
+        if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+
+        _PR_RUNQ_LOCK(cpu);
+#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
+#ifdef _PR_HAVE_ATOMIC_OPS
+        _PR_MD_ATOMIC_INCREMENT(&_pr_md_idle_cpus);
+#else
+        _PR_MD_LOCK(&_pr_md_idle_cpus_lock);
+        _pr_md_idle_cpus++;
+        _PR_MD_UNLOCK(&_pr_md_idle_cpus_lock);
+#endif /* _PR_HAVE_ATOMIC_OPS */
+#endif
+        /* If someone on runq; do a nonblocking PAUSECPU */
+        if (_PR_RUNQREADYMASK(me->cpu) != 0) {
+            _PR_RUNQ_UNLOCK(cpu);
+            timeout = PR_INTERVAL_NO_WAIT;
+        } else {
+            _PR_RUNQ_UNLOCK(cpu);
+
+            _PR_SLEEPQ_LOCK(cpu);
+            if (PR_CLIST_IS_EMPTY(&_PR_SLEEPQ(me->cpu))) {
+                timeout = PR_INTERVAL_NO_TIMEOUT;
+            } else {
+                PRThread *wakeThread;
+                wakeThread = _PR_THREAD_PTR(_PR_SLEEPQ(me->cpu).next);
+                timeout = wakeThread->sleep;
+            }
+            _PR_SLEEPQ_UNLOCK(cpu);
+        }
+
+        /* Wait for an IO to complete */
+        (void)_PR_MD_PAUSE_CPU(timeout);
+
+#ifdef WINNT
+        if (_pr_cpus_exit) {
+            /* _PR_CleanupCPUs tells us to exit */
+            _PR_MD_END_THREAD();
+        }
+#endif
+
+#if !defined(_PR_LOCAL_THREADS_ONLY) && !defined(_PR_GLOBAL_THREADS_ONLY)
+#ifdef _PR_HAVE_ATOMIC_OPS
+        _PR_MD_ATOMIC_DECREMENT(&_pr_md_idle_cpus);
+#else
+        _PR_MD_LOCK(&_pr_md_idle_cpus_lock);
+        _pr_md_idle_cpus--;
+        _PR_MD_UNLOCK(&_pr_md_idle_cpus_lock);
+#endif /* _PR_HAVE_ATOMIC_OPS */
+#endif
+
+		_PR_ClockInterrupt();
+
+		/* Now schedule any thread that is on the runq
+		 * INTS must be OFF when calling PR_Schedule()
+		 */
+		me->state = _PR_RUNNABLE;
+		_PR_MD_SWITCH_CONTEXT(me);
+		if (!_PR_IS_NATIVE_THREAD(me)) _PR_FAST_INTSON(is);
+    }
+}
+#endif /* _PR_GLOBAL_THREADS_ONLY */
+
+PR_IMPLEMENT(void) PR_SetConcurrency(PRUintn numCPUs)
+{
+#if defined(_PR_GLOBAL_THREADS_ONLY) || defined(_PR_LOCAL_THREADS_ONLY)
+#ifdef XP_MAC 
+#pragma unused(numCPUs) 
+#endif
+
+    /* do nothing */
+
+#else /* combined, MxN thread model */
+
+    PRUintn newCPU;
+    _PRCPU *cpu;
+    PRThread *thr;
+
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+	if (_native_threads_only)
+		return;
+    
+    _PR_CPU_LIST_LOCK();
+    if (_pr_numCPU < numCPUs) {
+        newCPU = numCPUs - _pr_numCPU;
+        _pr_numCPU = numCPUs;
+    } else newCPU = 0;
+    _PR_CPU_LIST_UNLOCK();
+
+    for (; newCPU; newCPU--) {
+        cpu = _PR_CreateCPU();
+        thr = _PR_CreateThread(PR_SYSTEM_THREAD,
+                              _PR_RunCPU,
+                              cpu,
+                              PR_PRIORITY_NORMAL,
+                              PR_GLOBAL_THREAD,
+                              PR_UNJOINABLE_THREAD,
+                              0,
+                              _PR_IDLE_THREAD);
+    }
+#endif
+}
+
+PR_IMPLEMENT(_PRCPU *) _PR_GetPrimordialCPU(void)
+{
+    if (_pr_primordialCPU)
+        return _pr_primordialCPU;
+    else
+        return _PR_MD_CURRENT_CPU();
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prucv.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prucv.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,681 @@
+/* -*- 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 "prinrval.h"
+#include "prtypes.h"
+
+#if defined(WIN95)
+/*
+** Some local variables report warnings on Win95 because the code paths 
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+** 
+*/
+#pragma warning(disable : 4101)
+#endif
+
+
+/*
+** Notify one thread that it has finished waiting on a condition variable
+** Caller must hold the _PR_CVAR_LOCK(cv)
+*/
+PRBool _PR_NotifyThread (PRThread *thread, PRThread *me)
+{
+    PRBool rv;
+
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
+
+    _PR_THREAD_LOCK(thread);
+    PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+    if ( !_PR_IS_NATIVE_THREAD(thread) ) {
+        if (thread->wait.cvar != NULL) {
+            thread->wait.cvar = NULL;
+
+            _PR_SLEEPQ_LOCK(thread->cpu);
+            /* The notify and timeout can collide; in which case both may
+             * attempt to delete from the sleepQ; only let one do it.
+             */
+            if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ))
+                _PR_DEL_SLEEPQ(thread, PR_TRUE);
+            _PR_SLEEPQ_UNLOCK(thread->cpu);
+
+	    if (thread->flags & _PR_SUSPENDING) {
+		/*
+		 * set thread state to SUSPENDED; a Resume operation
+		 * on the thread will move it to the runQ
+		 */
+            	thread->state = _PR_SUSPENDED;
+		_PR_MISCQ_LOCK(thread->cpu);
+		_PR_ADD_SUSPENDQ(thread, thread->cpu);
+		_PR_MISCQ_UNLOCK(thread->cpu);
+            	_PR_THREAD_UNLOCK(thread);
+	    } else {
+            	/* Make thread runnable */
+            	thread->state = _PR_RUNNABLE;
+            	_PR_THREAD_UNLOCK(thread);
+
+                _PR_AddThreadToRunQ(me, thread);
+                _PR_MD_WAKEUP_WAITER(thread);
+            }
+
+            rv = PR_TRUE;
+        } else {
+            /* Thread has already been notified */
+            _PR_THREAD_UNLOCK(thread);
+            rv = PR_FALSE;
+        }
+    } else { /* If the thread is a native thread */
+        if (thread->wait.cvar) {
+            thread->wait.cvar = NULL;
+
+	    if (thread->flags & _PR_SUSPENDING) {
+		/*
+		 * set thread state to SUSPENDED; a Resume operation
+		 * on the thread will enable the thread to run
+		 */
+            	thread->state = _PR_SUSPENDED;
+	     } else
+            	thread->state = _PR_RUNNING;
+            _PR_THREAD_UNLOCK(thread);
+            _PR_MD_WAKEUP_WAITER(thread);
+            rv = PR_TRUE;
+        } else {
+            _PR_THREAD_UNLOCK(thread);
+            rv = PR_FALSE;
+        }    
+    }    
+
+    return rv;
+}
+
+/*
+ * Notify thread waiting on cvar; called when thread is interrupted
+ * 	The thread lock is held on entry and released before return
+ */
+void _PR_NotifyLockedThread (PRThread *thread)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRCondVar *cvar;
+    PRThreadPriority pri;
+
+    if ( !_PR_IS_NATIVE_THREAD(me))
+    	PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
+
+    cvar = thread->wait.cvar;
+    thread->wait.cvar = NULL;
+    _PR_THREAD_UNLOCK(thread);
+
+    _PR_CVAR_LOCK(cvar);
+    _PR_THREAD_LOCK(thread);
+
+    if (!_PR_IS_NATIVE_THREAD(thread)) {
+            _PR_SLEEPQ_LOCK(thread->cpu);
+            /* The notify and timeout can collide; in which case both may
+             * attempt to delete from the sleepQ; only let one do it.
+             */
+            if (thread->flags & (_PR_ON_SLEEPQ|_PR_ON_PAUSEQ))
+                _PR_DEL_SLEEPQ(thread, PR_TRUE);
+            _PR_SLEEPQ_UNLOCK(thread->cpu);
+
+	    /* Make thread runnable */
+	    pri = thread->priority;
+	    thread->state = _PR_RUNNABLE;
+
+	    PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+
+            _PR_AddThreadToRunQ(me, thread);
+            _PR_THREAD_UNLOCK(thread);
+
+            _PR_MD_WAKEUP_WAITER(thread);
+    } else {
+	    if (thread->flags & _PR_SUSPENDING) {
+		/*
+		 * set thread state to SUSPENDED; a Resume operation
+		 * on the thread will enable the thread to run
+		 */
+            	thread->state = _PR_SUSPENDED;
+	     } else
+            	thread->state = _PR_RUNNING;
+            _PR_THREAD_UNLOCK(thread);
+            _PR_MD_WAKEUP_WAITER(thread);
+    }    
+
+    _PR_CVAR_UNLOCK(cvar);
+    return;
+}
+
+/*
+** Make the given thread wait for the given condition variable
+*/
+PRStatus _PR_WaitCondVar(
+    PRThread *thread, PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout)
+{
+    PRIntn is;
+    PRStatus rv = PR_SUCCESS;
+
+    PR_ASSERT(thread == _PR_MD_CURRENT_THREAD());
+    PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    if (_PR_PENDING_INTERRUPT(thread)) {
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        thread->flags &= ~_PR_INTERRUPT;
+        return PR_FAILURE;
+    }
+
+    thread->wait.cvar = cvar;
+    lock->owner = NULL;
+    _PR_MD_WAIT_CV(&cvar->md,&lock->ilock, timeout);
+    thread->wait.cvar = NULL;
+    lock->owner = thread;
+    if (_PR_PENDING_INTERRUPT(thread)) {
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        thread->flags &= ~_PR_INTERRUPT;
+        return PR_FAILURE;
+    }
+
+    return PR_SUCCESS;
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+
+    if ( !_PR_IS_NATIVE_THREAD(thread))
+    	_PR_INTSOFF(is);
+
+    _PR_CVAR_LOCK(cvar);
+    _PR_THREAD_LOCK(thread);
+
+    if (_PR_PENDING_INTERRUPT(thread)) {
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        thread->flags &= ~_PR_INTERRUPT;
+    	_PR_CVAR_UNLOCK(cvar);
+    	_PR_THREAD_UNLOCK(thread);
+    	if ( !_PR_IS_NATIVE_THREAD(thread))
+    		_PR_INTSON(is);
+        return PR_FAILURE;
+    }
+
+    thread->state = _PR_COND_WAIT;
+    thread->wait.cvar = cvar;
+
+    /*
+    ** Put the caller thread on the condition variable's wait Q
+    */
+    PR_APPEND_LINK(&thread->waitQLinks, &cvar->condQ);
+
+    /* Note- for global scope threads, we don't put them on the
+     *       global sleepQ, so each global thread must put itself
+     *       to sleep only for the time it wants to.
+     */
+    if ( !_PR_IS_NATIVE_THREAD(thread) ) {
+        _PR_SLEEPQ_LOCK(thread->cpu);
+        _PR_ADD_SLEEPQ(thread, timeout);
+        _PR_SLEEPQ_UNLOCK(thread->cpu);
+    }
+    _PR_CVAR_UNLOCK(cvar);
+    _PR_THREAD_UNLOCK(thread);
+   
+    /* 
+    ** Release lock protecting the condition variable and thereby giving time 
+    ** to the next thread which can potentially notify on the condition variable
+    */
+    PR_Unlock(lock);
+
+    PR_LOG(_pr_cvar_lm, PR_LOG_MIN,
+	   ("PR_Wait: cvar=%p waiting for %d", cvar, timeout));
+
+    rv = _PR_MD_WAIT(thread, timeout);
+
+    _PR_CVAR_LOCK(cvar);
+    PR_REMOVE_LINK(&thread->waitQLinks);
+    _PR_CVAR_UNLOCK(cvar);
+
+    PR_LOG(_pr_cvar_lm, PR_LOG_MIN,
+	   ("PR_Wait: cvar=%p done waiting", cvar));
+
+    if ( !_PR_IS_NATIVE_THREAD(thread))
+    	_PR_INTSON(is);
+
+    /* Acquire lock again that we had just relinquished */
+    PR_Lock(lock);
+
+    if (_PR_PENDING_INTERRUPT(thread)) {
+        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
+        thread->flags &= ~_PR_INTERRUPT;
+        return PR_FAILURE;
+    }
+
+    return rv;
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+void _PR_NotifyCondVar(PRCondVar *cvar, PRThread *me)
+{
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    _PR_MD_NOTIFY_CV(&cvar->md, &cvar->lock->ilock);
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+
+    PRCList *q;
+    PRIntn is;
+
+    if ( !_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSOFF(is);
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
+
+    _PR_CVAR_LOCK(cvar);
+    q = cvar->condQ.next;
+    while (q != &cvar->condQ) {
+#ifndef XP_MAC
+        PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("_PR_NotifyCondVar: cvar=%p", cvar));
+#endif
+        if (_PR_THREAD_CONDQ_PTR(q)->wait.cvar)  {
+            if (_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me) == PR_TRUE)
+                break;
+        }
+        q = q->next;
+    }
+    _PR_CVAR_UNLOCK(cvar);
+
+    if ( !_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSON(is);
+
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+/*
+** Cndition variable debugging log info.
+*/
+PRUint32 _PR_CondVarToString(PRCondVar *cvar, char *buf, PRUint32 buflen)
+{
+    PRUint32 nb;
+
+    if (cvar->lock->owner) {
+	nb = PR_snprintf(buf, buflen, "[%p] owner=%ld[%p]",
+			 cvar, cvar->lock->owner->id, cvar->lock->owner);
+    } else {
+	nb = PR_snprintf(buf, buflen, "[%p]", cvar);
+    }
+    return nb;
+}
+
+/*
+** Expire condition variable waits that are ready to expire. "now" is the current
+** time.
+*/
+void _PR_ClockInterrupt(void)
+{
+    PRThread *thread, *me = _PR_MD_CURRENT_THREAD();
+    _PRCPU *cpu = me->cpu;
+    PRIntervalTime elapsed, now;
+ 
+    PR_ASSERT(_PR_MD_GET_INTSOFF() != 0);
+    /* Figure out how much time elapsed since the last clock tick */
+    now = PR_IntervalNow();
+    elapsed = now - cpu->last_clock;
+    cpu->last_clock = now;
+
+#ifndef XP_MAC
+    PR_LOG(_pr_clock_lm, PR_LOG_MAX,
+	   ("ExpireWaits: elapsed=%lld usec", elapsed));
+#endif
+
+    while(1) {
+        _PR_SLEEPQ_LOCK(cpu);
+        if (_PR_SLEEPQ(cpu).next == &_PR_SLEEPQ(cpu)) {
+            _PR_SLEEPQ_UNLOCK(cpu);
+            break;
+        }
+
+        thread = _PR_THREAD_PTR(_PR_SLEEPQ(cpu).next);
+        PR_ASSERT(thread->cpu == cpu);
+
+        if (elapsed < thread->sleep) {
+            thread->sleep -= elapsed;
+            _PR_SLEEPQMAX(thread->cpu) -= elapsed;
+            _PR_SLEEPQ_UNLOCK(cpu);
+            break;
+        }
+        _PR_SLEEPQ_UNLOCK(cpu);
+
+        PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread));
+
+        _PR_THREAD_LOCK(thread);
+
+        if (thread->cpu != cpu) {
+            /*
+            ** The thread was switched to another CPU
+            ** between the time we unlocked the sleep
+            ** queue and the time we acquired the thread
+            ** lock, so it is none of our business now.
+            */
+            _PR_THREAD_UNLOCK(thread);
+            continue;
+        }
+
+        /*
+        ** Consume this sleeper's amount of elapsed time from the elapsed
+        ** time value. The next remaining piece of elapsed time will be
+        ** available for the next sleeping thread's timer.
+        */
+        _PR_SLEEPQ_LOCK(cpu);
+        PR_ASSERT(!(thread->flags & _PR_ON_PAUSEQ));
+        if (thread->flags & _PR_ON_SLEEPQ) {
+            _PR_DEL_SLEEPQ(thread, PR_FALSE);
+            elapsed -= thread->sleep;
+            _PR_SLEEPQ_UNLOCK(cpu);
+        } else {
+            /* Thread was already handled; Go get another one */
+            _PR_SLEEPQ_UNLOCK(cpu);
+            _PR_THREAD_UNLOCK(thread);
+            continue;
+        }
+
+        /* Notify the thread waiting on the condition variable */
+        if (thread->flags & _PR_SUSPENDING) {
+		PR_ASSERT((thread->state == _PR_IO_WAIT) ||
+				(thread->state == _PR_COND_WAIT));
+            /*
+            ** Thread is suspended and its condition timeout
+            ** expired. Transfer thread from sleepQ to suspendQ.
+            */
+            thread->wait.cvar = NULL;
+            _PR_MISCQ_LOCK(cpu);
+            thread->state = _PR_SUSPENDED;
+            _PR_ADD_SUSPENDQ(thread, cpu);
+            _PR_MISCQ_UNLOCK(cpu);
+        } else {
+            if (thread->wait.cvar) {
+                PRThreadPriority pri;
+
+                /* Do work very similar to what _PR_NotifyThread does */
+                PR_ASSERT( !_PR_IS_NATIVE_THREAD(thread) );
+
+                /* Make thread runnable */
+                pri = thread->priority;
+                thread->state = _PR_RUNNABLE;
+                PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+
+                PR_ASSERT(thread->cpu == cpu);
+                _PR_RUNQ_LOCK(cpu);
+                _PR_ADD_RUNQ(thread, cpu, pri);
+                _PR_RUNQ_UNLOCK(cpu);
+
+                if (pri > me->priority)
+                    _PR_SET_RESCHED_FLAG();
+
+                thread->wait.cvar = NULL;
+
+                _PR_MD_WAKEUP_WAITER(thread);
+
+            } else if (thread->io_pending == PR_TRUE) {
+                /* Need to put IO sleeper back on runq */
+                int pri = thread->priority;
+
+                thread->io_suspended = PR_TRUE;
+#ifdef WINNT
+				/*
+				 * For NT, record the cpu on which I/O was issued
+				 * I/O cancellation is done on the same cpu
+				 */
+                thread->md.thr_bound_cpu = cpu;
+#endif
+
+				PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+                PR_ASSERT(thread->cpu == cpu);
+                thread->state = _PR_RUNNABLE;
+                _PR_RUNQ_LOCK(cpu);
+                _PR_ADD_RUNQ(thread, cpu, pri);
+                _PR_RUNQ_UNLOCK(cpu);
+            }
+        }
+        _PR_THREAD_UNLOCK(thread);
+    }
+}
+
+/************************************************************************/
+
+/*
+** Create a new condition variable.
+** 	"lock" is the lock to use with the condition variable.
+**
+** Condition variables are synchronization objects that threads can use
+** to wait for some condition to occur.
+**
+** This may fail if memory is tight or if some operating system resource
+** is low.
+*/
+PR_IMPLEMENT(PRCondVar*) PR_NewCondVar(PRLock *lock)
+{
+    PRCondVar *cvar;
+
+    PR_ASSERT(lock != NULL);
+
+    cvar = PR_NEWZAP(PRCondVar);
+    if (cvar) {
+#ifdef _PR_GLOBAL_THREADS_ONLY
+	if(_PR_MD_NEW_CV(&cvar->md)) {
+		PR_DELETE(cvar);
+		PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+		return NULL;
+	}
+#endif
+        if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE) {
+		PR_DELETE(cvar);
+		PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+		return NULL;
+	}
+    cvar->lock = lock;
+	PR_INIT_CLIST(&cvar->condQ);
+
+    } else {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+    }
+    return cvar;
+}
+
+/*
+** Destroy a condition variable. There must be no thread
+** waiting on the condvar. The caller is responsible for guaranteeing
+** that the condvar is no longer in use.
+**
+*/
+PR_IMPLEMENT(void) PR_DestroyCondVar(PRCondVar *cvar)
+{
+    PR_ASSERT(cvar->condQ.next == &cvar->condQ);
+
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    _PR_MD_FREE_CV(&cvar->md);
+#endif
+    _PR_MD_FREE_LOCK(&(cvar->ilock));
+ 
+    PR_DELETE(cvar);
+}
+
+/*
+** Wait for a notify on the condition variable. Sleep for "tiemout" amount
+** of ticks (if "timeout" is zero then the sleep is indefinite). While
+** the thread is waiting it unlocks lock. When the wait has
+** finished the thread regains control of the condition variable after
+** locking the associated lock.
+**
+** The thread waiting on the condvar will be resumed when the condvar is
+** notified (assuming the thread is the next in line to receive the
+** notify) or when the timeout elapses.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable or the thread has been interrupted.
+*/
+extern PRThread *suspendAllThread;
+PR_IMPLEMENT(PRStatus) PR_WaitCondVar(PRCondVar *cvar, PRIntervalTime timeout)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	PR_ASSERT(cvar->lock->owner == me);
+	PR_ASSERT(me != suspendAllThread);
+    	if (cvar->lock->owner != me) return PR_FAILURE;
+
+	return _PR_WaitCondVar(me, cvar, cvar->lock, timeout);
+}
+
+/*
+** Notify the highest priority thread waiting on the condition
+** variable. If a thread is waiting on the condition variable (using
+** PR_Wait) then it is awakened and begins waiting on the lock.
+*/
+PR_IMPLEMENT(PRStatus) PR_NotifyCondVar(PRCondVar *cvar)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(cvar->lock->owner == me);
+    PR_ASSERT(me != suspendAllThread);
+    if (cvar->lock->owner != me) return PR_FAILURE;
+
+    _PR_NotifyCondVar(cvar, me);
+    return PR_SUCCESS;
+}
+
+/*
+** Notify all of the threads waiting on the condition variable. All of
+** threads are notified in turn. The highest priority thread will
+** probably acquire the lock.
+*/
+PR_IMPLEMENT(PRStatus) PR_NotifyAllCondVar(PRCondVar *cvar)
+{
+    PRCList *q;
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(cvar->lock->owner == me);
+    if (cvar->lock->owner != me) return PR_FAILURE;
+
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    _PR_MD_NOTIFYALL_CV(&cvar->md, &cvar->lock->ilock);
+    return PR_SUCCESS;
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+    if ( !_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSOFF(is);
+    _PR_CVAR_LOCK(cvar);
+    q = cvar->condQ.next;
+    while (q != &cvar->condQ) {
+		PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar));
+		_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
+		q = q->next;
+    }
+    _PR_CVAR_UNLOCK(cvar);
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSON(is);
+
+    return PR_SUCCESS;
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+
+/*********************************************************************/
+/*********************************************************************/
+/********************ROUTINES FOR DCE EMULATION***********************/
+/*********************************************************************/
+/*********************************************************************/
+#include "prpdce.h"
+
+PR_IMPLEMENT(PRCondVar*) PRP_NewNakedCondVar(void)
+{
+    PRCondVar *cvar = PR_NEWZAP(PRCondVar);
+    if (NULL != cvar)
+    {
+        if (_PR_MD_NEW_LOCK(&(cvar->ilock)) == PR_FAILURE)
+        {
+		    PR_DELETE(cvar); cvar = NULL;
+	    }
+	    else
+	    {
+	        PR_INIT_CLIST(&cvar->condQ);
+            cvar->lock = _PR_NAKED_CV_LOCK;
+	    }
+
+    }
+    return cvar;
+}
+
+PR_IMPLEMENT(void) PRP_DestroyNakedCondVar(PRCondVar *cvar)
+{
+    PR_ASSERT(cvar->condQ.next == &cvar->condQ);
+    PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
+
+    _PR_MD_FREE_LOCK(&(cvar->ilock));
+ 
+    PR_DELETE(cvar);
+}
+
+PR_IMPLEMENT(PRStatus) PRP_NakedWait(
+	PRCondVar *cvar, PRLock *lock, PRIntervalTime timeout)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
+	return _PR_WaitCondVar(me, cvar, lock, timeout);
+}  /* PRP_NakedWait */
+
+PR_IMPLEMENT(PRStatus) PRP_NakedNotify(PRCondVar *cvar)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
+
+    _PR_NotifyCondVar(cvar, me);
+
+    return PR_SUCCESS;
+}  /* PRP_NakedNotify */
+
+PR_IMPLEMENT(PRStatus) PRP_NakedBroadcast(PRCondVar *cvar)
+{
+    PRCList *q;
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PR_ASSERT(_PR_NAKED_CV_LOCK == cvar->lock);
+
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+	_PR_MD_LOCK( &(cvar->ilock) );
+    q = cvar->condQ.next;
+    while (q != &cvar->condQ) {
+		PR_LOG(_pr_cvar_lm, PR_LOG_MIN, ("PR_NotifyAll: cvar=%p", cvar));
+		_PR_NotifyThread(_PR_THREAD_CONDQ_PTR(q), me);
+		q = q->next;
+    }
+	_PR_MD_UNLOCK( &(cvar->ilock) );
+    if (!_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
+
+    return PR_SUCCESS;
+}  /* PRP_NakedBroadcast */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prulock.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prulock.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,463 @@
+/* -*- 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"
+
+#if defined(WIN95)
+/*
+** Some local variables report warnings on Win95 because the code paths 
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+** 
+*/
+#pragma warning(disable : 4101)
+#endif
+
+
+void _PR_InitLocks(void)
+{
+	_PR_MD_INIT_LOCKS();
+}
+
+/*
+** Deal with delayed interrupts/requested reschedule during interrupt
+** re-enables.
+*/
+void _PR_IntsOn(_PRCPU *cpu)
+{
+    PRUintn missed, pri, i;
+    _PRInterruptTable *it;
+    PRThread *me;
+
+    PR_ASSERT(cpu);   /* Global threads don't have CPUs */
+    PR_ASSERT(_PR_MD_GET_INTSOFF() > 0);
+	me = _PR_MD_CURRENT_THREAD();
+#if !defined(XP_MAC)
+    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD));
+#endif
+
+    /*
+    ** Process delayed interrupts. This logic is kinda scary because we
+    ** need to avoid losing an interrupt (it's ok to delay an interrupt
+    ** until later).
+    **
+    ** There are two missed state words. _pr_ints.where indicates to the
+    ** interrupt handler which state word is currently safe for
+    ** modification.
+    **
+    ** This code scans both interrupt state words, using the where flag
+    ** to indicate to the interrupt which state word is safe for writing.
+    ** If an interrupt comes in during a scan the other word will be
+    ** modified. This modification will be noticed during the next
+    ** iteration of the loop or during the next call to this routine.
+    */
+    for (i = 0; i < 2; i++) {
+        cpu->where = (1 - i);
+        missed = cpu->u.missed[i];
+        if (missed != 0) {
+            cpu->u.missed[i] = 0;
+            for (it = _pr_interruptTable; it->name; it++) {
+                if (missed & it->missed_bit) {
+#ifndef XP_MAC
+                    PR_LOG(_pr_sched_lm, PR_LOG_MIN,
+                           ("IntsOn[0]: %s intr", it->name));
+#endif
+                    (*it->handler)();
+                }
+            }
+        }
+    }
+
+    if (cpu->u.missed[3] != 0) {
+        _PRCPU *cpu;
+
+		_PR_THREAD_LOCK(me);
+        me->state = _PR_RUNNABLE;
+        pri = me->priority;
+
+        cpu = me->cpu;
+		_PR_RUNQ_LOCK(cpu);
+        _PR_ADD_RUNQ(me, cpu, pri);
+		_PR_RUNQ_UNLOCK(cpu);
+		_PR_THREAD_UNLOCK(me);
+        _PR_MD_SWITCH_CONTEXT(me);
+    }
+}
+
+/*
+** Unblock the first runnable waiting thread. Skip over
+** threads that are trying to be suspended
+** Note: Caller must hold _PR_LOCK_LOCK()
+*/
+void _PR_UnblockLockWaiter(PRLock *lock)
+{
+    PRThread *t = NULL;
+    PRThread *me;
+    PRCList *q;
+
+    q = lock->waitQ.next;
+    PR_ASSERT(q != &lock->waitQ);
+    while (q != &lock->waitQ) {
+        /* Unblock first waiter */
+        t = _PR_THREAD_CONDQ_PTR(q);
+
+		/* 
+		** We are about to change the thread's state to runnable and for local
+		** threads, we are going to assign a cpu to it.  So, protect thread's
+		** data structure.
+		*/
+        _PR_THREAD_LOCK(t);
+
+        if (t->flags & _PR_SUSPENDING) {
+            q = q->next;
+            _PR_THREAD_UNLOCK(t);
+            continue;
+        }
+
+        /* Found a runnable thread */
+	    PR_ASSERT(t->state == _PR_LOCK_WAIT);
+	    PR_ASSERT(t->wait.lock == lock);
+        t->wait.lock = 0;
+        PR_REMOVE_LINK(&t->waitQLinks);         /* take it off lock's waitQ */
+
+		/*
+		** If this is a native thread, nothing else to do except to wake it
+		** up by calling the machine dependent wakeup routine.
+		**
+		** If this is a local thread, we need to assign it a cpu and
+		** put the thread on that cpu's run queue.  There are two cases to
+		** take care of.  If the currently running thread is also a local
+		** thread, we just assign our own cpu to that thread and put it on
+		** the cpu's run queue.  If the the currently running thread is a
+		** native thread, we assign the primordial cpu to it (on NT,
+		** MD_WAKEUP handles the cpu assignment).  
+		*/
+		
+        if ( !_PR_IS_NATIVE_THREAD(t) ) {
+
+            t->state = _PR_RUNNABLE;
+
+            me = _PR_MD_CURRENT_THREAD();
+
+            _PR_AddThreadToRunQ(me, t);
+            _PR_THREAD_UNLOCK(t);
+        } else {
+            t->state = _PR_RUNNING;
+            _PR_THREAD_UNLOCK(t);
+        }
+        _PR_MD_WAKEUP_WAITER(t);
+        break;
+    }
+    return;
+}
+
+/************************************************************************/
+
+
+PR_IMPLEMENT(PRLock*) PR_NewLock(void)
+{
+    PRLock *lock;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    lock = PR_NEWZAP(PRLock);
+    if (lock) {
+        if (_PR_MD_NEW_LOCK(&lock->ilock) == PR_FAILURE) {
+		PR_DELETE(lock);
+		return(NULL);
+	}
+        PR_INIT_CLIST(&lock->links);
+        PR_INIT_CLIST(&lock->waitQ);
+    }
+    return lock;
+}
+
+/*
+** Destroy the given lock "lock". There is no point in making this race
+** free because if some other thread has the pointer to this lock all
+** bets are off.
+*/
+PR_IMPLEMENT(void) PR_DestroyLock(PRLock *lock)
+{
+    PR_ASSERT(lock->owner == 0);
+	_PR_MD_FREE_LOCK(&lock->ilock);
+    PR_DELETE(lock);
+}
+
+extern PRThread *suspendAllThread;
+/*
+** Lock the lock.
+*/
+PR_IMPLEMENT(void) PR_Lock(PRLock *lock)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntn is;
+    PRThread *t;
+    PRCList *q;
+
+    PR_ASSERT(me != suspendAllThread); 
+#if !defined(XP_MAC)
+    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD));
+#endif
+    PR_ASSERT(lock != NULL);
+#ifdef _PR_GLOBAL_THREADS_ONLY 
+    PR_ASSERT(lock->owner != me);
+    _PR_MD_LOCK(&lock->ilock);
+    lock->owner = me;
+    return;
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+
+	if (_native_threads_only) {
+		PR_ASSERT(lock->owner != me);
+		_PR_MD_LOCK(&lock->ilock);
+		lock->owner = me;
+		return;
+	}
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSOFF(is);
+
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
+
+retry:
+    _PR_LOCK_LOCK(lock);
+    if (lock->owner == 0) {
+        /* Just got the lock */
+        lock->owner = me;
+        lock->priority = me->priority;
+		/* Add the granted lock to this owning thread's lock list */
+        PR_APPEND_LINK(&lock->links, &me->lockList);
+        _PR_LOCK_UNLOCK(lock);
+    	if (!_PR_IS_NATIVE_THREAD(me))
+        	_PR_FAST_INTSON(is);
+        return;
+    }
+
+    /* If this thread already owns this lock, then it is a deadlock */
+    PR_ASSERT(lock->owner != me);
+
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
+
+#if 0
+    if (me->priority > lock->owner->priority) {
+        /*
+        ** Give the lock owner a priority boost until we get the
+        ** lock. Record the priority we boosted it to.
+        */
+        lock->boostPriority = me->priority;
+        _PR_SetThreadPriority(lock->owner, me->priority);
+    }
+#endif
+
+    /* 
+    Add this thread to the asked for lock's list of waiting threads.  We
+    add this thread thread in the right priority order so when the unlock
+    occurs, the thread with the higher priority will get the lock.
+    */
+    q = lock->waitQ.next;
+    if (q == &lock->waitQ || _PR_THREAD_CONDQ_PTR(q)->priority ==
+      	_PR_THREAD_CONDQ_PTR(lock->waitQ.prev)->priority) {
+		/*
+		 * If all the threads in the lock waitQ have the same priority,
+		 * then avoid scanning the list:  insert the element at the end.
+		 */
+		q = &lock->waitQ;
+    } else {
+		/* Sort thread into lock's waitQ at appropriate point */
+		/* Now scan the list for where to insert this entry */
+		while (q != &lock->waitQ) {
+			t = _PR_THREAD_CONDQ_PTR(lock->waitQ.next);
+			if (me->priority > t->priority) {
+				/* Found a lower priority thread to insert in front of */
+				break;
+			}
+			q = q->next;
+		}
+	}
+    PR_INSERT_BEFORE(&me->waitQLinks, q);
+
+	/* 
+	Now grab the threadLock since we are about to change the state.  We have
+	to do this since a PR_Suspend or PR_SetThreadPriority type call that takes
+	a PRThread* as an argument could be changing the state of this thread from
+	a thread running on a different cpu.
+	*/
+
+    _PR_THREAD_LOCK(me);
+    me->state = _PR_LOCK_WAIT;
+    me->wait.lock = lock;
+    _PR_THREAD_UNLOCK(me);
+
+    _PR_LOCK_UNLOCK(lock);
+
+    _PR_MD_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+	goto retry;
+
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+/*
+** Unlock the lock.
+*/
+PR_IMPLEMENT(PRStatus) PR_Unlock(PRLock *lock)
+{
+    PRCList *q;
+    PRThreadPriority pri, boost;
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(lock != NULL);
+    PR_ASSERT(lock->owner == me);
+    PR_ASSERT(me != suspendAllThread); 
+#if !defined(XP_MAC)
+    PR_ASSERT(!(me->flags & _PR_IDLE_THREAD));
+#endif
+    if (lock->owner != me) {
+        return PR_FAILURE;
+    }
+
+#ifdef _PR_GLOBAL_THREADS_ONLY 
+    lock->owner = 0;
+    _PR_MD_UNLOCK(&lock->ilock);
+    return PR_SUCCESS;
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+
+	if (_native_threads_only) {
+		lock->owner = 0;
+		_PR_MD_UNLOCK(&lock->ilock);
+		return PR_SUCCESS;
+	}
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSOFF(is);
+    _PR_LOCK_LOCK(lock);
+
+	/* Remove the lock from the owning thread's lock list */
+    PR_REMOVE_LINK(&lock->links);
+    pri = lock->priority;
+    boost = lock->boostPriority;
+    if (boost > pri) {
+        /*
+        ** We received a priority boost during the time we held the lock.
+        ** We need to figure out what priority to move to by scanning
+        ** down our list of lock's that we are still holding and using
+        ** the highest boosted priority found.
+        */
+        q = me->lockList.next;
+        while (q != &me->lockList) {
+            PRLock *ll = _PR_LOCK_PTR(q);
+            if (ll->boostPriority > pri) {
+                pri = ll->boostPriority;
+            }
+            q = q->next;
+        }
+        if (pri != me->priority) {
+            _PR_SetThreadPriority(me, pri);
+        }
+    }
+
+    /* Unblock the first waiting thread */
+    q = lock->waitQ.next;
+    if (q != &lock->waitQ)
+        _PR_UnblockLockWaiter(lock);
+    lock->boostPriority = PR_PRIORITY_LOW;
+    lock->owner = 0;
+    _PR_LOCK_UNLOCK(lock);
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSON(is);
+    return PR_SUCCESS;
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+/*
+** Test and then lock the lock if it's not already locked by some other
+** thread. Return PR_FALSE if some other thread owned the lock at the
+** time of the call.
+*/
+PR_IMPLEMENT(PRBool) PR_TestAndLock(PRLock *lock)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRBool rv = PR_FALSE;
+    PRIntn is;
+
+#ifdef _PR_GLOBAL_THREADS_ONLY 
+    is = _PR_MD_TEST_AND_LOCK(&lock->ilock);
+    if (is == 0) {
+        lock->owner = me;
+        return PR_TRUE;
+    }
+    return PR_FALSE;
+#else  /* _PR_GLOBAL_THREADS_ONLY */
+
+#ifndef _PR_LOCAL_THREADS_ONLY
+	if (_native_threads_only) {
+		is = _PR_MD_TEST_AND_LOCK(&lock->ilock);
+		if (is == 0) {
+			lock->owner = me;
+			return PR_TRUE;
+		}
+    	return PR_FALSE;
+	}
+#endif
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSOFF(is);
+
+    _PR_LOCK_LOCK(lock);
+    if (lock->owner == 0) {
+        /* Just got the lock */
+        lock->owner = me;
+        lock->priority = me->priority;
+		/* Add the granted lock to this owning thread's lock list */
+        PR_APPEND_LINK(&lock->links, &me->lockList);
+        rv = PR_TRUE;
+    }
+    _PR_LOCK_UNLOCK(lock);
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    	_PR_INTSON(is);
+    return rv;
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+/************************************************************************/
+/************************************************************************/
+/***********************ROUTINES FOR DCE EMULATION***********************/
+/************************************************************************/
+/************************************************************************/
+PR_IMPLEMENT(PRStatus) PRP_TryLock(PRLock *lock)
+    { return (PR_TestAndLock(lock)) ? PR_SUCCESS : PR_FAILURE; }

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prustack.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/prustack.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,206 @@
+/* -*- 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"
+
+/* List of free stack virtual memory chunks */
+PRLock *_pr_stackLock;
+PRCList _pr_freeStacks = PR_INIT_STATIC_CLIST(&_pr_freeStacks);
+PRIntn _pr_numFreeStacks;
+PRIntn _pr_maxFreeStacks = 4;
+
+#ifdef DEBUG
+/*
+** A variable that can be set via the debugger...
+*/
+PRBool _pr_debugStacks = PR_FALSE;
+#endif
+
+/* How much space to leave between the stacks, at each end */
+#define REDZONE		(2 << _pr_pageShift)
+
+#define _PR_THREAD_STACK_PTR(_qp) \
+    ((PRThreadStack*) ((char*) (_qp) - offsetof(PRThreadStack,links)))
+
+void _PR_InitStacks(void)
+{
+    _pr_stackLock = PR_NewLock();
+}
+
+void _PR_CleanupStacks(void)
+{
+    if (_pr_stackLock) {
+        PR_DestroyLock(_pr_stackLock);
+        _pr_stackLock = NULL;
+    }
+}
+
+/*
+** Allocate a stack for a thread.
+*/
+PRThreadStack *_PR_NewStack(PRUint32 stackSize)
+{
+    PRCList *qp;
+    PRThreadStack *ts;
+    PRThread *thr;
+
+    /*
+    ** Trim the list of free stacks. Trim it backwards, tossing out the
+    ** oldest stack found first (this way more recent stacks have a
+    ** chance of being present in the data cache).
+    */
+    PR_Lock(_pr_stackLock);
+    qp = _pr_freeStacks.prev;
+    while ((_pr_numFreeStacks > _pr_maxFreeStacks) && (qp != &_pr_freeStacks)) {
+	ts = _PR_THREAD_STACK_PTR(qp);
+	thr = _PR_THREAD_STACK_TO_PTR(ts);
+	qp = qp->prev;
+	/*
+	 * skip stacks which are still being used
+	 */
+	if (thr->no_sched)
+		continue;
+	PR_REMOVE_LINK(&ts->links);
+
+	/* Give platform OS to clear out the stack for debugging */
+	_PR_MD_CLEAR_STACK(ts);
+
+	_pr_numFreeStacks--;
+	_PR_DestroySegment(ts->seg);
+	PR_DELETE(ts);
+    }
+
+    /*
+    ** Find a free thread stack. This searches the list of free'd up
+    ** virtually mapped thread stacks.
+    */
+    qp = _pr_freeStacks.next;
+    ts = 0;
+    while (qp != &_pr_freeStacks) {
+	ts = _PR_THREAD_STACK_PTR(qp);
+	thr = _PR_THREAD_STACK_TO_PTR(ts);
+	qp = qp->next;
+	/*
+	 * skip stacks which are still being used
+	 */
+	if ((!(thr->no_sched)) && ((ts->allocSize - 2*REDZONE) >= stackSize)) {
+	    /*
+	    ** Found a stack that is not in use and is big enough. Change
+	    ** stackSize to fit it.
+	    */
+	    stackSize = ts->allocSize - 2*REDZONE;
+	    PR_REMOVE_LINK(&ts->links);
+	    _pr_numFreeStacks--;
+	    ts->links.next = 0;
+	    ts->links.prev = 0;
+	    PR_Unlock(_pr_stackLock);
+	    goto done;
+	}
+	ts = 0;
+    }
+    PR_Unlock(_pr_stackLock);
+
+    if (!ts) {
+	/* Make a new thread stack object. */
+	ts = PR_NEWZAP(PRThreadStack);
+	if (!ts) {
+	    return NULL;
+	}
+
+	/*
+	** Assign some of the virtual space to the new stack object. We
+	** may not get that piece of VM, but if nothing else we will
+	** advance the pointer so we don't collide (unless the OS screws
+	** up).
+	*/
+	ts->allocSize = stackSize + 2*REDZONE;
+	ts->seg = _PR_NewSegment(ts->allocSize, 0);
+	if (!ts->seg) {
+	    PR_DELETE(ts);
+	    return NULL;
+	}
+	}
+
+  done:
+    ts->allocBase = (char*)ts->seg->vaddr;
+    ts->flags = _PR_STACK_MAPPED;
+    ts->stackSize = stackSize;
+
+#ifdef HAVE_STACK_GROWING_UP
+    ts->stackTop = ts->allocBase + REDZONE;
+    ts->stackBottom = ts->stackTop + stackSize;
+#else
+    ts->stackBottom = ts->allocBase + REDZONE;
+    ts->stackTop = ts->stackBottom + stackSize;
+#endif
+
+    PR_LOG(_pr_thread_lm, PR_LOG_NOTICE,
+	   ("thread stack: base=0x%x limit=0x%x bottom=0x%x top=0x%x\n",
+	    ts->allocBase, ts->allocBase + ts->allocSize - 1,
+	    ts->allocBase + REDZONE,
+	    ts->allocBase + REDZONE + stackSize - 1));
+	    
+    _PR_MD_INIT_STACK(ts,REDZONE);
+
+    return ts;
+}
+
+/*
+** Free the stack for the current thread
+*/
+void _PR_FreeStack(PRThreadStack *ts)
+{
+    if (!ts) {
+	return;
+    }
+    if (ts->flags & _PR_STACK_PRIMORDIAL) {
+	PR_DELETE(ts);
+	return;
+    }
+
+    /*
+    ** Put the stack on the free list. This is done because we are still
+    ** using the stack. Next time a thread is created we will trim the
+    ** list down; it's safe to do it then because we will have had to
+    ** context switch to a live stack before another thread can be
+    ** created.
+    */
+    PR_Lock(_pr_stackLock);
+    PR_APPEND_LINK(&ts->links, _pr_freeStacks.prev);
+    _pr_numFreeStacks++;
+    PR_Unlock(_pr_stackLock);
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/pruthr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/combined/pruthr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1918 @@
+/* -*- 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 <signal.h>
+#include <string.h>
+
+#if defined(WIN95)                                                                         
+/*
+** Some local variables report warnings on Win95 because the code paths
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+**
+*/
+#pragma warning(disable : 4101)
+#endif          
+
+#if defined(XP_MAC)
+#include <LowMem.h>
+#endif
+
+/* _pr_activeLock protects the following global variables */
+PRLock *_pr_activeLock;
+PRInt32 _pr_primordialExitCount;   /* In PR_Cleanup(), the primordial thread
+                    * waits until all other user (non-system)
+                    * threads have terminated before it exits.
+                    * So whenever we decrement _pr_userActive,
+                    * it is compared with
+                    * _pr_primordialExitCount.
+                    * If the primordial thread is a system
+                    * thread, then _pr_primordialExitCount
+                    * is 0.  If the primordial thread is
+                    * itself a user thread, then 
+                    * _pr_primordialThread is 1.
+                    */
+PRCondVar *_pr_primordialExitCVar; /* When _pr_userActive is decremented to
+                    * _pr_primordialExitCount, this condition
+                    * variable is notified.
+                    */
+
+PRLock *_pr_deadQLock;
+PRUint32 _pr_numNativeDead;
+PRUint32 _pr_numUserDead;
+PRCList _pr_deadNativeQ;
+PRCList _pr_deadUserQ;
+
+PRUint32 _pr_join_counter;
+
+PRUint32 _pr_local_threads;
+PRUint32 _pr_global_threads;
+
+PRBool suspendAllOn = PR_FALSE;
+PRThread *suspendAllThread = NULL;
+
+extern PRCList _pr_active_global_threadQ;
+extern PRCList _pr_active_local_threadQ;
+
+static void _PR_DecrActiveThreadCount(PRThread *thread);
+static PRThread *_PR_AttachThread(PRThreadType, PRThreadPriority, PRThreadStack *);
+static void _PR_InitializeNativeStack(PRThreadStack *ts);
+static void _PR_InitializeRecycledThread(PRThread *thread);
+static void _PR_UserRunThread(void);
+
+void _PR_InitThreads(PRThreadType type, PRThreadPriority priority,
+    PRUintn maxPTDs)
+{
+#if defined(XP_MAC)
+#pragma unused (maxPTDs)
+#endif
+
+    PRThread *thread;
+    PRThreadStack *stack;
+
+    _pr_terminationCVLock = PR_NewLock();
+    _pr_activeLock = PR_NewLock();
+
+#ifndef HAVE_CUSTOM_USER_THREADS
+    stack = PR_NEWZAP(PRThreadStack);
+#ifdef HAVE_STACK_GROWING_UP
+    stack->stackTop = (char*) ((((long)&type) >> _pr_pageShift)
+                  << _pr_pageShift);
+#else
+#if defined(SOLARIS) || defined (UNIXWARE) && defined (USR_SVR4_THREADS)
+    stack->stackTop = (char*) &thread;
+#elif defined(XP_MAC)
+    stack->stackTop = (char*) LMGetCurStackBase();
+#else
+    stack->stackTop = (char*) ((((long)&type + _pr_pageSize - 1)
+                >> _pr_pageShift) << _pr_pageShift);
+#endif
+#endif
+#else
+    /* If stack is NULL, we're using custom user threads like NT fibers. */
+    stack = PR_NEWZAP(PRThreadStack);
+    if (stack) {
+        stack->stackSize = 0;
+        _PR_InitializeNativeStack(stack);
+    }
+#endif /* HAVE_CUSTOM_USER_THREADS */
+
+    thread = _PR_AttachThread(type, priority, stack);
+    if (thread) {
+        _PR_MD_SET_CURRENT_THREAD(thread);
+
+        if (type == PR_SYSTEM_THREAD) {
+            thread->flags = _PR_SYSTEM;
+            _pr_systemActive++;
+            _pr_primordialExitCount = 0;
+        } else {
+            _pr_userActive++;
+            _pr_primordialExitCount = 1;
+        }
+    thread->no_sched = 1;
+    _pr_primordialExitCVar = PR_NewCondVar(_pr_activeLock);
+    }
+
+    if (!thread) PR_Abort();
+#ifdef _PR_LOCAL_THREADS_ONLY
+    thread->flags |= _PR_PRIMORDIAL;
+#else
+    thread->flags |= _PR_PRIMORDIAL | _PR_GLOBAL_SCOPE;
+#endif
+
+    /*
+     * Needs _PR_PRIMORDIAL flag set before calling
+     * _PR_MD_INIT_THREAD()
+     */
+    if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) {
+        /*
+         * XXX do what?
+         */
+    }
+
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+        PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_GLOBAL_THREADQ());
+        _pr_global_threads++;
+    } else {
+        PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_LOCAL_THREADQ());
+        _pr_local_threads++;
+    }
+
+    _pr_recycleThreads = 0;
+    _pr_deadQLock = PR_NewLock();
+    _pr_numNativeDead = 0;
+    _pr_numUserDead = 0;
+    PR_INIT_CLIST(&_pr_deadNativeQ);
+    PR_INIT_CLIST(&_pr_deadUserQ);
+}
+
+void _PR_CleanupThreads(void)
+{
+    if (_pr_terminationCVLock) {
+        PR_DestroyLock(_pr_terminationCVLock);
+        _pr_terminationCVLock = NULL;
+    }
+    if (_pr_activeLock) {
+        PR_DestroyLock(_pr_activeLock);
+        _pr_activeLock = NULL;
+    }
+    if (_pr_primordialExitCVar) {
+        PR_DestroyCondVar(_pr_primordialExitCVar);
+        _pr_primordialExitCVar = NULL;
+    }
+    /* TODO _pr_dead{Native,User}Q need to be deleted */
+    if (_pr_deadQLock) {
+        PR_DestroyLock(_pr_deadQLock);
+        _pr_deadQLock = NULL;
+    }
+}
+
+/*
+** Initialize a stack for a native thread
+*/
+static void _PR_InitializeNativeStack(PRThreadStack *ts)
+{
+    if( ts && (ts->stackTop == 0) ) {
+        ts->allocSize = ts->stackSize;
+
+        /*
+        ** Setup stackTop and stackBottom values.
+        */
+#ifdef HAVE_STACK_GROWING_UP
+    ts->allocBase = (char*) ((((long)&ts) >> _pr_pageShift)
+                  << _pr_pageShift);
+        ts->stackBottom = ts->allocBase + ts->stackSize;
+        ts->stackTop = ts->allocBase;
+#else
+        ts->allocBase = (char*) ((((long)&ts + _pr_pageSize - 1)
+                >> _pr_pageShift) << _pr_pageShift);
+        ts->stackTop    = ts->allocBase;
+        ts->stackBottom = ts->allocBase - ts->stackSize;
+#endif
+    }
+}
+
+void _PR_NotifyJoinWaiters(PRThread *thread)
+{
+    /*
+    ** Handle joinable threads.  Change the state to waiting for join.
+    ** Remove from our run Q and put it on global waiting to join Q.
+    ** Notify on our "termination" condition variable so that joining
+    ** thread will know about our termination.  Switch our context and
+    ** come back later on to continue the cleanup.
+    */    
+    PR_ASSERT(thread == _PR_MD_CURRENT_THREAD());
+    if (thread->term != NULL) {
+        PR_Lock(_pr_terminationCVLock);
+        _PR_THREAD_LOCK(thread);
+        thread->state = _PR_JOIN_WAIT;
+        if ( !_PR_IS_NATIVE_THREAD(thread) ) {
+            _PR_MISCQ_LOCK(thread->cpu);
+            _PR_ADD_JOINQ(thread, thread->cpu);
+            _PR_MISCQ_UNLOCK(thread->cpu);
+        }
+        _PR_THREAD_UNLOCK(thread);
+        PR_NotifyCondVar(thread->term);
+        PR_Unlock(_pr_terminationCVLock);
+        _PR_MD_WAIT(thread, PR_INTERVAL_NO_TIMEOUT);
+        PR_ASSERT(thread->state != _PR_JOIN_WAIT);
+    }
+
+}
+
+/*
+ * Zero some of the data members of a recycled thread.
+ *
+ * Note that we can do this either when a dead thread is added to
+ * the dead thread queue or when it is reused.  Here, we are doing
+ * this lazily, when the thread is reused in _PR_CreateThread().
+ */
+static void _PR_InitializeRecycledThread(PRThread *thread)
+{
+    /*
+     * Assert that the following data members are already zeroed
+     * by _PR_CleanupThread().
+     */
+#ifdef DEBUG
+    if (thread->privateData) {
+        unsigned int i;
+        for (i = 0; i < thread->tpdLength; i++) {
+            PR_ASSERT(thread->privateData[i] == NULL);
+        }
+    }
+#endif
+    PR_ASSERT(thread->dumpArg == 0 && thread->dump == 0);
+    PR_ASSERT(thread->errorString == 0 && thread->errorStringSize == 0);
+    PR_ASSERT(thread->errorStringLength == 0);
+
+    /* Reset data members in thread structure */
+    thread->errorCode = thread->osErrorCode = 0;
+    thread->io_pending = thread->io_suspended = PR_FALSE;
+    thread->environment = 0;
+    PR_INIT_CLIST(&thread->lockList);
+}
+
+PRStatus _PR_RecycleThread(PRThread *thread)
+{
+    if ( _PR_IS_NATIVE_THREAD(thread) &&
+            _PR_NUM_DEADNATIVE < _pr_recycleThreads) {
+        _PR_DEADQ_LOCK;
+        PR_APPEND_LINK(&thread->links, &_PR_DEADNATIVEQ);
+        _PR_INC_DEADNATIVE;
+        _PR_DEADQ_UNLOCK;
+    return (PR_SUCCESS);
+    } else if ( !_PR_IS_NATIVE_THREAD(thread) &&
+                _PR_NUM_DEADUSER < _pr_recycleThreads) {
+        _PR_DEADQ_LOCK;
+        PR_APPEND_LINK(&thread->links, &_PR_DEADUSERQ);
+        _PR_INC_DEADUSER;
+        _PR_DEADQ_UNLOCK;
+    return (PR_SUCCESS);
+    }
+    return (PR_FAILURE);
+}
+
+/*
+ * Decrement the active thread count, either _pr_systemActive or
+ * _pr_userActive, depending on whether the thread is a system thread
+ * or a user thread.  If all the user threads, except possibly
+ * the primordial thread, have terminated, we notify the primordial
+ * thread of this condition.
+ *
+ * Since this function will lock _pr_activeLock, do not call this
+ * function while holding the _pr_activeLock lock, as this will result
+ * in a deadlock.
+ */
+
+static void
+_PR_DecrActiveThreadCount(PRThread *thread)
+{
+    PR_Lock(_pr_activeLock);
+    if (thread->flags & _PR_SYSTEM) {
+        _pr_systemActive--;
+    } else {
+        _pr_userActive--;
+        if (_pr_userActive == _pr_primordialExitCount) {
+            PR_NotifyCondVar(_pr_primordialExitCVar);
+        }
+    }
+    PR_Unlock(_pr_activeLock);
+}
+
+/*
+** Detach thread structure
+*/
+static void
+_PR_DestroyThread(PRThread *thread)
+{
+    _PR_MD_FREE_LOCK(&thread->threadLock);
+    PR_DELETE(thread);
+}
+
+void
+_PR_NativeDestroyThread(PRThread *thread)
+{
+    if(thread->term) {
+        PR_DestroyCondVar(thread->term);
+        thread->term = 0;
+    }
+    if (NULL != thread->privateData) {
+        PR_ASSERT(0 != thread->tpdLength);
+        PR_DELETE(thread->privateData);
+        thread->tpdLength = 0;
+    }
+    PR_DELETE(thread->stack);
+    _PR_DestroyThread(thread);
+}
+
+void
+_PR_UserDestroyThread(PRThread *thread)
+{
+    if(thread->term) {
+        PR_DestroyCondVar(thread->term);
+        thread->term = 0;
+    }
+    if (NULL != thread->privateData) {
+        PR_ASSERT(0 != thread->tpdLength);
+        PR_DELETE(thread->privateData);
+        thread->tpdLength = 0;
+    }
+    _PR_MD_FREE_LOCK(&thread->threadLock);
+    if (thread->threadAllocatedOnStack == 1) {
+        _PR_MD_CLEAN_THREAD(thread);
+        /*
+         *  Because the no_sched field is set, this thread/stack will
+         *  will not be re-used until the flag is cleared by the thread
+         *  we will context switch to.
+         */
+        _PR_FreeStack(thread->stack);
+    } else {
+#ifdef WINNT
+        _PR_MD_CLEAN_THREAD(thread);
+#else
+        /*
+         * This assertion does not apply to NT.  On NT, every fiber
+         * has its threadAllocatedOnStack equal to 0.  Elsewhere,
+         * only the primordial thread has its threadAllocatedOnStack
+         * equal to 0.
+         */
+        PR_ASSERT(thread->flags & _PR_PRIMORDIAL);
+#endif
+    }
+}
+
+
+/*
+** Run a thread's start function. When the start function returns the
+** thread is done executing and no longer needs the CPU. If there are no
+** more user threads running then we can exit the program.
+*/
+void _PR_NativeRunThread(void *arg)
+{
+    PRThread *thread = (PRThread *)arg;
+
+    _PR_MD_SET_CURRENT_THREAD(thread);
+
+    _PR_MD_SET_CURRENT_CPU(NULL);
+
+    /* Set up the thread stack information */
+    _PR_InitializeNativeStack(thread->stack);
+
+    /* Set up the thread md information */
+    if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) {
+        /*
+         * thread failed to initialize itself, possibly due to
+         * failure to allocate per-thread resources
+         */
+        return;
+    }
+
+    while(1) {
+        thread->state = _PR_RUNNING;
+
+        /*
+         * Add to list of active threads
+         */
+        PR_Lock(_pr_activeLock);
+        PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_GLOBAL_THREADQ());
+        _pr_global_threads++;
+        PR_Unlock(_pr_activeLock);
+
+        (*thread->startFunc)(thread->arg);
+
+        /*
+         * The following two assertions are meant for NT asynch io.
+         *
+         * The thread should have no asynch io in progress when it
+         * exits, otherwise the overlapped buffer, which is part of
+         * the thread structure, would become invalid.
+         */
+        PR_ASSERT(thread->io_pending == PR_FALSE);
+        /*
+         * This assertion enforces the programming guideline that
+         * if an io function times out or is interrupted, the thread
+         * should close the fd to force the asynch io to abort
+         * before it exits.  Right now, closing the fd is the only
+         * way to clear the io_suspended flag.
+         */
+        PR_ASSERT(thread->io_suspended == PR_FALSE);
+
+        /*
+         * remove thread from list of active threads
+         */
+        PR_Lock(_pr_activeLock);
+        PR_REMOVE_LINK(&thread->active);
+        _pr_global_threads--;
+        PR_Unlock(_pr_activeLock);
+
+        PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("thread exiting"));
+
+        /* All done, time to go away */
+        _PR_CleanupThread(thread);
+
+        _PR_NotifyJoinWaiters(thread);
+
+        _PR_DecrActiveThreadCount(thread);
+
+        thread->state = _PR_DEAD_STATE;
+
+        if (!_pr_recycleThreads || (_PR_RecycleThread(thread) ==
+                        PR_FAILURE)) {
+            /*
+             * thread not recycled
+             * platform-specific thread exit processing
+             *        - for stuff like releasing native-thread resources, etc.
+             */
+            _PR_MD_EXIT_THREAD(thread);
+            /*
+             * Free memory allocated for the thread
+             */
+            _PR_NativeDestroyThread(thread);
+            /*
+             * thread gone, cannot de-reference thread now
+             */
+            return;
+        }
+
+        /* Now wait for someone to activate us again... */
+        _PR_MD_WAIT(thread, PR_INTERVAL_NO_TIMEOUT);
+    }
+}
+
+static void _PR_UserRunThread(void)
+{
+    PRThread *thread = _PR_MD_CURRENT_THREAD();
+    PRIntn is;
+
+    if (_MD_LAST_THREAD())
+    _MD_LAST_THREAD()->no_sched = 0;
+
+#ifdef HAVE_CUSTOM_USER_THREADS
+    if (thread->stack == NULL) {
+        thread->stack = PR_NEWZAP(PRThreadStack);
+        _PR_InitializeNativeStack(thread->stack);
+    }
+#endif /* HAVE_CUSTOM_USER_THREADS */
+
+    while(1) {
+        /* Run thread main */
+        if ( !_PR_IS_NATIVE_THREAD(thread)) _PR_MD_SET_INTSOFF(0);
+
+    /*
+     * Add to list of active threads
+     */
+    if (!(thread->flags & _PR_IDLE_THREAD)) {
+        PR_Lock(_pr_activeLock);
+        PR_APPEND_LINK(&thread->active, &_PR_ACTIVE_LOCAL_THREADQ());
+        _pr_local_threads++;
+        PR_Unlock(_pr_activeLock);
+    }
+
+        (*thread->startFunc)(thread->arg);
+
+        /*
+         * The following two assertions are meant for NT asynch io.
+         *
+         * The thread should have no asynch io in progress when it
+         * exits, otherwise the overlapped buffer, which is part of
+         * the thread structure, would become invalid.
+         */
+        PR_ASSERT(thread->io_pending == PR_FALSE);
+        /*
+         * This assertion enforces the programming guideline that
+         * if an io function times out or is interrupted, the thread
+         * should close the fd to force the asynch io to abort
+         * before it exits.  Right now, closing the fd is the only
+         * way to clear the io_suspended flag.
+         */
+        PR_ASSERT(thread->io_suspended == PR_FALSE);
+
+        PR_Lock(_pr_activeLock);
+    /*
+     * remove thread from list of active threads
+     */
+    if (!(thread->flags & _PR_IDLE_THREAD)) {
+           PR_REMOVE_LINK(&thread->active);
+        _pr_local_threads--;
+    }
+    PR_Unlock(_pr_activeLock);
+        PR_LOG(_pr_thread_lm, PR_LOG_MIN, ("thread exiting"));
+
+        /* All done, time to go away */
+        _PR_CleanupThread(thread);
+
+        _PR_INTSOFF(is);    
+
+        _PR_NotifyJoinWaiters(thread);
+
+    _PR_DecrActiveThreadCount(thread);
+
+        thread->state = _PR_DEAD_STATE;
+
+        if (!_pr_recycleThreads || (_PR_RecycleThread(thread) ==
+                        PR_FAILURE)) {
+            /*
+            ** Destroy the thread resources
+            */
+        _PR_UserDestroyThread(thread);
+        }
+
+        /*
+        ** Find another user thread to run. This cpu has finished the
+        ** previous threads main and is now ready to run another thread.
+        */
+        {
+            PRInt32 is;
+            _PR_INTSOFF(is);
+            _PR_MD_SWITCH_CONTEXT(thread);
+        }
+
+        /* Will land here when we get scheduled again if we are recycling... */
+    }
+}
+
+void _PR_SetThreadPriority(PRThread *thread, PRThreadPriority newPri)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRIntn is;
+
+    if ( _PR_IS_NATIVE_THREAD(thread) ) {
+        _PR_MD_SET_PRIORITY(&(thread->md), newPri);
+        return;
+    }
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(thread);
+    if (newPri != thread->priority) {
+    _PRCPU *cpu = thread->cpu;
+
+    switch (thread->state) {
+      case _PR_RUNNING:
+        /* Change my priority */
+
+            _PR_RUNQ_LOCK(cpu);
+        thread->priority = newPri;
+        if (_PR_RUNQREADYMASK(cpu) >> (newPri + 1)) {
+            if (!_PR_IS_NATIVE_THREAD(me))
+                    _PR_SET_RESCHED_FLAG();
+        }
+            _PR_RUNQ_UNLOCK(cpu);
+        break;
+
+      case _PR_RUNNABLE:
+
+        _PR_RUNQ_LOCK(cpu);
+            /* Move to different runQ */
+            _PR_DEL_RUNQ(thread);
+            thread->priority = newPri;
+            PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+            _PR_ADD_RUNQ(thread, cpu, newPri);
+        _PR_RUNQ_UNLOCK(cpu);
+
+            if (newPri > me->priority) {
+            if (!_PR_IS_NATIVE_THREAD(me))
+                    _PR_SET_RESCHED_FLAG();
+            }
+
+        break;
+
+      case _PR_LOCK_WAIT:
+      case _PR_COND_WAIT:
+      case _PR_IO_WAIT:
+      case _PR_SUSPENDED:
+
+        thread->priority = newPri;
+        break;
+    }
+    }
+    _PR_THREAD_UNLOCK(thread);
+    if (!_PR_IS_NATIVE_THREAD(me))
+    _PR_INTSON(is);
+}
+
+/*
+** Suspend the named thread and copy its gc registers into regBuf
+*/
+static void _PR_Suspend(PRThread *thread)
+{
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    PR_ASSERT(thread != me);
+    PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread) || (!thread->cpu));
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(thread);
+    switch (thread->state) {
+      case _PR_RUNNABLE:
+        if (!_PR_IS_NATIVE_THREAD(thread)) {
+            _PR_RUNQ_LOCK(thread->cpu);
+            _PR_DEL_RUNQ(thread);
+            _PR_RUNQ_UNLOCK(thread->cpu);
+
+            _PR_MISCQ_LOCK(thread->cpu);
+            _PR_ADD_SUSPENDQ(thread, thread->cpu);
+            _PR_MISCQ_UNLOCK(thread->cpu);
+        } else {
+            /*
+             * Only LOCAL threads are suspended by _PR_Suspend
+             */
+             PR_ASSERT(0);
+        }
+        thread->state = _PR_SUSPENDED;
+        break;
+
+      case _PR_RUNNING:
+        /*
+         * The thread being suspended should be a LOCAL thread with
+         * _pr_numCPUs == 1. Hence, the thread cannot be in RUNNING state
+         */
+        PR_ASSERT(0);
+        break;
+
+      case _PR_LOCK_WAIT:
+      case _PR_IO_WAIT:
+      case _PR_COND_WAIT:
+        if (_PR_IS_NATIVE_THREAD(thread)) {
+            _PR_MD_SUSPEND_THREAD(thread);
+    }
+        thread->flags |= _PR_SUSPENDING;
+        break;
+
+      default:
+        PR_Abort();
+    }
+    _PR_THREAD_UNLOCK(thread);
+    if (!_PR_IS_NATIVE_THREAD(me))
+    _PR_INTSON(is);
+}
+
+static void _PR_Resume(PRThread *thread)
+{
+    PRThreadPriority pri;
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+    _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(thread);
+    switch (thread->state) {
+      case _PR_SUSPENDED:
+        thread->state = _PR_RUNNABLE;
+        thread->flags &= ~_PR_SUSPENDING;
+        if (!_PR_IS_NATIVE_THREAD(thread)) {
+            _PR_MISCQ_LOCK(thread->cpu);
+            _PR_DEL_SUSPENDQ(thread);
+            _PR_MISCQ_UNLOCK(thread->cpu);
+
+            pri = thread->priority;
+
+            _PR_RUNQ_LOCK(thread->cpu);
+            _PR_ADD_RUNQ(thread, thread->cpu, pri);
+            _PR_RUNQ_UNLOCK(thread->cpu);
+
+            if (pri > _PR_MD_CURRENT_THREAD()->priority) {
+                if (!_PR_IS_NATIVE_THREAD(me))
+                    _PR_SET_RESCHED_FLAG();
+            }
+        } else {
+            PR_ASSERT(0);
+        }
+        break;
+
+      case _PR_IO_WAIT:
+      case _PR_COND_WAIT:
+        thread->flags &= ~_PR_SUSPENDING;
+/*      PR_ASSERT(thread->wait.monitor->stickyCount == 0); */
+        break;
+
+      case _PR_LOCK_WAIT: 
+      {
+        PRLock *wLock = thread->wait.lock;
+
+        thread->flags &= ~_PR_SUSPENDING;
+ 
+        _PR_LOCK_LOCK(wLock);
+        if (thread->wait.lock->owner == 0) {
+            _PR_UnblockLockWaiter(thread->wait.lock);
+        }
+        _PR_LOCK_UNLOCK(wLock);
+        break;
+      }
+      case _PR_RUNNABLE:
+        break;
+      case _PR_RUNNING:
+        /*
+         * The thread being suspended should be a LOCAL thread with
+         * _pr_numCPUs == 1. Hence, the thread cannot be in RUNNING state
+         */
+        PR_ASSERT(0);
+        break;
+
+      default:
+    /*
+     * thread should have been in one of the above-listed blocked states
+     * (_PR_JOIN_WAIT, _PR_IO_WAIT, _PR_UNBORN, _PR_DEAD_STATE)
+     */
+        PR_Abort();
+    }
+    _PR_THREAD_UNLOCK(thread);
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSON(is);
+
+}
+
+#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
+static PRThread *get_thread(_PRCPU *cpu, PRBool *wakeup_cpus)
+{
+    PRThread *thread;
+    PRIntn pri;
+    PRUint32 r;
+    PRCList *qp;
+    PRIntn priMin, priMax;
+
+    _PR_RUNQ_LOCK(cpu);
+    r = _PR_RUNQREADYMASK(cpu);
+    if (r==0) {
+        priMin = priMax = PR_PRIORITY_FIRST;
+    } else if (r == (1<<PR_PRIORITY_NORMAL) ) {
+        priMin = priMax = PR_PRIORITY_NORMAL;
+    } else {
+        priMin = PR_PRIORITY_FIRST;
+        priMax = PR_PRIORITY_LAST;
+    }
+    thread = NULL;
+    for (pri = priMax; pri >= priMin ; pri-- ) {
+    if (r & (1 << pri)) {
+            for (qp = _PR_RUNQ(cpu)[pri].next; 
+                 qp != &_PR_RUNQ(cpu)[pri];
+                 qp = qp->next) {
+                thread = _PR_THREAD_PTR(qp);
+                /*
+                * skip non-schedulable threads
+                */
+                PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+                if (thread->no_sched) {
+                    thread = NULL;
+                    /*
+                     * Need to wakeup cpus to avoid missing a
+                     * runnable thread
+                     * Waking up all CPU's need happen only once.
+                     */
+
+                    *wakeup_cpus = PR_TRUE;
+                    continue;
+                } else if (thread->flags & _PR_BOUND_THREAD) {
+                    /*
+                     * Thread bound to cpu 0
+                     */
+
+                    thread = NULL;
+#ifdef IRIX
+					_PR_MD_WAKEUP_PRIMORDIAL_CPU();
+#endif
+                    continue;
+                } else if (thread->io_pending == PR_TRUE) {
+                    /*
+                     * A thread that is blocked for I/O needs to run
+                     * on the same cpu on which it was blocked. This is because
+                     * the cpu's ioq is accessed without lock protection and scheduling
+                     * the thread on a different cpu would preclude this optimization.
+                     */
+                    thread = NULL;
+                    continue;
+                } else {
+                    /* Pull thread off of its run queue */
+                    _PR_DEL_RUNQ(thread);
+                    _PR_RUNQ_UNLOCK(cpu);
+                    return(thread);
+                }
+            }
+        }
+        thread = NULL;
+    }
+    _PR_RUNQ_UNLOCK(cpu);
+    return(thread);
+}
+#endif /* !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX) */
+
+/*
+** Schedule this native thread by finding the highest priority nspr
+** thread that is ready to run.
+**
+** Note- everyone really needs to call _PR_MD_SWITCH_CONTEXT (which calls
+**       PR_Schedule() rather than calling PR_Schedule.  Otherwise if there
+**       is initialization required for switching from SWITCH_CONTEXT,
+**       it will not get done!
+*/
+void _PR_Schedule(void)
+{
+    PRThread *thread, *me = _PR_MD_CURRENT_THREAD();
+    _PRCPU *cpu = _PR_MD_CURRENT_CPU();
+    PRIntn pri;
+    PRUint32 r;
+    PRCList *qp;
+    PRIntn priMin, priMax;
+#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
+    PRBool wakeup_cpus;
+#endif
+
+    /* Interrupts must be disabled */
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me) || _PR_MD_GET_INTSOFF() != 0);
+
+    /* Since we are rescheduling, we no longer want to */
+    _PR_CLEAR_RESCHED_FLAG();
+
+    /*
+    ** Find highest priority thread to run. Bigger priority numbers are
+    ** higher priority threads
+    */
+    _PR_RUNQ_LOCK(cpu);
+    /*
+     *  if we are in SuspendAll mode, can schedule only the thread
+     *    that called PR_SuspendAll
+     *
+     *  The thread may be ready to run now, after completing an I/O
+     *  operation, for example
+     */
+    if ((thread = suspendAllThread) != 0) {
+    if ((!(thread->no_sched)) && (thread->state == _PR_RUNNABLE)) {
+            /* Pull thread off of its run queue */
+            _PR_DEL_RUNQ(thread);
+            _PR_RUNQ_UNLOCK(cpu);
+            goto found_thread;
+    } else {
+            thread = NULL;
+            _PR_RUNQ_UNLOCK(cpu);
+            goto idle_thread;
+    }
+    }
+    r = _PR_RUNQREADYMASK(cpu);
+    if (r==0) {
+        priMin = priMax = PR_PRIORITY_FIRST;
+    } else if (r == (1<<PR_PRIORITY_NORMAL) ) {
+        priMin = priMax = PR_PRIORITY_NORMAL;
+    } else {
+        priMin = PR_PRIORITY_FIRST;
+        priMax = PR_PRIORITY_LAST;
+    }
+    thread = NULL;
+    for (pri = priMax; pri >= priMin ; pri-- ) {
+    if (r & (1 << pri)) {
+            for (qp = _PR_RUNQ(cpu)[pri].next; 
+                 qp != &_PR_RUNQ(cpu)[pri];
+                 qp = qp->next) {
+                thread = _PR_THREAD_PTR(qp);
+                /*
+                * skip non-schedulable threads
+                */
+#if !defined(XP_MAC)
+                PR_ASSERT(!(thread->flags & _PR_IDLE_THREAD));
+#endif
+                if ((thread->no_sched) && (me != thread)){
+                    thread = NULL;
+                    continue;
+                } else {
+                    /* Pull thread off of its run queue */
+                    _PR_DEL_RUNQ(thread);
+                    _PR_RUNQ_UNLOCK(cpu);
+                    goto found_thread;
+                }
+            }
+        }
+        thread = NULL;
+    }
+    _PR_RUNQ_UNLOCK(cpu);
+
+#if !defined(_PR_LOCAL_THREADS_ONLY) && defined(XP_UNIX)
+
+    wakeup_cpus = PR_FALSE;
+    _PR_CPU_LIST_LOCK();
+    for (qp = _PR_CPUQ().next; qp != &_PR_CPUQ(); qp = qp->next) {
+        if (cpu != _PR_CPU_PTR(qp)) {
+            if ((thread = get_thread(_PR_CPU_PTR(qp), &wakeup_cpus))
+                                        != NULL) {
+                thread->cpu = cpu;
+                _PR_CPU_LIST_UNLOCK();
+                if (wakeup_cpus == PR_TRUE)
+                    _PR_MD_WAKEUP_CPUS();
+                goto found_thread;
+            }
+        }
+    }
+    _PR_CPU_LIST_UNLOCK();
+    if (wakeup_cpus == PR_TRUE)
+        _PR_MD_WAKEUP_CPUS();
+
+#endif        /* _PR_LOCAL_THREADS_ONLY */
+
+idle_thread:
+   /*
+    ** There are no threads to run. Switch to the idle thread
+    */
+    PR_LOG(_pr_sched_lm, PR_LOG_MAX, ("pausing"));
+    thread = _PR_MD_CURRENT_CPU()->idle_thread;
+
+found_thread:
+    PR_ASSERT((me == thread) || ((thread->state == _PR_RUNNABLE) &&
+                    (!(thread->no_sched))));
+
+    /* Resume the thread */
+    PR_LOG(_pr_sched_lm, PR_LOG_MAX,
+       ("switching to %d[%p]", thread->id, thread));
+    PR_ASSERT(thread->state != _PR_RUNNING);
+    thread->state = _PR_RUNNING;
+ 
+    /* If we are on the runq, it just means that we went to sleep on some
+     * resource, and by the time we got here another real native thread had
+     * already given us the resource and put us back on the runqueue 
+     */
+	PR_ASSERT(thread->cpu == _PR_MD_CURRENT_CPU());
+    if (thread != me) 
+        _PR_MD_RESTORE_CONTEXT(thread);
+#if 0
+    /* XXXMB; with setjmp/longjmp it is impossible to land here, but 
+     * it is not with fibers... Is this a bad thing?  I believe it is 
+     * still safe.
+     */
+    PR_NOT_REACHED("impossible return from schedule");
+#endif
+}
+
+/*
+** Attaches a thread.  
+** Does not set the _PR_MD_CURRENT_THREAD.  
+** Does not specify the scope of the thread.
+*/
+static PRThread *
+_PR_AttachThread(PRThreadType type, PRThreadPriority priority,
+    PRThreadStack *stack)
+{
+#if defined(XP_MAC)
+#pragma unused (type)
+#endif
+
+    PRThread *thread;
+    char *mem;
+
+    if (priority > PR_PRIORITY_LAST) {
+        priority = PR_PRIORITY_LAST;
+    } else if (priority < PR_PRIORITY_FIRST) {
+        priority = PR_PRIORITY_FIRST;
+    }
+
+    mem = (char*) PR_CALLOC(sizeof(PRThread));
+    if (mem) {
+        thread = (PRThread*) mem;
+        thread->priority = priority;
+        thread->stack = stack;
+        thread->state = _PR_RUNNING;
+        PR_INIT_CLIST(&thread->lockList);
+        if (_PR_MD_NEW_LOCK(&thread->threadLock) == PR_FAILURE) {
+        PR_DELETE(thread);
+        return 0;
+    }
+
+        return thread;
+    }
+    return 0;
+}
+
+
+
+PR_IMPLEMENT(PRThread*) 
+_PR_NativeCreateThread(PRThreadType type,
+                     void (*start)(void *arg),
+                     void *arg,
+                     PRThreadPriority priority,
+                     PRThreadScope scope,
+                     PRThreadState state,
+                     PRUint32 stackSize,
+                     PRUint32 flags)
+{
+#if defined(XP_MAC)
+#pragma unused (scope)
+#endif
+
+    PRThread *thread;
+
+    thread = _PR_AttachThread(type, priority, NULL);
+
+    if (thread) {
+        PR_Lock(_pr_activeLock);
+        thread->flags = (flags | _PR_GLOBAL_SCOPE);
+        thread->id = ++_pr_utid;
+        if (type == PR_SYSTEM_THREAD) {
+            thread->flags |= _PR_SYSTEM;
+            _pr_systemActive++;
+        } else {
+            _pr_userActive++;
+        }
+        PR_Unlock(_pr_activeLock);
+
+        thread->stack = PR_NEWZAP(PRThreadStack);
+        if (!thread->stack) {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            goto done;
+        }
+        thread->stack->stackSize = stackSize?stackSize:_MD_DEFAULT_STACK_SIZE;
+        thread->stack->thr = thread;
+        thread->startFunc = start;
+        thread->arg = arg;
+
+        /* 
+          Set thread flags related to scope and joinable state. If joinable
+          thread, allocate a "termination" conidition variable.
+         */
+        if (state == PR_JOINABLE_THREAD) {
+            thread->term = PR_NewCondVar(_pr_terminationCVLock);
+        if (thread->term == NULL) {
+        PR_DELETE(thread->stack);
+        goto done;
+        }
+        }
+
+    thread->state = _PR_RUNNING;
+        if (_PR_MD_CREATE_THREAD(thread, _PR_NativeRunThread, priority,
+            scope,state,stackSize) == PR_SUCCESS) {
+            return thread;
+        }
+        if (thread->term) {
+            PR_DestroyCondVar(thread->term);
+            thread->term = NULL;
+        }
+    PR_DELETE(thread->stack);
+    }
+
+done:
+    if (thread) {
+    _PR_DecrActiveThreadCount(thread);
+        _PR_DestroyThread(thread);
+    }
+    return NULL;
+}
+
+/************************************************************************/
+
+PR_IMPLEMENT(PRThread*) _PR_CreateThread(PRThreadType type,
+                     void (*start)(void *arg),
+                     void *arg,
+                     PRThreadPriority priority,
+                     PRThreadScope scope,
+                     PRThreadState state,
+                     PRUint32 stackSize,
+                     PRUint32 flags)
+{
+    PRThread *me;
+    PRThread *thread = NULL;
+    PRThreadStack *stack;
+    char *top;
+    PRIntn is;
+    PRIntn native = 0;
+    PRIntn useRecycled = 0;
+    PRBool status;
+
+    /* 
+    First, pin down the priority.  Not all compilers catch passing out of
+    range enum here.  If we let bad values thru, priority queues won't work.
+    */
+    if (priority > PR_PRIORITY_LAST) {
+        priority = PR_PRIORITY_LAST;
+    } else if (priority < PR_PRIORITY_FIRST) {
+        priority = PR_PRIORITY_FIRST;
+    }
+        
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (! (flags & _PR_IDLE_THREAD))
+        me = _PR_MD_CURRENT_THREAD();
+
+#if    defined(_PR_GLOBAL_THREADS_ONLY)
+	/*
+	 * can create global threads only
+	 */
+    if (scope == PR_LOCAL_THREAD)
+    	scope = PR_GLOBAL_THREAD;
+#endif
+
+	if (_native_threads_only)
+		scope = PR_GLOBAL_THREAD;
+
+    native = (((scope == PR_GLOBAL_THREAD)|| (scope == PR_GLOBAL_BOUND_THREAD))
+							&& _PR_IS_NATIVE_THREAD_SUPPORTED());
+
+    _PR_ADJUST_STACKSIZE(stackSize);
+
+    if (native) {
+    /*
+     * clear the IDLE_THREAD flag which applies to LOCAL
+     * threads only
+     */
+    flags &= ~_PR_IDLE_THREAD;
+        flags |= _PR_GLOBAL_SCOPE;
+        if (_PR_NUM_DEADNATIVE > 0) {
+            _PR_DEADQ_LOCK;
+
+            if (_PR_NUM_DEADNATIVE == 0) { /* Thread safe check */
+                _PR_DEADQ_UNLOCK;
+            } else {
+                thread = _PR_THREAD_PTR(_PR_DEADNATIVEQ.next);
+                PR_REMOVE_LINK(&thread->links);
+                _PR_DEC_DEADNATIVE;
+                _PR_DEADQ_UNLOCK;
+
+                _PR_InitializeRecycledThread(thread);
+                thread->startFunc = start;
+                thread->arg = arg;
+            thread->flags = (flags | _PR_GLOBAL_SCOPE);
+            if (type == PR_SYSTEM_THREAD)
+            {
+                thread->flags |= _PR_SYSTEM;
+                PR_AtomicIncrement(&_pr_systemActive);
+            }
+            else PR_AtomicIncrement(&_pr_userActive);
+
+            if (state == PR_JOINABLE_THREAD) {
+                if (!thread->term) 
+                       thread->term = PR_NewCondVar(_pr_terminationCVLock);
+            }
+        else {
+                if(thread->term) {
+                    PR_DestroyCondVar(thread->term);
+                        thread->term = 0;
+            }
+            }
+
+                thread->priority = priority;
+        _PR_MD_SET_PRIORITY(&(thread->md), priority);
+        /* XXX what about stackSize? */
+        thread->state = _PR_RUNNING;
+                _PR_MD_WAKEUP_WAITER(thread);
+        return thread;
+            }
+        }
+        thread = _PR_NativeCreateThread(type, start, arg, priority, 
+                                            scope, state, stackSize, flags);
+    } else {
+        if (_PR_NUM_DEADUSER > 0) {
+            _PR_DEADQ_LOCK;
+
+            if (_PR_NUM_DEADUSER == 0) {  /* thread safe check */
+                _PR_DEADQ_UNLOCK;
+            } else {
+                PRCList *ptr;
+
+                /* Go down list checking for a recycled thread with a 
+                 * large enough stack.  XXXMB - this has a bad degenerate case.
+                 */
+                ptr = _PR_DEADUSERQ.next;
+                while( ptr != &_PR_DEADUSERQ ) {
+                    thread = _PR_THREAD_PTR(ptr);
+                    if ((thread->stack->stackSize >= stackSize) &&
+                (!thread->no_sched)) {
+                        PR_REMOVE_LINK(&thread->links);
+                        _PR_DEC_DEADUSER;
+                        break;
+                    } else {
+                        ptr = ptr->next;
+                        thread = NULL;
+                    }
+                } 
+
+                _PR_DEADQ_UNLOCK;
+
+               if (thread) {
+                    _PR_InitializeRecycledThread(thread);
+                    thread->startFunc = start;
+                    thread->arg = arg;
+                    thread->priority = priority;
+            if (state == PR_JOINABLE_THREAD) {
+            if (!thread->term) 
+               thread->term = PR_NewCondVar(_pr_terminationCVLock);
+            } else {
+            if(thread->term) {
+               PR_DestroyCondVar(thread->term);
+                thread->term = 0;
+            }
+            }
+                    useRecycled++;
+                }
+            }
+        } 
+        if (thread == NULL) {
+#ifndef HAVE_CUSTOM_USER_THREADS
+            stack = _PR_NewStack(stackSize);
+            if (!stack) {
+                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                return NULL;
+            }
+
+            /* Allocate thread object and per-thread data off the top of the stack*/
+            top = stack->stackTop;
+#ifdef HAVE_STACK_GROWING_UP
+            thread = (PRThread*) top;
+            top = top + sizeof(PRThread);
+            /*
+             * Make stack 64-byte aligned
+             */
+            if ((PRUptrdiff)top & 0x3f) {
+                top = (char*)(((PRUptrdiff)top + 0x40) & ~0x3f);
+            }
+#else
+            top = top - sizeof(PRThread);
+            thread = (PRThread*) top;
+            /*
+             * Make stack 64-byte aligned
+             */
+            if ((PRUptrdiff)top & 0x3f) {
+                top = (char*)((PRUptrdiff)top & ~0x3f);
+            }
+#endif
+#if defined(GC_LEAK_DETECTOR)
+            /*
+             * sorry, it is not safe to allocate the thread on the stack,
+             * because we assign to this object before the GC can learn
+             * about this thread. we'll just leak thread objects instead.
+             */
+            thread = PR_NEW(PRThread);
+#endif
+            stack->thr = thread;
+            memset(thread, 0, sizeof(PRThread));
+            thread->threadAllocatedOnStack = 1;
+#else
+            thread = _PR_MD_CREATE_USER_THREAD(stackSize, start, arg);
+            if (!thread) {
+                PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+                return NULL;
+            }
+            thread->threadAllocatedOnStack = 0;
+            stack = NULL;
+            top = NULL;
+#endif
+
+            /* Initialize thread */
+            thread->tpdLength = 0;
+            thread->privateData = NULL;
+            thread->stack = stack;
+            thread->priority = priority;
+            thread->startFunc = start;
+            thread->arg = arg;
+            PR_INIT_CLIST(&thread->lockList);
+
+            if (_PR_MD_INIT_THREAD(thread) == PR_FAILURE) {
+                if (thread->threadAllocatedOnStack == 1)
+                    _PR_FreeStack(thread->stack);
+                else {
+                    PR_DELETE(thread);
+                }
+                PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+                return NULL;
+            }
+
+            if (_PR_MD_NEW_LOCK(&thread->threadLock) == PR_FAILURE) {
+                if (thread->threadAllocatedOnStack == 1)
+                    _PR_FreeStack(thread->stack);
+                else {
+                    PR_DELETE(thread->privateData);
+                    PR_DELETE(thread);
+                }
+                PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
+                return NULL;
+            }
+
+            _PR_MD_INIT_CONTEXT(thread, top, _PR_UserRunThread, &status);
+
+            if (status == PR_FALSE) {
+                _PR_MD_FREE_LOCK(&thread->threadLock);
+                if (thread->threadAllocatedOnStack == 1)
+                    _PR_FreeStack(thread->stack);
+                else {
+                    PR_DELETE(thread->privateData);
+                    PR_DELETE(thread);
+                }
+                return NULL;
+            }
+
+            /* 
+              Set thread flags related to scope and joinable state. If joinable
+              thread, allocate a "termination" condition variable.
+            */
+            if (state == PR_JOINABLE_THREAD) {
+                thread->term = PR_NewCondVar(_pr_terminationCVLock);
+                if (thread->term == NULL) {
+                    _PR_MD_FREE_LOCK(&thread->threadLock);
+                    if (thread->threadAllocatedOnStack == 1)
+                        _PR_FreeStack(thread->stack);
+                    else {
+                        PR_DELETE(thread->privateData);
+                        PR_DELETE(thread);
+                    }
+                    return NULL;
+                }
+            }
+  
+        }
+  
+        /* Update thread type counter */
+        PR_Lock(_pr_activeLock);
+        thread->flags = flags;
+        thread->id = ++_pr_utid;
+        if (type == PR_SYSTEM_THREAD) {
+            thread->flags |= _PR_SYSTEM;
+            _pr_systemActive++;
+        } else {
+            _pr_userActive++;
+        }
+
+        /* Make thread runnable */
+        thread->state = _PR_RUNNABLE;
+    /*
+     * Add to list of active threads
+     */
+        PR_Unlock(_pr_activeLock);
+
+        if ((! (thread->flags & _PR_IDLE_THREAD)) && _PR_IS_NATIVE_THREAD(me) )
+            thread->cpu = _PR_GetPrimordialCPU();
+        else
+            thread->cpu = _PR_MD_CURRENT_CPU();
+
+        PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread));
+
+        if ((! (thread->flags & _PR_IDLE_THREAD)) && !_PR_IS_NATIVE_THREAD(me)) {
+            _PR_INTSOFF(is);
+            _PR_RUNQ_LOCK(thread->cpu);
+            _PR_ADD_RUNQ(thread, thread->cpu, priority);
+            _PR_RUNQ_UNLOCK(thread->cpu);
+        }
+
+        if (thread->flags & _PR_IDLE_THREAD) {
+            /*
+            ** If the creating thread is a kernel thread, we need to
+            ** awaken the user thread idle thread somehow; potentially
+            ** it could be sleeping in its idle loop, and we need to poke
+            ** it.  To do so, wake the idle thread...  
+            */
+            _PR_MD_WAKEUP_WAITER(NULL);
+        } else if (_PR_IS_NATIVE_THREAD(me)) {
+            _PR_MD_WAKEUP_WAITER(thread);
+        }
+        if ((! (thread->flags & _PR_IDLE_THREAD)) && !_PR_IS_NATIVE_THREAD(me) )
+            _PR_INTSON(is);
+    }
+
+    return thread;
+}
+
+PR_IMPLEMENT(PRThread*) PR_CreateThread(PRThreadType type,
+                     void (*start)(void *arg),
+                     void *arg,
+                     PRThreadPriority priority,
+                     PRThreadScope scope,
+                     PRThreadState state,
+                     PRUint32 stackSize)
+{
+    return _PR_CreateThread(type, start, arg, priority, scope, state, 
+                            stackSize, 0);
+}
+
+/*
+** Associate a thread object with an existing native thread.
+**     "type" is the type of thread object to attach
+**     "priority" is the priority to assign to the thread
+**     "stack" defines the shape of the threads stack
+**
+** This can return NULL if some kind of error occurs, or if memory is
+** tight.
+**
+** This call is not normally needed unless you create your own native
+** thread. PR_Init does this automatically for the primordial thread.
+*/
+PRThread* _PRI_AttachThread(PRThreadType type,
+    PRThreadPriority priority, PRThreadStack *stack, PRUint32 flags)
+{
+    PRThread *thread;
+
+    if ((thread = _PR_MD_GET_ATTACHED_THREAD()) != NULL) {
+        return thread;
+    }
+    _PR_MD_SET_CURRENT_THREAD(NULL);
+
+    /* Clear out any state if this thread was attached before */
+    _PR_MD_SET_CURRENT_CPU(NULL);
+
+    thread = _PR_AttachThread(type, priority, stack);
+    if (thread) {
+        PRIntn is;
+
+        _PR_MD_SET_CURRENT_THREAD(thread);
+
+        thread->flags = flags | _PR_GLOBAL_SCOPE | _PR_ATTACHED;
+
+        if (!stack) {
+            thread->stack = PR_NEWZAP(PRThreadStack);
+            if (!thread->stack) {
+                _PR_DestroyThread(thread);
+                return NULL;
+            }
+            thread->stack->stackSize = _MD_DEFAULT_STACK_SIZE;
+        }
+        PR_INIT_CLIST(&thread->links);
+
+        if (_PR_MD_INIT_ATTACHED_THREAD(thread) == PR_FAILURE) {
+                PR_DELETE(thread->stack);
+                _PR_DestroyThread(thread);
+                return NULL;
+        }
+
+        _PR_MD_SET_CURRENT_CPU(NULL);
+
+        if (_PR_MD_CURRENT_CPU()) {
+            _PR_INTSOFF(is);
+            PR_Lock(_pr_activeLock);
+        }
+        if (type == PR_SYSTEM_THREAD) {
+            thread->flags |= _PR_SYSTEM;
+            _pr_systemActive++;
+        } else {
+            _pr_userActive++;
+        }
+        if (_PR_MD_CURRENT_CPU()) {
+            PR_Unlock(_pr_activeLock);
+            _PR_INTSON(is);
+        }
+    }
+    return thread;
+}
+
+PR_IMPLEMENT(PRThread*) PR_AttachThread(PRThreadType type,
+    PRThreadPriority priority, PRThreadStack *stack)
+{
+#ifdef XP_MAC
+#pragma unused( type, priority, stack )
+#endif
+    return PR_GetCurrentThread();
+}
+
+PR_IMPLEMENT(void) PR_DetachThread(void)
+{
+    /*
+     * On IRIX, Solaris, and Windows, foreign threads are detached when
+     * they terminate.
+     */
+#if !defined(IRIX) && !defined(WIN32) \
+        && !(defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY))
+    PRThread *me;
+    if (_pr_initialized) {
+        me = _PR_MD_GET_ATTACHED_THREAD();
+        if ((me != NULL) && (me->flags & _PR_ATTACHED))
+            _PRI_DetachThread();
+    }
+#endif
+}
+
+void _PRI_DetachThread(void)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+	if (me->flags & _PR_PRIMORDIAL) {
+		/*
+		 * ignore, if primordial thread
+		 */
+		return;
+	}
+    PR_ASSERT(me->flags & _PR_ATTACHED);
+    PR_ASSERT(_PR_IS_NATIVE_THREAD(me));
+    _PR_CleanupThread(me);
+    PR_DELETE(me->privateData);
+
+    _PR_DecrActiveThreadCount(me);
+
+    _PR_MD_CLEAN_THREAD(me);
+    _PR_MD_SET_CURRENT_THREAD(NULL);
+    if (!me->threadAllocatedOnStack) 
+        PR_DELETE(me->stack);
+    _PR_MD_FREE_LOCK(&me->threadLock);
+    PR_DELETE(me);
+}
+
+/*
+** Wait for thread termination:
+**     "thread" is the target thread 
+**
+** This can return PR_FAILURE if no joinable thread could be found 
+** corresponding to the specified target thread.
+**
+** The calling thread is suspended until the target thread completes.
+** Several threads cannot wait for the same thread to complete; one thread
+** will complete successfully and others will terminate with an error PR_FAILURE.
+** The calling thread will not be blocked if the target thread has already
+** terminated.
+*/
+PR_IMPLEMENT(PRStatus) PR_JoinThread(PRThread *thread)
+{
+    PRIntn is;
+    PRCondVar *term;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSOFF(is);
+    term = thread->term;
+    /* can't join a non-joinable thread */
+    if (term == NULL) {
+        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+        goto ErrorExit;
+    }
+
+    /* multiple threads can't wait on the same joinable thread */
+    if (term->condQ.next != &term->condQ) {
+        goto ErrorExit;
+    }
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSON(is);
+
+    /* wait for the target thread's termination cv invariant */
+    PR_Lock (_pr_terminationCVLock);
+    while (thread->state != _PR_JOIN_WAIT) {
+        (void) PR_WaitCondVar(term, PR_INTERVAL_NO_TIMEOUT);
+    }
+    (void) PR_Unlock (_pr_terminationCVLock);
+    
+    /* 
+     Remove target thread from global waiting to join Q; make it runnable
+     again and put it back on its run Q.  When it gets scheduled later in
+     _PR_RunThread code, it will clean up its stack.
+    */    
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSOFF(is);
+    thread->state = _PR_RUNNABLE;
+    if ( !_PR_IS_NATIVE_THREAD(thread) ) {
+        _PR_THREAD_LOCK(thread);
+
+        _PR_MISCQ_LOCK(thread->cpu);
+        _PR_DEL_JOINQ(thread);
+        _PR_MISCQ_UNLOCK(thread->cpu);
+
+        _PR_AddThreadToRunQ(me, thread);
+        _PR_THREAD_UNLOCK(thread);
+    }
+    if (!_PR_IS_NATIVE_THREAD(me))
+        _PR_INTSON(is);
+
+    _PR_MD_WAKEUP_WAITER(thread);
+
+    return PR_SUCCESS;
+
+ErrorExit:
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
+    return PR_FAILURE;   
+}
+
+PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thread,
+    PRThreadPriority newPri)
+{
+
+    /* 
+    First, pin down the priority.  Not all compilers catch passing out of
+    range enum here.  If we let bad values thru, priority queues won't work.
+    */
+    if ((PRIntn)newPri > (PRIntn)PR_PRIORITY_LAST) {
+        newPri = PR_PRIORITY_LAST;
+    } else if ((PRIntn)newPri < (PRIntn)PR_PRIORITY_FIRST) {
+        newPri = PR_PRIORITY_FIRST;
+    }
+        
+    if ( _PR_IS_NATIVE_THREAD(thread) ) {
+        thread->priority = newPri;
+        _PR_MD_SET_PRIORITY(&(thread->md), newPri);
+    } else _PR_SetThreadPriority(thread, newPri);
+}
+
+
+/*
+** This routine prevents all other threads from running. This call is needed by 
+** the garbage collector.
+*/
+PR_IMPLEMENT(void) PR_SuspendAll(void)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRCList *qp;
+
+    /*
+     * Stop all user and native threads which are marked GC able.
+     */
+    PR_Lock(_pr_activeLock);
+    suspendAllOn = PR_TRUE;
+    suspendAllThread = _PR_MD_CURRENT_THREAD();
+    _PR_MD_BEGIN_SUSPEND_ALL();
+    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
+        qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) {
+        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && 
+            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp))) {
+            _PR_Suspend(_PR_ACTIVE_THREAD_PTR(qp));
+                PR_ASSERT((_PR_ACTIVE_THREAD_PTR(qp))->state != _PR_RUNNING);
+            }
+    }
+    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
+        qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) {
+        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) &&
+            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp)))
+            /* PR_Suspend(_PR_ACTIVE_THREAD_PTR(qp)); */
+                _PR_MD_SUSPEND_THREAD(_PR_ACTIVE_THREAD_PTR(qp)); 
+    }
+    _PR_MD_END_SUSPEND_ALL();
+}
+
+/*
+** This routine unblocks all other threads that were suspended from running by 
+** PR_SuspendAll(). This call is needed by the garbage collector.
+*/
+PR_IMPLEMENT(void) PR_ResumeAll(void)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    PRCList *qp;
+
+    /*
+     * Resume all user and native threads which are marked GC able.
+     */
+    _PR_MD_BEGIN_RESUME_ALL();
+    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
+        qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp->next) {
+        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) && 
+            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp)))
+            _PR_Resume(_PR_ACTIVE_THREAD_PTR(qp));
+    }
+    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
+        qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp->next) {
+        if ((me != _PR_ACTIVE_THREAD_PTR(qp)) &&
+            _PR_IS_GCABLE_THREAD(_PR_ACTIVE_THREAD_PTR(qp)))
+                _PR_MD_RESUME_THREAD(_PR_ACTIVE_THREAD_PTR(qp));
+    }
+    _PR_MD_END_RESUME_ALL();
+    suspendAllThread = NULL;
+    suspendAllOn = PR_FALSE;
+    PR_Unlock(_pr_activeLock);
+}
+
+PR_IMPLEMENT(PRStatus) PR_EnumerateThreads(PREnumerator func, void *arg)
+{
+    PRCList *qp, *qp_next;
+    PRIntn i = 0;
+    PRStatus rv = PR_SUCCESS;
+    PRThread* t;
+
+    /*
+    ** Currently Enumerate threads happen only with suspension and
+    ** pr_activeLock held
+    */
+    PR_ASSERT(suspendAllOn);
+
+    /* Steve Morse, 4-23-97: Note that we can't walk a queue by taking
+     * qp->next after applying the function "func".  In particular, "func"
+     * might remove the thread from the queue and put it into another one in
+     * which case qp->next no longer points to the next entry in the original
+     * queue.
+     *
+     * To get around this problem, we save qp->next in qp_next before applying
+     * "func" and use that saved value as the next value after applying "func".
+     */
+
+    /*
+     * Traverse the list of local and global threads
+     */
+    for (qp = _PR_ACTIVE_LOCAL_THREADQ().next;
+         qp != &_PR_ACTIVE_LOCAL_THREADQ(); qp = qp_next)
+    {
+        qp_next = qp->next;
+        t = _PR_ACTIVE_THREAD_PTR(qp);
+        if (_PR_IS_GCABLE_THREAD(t))
+        {
+            rv = (*func)(t, i, arg);
+            if (rv != PR_SUCCESS)
+                return rv;
+            i++;
+        }
+    }
+    for (qp = _PR_ACTIVE_GLOBAL_THREADQ().next;
+         qp != &_PR_ACTIVE_GLOBAL_THREADQ(); qp = qp_next)
+    {
+        qp_next = qp->next;
+        t = _PR_ACTIVE_THREAD_PTR(qp);
+        if (_PR_IS_GCABLE_THREAD(t))
+        {
+            rv = (*func)(t, i, arg);
+            if (rv != PR_SUCCESS)
+                return rv;
+            i++;
+        }
+    }
+    return rv;
+}
+
+/* FUNCTION: _PR_AddSleepQ
+** DESCRIPTION:
+**    Adds a thread to the sleep/pauseQ.
+** RESTRICTIONS:
+**    Caller must have the RUNQ lock.
+**    Caller must be a user level thread
+*/
+PR_IMPLEMENT(void)
+_PR_AddSleepQ(PRThread *thread, PRIntervalTime timeout)
+{
+    _PRCPU *cpu = thread->cpu;
+
+    if (timeout == PR_INTERVAL_NO_TIMEOUT) {
+        /* append the thread to the global pause Q */
+        PR_APPEND_LINK(&thread->links, &_PR_PAUSEQ(thread->cpu));
+        thread->flags |= _PR_ON_PAUSEQ;
+    } else {
+        PRIntervalTime sleep;
+        PRCList *q;
+        PRThread *t;
+
+        /* sort onto global sleepQ */
+        sleep = timeout;
+
+        /* Check if we are longest timeout */
+        if (timeout >= _PR_SLEEPQMAX(cpu)) {
+            PR_INSERT_BEFORE(&thread->links, &_PR_SLEEPQ(cpu));
+            thread->sleep = timeout - _PR_SLEEPQMAX(cpu);
+            _PR_SLEEPQMAX(cpu) = timeout;
+        } else {
+            /* Sort thread into global sleepQ at appropriate point */
+            q = _PR_SLEEPQ(cpu).next;
+
+            /* Now scan the list for where to insert this entry */
+            while (q != &_PR_SLEEPQ(cpu)) {
+                t = _PR_THREAD_PTR(q);
+                if (sleep < t->sleep) {
+                    /* Found sleeper to insert in front of */
+                    break;
+                }
+                sleep -= t->sleep;
+                q = q->next;
+            }
+            thread->sleep = sleep;
+            PR_INSERT_BEFORE(&thread->links, q);
+
+            /*
+            ** Subtract our sleep time from the sleeper that follows us (there
+            ** must be one) so that they remain relative to us.
+            */
+            PR_ASSERT (thread->links.next != &_PR_SLEEPQ(cpu));
+          
+            t = _PR_THREAD_PTR(thread->links.next);
+            PR_ASSERT(_PR_THREAD_PTR(t->links.prev) == thread);
+            t->sleep -= sleep;
+        }
+
+        thread->flags |= _PR_ON_SLEEPQ;
+    }
+}
+
+/* FUNCTION: _PR_DelSleepQ
+** DESCRIPTION:
+**    Removes a thread from the sleep/pauseQ.
+** INPUTS:
+**    If propogate_time is true, then the thread following the deleted
+**    thread will be get the time from the deleted thread.  This is used
+**    when deleting a sleeper that has not timed out.
+** RESTRICTIONS:
+**    Caller must have the RUNQ lock.
+**    Caller must be a user level thread
+*/
+PR_IMPLEMENT(void)
+_PR_DelSleepQ(PRThread *thread, PRBool propogate_time)
+{
+    _PRCPU *cpu = thread->cpu;
+
+    /* Remove from pauseQ/sleepQ */
+    if (thread->flags & (_PR_ON_PAUSEQ|_PR_ON_SLEEPQ)) {
+        if (thread->flags & _PR_ON_SLEEPQ) {
+            PRCList *q = thread->links.next;
+            if (q != &_PR_SLEEPQ(cpu)) {
+                if (propogate_time == PR_TRUE) {
+                    PRThread *after = _PR_THREAD_PTR(q);
+                    after->sleep += thread->sleep;
+                } else 
+                    _PR_SLEEPQMAX(cpu) -= thread->sleep;
+            } else {
+                /* Check if prev is the beggining of the list; if so,
+                 * we are the only element on the list.  
+                 */
+                if (thread->links.prev != &_PR_SLEEPQ(cpu))
+                    _PR_SLEEPQMAX(cpu) -= thread->sleep;
+                else
+                    _PR_SLEEPQMAX(cpu) = 0;
+            }
+            thread->flags &= ~_PR_ON_SLEEPQ;
+        } else {
+            thread->flags &= ~_PR_ON_PAUSEQ;
+        }
+        PR_REMOVE_LINK(&thread->links);
+    } else 
+        PR_ASSERT(0);
+}
+
+void
+_PR_AddThreadToRunQ(
+    PRThread *me,     /* the current thread */
+    PRThread *thread) /* the local thread to be added to a run queue */
+{
+    PRThreadPriority pri = thread->priority;
+    _PRCPU *cpu = thread->cpu;
+
+    PR_ASSERT(!_PR_IS_NATIVE_THREAD(thread));
+
+#if defined(WINNT)
+    /*
+     * On NT, we can only reliably know that the current CPU
+     * is not idle.  We add the awakened thread to the run
+     * queue of its CPU if its CPU is the current CPU.
+     * For any other CPU, we don't really know whether it
+     * is busy or idle.  So in all other cases, we just
+     * "post" the awakened thread to the IO completion port
+     * for the next idle CPU to execute (this is done in
+     * _PR_MD_WAKEUP_WAITER).
+	 * Threads with a suspended I/O operation remain bound to
+	 * the same cpu until I/O is cancelled
+     *
+     * NOTE: the boolean expression below must be the exact
+     * opposite of the corresponding boolean expression in
+     * _PR_MD_WAKEUP_WAITER.
+     */
+    if ((!_PR_IS_NATIVE_THREAD(me) && (cpu == me->cpu)) ||
+					(thread->md.thr_bound_cpu)) {
+		PR_ASSERT(!thread->md.thr_bound_cpu ||
+							(thread->md.thr_bound_cpu == cpu));
+        _PR_RUNQ_LOCK(cpu);
+        _PR_ADD_RUNQ(thread, cpu, pri);
+        _PR_RUNQ_UNLOCK(cpu);
+    }
+#else
+    _PR_RUNQ_LOCK(cpu);
+    _PR_ADD_RUNQ(thread, cpu, pri);
+    _PR_RUNQ_UNLOCK(cpu);
+    if (!_PR_IS_NATIVE_THREAD(me) && (cpu == me->cpu)) {
+        if (pri > me->priority) {
+            _PR_SET_RESCHED_FLAG();
+        }
+    }
+#endif
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prcmon.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prcmon.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,410 @@
+/* -*- 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 <stdlib.h>
+#include <stddef.h>
+
+/* Lock used to lock the monitor cache */
+#ifdef _PR_NO_PREEMPT
+#define _PR_NEW_LOCK_MCACHE()
+#define _PR_LOCK_MCACHE()
+#define _PR_UNLOCK_MCACHE()
+#else
+#ifdef _PR_LOCAL_THREADS_ONLY
+#define _PR_NEW_LOCK_MCACHE()
+#define _PR_LOCK_MCACHE() { PRIntn _is; _PR_INTSOFF(_is)
+#define _PR_UNLOCK_MCACHE() _PR_INTSON(_is); }
+#else
+PRLock *_pr_mcacheLock;
+#define _PR_NEW_LOCK_MCACHE() (_pr_mcacheLock = PR_NewLock())
+#define _PR_LOCK_MCACHE() PR_Lock(_pr_mcacheLock)
+#define _PR_UNLOCK_MCACHE() PR_Unlock(_pr_mcacheLock)
+#endif
+#endif
+
+/************************************************************************/
+
+typedef struct MonitorCacheEntryStr MonitorCacheEntry;
+
+struct MonitorCacheEntryStr {
+    MonitorCacheEntry*  next;
+    void*               address;
+    PRMonitor*          mon;
+    long                cacheEntryCount;
+};
+
+static PRUint32 hash_mask;
+static PRUintn num_hash_buckets;
+static PRUintn num_hash_buckets_log2;
+static MonitorCacheEntry **hash_buckets;
+static MonitorCacheEntry *free_entries;
+static PRUintn num_free_entries;
+static PRBool expanding;
+int _pr_mcache_ready;
+
+static void (*OnMonitorRecycle)(void *address);
+
+#define HASH(address)                               \
+    ((PRUint32) ( ((PRUptrdiff)(address) >> 2) ^    \
+                  ((PRUptrdiff)(address) >> 10) )   \
+     & hash_mask)
+
+/*
+** Expand the monitor cache. This grows the hash buckets and allocates a
+** new chunk of cache entries and throws them on the free list. We keep
+** as many hash buckets as there are entries.
+**
+** Because we call malloc and malloc may need the monitor cache, we must
+** ensure that there are several free monitor cache entries available for
+** malloc to get. FREE_THRESHOLD is used to prevent monitor cache
+** starvation during monitor cache expansion.
+*/
+
+#define FREE_THRESHOLD  5
+
+static PRStatus ExpandMonitorCache(PRUintn new_size_log2)
+{
+    MonitorCacheEntry **old_hash_buckets, *p;
+    PRUintn i, entries, old_num_hash_buckets, added;
+    MonitorCacheEntry **new_hash_buckets, *new_entries;
+
+    entries = 1L << new_size_log2;
+
+    /*
+    ** Expand the monitor-cache-entry free list
+    */
+    new_entries = (MonitorCacheEntry*)
+        PR_CALLOC(entries * sizeof(MonitorCacheEntry));
+    if (NULL == new_entries) return PR_FAILURE;
+
+    /*
+    ** Allocate system monitors for the new monitor cache entries. If we
+    ** run out of system monitors, break out of the loop.
+    */
+    for (i = 0, added = 0, p = new_entries; i < entries; i++, p++, added++) {
+        p->mon = PR_NewMonitor();
+        if (!p->mon)
+            break;
+    }
+    if (added != entries) {
+        if (added == 0) {
+            /* Totally out of system monitors. Lossage abounds */
+            PR_DELETE(new_entries);
+            return PR_FAILURE;
+        }
+
+        /*
+        ** We were able to allocate some of the system monitors. Use
+        ** realloc to shrink down the new_entries memory
+        */
+        p = (MonitorCacheEntry*)
+            PR_REALLOC(new_entries, added * sizeof(MonitorCacheEntry));
+        if (p == 0) {
+            /*
+            ** Total lossage. We just leaked a bunch of system monitors
+            ** all over the floor. This should never ever happen.
+            */
+            PR_ASSERT(p != 0);
+            return PR_FAILURE;
+        }
+    }
+
+    /*
+    ** Now that we have allocated all of the system monitors, build up
+    ** the new free list. We can just update the free_list because we own
+    ** the mcache-lock and we aren't calling anyone who might want to use
+    ** it.
+    */
+    for (i = 0, p = new_entries; i < added - 1; i++, p++)
+        p->next = p + 1;
+    p->next = free_entries;
+    free_entries = new_entries;
+    num_free_entries += added;
+
+    /* Try to expand the hash table */
+    new_hash_buckets = (MonitorCacheEntry**)
+        PR_CALLOC(entries * sizeof(MonitorCacheEntry*));
+    if (NULL == new_hash_buckets) {
+        /*
+        ** Partial lossage. In this situation we don't get any more hash
+        ** buckets, which just means that the table lookups will take
+        ** longer. This is bad, but not fatal
+        */
+        PR_LOG(_pr_cmon_lm, PR_LOG_WARNING,
+               ("unable to grow monitor cache hash buckets"));
+        return PR_SUCCESS;
+    }
+
+    /*
+    ** Compute new hash mask value. This value is used to mask an address
+    ** until it's bits are in the right spot for indexing into the hash
+    ** table.
+    */
+    hash_mask = entries - 1;
+
+    /*
+    ** Expand the hash table. We have to rehash everything in the old
+    ** table into the new table.
+    */
+    old_hash_buckets = hash_buckets;
+    old_num_hash_buckets = num_hash_buckets;
+    for (i = 0; i < old_num_hash_buckets; i++) {
+        p = old_hash_buckets[i];
+        while (p) {
+            MonitorCacheEntry *next = p->next;
+
+            /* Hash based on new table size, and then put p in the new table */
+            PRUintn hash = HASH(p->address);
+            p->next = new_hash_buckets[hash];
+            new_hash_buckets[hash] = p;
+
+            p = next;
+        }
+    }
+
+    /*
+    ** Switch over to new hash table and THEN call free of the old
+    ** table. Since free might re-enter _pr_mcache_lock, things would
+    ** break terribly if it used the old hash table.
+    */
+    hash_buckets = new_hash_buckets;
+    num_hash_buckets = entries;
+    num_hash_buckets_log2 = new_size_log2;
+    PR_DELETE(old_hash_buckets);
+
+    PR_LOG(_pr_cmon_lm, PR_LOG_NOTICE,
+           ("expanded monitor cache to %d (buckets %d)",
+            num_free_entries, entries));
+
+    return PR_SUCCESS;
+}  /* ExpandMonitorCache */
+
+/*
+** Lookup a monitor cache entry by address. Return a pointer to the
+** pointer to the monitor cache entry on success, null on failure.
+*/
+static MonitorCacheEntry **LookupMonitorCacheEntry(void *address)
+{
+    PRUintn hash;
+    MonitorCacheEntry **pp, *p;
+
+    hash = HASH(address);
+    pp = hash_buckets + hash;
+    while ((p = *pp) != 0) {
+        if (p->address == address) {
+            if (p->cacheEntryCount > 0)
+                return pp;
+            return NULL;
+        }
+        pp = &p->next;
+    }
+    return NULL;
+}
+
+/*
+** Try to create a new cached monitor. If it's already in the cache,
+** great - return it. Otherwise get a new free cache entry and set it
+** up. If the cache free space is getting low, expand the cache.
+*/
+static PRMonitor *CreateMonitor(void *address)
+{
+    PRUintn hash;
+    MonitorCacheEntry **pp, *p;
+
+    hash = HASH(address);
+    pp = hash_buckets + hash;
+    while ((p = *pp) != 0) {
+        if (p->address == address) goto gotit;
+
+        pp = &p->next;
+    }
+
+    /* Expand the monitor cache if we have run out of free slots in the table */
+    if (num_free_entries < FREE_THRESHOLD) {
+        /* Expand monitor cache */
+
+        /*
+        ** This function is called with the lock held. So what's the 'expanding'
+        ** boolean all about? Seems a bit redundant.
+        */
+        if (!expanding) {
+            PRStatus rv;
+
+            expanding = PR_TRUE;
+            rv = ExpandMonitorCache(num_hash_buckets_log2 + 1);
+            expanding = PR_FALSE;
+            if (PR_FAILURE == rv)  return NULL;
+
+            /* redo the hash because it'll be different now */
+            hash = HASH(address);
+        } else {
+            /*
+            ** We are in process of expanding and we need a cache
+            ** monitor.  Make sure we have enough!
+            */
+            PR_ASSERT(num_free_entries > 0);
+        }
+    }
+
+    /* Make a new monitor */
+    p = free_entries;
+    free_entries = p->next;
+    num_free_entries--;
+    if (OnMonitorRecycle && p->address)
+        OnMonitorRecycle(p->address);
+    p->address = address;
+    p->next = hash_buckets[hash];
+    hash_buckets[hash] = p;
+    PR_ASSERT(p->cacheEntryCount == 0);
+
+  gotit:
+    p->cacheEntryCount++;
+    return p->mon;
+}
+
+/*
+** Initialize the monitor cache
+*/
+void _PR_InitCMon(void)
+{
+    _PR_NEW_LOCK_MCACHE();
+    ExpandMonitorCache(3);
+    _pr_mcache_ready = 1;
+}
+
+/*
+** Create monitor for address. Don't enter the monitor while we have the
+** mcache locked because we might block!
+*/
+PR_IMPLEMENT(PRMonitor*) PR_CEnterMonitor(void *address)
+{
+    PRMonitor *mon;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    _PR_LOCK_MCACHE();
+    mon = CreateMonitor(address);
+    _PR_UNLOCK_MCACHE();
+
+    if (!mon) return NULL;
+
+    PR_EnterMonitor(mon);
+    return mon;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CExitMonitor(void *address)
+{
+    MonitorCacheEntry **pp, *p;
+    PRStatus status = PR_SUCCESS;
+
+    _PR_LOCK_MCACHE();
+    pp = LookupMonitorCacheEntry(address);
+    if (pp != NULL) {
+        p = *pp;
+        if (--p->cacheEntryCount == 0) {
+            /*
+            ** Nobody is using the system monitor. Put it on the cached free
+            ** list. We are safe from somebody trying to use it because we
+            ** have the mcache locked.
+            */
+            p->address = 0;             /* defensive move */
+            *pp = p->next;              /* unlink from hash_buckets */
+            p->next = free_entries;     /* link into free list */
+            free_entries = p;
+            num_free_entries++;         /* count it as free */
+        }
+        status = PR_ExitMonitor(p->mon);
+    } else {
+        status = PR_FAILURE;
+    }
+    _PR_UNLOCK_MCACHE();
+
+    return status;
+}
+
+PR_IMPLEMENT(PRStatus) PR_CWait(void *address, PRIntervalTime ticks)
+{
+    MonitorCacheEntry **pp;
+    PRMonitor *mon;
+
+    _PR_LOCK_MCACHE();
+    pp = LookupMonitorCacheEntry(address);
+    mon = pp ? ((*pp)->mon) : NULL;
+    _PR_UNLOCK_MCACHE();
+
+    if (mon == NULL)
+        return PR_FAILURE;
+    return PR_Wait(mon, ticks);
+}
+
+PR_IMPLEMENT(PRStatus) PR_CNotify(void *address)
+{
+    MonitorCacheEntry **pp;
+    PRMonitor *mon;
+
+    _PR_LOCK_MCACHE();
+    pp = LookupMonitorCacheEntry(address);
+    mon = pp ? ((*pp)->mon) : NULL;
+    _PR_UNLOCK_MCACHE();
+
+    if (mon == NULL)
+        return PR_FAILURE;
+    return PR_Notify(mon);
+}
+
+PR_IMPLEMENT(PRStatus) PR_CNotifyAll(void *address)
+{
+    MonitorCacheEntry **pp;
+    PRMonitor *mon;
+
+    _PR_LOCK_MCACHE();
+    pp = LookupMonitorCacheEntry(address);
+    mon = pp ? ((*pp)->mon) : NULL;
+    _PR_UNLOCK_MCACHE();
+
+    if (mon == NULL)
+        return PR_FAILURE;
+    return PR_NotifyAll(mon);
+}
+
+PR_IMPLEMENT(void)
+PR_CSetOnMonitorRecycle(void (*callback)(void *address))
+{
+    OnMonitorRecycle = callback;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prcthr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prcthr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,446 @@
+/* -*- 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"
+
+#if defined(WIN95)
+/*
+** Some local variables report warnings on Win95 because the code paths 
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+** 
+*/
+#pragma warning(disable : 4101)
+#endif
+
+
+extern PRLock *_pr_sleeplock;  /* allocated and initialized in prinit */
+/* 
+** Routines common to both native and user threads.
+**
+**
+** Clean up a thread object, releasing all of the attached data. Do not
+** free the object itself (it may not have been malloc'd)
+*/
+void _PR_CleanupThread(PRThread *thread)
+{
+    /* Free up per-thread-data */
+    _PR_DestroyThreadPrivate(thread);
+
+    /* Free any thread dump procs */
+    if (thread->dumpArg) {
+        PR_DELETE(thread->dumpArg);
+    }
+    thread->dump = 0;
+
+    PR_DELETE(thread->errorString);
+    thread->errorStringSize = 0;
+    thread->errorStringLength = 0;
+    thread->environment = NULL;
+}
+
+PR_IMPLEMENT(PRStatus) PR_Yield()
+{
+    static PRBool warning = PR_TRUE;
+    if (warning) warning = _PR_Obsolete(
+        "PR_Yield()", "PR_Sleep(PR_INTERVAL_NO_WAIT)");
+    return (PR_Sleep(PR_INTERVAL_NO_WAIT));
+}
+
+/*
+** Make the current thread sleep until "timeout" ticks amount of time
+** has expired. If "timeout" is PR_INTERVAL_NO_WAIT then the call is
+** equivalent to a yield. Waiting for an infinite amount of time is
+** allowed in the expectation that another thread will interrupt().
+**
+** A single lock is used for all threads calling sleep. Each caller
+** does get its own condition variable since each is expected to have
+** a unique 'timeout'.
+*/
+PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime timeout)
+{
+    PRStatus rv = PR_SUCCESS;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (PR_INTERVAL_NO_WAIT == timeout)
+    {
+        /*
+        ** This is a simple yield, nothing more, nothing less.
+        */
+        PRIntn is;
+        PRThread *me = PR_GetCurrentThread();
+        PRUintn pri = me->priority;
+        _PRCPU *cpu = _PR_MD_CURRENT_CPU();
+
+        if ( _PR_IS_NATIVE_THREAD(me) ) _PR_MD_YIELD();
+        else
+        {
+            _PR_INTSOFF(is);
+            _PR_RUNQ_LOCK(cpu);
+            if (_PR_RUNQREADYMASK(cpu) >> pri) {
+                me->cpu = cpu;
+                me->state = _PR_RUNNABLE;
+                _PR_ADD_RUNQ(me, cpu, pri);
+                _PR_RUNQ_UNLOCK(cpu);
+
+                PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("PR_Yield: yielding"));
+                _PR_MD_SWITCH_CONTEXT(me);
+                PR_LOG(_pr_sched_lm, PR_LOG_MIN, ("PR_Yield: done"));
+
+                _PR_FAST_INTSON(is);
+            }
+            else
+            {
+                _PR_RUNQ_UNLOCK(cpu);
+                _PR_INTSON(is);
+            }
+        }
+    }
+    else
+    {
+        /*
+        ** This is waiting for some finite period of time.
+        ** A thread in this state is interruptible (PR_Interrupt()),
+        ** but the lock and cvar used are local to the implementation
+        ** and not visible to the caller, therefore not notifiable.
+        */
+        PRCondVar *cv;
+        PRIntervalTime timein;
+
+        timein = PR_IntervalNow();
+        cv = PR_NewCondVar(_pr_sleeplock);
+        PR_ASSERT(cv != NULL);
+        PR_Lock(_pr_sleeplock);
+        do
+        {
+            PRIntervalTime delta = PR_IntervalNow() - timein;
+            if (delta > timeout) break;
+            rv = PR_WaitCondVar(cv, timeout - delta);
+        } while (rv == PR_SUCCESS);
+        PR_Unlock(_pr_sleeplock);
+        PR_DestroyCondVar(cv);
+    }
+    return rv;
+}
+
+PR_IMPLEMENT(PRUint32) PR_GetThreadID(PRThread *thread)
+{
+    return thread->id;
+}
+
+PR_IMPLEMENT(PRThreadPriority) PR_GetThreadPriority(const PRThread *thread)
+{
+    return (PRThreadPriority) thread->priority;
+}
+
+PR_IMPLEMENT(PRThread *) PR_GetCurrentThread()
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    return _PR_MD_CURRENT_THREAD();
+}
+
+/*
+** Set the interrupt flag for a thread. The thread will be unable to
+** block in i/o functions when this happens. Also, any PR_Wait's in
+** progress will be undone. The interrupt remains in force until
+** PR_ClearInterrupt is called.
+*/
+PR_IMPLEMENT(PRStatus) PR_Interrupt(PRThread *thread)
+{
+#ifdef _PR_GLOBAL_THREADS_ONLY
+    PRCondVar *victim;
+
+    _PR_THREAD_LOCK(thread);
+    thread->flags |= _PR_INTERRUPT;
+    victim = thread->wait.cvar;
+    _PR_THREAD_UNLOCK(thread);
+    if ((NULL != victim) && (!(thread->flags & _PR_INTERRUPT_BLOCKED))) {
+        int haveLock = (victim->lock->owner == _PR_MD_CURRENT_THREAD());
+
+        if (!haveLock) PR_Lock(victim->lock);
+        PR_NotifyAllCondVar(victim);
+        if (!haveLock) PR_Unlock(victim->lock);
+    }
+    return PR_SUCCESS;
+#else  /* ! _PR_GLOBAL_THREADS_ONLY */
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+            if (!_PR_IS_NATIVE_THREAD(me))
+            	_PR_INTSOFF(is);
+
+            _PR_THREAD_LOCK(thread);
+            thread->flags |= _PR_INTERRUPT;
+        switch (thread->state) {
+                case _PR_COND_WAIT:
+                        /*
+                         * call is made with thread locked;
+                         * on return lock is released
+                         */
+						if (!(thread->flags & _PR_INTERRUPT_BLOCKED))
+                        	_PR_NotifyLockedThread(thread);
+                        break;
+                case _PR_IO_WAIT:
+                        /*
+                         * Need to hold the thread lock when calling
+                         * _PR_Unblock_IO_Wait().  On return lock is
+                         * released. 
+                         */
+#if defined(XP_UNIX) || defined(WINNT) || defined(WIN16)
+						if (!(thread->flags & _PR_INTERRUPT_BLOCKED))
+                        	_PR_Unblock_IO_Wait(thread);
+#else
+                        _PR_THREAD_UNLOCK(thread);
+#endif
+                        break;
+                case _PR_RUNNING:
+                case _PR_RUNNABLE:
+                case _PR_LOCK_WAIT:
+                default:
+                            _PR_THREAD_UNLOCK(thread);
+                        break;
+        }
+            if (!_PR_IS_NATIVE_THREAD(me))
+            	_PR_INTSON(is);
+            return PR_SUCCESS;
+#endif  /* _PR_GLOBAL_THREADS_ONLY */
+}
+
+/*
+** Clear the interrupt flag for self.
+*/
+PR_IMPLEMENT(void) PR_ClearInterrupt()
+{
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+        if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(me);
+         me->flags &= ~_PR_INTERRUPT;
+    _PR_THREAD_UNLOCK(me);
+        if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
+}
+
+PR_IMPLEMENT(void) PR_BlockInterrupt()
+{
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(me);
+    _PR_THREAD_BLOCK_INTERRUPT(me);
+    _PR_THREAD_UNLOCK(me);
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
+}  /* PR_BlockInterrupt */
+
+PR_IMPLEMENT(void) PR_UnblockInterrupt()
+{
+    PRIntn is;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSOFF(is);
+    _PR_THREAD_LOCK(me);
+    _PR_THREAD_UNBLOCK_INTERRUPT(me);
+    _PR_THREAD_UNLOCK(me);
+    if ( !_PR_IS_NATIVE_THREAD(me)) _PR_INTSON(is);
+}  /* PR_UnblockInterrupt */
+
+/*
+** Return the thread stack pointer of the given thread.
+*/
+PR_IMPLEMENT(void *) PR_GetSP(PRThread *thread)
+{
+        return (void *)_PR_MD_GET_SP(thread);
+}
+
+PR_IMPLEMENT(void*) GetExecutionEnvironment(PRThread *thread)
+{
+        return thread->environment;
+}
+
+PR_IMPLEMENT(void) SetExecutionEnvironment(PRThread *thread, void *env)
+{
+        thread->environment = env;
+}
+
+
+PR_IMPLEMENT(PRInt32) PR_GetThreadAffinityMask(PRThread *thread, PRUint32 *mask)
+{
+#ifdef HAVE_THREAD_AFFINITY
+    return _PR_MD_GETTHREADAFFINITYMASK(thread, mask);
+#else
+
+#if defined(XP_MAC)
+#pragma unused (thread, mask)
+#endif
+
+    return 0;
+#endif
+}
+
+PR_IMPLEMENT(PRInt32) PR_SetThreadAffinityMask(PRThread *thread, PRUint32 mask )
+{
+#ifdef HAVE_THREAD_AFFINITY
+#ifndef IRIX
+    return _PR_MD_SETTHREADAFFINITYMASK(thread, mask);
+#else
+	return 0;
+#endif
+#else
+
+#if defined(XP_MAC)
+#pragma unused (thread, mask)
+#endif
+
+    return 0;
+#endif
+}
+
+/* This call is thread unsafe if another thread is calling SetConcurrency()
+ */
+PR_IMPLEMENT(PRInt32) PR_SetCPUAffinityMask(PRUint32 mask)
+{
+#ifdef HAVE_THREAD_AFFINITY
+    PRCList *qp;
+    extern PRUint32 _pr_cpu_affinity_mask;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    _pr_cpu_affinity_mask = mask;
+
+    qp = _PR_CPUQ().next;
+    while(qp != &_PR_CPUQ()) {
+        _PRCPU *cpu;
+
+        cpu = _PR_CPU_PTR(qp);
+        PR_SetThreadAffinityMask(cpu->thread, mask);
+
+        qp = qp->next;
+    }
+#endif
+
+#if defined(XP_MAC)
+#pragma unused (mask)
+#endif
+
+    return 0;
+}
+
+PRUint32 _pr_recycleThreads = 0;
+PR_IMPLEMENT(void) PR_SetThreadRecycleMode(PRUint32 count)
+{
+    _pr_recycleThreads = count;
+}
+
+PR_IMPLEMENT(PRThread*) PR_CreateThreadGCAble(PRThreadType type,
+                                     void (*start)(void *arg),
+                                     void *arg,
+                                     PRThreadPriority priority,
+                                     PRThreadScope scope,
+                                     PRThreadState state,
+                                     PRUint32 stackSize)
+{
+    return _PR_CreateThread(type, start, arg, priority, scope, state, 
+                            stackSize, _PR_GCABLE_THREAD);
+}
+
+#ifdef SOLARIS
+PR_IMPLEMENT(PRThread*) PR_CreateThreadBound(PRThreadType type,
+                                     void (*start)(void *arg),
+                                     void *arg,
+                                     PRUintn priority,
+                                     PRThreadScope scope,
+                                     PRThreadState state,
+                                     PRUint32 stackSize)
+{
+    return _PR_CreateThread(type, start, arg, priority, scope, state, 
+                            stackSize, _PR_BOUND_THREAD);
+}
+#endif
+
+
+PR_IMPLEMENT(PRThread*) PR_AttachThreadGCAble(
+    PRThreadType type, PRThreadPriority priority, PRThreadStack *stack)
+{
+#ifdef XP_MAC
+#pragma unused (type, priority, stack)
+#endif
+    /* $$$$ not sure how to finese this one */
+    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+    return NULL;
+}
+
+PR_IMPLEMENT(void) PR_SetThreadGCAble()
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    PR_Lock(_pr_activeLock);
+        _PR_MD_CURRENT_THREAD()->flags |= _PR_GCABLE_THREAD;
+        PR_Unlock(_pr_activeLock);        
+}
+
+PR_IMPLEMENT(void) PR_ClearThreadGCAble()
+{
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+    PR_Lock(_pr_activeLock);
+        _PR_MD_CURRENT_THREAD()->flags &= (~_PR_GCABLE_THREAD);
+        PR_Unlock(_pr_activeLock);
+}
+
+PR_IMPLEMENT(PRThreadScope) PR_GetThreadScope(const PRThread *thread)
+{
+#ifdef XP_MAC
+#pragma unused( thread )
+#endif
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    if (_PR_IS_NATIVE_THREAD(thread)) {
+    	return (thread->flags & _PR_BOUND_THREAD) ? PR_GLOBAL_BOUND_THREAD :
+										PR_GLOBAL_THREAD;
+    } else
+        return PR_LOCAL_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadType) PR_GetThreadType(const PRThread *thread)
+{
+    return (thread->flags & _PR_SYSTEM) ? PR_SYSTEM_THREAD : PR_USER_THREAD;
+}
+
+PR_IMPLEMENT(PRThreadState) PR_GetThreadState(const PRThread *thread)
+{
+    return (NULL == thread->term) ? PR_UNJOINABLE_THREAD : PR_JOINABLE_THREAD;
+}  /* PR_GetThreadState */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prdump.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prdump.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+#include "primpl.h"
+
+#if defined(WIN95)
+/*
+** Some local variables report warnings on Win95 because the code paths 
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+** 
+*/
+#pragma warning(disable : 4101)
+#endif
+
+/* XXX use unbuffered nspr stdio */
+
+PRFileDesc *_pr_dumpOut;
+
+PRUint32 _PR_DumpPrintf(PRFileDesc *fd, const char *fmt, ...)
+{
+    char buf[100];
+    PRUint32 nb;
+    va_list ap;
+
+    va_start(ap, fmt);
+    nb = PR_vsnprintf(buf, sizeof(buf), fmt, ap);
+    va_end(ap);
+    PR_Write(fd, buf, nb);
+
+    return nb;
+}
+
+void _PR_DumpThread(PRFileDesc *fd, PRThread *thread)
+{
+
+#ifndef _PR_GLOBAL_THREADS_ONLY
+    _PR_DumpPrintf(fd, "%05d[%08p] pri=%2d flags=0x%02x",
+                   thread->id, thread, thread->priority, thread->flags);
+    switch (thread->state) {
+      case _PR_RUNNABLE:
+      case _PR_RUNNING:
+        break;
+      case _PR_LOCK_WAIT:
+        _PR_DumpPrintf(fd, " lock=%p", thread->wait.lock);
+        break;
+      case _PR_COND_WAIT:
+        _PR_DumpPrintf(fd, " condvar=%p sleep=%lldms",
+                       thread->wait.cvar, thread->sleep);
+        break;
+      case _PR_SUSPENDED:
+        _PR_DumpPrintf(fd, " suspended");
+        break;
+    }
+    PR_Write(fd, "\n", 1);
+#endif
+
+    /* Now call dump routine */
+    if (thread->dump) {
+	thread->dump(fd, thread, thread->dumpArg);
+    }
+}
+
+static void DumpThreadQueue(PRFileDesc *fd, PRCList *list)
+{
+#ifndef _PR_GLOBAL_THREADS_ONLY
+    PRCList *q;
+
+    q = list->next;
+    while (q != list) {
+        PRThread *t = _PR_THREAD_PTR(q);
+        _PR_DumpThread(fd, t);
+        q = q->next;
+    }
+#endif
+}
+
+void _PR_DumpThreads(PRFileDesc *fd)
+{
+    PRThread *t;
+    PRIntn i;
+
+    _PR_DumpPrintf(fd, "Current Thread:\n");
+    t = _PR_MD_CURRENT_THREAD();
+    _PR_DumpThread(fd, t);
+
+    _PR_DumpPrintf(fd, "Runnable Threads:\n");
+    for (i = 0; i < 32; i++) {
+        DumpThreadQueue(fd, &_PR_RUNQ(t->cpu)[i]);
+    }
+
+    _PR_DumpPrintf(fd, "CondVar timed wait Threads:\n");
+    DumpThreadQueue(fd, &_PR_SLEEPQ(t->cpu));
+
+    _PR_DumpPrintf(fd, "CondVar wait Threads:\n");
+    DumpThreadQueue(fd, &_PR_PAUSEQ(t->cpu));
+
+    _PR_DumpPrintf(fd, "Suspended Threads:\n");
+    DumpThreadQueue(fd, &_PR_SUSPENDQ(t->cpu));
+}
+
+PR_IMPLEMENT(void) PR_ShowStatus(void)
+{
+    PRIntn is;
+
+    if ( _PR_MD_CURRENT_THREAD()
+    && !_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) _PR_INTSOFF(is);
+    _pr_dumpOut = _pr_stderr;
+    _PR_DumpThreads(_pr_dumpOut);
+    if ( _PR_MD_CURRENT_THREAD()
+    && !_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) _PR_FAST_INTSON(is);
+}
+
+PR_IMPLEMENT(void)
+PR_SetThreadDumpProc(PRThread* thread, PRThreadDumpProc dump, void *arg)
+{
+    thread->dump = dump;
+    thread->dumpArg = arg;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prmon.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prmon.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,222 @@
+/* -*- 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"
+
+/************************************************************************/
+
+/*
+** Create a new monitor.
+*/
+PR_IMPLEMENT(PRMonitor*) PR_NewMonitor()
+{
+    PRMonitor *mon;
+	PRCondVar *cvar;
+	PRLock *lock;
+
+    mon = PR_NEWZAP(PRMonitor);
+    if (mon) {
+		lock = PR_NewLock();
+	    if (!lock) {
+			PR_DELETE(mon);
+			return 0;
+    	}
+
+	    cvar = PR_NewCondVar(lock);
+	    if (!cvar) {
+	    	PR_DestroyLock(lock);
+			PR_DELETE(mon);
+			return 0;
+    	}
+    	mon->cvar = cvar;
+	mon->name = NULL;
+    }
+    return mon;
+}
+
+PR_IMPLEMENT(PRMonitor*) PR_NewNamedMonitor(const char* name)
+{
+    PRMonitor* mon = PR_NewMonitor();
+    if (mon)
+        mon->name = name;
+    return mon;
+}
+
+/*
+** Destroy a monitor. There must be no thread waiting on the monitor's
+** condition variable. The caller is responsible for guaranteeing that the
+** monitor is no longer in use.
+*/
+PR_IMPLEMENT(void) PR_DestroyMonitor(PRMonitor *mon)
+{
+	PR_DestroyLock(mon->cvar->lock);
+    PR_DestroyCondVar(mon->cvar);
+    PR_DELETE(mon);
+}
+
+/*
+** Enter the lock associated with the monitor.
+*/
+PR_IMPLEMENT(void) PR_EnterMonitor(PRMonitor *mon)
+{
+    if (mon->cvar->lock->owner == _PR_MD_CURRENT_THREAD()) {
+		mon->entryCount++;
+    } else {
+		PR_Lock(mon->cvar->lock);
+		mon->entryCount = 1;
+    }
+}
+
+/*
+** Test and then enter the lock associated with the monitor if it's not
+** already entered by some other thread. Return PR_FALSE if some other
+** thread owned the lock at the time of the call.
+*/
+PR_IMPLEMENT(PRBool) PR_TestAndEnterMonitor(PRMonitor *mon)
+{
+    if (mon->cvar->lock->owner == _PR_MD_CURRENT_THREAD()) {
+		mon->entryCount++;
+		return PR_TRUE;
+    } else {
+		if (PR_TestAndLock(mon->cvar->lock)) {
+	    	mon->entryCount = 1;
+	   	 	return PR_TRUE;
+		}
+    }
+    return PR_FALSE;
+}
+
+/*
+** Exit the lock associated with the monitor once.
+*/
+PR_IMPLEMENT(PRStatus) PR_ExitMonitor(PRMonitor *mon)
+{
+    if (mon->cvar->lock->owner != _PR_MD_CURRENT_THREAD()) {
+        return PR_FAILURE;
+    }
+    if (--mon->entryCount == 0) {
+		return PR_Unlock(mon->cvar->lock);
+    }
+    return PR_SUCCESS;
+}
+
+/*
+** Return the number of times that the current thread has entered the
+** lock. Returns zero if the current thread has not entered the lock.
+*/
+PR_IMPLEMENT(PRIntn) PR_GetMonitorEntryCount(PRMonitor *mon)
+{
+    return (mon->cvar->lock->owner == _PR_MD_CURRENT_THREAD()) ?
+        mon->entryCount : 0;
+}
+
+/*
+** Wait for a notify on the condition variable. Sleep for "ticks" amount
+** of time (if "tick" is 0 then the sleep is indefinite). While
+** the thread is waiting it exits the monitors lock (as if it called
+** PR_ExitMonitor as many times as it had called PR_EnterMonitor).  When
+** the wait has finished the thread regains control of the monitors lock
+** with the same entry count as before the wait began.
+**
+** The thread waiting on the monitor will be resumed when the monitor is
+** notified (assuming the thread is the next in line to receive the
+** notify) or when the "ticks" elapses.
+**
+** Returns PR_FAILURE if the caller has not locked the lock associated
+** with the condition variable.
+** This routine can return PR_PENDING_INTERRUPT if the waiting thread 
+** has been interrupted.
+*/
+PR_IMPLEMENT(PRStatus) PR_Wait(PRMonitor *mon, PRIntervalTime ticks)
+{
+    PRUintn entryCount;
+	PRStatus status;
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (mon->cvar->lock->owner != me) return PR_FAILURE;
+
+    entryCount = mon->entryCount;
+    mon->entryCount = 0;
+
+	status = _PR_WaitCondVar(me, mon->cvar, mon->cvar->lock, ticks);
+
+    mon->entryCount = entryCount;
+
+    return status;
+}
+
+/*
+** Notify the highest priority thread waiting on the condition
+** variable. If a thread is waiting on the condition variable (using
+** PR_Wait) then it is awakened and begins waiting on the monitor's lock.
+*/
+PR_IMPLEMENT(PRStatus) PR_Notify(PRMonitor *mon)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    if (mon->cvar->lock->owner != me) return PR_FAILURE;
+    PR_NotifyCondVar(mon->cvar);
+    return PR_SUCCESS;
+}
+
+/*
+** Notify all of the threads waiting on the condition variable. All of
+** threads are notified in turn. The highest priority thread will
+** probably acquire the monitor first when the monitor is exited.
+*/
+PR_IMPLEMENT(PRStatus) PR_NotifyAll(PRMonitor *mon)
+{
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+    if (mon->cvar->lock->owner != me) return PR_FAILURE;
+    PR_NotifyAllCondVar(mon->cvar);
+    return PR_SUCCESS;
+}
+
+/************************************************************************/
+
+PRUint32 _PR_MonitorToString(PRMonitor *mon, char *buf, PRUint32 buflen)
+{
+    PRUint32 nb;
+
+    if (mon->cvar->lock->owner) {
+	nb = PR_snprintf(buf, buflen, "[%p] owner=%d[%p] count=%ld",
+			 mon, mon->cvar->lock->owner->id,
+			 mon->cvar->lock->owner, mon->entryCount);
+    } else {
+	nb = PR_snprintf(buf, buflen, "[%p]", mon);
+    }
+    return nb;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prrwlock.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prrwlock.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,512 @@
+/* -*- 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 <string.h>
+
+#if defined(HPUX) && defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+
+#include <pthread.h>
+#define HAVE_UNIX98_RWLOCK
+#define RWLOCK_T pthread_rwlock_t
+#define RWLOCK_INIT(lock) pthread_rwlock_init(lock, NULL)
+#define RWLOCK_DESTROY(lock) pthread_rwlock_destroy(lock)
+#define RWLOCK_RDLOCK(lock) pthread_rwlock_rdlock(lock)
+#define RWLOCK_WRLOCK(lock) pthread_rwlock_wrlock(lock)
+#define RWLOCK_UNLOCK(lock) pthread_rwlock_unlock(lock)
+
+#elif defined(SOLARIS) && (defined(_PR_PTHREADS) \
+        || defined(_PR_GLOBAL_THREADS_ONLY))
+
+#include <synch.h>
+#define HAVE_UI_RWLOCK
+#define RWLOCK_T rwlock_t
+#define RWLOCK_INIT(lock) rwlock_init(lock, USYNC_THREAD, NULL)
+#define RWLOCK_DESTROY(lock) rwlock_destroy(lock)
+#define RWLOCK_RDLOCK(lock) rw_rdlock(lock)
+#define RWLOCK_WRLOCK(lock) rw_wrlock(lock)
+#define RWLOCK_UNLOCK(lock) rw_unlock(lock)
+
+#endif
+
+/*
+ * Reader-writer lock
+ */
+struct PRRWLock {
+	char			*rw_name;			/* lock name					*/
+	PRUint32		rw_rank;			/* rank of the lock				*/
+
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	RWLOCK_T		rw_lock;
+#else
+    PRLock			*rw_lock;
+	PRInt32			rw_lock_cnt;		/* ==  0, if unlocked			*/
+										/* == -1, if write-locked		*/
+										/* > 0	, # of read locks		*/
+	PRUint32		rw_reader_cnt;		/* number of waiting readers	*/
+	PRUint32		rw_writer_cnt;		/* number of waiting writers	*/
+	PRCondVar   	*rw_reader_waitq;	/* cvar for readers 			*/
+	PRCondVar   	*rw_writer_waitq;	/* cvar for writers				*/
+#ifdef DEBUG
+    PRThread 		*rw_owner;			/* lock owner for write-lock	*/
+#endif
+#endif
+};
+
+#ifdef DEBUG
+#define _PR_RWLOCK_RANK_ORDER_DEBUG	/* enable deadlock detection using
+									   rank-order for locks
+									*/
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+
+static PRUintn	pr_thread_rwlock_key;			/* TPD key for lock stack */
+static PRUintn	pr_thread_rwlock_alloc_failed;
+
+#define	_PR_RWLOCK_RANK_ORDER_LIMIT	10
+
+typedef struct thread_rwlock_stack {
+	PRInt32		trs_index;									/* top of stack */
+	PRRWLock	*trs_stack[_PR_RWLOCK_RANK_ORDER_LIMIT];	/* stack of lock
+														 	   pointers */
+
+} thread_rwlock_stack;
+
+static void _PR_SET_THREAD_RWLOCK_RANK(PRRWLock *rwlock);
+static PRUint32 _PR_GET_THREAD_RWLOCK_RANK(void);
+static void _PR_UNSET_THREAD_RWLOCK_RANK(PRRWLock *rwlock);
+static void _PR_RELEASE_LOCK_STACK(void *lock_stack);
+
+#endif
+
+/*
+ * Reader/Writer Locks
+ */
+
+/*
+ * PR_NewRWLock
+ *		Create a reader-writer lock, with the given lock rank and lock name
+ *	
+ */
+
+PR_IMPLEMENT(PRRWLock *)
+PR_NewRWLock(PRUint32 lock_rank, const char *lock_name)
+{
+    PRRWLock *rwlock;
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	int err;
+#endif
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    rwlock = PR_NEWZAP(PRRWLock);
+    if (rwlock == NULL)
+		return NULL;
+
+	rwlock->rw_rank = lock_rank;
+	if (lock_name != NULL) {
+		rwlock->rw_name = (char*) PR_Malloc(strlen(lock_name) + 1);
+    	if (rwlock->rw_name == NULL) {
+			PR_DELETE(rwlock);
+			return(NULL);
+		}
+		strcpy(rwlock->rw_name, lock_name);
+	} else {
+		rwlock->rw_name = NULL;
+	}
+	
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	err = RWLOCK_INIT(&rwlock->rw_lock);
+	if (err != 0) {
+		PR_SetError(PR_UNKNOWN_ERROR, err);
+		PR_Free(rwlock->rw_name);
+		PR_DELETE(rwlock);
+		return NULL;
+	}
+	return rwlock;
+#else
+	rwlock->rw_lock = PR_NewLock();
+    if (rwlock->rw_lock == NULL) {
+		goto failed;
+	}
+	rwlock->rw_reader_waitq = PR_NewCondVar(rwlock->rw_lock);
+    if (rwlock->rw_reader_waitq == NULL) {
+		goto failed;
+	}
+	rwlock->rw_writer_waitq = PR_NewCondVar(rwlock->rw_lock);
+    if (rwlock->rw_writer_waitq == NULL) {
+		goto failed;
+	}
+	rwlock->rw_reader_cnt = 0;
+	rwlock->rw_writer_cnt = 0;
+	rwlock->rw_lock_cnt = 0;
+	return rwlock;
+
+failed:
+	if (rwlock->rw_reader_waitq != NULL) {
+		PR_DestroyCondVar(rwlock->rw_reader_waitq);	
+	}
+	if (rwlock->rw_lock != NULL) {
+		PR_DestroyLock(rwlock->rw_lock);
+	}
+	PR_Free(rwlock->rw_name);
+	PR_DELETE(rwlock);
+	return NULL;
+#endif
+}
+
+/*
+** Destroy the given RWLock "lock".
+*/
+PR_IMPLEMENT(void)
+PR_DestroyRWLock(PRRWLock *rwlock)
+{
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	int err;
+	err = RWLOCK_DESTROY(&rwlock->rw_lock);
+	PR_ASSERT(err == 0);
+#else
+	PR_ASSERT(rwlock->rw_reader_cnt == 0);
+	PR_DestroyCondVar(rwlock->rw_reader_waitq);	
+	PR_DestroyCondVar(rwlock->rw_writer_waitq);	
+	PR_DestroyLock(rwlock->rw_lock);
+#endif
+	if (rwlock->rw_name != NULL)
+		PR_Free(rwlock->rw_name);
+    PR_DELETE(rwlock);
+}
+
+/*
+** Read-lock the RWLock.
+*/
+PR_IMPLEMENT(void)
+PR_RWLock_Rlock(PRRWLock *rwlock)
+{
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+int err;
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+	/*
+	 * assert that rank ordering is not violated; the rank of 'rwlock' should
+	 * be equal to or greater than the highest rank of all the locks held by
+	 * the thread.
+	 */
+	PR_ASSERT((rwlock->rw_rank == PR_RWLOCK_RANK_NONE) || 
+					(rwlock->rw_rank >= _PR_GET_THREAD_RWLOCK_RANK()));
+#endif
+
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	err = RWLOCK_RDLOCK(&rwlock->rw_lock);
+	PR_ASSERT(err == 0);
+#else
+	PR_Lock(rwlock->rw_lock);
+	/*
+	 * wait if write-locked or if a writer is waiting; preference for writers
+	 */
+	while ((rwlock->rw_lock_cnt < 0) ||
+			(rwlock->rw_writer_cnt > 0)) {
+		rwlock->rw_reader_cnt++;
+		PR_WaitCondVar(rwlock->rw_reader_waitq, PR_INTERVAL_NO_TIMEOUT);
+		rwlock->rw_reader_cnt--;
+	}
+	/*
+	 * Increment read-lock count
+	 */
+	rwlock->rw_lock_cnt++;
+
+	PR_Unlock(rwlock->rw_lock);
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+	/*
+	 * update thread's lock rank
+	 */
+	_PR_SET_THREAD_RWLOCK_RANK(rwlock);
+#endif
+}
+
+/*
+** Write-lock the RWLock.
+*/
+PR_IMPLEMENT(void)
+PR_RWLock_Wlock(PRRWLock *rwlock)
+{
+#if defined(DEBUG)
+PRThread *me = PR_GetCurrentThread();
+#endif
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+int err;
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+	/*
+	 * assert that rank ordering is not violated; the rank of 'rwlock' should
+	 * be equal to or greater than the highest rank of all the locks held by
+	 * the thread.
+	 */
+	PR_ASSERT((rwlock->rw_rank == PR_RWLOCK_RANK_NONE) || 
+					(rwlock->rw_rank >= _PR_GET_THREAD_RWLOCK_RANK()));
+#endif
+
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	err = RWLOCK_WRLOCK(&rwlock->rw_lock);
+	PR_ASSERT(err == 0);
+#else
+	PR_Lock(rwlock->rw_lock);
+	/*
+	 * wait if read locked
+	 */
+	while (rwlock->rw_lock_cnt != 0) {
+		rwlock->rw_writer_cnt++;
+		PR_WaitCondVar(rwlock->rw_writer_waitq, PR_INTERVAL_NO_TIMEOUT);
+		rwlock->rw_writer_cnt--;
+	}
+	/*
+	 * apply write lock
+	 */
+	rwlock->rw_lock_cnt--;
+	PR_ASSERT(rwlock->rw_lock_cnt == -1);
+#ifdef DEBUG
+	PR_ASSERT(me != NULL);
+	rwlock->rw_owner = me;
+#endif
+	PR_Unlock(rwlock->rw_lock);
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+	/*
+	 * update thread's lock rank
+	 */
+	_PR_SET_THREAD_RWLOCK_RANK(rwlock);
+#endif
+}
+
+/*
+** Unlock the RW lock.
+*/
+PR_IMPLEMENT(void)
+PR_RWLock_Unlock(PRRWLock *rwlock)
+{
+#if defined(DEBUG)
+PRThread *me = PR_GetCurrentThread();
+#endif
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+int err;
+#endif
+
+#if defined(HAVE_UNIX98_RWLOCK) || defined(HAVE_UI_RWLOCK)
+	err = RWLOCK_UNLOCK(&rwlock->rw_lock);
+	PR_ASSERT(err == 0);
+#else
+	PR_Lock(rwlock->rw_lock);
+	/*
+	 * lock must be read or write-locked
+	 */
+	PR_ASSERT(rwlock->rw_lock_cnt != 0);
+	if (rwlock->rw_lock_cnt > 0) {
+
+		/*
+		 * decrement read-lock count
+		 */
+		rwlock->rw_lock_cnt--;
+		if (rwlock->rw_lock_cnt == 0) {
+			/*
+			 * lock is not read-locked anymore; wakeup a waiting writer
+			 */
+			if (rwlock->rw_writer_cnt > 0)
+				PR_NotifyCondVar(rwlock->rw_writer_waitq);
+		}
+	} else {
+		PR_ASSERT(rwlock->rw_lock_cnt == -1);
+
+		rwlock->rw_lock_cnt = 0;
+#ifdef DEBUG
+    	PR_ASSERT(rwlock->rw_owner == me);
+    	rwlock->rw_owner = NULL;
+#endif
+		/*
+		 * wakeup a writer, if present; preference for writers
+		 */
+		if (rwlock->rw_writer_cnt > 0)
+			PR_NotifyCondVar(rwlock->rw_writer_waitq);
+		/*
+		 * else, wakeup all readers, if any
+		 */
+		else if (rwlock->rw_reader_cnt > 0)
+			PR_NotifyAllCondVar(rwlock->rw_reader_waitq);
+	}
+	PR_Unlock(rwlock->rw_lock);
+#endif
+
+#ifdef _PR_RWLOCK_RANK_ORDER_DEBUG
+	/*
+	 * update thread's lock rank
+	 */
+	_PR_UNSET_THREAD_RWLOCK_RANK(rwlock);
+#endif
+	return;
+}
+
+#ifndef _PR_RWLOCK_RANK_ORDER_DEBUG
+
+void _PR_InitRWLocks(void) { }
+
+#else
+
+void _PR_InitRWLocks(void)
+{
+	/*
+	 * allocated thread-private-data index for rwlock list
+	 */
+	if (PR_NewThreadPrivateIndex(&pr_thread_rwlock_key,
+			_PR_RELEASE_LOCK_STACK) == PR_FAILURE) {
+		pr_thread_rwlock_alloc_failed = 1;
+		return;
+	}
+}
+
+/*
+ * _PR_SET_THREAD_RWLOCK_RANK
+ *		Set a thread's lock rank, which is the highest of the ranks of all
+ *		the locks held by the thread. Pointers to the locks are added to a
+ *		per-thread list, which is anchored off a thread-private data key.
+ */
+
+static void
+_PR_SET_THREAD_RWLOCK_RANK(PRRWLock *rwlock)
+{
+thread_rwlock_stack *lock_stack;
+PRStatus rv;
+
+	/*
+	 * allocate a lock stack
+	 */
+	if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key)) == NULL) {
+		lock_stack = (thread_rwlock_stack *)
+						PR_CALLOC(1 * sizeof(thread_rwlock_stack));
+		if (lock_stack) {
+			rv = PR_SetThreadPrivate(pr_thread_rwlock_key, lock_stack);
+			if (rv == PR_FAILURE) {
+				PR_DELETE(lock_stack);
+				pr_thread_rwlock_alloc_failed = 1;
+				return;
+			}
+		} else {
+			pr_thread_rwlock_alloc_failed = 1;
+			return;
+		}
+	}
+	/*
+	 * add rwlock to lock stack, if limit is not exceeded
+	 */
+	if (lock_stack) {
+		if (lock_stack->trs_index < _PR_RWLOCK_RANK_ORDER_LIMIT)
+			lock_stack->trs_stack[lock_stack->trs_index++] = rwlock;	
+	}
+}
+
+static void
+_PR_RELEASE_LOCK_STACK(void *lock_stack)
+{
+	PR_ASSERT(lock_stack);
+	PR_DELETE(lock_stack);
+}
+
+/*
+ * _PR_GET_THREAD_RWLOCK_RANK
+ *
+ *		return thread's lock rank. If thread-private-data for the lock
+ *		stack is not allocated, return PR_RWLOCK_RANK_NONE.
+ */
+	
+static PRUint32
+_PR_GET_THREAD_RWLOCK_RANK(void)
+{
+	thread_rwlock_stack *lock_stack;
+
+	if ((lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key)) == NULL)
+		return (PR_RWLOCK_RANK_NONE);
+	else
+		return(lock_stack->trs_stack[lock_stack->trs_index - 1]->rw_rank);
+}
+
+/*
+ * _PR_UNSET_THREAD_RWLOCK_RANK
+ *
+ *		remove the rwlock from the lock stack. Since locks may not be
+ *		unlocked in a FIFO order, the entire lock stack is searched.
+ */
+	
+static void
+_PR_UNSET_THREAD_RWLOCK_RANK(PRRWLock *rwlock)
+{
+	thread_rwlock_stack *lock_stack;
+	int new_index = 0, index, done = 0;
+
+	lock_stack = PR_GetThreadPrivate(pr_thread_rwlock_key);
+
+	PR_ASSERT(lock_stack != NULL);
+
+	index = lock_stack->trs_index - 1;
+	while (index-- >= 0) {
+		if ((lock_stack->trs_stack[index] == rwlock) && !done)  {
+			/*
+			 * reset the slot for rwlock
+			 */
+			lock_stack->trs_stack[index] = NULL;
+			done = 1;
+		}
+		/*
+		 * search for the lowest-numbered empty slot, above which there are
+		 * no non-empty slots
+		 */
+		if ((lock_stack->trs_stack[index] != NULL) && !new_index)
+			new_index = index + 1;
+		if (done && new_index)
+			break;
+	}
+	/*
+	 * set top of stack to highest numbered empty slot
+	 */
+	lock_stack->trs_index = new_index;
+
+}
+
+#endif 	/* _PR_RWLOCK_RANK_ORDER_DEBUG */

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prsem.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prsem.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,174 @@
+/* -*- 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"
+#if defined(XP_MAC)
+#include "prsem.h"
+#else
+#include "obsolete/prsem.h"
+#endif
+
+/************************************************************************/
+
+/*
+** Create a new semaphore.
+*/
+PR_IMPLEMENT(PRSemaphore*) PR_NewSem(PRUintn value)
+{
+    PRSemaphore *sem;
+    PRCondVar *cvar;
+    PRLock *lock;
+
+    sem = PR_NEWZAP(PRSemaphore);
+    if (sem) {
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+        _PR_MD_NEW_SEM(&sem->md, value);
+#else
+        lock = PR_NewLock();
+        if (!lock) {
+            PR_DELETE(sem);
+            return NULL;
+    	}
+
+        cvar = PR_NewCondVar(lock);
+        if (!cvar) {
+            PR_DestroyLock(lock);
+            PR_DELETE(sem);
+            return NULL;
+    	}
+    	sem->cvar = cvar;
+    	sem->count = value;
+#endif
+    }
+    return sem;
+}
+
+/*
+** Destroy a semaphore. There must be no thread waiting on the semaphore.
+** The caller is responsible for guaranteeing that the semaphore is
+** no longer in use.
+*/
+PR_IMPLEMENT(void) PR_DestroySem(PRSemaphore *sem)
+{
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+    _PR_MD_DESTROY_SEM(&sem->md);
+#else
+    PR_ASSERT(sem->waiters == 0);
+
+    PR_DestroyLock(sem->cvar->lock);
+    PR_DestroyCondVar(sem->cvar);
+#endif
+    PR_DELETE(sem);
+}
+
+/*
+** Wait on a Semaphore.
+** 
+** This routine allows a calling thread to wait or proceed depending upon the 
+** state of the semahore sem. The thread can proceed only if the counter value 
+** of the semaphore sem is currently greater than 0. If the value of semaphore 
+** sem is positive, it is decremented by one and the routine returns immediately 
+** allowing the calling thread to continue. If the value of semaphore sem is 0, 
+** the calling thread blocks awaiting the semaphore to be released by another 
+** thread.
+** 
+** This routine can return PR_PENDING_INTERRUPT if the waiting thread 
+** has been interrupted.
+*/
+PR_IMPLEMENT(PRStatus) PR_WaitSem(PRSemaphore *sem)
+{
+	PRStatus status = PR_SUCCESS;
+
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+	return _PR_MD_WAIT_SEM(&sem->md);
+#else
+	PR_Lock(sem->cvar->lock);
+	while (sem->count == 0) {
+		sem->waiters++;
+		status = PR_WaitCondVar(sem->cvar, PR_INTERVAL_NO_TIMEOUT);
+		sem->waiters--;
+		if (status != PR_SUCCESS)
+			break;
+	}
+	if (status == PR_SUCCESS)
+		sem->count--;
+	PR_Unlock(sem->cvar->lock);
+#endif
+	
+	return (status);
+}
+
+/*
+** This routine increments the counter value of the semaphore. If other threads 
+** are blocked for the semaphore, then the scheduler will determine which ONE 
+** thread will be unblocked.
+*/
+PR_IMPLEMENT(void) PR_PostSem(PRSemaphore *sem)
+{
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+	_PR_MD_POST_SEM(&sem->md);
+#else
+	PR_Lock(sem->cvar->lock);
+	if (sem->waiters)
+		PR_NotifyCondVar(sem->cvar);
+	sem->count++;
+	PR_Unlock(sem->cvar->lock);
+#endif
+}
+
+#if DEBUG
+/*
+** Returns the value of the semaphore referenced by sem without affecting
+** the state of the semaphore.  The value represents the semaphore vaule
+** at the time of the call, but may not be the actual value when the
+** caller inspects it. (FOR DEBUGGING ONLY)
+*/
+PR_IMPLEMENT(PRUintn) PR_GetValueSem(PRSemaphore *sem)
+{
+	PRUintn rv;
+
+#ifdef HAVE_CVAR_BUILT_ON_SEM
+	rv = _PR_MD_GET_VALUE_SEM(&sem->md);
+#else
+	PR_Lock(sem->cvar->lock);
+	rv = sem->count;
+	PR_Unlock(sem->cvar->lock);
+#endif
+	
+	return rv;
+}
+#endif

Added: freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prtpd.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/src/threads/prtpd.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,280 @@
+/* -*- 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 ***** */
+
+/*
+** Thread Private Data
+**
+** There is an aribitrary limit on the number of keys that will be allocated
+** by the runtime. It's largish, so it is intended to be a sanity check, not
+** an impediment.
+**
+** There is a counter, initialized to zero and incremented every time a
+** client asks for a new key, that holds the high water mark for keys. All
+** threads logically have the same high water mark and are permitted to
+** ask for TPD up to that key value.
+**
+** The vector to hold the TPD are allocated when PR_SetThreadPrivate() is
+** called. The size of the vector will be some value greater than or equal
+** to the current high water mark. Each thread has its own TPD length and
+** vector.
+**
+** Threads that get private data for keys they have not set (or perhaps
+** don't even exist for that thread) get a NULL return. If the key is
+** beyond the high water mark, an error will be returned.
+*/
+
+/*
+** As of this time, BeOS has its own TPD implementation.  Integrating
+** this standard one is a TODO for anyone with a bit of spare time on
+** their hand.  For now, we just #ifdef out this whole file and use
+** the routines in pr/src/btthreads/
+*/
+
+#ifndef XP_BEOS
+
+#include "primpl.h"
+
+#include <string.h>
+
+#if defined(WIN95)
+/*
+** Some local variables report warnings on Win95 because the code paths 
+** using them are conditioned on HAVE_CUSTOME_USER_THREADS.
+** The pragma suppresses the warning.
+** 
+*/
+#pragma warning(disable : 4101)
+#endif
+
+#define _PR_TPD_LIMIT 128               /* arbitary limit on the TPD slots */
+static PRInt32 _pr_tpd_length = 0;      /* current length of destructor vector */
+static PRInt32 _pr_tpd_highwater = 0;   /* next TPD key to be assigned */
+static PRThreadPrivateDTOR *_pr_tpd_destructors = NULL;
+                                        /* the destructors are associated with
+                                            the keys, therefore asserting that
+                                            the TPD key depicts the data's 'type' */
+
+/*
+** Initialize the thread private data manipulation
+*/
+void _PR_InitTPD(void)
+{
+    _pr_tpd_destructors = (PRThreadPrivateDTOR*)
+        PR_CALLOC(_PR_TPD_LIMIT * sizeof(PRThreadPrivateDTOR*));
+    PR_ASSERT(NULL != _pr_tpd_destructors);
+    _pr_tpd_length = _PR_TPD_LIMIT;
+}
+
+/*
+** Clean up the thread private data manipulation
+*/
+void _PR_CleanupTPD(void)
+{
+}  /* _PR_CleanupTPD */
+
+/*
+** This routine returns a new index for per-thread-private data table. 
+** The index is visible to all threads within a process. This index can 
+** be used with the PR_SetThreadPrivate() and PR_GetThreadPrivate() routines 
+** to save and retrieve data associated with the index for a thread.
+**
+** The index independently maintains specific values for each binding thread. 
+** A thread can only get access to its own thread-specific-data.
+**
+** Upon a new index return the value associated with the index for all threads
+** is NULL, and upon thread creation the value associated with all indices for 
+** that thread is NULL. 
+**
+**     "dtor" is the destructor function to invoke when the private
+**       data is set or destroyed
+**
+** Returns PR_FAILURE if the total number of indices will exceed the maximun 
+** allowed.
+*/
+
+PR_IMPLEMENT(PRStatus) PR_NewThreadPrivateIndex(
+    PRUintn *newIndex, PRThreadPrivateDTOR dtor)
+{
+    PRStatus rv;
+    PRInt32 index;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    PR_ASSERT(NULL != newIndex);
+    PR_ASSERT(NULL != _pr_tpd_destructors);
+
+    index = PR_AtomicIncrement(&_pr_tpd_highwater) - 1;  /* allocate index */
+    if (_PR_TPD_LIMIT <= index)
+    {
+        PR_SetError(PR_TPD_RANGE_ERROR, 0);
+        rv = PR_FAILURE;  /* that's just wrong */
+    }
+    else
+    {
+        _pr_tpd_destructors[index] = dtor;  /* record destructor @index */
+        *newIndex = (PRUintn)index;  /* copy into client's location */
+        rv = PR_SUCCESS;  /* that's okay */
+    }
+
+    return rv;
+}
+
+/*
+** Define some per-thread-private data.
+**     "index" is an index into the per-thread private data table
+**     "priv" is the per-thread-private data 
+**
+** If the per-thread private data table has a previously registered
+** destructor function and a non-NULL per-thread-private data value,
+** the destructor function is invoked.
+**
+** This can return PR_FAILURE if index is invalid (ie., beyond the current
+** high water mark) or memory is insufficient to allocate an exanded vector.
+*/
+
+PR_IMPLEMENT(PRStatus) PR_SetThreadPrivate(PRUintn index, void *priv)
+{
+    PRThread *self = PR_GetCurrentThread();
+
+    /*
+    ** The index being set might not have a sufficient vector in this
+    ** thread. But if the index has been allocated, it's okay to go
+    ** ahead and extend this one now.
+    */
+    if ((index >= _PR_TPD_LIMIT) || (index >= _pr_tpd_highwater))
+    {
+        PR_SetError(PR_TPD_RANGE_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    PR_ASSERT(((NULL == self->privateData) && (0 == self->tpdLength))
+        || ((NULL != self->privateData) && (0 != self->tpdLength)));
+
+    if ((NULL == self->privateData) || (self->tpdLength <= index))
+    {
+        void *extension = PR_CALLOC(_pr_tpd_length * sizeof(void*));
+        if (NULL == extension)
+        {
+            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+            return PR_FAILURE;
+        }
+        if (self->privateData) {
+            (void)memcpy(
+                extension, self->privateData,
+                self->tpdLength * sizeof(void*));
+            PR_DELETE(self->privateData);
+        }
+        self->tpdLength = _pr_tpd_length;
+        self->privateData = (void**)extension;
+    }
+    /*
+    ** There wasn't much chance of having to call the destructor
+    ** unless the slot already existed.
+    */
+    else if (self->privateData[index] && _pr_tpd_destructors[index])
+    {
+        void *data = self->privateData[index];
+        self->privateData[index] = NULL;
+        (*_pr_tpd_destructors[index])(data);
+    }
+
+    PR_ASSERT(index < self->tpdLength);
+    self->privateData[index] = priv;
+
+    return PR_SUCCESS;
+}
+
+/*
+** Recover the per-thread-private data for the current thread. "index" is
+** the index into the per-thread private data table. 
+**
+** The returned value may be NULL which is indistinguishable from an error 
+** condition.
+**
+*/
+
+PR_IMPLEMENT(void*) PR_GetThreadPrivate(PRUintn index)
+{
+    PRThread *self = PR_GetCurrentThread();
+    void *tpd = ((NULL == self->privateData) || (index >= self->tpdLength)) ?
+        NULL : self->privateData[index];
+
+    return tpd;
+}
+
+/*
+** Destroy the thread's private data, if any exists. This is called at
+** thread termination time only. There should be no threading issues
+** since this is being called by the thread itself.
+*/
+void _PR_DestroyThreadPrivate(PRThread* self)
+{
+#define _PR_TPD_DESTRUCTOR_ITERATIONS 4
+
+    if (NULL != self->privateData)  /* we have some */
+    {
+        PRBool clean;
+        PRUint32 index;
+        PRInt32 passes = _PR_TPD_DESTRUCTOR_ITERATIONS;
+        PR_ASSERT(0 != self->tpdLength);
+        do
+        {
+            clean = PR_TRUE;
+            for (index = 0; index < self->tpdLength; ++index)
+            {
+                void *priv = self->privateData[index];  /* extract */
+                if (NULL != priv)  /* we have data at this index */
+                {
+                    if (NULL != _pr_tpd_destructors[index])
+                    {
+                        self->privateData[index] = NULL;  /* precondition */
+                        (*_pr_tpd_destructors[index])(priv);  /* destroy */
+                        clean = PR_FALSE;  /* unknown side effects */
+                    }
+                }
+            }
+        } while ((--passes > 0) && !clean);  /* limit # of passes */
+        /*
+        ** We give up after a fixed number of passes. Any non-NULL
+        ** thread-private data value with a registered destructor
+        ** function is not destroyed.
+        */
+        memset(self->privateData, 0, self->tpdLength * sizeof(void*));
+    }
+}  /* _PR_DestroyThreadPrivate */
+
+#endif /* !XP_BEOS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,172 @@
+/.cvsignore/1.2/Sat May 12 05:06:18 2001//
+/Makefile.in/1.49/Sat Dec 24 15:03:31 2005//
+/README.TXT/3.1/Fri Mar  5 22:32:55 1999//
+/accept.c/3.11/Sun Apr 25 15:01:02 2004//
+/acceptread.c/1.7/Sun Apr 25 15:01:02 2004//
+/acceptreademu.c/3.4/Sun Apr 25 15:01:02 2004//
+/addrstr.c/3.5/Sun Apr 25 15:01:02 2004//
+/affinity.c/3.6/Sun Apr 25 15:01:02 2004//
+/alarm.c/3.7/Sun Apr 25 15:01:02 2004//
+/anonfm.c/3.7/Sun Apr 25 15:01:02 2004//
+/append.c/1.2/Sun Apr 25 15:01:02 2004//
+/atomic.c/3.8/Sun Apr 25 15:01:02 2004//
+/attach.c/3.12/Sun Apr 25 15:01:02 2004//
+/bigfile.c/3.8/Sun Apr 25 15:01:02 2004//
+/bigfile2.c/3.6/Sun Apr 25 15:01:02 2004//
+/bigfile3.c/3.6/Fri Apr 29 22:46:05 2005//
+/bug1test.c/3.5/Sun Apr 25 15:01:02 2004//
+/cleanup.c/3.5/Sun Apr 25 15:01:02 2004//
+/cltsrv.c/3.13/Mon Nov  7 22:39:02 2005//
+/concur.c/3.7/Sun Apr 25 15:01:02 2004//
+/cvar.c/3.5/Sun Apr 25 15:01:02 2004//
+/cvar2.c/3.8/Sun Apr 25 15:01:02 2004//
+/dbmalloc.c/3.5/Sun Apr 25 15:01:02 2004//
+/dbmalloc1.c/3.5/Sun Apr 25 15:01:02 2004//
+/dceemu.c/3.6/Sun Apr 25 15:01:02 2004//
+/depend.c/3.5/Sun Apr 25 15:01:02 2004//
+/dlltest.c/3.7/Sun Apr 25 15:01:02 2004//
+/dtoa.c/1.5/Sun Apr 25 15:01:02 2004//
+/env.c/1.4/Fri Apr 29 22:46:05 2005//
+/errcodes.c/3.5/Sun Apr 25 15:01:02 2004//
+/errset.c/1.2/Sun Apr 25 15:01:02 2004//
+/exit.c/3.5/Sun Apr 25 15:01:02 2004//
+/fdcach.c/1.5/Sun Apr 25 15:01:02 2004//
+/fileio.c/3.5/Sun Apr 25 15:01:02 2004//
+/foreign.c/3.12/Tue Mar  8 01:22:57 2005//
+/forktest.c/3.6/Sun Apr 25 15:01:02 2004//
+/formattm.c/1.4/Sun Apr 25 15:01:02 2004//
+/freeif.c/3.6/Sun Apr 25 15:01:02 2004//
+/fsync.c/3.6/Sun Apr 25 15:01:02 2004//
+/getai.c/1.3/Sun Apr 25 15:01:02 2004//
+/gethost.c/3.8/Sun Apr 25 15:01:02 2004//
+/getproto.c/3.5/Sun Apr 25 15:01:02 2004//
+/i2l.c/3.5/Sun Apr 25 15:01:02 2004//
+/initclk.c/3.7/Fri Apr 29 22:46:05 2005//
+/inrval.c/3.6/Sun Apr 25 15:01:02 2004//
+/instrumt.c/3.8/Sun Apr 25 15:01:02 2004//
+/intrio.c/3.5/Sun Apr 25 15:01:02 2004//
+/intrupt.c/3.8/Mon Nov  7 22:39:09 2005//
+/io_timeout.c/3.9/Sun Apr 25 15:01:02 2004//
+/io_timeoutk.c/3.5/Sun Apr 25 15:01:02 2004//
+/io_timeoutu.c/3.5/Sun Apr 25 15:01:02 2004//
+/ioconthr.c/3.6/Sun Apr 25 15:01:02 2004//
+/ipv6.c/3.12/Sun Apr 25 15:01:02 2004//
+/join.c/3.7/Sun Apr 25 15:01:02 2004//
+/joinkk.c/3.6/Sun Apr 25 15:01:02 2004//
+/joinku.c/3.5/Sun Apr 25 15:01:02 2004//
+/joinuk.c/3.5/Sun Apr 25 15:01:02 2004//
+/joinuu.c/3.5/Sun Apr 25 15:01:02 2004//
+/layer.c/3.11/Fri Apr 29 22:46:05 2005//
+/lazyinit.c/3.5/Sun Apr 25 15:01:02 2004//
+/libfilename.c/1.2/Sun Apr 25 15:01:02 2004//
+/lltest.c/3.6/Sun Apr 25 15:01:02 2004//
+/lock.c/3.6/Sun Apr 25 15:01:02 2004//
+/lockfile.c/3.6/Sun Apr 25 15:01:02 2004//
+/logger.c/3.7/Sun Apr 25 15:01:02 2004//
+/makedir.c/3.5/Sun Apr 25 15:01:02 2004//
+/many_cv.c/3.8/Sun Apr 25 15:01:02 2004//
+/mbcs.c/3.4/Sun Apr 25 15:01:02 2004//
+/multiacc.c/3.7/Sun Apr 25 15:01:02 2004//
+/multiwait.c/3.8/Sun Apr 25 15:01:02 2004//
+/nameshm1.c/3.4/Sun Apr 25 15:01:02 2004//
+/nbconn.c/3.8/Fri Apr 29 22:46:05 2005//
+/nblayer.c/1.10/Sun Apr 25 15:01:02 2004//
+/nonblock.c/3.8/Sun Apr 25 15:01:02 2004//
+/ntioto.c/1.7/Fri Apr 29 22:46:05 2005//
+/ntoh.c/3.5/Sun Apr 25 15:01:02 2004//
+/obsints.c/3.5/Sun Apr 25 15:01:02 2004//
+/op_2long.c/3.8/Sun Apr 25 15:01:02 2004//
+/op_excl.c/1.5/Sun Apr 25 15:01:02 2004//
+/op_filnf.c/3.6/Fri Apr 29 22:46:05 2005//
+/op_filok.c/3.10/Sun Apr 25 15:01:02 2004//
+/op_noacc.c/3.6/Sun Apr 25 15:01:02 2004//
+/op_nofil.c/3.6/Sun Apr 25 15:01:02 2004//
+/openfile.c/3.5/Sun Apr 25 15:01:02 2004//
+/parent.c/3.10/Sun Apr 25 15:01:02 2004//
+/peek.c/3.6/Sun Apr 25 15:01:02 2004//
+/perf.c/3.7/Mon Nov  7 22:39:09 2005//
+/pipeping.c/3.9/Sun Apr 25 15:01:02 2004//
+/pipeping2.c/3.5/Sun Apr 25 15:01:02 2004//
+/pipepong.c/3.7/Sun Apr 25 15:01:02 2004//
+/pipepong2.c/3.5/Sun Apr 25 15:01:02 2004//
+/pipeself.c/3.8/Sun Apr 25 15:01:02 2004//
+/poll_er.c/3.6/Sun Apr 25 15:01:02 2004//
+/poll_nm.c/3.9/Sun Apr 25 15:01:02 2004//
+/poll_to.c/3.8/Sun Apr 25 15:01:02 2004//
+/pollable.c/3.6/Sun Apr 25 15:01:02 2004//
+/prftest.c/3.6/Sun Apr 25 15:01:02 2004//
+/prftest1.c/3.5/Sun Apr 25 15:01:02 2004//
+/prftest2.c/3.6/Sun Apr 25 15:01:02 2004//
+/primblok.c/3.5/Sun Apr 25 15:01:02 2004//
+/priotest.c/3.7/Sun Apr 25 15:01:02 2004//
+/provider.c/3.13/Mon Nov  7 22:39:09 2005//
+/prpoll.c/3.11/Fri Oct 21 18:21:43 2005//
+/prpollml.c/3.6/Sun Apr 25 15:01:02 2004//
+/prselect.c/3.5/Sun Apr 25 15:01:02 2004//
+/prttools.h/3.5/Sun Apr 25 15:01:02 2004//
+/randseed.c/1.5/Fri Apr 29 22:46:05 2005//
+/ranfile.c/3.7/Sun Apr 25 15:01:02 2004//
+/rmdir.c/1.2/Sun Apr 25 15:01:02 2004//
+/runtests.ksh/1.30/Sun Apr 25 15:01:02 2004//
+/runtests.sh/1.5/Sun Apr 25 15:01:02 2004//
+/runy2ktests.ksh/3.6/Sun Apr 25 15:01:02 2004//
+/rwlocktest.c/1.5/Sun Apr 25 15:01:02 2004//
+/sel_spd.c/3.13/Fri Apr 29 21:02:55 2005//
+/selct_er.c/3.6/Sun Apr 25 15:01:02 2004//
+/selct_nm.c/3.7/Sun Apr 25 15:01:02 2004//
+/selct_to.c/3.7/Sun Apr 25 15:01:02 2004//
+/select2.c/3.9/Sun Apr 25 15:01:02 2004//
+/selintr.c/3.5/Sun Apr 25 15:01:02 2004//
+/sem.c/3.5/Sun Apr 25 15:01:02 2004//
+/sema.c/3.6/Sun Apr 25 15:01:02 2004//
+/semaerr.c/3.5/Sun Apr 25 15:01:02 2004//
+/semaerr1.c/3.5/Sun Apr 25 15:01:02 2004//
+/semaping.c/3.7/Sun Apr 25 15:01:02 2004//
+/semapong.c/3.7/Sun Apr 25 15:01:02 2004//
+/sendzlf.c/3.5/Sun Apr 25 15:01:02 2004//
+/server_test.c/3.10/Wed Jun 29 18:02:44 2005//
+/servr_kk.c/3.12/Wed Jun 29 18:02:44 2005//
+/servr_ku.c/3.11/Wed Jun 29 18:02:44 2005//
+/servr_uk.c/3.11/Wed Jun 29 18:02:44 2005//
+/servr_uu.c/3.11/Wed Jun 29 18:02:44 2005//
+/short_thread.c/1.5/Sun Apr 25 15:01:02 2004//
+/sigpipe.c/3.8/Sun Apr 25 15:01:02 2004//
+/sleep.c/3.7/Sun Apr 25 15:01:02 2004//
+/socket.c/3.18/Sun Apr 25 15:01:02 2004//
+/sockopt.c/3.12/Sun Apr 25 15:01:02 2004//
+/sockping.c/3.9/Sun Apr 25 15:01:02 2004//
+/sockpong.c/3.7/Sun Apr 25 15:01:02 2004//
+/sprintf.c/3.5/Sun Apr 25 15:01:02 2004//
+/sproc_ch.c/3.5/Sun Apr 25 15:01:02 2004//
+/sproc_p.c/3.5/Sun Apr 25 15:01:02 2004//
+/stack.c/3.6/Sun Apr 25 15:01:02 2004//
+/stat.c/3.6/Sun Apr 25 15:01:02 2004//
+/stdio.c/3.5/Sun Apr 25 15:01:02 2004//
+/str2addr.c/3.5/Sun Apr 25 15:01:02 2004//
+/strod.c/3.7/Sun Apr 25 15:01:02 2004//
+/suspend.c/3.7/Sun Apr 25 15:01:02 2004//
+/switch.c/3.6/Sun Apr 25 15:01:02 2004//
+/system.c/3.7/Fri May  6 18:46:11 2005//
+/testbit.c/1.5/Sun Apr 25 15:01:02 2004//
+/testfile.c/3.15/Tue Oct 11 21:48:09 2005//
+/threads.c/3.5/Sun Apr 25 15:01:02 2004//
+/thrpool_client.c/3.6/Sun Apr 25 15:01:02 2004//
+/thrpool_server.c/3.7/Sun Apr 25 15:01:02 2004//
+/thruput.c/3.8/Sun Apr 25 15:01:02 2004//
+/time.c/3.7/Sun Apr 25 15:01:02 2004//
+/timemac.c/3.5/Sun Apr 25 15:01:02 2004//
+/timetest.c/3.8/Sun Apr 25 15:01:02 2004//
+/tmoacc.c/3.8/Sun Apr 25 15:01:02 2004//
+/tmocon.c/3.10/Tue Jun 20 21:47:20 2000//
+/tpd.c/3.8/Sun Apr 25 15:01:02 2004//
+/udpsrv.c/3.7/Sun Apr 25 15:01:02 2004//
+/ut_ttools.h/3.5/Sun Apr 25 15:01:02 2004//
+/vercheck.c/1.20/Wed Sep 14 23:39:56 2005//
+/version.c/3.7/Sun Apr 25 15:01:02 2004//
+/writev.c/3.5/Sun Apr 25 15:01:02 2004//
+/xnotify.c/3.5/Sun Apr 25 15:01:02 2004//
+/y2k.c/3.7/Sun Apr 25 15:01:02 2004//
+/y2ktmo.c/3.5/Sun Apr 25 15:01:02 2004//
+/yield.c/3.7/Sun Apr 25 15:01:02 2004//
+/zerolen.c/3.5/Sun Apr 25 15:01:02 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Entries.Log
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Entries.Log	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3 @@
+A D/dll////
+A D/macbuild////
+A D/w16gui////

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/tests

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,567 @@
+# 
+# ***** 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
+
+DIRS = dll
+
+CSRCS =             \
+	accept.c		\
+	acceptread.c	\
+	acceptreademu.c	\
+	addrstr.c		\
+	affinity.c		\
+	alarm.c			\
+	anonfm.c		\
+	append.c		\
+	atomic.c		\
+	attach.c		\
+	bigfile.c		\
+	bigfile2.c		\
+	bigfile3.c		\
+	cleanup.c		\
+	cltsrv.c		\
+	concur.c	    \
+	cvar.c			\
+	cvar2.c			\
+	dceemu.c		\
+	dlltest.c		\
+	dtoa.c			\
+	env.c			\
+	errcodes.c		\
+	errset.c		\
+	exit.c  		\
+	fdcach.c		\
+	fileio.c		\
+	foreign.c	    \
+	forktest.c	    \
+	formattm.c	    \
+	fsync.c	        \
+	getai.c			\
+	gethost.c		\
+	getproto.c		\
+	i2l.c		    \
+	initclk.c		\
+	inrval.c		\
+	instrumt.c      \
+	intrio.c        \
+	intrupt.c       \
+	io_timeout.c    \
+	ioconthr.c      \
+	ipv6.c          \
+	join.c    		\
+	joinkk.c        \
+	joinku.c        \
+	joinuk.c        \
+	joinuu.c        \
+	layer.c		    \
+	lazyinit.c		\
+	libfilename.c	\
+	lltest.c        \
+	lock.c          \
+	lockfile.c      \
+	logger.c		\
+	makedir.c		\
+	mbcs.c			\
+	multiacc.c		\
+	multiwait.c		\
+	many_cv.c		\
+	nameshm1.c      \
+	nbconn.c		\
+	nblayer.c		\
+	nonblock.c		\
+	ntioto.c        \
+	ntoh.c			\
+	obsints.c		\
+	op_2long.c      \
+	op_excl.c		\
+	op_filnf.c		\
+	op_filok.c		\
+	op_noacc.c		\
+	op_nofil.c		\
+	openfile.c		\
+	parent.c    	\
+	peek.c    		\
+	perf.c    		\
+	pipeping.c		\
+	pipeping2.c		\
+	pipepong.c		\
+	pipepong2.c		\
+	pipeself.c		\
+	poll_er.c		\
+	poll_nm.c		\
+	poll_to.c		\
+	pollable.c		\
+	prftest.c		\
+	prftest1.c		\
+	prftest2.c		\
+	primblok.c		\
+	priotest.c		\
+	provider.c		\
+	prpoll.c		\
+	prpollml.c		\
+	ranfile.c       \
+	randseed.c      \
+	rmdir.c			\
+	rwlocktest.c    \
+	sel_spd.c  		\
+	selct_er.c	    \
+	selct_nm.c	    \
+	selct_to.c	    \
+	select2.c  		\
+	selintr.c  		\
+	sem.c 	  		\
+	sema.c 	  		\
+	semaerr.c 		\
+	semaerr1.c 		\
+	semaping.c 		\
+	semapong.c 		\
+	sendzlf.c 		\
+	server_test.c	\
+	servr_kk.c		\
+	servr_ku.c		\
+	servr_uk.c		\
+	servr_uu.c		\
+	short_thread.c	\
+	sigpipe.c		\
+	socket.c		\
+	sockopt.c		\
+	sockping.c		\
+	sockpong.c		\
+	sprintf.c		\
+	sproc_ch.c	    \
+	sproc_p.c	    \
+	stack.c		    \
+	stdio.c		    \
+	str2addr.c		\
+	strod.c			\
+	suspend.c		\
+	switch.c		\
+	system.c		\
+	testbit.c    	\
+	testfile.c    	\
+	thrpool_server.c \
+	thrpool_client.c \
+	threads.c 	  	\
+	thruput.c 	  	\
+	timemac.c		\
+	timetest.c		\
+	tmoacc.c        \
+	tmocon.c        \
+	tpd.c			\
+	vercheck.c		\
+	version.c	    \
+	udpsrv.c	    \
+	writev.c        \
+	xnotify.c       \
+	y2k.c           \
+	y2ktmo.c        \
+	zerolen.c       \
+	$(NULL)
+
+ifeq ($(OS_TARGET),OS2)
+CSRCS +=            \
+	sleep.c			\
+	stat.c		    \
+	yield.c         \
+	$(NULL)
+endif
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX)))
+
+TARGETS = $(PROGS)
+
+INCLUDES = -I$(dist_includedir) -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
+
+ifeq ($(OS_ARCH), WINNT)
+ifdef NS_USE_GCC
+  EXTRA_LIBS += -lwsock32
+else
+  EXTRA_LIBS += wsock32.lib
+  LDOPTS = -NOLOGO -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO
+  ifdef PROFILE                                                                              
+    LDOPTS += -PROFILE -MAP                                                                  
+  endif # profile
+endif # NS_USE_GCC
+endif
+
+ifeq ($(OS_ARCH),OS2)
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+  LDOPTS = -NOE -DEBUG -nologo -PMTYPE:VIO
+else
+  EXTRA_LIBS = $(OS_LIBS)
+  LDOPTS = -Zomf -Zlinker /PM:VIO -Zlinker /ST:0x64000
+endif
+endif
+
+ifneq ($(OS_ARCH), WINNT)
+# Use an absolute pathname as the runtime library path (for the -R
+# or -rpath linker option or the LD_RUN_PATH environment variable).
+ifeq (,$(patsubst /%,,$(DIST)))
+# $(DIST) is already an absolute pathname.
+ABSOLUTE_LIB_DIR = $(dist_libdir)
+else
+# $(DIST) is a relative pathname: prepend the current directory.
+PWD = $(shell pwd)
+ABSOLUTE_LIB_DIR = $(PWD)/$(dist_libdir)
+endif
+endif
+
+ifeq ($(OS_ARCH), IRIX)
+    ifeq ($(USE_CPLUS), 1)
+        CC = CC
+    endif
+    LDOPTS += -rpath $(ABSOLUTE_LIB_DIR)
+    ifdef NS_USE_GCC
+        LDOPTS += -Wl,-rdata_shared
+    else
+        LDOPTS += -rdata_shared
+    endif
+# For 6.x machines, include this flag
+    ifeq ($(basename $(OS_RELEASE)),6)
+        ifndef NS_USE_GCC
+            ifeq ($(USE_N32),1)
+                LDOPTS += -n32
+            else
+                LDOPTS += -32
+            endif
+
+            ifeq ($(USE_PTHREADS), 1)
+                ifeq ($(OS_RELEASE), 6.2)
+                    LDOPTS += -Wl,-woff,85
+                endif
+            endif
+        endif
+    endif
+endif
+
+ifeq ($(OS_ARCH), OSF1)
+    ifeq ($(USE_CPLUS), 1)
+        CC = cxx
+    endif
+# I haven't figured out how to pass -rpath to cc on OSF1 V3.2, so
+# we do static linking.
+    ifeq (,$(filter-out V2.0 V3.2,$(OS_RELEASE)))
+        LIBNSPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+        LIBPLC = $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).a
+        EXTRA_LIBS = -lc_r
+    else
+        LDOPTS += -rpath $(ABSOLUTE_LIB_DIR)
+    endif
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+    LDOPTS += -z -Wl,+s,+b,$(ABSOLUTE_LIB_DIR)
+    ifeq ($(USE_64),1)
+        LDOPTS += +DD64
+    endif
+    ifeq ($(USE_PTHREADS),1)
+        EXTRA_LIBS = $(LIBPTHREAD)
+    endif
+endif
+
+# AIX
+ifeq ($(OS_ARCH),AIX)
+    LDOPTS += -blibpath:$(ABSOLUTE_LIB_DIR):/usr/lib:/lib
+    ifneq ($(OS_ARCH)$(OS_RELEASE),AIX4.1)
+        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 $(ABSOLUTE_LIB_DIR)
+        else
+            ifeq ($(USE_CPLUS), 1)
+                CC = CC
+            endif
+            LDOPTS += -R $(ABSOLUTE_LIB_DIR)
+        endif
+    endif
+
+    ifneq ($(LOCAL_THREADS_ONLY),1)
+        ifdef USE_PTHREADS
+            EXTRA_LIBS = -lpthread -lthread
+        else
+            EXTRA_LIBS = -lthread
+        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 = $(ABSOLUTE_LIB_DIR)
+endif
+
+ifeq ($(OS_ARCH), NCR)
+# NCR needs to link against -lsocket -lnsl -ldl (and -lc, which is
+# linked implicitly by $(CC)).  Note that we did not link with these
+# system libraries when we built libnspr.so.
+    EXTRA_LIBS = -lsocket -lnsl -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 = $(ABSOLUTE_LIB_DIR)
+endif
+
+ifeq ($(OS_ARCH), NEXTSTEP)
+# balazs.pataki at sztaki.hu: linkage is done in a different pass in the `tests'
+# modeul, so we have to pass the `-posix' flag by "hand" to `ld'
+LDOPTS += -posix
+endif
+
+ifeq ($(OS_ARCH), NEWS-OS)
+# 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 = $(ABSOLUTE_LIB_DIR)
+    LIBNSPR = $(dist_libdir)/libnspr$(MOD_MAJOR_VERSION).a
+    LIBPLC = $(dist_libdir)/libplc$(MOD_MAJOR_VERSION).a
+    EXTRA_LIBS = -lsocket -lnsl -lgen -lresolv
+endif
+
+ifeq (,$(filter-out Linux GNU GNU_%,$(OS_ARCH)))
+    LDOPTS += -Xlinker -rpath $(ABSOLUTE_LIB_DIR)
+    ifeq ($(USE_PTHREADS),1)
+        EXTRA_LIBS = -lpthread
+    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 = $(ABSOLUTE_LIB_DIR)
+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 = $(ABSOLUTE_LIB_DIR)
+endif
+
+ifeq ($(OS_ARCH),OpenUNIX)
+export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR)
+ifeq ($(USE_PTHREADS),1)
+LDOPTS += -pthread
+endif
+endif
+
+ifeq ($(OS_ARCH), UNIXWARE)
+export LD_RUN_PATH = $(ABSOLUTE_LIB_DIR)
+endif
+
+ifeq ($(OS_ARCH),FreeBSD)
+ifeq ($(USE_PTHREADS),1)
+LDOPTS += -pthread
+endif
+LDOPTS += -Xlinker -R $(ABSOLUTE_LIB_DIR)
+endif
+
+ifeq ($(OS_ARCH),OpenBSD)
+ifeq ($(USE_PTHREADS),1)
+LDOPTS += -pthread
+endif
+endif
+
+ifeq ($(OS_ARCH),BSD_OS)
+ifneq ($(OS_RELEASE),1.1)
+EXTRA_LIBS = -ldl
+endif
+endif
+
+ifeq ($(USE_PTHREADS),1)
+LIBPTHREAD = -lpthread
+ifeq ($(OS_ARCH),AIX)
+LIBPTHREAD = -lpthreads
+endif
+ifeq (,$(filter-out FreeBSD OpenBSD BSD_OS QNX Darwin OpenUNIX,$(OS_ARCH)))
+LIBPTHREAD =
+endif
+ifeq ($(OS_ARCH)$(basename $(OS_RELEASE)),HP-UXB.10)
+LIBPTHREAD = -ldce
+endif
+endif
+
+
+#####################################################
+#
+# The rules
+#
+#####################################################
+
+include $(topsrcdir)/config/rules.mk
+
+AIX_PRE_4_2 = 0
+ifeq ($(OS_ARCH),AIX)
+ifeq ($(OS_RELEASE),4.1)
+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 ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+	link $(LDOPTS) $(EXTRA_LDOPTS) $< $(LIBPLC) $(LIBNSPR) $(EXTRA_LIBS) -out:$@
+else
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+	$(LD) $(EXEFLAGS) $(LDOPTS) $< $(LIBPLC) $(LIBNSPR) $(OS_LIBS) $(EXTRA_LIBS)
+else
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(EXTRA_LIBS) -o $@
+endif # OS/2
+endif # WINNT
+endif # AIX_PRE_4_2
+
+export:: $(TARGETS)
+clean::
+	rm -f $(TARGETS)
+
+# The following tests call BSD socket functions, so they need to link
+# with -lsocket on some platforms.
+ifeq ($(OS_ARCH),SunOS)
+ifneq ($(OS_RELEASE),4.1.3_U1)
+ifeq ($(USE_IPV6),1)
+$(OBJDIR)/gethost: $(OBJDIR)/gethost.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) -lsocket $(EXTRA_LIBS) -o $@
+endif
+$(OBJDIR)/prpoll: $(OBJDIR)/prpoll.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) -lsocket $(EXTRA_LIBS) -o $@
+endif
+endif
+
+ifeq ($(USE_PTHREADS), 1)
+$(OBJDIR)/attach: $(OBJDIR)/attach.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@
+$(OBJDIR)/foreign: $(OBJDIR)/foreign.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@
+$(OBJDIR)/provider: $(OBJDIR)/provider.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@
+$(OBJDIR)/socket: $(OBJDIR)/socket.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@
+$(OBJDIR)/testfile: $(OBJDIR)/testfile.o
+	$(PURE) $(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBNSPR) $(LIBPTHREAD) $(EXTRA_LIBS) -o $@
+endif
+
+#
+# Run the test programs with no arguments
+#
+# Test output goes to the file pointed to by the environment variable
+# NSPR_TEST_LOGFILE, if set, else to /dev/null
+#
+ECHO = echo
+PROGRAMS = $(notdir $(PROGS))
+ifdef NSPR_TEST_LOGFILE
+LOGFILE = $(NSPR_TEST_LOGFILE)
+else
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+LOGFILE = nul
+else
+LOGFILE = /dev/null
+endif
+endif
+
+ifeq ($(OS_TARGET),Linux)
+ECHO = /bin/echo
+endif
+
+ALWAYS:
+
+runtests:: $(PROGS) ALWAYS
+	@$(ECHO) "\nNSPR Test Results - $(OBJDIR)\n"
+	@$(ECHO) "BEGIN\t\t\t`date`"
+	@$(ECHO) "NSPR_TEST_LOGFILE\t$(LOGFILE)\n"
+	@$(ECHO) "Test\t\t\tResult\n"
+	@cd $(OBJDIR); for i in $(PROGRAMS); do					\
+	$(ECHO) "$$i\c";										\
+	./$$i >> $(LOGFILE) 2>&1 ;								\
+	if  [ 0 = $$? ] ; then									\
+		$(ECHO) "\t\t\tPassed";								\
+	else													\
+		$(ECHO) "\t\t\tFAILED";								\
+	fi;														\
+	done
+	@$(ECHO) "\nEND\t\t`date`\n"

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/README.TXT
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/README.TXT	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,434 @@
+File: pr/tests/readme
+
+This document describes the test cases in the NSPR directory
+pr/tests.
+
+=====================================================================
+There are some sub-directories here:
+
+dll
+	sources for the .dll(.so) used by test dlltest.c
+
+macbuild
+	MacIntosh project files
+
+server
+	an empty directory. Does anyone remember why?
+
+w16gui
+	Sources for a modified version of the poppad application from
+	Charles Petzold's book "Programming Windows 3.1". These
+	sources were modified to test the library lib/ds/PLEvent.
+	These files are obsolete and will not be maintained.
+	
+	This test was superceded by lib/tests/windows/winevent.c and
+	lib/event.c and is now owned by CPD.
+
+=====================================================================
+The individual files are described here.
+
+The script 'runtests.ksh' enumerates and runs test cases that are
+expected to run on all platforms.
+
+
+accept.c
+	Tests PR_Accept() and related socket functions.
+
+acceptread.c
+	Tests PR_AcceptRead()
+
+alarm.c
+	Tests alarm functions declared in obsolete/pralarm.h.
+	The alarm functions are obsolete, so is this test.
+
+atomic.c
+	Tests Atomic operations defined in pratom.h
+
+attach.c
+	Test PR_AttachThread()
+	Note: This is an NSPR private function.
+
+bigfile.c
+	Test 64bit file offset functions declared in prio.h
+
+bug1test.c
+	Demonstrates a bug on NT.
+
+cleanup.c
+	Tests PR_Cleanup() declared in prinit.h
+
+cltsrv.c
+	Tests many socket functions.
+
+concur.c
+	Tests threading functions and concurrent operations.
+
+cvar.c
+	Tests condition variables.
+
+cvar2.c
+	Tests condition variables. A rather abusive test.
+
+dbmalloc.c
+	Obsolete. Originally for testing debug builds of NSPR's malloc.
+
+dbmalloc1.c
+	Obsolete. Originally for testing debug builds of NSPR's malloc.
+
+dceemu.c
+	Tests special functions for DCE emulation.
+
+depend.c
+	Obsoltet. Tests early spec for library dependency.
+
+dlltest.c
+	Tests dynamic library fucntions. Used with dll/my.c
+
+dtoa.c
+	Tests conversions of double to string.
+
+exit.c
+	Tests PR_ProcessExit() declared in prinit.h
+
+fileio.c
+	Tests NSPR semaphores a bit of file i/o and threading
+	functions.
+
+foreign.c
+	Test auto-attach of a thread created by something other than
+	NSPR.
+
+forktest.c
+	Limited use. Tests unix fork() and related functions.
+
+fsync.c
+	Tests use of PR_Sync() declared in prio.h
+
+getproto.c
+	Tests socket functions PR_GetProtoByName(), etc.
+
+i2l.c
+	Tests LongLong functions for converting 32bit integer to 64bit
+	integer.
+
+initclk.c
+	Tests timing on minimal use of condition variable
+
+inrval.c
+	Tests interval timing functions.
+
+instrumt.c
+	Tests instrumentation functions. prcountr.h prtrace.h
+
+intrupt.c
+	Tests PR_Interrupt()
+
+ioconthr.c
+	Tests i/o continuation mechanism in pthreads.
+
+io_timeout.c
+	Test socket i/o timeouts.
+
+io_timeoutk.c
+	Obsolete. Subsumed in io_timeout.c
+
+io_timeoutu.c
+	Obsolete. Subsumed in io_timeout.c
+
+ipv6.c
+	Tests IPv6. IPv6 is not used by NSPR clients.
+
+join.c
+	Tests PR_JoinThread()
+
+joinkk.c
+	Tests PR_JoinThread()
+
+joinku.c
+	Tests PR_JoinThread()
+
+joinuk.c
+	Tests PR_JoinThread()
+
+joinuu.c
+	Tests PR_JoinThread()
+
+layer.c
+	Tests layered I/O.
+
+lazyinit.c
+	Tests implicit initialization.
+
+lltest.c
+	Tests LongLong (64bit integer) arithmentic and conversions.
+
+lock.c
+	Tests PR_Lock() in heavily threaded environment.
+
+lockfile.c
+	Test PR_Lockfile().
+
+logger.c
+	Tests PR_LOG()
+
+makefile
+	The makefile that builds all the tests
+
+many_cv.c
+	Tests aquiring a large number of condition variables.
+
+multiwait.c
+	???
+
+nbconn.c
+	Test non-blocking connect.
+
+nblayer.c
+	Tests NSPR's layered I/O capability.
+
+nonblock.c
+	Tests operations on non-blocking socket.
+
+op_2long.c
+	Tests PR_Open() where filename is too long.
+
+op_filnf.c
+	Tests PR_Open() where filename is NotFound.
+
+op_filok.c
+	Tests PR_Open() where filename is accessable.
+
+op_noacc.c
+	Tests PR_Open() where file permissions are wrong.
+	Limited use. Windows has no concept of Unix style file permissions.
+
+op_nofil.c
+	Tests PR_Open() where filename does not exist.
+
+parent.c
+	Test parent/child process capability
+
+perf.c
+	Tests and measures context switch times for various thread
+	syncronization functions.
+
+pipeping.c
+	Tests inter-process pipes. Run with pipepong.c
+
+pipepong.c
+	Tests inter-process pipes. Run with pipeping.c
+
+pipeself.c
+	Tests inter-thread pipes.
+
+pollable.c
+	Tests pollable events. prio.h
+
+poll_er.c
+	Tests PR_Poll() where an error is expected.
+
+poll_nm.c
+	Tests PR_Poll() where normal operation is expected.
+
+poll_to.c
+	Tests PR_Poll() where timeout is expected.
+
+prftest.c
+	Tests printf-like formatting.
+
+prftest1.c
+	Obsolete. Subsumed in prftest.c
+
+prftest2.c
+	Obsolete. Subsumed in prftest.c
+
+priotest.c
+	Limited use. Tests NSPR thread dispatching priority.
+
+provider.c
+
+prpoll.c
+	Tests PR_Poll().
+
+prselect.c
+	Obsolete. PR_Select() is obsolete.
+
+prttools.h
+	Unused file.
+
+ranfile.c
+	Tests random file access.
+
+readme
+	This file.
+
+runtests.ksh
+	A korn shell script that runs a set of tests that should run
+	on any of the NSPR supported platforms.
+
+runtests.pl
+	A perl script to run the test cases. This srcipt runs tests
+	common to all platforms and runs tests applicable to specific
+	platforms. Uses file runtests.txt to control execution.
+
+runtests.txt
+	Control file for perl script: runtests.pl
+
+rwlocktest.c
+	Tests Reader/Writer lock
+
+selct_er.c
+	Obsolete. PR_Select() is obsolete.
+
+selct_nm.c
+	Obsolete. PR_Select() is obsolete.
+
+selct_to.c
+	Obsolete. PR_Select() is obsolete.
+
+select2.c
+	Obsolete. PR_Select() is obsolete.
+
+sel_spd.c
+	Obsolete. PR_Select() is obsolete.
+
+sem.c
+	Obsolete. Semaphores are not supported.
+
+server_test.c
+	Tests sockets by simulating a server in loopback mode.
+	Makes its own client threads.
+
+servr_kk.c
+	Tests client/server sockets, threads using system threads.
+
+servr_ku.c
+	Tests client/server sockets, threads using system and user threads.
+
+servr_uk.c
+	Tests client/server sockets, threads using system and user threads.
+
+servr_uu.c
+	Tests client/server sockets, threads user threads.
+
+short_thread.c
+	Tests short-running threads. Useful for testing for race conditions.
+
+sigpipe.c
+	Tests NSPR's SIGPIPE handler. Unix only.
+
+sleep.c
+	Limited use. Tests sleep capability of platform.
+
+socket.c
+	Tests many socket functions.
+
+sockopt.c
+	Tests setting and getting socket options.
+
+sprintf.c
+	Tests sprintf.
+
+sproc_ch.c
+	Obsolete. Tests IRIX sproc-based threads.
+
+sproc_p.c
+	Obsolete. Tests IRIX sproc-based threads.
+
+stack.c
+	Test atomic stack operations.
+
+stat.c
+	Tests performance of getfileinfo() vs. stat()
+
+stdio.c
+	Tests NSPR's handling of stdin, stdout, stderr.
+
+strod.c
+	Tests formatting of double precision floating point.
+
+suspend.c
+	Private interfaces PR_SuspendAll(), PR_ResumeAll(), etc.
+
+switch.c
+	Tests thread switching
+
+system.c
+	Tests PR_GetSystemInfo()
+
+testbit.c
+	Tests bit arrays.
+
+testfile.c
+	Tests many file I/O functions.
+
+threads.c
+	Tests thread caching.
+
+thruput.c
+	Tests socket thruput. Must be run by hand as client/server.
+	Does not self terminate.
+
+time.c
+	Incomplete. Limited use.
+
+timemac.c
+	Test time and date functions. Originally for Mac.
+
+timetest.c
+	Tests time conversion over a wide range of dates.
+
+tmoacc.c
+	Server to tmocon.c and writev.c
+	Do not run it by itself.
+
+tmocon.c
+	Client thread to tmoacc.c
+
+tpd.c
+	Tests thread private data.
+
+udpsrv.c
+	Tests UDP socket functions.
+
+ut_ttools.h
+	unused file.
+
+version.c
+	Extract and print library version data.
+
+vercheck.c
+	Test PR_VersionCheck().
+
+writev.c
+	Tests gather-write on a socket. Requires tmoacc.c
+
+xnotify.c
+	Tests cached monitors.
+
+yield.c
+	Limited use
+
+y2k.c
+	Test to verify NSPR's date functions as Y2K compliant.
+
+dll\Makefile
+	makefile for mygetval.c, mysetval.c
+
+dll\mygetval.c
+	Dynamic library test. See also dlltest.c
+
+dll\mysetval.c
+	Dynamic library test. See also dlltest.c
+
+w16gui\Makefile
+	Obsolete. Tests for lib/ds/PLEvent on Windows 3.1.
+w16gui\popfile.c
+w16gui\popfind.c
+w16gui\popfont.c
+w16gui\poppad.c
+w16gui\poppad.h
+w16gui\poppad.ico
+w16gui\poppad.rc
+w16gui\popprnt0.c
+w16gui\readme.1st

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/accept.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/accept.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,524 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+** Name: accept.c
+**
+** Description: Run accept() sucessful connection tests.
+**
+** Modification History:
+** 04-Jun-97 AGarcia - Reconvert test file to return a 0 for PASS and a 1 for FAIL
+** 13-May-97 AGarcia- Converted the test to accomodate the debug_mode 
+**             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.
+** 12-June-97 Revert to return code 0 and 1.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+
+#include "nspr.h"
+#include "prpriv.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "plgetopt.h"
+#include "plerror.h"
+
+#define BASE_PORT 10000
+
+#define CLIENT_DATA        128
+
+#define ACCEPT_NORMAL        0x1
+#define ACCEPT_FAST        0x2
+#define ACCEPT_READ        0x3
+#define ACCEPT_READ_FAST    0x4
+#define ACCEPT_READ_FAST_CB    0x5
+
+#define CLIENT_NORMAL        0x1
+#define CLIENT_TIMEOUT_ACCEPT    0x2
+#define CLIENT_TIMEOUT_SEND    0x3
+
+#define SERVER_MAX_BIND_COUNT        100
+
+#if defined(XP_MAC) || defined(XP_OS2)
+#define TIMEOUTSECS 10
+#else
+#define TIMEOUTSECS 2
+#endif
+PRIntervalTime timeoutTime;
+
+static PRInt32 count = 1;
+static PRFileDesc *output;
+static PRNetAddr serverAddr;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+static PRInt32 clientCommand;
+static PRInt32 iterations;
+static PRStatus rv;
+static PRFileDesc *listenSock;
+static PRFileDesc *clientSock = NULL;
+static PRNetAddr listenAddr;
+static PRNetAddr clientAddr;
+static PRThread *clientThread;
+static PRNetAddr *raddr;
+static char buf[4096 + 2*sizeof(PRNetAddr) + 32];
+static PRInt32 status;
+static PRInt32 bytesRead;
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+void Test_Assert(const char *msg, const char *file, PRIntn line)
+{
+    failed_already=1;
+    if (debug_mode) {
+        PR_fprintf(output,  "@%s:%d ", file, line);
+        PR_fprintf(output, msg);
+    }
+}  /* Test_Assert */
+
+#define TEST_ASSERT(expr) \
+    if (!(expr)) Test_Assert(#expr, __FILE__, __LINE__)
+
+#ifdef WINNT
+#define CALLBACK_MAGIC 0x12345678
+
+void timeout_callback(void *magic)
+{
+    TEST_ASSERT(magic == (void *)CALLBACK_MAGIC);
+    if (debug_mode)
+        PR_fprintf(output, "timeout callback called okay\n");
+}
+#endif
+
+
+static void PR_CALLBACK
+ClientThread(void *_action)
+{
+    PRInt32 action = * (PRInt32 *) _action;
+    PRInt32 iterations = count;
+    PRFileDesc *sock = NULL;
+
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = listenAddr.inet.port;
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    for (; iterations--;) {
+        PRInt32 rv;
+        char buf[CLIENT_DATA];
+
+        memset(buf, 0xaf, sizeof(buf)); /* initialize with arbitrary data */
+        sock = PR_NewTCPSocket();
+        if (!sock) {
+            if (!debug_mode)
+                failed_already=1;
+            else    
+                PR_fprintf(output, "client: unable to create socket\n");
+            return;
+        }
+
+        if (action != CLIENT_TIMEOUT_ACCEPT) {
+
+            if ((rv = PR_Connect(sock, &serverAddr,
+                timeoutTime)) < 0) {
+                if (!debug_mode)
+                    failed_already=1;
+                else    
+                    PR_fprintf(output, 
+                        "client: unable to connect to server (%ld, %ld, %ld, %ld)\n",
+                        iterations, rv, PR_GetError(), PR_GetOSError());
+                goto ErrorExit;
+            }
+
+            if (action != CLIENT_TIMEOUT_SEND) {
+                if ((rv = PR_Send(sock, buf, CLIENT_DATA,
+                    0, timeoutTime))< 0) {
+                    if (!debug_mode)
+                        failed_already=1;
+                    else    
+                        PR_fprintf(output, 
+                            "client: unable to send to server (%d, %ld, %ld)\n",
+                            CLIENT_DATA, rv, PR_GetError());
+                	goto ErrorExit;
+                }
+            } else {
+                PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1));
+            }
+        } else {
+            PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS + 1));
+        }
+        if (debug_mode)
+            PR_fprintf(output, ".");
+        PR_Close(sock);
+		sock = NULL;
+    }
+    if (debug_mode)
+        PR_fprintf(output, "\n");
+
+ErrorExit:
+	if (sock != NULL)
+        PR_Close(sock);
+}
+
+
+static void 
+RunTest(PRInt32 acceptType, PRInt32 clientAction)
+{
+int i;
+
+    /* First bind to the socket */
+    listenSock = PR_NewTCPSocket();
+    if (!listenSock) {
+        failed_already=1;
+        if (debug_mode)
+            PR_fprintf(output, "unable to create listen socket\n");
+        return;
+    }
+	memset(&listenAddr, 0 , sizeof(listenAddr));
+    listenAddr.inet.family = PR_AF_INET;
+    listenAddr.inet.port = PR_htons(BASE_PORT);
+    listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    /*
+     * try a few times to bind server's address, if addresses are in
+     * use
+     */
+    i = 0;
+    while (PR_Bind(listenSock, &listenAddr) == PR_FAILURE) {
+        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+            listenAddr.inet.port += 2;
+            if (i++ < SERVER_MAX_BIND_COUNT)
+                continue;
+        }
+        failed_already=1;
+        if (debug_mode)
+        	PR_fprintf(output,"accept: ERROR - PR_Bind failed\n");
+		return;
+    }
+
+
+    rv = PR_Listen(listenSock, 100);
+    if (rv == PR_FAILURE) {
+        failed_already=1;
+        if (debug_mode)
+            PR_fprintf(output, "unable to listen\n");
+        return;
+    }
+
+    clientCommand = clientAction;
+    clientThread = PR_CreateThread(PR_USER_THREAD, ClientThread,
+        (void *)&clientCommand, PR_PRIORITY_NORMAL, thread_scope,
+        PR_JOINABLE_THREAD, 0);
+    if (!clientThread) {
+        failed_already=1;
+        if (debug_mode)
+            PR_fprintf(output, "error creating client thread\n");
+        return;
+    }
+
+    iterations = count;
+    for (;iterations--;) {
+        switch (acceptType) {
+        case ACCEPT_NORMAL:
+            clientSock = PR_Accept(listenSock, &clientAddr,
+                timeoutTime);
+            switch(clientAction) {
+            case CLIENT_TIMEOUT_ACCEPT:
+                TEST_ASSERT(clientSock == 0);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            case CLIENT_NORMAL:
+                TEST_ASSERT(clientSock);
+                bytesRead = PR_Recv(clientSock,
+                    buf,  CLIENT_DATA,  0,  timeoutTime);
+                TEST_ASSERT(bytesRead == CLIENT_DATA);
+                break;
+            case CLIENT_TIMEOUT_SEND:
+                TEST_ASSERT(clientSock);
+                bytesRead = PR_Recv(clientSock,
+                    buf,  CLIENT_DATA,  0,  timeoutTime);
+                TEST_ASSERT(bytesRead == -1);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            }
+            break;
+        case ACCEPT_READ:
+            status = PR_AcceptRead(listenSock, &clientSock,
+                &raddr, buf, CLIENT_DATA, timeoutTime);
+            switch(clientAction) {
+            case CLIENT_TIMEOUT_ACCEPT:
+                /* Invalid test case */
+                TEST_ASSERT(0);
+                break;
+            case CLIENT_NORMAL:
+                TEST_ASSERT(clientSock);
+                TEST_ASSERT(status == CLIENT_DATA);
+                break;
+            case CLIENT_TIMEOUT_SEND:
+                TEST_ASSERT(status == -1);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            }
+            break;
+#ifdef WINNT
+        case ACCEPT_FAST:
+            clientSock = PR_NTFast_Accept(listenSock,
+                &clientAddr, timeoutTime);
+            switch(clientAction) {
+            case CLIENT_TIMEOUT_ACCEPT:
+                TEST_ASSERT(clientSock == 0);
+                if (debug_mode)
+                    PR_fprintf(output, "PR_GetError is %ld\n", PR_GetError());
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            case CLIENT_NORMAL:
+                TEST_ASSERT(clientSock);
+                bytesRead = PR_Recv(clientSock,
+                    buf,  CLIENT_DATA,  0,  timeoutTime);
+                TEST_ASSERT(bytesRead == CLIENT_DATA);
+                break;
+            case CLIENT_TIMEOUT_SEND:
+                TEST_ASSERT(clientSock);
+                bytesRead = PR_Recv(clientSock,
+                    buf,  CLIENT_DATA,  0,  timeoutTime);
+                TEST_ASSERT(bytesRead == -1);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            }
+            break;
+            break;
+        case ACCEPT_READ_FAST:
+            status = PR_NTFast_AcceptRead(listenSock,
+                &clientSock, &raddr, buf, 4096, timeoutTime);
+            switch(clientAction) {
+            case CLIENT_TIMEOUT_ACCEPT:
+                /* Invalid test case */
+                TEST_ASSERT(0);
+                break;
+            case CLIENT_NORMAL:
+                TEST_ASSERT(clientSock);
+                TEST_ASSERT(status == CLIENT_DATA);
+                break;
+            case CLIENT_TIMEOUT_SEND:
+                TEST_ASSERT(clientSock == NULL);
+                TEST_ASSERT(status == -1);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            }
+            break;
+        case ACCEPT_READ_FAST_CB:
+            status = PR_NTFast_AcceptRead_WithTimeoutCallback(
+                listenSock, &clientSock, &raddr, buf, 4096,
+                timeoutTime, timeout_callback, (void *)CALLBACK_MAGIC);
+            switch(clientAction) {
+            case CLIENT_TIMEOUT_ACCEPT:
+                /* Invalid test case */
+                TEST_ASSERT(0);
+                break;
+            case CLIENT_NORMAL:
+                TEST_ASSERT(clientSock);
+                TEST_ASSERT(status == CLIENT_DATA);
+                break;
+            case CLIENT_TIMEOUT_SEND:
+                if (debug_mode)
+                    PR_fprintf(output, "clientSock = 0x%8.8lx\n", clientSock);
+                TEST_ASSERT(clientSock == NULL);
+                TEST_ASSERT(status == -1);
+                TEST_ASSERT(PR_GetError() == PR_IO_TIMEOUT_ERROR);
+                break;
+            }
+            break;
+#endif
+        }
+        if (clientSock != NULL) {
+            PR_Close(clientSock);
+            clientSock = NULL;
+        }
+    }
+    PR_Close(listenSock);
+
+    PR_JoinThread(clientThread);
+}
+
+
+void AcceptUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_NORMAL, CLIENT_NORMAL); 
+}
+void AcceptNotUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_FAST, CLIENT_NORMAL); 
+}
+void AcceptReadTest(void)
+{ 
+    RunTest(ACCEPT_READ, CLIENT_NORMAL); 
+}
+void AcceptReadNotUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_READ_FAST, CLIENT_NORMAL); 
+}
+void AcceptReadCallbackTest(void)
+{ 
+    RunTest(ACCEPT_READ_FAST_CB, CLIENT_NORMAL); 
+}
+
+void TimeoutAcceptUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_ACCEPT); 
+}
+void TimeoutAcceptNotUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_ACCEPT); 
+}
+void TimeoutAcceptReadCallbackTest(void)
+{ 
+    RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_ACCEPT); 
+}
+
+void TimeoutReadUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_NORMAL, CLIENT_TIMEOUT_SEND); 
+}
+void TimeoutReadNotUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_FAST, CLIENT_TIMEOUT_SEND); 
+}
+void TimeoutReadReadTest(void)
+{ 
+    RunTest(ACCEPT_READ, CLIENT_TIMEOUT_SEND); 
+}
+void TimeoutReadReadNotUpdatedTest(void)
+{ 
+    RunTest(ACCEPT_READ_FAST, CLIENT_TIMEOUT_SEND); 
+}
+void TimeoutReadReadCallbackTest(void)
+{ 
+    RunTest(ACCEPT_READ_FAST_CB, CLIENT_TIMEOUT_SEND); 
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+    if (debug_mode)
+        PR_fprintf(output, "%40s: %6.2f usec\n", msg, d / count);
+
+}
+
+int main(int argc, char **argv)
+{
+
+    /* 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] [-c n]
+    */
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "Gdc:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'd':  /* debug mode */
+            debug_mode = 1;
+            break;
+        case 'c':  /* loop counter */
+            count = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    output = PR_STDERR;
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+    SetupMacPrintfLog("accept.log");
+    debug_mode = 1;
+#endif
+
+    timeoutTime = PR_SecondsToInterval(TIMEOUTSECS);
+    if (debug_mode)
+        PR_fprintf(output, "\nRun accept() sucessful connection tests\n");
+
+    Measure(AcceptUpdatedTest, "PR_Accept()");
+    Measure(AcceptReadTest, "PR_AcceptRead()");
+#ifdef WINNT
+    Measure(AcceptNotUpdatedTest, "PR_NTFast_Accept()");
+    Measure(AcceptReadNotUpdatedTest, "PR_NTFast_AcceptRead()");
+    Measure(AcceptReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
+#endif
+    if (debug_mode)
+        PR_fprintf(output, "\nRun accept() timeout in the accept tests\n");
+#ifdef WINNT
+    Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
+#endif
+    Measure(TimeoutReadUpdatedTest, "PR_Accept()");
+    if (debug_mode)
+        PR_fprintf(output, "\nRun accept() timeout in the read tests\n");
+    Measure(TimeoutReadReadTest, "PR_AcceptRead()");
+#ifdef WINNT
+    Measure(TimeoutReadNotUpdatedTest, "PR_NTFast_Accept()");
+    Measure(TimeoutReadReadNotUpdatedTest, "PR_NTFast_AcceptRead()");
+    Measure(TimeoutReadReadCallbackTest, "PR_NTFast_AcceptRead_WithTimeoutCallback()");
+#endif
+    PR_fprintf(output, "%s\n", (failed_already) ? "FAIL" : "PASS");
+    return failed_already;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/acceptread.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/acceptread.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,272 @@
+/* -*- 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 <prio.h>
+#include <prprf.h>
+#include <prinit.h>
+#include <prnetdb.h>
+#include <prinrval.h>
+#include <prthread.h>
+
+#include <plerror.h>
+
+#include <stdlib.h>
+
+#define DEFAULT_PORT 12273
+#define GET "GET / HTTP/1.0\n\n"
+static PRFileDesc *std_out, *err_out;
+static PRIntervalTime write_dally, accept_timeout;
+
+static PRStatus PrintAddress(const PRNetAddr* address)
+{
+    char buffer[100];
+    PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
+    if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_NetAddrToString");
+    else PR_fprintf(
+        std_out, "Accepted connection from (0x%p)%s:%d\n",
+        address, buffer, address->inet.port);
+    return rv;
+}  /* PrintAddress */
+
+static void ConnectingThread(void *arg)
+{
+    PRInt32 nbytes;
+    char buf[1024];
+    PRFileDesc *sock;
+    PRNetAddr peer_addr, *addr;
+
+    addr = (PRNetAddr*)arg;
+
+    sock = PR_NewTCPSocket();
+    if (sock == NULL)
+    {
+        PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed");
+        PR_ProcessExit(1);
+    }
+
+    if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE)
+    {
+        PL_FPrintError(err_out, "PR_Connect (client) failed");
+        PR_ProcessExit(1);
+    }
+    if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE)
+    {
+        PL_FPrintError(err_out, "PR_GetPeerName (client) failed");
+        PR_ProcessExit(1);
+    }
+
+    /*
+    ** Then wait between the connection coming up and sending the expected
+    ** data. At some point in time, the server should fail due to a timeou
+    ** on the AcceptRead() operation, which according to the document is
+    ** only due to the read() portion.
+    */
+    PR_Sleep(write_dally);
+
+    nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed");
+
+    nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed");
+    else
+    {
+        PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes);
+        buf[sizeof(buf) - 1] = '\0';
+        PR_fprintf(std_out, "%s\n", buf);
+    }
+
+    if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH))
+        PL_FPrintError(err_out, "PR_Shutdown (client) failed");
+
+    if (PR_FAILURE == PR_Close(sock))
+        PL_FPrintError(err_out, "PR_Close (client) failed");
+
+    return;
+}  /* ConnectingThread */
+
+#define BUF_SIZE 117
+static void AcceptingThread(void *arg)
+{
+    PRStatus rv;
+    PRInt32 bytes;
+    PRSize buf_size = BUF_SIZE;
+    PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32];
+    PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg;
+    PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket();
+    PRSocketOptionData sock_opt;
+
+    if (NULL == listen_sock)
+    {
+        PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed");
+        PR_ProcessExit(1);        
+    }
+    sock_opt.option = PR_SockOpt_Reuseaddr;
+    sock_opt.value.reuse_addr = PR_TRUE;
+    rv = PR_SetSocketOption(listen_sock, &sock_opt);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_SetSocketOption (server) failed");
+        PR_ProcessExit(1);        
+    }
+    rv = PR_Bind(listen_sock, listen_addr);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_Bind (server) failed");
+        PR_ProcessExit(1);        
+    }
+    rv = PR_Listen(listen_sock, 10);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_Listen (server) failed");
+        PR_ProcessExit(1);        
+    }
+    bytes = PR_AcceptRead(
+        listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout);
+
+    if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed");
+    else
+    {
+        PrintAddress(accept_addr);
+        PR_fprintf(
+            std_out, "(Server) read [0x%p..0x%p) %s\n",
+            buf, &buf[BUF_SIZE], buf);
+        bytes = PR_Write(accept_sock, buf, bytes);
+        rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err_out, "PR_Shutdown (server) failed");
+    }
+
+    if (-1 != bytes)
+    {
+        rv = PR_Close(accept_sock);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err_out, "PR_Close (server) failed");
+    }
+
+    rv = PR_Close(listen_sock);
+    if (PR_FAILURE == rv)
+        PL_FPrintError(err_out, "PR_Close (server) failed");
+}  /* AcceptingThread */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRHostEnt he;
+    PRStatus status;
+    PRIntn next_index;
+    PRUint16 port_number;
+    char netdb_buf[PR_NETDB_BUF_SIZE];
+    PRNetAddr client_addr, server_addr;
+    PRThread *client_thread, *server_thread;
+    PRIntervalTime delta = PR_MillisecondsToInterval(500);
+
+    err_out = PR_STDERR;
+    std_out = PR_STDOUT;
+    accept_timeout = PR_SecondsToInterval(2);
+
+    if (argc != 2 && argc != 3) port_number = DEFAULT_PORT;
+    else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]);
+
+    status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr);
+    if (PR_SUCCESS != status)
+    {
+        PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
+        PR_ProcessExit(1);
+    }
+    if (argc < 3)
+    {
+        status = PR_InitializeNetAddr(
+            PR_IpAddrLoopback, port_number, &client_addr);
+        if (PR_SUCCESS != status)
+        {
+            PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
+            PR_ProcessExit(1);
+        }
+    }
+    else
+    {
+        status = PR_GetHostByName(
+            argv[1], netdb_buf, sizeof(netdb_buf), &he);
+        if (status == PR_FAILURE)
+        {
+            PL_FPrintError(err_out, "PR_GetHostByName failed");
+            PR_ProcessExit(1);
+        }
+        next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr);
+        if (next_index == -1)
+        {
+            PL_FPrintError(err_out, "PR_EnumerateHostEnt failed");
+            PR_ProcessExit(1);
+        }
+    }
+
+    for (
+        write_dally = 0;
+        write_dally < accept_timeout + (2 * delta);
+        write_dally += delta)
+    {
+        PR_fprintf(
+            std_out, "Testing w/ write_dally = %d msec\n",
+            PR_IntervalToMilliseconds(write_dally));
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, AcceptingThread, &server_addr,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (server_thread == NULL)
+        {
+            PL_FPrintError(err_out, "PR_CreateThread (server) failed");
+            PR_ProcessExit(1);
+        }
+
+        PR_Sleep(delta);  /* let the server pot thicken */
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, ConnectingThread, &client_addr,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (client_thread == NULL)
+        {
+            PL_FPrintError(err_out, "PR_CreateThread (client) failed");
+            PR_ProcessExit(1);
+        }
+
+        if (PR_JoinThread(client_thread) == PR_FAILURE)
+            PL_FPrintError(err_out, "PR_JoinThread (client) failed");
+
+        if (PR_JoinThread(server_thread) == PR_FAILURE)
+            PL_FPrintError(err_out, "PR_JoinThread (server) failed");
+    }
+
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/acceptreademu.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/acceptreademu.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,302 @@
+/* -*- 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 ***** */
+
+/*
+ * This test is the same as acceptread.c except that it uses the
+ * emulated acceptread method instead of the regular acceptread.
+ */
+
+#include <prio.h>
+#include <prprf.h>
+#include <prinit.h>
+#include <prnetdb.h>
+#include <prinrval.h>
+#include <prthread.h>
+#include <pprio.h>
+
+#include <plerror.h>
+
+#include <stdlib.h>
+
+#define DEFAULT_PORT 12273
+#define GET "GET / HTTP/1.0\n\n"
+static PRFileDesc *std_out, *err_out;
+static PRIntervalTime write_dally, accept_timeout;
+static PRDescIdentity emu_layer_ident;
+static PRIOMethods emu_layer_methods;
+
+/* the acceptread method in emu_layer_methods */
+static PRInt32 PR_CALLBACK emu_AcceptRead(PRFileDesc *sd, PRFileDesc **nd,
+    PRNetAddr **raddr, void *buf, PRInt32 amount, PRIntervalTime timeout)
+{
+    return PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout);
+}
+
+static PRStatus PrintAddress(const PRNetAddr* address)
+{
+    char buffer[100];
+    PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
+    if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_NetAddrToString");
+    else PR_fprintf(
+        std_out, "Accepted connection from (0x%p)%s:%d\n",
+        address, buffer, address->inet.port);
+    return rv;
+}  /* PrintAddress */
+
+static void ConnectingThread(void *arg)
+{
+    PRInt32 nbytes;
+    char buf[1024];
+    PRFileDesc *sock;
+    PRNetAddr peer_addr, *addr;
+
+    addr = (PRNetAddr*)arg;
+
+    sock = PR_NewTCPSocket();
+    if (sock == NULL)
+    {
+        PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed");
+        PR_ProcessExit(1);
+    }
+
+    if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE)
+    {
+        PL_FPrintError(err_out, "PR_Connect (client) failed");
+        PR_ProcessExit(1);
+    }
+    if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE)
+    {
+        PL_FPrintError(err_out, "PR_GetPeerName (client) failed");
+        PR_ProcessExit(1);
+    }
+
+    /*
+    ** Then wait between the connection coming up and sending the expected
+    ** data. At some point in time, the server should fail due to a timeou
+    ** on the AcceptRead() operation, which according to the document is
+    ** only due to the read() portion.
+    */
+    PR_Sleep(write_dally);
+
+    nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed");
+
+    nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed");
+    else
+    {
+        PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes);
+        buf[sizeof(buf) - 1] = '\0';
+        PR_fprintf(std_out, "%s\n", buf);
+    }
+
+    if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH))
+        PL_FPrintError(err_out, "PR_Shutdown (client) failed");
+
+    if (PR_FAILURE == PR_Close(sock))
+        PL_FPrintError(err_out, "PR_Close (client) failed");
+
+    return;
+}  /* ConnectingThread */
+
+#define BUF_SIZE 117
+static void AcceptingThread(void *arg)
+{
+    PRStatus rv;
+    PRInt32 bytes;
+    PRSize buf_size = BUF_SIZE;
+    PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32];
+    PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg;
+    PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket();
+    PRFileDesc *layer;
+    PRSocketOptionData sock_opt;
+
+    if (NULL == listen_sock)
+    {
+        PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed");
+        PR_ProcessExit(1);        
+    }
+    layer = PR_CreateIOLayerStub(emu_layer_ident, &emu_layer_methods);
+    if (NULL == layer)
+    {
+        PL_FPrintError(err_out, "PR_CreateIOLayerStub (server) failed");
+        PR_ProcessExit(1);        
+    }
+    if (PR_PushIOLayer(listen_sock, PR_TOP_IO_LAYER, layer) == PR_FAILURE)
+    {
+        PL_FPrintError(err_out, "PR_PushIOLayer (server) failed");
+        PR_ProcessExit(1);        
+    }
+    sock_opt.option = PR_SockOpt_Reuseaddr;
+    sock_opt.value.reuse_addr = PR_TRUE;
+    rv = PR_SetSocketOption(listen_sock, &sock_opt);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_SetSocketOption (server) failed");
+        PR_ProcessExit(1);        
+    }
+    rv = PR_Bind(listen_sock, listen_addr);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_Bind (server) failed");
+        PR_ProcessExit(1);        
+    }
+    rv = PR_Listen(listen_sock, 10);
+    if (PR_FAILURE == rv)
+    {
+        PL_FPrintError(err_out, "PR_Listen (server) failed");
+        PR_ProcessExit(1);        
+    }
+    bytes = PR_AcceptRead(
+        listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout);
+
+    if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed");
+    else
+    {
+        PrintAddress(accept_addr);
+        PR_fprintf(
+            std_out, "(Server) read [0x%p..0x%p) %s\n",
+            buf, &buf[BUF_SIZE], buf);
+        bytes = PR_Write(accept_sock, buf, bytes);
+        rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err_out, "PR_Shutdown (server) failed");
+    }
+
+    if (-1 != bytes)
+    {
+        rv = PR_Close(accept_sock);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err_out, "PR_Close (server) failed");
+    }
+
+    rv = PR_Close(listen_sock);
+    if (PR_FAILURE == rv)
+        PL_FPrintError(err_out, "PR_Close (server) failed");
+}  /* AcceptingThread */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRHostEnt he;
+    PRStatus status;
+    PRIntn next_index;
+    PRUint16 port_number;
+    char netdb_buf[PR_NETDB_BUF_SIZE];
+    PRNetAddr client_addr, server_addr;
+    PRThread *client_thread, *server_thread;
+    PRIntervalTime delta = PR_MillisecondsToInterval(500);
+
+    err_out = PR_STDERR;
+    std_out = PR_STDOUT;
+    accept_timeout = PR_SecondsToInterval(2);
+    emu_layer_ident = PR_GetUniqueIdentity("Emulated AcceptRead");
+    emu_layer_methods = *PR_GetDefaultIOMethods();
+    emu_layer_methods.acceptread = emu_AcceptRead;
+
+    if (argc != 2 && argc != 3) port_number = DEFAULT_PORT;
+    else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]);
+
+    status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr);
+    if (PR_SUCCESS != status)
+    {
+        PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
+        PR_ProcessExit(1);
+    }
+    if (argc < 3)
+    {
+        status = PR_InitializeNetAddr(
+            PR_IpAddrLoopback, port_number, &client_addr);
+        if (PR_SUCCESS != status)
+        {
+            PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
+            PR_ProcessExit(1);
+        }
+    }
+    else
+    {
+        status = PR_GetHostByName(
+            argv[1], netdb_buf, sizeof(netdb_buf), &he);
+        if (status == PR_FAILURE)
+        {
+            PL_FPrintError(err_out, "PR_GetHostByName failed");
+            PR_ProcessExit(1);
+        }
+        next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr);
+        if (next_index == -1)
+        {
+            PL_FPrintError(err_out, "PR_EnumerateHostEnt failed");
+            PR_ProcessExit(1);
+        }
+    }
+
+    for (
+        write_dally = 0;
+        write_dally < accept_timeout + (2 * delta);
+        write_dally += delta)
+    {
+        PR_fprintf(
+            std_out, "Testing w/ write_dally = %d msec\n",
+            PR_IntervalToMilliseconds(write_dally));
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, AcceptingThread, &server_addr,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (server_thread == NULL)
+        {
+            PL_FPrintError(err_out, "PR_CreateThread (server) failed");
+            PR_ProcessExit(1);
+        }
+
+        PR_Sleep(delta);  /* let the server pot thicken */
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, ConnectingThread, &client_addr,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+        if (client_thread == NULL)
+        {
+            PL_FPrintError(err_out, "PR_CreateThread (client) failed");
+            PR_ProcessExit(1);
+        }
+
+        if (PR_JoinThread(client_thread) == PR_FAILURE)
+            PL_FPrintError(err_out, "PR_JoinThread (client) failed");
+
+        if (PR_JoinThread(server_thread) == PR_FAILURE)
+            PL_FPrintError(err_out, "PR_JoinThread (server) failed");
+    }
+
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/addrstr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/addrstr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,114 @@
+/* -*- 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) 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 "prnetdb.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+const char *testaddrs[] = {
+    "::", "::",
+    "::1", "::1",
+    "::ffff", "::ffff",
+    "::1:0", "::0.1.0.0",
+    "::127.0.0.1", "::127.0.0.1",
+    "::FFFF:127.0.0.1", "::ffff:127.0.0.1",
+    "::FFFE:9504:3501", "::fffe:9504:3501",
+    "0:0:1:0:35c:0:0:0", "0:0:1:0:35c::",
+    "0:0:3f4c:0:0:4552:0:0", "::3f4c:0:0:4552:0:0",
+    "0:0:1245:0:0:0:0567:0", "0:0:1245::567:0", 
+    "0:1:2:3:4:5:6:7", "0:1:2:3:4:5:6:7", 
+    "1:2:3:0:4:5:6:7", "1:2:3:0:4:5:6:7", 
+    "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:0", 
+    "1:2:3:4:5:6:7:8", "1:2:3:4:5:6:7:8", 
+    "1:2:3:4:5:6::7", "1:2:3:4:5:6:0:7", 
+    0
+};
+
+const char *badaddrs[] = {
+    "::.1.2.3",
+    "ffff::.1.2.3",
+    "1:2:3:4:5:6:7::8",
+    "1:2:3:4:5:6::7:8",
+    "::ff99.2.3.4",
+    0
+};
+
+int failed_already = 0;
+
+int main()
+{
+    const char **nexttestaddr = testaddrs;
+    const char **nextbadaddr = badaddrs;
+    const char *in, *expected_out;
+    PRNetAddr addr;
+    char buf[256];
+    PRStatus rv;
+
+    while ((in = *nexttestaddr++) != 0) {
+	expected_out = *nexttestaddr++;
+	rv = PR_StringToNetAddr(in, &addr);
+	if (rv) {
+	    printf("cannot convert %s to addr: %d\n", in, rv);
+            failed_already = 1;
+	    continue;
+	}
+	rv = PR_NetAddrToString(&addr, buf, sizeof(buf));
+	if (rv) {
+	    printf("cannot convert %s back to string: %d\n", in, rv);
+            failed_already = 1;
+	    continue;
+	}
+	if (strcmp(buf, expected_out)) {
+            /* This is not necessarily an error */
+	    printf("%s expected %s got %s\n", in, expected_out, buf);
+	}
+    }
+    while ((in = *nextbadaddr++) != 0) {
+        if (PR_StringToNetAddr(in, &addr) == PR_SUCCESS) {
+            printf("converted bad addr %s\n", in);
+            failed_already = 1;
+        }
+    }
+    if (failed_already) {
+        printf("FAIL\n");
+        return 1;
+    }
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/affinity.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/affinity.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,124 @@
+/* -*- 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 "nspr.h"
+#include "pprthred.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef XP_BEOS
+
+/*
+ * Test PR_GetThreadAffinityMask
+ *		The function is called by each of local, global and global bound threads
+ *		The test should be run on both single and multi-cpu systems
+ */
+static void PR_CALLBACK thread_start(void *arg)
+{
+PRUint32 mask = 0;
+
+	if (PR_GetThreadAffinityMask(PR_GetCurrentThread(), &mask)) 
+		printf("\tthread_start: PR_GetCurrentThreadAffinityMask failed\n");
+	else
+		printf("\tthread_start: AffinityMask = 0x%x\n",mask);
+
+}
+
+int main(int argc, char **argv)
+{
+	PRThread *t;
+
+	printf("main: creating local thread\n");
+
+	t = PR_CreateThread(PR_USER_THREAD,
+				  thread_start, 0, 
+				  PR_PRIORITY_NORMAL,
+				  PR_LOCAL_THREAD,
+				  PR_JOINABLE_THREAD,
+				  0);
+
+	if (NULL == t) {
+		printf("main: cannot create local thread\n");
+		exit(1);
+	}
+
+	PR_JoinThread(t);
+
+	printf("main: creating global thread\n");
+	t = PR_CreateThread(PR_USER_THREAD,
+				  thread_start, 0, 
+				  PR_PRIORITY_NORMAL,
+				  PR_GLOBAL_THREAD,
+				  PR_JOINABLE_THREAD,
+				  0);
+
+	if (NULL == t) {
+		printf("main: cannot create global thread\n");
+		exit(1);
+	}
+
+	PR_JoinThread(t);
+
+	printf("main: creating global bound thread\n");
+	t = PR_CreateThread(PR_USER_THREAD,
+				  thread_start, 0, 
+				  PR_PRIORITY_NORMAL,
+				  PR_GLOBAL_BOUND_THREAD,
+				  PR_JOINABLE_THREAD,
+				  0);
+
+	if (NULL == t) {
+		printf("main: cannot create global bound thread\n");
+		exit(1);
+	}
+
+	PR_JoinThread(t);
+
+    return 0;
+}
+
+#else /* !XP_BEOS */
+
+int main()
+{
+	printf( "This test is not supported on the BeOS\n" );
+	return 0;
+}
+#endif /* !XP_BEOS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/alarm.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/alarm.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,569 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+** Name: alarmtst.c
+**
+** Description: Test alarms
+**
+** Modification History:
+** 13-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 "prlog.h"
+#include "prinit.h"
+#ifdef XP_MAC
+#include "pralarm.h"
+#else
+#include "obsolete/pralarm.h"
+#endif
+#include "prlock.h"
+#include "prlong.h"
+#include "prcvar.h"
+#include "prinrval.h"
+#include "prtime.h"
+
+/* Used to get the command line option */
+#include "plgetopt.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(XP_UNIX)
+#include <sys/time.h>
+#endif
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+static PRIntn debug_mode;
+static PRIntn failed_already=0;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+typedef struct notifyData {
+    PRLock *ml;
+    PRCondVar *child;
+    PRCondVar *parent;
+    PRBool pending;
+    PRUint32 counter;
+} NotifyData;
+
+static void Notifier(void *arg)
+{
+    NotifyData *notifyData = (NotifyData*)arg;
+    PR_Lock(notifyData->ml);
+    while (notifyData->counter > 0)
+    {
+        while (!notifyData->pending)
+            PR_WaitCondVar(notifyData->child, PR_INTERVAL_NO_TIMEOUT);
+        notifyData->counter -= 1;
+        notifyData->pending = PR_FALSE;
+        PR_NotifyCondVar(notifyData->parent);
+    }
+    PR_Unlock(notifyData->ml);
+}  /* Notifier */
+/***********************************************************************
+** PRIVATE FUNCTION:    ConditionNotify
+** DESCRIPTION:
+** 
+** INPUTS:      loops
+** OUTPUTS:     None
+** RETURN:      overhead
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:
+**      
+***********************************************************************/
+
+
+static PRIntervalTime ConditionNotify(PRUint32 loops)
+{
+    PRThread *thread;
+    NotifyData notifyData;
+    PRIntervalTime timein, overhead;
+    
+    timein = PR_IntervalNow();
+
+    notifyData.counter = loops;
+    notifyData.ml = PR_NewLock();
+    notifyData.child = PR_NewCondVar(notifyData.ml);
+    notifyData.parent = PR_NewCondVar(notifyData.ml);
+    thread = PR_CreateThread(
+        PR_USER_THREAD, Notifier, &notifyData,
+        PR_GetThreadPriority(PR_GetCurrentThread()),
+        thread_scope, PR_JOINABLE_THREAD, 0);
+
+    overhead = PR_IntervalNow() - timein;  /* elapsed so far */
+
+    PR_Lock(notifyData.ml);
+    while (notifyData.counter > 0)
+    {
+        notifyData.pending = PR_TRUE;
+        PR_NotifyCondVar(notifyData.child);
+        while (notifyData.pending)
+            PR_WaitCondVar(notifyData.parent, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(notifyData.ml);
+
+    timein = PR_IntervalNow();
+
+    (void)PR_JoinThread(thread);
+    PR_DestroyCondVar(notifyData.child);
+    PR_DestroyCondVar(notifyData.parent);
+    PR_DestroyLock(notifyData.ml);
+    
+    overhead += (PR_IntervalNow() - timein);  /* more overhead */
+
+    return overhead;
+}  /* ConditionNotify */
+
+static PRIntervalTime ConditionTimeout(PRUint32 loops)
+{
+    PRUintn count;
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PR_NewCondVar(ml);
+    PRIntervalTime interval = PR_MillisecondsToInterval(50);
+
+    overhead = PR_IntervalNow() - timein;
+
+    PR_Lock(ml);
+    for (count = 0; count < loops; ++count)
+    {
+        overhead += interval;
+        PR_ASSERT(PR_WaitCondVar(cv, interval) == PR_SUCCESS);
+    }
+    PR_Unlock(ml);
+
+    timein = PR_IntervalNow();
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    overhead += (PR_IntervalNow() - timein);
+
+    return overhead;
+}  /* ConditionTimeout */
+
+typedef struct AlarmData {
+    PRLock *ml;
+    PRCondVar *cv;
+    PRUint32 rate, late, times;
+    PRIntervalTime duration, timein, period;
+} AlarmData;
+
+static PRBool AlarmFn1(PRAlarmID *id, void *clientData, PRUint32 late)
+{
+    PRStatus rv = PR_SUCCESS;
+    PRBool keepGoing, resetAlarm;
+    PRIntervalTime interval, now = PR_IntervalNow();
+    AlarmData *ad = (AlarmData*)clientData;
+
+    PR_Lock(ad->ml);
+    ad->late += late;
+    ad->times += 1;
+    keepGoing = ((PRIntervalTime)(now - ad->timein) < ad->duration) ?
+        PR_TRUE : PR_FALSE;
+    if (!keepGoing)
+        rv = PR_NotifyCondVar(ad->cv);
+    resetAlarm = ((ad->times % 31) == 0) ? PR_TRUE : PR_FALSE;
+                                         
+    interval = (ad->period + ad->rate - 1) / ad->rate;
+    if (!late && (interval > 10))
+    {
+        interval &= (now & 0x03) + 1;
+        PR_WaitCondVar(ad->cv, interval);
+    }
+          
+    PR_Unlock(ad->ml);
+
+    if (rv != PR_SUCCESS)
+    {
+		if (!debug_mode) failed_already=1;
+		else
+		 printf("AlarmFn: notify status: FAIL\n");
+		
+	}
+
+    if (resetAlarm)
+    {   
+        ad->rate += 3;
+        ad->late = ad->times = 0;
+        if (PR_ResetAlarm(id, ad->period, ad->rate) != PR_SUCCESS)
+        {
+			if (!debug_mode)
+				failed_already=1;
+			else		
+				printf("AlarmFn: Resetting alarm status: FAIL\n");
+
+            keepGoing = PR_FALSE;
+        }
+
+    }
+
+    return keepGoing;
+}  /* AlarmFn1 */
+
+static PRIntervalTime Alarms1(PRUint32 loops)
+{
+    PRAlarm *alarm;
+    AlarmData ad;
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+    PRIntervalTime duration = PR_SecondsToInterval(3);
+
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PR_NewCondVar(ml);
+
+    ad.ml = ml;
+    ad.cv = cv;
+    ad.rate = 1;
+    ad.times = loops;
+    ad.late = ad.times = 0;
+    ad.duration = duration;
+    ad.timein = PR_IntervalNow();
+    ad.period = PR_SecondsToInterval(1);
+
+    alarm = PR_CreateAlarm();
+
+    (void)PR_SetAlarm(
+        alarm, ad.period, ad.rate, AlarmFn1, &ad);
+        
+    overhead = PR_IntervalNow() - timein;
+
+    PR_Lock(ml);
+    while ((PRIntervalTime)(PR_IntervalNow() - ad.timein) < duration)
+        PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT);
+    PR_Unlock(ml);
+
+    timein = PR_IntervalNow();
+    (void)PR_DestroyAlarm(alarm);
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    overhead += (PR_IntervalNow() - timein);
+    
+    return duration + overhead;
+}  /* Alarms1 */
+
+static PRBool AlarmFn2(PRAlarmID *id, void *clientData, PRUint32 late)
+{
+#if defined(XP_MAC)
+#pragma unused (id)
+#endif
+
+    PRBool keepGoing;
+    PRStatus rv = PR_SUCCESS;
+    AlarmData *ad = (AlarmData*)clientData;
+    PRIntervalTime interval, now = PR_IntervalNow();
+
+    PR_Lock(ad->ml);
+    ad->times += 1;
+    keepGoing = ((PRIntervalTime)(now - ad->timein) < ad->duration) ?
+        PR_TRUE : PR_FALSE;
+    interval = (ad->period + ad->rate - 1) / ad->rate;
+
+    if (!late && (interval > 10))
+    {
+        interval &= (now & 0x03) + 1;
+        PR_WaitCondVar(ad->cv, interval);
+    }
+
+    if (!keepGoing) rv = PR_NotifyCondVar(ad->cv);
+
+    PR_Unlock(ad->ml);
+
+
+    if (rv != PR_SUCCESS)
+		failed_already=1;;
+
+    return keepGoing;
+}  /* AlarmFn2 */
+
+static PRIntervalTime Alarms2(PRUint32 loops)
+{
+    PRStatus rv;
+    PRAlarm *alarm;
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+    AlarmData ad;
+    PRIntervalTime duration = PR_SecondsToInterval(30);
+
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PR_NewCondVar(ml);
+
+    ad.ml = ml;
+    ad.cv = cv;
+    ad.rate = 1;
+    ad.times = loops;
+    ad.late = ad.times = 0;
+    ad.duration = duration;
+    ad.timein = PR_IntervalNow();
+    ad.period = PR_SecondsToInterval(1);
+
+    alarm = PR_CreateAlarm();
+
+    (void)PR_SetAlarm(
+        alarm, ad.period, ad.rate, AlarmFn2, &ad);
+        
+    overhead = PR_IntervalNow() - timein;
+
+    PR_Lock(ml);
+    while ((PRIntervalTime)(PR_IntervalNow() - ad.timein) < duration)
+        PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT);
+    PR_Unlock(ml);
+    
+    timein = PR_IntervalNow();
+
+    rv = PR_DestroyAlarm(alarm);
+    if (rv != PR_SUCCESS)
+    {
+		if (!debug_mode)
+			failed_already=1;
+		else	
+			printf("***Destroying alarm status: FAIL\n");
+    }
+		
+
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    
+    overhead += (PR_IntervalNow() - timein);
+    
+    return duration + overhead;
+}  /* Alarms2 */
+
+static PRIntervalTime Alarms3(PRUint32 loops)
+{
+    PRIntn i;
+    PRStatus rv;
+    PRAlarm *alarm;
+    AlarmData ad[3];
+    PRIntervalTime duration = PR_SecondsToInterval(30);
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PR_NewCondVar(ml);
+
+    for (i = 0; i < 3; ++i)
+    {
+        ad[i].ml = ml;
+        ad[i].cv = cv;
+        ad[i].rate = 1;
+        ad[i].times = loops;
+        ad[i].duration = duration;
+        ad[i].late = ad[i].times = 0;
+        ad[i].timein = PR_IntervalNow();
+        ad[i].period = PR_SecondsToInterval(1);
+
+        /* more loops, faster rate => same elapsed time */
+        ad[i].times = (i + 1) * loops;
+        ad[i].rate = (i + 1) * 10;
+    }
+
+    alarm = PR_CreateAlarm();
+
+    for (i = 0; i < 3; ++i)
+    {
+        (void)PR_SetAlarm(
+            alarm, ad[i].period, ad[i].rate,
+            AlarmFn2, &ad[i]);
+    }
+        
+    overhead = PR_IntervalNow() - timein;
+
+    PR_Lock(ml);
+    for (i = 0; i < 3; ++i)
+    {
+        while ((PRIntervalTime)(PR_IntervalNow() - ad[i].timein) < duration)
+            PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(ml);
+
+    timein = PR_IntervalNow();
+
+	if (debug_mode)
+	printf
+        ("Alarms3 finished at %u, %u, %u\n",
+        ad[0].timein, ad[1].timein, ad[2].timein);
+    
+    rv = PR_DestroyAlarm(alarm);
+    if (rv != PR_SUCCESS)
+    {
+		if (!debug_mode)		
+			failed_already=1;
+		else	
+		   printf("***Destroying alarm status: FAIL\n");
+	}
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    
+    overhead += (duration / 3);
+    overhead += (PR_IntervalNow() - timein);
+
+    return overhead;
+}  /* Alarms3 */
+
+static PRUint32 TimeThis(
+    const char *msg, PRUint32 (*func)(PRUint32 loops), PRUint32 loops)
+{
+    PRUint32 overhead, usecs;
+    PRIntervalTime predicted, timein, timeout, ticks;
+
+ if (debug_mode)
+    printf("Testing %s ...", msg);
+
+    timein = PR_IntervalNow();
+    predicted = func(loops);
+    timeout = PR_IntervalNow();
+
+  if (debug_mode)
+    printf(" done\n");
+
+    ticks = timeout - timein;
+    usecs = PR_IntervalToMicroseconds(ticks);
+    overhead = PR_IntervalToMicroseconds(predicted);
+
+    if(ticks < predicted)
+    {
+		if (debug_mode) {
+        printf("\tFinished in negative time\n");
+        printf("\tpredicted overhead was %d usecs\n", overhead);
+        printf("\ttest completed in %d usecs\n\n", usecs);
+		}
+    }
+    else
+    {
+	if (debug_mode)		
+        printf(
+            "\ttotal: %d usecs\n\toverhead: %d usecs\n\tcost: %6.3f usecs\n\n",
+            usecs, overhead, ((double)(usecs - overhead) / (double)loops));
+    }
+
+    return overhead;
+}  /* TimeThis */
+
+int prmain(int argc, char** argv)
+{
+    PRUint32 cpu, cpus = 0, loops = 0;
+
+	/* 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, "Gdl:c:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* GLOBAL threads */
+			thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'l':  /* loop count */
+			loops = atoi(opt->value);
+            break;
+        case 'c':  /* concurrency limit */
+			cpus = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+
+    if (cpus == 0) cpus = 1;
+    if (loops == 0) loops = 4;
+
+	if (debug_mode)
+		printf("Alarm: Using %d loops\n", loops);
+
+	if (debug_mode)		
+        printf("Alarm: Using %d cpu(s)\n", cpus);
+#ifdef XP_MAC
+	SetupMacPrintfLog("alarm.log");
+	debug_mode = 1;
+#endif
+
+    for (cpu = 1; cpu <= cpus; ++cpu)
+    {
+    if (debug_mode)
+        printf("\nAlarm: Using %d CPU(s)\n", cpu);
+
+	PR_SetConcurrency(cpu);
+        
+        /* some basic time test */
+        (void)TimeThis("ConditionNotify", ConditionNotify, loops);
+        (void)TimeThis("ConditionTimeout", ConditionTimeout, loops);
+        (void)TimeThis("Alarms1", Alarms1, loops);
+        (void)TimeThis("Alarms2", Alarms2, loops);
+        (void)TimeThis("Alarms3", Alarms3, loops);
+    }
+    return 0;
+}
+
+int main(int argc, char** argv)
+{
+     PR_Initialize(prmain, argc, argv, 0);
+     PR_STDIO_INIT();
+	 if (failed_already) return 1;
+	 else return 0;
+
+}  /* main */
+
+
+/* alarmtst.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/anonfm.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/anonfm.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,343 @@
+/* -*- 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: anonfm.c
+** Description: Test anonymous file map 
+**
+** Synopsis: anonfm [options] [dirName]
+**
+** Options:
+** -d   enable debug mode
+** -h   display a help message
+** -s <n>  size of the anonymous memory map, in KBytes. default: 100KBytes.
+** -C 1 Operate this process as ClientOne() 
+** -C 2 Operate this process as ClientTwo()
+**
+** anonfn.c contains two tests, corresponding to the two protocols for
+** passing an anonymous file map to a child process.
+**
+** ServerOne()/ClientOne() tests the passing of "raw" file map; it uses
+** PR_CreateProcess() [for portability of the test case] to create the
+** child process, but does not use the PRProcessAttr structure for
+** passing the file map data.
+**
+** ServerTwo()/ClientTwo() tests the passing of the file map using the
+** PRProcessAttr structure.
+**
+*/
+#include <plgetopt.h> 
+#include <nspr.h> 
+#include <private/primpl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Test harness infrastructure
+*/
+PRLogModuleInfo *lm;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRUint32  failed_already = 0;
+
+PRIntn  debug = 0;
+PRIntn  client = 0; /* invoke client, style */
+char    dirName[512] = "."; /* directory name to contain anon mapped file */
+PRSize  fmSize = (100 * 1024 );
+PRUint32 fmMode = 0600;
+PRFileMapProtect fmProt = PR_PROT_READWRITE;
+const char *fmEnvName = "nsprFileMapEnvVariable";
+
+/*
+** Emit help text for this test
+*/
+static void Help( void )
+{
+    printf("anonfm [options] [dirName]\n");
+    printf("-d -- enable debug mode\n");
+    printf("dirName is alternate directory name. Default: . (current directory)\n");
+    exit(1);
+} /* end Help() */
+
+
+/*
+** ClientOne() --
+*/
+static void ClientOne( void )
+{
+    PRFileMap   *fm;
+    char        *fmString;
+    char        *addr;
+    PRStatus    rc;
+
+    PR_LOG(lm, msgLevel,
+        ("ClientOne() starting"));
+    
+    fmString = PR_GetEnv( fmEnvName );
+    if ( NULL == fmString ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+                ("ClientOne(): PR_Getenv() failed"));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ClientOne(): PR_Getenv(): found: %s", fmString));
+
+    fm = PR_ImportFileMapFromString( fmString );
+    if ( NULL == fm ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+                ("ClientOne(): PR_ImportFileMapFromString() failed"));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ClientOne(): PR_ImportFileMapFromString(): fm: %p", fm ));
+
+    addr = PR_MemMap( fm, LL_ZERO, fmSize );
+    if ( NULL == addr ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("ClientOne(): PR_MemMap() failed, OSError: %d", PR_GetOSError() ));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ClientOne(): PR_MemMap(): addr: %p", addr ));
+
+    /* write to memory map to release server */
+    *addr = 1;
+
+    rc = PR_MemUnmap( addr, fmSize );
+    PR_ASSERT( rc == PR_SUCCESS );
+    PR_LOG(lm, msgLevel,
+        ("ClientOne(): PR_MemUnap(): success" ));
+
+    rc = PR_CloseFileMap( fm );
+    if ( PR_FAILURE == rc ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("ClientOne(): PR_MemUnap() failed, OSError: %d", PR_GetOSError() ));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ClientOne(): PR_CloseFileMap(): success" ));
+
+    return;
+} /* end ClientOne() */
+
+/*
+** ClientTwo() --
+*/
+static void ClientTwo( void )
+{
+    failed_already = 1;
+} /* end ClientTwo() */
+
+/*
+** ServerOne() --
+*/
+static void ServerOne( void )
+{
+    PRFileMap   *fm;
+    PRStatus    rc;
+    PRIntn      i;
+    char        *addr;
+    char        fmString[256];
+    char        envBuf[256];
+    char        *child_argv[8];
+    PRProcess   *proc;
+    PRInt32     exit_status;
+
+    PR_LOG(lm, msgLevel,
+        ("ServerOne() starting"));
+    
+    fm = PR_OpenAnonFileMap( dirName, fmSize, fmProt );
+    if ( NULL == fm )      {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+                ("PR_OpenAnonFileMap() failed"));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): FileMap: %p", fm ));
+    
+    rc = PR_ExportFileMapAsString( fm, sizeof(fmString), fmString );
+    if ( PR_FAILURE == rc )  {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("PR_ExportFileMap() failed"));
+        return;
+    }
+
+    /*
+    ** put the string into the environment
+    */
+    PR_snprintf( envBuf, sizeof(envBuf), "%s=%s", fmEnvName, fmString);
+    putenv( envBuf );
+    
+    addr = PR_MemMap( fm, LL_ZERO, fmSize );
+    if ( NULL == addr ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("PR_MemMap() failed"));
+        return;
+    }
+
+    /* set initial value for client */
+    for (i = 0; i < (PRIntn)fmSize ; i++ )
+        *(addr+i) = 0x00;  
+
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): PR_MemMap(): addr: %p", addr ));
+    
+    /*
+    ** set arguments for child process
+    */
+    child_argv[0] = "anonfm";
+    child_argv[1] = "-C";
+    child_argv[2] = "1";
+    child_argv[3] = NULL;
+
+    proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
+    PR_ASSERT( proc );
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): PR_CreateProcess(): proc: %x", proc ));
+
+    /*
+    ** ClientOne() will set the memory to 1
+    */
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): waiting on Client, *addr: %x", *addr ));
+    while( *addr == 0x00 ) {
+        if ( debug )
+            fprintf(stderr, ".");
+        PR_Sleep(PR_MillisecondsToInterval(300));
+    }
+    if ( debug )
+        fprintf(stderr, "\n");
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): Client responded" ));
+
+    rc = PR_WaitProcess( proc, &exit_status );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_MemUnmap( addr, fmSize);
+    if ( PR_FAILURE == rc ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("PR_MemUnmap() failed"));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): PR_MemUnmap(): success" ));
+
+    rc = PR_CloseFileMap(fm);
+    if ( PR_FAILURE == rc ) {
+        failed_already = 1;    
+        PR_LOG(lm, msgLevel,
+            ("PR_CloseFileMap() failed"));
+        return;
+    }
+    PR_LOG(lm, msgLevel,
+        ("ServerOne(): PR_CloseFileMap() success" ));
+
+    return;
+} /* end ServerOne() */
+
+/*
+** ServerTwo() --
+*/
+static void ServerTwo( void )
+{
+    PR_LOG(lm, msgLevel,
+        ("ServerTwo(): Not implemented yet" ));
+} /* end ServerTwo() */
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    {
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "hdC:");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'C':  /* Client style */
+                client = atol(opt->value);
+                break;
+            case 's':  /* file size */
+                fmSize = atol( opt->value ) * 1024;
+                break;
+            case 'd':  /* debug */
+                debug = 1;
+			    msgLevel = PR_LOG_DEBUG;
+                break;
+            case 'h':  /* help message */
+			    Help();
+                break;
+             default:
+                strcpy(dirName, opt->value);
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    }
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+
+    if ( client == 1 ) {
+        ClientOne();
+    } else if ( client == 2 )  {
+        ClientTwo();
+    } else {
+        ServerOne();
+        if ( failed_already ) goto Finished;
+        ServerTwo();
+    }
+
+Finished:
+    if ( debug )
+        printf("%s\n", (failed_already)? "FAIL" : "PASS");
+    return( (failed_already == PR_TRUE )? 1 : 0 );
+}  /* main() */
+/* end anonfm.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/append.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/append.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,158 @@
+/* -*- 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:        append.c
+** Description: Testing File writes where PR_APPEND was used on open
+**
+** append attempts to verify that a file opened with PR_APPEND
+** will always append to the end of file, regardless where the
+** current file pointer is positioned. To do this, PR_Seek() is
+** called before each write with the position set to beginning of
+** file. Subsequent writes should always append.
+** The file is read back, summing the integer data written to the
+** file. If the expected result is equal, the test passes.
+**
+** See BugSplat: 4090
+*/
+#include "plgetopt.h"
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+PRIntn  debug = 0;
+PRIntn  verbose = 0;
+PRBool  failedAlready = PR_FALSE;
+const PRInt32 addedBytes = 1000;
+const PRInt32   buf = 1; /* constant written to fd, addedBytes times */
+PRInt32         inBuf;   /* read it back into here */
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRStatus    rc;
+    PRInt32     rv;
+    PRFileDesc  *fd;
+    PRIntn      i;
+    PRInt32     sum = 0;
+
+    {   /* Get command line options */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "vd");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+                break;
+            case 'v':  /* verbose */
+                verbose = 1;
+                break;
+             default:
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    } /* end block "Get command line options" */
+/* ---------------------------------------------------------------------- */
+    fd = PR_Open( "/tmp/nsprAppend", (PR_APPEND | PR_CREATE_FILE | PR_TRUNCATE | PR_WRONLY), 0666 );
+    if ( NULL == fd )  {
+        if (debug) printf("PR_Open() failed for writing: %d\n", PR_GetError());
+        failedAlready = PR_TRUE;
+        goto Finished;
+    }
+
+    for ( i = 0; i < addedBytes ; i++ ) {
+        rv = PR_Write( fd, &buf, sizeof(buf));
+        if ( sizeof(buf) != rv )  {
+            if (debug) printf("PR_Write() failed: %d\n", PR_GetError());
+            failedAlready = PR_TRUE;
+            goto Finished;
+        }
+        rv = PR_Seek( fd, 0 , PR_SEEK_SET );
+        if ( -1 == rv )  {
+            if (debug) printf("PR_Seek() failed: %d\n", PR_GetError());
+            failedAlready = PR_TRUE;
+            goto Finished;
+        }
+    }
+    rc = PR_Close( fd );
+    if ( PR_FAILURE == rc ) {
+        if (debug) printf("PR_Close() failed after writing: %d\n", PR_GetError());
+        failedAlready = PR_TRUE;
+        goto Finished;
+    }
+/* ---------------------------------------------------------------------- */
+    fd = PR_Open( "/tmp/nsprAppend", PR_RDONLY, 0 );
+    if ( NULL == fd )  {
+        if (debug) printf("PR_Open() failed for reading: %d\n", PR_GetError());
+        failedAlready = PR_TRUE;
+        goto Finished;
+    }
+
+    for ( i = 0; i < addedBytes ; i++ ) {
+        rv = PR_Read( fd, &inBuf, sizeof(inBuf));
+        if ( sizeof(inBuf) != rv)  {
+            if (debug) printf("PR_Write() failed: %d\n", PR_GetError());
+            failedAlready = PR_TRUE;
+            goto Finished;
+        }
+        sum += inBuf;
+    }
+
+    rc = PR_Close( fd );
+    if ( PR_FAILURE == rc ) {
+        if (debug) printf("PR_Close() failed after reading: %d\n", PR_GetError());
+        failedAlready = PR_TRUE;
+        goto Finished;
+    }
+    if ( sum != addedBytes )  {
+        if (debug) printf("Uh Oh! addedBytes: %d. Sum: %d\n", addedBytes, sum);
+        failedAlready = PR_TRUE;
+        goto Finished;
+    }
+
+/* ---------------------------------------------------------------------- */
+Finished:
+    if (debug || verbose) printf("%s\n", (failedAlready)? "FAILED" : "PASSED" );
+    return( (failedAlready)? 1 : 0 );
+}  /* main() */
+
+/* append.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/atomic.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/atomic.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+ 
+#include "prio.h"
+#include "prprf.h"
+#include "pratom.h"
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRInt32 rv, oldval, test, result = 0;
+    PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput);
+
+    oldval = test = -2;
+    rv = PR_AtomicIncrement(&test);
+    result = result | ((rv == -1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicIncrement(%d) == %d: %s\n",
+        oldval, rv, (rv == -1) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicIncrement(&test);
+    result = result | ((rv == 0) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicIncrement(%d) == %d: %s\n",
+        oldval, rv, (rv == 0) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicIncrement(&test);
+    result = result | ((rv == 1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicIncrement(%d) == %d: %s\n",
+        oldval, rv, (rv == 1) ? "PASSED" : "FAILED");
+
+    oldval = test = -2;
+    rv = PR_AtomicAdd(&test,1);
+    result = result | ((rv == -1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicAdd(%d,%d) == %d: %s\n",
+        oldval, 1, rv, (rv == -1) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicAdd(&test, 4);
+    result = result | ((rv == 3) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicAdd(%d,%d) == %d: %s\n",
+        oldval, 4, rv, (rv == 3) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicAdd(&test, -6);
+    result = result | ((rv == -3) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicAdd(%d,%d) == %d: %s\n",
+        oldval, -6, rv, (rv == -3) ? "PASSED" : "FAILED");
+
+    oldval = test = 2;
+    rv = PR_AtomicDecrement(&test);
+    result = result | ((rv == 1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicDecrement(%d) == %d: %s\n",
+        oldval, rv, (rv == 1) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicDecrement(&test);
+    result = result | ((rv == 0) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicDecrement(%d) == %d: %s\n",
+        oldval, rv, (rv == 0) ? "PASSED" : "FAILED");
+    oldval = test;
+    rv = PR_AtomicDecrement(&test);
+    result = result | ((rv == -1) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicDecrement(%d) == %d: %s\n",
+        oldval, rv, (rv == -1) ? "PASSED" : "FAILED");
+
+    /* set to a different value */
+    oldval = test = -2;
+    rv = PR_AtomicSet(&test, 2);
+    result = result | (((rv == -2) && (test == 2)) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicSet(%d, %d) == %d: %s\n",
+        oldval, 2, rv, ((rv == -2) && (test == 2)) ? "PASSED" : "FAILED");
+
+    /* set to the same value */
+    oldval = test = -2;
+    rv = PR_AtomicSet(&test, -2);
+    result = result | (((rv == -2) && (test == -2)) ? 0 : 1);
+    PR_fprintf(
+        output, "PR_AtomicSet(%d, %d) == %d: %s\n",
+        oldval, -2, rv, ((rv == -2) && (test == -2)) ? "PASSED" : "FAILED");
+
+    PR_fprintf(
+        output, "Atomic operations test %s\n",
+        (result == 0) ? "PASSED" : "FAILED");
+    return result;
+}  /* main */
+
+/* atomic.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/attach.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/attach.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,392 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+** Name: attach.c
+**
+** Description: Platform-specific code to create a native thread. The native thread will
+**                            repeatedly call PR_AttachThread and PR_DetachThread. The
+**                            primordial thread waits for this new thread to finish.
+**
+** Modification History:
+** 13-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.
+** 12-June-97 Revert to return code 0 and 1.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+
+/* Used to get the command line option */
+#include "nspr.h"
+#include "pprthred.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#ifdef WIN32
+#include <windows.h>
+#include <process.h>
+#elif defined(_PR_PTHREADS)
+#include <pthread.h>
+#include "md/_pth.h"
+#elif defined(IRIX)
+#include <sys/types.h>
+#include <sys/prctl.h>
+#include <sys/wait.h>
+#include <errno.h>
+#elif defined(SOLARIS)
+#include <thread.h>
+#elif defined(OS2)
+#define INCL_DOS
+#define INCL_ERRORS
+#include <os2.h>
+#include <process.h>
+#elif defined(XP_BEOS)
+#include <kernel/OS.h>
+#endif
+
+#define DEFAULT_COUNT 1000
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+int count;
+
+
+static void 
+AttachDetach(void)
+{
+    PRThread *me;
+    PRInt32 index;
+
+    for (index=0;index<count; index++) {
+        me = PR_AttachThread(PR_USER_THREAD, 
+                             PR_PRIORITY_NORMAL,
+                             NULL);
+ 
+        if (!me) {
+            fprintf(stderr, "Error attaching thread %d: PR_AttachThread failed\n",
+		    count);
+	    	failed_already = 1;
+	    	return;
+        }
+        PR_DetachThread();
+    }
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+	if (debug_mode)
+    printf("%40s: %6.2f usec\n", msg, d / count);
+}
+
+#ifdef WIN32
+static unsigned __stdcall threadStartFunc(void *arg)
+#elif defined(IRIX) && !defined(_PR_PTHREADS)
+static void threadStartFunc(void *arg)
+#elif defined(XP_BEOS)
+static int32 threadStartFunc(void *arg)
+#else
+static void * threadStartFunc(void *arg)
+#endif
+{
+#ifdef _PR_DCETHREADS
+    {
+        int rv;
+        pthread_t self = pthread_self();
+        rv = pthread_detach(&self);
+        if (debug_mode) PR_ASSERT(0 == rv);
+		else if (0 != rv) failed_already=1;
+    }
+#endif
+
+    Measure(AttachDetach, "Attach/Detach");
+
+#ifndef IRIX
+    return 0;
+#endif
+}
+
+int main(int argc, char **argv)
+{
+#ifdef _PR_PTHREADS
+    int rv;
+    pthread_t threadID;
+    pthread_attr_t attr;
+#elif defined(SOLARIS)
+    int rv;
+    thread_t threadID;
+#elif defined(WIN32)
+    DWORD rv;
+    unsigned threadID;
+    HANDLE hThread;
+#elif defined(IRIX)
+    int rv;
+    int threadID;
+#elif defined(OS2)
+    int rv;
+    TID threadID;
+#elif defined(XP_BEOS)
+	thread_id threadID;
+	int32 threadRV;
+	status_t waitRV;
+#endif
+
+	/* 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] [-c n]
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dc:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'c':  /* loop count */
+			count = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+#if defined(WIN16)
+    printf("attach: This test is not valid for Win16\n");
+    goto exit_now;
+#endif
+
+	if(0 == count) count = DEFAULT_COUNT;	
+
+    /*
+     * To force the implicit initialization of nspr20
+     */
+    PR_SetError(0, 0);
+    PR_STDIO_INIT();
+
+    /*
+     * Platform-specific code to create a native thread.  The native
+     * thread will repeatedly call PR_AttachThread and PR_DetachThread.
+     * The primordial thread waits for this new thread to finish.
+     */
+
+#ifdef _PR_PTHREADS
+
+    rv = _PT_PTHREAD_ATTR_INIT(&attr);
+    if (debug_mode) PR_ASSERT(0 == rv);
+	else if (0 != rv) {
+		failed_already=1;
+		goto exit_now;
+	}
+	
+#ifndef _PR_DCETHREADS
+    rv = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+    if (debug_mode) PR_ASSERT(0 == rv);
+	else if (0 != rv) {
+		failed_already=1;
+		goto exit_now;
+	}
+#endif  /* !_PR_DCETHREADS */
+    rv = _PT_PTHREAD_CREATE(&threadID, attr, threadStartFunc, NULL);
+    if (rv != 0) {
+			fprintf(stderr, "thread creation failed: error code %d\n", rv);
+			failed_already=1;
+			goto exit_now;
+	}
+	else {
+		if (debug_mode)
+			printf ("thread creation succeeded \n");
+
+	}
+    rv = _PT_PTHREAD_ATTR_DESTROY(&attr);
+    if (debug_mode) PR_ASSERT(0 == rv);
+	else if (0 != rv) {
+		failed_already=1;
+		goto exit_now;
+	}
+    rv = pthread_join(threadID, NULL);
+    if (debug_mode) PR_ASSERT(0 == rv);
+	else if (0 != rv) {
+		failed_already=1;
+		goto exit_now;
+	}
+
+#elif defined(SOLARIS)
+
+    rv = thr_create(NULL, 0, threadStartFunc, NULL, 0, &threadID);
+    if (rv != 0) {
+	if(!debug_mode) {
+		failed_already=1;
+		goto exit_now;
+	} else	
+		fprintf(stderr, "thread creation failed: error code %d\n", rv);
+    }
+    rv = thr_join(threadID, NULL, NULL);
+    if (debug_mode) PR_ASSERT(0 == rv);
+	else if (0 != rv)
+	{
+		failed_already=1;
+		goto exit_now;
+	}
+
+
+#elif defined(WIN32)
+
+    hThread = (HANDLE) _beginthreadex(NULL, 0, threadStartFunc, NULL,
+            0, &threadID); 
+    if (hThread == 0) {
+        fprintf(stderr, "thread creation failed: error code %d\n",
+                GetLastError());
+		failed_already=1;
+		goto exit_now;
+    }
+    rv = WaitForSingleObject(hThread, INFINITE);
+    if (debug_mode)PR_ASSERT(rv != WAIT_FAILED);
+	else if (rv == WAIT_FAILED) {
+		failed_already=1;
+		goto exit_now;
+	}
+
+#elif defined(IRIX)
+
+    threadID = sproc(threadStartFunc, PR_SALL, NULL);
+    if (threadID == -1) {
+
+			fprintf(stderr, "thread creation failed: error code %d\n",
+					errno);
+			failed_already=1;
+			goto exit_now;
+	
+	}
+	else {
+		if (debug_mode) 
+			printf ("thread creation succeeded \n");
+		sleep(3);
+		goto exit_now;
+	}
+    rv = waitpid(threadID, NULL, 0);
+    if (debug_mode) PR_ASSERT(rv != -1);
+	else  if (rv != -1) {
+		failed_already=1;
+		goto exit_now;
+	}
+
+#elif defined(OS2)
+
+# ifdef __EMX__
+    threadID = (TID) _beginthread((void *)threadStartFunc, NULL,
+            32768, NULL); 
+# else
+    threadID = (TID) _beginthread((void(* _Optlink)(void*))threadStartFunc, NULL,
+            32768, NULL); 
+# endif
+    if (threadID == -1) {
+        fprintf(stderr, "thread creation failed: error code %d\n", errno);
+        failed_already=1;
+        goto exit_now;
+    }
+    rv = DosWaitThread(&threadID, DCWW_WAIT);
+    if (debug_mode) {
+        PR_ASSERT(rv == NO_ERROR);
+    } else if (rv != NO_ERROR) {
+        failed_already=1;
+        goto exit_now;
+    }
+
+#elif defined(XP_BEOS)
+	
+	threadID = spawn_thread(threadStartFunc, NULL, B_NORMAL_PRIORITY, NULL);
+	if (threadID <= B_ERROR) {
+		fprintf(stderr, "thread creation failed: error code %08lx\n", threadID);
+		failed_already = 1;
+		goto exit_now;
+	}
+	if (resume_thread(threadID) != B_OK) {
+		fprintf(stderr, "failed starting thread: error code %08lx\n", threadID);
+		failed_already = 1;
+		goto exit_now;
+	}
+
+	waitRV = wait_for_thread(threadID, &threadRV);
+	if (debug_mode)
+		PR_ASSERT(waitRV == B_OK);
+	else if (waitRV != B_OK) {
+		failed_already = 1;
+		goto exit_now;
+	}
+	
+#else
+	if (!debug_mode)
+		failed_already=1;
+	else	
+		printf("The attach test does not apply to this platform because\n"
+	    "either this platform does not have native threads or the\n"
+	    "test needs to be written for this platform.\n");
+	goto exit_now;
+#endif
+
+exit_now:
+   if(failed_already)	
+		return 1;
+	else
+		return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/bigfile.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/bigfile.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,318 @@
+/* -*- 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 "prio.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prinit.h"
+#include "prerror.h"
+#include "prthread.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#define DEFAULT_COUNT 10
+#define DEFAULT_FILESIZE 1
+#define BUFFER_SIZE 1000000
+
+typedef enum {v_silent, v_whisper, v_shout} Verbosity;
+static void Verbose(Verbosity, const char*, const char*, PRIntn);
+
+#define VERBOSE(_l, _m) Verbose(_l, _m, __FILE__, __LINE__)
+
+static PRIntn test_result = 2;
+static PRFileDesc *output = NULL;
+static PRIntn verbose = v_silent;
+static PRIntn filesize = DEFAULT_FILESIZE;
+
+static PRIntn Usage(void)
+{
+    PR_fprintf(output, "Bigfile test usage:\n");
+    PR_fprintf(output, ">bigfile [-G] [-d] [-v[*v]] [-s <n>] <filename>\n");
+    PR_fprintf(output, "\td\tdebug mode (equivalent to -vvv)\t(false)\n");
+    PR_fprintf(output, "\tv\tAdditional levels of output\t(none)\n");
+    PR_fprintf(output, "\tk\tKeep data file after exit\t(false)\n");
+    PR_fprintf(output, "\ts <n>\tFile size in megabytes\t\t(1 megabyte)\n");
+    PR_fprintf(output, "\t<filename>\tName of test file\t(none)\n");
+    return 2;  /* nothing happened */
+}  /* Usage */
+
+static PRStatus DeleteIfFound(const char *filename)
+{
+    PRStatus rv;
+    VERBOSE(v_shout, "Checking for existing file");
+    rv = PR_Access(filename, PR_ACCESS_WRITE_OK);
+    if (PR_SUCCESS == rv)
+    {
+        VERBOSE(v_shout, "Deleting existing file");
+        rv = PR_Delete(filename);
+        if (PR_FAILURE == rv) VERBOSE(v_shout, "Cannot delete big file");
+    }
+    else if (PR_FILE_NOT_FOUND_ERROR !=  PR_GetError())
+        VERBOSE(v_shout, "Cannot access big file");
+    else rv = PR_SUCCESS;
+    return rv;
+}  /* DeleteIfFound */
+
+static PRIntn Error(const char *msg, const char *filename)
+{
+    PRInt32 error = PR_GetError();
+    if (NULL != msg)
+    {
+        if (0 == error) PR_fprintf(output, msg);
+        else PL_FPrintError(output, msg);
+    }
+    (void)DeleteIfFound(filename);
+    if (v_shout == verbose) PR_Abort();
+    return 1;
+}  /* Error */
+
+static void Verbose(
+    Verbosity level, const char *msg, const char *file, PRIntn line)
+{
+    if (level <= verbose)
+        PR_fprintf(output, "[%s : %d]: %s\n", file, line, msg);
+}  /* Verbose */
+
+static void PrintInfo(PRFileInfo64 *info, const char *filename)
+{
+    PRExplodedTime tm;
+    char ctime[40], mtime[40];
+    static const char *types[] = {"FILE", "DIRECTORY", "OTHER"};
+    PR_fprintf(
+        output, "[%s : %d]: File info for %s\n",
+        __FILE__, __LINE__, filename);
+    PR_fprintf(
+        output, "    type: %s, size: %llu bytes,\n",
+        types[info->type - 1], info->size);
+
+    PR_ExplodeTime(info->creationTime, PR_GMTParameters, &tm);
+    (void)PR_FormatTime(ctime, sizeof(ctime), "%c GMT", &tm);
+    PR_ExplodeTime(info->modifyTime, PR_GMTParameters, &tm);
+    (void)PR_FormatTime(mtime, sizeof(mtime), "%c GMT", &tm);
+
+    PR_fprintf(
+        output, "    creation: %s,\n    modify: %s\n", ctime, mtime);
+}  /* PrintInfo */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    char *buffer;
+    PLOptStatus os;
+    PRInt32 loop, bytes;
+    PRFileInfo small_info;
+    PRFileInfo64 big_info;
+    PRBool keep = PR_FALSE;
+    PRFileDesc *file = NULL;
+    const char *filename = NULL;
+    PRIntn count = DEFAULT_COUNT;
+    PRInt64 filesize64, big_answer, big_size, one_meg, zero_meg, big_fragment;
+    PRInt64 sevenFox = LL_INIT(0,0x7fffffff);
+
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dtvhs:");
+
+    output = PR_GetSpecialFD(PR_StandardError);
+    PR_STDIO_INIT();
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:
+            filename = opt->value;
+            break;
+        case 'd':  /* debug mode */
+            verbose = v_shout;
+            break;
+        case 'k':  /* keep file */
+            keep = PR_TRUE;
+            break;
+        case 'v':  /* verbosity */
+            if (v_shout > verbose) verbose += 1;
+            break;
+        case 'c':  /* loop counter */
+            count = atoi(opt->value);
+            break;
+        case 's':  /* filesize */
+            filesize = atoi(opt->value);
+            break;
+        case 'h':  /* confused */
+        default:
+            return Usage();
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (0 == count) count = DEFAULT_COUNT;
+    if (0 == filesize) filesize = DEFAULT_FILESIZE;
+    if (NULL == filename)
+    {
+        if (DEFAULT_FILESIZE != filesize) return Usage();
+        else filename = "bigfile.dat";
+    }
+
+    if (PR_FAILURE == DeleteIfFound(filename)) return 1;
+
+    test_result = 0;
+
+    LL_I2L(zero_meg, 0);
+    LL_I2L(one_meg, 1000000);
+    LL_I2L(filesize64, filesize);
+    buffer = (char*)PR_MALLOC(BUFFER_SIZE);
+    LL_I2L(big_fragment, BUFFER_SIZE);
+    LL_MUL(filesize64, filesize64, one_meg); 
+
+    for (loop = 0; loop < BUFFER_SIZE; ++loop) buffer[loop] = (char)loop;
+
+    VERBOSE(v_whisper, "Creating big file");
+    file = PR_Open(filename, PR_CREATE_FILE | PR_WRONLY, 0666);
+    if (NULL == file) return Error("PR_Open()", filename);
+    
+    VERBOSE(v_whisper, "Testing available space in empty file");
+    big_answer = file->methods->available64(file);
+    if (!LL_IS_ZERO(big_answer)) return Error("empty available64()", filename);
+
+	LL_SUB(big_size, filesize64, one_meg);
+    VERBOSE(v_whisper, "Creating sparse big file by seeking to end");
+	big_answer = file->methods->seek64(file, big_size, PR_SEEK_SET);
+    if (!LL_EQ(big_answer, big_size)) return Error("seek", filename);
+
+    VERBOSE(v_whisper, "Writing block at end of sparse file");
+	bytes = file->methods->write(file, buffer, BUFFER_SIZE);
+    if (bytes != BUFFER_SIZE) return Error("write", filename);
+
+    VERBOSE(v_whisper, "Testing available space at end of sparse file");
+    big_answer = file->methods->available64(file);
+    if (!LL_IS_ZERO(big_answer)) return Error("eof available64()", filename);
+
+    VERBOSE(v_whisper, "Getting big info on sparse big file");
+    rv = file->methods->fileInfo64(file, &big_info);
+    if (PR_FAILURE == rv) return Error("fileInfo64()", filename);
+    if (v_shout <= verbose) PrintInfo(&big_info, filename);
+
+    VERBOSE(v_whisper, "Getting small info on sparse big file");
+    rv = file->methods->fileInfo(file, &small_info);
+    if (LL_CMP(sevenFox, <, filesize64) && (PR_SUCCESS == rv))
+    {
+        VERBOSE(v_whisper, "Should have failed and didn't");
+        return Error("fileInfo()", filename);
+    }
+    else if (LL_CMP(sevenFox, >, filesize64) && (PR_FAILURE == rv))
+    {
+        VERBOSE(v_whisper, "Should have succeeded and didn't");
+        return Error("fileInfo()", filename);
+    }
+
+    VERBOSE(v_whisper, "Rewinding big file");
+    big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_SET);
+    if (!LL_IS_ZERO(big_answer)) return Error("rewind seek64()", filename);
+
+    VERBOSE(v_whisper, "Establishing available space in rewound file");
+    big_answer = file->methods->available64(file);
+    if (LL_NE(filesize64, big_answer))
+        return Error("bof available64()", filename);
+
+    VERBOSE(v_whisper, "Closing big file");
+    rv = file->methods->close(file);
+    if (PR_FAILURE == rv) return Error("close()", filename);
+
+    VERBOSE(v_whisper, "Reopening big file");
+    file = PR_Open(filename, PR_RDWR, 0666);
+    if (NULL == file) return Error("open failed", filename);
+
+    VERBOSE(v_whisper, "Checking available data in reopened file");
+    big_answer = file->methods->available64(file);
+    if (LL_NE(filesize64, big_answer))
+        return Error("reopened available64()", filename);
+
+    big_answer = zero_meg;
+    VERBOSE(v_whisper, "Rewriting every byte of big file data");
+    do
+    {
+        bytes = file->methods->write(file, buffer, BUFFER_SIZE);
+        if (bytes != BUFFER_SIZE)
+            return Error("write", filename);
+        LL_ADD(big_answer, big_answer, big_fragment);
+    } while (LL_CMP(big_answer, <, filesize64));
+
+    VERBOSE(v_whisper, "Checking position at eof");
+    big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_CUR);
+    if (LL_NE(big_answer, filesize64))
+        return Error("file size error", filename);
+
+    VERBOSE(v_whisper, "Testing available space at eof");
+    big_answer = file->methods->available64(file);
+    if (!LL_IS_ZERO(big_answer))
+        return Error("eof available64()", filename);
+
+    VERBOSE(v_whisper, "Rewinding full file");
+    big_answer = file->methods->seek64(file, zero_meg, PR_SEEK_SET);
+    if (!LL_IS_ZERO(big_answer)) return Error("bof seek64()", filename);
+
+    VERBOSE(v_whisper, "Testing available space in rewound file");
+    big_answer = file->methods->available64(file);
+    if (LL_NE(big_answer, filesize64)) return Error("bof available64()", filename);
+
+    VERBOSE(v_whisper, "Seeking to end of big file");
+    big_answer = file->methods->seek64(file, filesize64, PR_SEEK_SET);
+    if (LL_NE(big_answer, filesize64)) return Error("eof seek64()", filename);
+
+    VERBOSE(v_whisper, "Getting info on big file while it's open");
+    rv = file->methods->fileInfo64(file, &big_info);
+    if (PR_FAILURE == rv) return Error("fileInfo64()", filename);
+    if (v_shout <= verbose) PrintInfo(&big_info, filename);
+
+    VERBOSE(v_whisper, "Closing big file");
+    rv = file->methods->close(file);
+    if (PR_FAILURE == rv) return Error("close()", filename);
+
+    VERBOSE(v_whisper, "Getting info on big file after it's closed");
+    rv = PR_GetFileInfo64(filename, &big_info);
+    if (PR_FAILURE == rv) return Error("fileInfo64()", filename);
+    if (v_shout <= verbose) PrintInfo(&big_info, filename);
+
+    VERBOSE(v_whisper, "Deleting big file");
+    rv = PR_Delete(filename);
+    if (PR_FAILURE == rv) return Error("PR_Delete()", filename);
+
+    PR_DELETE(buffer);
+    return test_result;
+} /* main */
+
+/* bigfile.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/bigfile2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/bigfile2.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,127 @@
+/* -*- 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 "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#define TEST_FILE_NAME "bigfile2.txt"
+
+#define MESSAGE "Hello world!"
+#define MESSAGE_SIZE 13
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *fd;
+    PRInt64 offset, position;
+    PRInt32 nbytes;
+    char buf[MESSAGE_SIZE];
+#ifdef _WIN32
+    HANDLE hFile;
+    LARGE_INTEGER li;
+#endif /* _WIN32 */
+
+    LL_I2L(offset, 1);
+    LL_SHL(offset, offset, 32);
+
+    fd = PR_Open(TEST_FILE_NAME,
+            PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0666);
+    if (fd == NULL) {
+        fprintf(stderr, "PR_Open failed\n");
+        exit(1);
+    }
+    position = PR_Seek64(fd, offset, PR_SEEK_SET);
+    if (!LL_GE_ZERO(position)) {
+        fprintf(stderr, "PR_Seek64 failed\n");
+        exit(1);
+    }
+    PR_ASSERT(LL_EQ(position, offset));
+    strcpy(buf, MESSAGE);
+    nbytes = PR_Write(fd, buf, sizeof(buf));
+    if (nbytes != sizeof(buf)) {
+        fprintf(stderr, "PR_Write failed\n");
+        exit(1);
+    }
+    if (PR_Close(fd) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    memset(buf, 0, sizeof(buf));
+
+#ifdef _WIN32
+    hFile = CreateFile(TEST_FILE_NAME, GENERIC_READ, 0, NULL,
+            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (hFile == INVALID_HANDLE_VALUE) {
+        fprintf(stderr, "CreateFile failed\n");
+        exit(1);
+    }
+    li.QuadPart = offset;
+    li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
+    if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+        fprintf(stderr, "SetFilePointer failed\n");
+        exit(1);
+    }
+    PR_ASSERT(li.QuadPart == offset);
+    if (ReadFile(hFile, buf, sizeof(buf), &nbytes, NULL) == 0) {
+        fprintf(stderr, "ReadFile failed\n");
+        exit(1);
+    }
+    PR_ASSERT(nbytes == sizeof(buf));
+    if (strcmp(buf, MESSAGE)) {
+        fprintf(stderr, "corrupt data:$%s$\n", buf);
+        exit(1);
+    }
+    if (CloseHandle(hFile) == 0) {
+        fprintf(stderr, "CloseHandle failed\n");
+        exit(1);
+    }
+#endif /* _WIN32 */
+
+    if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) {
+        fprintf(stderr, "PR_Delete failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/bigfile3.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/bigfile3.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#define TEST_FILE_NAME "bigfile3.txt"
+
+#define MESSAGE "Hello world!"
+#define MESSAGE_SIZE 13
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *fd;
+    PRInt64 offset, position;
+    PRInt32 nbytes;
+    char buf[MESSAGE_SIZE];
+#ifdef _WIN32
+    HANDLE hFile;
+    LARGE_INTEGER li;
+#endif /* _WIN32 */
+
+    LL_I2L(offset, 1);
+    LL_SHL(offset, offset, 32);
+
+#ifdef _WIN32
+    hFile = CreateFile(TEST_FILE_NAME, GENERIC_WRITE, 0, NULL,
+            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (hFile == INVALID_HANDLE_VALUE) {
+        fprintf(stderr, "CreateFile failed\n");
+        exit(1);
+    }
+    li.QuadPart = offset;
+    li.LowPart = SetFilePointer(hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
+    if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
+        fprintf(stderr, "SetFilePointer failed\n");
+        exit(1);
+    }
+    PR_ASSERT(li.QuadPart == offset);
+    strcpy(buf, MESSAGE);
+    if (WriteFile(hFile, buf, sizeof(buf), &nbytes, NULL) == 0) {
+        fprintf(stderr, "WriteFile failed\n");
+        exit(1);
+    }
+    PR_ASSERT(nbytes == sizeof(buf));
+    if (CloseHandle(hFile) == 0) {
+        fprintf(stderr, "CloseHandle failed\n");
+        exit(1);
+    }
+#endif /* _WIN32 */
+
+    memset(buf, 0, sizeof(buf));
+
+    fd = PR_Open(TEST_FILE_NAME, PR_RDONLY, 0666);
+    if (fd == NULL) {
+        fprintf(stderr, "PR_Open failed\n");
+        exit(1);
+    }
+    position = PR_Seek64(fd, offset, PR_SEEK_SET);
+    if (!LL_GE_ZERO(position)) {
+        fprintf(stderr, "PR_Seek64 failed\n");
+        exit(1);
+    }
+    PR_ASSERT(LL_EQ(position, offset));
+    nbytes = PR_Read(fd, buf, sizeof(buf));
+    if (nbytes != sizeof(buf)) {
+        fprintf(stderr, "PR_Read failed\n");
+        exit(1);
+    }
+    if (strcmp(buf, MESSAGE)) {
+        fprintf(stderr, "corrupt data:$%s$\n", buf);
+        exit(1);
+    }
+    if (PR_Close(fd) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) {
+        fprintf(stderr, "PR_Delete failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/bug1test.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/bug1test.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+Attached is a test program that uses the nspr1 to demonstrate a bug
+under NT4.0. The fix has already been mentioned (add a ResetEvent just
+before leaving the critical section in _PR_CondWait in hwmon.c).
+*/
+
+#include "prthread.h"
+#include "prtypes.h"
+#include "prinit.h"
+#include "prmon.h"
+#include "prlog.h"
+
+typedef struct Arg_s
+{
+	PRInt32 a, b;
+} Arg_t;
+
+PRMonitor*  gMonitor;       // the monitor
+PRInt32     gReading;       // number of read locks
+PRInt32     gWriteWaiting;  // number of threads waiting for write lock
+PRInt32     gReadWaiting;   // number of threads waiting for read lock
+
+PRInt32     gCounter;       // a counter
+
+                            // stats
+PRInt32     gReads;         // number of successful reads
+PRInt32     gMaxReads;      // max number of simultaneous reads
+PRInt32     gMaxWriteWaits; // max number of writes that waited for read
+PRInt32     gMaxReadWaits;  // max number of reads that waited for write wait
+
+
+void spin (PRInt32 aDelay)
+{
+  PRInt32 index;
+  PRInt32 delay = aDelay * 1000;
+
+  PR_Sleep(0);
+
+  // randomize delay a bit
+  delay = (delay / 2) + (PRInt32)((float)delay *
+	  ((float)rand () / (float)RAND_MAX));
+
+  for (index = 0; index < delay * 10; index++)
+	  // consume a bunch of cpu cycles
+    ;
+  PR_Sleep(0); 
+}
+
+void  doWriteThread (void* arg)
+{
+  PRInt32 last;
+  Arg_t *args = (Arg_t*)arg;
+  PRInt32 aWorkDelay = args->a, aWaitDelay = args->b;
+  PR_Sleep(0);
+
+  while (1)
+  {
+    // -- enter write lock
+    PR_EnterMonitor (gMonitor);
+
+    if (0 < gReading)     // wait for read locks to go away
+    {
+      PRIntervalTime fiveSecs = PR_SecondsToInterval(5);
+
+      gWriteWaiting++;
+      if (gWriteWaiting > gMaxWriteWaits) // stats
+        gMaxWriteWaits = gWriteWaiting;
+      while (0 < gReading)
+        PR_Wait (gMonitor, fiveSecs);
+      gWriteWaiting--;
+    }
+    // -- write lock entered
+
+    last = gCounter;
+    gCounter++;
+
+    spin (aWorkDelay);
+
+    PR_ASSERT (gCounter == (last + 1)); // test invariance
+
+    // -- exit write lock        
+//    if (0 < gReadWaiting)   // notify waiting reads (do it anyway to show off the CondWait bug)
+      PR_NotifyAll (gMonitor);
+
+    PR_ExitMonitor (gMonitor);
+    // -- write lock exited
+
+    spin (aWaitDelay);
+  }
+}
+
+void  doReadThread (void* arg)
+{
+  PRInt32 last;
+  Arg_t *args = (Arg_t*)arg;
+  PRInt32 aWorkDelay = args->a, aWaitDelay = args->b;
+  PR_Sleep(0);
+
+  while (1)
+  {
+    // -- enter read lock
+    PR_EnterMonitor (gMonitor); 
+
+    if (0 < gWriteWaiting)  // give up the monitor to waiting writes
+    {
+      PRIntervalTime fiveSecs = PR_SecondsToInterval(5);
+
+      gReadWaiting++;
+      if (gReadWaiting > gMaxReadWaits) // stats
+        gMaxReadWaits = gReadWaiting;
+      while (0 < gWriteWaiting)
+        PR_Wait (gMonitor, fiveSecs);
+      gReadWaiting--;
+    }
+
+    gReading++;
+
+    gReads++;   // stats
+    if (gReading > gMaxReads) // stats
+      gMaxReads = gReading;
+
+    PR_ExitMonitor (gMonitor);
+    // -- read lock entered
+
+    last = gCounter;
+
+    spin (aWorkDelay);
+
+    PR_ASSERT (gCounter == last); // test invariance
+
+    // -- exit read lock
+    PR_EnterMonitor (gMonitor);  // read unlock
+    gReading--;
+
+//    if ((0 == gReading) && (0 < gWriteWaiting))  // notify waiting writes  (do it anyway to show off the CondWait bug)
+      PR_NotifyAll (gMonitor);
+    PR_ExitMonitor (gMonitor);
+    // -- read lock exited
+
+    spin (aWaitDelay);
+  }
+}
+
+
+void fireThread (
+    char* aName, void (*aProc)(void *arg), Arg_t *aArg)
+{
+  PRThread *thread = PR_CreateThread(
+	  PR_USER_THREAD, aProc, aArg, PR_PRIORITY_NORMAL,
+	  PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+}
+
+int pseudoMain (int argc, char** argv, char *pad)
+{
+  PRInt32 lastWriteCount  = gCounter;
+  PRInt32 lastReadCount   = gReads;
+  Arg_t a1 = {500, 250};
+  Arg_t a2 = {500, 500};
+  Arg_t a3 = {250, 500};
+  Arg_t a4 = {750, 250};
+  Arg_t a5 = {100, 750};
+  Arg_t a6 = {100, 500};
+  Arg_t a7 = {100, 750};
+
+  gMonitor = PR_NewMonitor ();
+
+  fireThread ("R1", doReadThread,   &a1);
+  fireThread ("R2", doReadThread,   &a2);
+  fireThread ("R3", doReadThread,   &a3);
+  fireThread ("R4", doReadThread,   &a4);
+
+  fireThread ("W1", doWriteThread,  &a5);
+  fireThread ("W2", doWriteThread,  &a6);
+  fireThread ("W3", doWriteThread,  &a7);
+
+  fireThread ("R5", doReadThread,   &a1);
+  fireThread ("R6", doReadThread,   &a2);
+  fireThread ("R7", doReadThread,   &a3);
+  fireThread ("R8", doReadThread,   &a4);
+
+  fireThread ("W4", doWriteThread,  &a5);
+  fireThread ("W5", doWriteThread,  &a6);
+  fireThread ("W6", doWriteThread,  &a7);
+  
+  while (1)
+  {
+	PRInt32 writeCount, readCount;
+    PRIntervalTime fiveSecs = PR_SecondsToInterval(5);
+    PR_Sleep (fiveSecs);  // get out of the way
+
+    // print some stats, not threadsafe, informative only
+    writeCount = gCounter;
+    readCount   = gReads;
+    printf ("\ntick %d writes (+%d), %d reads (+%d) [max %d, %d, %d]", 
+            writeCount, writeCount - lastWriteCount,
+            readCount, readCount - lastReadCount, 
+            gMaxReads, gMaxWriteWaits, gMaxReadWaits);
+    lastWriteCount = writeCount;
+    lastReadCount = readCount;
+    gMaxReads = gMaxWriteWaits = gMaxReadWaits = 0;
+  }
+  return 0;
+}
+
+
+static void padStack (int argc, char** argv)
+{
+  char pad[512];      /* Work around bug in nspr on windoze */
+  pseudoMain (argc, argv, pad);
+}
+
+void main (int argc, char **argv)
+{
+  PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+  PR_STDIO_INIT();
+  padStack (argc, argv);
+}
+
+
+/* bug1test.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/cleanup.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/cleanup.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,131 @@
+/* -*- 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 "prprf.h"
+#include "prio.h"
+#include "prinit.h"
+#include "prthread.h"
+#include "prinrval.h"
+
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+static void PR_CALLBACK Thread(void *sleep)
+{
+    PR_Sleep(PR_SecondsToInterval((PRUint32)sleep));
+    printf("Thread exiting\n");
+}
+
+static void Help(void)
+{
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PR_fprintf(err, "Cleanup usage: [-g] [-s n] [-t n] [-c n] [-h]\n");
+    PR_fprintf(err, "\t-c   Call cleanup before exiting     (default: false)\n");
+    PR_fprintf(err, "\t-G   Use global threads only         (default: local)\n");
+    PR_fprintf(err, "\t-t n Number of threads involved      (default: 1)\n");
+    PR_fprintf(err, "\t-s n Seconds thread(s) should dally  (defaut: 10)\n");
+    PR_fprintf(err, "\t-S n Seconds main() should dally     (defaut: 5)\n");
+    PR_fprintf(err, "\t-C n Value to set concurrency        (default 1)\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PLOptStatus os;
+    PRBool cleanup = PR_FALSE;
+	PRThreadScope type = PR_LOCAL_THREAD;
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PLOptState *opt = PL_CreateOptState(argc, argv, "Ghs:S:t:cC:");
+    PRIntn concurrency = 1, child_sleep = 10, main_sleep = 5, threads = 1;
+
+    PR_STDIO_INIT();
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'c':  /* call PR_Cleanup() before exiting */
+            cleanup = PR_TRUE;
+            break;
+        case 'G':  /* local vs global threads */
+            type = PR_GLOBAL_THREAD;
+            break;
+        case 's':  /* time to sleep */
+            child_sleep = atoi(opt->value);
+            break;
+        case 'S':  /* time to sleep */
+            main_sleep = atoi(opt->value);
+            break;
+        case 'C':  /* number of cpus to create */
+            concurrency = atoi(opt->value);
+            break;
+        case 't':  /* number of threads to create */
+            threads = atoi(opt->value);
+            break;
+        case 'h':  /* user wants some guidance */
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+            break;
+         default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_fprintf(err, "Cleanup settings\n");
+    PR_fprintf(err, "\tThread type: %s\n",
+        (PR_LOCAL_THREAD == type) ? "LOCAL" : "GLOBAL");
+    PR_fprintf(err, "\tConcurrency: %d\n", concurrency);
+    PR_fprintf(err, "\tNumber of threads: %d\n", threads);
+    PR_fprintf(err, "\tThread sleep: %d\n", child_sleep);
+    PR_fprintf(err, "\tMain sleep: %d\n", main_sleep); 
+    PR_fprintf(err, "\tCleanup will %sbe called\n\n", (cleanup) ? "" : "NOT "); 
+
+    PR_SetConcurrency(concurrency);
+
+	while (threads-- > 0)
+		(void)PR_CreateThread(
+        	PR_USER_THREAD, Thread, (void*)child_sleep, PR_PRIORITY_NORMAL,
+       		type, PR_UNJOINABLE_THREAD, 0);
+    PR_Sleep(PR_SecondsToInterval(main_sleep));
+
+    if (cleanup) PR_Cleanup();
+
+    PR_fprintf(err, "main() exiting\n");
+    return 0;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/cltsrv.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/cltsrv.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1226 @@
+/* -*- 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 ***** */
+
+/*
+ *
+ * Notes:
+ * [1] lth. The call to Sleep() is a hack to get the test case to run
+ * on Windows 95. Without it, the test case fails with an error
+ * WSAECONNRESET following a recv() call. The error is caused by the
+ * server side thread termination without a shutdown() or closesocket()
+ * call. Windows docmunentation suggests that this is predicted
+ * behavior; that other platforms get away with it is ... serindipity.
+ * The test case should shutdown() or closesocket() before
+ * thread termination. I didn't have time to figure out where or how
+ * to do it. The Sleep() call inserts enough delay to allow the
+ * client side to recv() all his data before the server side thread
+ * terminates. Whew! ...
+ *
+ ** Modification History:
+ * 14-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. 
+ */
+
+#include "prclist.h"
+#include "prcvar.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prtime.h"
+#include "prmem.h"
+#include "prnetdb.h"
+#include "prprf.h"
+#include "prthread.h"
+
+#include "pprio.h"
+#include "primpl.h"
+
+#include "plstr.h"
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#if defined(XP_UNIX)
+#include <math.h>
+#endif
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#endif
+
+/*
+** This is the beginning of the test
+*/
+
+#define RECV_FLAGS 0
+#define SEND_FLAGS 0
+#define DEFAULT_LOW 0
+#define DEFAULT_HIGH 0
+#define BUFFER_SIZE 1024
+#define DEFAULT_BACKLOG 5
+#define DEFAULT_PORT 12849
+#define DEFAULT_CLIENTS 1
+#define ALLOWED_IN_ACCEPT 1
+#define DEFAULT_CLIPPING 1000
+#define DEFAULT_WORKERS_MIN 1
+#define DEFAULT_WORKERS_MAX 1
+#define DEFAULT_SERVER "localhost"
+#define DEFAULT_EXECUTION_TIME 10
+#define DEFAULT_CLIENT_TIMEOUT 4000
+#define DEFAULT_SERVER_TIMEOUT 4000
+#define DEFAULT_SERVER_PRIORITY PR_PRIORITY_HIGH
+
+typedef enum CSState_e {cs_init, cs_run, cs_stop, cs_exit} CSState_t;
+
+static void PR_CALLBACK Worker(void *arg);
+typedef struct CSPool_s CSPool_t;
+typedef struct CSWorker_s CSWorker_t;
+typedef struct CSServer_s CSServer_t;
+typedef enum Verbosity
+{
+    TEST_LOG_ALWAYS,
+    TEST_LOG_ERROR,
+    TEST_LOG_WARNING,
+    TEST_LOG_NOTICE,
+    TEST_LOG_INFO,
+    TEST_LOG_STATUS,
+    TEST_LOG_VERBOSE
+} Verbosity;
+
+static PRInt32 domain = AF_INET;
+static PRInt32 protocol = 6;  /* TCP */
+static PRFileDesc *debug_out = NULL;
+static PRBool debug_mode = PR_FALSE;
+static PRBool pthread_stats = PR_FALSE;
+static Verbosity verbosity = TEST_LOG_ALWAYS;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+struct CSWorker_s
+{
+    PRCList element;        /* list of the server's workers */
+
+    PRThread *thread;       /* this worker objects thread */
+    CSServer_t *server;     /* back pointer to server structure */
+};
+
+struct CSPool_s
+{
+    PRCondVar *exiting;
+    PRCondVar *acceptComplete;
+    PRUint32 accepting, active, workers;
+};
+
+struct CSServer_s
+{
+    PRCList list;           /* head of worker list */
+
+    PRLock *ml;
+    PRThread *thread;       /* the main server thread */
+    PRCondVar *stateChange;
+
+    PRUint16 port;          /* port we're listening on */
+    PRUint32 backlog;       /* size of our listener backlog */
+    PRFileDesc *listener;   /* the fd accepting connections */
+
+    CSPool_t pool;          /* statistics on worker threads */
+    CSState_t state;        /* the server's state */
+    struct                  /* controlling worker counts */
+    {
+        PRUint32 minimum, maximum, accepting;
+    } workers;
+
+    /* statistics */
+    PRIntervalTime started, stopped;
+    PRUint32 operations, bytesTransferred;
+};
+
+typedef struct CSDescriptor_s
+{
+    PRInt32 size;       /* size of transfer */
+    char filename[60];  /* filename, null padded */
+} CSDescriptor_t;
+
+typedef struct CSClient_s
+{
+    PRLock *ml;
+    PRThread *thread;
+    PRCondVar *stateChange;
+    PRNetAddr serverAddress;
+
+    CSState_t state;
+
+    /* statistics */
+    PRIntervalTime started, stopped;
+    PRUint32 operations, bytesTransferred;
+} CSClient_t;
+
+#define TEST_LOG(l, p, a) \
+    do { \
+        if (debug_mode || (p <= verbosity)) printf a; \
+    } while (0)
+
+PRLogModuleInfo *cltsrv_log_file = NULL;
+
+#define MY_ASSERT(_expr) \
+    ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__))
+
+#define TEST_ASSERT(_expr) \
+    ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__))
+
+static void _MY_Assert(const char *s, const char *file, PRIntn ln)
+{
+    PL_PrintError(NULL);
+#if DEBUG
+    PR_Assert(s, file, ln);
+#endif
+}  /* _MW_Assert */
+
+static PRBool Aborted(PRStatus rv)
+{
+    return ((PR_FAILURE == rv) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) ?
+        PR_TRUE : PR_FALSE;
+}
+
+static void TimeOfDayMessage(const char *msg, PRThread* me)
+{
+    char buffer[100];
+    PRExplodedTime tod;
+    PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &tod);
+    (void)PR_FormatTime(buffer, sizeof(buffer), "%T", &tod);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("%s(0x%p): %s\n", msg, me, buffer));
+}  /* TimeOfDayMessage */
+
+
+static void PR_CALLBACK Client(void *arg)
+{
+    PRStatus rv;
+    PRIntn index;
+    char buffer[1024];
+    PRFileDesc *fd = NULL;
+    PRUintn clipping = DEFAULT_CLIPPING;
+    PRThread *me = PR_GetCurrentThread();
+    CSClient_t *client = (CSClient_t*)arg;
+    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);
+    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_CLIENT_TIMEOUT);
+
+
+    for (index = 0; index < sizeof(buffer); ++index)
+        buffer[index] = (char)index;
+
+    client->started = PR_IntervalNow();
+
+    PR_Lock(client->ml);
+    client->state = cs_run;
+    PR_NotifyCondVar(client->stateChange);
+    PR_Unlock(client->ml);
+
+    TimeOfDayMessage("Client started at", me);
+
+    while (cs_run == client->state)
+    {
+        PRInt32 bytes, descbytes, filebytes, netbytes;
+
+        (void)PR_NetAddrToString(&client->serverAddress, buffer, sizeof(buffer));
+        TEST_LOG(cltsrv_log_file, TEST_LOG_INFO, 
+            ("\tClient(0x%p): connecting to server at %s\n", me, buffer));
+
+        fd = PR_Socket(domain, SOCK_STREAM, protocol);
+        TEST_ASSERT(NULL != fd);
+        rv = PR_Connect(fd, &client->serverAddress, timeout);
+        if (PR_FAILURE == rv)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tClient(0x%p): conection failed (%d, %d)\n",
+                me, PR_GetError(), PR_GetOSError()));
+            goto aborted;
+        }
+
+        memset(descriptor, 0, sizeof(*descriptor));
+        descriptor->size = PR_htonl(descbytes = rand() % clipping);
+        PR_snprintf(
+            descriptor->filename, sizeof(descriptor->filename),
+            "CS%p%p-%p.dat", client->started, me, client->operations);
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes));
+        bytes = PR_Send(
+            fd, descriptor, sizeof(*descriptor), SEND_FLAGS, timeout);
+        if (sizeof(CSDescriptor_t) != bytes)
+        {
+            if (Aborted(PR_FAILURE)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\tClient(0x%p): send descriptor timeout\n", me));
+                goto retry;
+            }
+        }
+        TEST_ASSERT(sizeof(*descriptor) == bytes);
+
+        netbytes = 0;
+        while (netbytes < descbytes)
+        {
+            filebytes = sizeof(buffer);
+            if ((descbytes - netbytes) < filebytes)
+                filebytes = descbytes - netbytes;
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\tClient(0x%p): sending %d bytes\n", me, filebytes));
+            bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);
+            if (filebytes != bytes)
+            {
+                if (Aborted(PR_FAILURE)) goto aborted;
+                if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                {
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): send data timeout\n", me));
+                    goto retry;
+                }
+            }
+            TEST_ASSERT(bytes == filebytes);
+            netbytes += bytes;
+        }
+        filebytes = 0;
+        while (filebytes < descbytes)
+        {
+            netbytes = sizeof(buffer);
+            if ((descbytes - filebytes) < netbytes)
+                netbytes = descbytes - filebytes;
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\tClient(0x%p): receiving %d bytes\n", me, netbytes));
+            bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);
+            if (-1 == bytes)
+            {
+                if (Aborted(PR_FAILURE))
+                {
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive data aborted\n", me));
+                    goto aborted;
+                }
+                else if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive data timeout\n", me));
+				else
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive error (%d, %d)\n",
+						me, PR_GetError(), PR_GetOSError()));
+                goto retry;
+           }
+            if (0 == bytes)
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tClient(0x%p): unexpected end of stream\n",
+                    PR_GetCurrentThread()));
+                break;
+            }
+            filebytes += bytes;
+        }
+
+        rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+        if (Aborted(rv)) goto aborted;
+        TEST_ASSERT(PR_SUCCESS == rv);
+retry:
+        (void)PR_Close(fd); fd = NULL;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_INFO,
+            ("\tClient(0x%p): disconnected from server\n", me));
+
+        PR_Lock(client->ml);
+        client->operations += 1;
+        client->bytesTransferred += 2 * descbytes;
+        rv = PR_WaitCondVar(client->stateChange, rand() % clipping);
+        PR_Unlock(client->ml);
+        if (Aborted(rv)) break;
+    }
+
+aborted:
+    client->stopped = PR_IntervalNow();
+
+    PR_ClearInterrupt();
+    if (NULL != fd) rv = PR_Close(fd);
+
+    PR_Lock(client->ml);
+    client->state = cs_exit;
+    PR_NotifyCondVar(client->stateChange);
+    PR_Unlock(client->ml);
+    PR_DELETE(descriptor);
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("\tClient(0x%p): stopped after %u operations and %u bytes\n",
+        PR_GetCurrentThread(), client->operations, client->bytesTransferred));
+
+}  /* Client */
+
+static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server)
+{
+    PRStatus drv, rv;
+    char buffer[1024];
+    PRFileDesc *file = NULL;
+    PRThread * me = PR_GetCurrentThread();
+    PRInt32 bytes, descbytes, netbytes, filebytes = 0;
+    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);
+    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\tProcessRequest(0x%p): receiving desciptor\n", me));
+    bytes = PR_Recv(
+        fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout);
+    if (-1 == bytes)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto exit;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tProcessRequest(0x%p): receive timeout\n", me));
+        }
+        goto exit;
+    }
+    if (0 == bytes)
+    {
+        rv = PR_FAILURE;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_ERROR,
+            ("\tProcessRequest(0x%p): unexpected end of file\n", me));
+        goto exit;
+    }
+    descbytes = PR_ntohl(descriptor->size);
+    TEST_ASSERT(sizeof(*descriptor) == bytes);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE, 
+        ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n",
+        me, descbytes, descriptor->filename));
+
+    file = PR_Open(
+        descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666);
+    if (NULL == file)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto aborted;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tProcessRequest(0x%p): open file timeout\n", me));
+            goto aborted;
+        }
+    }
+    TEST_ASSERT(NULL != file);
+
+    filebytes = 0;
+    while (filebytes < descbytes)
+    {
+        netbytes = sizeof(buffer);
+        if ((descbytes - filebytes) < netbytes)
+            netbytes = descbytes - filebytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes));
+        bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);
+        if (-1 == bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): receive data timeout\n", me));
+                goto aborted;
+            }
+            /*
+             * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED)
+             * on NT here.  This is equivalent to ECONNRESET on Unix.
+             *     -wtc
+             */
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_WARNING,
+                ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n",
+                me, PR_GetError(), PR_GetOSError()));
+            goto aborted;
+        }
+        if(0 == bytes)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_WARNING,
+                ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me));
+            rv = PR_FAILURE;
+            goto aborted;
+        }
+        filebytes += bytes;
+        netbytes = bytes;
+        /* The byte count for PR_Write should be positive */
+        MY_ASSERT(netbytes > 0);
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes));
+        bytes = PR_Write(file, buffer, netbytes);
+        if (netbytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): write file timeout\n", me));
+                goto aborted;
+            }
+        }
+        TEST_ASSERT(bytes > 0);
+    }
+
+    PR_Lock(server->ml);
+    server->operations += 1;
+    server->bytesTransferred += filebytes;
+    PR_Unlock(server->ml);
+
+    rv = PR_Close(file);
+    if (Aborted(rv)) goto aborted;
+    TEST_ASSERT(PR_SUCCESS == rv);
+    file = NULL;
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename));
+    file = PR_Open(descriptor->filename, PR_RDONLY, 0);
+    if (NULL == file)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto aborted;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\t\tProcessRequest(0x%p): open file timeout\n",
+                PR_GetCurrentThread()));
+            goto aborted;
+        }
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_ERROR,
+            ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n",
+            me, PR_GetError(), PR_GetOSError()));
+        goto aborted;
+    }
+    TEST_ASSERT(NULL != file);
+
+    netbytes = 0;
+    while (netbytes < descbytes)
+    {
+        filebytes = sizeof(buffer);
+        if ((descbytes - netbytes) < filebytes)
+            filebytes = descbytes - netbytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes));
+        bytes = PR_Read(file, buffer, filebytes);
+        if (filebytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): read file timeout\n", me));
+            else
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n",
+                    me, PR_GetError(), PR_GetOSError()));
+            goto aborted;
+        }
+        TEST_ASSERT(bytes > 0);
+        netbytes += bytes;
+        filebytes = bytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes));
+        bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);
+        if (filebytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): send data timeout\n", me));
+                goto aborted;
+            }
+            break;
+        }
+       TEST_ASSERT(bytes > 0);
+    }
+    
+    PR_Lock(server->ml);
+    server->bytesTransferred += filebytes;
+    PR_Unlock(server->ml);
+
+    rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+    if (Aborted(rv)) goto aborted;
+
+    rv = PR_Close(file);
+    if (Aborted(rv)) goto aborted;
+    TEST_ASSERT(PR_SUCCESS == rv);
+    file = NULL;
+
+aborted:
+    PR_ClearInterrupt();
+    if (NULL != file) PR_Close(file);
+    drv = PR_Delete(descriptor->filename);
+    TEST_ASSERT(PR_SUCCESS == drv);
+exit:
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\t\tProcessRequest(0x%p): Finished\n", me));
+
+    PR_DELETE(descriptor);
+
+#if defined(WIN95)
+    PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */
+#endif
+    return rv;
+}  /* ProcessRequest */
+
+static PRStatus CreateWorker(CSServer_t *server, CSPool_t *pool)
+{
+    CSWorker_t *worker = PR_NEWZAP(CSWorker_t);
+    worker->server = server;
+    PR_INIT_CLIST(&worker->element);
+    worker->thread = PR_CreateThread(
+        PR_USER_THREAD, Worker, worker,
+        DEFAULT_SERVER_PRIORITY, thread_scope,
+        PR_UNJOINABLE_THREAD, 0);
+    if (NULL == worker->thread)
+    {
+        PR_DELETE(worker);
+        return PR_FAILURE;
+    }
+
+    TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, 
+        ("\tCreateWorker(0x%p): create new worker (0x%p)\n",
+        PR_GetCurrentThread(), worker->thread));
+
+    return PR_SUCCESS;
+}  /* CreateWorker */
+
+static void PR_CALLBACK Worker(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr from;
+    PRFileDesc *fd = NULL;
+    PRThread *me = PR_GetCurrentThread();
+    CSWorker_t *worker = (CSWorker_t*)arg;
+    CSServer_t *server = worker->server;
+    CSPool_t *pool = &server->pool;
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_NOTICE,
+        ("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1));
+
+    PR_Lock(server->ml);
+    PR_APPEND_LINK(&worker->element, &server->list);
+    pool->workers += 1;  /* define our existance */
+
+    while (cs_run == server->state)
+    {
+        while (pool->accepting >= server->workers.accepting)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\t\tWorker(0x%p): waiting for accept slot[%d]\n",
+                me, pool->accepting));
+            rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT);
+            if (Aborted(rv) || (cs_run != server->state))
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_NOTICE,
+                    ("\tWorker(0x%p): has been %s\n",
+                    me, (Aborted(rv) ? "interrupted" : "stopped")));
+                goto exit;
+            }
+        } 
+        pool->accepting += 1;  /* how many are really in accept */
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\t\tWorker(0x%p): calling accept\n", me));
+        fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT);
+
+        PR_Lock(server->ml);        
+        pool->accepting -= 1;
+        PR_NotifyCondVar(pool->acceptComplete);
+
+        if ((NULL == fd) && Aborted(PR_FAILURE))
+        {
+            if (NULL != server->listener)
+            {
+                PR_Close(server->listener);
+                server->listener = NULL;
+            }
+            goto exit;
+        }
+
+        if (NULL != fd)
+        {
+            /*
+            ** Create another worker of the total number of workers is
+            ** less than the minimum specified or we have none left in
+            ** accept() AND we're not over the maximum.
+            ** This sort of presumes that the number allowed in accept
+            ** is at least as many as the minimum. Otherwise we'll keep
+            ** creating new threads and deleting them soon after.
+            */
+            PRBool another =
+                ((pool->workers < server->workers.minimum) ||
+                ((0 == pool->accepting)
+                    && (pool->workers < server->workers.maximum))) ?
+                    PR_TRUE : PR_FALSE;
+            pool->active += 1;
+            PR_Unlock(server->ml);
+
+            if (another) (void)CreateWorker(server, pool);
+
+            rv = ProcessRequest(fd, server);
+            if (PR_SUCCESS != rv)
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tWorker(0x%p): server process ended abnormally\n", me));
+            (void)PR_Close(fd); fd = NULL;
+
+            PR_Lock(server->ml);
+            pool->active -= 1;
+        }
+    }
+
+exit:
+    PR_ClearInterrupt();    
+    PR_Unlock(server->ml);
+
+    if (NULL != fd)
+    {
+        (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+        (void)PR_Close(fd);
+    }
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_NOTICE,
+        ("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool->workers));
+
+    PR_Lock(server->ml);
+    pool->workers -= 1;  /* undefine our existance */
+    PR_REMOVE_AND_INIT_LINK(&worker->element);
+    PR_NotifyCondVar(pool->exiting);
+    PR_Unlock(server->ml);
+
+    PR_DELETE(worker);  /* destruction of the "worker" object */
+
+}  /* Worker */
+
+static void PR_CALLBACK Server(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr serverAddress;
+    PRThread *me = PR_GetCurrentThread();
+    CSServer_t *server = (CSServer_t*)arg;
+    PRSocketOptionData sockOpt;
+
+    server->listener = PR_Socket(domain, SOCK_STREAM, protocol);
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    rv = PR_SetSocketOption(server->listener, &sockOpt);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    memset(&serverAddress, 0, sizeof(serverAddress));
+	if (PR_AF_INET6 != domain)
+		rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress);
+	else
+		rv = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, DEFAULT_PORT,
+													&serverAddress);
+    rv = PR_Bind(server->listener, &serverAddress);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    rv = PR_Listen(server->listener, server->backlog);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    server->started = PR_IntervalNow();
+    TimeOfDayMessage("Server started at", me);
+
+    PR_Lock(server->ml);
+    server->state = cs_run;
+    PR_NotifyCondVar(server->stateChange);
+    PR_Unlock(server->ml);
+
+    /*
+    ** Create the first worker (actually, a thread that accepts
+    ** connections and then processes the work load as needed).
+    ** From this point on, additional worker threads are created
+    ** as they are needed by existing worker threads.
+    */
+    rv = CreateWorker(server, &server->pool);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    /*
+    ** From here on this thread is merely hanging around as the contact
+    ** point for the main test driver. It's just waiting for the driver
+    ** to declare the test complete.
+    */
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\tServer(0x%p): waiting for state change\n", me));
+
+    PR_Lock(server->ml);
+    while ((cs_run == server->state) && !Aborted(rv))
+    {
+        rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(server->ml);
+    PR_ClearInterrupt();
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_INFO,
+        ("\tServer(0x%p): shutting down workers\n", me));
+
+    /*
+    ** Get all the worker threads to exit. They know how to
+    ** clean up after themselves, so this is just a matter of
+    ** waiting for clorine in the pool to take effect. During
+    ** this stage we're ignoring interrupts.
+    */
+    server->workers.minimum = server->workers.maximum = 0;
+
+    PR_Lock(server->ml);
+    while (!PR_CLIST_IS_EMPTY(&server->list))
+    {
+        PRCList *head = PR_LIST_HEAD(&server->list);
+        CSWorker_t *worker = (CSWorker_t*)head;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker));
+        rv = PR_Interrupt(worker->thread);
+        TEST_ASSERT(PR_SUCCESS == rv);
+        PR_REMOVE_AND_INIT_LINK(head);
+    }
+
+    while (server->pool.workers > 0)
+    {
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE,
+            ("\tServer(0x%p): waiting for %u workers to exit\n",
+            me, server->pool.workers));
+        (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+    server->state = cs_exit;
+    PR_NotifyCondVar(server->stateChange);
+    PR_Unlock(server->ml);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("\tServer(0x%p): stopped after %u operations and %u bytes\n",
+        me, server->operations, server->bytesTransferred));
+
+    if (NULL != server->listener) PR_Close(server->listener);
+    server->stopped = PR_IntervalNow();
+
+}  /* Server */
+
+static void WaitForCompletion(PRIntn execution)
+{
+    while (execution > 0)
+    { 
+        PRIntn dally = (execution > 30) ? 30 : execution;
+        PR_Sleep(PR_SecondsToInterval(dally));
+        if (pthread_stats) PT_FPrintStats(debug_out, "\nPThread Statistics\n");
+        execution -= dally;
+    }
+}  /* WaitForCompletion */
+
+static void Help(void)
+{
+    PR_fprintf(debug_out, "cltsrv test program usage:\n");
+    PR_fprintf(debug_out, "\t-a <n>       threads allowed in accept        (5)\n");
+    PR_fprintf(debug_out, "\t-b <n>       backlock for listen              (5)\n");
+    PR_fprintf(debug_out, "\t-c <threads> number of clients to create      (1)\n");
+    PR_fprintf(debug_out, "\t-f <low>     low water mark for fd caching    (0)\n");
+    PR_fprintf(debug_out, "\t-F <high>    high water mark for fd caching   (0)\n");
+    PR_fprintf(debug_out, "\t-w <threads> minimal number of server threads (1)\n");
+    PR_fprintf(debug_out, "\t-W <threads> maximum number of server threads (1)\n");
+    PR_fprintf(debug_out, "\t-e <seconds> duration of the test in seconds  (10)\n");
+    PR_fprintf(debug_out, "\t-s <string>  dsn name of server               (localhost)\n");
+    PR_fprintf(debug_out, "\t-G           use GLOBAL threads               (LOCAL)\n");
+    PR_fprintf(debug_out, "\t-X           use XTP as transport             (TCP)\n");
+    PR_fprintf(debug_out, "\t-6           Use IPv6                         (IPv4)\n");
+    PR_fprintf(debug_out, "\t-v           verbosity (accumulative)         (0)\n");
+    PR_fprintf(debug_out, "\t-p           pthread statistics               (FALSE)\n");
+    PR_fprintf(debug_out, "\t-d           debug mode                       (FALSE)\n");
+    PR_fprintf(debug_out, "\t-h           this message\n");
+}  /* Help */
+
+static Verbosity IncrementVerbosity(void)
+{
+    PRIntn verboge = (PRIntn)verbosity + 1;
+    return (Verbosity)verboge;
+}  /* IncrementVerbosity */
+
+PRIntn main(PRIntn argc, char** argv)
+{
+    PRUintn index;
+    PRBool boolean;
+    CSClient_t *client;
+    PRStatus rv, joinStatus;
+    CSServer_t *server = NULL;
+
+    PRUintn backlog = DEFAULT_BACKLOG;
+    PRUintn clients = DEFAULT_CLIENTS;
+    const char *serverName = DEFAULT_SERVER;
+    PRBool serverIsLocal = PR_TRUE;
+    PRUintn accepting = ALLOWED_IN_ACCEPT;
+    PRUintn workersMin = DEFAULT_WORKERS_MIN;
+    PRUintn workersMax = DEFAULT_WORKERS_MAX;
+    PRIntn execution = DEFAULT_EXECUTION_TIME;
+    PRIntn low = DEFAULT_LOW, high = DEFAULT_HIGH;
+
+    /*
+     * -G           use global threads
+     * -a <n>       threads allowed in accept
+     * -b <n>       backlock for listen
+     * -c <threads> number of clients to create
+     * -f <low>     low water mark for caching FDs
+     * -F <high>    high water mark for caching FDs
+     * -w <threads> minimal number of server threads
+     * -W <threads> maximum number of server threads
+     * -e <seconds> duration of the test in seconds
+     * -s <string>  dsn name of server (implies no server here)
+     * -v           verbosity
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:f:F:w:W:e:s:vdhp");
+
+    debug_out = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'X':  /* use XTP as transport */
+            protocol = 36;
+            break;
+        case '6':  /* Use IPv6 */
+            domain = PR_AF_INET6;
+            break;
+        case 'a':  /* the value for accepting */
+            accepting = atoi(opt->value);
+            break;
+        case 'b':  /* the value for backlock */
+            backlog = atoi(opt->value);
+            break;
+        case 'c':  /* number of client threads */
+            clients = atoi(opt->value);
+            break;
+        case 'f':  /* low water fd cache */
+            low = atoi(opt->value);
+            break;
+        case 'F':  /* low water fd cache */
+            high = atoi(opt->value);
+            break;
+        case 'w':  /* minimum server worker threads */
+            workersMin = atoi(opt->value);
+            break;
+        case 'W':  /* maximum server worker threads */
+            workersMax = atoi(opt->value);
+            break;
+        case 'e':  /* program execution time in seconds */
+            execution = atoi(opt->value);
+            break;
+        case 's':  /* server's address */
+            serverName = opt->value;
+            break;
+        case 'v':  /* verbosity */
+            verbosity = IncrementVerbosity();
+            break;
+        case 'd':  /* debug mode */
+            debug_mode = PR_TRUE;
+            break;
+        case 'p':  /* pthread mode */
+            pthread_stats = PR_TRUE;
+            break;
+        case 'h':
+        default:
+            Help();
+            return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (0 != PL_strcmp(serverName, DEFAULT_SERVER)) serverIsLocal = PR_FALSE;
+    if (0 == execution) execution = DEFAULT_EXECUTION_TIME;
+    if (0 == workersMax) workersMax = DEFAULT_WORKERS_MAX;
+    if (0 == workersMin) workersMin = DEFAULT_WORKERS_MIN;
+    if (0 == accepting) accepting = ALLOWED_IN_ACCEPT;
+    if (0 == backlog) backlog = DEFAULT_BACKLOG;
+
+    if (workersMin > accepting) accepting = workersMin;
+
+    PR_STDIO_INIT();
+    TimeOfDayMessage("Client/Server started at", PR_GetCurrentThread());
+
+    cltsrv_log_file = PR_NewLogModule("cltsrv_log");
+    MY_ASSERT(NULL != cltsrv_log_file);
+    boolean = PR_SetLogFile("cltsrv.log");
+    MY_ASSERT(boolean);
+
+#ifdef XP_MAC
+    debug_mode = PR_TRUE;
+#endif
+
+    rv = PR_SetFDCacheSize(low, high);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    if (serverIsLocal)
+    {
+        /* Establish the server */
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_INFO,
+            ("main(0x%p): starting server\n", PR_GetCurrentThread()));
+
+        server = PR_NEWZAP(CSServer_t);
+        PR_INIT_CLIST(&server->list);
+        server->state = cs_init;
+        server->ml = PR_NewLock();
+        server->backlog = backlog;
+        server->port = DEFAULT_PORT;
+        server->workers.minimum = workersMin;
+        server->workers.maximum = workersMax;
+        server->workers.accepting = accepting;
+        server->stateChange = PR_NewCondVar(server->ml);
+        server->pool.exiting = PR_NewCondVar(server->ml);
+        server->pool.acceptComplete = PR_NewCondVar(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE,
+            ("main(0x%p): creating server thread\n", PR_GetCurrentThread()));
+
+        server->thread = PR_CreateThread(
+            PR_USER_THREAD, Server, server, PR_PRIORITY_HIGH,
+            thread_scope, PR_JOINABLE_THREAD, 0);
+        TEST_ASSERT(NULL != server->thread);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): waiting for server init\n", PR_GetCurrentThread()));
+
+        PR_Lock(server->ml);
+        while (server->state == cs_init)
+            PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): server init complete (port #%d)\n",
+            PR_GetCurrentThread(), server->port));
+    }
+
+    if (clients != 0)
+    {
+        /* Create all of the clients */
+        PRHostEnt host;
+        char buffer[BUFFER_SIZE];
+        client = (CSClient_t*)PR_CALLOC(clients * sizeof(CSClient_t));
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): creating %d client threads\n",
+            PR_GetCurrentThread(), clients));
+        
+        if (!serverIsLocal)
+        {
+            rv = PR_GetHostByName(serverName, buffer, BUFFER_SIZE, &host);
+            if (PR_SUCCESS != rv)
+            {
+                PL_FPrintError(PR_STDERR, "PR_GetHostByName");
+                return 2;
+            }
+        }
+
+        for (index = 0; index < clients; ++index)
+        {
+            client[index].state = cs_init;
+            client[index].ml = PR_NewLock();
+            if (serverIsLocal)
+            {
+				if (PR_AF_INET6 != domain)
+                	(void)PR_InitializeNetAddr(
+                    	PR_IpAddrLoopback, DEFAULT_PORT,
+                    	&client[index].serverAddress);
+				else
+					rv = PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6,
+							DEFAULT_PORT, &client[index].serverAddress);
+            }
+            else
+            {
+                (void)PR_EnumerateHostEnt(
+                    0, &host, DEFAULT_PORT, &client[index].serverAddress);
+            }
+            client[index].stateChange = PR_NewCondVar(client[index].ml);
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_INFO,
+                ("main(0x%p): creating client threads\n", PR_GetCurrentThread()));
+            client[index].thread = PR_CreateThread(
+                PR_USER_THREAD, Client, &client[index], PR_PRIORITY_NORMAL,
+                thread_scope, PR_JOINABLE_THREAD, 0);
+            TEST_ASSERT(NULL != client[index].thread);
+            PR_Lock(client[index].ml);
+            while (cs_init == client[index].state)
+                PR_WaitCondVar(client[index].stateChange, PR_INTERVAL_NO_TIMEOUT);
+            PR_Unlock(client[index].ml);
+        }
+    }
+
+    /* Then just let them go at it for a bit */
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("main(0x%p): waiting for execution interval (%d seconds)\n",
+        PR_GetCurrentThread(), execution));
+
+    WaitForCompletion(execution);
+
+    TimeOfDayMessage("Shutting down", PR_GetCurrentThread());
+
+    if (clients != 0)
+    {
+        for (index = 0; index < clients; ++index)
+        {
+            TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, 
+                ("main(0x%p): notifying client(0x%p) to stop\n",
+                PR_GetCurrentThread(), client[index].thread));
+
+            PR_Lock(client[index].ml);
+            if (cs_run == client[index].state)
+            {
+                client[index].state = cs_stop;
+                PR_Interrupt(client[index].thread);
+                while (cs_stop == client[index].state)
+                    PR_WaitCondVar(
+                        client[index].stateChange, PR_INTERVAL_NO_TIMEOUT);
+            }
+            PR_Unlock(client[index].ml);
+
+            TEST_LOG(cltsrv_log_file, TEST_LOG_VERBOSE, 
+                ("main(0x%p): joining client(0x%p)\n",
+                PR_GetCurrentThread(), client[index].thread));
+
+		    joinStatus = PR_JoinThread(client[index].thread);
+		    TEST_ASSERT(PR_SUCCESS == joinStatus);
+            PR_DestroyCondVar(client[index].stateChange);
+            PR_DestroyLock(client[index].ml);
+        }
+        PR_DELETE(client);
+    }
+
+    if (NULL != server)
+    {
+        /* All clients joined - retrieve the server */
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE, 
+            ("main(0x%p): notifying server(0x%p) to stop\n",
+            PR_GetCurrentThread(), server->thread));
+
+        PR_Lock(server->ml);
+        server->state = cs_stop;
+        PR_Interrupt(server->thread);
+        while (cs_exit != server->state)
+            PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE, 
+            ("main(0x%p): joining server(0x%p)\n",
+            PR_GetCurrentThread(), server->thread));
+        joinStatus = PR_JoinThread(server->thread);
+        TEST_ASSERT(PR_SUCCESS == joinStatus);
+
+        PR_DestroyCondVar(server->stateChange);
+        PR_DestroyCondVar(server->pool.exiting);
+        PR_DestroyCondVar(server->pool.acceptComplete);
+        PR_DestroyLock(server->ml);
+        PR_DELETE(server);
+    }
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS, 
+        ("main(0x%p): test complete\n", PR_GetCurrentThread()));
+
+    PT_FPrintStats(debug_out, "\nPThread Statistics\n");
+
+    TimeOfDayMessage("Test exiting at", PR_GetCurrentThread());
+    PR_Cleanup();
+    return 0;
+}  /* main */
+
+/* cltsrv.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/concur.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/concur.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,193 @@
+/* -*- 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:            concur.c 
+** Description:     test of adding and removing concurrency options
+*/
+
+#include "prcvar.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prlock.h"
+#include "prprf.h"
+#include "prmem.h"
+#include "prlog.h"
+
+#include "plgetopt.h"
+
+#if defined(XP_MAC)
+#include "pprio.h"
+#else
+#include "private/pprio.h"
+#endif
+
+#include <stdlib.h>
+
+#define DEFAULT_RANGE 10
+#define DEFAULT_LOOPS 100
+
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+typedef struct Context
+{
+    PRLock *ml;
+    PRCondVar *cv;
+    PRIntn want, have;
+} Context;
+
+
+/*
+** Make the instance of 'context' static (not on the stack)
+** for Win16 threads
+*/
+static Context context = {NULL, NULL, 0, 0};
+
+static void PR_CALLBACK Dull(void *arg)
+{
+    Context *context = (Context*)arg;
+    PR_Lock(context->ml);
+    context->have += 1;
+    while (context->want >= context->have)
+        PR_WaitCondVar(context->cv, PR_INTERVAL_NO_TIMEOUT);
+    context->have -= 1;
+    PR_Unlock(context->ml);
+}  /* Dull */
+
+PRIntn PR_CALLBACK Concur(PRIntn argc, char **argv)
+{
+    PRUintn cpus;
+	PLOptStatus os;
+	PRThread **threads;
+    PRBool debug = PR_FALSE;
+    PRUintn range = DEFAULT_RANGE;
+	PRStatus rc;
+    PRUintn cnt;
+    PRUintn loops = DEFAULT_LOOPS;
+	PRIntervalTime hundredMills = PR_MillisecondsToInterval(100);
+	PLOptState *opt = PL_CreateOptState(argc, argv, "Gdl:r:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* GLOBAL threads */
+			thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'd':  /* debug mode */
+			debug = PR_TRUE;
+            break;
+        case 'r':  /* range limit */
+			range = atoi(opt->value);
+            break;
+        case 'l':  /* loop counter */
+			loops = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (0 == range) range = DEFAULT_RANGE;
+    if (0 == loops) loops = DEFAULT_LOOPS;
+
+    context.ml = PR_NewLock();
+    context.cv = PR_NewCondVar(context.ml);
+
+    if (debug)
+        PR_fprintf(
+            PR_STDERR, "Testing with %d CPUs and %d interations\n", range, loops);
+
+	threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * range);
+    while (--loops > 0)
+    {
+        for (cpus = 1; cpus <= range; ++cpus)
+        {
+            PR_SetConcurrency(cpus);
+            context.want = cpus;
+
+            threads[cpus - 1] = PR_CreateThread(
+                PR_USER_THREAD, Dull, &context, PR_PRIORITY_NORMAL,
+				      thread_scope, PR_JOINABLE_THREAD, 0);
+        }
+
+        PR_Sleep(hundredMills);
+
+        for (cpus = range; cpus > 0; cpus--)
+        {
+            PR_SetConcurrency(cpus);
+            context.want = cpus - 1;
+
+            PR_Lock(context.ml);
+            PR_NotifyCondVar(context.cv);
+            PR_Unlock(context.ml);
+        }
+		for(cnt = 0; cnt < range; cnt++) {
+			rc = PR_JoinThread(threads[cnt]);
+			PR_ASSERT(rc == PR_SUCCESS);
+		}
+    }
+
+    
+    if (debug)
+        PR_fprintf(
+            PR_STDERR, "Waiting for %d thread(s) to exit\n", context.have);
+
+    while (context.have > 0) PR_Sleep(hundredMills);
+
+    if (debug)
+        PR_fprintf(
+            PR_STDERR, "Finished [want: %d, have: %d]\n",
+            context.want, context.have);
+
+    PR_DestroyLock(context.ml);
+    PR_DestroyCondVar(context.cv);
+    PR_DELETE(threads);
+
+    PR_fprintf(PR_STDERR, "PASSED\n");
+
+    return 0;
+} /* Concur */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PR_STDIO_INIT();
+    return PR_Initialize(Concur, argc, argv, 0);
+}  /* main */
+
+/* concur.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/cvar.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/cvar.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,334 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+** Name: cvar.c
+**
+** Description: Tests Condition Variable Operations 
+**
+** Modification History:
+** 13-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.
+** 12-June-97 Revert to return code 0 and 1.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+
+#include "nspr.h"
+
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+PRMonitor *mon;
+#define DEFAULT_COUNT   1000
+PRInt32 count = 0;
+PRIntn debug_mode;
+
+#define kQSIZE	1
+
+typedef struct {
+	PRLock		*bufLock;
+	int			startIdx;
+	int			numFull;
+	PRCondVar	*notFull;
+	PRCondVar	*notEmpty;
+	void		*data[kQSIZE];
+} CircBuf;
+
+static PRBool failed = PR_FALSE;
+
+/*
+** NewCB creates and initializes a new circular buffer.
+*/
+static CircBuf* NewCB(void)
+{
+	CircBuf		*cbp;
+	
+	cbp = PR_NEW(CircBuf);
+	if (cbp == NULL)
+		return (NULL);
+		
+	cbp->bufLock 	= PR_NewLock();
+	cbp->startIdx 	= 0;
+	cbp->numFull 	= 0;
+	cbp->notFull	= PR_NewCondVar(cbp->bufLock);
+	cbp->notEmpty	= PR_NewCondVar(cbp->bufLock);
+	
+	return (cbp);
+}
+
+/*
+** DeleteCB frees a circular buffer.
+*/
+static void DeleteCB(CircBuf *cbp)
+{
+	PR_DestroyLock(cbp->bufLock);
+	PR_DestroyCondVar(cbp->notFull);
+	PR_DestroyCondVar(cbp->notEmpty);
+	PR_DELETE(cbp);
+}
+
+
+/*
+** PutCBData puts new data on the queue.  If the queue is full, it waits 
+** until there is room.
+*/
+static void PutCBData(CircBuf *cbp, void *data)
+{
+	PR_Lock(cbp->bufLock);
+	/* wait while the buffer is full */
+	while (cbp->numFull == kQSIZE)
+		PR_WaitCondVar(cbp->notFull,PR_INTERVAL_NO_TIMEOUT);
+	cbp->data[(cbp->startIdx + cbp->numFull) % kQSIZE] = data;
+	cbp->numFull += 1;
+	
+	/* let a waiting reader know that there is data */
+	PR_NotifyCondVar(cbp->notEmpty);
+	PR_Unlock(cbp->bufLock);
+
+}
+
+
+/*
+** GetCBData gets the oldest data on the queue.  If the queue is empty, it waits 
+** until new data appears.
+*/
+static void* GetCBData(CircBuf *cbp)
+{
+	void *data;
+	
+	PR_Lock(cbp->bufLock);
+	/* wait while the buffer is empty */
+	while (cbp->numFull == 0)
+		PR_WaitCondVar(cbp->notEmpty,PR_INTERVAL_NO_TIMEOUT);
+	data = cbp->data[cbp->startIdx];
+	cbp->startIdx =(cbp->startIdx + 1) % kQSIZE;
+	cbp->numFull -= 1;
+	
+	/* let a waiting writer know that there is room */
+	PR_NotifyCondVar(cbp->notFull);
+	PR_Unlock(cbp->bufLock);
+	
+	return (data);
+}
+
+
+/************************************************************************/
+
+static int alive;
+
+static void PR_CALLBACK CXReader(void *arg)
+{
+	CircBuf *cbp = (CircBuf *)arg;
+    PRInt32 i, n;
+    void *data;
+
+    n = count / 2;
+    for (i = 0; i < n; i++) {
+		data = GetCBData(cbp);
+		if ((int)data != i)
+    		if (debug_mode) printf("data mismatch at for i = %d usec\n", i);
+    }
+ 
+    PR_EnterMonitor(mon);
+    --alive;
+    PR_Notify(mon);
+    PR_ExitMonitor(mon);
+}
+
+static void PR_CALLBACK CXWriter(void *arg)
+{
+	CircBuf *cbp = (CircBuf *)arg;
+    PRInt32 i, n;
+
+    n = count / 2;
+    for (i = 0; i < n; i++)
+		PutCBData(cbp, (void *)i);
+
+    PR_EnterMonitor(mon);
+    --alive;
+    PR_Notify(mon);
+    PR_ExitMonitor(mon);
+}
+
+static void CondWaitContextSwitch(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *t1, *t2;
+	CircBuf *cbp;
+
+    PR_EnterMonitor(mon);
+
+    alive = 2;
+
+	cbp =  NewCB();
+
+	t1 = PR_CreateThread(PR_USER_THREAD,
+				      CXReader, cbp, 
+				      PR_PRIORITY_NORMAL,
+				      scope1,
+    				  PR_UNJOINABLE_THREAD,
+				      0);
+	PR_ASSERT(t1);
+	t2 = PR_CreateThread(PR_USER_THREAD,
+				      CXWriter, cbp, 
+				      PR_PRIORITY_NORMAL,
+				      scope2,
+    				  PR_UNJOINABLE_THREAD,
+				      0);
+	PR_ASSERT(t2);
+
+    /* Wait for both of the threads to exit */
+    while (alive) {
+	PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+	DeleteCB(cbp);
+
+    PR_ExitMonitor(mon);
+}
+
+static void CondWaitContextSwitchUU(void)
+{
+    CondWaitContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void CondWaitContextSwitchUK(void)
+{
+    CondWaitContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+static void CondWaitContextSwitchKK(void)
+{
+    CondWaitContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("%40s: %6.2f usec\n", msg, d / count);
+
+    if (0 ==  d) failed = PR_TRUE;
+}
+
+static PRIntn PR_CALLBACK RealMain(int argc, char **argv)
+{
+	/* 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] [-c n]
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dc:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'c':  /* loop count */
+            count = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (0 == count) count = DEFAULT_COUNT;
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("cvar.log");
+	debug_mode = 1;
+#endif
+
+    mon = PR_NewMonitor();
+
+    Measure(CondWaitContextSwitchUU, "cond var wait context switch- user/user");
+    Measure(CondWaitContextSwitchUK, "cond var wait context switch- user/kernel");
+    Measure(CondWaitContextSwitchKK, "cond var wait context switch- kernel/kernel");
+
+	PR_DestroyMonitor(mon);
+
+	if (debug_mode) printf("%s\n", (failed) ? "FAILED" : "PASSED");
+
+	if(failed)
+		return 1;
+	else
+		return 0;
+}
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/cvar2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/cvar2.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1008 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+** Name: cvar2.c
+**
+** Description: Simple test creates several local and global threads;
+**              half use a single,shared condvar, and the
+**              other half have their own condvar. The main thread then loops
+**				notifying them to wakeup. 
+**
+** Modification History:
+** 14-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. 
+***********************************************************************/
+
+#include "nspr.h"
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int _debug_on = 0;
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+#define DEFAULT_COUNT   100
+#define DEFAULT_THREADS 5
+PRInt32 count = DEFAULT_COUNT;
+
+typedef struct threadinfo {
+    PRThread        *thread;
+    PRInt32          id;
+    PRBool           internal;
+    PRInt32         *tcount;
+    PRLock          *lock;
+    PRCondVar       *cvar;
+    PRIntervalTime   timeout;
+    PRInt32          loops;
+
+    PRLock          *exitlock;
+    PRCondVar       *exitcvar;
+    PRInt32         *exitcount;
+} threadinfo;
+
+/*
+** Make exitcount, tcount static. for Win16.
+*/
+static PRInt32 exitcount=0;
+static PRInt32 tcount=0;
+
+
+/* Thread that gets notified; many threads share the same condvar */
+void PR_CALLBACK
+SharedCondVarThread(void *_info)
+{
+    threadinfo *info = (threadinfo *)_info;
+    PRInt32 index;
+
+    for (index=0; index<info->loops; index++) {
+        PR_Lock(info->lock);
+        if (*info->tcount == 0)
+            PR_WaitCondVar(info->cvar, info->timeout);
+#if 0
+        printf("shared thread %ld notified in loop %ld\n", info->id, index);
+#endif
+        (*info->tcount)--;
+        PR_Unlock(info->lock);
+
+        PR_Lock(info->exitlock);
+        (*info->exitcount)++;
+        PR_NotifyCondVar(info->exitcvar);
+        PR_Unlock(info->exitlock);
+    }
+#if 0
+    printf("shared thread %ld terminating\n", info->id);
+#endif
+}
+
+/* Thread that gets notified; no other threads use the same condvar */
+void PR_CALLBACK
+PrivateCondVarThread(void *_info)
+{
+    threadinfo *info = (threadinfo *)_info;
+    PRInt32 index;
+
+    for (index=0; index<info->loops; index++) {
+        PR_Lock(info->lock);
+        if (*info->tcount == 0) {
+	    DPRINTF(("PrivateCondVarThread: thread 0x%lx waiting on cvar = 0x%lx\n",
+				PR_GetCurrentThread(), info->cvar));
+            PR_WaitCondVar(info->cvar, info->timeout);
+	}
+#if 0
+        printf("solo   thread %ld notified in loop %ld\n", info->id, index);
+#endif
+        (*info->tcount)--;
+        PR_Unlock(info->lock);
+
+        PR_Lock(info->exitlock);
+        (*info->exitcount)++;
+        PR_NotifyCondVar(info->exitcvar);
+DPRINTF(("PrivateCondVarThread: thread 0x%lx notified exitcvar = 0x%lx cnt = %ld\n",
+			PR_GetCurrentThread(), info->exitcvar,(*info->exitcount)));
+        PR_Unlock(info->exitlock);
+    }
+#if 0
+    printf("solo   thread %ld terminating\n", info->id);
+#endif
+}
+
+void 
+CreateTestThread(threadinfo *info, 
+                 PRInt32 id,
+                 PRLock *lock,
+                 PRCondVar *cvar,
+                 PRInt32 loops,
+                 PRIntervalTime timeout,
+                 PRInt32 *tcount,
+                 PRLock *exitlock,
+                 PRCondVar *exitcvar,
+                 PRInt32 *exitcount,
+                 PRBool shared, 
+                 PRThreadScope scope)
+{
+    info->id = id;
+    info->internal = (shared) ? PR_FALSE : PR_TRUE;
+    info->lock = lock;
+    info->cvar = cvar;
+    info->loops = loops;
+    info->timeout = timeout;
+    info->tcount = tcount;
+    info->exitlock = exitlock;
+    info->exitcvar = exitcvar;
+    info->exitcount = exitcount;
+    info->thread = PR_CreateThread(
+                           PR_USER_THREAD,
+                           shared?SharedCondVarThread:PrivateCondVarThread,
+                           info,
+                           PR_PRIORITY_NORMAL,
+                           scope,
+                           PR_JOINABLE_THREAD,
+                           0);
+    if (!info->thread)
+        PL_PrintError("error creating thread\n");
+}
+
+
+void 
+CondVarTestSUU(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    
+    exitcount=0;
+    tcount=0;
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg; ) {
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_LOCAL_THREAD);
+        index++;
+	DPRINTF(("CondVarTestSUU: created thread 0x%lx\n",list[index].thread));
+    }
+
+    for (loops = 0; loops < count; loops++) {
+        /* Notify the threads */
+        for(index=0; index<(arg); index++) {
+            PR_Lock(list[index].lock);
+            (*list[index].tcount)++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+	    DPRINTF(("PrivateCondVarThread: thread 0x%lx notified cvar = 0x%lx\n",
+				PR_GetCurrentThread(), list[index].cvar));
+        }
+
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg);
+        exitcount -= arg;
+        PR_Unlock(exitlock);
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg); index++) 
+        PR_JoinThread(list[index].thread);
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+}
+
+void 
+CondVarTestSUK(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    exitcount=0;
+    tcount=0;
+
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg; ) {
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_GLOBAL_THREAD);
+        index++;
+    }
+
+    for (loops = 0; loops < count; loops++) {
+        /* Notify the threads */
+        for(index=0; index<(arg); index++) {
+
+            PR_Lock(list[index].lock);
+            (*list[index].tcount)++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+        }
+
+#if 0
+        printf("wait for threads to be done\n");
+#endif
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg);
+        exitcount -= arg;
+        PR_Unlock(exitlock);
+#if 0
+        printf("threads ready\n");
+#endif
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg); index++) 
+        PR_JoinThread(list[index].thread);
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+}
+
+void 
+CondVarTestPUU(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    PRInt32 *tcount, *saved_tcount;
+
+    exitcount=0;
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+    saved_tcount = tcount = (PRInt32 *)PR_CALLOC(sizeof(*tcount) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg; ) {
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_LOCAL_THREAD);
+
+	DPRINTF(("CondVarTestPUU: created thread 0x%lx\n",list[index].thread));
+        index++;
+	tcount++;
+    }
+
+    for (loops = 0; loops < count; loops++) {
+        /* Notify the threads */
+        for(index=0; index<(arg); index++) {
+
+            PR_Lock(list[index].lock);
+            (*list[index].tcount)++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+        }
+
+	PR_Lock(exitlock);
+        /* Wait for threads to finish */
+        while(exitcount < arg) {
+DPRINTF(("CondVarTestPUU: thread 0x%lx waiting on exitcvar = 0x%lx cnt = %ld\n",
+				PR_GetCurrentThread(), exitcvar, exitcount));
+            	PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+	}
+        PR_ASSERT(exitcount >= arg);
+        exitcount -= arg;
+        PR_Unlock(exitlock);
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg); index++)  {
+	DPRINTF(("CondVarTestPUU: joining thread 0x%lx\n",list[index].thread));
+        PR_JoinThread(list[index].thread);
+        if (list[index].internal) {
+            PR_Lock(list[index].lock);
+            PR_DestroyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+            PR_DestroyLock(list[index].lock);
+        }
+    }
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+    PR_DELETE(saved_tcount);
+}
+
+void 
+CondVarTestPUK(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    PRInt32 *tcount, *saved_tcount;
+
+    exitcount=0;
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+    saved_tcount = tcount = (PRInt32 *)PR_CALLOC(sizeof(*tcount) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg; ) {
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_GLOBAL_THREAD);
+
+        index++;
+        tcount++;
+    }
+
+    for (loops = 0; loops < count; loops++) {
+        /* Notify the threads */
+        for(index=0; index<(arg); index++) {
+
+            PR_Lock(list[index].lock);
+            (*list[index].tcount)++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+        }
+
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg);
+        exitcount -= arg;
+        PR_Unlock(exitlock);
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg); index++) {
+        PR_JoinThread(list[index].thread);
+        if (list[index].internal) {
+            PR_Lock(list[index].lock);
+            PR_DestroyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+            PR_DestroyLock(list[index].lock);
+        }
+    }
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+    PR_DELETE(saved_tcount);
+}
+
+void 
+CondVarTest(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    PRInt32 *ptcount, *saved_ptcount;
+
+    exitcount=0;
+    tcount=0;
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+    saved_ptcount = ptcount = (PRInt32 *)PR_CALLOC(sizeof(*ptcount) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg*4; ) {
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_LOCAL_THREAD);
+
+        index++;
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_GLOBAL_THREAD);
+
+        index++;
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         ptcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_LOCAL_THREAD);
+        index++;
+	ptcount++;
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_INTERVAL_NO_TIMEOUT,
+                         ptcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_GLOBAL_THREAD);
+
+        index++;
+	ptcount++;
+    }
+
+    for (loops = 0; loops < count; loops++) {
+
+        /* Notify the threads */
+        for(index=0; index<(arg*4); index++) {
+            PR_Lock(list[index].lock);
+            (*list[index].tcount)++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+        }
+
+#if 0
+        printf("wait for threads done\n");
+#endif
+
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg*4)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg*4);
+        exitcount -= arg*4;
+        PR_Unlock(exitlock);
+#if 0
+        printf("threads ready\n");
+#endif
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg*4); index++) {
+        PR_JoinThread(list[index].thread);
+        if (list[index].internal) {
+            PR_Lock(list[index].lock);
+            PR_DestroyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+            PR_DestroyLock(list[index].lock);
+        }
+    }
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+    PR_DELETE(saved_ptcount);
+}
+
+void 
+CondVarTimeoutTest(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg*4; ) {
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_LOCAL_THREAD);
+        index++;
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_GLOBAL_THREAD);
+        index++;
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_LOCAL_THREAD);
+        index++;
+
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_GLOBAL_THREAD);
+
+        index++;
+    }
+
+    for (loops = 0; loops < count; loops++) {
+
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg*4)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg*4);
+        exitcount -= arg*4;
+        PR_Unlock(exitlock);
+    }
+
+
+    /* Join all the threads */
+    for(index=0; index<(arg*4); index++) {
+        PR_JoinThread(list[index].thread);
+        if (list[index].internal) {
+            PR_Lock(list[index].lock);
+            PR_DestroyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+            PR_DestroyLock(list[index].lock);
+        }
+    }
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+    PR_DestroyCondVar(exitcvar);
+    PR_DestroyLock(exitlock);
+
+    PR_DELETE(list);
+}
+
+void 
+CondVarMixedTest(void *_arg)
+{
+    PRInt32 arg = (PRInt32)_arg;
+    PRInt32 index, loops;
+    threadinfo *list;
+    PRLock *sharedlock;
+    PRCondVar *sharedcvar;
+    PRLock *exitlock;
+    PRCondVar *exitcvar;
+    PRInt32 *ptcount;
+
+    exitcount=0;
+    tcount=0;
+    list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4));
+    ptcount = (PRInt32 *)PR_CALLOC(sizeof(*ptcount) * (arg * 4));
+
+    sharedlock = PR_NewLock();
+    sharedcvar = PR_NewCondVar(sharedlock);
+    exitlock = PR_NewLock();
+    exitcvar = PR_NewCondVar(exitlock);
+
+    /* Create the threads */
+    for(index=0; index<arg*4; ) {
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_LOCAL_THREAD);
+        index++;
+        CreateTestThread(&list[index],
+                         index,
+                         sharedlock,
+                         sharedcvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         &tcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_TRUE,
+                         PR_GLOBAL_THREAD);
+        index++;
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         ptcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_LOCAL_THREAD);
+        index++;
+	ptcount++;
+
+        list[index].lock = PR_NewLock();
+        list[index].cvar = PR_NewCondVar(list[index].lock);
+        CreateTestThread(&list[index],
+                         index,
+                         list[index].lock,
+                         list[index].cvar,
+                         count,
+                         PR_MillisecondsToInterval(50),
+                         ptcount,
+                         exitlock,
+                         exitcvar,
+                         &exitcount,
+                         PR_FALSE,
+                         PR_GLOBAL_THREAD);
+        index++;
+	ptcount++;
+    }
+
+
+    /* Notify every 3rd thread */
+    for (loops = 0; loops < count; loops++) {
+
+        /* Notify the threads */
+        for(index=0; index<(arg*4); index+=3) {
+
+            PR_Lock(list[index].lock);
+            *list[index].tcount++;
+            PR_NotifyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+
+        }
+        /* Wait for threads to finish */
+        PR_Lock(exitlock);
+        while(exitcount < arg*4)
+            PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60));
+        PR_ASSERT(exitcount >= arg*4);
+        exitcount -= arg*4;
+        PR_Unlock(exitlock);
+    }
+
+    /* Join all the threads */
+    for(index=0; index<(arg*4); index++) {
+        PR_JoinThread(list[index].thread);
+        if (list[index].internal) {
+            PR_Lock(list[index].lock);
+            PR_DestroyCondVar(list[index].cvar);
+            PR_Unlock(list[index].lock);
+            PR_DestroyLock(list[index].lock);
+        }
+    }
+
+    PR_DestroyCondVar(sharedcvar);
+    PR_DestroyLock(sharedlock);
+
+    PR_DELETE(list);
+}
+
+void 
+CondVarCombinedTest(void *arg)
+{
+    PRThread *threads[3];
+
+    threads[0] = PR_CreateThread(PR_USER_THREAD,
+                                 CondVarTest,
+                                 (void *)arg,
+                                 PR_PRIORITY_NORMAL,
+                                 PR_GLOBAL_THREAD,
+                                 PR_JOINABLE_THREAD,
+                                 0);
+    threads[1] = PR_CreateThread(PR_USER_THREAD,
+                                 CondVarTimeoutTest,
+                                 (void *)arg,
+                                 PR_PRIORITY_NORMAL,
+                                 PR_GLOBAL_THREAD,
+                                 PR_JOINABLE_THREAD,
+                                 0);
+    threads[2] = PR_CreateThread(PR_USER_THREAD,
+                                 CondVarMixedTest,
+                                 (void *)arg,
+                                 PR_PRIORITY_NORMAL,
+                                 PR_GLOBAL_THREAD,
+                                 PR_JOINABLE_THREAD,
+                                 0);
+
+    PR_JoinThread(threads[0]);
+    PR_JoinThread(threads[1]);
+    PR_JoinThread(threads[2]);
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void *), PRInt32 arg, const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)((void *)arg);
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    printf("%40s: %6.2f usec\n", msg, d / count);
+}
+
+static PRIntn PR_CALLBACK RealMain(int argc, char **argv)
+{
+    PRInt32 threads, default_threads = DEFAULT_THREADS;
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "vc:t:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'v':  /* debug mode */
+			_debug_on = 1;
+            break;
+        case 'c':  /* loop counter */
+			count = atoi(opt->value);
+            break;
+        case 't':  /* number of threads involved */
+			default_threads = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (0 == count) count = DEFAULT_COUNT;
+    if (0 == default_threads) default_threads = DEFAULT_THREADS;
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("cvar2.log");
+#endif
+
+    printf("\n\
+CondVar Test:                                                           \n\
+                                                                        \n\
+Simple test creates several local and global threads; half use a single,\n\
+shared condvar, and the other half have their own condvar.  The main    \n\
+thread then loops notifying them to wakeup.                             \n\
+                                                                        \n\
+The timeout test is very similar except that the threads are not        \n\
+notified.  They will all wakeup on a 1 second timeout.                  \n\
+                                                                        \n\
+The mixed test combines the simple test and the timeout test; every     \n\
+third thread is notified, the other threads are expected to timeout     \n\
+correctly.                                                              \n\
+                                                                        \n\
+Lastly, the combined test creates a thread for each of the above three  \n\
+cases and they all run simultaneously.                                  \n\
+                                                                        \n\
+This test is run with %d, %d, %d, and %d threads of each type.\n\n",
+default_threads, default_threads*2, default_threads*3, default_threads*4);
+
+    PR_SetConcurrency(2);
+
+    for (threads = default_threads; threads < default_threads*5; threads+=default_threads) {
+        printf("\n%ld Thread tests\n", threads);
+        Measure(CondVarTestSUU, threads, "Condvar simple test shared UU");
+        Measure(CondVarTestSUK, threads, "Condvar simple test shared UK");
+        Measure(CondVarTestPUU, threads, "Condvar simple test priv UU");
+        Measure(CondVarTestPUK, threads, "Condvar simple test priv UK");
+#ifdef XP_MAC
+	/* Mac heaps can't handle thread*4 stack allocations at a time for (10, 15, 20)*4 */
+        Measure(CondVarTest, 5, "Condvar simple test All");
+        Measure(CondVarTimeoutTest, 5,  "Condvar timeout test");
+#else
+        Measure(CondVarTest, threads, "Condvar simple test All");
+        Measure(CondVarTimeoutTest, threads,  "Condvar timeout test");
+#endif
+#if 0
+        Measure(CondVarMixedTest, threads,  "Condvar mixed timeout test");
+        Measure(CondVarCombinedTest, threads, "Combined condvar test");
+#endif
+    }
+
+    printf("PASS\n");
+
+    return 0;
+}
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dbmalloc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dbmalloc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,347 @@
+/* -*- 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: dbmalloc.c
+**
+** Description: Testing malloc (OBSOLETE)
+**
+** Modification History:
+** 14-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. 
+***********************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "nspr.h"
+
+void
+usage
+(
+    void
+)
+{
+    fprintf(stderr, "Usage: dbmalloc ('-m'|'-s') '-f' num_fails ('-d'|'-n') filename [...]\n");
+    exit(0);
+}
+
+typedef struct node_struct
+{
+    struct node_struct *next, *prev;
+    int line;
+    char value[4];
+}
+    node_t,
+   *node_pt;
+
+node_pt get_node(const char *line)
+{
+    node_pt rv;
+    int l = strlen(line);
+    rv = (node_pt)PR_MALLOC(sizeof(node_t) + l + 1 - 4);
+    if( (node_pt)0 == rv ) return (node_pt)0;
+    memcpy(&rv->value[0], line, l+1);
+    rv->next = rv->prev = (node_pt)0;
+    return rv;
+}
+
+void
+dump
+(
+    const char *name,
+    node_pt     node,
+    int         mf,
+    int         debug
+)
+{
+    if( (node_pt)0 != node->prev ) dump(name, node->prev, mf, debug);
+    if( 0 != debug ) printf("[%s]: %6d: %s", name, node->line, node->value);
+    if( node->line == mf ) fprintf(stderr, "[%s]: Line %d was allocated!\n", name, node->line);
+    if( (node_pt)0 != node->next ) dump(name, node->next, mf, debug);
+    return;
+}
+
+void
+release
+(
+    node_pt node
+)
+{
+    if( (node_pt)0 != node->prev ) release(node->prev);
+    if( (node_pt)0 != node->next ) release(node->next);
+    PR_DELETE(node);
+}
+
+int
+t2
+(
+    const char *name,
+    int         mf,
+    int         debug
+)
+{
+    int rv;
+    FILE *fp;
+    int l = 0;
+    node_pt head = (node_pt)0;
+    char buffer[ BUFSIZ ];
+
+    fp = fopen(name, "r");
+    if( (FILE *)0 == fp )
+    {
+        fprintf(stderr, "[%s]: Cannot open \"%s.\"\n", name, name);
+        return -1;
+    }
+
+    /* fgets mallocs a buffer, first time through. */
+    if( (char *)0 == fgets(buffer, BUFSIZ, fp) )
+    {
+        fprintf(stderr, "[%s]: \"%s\" is empty.\n", name, name);
+        (void)fclose(fp);
+        return -1;
+    }
+
+    rewind(fp);
+
+    if( PR_SUCCESS != PR_ClearMallocCount() )
+    {
+        fprintf(stderr, "[%s]: Cannot clear malloc count.\n", name);
+        (void)fclose(fp);
+        return -1;
+    }
+
+    if( PR_SUCCESS != PR_SetMallocCountdown(mf) )
+    {
+        fprintf(stderr, "[%s]: Cannot set malloc countdown to %d\n", name, mf);
+        (void)fclose(fp);
+        return -1;
+    }
+
+    while( fgets(buffer, BUFSIZ, fp) )
+    {
+        node_pt n;
+        node_pt *w = &head;
+
+        if( (strlen(buffer) == (BUFSIZ-1)) && (buffer[BUFSIZ-2] != '\n') )
+            buffer[BUFSIZ-2] == '\n';
+
+        l++;
+
+        n = get_node(buffer);
+        if( (node_pt)0 == n ) 
+        {
+            printf("[%s]: Line %d: malloc failure!\n", name, l);
+            continue;
+        }
+
+        n->line = l;
+
+        while( 1 )
+        {
+            int comp;
+
+            if( (node_pt)0 == *w )
+            {
+                *w = n;
+                break;
+            }
+
+            comp = strcmp((*w)->value, n->value);
+            if( comp < 0 ) w = &(*w)->next;
+            else w = &(*w)->prev;
+        }
+    }
+
+    (void)fclose(fp);
+
+    dump(name, head, mf, debug);
+
+    rv = PR_GetMallocCount();
+    PR_ClearMallocCountdown();
+
+    release(head);
+
+    return rv;
+}
+
+int nf = 0;
+int debug = 0;
+
+void
+test
+(
+    const char *name
+)
+{
+    int n, i;
+
+    extern int nf, debug;
+
+    printf("[%s]: starting test 0\n", name);
+    n = t2(name, 0, debug);
+    if( -1 == n ) return;
+    printf("[%s]: test 0 had %ld allocations.\n", name, n);
+
+    if( 0 >= n ) return;
+
+    for( i = 0; i < nf; i++ )
+    {
+        int which = rand() % n;
+        if( 0 == which ) printf("[%s]: starting test %d -- no allocation should fail\n", name, i+1);
+        else printf("[%s]: starting test %d -- allocation %d should fail\n", name, i+1, which);
+        (void)t2(name, which, debug);
+        printf("[%s]: test %d done.\n", name, i+1);
+    }
+
+    return;
+}
+
+int
+main
+(
+    int     argc,
+    char   *argv[]
+)
+{
+    int okay = 0;
+    int multithread = 0;
+
+    struct threadlist
+    {
+        struct threadlist *next;
+        PRThread *thread;
+    }
+        *threadhead = (struct threadlist *)0;
+
+    extern int nf, debug;
+
+    srand(time(0));
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    printf("[main]: We %s using the debugging malloc.\n",
+           PR_IsDebuggingMalloc() ? "ARE" : "ARE NOT");
+
+    while( argv++, --argc )
+    {
+        if( '-' == argv[0][0] )
+        {
+            switch( argv[0][1] )
+            {
+                case 'f':
+                    nf = atoi(argv[0][2] ? &argv[0][2] :
+                              --argc ? *++argv : "0");
+                    break;
+                case 'd':
+                    debug = 1;
+                    break;
+                case 'n':
+                    debug = 0;
+                    break;
+                case 'm':
+                    multithread = 1;
+                    break;
+                case 's':
+                    multithread = 0;
+                    break;
+                default:
+                    usage();
+                    break;
+            }
+        }
+        else
+        {
+            FILE *fp = fopen(*argv, "r");
+            if( (FILE *)0 == fp )
+            {
+                fprintf(stderr, "Cannot open \"%s.\"\n", *argv);
+                continue;
+            }
+
+            okay++;
+            (void)fclose(fp);
+            if( multithread )
+            {
+                struct threadlist *n;
+
+                n = (struct threadlist *)malloc(sizeof(struct threadlist));
+                if( (struct threadlist *)0 == n ) 
+                {
+                    fprintf(stderr, "This is getting tedious. \"%s\"\n", *argv);
+                    continue;
+                }
+
+                n->next = threadhead;
+                n->thread = PR_CreateThread(PR_USER_THREAD, (void (*)(void *))test, 
+                                            *argv, PR_PRIORITY_NORMAL, 
+                                            PR_LOCAL_THREAD, PR_JOINABLE_THREAD,
+                                            0);
+                if( (PRThread *)0 == n->thread )
+                {
+                    fprintf(stderr, "Can't create thread for \"%s.\"\n", *argv);
+                    continue;
+                }
+                else
+                {
+                    threadhead = n;
+                }
+            }
+            else
+            {
+                test(*argv);
+            }
+        }
+    }
+
+    if( okay == 0 ) usage();
+    else while( (struct threadlist *)0 != threadhead )
+    {
+        struct threadlist *x = threadhead->next;
+        (void)PR_JoinThread(threadhead->thread);
+        PR_DELETE(threadhead);
+        threadhead = x;
+    }
+
+    return 0;
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dbmalloc1.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dbmalloc1.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,141 @@
+/* -*- 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: dbmalloc1.c (OBSOLETE)
+**
+** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions.
+**
+** Modification History:
+** 14-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.
+**
+** 12-June-97 AGarcia Revert to return code 0 and 1, remove debug option (obsolete).
+***********************************************************************/
+
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include "nspr.h"
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+/* variable used for both r1 and r2 tests */
+int should_fail =0;
+int actually_failed=0;
+
+
+void
+r1
+(
+    void
+)
+{
+    int i;
+	actually_failed=0;
+    for(  i = 0; i < 5; i++ )
+    {
+        void *x = PR_MALLOC(128);
+        if( (void *)0 == x ) {
+			if (debug_mode) printf("\tMalloc %d failed.\n", i+1);
+			actually_failed = 1;
+		}
+        PR_DELETE(x);
+    }
+
+	if (((should_fail != actually_failed) & (!debug_mode))) failed_already=1;
+
+
+    return;
+}
+
+void
+r2
+(
+    void
+)
+{
+    int i;
+
+    for( i = 0; i <= 5; i++ )
+    {
+		should_fail =0;
+        if( 0 == i ) {
+			if (debug_mode) printf("No malloc should fail:\n");
+		}
+        else {
+			if (debug_mode) printf("Malloc %d should fail:\n", i);
+			should_fail = 1;
+		}
+        PR_SetMallocCountdown(i);
+        r1();
+        PR_ClearMallocCountdown();
+    }
+}
+
+int
+main
+(
+    int     argc,
+    char   *argv[]
+)
+{
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+    r2();
+
+    if(failed_already)    
+        return 1;
+    else
+        return 0;
+
+    
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dceemu.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dceemu.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,132 @@
+/* -*- 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:        dceemu.c
+** Description: testing the DCE emulation api
+**
+** Modification History:
+** 14-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.
+** 12-June-97 Revert to return code 0 and 1, remove debug option (obsolete).
+**/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+
+
+#if defined(_PR_DCETHREADS)
+
+#include "prlog.h"
+#include "prinit.h"
+#include "prpdce.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+PRIntn failed_already=0;
+PRIntn debug_mode=0;
+
+static PRIntn prmain(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PRP_NewNakedCondVar();
+    PRIntervalTime tenmsecs = PR_MillisecondsToInterval(10);
+
+    rv = PRP_TryLock(ml);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; 
+    
+    rv = PRP_TryLock(ml);
+    PR_ASSERT(PR_FAILURE == rv);
+    if ((rv != PR_FAILURE) & (!debug_mode)) failed_already=1; 
+
+    rv = PRP_NakedNotify(cv);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; 
+
+    rv = PRP_NakedBroadcast(cv);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1; 
+
+    rv = PRP_NakedWait(cv, ml, tenmsecs);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1;     
+
+    PR_Unlock(ml);    
+        
+    rv = PRP_NakedNotify(cv);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1;     
+
+    rv = PRP_NakedBroadcast(cv);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if ((rv != PR_SUCCESS) & (!debug_mode)) failed_already=1;     
+
+    PRP_DestroyNakedCondVar(cv);
+    PR_DestroyLock(ml);
+
+    if (debug_mode) printf("Test succeeded\n");
+
+    return 0;
+
+}  /* prmain */
+
+#endif /* #if defined(_PR_DCETHREADS) */
+
+int main(int argc, char **argv)
+{
+
+#if defined(_PR_DCETHREADS)
+    PR_Initialize(prmain, argc, argv, 0);
+    if(failed_already)    
+        return 1;
+    else
+        return 0;
+#else
+    return 0;
+#endif
+}  /* main */
+
+
+/* decemu.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/depend.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/depend.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/***********************************************************************
+**  1996 - Netscape Communications Corporation
+**
+**
+** Name:		depend.c
+** Description: Test to enumerate the dependencies
+*
+** Modification History:
+** 14-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. 
+***********************************************************************/
+#include "prinit.h"
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static void PrintVersion(
+    const char *msg, const PRVersion* info, PRIntn tab)
+{
+    static const len = 20;
+    static const char *tabs = {"                    "};
+
+    tab *= 2;
+    if (tab > len) tab = len;
+    printf("%s", &tabs[len - tab]);
+    printf("%s ", msg);
+    printf("%s ", info->id);
+    printf("%d.%d", info->major, info->minor);
+    if (0 != info->patch)
+        printf(".p%d", info->patch);
+    printf("\n");
+}  /* PrintDependency */
+
+static void ChaseDependents(const PRVersionInfo *info, PRIntn tab)
+{
+    PrintVersion("exports", &info->selfExport, tab);
+    if (NULL != info->importEnumerator)
+    {
+        const PRDependencyInfo *dependent = NULL;
+        while (NULL != (dependent = info->importEnumerator(dependent)))
+        {
+            const PRVersionInfo *import = dependent->exportInfoFn();
+            PrintVersion("imports", &dependent->importNeeded, tab);
+            ChaseDependents(import, tab + 1);
+        }
+    }
+}  /* ChaseDependents */
+
+static PRVersionInfo hack_export;
+static PRVersionInfo dummy_export;
+static PRDependencyInfo dummy_imports[2];
+
+static const PRVersionInfo *HackExportInfo(void)
+{
+    hack_export.selfExport.major = 11;
+    hack_export.selfExport.minor = 10;
+    hack_export.selfExport.patch = 200;
+    hack_export.selfExport.id = "Hack";
+    hack_export.importEnumerator = NULL;
+    return &hack_export;
+}
+
+static const PRDependencyInfo *DummyImports(
+    const PRDependencyInfo *previous)
+{
+    if (NULL == previous) return &dummy_imports[0];
+    else if (&dummy_imports[0] == previous) return &dummy_imports[1];
+    else if (&dummy_imports[1] == previous) return NULL;
+}  /* DummyImports */
+
+static const PRVersionInfo *DummyLibVersion(void)
+{
+    dummy_export.selfExport.major = 1;
+    dummy_export.selfExport.minor = 0;
+    dummy_export.selfExport.patch = 0;
+    dummy_export.selfExport.id = "Dumbass application";
+    dummy_export.importEnumerator = DummyImports;
+
+    dummy_imports[0].importNeeded.major = 2;
+    dummy_imports[0].importNeeded.minor = 0;
+    dummy_imports[0].importNeeded.patch = 0;
+    dummy_imports[0].importNeeded.id = "Netscape Portable Runtime";
+    dummy_imports[0].exportInfoFn = PR_ExportInfo;
+
+    dummy_imports[1].importNeeded.major = 5;
+    dummy_imports[1].importNeeded.minor = 1;
+    dummy_imports[1].importNeeded.patch = 2;
+    dummy_imports[1].importNeeded.id = "Hack Library";
+    dummy_imports[1].exportInfoFn = HackExportInfo;
+
+    return &dummy_export;
+}  /* DummyLibVersion */
+
+int main(int argc, char **argv)
+{
+    PRIntn tab = 0;
+    const PRVersionInfo *info = DummyLibVersion();
+    const char *buildDate = __DATE__, *buildTime = __TIME__;
+
+    printf("Depend.c build time is %s %s\n", buildDate, buildTime);
+    
+    if (NULL != info) ChaseDependents(info, tab);
+
+    return 0;
+}  /* main */
+
+/* depend.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,6 @@
+/.cvsignore/1.2/Sat May 12 05:07:36 2001//
+/Makefile.in/1.16/Wed Jun  1 14:28:35 2005//
+/my.def/1.3/Tue Mar  8 03:01:05 2005//
+/mygetval.c/3.5/Sun Apr 25 15:01:03 2004//
+/mysetval.c/3.5/Sun Apr 25 15:01:03 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/tests/dll

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,121 @@
+# 
+# ***** 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 =
+endif
+endif
+
+CSRCS = mygetval.c mysetval.c
+
+INCLUDES = -I$(dist_includedir)
+
+OBJS = $(OBJDIR)/mygetval.$(OBJ_SUFFIX) \
+	$(OBJDIR)/mysetval.$(OBJ_SUFFIX)
+
+ifeq ($(OS_TARGET), WIN16)
+W16OBJS = $(subst $(space),$(comma)$(space),$(OBJS))
+endif
+
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET), WIN16)
+# do nothing
+else
+ifdef NS_USE_GCC
+DLLBASE=-Wl,--image-base -Wl,0x30000000
+else
+DLLBASE=-BASE:0x30000000
+endif
+RES=$(OBJDIR)/my.res
+RESNAME=../../../pr/src/nspr.rc
+endif
+endif
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+IMPORT_LIBRARY	= $(OBJDIR)/my.$(LIB_SUFFIX)
+SHARED_LIBRARY	= $(OBJDIR)/my.dll
+ifeq ($(OS_ARCH), OS2)
+MAPFILE		= $(OBJDIR)/my.def
+GARBAGE		+= $(MAPFILE)
+MKSHLIB		+= $(MAPFILE)
+endif
+TARGETS		= $(SHARED_LIBRARY) $(IMPORT_LIBRARY)
+else
+ifdef MKSHLIB
+SHARED_LIBRARY	= $(OBJDIR)/libmy.$(DLL_SUFFIX)
+endif
+TARGETS		= $(SHARED_LIBRARY)
+endif
+
+#
+# To create a loadable module on Rhapsody, we must override
+# -dynamiclib with -bundle.
+#
+ifeq ($(OS_ARCH),Darwin)
+DSO_LDOPTS = -bundle
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+ifeq ($(OS_TARGET), WIN16)
+# Note: The Win16 target: my.dll requires these macros
+# to be overridden to build the test .dll
+# default values in win16...mk are for release targets.
+#
+OS_DLL_OPTION = NOCASEEXACT
+OS_LIB_FLAGS = -irn
+endif
+
+ifdef SHARED_LIBRARY
+export:: $(TARGETS)
+
+clean::
+	rm -rf $(TARGETS)
+endif

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/my.def
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/my.def	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,58 @@
+;+#
+;+# ***** 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) 2002-2003
+;+# 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 *****
+;+#
+;+# 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 ";-"
+;+#
+;+MY_1.0 {
+;+	global:
+LIBRARY my ;-
+EXPORTS ;-
+		My_GetValue;
+		My_SetValue;
+;+	local: *;
+;+};

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/mygetval.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/mygetval.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,58 @@
+/* -*- 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"
+
+extern PRIntn my_global;
+
+PR_IMPLEMENT(PRIntn) My_GetValue()
+{
+    return my_global;
+}
+
+#if defined(WIN16)
+int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg, 
+                      WORD cbHeapSize, LPSTR lpszCmdLine )
+{
+    return TRUE;
+}
+#endif /* WIN16 */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/mysetval.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dll/mysetval.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,45 @@
+/* -*- 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 "prtypes.h"
+
+PRIntn my_global = 0;
+
+PR_IMPLEMENT(void) My_SetValue(PRIntn val)
+{
+    my_global = val;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dlltest.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dlltest.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,221 @@
+/* -*- 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: dlltest.c
+**
+** Description: test dll functionality.
+**
+** Modification History:
+** 14-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.
+** 12-June-97 Revert to return code 0 and 1.
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+#include "prinit.h"
+#include "prlink.h"
+#include "prmem.h"
+#include "prerror.h"
+
+#include "plstr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef PRIntn (PR_CALLBACK *GetFcnType)(void);
+typedef void (PR_CALLBACK *SetFcnType)(PRIntn);
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+int main(int argc, char** argv)
+{
+    PRLibrary *lib, *lib2;  /* two handles to the same library */
+    GetFcnType getFcn;
+    SetFcnType setFcn;
+    PRIntn value;
+    PRStatus status;
+    char *libName;
+
+    if (argc >= 2 && PL_strcmp(argv[1], "-d") == 0) {
+        debug_mode = 1;
+    }
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    /*
+     * Test 1: load the library, look up the symbols, call the functions,
+     * and check the results.
+     */
+
+    libName = PR_GetLibraryName("dll", "my");
+    if (debug_mode) printf("Loading library %s\n", libName);
+    lib = PR_LoadLibrary(libName);
+    PR_FreeLibraryName(libName);
+    if (lib == NULL) {
+        PRInt32 textLength = PR_GetErrorTextLength();
+        char *text = (char*)PR_MALLOC(textLength);
+        (void)PR_GetErrorText(text);
+        fprintf(
+            stderr, "PR_LoadLibrary failed (%d, %d, %s)\n",
+            PR_GetError(), PR_GetOSError(), text);
+        if (!debug_mode) failed_already=1;
+    }
+    getFcn = (GetFcnType) PR_FindSymbol(lib, "My_GetValue");
+    setFcn = (SetFcnType) PR_FindFunctionSymbol(lib, "My_SetValue");
+    (*setFcn)(888);
+    value = (*getFcn)();
+    if (value != 888) {
+        fprintf(stderr, "Test 1 failed: set value to 888, but got %d\n", value);
+        if (!debug_mode) failed_already=1;
+    }
+    if (debug_mode) printf("Test 1 passed\n");
+
+    /*
+     * Test 2: get a second handle to the same library (this should increment
+     * the reference count), look up the symbols, call the functions, and
+     * check the results.
+     */
+
+    getFcn = (GetFcnType) PR_FindSymbolAndLibrary("My_GetValue", &lib2);
+    if (NULL == getFcn || lib != lib2) {
+        fprintf(stderr, "Test 2 failed: handles for the same library are not "
+            "equal: handle 1: %p, handle 2: %p\n", lib, lib2);
+        if (!debug_mode) failed_already=1;
+    }
+    setFcn = (SetFcnType) PR_FindSymbol(lib2, "My_SetValue");
+    value = (*getFcn)();
+    if (value != 888) {
+        fprintf(stderr, "Test 2 failed: value should be 888, but got %d\n",
+            value);
+        if (!debug_mode) failed_already=1;
+    }
+    (*setFcn)(777);
+    value = (*getFcn)();
+    if (value != 777) {
+        fprintf(stderr, "Test 2 failed: set value to 777, but got %d\n", value);
+        if (!debug_mode) failed_already=1;
+        goto exit_now;
+    }
+    if (debug_mode) printf("Test 2 passed\n");
+
+    /*
+     * Test 3: unload the library.  The library should still be accessible
+     * via the second handle.  do the same things as above.
+     */
+
+    status = PR_UnloadLibrary(lib);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "Test 3 failed: cannot unload library: (%d, %d)\n",
+            PR_GetError(), PR_GetOSError());
+        if (!debug_mode) failed_already=1;
+        goto exit_now;
+    }
+    getFcn = (GetFcnType) PR_FindFunctionSymbol(lib2, "My_GetValue");
+    setFcn = (SetFcnType) PR_FindSymbol(lib2, "My_SetValue");
+    (*setFcn)(666);
+    value = (*getFcn)();
+    if (value != 666) {
+        fprintf(stderr, "Test 3 failed: set value to 666, but got %d\n", value);
+        if (!debug_mode) failed_already=1;
+        goto exit_now;
+    }
+    if (debug_mode) printf("Test 3 passed\n");
+
+    /*
+     * Test 4: unload the library, testing the reference count mechanism.
+     */
+
+    status = PR_UnloadLibrary(lib2);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "Test 4 failed: cannot unload library: (%d, %d)\n",
+            PR_GetError(), PR_GetOSError());
+        if (!debug_mode) failed_already=1;
+        goto exit_now;
+    }
+    getFcn = (GetFcnType) PR_FindFunctionSymbolAndLibrary("My_GetValue", &lib2);
+    if (NULL != getFcn) {
+        fprintf(stderr, "Test 4 failed: how can we find a symbol "
+            "in an already unloaded library?\n");
+        if (!debug_mode) failed_already=1;
+        goto exit_now;
+    }
+    if (debug_mode) {
+        printf("Test 4 passed\n");
+    }
+
+    /*
+    ** Test 5: LoadStaticLibrary()
+    */
+    {
+        PRStaticLinkTable   slt[10];
+        PRLibrary           *lib;
+        
+        lib = PR_LoadStaticLibrary( "my.dll", slt );
+        if ( lib == NULL )
+        {
+            fprintf(stderr, "Test 5: LoadStatiLibrary() failed\n" );
+            goto exit_now;
+        }
+        if (debug_mode)
+        {
+            printf("Test 5 passed\n");
+        }
+    }
+
+    goto exit_now;
+exit_now: 
+    PR_Cleanup();
+
+    if (failed_already) {
+        printf("FAILED\n");
+        return 1;
+    } else {
+        printf("PASSED\n");
+        return 0;
+    }
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/dtoa.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/dtoa.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,217 @@
+/* -*- 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 ***** */
+
+/******************************************************************************
+ *
+ * This file contains a test program for the function conversion functions
+ * for double precision code:
+ * PR_strtod
+ * PR_dtoa
+ * PR_cnvtf
+ *
+ * This file was ns/nspr/tests/dtoa.c, created by rrj on 1996/06/22.
+ *
+ *****************************************************************************/
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <locale.h>
+#include "prprf.h"
+#include "prdtoa.h"
+
+static int failed_already = 0;
+
+int main( int argc, char* argv[] )
+{
+    double num;
+    double num1;
+    double zero = 0.0;
+    char   cnvt[50];
+    
+    num = 1e24;
+    num1 = PR_strtod("1e24",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","1e24");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("1e+24",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 0.001e7;
+    num1 = PR_strtod("0.001e7",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","0.001e7");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("10000",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 0.0000000000000753;
+    num1 = PR_strtod("0.0000000000000753",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n",
+		"0.0000000000000753");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("7.53e-14",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 1.867e73;
+    num1 = PR_strtod("1.867e73",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","1.867e73");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("1.867e+73",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+
+    num = -1.867e73;
+    num1 = PR_strtod("-1.867e73",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e73");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-1.867e+73",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = -1.867e-73;
+    num1 = PR_strtod("-1.867e-73",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e-73");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-1.867e-73",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    /* Testing for infinity */
+    num = 1.0 / zero;
+    num1 = PR_strtod("1.867e765",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","1.867e765");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("Infinity",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = -1.0 / zero;
+    num1 = PR_strtod("-1.867e765",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n","-1.867e765");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-Infinity",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    /* Testing for NaN. PR_strtod can't parse "NaN" and "Infinity" */
+    num = zero / zero;
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("NaN",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = - zero / zero;
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("NaN",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+    num = 1.0000000001e21;
+    num1 = PR_strtod("1.0000000001e21",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n",
+		"1.0000000001e21");
+        failed_already = 1;
+    }
+
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("1.0000000001e+21",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+
+
+    num = -1.0000000001e-21;
+    num1 = PR_strtod("-1.0000000001e-21",NULL);
+    if(num1 != num){
+	fprintf(stderr,"Failed to convert numeric value %s\n",
+		"-1.0000000001e-21");
+        failed_already = 1;
+    }
+    PR_cnvtf(cnvt,sizeof(cnvt),20,num);
+    if(strcmp("-1.0000000001e-21",cnvt) != 0){
+	fprintf(stderr,"Failed to convert numeric value %lf %s\n",num,cnvt);
+        failed_already = 1;
+    }
+    if (failed_already) {
+        printf("FAILED\n");
+    } else {
+        printf("PASSED\n");
+    }
+    return failed_already;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/env.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/env.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,222 @@
+/* -*- 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:        env.c
+** Description: Testing environment variable operations
+**
+*/
+#include "prenv.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRIntn  debug = 0;
+PRIntn  verbose = 0;
+PRBool  failedAlready = PR_FALSE;
+
+#define  ENVNAME    "NSPR_ENVIRONMENT_TEST_VARIABLE"
+#define  ENVVALUE   "The expected result"
+#define  ENVBUFSIZE 256
+
+char    *envBuf; /* buffer pointer. We leak memory here on purpose! */
+
+static char * NewBuffer( size_t size )
+{
+    char *buf = malloc( size );
+    if ( NULL == buf ) {
+        printf("env: NewBuffer() failed\n");
+        exit(1);
+    }
+    return(buf);
+} /* end NewBuffer() */
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    char    *value;
+    PRStatus    rc;
+
+    {   /* Get command line options */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "vd");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+                break;
+            case 'v':  /* verbose */
+                verbose = 1;
+                break;
+             default:
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    } /* end block "Get command line options" */
+
+#if 0 
+    {
+        /*
+        ** This uses Windows native environment manipulation
+        ** as an experiment. Note the separation of namespace!
+        */
+        BOOL rv;
+        DWORD   size;
+        rv = SetEnvironmentVariable( ENVNAME, ENVVALUE );
+        if ( rv == 0 )  {
+            if (debug) printf("env: Shit! SetEnvironmentVariable() failed\n");
+            failedAlready = PR_TRUE;
+        }
+        if (verbose) printf("env: SetEnvironmentVariable() worked\n");
+
+        size = GetEnvironmentVariable( ENVNAME, envBuf, ENVBUFSIZE );    
+        if ( size == 0 )  {
+            if (debug) printf("env: Shit! GetEnvironmentVariable() failed. Found: %s\n", envBuf );
+            failedAlready = PR_TRUE;
+        }
+        if (verbose) printf("env: GetEnvironmentVariable() worked. Found: %s\n", envBuf);
+
+        value = PR_GetEnv( ENVNAME );
+        if ( (NULL == value ) || (strcmp( value, ENVVALUE)))  {
+            if (debug) printf( "env: PR_GetEnv() failed retrieving WinNative. Found: %s\n", value);
+            failedAlready = PR_TRUE;
+        }
+        if (verbose) printf("env: PR_GetEnv() worked. Found: %s\n", value);
+    }
+#endif
+
+    /* set an environment variable, read it back */
+    envBuf = NewBuffer( ENVBUFSIZE );
+    sprintf( envBuf, ENVNAME "=" ENVVALUE );
+    rc = PR_SetEnv( envBuf );
+    if ( PR_FAILURE == rc )  {
+        if (debug) printf( "env: PR_SetEnv() failed setting\n");
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf("env: PR_SetEnv() worked.\n");
+    }
+
+    value = PR_GetEnv( ENVNAME );
+    if ( (NULL == value ) || (strcmp( value, ENVVALUE)))  {
+        if (debug) printf( "env: PR_GetEnv() Failed after setting\n" );
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf("env: PR_GetEnv() worked after setting it. Found: %s\n", value );
+    }
+
+/* ---------------------------------------------------------------------- */
+    /* un-set the variable, using RAW name... should not work */
+    envBuf = NewBuffer( ENVBUFSIZE );
+    sprintf( envBuf, ENVNAME );
+    rc = PR_SetEnv( envBuf );
+    if ( PR_FAILURE == rc )  {
+        if (verbose) printf( "env: PR_SetEnv() not un-set using RAW name. Good!\n");
+    } else {
+        if (debug) printf("env: PR_SetEnv() un-set using RAW name. Bad!\n" );
+        failedAlready = PR_TRUE;
+    }
+
+    value = PR_GetEnv( ENVNAME );
+    if ( NULL == value ) {
+        if (debug) printf("env: PR_GetEnv() after un-set using RAW name. Bad!\n" );
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf( "env: PR_GetEnv() after RAW un-set found: %s\n", value );
+    }
+    
+/* ---------------------------------------------------------------------- */
+    /* set it again ... */
+    envBuf = NewBuffer( ENVBUFSIZE );
+    sprintf( envBuf, ENVNAME "=" ENVVALUE );
+    rc = PR_SetEnv( envBuf );
+    if ( PR_FAILURE == rc )  {
+        if (debug) printf( "env: PR_SetEnv() failed setting the second time.\n");
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf("env: PR_SetEnv() worked.\n");
+    }
+
+    /* un-set the variable using the form name= */
+    envBuf = NewBuffer( ENVBUFSIZE );
+    sprintf( envBuf, ENVNAME "=" );
+    rc = PR_SetEnv( envBuf );
+    if ( PR_FAILURE == rc )  {
+        if (debug) printf( "env: PR_SetEnv() failed un-setting using name=\n");
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf("env: PR_SetEnv() un-set using name= worked\n" );
+    }
+
+    value = PR_GetEnv( ENVNAME );
+    if (( NULL == value ) || ( 0x00 == *value )) {
+        if (verbose) printf("env: PR_GetEnv() after un-set using name= worked\n" );
+    } else {
+        if (debug) printf( "env: PR_GetEnv() after un-set using name=. Found: %s\n", value );
+        failedAlready = PR_TRUE;
+    }
+/* ---------------------------------------------------------------------- */
+    /* un-set the variable using the form name= */
+    envBuf = NewBuffer( ENVBUFSIZE );
+    sprintf( envBuf, ENVNAME "999=" );
+    rc = PR_SetEnv( envBuf );
+    if ( PR_FAILURE == rc )  {
+        if (debug) printf( "env: PR_SetEnv() failed un-setting using name=\n");
+        failedAlready = PR_TRUE;
+    } else {
+        if (verbose) printf("env: PR_SetEnv() un-set using name= worked\n" );
+    }
+
+    value = PR_GetEnv( ENVNAME "999" );
+    if (( NULL == value ) || ( 0x00 == *value )) {
+        if (verbose) printf("env: PR_GetEnv() after un-set using name= worked\n" );
+    } else {
+        if (debug) printf( "env: PR_GetEnv() after un-set using name=. Found: %s\n", value );
+        failedAlready = PR_TRUE;
+    }
+
+/* ---------------------------------------------------------------------- */
+    if (debug || verbose) printf("\n%s\n", (failedAlready)? "FAILED" : "PASSED" );
+    return( (failedAlready)? 1 : 0 );
+}  /* main() */
+
+/* env.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/errcodes.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/errcodes.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,167 @@
+/* -*- 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: errcodes.c
+**
+** Description: print nspr error codes
+**
+*/
+#include "prerror.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+static int _debug_on = 0;
+
+struct errinfo {
+	PRErrorCode errcode;
+	char 		*errname;
+};
+
+struct errinfo errcodes[] = {
+{PR_OUT_OF_MEMORY_ERROR,			"PR_OUT_OF_MEMORY_ERROR"},
+{PR_BAD_DESCRIPTOR_ERROR,			"PR_BAD_DESCRIPTOR_ERROR"},
+{PR_WOULD_BLOCK_ERROR,				"PR_WOULD_BLOCK_ERROR"},
+{PR_ACCESS_FAULT_ERROR,				"PR_ACCESS_FAULT_ERROR"},
+{PR_INVALID_METHOD_ERROR,			"PR_INVALID_METHOD_ERROR"},
+{PR_ILLEGAL_ACCESS_ERROR,			"PR_ILLEGAL_ACCESS_ERROR"},
+{PR_UNKNOWN_ERROR,					"PR_UNKNOWN_ERROR"},
+{PR_PENDING_INTERRUPT_ERROR,		"PR_PENDING_INTERRUPT_ERROR"},
+{PR_NOT_IMPLEMENTED_ERROR,			"PR_NOT_IMPLEMENTED_ERROR"},
+{PR_IO_ERROR,						"PR_IO_ERROR"},
+{PR_IO_TIMEOUT_ERROR,				"PR_IO_TIMEOUT_ERROR"},
+{PR_IO_PENDING_ERROR,				"PR_IO_PENDING_ERROR"},
+{PR_DIRECTORY_OPEN_ERROR,			"PR_DIRECTORY_OPEN_ERROR"},
+{PR_INVALID_ARGUMENT_ERROR,			"PR_INVALID_ARGUMENT_ERROR"},
+{PR_ADDRESS_NOT_AVAILABLE_ERROR,	"PR_ADDRESS_NOT_AVAILABLE_ERROR"},
+{PR_ADDRESS_NOT_SUPPORTED_ERROR,	"PR_ADDRESS_NOT_SUPPORTED_ERROR"},
+{PR_IS_CONNECTED_ERROR,				"PR_IS_CONNECTED_ERROR"},
+{PR_BAD_ADDRESS_ERROR,				"PR_BAD_ADDRESS_ERROR"},
+{PR_ADDRESS_IN_USE_ERROR,			"PR_ADDRESS_IN_USE_ERROR"},
+{PR_CONNECT_REFUSED_ERROR,			"PR_CONNECT_REFUSED_ERROR"},
+{PR_NETWORK_UNREACHABLE_ERROR,		"PR_NETWORK_UNREACHABLE_ERROR"},
+{PR_CONNECT_TIMEOUT_ERROR,			"PR_CONNECT_TIMEOUT_ERROR"},
+{PR_NOT_CONNECTED_ERROR,			"PR_NOT_CONNECTED_ERROR"},
+{PR_LOAD_LIBRARY_ERROR,				"PR_LOAD_LIBRARY_ERROR"},
+{PR_UNLOAD_LIBRARY_ERROR,			"PR_UNLOAD_LIBRARY_ERROR"},
+{PR_FIND_SYMBOL_ERROR,				"PR_FIND_SYMBOL_ERROR"},
+{PR_INSUFFICIENT_RESOURCES_ERROR,	"PR_INSUFFICIENT_RESOURCES_ERROR"},
+{PR_DIRECTORY_LOOKUP_ERROR,			"PR_DIRECTORY_LOOKUP_ERROR"},
+{PR_TPD_RANGE_ERROR,				"PR_TPD_RANGE_ERROR"},
+{PR_PROC_DESC_TABLE_FULL_ERROR,		"PR_PROC_DESC_TABLE_FULL_ERROR"},
+{PR_SYS_DESC_TABLE_FULL_ERROR,		"PR_SYS_DESC_TABLE_FULL_ERROR"},
+{PR_NOT_SOCKET_ERROR,				"PR_NOT_SOCKET_ERROR"},
+{PR_NOT_TCP_SOCKET_ERROR,			"PR_NOT_TCP_SOCKET_ERROR"},
+{PR_SOCKET_ADDRESS_IS_BOUND_ERROR,	"PR_SOCKET_ADDRESS_IS_BOUND_ERROR"},
+{PR_NO_ACCESS_RIGHTS_ERROR,			"PR_NO_ACCESS_RIGHTS_ERROR"},
+{PR_OPERATION_NOT_SUPPORTED_ERROR,	"PR_OPERATION_NOT_SUPPORTED_ERROR"},
+{PR_PROTOCOL_NOT_SUPPORTED_ERROR,	"PR_PROTOCOL_NOT_SUPPORTED_ERROR"},
+{PR_REMOTE_FILE_ERROR,				"PR_REMOTE_FILE_ERROR"},
+{PR_BUFFER_OVERFLOW_ERROR,			"PR_BUFFER_OVERFLOW_ERROR"},
+{PR_CONNECT_RESET_ERROR,			"PR_CONNECT_RESET_ERROR"},
+{PR_RANGE_ERROR,					"PR_RANGE_ERROR"},
+{PR_DEADLOCK_ERROR,					"PR_DEADLOCK_ERROR"},
+{PR_FILE_IS_LOCKED_ERROR,			"PR_FILE_IS_LOCKED_ERROR"},
+{PR_FILE_TOO_BIG_ERROR,				"PR_FILE_TOO_BIG_ERROR"},
+{PR_NO_DEVICE_SPACE_ERROR,			"PR_NO_DEVICE_SPACE_ERROR"},
+{PR_PIPE_ERROR,						"PR_PIPE_ERROR"},
+{PR_NO_SEEK_DEVICE_ERROR,			"PR_NO_SEEK_DEVICE_ERROR"},
+{PR_IS_DIRECTORY_ERROR,				"PR_IS_DIRECTORY_ERROR"},
+{PR_LOOP_ERROR,						"PR_LOOP_ERROR"},
+{PR_NAME_TOO_LONG_ERROR,			"PR_NAME_TOO_LONG_ERROR"},
+{PR_FILE_NOT_FOUND_ERROR,			"PR_FILE_NOT_FOUND_ERROR"},
+{PR_NOT_DIRECTORY_ERROR,			"PR_NOT_DIRECTORY_ERROR"},
+{PR_READ_ONLY_FILESYSTEM_ERROR,		"PR_READ_ONLY_FILESYSTEM_ERROR"},
+{PR_DIRECTORY_NOT_EMPTY_ERROR,		"PR_DIRECTORY_NOT_EMPTY_ERROR"},
+{PR_FILESYSTEM_MOUNTED_ERROR,		"PR_FILESYSTEM_MOUNTED_ERROR"},
+{PR_NOT_SAME_DEVICE_ERROR,			"PR_NOT_SAME_DEVICE_ERROR"},
+{PR_DIRECTORY_CORRUPTED_ERROR,		"PR_DIRECTORY_CORRUPTED_ERROR"},
+{PR_FILE_EXISTS_ERROR,				"PR_FILE_EXISTS_ERROR"},
+{PR_MAX_DIRECTORY_ENTRIES_ERROR,	"PR_MAX_DIRECTORY_ENTRIES_ERROR"},
+{PR_INVALID_DEVICE_STATE_ERROR,		"PR_INVALID_DEVICE_STATE_ERROR"},
+{PR_DEVICE_IS_LOCKED_ERROR,			"PR_DEVICE_IS_LOCKED_ERROR"},
+{PR_NO_MORE_FILES_ERROR,			"PR_NO_MORE_FILES_ERROR"},
+{PR_END_OF_FILE_ERROR,				"PR_END_OF_FILE_ERROR"},
+{PR_FILE_SEEK_ERROR,				"PR_FILE_SEEK_ERROR"},
+{PR_FILE_IS_BUSY_ERROR,				"PR_FILE_IS_BUSY_ERROR"},
+{PR_IN_PROGRESS_ERROR,				"PR_IN_PROGRESS_ERROR"},
+{PR_ALREADY_INITIATED_ERROR,		"PR_ALREADY_INITIATED_ERROR"},
+{PR_GROUP_EMPTY_ERROR,				"PR_GROUP_EMPTY_ERROR"},
+{PR_INVALID_STATE_ERROR,			"PR_INVALID_STATE_ERROR"},
+{PR_NETWORK_DOWN_ERROR,				"PR_NETWORK_DOWN_ERROR"},
+{PR_SOCKET_SHUTDOWN_ERROR,			"PR_SOCKET_SHUTDOWN_ERROR"},
+{PR_CONNECT_ABORTED_ERROR,			"PR_CONNECT_ABORTED_ERROR"},
+{PR_HOST_UNREACHABLE_ERROR,			"PR_HOST_UNREACHABLE_ERROR"}
+};
+
+int
+main(int argc, char **argv)
+{
+
+	int count, errnum;
+
+    /*
+     * -d           debug mode
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+	count = sizeof(errcodes)/sizeof(errcodes[0]);
+	printf("\nNumber of error codes = %d\n\n",count);
+	for (errnum = 0; errnum < count; errnum++) {
+		printf("%-40s = %d\n",errcodes[errnum].errname,
+						errcodes[errnum].errcode);
+	}
+
+	return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/errset.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/errset.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,186 @@
+/* -*- 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 security libraries.
+ *
+ * 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: errset.c
+**
+** Description: errset.c exercises the functions in prerror.c.
+** This code is a unit test of the prerror.c capability.
+**
+** Note: There's some fluff in here. The guts of the test
+** were plagerized from another test. So, sue me.
+**
+**
+*/
+#include "prerror.h"
+#include "plgetopt.h"
+#include "prlog.h"
+
+#include <stdio.h>
+#include <string.h>
+
+static int _debug_on = 0;
+
+struct errinfo {
+	PRErrorCode errcode;
+	char 		*errname;
+};
+
+struct errinfo errcodes[] = {
+{PR_OUT_OF_MEMORY_ERROR,			"PR_OUT_OF_MEMORY_ERROR"},
+{PR_UNKNOWN_ERROR, "An intentionally long error message text intended to force a delete of the current errorString buffer and get another one."},
+{PR_BAD_DESCRIPTOR_ERROR,			"PR_BAD_DESCRIPTOR_ERROR"},
+{PR_WOULD_BLOCK_ERROR,				"PR_WOULD_BLOCK_ERROR"},
+{PR_ACCESS_FAULT_ERROR,				"PR_ACCESS_FAULT_ERROR"},
+{PR_INVALID_METHOD_ERROR,			"PR_INVALID_METHOD_ERROR"},
+{PR_ILLEGAL_ACCESS_ERROR,			"PR_ILLEGAL_ACCESS_ERROR"},
+{PR_UNKNOWN_ERROR,					"PR_UNKNOWN_ERROR"},
+{PR_PENDING_INTERRUPT_ERROR,		"PR_PENDING_INTERRUPT_ERROR"},
+{PR_NOT_IMPLEMENTED_ERROR,			"PR_NOT_IMPLEMENTED_ERROR"},
+{PR_IO_ERROR,						"PR_IO_ERROR"},
+{PR_IO_TIMEOUT_ERROR,				"PR_IO_TIMEOUT_ERROR"},
+{PR_IO_PENDING_ERROR,				"PR_IO_PENDING_ERROR"},
+{PR_DIRECTORY_OPEN_ERROR,			"PR_DIRECTORY_OPEN_ERROR"},
+{PR_INVALID_ARGUMENT_ERROR,			"PR_INVALID_ARGUMENT_ERROR"},
+{PR_ADDRESS_NOT_AVAILABLE_ERROR,	"PR_ADDRESS_NOT_AVAILABLE_ERROR"},
+{PR_ADDRESS_NOT_SUPPORTED_ERROR,	"PR_ADDRESS_NOT_SUPPORTED_ERROR"},
+{PR_IS_CONNECTED_ERROR,				"PR_IS_CONNECTED_ERROR"},
+{PR_BAD_ADDRESS_ERROR,				"PR_BAD_ADDRESS_ERROR"},
+{PR_ADDRESS_IN_USE_ERROR,			"PR_ADDRESS_IN_USE_ERROR"},
+{PR_CONNECT_REFUSED_ERROR,			"PR_CONNECT_REFUSED_ERROR"},
+{PR_NETWORK_UNREACHABLE_ERROR,		"PR_NETWORK_UNREACHABLE_ERROR"},
+{PR_CONNECT_TIMEOUT_ERROR,			"PR_CONNECT_TIMEOUT_ERROR"},
+{PR_NOT_CONNECTED_ERROR,			"PR_NOT_CONNECTED_ERROR"},
+{PR_LOAD_LIBRARY_ERROR,				"PR_LOAD_LIBRARY_ERROR"},
+{PR_UNLOAD_LIBRARY_ERROR,			"PR_UNLOAD_LIBRARY_ERROR"},
+{PR_FIND_SYMBOL_ERROR,				"PR_FIND_SYMBOL_ERROR"},
+{PR_INSUFFICIENT_RESOURCES_ERROR,	"PR_INSUFFICIENT_RESOURCES_ERROR"},
+{PR_DIRECTORY_LOOKUP_ERROR,			"PR_DIRECTORY_LOOKUP_ERROR"},
+{PR_TPD_RANGE_ERROR,				"PR_TPD_RANGE_ERROR"},
+{PR_PROC_DESC_TABLE_FULL_ERROR,		"PR_PROC_DESC_TABLE_FULL_ERROR"},
+{PR_SYS_DESC_TABLE_FULL_ERROR,		"PR_SYS_DESC_TABLE_FULL_ERROR"},
+{PR_NOT_SOCKET_ERROR,				"PR_NOT_SOCKET_ERROR"},
+{PR_NOT_TCP_SOCKET_ERROR,			"PR_NOT_TCP_SOCKET_ERROR"},
+{PR_SOCKET_ADDRESS_IS_BOUND_ERROR,	"PR_SOCKET_ADDRESS_IS_BOUND_ERROR"},
+{PR_NO_ACCESS_RIGHTS_ERROR,			"PR_NO_ACCESS_RIGHTS_ERROR"},
+{PR_OPERATION_NOT_SUPPORTED_ERROR,	"PR_OPERATION_NOT_SUPPORTED_ERROR"},
+{PR_PROTOCOL_NOT_SUPPORTED_ERROR,	"PR_PROTOCOL_NOT_SUPPORTED_ERROR"},
+{PR_REMOTE_FILE_ERROR,				"PR_REMOTE_FILE_ERROR"},
+{PR_BUFFER_OVERFLOW_ERROR,			"PR_BUFFER_OVERFLOW_ERROR"},
+{PR_CONNECT_RESET_ERROR,			"PR_CONNECT_RESET_ERROR"},
+{PR_RANGE_ERROR,					"PR_RANGE_ERROR"},
+{PR_DEADLOCK_ERROR,					"PR_DEADLOCK_ERROR"},
+{PR_FILE_IS_LOCKED_ERROR,			"PR_FILE_IS_LOCKED_ERROR"},
+{PR_FILE_TOO_BIG_ERROR,				"PR_FILE_TOO_BIG_ERROR"},
+{PR_NO_DEVICE_SPACE_ERROR,			"PR_NO_DEVICE_SPACE_ERROR"},
+{PR_PIPE_ERROR,						"PR_PIPE_ERROR"},
+{PR_NO_SEEK_DEVICE_ERROR,			"PR_NO_SEEK_DEVICE_ERROR"},
+{PR_IS_DIRECTORY_ERROR,				"PR_IS_DIRECTORY_ERROR"},
+{PR_LOOP_ERROR,						"PR_LOOP_ERROR"},
+{PR_NAME_TOO_LONG_ERROR,			"PR_NAME_TOO_LONG_ERROR"},
+{PR_FILE_NOT_FOUND_ERROR,			"PR_FILE_NOT_FOUND_ERROR"},
+{PR_NOT_DIRECTORY_ERROR,			"PR_NOT_DIRECTORY_ERROR"},
+{PR_READ_ONLY_FILESYSTEM_ERROR,		"PR_READ_ONLY_FILESYSTEM_ERROR"},
+{PR_DIRECTORY_NOT_EMPTY_ERROR,		"PR_DIRECTORY_NOT_EMPTY_ERROR"},
+{PR_FILESYSTEM_MOUNTED_ERROR,		"PR_FILESYSTEM_MOUNTED_ERROR"},
+{PR_NOT_SAME_DEVICE_ERROR,			"PR_NOT_SAME_DEVICE_ERROR"},
+{PR_DIRECTORY_CORRUPTED_ERROR,		"PR_DIRECTORY_CORRUPTED_ERROR"},
+{PR_FILE_EXISTS_ERROR,				"PR_FILE_EXISTS_ERROR"},
+{PR_MAX_DIRECTORY_ENTRIES_ERROR,	"PR_MAX_DIRECTORY_ENTRIES_ERROR"},
+{PR_INVALID_DEVICE_STATE_ERROR,		"PR_INVALID_DEVICE_STATE_ERROR"},
+{PR_DEVICE_IS_LOCKED_ERROR,			"PR_DEVICE_IS_LOCKED_ERROR"},
+{PR_NO_MORE_FILES_ERROR,			"PR_NO_MORE_FILES_ERROR"},
+{PR_END_OF_FILE_ERROR,				"PR_END_OF_FILE_ERROR"},
+{PR_FILE_SEEK_ERROR,				"PR_FILE_SEEK_ERROR"},
+{PR_FILE_IS_BUSY_ERROR,				"PR_FILE_IS_BUSY_ERROR"},
+{PR_IN_PROGRESS_ERROR,				"PR_IN_PROGRESS_ERROR"},
+{PR_ALREADY_INITIATED_ERROR,		"PR_ALREADY_INITIATED_ERROR"},
+{PR_GROUP_EMPTY_ERROR,				"PR_GROUP_EMPTY_ERROR"},
+{PR_INVALID_STATE_ERROR,			"PR_INVALID_STATE_ERROR"},
+{PR_NETWORK_DOWN_ERROR,				"PR_NETWORK_DOWN_ERROR"},
+{PR_SOCKET_SHUTDOWN_ERROR,			"PR_SOCKET_SHUTDOWN_ERROR"},
+{PR_CONNECT_ABORTED_ERROR,			"PR_CONNECT_ABORTED_ERROR"},
+{PR_HOST_UNREACHABLE_ERROR,			"PR_HOST_UNREACHABLE_ERROR"}
+};
+
+int
+main(int argc, char **argv)
+{
+
+	int count, errnum;
+
+    /*
+     * -d           debug mode
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+	count = sizeof(errcodes)/sizeof(errcodes[0]);
+	printf("\nNumber of error codes = %d\n\n",count);
+	for (errnum = 0; errnum < count; errnum++) {
+        PRInt32 len1, len2, err;
+        char    msg[256];
+
+        PR_SetError( errnum, -5 );
+        err = PR_GetError();
+        PR_ASSERT( err == errnum );
+        err = PR_GetOSError();
+        PR_ASSERT( err == -5 );
+        PR_SetErrorText( strlen(errcodes[errnum].errname), errcodes[errnum].errname );
+        len1 = PR_GetErrorTextLength();
+        len2 = PR_GetErrorText( msg );
+        PR_ASSERT( len1 == len2 );
+        printf("%5.5d -- %s\n", errnum, msg );
+    }
+
+	return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/exit.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/exit.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,137 @@
+/* -*- 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 "prio.h"
+#include "prprf.h"
+#include "prinit.h"
+#include "prthread.h"
+#include "prproces.h"
+#include "prinrval.h"
+
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+static PRInt32 dally = 0;
+static PRFileDesc *err = NULL;
+static PRBool verbose = PR_FALSE, force = PR_FALSE;
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: [-t s] [-h]\n");
+    PR_fprintf(err, "\t-d   Verbose output              (default: FALSE)\n");
+    PR_fprintf(err, "\t-x   Forced termination          (default: FALSE)\n");
+    PR_fprintf(err, "\t-t   Time for thread to block    (default: 10 seconds)\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+static void Dull(void *arg)
+{
+    PR_Sleep(PR_SecondsToInterval(dally));
+    if (verbose && force)
+        PR_fprintf(err, "If you see this, the test failed\n");
+}  /* Dull */
+
+static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv)
+{
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "ht:dx");
+
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* verbosity */
+            verbose = PR_TRUE;
+            break;
+        case 'x':  /* force exit */
+            force = PR_TRUE;
+            break;
+        case 't':  /* seconds to dally in child */
+            dally = atoi(opt->value);
+            break;
+        case 'h':  /* user wants some guidance */
+        default:
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (0 == dally) dally = 10;
+
+	/*
+	 * Create LOCAL and GLOBAL threads
+	 */
+    (void)PR_CreateThread(
+        PR_USER_THREAD, Dull, NULL, PR_PRIORITY_NORMAL,
+			  PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+
+    (void)PR_CreateThread(
+        PR_USER_THREAD, Dull, NULL, PR_PRIORITY_NORMAL,
+			  PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+
+    if (verbose)
+        PR_fprintf(
+            err, "Main is exiting now. Program should exit %s.\n",
+            (force) ? "immediately" : "after child dally time");
+
+    if (force)
+    {
+        PR_ProcessExit(0);
+        if (verbose)
+        {
+            PR_fprintf(err, "You should not have gotten here.\n");
+            return 1;
+        }
+    }
+    return 0;
+        
+}
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/fdcach.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/fdcach.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,259 @@
+/* -*- 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 ***** */
+
+/*
+ * File: fdcach.c
+ * Description:
+ *   This test verifies that the fd cache and stack are working
+ *   correctly.
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * Define ORDER_PRESERVED if the implementation of PR_SetFDCacheSize
+ * preserves the ordering of the fd's when moving them between the
+ * cache and the stack.
+ */
+#define ORDER_PRESERVED 1
+
+/*
+ * NUM_FDS must be <= FD_CACHE_SIZE.
+ */
+#define FD_CACHE_SIZE 1024
+#define NUM_FDS 20
+
+int main(int argc, char **argv)
+{
+    int i;
+    PRFileDesc *fds[NUM_FDS];
+    PRFileDesc *savefds[NUM_FDS];
+    int numfds = sizeof(fds)/sizeof(fds[0]);
+
+    /*
+     * Switch between cache and stack when they are empty.
+     * Then start with the fd cache.
+     */
+    PR_SetFDCacheSize(0, FD_CACHE_SIZE);
+    PR_SetFDCacheSize(0, 0);
+    PR_SetFDCacheSize(0, FD_CACHE_SIZE);
+
+    /* Add some fd's to the fd cache. */
+    for (i = 0; i < numfds; i++) {
+        savefds[i] = PR_NewTCPSocket();
+        if (NULL == savefds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+    }
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    /*
+     * Create some fd's.  These fd's should come from
+     * the fd cache.  Verify the FIFO ordering of the fd
+     * cache.
+     */
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+        if (fds[i] != savefds[i]) {
+            fprintf(stderr, "fd cache malfunctioned\n");
+            exit(1);
+        }
+    }
+    /* Put the fd's back to the fd cache. */
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    /* Switch to the fd stack. */
+    PR_SetFDCacheSize(0, 0);
+
+    /*
+     * Create some fd's.  These fd's should come from
+     * the fd stack.
+     */
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+#ifdef ORDER_PRESERVED
+        if (fds[i] != savefds[numfds-1-i]) {
+            fprintf(stderr, "fd stack malfunctioned\n");
+            exit(1);
+        }
+#else
+        savefds[numfds-1-i] = fds[i];
+#endif
+    }
+    /* Put the fd's back to the fd stack. */
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    /*
+     * Now create some fd's and verify the LIFO ordering of
+     * the fd stack.
+     */
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+        if (fds[i] != savefds[numfds-1-i]) {
+            fprintf(stderr, "fd stack malfunctioned\n");
+            exit(1);
+        }
+    }
+    /* Put the fd's back to the fd stack. */
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    /* Switch to the fd cache. */
+    PR_SetFDCacheSize(0, FD_CACHE_SIZE);
+
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+#ifdef ORDER_PRESERVED
+        if (fds[i] != savefds[i]) {
+            fprintf(stderr, "fd cache malfunctioned\n");
+            exit(1);
+        }
+#else
+        savefds[i] = fds[i];
+#endif
+    }
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+        if (fds[i] != savefds[i]) {
+            fprintf(stderr, "fd cache malfunctioned\n");
+            exit(1);
+        }
+    }
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    /* Switch to the fd stack. */
+    PR_SetFDCacheSize(0, 0);
+
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+#ifdef ORDER_PRESERVED
+        if (fds[i] != savefds[numfds-1-i]) {
+            fprintf(stderr, "fd stack malfunctioned\n");
+            exit(1);
+        }
+#else
+        savefds[numfds-1-i];
+#endif
+    }
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    for (i = 0; i < numfds; i++) {
+        fds[i] = PR_NewTCPSocket();
+        if (NULL == fds[i]) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+        if (fds[i] != savefds[numfds-1-i]) {
+            fprintf(stderr, "fd stack malfunctioned\n");
+            exit(1);
+        }
+    }
+    for (i = 0; i < numfds; i++) {
+        if (PR_Close(savefds[i]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        } 
+    }
+
+    PR_Cleanup();
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/fileio.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/fileio.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,250 @@
+/* -*- 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: fileio.c
+**
+** Description: Program to copy one file to another. 
+**
+** Modification History:
+** 14-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.
+** 12-June-97 Revert to return code 0 and 1, remove debug option (obsolete).
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+#include "prinit.h"
+#include "prthread.h"
+#include "prlock.h"
+#include "prcvar.h"
+#include "prmon.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prlog.h"
+
+#include <stdio.h>
+
+#ifdef XP_MAC
+#include "prsem.h"
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#else
+#include "obsolete/prsem.h"
+#endif
+
+
+#define TBSIZE 1024
+
+static PRUint8 tbuf[TBSIZE];
+
+static PRFileDesc *t1, *t2;
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+static void InitialSetup(void)
+{
+	PRUintn	i;
+	PRInt32 nWritten, rv;
+	
+	t1 = PR_Open("t1.tmp", PR_CREATE_FILE | PR_RDWR, 0);
+	PR_ASSERT(t1 != NULL);	
+	
+	for (i=0; i<TBSIZE; i++)
+		tbuf[i] = i;
+		
+	nWritten = PR_Write((PRFileDesc*)t1, tbuf, TBSIZE);
+	PR_ASSERT(nWritten == TBSIZE);	
+   		
+	rv = PR_Seek(t1,0,PR_SEEK_SET);
+	PR_ASSERT(rv == 0);	
+
+   	t2 = PR_Open("t2.tmp", PR_CREATE_FILE | PR_RDWR, 0);
+	PR_ASSERT(t2 != NULL);	
+}
+
+
+static void VerifyAndCleanup(void)
+{
+	PRUintn	i;
+	PRInt32 nRead, rv;
+	
+	for (i=0; i<TBSIZE; i++)
+		tbuf[i] = 0;
+		
+	rv = PR_Seek(t2,0,PR_SEEK_SET);
+	PR_ASSERT(rv == 0);	
+
+	nRead = PR_Read((PRFileDesc*)t2, tbuf, TBSIZE);
+	PR_ASSERT(nRead == TBSIZE);	
+   		
+	for (i=0; i<TBSIZE; i++)
+		if (tbuf[i] != (PRUint8)i) {
+			if (debug_mode) printf("data mismatch for index= %d \n", i);
+			else failed_already=1;
+		}
+   	PR_Close(t1);
+   	PR_Close(t2);
+
+   	PR_Delete("t1.tmp");
+   	PR_Delete("t2.tmp");
+
+    if (debug_mode) printf("fileio test passed\n");
+}
+
+
+/*------------------ Following is the real test program ---------*/
+/*
+	Program to copy one file to another.  Two temporary files get
+	created.  First one gets written in one write call.  Then,
+	a reader thread reads from this file into a double buffer.
+	The writer thread writes from double buffer into the other
+	temporary file.  The second temporary file gets verified
+	for accurate data.
+*/
+
+PRSemaphore	*emptyBufs;	/* number of empty buffers */
+PRSemaphore *fullBufs;	/* number of buffers that are full */
+
+#define BSIZE	100
+
+struct {
+	char data[BSIZE];
+	PRUintn nbytes;		/* number of bytes in this buffer */
+} buf[2];
+
+static void PR_CALLBACK reader(void *arg)
+{
+	PRUintn	i = 0;
+	PRInt32	nbytes;
+	
+	do {
+		(void) PR_WaitSem(emptyBufs);
+		nbytes = PR_Read((PRFileDesc*)arg, buf[i].data, BSIZE);
+		if (nbytes >= 0) {
+			buf[i].nbytes = nbytes;
+			PR_PostSem(fullBufs);
+			i = (i + 1) % 2;
+		}
+	} while (nbytes > 0);
+}
+
+static void PR_CALLBACK writer(void *arg)
+{
+	PRUintn	i = 0;
+	PRInt32	nbytes;
+	
+	do {
+		(void) PR_WaitSem(fullBufs);
+		nbytes = buf[i].nbytes;
+		if (nbytes > 0) {
+			nbytes = PR_Write((PRFileDesc*)arg, buf[i].data, nbytes);
+			PR_PostSem(emptyBufs);
+			i = (i + 1) % 2;
+		}
+	} while (nbytes > 0);
+}
+
+int main(int argc, char **argv)
+{
+	PRThread *r, *w;
+
+
+	PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("fileio.log");
+	debug_mode = 1;
+#endif
+
+    emptyBufs = PR_NewSem(2);	/* two empty buffers */
+
+    fullBufs = PR_NewSem(0);	/* zero full buffers */
+
+	/* Create initial temp file setup */
+	InitialSetup();
+	
+	/* create the reader thread */
+	
+	r = PR_CreateThread(PR_USER_THREAD,
+				      reader, t1, 
+				      PR_PRIORITY_NORMAL,
+				      PR_LOCAL_THREAD,
+    				  PR_JOINABLE_THREAD,
+				      0);
+
+	w = PR_CreateThread(PR_USER_THREAD,
+				      writer, t2, 
+				      PR_PRIORITY_NORMAL,
+                      PR_LOCAL_THREAD,
+                      PR_JOINABLE_THREAD,
+                      0);
+
+    /* Do the joining for both threads */
+    (void) PR_JoinThread(r);
+    (void) PR_JoinThread(w);
+
+    /* Do the verification and clean up */
+    VerifyAndCleanup();
+
+    PR_DestroySem(emptyBufs);
+    PR_DestroySem(fullBufs);
+
+    PR_Cleanup();
+
+    if(failed_already)
+    {
+        printf("Fail\n");
+        return 1;
+    }
+    else
+    {
+        printf("PASS\n");
+        return 0;
+    }
+
+
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/foreign.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/foreign.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,414 @@
+/* -*- 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:        foreign.c
+** Description: Testing various functions w/ foreign threads
+**
+**      We create a thread and get it to call exactly one runtime function.
+**      The thread is allowed to be created by some other environment that
+**      NSPR, but it does not announce itself to the runtime prior to calling
+**      in.
+**
+**      The goal: try to survive.
+**      
+*/
+
+#include "prcvar.h"
+#include "prenv.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmem.h"
+#include "prthread.h"
+#include "prtypes.h"
+#include "prprf.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static enum {
+    thread_nspr, thread_pthread, thread_uithread, thread_sproc, thread_win32
+} thread_provider;
+
+typedef void (*StartFn)(void*);
+typedef struct StartObject
+{
+    StartFn start;
+    void *arg;
+} StartObject;
+
+static PRFileDesc *output;
+
+static int _debug_on = 0;
+
+#define DEFAULT_THREAD_COUNT	10
+
+#define DPRINTF(arg)	if (_debug_on) PR_fprintf arg
+
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include <pthread.h>
+#include "md/_pth.h"
+static void *pthread_start(void *arg)
+{
+    StartFn start = ((StartObject*)arg)->start;
+    void *data = ((StartObject*)arg)->arg;
+    PR_Free(arg);
+    start(data);
+    return NULL;
+}  /* pthread_start */
+#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
+
+#if defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)
+#include <thread.h>
+static void *uithread_start(void *arg)
+{
+    StartFn start = ((StartObject*)arg)->start;
+    void *data = ((StartObject*)arg)->arg;
+    PR_Free(arg);
+    start(data);
+    return NULL;
+}  /* uithread_start */
+#endif /* defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) */
+
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+#include <sys/types.h>
+#include <sys/prctl.h>
+static void sproc_start(void *arg, PRSize size)
+{
+    StartObject *so = (StartObject*)arg;
+    StartFn start = so->start;
+    void *data = so->arg;
+    PR_Free(so);
+    start(data);
+}  /* sproc_start */
+#endif  /* defined(IRIX) && !defined(_PR_PTHREADS) */
+
+#if defined(WIN32)
+#include <process.h>  /* for _beginthreadex() */
+
+static PRUintn __stdcall windows_start(void *arg)
+{
+    StartObject *so = (StartObject*)arg;
+    StartFn start = so->start;
+    void *data = so->arg;
+    PR_Free(so);
+    start(data);
+    return 0;
+}  /* windows_start */
+#endif /* defined(WIN32) */
+
+static PRStatus CreateThread(StartFn start, void *arg)
+{
+    PRStatus rv;
+
+    switch (thread_provider)
+    {
+    case thread_nspr:
+        {
+            PRThread *thread = PR_CreateThread(
+                PR_USER_THREAD, start, arg,
+                PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+                PR_UNJOINABLE_THREAD, 0);
+            rv = (NULL == thread) ? PR_FAILURE : PR_SUCCESS;
+        }
+        break;
+    case thread_pthread:
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+        {
+            int rv;
+            pthread_t id;
+            pthread_attr_t tattr;
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+
+            rv = _PT_PTHREAD_ATTR_INIT(&tattr);
+            PR_ASSERT(0 == rv);
+
+            rv = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
+            PR_ASSERT(0 == rv);
+
+            rv = pthread_attr_setstacksize(&tattr, 64 * 1024);
+            PR_ASSERT(0 == rv);
+
+            rv = _PT_PTHREAD_CREATE(&id, tattr, pthread_start, start_object);
+            (void)_PT_PTHREAD_ATTR_DESTROY(&tattr);
+            return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+        break;
+#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
+
+    case thread_uithread:
+#if defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)
+        {
+            int rv;
+            thread_t id;
+            long flags;
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+
+            flags = THR_DETACHED;
+
+            rv = thr_create(NULL, NULL, uithread_start, start_object, flags, &id);
+            return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+        break;
+#endif /* defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) */
+
+    case thread_sproc:
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+        {
+            PRInt32 pid;
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+            pid = sprocsp(
+                sproc_start, PR_SALL, start_object, NULL, 64 * 1024);
+            rv = (0 < pid) ? PR_SUCCESS : PR_FAILURE;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+#endif  /* defined(IRIX) && !defined(_PR_PTHREADS) */
+        break;
+    case thread_win32:
+#if defined(WIN32)
+        {
+            void *th;
+            PRUintn id;       
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+            th = (void*)_beginthreadex(
+                NULL, /* LPSECURITY_ATTRIBUTES - pointer to thread security attributes */  
+                0U, /* DWORD - initial thread stack size, in bytes */
+                windows_start, /* LPTHREAD_START_ROUTINE - pointer to thread function */
+                start_object, /* LPVOID - argument for new thread */
+                0U, /*DWORD dwCreationFlags - creation flags */
+                &id /* LPDWORD - pointer to returned thread identifier */ );
+
+            rv = (NULL == th) ? PR_FAILURE : PR_SUCCESS;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+#endif
+        break;
+    default:
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+    }
+    return rv;
+}  /* CreateThread */
+
+static void PR_CALLBACK lazyEntry(void *arg)
+{
+    PR_ASSERT(NULL == arg);
+}  /* lazyEntry */
+
+
+static void OneShot(void *arg)
+{
+    PRUintn pdkey;
+    PRLock *lock;
+    PRFileDesc *fd;
+    PRDir *dir;
+    PRFileDesc *pair[2];
+    PRIntn test = (PRIntn)arg;
+
+	for (test = 0; test < 12; ++test) {
+
+    switch (test)
+    {
+        case 0:
+            lock = PR_NewLock(); 
+			DPRINTF((output,"Thread[0x%x] called PR_NewLock\n",
+			PR_GetCurrentThread()));
+            PR_DestroyLock(lock);
+            break;
+            
+        case 1:
+            (void)PR_SecondsToInterval(1);
+			DPRINTF((output,"Thread[0x%x] called PR_SecondsToInterval\n",
+			PR_GetCurrentThread()));
+            break;
+            
+        case 2: (void)PR_CreateThread(
+            PR_USER_THREAD, lazyEntry, NULL, PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); 
+			DPRINTF((output,"Thread[0x%x] called PR_CreateThread\n",
+			PR_GetCurrentThread()));
+            break;
+            
+        case 3:
+            fd = PR_Open("foreign.tmp", PR_CREATE_FILE | PR_RDWR, 0666); 
+			DPRINTF((output,"Thread[0x%x] called PR_Open\n",
+			PR_GetCurrentThread()));
+            PR_Close(fd);
+            break;
+            
+        case 4:
+            fd = PR_NewUDPSocket(); 
+			DPRINTF((output,"Thread[0x%x] called PR_NewUDPSocket\n",
+			PR_GetCurrentThread()));
+            PR_Close(fd);
+            break;
+            
+        case 5:
+            fd = PR_NewTCPSocket(); 
+			DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocket\n",
+			PR_GetCurrentThread()));
+            PR_Close(fd);
+            break;
+            
+        case 6:
+            dir = PR_OpenDir("/tmp/"); 
+			DPRINTF((output,"Thread[0x%x] called PR_OpenDir\n",
+			PR_GetCurrentThread()));
+            PR_CloseDir(dir);
+            break;
+            
+        case 7:
+            (void)PR_NewThreadPrivateIndex(&pdkey, NULL);
+			DPRINTF((output,"Thread[0x%x] called PR_NewThreadPrivateIndex\n",
+			PR_GetCurrentThread()));
+            break;
+        
+        case 8:
+            (void)PR_GetEnv("PATH");
+			DPRINTF((output,"Thread[0x%x] called PR_GetEnv\n",
+			PR_GetCurrentThread()));
+            break;
+            
+        case 9:
+            (void)PR_NewTCPSocketPair(pair);
+			DPRINTF((output,"Thread[0x%x] called PR_NewTCPSocketPair\n",
+			PR_GetCurrentThread()));
+            PR_Close(pair[0]);
+            PR_Close(pair[1]);
+            break;
+            
+        case 10:
+            PR_SetConcurrency(2);
+			DPRINTF((output,"Thread[0x%x] called PR_SetConcurrency\n",
+			PR_GetCurrentThread()));
+            break;
+
+        case 11:
+            PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_HIGH);
+			DPRINTF((output,"Thread[0x%x] called PR_SetThreadPriority\n",
+			PR_GetCurrentThread()));
+            break;
+            
+        default: 
+            break;
+    } /* switch() */
+	}
+}  /* OneShot */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+	PRInt32	thread_cnt = DEFAULT_THREAD_COUNT;
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:");
+
+#if defined(WIN32)
+	thread_provider = thread_win32;
+#elif defined(_PR_PTHREADS)
+	thread_provider = thread_pthread;
+#elif defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)
+	thread_provider = thread_uithread;
+#elif defined(IRIX)
+	thread_provider = thread_sproc;
+#else
+    thread_provider = thread_nspr;
+#endif
+
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			_debug_on = 1;
+            break;
+        case 't':  /* thread count */
+            thread_cnt = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+	PR_SetConcurrency(2);
+
+	output = PR_GetSpecialFD(PR_StandardOutput);
+
+    while (thread_cnt-- > 0)
+    {
+        rv = CreateThread(OneShot, (void*)thread_cnt);
+        PR_ASSERT(PR_SUCCESS == rv);
+        PR_Sleep(PR_MillisecondsToInterval(5));
+    }
+    PR_Sleep(PR_SecondsToInterval(3));
+    return (PR_SUCCESS == PR_Cleanup()) ? 0 : 1;
+}  /* main */
+
+/* foreign.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/forktest.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/forktest.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,346 @@
+/* -*- 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: forktest.c
+**
+** Description: UNIX test for fork functions.
+**
+** Modification History:
+** 15-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.
+** 12-June-97 AGarcic - Revert to return code 0 and 1, remove debug option (obsolete).
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+PRIntn failed_already=0;
+
+#ifdef XP_UNIX
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+
+static char *message = "Hello world!";
+
+static void
+ClientThreadFunc(void *arg)
+{
+    PRNetAddr addr;
+    PRFileDesc *sock = NULL;
+    PRInt32 tmp = (PRInt32)arg;
+
+    /*
+     * Make sure the PR_Accept call will block
+     */
+
+    printf("Wait one second before connect\n");
+    fflush(stdout);
+    PR_Sleep(PR_SecondsToInterval(1));
+
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = 0;
+    if ((sock = PR_NewTCPSocket()) == NULL) {
+        fprintf(stderr, "failed to create TCP socket: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    if (PR_Bind(sock, &addr) != PR_SUCCESS) {
+        fprintf(stderr, "PR_Bind failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+    addr.inet.port = PR_htons((PRInt16)tmp);
+    printf("Connecting to port %hu\n", PR_ntohs(addr.inet.port));
+    fflush(stdout);
+    if (PR_Connect(sock, &addr, PR_SecondsToInterval(5)) !=
+        PR_SUCCESS) {
+        fprintf(stderr, "PR_Connect failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    printf("Writing message \"%s\"\n", message);
+    fflush(stdout);
+    if (PR_Send(sock, message, strlen(message) + 1, 0, PR_INTERVAL_NO_TIMEOUT) ==
+        -1) {
+        fprintf(stderr, "PR_Send failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+finish:
+    if (sock) {
+        PR_Close(sock);
+    }
+    return;
+}
+
+/*
+ * DoIO --
+ *     This function creates a thread that acts as a client and itself.
+ *     acts as a server.  Then it joins the client thread.
+ */
+static void
+DoIO(void)
+{
+    PRThread *clientThread;
+    PRFileDesc *listenSock = NULL;
+    PRFileDesc *sock = NULL;
+    PRNetAddr addr;
+    PRInt32 nBytes;
+    char buf[128];
+
+    listenSock = PR_NewTCPSocket();
+    if (!listenSock) {
+        fprintf(stderr, "failed to create a TCP socket: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = 0;
+    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "failed to bind socket: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "failed to get socket port number: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    clientThread = PR_CreateThread( PR_USER_THREAD, ClientThreadFunc,
+        (void *) PR_ntohs(addr.inet.port), PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+        PR_JOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+        fprintf(stderr, "Cannot create client thread: (%d, %d)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already = 1;
+        goto finish;
+    }
+    printf("Accepting connection at port %hu\n", PR_ntohs(addr.inet.port));
+    fflush(stdout);
+    sock = PR_Accept(listenSock, &addr, PR_SecondsToInterval(5));
+    if (!sock) {
+        fprintf(stderr, "PR_Accept failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+    nBytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nBytes == -1) {
+        fprintf(stderr, "PR_Recv failed: error code %d\n",
+            PR_GetError());
+        failed_already = 1;
+        goto finish;
+    }
+
+    /*
+     * Make sure it has proper null byte to mark end of string 
+     */
+
+    buf[sizeof(buf) - 1] = '\0';
+    printf("Received \"%s\" from the client\n", buf);
+    fflush(stdout);
+    if (!strcmp(buf, message)) {
+        PR_JoinThread(clientThread);
+
+        printf("The message is received correctly\n");
+        fflush(stdout);
+    } else {
+        fprintf(stderr, "The message should be \"%s\"\n",
+            message);
+        failed_already = 1;
+    }
+
+finish:
+    if (listenSock) {
+        PR_Close(listenSock);
+    }
+    if (sock) {
+        PR_Close(sock);
+    }
+    return;
+}
+
+#ifdef _PR_DCETHREADS
+
+#include <syscall.h>
+
+pid_t PR_UnixFork1(void)
+{
+    pid_t parent = getpid();
+    int rv = syscall(SYS_fork);
+
+    if (rv == -1) {
+        return (pid_t) -1;
+    } else {
+        /* For each process, rv is the pid of the other process */
+        if (rv == parent) {
+            /* the child */
+            return 0;
+        } else {
+            /* the parent */
+            return rv;
+        }
+    }
+}
+
+#elif defined(SOLARIS)
+
+/*
+ * It seems like that in Solaris 2.4 one must call fork1() if the
+ * the child process is going to use thread functions.  Solaris 2.5
+ * doesn't have this problem. Calling fork() also works. 
+ */
+
+pid_t PR_UnixFork1(void)
+{
+    return fork1();
+}
+
+#else
+
+pid_t PR_UnixFork1(void)
+{
+    return fork();
+}
+
+#endif  /* PR_DCETHREADS */
+
+int main(
+int     argc,
+char   *argv[]
+)
+{
+    pid_t pid;
+	int rv;
+
+    /* main test program */
+
+    DoIO();
+
+    pid = PR_UnixFork1();
+
+    if (pid  == (pid_t) -1) {
+        fprintf(stderr, "Fork failed: errno %d\n", errno);
+        failed_already=1;
+        return 1;
+    } else if (pid > 0) {
+        int childStatus;
+
+        printf("Fork succeeded.  Parent process continues.\n");
+        DoIO();
+        if ((rv = waitpid(pid, &childStatus, 0)) != pid) {
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+			/*
+			 * nspr may handle SIGCLD signal
+			 */
+			if ((rv < 0) && (errno == ECHILD)) {
+			} else 
+#endif
+			{
+				fprintf(stderr, "waitpid failed: %d\n", errno);
+				failed_already = 1;
+			}
+        } else if (!WIFEXITED(childStatus)
+                || WEXITSTATUS(childStatus) != 0) {
+            failed_already = 1;
+        }
+        printf("Parent process exits.\n");
+        if (!failed_already) {
+            printf("PASSED\n");
+        } else {
+            printf("FAILED\n");
+        }
+        return failed_already;
+    } else {
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+		extern void _PR_IRIX_CHILD_PROCESS(void);
+		_PR_IRIX_CHILD_PROCESS();
+#endif
+        printf("Fork succeeded.  Child process continues.\n");
+        DoIO();
+        printf("Child process exits.\n");
+        return failed_already;
+    }
+}
+
+#else  /* XP_UNIX */
+
+int main(    int     argc,
+char   *argv[]
+)
+{
+
+    printf("The fork test is applicable to Unix only.\n");
+    return 0;
+
+}
+
+#endif  /* XP_UNIX */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/formattm.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/formattm.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,59 @@
+/* -*- 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) 2003
+ * 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 ***** */
+
+/* A test program for PR_FormatTime and PR_FormatTimeUSEnglish */
+
+#include "prtime.h"
+
+#include <stdio.h>
+
+int main()
+{
+    char buffer[256];
+    PRTime now;
+    PRExplodedTime tod;
+
+    now = PR_Now();
+    PR_ExplodeTime(now, PR_LocalTimeParameters, &tod);
+    (void)PR_FormatTime(buffer, sizeof(buffer),
+        "%a %b %d %H:%M:%S %Z %Y", &tod);
+    printf("%s\n", buffer);
+    (void)PR_FormatTimeUSEnglish(buffer, sizeof(buffer),
+        "%a %b %d %H:%M:%S %Z %Y", &tod);
+    printf("%s\n", buffer);
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/freeif.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/freeif.c	Mon Dec 18 10:53:47 2006
@@ -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) 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 ***** */
+
+/*
+ * A test to see if the macros PR_DELETE and PR_FREEIF are
+ * properly defined.  (See Bugzilla bug #39110.)
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static void Noop(void) { }
+
+static void Fail(void)
+{
+    printf("FAIL\n");
+    exit(1);
+}
+
+int main()
+{
+    int foo = 1;
+    char *ptr = NULL;
+
+    /* this fails to compile with the old definition of PR_DELETE */
+    if (foo)
+        PR_DELETE(ptr);
+    else
+        Noop();
+
+    /* this nests incorrectly with the old definition of PR_FREEIF */
+    if (foo)
+        PR_FREEIF(ptr);
+    else
+        Fail();
+
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/fsync.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/fsync.c	Mon Dec 18 10:53:47 2006
@@ -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 "prio.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prinrval.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+static PRFileDesc *err = NULL;
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: [-S] [-K <n>] [-h] <filename>\n");
+    PR_fprintf(err, "\t-c   Nuber of iterations     (default: 10)\n");
+    PR_fprintf(err, "\t-S   Sync the file           (default: FALSE)\n");
+    PR_fprintf(err, "\t-K   Size of file (K bytes)  (default: 10)\n");
+    PR_fprintf(err, "\t     Name of file to write   (default: /usr/tmp/sync.dat)\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    PLOptStatus os;
+    PRUint8 *buffer;
+    PRFileDesc *file = NULL;
+    const char *filename = "sync.dat";
+    PRUint32 index, loops, iterations = 10, filesize = 10;
+    PRIntn flags = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hSK:c:");
+    PRIntervalTime time, total = 0, shortest = 0x7fffffff, longest = 0;
+
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:       /* Name of file to create */
+            filename = opt->value;
+            break;
+        case 'S':       /* Use sych option on file */
+            flags |= PR_SYNC;
+            break;
+        case 'K':       /* Size of file to write */
+            filesize = atoi(opt->value);
+            break;
+        case 'c':       /* Number of iterations */
+            iterations = atoi(opt->value);
+            break;
+        case 'h':       /* user wants some guidance */
+        default:        /* user needs some guidance */
+            Help();     /* so give him an earful */
+            return 2;   /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    file = PR_Open(filename, flags, 0666);
+    if (NULL == file)
+    {
+        PL_FPrintError(err, "Failed to open file");
+        return 1;
+    }
+
+    buffer = (PRUint8*)PR_CALLOC(1024);
+    if (NULL == buffer)
+    {
+        PL_FPrintError(err, "Cannot allocate buffer");
+        return 1;
+    }
+
+    for (index = 0; index < sizeof(buffer); ++index)
+        buffer[index] = (PRUint8)index;
+
+    for (loops = 0; loops < iterations; ++loops)
+    {
+        time = PR_IntervalNow();
+        for (index = 0; index < filesize; ++index)
+        {
+            PR_Write(file, buffer, 1024);
+        }
+        time = (PR_IntervalNow() - time);
+
+        total += time;
+        if (time < shortest) shortest = time;
+        else if (time > longest) longest = time;
+        if (0 != PR_Seek(file, 0, PR_SEEK_SET))
+        {
+           PL_FPrintError(err, "Rewinding file");
+           return 1;
+        }
+    }
+
+    total = total / iterations;
+    PR_fprintf(
+        err, "%u iterations over a %u kbyte %sfile: %u [%u] %u\n",
+        iterations, filesize, ((flags & PR_SYNC) ? "SYNCH'd " : ""),
+        PR_IntervalToMicroseconds(shortest),
+        PR_IntervalToMicroseconds(total),
+        PR_IntervalToMicroseconds(longest));
+
+    PR_DELETE(buffer);
+    rv = PR_Close(file);
+    if (PR_SUCCESS != rv)
+    {
+        PL_FPrintError(err, "Closing file failed");
+        return 1;
+    }
+    rv = PR_Delete(filename);
+    if (PR_SUCCESS != rv)
+    {
+        PL_FPrintError(err, "Deleting file failed");
+        return 1;
+    }
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/getai.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/getai.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,64 @@
+/* -*- 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) 2003
+ * 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 "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+    PRAddrInfo *ai;
+    void *iter;
+    PRNetAddr addr;
+
+    ai = PR_GetAddrInfoByName(argv[1], PR_AF_UNSPEC, PR_AI_ADDRCONFIG);
+    if (ai == NULL) {
+        fprintf(stderr, "PR_GetAddrInfoByName failed: (%d, %d)\n",
+            PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    printf("%s\n", PR_GetCanonNameFromAddrInfo(ai));
+    iter = NULL;
+    while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) {
+        char buf[128];
+        PR_NetAddrToString(&addr, buf, sizeof buf);
+        printf("%s\n", buf);
+    }
+    PR_FreeAddrInfo(ai);
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/gethost.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/gethost.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,291 @@
+/* -*- 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 ***** */
+
+/*
+ * File: gethost.c
+ *
+ * Description: tests various functions in prnetdb.h
+ *
+ * Usage: gethost [-6] [hostname]
+ */
+
+#include "prio.h"
+#include "prnetdb.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DEFAULT_HOST_NAME "mcom.com"
+
+static void Help(void)
+{
+    fprintf(stderr, "Usage: gethost [-h] [hostname]\n");
+    fprintf(stderr, "\t-h          help\n");
+    fprintf(stderr, "\thostname    Name of host    (default: %s)\n",
+            DEFAULT_HOST_NAME);
+}  /* Help */
+
+/*
+ * Prints the contents of a PRHostEnt structure
+ */
+void PrintHostent(const PRHostEnt *he)
+{
+    int i;
+    int j;
+
+    printf("h_name: %s\n", he->h_name);
+    for (i = 0; he->h_aliases[i]; i++) {
+        printf("h_aliases[%d]: %s\n", i, he->h_aliases[i]);
+    }
+    printf("h_addrtype: %d\n", he->h_addrtype);
+    printf("h_length: %d\n", he->h_length);
+    for (i = 0; he->h_addr_list[i]; i++) {
+        printf("h_addr_list[%d]: ", i);
+        for (j = 0; j < he->h_length; j++) {
+            if (j != 0) printf(".");
+            printf("%u", (unsigned char)he->h_addr_list[i][j]);
+        }
+        printf("\n");
+    }
+}
+
+int main(int argc, char **argv)
+{
+    const char *hostName = DEFAULT_HOST_NAME;
+    PRHostEnt he, reversehe;
+    char buf[PR_NETDB_BUF_SIZE];
+    char reversebuf[PR_NETDB_BUF_SIZE];
+    PRIntn idx;
+    PRNetAddr addr;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "h");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 0:  /* naked */
+                hostName = opt->value;
+                break;
+            case 'h':  /* Help message */
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (PR_GetHostByName(hostName, buf, sizeof(buf), &he) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetHostByName failed\n");
+        exit(1);
+    }
+    PrintHostent(&he);
+    idx = 0;
+    while (1) {
+        idx = PR_EnumerateHostEnt(idx, &he, 0, &addr);
+        if (idx == -1) {
+            fprintf(stderr, "PR_EnumerateHostEnt failed\n");
+            exit(1);
+        }
+        if (idx == 0) break;  /* normal loop termination */
+        printf("reverse lookup\n");
+        if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf),
+                &reversehe) == PR_FAILURE) {
+            fprintf(stderr, "PR_GetHostByAddr failed\n");
+            exit(1);
+        }
+        PrintHostent(&reversehe);
+    }
+
+    printf("PR_GetIPNodeByName with PR_AF_INET\n");
+    if (PR_GetIPNodeByName(hostName, PR_AF_INET, PR_AI_DEFAULT,
+            buf, sizeof(buf), &he) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetIPNodeByName failed\n");
+        exit(1);
+    }
+    PrintHostent(&he);
+    printf("PR_GetIPNodeByName with PR_AF_INET6\n");
+    if (PR_GetIPNodeByName(hostName, PR_AF_INET6, PR_AI_DEFAULT,
+            buf, sizeof(buf), &he) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetIPNodeByName failed\n");
+        exit(1);
+    }
+    PrintHostent(&he);
+    idx = 0;
+    printf("PR_GetHostByAddr with PR_AF_INET6\n");
+    while (1) {
+        idx = PR_EnumerateHostEnt(idx, &he, 0, &addr);
+        if (idx == -1) {
+            fprintf(stderr, "PR_EnumerateHostEnt failed\n");
+            exit(1);
+        }
+        if (idx == 0) break;  /* normal loop termination */
+        printf("reverse lookup\n");
+        if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf),
+                &reversehe) == PR_FAILURE) {
+            fprintf(stderr, "PR_GetHostByAddr failed\n");
+            exit(1);
+        }
+        PrintHostent(&reversehe);
+    }
+    printf("PR_GetHostByAddr with PR_AF_INET6 done\n");
+  
+    PR_StringToNetAddr("::1", &addr);
+    if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_TRUE) {
+        fprintf(stderr, "addr should not be ipv4 mapped address\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+
+    PR_StringToNetAddr("127.0.0.1", &addr);
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+    PR_StringToNetAddr("::FFFF:127.0.0.1", &addr);
+    if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_FALSE) {
+        fprintf(stderr, "addr should be ipv4 mapped address\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+
+    if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
+        fprintf(stderr, "addr should be unspecified address\n");
+        exit(1);
+    }
+    if (PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+
+    if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
+        fprintf(stderr, "addr should be unspecified address\n");
+        exit(1);
+    }
+    if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = 0;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
+        fprintf(stderr, "addr should be unspecified address\n");
+        exit(1);
+    }
+	{
+		char buf[256];
+		PR_NetAddrToString(&addr, buf, 256);
+		printf("IPv4 INADDRANY: %s\n", buf);
+	}
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = 0;
+    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+	{
+		char buf[256];
+		PR_NetAddrToString(&addr, buf, 256);
+		printf("IPv4 LOOPBACK: %s\n", buf);
+	}
+
+    if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
+        fprintf(stderr, "addr should be unspecified address\n");
+        exit(1);
+    }
+	{
+		char buf[256];
+		PR_NetAddrToString(&addr, buf, 256);
+		printf("IPv6 INADDRANY: %s\n", buf);
+	}
+    if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
+        fprintf(stderr, "addr should be loopback address\n");
+        exit(1);
+    }
+	{
+		char buf[256];
+		PR_NetAddrToString(&addr, buf, 256);
+		printf("IPv6 LOOPBACK: %s\n", buf);
+	}
+	{
+		PRIPv6Addr v6addr;
+		char tmp_buf[256];
+
+    	PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr);
+
+		PR_ConvertIPv4AddrToIPv6(addr.inet.ip, &v6addr);
+    	PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr);
+		addr.ipv6.ip = v6addr;
+		PR_NetAddrToString(&addr, tmp_buf, 256);
+		printf("IPv4-mapped IPv6 LOOPBACK: %s\n", tmp_buf);
+	}
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/getproto.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/getproto.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,114 @@
+/* -*- 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: getproto.c
+ *
+ * A test program for PR_GetProtoByName and PR_GetProtoByNumber
+ *
+ *************************************************************************
+ */
+
+#include "plstr.h"
+#include "plerror.h"
+#include "prinit.h"
+#include "prprf.h"
+#include "prnetdb.h"
+#include "prerror.h"
+
+int main()
+{
+    PRFileDesc *prstderr = PR_GetSpecialFD(PR_StandardError);
+    PRBool failed = PR_FALSE;
+    PRProtoEnt proto;
+    char buf[2048];
+    PRStatus rv;
+
+    PR_STDIO_INIT();
+    rv = PR_GetProtoByName("tcp", buf, sizeof(buf), &proto);
+    if (PR_FAILURE == rv) {
+        failed = PR_TRUE;
+        PL_FPrintError(prstderr, "PR_GetProtoByName failed");
+    }
+    else if (6 != proto.p_num) {
+        PR_fprintf(
+            prstderr,"tcp is usually 6, but is %d on this machine\n",
+            proto.p_num);
+    }
+    else PR_fprintf(prstderr, "tcp is protocol number %d\n", proto.p_num);
+
+    rv = PR_GetProtoByName("udp", buf, sizeof(buf), &proto);
+    if (PR_FAILURE == rv) {
+        failed = PR_TRUE;
+        PL_FPrintError(prstderr, "PR_GetProtoByName failed");
+    }
+    else if (17 != proto.p_num) {
+        PR_fprintf(
+            prstderr, "udp is usually 17, but is %d on this machine\n",
+            proto.p_num);
+    }
+    else PR_fprintf(prstderr, "udp is protocol number %d\n", proto.p_num);
+
+    rv = PR_GetProtoByNumber(6, buf, sizeof(buf), &proto);
+    if (PR_FAILURE == rv) {
+        failed = PR_TRUE;
+        PL_FPrintError(prstderr, "PR_GetProtoByNumber failed");
+    }
+    else if (PL_strcmp("tcp", proto.p_name)) {
+        PR_fprintf(
+            prstderr, "Protocol number 6 is usually tcp, but is %s"
+            " on this platform\n", proto.p_name);
+    }
+    else PR_fprintf(prstderr, "Protocol number 6 is %s\n", proto.p_name);
+
+    rv = PR_GetProtoByNumber(17, buf, sizeof(buf), &proto);
+    if (PR_FAILURE == rv) {
+        failed = PR_TRUE;
+        PL_FPrintError(prstderr, "PR_GetProtoByNumber failed");
+    }
+    else if (PL_strcmp("udp", proto.p_name)) {
+        PR_fprintf(
+            prstderr, "Protocol number 17 is usually udp, but is %s"
+            " on this platform\n", proto.p_name);
+    }
+    else PR_fprintf(prstderr, "Protocol number 17 is %s\n", proto.p_name);
+
+    PR_fprintf(prstderr, (failed) ? "FAILED\n" : "PASSED\n");
+    return (failed) ? 1 : 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/i2l.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/i2l.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,133 @@
+/* -*- 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 <stdlib.h>
+
+#include "prio.h"
+#include "prinit.h"
+#include "prprf.h"
+#include "prlong.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+typedef union Overlay_i
+{
+    PRInt32 i;
+    PRInt64 l;
+} Overlay_i;
+
+typedef union Overlay_u
+{
+    PRUint32 i;
+    PRUint64 l;
+} Overlay_u;
+
+static PRFileDesc *err = NULL;
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: -i n | -u n | -h\n");
+    PR_fprintf(err, "\t-i n treat following number as signed integer\n");
+    PR_fprintf(err, "\t-u n treat following number as unsigned integer\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv)
+{
+    Overlay_i si;
+    Overlay_u ui;
+    PLOptStatus os;
+    PRBool bsi = PR_FALSE, bui = PR_FALSE;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hi:u:");
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'i':  /* signed integer */
+            si.i = (PRInt32)atoi(opt->value);
+            bsi = PR_TRUE;
+            break;
+        case 'u':  /* unsigned */
+            ui.i = (PRUint32)atoi(opt->value);
+            bui = PR_TRUE;
+            break;
+        case 'h':  /* user wants some guidance */
+         default:
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+#if defined(HAVE_LONG_LONG)
+    PR_fprintf(err, "We have long long\n");
+#else
+    PR_fprintf(err, "We don't have long long\n");
+#endif
+
+    if (bsi)
+    {
+        PR_fprintf(err, "Converting %ld: ", si.i);
+        LL_I2L(si.l, si.i);
+        PR_fprintf(err, "%lld\n", si.l);
+    }
+
+    if (bui)
+    {
+        PR_fprintf(err, "Converting %lu: ", ui.i);
+        LL_I2L(ui.l, ui.i);
+        PR_fprintf(err, "%llu\n", ui.l);
+    }
+    return 0;
+
+}  /* main */
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
+
+/* i2l.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/initclk.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/initclk.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,109 @@
+/* -*- 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 ***** */
+
+/*
+ * This is a regression test for the bug that the interval timer
+ * is not initialized when _PR_CreateCPU calls PR_IntervalNow.
+ * The bug would make this test program finish prematurely,
+ * when the SHORT_TIMEOUT period expires.  The correct behavior
+ * is for the test to finish when the LONG_TIMEOUT period expires.
+ */
+
+#include "prlock.h"
+#include "prcvar.h"
+#include "prthread.h"
+#include "prinrval.h"
+#include "prlog.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+/* The timeouts, in milliseconds */
+#define SHORT_TIMEOUT 1000
+#define LONG_TIMEOUT 3000
+
+PRLock *lock1, *lock2;
+PRCondVar *cv1, *cv2;
+
+void ThreadFunc(void *arg)
+{
+    PR_Lock(lock1);
+    PR_WaitCondVar(cv1, PR_MillisecondsToInterval(SHORT_TIMEOUT));
+    PR_Unlock(lock1);
+}
+
+int main()
+{
+    PRThread *thread;
+    PRIntervalTime start, end;
+    PRUint32 elapsed_ms;
+
+    lock1 = PR_NewLock();
+    PR_ASSERT(NULL != lock1);
+    cv1 = PR_NewCondVar(lock1);
+    PR_ASSERT(NULL != cv1);
+    lock2 = PR_NewLock();
+    PR_ASSERT(NULL != lock2);
+    cv2 = PR_NewCondVar(lock2);
+    PR_ASSERT(NULL != cv2);
+    start = PR_IntervalNow();
+    thread = PR_CreateThread(
+            PR_USER_THREAD,
+            ThreadFunc,
+            NULL,
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_JOINABLE_THREAD,
+            0);
+    PR_ASSERT(NULL != thread);
+    PR_Lock(lock2);
+    PR_WaitCondVar(cv2, PR_MillisecondsToInterval(LONG_TIMEOUT));
+    PR_Unlock(lock2);
+    PR_JoinThread(thread);
+    end = PR_IntervalNow();
+    elapsed_ms = PR_IntervalToMilliseconds((PRIntervalTime)(end - start));
+    /* Allow 100ms imprecision */
+    if (elapsed_ms < LONG_TIMEOUT - 100 || elapsed_ms > LONG_TIMEOUT + 100) {
+        printf("Elapsed time should be %u ms but is %u ms\n",
+                LONG_TIMEOUT, elapsed_ms);
+        printf("FAIL\n");
+        exit(1);
+    }
+	printf("Elapsed time: %u ms, expected time: %u ms\n",
+               LONG_TIMEOUT, elapsed_ms);
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/inrval.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/inrval.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,242 @@
+/* -*- 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:            inrval.c
+** description:     Interval conversion test.
+** Modification History:
+** 15-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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#ifdef XP_MAC
+#include "pralarm.h"
+#else
+#include "obsolete/pralarm.h"
+#endif
+
+#include "prio.h"
+#include "prprf.h"
+#include "prlock.h"
+#include "prlong.h"
+#include "prcvar.h"
+#include "prinrval.h"
+#include "prtime.h"
+
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static PRIntn debug_mode;
+static PRFileDesc *output;
+
+
+static void TestConversions(void)
+{
+    PRIntervalTime ticks = PR_TicksPerSecond();
+
+	if (debug_mode) {
+    PR_fprintf(output, "PR_TicksPerSecond: %ld\n\n", ticks);
+    PR_fprintf(output, "PR_SecondsToInterval(1): %ld\n", PR_SecondsToInterval(1));
+    PR_fprintf(output, "PR_MillisecondsToInterval(1000): %ld\n", PR_MillisecondsToInterval(1000));
+    PR_fprintf(output, "PR_MicrosecondsToInterval(1000000): %ld\n\n", PR_MicrosecondsToInterval(1000000));
+
+    PR_fprintf(output, "PR_SecondsToInterval(3): %ld\n", PR_SecondsToInterval(3));
+    PR_fprintf(output, "PR_MillisecondsToInterval(3000): %ld\n", PR_MillisecondsToInterval(3000));
+    PR_fprintf(output, "PR_MicrosecondsToInterval(3000000): %ld\n\n", PR_MicrosecondsToInterval(3000000));
+
+    PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks));
+    PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks));
+    PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks));
+
+    ticks *= 3;
+    PR_fprintf(output, "PR_IntervalToSeconds(%ld): %ld\n", ticks, PR_IntervalToSeconds(ticks));
+    PR_fprintf(output, "PR_IntervalToMilliseconds(%ld): %ld\n", ticks, PR_IntervalToMilliseconds(ticks));
+    PR_fprintf(output, "PR_IntervalToMicroseconds(%ld): %ld\n\n", ticks, PR_IntervalToMicroseconds(ticks));
+	} /*end debug mode */
+}  /* TestConversions */
+
+static void TestIntervalOverhead(void)
+{
+    /* Hopefully the optimizer won't delete this function */
+    PRUint32 elapsed, per_call, loops = 1000000;
+
+    PRIntervalTime timeout, timein = PR_IntervalNow();
+    while (--loops > 0)
+        timeout = PR_IntervalNow();
+
+    elapsed = 1000U * PR_IntervalToMicroseconds(timeout - timein);
+    per_call = elapsed / 1000000U;
+    PR_fprintf(
+        output, "Overhead of 'PR_IntervalNow()' is %u nsecs\n\n", per_call);
+}  /* TestIntervalOverhead */
+
+static void TestNowOverhead(void)
+{
+    PRTime timeout, timein;
+    PRInt32 overhead, loops = 1000000;
+    PRInt64 elapsed, per_call, ten23rd, ten26th;
+
+    LL_I2L(ten23rd, 1000);
+    LL_I2L(ten26th, 1000000);
+
+    timein = PR_Now();
+    while (--loops > 0)
+        timeout = PR_Now();
+
+    LL_SUB(elapsed, timeout, timein);
+    LL_MUL(elapsed, elapsed, ten23rd);
+    LL_DIV(per_call, elapsed, ten26th);
+    LL_L2I(overhead, per_call);
+    PR_fprintf(
+        output, "Overhead of 'PR_Now()' is %u nsecs\n\n", overhead);
+}  /* TestNowOverhead */
+
+static void TestIntervals(void)
+{
+    PRStatus rv;
+    PRUint32 delta;
+    PRInt32 seconds;
+    PRUint64 elapsed, thousand;
+    PRTime timein, timeout;
+    PRLock *ml = PR_NewLock();
+    PRCondVar *cv = PR_NewCondVar(ml);
+    for (seconds = 0; seconds < 10; ++seconds)
+    {
+        PRIntervalTime ticks = PR_SecondsToInterval(seconds);
+        PR_Lock(ml);
+        timein = PR_Now();
+        rv = PR_WaitCondVar(cv, ticks);
+        timeout = PR_Now();
+        PR_Unlock(ml);
+        LL_SUB(elapsed, timeout, timein);
+        LL_I2L(thousand, 1000);
+        LL_DIV(elapsed, elapsed, thousand);
+        LL_L2UI(delta, elapsed);
+        if (debug_mode) PR_fprintf(output, 
+            "TestIntervals: %swaiting %ld seconds took %ld msecs\n",
+            ((rv == PR_SUCCESS) ? "" : "FAILED "), seconds, delta);
+    }
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    if (debug_mode) PR_fprintf(output, "\n");
+}  /* TestIntervals */
+
+static PRIntn PR_CALLBACK RealMain(int argc, char** argv)
+{
+    PRUint32 vcpu, cpus = 0, loops = 1000;
+
+	/* 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
+	*/
+
+ /* main test */
+	
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dl:c:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'c':  /* concurrency counter */
+			cpus = atoi(opt->value);
+            break;
+        case 'l':  /* loop counter */
+			loops = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+	
+    output = PR_GetSpecialFD(PR_StandardOutput);
+    PR_fprintf(output, "inrval: Examine stdout to determine results.\n");
+
+    if (cpus == 0) cpus = 8;
+    if (loops == 0) loops = 1000;
+
+    if (debug_mode > 0)
+    {
+        PR_fprintf(output, "Inrval: Using %d loops\n", loops);
+        PR_fprintf(output, "Inrval: Using 1 and %d cpu(s)\n", cpus);
+    }
+
+    for (vcpu = 1; vcpu <= cpus; vcpu += cpus - 1)
+    {
+        if (debug_mode)
+            PR_fprintf(output, "\nInrval: Using %d CPU(s)\n\n", vcpu);
+        PR_SetConcurrency(vcpu);
+
+        TestNowOverhead();
+        TestIntervalOverhead();
+        TestConversions();
+        TestIntervals();
+    }
+        
+    return 0;
+}
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/instrumt.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/instrumt.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,507 @@
+/* -*- 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:    instrumt.c
+** Description: This test is for the NSPR debug aids defined in
+** prcountr.h, prtrace.h, prolock.h
+**
+** The test case tests the three debug aids in NSPR:
+**
+** Diagnostic messages can be enabled using "instrumt -v 6"
+** This sets the msgLevel to something that PR_LOG() likes.
+** Also define in the environment "NSPR_LOG_MODULES=Test:6"
+**
+** CounterTest() tests the counter facility. This test
+** creates 4 threads. Each thread either increments, decrements,
+** adds to or subtracts from a counter, depending on an argument
+** passed to the thread at thread-create time. Each of these threads
+** does COUNT_LIMIT iterations doing its thing. When all 4 threads
+** are done, the result of the counter is evaluated. If all was atomic,
+** the the value of the counter should be zero.
+**
+** TraceTest():
+** This test mingles with the counter test. Counters trace.
+** A thread to extract trace entries on the fly is started.
+** A thread to dump trace entries to a file is started.
+**
+** OrderedLockTest():
+**
+**
+**
+**
+**
+*/
+
+#include <stdio.h>
+#include <plstr.h>
+#include <prclist.h>
+#include <prmem.h>
+#include <plgetopt.h> 
+#include <prlog.h> 
+#include <prmon.h> 
+#include <pratom.h> 
+#include <prtrace.h> 
+#include <prcountr.h> 
+#include <prolock.h> 
+
+#define COUNT_LIMIT  (10 * ( 1024))
+
+#define SMALL_TRACE_BUFSIZE  ( 60 * 1024 )
+
+typedef enum 
+{
+    CountLoop = 1,
+    TraceLoop = 2,
+    TraceFlow = 3
+} TraceTypes;
+
+
+PRLogModuleLevel msgLevel = PR_LOG_ALWAYS;
+
+PRBool  help = PR_FALSE;
+PRBool  failed = PR_FALSE;
+
+
+PRLogModuleInfo *lm;
+PRMonitor   *mon;
+PRInt32     activeThreads = 0;
+PR_DEFINE_COUNTER( hCounter );
+PR_DEFINE_TRACE( hTrace );
+
+static void Help(void)
+{
+    printf("Help? ... Ha!\n");
+}    
+
+static void ListCounters(void)
+{
+    PR_DEFINE_COUNTER( qh );
+    PR_DEFINE_COUNTER( rh );
+    const char *qn, *rn, *dn;
+    const char **qname = &qn, **rname = &rn, **desc = &dn;
+    PRUint32    tCtr;
+
+    PR_INIT_COUNTER_HANDLE( qh, NULL );
+    PR_FIND_NEXT_COUNTER_QNAME(qh, qh );
+    while ( qh != NULL )
+    {
+        PR_INIT_COUNTER_HANDLE( rh, NULL );
+        PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh );
+        while ( rh != NULL )
+        {
+            PR_GET_COUNTER_NAME_FROM_HANDLE( rh, qname, rname, desc );
+            tCtr = PR_GET_COUNTER(tCtr, rh);
+            PR_LOG( lm, msgLevel,
+                ( "QName: %s  RName: %s  Desc: %s  Value: %ld\n", 
+                qn, rn, dn, tCtr ));
+            PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh );
+        } 
+        PR_FIND_NEXT_COUNTER_QNAME(qh, qh);
+    }
+    return;    
+} /* end ListCounters() */
+
+static void ListTraces(void)
+{
+    PR_DEFINE_TRACE( qh );
+    PR_DEFINE_TRACE( rh );
+    const char *qn, *rn, *dn;
+    const char **qname = &qn, **rname = &rn, **desc = &dn;
+
+    PR_INIT_TRACE_HANDLE( qh, NULL );
+    PR_FIND_NEXT_TRACE_QNAME(qh, qh );
+    while ( qh != NULL )
+    {
+        PR_INIT_TRACE_HANDLE( rh, NULL );
+        PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh );
+        while ( rh != NULL )
+        {
+            PR_GET_TRACE_NAME_FROM_HANDLE( rh, qname, rname, desc );
+            PR_LOG( lm, msgLevel,
+                ( "QName: %s  RName: %s  Desc: %s", 
+                qn, rn, dn ));
+            PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh );
+        } 
+        PR_FIND_NEXT_TRACE_QNAME(qh, qh);
+    }
+    return;    
+} /* end ListCounters() */
+
+
+static PRInt32 one = 1;
+static PRInt32 two = 2;
+static PRInt32 three = 3;
+static PRInt32 four = 4;
+
+/*
+** Thread to iteratively count something.
+*/
+static void PR_CALLBACK CountSomething( void *arg )
+{
+    PRInt32 switchVar = *((PRInt32 *)arg);
+    PRInt32 i;
+
+    PR_LOG( lm, msgLevel,
+        ("CountSomething: begin thread %ld", switchVar ));
+    
+    for ( i = 0; i < COUNT_LIMIT ; i++)
+    {
+        switch ( switchVar )
+        {
+        case 1 :
+            PR_INCREMENT_COUNTER( hCounter );
+            break;
+        case 2 :
+            PR_DECREMENT_COUNTER( hCounter );
+            break;
+        case 3 :
+            PR_ADD_TO_COUNTER( hCounter, 1 );
+            break;
+        case 4 :
+            PR_SUBTRACT_FROM_COUNTER( hCounter, 1 );
+            break;
+        default :
+            PR_ASSERT( 0 );
+            break;
+        }
+        PR_TRACE( hTrace, CountLoop, switchVar, i, 0, 0, 0, 0, 0 );
+    } /* end for() */
+
+    PR_LOG( lm, msgLevel,
+        ("CounterSomething: end thread %ld", switchVar ));
+    
+    PR_EnterMonitor(mon);
+    --activeThreads;
+    PR_Notify( mon );
+    PR_ExitMonitor(mon);
+
+    return;    
+} /* end CountSomething() */
+
+/*
+** Create the counter threads.
+*/
+static void CounterTest( void )
+{
+    PRThread *t1, *t2, *t3, *t4;
+    PRIntn i = 0;
+    PR_DEFINE_COUNTER( tc );
+    PR_DEFINE_COUNTER( zCounter );
+
+    PR_LOG( lm, msgLevel,
+        ("Begin CounterTest"));
+    
+    /*
+    ** Test Get and Set of a counter.
+    **
+    */
+    PR_CREATE_COUNTER( zCounter, "Atomic", "get/set test", "test get and set of counter" );
+    PR_SET_COUNTER( zCounter, 9 );
+    PR_GET_COUNTER( i, zCounter );
+    if ( i != 9 )
+    {
+        failed = PR_TRUE;
+        PR_LOG( lm, msgLevel,
+            ("Counter set/get failed"));
+    }
+
+    activeThreads += 4;
+    PR_CREATE_COUNTER( hCounter, "Atomic", "SMP Tests", "test atomic nature of counter" );
+
+    PR_GET_COUNTER_HANDLE_FROM_NAME( tc, "Atomic", "SMP Tests" );
+    PR_ASSERT( tc == hCounter );
+
+	t1 = PR_CreateThread(PR_USER_THREAD,
+	        CountSomething, &one, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t1);
+
+	t2 = PR_CreateThread(PR_USER_THREAD,
+			CountSomething, &two, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t2);
+        
+	t3 = PR_CreateThread(PR_USER_THREAD,
+			CountSomething, &three, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t3);
+        
+	t4 = PR_CreateThread(PR_USER_THREAD,
+			CountSomething, &four, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t4);
+
+    PR_LOG( lm, msgLevel,
+        ("Counter Threads started"));
+
+    ListCounters();
+    return;
+} /* end CounterTest() */
+
+/*
+** Thread to dump trace buffer to a file.
+*/
+static void PR_CALLBACK RecordTrace(void *arg )
+{
+    PR_RECORD_TRACE_ENTRIES();
+
+    PR_EnterMonitor(mon);
+    --activeThreads;
+    PR_Notify( mon );
+    PR_ExitMonitor(mon);
+
+    return;    
+} /* end RecordTrace() */
+
+
+
+#define NUM_TRACE_RECORDS ( 10000 )
+/*
+** Thread to extract and print trace entries from the buffer.
+*/
+static void PR_CALLBACK SampleTrace( void *arg )
+{
+#if defined(DEBUG) || defined(FORCE_NSPR_TRACE)
+    PRInt32 found, rc;
+    PRTraceEntry    *foundEntries;
+    PRInt32 i;
+    
+    foundEntries = (PRTraceEntry *)PR_Malloc( NUM_TRACE_RECORDS * sizeof(PRTraceEntry));
+    PR_ASSERT(foundEntries != NULL );
+
+    do
+    {
+        rc = PR_GetTraceEntries( foundEntries, NUM_TRACE_RECORDS, &found);
+        PR_LOG( lm, msgLevel,
+            ("SampleTrace: Lost Data: %ld found: %ld", rc, found ));
+
+        if ( found != 0)
+        {
+            for ( i = 0 ; i < found; i++ )
+            {
+                PR_LOG( lm, msgLevel,
+                    ("SampleTrace, detail: Thread: %p, Time: %llX, UD0: %ld, UD1: %ld, UD2: %8.8ld",
+                        (foundEntries +i)->thread,
+                        (foundEntries +i)->time,
+                        (foundEntries +i)->userData[0], 
+                        (foundEntries +i)->userData[1], 
+                        (foundEntries +i)->userData[2] )); 
+            }
+        }
+        PR_Sleep(PR_MillisecondsToInterval(50));
+    }
+    while( found != 0 && activeThreads >= 1 );
+
+    PR_Free( foundEntries );
+
+    PR_EnterMonitor(mon);
+    --activeThreads;
+    PR_Notify( mon );
+    PR_ExitMonitor(mon);
+
+    PR_LOG( lm, msgLevel,
+        ("SampleTrace(): exiting"));
+
+#endif
+    return;    
+} /* end RecordTrace() */
+
+/*
+** Basic trace test.
+*/
+static void TraceTest( void )
+{
+    PRInt32 i;
+    PRInt32 size;
+    PR_DEFINE_TRACE( th );
+    PRThread *t1, *t2;
+    
+    PR_LOG( lm, msgLevel,
+        ("Begin TraceTest"));    
+
+    size = SMALL_TRACE_BUFSIZE;
+    PR_SET_TRACE_OPTION( PRTraceBufSize, &size );
+    PR_GET_TRACE_OPTION( PRTraceBufSize, &i );
+    
+    PR_CREATE_TRACE( th, "TraceTest", "tt2", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt3", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt4", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt5", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt6", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt7", "A description for the trace test" );
+    PR_CREATE_TRACE( th, "TraceTest", "tt8", "A description for the trace test" );
+
+    PR_CREATE_TRACE( th, "Trace Test", "tt0", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt1", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt2", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt3", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt4", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt5", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt6", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt7", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt8", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt9", "QName is Trace Test, not TraceTest" );
+    PR_CREATE_TRACE( th, "Trace Test", "tt10", "QName is Trace Test, not TraceTest" );
+
+
+
+    activeThreads += 2;
+	t1 = PR_CreateThread(PR_USER_THREAD,
+			RecordTrace, NULL, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t1);
+
+	t2 = PR_CreateThread(PR_USER_THREAD,
+			SampleTrace, 0, 
+			PR_PRIORITY_NORMAL,
+			PR_GLOBAL_THREAD,
+    		PR_UNJOINABLE_THREAD,
+			0);
+	PR_ASSERT(t2);
+        
+    ListTraces();
+
+    PR_GET_TRACE_HANDLE_FROM_NAME( th, "TraceTest","tt1" );
+    PR_ASSERT( th == hTrace );
+
+    PR_LOG( lm, msgLevel,
+        ("End TraceTest"));    
+    return;
+} /* end TraceTest() */
+
+
+/*
+** Ordered lock test.
+*/
+static void OrderedLockTest( void )
+{
+    PR_LOG( lm, msgLevel,
+        ("Begin OrderedLockTest"));    
+
+    
+} /* end OrderedLockTest() */
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+#if defined(DEBUG) || defined(FORCE_NSPR_TRACE)
+    PRUint32    counter;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hdv:");
+    lm = PR_NewLogModule("Test");
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'v':  /* verbose mode */
+			msgLevel = (PRLogModuleLevel)atol( opt->value);
+            break;
+        case 'h':  /* help message */
+			Help();
+			help = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    PR_CREATE_TRACE( hTrace, "TraceTest", "tt1", "A description for the trace test" );
+    mon = PR_NewMonitor();
+    PR_EnterMonitor( mon );
+
+    TraceTest();
+    CounterTest();
+    OrderedLockTest();
+
+    /* Wait for all threads to exit */
+    while ( activeThreads > 0 ) {
+        if ( activeThreads == 1 )
+            PR_SET_TRACE_OPTION( PRTraceStopRecording, NULL );
+    	PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+        PR_GET_COUNTER( counter, hCounter );
+    }
+    PR_ExitMonitor( mon );
+
+    /*
+    ** Evaluate results
+    */
+    PR_GET_COUNTER( counter, hCounter );
+    if ( counter != 0 )
+    {
+        failed = PR_TRUE;
+        PR_LOG( lm, msgLevel,
+            ("Expected counter == 0, found: %ld", counter));
+        printf("FAIL\n");
+    }
+    else
+    {
+        printf("PASS\n");
+    }
+
+
+    PR_DESTROY_COUNTER( hCounter );
+
+    PR_DestroyMonitor( mon );
+
+    PR_TRACE( hTrace, TraceFlow, 0xfff,0,0,0,0,0,0);
+    PR_DESTROY_TRACE( hTrace );
+#else
+    printf("Test not defined\n");
+#endif
+    return 0;
+}  /* main() */
+/* end instrumt.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/intrio.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/intrio.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,169 @@
+/* -*- 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) 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:        intrio.c
+ * Purpose:     testing i/o interrupts (see Bugzilla bug #31120)
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+/* for synchronization between the main thread and iothread */
+static PRLock *lock;
+static PRCondVar *cvar;
+static PRBool iothread_ready;
+
+static void PR_CALLBACK AbortIO(void *arg)
+{
+    PRStatus rv;
+    PR_Sleep(PR_SecondsToInterval(2));
+    rv = PR_Interrupt((PRThread*)arg);
+    PR_ASSERT(PR_SUCCESS == rv);
+}  /* AbortIO */
+
+static void PR_CALLBACK IOThread(void *arg)
+{
+    PRFileDesc *sock, *newsock;
+    PRNetAddr addr;
+
+    sock = PR_OpenTCPSocket(PR_AF_INET6);
+    if (sock == NULL) {
+        fprintf(stderr, "PR_OpenTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&addr, 0, sizeof(addr));
+    if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Bind(sock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    if (PR_Listen(sock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+    /* tell the main thread that we are ready */
+    PR_Lock(lock);
+    iothread_ready = PR_TRUE;
+    PR_NotifyCondVar(cvar);
+    PR_Unlock(lock);
+    newsock = PR_Accept(sock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (newsock != NULL) {
+        fprintf(stderr, "PR_Accept shouldn't have succeeded\n");
+        exit(1);
+    }
+    if (PR_GetError() != PR_PENDING_INTERRUPT_ERROR) {
+        fprintf(stderr, "PR_Accept failed (%d, %d)\n",
+            PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    printf("PR_Accept() is interrupted as expected\n");
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+static void Test(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *iothread, *abortio;
+
+    printf("A %s thread will be interrupted by a %s thread\n",
+        (scope1 == PR_LOCAL_THREAD ? "local" : "global"),
+        (scope2 == PR_LOCAL_THREAD ? "local" : "global"));
+    iothread_ready = PR_FALSE;
+    iothread = PR_CreateThread(
+        PR_USER_THREAD, IOThread, NULL, PR_PRIORITY_NORMAL,
+        scope1, PR_JOINABLE_THREAD, 0);
+    if (iothread == NULL) {
+        fprintf(stderr, "cannot create thread\n");
+        exit(1);
+    }
+    PR_Lock(lock);
+    while (!iothread_ready)
+        PR_WaitCondVar(cvar, PR_INTERVAL_NO_TIMEOUT);
+    PR_Unlock(lock);
+    abortio = PR_CreateThread(
+        PR_USER_THREAD, AbortIO, iothread, PR_PRIORITY_NORMAL,
+        scope2, PR_JOINABLE_THREAD, 0);
+    if (abortio == NULL) {
+        fprintf(stderr, "cannot create thread\n");
+        exit(1);
+    }
+    if (PR_JoinThread(iothread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(abortio) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+}
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PR_STDIO_INIT();
+    lock = PR_NewLock();
+    if (lock == NULL) {
+        fprintf(stderr, "PR_NewLock failed\n");
+        exit(1);
+    }
+    cvar = PR_NewCondVar(lock);
+    if (cvar == NULL) {
+        fprintf(stderr, "PR_NewCondVar failed\n");
+        exit(1);
+    }
+    /* test all four combinations */
+    Test(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+    Test(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+    Test(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+    Test(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+    printf("PASSED\n");
+    return 0;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/intrupt.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/intrupt.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,373 @@
+/* -*- 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:        intrupt.c
+ * Purpose:     testing thread interrupts
+ */
+
+#include "plgetopt.h"
+#include "prcvar.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prthread.h"
+#include "prtypes.h"
+#include "prnetdb.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+#define DEFAULT_TCP_PORT 12500
+
+static PRLock *ml = NULL;
+static PRCondVar *cv = NULL;
+
+static PRBool passed = PR_TRUE;
+static PRBool debug_mode = PR_FALSE;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+static void PR_CALLBACK AbortCV(void *arg)
+{
+    PRStatus rv;
+    PRThread *me = PR_GetCurrentThread();
+
+    /* some other thread (main) is doing the interrupt */
+    PR_Lock(ml);
+    rv = PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT);
+    if (debug_mode) printf( "Expected interrupt on wait CV and ");
+    if (PR_FAILURE == rv)
+    {
+        if (PR_PENDING_INTERRUPT_ERROR == PR_GetError())
+        {
+            if (debug_mode) printf("got it\n");
+        }
+        else
+        {
+            if (debug_mode) printf("got random error\n");
+            passed = PR_FALSE;
+        }
+    }
+    else
+    {
+        if (debug_mode) printf("got a successful completion\n");
+        passed = PR_FALSE;
+    }
+
+    rv = PR_WaitCondVar(cv, 10);
+    if (debug_mode)
+    {
+        printf(
+            "Expected success on wait CV and %s\n",
+            (PR_SUCCESS == rv) ? "got it" : "failed");
+    }
+    passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
+
+    /* interrupt myself, then clear */
+    PR_Interrupt(me);
+    PR_ClearInterrupt();
+    rv = PR_WaitCondVar(cv, 10);
+    if (debug_mode)
+    {
+        printf("Expected success on wait CV and ");
+        if (PR_FAILURE == rv)
+        {
+            printf(
+                "%s\n", (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) ?
+                "got interrupted" : "a random failure");
+        }
+        printf("got it\n");
+    }
+    passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
+
+    /* set, then wait - interrupt - then wait again */
+    PR_Interrupt(me);
+    rv = PR_WaitCondVar(cv, 10);
+    if (debug_mode) printf( "Expected interrupt on wait CV and ");
+    if (PR_FAILURE == rv)
+    {
+        if (PR_PENDING_INTERRUPT_ERROR == PR_GetError())
+        {
+            if (debug_mode) printf("got it\n");
+        }
+        else
+        {
+            if (debug_mode) printf("failed\n");
+            passed = PR_FALSE;
+        }
+    }
+    else
+    {
+        if (debug_mode) printf("got a successful completion\n");
+        passed = PR_FALSE;
+    }
+
+    rv = PR_WaitCondVar(cv, 10);
+    if (debug_mode)
+    {
+        printf(
+            "Expected success on wait CV and %s\n",
+            (PR_SUCCESS == rv) ? "got it" : "failed");
+    }
+    passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
+
+    PR_Unlock(ml);
+
+}  /* AbortCV */
+
+static void PR_CALLBACK AbortIO(void *arg)
+{
+    PRStatus rv;
+    PR_Sleep(PR_SecondsToInterval(2));
+    rv = PR_Interrupt((PRThread*)arg);
+    PR_ASSERT(PR_SUCCESS == rv);
+}  /* AbortIO */
+
+static void PR_CALLBACK AbortJoin(void *arg)
+{
+}  /* AbortJoin */
+
+static void setup_listen_socket(PRFileDesc **listner, PRNetAddr *netaddr)
+{
+    PRStatus rv;
+    PRInt16 port = DEFAULT_TCP_PORT;
+
+    *listner = PR_NewTCPSocket();
+    PR_ASSERT(*listner != NULL);
+    memset(netaddr, 0, sizeof(*netaddr));
+    (*netaddr).inet.ip = PR_htonl(PR_INADDR_ANY);
+    (*netaddr).inet.family = PR_AF_INET;
+    do
+    {
+        (*netaddr).inet.port = PR_htons(port);
+        rv = PR_Bind(*listner, netaddr);
+        port += 1;
+        PR_ASSERT(port < (DEFAULT_TCP_PORT + 10));
+    } while (PR_FAILURE == rv);
+
+    rv = PR_Listen(*listner, 5);
+
+	if (PR_GetSockName(*listner, netaddr) < 0) {
+		if (debug_mode) printf("intrupt: ERROR - PR_GetSockName failed\n");
+		passed = PR_FALSE;
+		return;
+	}
+
+}
+
+static void PR_CALLBACK IntrBlock(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr netaddr;
+    PRFileDesc *listner;
+
+    /* some other thread (main) is doing the interrupt */
+	/* block the interrupt */
+	PR_BlockInterrupt();
+    PR_Lock(ml);
+    rv = PR_WaitCondVar(cv, PR_SecondsToInterval(4));
+	PR_Unlock(ml);
+    if (debug_mode)
+    {
+        printf("Expected success on wait CV and ");
+        if (PR_FAILURE == rv)
+        {
+            printf(
+                "%s\n", (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) ?
+                "got interrupted" : "got a random failure");
+        } else
+        	printf("got it\n");
+    }
+    passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
+
+	setup_listen_socket(&listner, &netaddr);
+	PR_UnblockInterrupt();
+    if (PR_Accept(listner, &netaddr, PR_INTERVAL_NO_TIMEOUT) == NULL)
+    {
+        PRInt32 error = PR_GetError();
+        if (debug_mode) printf("Expected interrupt on PR_Accept() and ");
+        if (PR_PENDING_INTERRUPT_ERROR == error)
+        {
+            if (debug_mode) printf("got it\n");
+        }
+        else
+        {
+            if (debug_mode) printf("failed\n");
+            passed = PR_FALSE;
+        }
+    }
+    else
+    {
+        if (debug_mode) printf("Failed to interrupt PR_Accept()\n");
+        passed = PR_FALSE;
+    }
+
+    (void)PR_Close(listner); listner = NULL;
+}  /* TestIntrBlock */
+
+void PR_CALLBACK Intrupt(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr netaddr;
+    PRFileDesc *listner;
+    PRThread *abortCV, *abortIO, *abortJoin, *intrBlock;
+
+    ml = PR_NewLock();
+    cv = PR_NewCondVar(ml);
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("intrupt.log");
+	debug_mode = PR_TRUE;
+#endif
+
+    /* Part I */
+    if (debug_mode) printf("Part I\n");
+    abortCV = PR_CreateThread(
+        PR_USER_THREAD, AbortCV, 0, PR_PRIORITY_NORMAL,
+        thread_scope, PR_JOINABLE_THREAD, 0);
+
+    PR_Sleep(PR_SecondsToInterval(2));
+    rv = PR_Interrupt(abortCV);
+    PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_JoinThread(abortCV);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    /* Part II */
+    if (debug_mode) printf("Part II\n");
+    abortJoin = PR_CreateThread(
+        PR_USER_THREAD, AbortJoin, 0, PR_PRIORITY_NORMAL,
+        thread_scope, PR_JOINABLE_THREAD, 0);
+    PR_Sleep(PR_SecondsToInterval(2));
+    if (debug_mode) printf("Expecting to interrupt an exited thread ");
+    rv = PR_Interrupt(abortJoin);
+    PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_JoinThread(abortJoin);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if (debug_mode) printf("and succeeded\n");
+
+    /* Part III */
+    if (debug_mode) printf("Part III\n");
+	setup_listen_socket(&listner, &netaddr);
+    abortIO = PR_CreateThread(
+        PR_USER_THREAD, AbortIO, PR_GetCurrentThread(), PR_PRIORITY_NORMAL,
+        thread_scope, PR_JOINABLE_THREAD, 0);
+
+    if (PR_Accept(listner, &netaddr, PR_INTERVAL_NO_TIMEOUT) == NULL)
+    {
+        PRInt32 error = PR_GetError();
+        if (debug_mode) printf("Expected interrupt on PR_Accept() and ");
+        if (PR_PENDING_INTERRUPT_ERROR == error)
+        {
+            if (debug_mode) printf("got it\n");
+        }
+        else
+        {
+            if (debug_mode) printf("failed\n");
+            passed = PR_FALSE;
+        }
+    }
+    else
+    {
+        if (debug_mode) printf("Failed to interrupt PR_Accept()\n");
+        passed = PR_FALSE;
+    }
+
+    (void)PR_Close(listner); listner = NULL;
+
+    rv = PR_JoinThread(abortIO);
+    PR_ASSERT(PR_SUCCESS == rv);
+    /* Part VI */
+    if (debug_mode) printf("Part VI\n");
+    intrBlock = PR_CreateThread(
+        PR_USER_THREAD, IntrBlock, 0, PR_PRIORITY_NORMAL,
+        thread_scope, PR_JOINABLE_THREAD, 0);
+
+    PR_Sleep(PR_SecondsToInterval(2));
+    rv = PR_Interrupt(intrBlock);
+    PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_JoinThread(intrBlock);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);    
+}  /* Intrupt */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRThread *intrupt;
+	PLOptStatus os;
+  	PLOptState *opt = PL_CreateOptState(argc, argv, "dG");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+    PR_STDIO_INIT();
+    intrupt = PR_CreateThread(
+        PR_USER_THREAD, Intrupt, NULL, PR_PRIORITY_NORMAL,
+        thread_scope, PR_JOINABLE_THREAD, 0);
+    if (intrupt == NULL) {
+        fprintf(stderr, "cannot create thread\n");
+        passed = PR_FALSE;
+    } else {
+        PRStatus rv;
+        rv = PR_JoinThread(intrupt);
+        PR_ASSERT(rv == PR_SUCCESS);
+    }
+    printf("%s\n", ((passed) ? "PASSED" : "FAILED"));
+	return ((passed) ? 0 : 1);
+}  /* main */
+
+/* intrupt.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/io_timeout.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/io_timeout.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,299 @@
+/* -*- 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 ***** */
+
+/*
+** Test socket IO timeouts
+**
+**
+**
+**
+** Modification History:
+** 14-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. 
+***********************************************************************/
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include "nspr.h"
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+#define NUM_THREADS 1
+#define BASE_PORT   8000
+#define DEFAULT_ACCEPT_TIMEOUT 2
+
+typedef struct threadInfo {
+    PRInt16 id;
+    PRInt16 accept_timeout;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32   *alive;
+} threadInfo;
+
+PRIntn failed_already = 0;
+PRIntn debug_mode = 0;
+
+#define	LOCAL_SCOPE_STRING			"LOCAL scope"
+#define	GLOBAL_SCOPE_STRING			"GLOBAL scope"
+#define	GLOBAL_BOUND_SCOPE_STRING	"GLOBAL_BOUND scope"
+
+void 
+thread_main(void *_info)
+{
+    threadInfo *info = (threadInfo *)_info;
+    PRNetAddr listenAddr;
+    PRNetAddr clientAddr;
+    PRFileDesc *listenSock = NULL;
+    PRFileDesc *clientSock;
+    PRStatus rv;
+	PRThreadScope tscope;
+	char *scope_str;
+
+ 
+	if (debug_mode)
+    	printf("thread %d is alive\n", info->id);
+	tscope = PR_GetThreadScope(PR_GetCurrentThread());
+
+	switch(tscope) {
+		case PR_LOCAL_THREAD:
+			scope_str = LOCAL_SCOPE_STRING;
+			break;
+		case PR_GLOBAL_THREAD:
+			scope_str = GLOBAL_SCOPE_STRING;
+			break;
+		case PR_GLOBAL_BOUND_THREAD:
+			scope_str = GLOBAL_BOUND_SCOPE_STRING;
+			break;
+		default:
+			PR_ASSERT(!"Invalid thread scope");
+			break;
+	}
+	printf("thread id %d, scope %s\n", info->id, scope_str);
+
+    listenSock = PR_NewTCPSocket();
+    if (!listenSock) {
+		if (debug_mode)
+        	printf("unable to create listen socket\n");
+		failed_already=1;
+        goto dead;
+    }
+  
+    listenAddr.inet.family = PR_AF_INET;
+    listenAddr.inet.port = PR_htons(BASE_PORT + info->id);
+    listenAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    rv = PR_Bind(listenSock, &listenAddr);
+    if (rv == PR_FAILURE) {
+		if (debug_mode)
+        	printf("unable to bind\n");
+		failed_already=1;
+        goto dead;
+    }
+
+    rv = PR_Listen(listenSock, 4);
+    if (rv == PR_FAILURE) {
+		if (debug_mode)
+        	printf("unable to listen\n");
+		failed_already=1;
+        goto dead;
+    }
+
+	if (debug_mode)
+    	printf("thread %d going into accept for %d seconds\n", 
+        	info->id, info->accept_timeout + info->id);
+
+    clientSock = PR_Accept(listenSock, &clientAddr, PR_SecondsToInterval(info->accept_timeout +info->id));
+
+    if (clientSock == NULL) {
+        if (PR_GetError() == PR_IO_TIMEOUT_ERROR) {
+			if (debug_mode) {	
+            	printf("PR_Accept() timeout worked!\n"); 
+				printf("TEST PASSED! PR_Accept() returned error %d\n",
+							PR_IO_TIMEOUT_ERROR);
+			}
+    	} else {
+			if (debug_mode)
+            	printf("TEST FAILED! PR_Accept() returned error %d\n",
+														PR_GetError());
+			failed_already=1;
+		}
+    } else {
+		if (debug_mode)
+        	printf ("TEST FAILED! PR_Accept() succeeded?\n");
+		failed_already=1;
+		PR_Close(clientSock);
+    }
+
+dead:
+    if (listenSock) {
+		PR_Close(listenSock);
+    }
+    PR_Lock(info->dead_lock);
+    (*info->alive)--;
+    PR_NotifyCondVar(info->dead_cv);
+    PR_Unlock(info->dead_lock);
+
+	if (debug_mode)
+    	printf("thread %d is dead\n", info->id);
+
+    PR_Free(info);
+}
+
+void
+thread_test(PRThreadScope scope, PRInt32 num_threads)
+{
+    PRInt32 index;
+    PRThread *thr;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32 alive;
+
+	if (debug_mode)
+    	printf("IO Timeout test started with %d threads\n", num_threads);
+
+    dead_lock = PR_NewLock();
+    dead_cv = PR_NewCondVar(dead_lock);
+    alive = num_threads;
+    
+    for (index = 0; index < num_threads; index++) {
+        threadInfo *info = (threadInfo *)PR_Malloc(sizeof(threadInfo));
+
+        info->id = index;
+        info->dead_lock = dead_lock;
+        info->dead_cv = dead_cv;
+        info->alive = &alive;
+        info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT;
+        
+        thr = PR_CreateThread( PR_USER_THREAD,
+                               thread_main,
+                               (void *)info,
+                               PR_PRIORITY_NORMAL,
+                               scope,
+                               PR_UNJOINABLE_THREAD,
+                               0);
+
+        if (!thr) {
+        	printf("Failed to create thread, error = %d(%d)\n",
+											PR_GetError(), PR_GetOSError());
+			failed_already=1;
+
+            PR_Lock(dead_lock);
+            alive--;
+            PR_Unlock(dead_lock);
+        }
+    }
+
+    PR_Lock(dead_lock);
+    while(alive) {
+		if (debug_mode)
+        	printf("main loop awake; alive = %d\n", alive);
+        PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(dead_lock);
+
+    PR_DestroyCondVar(dead_cv);
+    PR_DestroyLock(dead_lock);
+}
+
+int main(int argc, char **argv)
+{
+    PRInt32 num_threads = 0;
+
+	/* 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] [-t <threads>]
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 't':  /* threads to involve */
+			num_threads = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    if (0 == num_threads)
+        num_threads = NUM_THREADS;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("io_timeout.log");
+	debug_mode = 1;
+#endif
+
+    printf("test with global bound thread\n");
+    thread_test(PR_GLOBAL_BOUND_THREAD, num_threads);
+
+    printf("test with local thread\n");
+    thread_test(PR_LOCAL_THREAD, num_threads);
+
+    printf("test with global thread\n");
+    thread_test(PR_GLOBAL_THREAD, num_threads);
+
+    PR_Cleanup();
+
+	if (failed_already)
+		return 1;
+	else
+    	return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/io_timeoutk.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/io_timeoutk.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,233 @@
+/* -*- 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 io_timeoutk.c
+** Description:Test socket IO timeouts (kernel level)
+**
+** 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include "nspr.h"
+
+#define NUM_THREADS 1
+#define BASE_PORT   8000
+#define DEFAULT_ACCEPT_TIMEOUT 2
+
+typedef struct threadInfo {
+    PRInt16 id;
+    PRInt16 accept_timeout;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32   *alive;
+} threadInfo;
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+void 
+thread_main(void *_info)
+{
+    threadInfo *info = (threadInfo *)_info;
+    PRNetAddr listenAddr;
+    PRNetAddr clientAddr;
+    PRFileDesc *listenSock = NULL;
+    PRFileDesc *clientSock;
+    PRStatus rv;
+ 
+    if (debug_mode) printf("thread %d is alive\n", info->id);
+
+    listenSock = PR_NewTCPSocket();
+    if (!listenSock) {
+        if (debug_mode) printf("unable to create listen socket\n");
+        goto dead;
+    }
+  
+    listenAddr.inet.family = AF_INET;
+    listenAddr.inet.port = PR_htons(BASE_PORT + info->id);
+    listenAddr.inet.ip = PR_htonl(INADDR_ANY);
+    rv = PR_Bind(listenSock, &listenAddr);
+    if (rv == PR_FAILURE) {
+        if (debug_mode) printf("unable to bind\n");
+        goto dead;
+    }
+
+    rv = PR_Listen(listenSock, 4);
+    if (rv == PR_FAILURE) {
+        if (debug_mode) printf("unable to listen\n");
+        goto dead;
+    }
+
+    if (debug_mode) printf("thread %d going into accept for %d seconds\n", 
+        info->id, info->accept_timeout + info->id);
+
+    clientSock = PR_Accept(listenSock, &clientAddr, PR_SecondsToInterval(info->accept_timeout +info->id));
+
+    if (clientSock == NULL) {
+        if (PR_GetError() == PR_IO_TIMEOUT_ERROR) 
+            if (debug_mode) {
+				printf("PR_Accept() timeout worked!\n");
+                printf("TEST FAILED! PR_Accept() returned error %d\n",
+								   PR_GetError());
+			}
+			else failed_already=1;
+    } else {
+        if (debug_mode) printf ("TEST FAILED! PR_Accept() succeeded?\n");
+		else failed_already=1;
+	PR_Close(clientSock);
+    }
+
+dead:
+    if (listenSock) {
+	PR_Close(listenSock);
+    }
+    PR_Lock(info->dead_lock);
+    (*info->alive)--;
+    PR_NotifyCondVar(info->dead_cv);
+    PR_Unlock(info->dead_lock);
+
+    if (debug_mode) printf("thread %d is dead\n", info->id);
+}
+
+void
+thread_test(PRInt32 scope, PRInt32 num_threads)
+{
+    PRInt32 index;
+    PRThread *thr;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32 alive;
+
+    if (debug_mode) printf("IO Timeout test started with %d threads\n", num_threads);
+
+    dead_lock = PR_NewLock();
+    dead_cv = PR_NewCondVar(dead_lock);
+    alive = num_threads;
+    
+    for (index = 0; index < num_threads; index++) {
+        threadInfo *info = (threadInfo *)malloc(sizeof(threadInfo));
+
+        info->id = index;
+        info->dead_lock = dead_lock;
+        info->dead_cv = dead_cv;
+        info->alive = &alive;
+        info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT;
+        
+        thr = PR_CreateThread( PR_USER_THREAD,
+                               thread_main,
+                               (void *)info,
+                               PR_PRIORITY_NORMAL,
+                               scope,
+                               PR_UNJOINABLE_THREAD,
+                               0);
+
+        if (!thr) {
+            PR_Lock(dead_lock);
+            alive--;
+            PR_Unlock(dead_lock);
+        }
+    }
+
+    PR_Lock(dead_lock);
+    while(alive) {
+        if (debug_mode) printf("main loop awake; alive = %d\n", alive);
+        PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(dead_lock);
+}
+
+int main(int argc, char **argv)
+{
+    PRInt32 num_threads;
+
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    if (argc > 2)
+        num_threads = atoi(argv[2]);
+    else
+        num_threads = NUM_THREADS;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode)     printf("kernel level test\n");
+    thread_test(PR_GLOBAL_THREAD, num_threads);
+
+     PR_Cleanup();
+     
+     if(failed_already)    
+        return 1;
+    else
+        return 0;
+
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/io_timeoutu.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/io_timeoutu.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,234 @@
+/* -*- 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 io_timeoutu.c
+** Description: Test socket IO timeouts (user level)
+**
+** 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include "nspr.h"
+
+#define NUM_THREADS 1
+#define BASE_PORT   8000
+#define DEFAULT_ACCEPT_TIMEOUT 2
+
+typedef struct threadInfo {
+    PRInt16 id;
+    PRInt16 accept_timeout;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32   *alive;
+} threadInfo;
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+void 
+thread_main(void *_info)
+{
+    threadInfo *info = (threadInfo *)_info;
+    PRNetAddr listenAddr;
+    PRNetAddr clientAddr;
+    PRFileDesc *listenSock = NULL;
+    PRFileDesc *clientSock;
+    PRStatus rv;
+ 
+    if (debug_mode) printf("thread %d is alive\n", info->id);
+
+    listenSock = PR_NewTCPSocket();
+    if (!listenSock) {
+        if (debug_mode) printf("unable to create listen socket\n");
+        goto dead;
+    }
+  
+    listenAddr.inet.family = AF_INET;
+    listenAddr.inet.port = PR_htons(BASE_PORT + info->id);
+    listenAddr.inet.ip = PR_htonl(INADDR_ANY);
+    rv = PR_Bind(listenSock, &listenAddr);
+    if (rv == PR_FAILURE) {
+        if (debug_mode) printf("unable to bind\n");
+        goto dead;
+    }
+
+    rv = PR_Listen(listenSock, 4);
+    if (rv == PR_FAILURE) {
+        if (debug_mode) printf("unable to listen\n");
+        goto dead;
+    }
+
+    if (debug_mode) printf("thread %d going into accept for %d seconds\n", 
+        info->id, info->accept_timeout + info->id);
+
+    clientSock = PR_Accept(
+		listenSock, &clientAddr, PR_SecondsToInterval(
+			info->accept_timeout + info->id));
+
+    if (clientSock == NULL) {
+        if (PR_GetError() == PR_IO_TIMEOUT_ERROR) 
+            if (debug_mode) {
+				printf("PR_Accept() timeout worked!\n");
+                printf("TEST FAILED! PR_Accept() returned error %d\n",
+			}
+								   PR_GetError());
+			else failed_already=1;
+    } else {
+        if (debug_mode) printf ("TEST FAILED! PR_Accept() succeeded?\n");
+		else failed_already=1;
+	PR_Close(clientSock);
+    }
+
+dead:
+    if (listenSock) {
+	PR_Close(listenSock);
+    }
+    PR_Lock(info->dead_lock);
+    (*info->alive)--;
+    PR_NotifyCondVar(info->dead_cv);
+    PR_Unlock(info->dead_lock);
+
+    if (debug_mode) printf("thread %d is dead\n", info->id);
+}
+
+void
+thread_test(PRInt32 scope, PRInt32 num_threads)
+{
+    PRInt32 index;
+    PRThread *thr;
+    PRLock *dead_lock;
+    PRCondVar *dead_cv;
+    PRInt32 alive;
+
+    if (debug_mode) printf("IO Timeout test started with %d threads\n", num_threads);
+
+    dead_lock = PR_NewLock();
+    dead_cv = PR_NewCondVar(dead_lock);
+    alive = num_threads;
+    
+    for (index = 0; index < num_threads; index++) {
+        threadInfo *info = (threadInfo *)malloc(sizeof(threadInfo));
+
+        info->id = index;
+        info->dead_lock = dead_lock;
+        info->dead_cv = dead_cv;
+        info->alive = &alive;
+        info->accept_timeout = DEFAULT_ACCEPT_TIMEOUT;
+        
+        thr = PR_CreateThread( PR_USER_THREAD,
+                               thread_main,
+                               (void *)info,
+                               PR_PRIORITY_NORMAL,
+                               scope,
+                               PR_UNJOINABLE_THREAD,
+                               0);
+
+        if (!thr) {
+            PR_Lock(dead_lock);
+            alive--;
+            PR_Unlock(dead_lock);
+        }
+    }
+
+    PR_Lock(dead_lock);
+    while(alive) {
+        if (debug_mode) printf("main loop awake; alive = %d\n", alive);
+        PR_WaitCondVar(dead_cv, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(dead_lock);
+}
+
+int main(int argc, char **argv)
+{
+    PRInt32 num_threads;
+
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    if (argc > 2)
+        num_threads = atoi(argv[2]);
+    else
+        num_threads = NUM_THREADS;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_LOW, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) printf("user level test\n");
+    thread_test(PR_LOCAL_THREAD, num_threads);
+
+     PR_Cleanup();
+     if(failed_already)    
+        return 1;
+     else
+        return 0;
+     
+
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/ioconthr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/ioconthr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,146 @@
+/* -*- 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 ***** */
+
+/*
+ * This is a test for the io continuation thread machinery
+ * in pthreads.
+ */
+
+#include "nspr.h"
+#include <stdio.h>
+
+int num_threads = 10;  /* must be an even number */
+PRThreadScope thread_scope = PR_GLOBAL_THREAD;
+
+void ThreadFunc(void *arg)
+{
+    PRFileDesc *fd = (PRFileDesc *) arg;
+    char buf[1024];
+    PRInt32 nbytes;
+    PRErrorCode err;
+
+    nbytes = PR_Recv(fd, buf, sizeof(buf), 0, PR_SecondsToInterval(20));
+    if (nbytes == -1) {
+        err = PR_GetError();
+        if (err != PR_PENDING_INTERRUPT_ERROR) {
+            fprintf(stderr, "PR_Recv failed: (%d, %d)\n",
+                    err, PR_GetOSError());
+            PR_ProcessExit(1);
+        }
+        /*
+         * After getting an I/O interrupt, this thread must
+         * close the fd before it exits due to a limitation
+         * of our NT implementation.
+         */
+        if (PR_Close(fd) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            PR_ProcessExit(1);
+        }
+    } else {
+        fprintf(stderr, "PR_Recv received %d bytes!?\n", nbytes);
+        PR_ProcessExit(1);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc **fds;
+    PRThread **threads;
+    PRIntervalTime start, elapsed;
+    int index;
+
+    fds = (PRFileDesc **) PR_MALLOC(2 * num_threads * sizeof(PRFileDesc *));
+    PR_ASSERT(fds != NULL);
+    threads = (PRThread **) PR_MALLOC(num_threads * sizeof(PRThread *));
+    PR_ASSERT(threads != NULL);
+
+    for (index = 0; index < num_threads; index++) {
+        if (PR_NewTCPSocketPair(&fds[2 * index]) == PR_FAILURE) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            PR_ProcessExit(1);
+        }
+        threads[index] = PR_CreateThread(
+                PR_USER_THREAD, ThreadFunc, fds[2 * index],
+                PR_PRIORITY_NORMAL, thread_scope, PR_JOINABLE_THREAD, 0);
+        if (NULL == threads[index]) {
+            fprintf(stderr, "PR_CreateThread failed\n");
+            PR_ProcessExit(1);
+        }
+    }
+
+    /* Let the threads block in PR_Recv */
+    PR_Sleep(PR_SecondsToInterval(2));
+
+    printf("Interrupting the threads\n");
+    fflush(stdout);
+    start = PR_IntervalNow();
+    for (index = 0; index < num_threads; index++) {
+        if (PR_Interrupt(threads[index]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Interrupt failed\n");
+            PR_ProcessExit(1);
+        }
+    }
+    for (index = 0; index < num_threads; index++) {
+        if (PR_JoinThread(threads[index]) == PR_FAILURE) {
+            fprintf(stderr, "PR_JoinThread failed\n");
+            PR_ProcessExit(1);
+        }
+    }
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start);
+    printf("Threads terminated in %d milliseconds\n",
+            PR_IntervalToMilliseconds(elapsed));
+    fflush(stdout);
+    
+    /* We are being very generous and allow 10 seconds. */
+    if (elapsed >= PR_SecondsToInterval(10)) {
+        fprintf(stderr, "Interrupting threads took longer than 10 seconds!!\n");
+        PR_ProcessExit(1);
+    }
+
+    for (index = 0; index < num_threads; index++) {
+        /* fds[2 * index] was passed to and closed by threads[index]. */
+        if (PR_Close(fds[2 * index + 1]) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            PR_ProcessExit(1);
+        }
+    }
+    PR_DELETE(threads);
+    PR_DELETE(fds);
+    printf("PASS\n");
+    PR_Cleanup();
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/ipv6.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/ipv6.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,248 @@
+/* -*- 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 "prio.h"
+#include "prenv.h"
+#include "prmem.h"
+#include "prlink.h"
+#include "prsystem.h"
+#include "prnetdb.h"
+#include "prprf.h"
+#include "prvrsion.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+#include "obsolete/probslet.h"
+
+#include <string.h>
+
+#define DNS_BUFFER 100
+#define ADDR_BUFFER 100
+#define HOST_BUFFER 1024
+#define PROTO_BUFFER 1500
+
+#define NETADDR_SIZE(addr) \
+    (PR_AF_INET == (addr)->raw.family ? \
+    sizeof((addr)->inet) : sizeof((addr)->ipv6))
+
+static PRFileDesc *err = NULL;
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: [-V] [-h]\n");
+    PR_fprintf(err, "\t<nul>    Name of host to lookup          (default: self)\n");
+    PR_fprintf(err, "\t-V       Display runtime version info    (default: FALSE)\n");
+    PR_fprintf(err, "\t-h       This message and nothing else\n");
+}  /* Help */
+
+static void DumpAddr(const PRNetAddr* address, const char *msg)
+{
+    PRUint32 *word = (PRUint32*)address;
+    PRUint32 addr_len = sizeof(PRNetAddr);
+    PR_fprintf(err, "%s[%d]\t", msg, NETADDR_SIZE(address));
+    while (addr_len > 0)
+    {
+        PR_fprintf(err, " %08x", *word++);
+        addr_len -= sizeof(PRUint32);
+    }
+    PR_fprintf(err, "\n");
+}  /* DumpAddr */
+
+static PRStatus PrintAddress(const PRNetAddr* address)
+{
+    PRNetAddr translation;
+    char buffer[ADDR_BUFFER];
+    PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
+    if (PR_FAILURE == rv) PL_FPrintError(err, "PR_NetAddrToString");
+    else
+    {
+        PR_fprintf(err, "\t%s\n", buffer);
+        memset(&translation, 0, sizeof(translation));
+        rv = PR_StringToNetAddr(buffer, &translation);
+        if (PR_FAILURE == rv) PL_FPrintError(err, "PR_StringToNetAddr");
+        else
+        {
+            PRSize addr_len = NETADDR_SIZE(address);
+            if (0 != memcmp(address, &translation, addr_len))
+            {
+                PR_fprintf(err, "Address translations do not match\n");
+                DumpAddr(address, "original");
+                DumpAddr(&translation, "translate");
+                rv = PR_FAILURE;
+            }
+        }
+    }
+    return rv;
+}  /* PrintAddress */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    PLOptStatus os;
+    PRHostEnt host;
+    PRProtoEnt proto;
+    const char *name = NULL;
+    PRBool failed = PR_FALSE, version = PR_FALSE;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "Vh");
+
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:  /* Name of host to lookup */
+            name = opt->value;
+            break;
+         case 'V':  /* Do version discovery */
+            version = PR_TRUE;
+            break;
+        case 'h':  /* user wants some guidance */
+         default:
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (version)
+    {
+#if defined(WINNT)
+#define NSPR_LIB "libnspr4"
+#else
+#define NSPR_LIB "nspr4"
+#endif
+        const PRVersionDescription *version_info;
+        char *nspr_path = PR_GetEnv("LD_LIBRARY_PATH");
+        char *nspr_name = PR_GetLibraryName(nspr_path, NSPR_LIB);
+        PRLibrary *runtime = PR_LoadLibrary(nspr_name);
+        if (NULL == runtime)
+            PL_FPrintError(err, "PR_LoadLibrary");
+        else
+        {
+            versionEntryPointType versionPoint = (versionEntryPointType)
+                PR_FindSymbol(runtime, "libVersionPoint");
+            if (NULL == versionPoint)
+                PL_FPrintError(err, "PR_FindSymbol");
+            else
+            {
+                char buffer[100];
+                PRExplodedTime exploded;
+                version_info = versionPoint();
+                (void)PR_fprintf(err, "Runtime library version information\n");
+                PR_ExplodeTime(
+                    version_info->buildTime, PR_GMTParameters, &exploded);
+                (void)PR_FormatTime(
+                    buffer, sizeof(buffer), "%d %b %Y %H:%M:%S", &exploded);
+                (void)PR_fprintf(err, "  Build time: %s GMT\n", buffer);
+                (void)PR_fprintf(
+                    err, "  Build time: %s\n", version_info->buildTimeString);
+                (void)PR_fprintf(
+                    err, "  %s V%u.%u.%u (%s%s%s)\n",
+                    version_info->description,
+                    version_info->vMajor,
+                    version_info->vMinor,
+                    version_info->vPatch,
+                    (version_info->beta ? " beta " : ""),
+                    (version_info->debug ? " debug " : ""),
+                    (version_info->special ? " special" : ""));
+                (void)PR_fprintf(err, "  filename: %s\n", version_info->filename);
+                (void)PR_fprintf(err, "  security: %s\n", version_info->security);
+                (void)PR_fprintf(err, "  copyright: %s\n", version_info->copyright);
+                (void)PR_fprintf(err, "  comment: %s\n", version_info->comment);
+            }
+        }
+        if (NULL != nspr_name) PR_FreeLibraryName(nspr_name);
+    }
+
+    {
+        if (NULL == name)
+        {
+            char *me = (char*)PR_MALLOC(DNS_BUFFER);
+            rv = PR_GetSystemInfo(PR_SI_HOSTNAME, me, DNS_BUFFER);
+            if (PR_FAILURE == rv)
+            {
+                failed = PR_TRUE;
+                PL_FPrintError(err, "PR_GetSystemInfo");
+                return 2;
+            }
+            name = me;  /* just leak the storage */
+        }
+    }
+
+    {
+        char buffer[HOST_BUFFER];
+        PR_fprintf(err, "Translating the name %s ...", name);
+
+        rv = PR_GetHostByName(name, buffer, sizeof(buffer), &host);
+        if (PR_FAILURE == rv)
+        {
+            failed = PR_TRUE;
+            PL_FPrintError(err, "PR_GetHostByName");
+        }
+        else
+        {
+            PRIntn index = 0;
+            PRNetAddr address;
+            memset(&address, 0, sizeof(PRNetAddr));
+            PR_fprintf(err, "success .. enumerating results\n");
+            do
+            {
+                index = PR_EnumerateHostEnt(index, &host, 0, &address);
+                if (index > 0) PrintAddress(&address);
+                else if (-1 == index)
+                {
+                    failed = PR_TRUE;
+                    PL_FPrintError(err, "PR_EnumerateHostEnt");
+                }
+            } while (index > 0);
+        }
+    }
+
+
+    {
+        char buffer[PROTO_BUFFER];
+        /*
+        ** Get Proto by name/number
+        */
+        rv = PR_GetProtoByName("tcp", &buffer[1], sizeof(buffer) - 1, &proto);
+        rv = PR_GetProtoByNumber(6, &buffer[3], sizeof(buffer) - 3, &proto);
+    }
+
+    return (failed) ? 1 : 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/join.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/join.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,264 @@
+/* -*- 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: dbmalloc1.c
+**
+** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions.
+**
+** Modification History:
+** 
+** 19-May-97 AGarcia - separate the four join tests into different unit test modules.
+**		    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. 
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+#include "prttools.h"
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+/***********************************************************************
+** PRIVATE FUNCTION:    Test_Result
+** DESCRIPTION: Used in conjunction with the regress tool, prints out the
+**		        status of the test case.
+** INPUTS:      PASS/FAIL
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:   Determine what the status is and print accordingly.
+**      
+***********************************************************************/
+
+
+static void Test_Result (int result)
+{
+    if (result == PASS)
+        printf ("PASS\n");
+    else
+        printf ("FAIL\n");
+    exit (1);
+}
+
+
+/*
+    Program to test joining of threads.  Two threads are created.  One
+    to be waited upon until it has started.  The other to join after it has
+    completed.
+*/
+
+
+static void PR_CALLBACK lowPriority(void *arg)
+{
+}
+
+static void PR_CALLBACK highPriority(void *arg)
+{
+}
+
+static void PR_CALLBACK unjoinable(void *arg)
+{
+    PR_Sleep(PR_INTERVAL_NO_TIMEOUT);
+}
+
+void runTest(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *low,*high;
+
+    /* create the low and high priority threads */
+    
+    low = PR_CreateThread(PR_USER_THREAD,
+                     lowPriority, 0, 
+                     PR_PRIORITY_LOW,
+                     scope1,
+                     PR_JOINABLE_THREAD,
+                     0);
+    if (!low) {
+        if (debug_mode) printf("\tcannot create low priority thread\n");
+        else Test_Result(FAIL);
+        return;
+    }
+
+    high = PR_CreateThread(PR_USER_THREAD,
+                     highPriority, 0, 
+                     PR_PRIORITY_HIGH,
+                     scope2,
+                     PR_JOINABLE_THREAD,
+                     0);
+    if (!high) {
+        if (debug_mode) printf("\tcannot create high priority thread\n");
+        else Test_Result(FAIL);
+        return;
+    }
+
+    /* Do the joining for both threads */
+    if (PR_JoinThread(low) == PR_FAILURE) {
+        if (debug_mode) printf("\tcannot join low priority thread\n");
+        else Test_Result (FAIL);
+        return;
+    } else {
+        if (debug_mode) printf("\tjoined low priority thread\n");
+    }
+    if (PR_JoinThread(high) == PR_FAILURE) {
+        if (debug_mode) printf("\tcannot join high priority thread\n");
+        else Test_Result(FAIL);
+        return;
+    } else {
+        if (debug_mode) printf("\tjoined high priority thread\n");
+    }
+}
+
+void joinWithUnjoinable(void)
+{
+    PRThread *thread;
+
+    /* create the unjoinable thread */
+    
+    thread = PR_CreateThread(PR_USER_THREAD,
+                     unjoinable, 0, 
+                     PR_PRIORITY_NORMAL,
+                     PR_GLOBAL_THREAD,
+                     PR_UNJOINABLE_THREAD,
+                     0);
+    if (!thread) {
+        if (debug_mode) printf("\tcannot create unjoinable thread\n");
+        else Test_Result(FAIL);
+        return;
+    }
+
+    if (PR_JoinThread(thread) == PR_SUCCESS) {
+        if (debug_mode) printf("\tsuccessfully joined with unjoinable thread?!\n");
+        else Test_Result(FAIL);
+        return;
+    } else {
+        if (debug_mode) printf("\tcannot join with unjoinable thread, as expected\n");
+        if (PR_GetError() != PR_INVALID_ARGUMENT_ERROR) {
+            if (debug_mode) printf("\tWrong error code\n");
+            else Test_Result(FAIL);
+            return;
+        }
+    }
+    if (PR_Interrupt(thread) == PR_FAILURE) {
+        if (debug_mode) printf("\tcannot interrupt unjoinable thread\n");
+        else Test_Result(FAIL);
+        return;
+    } else {
+        if (debug_mode) printf("\tinterrupted unjoinable thread\n");
+    }
+}
+
+static PRIntn PR_CALLBACK RealMain(int argc, char **argv)
+{
+    /* 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, "d:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+#ifdef XP_MAC
+    SetupMacPrintfLog("join.log");
+    debug_mode = 1;
+#endif
+
+    
+    
+ /* main test */
+    printf("User-User test\n");
+    runTest(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+    printf("User-Kernel test\n");
+    runTest(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+    printf("Kernel-User test\n");
+    runTest(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+    printf("Kernel-Kernel test\n");
+    runTest(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+    printf("Join with unjoinable thread\n");
+    joinWithUnjoinable();
+
+    printf("PASSED\n");
+
+    return 0;
+}
+
+
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/joinkk.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/joinkk.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,193 @@
+/* -*- 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: dbmalloc1.c
+**
+** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions.
+**
+** Modification History:
+** 
+** 19-May-97 AGarcia - separate the four join tests into different unit test modules.
+**			 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#endif
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+/*
+	Program to test joining of threads.  Two threads are created.  One
+	to be waited upon until it has started.  The other to join after it has
+	completed.
+*/
+
+
+static void lowPriority(void *arg)
+{
+}
+
+static void highPriority(void *arg)
+{
+}
+
+void runTest(PRThreadScope scope1, PRThreadScope scope2)
+{
+	PRThread *low,*high;
+
+	/* create the low and high priority threads */
+	
+	low = PR_CreateThread(PR_USER_THREAD,
+				      lowPriority, 0, 
+				      PR_PRIORITY_LOW,
+				      scope1,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!low) {
+		if (debug_mode) printf("\tcannot create low priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	high = PR_CreateThread(PR_USER_THREAD,
+				      highPriority, 0, 
+				      PR_PRIORITY_HIGH,
+				      scope2,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!high) {
+		if (debug_mode) printf("\tcannot create high priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	/* Do the joining for both threads */
+	if (PR_JoinThread(low) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join low priority thread\n");
+		else  failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined low priority thread\n");
+    }
+	if (PR_JoinThread(high) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join high priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined high priority thread\n");
+    }
+}
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("join.log");
+#endif
+
+	
+	
+ /* main test */
+
+    if (debug_mode) printf("Kernel-Kernel test\n");
+    runTest(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+
+	if(failed_already)	
+	{
+        printf("FAIL\n");
+		return 1;
+	}
+	else
+	{
+        printf("PASS\n");
+		return 0;
+	}
+
+}
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/joinku.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/joinku.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,199 @@
+/* -*- 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: dbmalloc1.c
+**
+** Description: Tests PR_SetMallocCountdown PR_ClearMallocCountdown functions.
+**
+** Modification History:
+** 
+** 19-May-97 AGarcia - separate the four join tests into different unit test modules.
+**			 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#endif
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+/*
+	Program to test joining of threads.  Two threads are created.  One
+	to be waited upon until it has started.  The other to join after it has
+	completed.
+*/
+
+
+static void lowPriority(void *arg)
+{
+}
+
+static void highPriority(void *arg)
+{
+}
+
+void runTest(PRThreadScope scope1, PRThreadScope scope2)
+{
+	PRThread *low,*high;
+
+	/* create the low and high priority threads */
+	
+	low = PR_CreateThread(PR_USER_THREAD,
+				      lowPriority, 0, 
+				      PR_PRIORITY_LOW,
+				      scope1,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!low) {
+		if (debug_mode) printf("\tcannot create low priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	high = PR_CreateThread(PR_USER_THREAD,
+				      highPriority, 0, 
+				      PR_PRIORITY_HIGH,
+				      scope2,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!high) {
+		if (debug_mode) printf("\tcannot create high priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	/* Do the joining for both threads */
+	if (PR_JoinThread(low) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join low priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined low priority thread\n");
+    }
+	if (PR_JoinThread(high) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join high priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined high priority thread\n");
+    }
+}
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("joinku.log");
+#endif
+
+	
+	
+ /* main test */
+
+    if (debug_mode) printf("Kernel-User test\n");
+    runTest(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+
+
+	if(failed_already)	
+    {
+		printf("FAIL\n");    
+		return 1;
+	}
+	else
+	{
+		printf("PASS\n");    
+		return 0;
+	}
+
+}
+
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/joinuk.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/joinuk.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,195 @@
+/* -*- 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: joinuk.c
+**
+** Description: Join kernel - user
+**
+** Modification History:
+** 
+** 19-May-97 AGarcia - separate the four join tests into different unit test modules.
+**			 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#endif
+PRIntn failed_already=0;
+PRIntn debug_mode;
+/*
+	Program to test joining of threads.  Two threads are created.  One
+	to be waited upon until it has started.  The other to join after it has
+	completed.
+*/
+
+
+static void lowPriority(void *arg)
+{
+}
+
+static void highPriority(void *arg)
+{
+}
+
+void runTest(PRThreadScope scope1, PRThreadScope scope2)
+{
+	PRThread *low,*high;
+
+	/* create the low and high priority threads */
+	
+	low = PR_CreateThread(PR_USER_THREAD,
+				      lowPriority, 0, 
+				      PR_PRIORITY_LOW,
+				      scope1,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!low) {
+		if (debug_mode) printf("\tcannot create low priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	high = PR_CreateThread(PR_USER_THREAD,
+				      highPriority, 0, 
+				      PR_PRIORITY_HIGH,
+				      scope2,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!high) {
+		if (debug_mode) printf("\tcannot create high priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	/* Do the joining for both threads */
+	if (PR_JoinThread(low) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join low priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined low priority thread\n");
+    }
+	if (PR_JoinThread(high) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join high priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined high priority thread\n");
+    }
+}
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("joinuk.log");
+#endif
+
+	
+	
+ /* main test */
+
+    if (debug_mode) printf("User-Kernel test\n");
+    runTest(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+
+
+	if(failed_already)	
+	{
+        printf("FAIL\n");
+		return 1;
+    } else 
+    {
+        printf("PASS\n");
+		return 0;
+    }
+}
+
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/joinuu.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/joinuu.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,197 @@
+/* -*- 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: dbmalloc1.c
+**
+** Description: Join tests user - user
+**
+** Modification History:
+** 
+** 19-May-97 AGarcia - separate the four join tests into different unit test modules.
+**			 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#endif
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+/*
+	Program to test joining of threads.  Two threads are created.  One
+	to be waited upon until it has started.  The other to join after it has
+	completed.
+*/
+
+
+static void lowPriority(void *arg)
+{
+}
+
+static void highPriority(void *arg)
+{
+}
+
+void runTest(PRThreadScope scope1, PRThreadScope scope2)
+{
+	PRThread *low,*high;
+
+	/* create the low and high priority threads */
+	
+	low = PR_CreateThread(PR_USER_THREAD,
+				      lowPriority, 0, 
+				      PR_PRIORITY_LOW,
+				      scope1,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!low) {
+		if (debug_mode) printf("\tcannot create low priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	high = PR_CreateThread(PR_USER_THREAD,
+				      highPriority, 0, 
+				      PR_PRIORITY_HIGH,
+				      scope2,
+    				  PR_JOINABLE_THREAD,
+				      0);
+	if (!high) {
+		if (debug_mode) printf("\tcannot create high priority thread\n");
+		else failed_already=1;
+		return;
+	}
+
+	/* Do the joining for both threads */
+	if (PR_JoinThread(low) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join low priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined low priority thread\n");
+    }
+	if (PR_JoinThread(high) == PR_FAILURE) {
+		if (debug_mode) printf("\tcannot join high priority thread\n");
+		else failed_already=1;
+		return;
+	} else {
+    	if (debug_mode) printf("\tjoined high priority thread\n");
+    }
+}
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("joinuu.log");
+#endif
+
+	
+	
+ /* main test */
+    if (debug_mode) printf("User-User test\n");
+    runTest(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+
+	if(failed_already)	
+	{
+        printf("FAIL\n");
+		return 1;
+    } else 
+    {
+        printf("PASS\n");
+		return 0;
+    }
+
+
+}
+
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/layer.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/layer.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,466 @@
+/* -*- 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 "prio.h"
+#include "prprf.h"
+#include "prlog.h"
+#include "prnetdb.h"
+#include "prthread.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+#include "prwin16.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Testing layering of I/O
+**
+**      The layered server
+** A thread that acts as a server. It creates a TCP listener with a dummy
+** layer pushed on top. Then listens for incoming connections. Each connection
+** request for connection will be layered as well, accept one request, echo
+** it back and close.
+**
+**      The layered client
+** Pretty much what you'd expect.
+*/
+
+static PRFileDesc *logFile;
+static PRDescIdentity identity;
+static PRNetAddr server_address;
+
+static PRIOMethods myMethods;
+
+typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity;
+
+static PRIntn minor_iterations = 5;
+static PRIntn major_iterations = 1;
+static Verbosity verbosity = quiet;
+static PRUint16 default_port = 12273;
+
+static PRFileDesc *PushLayer(PRFileDesc *stack)
+{
+    PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods);
+    PRStatus rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return stack;
+}  /* PushLayer */
+
+static PRFileDesc *PushNewLayers(PRFileDesc *stack)
+{
+	PRDescIdentity tmp_identity;
+    PRFileDesc *layer;
+    PRStatus rv;
+
+	/* push a dummy layer */
+    tmp_identity = PR_GetUniqueIdentity("Dummy 1");
+    layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods());
+    rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer,
+															stack);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+	/* push a data procesing layer */
+    layer = PR_CreateIOLayerStub(identity, &myMethods);
+    rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer,
+													stack);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+	/* push another dummy layer */
+    tmp_identity = PR_GetUniqueIdentity("Dummy 2");
+    layer = PR_CreateIOLayerStub(tmp_identity, PR_GetDefaultIOMethods());
+    rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer,
+															stack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return stack;
+}  /* PushLayer */
+
+#if 0
+static PRFileDesc *PopLayer(PRFileDesc *stack)
+{
+    PRFileDesc *popped = PR_PopIOLayer(stack, identity);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack);
+    popped->dtor(popped);
+    
+    return stack;
+}  /* PopLayer */
+#endif
+
+static void PR_CALLBACK Client(void *arg)
+{
+    PRStatus rv;
+    PRUint8 buffer[100];
+    PRIntn empty_flags = 0;
+    PRIntn bytes_read, bytes_sent;
+    PRFileDesc *stack = (PRFileDesc*)arg;
+
+    /* Initialize the buffer so that Purify won't complain */
+    memset(buffer, 0, sizeof(buffer));
+
+    rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT);
+    PR_ASSERT(PR_SUCCESS == rv);
+    while (minor_iterations-- > 0)
+    {
+        bytes_sent = PR_Send(
+            stack, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT);
+        PR_ASSERT(sizeof(buffer) == bytes_sent);
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Client sending %d bytes\n", bytes_sent);
+        bytes_read = PR_Recv(
+            stack, buffer, bytes_sent, empty_flags, PR_INTERVAL_NO_TIMEOUT);
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Client receiving %d bytes\n", bytes_read);
+        PR_ASSERT(bytes_read == bytes_sent);
+    }
+
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Client shutting down stack\n");
+    
+    rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
+}  /* Client */
+
+static void PR_CALLBACK Server(void *arg)
+{
+    PRStatus rv;
+    PRUint8 buffer[100];
+    PRFileDesc *service;
+    PRUintn empty_flags = 0;
+    PRIntn bytes_read, bytes_sent;
+    PRFileDesc *stack = (PRFileDesc*)arg;
+    PRNetAddr client_address;
+
+    service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Server accepting connection\n");
+
+    do
+    {
+        bytes_read = PR_Recv(
+            service, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT);
+        if (0 != bytes_read)
+        {
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server receiving %d bytes\n", bytes_read);
+            PR_ASSERT(bytes_read > 0);
+            bytes_sent = PR_Send(
+                service, buffer, bytes_read, empty_flags, PR_INTERVAL_NO_TIMEOUT);
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server sending %d bytes\n", bytes_sent);
+            PR_ASSERT(bytes_read == bytes_sent);
+        }
+
+    } while (0 != bytes_read);
+
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Server shutting down and closing stack\n");
+    rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+
+}  /* Server */
+
+static PRInt32 PR_CALLBACK MyRecv(
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    char *b = (char*)buf;
+    PRFileDesc *lo = fd->lower;
+    PRInt32 rv, readin = 0, request = 0;
+    rv = lo->methods->recv(lo, &request, sizeof(request), flags, timeout);
+    if (verbosity > chatty) PR_fprintf(
+        logFile, "MyRecv sending permission for %d bytes\n", request);
+    if (0 < rv)
+    {
+        if (verbosity > chatty) PR_fprintf(
+            logFile, "MyRecv received permission request for %d bytes\n", request);
+        rv = lo->methods->send(
+            lo, &request, sizeof(request), flags, timeout);
+        if (0 < rv)
+        {
+            if (verbosity > chatty) PR_fprintf(
+                logFile, "MyRecv sending permission for %d bytes\n", request);
+            while (readin < request)
+            {
+                rv = lo->methods->recv(
+                    lo, b + readin, amount - readin, flags, timeout);
+                if (rv <= 0) break;
+                if (verbosity > chatty) PR_fprintf(
+                    logFile, "MyRecv received %d bytes\n", rv);
+                readin += rv;
+            }
+            rv = readin;
+        }
+    }
+    return rv;
+}  /* MyRecv */
+
+static PRInt32 PR_CALLBACK MySend(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    PRFileDesc *lo = fd->lower;
+    const char *b = (const char*)buf;
+    PRInt32 rv, wroteout = 0, request;
+    if (verbosity > chatty) PR_fprintf(
+        logFile, "MySend asking permission to send %d bytes\n", amount);
+    rv = lo->methods->send(lo, &amount, sizeof(amount), flags, timeout);
+    if (0 < rv)
+    {
+        rv = lo->methods->recv(
+            lo, &request, sizeof(request), flags, timeout);
+        if (0 < rv)
+        {
+            PR_ASSERT(request == amount);
+            if (verbosity > chatty) PR_fprintf(
+                logFile, "MySend got permission to send %d bytes\n", request);
+            while (wroteout < request)
+            {
+                rv = lo->methods->send(
+                    lo, b + wroteout, request - wroteout, flags, timeout);
+                if (rv <= 0) break;
+                if (verbosity > chatty) PR_fprintf(
+                    logFile, "MySend wrote %d bytes\n", rv);
+                wroteout += rv;
+            }
+            rv = amount;
+        }
+    }
+    return rv;
+}  /* MySend */
+
+static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta)
+{
+    PRIntn verbage = (PRIntn)verbosity + delta;
+    if (verbage < (PRIntn)silent) verbage = (PRIntn)silent;
+    else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy;
+    return (Verbosity)verbage;
+}  /* ChangeVerbosity */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    PRIntn mits;
+    PLOptStatus os;
+    PRFileDesc *client, *service;
+    PRFileDesc *client_stack, *service_stack;
+    PRNetAddr any_address;
+    const char *server_name = NULL;
+    const PRIOMethods *stubMethods;
+    PRThread *client_thread, *server_thread;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:
+            server_name = opt->value;
+            break;
+        case 'd':  /* debug mode */
+            if (verbosity < noisy)
+                verbosity = ChangeVerbosity(verbosity, 1);
+            break;
+        case 'q':  /* debug mode */
+            if (verbosity > silent)
+                verbosity = ChangeVerbosity(verbosity, -1);
+            break;
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'C':  /* number of threads waiting */
+            major_iterations = atoi(opt->value);
+            break;
+        case 'c':  /* number of client threads */
+            minor_iterations = atoi(opt->value);
+            break;
+        case 'p':  /* default port */
+            default_port = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+    PR_STDIO_INIT();
+
+    logFile = PR_GetSpecialFD(PR_StandardError);
+
+    identity = PR_GetUniqueIdentity("Dummy");
+    stubMethods = PR_GetDefaultIOMethods();
+
+    /*
+    ** The protocol we're going to implement is one where in order to initiate
+    ** a send, the sender must first solicit permission. Therefore, every
+    ** send is really a send - receive - send sequence.
+    */
+    myMethods = *stubMethods;  /* first get the entire batch */
+    myMethods.recv = MyRecv;  /* then override the ones we care about */
+    myMethods.send = MySend;  /* then override the ones we care about */
+
+    if (NULL == server_name)
+        rv = PR_InitializeNetAddr(
+            PR_IpAddrLoopback, default_port, &server_address);
+    else
+    {
+        rv = PR_StringToNetAddr(server_name, &server_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_InitializeNetAddr(
+            PR_IpAddrNull, default_port, &server_address);
+    }
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    /* one type w/o layering */
+
+    mits = minor_iterations;
+    while (major_iterations-- > 0)
+    {
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Beginning non-layered test\n");
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
+
+        minor_iterations = mits;
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, service,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, client,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Ending non-layered test\n");
+
+        /* with layering */
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Beginning layered test\n");
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+        PushLayer(client);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+        PushLayer(service);
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
+
+        minor_iterations = mits;
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, service,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, client,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+        /* with layering, using new style stack */
+        if (verbosity > silent)
+            PR_fprintf(logFile,
+							"Beginning layered test with new style stack\n");
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+    	client_stack = PR_CreateIOLayer(client);
+        PushNewLayers(client_stack);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+    	service_stack = PR_CreateIOLayer(service);
+        PushNewLayers(service_stack);
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
+
+        minor_iterations = mits;
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, service_stack,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, client_stack,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(client_stack); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(service_stack); PR_ASSERT(PR_SUCCESS == rv);
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Ending layered test\n");
+    }
+    return 0;
+}  /* main */
+
+/* layer.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/lazyinit.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/lazyinit.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,139 @@
+/* -*- 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:        lazyinit.c
+** Description: Testing lazy initialization
+**
+**      Since you only get to initialize once, you have to rerun the test
+**      for each test case. The test cases are numbered. If you want to
+**      add more tests, take the next number and add it to the switch
+**      statement.
+**
+**      This test is problematic on systems that don't support the notion
+**      of console output. The workarounds to emulate that feature include
+**      initializations themselves, which defeats the purpose here.
+*/
+
+#include "prcvar.h"
+#include "prenv.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prthread.h"
+#include "prtypes.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static void PR_CALLBACK lazyEntry(void *arg)
+{
+    PR_ASSERT(NULL == arg);
+}  /* lazyEntry */
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRUintn pdkey;
+    PRStatus status;
+    char *path = NULL;
+    PRDir *dir = NULL;
+    PRLock *ml = NULL;
+    PRCondVar *cv = NULL;
+    PRThread *thread = NULL;
+    PRIntervalTime interval = 0;
+    PRFileDesc *file, *udp, *tcp, *pair[2];
+    PRIntn test;
+
+    if ( argc < 2)
+    {
+        test = 0;
+    }
+    else
+        test = atoi(argv[1]);
+        
+    switch (test)
+    {
+        case 0: ml = PR_NewLock(); 
+            break;
+            
+        case 1: interval = PR_SecondsToInterval(1);
+            break;
+            
+        case 2: thread = PR_CreateThread(
+            PR_USER_THREAD, lazyEntry, NULL, PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); 
+            break;
+            
+        case 3: file = PR_Open("/usr/tmp/", PR_RDONLY, 0); 
+            break;
+            
+        case 4: udp = PR_NewUDPSocket(); 
+            break;
+            
+        case 5: tcp = PR_NewTCPSocket(); 
+            break;
+            
+        case 6: dir = PR_OpenDir("/usr/tmp/"); 
+            break;
+            
+        case 7: (void)PR_NewThreadPrivateIndex(&pdkey, NULL);
+            break;
+        
+        case 8: path = PR_GetEnv("PATH");
+            break;
+            
+        case 9: status = PR_NewTCPSocketPair(pair);
+            break;
+            
+        case 10: PR_SetConcurrency(2);
+            break;
+            
+        default: 
+            printf(
+                "lazyinit: unrecognized command line argument: %s\n", 
+                argv[1] );
+            printf( "FAIL\n" );
+            exit( 1 );
+            break;
+    } /* switch() */
+    return 0;
+}  /* Lazy */
+
+/* lazyinit.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/libfilename.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/libfilename.c	Mon Dec 18 10:53:47 2006
@@ -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) 2003
+ * 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: libfilename.c
+**
+** Description: test PR_GetLibraryFilePathname.
+**
+***********************************************************************/
+
+#include "nspr.h"
+#include "pprio.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRBool debug_mode = PR_FALSE;
+
+static PRStatus RunTest(const char *name, PRFuncPtr addr)
+{
+    char *pathname;
+    PRFileDesc *fd;
+
+    pathname = PR_GetLibraryFilePathname(name, addr);
+    if (pathname == NULL) {
+        fprintf(stderr, "PR_GetLibraryFilePathname failed\n");
+        /* we let this test pass if this function is not implemented */
+        if (PR_GetError() == PR_NOT_IMPLEMENTED_ERROR) {
+            return PR_SUCCESS;
+        }
+        return PR_FAILURE;
+    }
+
+    if (debug_mode) printf("Pathname is %s\n", pathname);
+    fd = PR_OpenFile(pathname, PR_RDONLY, 0);
+    if (fd == NULL) {
+        fprintf(stderr, "PR_Open failed: %d\n", (int)PR_GetError());
+        return PR_FAILURE;
+    }
+    if (PR_Close(fd) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed: %d\n", (int)PR_GetError());
+        return PR_FAILURE;
+    }
+    PR_Free(pathname);
+    return PR_SUCCESS;
+}
+
+int main(int argc, char *argv[])
+{
+    char *name;
+    PRFuncPtr addr;
+    PRLibrary *lib;
+    PRBool failed = PR_FALSE;
+
+    if (argc >= 2 && strcmp(argv[1], "-d") == 0) {
+        debug_mode = PR_TRUE;
+    }
+
+    /* First test a library that is implicitly linked. */
+#ifdef WINNT
+    name = PR_Malloc(strlen("libnspr4.dll")+1);
+    strcpy(name, "libnspr4.dll");
+#else
+    name = PR_GetLibraryName(NULL, "nspr4");
+#endif
+    addr = (PRFuncPtr)PR_GetTCPMethods()->close;
+    if (RunTest(name, addr) == PR_FAILURE) {
+        failed = PR_TRUE;
+    }
+    PR_FreeLibraryName(name);
+
+    /* Next test a library that is dynamically loaded. */
+    name = PR_GetLibraryName("dll", "my");
+    if (debug_mode) printf("Loading library %s\n", name);
+    lib = PR_LoadLibrary(name);
+    if (!lib) {
+        fprintf(stderr, "PR_LoadLibrary failed\n");
+        exit(1);
+    }
+    PR_FreeLibraryName(name);
+    name = PR_GetLibraryName(NULL, "my");
+    addr = PR_FindFunctionSymbol(lib, "My_GetValue");
+    if (RunTest(name, addr) == PR_FAILURE) {
+        failed = PR_TRUE;
+    }
+    PR_FreeLibraryName(name);
+    PR_UnloadLibrary(lib);
+    if (failed) {
+        printf("FAIL\n");
+        return 1;
+    }
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/lltest.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/lltest.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,859 @@
+/* -*- 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 ***** */
+ 
+/*
+** testll.c -- test suite for 64bit integer (longlong) operations
+**
+** Summary: testll [-d] | [-h]
+**
+** Where:
+** -d       set debug mode on; displays individual test failures
+** -v       verbose mode; displays progress in test, plus -d
+** -h       gives usage message.
+**
+** Description:
+** lltest.c tests the functions defined in NSPR 2.0's prlong.h.
+** 
+** Successive tests begin to depend on other LL functions working
+** correctly. So, ... Do not change the order of the tests as run
+** from main().
+** 
+** Caveats:
+** Do not even begin to think that this is an exhaustive test!
+**
+** These tests try a little of everything, but not all boundary
+** conditions and limits are tested.
+** You want better coverage? ... Add it.
+**
+** ---
+** Author: Lawrence Hardiman <larryh at netscape.com>.
+** ---
+** Revision History:
+** 01-Oct-1997. Original implementation.
+**
+*/
+
+#include "nspr.h"
+#include "plgetopt.h"
+
+/* --- Local Definitions --- */
+#define ReportProgress(m) if (verboseMode) PR_fprintf(output, (m));
+
+
+/* --- Global variables --- */
+static PRIntn  failedAlready = 0;
+static PRFileDesc* output = NULL;
+static PRBool  debugMode = PR_FALSE;
+static PRBool  verboseMode = PR_FALSE;
+
+/*
+** Constants used in tests.
+*/
+const PRInt64 bigZero        = LL_INIT( 0, 0 );
+const PRInt64 bigOne         = LL_INIT( 0, 1 );
+const PRInt64 bigTwo         = LL_INIT( 0, 2 );
+const PRInt64 bigSixTeen     = LL_INIT( 0, 16 );        
+const PRInt64 bigThirtyTwo   = LL_INIT( 0, 32 );        
+const PRInt64 bigMinusOne    = LL_INIT( 0xffffffff, 0xffffffff );
+const PRInt64 bigMinusTwo    = LL_INIT( 0xffffffff, 0xfffffffe );
+const PRInt64 bigNumber      = LL_INIT( 0x7fffffff, 0xffffffff );
+const PRInt64 bigMinusNumber = LL_INIT( 0x80000000, 0x00000001 );
+const PRInt64 bigMaxInt32    = LL_INIT( 0x00000000, 0x7fffffff );
+const PRInt64 big2To31       = LL_INIT( 0x00000000, 0x80000000 );
+const PRUint64 bigZeroFox    = LL_INIT( 0x00000000, 0xffffffff );
+const PRUint64 bigFoxFox     = LL_INIT( 0xffffffff, 0xffffffff );
+const PRUint64 bigFoxZero    = LL_INIT( 0xffffffff, 0x00000000 );
+const PRUint64 bigEightZero  = LL_INIT( 0x80000000, 0x00000000 );
+const PRUint64 big64K        = LL_INIT( 0x00000000, 0x00010000 );
+const PRInt64 bigInt0        = LL_INIT( 0x01a00000, 0x00001000 );
+const PRInt64 bigInt1        = LL_INIT( 0x01a00000, 0x00001100 );
+const PRInt64 bigInt2        = LL_INIT( 0x01a00000, 0x00000100 );
+const PRInt64 bigInt3        = LL_INIT( 0x01a00001, 0x00001000 );
+const PRInt64 bigInt4        = LL_INIT( 0x01a00001, 0x00001100 );
+const PRInt64 bigInt5        = LL_INIT( 0x01a00001, 0x00000100 );
+const PRInt64 bigInt6        = LL_INIT( 0xb1a00000, 0x00001000 );
+const PRInt64 bigInt7        = LL_INIT( 0xb1a00000, 0x00001100 );
+const PRInt64 bigInt8        = LL_INIT( 0xb1a00000, 0x00000100 );
+const PRInt64 bigInt9        = LL_INIT( 0xb1a00001, 0x00001000 );
+const PRInt64 bigInt10       = LL_INIT( 0xb1a00001, 0x00001100 );
+const PRInt64 bigInt11       = LL_INIT( 0xb1a00001, 0x00000100 );
+const PRInt32 one = 1l;
+const PRInt32 minusOne = -1l;
+const PRInt32 sixteen  = 16l;
+const PRInt32 thirtyTwo = 32l;
+const PRInt32   sixtyThree = 63l;
+
+/*
+** SetFailed() -- Report individual test failure
+**
+*/
+static void
+SetFailed( char *what, char *how )
+{
+    failedAlready = 1;
+    if ( debugMode )
+        PR_fprintf(output, "%s: failed: %s\n", what, how );
+    return;
+}
+
+static void
+ResultFailed( char *what, char *how, PRInt64 expected, PRInt64 got)
+{
+    if ( debugMode)
+    {
+        SetFailed( what, how );
+        PR_fprintf(output, "Expected: 0x%llx   Got: 0x%llx\n", expected, got );
+    }
+    return;
+}    
+
+
+/*
+** TestAssignment() -- Test the assignment
+*/
+static void TestAssignment( void )
+{
+    PRInt64 zero = LL_Zero();
+    PRInt64 min = LL_MinInt();
+    PRInt64 max = LL_MaxInt();
+    if (!LL_EQ(zero, bigZero))
+        SetFailed("LL_EQ(zero, bigZero)", "!=");
+    if (!LL_CMP(max, >, min))
+        SetFailed("LL_CMP(max, >, min)", "!>");
+}
+
+/*
+** TestComparisons() -- Test the longlong comparison operations
+*/
+static void    
+TestComparisons( void )
+{
+    ReportProgress("Testing Comparisons Operations\n");
+         
+    /* test for zero */   
+    if ( !LL_IS_ZERO( bigZero ))
+        SetFailed( "LL_IS_ZERO", "Zero is not zero" );
+        
+    if ( LL_IS_ZERO( bigOne ))
+        SetFailed( "LL_IS_ZERO", "One tests as zero" );
+    
+    if ( LL_IS_ZERO( bigMinusOne ))
+        SetFailed( "LL_IS_ZERO", "Minus One tests as zero" );
+        
+    /* test equal */
+    if ( !LL_EQ( bigZero, bigZero ))
+        SetFailed( "LL_EQ", "zero EQ zero");
+        
+    if ( !LL_EQ( bigOne, bigOne ))
+        SetFailed( "LL_EQ", "one EQ one" );
+        
+    if ( !LL_EQ( bigNumber, bigNumber ))
+        SetFailed( "LL_EQ", "bigNumber EQ bigNumber" );
+        
+    if ( !LL_EQ( bigMinusOne, bigMinusOne ))
+        SetFailed( "LL_EQ", "minus one EQ minus one");
+    
+    if ( LL_EQ( bigZero, bigOne ))
+        SetFailed( "LL_EQ", "zero EQ one");
+        
+    if ( LL_EQ( bigOne, bigZero ))
+        SetFailed( "LL_EQ", "one EQ zero" );
+        
+    if ( LL_EQ( bigMinusOne, bigOne ))
+        SetFailed( "LL_EQ", "minus one EQ one");
+        
+    if ( LL_EQ( bigNumber, bigOne ))
+        SetFailed( "LL_EQ", "bigNumber EQ one");
+    
+    /* test not equal */
+    if ( LL_NE( bigZero, bigZero ))
+        SetFailed( "LL_NE", "0 NE 0");
+    
+    if ( LL_NE( bigOne, bigOne ))
+        SetFailed( "LL_NE", "1 NE 1");
+    
+    if ( LL_NE( bigMinusOne, bigMinusOne ))
+        SetFailed( "LL_NE", "-1 NE -1");
+    
+    if ( LL_NE( bigNumber, bigNumber ))
+        SetFailed( "LL_NE", "n NE n");
+    
+    if ( LL_NE( bigMinusNumber, bigMinusNumber ))
+        SetFailed( "LL_NE", "-n NE -n");
+        
+    if ( !LL_NE( bigZero, bigOne))
+        SetFailed( "LL_NE", "0 NE 1");
+    
+    if ( !LL_NE( bigOne, bigMinusNumber))
+        SetFailed( "LL_NE", "1 NE -n");
+        
+    /* Greater than or equal to zero */
+    if ( !LL_GE_ZERO( bigZero ))
+        SetFailed( "LL_GE_ZERO", "0");
+    
+    if ( !LL_GE_ZERO( bigOne ))
+        SetFailed( "LL_GE_ZERO", "1");
+    
+    if ( !LL_GE_ZERO( bigNumber ))
+        SetFailed( "LL_GE_ZERO", "n");
+    
+    if ( LL_GE_ZERO( bigMinusOne ))
+        SetFailed( "LL_GE_ZERO", "-1");
+        
+    if ( LL_GE_ZERO( bigMinusNumber ))
+        SetFailed( "LL_GE_ZERO", "-n");
+        
+    /* Algebraic Compare two values */
+    if ( !LL_CMP( bigZero, ==, bigZero ))
+        SetFailed( "LL_CMP", "0 == 0");
+    
+    if ( LL_CMP( bigZero, >, bigZero ))
+        SetFailed( "LL_CMP", "0 > 0");
+        
+    if ( LL_CMP( bigZero, <, bigZero ))
+        SetFailed( "LL_CMP", "0 < 0");
+        
+    if ( LL_CMP( bigNumber, <, bigOne ))
+        SetFailed( "LL_CMP", "n < 1");
+        
+    if ( !LL_CMP( bigNumber, >, bigOne ))
+        SetFailed( "LL_CMP", "n <= 1");
+        
+    if ( LL_CMP( bigOne, >, bigNumber ))
+        SetFailed( "LL_CMP", "1 > n");
+        
+    if ( LL_CMP( bigMinusNumber, >, bigNumber ))
+        SetFailed( "LL_CMP", "-n > n");
+        
+    if ( LL_CMP( bigNumber, !=, bigNumber))
+        SetFailed( "LL_CMP", "n != n");
+
+    if ( !LL_CMP( bigMinusOne, >, bigMinusTwo ))
+        SetFailed( "LL_CMP", "-1 <= -2");
+
+    if ( !LL_CMP( bigMaxInt32, <, big2To31 ))
+        SetFailed( "LL_CMP", "Max 32-bit signed int >= 2^31");
+
+    /* Two positive numbers */
+    if ( !LL_CMP( bigInt0, <=, bigInt0 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt0, <=, bigInt1 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( LL_CMP( bigInt0, <=, bigInt2 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt0, <=, bigInt3 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt0, <=, bigInt4 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt0, <=, bigInt5 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    /* Two negative numbers */
+    if ( !LL_CMP( bigInt6, <=, bigInt6 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt6, <=, bigInt7 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( LL_CMP( bigInt6, <=, bigInt8 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt6, <=, bigInt9 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt6, <=, bigInt10 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( !LL_CMP( bigInt6, <=, bigInt11 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    /* One positive, one negative */
+    if ( LL_CMP( bigInt0, <=, bigInt6 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( LL_CMP( bigInt0, <=, bigInt7 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    if ( LL_CMP( bigInt0, <=, bigInt8 ))
+        SetFailed( "LL_CMP", "LL_CMP(<=) failed");
+
+    /* Bitwise Compare two numbers */
+    if ( !LL_UCMP( bigZero, ==, bigZero ))
+        SetFailed( "LL_UCMP", "0 == 0");
+    
+    if ( LL_UCMP( bigZero, >, bigZero ))
+        SetFailed( "LL_UCMP", "0 > 0");
+        
+    if ( LL_UCMP( bigZero, <, bigZero ))
+        SetFailed( "LL_UCMP", "0 < 0");
+        
+    if ( LL_UCMP( bigNumber, <, bigOne ))
+        SetFailed( "LL_UCMP", "n < 1");
+        
+    if ( !LL_UCMP( bigNumber, >, bigOne ))
+        SetFailed( "LL_UCMP", "n < 1");
+        
+    if ( LL_UCMP( bigOne, >, bigNumber ))
+        SetFailed( "LL_UCMP", "1 > n");
+        
+    if ( LL_UCMP( bigMinusNumber, <, bigNumber ))
+        SetFailed( "LL_UCMP", "-n < n");
+
+    /* Two positive numbers */
+    if ( !LL_UCMP( bigInt0, <=, bigInt0 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt1 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( LL_UCMP( bigInt0, <=, bigInt2 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt3 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt4 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt5 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    /* Two negative numbers */
+    if ( !LL_UCMP( bigInt6, <=, bigInt6 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt6, <=, bigInt7 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( LL_UCMP( bigInt6, <=, bigInt8 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt6, <=, bigInt9 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt6, <=, bigInt10 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt6, <=, bigInt11 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    /* One positive, one negative */
+    if ( !LL_UCMP( bigInt0, <=, bigInt6 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt7 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    if ( !LL_UCMP( bigInt0, <=, bigInt8 ))
+        SetFailed( "LL_UCMP", "LL_UCMP(<=) failed");
+
+    return;
+}
+
+/*
+**  TestLogicalOperations() -- Tests for AND, OR, ...
+**
+*/
+static void
+TestLogicalOperations( void )
+{
+    PRUint64    result, result2;
+    
+    ReportProgress("Testing Logical Operations\n");
+    
+    /* Test AND */
+    LL_AND( result, bigZero, bigZero );
+    if ( !LL_IS_ZERO( result ))
+        ResultFailed( "LL_AND", "0 & 0", bigZero, result );
+    
+    LL_AND( result, bigOne, bigOne );
+    if ( LL_IS_ZERO( result ))
+        ResultFailed( "LL_AND", "1 & 1", bigOne, result );
+
+    LL_AND( result, bigZero, bigOne );
+    if ( !LL_IS_ZERO( result ))
+        ResultFailed( "LL_AND", "1 & 1", bigZero, result );
+
+    LL_AND( result, bigMinusOne, bigMinusOne );
+    if ( !LL_UCMP( result, ==, bigMinusOne ))
+        ResultFailed( "LL_AND", "-1 & -1", bigMinusOne, result );
+        
+    /* test OR */
+    LL_OR( result, bigZero, bigZero );
+    if ( !LL_IS_ZERO( result ))
+        ResultFailed( "LL_OR", "0 | 1", bigZero, result);
+    
+    LL_OR( result, bigZero, bigOne );
+    if ( LL_IS_ZERO( result ))
+        ResultFailed( "LL_OR", "0 | 1", bigOne, result );
+    
+    LL_OR( result, bigZero, bigMinusNumber );
+    if ( !LL_UCMP( result, ==, bigMinusNumber ))
+        ResultFailed( "LL_OR", "0 | -n", bigMinusNumber, result);
+    
+    LL_OR( result, bigMinusNumber, bigZero );
+    if ( !LL_UCMP( result, ==, bigMinusNumber ))
+        ResultFailed( "LL_OR", "-n | 0", bigMinusNumber, result );
+    
+    /* test XOR */
+    LL_XOR( result, bigZero, bigZero );
+    if ( LL_UCMP( result, !=, bigZero ))
+        ResultFailed( "LL_XOR", "0 ^ 0", bigZero, result);
+    
+    LL_XOR( result, bigOne, bigZero );
+    if ( LL_UCMP( result, !=, bigOne ))
+        ResultFailed( "LL_XOR", "1 ^ 0", bigZero, result );
+        
+    LL_XOR( result, bigMinusNumber, bigZero );
+    if ( LL_UCMP( result, !=, bigMinusNumber ))
+        ResultFailed( "LL_XOR", "-n ^ 0", bigMinusNumber, result );
+    
+    LL_XOR( result, bigMinusNumber, bigMinusNumber );
+    if ( LL_UCMP( result, !=, bigZero ))
+        ResultFailed( "LL_XOR", "-n ^ -n", bigMinusNumber, result);
+        
+    /* test OR2.  */
+    result = bigZero;
+    LL_OR2( result, bigOne );
+    if ( LL_UCMP( result, !=, bigOne ))
+        ResultFailed( "LL_OR2", "(r=0) |= 1", bigOne, result);
+        
+    result = bigOne;
+    LL_OR2( result, bigNumber );
+    if ( LL_UCMP( result, !=, bigNumber ))
+        ResultFailed( "LL_OR2", "(r=1) |= n", bigNumber, result);
+
+    result = bigMinusNumber;
+    LL_OR2( result, bigMinusNumber );
+    if ( LL_UCMP( result, !=, bigMinusNumber ))
+        ResultFailed( "LL_OR2", "(r=-n) |= -n", bigMinusNumber, result);
+
+    /* test NOT */
+    LL_NOT( result, bigMinusNumber);
+    LL_NOT( result2, result);
+    if ( LL_UCMP( result2, !=, bigMinusNumber ))
+        ResultFailed( "LL_NOT", "r != ~(~-n)", bigMinusNumber, result);
+            
+    /* test Negation */
+    LL_NEG( result, bigMinusNumber );
+    LL_NEG( result2, result );
+    if ( LL_CMP( result2, !=, bigMinusNumber ))
+        ResultFailed( "LL_NEG", "r != -(-(-n))", bigMinusNumber, result);
+
+    return;
+}
+
+
+
+/*
+**  TestConversion() -- Test Conversion Operations
+**
+*/
+static void
+TestConversion( void )
+{
+    PRInt64     result;
+    PRInt64     resultU;
+    PRInt32     result32;
+    PRUint32    resultU32;
+    float       resultF;
+    PRFloat64   resultD;
+    
+    ReportProgress("Testing Conversion Operations\n");
+    
+    /* LL_L2I  -- Convert to signed 32bit */
+    LL_L2I(result32, bigOne );
+    if ( result32 != one )  
+        SetFailed( "LL_L2I", "r != 1");
+    
+    LL_L2I(result32, bigMinusOne );
+    if ( result32 != minusOne )  
+        SetFailed( "LL_L2I", "r != -1");
+    
+    /* LL_L2UI -- Convert 64bit to unsigned 32bit */
+    LL_L2UI( resultU32, bigMinusOne );
+    if ( resultU32 != (PRUint32) minusOne )
+        SetFailed( "LL_L2UI", "r != -1");
+    
+    LL_L2UI( resultU32, bigOne );
+    if ( resultU32 != (PRUint32) one )
+        SetFailed( "LL_L2UI", "r != 1");
+        
+    /* LL_L2F  -- Convert to 32bit floating point */
+    LL_L2F( resultF, bigOne );
+    if ( resultF != 1.0 )
+        SetFailed( "LL_L2F", "r != 1.0");
+        
+    LL_L2F( resultF, bigMinusOne );
+    if ( resultF != -1.0 )
+        SetFailed( "LL_L2F", "r != 1.0");
+    
+    /* LL_L2D  -- Convert to 64bit floating point */
+    LL_L2D( resultD, bigOne );
+    if ( resultD != 1.0L )
+        SetFailed( "LL_L2D", "r != 1.0");
+        
+    LL_L2D( resultD, bigMinusOne );
+    if ( resultD != -1.0L )
+        SetFailed( "LL_L2D", "r != -1.0");
+        
+    /* LL_I2L  -- Convert 32bit signed to 64bit signed */
+    LL_I2L( result, one );
+    if ( LL_CMP(result, !=, bigOne ))
+        SetFailed( "LL_I2L", "r != 1");
+        
+    LL_I2L( result, minusOne );
+    if ( LL_CMP(result, !=, bigMinusOne ))
+        SetFailed( "LL_I2L", "r != -1");
+        
+    /* LL_UI2L -- Convert 32bit unsigned to 64bit unsigned */
+    LL_UI2L( resultU, (PRUint32) one );
+    if ( LL_CMP(resultU, !=, bigOne ))
+        SetFailed( "LL_UI2L", "r != 1");
+        
+    /* [lth.] This did not behave as expected, but it is correct 
+    */
+    LL_UI2L( resultU, (PRUint32) minusOne );
+    if ( LL_CMP(resultU, !=, bigZeroFox ))
+        ResultFailed( "LL_UI2L", "r != -1", bigZeroFox, resultU);
+        
+    /* LL_F2L  -- Convert 32bit float to 64bit signed */
+    LL_F2L( result, 1.0 );
+    if ( LL_CMP(result, !=, bigOne ))
+        SetFailed( "LL_F2L", "r != 1");
+        
+    LL_F2L( result, -1.0 );
+    if ( LL_CMP(result, !=, bigMinusOne ))
+        SetFailed( "LL_F2L", "r != -1");
+    
+    /* LL_D2L  -- Convert 64bit Float to 64bit signed */
+    LL_D2L( result, 1.0L );
+    if ( LL_CMP(result, !=, bigOne ))
+        SetFailed( "LL_D2L", "r != 1");
+        
+    LL_D2L( result, -1.0L );
+    if ( LL_CMP(result, !=, bigMinusOne ))
+        SetFailed( "LL_D2L", "r != -1");
+
+    return;
+}
+
+static void ShiftCompileOnly()
+{
+    /*
+    ** This function is only compiled, never called.
+    ** The real test is to see if it compiles w/o
+    ** warnings. This is no small feat, by the way.
+    */
+    PRInt64 ia, ib;
+    PRUint64 ua, ub;
+    LL_SHR(ia, ib, 32);
+    LL_SHL(ia, ib, 32);
+
+    LL_USHR(ua, ub, 32);
+    LL_ISHL(ia, 49, 32);
+
+}  /* ShiftCompileOnly */
+   
+
+/*
+**  TestShift() -- Test Shifting Operations
+**
+*/
+static void
+TestShift( void )
+{
+    static const PRInt64 largeTwoZero = LL_INIT( 0x00000002, 0x00000000 );
+    PRInt64     result;
+    PRUint64    resultU;
+
+    ReportProgress("Testing Shifting Operations\n");
+    
+    /* LL_SHL  -- Shift left algebraic */
+    LL_SHL( result, bigOne, one );
+    if ( LL_CMP( result, !=, bigTwo ))
+        ResultFailed( "LL_SHL", "r != 2", bigOne, result );
+    
+    LL_SHL( result, bigTwo, thirtyTwo );
+    if ( LL_CMP( result, !=, largeTwoZero ))
+        ResultFailed( "LL_SHL", "r != twoZero", largeTwoZero, result);
+    
+    /* LL_SHR  -- Shift right algebraic */
+    LL_SHR( result, bigFoxZero, thirtyTwo );
+    if ( LL_CMP( result, !=, bigMinusOne ))
+        ResultFailed( "LL_SHR", "r != -1", bigMinusOne, result);
+    
+    LL_SHR( result, bigTwo, one );
+    if ( LL_CMP( result, !=, bigOne ))
+        ResultFailed( "LL_SHR", "r != 1", bigOne, result);
+
+    LL_SHR( result, bigFoxFox, thirtyTwo );
+    if ( LL_CMP( result, !=, bigMinusOne ))
+        ResultFailed( "LL_SHR", "r != -1 (was ff,ff)", bigMinusOne, result);
+    
+    /* LL_USHR -- Logical shift right */
+    LL_USHR( resultU, bigZeroFox, thirtyTwo );
+    if ( LL_UCMP( resultU, !=, bigZero ))
+        ResultFailed( "LL_USHR", "r != 0 ", bigZero, result);
+    
+    LL_USHR( resultU, bigFoxFox, thirtyTwo );
+    if ( LL_UCMP( resultU, !=, bigZeroFox ))
+        ResultFailed( "LL_USHR", "r != 0 ", bigZeroFox, result);
+    
+    /* LL_ISHL -- Shift a 32bit integer into a 64bit result */
+    LL_ISHL( resultU, minusOne, thirtyTwo );
+    if ( LL_UCMP( resultU, !=, bigFoxZero ))
+        ResultFailed( "LL_ISHL", "r != ff,00 ", bigFoxZero, result);
+    
+    LL_ISHL( resultU, one, sixtyThree );
+    if ( LL_UCMP( resultU, !=, bigEightZero ))
+        ResultFailed( "LL_ISHL", "r != 80,00 ", bigEightZero, result);
+    
+    LL_ISHL( resultU, one, sixteen );
+    if ( LL_UCMP( resultU, !=, big64K ))
+        ResultFailed( "LL_ISHL", "r != 64K ", big64K, resultU);
+    
+    return;
+}    
+
+
+/*
+**  TestArithmetic() -- Test arithmetic operations.
+**
+*/
+static void
+TestArithmetic( void )
+{
+    PRInt64 largeVal          = LL_INIT( 0x00000001, 0xffffffff );
+    PRInt64 largeValPlusOne   = LL_INIT( 0x00000002, 0x00000000 );
+    PRInt64 largeValTimesTwo  = LL_INIT( 0x00000003, 0xfffffffe );
+    PRInt64 largeMultCand     = LL_INIT( 0x00000000, 0x7fffffff );
+    PRInt64 largeMinusMultCand = LL_INIT( 0xffffffff, 0x10000001 );
+    PRInt64 largeMultCandx64K = LL_INIT( 0x00007fff, 0xffff0000 );
+    PRInt64 largeNumSHL5      = LL_INIT( 0x0000001f, 0xffffffe0 );        
+    PRInt64 result, result2;
+
+    /* Addition */    
+    LL_ADD( result, bigOne, bigOne );
+    if ( LL_CMP( result, !=, bigTwo ))
+        ResultFailed( "LL_ADD", "r != 1 + 1", bigTwo, result);
+
+    LL_ADD( result, bigMinusOne, bigOne );
+    if ( LL_CMP( result, !=, bigZero ))
+        ResultFailed( "LL_ADD", "r != -1 + 1", bigOne, result);
+
+    LL_ADD( result, largeVal, bigOne );
+    if ( LL_CMP( result, !=, largeValPlusOne ))
+        ResultFailed( "LL_ADD", "lVP1 != lV + 1", largeValPlusOne, result);
+            
+    /* Subtraction */
+    LL_SUB( result, bigOne, bigOne );
+    if ( LL_CMP( result, !=, bigZero ))
+        ResultFailed( "LL_SUB", "r != 1 - 1", bigZero, result);
+            
+    LL_SUB( result, bigTwo, bigOne );
+    if ( LL_CMP( result, !=, bigOne ))
+        ResultFailed( "LL_SUB", "r != 2 - 1", bigOne, result);
+            
+    LL_SUB( result, largeValPlusOne, bigOne );
+    if ( LL_CMP( result, !=, largeVal ))
+        ResultFailed( "LL_SUB", "r != lVP1 - 1", largeVal, result);
+            
+    
+    /* Multiply */
+    LL_MUL( result, largeVal, bigTwo );
+    if ( LL_CMP( result, !=, largeValTimesTwo ))
+        ResultFailed( "LL_MUL", "r != lV*2", largeValTimesTwo, result);
+    
+    LL_MUL( result, largeMultCand, big64K );
+    if ( LL_CMP( result, !=, largeMultCandx64K ))
+        ResultFailed( "LL_MUL", "r != lV*64K", largeMultCandx64K, result);
+        
+    LL_NEG( result2, largeMultCand );
+    LL_MUL( result, largeMultCand, bigMinusOne );
+    if ( LL_CMP( result, !=, result2  ))
+        ResultFailed( "LL_MUL", "r != -lMC", result2, result);
+
+    LL_SHL( result2, bigZeroFox, 5);
+    LL_MUL( result, bigZeroFox, bigThirtyTwo );
+    if ( LL_CMP( result, !=, largeNumSHL5  ))
+        ResultFailed( "LL_MUL", "r != 0f<<5", largeNumSHL5, result );
+
+    
+
+    /* LL_DIV() Division */
+    LL_DIV( result, bigOne, bigOne);
+    if ( LL_CMP( result, !=, bigOne ))
+        ResultFailed( "LL_DIV", "1 != 1", bigOne, result);
+    
+    LL_DIV( result, bigNumber, bigOne );
+    if ( LL_CMP( result, !=, bigNumber  ))
+        ResultFailed( "LL_DIV", "r != n / 1", bigNumber, result);
+
+    LL_DIV( result, bigNumber, bigMinusOne );
+    if ( LL_CMP( result, !=, bigMinusNumber  ))
+        ResultFailed( "LL_DIV", "r != n / -1", bigMinusNumber, result);
+
+    LL_DIV( result, bigMinusNumber, bigMinusOne );
+    if ( LL_CMP( result, !=, bigNumber  ))
+        ResultFailed( "LL_DIV", "r != -n / -1", bigNumber, result);
+        
+    LL_SHL( result2, bigZeroFox, 5 );
+    LL_DIV( result, result2, bigOne );
+    if ( LL_CMP( result, !=, result2  ))
+        ResultFailed( "LL_DIV", "0f<<5 != 0f<<5", result2, result);
+    
+    LL_SHL( result2, bigZeroFox, 5 );
+    LL_NEG( result2, result2 );
+    LL_DIV( result, result2, bigOne );
+    if ( LL_CMP( result, !=, result2  ))
+        ResultFailed( "LL_DIV", "-0f<<5 != -0f<<5", result2, result);
+    
+    LL_SHL( result2, bigZeroFox, 17 );
+    LL_DIV( result, result2, bigMinusOne );
+    LL_NEG( result2, result2 );
+    if ( LL_CMP( result, !=, result2  ))
+        ResultFailed( "LL_DIV", "-0f<<17 != -0f<<17", result2, result);
+    
+    
+    /* LL_MOD() Modulo Division */
+    LL_ADD( result2, bigThirtyTwo, bigOne );
+    LL_MOD( result, result2, bigSixTeen );
+    if ( LL_CMP( result, !=, bigOne ))
+        ResultFailed( "LL_MOD", "r != 1", bigSixTeen, result);
+    
+    
+    LL_MUL( result2, bigZeroFox, bigThirtyTwo );
+    LL_ADD( result2, result2, bigSixTeen);
+    LL_MOD( result, result2, bigThirtyTwo );
+    if ( LL_CMP( result, !=, bigSixTeen ))
+        ResultFailed( "LL_MOD", "r != 16", bigSixTeen, result);
+
+    /* LL_UDIVMOD */
+    LL_DIV( result, bigOne, bigOne);
+    if ( LL_CMP( result, !=, bigOne ))
+        ResultFailed( "LL_DIV", "r != 16", bigSixTeen, result);
+    
+
+    return;
+} 
+
+static void TestWellknowns(void)
+{
+    PRInt64 max = LL_MAXINT, min = LL_MININT, zero = LL_ZERO;
+    PRInt64 mmax = LL_MaxInt(), mmin = LL_MinInt(), mzero = LL_Zero();
+    if (LL_NE(max, mmax))
+        ResultFailed( "max, mmax", "max != mmax", max, mmax);
+    if (LL_NE(min, mmin))
+        ResultFailed( "min, mmin", "min != mmin", max, mmin);
+    if (LL_NE(zero, mzero))
+        ResultFailed( "zero, mzero", "zero != mzero", zero, mzero);
+}  /* TestWellknowns */ 
+
+/*
+** Initialize() -- Initialize the test case
+**
+** Parse command line options
+**
+*/
+static PRIntn
+Initialize( PRIntn argc, char **argv )
+{
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dvh");
+    PLOptStatus os;
+
+    /*
+    ** Parse command line options
+    */    
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* set debug mode */
+            debugMode = PR_TRUE;
+            break;
+            
+        case 'v':  /* set verbose mode */
+            verboseMode = PR_TRUE;
+            debugMode = PR_TRUE;
+            break;
+            
+        case 'h':  /* user wants some guidance */
+        default:
+            PR_fprintf(output, "You get help.\n");
+            return(1);
+        }
+    }
+    PL_DestroyOptState(opt);
+    return(0);
+}    
+
+PRIntn main( int argc, char **argv )
+{
+    PR_STDIO_INIT();
+    output = PR_GetSpecialFD(PR_StandardError);
+
+    if ( Initialize( argc, argv ))
+        return(1);
+
+    TestAssignment();
+    TestComparisons();
+    TestLogicalOperations();
+    TestConversion();
+    TestShift();
+    TestArithmetic();
+    TestWellknowns();
+    
+    /*
+    ** That's all folks!
+    */
+    if ( failedAlready )
+    {
+        PR_fprintf(output, "FAIL\n");\
+    } 
+    else
+    {
+        PR_fprintf(output, "PASS\n");\
+    }
+    return failedAlready;
+} /* end main() */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/lock.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/lock.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,547 @@
+/* -*- 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:        lock.c
+** Purpose:     test basic locking functions
+**
+** Modification History:
+** 14-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.
+**
+** 11-Aug-97 LarryH. Win16 port of NSPR.
+**           - Added "PASS", "FAIL" messages on completion.
+**           - Change stack variables to static scope variables
+**             because of shadow-stack use by Win16
+**           - Added PR_CALLBACK attribute to functions called by NSPR
+**           - Added command line arguments:
+**             - l <num> to control the number of loops
+**             - c <num> to control the number of CPUs.
+**             (was positional argv).
+** 
+**
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prio.h"
+#include "prcmon.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prprf.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmon.h"
+#include "prmem.h"
+#include "prthread.h"
+#include "prtypes.h"
+
+#include "plstr.h"
+
+#include <stdlib.h>
+
+#if defined(XP_UNIX)
+#include <string.h>
+#endif
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+static PRIntn failed_already=0;
+static PRFileDesc *std_err = NULL;
+static PRBool verbosity = PR_FALSE;
+static PRBool debug_mode = PR_FALSE;
+
+const static PRIntervalTime contention_interval = 50;
+
+typedef struct LockContentious_s {
+    PRLock *ml;
+    PRInt32 loops;
+    PRUint32 contender;
+    PRUint32 contentious;
+    PRIntervalTime overhead;
+    PRIntervalTime interval;
+} LockContentious_t;
+
+typedef struct MonitorContentious_s {
+    PRMonitor *ml;
+    PRInt32 loops;
+    PRUint32 contender;
+    PRUint32 contentious;
+    PRIntervalTime overhead;
+    PRIntervalTime interval;
+} MonitorContentious_t;
+
+
+static PRIntervalTime Sleeper(PRUint32 loops)
+{
+    PRIntervalTime predicted = 0;
+    while (loops-- > 0)
+    {
+        predicted += contention_interval;
+        (void)PR_Sleep(contention_interval);
+    }
+    return predicted;
+}  /* Sleeper */
+
+/*
+** BASIC LOCKS
+*/
+static PRIntervalTime MakeLock(PRUint32 loops)
+{
+    PRLock *ml = NULL;
+    while (loops-- > 0)
+    {
+        ml = PR_NewLock();
+        PR_DestroyLock(ml);
+        ml = NULL;
+    }
+    return 0;
+}  /* MakeLock */
+
+static PRIntervalTime NonContentiousLock(PRUint32 loops)
+{
+    PRLock *ml = NULL;
+    ml = PR_NewLock();
+    while (loops-- > 0)
+    {
+        PR_Lock(ml);
+        PR_Unlock(ml);
+    }
+    PR_DestroyLock(ml);
+    return 0;
+}  /* NonContentiousLock */
+
+static void PR_CALLBACK LockContender(void *arg)
+{
+    LockContentious_t *contention = (LockContentious_t*)arg;
+    while (contention->loops-- > 0)
+    {
+        PR_Lock(contention->ml);
+        contention->contender+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_Unlock(contention->ml);
+    }
+}  /* LockContender */
+
+static PRIntervalTime ContentiousLock(PRUint32 loops)
+{
+    PRStatus status;
+    PRThread *thread = NULL;
+    LockContentious_t * contention;
+    PRIntervalTime rv, overhead, timein = PR_IntervalNow();
+
+    contention = PR_NEWZAP(LockContentious_t);
+    contention->loops = loops;
+    contention->overhead = 0;
+    contention->ml = PR_NewLock();
+    contention->interval = contention_interval;
+    thread = PR_CreateThread(
+        PR_USER_THREAD, LockContender, contention,
+        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(thread != NULL);
+
+    overhead = PR_IntervalNow() - timein;
+
+    while (contention->loops-- > 0)
+    {
+        PR_Lock(contention->ml);
+        contention->contentious+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_Unlock(contention->ml);
+    }
+
+    timein = PR_IntervalNow();
+    status = PR_JoinThread(thread);
+    PR_DestroyLock(contention->ml);
+    overhead += (PR_IntervalNow() - timein);
+    rv = overhead + contention->overhead;
+    if (verbosity)
+        PR_fprintf(
+            std_err, "Access ratio: %u to %u\n",
+            contention->contentious, contention->contender);
+    PR_Free(contention);
+    return rv;
+}  /* ContentiousLock */
+
+/*
+** MONITORS
+*/
+static PRIntervalTime MakeMonitor(PRUint32 loops)
+{
+    PRMonitor *ml = NULL;
+    while (loops-- > 0)
+    {
+        ml = PR_NewMonitor();
+        PR_DestroyMonitor(ml);
+        ml = NULL;
+    }
+    return 0;
+}  /* MakeMonitor */
+
+static PRIntervalTime NonContentiousMonitor(PRUint32 loops)
+{
+    PRMonitor *ml = NULL;
+    ml = PR_NewMonitor();
+    while (loops-- > 0)
+    {
+        PR_EnterMonitor(ml);
+        PR_ExitMonitor(ml);
+    }
+    PR_DestroyMonitor(ml);
+    return 0;
+}  /* NonContentiousMonitor */
+
+static void PR_CALLBACK TryEntry(void *arg)
+{
+    PRMonitor *ml = (PRMonitor*)arg;
+    if (debug_mode) PR_fprintf(std_err, "Reentrant thread created\n");
+    PR_EnterMonitor(ml);
+    if (debug_mode) PR_fprintf(std_err, "Reentrant thread acquired monitor\n");
+    PR_ExitMonitor(ml);
+    if (debug_mode) PR_fprintf(std_err, "Reentrant thread released monitor\n");
+}  /* TryEntry */
+
+static PRIntervalTime ReentrantMonitor(PRUint32 loops)
+{
+    PRStatus status;
+    PRThread *thread;
+    PRMonitor *ml = PR_NewMonitor();
+    if (debug_mode) PR_fprintf(std_err, "\nMonitor created for reentrant test\n");
+
+    PR_EnterMonitor(ml);
+    PR_EnterMonitor(ml);
+    if (debug_mode) PR_fprintf(std_err, "Monitor acquired twice\n");
+
+    thread = PR_CreateThread(
+        PR_USER_THREAD, TryEntry, ml,
+        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(thread != NULL);
+    PR_Sleep(PR_SecondsToInterval(1));
+
+    PR_ExitMonitor(ml);
+    if (debug_mode) PR_fprintf(std_err, "Monitor released first time\n");
+
+    PR_ExitMonitor(ml);
+    if (debug_mode) PR_fprintf(std_err, "Monitor released second time\n");
+
+    status = PR_JoinThread(thread);
+    if (debug_mode) PR_fprintf(std_err, 
+        "Reentrant thread joined %s\n",
+        (status == PR_SUCCESS) ? "successfully" : "in error");
+
+    PR_DestroyMonitor(ml);
+    return 0;
+}  /* ReentrantMonitor */
+
+static void PR_CALLBACK MonitorContender(void *arg)
+{
+    MonitorContentious_t *contention = (MonitorContentious_t*)arg;
+    while (contention->loops-- > 0)
+    {
+        PR_EnterMonitor(contention->ml);
+        contention->contender+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_ExitMonitor(contention->ml);
+    }
+}  /* MonitorContender */
+
+static PRUint32 ContentiousMonitor(PRUint32 loops)
+{
+    PRStatus status;
+    PRThread *thread = NULL;
+    MonitorContentious_t * contention;
+    PRIntervalTime rv, overhead, timein = PR_IntervalNow();
+
+    contention = PR_NEWZAP(MonitorContentious_t);
+    contention->loops = loops;
+    contention->overhead = 0;
+    contention->ml = PR_NewMonitor();
+    contention->interval = contention_interval;
+    thread = PR_CreateThread(
+        PR_USER_THREAD, MonitorContender, contention,
+        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(thread != NULL);
+
+    overhead = PR_IntervalNow() - timein;
+
+    while (contention->loops-- > 0)
+    {
+        PR_EnterMonitor(contention->ml);
+        contention->contentious+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_ExitMonitor(contention->ml);
+    }
+
+    timein = PR_IntervalNow();
+    status = PR_JoinThread(thread);
+    PR_DestroyMonitor(contention->ml);
+    overhead += (PR_IntervalNow() - timein);
+    rv = overhead + contention->overhead;
+    if (verbosity)
+        PR_fprintf(
+            std_err, "Access ratio: %u to %u\n",
+            contention->contentious, contention->contender);
+    PR_Free(contention);
+    return rv;
+}  /* ContentiousMonitor */
+
+/*
+** CACHED MONITORS
+*/
+static PRIntervalTime NonContentiousCMonitor(PRUint32 loops)
+{
+    MonitorContentious_t contention;
+    while (loops-- > 0)
+    {
+        PR_CEnterMonitor(&contention);
+        PR_CExitMonitor(&contention);
+    }
+    return 0;
+}  /* NonContentiousCMonitor */
+
+static void PR_CALLBACK Contender(void *arg)
+{
+    MonitorContentious_t *contention = (MonitorContentious_t*)arg;
+    while (contention->loops-- > 0)
+    {
+        PR_CEnterMonitor(contention);
+        contention->contender+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_CExitMonitor(contention);
+    }
+}  /* Contender */
+
+static PRIntervalTime ContentiousCMonitor(PRUint32 loops)
+{
+    PRStatus status;
+    PRThread *thread = NULL;
+    MonitorContentious_t * contention;
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+
+    contention = PR_NEWZAP(MonitorContentious_t);
+    contention->ml = NULL;
+    contention->loops = loops;
+    contention->interval = contention_interval;
+    thread = PR_CreateThread(
+        PR_USER_THREAD, Contender, contention,
+        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(thread != NULL);
+
+    overhead = PR_IntervalNow() - timein;
+
+    while (contention->loops-- > 0)
+    {
+        PR_CEnterMonitor(contention);
+        contention->contentious+= 1;
+        contention->overhead += contention->interval;
+        PR_Sleep(contention->interval);
+        PR_CExitMonitor(contention);
+    }
+
+    timein = PR_IntervalNow();
+    status = PR_JoinThread(thread);
+    overhead += (PR_IntervalNow() - timein);
+    overhead += overhead + contention->overhead;
+    if (verbosity)
+        PR_fprintf(
+            std_err, "Access ratio: %u to %u\n",
+            contention->contentious, contention->contender);
+    PR_Free(contention);
+    return overhead;
+}  /* ContentiousCMonitor */
+
+static PRIntervalTime Test(
+    const char* msg, PRUint32 (*test)(PRUint32 loops),
+    PRUint32 loops, PRIntervalTime overhead)
+{ 
+    /*
+     * overhead - overhead not measured by the test.
+     * duration - wall clock time it took to perform test.
+     * predicted - extra time test says should not be counted 
+     *
+     * Time accountable to the test is duration - overhead - predicted
+     * All times are Intervals and accumulated for all iterations.
+     */
+    PRFloat64 elapsed;
+    PRIntervalTime accountable, duration;    
+    PRUintn spaces = PL_strlen(msg);
+    PRIntervalTime timeout, timein = PR_IntervalNow();
+    PRIntervalTime predicted = test(loops);
+    timeout = PR_IntervalNow();
+    duration = timeout - timein;
+
+    if (debug_mode)
+    {
+        accountable = duration - predicted;
+        accountable -= overhead;
+        elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable);
+        PR_fprintf(PR_STDOUT, "%s:", msg);
+        while (spaces++ < 50) PR_fprintf(PR_STDOUT, " ");
+        if ((PRInt32)accountable < 0)
+            PR_fprintf(PR_STDOUT, "*****.** usecs/iteration\n");
+        else
+            PR_fprintf(PR_STDOUT, "%8.2f usecs/iteration\n", elapsed/loops);
+    }
+    return duration;
+}  /* Test */
+
+int main(int argc,  char **argv)
+{
+    PRBool rv = PR_TRUE;
+    PRIntervalTime duration;
+    PRUint32 cpu, cpus = 2, loops = 100;
+
+	
+    PR_STDIO_INIT();
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    {
+    	/* 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.
+        Command line argument -l <num> sets the number of loops.
+        Command line argument -c <num> sets the number of cpus.
+        Usage: lock [-d] [-l <num>] [-c <num>]
+    	*/
+    	PLOptStatus os;
+    	PLOptState *opt = PL_CreateOptState(argc, argv, "dvl:c:");
+    	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+    		if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug mode */
+    			debug_mode = PR_TRUE;
+                break;
+            case 'v':  /* debug mode */
+    			verbosity = PR_TRUE;
+                break;
+            case 'l':  /* number of loops */
+                loops = atoi(opt->value);
+                break;
+            case 'c':  /* number of cpus */
+                cpus = atoi(opt->value);
+                break;
+             default:
+                break;
+            }
+        }
+    	PL_DestroyOptState(opt);
+    }
+
+ /* main test */
+    PR_SetConcurrency(8);
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("lock.log");
+	debug_mode = 1;
+#endif
+
+    if (loops == 0) loops = 100;
+    if (debug_mode)
+    {
+        std_err = PR_STDERR;
+        PR_fprintf(std_err, "Lock: Using %d loops\n", loops);
+    }
+
+    if (cpus == 0) cpus = 2;
+    if (debug_mode) PR_fprintf(std_err, "Lock: Using %d cpu(s)\n", cpus);
+
+    (void)Sleeper(10);  /* try filling in the caches */
+
+    for (cpu = 1; cpu <= cpus; ++cpu)
+    {
+        if (debug_mode) PR_fprintf(std_err, "\nLock: Using %d CPU(s)\n", cpu);
+        PR_SetConcurrency(cpu);
+
+        duration = Test("Overhead of PR_Sleep", Sleeper, loops, 0);
+        duration = 0;
+
+        (void)Test("Lock creation/deletion", MakeLock, loops, 0);
+        (void)Test("Lock non-contentious locking/unlocking", NonContentiousLock, loops, 0);
+        (void)Test("Lock contentious locking/unlocking", ContentiousLock, loops, duration);
+        (void)Test("Monitor creation/deletion", MakeMonitor, loops, 0);
+        (void)Test("Monitor non-contentious locking/unlocking", NonContentiousMonitor, loops, 0);
+        (void)Test("Monitor contentious locking/unlocking", ContentiousMonitor, loops, duration);
+
+        (void)Test("Cached monitor non-contentious locking/unlocking", NonContentiousCMonitor, loops, 0);
+        (void)Test("Cached monitor contentious locking/unlocking", ContentiousCMonitor, loops, duration);
+
+        (void)ReentrantMonitor(loops);
+    }
+
+    if (debug_mode)
+        PR_fprintf(
+            std_err, "%s: test %s\n", "Lock(mutex) test",
+            ((rv) ? "passed" : "failed"));
+	else {
+		 if (!rv)
+			 failed_already=1;
+	}
+
+	if(failed_already)	
+	{
+	    PR_fprintf(PR_STDOUT, "FAIL\n"); 
+		return 1;
+    } 
+	else
+    {
+	    PR_fprintf(PR_STDOUT, "PASS\n"); 
+		return 0;
+    }
+
+}  /* main */
+
+/* testlock.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/lockfile.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/lockfile.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,276 @@
+/* -*- 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:        lockfile.c
+** Purpose:     test basic locking functions
+**              Just because this times stuff, don't think its a perforamnce
+**              test!!!
+**
+** 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prcmon.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmon.h"
+#include "prthread.h"
+#include "prtypes.h"
+
+#ifndef XP_MAC
+#include "private/pprio.h"
+#else
+#include "pprio.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.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;
+
+const static PRIntervalTime contention_interval = 50;
+
+typedef struct LockContentious_s {
+    PRLock *ml;
+    PRInt32 loops;
+    PRIntervalTime overhead;
+    PRIntervalTime interval;
+} LockContentious_t;
+
+#define LOCKFILE "prlock.fil"
+
+
+
+static PRIntervalTime NonContentiousLock(PRInt32 loops)
+{
+    PRFileDesc *_lockfile;
+    while (loops-- > 0)
+    {
+        _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666);
+        if (!_lockfile) {
+            if (debug_mode) printf(
+                "could not create lockfile: %d [%d]\n",
+                PR_GetError(), PR_GetOSError());
+            return PR_INTERVAL_NO_TIMEOUT;
+        }
+        PR_LockFile(_lockfile);
+        PR_UnlockFile(_lockfile);
+        PR_Close(_lockfile);
+    }
+    return 0;
+}  /* NonContentiousLock */
+
+static void PR_CALLBACK LockContender(void *arg)
+{
+    LockContentious_t *contention = (LockContentious_t*)arg;
+    PRFileDesc *_lockfile;
+    while (contention->loops-- > 0)
+    {
+        _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666);
+        if (!_lockfile) {
+            if (debug_mode) printf(
+                "could not create lockfile: %d [%d]\n",
+                PR_GetError(), PR_GetOSError());
+            break;
+        }
+        PR_LockFile(_lockfile);
+        PR_Sleep(contention->interval);
+        PR_UnlockFile(_lockfile);
+        PR_Close(_lockfile);
+    }
+
+}  /* LockContender */
+
+/*
+** Win16 requires things passed to Threads not be on the stack
+*/
+static LockContentious_t contention;
+
+static PRIntervalTime ContentiousLock(PRInt32 loops)
+{
+    PRStatus status;
+    PRThread *thread = NULL;
+    PRIntervalTime overhead, timein = PR_IntervalNow();
+
+    contention.loops = loops;
+    contention.overhead = 0;
+    contention.ml = PR_NewLock();
+    contention.interval = contention_interval;
+    thread = PR_CreateThread(
+        PR_USER_THREAD, LockContender, &contention,
+        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_ASSERT(thread != NULL);
+
+    overhead = PR_IntervalNow() - timein;
+
+    while (contention.loops > 0)
+    {
+        PR_Lock(contention.ml);
+        contention.overhead += contention.interval;
+        PR_Sleep(contention.interval);
+        PR_Unlock(contention.ml);
+    }
+
+    timein = PR_IntervalNow();
+    status = PR_JoinThread(thread);
+    PR_DestroyLock(contention.ml);
+    overhead += (PR_IntervalNow() - timein);
+    return overhead + contention.overhead;
+}  /* ContentiousLock */
+
+static PRIntervalTime Test(
+    const char* msg, PRIntervalTime (*test)(PRInt32 loops),
+    PRInt32 loops, PRIntervalTime overhead)
+{ 
+    /*
+     * overhead - overhead not measured by the test.
+     * duration - wall clock time it took to perform test.
+     * predicted - extra time test says should not be counted 
+     *
+     * Time accountable to the test is duration - overhead - predicted
+     * All times are Intervals and accumulated for all iterations.
+     */
+    PRFloat64 elapsed;
+    PRIntervalTime accountable, duration;    
+    PRUintn spaces = strlen(msg);
+    PRIntervalTime timeout, timein = PR_IntervalNow();
+    PRIntervalTime predicted = test(loops);
+    timeout = PR_IntervalNow();
+    duration = timeout - timein;
+    accountable = duration - predicted;
+    accountable -= overhead;
+    elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable);
+    if (debug_mode) printf("%s:", msg);
+    while (spaces++ < 50) if (debug_mode) printf(" ");
+    if ((PRInt32)accountable < 0) {
+        if (debug_mode) printf("*****.** usecs/iteration\n");
+    } else {
+        if (debug_mode) printf("%8.2f usecs/iteration\n", elapsed/loops);
+    }
+    return duration;
+}  /* Test */
+
+int main(int argc,  char **argv)
+{
+    PRIntervalTime duration;
+    PRUint32 cpu, cpus = 2;
+    PRInt32 loops = 100;
+
+	
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("lockfile.log");
+	debug_mode = 1;
+#endif
+
+    if (argc > 1) loops = atoi(argv[1]);
+    if (loops == 0) loops = 100;
+    if (debug_mode) printf("Lock: Using %d loops\n", loops);
+
+    cpus = (argc < 3) ? 2 : atoi(argv[2]);
+    if (cpus == 0) cpus = 2;
+    if (debug_mode) printf("Lock: Using %d cpu(s)\n", cpus);
+
+
+    for (cpu = 1; cpu <= cpus; ++cpu)
+    {
+        if (debug_mode) printf("\nLockFile: Using %d CPU(s)\n", cpu);
+        PR_SetConcurrency(cpu);
+        
+        duration = Test("LockFile non-contentious locking/unlocking", NonContentiousLock, loops, 0);
+        (void)Test("LockFile contentious locking/unlocking", ContentiousLock, loops, duration);
+    }
+
+    PR_Delete(LOCKFILE);  /* try to get rid of evidence */
+
+    if (debug_mode) printf("%s: test %s\n", "Lock(mutex) test", ((failed_already) ? "failed" : "passed"));
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}  /* main */
+
+/* testlock.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/logger.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/logger.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,167 @@
+/* -*- 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:        logger.c
+ * Description: test program for logging's basic functions
+ */
+
+#include "prinit.h"
+#include "prlog.h"
+#include "prlock.h"
+#include "prcvar.h"
+#include "prthread.h"
+#include "prinrval.h"
+
+#include <stdio.h>
+
+#ifdef XP_MAC
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+/* lth. re-define PR_LOG() */
+#if 0
+#undef PR_LOG_TEST
+#undef PR_LOG
+#define PR_LOG_TEST(_module,_level) ((_module)->level <= (_level))
+#define PR_LOG(_module,_level,_args)    \
+  {                                     \
+    if (PR_LOG_TEST(_module,_level))    \
+       PR_LogPrint _args   ;             \
+  }
+#endif
+
+
+static void Error(const char* msg)
+{
+    printf("\t%s\n", msg);
+}  /* Error */
+
+static void PR_CALLBACK forked(void *arg)
+{
+    PRIntn i;
+	PRLock *ml;
+	PRCondVar *cv;
+	
+    PR_LogPrint("%s logging creating mutex\n", (const char*)arg);
+    ml = PR_NewLock();
+    PR_LogPrint("%s logging creating condition variable\n", (const char*)arg);
+    cv = PR_NewCondVar(ml);
+
+    PR_LogPrint("%s waiting on condition timeout 10 times\n", (const char*)arg);
+    for (i = 0; i < 10; ++i)
+    {
+        PR_Lock(ml);
+        PR_WaitCondVar(cv, PR_SecondsToInterval(1));
+        PR_Unlock(ml);
+    }
+    
+    PR_LogPrint("%s logging destroying condition variable\n", (const char*)arg);
+    PR_DestroyCondVar(cv);
+    PR_LogPrint("%s logging destroying mutex\n", (const char*)arg);
+    PR_DestroyLock(ml);
+    PR_LogPrint("%s forked thread exiting\n", (const char*)arg);
+}
+
+static void UserLogStuff( void )
+{
+    PRLogModuleInfo *myLM;
+    PRIntn i;
+
+    myLM = PR_NewLogModule( "userStuff" );
+    if (! myLM )
+      {
+        printf("UserLogStuff(): can't create new log module\n" );
+        return;
+      }
+
+    PR_LOG( myLM, PR_LOG_NOTICE, ("Log a Notice %d\n", 1 ));
+
+    for (i = 0; i < 10 ; i++ )
+      {
+        PR_LOG( myLM, PR_LOG_DEBUG, ("Log Debug number: %d\n", i));
+        PR_Sleep( 300 );
+      }
+
+} /* end UserLogStuff() */
+
+int main(PRIntn argc, const char **argv)
+{
+    PRThread *thread;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifndef XP_MAC
+    if (argc > 1)
+    {
+        if (!PR_SetLogFile(argv[1]))
+        {
+            Error("Access: Cannot create log file");
+            goto exit;
+        }
+    }
+#else
+	SetupMacPrintfLog("logger.log");
+#endif
+
+    /* Start logging something here */
+    PR_LogPrint("%s logging into %s\n", argv[0], argv[1]);
+
+    PR_LogPrint("%s creating new thread\n", argv[0]);
+
+    /*
+    ** Now change buffering.
+    */
+    PR_SetLogBuffering( 65500 );    
+	thread = PR_CreateThread(
+	    PR_USER_THREAD, forked, (void*)argv[0], PR_PRIORITY_NORMAL,
+	    PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    PR_LogPrint("%s joining thread\n", argv[0]);
+
+    UserLogStuff();
+
+    PR_JoinThread(thread);
+
+    PR_LogFlush();
+    return 0;
+
+exit:
+    return -1;
+}
+
+/* logger.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/macbuild/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/macbuild/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/macbuild/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/macbuild/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/tests/macbuild

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/macbuild/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/macbuild/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/makedir.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/makedir.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,99 @@
+/* -*- 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) 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 ***** */
+
+/*
+ * This test calls PR_MakeDir to create a bunch of directories
+ * with various mode bits.
+ */
+
+#include "prio.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main()
+{
+    if (PR_MakeDir("tdir0400", 0400) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0200", 0200) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0100", 0100) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0500", 0500) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0600", 0600) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0300", 0300) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0700", 0700) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0640", 0640) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0660", 0660) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0644", 0644) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0664", 0664) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    if (PR_MakeDir("tdir0666", 0666) == PR_FAILURE) {
+        fprintf(stderr, "PR_MakeDir failed\n");
+        exit(1);
+    }
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/many_cv.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/many_cv.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,150 @@
+/* -*- 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 "prprf.h"
+#include "prthread.h"
+#include "prcvar.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmem.h"
+
+#include "primpl.h"
+
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+static PRInt32 Random(void)
+{
+    PRInt32 ran = rand() >> 16;
+    return ran;
+}  /* Random */
+
+static void Help(void)
+{
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PR_fprintf(err, "many_cv usage: [-c n] [-l n] [-h]\n");
+    PR_fprintf(err, "\t-c n Number of conditions per lock       (default: 10)\n");
+    PR_fprintf(err, "\t-l n Number of times to loop the test    (default:  1)\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+    PLOptStatus os;
+    PRIntn index, nl;
+    PRLock *ml = NULL;
+    PRCondVar **cv = NULL;
+    PRBool stats = PR_FALSE;
+    PRIntn nc, loops = 1, cvs = 10;
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hsc:l:");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 's':  /* number of CVs to association with lock */
+            stats = PR_TRUE;
+            break;
+        case 'c':  /* number of CVs to association with lock */
+            cvs = atoi(opt->value);
+            break;
+        case 'l':  /* number of times to run the tests */
+            loops = atoi(opt->value);
+            break;
+        case 'h':  /* user wants some guidance */
+         default:
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_fprintf(err, "Settings\n");
+    PR_fprintf(err, "\tConditions / lock: %d\n", cvs);
+    PR_fprintf(err, "\tLoops to run test: %d\n", loops);
+
+    ml = PR_NewLock();
+    PR_ASSERT(NULL != ml);
+
+    cv = (PRCondVar**)PR_CALLOC(sizeof(PRCondVar*) * cvs);
+    PR_ASSERT(NULL != cv);
+
+    for (index = 0; index < cvs; ++index)
+    {
+        cv[index] = PR_NewCondVar(ml);
+        PR_ASSERT(NULL != cv[index]);
+    }
+
+    for (index = 0; index < loops; ++index)
+    {
+        PR_Lock(ml);
+        for (nl = 0; nl < cvs; ++nl)
+        {
+            PRInt32 ran = Random() % 8;
+            if (0 == ran) PR_NotifyAllCondVar(cv[nl]);
+            else for (nc = 0; nc < ran; ++nc)
+                PR_NotifyCondVar(cv[nl]);
+        }
+        PR_Unlock(ml);
+    }
+
+    for (index = 0; index < cvs; ++index)
+        PR_DestroyCondVar(cv[index]);
+
+    PR_DELETE(cv);
+
+    PR_DestroyLock(ml);
+    
+    printf("PASS\n");
+
+    PT_FPrintStats(err, "\nPThread Statistics\n");
+    return 0;
+}
+
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/mbcs.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/mbcs.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,187 @@
+/* -*- 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: mbcs.c
+**
+** Synopsis: mbcs {dirName}
+**
+** where dirName is the directory to be traversed. dirName is required.
+**
+** Description: 
+** mbcs.c tests use of multi-byte characters, as would be passed to
+** NSPR funtions by internationalized applications. 
+**
+** mbcs.c, when run on any single-byte platform, should run correctly.
+** In truth, running the mbcs test on a single-byte platform is
+** really meaningless. mbcs.c, nor any NSPR library or test is not
+** intended for use with any wide character set, including Unicode.
+** mbcs.c should not be included in runtests.ksh because it requires
+** extensive user intervention to set-up and run.
+**
+** mbcs.c should be run on a platform using some form of multi-byte
+** characters. The initial platform for this test is a Japanese
+** language Windows NT 4.0 machine. ... Thank you Noriko Hoshi.
+**
+** To run mbcs.c, the tester should create a directory tree containing
+** some files in the same directory from which the test is run; i.e.
+** the current working directory. The directory and files should be
+** named such that when represented in the local multi-byte character
+** set, one or more characters of the name is longer than a single
+** byte.
+** 
+*/
+
+#include <plgetopt.h> 
+#include <nspr.h> 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Test harness infrastructure
+*/
+PRLogModuleInfo *lm;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRIntn  debug = 0;
+PRUint32  failed_already = 0;
+/* end Test harness infrastructure */
+
+char *dirName =  NULL;  /* directory name to traverse */
+
+/*
+** Traverse directory
+*/
+static void TraverseDirectory( unsigned char *dir )
+{
+    PRDir *cwd;
+    PRDirEntry *dirEntry;
+    PRFileInfo info;
+    PRStatus rc;
+    PRInt32 err;
+    PRFileDesc *fd;
+    char    nextDir[256];
+    char    file[256];
+
+    printf("Directory: %s\n", dir );
+    cwd = PR_OpenDir( dir );
+    if ( NULL == cwd )  {
+        printf("PR_OpenDir() failed on directory: %s, with error: %d, %d\n", 
+            dir, PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    while( NULL != (dirEntry = PR_ReadDir( cwd, PR_SKIP_BOTH | PR_SKIP_HIDDEN )))  {
+        sprintf( file, "%s/%s", dir, dirEntry->name );
+        rc = PR_GetFileInfo( file, &info );
+        if ( PR_FAILURE == rc ) {
+            printf("PR_GetFileInfo() failed on file: %s, with error: %d, %d\n", 
+                dirEntry->name, PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        if ( PR_FILE_FILE == info.type )  {
+            printf("File: %s \tsize: %ld\n", dirEntry->name, info.size );
+            fd = PR_Open( file, PR_RDONLY, 0 );
+            if ( NULL == fd )  {
+                printf("PR_Open() failed. Error: %ld, OSError: %ld\n", 
+                    PR_GetError(), PR_GetOSError());
+            }
+            rc = PR_Close( fd );
+            if ( PR_FAILURE == rc )  {
+                printf("PR_Close() failed. Error: %ld, OSError: %ld\n", 
+                    PR_GetError(), PR_GetOSError());
+            }
+        } else if ( PR_FILE_DIRECTORY == info.type ) {
+            sprintf( nextDir, "%s/%s", dir, dirEntry->name );
+            TraverseDirectory(nextDir);
+        } else {
+            printf("type is not interesting for file: %s\n", dirEntry->name );
+            /* keep going */
+        }
+    }
+    /* assume end-of-file, actually could be error */
+
+    rc = PR_CloseDir( cwd );
+    if ( PR_FAILURE == rc ) {
+        printf("PR_CloseDir() failed on directory: %s, with error: %d, %d\n", 
+            dir, PR_GetError(), PR_GetOSError());
+    }
+
+} /* end TraverseDirectory() */
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    { /* get command line options */
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "dv");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+			    msgLevel = PR_LOG_ERROR;
+                break;
+            case 'v':  /* verbose mode */
+			    msgLevel = PR_LOG_DEBUG;
+                break;
+             default:
+                dirName = strdup(opt->value); 
+                break; 
+            }
+        }
+	    PL_DestroyOptState(opt);
+    } /* end get command line options */
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+
+    
+    if ( dirName == NULL )  {
+        printf("you gotta specify a directory as an operand!\n");
+        exit(1);
+    }
+
+    TraverseDirectory( dirName );
+
+    if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS");
+    return( (failed_already == PR_TRUE )? 1 : 0 );
+}  /* main() */
+/* end template.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/multiacc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/multiacc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,252 @@
+/* -*- 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 ***** */
+
+/*
+ * File: multiacc.c
+ *
+ * Description:
+ * This test creates multiple threads that accept on the
+ * same listening socket.
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NUM_SERVER_THREADS 10
+
+static int num_server_threads = NUM_SERVER_THREADS;
+static PRThreadScope thread_scope = PR_GLOBAL_THREAD;
+static PRBool exit_flag = PR_FALSE;
+
+static void ServerThreadFunc(void *arg)
+{
+    PRFileDesc *listenSock = (PRFileDesc *) arg;
+    PRFileDesc *acceptSock;
+    PRErrorCode err;
+    PRStatus status;
+
+    while (!exit_flag) {
+        acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+        if (NULL == acceptSock) {
+            err = PR_GetError();
+            if (PR_PENDING_INTERRUPT_ERROR == err) {
+                printf("server thread is interrupted\n");
+                fflush(stdout);
+                continue;
+            }
+            fprintf(stderr, "PR_Accept failed: %d\n", err);
+            exit(1);
+        }
+        status = PR_Close(acceptSock);
+        if (PR_FAILURE == status) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        }
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *dummySock;
+    PRFileDesc *listenSock;
+    PRFileDesc *clientSock;
+    PRThread *dummyThread;
+    PRThread **serverThreads;
+    PRStatus status;
+    PRUint16 port;
+    int idx;
+    PRInt32 nbytes;
+    char buf[1024];
+
+    serverThreads = (PRThread **)
+            PR_Malloc(num_server_threads * sizeof(PRThread *));
+    if (NULL == serverThreads) {
+        fprintf(stderr, "PR_Malloc failed\n");
+        exit(1);
+    }
+
+    /*
+     * Create a dummy listening socket and have the first
+     * (dummy) thread listen on it.  This is to ensure that
+     * the first thread becomes the I/O continuation thread
+     * in the pthreads implementation (see ptio.c) and remains
+     * so throughout the test, so that we never have to
+     * recycle the I/O continuation thread.
+     */
+    dummySock = PR_NewTCPSocket();
+    if (NULL == dummySock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&serverAddr, 0, sizeof(serverAddr));
+    status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    status = PR_Bind(dummySock, &serverAddr);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    status = PR_Listen(dummySock, 5);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+
+    listenSock = PR_NewTCPSocket();
+    if (NULL == listenSock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&serverAddr, 0, sizeof(serverAddr));
+    status = PR_InitializeNetAddr(PR_IpAddrAny, 0, &serverAddr);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    status = PR_Bind(listenSock, &serverAddr);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    status = PR_GetSockName(listenSock, &serverAddr);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_GetSockName failed\n");
+        exit(1);
+    }
+    port = PR_ntohs(serverAddr.inet.port);
+    status = PR_Listen(listenSock, 5);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+
+    printf("creating dummy thread\n");
+    fflush(stdout);
+    dummyThread = PR_CreateThread(PR_USER_THREAD,
+            ServerThreadFunc, dummySock, PR_PRIORITY_NORMAL,
+            thread_scope, PR_JOINABLE_THREAD, 0);
+    if (NULL == dummyThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    printf("sleeping one second before creating server threads\n");
+    fflush(stdout);
+    PR_Sleep(PR_SecondsToInterval(1));
+    for (idx = 0; idx < num_server_threads; idx++) {
+        serverThreads[idx] = PR_CreateThread(PR_USER_THREAD,
+                ServerThreadFunc, listenSock, PR_PRIORITY_NORMAL,
+                thread_scope, PR_JOINABLE_THREAD, 0);
+        if (NULL == serverThreads[idx]) {
+            fprintf(stderr, "PR_CreateThread failed\n");
+            exit(1);
+        }
+    }
+
+    memset(&serverAddr, 0, sizeof(serverAddr));
+    PR_InitializeNetAddr(PR_IpAddrLoopback, port, &serverAddr);
+    clientSock = PR_NewTCPSocket();
+    if (NULL == clientSock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    printf("sleeping one second before connecting\n");
+    fflush(stdout);
+    PR_Sleep(PR_SecondsToInterval(1));
+    status = PR_Connect(clientSock, &serverAddr, PR_INTERVAL_NO_TIMEOUT);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Connect failed\n");
+        exit(1);
+    }
+    nbytes = PR_Read(clientSock, buf, sizeof(buf));
+    if (nbytes != 0) {
+        fprintf(stderr, "expected 0 bytes but got %d bytes\n", nbytes);
+        exit(1);
+    }
+    status = PR_Close(clientSock);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    printf("sleeping one second before shutting down server threads\n");
+    fflush(stdout);
+    PR_Sleep(PR_SecondsToInterval(1));
+
+    exit_flag = PR_TRUE;
+    status = PR_Interrupt(dummyThread);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Interrupt failed\n");
+        exit(1);
+    }
+    status = PR_JoinThread(dummyThread);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    for (idx = 0; idx < num_server_threads; idx++) {
+        status = PR_Interrupt(serverThreads[idx]);
+        if (PR_FAILURE == status) {
+            fprintf(stderr, "PR_Interrupt failed\n");
+            exit(1);
+        }
+        status = PR_JoinThread(serverThreads[idx]);
+        if (PR_FAILURE == status) {
+            fprintf(stderr, "PR_JoinThread failed\n");
+            exit(1);
+        }
+    }
+    PR_Free(serverThreads);
+    status = PR_Close(dummySock);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(listenSock);
+    if (PR_FAILURE == status) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/multiwait.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/multiwait.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,725 @@
+/* -*- 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 "prio.h"
+#include "prprf.h"
+#include "prlog.h"
+#include "prmem.h"
+#include "pratom.h"
+#include "prlock.h"
+#include "prmwait.h"
+#include "prclist.h"
+#include "prerror.h"
+#include "prinrval.h"
+#include "prnetdb.h"
+#include "prthread.h"
+
+#include "plstr.h"
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <string.h>
+
+typedef struct Shared
+{
+    const char *title;
+    PRLock *list_lock;
+    PRWaitGroup *group;
+    PRIntervalTime timeout;
+} Shared;
+
+typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity;
+
+static PRFileDesc *debug = NULL;
+static PRInt32 desc_allocated = 0;
+static PRUint16 default_port = 12273;
+static enum Verbosity verbosity = quiet;
+static PRInt32 ops_required = 1000, ops_done = 0;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+static PRIntn client_threads = 20, worker_threads = 2, wait_objects = 50;
+
+#if defined(DEBUG)
+#define MW_ASSERT(_expr) \
+    ((_expr)?((void)0):_MW_Assert(# _expr,__FILE__,__LINE__))
+static void _MW_Assert(const char *s, const char *file, PRIntn ln)
+{
+    if (NULL != debug) PL_FPrintError(debug, NULL);
+    PR_Assert(s, file, ln);
+}  /* _MW_Assert */
+#else
+#define MW_ASSERT(_expr)
+#endif
+
+static void PrintRecvDesc(PRRecvWait *desc, const char *msg)
+{
+    const char *tag[] = {
+        "PR_MW_INTERRUPT", "PR_MW_TIMEOUT",
+        "PR_MW_FAILURE", "PR_MW_SUCCESS", "PR_MW_PENDING"};
+    PR_fprintf(
+        debug, "%s: PRRecvWait(@0x%x): {fd: 0x%x, outcome: %s, tmo: %u}\n",
+        msg, desc, desc->fd, tag[desc->outcome + 3], desc->timeout);
+}  /* PrintRecvDesc */
+
+static Shared *MakeShared(const char *title)
+{
+    Shared *shared = PR_NEWZAP(Shared);
+    shared->group = PR_CreateWaitGroup(1);
+    shared->timeout = PR_SecondsToInterval(1);
+    shared->list_lock = PR_NewLock();
+    shared->title = title;
+    return shared;
+}  /* MakeShared */
+
+static void DestroyShared(Shared *shared)
+{
+    PRStatus rv;
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: destroying group\n", shared->title);
+    rv = PR_DestroyWaitGroup(shared->group);
+    MW_ASSERT(PR_SUCCESS == rv);
+    PR_DestroyLock(shared->list_lock);
+    PR_DELETE(shared);
+}  /* DestroyShared */
+
+static PRRecvWait *CreateRecvWait(PRFileDesc *fd, PRIntervalTime timeout)
+{
+    PRRecvWait *desc_out = PR_NEWZAP(PRRecvWait);
+    MW_ASSERT(NULL != desc_out);
+
+    MW_ASSERT(NULL != fd);
+    desc_out->fd = fd;
+    desc_out->timeout = timeout;
+    desc_out->buffer.length = 120;
+    desc_out->buffer.start = PR_CALLOC(120);
+
+    PR_AtomicIncrement(&desc_allocated);
+
+    if (verbosity > chatty)
+        PrintRecvDesc(desc_out, "Allocated");
+    return desc_out;
+}  /* CreateRecvWait */
+
+static void DestroyRecvWait(PRRecvWait *desc_out)
+{
+    if (verbosity > chatty)
+        PrintRecvDesc(desc_out, "Destroying");
+    PR_Close(desc_out->fd);
+    if (NULL != desc_out->buffer.start)
+        PR_DELETE(desc_out->buffer.start);
+    PR_Free(desc_out);
+    (void)PR_AtomicDecrement(&desc_allocated);
+}  /* DestroyRecvWait */
+
+static void CancelGroup(Shared *shared)
+{
+    PRRecvWait *desc_out;
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s Reclaiming wait descriptors\n", shared->title);
+
+    do
+    {
+        desc_out = PR_CancelWaitGroup(shared->group);
+        if (NULL != desc_out) DestroyRecvWait(desc_out);
+    } while (NULL != desc_out);
+
+    MW_ASSERT(0 == desc_allocated);
+    MW_ASSERT(PR_GROUP_EMPTY_ERROR == PR_GetError());
+}  /* CancelGroup */
+
+static void PR_CALLBACK ClientThread(void* arg)
+{
+    PRStatus rv;
+    PRInt32 bytes;
+    PRIntn empty_flags = 0;
+    PRNetAddr server_address;
+    unsigned char buffer[100];
+    Shared *shared = (Shared*)arg;
+    PRFileDesc *server = PR_NewTCPSocket();
+    if ((NULL == server)
+    && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) return;
+    MW_ASSERT(NULL != server);
+
+    if (verbosity > chatty)
+        PR_fprintf(debug, "%s: Server socket @0x%x\n", shared->title, server);
+
+    /* Initialize the buffer so that Purify won't complain */
+    memset(buffer, 0, sizeof(buffer));
+
+    rv = PR_InitializeNetAddr(PR_IpAddrLoopback, default_port, &server_address);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: Client opening connection\n", shared->title);
+    rv = PR_Connect(server, &server_address, PR_INTERVAL_NO_TIMEOUT);
+
+    if (PR_FAILURE == rv)
+    {
+        if (verbosity > silent) PL_FPrintError(debug, "Client connect failed");
+        return;
+    }
+
+    while (ops_done < ops_required)
+    {
+        bytes = PR_Send(
+            server, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT);
+        if ((-1 == bytes) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break;
+        MW_ASSERT(sizeof(buffer) == bytes);
+        if (verbosity > chatty)
+            PR_fprintf(
+                debug, "%s: Client sent %d bytes\n",
+                shared->title, sizeof(buffer));
+        bytes = PR_Recv(
+            server, buffer, sizeof(buffer), empty_flags, PR_INTERVAL_NO_TIMEOUT);
+        if (verbosity > chatty)
+            PR_fprintf(
+                debug, "%s: Client received %d bytes\n",
+                shared->title, sizeof(buffer));
+        if ((-1 == bytes) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break;
+        MW_ASSERT(sizeof(buffer) == bytes);
+        PR_Sleep(shared->timeout);
+    }
+    rv = PR_Close(server);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+}  /* ClientThread */
+
+static void OneInThenCancelled(Shared *shared)
+{
+    PRStatus rv;
+    PRRecvWait *desc_out, *desc_in = PR_NEWZAP(PRRecvWait);
+
+    shared->timeout = PR_INTERVAL_NO_TIMEOUT;
+
+    desc_in->fd = PR_NewTCPSocket();
+    desc_in->timeout = shared->timeout;
+
+    if (verbosity > chatty) PrintRecvDesc(desc_in, "Adding desc");
+
+    rv = PR_AddWaitFileDesc(shared->group, desc_in);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    if (verbosity > chatty) PrintRecvDesc(desc_in, "Cancelling");
+    rv = PR_CancelWaitFileDesc(shared->group, desc_in);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    desc_out = PR_WaitRecvReady(shared->group);
+    MW_ASSERT(desc_out == desc_in);
+    MW_ASSERT(PR_MW_INTERRUPT == desc_out->outcome);
+    MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
+    if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready");
+
+    rv = PR_Close(desc_in->fd);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: destroying group\n", shared->title);
+
+    PR_DELETE(desc_in);
+}  /* OneInThenCancelled */
+
+static void OneOpOneThread(Shared *shared)
+{
+    PRStatus rv;
+    PRRecvWait *desc_out, *desc_in = PR_NEWZAP(PRRecvWait);
+
+    desc_in->fd = PR_NewTCPSocket();
+    desc_in->timeout = shared->timeout;
+
+    if (verbosity > chatty) PrintRecvDesc(desc_in, "Adding desc");
+
+    rv = PR_AddWaitFileDesc(shared->group, desc_in);
+    MW_ASSERT(PR_SUCCESS == rv);
+    desc_out = PR_WaitRecvReady(shared->group);
+    MW_ASSERT(desc_out == desc_in);
+    MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome);
+    MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
+    if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready");
+
+    rv = PR_Close(desc_in->fd);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    PR_DELETE(desc_in);
+}  /* OneOpOneThread */
+
+static void ManyOpOneThread(Shared *shared)
+{
+    PRStatus rv;
+    PRIntn index;
+    PRRecvWait *desc_in;
+    PRRecvWait *desc_out;
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: adding %d descs\n", shared->title, wait_objects);
+
+    for (index = 0; index < wait_objects; ++index)
+    {
+        desc_in = CreateRecvWait(PR_NewTCPSocket(), shared->timeout);
+
+        rv = PR_AddWaitFileDesc(shared->group, desc_in);
+        MW_ASSERT(PR_SUCCESS == rv);
+    }
+
+    while (ops_done < ops_required)
+    {
+        desc_out = PR_WaitRecvReady(shared->group);
+        MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome);
+        MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
+        if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready/readding");
+        rv = PR_AddWaitFileDesc(shared->group, desc_out);
+        MW_ASSERT(PR_SUCCESS == rv);
+        (void)PR_AtomicIncrement(&ops_done);
+    }
+
+    CancelGroup(shared);
+}  /* ManyOpOneThread */
+
+static void PR_CALLBACK SomeOpsThread(void *arg)
+{
+    PRRecvWait *desc_out;
+    PRStatus rv = PR_SUCCESS;
+    Shared *shared = (Shared*)arg;
+    do  /* until interrupted */
+    {
+        desc_out = PR_WaitRecvReady(shared->group);
+        if (NULL == desc_out)
+        {
+            MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
+            if (verbosity > quiet) PR_fprintf(debug, "Aborted\n");
+            break;
+        }
+        MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome);
+        MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
+        if (verbosity > chatty) PrintRecvDesc(desc_out, "Ready");
+
+        if (verbosity > chatty) PrintRecvDesc(desc_out, "Re-Adding");
+        desc_out->timeout = shared->timeout;
+        rv = PR_AddWaitFileDesc(shared->group, desc_out);
+        PR_AtomicIncrement(&ops_done);
+        if (ops_done > ops_required) break;
+    } while (PR_SUCCESS == rv);
+    MW_ASSERT(PR_SUCCESS == rv);
+}  /* SomeOpsThread */
+
+static void SomeOpsSomeThreads(Shared *shared)
+{
+    PRStatus rv;
+    PRThread **thread;
+    PRIntn index;
+    PRRecvWait *desc_in;
+
+    thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * worker_threads);
+
+    /* Create some threads */
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: creating threads\n", shared->title);
+    for (index = 0; index < worker_threads; ++index)
+    {
+        thread[index] = PR_CreateThread(
+            PR_USER_THREAD, SomeOpsThread, shared,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+    }
+
+    /* then create some operations */
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: creating desc\n", shared->title);
+    for (index = 0; index < wait_objects; ++index)
+    {
+        desc_in = CreateRecvWait(PR_NewTCPSocket(), shared->timeout);
+        rv = PR_AddWaitFileDesc(shared->group, desc_in);
+        MW_ASSERT(PR_SUCCESS == rv);
+    }
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: sleeping\n", shared->title);
+    while (ops_done < ops_required) PR_Sleep(shared->timeout);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: interrupting/joining threads\n", shared->title);
+    for (index = 0; index < worker_threads; ++index)
+    {
+        rv = PR_Interrupt(thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+    }
+    PR_DELETE(thread);
+
+    CancelGroup(shared);
+}  /* SomeOpsSomeThreads */
+
+static PRStatus ServiceRequest(Shared *shared, PRRecvWait *desc)
+{
+    PRInt32 bytes_out;
+
+    if (verbosity > chatty)
+        PR_fprintf(
+            debug, "%s: Service received %d bytes\n",
+            shared->title, desc->bytesRecv);
+
+    if (0 == desc->bytesRecv) goto quitting;
+    if ((-1 == desc->bytesRecv)
+    && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) goto aborted;
+
+    bytes_out = PR_Send(
+        desc->fd, desc->buffer.start, desc->bytesRecv, 0, shared->timeout);
+    if (verbosity > chatty)
+        PR_fprintf(
+            debug, "%s: Service sent %d bytes\n",
+            shared->title, bytes_out);
+
+    if ((-1 == bytes_out)
+    && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) goto aborted;
+    MW_ASSERT(bytes_out == desc->bytesRecv);
+
+    return PR_SUCCESS;
+
+aborted:
+quitting:
+    return PR_FAILURE;
+}  /* ServiceRequest */
+
+static void PR_CALLBACK ServiceThread(void *arg)
+{
+    PRStatus rv = PR_SUCCESS;
+    PRRecvWait *desc_out = NULL;
+    Shared *shared = (Shared*)arg;
+    do  /* until interrupted */
+    {
+        if (NULL != desc_out)
+        {
+            desc_out->timeout = PR_INTERVAL_NO_TIMEOUT;
+            if (verbosity > chatty)
+                PrintRecvDesc(desc_out, "Service re-adding");
+            rv = PR_AddWaitFileDesc(shared->group, desc_out);
+            MW_ASSERT(PR_SUCCESS == rv);
+        }
+
+        desc_out = PR_WaitRecvReady(shared->group);
+        if (NULL == desc_out)
+        {
+            MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
+            break;
+        }
+
+        switch (desc_out->outcome)
+        {
+            case PR_MW_SUCCESS:
+            {
+                PR_AtomicIncrement(&ops_done);
+                if (verbosity > chatty)
+                    PrintRecvDesc(desc_out, "Service ready");
+                rv = ServiceRequest(shared, desc_out);
+                break;
+            }
+            case PR_MW_INTERRUPT:
+                MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
+                rv = PR_FAILURE;  /* if interrupted, then exit */
+                break;
+            case PR_MW_TIMEOUT:
+                MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
+            case PR_MW_FAILURE:
+                if (verbosity > silent)
+                    PL_FPrintError(debug, "RecvReady failure");
+                break;
+            default:
+                break;
+        }
+    } while (PR_SUCCESS == rv);
+
+    if (NULL != desc_out) DestroyRecvWait(desc_out);
+
+}  /* ServiceThread */
+
+static void PR_CALLBACK EnumerationThread(void *arg)
+{
+    PRStatus rv;
+    PRIntn count;
+    PRRecvWait *desc;
+    Shared *shared = (Shared*)arg;
+    PRIntervalTime five_seconds = PR_SecondsToInterval(5);
+    PRMWaitEnumerator *enumerator = PR_CreateMWaitEnumerator(shared->group);
+    MW_ASSERT(NULL != enumerator);
+
+    while (PR_SUCCESS == PR_Sleep(five_seconds))
+    {
+        count = 0;
+        desc = NULL;
+        while (NULL != (desc = PR_EnumerateWaitGroup(enumerator, desc)))
+        {
+            if (verbosity > chatty) PrintRecvDesc(desc, shared->title);
+            count += 1;
+        }
+        if (verbosity > silent)
+            PR_fprintf(debug,
+                "%s Enumerated %d objects\n", shared->title, count);
+    }
+
+    MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
+
+
+    rv = PR_DestroyMWaitEnumerator(enumerator);
+    MW_ASSERT(PR_SUCCESS == rv);
+}  /* EnumerationThread */
+
+static void PR_CALLBACK ServerThread(void *arg)
+{
+    PRStatus rv;
+    PRIntn index;
+    PRRecvWait *desc_in;
+    PRThread **worker_thread;
+    Shared *shared = (Shared*)arg;
+    PRFileDesc *listener, *service;
+    PRNetAddr server_address, client_address;
+
+    worker_thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * worker_threads);
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: Server creating worker_threads\n", shared->title);
+    for (index = 0; index < worker_threads; ++index)
+    {
+        worker_thread[index] = PR_CreateThread(
+            PR_USER_THREAD, ServiceThread, shared,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+    }
+
+    rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &server_address);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    listener = PR_NewTCPSocket(); MW_ASSERT(NULL != listener);
+    if (verbosity > chatty)
+        PR_fprintf(
+            debug, "%s: Server listener socket @0x%x\n",
+            shared->title, listener);
+    rv = PR_Bind(listener, &server_address); MW_ASSERT(PR_SUCCESS == rv);
+    rv = PR_Listen(listener, 10); MW_ASSERT(PR_SUCCESS == rv);
+    while (ops_done < ops_required)
+    {
+        if (verbosity > quiet)
+            PR_fprintf(debug, "%s: Server accepting connection\n", shared->title);
+        service = PR_Accept(listener, &client_address, PR_INTERVAL_NO_TIMEOUT);
+        if (NULL == service)
+        {
+            if (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) break;
+            PL_PrintError("Accept failed");
+            MW_ASSERT(!"Accept failed");
+        }
+        else
+        {
+            desc_in = CreateRecvWait(service, shared->timeout);
+            desc_in->timeout = PR_INTERVAL_NO_TIMEOUT;
+            if (verbosity > chatty)
+                PrintRecvDesc(desc_in, "Service adding");
+            rv = PR_AddWaitFileDesc(shared->group, desc_in);
+            MW_ASSERT(PR_SUCCESS == rv);
+        }
+    }
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: Server interrupting worker_threads\n", shared->title);
+    for (index = 0; index < worker_threads; ++index)
+    {
+        rv = PR_Interrupt(worker_thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(worker_thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+    }
+    PR_DELETE(worker_thread);
+
+    PR_Close(listener);
+
+    CancelGroup(shared);
+
+}  /* ServerThread */
+
+static void RealOneGroupIO(Shared *shared)
+{
+    /*
+    ** Create a server that listens for connections and then services
+    ** requests that come in over those connections. The server never
+    ** deletes a connection and assumes a basic RPC model of operation.
+    **
+    ** Use worker_threads threads to service how every many open ports
+    ** there might be.
+    **
+    ** Oh, ya. Almost forget. Create (some) clients as well.
+    */
+    PRStatus rv;
+    PRIntn index;
+    PRThread *server_thread, *enumeration_thread, **client_thread;
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: creating server_thread\n", shared->title);
+
+    server_thread = PR_CreateThread(
+        PR_USER_THREAD, ServerThread, shared,
+        PR_PRIORITY_HIGH, thread_scope,
+        PR_JOINABLE_THREAD, 16 * 1024);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: creating enumeration_thread\n", shared->title);
+
+    enumeration_thread = PR_CreateThread(
+        PR_USER_THREAD, EnumerationThread, shared,
+        PR_PRIORITY_HIGH, thread_scope,
+        PR_JOINABLE_THREAD, 16 * 1024);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: snoozing before creating clients\n", shared->title);
+    PR_Sleep(5 * shared->timeout);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: creating client_threads\n", shared->title);
+    client_thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * client_threads);
+    for (index = 0; index < client_threads; ++index)
+    {
+        client_thread[index] = PR_CreateThread(
+            PR_USER_THREAD, ClientThread, shared,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+    }
+
+    while (ops_done < ops_required) PR_Sleep(shared->timeout);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: interrupting/joining client_threads\n", shared->title);
+    for (index = 0; index < client_threads; ++index)
+    {
+        rv = PR_Interrupt(client_thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(client_thread[index]);
+        MW_ASSERT(PR_SUCCESS == rv);
+    }
+    PR_DELETE(client_thread);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: interrupting/joining enumeration_thread\n", shared->title);
+    rv = PR_Interrupt(enumeration_thread);
+    MW_ASSERT(PR_SUCCESS == rv);
+    rv = PR_JoinThread(enumeration_thread);
+    MW_ASSERT(PR_SUCCESS == rv);
+
+    if (verbosity > quiet)
+        PR_fprintf(debug, "%s: interrupting/joining server_thread\n", shared->title);
+    rv = PR_Interrupt(server_thread);
+    MW_ASSERT(PR_SUCCESS == rv);
+    rv = PR_JoinThread(server_thread);
+    MW_ASSERT(PR_SUCCESS == rv);
+}  /* RealOneGroupIO */
+
+static void RunThisOne(
+    void (*func)(Shared*), const char *name, const char *test_name)
+{
+    Shared *shared;
+    if ((NULL == test_name) || (0 == PL_strcmp(name, test_name)))
+    {
+        if (verbosity > silent)
+            PR_fprintf(debug, "%s()\n", name);
+        shared = MakeShared(name);
+        ops_done = 0;
+        func(shared);  /* run the test */
+        MW_ASSERT(0 == desc_allocated);
+        DestroyShared(shared);
+    }
+}  /* RunThisOne */
+
+static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta)
+{
+    PRIntn verbage = (PRIntn)verbosity;
+    return (Verbosity)(verbage += delta);
+}  /* ChangeVerbosity */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PLOptStatus os;
+    const char *test_name = NULL;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dqGc:o:p:t:w:");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:
+            test_name = opt->value;
+            break;
+        case 'd':  /* debug mode */
+            if (verbosity < noisy)
+                verbosity = ChangeVerbosity(verbosity, 1);
+            break;
+        case 'q':  /* debug mode */
+            if (verbosity > silent)
+                verbosity = ChangeVerbosity(verbosity, -1);
+            break;
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'c':  /* number of client threads */
+            client_threads = atoi(opt->value);
+            break;
+        case 'o':  /* operations to compelete */
+            ops_required = atoi(opt->value);
+            break;
+        case 'p':  /* default port */
+            default_port = atoi(opt->value);
+            break;
+        case 't':  /* number of threads waiting */
+            worker_threads = atoi(opt->value);
+            break;
+        case 'w':  /* number of wait objects */
+            wait_objects = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (verbosity > 0)
+        debug = PR_GetSpecialFD(PR_StandardError);
+
+    RunThisOne(OneInThenCancelled, "OneInThenCancelled", test_name);
+    RunThisOne(OneOpOneThread, "OneOpOneThread", test_name);
+    RunThisOne(ManyOpOneThread, "ManyOpOneThread", test_name);
+    RunThisOne(SomeOpsSomeThreads, "SomeOpsSomeThreads", test_name);
+    RunThisOne(RealOneGroupIO, "RealOneGroupIO", test_name);
+    return 0;
+}  /* main */
+
+/* multwait.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/nameshm1.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/nameshm1.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,599 @@
+/* -*- 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: nameshm1.c -- Test Named Shared Memory
+**
+** Description: 
+** nameshm1 tests Named Shared Memory. nameshm1 performs two tests of
+** named shared memory. 
+** 
+** The first test is a basic test. The basic test operates as a single
+** process. The process exercises all the API elements of the facility.
+** This test also attempts to write to all locations in the shared
+** memory.
+**
+** The second test is a client-server test. The client-server test
+** creates a new instance of nameshm1, passing the -C argument to the
+** new process; this creates the client-side process. The server-side
+** (the instance of nameshm1 created from the command line) and the
+** client-side interact via inter-process semaphores to verify that the
+** shared memory segment can be read and written by both sides in a
+** synchronized maner.
+**
+** Note: Because this test runs in two processes, the log files created
+** by the test are not in chronological sequence; makes it hard to read.
+** As a temporary circumvention, I changed the definition(s) of the
+** _PUT_LOG() macro in prlog.c to force a flushall(), or equivalent.
+** This causes the log entries to be emitted in true chronological
+** order.
+**
+** Synopsis: nameshm1 [options] [name]
+** 
+** Options:
+** -d       Enables debug trace via PR_LOG()
+** -v       Enables verbose mode debug trace via PR_LOG()
+** -w       Causes the basic test to attempt to write to the segment
+**          mapped as read-only. When this option is specified, the
+**          test should crash with a seg-fault; this is a destructive
+**          test and is considered successful when it seg-faults.
+** 
+** -C       Causes nameshm1 to start as the client-side of a
+**          client-server pair of processes. Only the instance
+**          of nameshm1 operating as the server-side process should
+**          specify the -C option when creating the client-side process;
+**          the -C option should not be specified at the command line.
+**          The client-side uses the shared memory segment created by
+**          the server-side to communicate with the server-side
+**          process.
+**          
+** -p <n>   Specify the number of iterations the client-server tests
+**          should perform. Default: 1000.
+**
+** -s <n>   Size, in KBytes (1024), of the shared memory segment.
+**          Default: (10 * 1024)
+**
+** -i <n>   Number of client-side iterations. Default: 3
+**
+** name     specifies the name of the shared memory segment to be used.
+**          Default: /tmp/xxxNSPRshm
+**
+**
+** See also: prshm.h
+**
+** /lth. Aug-1999.
+*/
+
+#include <plgetopt.h> 
+#include <nspr.h>
+#include <stdlib.h>
+#include <string.h>
+#include <private/primpl.h>
+
+#define SEM_NAME1 "/tmp/nameshmSEM1"
+#define SEM_NAME2 "/tmp/nameshmSEM2"
+#define SEM_MODE  0666
+#define SHM_MODE  0666
+
+#define NameSize (1024)
+
+PRIntn  debug = 0;
+PRIntn  failed_already = 0;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRLogModuleInfo *lm;
+
+/* command line options */
+PRIntn      optDebug = 0;
+PRIntn      optVerbose = 0;
+PRUint32    optWriteRO = 0;     /* test write to read-only memory. should crash  */
+PRUint32    optClient = 0;
+PRUint32    optCreate = 1;
+PRUint32    optAttachRW = 1;
+PRUint32    optAttachRO = 1;
+PRUint32    optClose = 1;
+PRUint32    optDelete = 1;
+PRInt32     optPing = 1000;
+PRUint32    optSize = (10 * 1024 );
+PRInt32     optClientIterations = 3;
+char        optName[NameSize] = "/tmp/xxxNSPRshm";
+
+char buf[1024] = "";
+
+
+static void BasicTest( void ) 
+{
+    PRSharedMemory  *shm;
+    char *addr; /* address of shared memory segment */
+    PRUint32  i;
+    PRInt32 rc;
+
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Begin BasicTest" ));
+
+    if ( PR_FAILURE == PR_DeleteSharedMemory( optName )) {
+        PR_LOG( lm, msgLevel,
+            ("nameshm1: Initial PR_DeleteSharedMemory() failed. No problem"));
+    } else
+        PR_LOG( lm, msgLevel,
+            ("nameshm1: Initial PR_DeleteSharedMemory() success"));
+
+
+    shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE );
+    if ( NULL == shm )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RW Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RW Create: success: %p", shm ));
+
+    addr = PR_AttachSharedMemory( shm , 0 );
+    if ( NULL == addr ) 
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RW Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RW Attach: success: %p", addr ));
+
+    /* fill memory with i */
+    for ( i = 0; i < optSize ;  i++ )
+    {
+         *(addr + i) = i;
+    }
+
+    rc = PR_DetachSharedMemory( shm, addr );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RW Detach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RW Detach: success: " ));
+
+    rc = PR_CloseSharedMemory( shm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RW Close: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RW Close: success: " ));
+
+    rc = PR_DeleteSharedMemory( optName );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RW Delete: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RW Delete: success: " ));
+
+    PR_LOG( lm, msgLevel,
+            ("nameshm1: BasicTest(): Passed"));
+
+    return;
+} /* end BasicTest() */
+
+static void ReadOnlyTest( void )
+{
+    PRSharedMemory  *shm;
+    char *roAddr; /* read-only address of shared memory segment */
+    PRInt32 rc;
+
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Begin ReadOnlyTest" ));
+
+    shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE);
+    if ( NULL == shm )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RO Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RO Create: success: %p", shm ));
+
+
+    roAddr = PR_AttachSharedMemory( shm , PR_SHM_READONLY );
+    if ( NULL == roAddr ) 
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RO Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RO Attach: success: %p", roAddr ));
+
+    if ( optWriteRO )
+    {
+        *roAddr = 0x00; /* write to read-only memory */
+        failed_already = 1;
+        PR_LOG( lm, msgLevel, ("nameshm1: Wrote to read-only memory segment!"));
+        return;
+    }
+
+    rc = PR_DetachSharedMemory( shm, roAddr );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RO Detach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RO Detach: success: " ));
+
+    rc = PR_CloseSharedMemory( shm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RO Close: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RO Close: success: " ));
+
+    rc = PR_DeleteSharedMemory( optName );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: RO Destroy: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: RO Destroy: success: " ));
+
+    PR_LOG( lm, msgLevel,
+        ("nameshm1: ReadOnlyTest(): Passed"));
+
+    return;
+} /* end ReadOnlyTest() */
+
+static void DoClient( void )
+{
+    PRStatus rc;
+    PRSem *sem1, *sem2;
+    PRSharedMemory  *shm;
+    PRUint32 *addr; 
+    PRInt32 i;
+
+    PR_LOG( lm, msgLevel,
+            ("nameshm1: DoClient(): Starting"));
+
+    sem1 = PR_OpenSemaphore( SEM_NAME1, 0, 0, 0 );
+    PR_ASSERT( sem1 );
+
+    sem2 = PR_OpenSemaphore( SEM_NAME2, 0, 0, 0 );
+    PR_ASSERT( sem1 );
+
+    shm = PR_OpenSharedMemory( optName, optSize, 0, SHM_MODE );
+    if ( NULL == shm )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: DoClient(): Create: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: DoClient(): Create: success: %p", shm ));
+
+    addr = PR_AttachSharedMemory( shm , 0 );
+    if ( NULL == addr ) 
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: DoClient(): Attach: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: DoClient(): Attach: success: %p", addr ));
+
+    PR_LOG( lm, msgLevel,
+        ( "Client found: %s", addr));
+
+    PR_Sleep(PR_SecondsToInterval(4));
+    for ( i = 0 ; i < optPing ; i++ )
+    {
+        rc = PR_WaitSemaphore( sem2 );
+        PR_ASSERT( PR_FAILURE != rc );
+        
+        (*addr)++;
+        PR_ASSERT( (*addr % 2) == 0 );        
+        if ( optVerbose )
+            PR_LOG( lm, msgLevel,
+                 ( "nameshm1: Client ping: %d, i: %d", *addr, i));
+
+        rc = PR_PostSemaphore( sem1 );
+        PR_ASSERT( PR_FAILURE != rc );
+    }
+
+    rc = PR_CloseSemaphore( sem1 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_CloseSemaphore( sem2 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_DetachSharedMemory( shm, addr );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: DoClient(): Detach: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: DoClient(): Detach: success: " ));
+
+    rc = PR_CloseSharedMemory( shm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: DoClient(): Close: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: DoClient(): Close: success: " ));
+
+    return;
+}    /* end DoClient() */
+
+static void ClientServerTest( void )
+{
+    PRStatus rc;
+    PRSem *sem1, *sem2;
+    PRProcess *proc;
+    PRInt32 exit_status;
+    PRSharedMemory  *shm;
+    PRUint32 *addr; 
+    PRInt32 i;
+    char *child_argv[8];
+    char buf[24];
+
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Begin ClientServerTest" ));
+
+    rc = PR_DeleteSharedMemory( optName );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: Server: Destroy: failed. No problem"));
+    } else
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: Server: Destroy: success" ));
+
+
+    shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE);
+    if ( NULL == shm )
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: Server: Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Server: Create: success: %p", shm ));
+
+    addr = PR_AttachSharedMemory( shm , 0 );
+    if ( NULL == addr ) 
+    {
+        PR_LOG( lm, msgLevel,
+                 ( "nameshm1: Server: Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Server: Attach: success: %p", addr ));
+
+    sem1 = PR_OpenSemaphore( SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0 );
+    PR_ASSERT( sem1 );
+
+    sem2 = PR_OpenSemaphore( SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 1 );
+    PR_ASSERT( sem1 );
+
+    strcpy( (char*)addr, "FooBar" );
+
+    child_argv[0] = "nameshm1";
+    child_argv[1] = "-C";
+    child_argv[2] = "-p";
+    sprintf( buf, "%d", optPing );
+    child_argv[3] = buf;
+    child_argv[4] = optName;
+    child_argv[5] = NULL;
+
+    proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
+    PR_ASSERT( proc );
+
+    PR_Sleep( PR_SecondsToInterval(4));
+
+    *addr = 1;
+    for ( i = 0 ; i < optPing ; i++ )
+    { 
+        rc = PR_WaitSemaphore( sem1 );
+        PR_ASSERT( PR_FAILURE != rc );
+
+        (*addr)++;
+        PR_ASSERT( (*addr % 2) == 1 );
+        if ( optVerbose )
+            PR_LOG( lm, msgLevel,
+                 ( "nameshm1: Server pong: %d, i: %d", *addr, i));
+
+    
+        rc = PR_PostSemaphore( sem2 );
+        PR_ASSERT( PR_FAILURE != rc );
+    }
+
+    rc = PR_WaitProcess( proc, &exit_status );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_CloseSemaphore( sem1 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_CloseSemaphore( sem2 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_DeleteSemaphore( SEM_NAME1 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_DeleteSemaphore( SEM_NAME2 );
+    PR_ASSERT( PR_FAILURE != rc );
+
+    rc = PR_DetachSharedMemory( shm, addr );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: Server: Detach: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Server: Detach: success: " ));
+
+    rc = PR_CloseSharedMemory( shm );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: Server: Close: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+        ( "nameshm1: Server: Close: success: " ));
+
+    rc = PR_DeleteSharedMemory( optName );
+    if ( PR_FAILURE == rc )
+    {
+        PR_LOG( lm, msgLevel,
+            ( "nameshm1: Server: Destroy: Error: %ld. OSError: %ld", 
+                PR_GetError(), PR_GetOSError()));
+        failed_already = 1;
+        return;
+    }
+    PR_LOG( lm, msgLevel,
+        ( "nameshm1: Server: Destroy: success" ));
+
+    return;
+} /* end ClientServerTest() */
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    {
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "Cdvw:s:p:i:");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'v':  /* debug mode */
+                optVerbose = 1;
+                /* no break! fall into debug option */
+            case 'd':  /* debug mode */
+                debug = 1;
+			    msgLevel = PR_LOG_DEBUG;
+                break;
+            case 'w':  /* try writing to memory mapped read-only */
+                optWriteRO = 1;
+                break;
+            case 'C':
+                optClient = 1;
+                break;
+            case 's':
+                optSize = atol(opt->value) * 1024;
+                break;
+            case 'p':
+                optPing = atol(opt->value);
+                break;
+            case 'i':
+                optClientIterations = atol(opt->value);
+                break;
+            default:
+                strcpy( optName, opt->value );
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    }
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+    
+    PR_LOG( lm, msgLevel,
+             ( "nameshm1: Starting" ));
+
+    if ( optClient )
+    {
+        DoClient();
+    } else {
+        BasicTest();
+        if ( failed_already != 0 )
+            goto Finished;
+        ReadOnlyTest();
+        if ( failed_already != 0 )
+            goto Finished;
+        ClientServerTest();
+    }
+
+Finished:
+    if ( debug ) printf("%s\n", (failed_already)? "FAIL" : "PASS" );
+    return( (failed_already)? 1 : 0 );
+}  /* main() */
+/* end instrumt.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/nbconn.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/nbconn.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,592 @@
+/* -*- 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 ***** */
+
+/*
+ * A test for nonblocking connect.  Functions tested include PR_Connect,
+ * PR_Poll, and PR_GetConnectStatus.
+ *
+ * The test should be invoked with a host name, for example:
+ *     nbconn www.netscape.com
+ * It will do a nonblocking connect to port 80 (HTTP) on that host,
+ * and when connected, issue the "GET /" HTTP command.
+ *
+ * You should run this test in three ways:
+ * 1. To a known web site, such as www.netscape.com.  The HTML of the
+ *    top-level page at the web site should be printed.
+ * 2. To a machine not running a web server at port 80.  This test should
+ *    fail.  Ideally the error code should be PR_CONNECT_REFUSED_ERROR.
+ *    But it is possible to return PR_UNKNOWN_ERROR on certain platforms.
+ * 3. To an unreachable machine, for example, a machine that is off line.
+ *    The test should fail after the connect times out.  Ideally the
+ *    error code should be PR_IO_TIMEOUT_ERROR, but it is possible to
+ *    return PR_UNKNOWN_ERROR on certain platforms.
+ */
+
+#include "nspr.h"
+#include "plgetopt.h"
+#include <stdio.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+static char *hosts[4] = {"cynic", "warp", "gandalf", "neon"};
+#endif
+
+#define SERVER_MAX_BIND_COUNT        100
+#define DATA_BUF_SIZE        		 256
+#define TCP_SERVER_PORT            10000
+#define TCP_UNUSED_PORT            211
+
+typedef struct Server_Param {
+    PRFileDesc *sp_fd;		/* server port */
+} Server_Param;
+static void PR_CALLBACK TCP_Server(void *arg);
+
+int _debug_on;
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+static PRIntn connection_success_test();
+static PRIntn connection_failure_test();
+
+int main(int argc, char **argv)
+{
+    PRHostEnt he;
+    char buf[1024];
+    PRNetAddr addr;
+    PRPollDesc pd;
+    PRStatus rv;
+    PRSocketOptionData optData;
+	const char *hostname = NULL;
+    PRIntn default_case, n, bytes_read, bytes_sent;
+	PRInt32 failed_already = 0;
+#ifdef XP_MAC
+	int index;
+	PRIntervalTime timeout;
+#endif
+
+    /*
+     * -d           debug mode
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:  /* debug mode */
+            hostname = opt->value;
+            break;
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("nbconn.log");
+	for (index=0; index<4; index++) {
+	argv[1] = hosts[index];
+	timeout = PR_INTERVAL_NO_TIMEOUT;
+	if (index == 3)
+		timeout = PR_SecondsToInterval(10UL);
+#endif
+
+
+    PR_STDIO_INIT();
+#ifndef XP_MAC
+    if (hostname)
+		default_case = 0;
+	else
+		default_case = 1;
+#endif
+
+	if (default_case) {
+
+		/*
+		 * In the default case the following tests are executed:
+		 *	1. successful connection: a server thread accepts a connection
+		 *	   from the main thread
+		 *	2. unsuccessful connection: the main thread tries to connect to a
+		 *	   non-existent port and expects to get an error
+		 */
+		rv = connection_success_test();
+		if (rv == 0)
+			rv = connection_failure_test();
+		return rv;
+	} else {
+    	PRFileDesc *sock;
+
+		if (PR_GetHostByName(argv[1], buf, sizeof(buf), &he) == PR_FAILURE) {
+			printf( "Unknown host: %s\n", argv[1]);
+			exit(1);
+		} else {
+			printf( "host: %s\n", buf);
+		}
+		PR_EnumerateHostEnt(0, &he, 80, &addr);
+
+		sock = PR_NewTCPSocket();
+		optData.option = PR_SockOpt_Nonblocking;
+		optData.value.non_blocking = PR_TRUE;
+		PR_SetSocketOption(sock, &optData);
+		rv = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+		if (rv == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) {
+			printf( "Connect in progress\n");
+		}
+
+		pd.fd = sock;
+		pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+#ifndef XP_MAC
+		n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+#else
+		n = PR_Poll(&pd, 1, timeout);
+#endif
+		if (n == -1) {
+			printf( "PR_Poll failed\n");
+			exit(1);
+		}
+		printf( "PR_Poll returns %d\n", n);
+		if (pd.out_flags & PR_POLL_READ) {
+			printf( "PR_POLL_READ\n");
+		}
+		if (pd.out_flags & PR_POLL_WRITE) {
+			printf( "PR_POLL_WRITE\n");
+		}
+		if (pd.out_flags & PR_POLL_EXCEPT) {
+			printf( "PR_POLL_EXCEPT\n");
+		}
+		if (pd.out_flags & PR_POLL_ERR) {
+			printf( "PR_POLL_ERR\n");
+		}
+		if (pd.out_flags & PR_POLL_NVAL) {
+			printf( "PR_POLL_NVAL\n");
+		}
+
+		if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
+			printf("PR_GetConnectStatus: connect succeeded\n");
+			/* Mac and Win16 have trouble printing to the console. */
+#if !defined(XP_MAC) && !defined(WIN16)
+			PR_Write(sock, "GET /\r\n\r\n", 9);
+			PR_Shutdown(sock, PR_SHUTDOWN_SEND);
+			pd.in_flags = PR_POLL_READ;
+			while (1) {
+				n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+				printf( "poll returns %d\n", n);
+				n = PR_Read(sock, buf, sizeof(buf));
+				printf( "read returns %d\n", n);
+				if (n <= 0) {
+					break;
+				}
+				PR_Write(PR_STDOUT, buf, n);
+			}
+#endif
+		} else {
+			if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
+				printf( "PR_GetConnectStatus: connect still in progress\n");
+				exit(1);
+			}
+			printf( "PR_GetConnectStatus: connect failed: (%ld, %ld)\n",
+					PR_GetError(), PR_GetOSError());
+		}
+		PR_Close(sock);
+#ifdef XP_MAC
+		} /* end of for loop */
+#endif
+    	printf( "PASS\n");
+    	return 0;
+
+	}
+}
+
+
+/*
+ * TCP Server
+ *    Server Thread
+ *    Accept a connection from the client and write some data
+ */
+static void PR_CALLBACK
+TCP_Server(void *arg)
+{
+    Server_Param *sp = (Server_Param *) arg;
+    PRFileDesc *sockfd, *newsockfd;
+	char data_buf[DATA_BUF_SIZE];
+    PRIntn rv, bytes_read;
+
+	sockfd = sp->sp_fd;
+	if ((newsockfd = PR_Accept(sockfd, NULL,
+		PR_INTERVAL_NO_TIMEOUT)) == NULL) {
+		fprintf(stderr,"ERROR - PR_Accept failed: (%d,%d)\n",
+										PR_GetError(), PR_GetOSError());
+		return;
+	}
+	bytes_read = 0;
+	while (bytes_read != DATA_BUF_SIZE) {
+		rv = PR_Read(newsockfd, data_buf + bytes_read ,
+									DATA_BUF_SIZE - bytes_read);
+		if (rv < 0) {
+			fprintf(stderr,"Error - PR_Read failed: (%d, %d)\n",
+							PR_GetError(), PR_GetOSError());
+			PR_Close(newsockfd);
+			return;
+		}
+		PR_ASSERT(rv != 0);
+		bytes_read += rv;
+	}
+	DPRINTF(("Bytes read from client - %d\n",bytes_read));
+	rv = PR_Write(newsockfd, data_buf,DATA_BUF_SIZE);
+	if (rv < 0) {
+		fprintf(stderr,"Error - PR_Write failed: (%d, %d)\n",
+						PR_GetError(), PR_GetOSError());
+		PR_Close(newsockfd);
+		return;
+	}
+	PR_ASSERT(rv == DATA_BUF_SIZE);
+	DPRINTF(("Bytes written to client - %d\n",rv));
+	PR_Close(newsockfd);
+}
+
+
+/*
+ * test for successful connection using a non-blocking socket
+ */
+static PRIntn
+connection_success_test()
+{
+	PRFileDesc *sockfd = NULL, *conn_fd = NULL;
+	PRNetAddr netaddr;
+	PRInt32 i, rv;
+    PRPollDesc pd;
+    PRSocketOptionData optData;
+	PRThread *thr = NULL;
+	Server_Param sp;
+	char send_buf[DATA_BUF_SIZE], recv_buf[DATA_BUF_SIZE];
+    PRIntn default_case, n, bytes_read, bytes_sent;
+    PRIntn failed_already = 0;
+
+	/*
+	 * Create a tcp socket
+	 */
+	if ((sockfd = PR_NewTCPSocket()) == NULL) {
+		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
+		failed_already=1;
+		goto def_exit;
+	}
+	memset(&netaddr, 0 , sizeof(netaddr));
+	netaddr.inet.family = PR_AF_INET;
+	netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
+	netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+	/*
+	 * try a few times to bind server's address, if addresses are in
+	 * use
+	 */
+	i = 0;
+	while (PR_Bind(sockfd, &netaddr) < 0) {
+		if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+			netaddr.inet.port += 2;
+			if (i++ < SERVER_MAX_BIND_COUNT)
+				continue;
+		}
+		fprintf(stderr,"ERROR - PR_Bind failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+
+	if (PR_Listen(sockfd, 32) < 0) {
+		fprintf(stderr,"ERROR - PR_Listen failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+
+	if (PR_GetSockName(sockfd, &netaddr) < 0) {
+		fprintf(stderr,"ERROR - PR_GetSockName failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+	if ((conn_fd = PR_NewTCPSocket()) == NULL) {
+		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
+		failed_already=1;
+		goto def_exit;
+	}
+	optData.option = PR_SockOpt_Nonblocking;
+	optData.value.non_blocking = PR_TRUE;
+	PR_SetSocketOption(conn_fd, &optData);
+	rv = PR_Connect(conn_fd, &netaddr, PR_INTERVAL_NO_TIMEOUT);
+	if (rv == PR_FAILURE) {
+		if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
+			DPRINTF(("Connect in progress\n"));
+		} else  {
+			fprintf(stderr,"Error - PR_Connect failed: (%d, %d)\n",
+									PR_GetError(), PR_GetOSError());
+			failed_already=1;
+			goto def_exit;
+		}
+	}
+	/*
+	 * Now create a thread to accept a connection
+	 */
+	sp.sp_fd = sockfd;
+	thr = PR_CreateThread(PR_USER_THREAD, TCP_Server, (void *)&sp, 
+			PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+	if (thr == NULL) {
+		fprintf(stderr,"Error - PR_CreateThread failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+	DPRINTF(("Created TCP_Server thread [0x%x]\n",thr));
+	pd.fd = conn_fd;
+	pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+#ifndef XP_MAC
+	n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+#else
+	n = PR_Poll(&pd, 1, timeout);
+#endif
+	if (n == -1) {
+		fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+	if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
+		PRInt32 rv;
+
+		DPRINTF(("Connection successful\n"));
+
+		/*
+		 * Write some data, read it back and check data integrity to
+		 * make sure the connection is good
+		 */
+		pd.in_flags = PR_POLL_WRITE;
+		bytes_sent = 0;
+		memset(send_buf, 'a', DATA_BUF_SIZE);
+		while (bytes_sent != DATA_BUF_SIZE) {
+			rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+			if (rv < 0) {
+				fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
+								PR_GetError(), PR_GetOSError());
+				failed_already=1;
+				goto def_exit;
+			}
+			PR_ASSERT((rv == 1) && (pd.out_flags == PR_POLL_WRITE));
+			rv = PR_Write(conn_fd, send_buf + bytes_sent,
+										DATA_BUF_SIZE - bytes_sent);
+			if (rv < 0) {
+				fprintf(stderr,"Error - PR_Write failed: (%d, %d)\n",
+								PR_GetError(), PR_GetOSError());
+				failed_already=1;
+				goto def_exit;
+			}
+			PR_ASSERT(rv > 0);
+			bytes_sent += rv;
+		}
+		DPRINTF(("Bytes written to server - %d\n",bytes_sent));
+		PR_Shutdown(conn_fd, PR_SHUTDOWN_SEND);
+		pd.in_flags = PR_POLL_READ;
+		bytes_read = 0;
+		memset(recv_buf, 0, DATA_BUF_SIZE);
+		while (bytes_read != DATA_BUF_SIZE) {
+			rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+			if (rv < 0) {
+				fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
+								PR_GetError(), PR_GetOSError());
+				failed_already=1;
+				goto def_exit;
+			}
+			PR_ASSERT((rv == 1) && (pd.out_flags == PR_POLL_READ));
+			rv = PR_Read(conn_fd, recv_buf + bytes_read ,
+										DATA_BUF_SIZE - bytes_read);
+			if (rv < 0) {
+				fprintf(stderr,"Error - PR_Read failed: (%d, %d)\n",
+								PR_GetError(), PR_GetOSError());
+				failed_already=1;
+				goto def_exit;
+			}
+			PR_ASSERT(rv != 0);
+			bytes_read += rv;
+		}
+		DPRINTF(("Bytes read from server - %d\n",bytes_read));
+		/*
+		 * verify the data read
+		 */
+		if (memcmp(send_buf, recv_buf, DATA_BUF_SIZE) != 0) {
+			fprintf(stderr,"ERROR - data corruption\n");
+			failed_already=1;
+			goto def_exit;
+		}
+		DPRINTF(("Data integrity verified\n"));
+	} else {
+		fprintf(stderr,"PR_GetConnectStatus: connect failed: (%ld, %ld)\n",
+				PR_GetError(), PR_GetOSError());
+		failed_already = 1;
+		goto def_exit;
+	}
+def_exit:
+	if (thr) {
+		PR_JoinThread(thr);
+		thr = NULL;
+	}
+	if (sockfd) {
+		PR_Close(sockfd);
+		sockfd = NULL;
+	}
+	if (conn_fd) {
+		PR_Close(conn_fd);
+		conn_fd = NULL;
+	}
+	if (failed_already)
+		return 1;
+	else
+		return 0;
+
+}
+
+/*
+ * test for connection to a non-existent port using a non-blocking socket
+ */
+static PRIntn
+connection_failure_test()
+{
+	PRFileDesc *sockfd = NULL, *conn_fd = NULL;
+	PRNetAddr netaddr;
+	PRInt32 i, rv;
+    PRPollDesc pd;
+    PRSocketOptionData optData;
+    PRIntn n, failed_already = 0;
+
+	/*
+	 * Create a tcp socket
+	 */
+	if ((sockfd = PR_NewTCPSocket()) == NULL) {
+		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
+		failed_already=1;
+		goto def_exit;
+	}
+	memset(&netaddr, 0 , sizeof(netaddr));
+	netaddr.inet.family = PR_AF_INET;
+	netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
+	netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+	/*
+	 * try a few times to bind server's address, if addresses are in
+	 * use
+	 */
+	i = 0;
+	while (PR_Bind(sockfd, &netaddr) < 0) {
+		if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+			netaddr.inet.port += 2;
+			if (i++ < SERVER_MAX_BIND_COUNT)
+				continue;
+		}
+		fprintf(stderr,"ERROR - PR_Bind failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+
+	if (PR_GetSockName(sockfd, &netaddr) < 0) {
+		fprintf(stderr,"ERROR - PR_GetSockName failed: (%d,%d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+#ifdef AIX
+	/*
+	 * On AIX, set to unused/reserved port
+	 */
+	netaddr.inet.port = PR_htons(TCP_UNUSED_PORT);
+#endif
+	if ((conn_fd = PR_NewTCPSocket()) == NULL) {
+		fprintf(stderr,"Error - PR_NewTCPSocket failed\n");
+		failed_already=1;
+		goto def_exit;
+	}
+	optData.option = PR_SockOpt_Nonblocking;
+	optData.value.non_blocking = PR_TRUE;
+	PR_SetSocketOption(conn_fd, &optData);
+	rv = PR_Connect(conn_fd, &netaddr, PR_INTERVAL_NO_TIMEOUT);
+	if (rv == PR_FAILURE) {
+		DPRINTF(("PR_Connect to a non-listen port failed: (%d, %d)\n",
+									PR_GetError(), PR_GetOSError()));
+	} else {
+		PR_ASSERT(rv == PR_SUCCESS);
+		fprintf(stderr,"Error - PR_Connect succeeded, expected to fail\n");
+		failed_already=1;
+		goto def_exit;
+	}
+	pd.fd = conn_fd;
+	pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+#ifndef XP_MAC
+	n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+#else
+	n = PR_Poll(&pd, 1, timeout);
+#endif
+	if (n == -1) {
+		fprintf(stderr,"Error - PR_Poll failed: (%d, %d)\n",
+									PR_GetError(), PR_GetOSError());
+		failed_already=1;
+		goto def_exit;
+	}
+	if (PR_GetConnectStatus(&pd) == PR_SUCCESS) {
+		PRInt32 rv;
+		fprintf(stderr,"PR_GetConnectStatus succeeded, expected to fail\n");
+		failed_already = 1;
+		goto def_exit;
+	}
+	rv = PR_GetError();
+	DPRINTF(("Connection failed, successfully with PR_Error %d\n",rv));
+def_exit:
+	if (sockfd) {
+		PR_Close(sockfd);
+		sockfd = NULL;
+	}
+	if (conn_fd) {
+		PR_Close(conn_fd);
+		conn_fd = NULL;
+	}
+	if (failed_already)
+		return 1;
+	else
+		return 0;
+
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/nblayer.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/nblayer.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,707 @@
+/* -*- 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 "prio.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prlog.h"
+#include "prerror.h"
+#include "prnetdb.h"
+#include "prthread.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+#include "prwin16.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Testing layering of I/O
+**
+**      The layered server
+** A thread that acts as a server. It creates a TCP listener with a dummy
+** layer pushed on top. Then listens for incoming connections. Each connection
+** request for connection will be layered as well, accept one request, echo
+** it back and close.
+**
+**      The layered client
+** Pretty much what you'd expect.
+*/
+
+static PRFileDesc *logFile;
+static PRDescIdentity identity;
+static PRNetAddr server_address;
+
+static PRIOMethods myMethods;
+
+typedef enum {rcv_get_debit, rcv_send_credit, rcv_data} RcvState;
+typedef enum {xmt_send_debit, xmt_recv_credit, xmt_data} XmtState;
+
+struct PRFilePrivate
+{
+    RcvState rcvstate;
+    XmtState xmtstate;
+    PRInt32 rcvreq, rcvinprogress;
+    PRInt32 xmtreq, xmtinprogress;
+};
+
+typedef enum Verbosity {silent, quiet, chatty, noisy} Verbosity;
+
+static PRIntn minor_iterations = 5;
+static PRIntn major_iterations = 1;
+static Verbosity verbosity = quiet;
+static PRUint16 default_port = 12273;
+
+static PRFileDesc *PushLayer(PRFileDesc *stack)
+{
+    PRStatus rv;
+    PRFileDesc *layer = PR_CreateIOLayerStub(identity, &myMethods);
+    layer->secret = PR_NEWZAP(PRFilePrivate);
+    rv = PR_PushIOLayer(stack, PR_GetLayersIdentity(stack), layer);
+    PR_ASSERT(PR_SUCCESS == rv);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Pushed layer(0x%x) onto stack(0x%x)\n", layer, stack);
+    return stack;
+}  /* PushLayer */
+
+static PRFileDesc *PopLayer(PRFileDesc *stack)
+{
+    PRFileDesc *popped = PR_PopIOLayer(stack, identity);
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Popped layer(0x%x) from stack(0x%x)\n", popped, stack);
+    PR_DELETE(popped->secret);
+    popped->dtor(popped);
+    return stack;
+}  /* PopLayer */
+
+static void PR_CALLBACK Client(void *arg)
+{
+    PRStatus rv;
+    PRIntn mits;
+    PRInt32 ready;
+    PRUint8 buffer[100];
+    PRPollDesc polldesc;
+    PRIntn empty_flags = 0;
+    PRIntn bytes_read, bytes_sent;
+    PRFileDesc *stack = (PRFileDesc*)arg;
+
+    /* Initialize the buffer so that Purify won't complain */
+    memset(buffer, 0, sizeof(buffer));
+
+    rv = PR_Connect(stack, &server_address, PR_INTERVAL_NO_TIMEOUT);
+    if ((PR_FAILURE == rv) && (PR_IN_PROGRESS_ERROR == PR_GetError()))
+    {
+        if (verbosity > quiet)
+            PR_fprintf(logFile, "Client connect 'in progress'\n");
+        do
+        {
+            polldesc.fd = stack;
+            polldesc.out_flags = 0;
+            polldesc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+            ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+            if ((1 != ready)  /* if not 1, then we're dead */
+            || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                { PR_ASSERT(!"Whoa!"); break; }
+            if (verbosity > quiet)
+                PR_fprintf(
+                    logFile, "Client connect 'in progress' [0x%x]\n",
+                    polldesc.out_flags);
+            rv = PR_GetConnectStatus(&polldesc);
+            if ((PR_FAILURE == rv)
+            && (PR_IN_PROGRESS_ERROR != PR_GetError())) break;
+        } while (PR_FAILURE == rv);
+    }
+    PR_ASSERT(PR_SUCCESS == rv);
+    if (verbosity > chatty)
+        PR_fprintf(logFile, "Client created connection\n");
+
+    for (mits = 0; mits < minor_iterations; ++mits)
+    {
+        bytes_sent = 0;
+        if (verbosity > quiet)
+            PR_fprintf(logFile, "Client sending %d bytes\n", sizeof(buffer));
+        do
+        {
+            if (verbosity > chatty)
+                PR_fprintf(
+                    logFile, "Client sending %d bytes\n",
+                    sizeof(buffer) - bytes_sent);
+            ready = PR_Send(
+                stack, buffer + bytes_sent, sizeof(buffer) - bytes_sent,
+                empty_flags, PR_INTERVAL_NO_TIMEOUT);
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Client send status [%d]\n", ready);
+            if (0 < ready) bytes_sent += ready;
+            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+            {
+                polldesc.fd = stack;
+                polldesc.out_flags = 0;
+                polldesc.in_flags = PR_POLL_WRITE;
+                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                if ((1 != ready)  /* if not 1, then we're dead */
+                || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                    { PR_ASSERT(!"Whoa!"); break; }
+            }
+            else break;
+        } while (bytes_sent < sizeof(buffer));
+        PR_ASSERT(sizeof(buffer) == bytes_sent);
+
+        bytes_read = 0;
+        do
+        {
+            if (verbosity > chatty)
+                PR_fprintf(
+                    logFile, "Client receiving %d bytes\n",
+                    bytes_sent - bytes_read);
+            ready = PR_Recv(
+                stack, buffer + bytes_read, bytes_sent - bytes_read,
+                empty_flags, PR_INTERVAL_NO_TIMEOUT);
+            if (verbosity > chatty)
+                PR_fprintf(
+                    logFile, "Client receive status [%d]\n", ready);
+            if (0 < ready) bytes_read += ready;
+            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+            {
+                polldesc.fd = stack;
+                polldesc.out_flags = 0;
+                polldesc.in_flags = PR_POLL_READ;
+                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                if ((1 != ready)  /* if not 1, then we're dead */
+                || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                    { PR_ASSERT(!"Whoa!"); break; }
+            }
+            else break;
+        } while (bytes_read < bytes_sent);
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Client received %d bytes\n", bytes_read);
+        PR_ASSERT(bytes_read == bytes_sent);
+    }
+
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Client shutting down stack\n");
+    
+    rv = PR_Shutdown(stack, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
+}  /* Client */
+
+static void PR_CALLBACK Server(void *arg)
+{
+    PRStatus rv;
+    PRInt32 ready;
+    PRUint8 buffer[100];
+    PRFileDesc *service;
+    PRUintn empty_flags = 0;
+    struct PRPollDesc polldesc;
+    PRIntn bytes_read, bytes_sent;
+    PRFileDesc *stack = (PRFileDesc*)arg;
+    PRNetAddr client_address;
+
+    do
+    {
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Server accepting connection\n");
+        service = PR_Accept(stack, &client_address, PR_INTERVAL_NO_TIMEOUT);
+        if (verbosity > chatty)
+            PR_fprintf(logFile, "Server accept status [0x%p]\n", service);
+        if ((NULL == service) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+        {
+            polldesc.fd = stack;
+            polldesc.out_flags = 0;
+            polldesc.in_flags = PR_POLL_READ | PR_POLL_EXCEPT;
+            ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+            if ((1 != ready)  /* if not 1, then we're dead */
+            || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                { PR_ASSERT(!"Whoa!"); break; }
+        }
+    } while (NULL == service);
+    PR_ASSERT(NULL != service);
+        
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Server accepting connection\n");
+
+    do
+    {
+        bytes_read = 0;
+        do
+        {
+            if (verbosity > chatty)
+                PR_fprintf(
+                    logFile, "Server receiving %d bytes\n",
+                    sizeof(buffer) - bytes_read);
+            ready = PR_Recv(
+                service, buffer + bytes_read, sizeof(buffer) - bytes_read,
+                empty_flags, PR_INTERVAL_NO_TIMEOUT);
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server receive status [%d]\n", ready);
+            if (0 < ready) bytes_read += ready;
+            else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+            {
+                polldesc.fd = service;
+                polldesc.out_flags = 0;
+                polldesc.in_flags = PR_POLL_READ;
+                ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                if ((1 != ready)  /* if not 1, then we're dead */
+                || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                    { PR_ASSERT(!"Whoa!"); break; }
+            }
+            else break;
+        } while (bytes_read < sizeof(buffer));
+
+        if (0 != bytes_read)
+        {
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server received %d bytes\n", bytes_read);
+            PR_ASSERT(bytes_read > 0);
+
+            bytes_sent = 0;
+            do
+            {
+                ready = PR_Send(
+                    service, buffer + bytes_sent, bytes_read - bytes_sent,
+                    empty_flags, PR_INTERVAL_NO_TIMEOUT);
+                if (0 < ready)
+                {
+                    bytes_sent += ready;
+                }
+                else if ((-1 == ready) && (PR_WOULD_BLOCK_ERROR == PR_GetError()))
+                {
+                    polldesc.fd = service;
+                    polldesc.out_flags = 0;
+                    polldesc.in_flags = PR_POLL_WRITE;
+                    ready = PR_Poll(&polldesc, 1, PR_INTERVAL_NO_TIMEOUT);
+                    if ((1 != ready)  /* if not 1, then we're dead */
+                    || (0 == (polldesc.in_flags & polldesc.out_flags)))
+                        { PR_ASSERT(!"Whoa!"); break; }
+                }
+                else break;
+            } while (bytes_sent < bytes_read);
+            PR_ASSERT(bytes_read == bytes_sent);
+            if (verbosity > chatty)
+                PR_fprintf(logFile, "Server sent %d bytes\n", bytes_sent);
+        }
+    } while (0 != bytes_read);
+
+    if (verbosity > quiet)
+        PR_fprintf(logFile, "Server shutting down stack\n");
+    rv = PR_Shutdown(service, PR_SHUTDOWN_BOTH); PR_ASSERT(PR_SUCCESS == rv);
+    rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+
+}  /* Server */
+
+static PRStatus PR_CALLBACK MyClose(PRFileDesc *fd)
+{
+    PR_DELETE(fd->secret);  /* manage my secret file object */
+    return (PR_GetDefaultIOMethods())->close(fd);  /* let him do all the work */
+}  /* MyClose */
+
+static PRInt16 PR_CALLBACK MyPoll(
+    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
+{
+    PRInt16 my_flags, new_flags;
+    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
+    if (0 != (PR_POLL_READ & in_flags))
+    {
+        /* client thinks he's reading */
+        switch (mine->rcvstate)
+        {
+            case rcv_send_credit:
+                my_flags = (in_flags & ~PR_POLL_READ) | PR_POLL_WRITE;
+                break;
+            case rcv_data:
+            case rcv_get_debit:
+                my_flags = in_flags;
+            default: break;
+        }
+    }
+    else if (0 != (PR_POLL_WRITE & in_flags))
+    {
+        /* client thinks he's writing */
+        switch (mine->xmtstate)
+        {
+            case xmt_recv_credit:
+                my_flags = (in_flags & ~PR_POLL_WRITE) | PR_POLL_READ;
+                break;
+            case xmt_send_debit:
+            case xmt_data:
+                my_flags = in_flags;
+            default: break;
+        }
+    }
+    else PR_ASSERT(!"How'd I get here?");
+    new_flags = (fd->lower->methods->poll)(fd->lower, my_flags, out_flags);
+    if (verbosity > chatty)
+        PR_fprintf(
+            logFile, "Poll [i: 0x%x, m: 0x%x, o: 0x%x, n: 0x%x]\n",
+            in_flags, my_flags, *out_flags, new_flags);
+    return new_flags;
+}  /* MyPoll */
+
+static PRFileDesc * PR_CALLBACK MyAccept(
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRStatus rv;
+    PRFileDesc *newfd, *layer = fd;
+    PRFileDesc *newstack;
+    PRFilePrivate *newsecret;
+
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    newstack = PR_NEW(PRFileDesc);
+    if (NULL == newstack)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    newsecret = PR_NEW(PRFilePrivate);
+    if (NULL == newsecret)
+    {
+        PR_DELETE(newstack);
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    *newstack = *fd;  /* make a copy of the accepting layer */
+    *newsecret = *fd->secret;
+    newstack->secret = newsecret;
+
+    newfd = (fd->lower->methods->accept)(fd->lower, addr, timeout);
+    if (NULL == newfd)
+    {
+        PR_DELETE(newsecret);
+        PR_DELETE(newstack);
+        return NULL;
+    }
+
+    /* this PR_PushIOLayer call cannot fail */
+    rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return newfd;  /* that's it */
+}
+
+static PRInt32 PR_CALLBACK MyRecv(
+    PRFileDesc *fd, void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    char *b;
+    PRInt32 rv;
+    PRFileDesc *lo = fd->lower;
+    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
+
+    do
+    {
+        switch (mine->rcvstate)
+        {
+        case rcv_get_debit:
+            b = (char*)&mine->rcvreq;
+            mine->rcvreq = amount;
+            rv = lo->methods->recv(
+                lo, b + mine->rcvinprogress,
+                sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout);
+            if (0 == rv) goto closed;
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->rcvinprogress += rv;  /* accumulate the read */
+            if (mine->rcvinprogress < sizeof(mine->rcvreq)) break;  /* loop */
+            mine->rcvstate = rcv_send_credit;
+            mine->rcvinprogress = 0;
+        case rcv_send_credit:
+            b = (char*)&mine->rcvreq;
+            rv = lo->methods->send(
+                lo, b + mine->rcvinprogress,
+                sizeof(mine->rcvreq) - mine->rcvinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->rcvinprogress += rv;  /* accumulate the read */
+            if (mine->rcvinprogress < sizeof(mine->rcvreq)) break;  /* loop */
+            mine->rcvstate = rcv_data;
+            mine->rcvinprogress = 0;
+        case rcv_data:
+            b = (char*)buf;
+            rv = lo->methods->recv(
+                lo, b + mine->rcvinprogress,
+                mine->rcvreq - mine->rcvinprogress, flags, timeout);
+            if (0 == rv) goto closed;
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->rcvinprogress += rv;  /* accumulate the read */
+            if (mine->rcvinprogress < amount) break;  /* loop */
+            mine->rcvstate = rcv_get_debit;
+            mine->rcvinprogress = 0;
+            return mine->rcvreq;  /* << -- that's it! */
+        default:
+            break;
+        }
+    } while (-1 != rv);
+    return rv;
+closed:
+    mine->rcvinprogress = 0;
+    mine->rcvstate = rcv_get_debit;
+    return 0;
+}  /* MyRecv */
+
+static PRInt32 PR_CALLBACK MySend(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, PRIntervalTime timeout)
+{
+    char *b;
+    PRInt32 rv;
+    PRFileDesc *lo = fd->lower;
+    PRFilePrivate *mine = (PRFilePrivate*)fd->secret;
+
+    do
+    {
+        switch (mine->xmtstate)
+        {
+        case xmt_send_debit:
+            b = (char*)&mine->xmtreq;
+            mine->xmtreq = amount;
+            rv = lo->methods->send(
+                lo, b - mine->xmtinprogress,
+                sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->xmtinprogress += rv;
+            if (mine->xmtinprogress < sizeof(mine->xmtreq)) break;
+            mine->xmtstate = xmt_recv_credit;
+            mine->xmtinprogress = 0;
+        case xmt_recv_credit:
+             b = (char*)&mine->xmtreq;
+             rv = lo->methods->recv(
+                lo, b + mine->xmtinprogress,
+                sizeof(mine->xmtreq) - mine->xmtinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->xmtinprogress += rv;
+            if (mine->xmtinprogress < sizeof(mine->xmtreq)) break;
+            mine->xmtstate = xmt_data;
+            mine->xmtinprogress = 0;
+        case xmt_data:
+            b = (char*)buf;
+            rv = lo->methods->send(
+                lo, b + mine->xmtinprogress,
+                mine->xmtreq - mine->xmtinprogress, flags, timeout);
+            if ((-1 == rv) && (PR_WOULD_BLOCK_ERROR == PR_GetError())) break;
+            mine->xmtinprogress += rv;
+            if (mine->xmtinprogress < amount) break;
+            mine->xmtstate = xmt_send_debit;
+            mine->xmtinprogress = 0;
+            return mine->xmtreq;  /* <<-- That's the one! */
+        default:
+            break;
+        }
+    } while (-1 != rv);
+    return rv;
+}  /* MySend */
+
+static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta)
+{
+    PRIntn verbage = (PRIntn)verbosity + delta;
+    if (verbage < (PRIntn)silent) verbage = (PRIntn)silent;
+    else if (verbage > (PRIntn)noisy) verbage = (PRIntn)noisy;
+    return (Verbosity)verbage;
+}  /* ChangeVerbosity */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    PLOptStatus os;
+    PRFileDesc *client, *service;
+    PRNetAddr any_address;
+    const char *server_name = NULL;
+    const PRIOMethods *stubMethods;
+    PRThread *client_thread, *server_thread;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+    PRSocketOptionData socket_noblock, socket_nodelay;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:
+            server_name = opt->value;
+            break;
+        case 'd':  /* debug mode */
+            if (verbosity < noisy)
+                verbosity = ChangeVerbosity(verbosity, 1);
+            break;
+        case 'q':  /* debug mode */
+            if (verbosity > silent)
+                verbosity = ChangeVerbosity(verbosity, -1);
+            break;
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'C':  /* number of threads waiting */
+            major_iterations = atoi(opt->value);
+            break;
+        case 'c':  /* number of client threads */
+            minor_iterations = atoi(opt->value);
+            break;
+        case 'p':  /* default port */
+            default_port = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+    PR_STDIO_INIT();
+
+    logFile = PR_GetSpecialFD(PR_StandardError);
+    identity = PR_GetUniqueIdentity("Dummy");
+    stubMethods = PR_GetDefaultIOMethods();
+
+    /*
+    ** The protocol we're going to implement is one where in order to initiate
+    ** a send, the sender must first solicit permission. Therefore, every
+    ** send is really a send - receive - send sequence.
+    */
+    myMethods = *stubMethods;  /* first get the entire batch */
+    myMethods.accept = MyAccept;  /* then override the ones we care about */
+    myMethods.recv = MyRecv;  /* then override the ones we care about */
+    myMethods.send = MySend;  /* then override the ones we care about */
+    myMethods.close = MyClose;  /* then override the ones we care about */
+    myMethods.poll = MyPoll;  /* then override the ones we care about */
+
+    if (NULL == server_name)
+        rv = PR_InitializeNetAddr(
+            PR_IpAddrLoopback, default_port, &server_address);
+    else
+    {
+        rv = PR_StringToNetAddr(server_name, &server_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_InitializeNetAddr(
+            PR_IpAddrNull, default_port, &server_address);
+    }
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    socket_noblock.value.non_blocking = PR_TRUE;
+    socket_noblock.option = PR_SockOpt_Nonblocking;
+    socket_nodelay.value.no_delay = PR_TRUE;
+    socket_nodelay.option = PR_SockOpt_NoDelay;
+
+    /* one type w/o layering */
+
+    while (major_iterations-- > 0)
+    {
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Beginning non-layered test\n");
+
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+
+        rv = PR_SetSocketOption(client, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(client, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
+
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, service,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, client,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Ending non-layered test\n");
+
+        /* with layering */
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Beginning layered test\n");
+        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
+        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
+
+        rv = PR_SetSocketOption(client, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_noblock);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(client, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetSocketOption(service, &socket_nodelay);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        PushLayer(client);
+        PushLayer(service);
+
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);
+
+        server_thread = PR_CreateThread(
+            PR_USER_THREAD, Server, service,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != server_thread);
+
+        client_thread = PR_CreateThread(
+            PR_USER_THREAD, Client, client,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 16 * 1024);
+        PR_ASSERT(NULL != client_thread);
+
+        rv = PR_JoinThread(client_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_JoinThread(server_thread);
+        PR_ASSERT(PR_SUCCESS == rv);
+
+        rv = PR_Close(PopLayer(client)); PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Close(PopLayer(service)); PR_ASSERT(PR_SUCCESS == rv);
+        if (verbosity > silent)
+            PR_fprintf(logFile, "Ending layered test\n");
+    }
+    return 0;
+}  /* main */
+
+/* nblayer.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/nonblock.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/nonblock.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,273 @@
+/* -*- 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 "nspr.h"
+#include "prio.h"
+#include "prerror.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prnetdb.h"
+#include "plerror.h"
+#ifndef XP_MAC
+#include "obsolete/probslet.h"
+#else
+#include "probslet.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUMBER_ROUNDS 5
+
+#if defined(WIN16)
+/*
+** Make win16 unit_time interval 300 milliseconds, others get 100
+*/
+#define UNIT_TIME  200       /* unit time in milliseconds */
+#else
+#define UNIT_TIME  100       /* unit time in milliseconds */
+#endif
+#define CHUNK_SIZE 10
+#undef USE_PR_SELECT         /* If defined, we use PR_Select.
+                              * If not defined, use PR_Poll instead. */
+
+#if defined(USE_PR_SELECT)
+#include "pprio.h"
+#endif
+
+#ifdef XP_MAC
+int fprintf(FILE *stream, const char *fmt, ...)
+{
+PR_LogPrint(fmt);
+return 0;
+}
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+static void PR_CALLBACK
+clientThreadFunc(void *arg)
+{
+    PRUintn port = (PRUintn)arg;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    char buf[CHUNK_SIZE];
+    int i;
+    PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);
+    PRSocketOptionData optval;
+    PRStatus retVal;
+    PRInt32 nBytes;
+
+    /* Initialize the buffer so that Purify won't complain */
+    memset(buf, 0, sizeof(buf));
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons((PRUint16)port);
+    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip);
+
+    /* time 1 */
+    PR_Sleep(unitTime);
+    sock = PR_NewTCPSocket();
+    optval.option = PR_SockOpt_Nonblocking;
+    optval.value.non_blocking = PR_TRUE;
+    PR_SetSocketOption(sock, &optval);
+    retVal = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+    if (retVal == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) {
+#if !defined(USE_PR_SELECT)
+	PRPollDesc pd;
+	PRInt32 n;
+	fprintf(stderr, "connect: EWOULDBLOCK, good\n");
+	pd.fd = sock;
+	pd.in_flags = PR_POLL_WRITE;
+	n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(n == 1);
+        PR_ASSERT(pd.out_flags == PR_POLL_WRITE);
+#else
+        PR_fd_set writeSet;
+        PRInt32 n;
+        fprintf(stderr, "connect: EWOULDBLOCK, good\n");
+        PR_FD_ZERO(&writeSet);
+        PR_FD_SET(sock, &writeSet);
+        n = PR_Select(0, NULL, &writeSet, NULL, PR_INTERVAL_NO_TIMEOUT);
+        PR_ASSERT(n == 1);
+        PR_ASSERT(PR_FD_ISSET(sock, &writeSet));
+#endif
+    }
+    printf("client connected\n");
+    fflush(stdout);
+
+    /* time 4, 7, 11, etc. */
+    for (i = 0; i < NUMBER_ROUNDS; i++) {
+        PR_Sleep(3 * unitTime);
+    	nBytes = PR_Write(sock, buf, sizeof(buf));
+	    if (nBytes == -1) {
+	    if (PR_GetError() == PR_WOULD_BLOCK_ERROR) {
+		fprintf(stderr, "write: EWOULDBLOCK\n");
+		exit(1);
+            } else {
+		fprintf(stderr, "write: failed\n");
+            }
+	}
+	printf("client sent %d bytes\n", nBytes);
+	fflush(stdout);
+    }
+
+    PR_Close(sock);
+}
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+    PRFileDesc *listenSock, *sock;
+    PRUint16 listenPort;
+    PRNetAddr addr;
+    char buf[CHUNK_SIZE];
+    PRThread *clientThread;
+    PRInt32 retVal;
+    PRSocketOptionData optval;
+    PRIntn i;
+    PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME);
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("nonblock.log");
+#endif
+
+    /* Create a listening socket */
+    if ((listenSock = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	exit(1);
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	exit(1);
+    }
+    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	exit(1);
+    }
+    listenPort = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	exit(1);
+    }
+
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on port %hu\n\n",
+	    listenPort);
+    printf("%s", buf);
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+    printf("client thread created.\n");
+
+    optval.option = PR_SockOpt_Nonblocking;
+    optval.value.non_blocking = PR_TRUE;
+    PR_SetSocketOption(listenSock, &optval);
+    /* time 0 */
+    sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (sock != NULL || PR_GetError() != PR_WOULD_BLOCK_ERROR) {
+        PL_PrintError("First Accept\n");
+        fprintf(stderr, "First PR_Accept() xxx\n" );
+		    exit(1);
+    }
+    printf("accept: EWOULDBLOCK, good\n");
+    fflush(stdout);
+    /* time 2 */
+    PR_Sleep(2 * unitTime);
+    sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (sock == NULL) {
+        PL_PrintError("Second Accept\n");
+        fprintf(stderr, "Second PR_Accept() failed: (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+		    exit(1);
+    }
+    printf("accept: succeeded, good\n");
+    fflush(stdout);
+    PR_Close(listenSock);
+
+    PR_SetSocketOption(sock, &optval);
+
+    /* time 3, 5, 6, 8, etc. */
+    for (i = 0; i < NUMBER_ROUNDS; i++) {
+	PR_Sleep(unitTime);
+	retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
+	if (retVal != -1 || PR_GetError() != PR_WOULD_BLOCK_ERROR) {
+        PL_PrintError("First Receive:\n");
+	    fprintf(stderr, "First PR_Recv: retVal: %ld, Error: %ld\n",
+            retVal, PR_GetError());
+	    exit(1);
+        }
+	printf("read: EWOULDBLOCK, good\n");
+	fflush(stdout);
+	PR_Sleep(2 * unitTime);
+	retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
+	if (retVal != CHUNK_SIZE) {
+        PL_PrintError("Second Receive:\n");
+	    fprintf(stderr, "Second PR_Recv: retVal: %ld, Error: %ld\n", 
+            retVal, PR_GetError());
+	    exit(1);
+        }
+	printf("read: %d bytes, good\n", retVal);
+	fflush(stdout);
+    }
+    PR_Close(sock);
+
+    printf("All tests finished\n");
+    printf("PASS\n");
+    return 0;
+}
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/ntioto.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/ntioto.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,318 @@
+/* -*- 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: ntioto.c
+** Description: 
+** This test, ntioto.c, was designed to reproduce a bug reported by NES
+** on WindowsNT (fibers implementation). NSPR was asserting in ntio.c
+** after PR_AcceptRead() had timed out. I/O performed subsequent to the
+** call to PR_AcceptRead() could complete on a CPU other than the one
+** on which it was started. The assert in ntio.c detected this, then
+** asserted.
+**
+** Design:
+** This test will fail with an assert in ntio.c if the problem it was
+** designed to catch occurs. It returns 0 otherwise.
+** 
+** The main() thread initializes and tears things down. A file is
+** opened for writing; this file will be written to by AcceptThread()
+** and JitterThread().  Main() creates a socket for reading, listens
+** and binds the socket.
+** 
+** ConnectThread() connects to the socket created by main, then polls
+** the "state" variable. When state is AllDone, ConnectThread() exits.
+**
+** AcceptThread() calls PR_AcceptRead() on the socket. He fully expects
+** it to time out. After the timeout, AccpetThread() interacts with
+** JitterThread() via a common condition variable and the state
+** variable. The two threads ping-pong back and forth, each thread
+** writes the the file opened by main. This should provoke the
+** condition reported by NES (if we didn't fix it).
+**
+** The failure is not solid. It may fail within a few ping-pongs between
+** AcceptThread() and JitterThread() or may take a while. The default
+** iteration count, jitter, is set by DEFAULT_JITTER. This may be
+** modified at the command line with the -j option.
+** 
+*/
+
+#include <plgetopt.h> 
+#include <nspr.h> 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Test harness infrastructure
+*/
+PRLogModuleInfo *lm;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRIntn  debug = 0;
+PRIntn  verbose = 0;
+PRUint32  failed_already = 0;
+/* end Test harness infrastructure */
+
+/* JITTER_DEFAULT: the number of times AcceptThread() and JitterThread() ping-pong */
+#define JITTER_DEFAULT  100000
+#define BASE_PORT 9867
+
+PRIntervalTime timeout;
+PRNetAddr   listenAddr;
+PRFileDesc  *listenSock;
+PRLock      *ml;
+PRCondVar   *cv;
+volatile enum  {
+    RunJitter,
+    RunAcceptRead,
+    AllDone
+} state = RunAcceptRead;
+PRFileDesc  *file1;
+PRIntn  iCounter = 0;
+PRIntn  jitter = JITTER_DEFAULT;
+PRBool  resume = PR_FALSE;
+
+/*
+** Emit help text for this test
+*/
+static void Help( void )
+{
+    printf("Template: Help(): display your help message(s) here");
+    exit(1);
+} /* end Help() */
+
+
+/*
+** static computation of PR_AcceptRead() buffer size.
+*/
+#define ACCEPT_READ_DATASIZE 10
+#define ACCEPT_READ_BUFSIZE (PR_ACCEPT_READ_BUF_OVERHEAD + ACCEPT_READ_DATASIZE)
+
+static void AcceptThread(void *arg)
+{
+    PRIntn bytesRead;
+    char dataBuf[ACCEPT_READ_BUFSIZE];
+    PRFileDesc  *arSock;
+    PRNetAddr   *arAddr;
+
+    bytesRead = PR_AcceptRead( listenSock, 
+        &arSock,
+        &arAddr,
+        dataBuf,
+        ACCEPT_READ_DATASIZE,
+        PR_SecondsToInterval(1));
+
+    if ( bytesRead == -1 && PR_GetError() == PR_IO_TIMEOUT_ERROR ) {
+        if ( debug ) printf("AcceptRead timed out\n");
+    } else {
+        if ( debug ) printf("Oops! read: %d, error: %d\n", bytesRead, PR_GetError());
+    }
+
+    while( state != AllDone )  {
+        PR_Lock( ml );
+        while( state != RunAcceptRead )
+            PR_WaitCondVar( cv, PR_INTERVAL_NO_TIMEOUT );
+        if ( ++iCounter >= jitter )
+            state = AllDone;
+        else
+            state = RunJitter;
+        if ( verbose ) printf(".");
+        PR_NotifyCondVar( cv );
+        PR_Unlock( ml );
+        PR_Write( file1, ".", 1 );
+    }
+
+    return;
+} /* end AcceptThread() */
+
+static void JitterThread(void *arg)
+{
+    while( state != AllDone )  {
+        PR_Lock( ml );
+        while( state != RunJitter && state != AllDone )
+            PR_WaitCondVar( cv, PR_INTERVAL_NO_TIMEOUT );
+        if ( state != AllDone)
+            state = RunAcceptRead;
+        if ( verbose ) printf("+");
+        PR_NotifyCondVar( cv );
+        PR_Unlock( ml );
+        PR_Write( file1, "+", 1 );
+    }
+    return;
+} /* end Goofy() */
+
+static void ConnectThread( void *arg )
+{
+    PRStatus    rv;
+    PRFileDesc  *clientSock;
+    PRNetAddr   serverAddress;
+    clientSock = PR_NewTCPSocket();
+
+    PR_ASSERT(clientSock);
+
+    if ( resume ) {
+        if ( debug ) printf("pausing 3 seconds before connect\n");
+        PR_Sleep( PR_SecondsToInterval(3));
+    }
+
+    memset(&serverAddress, 0, sizeof(serverAddress));
+    rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &serverAddress);
+    PR_ASSERT( PR_SUCCESS == rv );
+    rv = PR_Connect( clientSock, 
+        &serverAddress, 
+        PR_SecondsToInterval(1));
+    PR_ASSERT( PR_SUCCESS == rv );
+
+    /* that's all we do. ... Wait for the acceptread() to timeout */
+    while( state != AllDone )
+        PR_Sleep( PR_SecondsToInterval(1));
+    return;
+} /* end ConnectThread() */
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRThread *tJitter;
+    PRThread *tAccept;
+    PRThread *tConnect;
+    PRStatus rv;
+    /* This test if valid for WinNT only! */
+
+#if !defined(WINNT)
+    return 0;
+#endif
+
+    {
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "hdrvj:");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+			    msgLevel = PR_LOG_ERROR;
+                break;
+            case 'v':  /* verbose mode */
+                verbose = 1;
+			    msgLevel = PR_LOG_DEBUG;
+                break;
+            case 'j':
+                jitter = atoi(opt->value);
+                if ( jitter == 0)
+                    jitter = JITTER_DEFAULT;
+                break;
+            case 'r':
+                resume = PR_TRUE;
+                break;
+            case 'h':  /* help message */
+			    Help();
+                break;
+             default:
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    }
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+
+    /* set concurrency */
+    PR_SetConcurrency( 4 );
+
+    /* setup thread synchronization mechanics */
+    ml = PR_NewLock();
+    cv = PR_NewCondVar( ml );
+
+    /* setup a tcp socket */
+    memset(&listenAddr, 0, sizeof(listenAddr));
+    rv = PR_InitializeNetAddr(PR_IpAddrAny, BASE_PORT, &listenAddr);
+    PR_ASSERT( PR_SUCCESS == rv );
+
+    listenSock = PR_NewTCPSocket();
+    PR_ASSERT( listenSock );
+
+    rv = PR_Bind( listenSock, &listenAddr);
+    PR_ASSERT( PR_SUCCESS == rv );
+
+    rv = PR_Listen( listenSock, 5 );
+    PR_ASSERT( PR_SUCCESS == rv );
+
+    /* open a file for writing, provoke bug */
+    file1 = PR_Open("xxxTestFile", PR_CREATE_FILE | PR_RDWR, 666);
+
+    /* create Connect thread */
+    tConnect = PR_CreateThread(
+        PR_USER_THREAD, ConnectThread, NULL,
+        PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+        PR_JOINABLE_THREAD, 0 );
+    PR_ASSERT( tConnect );
+
+    /* create jitter off thread */
+    tJitter = PR_CreateThread(
+        PR_USER_THREAD, JitterThread, NULL,
+        PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+        PR_JOINABLE_THREAD, 0 );
+    PR_ASSERT( tJitter );
+
+    /* create acceptread thread */
+    tAccept = PR_CreateThread(
+        PR_USER_THREAD, AcceptThread, NULL,
+        PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+        PR_JOINABLE_THREAD, 0 );
+    PR_ASSERT( tAccept );
+
+    /* wait for all threads to quit, then terminate gracefully */
+    PR_JoinThread( tConnect );
+    PR_JoinThread( tAccept );
+    PR_JoinThread( tJitter );
+    PR_Close( listenSock );
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    PR_Close( file1 );
+    PR_Delete( "xxxTestFile");
+
+    /* test return and exit */
+    if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS");
+    return( (failed_already == PR_TRUE )? 1 : 0 );
+}  /* main() */
+/* end ntioto.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/ntoh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/ntoh.c	Mon Dec 18 10:53:47 2006
@@ -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) 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 ***** */
+
+/*
+ * A test program for PR_htons, PR_ntohs, PR_htonl, PR_ntohl,
+ * PR_htonll, and PR_ntohll.
+ */
+
+#include "prnetdb.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Byte sequence in network byte order */
+static unsigned char bytes_n[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+/* Integers in host byte order */
+static PRUint16 s_h = 0x0102;
+static PRUint32 l_h = 0x01020304;
+static PRUint64 ll_h = LL_INIT(0x01020304, 0x05060708);
+
+int main()
+{
+    union {
+        PRUint16 s;
+        PRUint32 l;
+        PRUint64 ll;
+        unsigned char bytes[8];
+    } un;
+
+    un.s = s_h;
+    printf("%u %u\n",
+        un.bytes[0], un.bytes[1]);
+    un.s = PR_htons(un.s);
+    printf("%u %u\n",
+        un.bytes[0], un.bytes[1]);
+    if (memcmp(un.bytes, bytes_n, 2)) {
+        fprintf(stderr, "PR_htons failed\n");
+        exit(1);
+    }
+    un.s = PR_ntohs(un.s);
+    printf("%u %u\n",
+        un.bytes[0], un.bytes[1]);
+    if (un.s != s_h) {
+        fprintf(stderr, "PR_ntohs failed\n");
+        exit(1);
+    }
+
+    un.l = l_h;
+    printf("%u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
+    un.l = PR_htonl(un.l);
+    printf("%u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
+    if (memcmp(un.bytes, bytes_n, 4)) {
+        fprintf(stderr, "PR_htonl failed\n");
+        exit(1);
+    }
+    un.l = PR_ntohl(un.l);
+    printf("%u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3]);
+    if (un.l != l_h) {
+        fprintf(stderr, "PR_ntohl failed\n");
+        exit(1);
+    }
+
+    un.ll = ll_h;
+    printf("%u %u %u %u %u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
+        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
+    un.ll = PR_htonll(un.ll);
+    printf("%u %u %u %u %u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
+        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
+    if (memcmp(un.bytes, bytes_n, 8)) {
+        fprintf(stderr, "PR_htonll failed\n");
+        exit(1);
+    }
+    un.ll = PR_ntohll(un.ll);
+    printf("%u %u %u %u %u %u %u %u\n",
+        un.bytes[0], un.bytes[1], un.bytes[2], un.bytes[3],
+        un.bytes[4], un.bytes[5], un.bytes[6], un.bytes[7]);
+    if (LL_NE(un.ll, ll_h)) {
+        fprintf(stderr, "PR_ntohll failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/obsints.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/obsints.c	Mon Dec 18 10:53:47 2006
@@ -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) 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 ***** */
+
+/*
+ * Test: obsints.c 
+ *
+ * Description: make sure that protypes.h defines the obsolete integer
+ * types intn, uintn, uint, int8, uint8, int16, uint16, int32, uint32,
+ * int64, and uint64.
+ */
+
+#include <stdio.h>
+
+#ifdef NO_NSPR_10_SUPPORT
+
+/* nothing to do */
+int main()
+{
+    printf("PASS\n");
+    return 0;
+}
+
+#else /* NO_NSPR_10_SUPPORT */
+
+#include "prtypes.h"  /* which includes protypes.h */
+
+int main()
+{
+    /*
+     * Compilation fails if any of these integer types are not
+     * defined by protypes.h.
+     */
+    intn in;
+    uintn uin;
+    uint ui;
+    int8 i8;
+    uint8 ui8;
+    int16 i16;
+    uint16 ui16;
+    int32 i32;
+    uint32 ui32;
+    int64 i64;
+    uint64 ui64;
+
+    printf("PASS\n");
+    return 0;
+}
+
+#endif /* NO_NSPR_10_SUPPORT */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/op_2long.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/op_2long.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/***********************************************************************
+**
+** Name: op_2long.c
+**
+** Description: Test Program to verify the PR_NAME_TOO_LONG_ERROR
+**
+** Modification History:
+** 03-June-97 AGarcia- Initial version
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "prinit.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prerror.h"
+#include <stdio.h>
+#include "plerror.h"
+#include "plgetopt.h"
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#else
+#endif
+
+static PRFileDesc *t1;
+PRIntn error_code;
+
+/*
+ * should exceed any system's maximum file name length
+ * Note: was set at 4096. This is legal on some unix (Linux 2.1+) platforms.
+ * 
+ */
+#define TOO_LONG 5000
+
+int main(int argc, char **argv)
+{
+	char nameTooLong[TOO_LONG];
+	int i;
+
+	/* Generate a really long pathname */
+	for (i = 0; i < TOO_LONG - 1; i++) {
+		if (i % 10 == 0) {
+			nameTooLong[i] = '/';
+		} else {
+			nameTooLong[i] = 'a';
+		}
+	}
+	nameTooLong[TOO_LONG - 1] = 0;
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("pr_open_re.log");
+#endif
+	
+    PR_STDIO_INIT();
+	t1 = PR_Open(nameTooLong, PR_RDWR, 0666);
+	if (t1 == NULL) {
+		if (PR_GetError() == PR_NAME_TOO_LONG_ERROR) {
+            PL_PrintError("error code is");
+			printf ("PASS\n");
+			return 0;
+		}
+		else {
+            PL_PrintError("error code is");
+			printf ("FAIL\n");
+			return 1;
+		}
+	}
+	
+		else {
+			printf ("Test passed\n");
+			return 0;
+		}
+	
+
+
+}			

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/op_excl.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/op_excl.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,156 @@
+/* -*- 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: op_excl.c
+**
+** Description: Test Program to verify function of PR_EXCL open flag
+**
+** Modification History:
+** 27-Oct-1999 lth. Initial version
+***********************************************************************/
+
+#include <plgetopt.h> 
+#include <nspr.h> 
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+** Test harness infrastructure
+*/
+PRLogModuleInfo *lm;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRIntn  debug = 0;
+PRUint32  failed_already = 0;
+/* end Test harness infrastructure */
+/*
+** Emit help text for this test
+*/
+static void Help( void )
+{
+    printf("op_excl: Help");
+    printf("op_excl [-d]");
+    printf("-d enables debug messages");
+    exit(1);
+} /* end Help() */
+
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRFileDesc  *fd;
+    PRStatus    rv;
+    PRInt32     written;
+    char        outBuf[] = "op_excl.c test file";
+#define OUT_SIZE sizeof(outBuf)
+#define NEW_FILENAME "xxxExclNewFile"
+
+    {
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "hd");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+			    msgLevel = PR_LOG_ERROR;
+                break;
+            case 'h':  /* help message */
+			    Help();
+                break;
+             default:
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    }
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+
+    /*
+    ** First, open a file, PR_EXCL, we believe not to exist
+    */
+    fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 );
+    if ( NULL == fd )  {
+        if (debug) fprintf( stderr, "Open exclusive. Expected success, got failure\n");
+        failed_already = 1;
+        goto Finished;
+    }
+
+    written = PR_Write( fd, outBuf, OUT_SIZE );
+    if ( OUT_SIZE != written )  {
+        if (debug) fprintf( stderr, "Write after open exclusive failed\n");
+        failed_already = 1;
+        goto Finished;
+    }
+
+    rv = PR_Close(fd);
+    if ( PR_FAILURE == rv )  {
+        if (debug) fprintf( stderr, "Close after open exclusive failed\n");
+        failed_already = 1;
+        goto Finished;
+    }
+
+    /*
+    ** Second, open the same file, PR_EXCL, expect it to fail
+    */
+    fd = PR_Open( NEW_FILENAME, PR_CREATE_FILE | PR_EXCL | PR_WRONLY, 0666 );
+    if ( NULL != fd )  {
+        if (debug) fprintf( stderr, "Open exclusive. Expected failure, got success\n");
+        failed_already = 1;
+        PR_Close(fd);
+    }
+
+    rv = PR_Delete( NEW_FILENAME );
+    if ( PR_FAILURE == rv ) {
+        if (debug) fprintf( stderr, "PR_Delete() failed\n");
+        failed_already = 1;
+    }
+
+Finished:
+    if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS");
+    return( (failed_already == PR_TRUE )? 1 : 0 );
+}  /* main() */
+/* end op_excl.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/op_filnf.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/op_filnf.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,96 @@
+/* -*- 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: op_filnf.c
+**
+** Description: Test Program to verify the PR_FILE_NOT_FOUND_ERROR
+**				This test program also uses the TRUNCATE option
+**
+** Modification History:
+** 03-June-97 AGarcia- Initial version
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "prinit.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prerror.h"
+#include <stdio.h>
+#include "plgetopt.h"
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#else
+#endif
+
+static PRFileDesc *t1;
+PRIntn error_code;
+
+int main(int argc, char **argv)
+{
+
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("pr_open_re.log");
+#endif
+	
+
+    PR_STDIO_INIT();
+	t1 = PR_Open("/usr/tmp/ttools/err03.tmp", PR_TRUNCATE | PR_RDWR, 0666);
+	if (t1 == NULL) {
+		if (PR_GetError() == PR_FILE_NOT_FOUND_ERROR) {
+				printf ("error code is %d \n", PR_GetError());
+				printf ("PASS\n");
+				return 0;
+		}
+		else {
+				printf ("error code is %d \n", PR_GetError());
+				printf ("FAIL\n");
+			return 1;
+		}
+	}
+	PR_Close(t1);
+	printf ("opened a file that should not exist\n");
+	printf ("FAIL\n");
+	return 1;
+}			

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/op_filok.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/op_filok.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,110 @@
+/* -*- 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: op_filok.c
+**
+** Description: Test Program to verify the PR_Open finding an existing file.
+**
+** Modification History:
+** 03-June-97 AGarcia- Initial version
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "prinit.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prerror.h"
+#include <stdio.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#else
+#endif
+
+/*
+ * The name of a file that is guaranteed to exist
+ * on every machine of a particular OS.
+ */
+#ifdef VMS
+#define EXISTING_FILENAME "SYS$LOGIN:LOGIN.COM"
+#elif XP_UNIX
+#define EXISTING_FILENAME "/bin/sh"
+#elif defined(WIN32)
+#define EXISTING_FILENAME "c:/autoexec.bat"
+#elif defined(OS2)
+#define EXISTING_FILENAME "c:/config.sys"
+#elif defined(BEOS)
+#define EXISTING_FILENAME "/boot/beos/bin/sh"
+#else
+#error "Unknown OS"
+#endif
+
+static PRFileDesc *t1;
+
+int main(int argc, char **argv)
+{
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("pr_open_re.log");
+#endif
+	
+    PR_STDIO_INIT();
+
+	t1 = PR_Open(EXISTING_FILENAME, PR_RDONLY, 0666);
+
+	if (t1 == NULL) {
+		printf ("error code is %d \n", PR_GetError());
+		printf ("File %s should be found\n",
+				EXISTING_FILENAME);
+		return 1;
+	} else {
+		if (PR_Close(t1) == PR_SUCCESS) {
+			printf ("Test passed \n");
+			return 0;
+		} else {
+			printf ("cannot close file\n");
+			printf ("error code is %d\n", PR_GetError());
+			return 1;
+		}
+	}
+}			

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/op_noacc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/op_noacc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,94 @@
+/* -*- 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: op_noacc.c
+**
+** Description: Test Program to verify the PR_NO_ACCESS_RIGHTS_ERROR in PR_Open
+**
+** Modification History:
+** 03-June-97 AGarcia- Initial version
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "prinit.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prerror.h"
+#include <stdio.h>
+#include "plgetopt.h"
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#else
+#endif
+
+static PRFileDesc *err01;
+PRIntn error_code;
+
+int main(int argc, char **argv)
+{
+
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("pr_open_re.log");
+#endif
+	
+#ifdef XP_PC
+    printf("op_noacc: Test not valid on MS-Windows.\n\tNo concept of 'mode' on Open() call\n");
+    return(0);
+#endif
+
+	
+    PR_STDIO_INIT();
+	err01 = PR_Open("err01.tmp", PR_CREATE_FILE | PR_RDWR, 0);
+	if (err01 == NULL) 
+		if (PR_GetError() == PR_NO_ACCESS_RIGHTS_ERROR) {
+				printf ("error code is %d\n",PR_GetError());
+				printf ("PASS\n");
+			return 0;
+		}
+		else {
+			printf ("FAIL\n");
+			return 1;
+		}
+}			

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/op_nofil.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/op_nofil.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,99 @@
+/* -*- 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: op_nofil.c
+**
+** Description: Test Program to verify the PR_FILE_NOT_FOUND_ERROR
+**
+** Modification History:
+** 03-June-97 AGarcia- Initial version
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "prinit.h"
+#include "prmem.h"
+#include "prio.h"
+#include "prerror.h"
+#include <stdio.h>
+#include "plgetopt.h"
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#else
+#endif
+
+/*
+ * A file name that cannot exist
+ */
+#define NO_SUCH_FILE "/no/such/file.tmp"
+
+static PRFileDesc *t1;
+
+int main(int argc, char **argv)
+{
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("pr_open_re.log");
+#endif
+	
+    PR_STDIO_INIT();
+	t1 = PR_Open(NO_SUCH_FILE,  PR_RDONLY, 0666);
+	if (t1 == NULL) {
+		if (PR_GetError() == PR_FILE_NOT_FOUND_ERROR) {
+			printf ("error code is PR_FILE_NOT_FOUND_ERROR, as expected\n");
+			printf ("PASS\n");
+			return 0;
+		} else {
+			printf ("error code is %d \n", PR_GetError());
+			printf ("FAIL\n");
+			return 1;
+		}
+	}
+	printf ("File %s exists on this machine!?\n", NO_SUCH_FILE);
+	if (PR_Close(t1) == PR_FAILURE) {
+		printf ("cannot close file\n");
+		printf ("error code is %d \n", PR_GetError());
+	}
+	printf ("FAIL\n");
+	return 1;
+}			

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/openfile.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/openfile.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,145 @@
+/* -*- 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) 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 ***** */
+
+/*
+ * This test calls PR_OpenFile to create a bunch of files
+ * with various file modes.
+ */
+
+#include "prio.h"
+#include "prerror.h"
+#include "prinit.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define TEMPLATE_FILE_NAME "template.txt"
+
+int main()
+{
+    FILE *template;
+    char buf[32];
+    PRInt32 nbytes;
+    PRFileDesc *fd;
+
+    
+    /* Write in text mode.  Let stdio deal with line endings. */
+    template = fopen(TEMPLATE_FILE_NAME, "w");
+    fputs("line 1\nline 2\n", template);
+    fclose(template);
+
+    /* Read in binary mode */
+    fd = PR_OpenFile(TEMPLATE_FILE_NAME, PR_RDONLY, 0666);
+    nbytes = PR_Read(fd, buf, sizeof(buf));
+    PR_Close(fd);
+    PR_Delete(TEMPLATE_FILE_NAME);
+
+    fd = PR_OpenFile("tfil0700.txt", PR_RDWR | PR_CREATE_FILE, 0700);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0500.txt", PR_RDWR | PR_CREATE_FILE, 0500);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0400.txt", PR_RDWR | PR_CREATE_FILE, 0400);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0644.txt", PR_RDWR | PR_CREATE_FILE, 0644);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0664.txt", PR_RDWR | PR_CREATE_FILE, 0664);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0660.txt", PR_RDWR | PR_CREATE_FILE, 0660);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0666.txt", PR_RDWR | PR_CREATE_FILE, 0666);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    fd = PR_OpenFile("tfil0640.txt", PR_RDWR | PR_CREATE_FILE, 0640);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_OpenFile failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    PR_Write(fd, buf, nbytes);
+    PR_Close(fd);
+
+    PR_Cleanup();
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/parent.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/parent.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,157 @@
+/* -*- 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:        parent.c
+** description: test the process machinery
+*/
+
+#include "prmem.h"
+#include "prprf.h"
+#include "prinit.h"
+#include "prproces.h"
+#include "prinrval.h"
+
+typedef struct Child
+{
+    const char *name;
+    char **argv;
+    PRProcess *process;
+    PRProcessAttr *attr;
+} Child;
+
+/* for the default test 'cvar -c 2000' */
+static char *default_argv[] = {"cvar", "-c", "2000", NULL};
+
+static void PrintUsage(void)
+{
+    PR_fprintf(PR_GetSpecialFD(PR_StandardError),
+        "Usage: parent [-d] child [options]\n");
+}
+
+PRIntn main (PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    PRInt32 test_status = 1;
+    PRIntervalTime t_start, t_elapsed;
+    PRFileDesc *debug = NULL;
+    Child *child = PR_NEWZAP(Child);
+
+    if (1 == argc)
+    {
+        /* no command-line arguments: run the default test */
+        child->argv = default_argv;
+    }
+    else
+    {
+        argv += 1;  /* don't care about our program name */
+        while (*argv != NULL && argv[0][0] == '-')
+        {
+            if (argv[0][1] == 'd')
+                debug = PR_GetSpecialFD(PR_StandardError);
+            else
+            {
+                PrintUsage();
+                return 2;  /* not sufficient */
+            }
+            argv += 1;
+        }
+        child->argv = argv;
+    }
+
+    if (NULL == *child->argv)
+    {
+        PrintUsage();
+        return 2;
+    }
+
+    child->name = *child->argv;
+    if (NULL != debug) PR_fprintf(debug, "Forking %s\n", child->name);
+
+    child->attr = PR_NewProcessAttr();
+    PR_ProcessAttrSetStdioRedirect(
+        child->attr, PR_StandardOutput,
+        PR_GetSpecialFD(PR_StandardOutput));
+    PR_ProcessAttrSetStdioRedirect(
+        child->attr, PR_StandardError,
+        PR_GetSpecialFD(PR_StandardError));
+
+    t_start = PR_IntervalNow();
+    child->process = PR_CreateProcess(
+        child->name, child->argv, NULL, child->attr);
+    t_elapsed = (PRIntervalTime) (PR_IntervalNow() - t_start);
+
+    PR_DestroyProcessAttr(child->attr);
+
+    test_status = (NULL == child->process) ? 1 : 0;
+    if (NULL != debug)
+    {
+        PR_fprintf(
+            debug, "Child was %sforked\n",
+            (0 == test_status) ? "" : "NOT ");
+        if (0 == test_status)
+            PR_fprintf(
+                debug, "PR_CreateProcess took %lu microseconds\n",
+                PR_IntervalToMicroseconds(t_elapsed));
+    }
+
+    if (0 == test_status)
+    {
+        if (NULL != debug) PR_fprintf(debug, "Waiting for child to exit\n");
+        rv = PR_WaitProcess(child->process, &test_status);
+        if (PR_SUCCESS == rv)
+        {
+            if (NULL != debug)
+                PR_fprintf(
+                    debug, "Child exited %s\n",
+                    (0 == test_status) ? "successfully" : "with error");
+        }
+        else
+        {
+            test_status = 1;
+            if (NULL != debug)
+                PR_fprintf(debug, "PR_WaitProcess failed\n");
+        }
+    }
+    PR_DELETE(child);
+    PR_Cleanup();
+    return test_status;
+    
+}  /* main */
+
+/* parent.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/peek.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/peek.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,392 @@
+/* -*- 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 ***** */
+
+/*
+ * A test case for the PR_MSG_PEEK flag of PR_Recv().
+ *
+ * Test both blocking and non-blocking sockets.
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define BUFFER_SIZE 1024
+
+static int iterations = 10;
+
+/*
+ * In iteration i, recv_amount[i] is the number of bytes we
+ * wish to receive, and send_amount[i] is the number of bytes
+ * we actually send.  Therefore, the number of elements in the
+ * recv_amount or send_amount array should equal to 'iterations'.
+ * For this test to pass we need to ensure that
+ *     recv_amount[i] <= BUFFER_SIZE,
+ *     send_amount[i] <= BUFFER_SIZE,
+ *     send_amount[i] <= recv_amount[i].
+ */
+static PRInt32 recv_amount[10] = {
+    16, 128, 256, 1024, 512, 512, 128, 256, 32, 32};
+static PRInt32 send_amount[10] = {
+    16,  64, 128, 1024, 512, 256, 128,  64, 16, 32};
+
+/* Blocking I/O */
+static void ServerB(void *arg)
+{
+    PRFileDesc *listenSock = (PRFileDesc *) arg;
+    PRFileDesc *sock;
+    char buf[BUFFER_SIZE];
+    PRInt32 nbytes;
+    int i;
+    int j;
+
+    sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == sock) {
+        fprintf(stderr, "PR_Accept failed\n");
+        exit(1);
+    }
+
+    for (i = 0; i < iterations; i++) {
+        memset(buf, 0, sizeof(buf));
+        nbytes = PR_Recv(sock, buf, recv_amount[i],
+                PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Recv failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "server: peeked expected data\n");
+
+        memset(buf, 0, sizeof(buf));
+        nbytes = PR_Recv(sock, buf, recv_amount[i],
+                PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Recv failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "server: peeked expected data\n");
+
+        memset(buf, 0, sizeof(buf));
+        nbytes = PR_Recv(sock, buf, recv_amount[i],
+                0, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Recv failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "server: received expected data\n");
+
+        PR_Sleep(PR_SecondsToInterval(1));
+        memset(buf, 2*i+1, send_amount[i]);
+        nbytes = PR_Send(sock, buf, send_amount[i],
+                0, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Send failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+    }
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+/* Non-blocking I/O */
+static void ClientNB(void *arg)
+{
+    PRFileDesc *sock;
+    PRSocketOptionData opt;
+    PRUint16 port = (PRUint16) arg;
+    PRNetAddr addr;
+    char buf[BUFFER_SIZE];
+    PRPollDesc pd;
+    PRInt32 npds;
+    PRInt32 nbytes;
+    int i;
+    int j;
+
+    sock = PR_OpenTCPSocket(PR_AF_INET6);
+    if (NULL == sock) {
+        fprintf(stderr, "PR_OpenTCPSocket failed\n");
+        exit(1);
+    }
+    opt.option = PR_SockOpt_Nonblocking;
+    opt.value.non_blocking = PR_TRUE;
+    if (PR_SetSocketOption(sock, &opt) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetSocketOption failed\n");
+        exit(1);
+    }
+    memset(&addr, 0, sizeof(addr));
+    if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, port, &addr)
+            == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+        if (PR_GetError() != PR_IN_PROGRESS_ERROR) {
+            fprintf(stderr, "PR_Connect failed\n");
+            exit(1);
+        }
+        pd.fd = sock;
+        pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
+        npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == npds) {
+            fprintf(stderr, "PR_Poll failed\n");
+            exit(1);
+        }
+        if (1 != npds) {
+            fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
+            exit(1);
+        }
+        if (PR_GetConnectStatus(&pd) == PR_FAILURE) {
+            fprintf(stderr, "PR_GetConnectStatus failed\n");
+            exit(1);
+        }
+    }
+
+    for (i = 0; i < iterations; i++) {
+        PR_Sleep(PR_SecondsToInterval(1));
+        memset(buf, 2*i, send_amount[i]);
+        while ((nbytes = PR_Send(sock, buf, send_amount[i],
+                0, PR_INTERVAL_NO_TIMEOUT)) == -1) {
+            if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
+                fprintf(stderr, "PR_Send failed\n");
+                exit(1);
+            }
+            pd.fd = sock;
+            pd.in_flags = PR_POLL_WRITE;
+            npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+            if (-1 == npds) {
+                fprintf(stderr, "PR_Poll failed\n");
+                exit(1);
+            }
+            if (1 != npds) {
+                fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
+                exit(1);
+            }
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+
+        memset(buf, 0, sizeof(buf));
+        while ((nbytes = PR_Recv(sock, buf, recv_amount[i],
+                PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT)) == -1) {
+            if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
+                fprintf(stderr, "PR_Recv failed\n");
+                exit(1);
+            }
+            pd.fd = sock;
+            pd.in_flags = PR_POLL_READ;
+            npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+            if (-1 == npds) {
+                fprintf(stderr, "PR_Poll failed\n");
+                exit(1);
+            }
+            if (1 != npds) {
+                fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds);
+                exit(1);
+            }
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i+1) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i+1, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "client: peeked expected data\n");
+
+        memset(buf, 0, sizeof(buf));
+        nbytes = PR_Recv(sock, buf, recv_amount[i],
+                PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Recv failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i+1) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i+1, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "client: peeked expected data\n");
+
+        memset(buf, 0, sizeof(buf));
+        nbytes = PR_Recv(sock, buf, recv_amount[i],
+                0, PR_INTERVAL_NO_TIMEOUT);
+        if (-1 == nbytes) {
+            fprintf(stderr, "PR_Recv failed\n");
+            exit(1);
+        }
+        if (send_amount[i] != nbytes) {
+            fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes);
+            exit(1);
+        }
+        for (j = 0; j < nbytes; j++) {
+            if (buf[j] != 2*i+1) {
+                fprintf(stderr, "byte %d should be %d but is %d\n",
+                        j, 2*i+1, buf[j]);
+                exit(1);
+            }
+        }
+        fprintf(stderr, "client: received expected data\n");
+    }
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+static void
+RunTest(PRThreadScope scope, PRFileDesc *listenSock, PRUint16 port)
+{
+    PRThread *server, *client;
+
+    server = PR_CreateThread(PR_USER_THREAD, ServerB, listenSock,
+            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
+    if (NULL == server) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    client = PR_CreateThread(
+            PR_USER_THREAD, ClientNB, (void *) port,
+            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
+    if (NULL == client) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+
+    if (PR_JoinThread(server) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(client) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock;
+    PRNetAddr addr;
+    PRUint16 port;
+
+    listenSock = PR_OpenTCPSocket(PR_AF_INET6);
+    if (NULL == listenSock) {
+        fprintf(stderr, "PR_OpenTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&addr, 0, sizeof(addr));
+    if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_SetNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetSockName failed\n");
+        exit(1);
+    }
+    port = PR_ntohs(addr.ipv6.port);
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+
+    fprintf(stderr, "Running the test with local threads\n");
+    RunTest(PR_LOCAL_THREAD, listenSock, port);
+    fprintf(stderr, "Running the test with global threads\n");
+    RunTest(PR_GLOBAL_THREAD, listenSock, port);
+
+    if (PR_Close(listenSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/perf.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/perf.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,485 @@
+/* -*- 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 "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int _debug_on = 0;
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+#ifdef XP_MAC
+#include "prlog.h"
+#include "prsem.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#else
+#include "obsolete/prsem.h"
+#endif
+
+PRLock *lock;
+PRMonitor *mon;
+PRMonitor *mon2;
+
+#define DEFAULT_COUNT    1000
+
+PRInt32 count;
+
+static void nop(int a, int b, int c)
+{
+}
+
+static void LocalProcedureCall(void)
+{
+    PRInt32 i;
+
+    for (i = 0; i < count; i++) {
+    nop(i, i, 5);
+    }
+}
+
+static void DLLProcedureCall(void)
+{
+    PRInt32 i;
+	PRThreadState state;
+	PRThread *self = PR_GetCurrentThread();
+
+    for (i = 0; i < count; i++) {
+    	state = PR_GetThreadState(self);
+    }
+}
+
+static void Now(void)
+{
+    PRInt32 i;
+    PRTime time;
+
+    for (i = 0; i < count; i++) {
+        time = PR_Now();
+    }
+}
+
+static void Interval(void)
+{
+    PRInt32 i;
+    PRIntervalTime time;
+
+    for (i = 0; i < count; i++) {
+        time = PR_IntervalNow();
+    }
+}
+
+static void IdleLock(void)
+{
+    PRInt32 i;
+
+    for (i = 0; i < count; i++) {
+    PR_Lock(lock);
+    PR_Unlock(lock);
+    }
+}
+
+static void IdleMonitor(void)
+{
+    PRInt32 i;
+
+    for (i = 0; i < count; i++) {
+    PR_EnterMonitor(mon);
+    PR_ExitMonitor(mon);
+    }
+}
+
+static void IdleCMonitor(void)
+{
+    PRInt32 i;
+
+    for (i = 0; i < count; i++) {
+    PR_CEnterMonitor((void*)7);
+    PR_CExitMonitor((void*)7);
+    }
+}
+
+/************************************************************************/
+
+static void PR_CALLBACK dull(void *arg)
+{
+}
+
+static void CDThread(void)
+{
+    PRInt32 i;
+    int num_threads = count;
+
+    /*
+     * Cannot create too many threads
+     */
+    if (num_threads > 1000)
+    num_threads = 1000;
+
+    for (i = 0; i < num_threads; i++) {
+        PRThread *t = PR_CreateThread(PR_USER_THREAD,
+                      dull, 0, 
+                      PR_PRIORITY_NORMAL,
+                      PR_LOCAL_THREAD,
+                      PR_UNJOINABLE_THREAD,
+                      0);
+        if (NULL == t) {
+            fprintf(stderr, "CDThread: cannot create thread %3d\n", i);
+        } else {
+            DPRINTF(("CDThread: created thread %3d \n",i));
+        }
+        PR_Sleep(0);
+    }
+}
+
+static int alive;
+static int cxq;
+
+static void PR_CALLBACK CXReader(void *arg)
+{
+    PRInt32 i, n;
+
+    PR_EnterMonitor(mon);
+    n = count / 2;
+    for (i = 0; i < n; i++) {
+    while (cxq == 0) {
+            DPRINTF(("CXReader: thread = 0x%lx waiting\n",
+                    PR_GetCurrentThread()));
+        PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+    }
+    --cxq;
+    PR_Notify(mon);
+    }
+    PR_ExitMonitor(mon);
+
+    PR_EnterMonitor(mon2);
+    --alive;
+    PR_Notify(mon2);
+    PR_ExitMonitor(mon2);
+    DPRINTF(("CXReader: thread = 0x%lx exiting\n", PR_GetCurrentThread()));
+}
+
+static void PR_CALLBACK CXWriter(void *arg)
+{
+    PRInt32 i, n;
+
+    PR_EnterMonitor(mon);
+    n = count / 2;
+    for (i = 0; i < n; i++) {
+    while (cxq == 1) {
+            DPRINTF(("CXWriter: thread = 0x%lx waiting\n",
+                    PR_GetCurrentThread()));
+        PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+    }
+    ++cxq;
+    PR_Notify(mon);
+    }
+    PR_ExitMonitor(mon);
+
+    PR_EnterMonitor(mon2);
+    --alive;
+    PR_Notify(mon2);
+    PR_ExitMonitor(mon2);
+    DPRINTF(("CXWriter: thread = 0x%lx exiting\n", PR_GetCurrentThread()));
+}
+
+static void ContextSwitch(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *t1, *t2;
+
+    PR_EnterMonitor(mon2);
+    alive = 2;
+    cxq = 0;
+
+    t1 = PR_CreateThread(PR_USER_THREAD,
+                      CXReader, 0, 
+                      PR_PRIORITY_NORMAL,
+                      scope1,
+                      PR_UNJOINABLE_THREAD,
+                      0);
+    if (NULL == t1) {
+        fprintf(stderr, "ContextSwitch: cannot create thread\n");
+    } else {
+        DPRINTF(("ContextSwitch: created %s thread = 0x%lx\n",
+                (scope1 == PR_GLOBAL_THREAD ?
+                "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),
+                            t1));
+    }
+    t2 = PR_CreateThread(PR_USER_THREAD,
+                      CXWriter, 0, 
+                      PR_PRIORITY_NORMAL,
+                      scope2,
+                      PR_UNJOINABLE_THREAD,
+                      0);
+    if (NULL == t2) {
+        fprintf(stderr, "ContextSwitch: cannot create thread\n");
+    } else {
+        DPRINTF(("ContextSwitch: created %s thread = 0x%lx\n",
+                (scope2 == PR_GLOBAL_THREAD ?
+                "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),
+                            t2));
+    }
+
+    /* Wait for both of the threads to exit */
+    while (alive) {
+    PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_ExitMonitor(mon2);
+}
+
+static void ContextSwitchUU(void)
+{
+    ContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void ContextSwitchUK(void)
+{
+    ContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+static void ContextSwitchKU(void)
+{
+    ContextSwitch(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void ContextSwitchKK(void)
+{
+    ContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+/************************************************************************/
+
+static void PR_CALLBACK SemaThread(void *argSema)
+{
+    PRSemaphore **sem = (PRSemaphore **)argSema;
+    PRInt32 i, n;
+
+    n = count / 2;
+    for (i = 0; i < n; i++) {
+        DPRINTF(("SemaThread: thread = 0x%lx waiting on sem = 0x%lx\n",
+                PR_GetCurrentThread(), sem[0]));
+        PR_WaitSem(sem[0]);
+        DPRINTF(("SemaThread: thread = 0x%lx posting on sem = 0x%lx\n",
+                PR_GetCurrentThread(), sem[1]));
+        PR_PostSem(sem[1]);
+    }
+
+    PR_EnterMonitor(mon2);
+    --alive;
+    PR_Notify(mon2);
+    PR_ExitMonitor(mon2);
+    DPRINTF(("SemaThread: thread = 0x%lx exiting\n", PR_GetCurrentThread()));
+}
+
+static  PRSemaphore *sem_set1[2];
+static  PRSemaphore *sem_set2[2];
+
+static void SemaContextSwitch(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *t1, *t2;
+    sem_set1[0] = PR_NewSem(1);
+    sem_set1[1] = PR_NewSem(0);
+    sem_set2[0] = sem_set1[1];
+    sem_set2[1] = sem_set1[0];
+
+    PR_EnterMonitor(mon2);
+    alive = 2;
+    cxq = 0;
+
+    t1 = PR_CreateThread(PR_USER_THREAD,
+                      SemaThread, 
+                      sem_set1, 
+                      PR_PRIORITY_NORMAL,
+                      scope1,
+                      PR_UNJOINABLE_THREAD,
+                      0);
+    if (NULL == t1) {
+        fprintf(stderr, "SemaContextSwitch: cannot create thread\n");
+    } else {
+        DPRINTF(("SemaContextSwitch: created %s thread = 0x%lx\n",
+                (scope1 == PR_GLOBAL_THREAD ?
+                "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),
+                            t1));
+    }
+    t2 = PR_CreateThread(PR_USER_THREAD,
+                      SemaThread, 
+                      sem_set2, 
+                      PR_PRIORITY_NORMAL,
+                      scope2,
+                      PR_UNJOINABLE_THREAD,
+                      0);
+    if (NULL == t2) {
+        fprintf(stderr, "SemaContextSwitch: cannot create thread\n");
+    } else {
+        DPRINTF(("SemaContextSwitch: created %s thread = 0x%lx\n",
+                (scope2 == PR_GLOBAL_THREAD ?
+                "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),
+                            t2));
+    }
+
+    /* Wait for both of the threads to exit */
+    while (alive) {
+        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_ExitMonitor(mon2);
+
+    PR_DestroySem(sem_set1[0]);
+    PR_DestroySem(sem_set1[1]);
+}
+
+static void SemaContextSwitchUU(void)
+{
+    SemaContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void SemaContextSwitchUK(void)
+{
+    SemaContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+static void SemaContextSwitchKU(void)
+{
+    SemaContextSwitch(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void SemaContextSwitchKK(void)
+{
+    SemaContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow() - start;
+    d = (double)PR_IntervalToMicroseconds(stop);
+
+    printf("%40s: %6.2f usec\n", msg, d / count);
+}
+
+int main(int argc, char **argv)
+{
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dc:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			_debug_on = 1;
+            break;
+        case 'c':  /* loop count */
+            count = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (0 == count) count = DEFAULT_COUNT;
+    
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+	PR_BlockClockInterrupts();
+	PR_UnblockClockInterrupts();
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+    SetupMacPrintfLog("perf.log");
+#endif
+
+    lock = PR_NewLock();
+    mon = PR_NewMonitor();
+    mon2 = PR_NewMonitor();
+
+    Measure(LocalProcedureCall, "local procedure call overhead");
+    Measure(DLLProcedureCall, "DLL procedure call overhead");
+    Measure(Now, "current calendar time");
+    Measure(Interval, "interval time");
+    Measure(IdleLock, "idle lock lock/unlock pair");
+    Measure(IdleMonitor, "idle monitor entry/exit pair");
+    Measure(IdleCMonitor, "idle cache monitor entry/exit pair");
+    Measure(CDThread, "create/destroy thread pair");
+    Measure(ContextSwitchUU, "context switch - user/user");
+    Measure(ContextSwitchUK, "context switch - user/kernel");
+    Measure(ContextSwitchKU, "context switch - kernel/user");
+    Measure(ContextSwitchKK, "context switch - kernel/kernel");
+    Measure(SemaContextSwitchUU, "sema context switch - user/user");
+    Measure(SemaContextSwitchUK, "sema context switch - user/kernel");
+    Measure(SemaContextSwitchKU, "sema context switch - kernel/user");
+    Measure(SemaContextSwitchKK, "sema context switch - kernel/kernel");
+
+    printf("--------------\n");
+    printf("Adding 7 additional CPUs\n");
+
+    PR_SetConcurrency(8);
+    printf("--------------\n");
+
+    Measure(LocalProcedureCall, "local procedure call overhead");
+    Measure(DLLProcedureCall, "DLL procedure call overhead");
+    Measure(Now, "current calendar time");
+    Measure(Interval, "interval time");
+    Measure(IdleLock, "idle lock lock/unlock pair");
+    Measure(IdleMonitor, "idle monitor entry/exit pair");
+    Measure(IdleCMonitor, "idle cache monitor entry/exit pair");
+    Measure(CDThread, "create/destroy thread pair");
+    Measure(ContextSwitchUU, "context switch - user/user");
+    Measure(ContextSwitchUK, "context switch - user/kernel");
+    Measure(ContextSwitchKU, "context switch - kernel/user");
+    Measure(ContextSwitchKK, "context switch - kernel/kernel");
+    Measure(SemaContextSwitchUU, "sema context switch - user/user");
+    Measure(SemaContextSwitchUK, "sema context switch - user/kernel");
+    Measure(SemaContextSwitchKU, "sema context switch - kernel/user");
+    Measure(SemaContextSwitchKK, "sema context switch - kernel/kernel");
+
+    PR_DestroyLock(lock);
+    PR_DestroyMonitor(mon);
+    PR_DestroyMonitor(mon2);
+
+    PR_Cleanup();
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/pipeping.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/pipeping.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,190 @@
+/* -*- 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 ***** */
+
+/*
+ * File: pipeping.c
+ *
+ * Description:
+ * This test runs in conjunction with the pipepong test.
+ * This test creates two pipes and redirects the stdin and
+ * stdout of the pipepong test to the pipes.  Then this
+ * test writes "ping" to the pipepong test and the pipepong
+ * test writes "pong" back.  To run this pair of tests,
+ * just invoke pipeping.
+ *
+ * Tested areas: process creation, pipes, file descriptor
+ * inheritance, standard I/O redirection.
+ */
+
+#include "prerror.h"
+#include "prio.h"
+#include "prproces.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_OS2
+static char *child_argv[] = { "pipepong.exe", NULL };
+#else
+static char *child_argv[] = { "pipepong", NULL };
+#endif
+
+#define NUM_ITERATIONS 10
+
+int main()
+{
+    PRFileDesc *in_pipe[2];
+    PRFileDesc *out_pipe[2];
+    PRStatus status;
+    PRProcess *process;
+    PRProcessAttr *attr;
+    char buf[1024];
+    PRInt32 nBytes;
+    PRInt32 exitCode;
+    int idx;
+
+    status = PR_CreatePipe(&in_pipe[0], &in_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+    status = PR_CreatePipe(&out_pipe[0], &out_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+
+    status = PR_SetFDInheritable(in_pipe[0], PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(in_pipe[1], PR_TRUE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(out_pipe[0], PR_TRUE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(out_pipe[1], PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+
+    attr = PR_NewProcessAttr();
+    if (attr == NULL) {
+        fprintf(stderr, "PR_NewProcessAttr failed\n");
+        exit(1);
+    }
+
+    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, out_pipe[0]);
+    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, in_pipe[1]);
+
+    process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr);
+    if (process == NULL) {
+        fprintf(stderr, "PR_CreateProcess failed\n");
+        exit(1);
+    }
+    PR_DestroyProcessAttr(attr);
+    status = PR_Close(out_pipe[0]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(in_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        strcpy(buf, "ping");
+        printf("ping process: sending \"%s\"\n", buf);
+        nBytes = PR_Write(out_pipe[1], buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
+                    PR_GetOSError());
+            exit(1);
+        }
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(in_pipe[0], buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        printf("ping process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "pong") != 0) {
+            fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+    }
+
+    status = PR_Close(in_pipe[0]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(out_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_WaitProcess(process, &exitCode);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_WaitProcess failed\n");
+        exit(1);
+    }
+    if (exitCode == 0) {
+        printf("PASS\n");
+        return 0;
+    } else {
+        printf("FAIL\n");
+        return 1;
+    }
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/pipeping2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/pipeping2.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,192 @@
+/* -*- 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) 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: pipeping2.c
+ *
+ * Description:
+ * This test runs in conjunction with the pipepong2 test.
+ * This test creates two pipes and passes two pipe fd's
+ * to the pipepong2 test.  Then this test writes "ping" to
+ * to the pipepong2 test and the pipepong2 test writes "pong"
+ * back.  To run this pair of tests, just invoke pipeping2.
+ *
+ * Tested areas: process creation, pipes, file descriptor
+ * inheritance.
+ */
+
+#include "prerror.h"
+#include "prio.h"
+#include "prproces.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUM_ITERATIONS 10
+
+static char *child_argv[] = { "pipepong2", NULL };
+
+int main()
+{
+    PRFileDesc *in_pipe[2];
+    PRFileDesc *out_pipe[2];
+    PRStatus status;
+    PRProcess *process;
+    PRProcessAttr *attr;
+    char buf[1024];
+    PRInt32 nBytes;
+    PRInt32 exitCode;
+    int idx;
+
+    status = PR_CreatePipe(&in_pipe[0], &in_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+    status = PR_CreatePipe(&out_pipe[0], &out_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+
+    status = PR_SetFDInheritable(in_pipe[0], PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(in_pipe[1], PR_TRUE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(out_pipe[0], PR_TRUE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(out_pipe[1], PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+
+    attr = PR_NewProcessAttr();
+    if (attr == NULL) {
+        fprintf(stderr, "PR_NewProcessAttr failed\n");
+        exit(1);
+    }
+
+    status = PR_ProcessAttrSetInheritableFD(attr, out_pipe[0], "PIPE_READ");
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n");
+        exit(1);
+    }
+    status = PR_ProcessAttrSetInheritableFD(attr, in_pipe[1], "PIPE_WRITE");
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n");
+        exit(1);
+    }
+
+    process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr);
+    if (process == NULL) {
+        fprintf(stderr, "PR_CreateProcess failed\n");
+        exit(1);
+    }
+    PR_DestroyProcessAttr(attr);
+    status = PR_Close(out_pipe[0]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(in_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        strcpy(buf, "ping");
+        printf("ping process: sending \"%s\"\n", buf);
+        nBytes = PR_Write(out_pipe[1], buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(in_pipe[0], buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed\n");
+            exit(1);
+        }
+        printf("ping process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "pong") != 0) {
+            fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+    }
+
+    status = PR_Close(in_pipe[0]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(out_pipe[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_WaitProcess(process, &exitCode);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_WaitProcess failed\n");
+        exit(1);
+    }
+    if (exitCode == 0) {
+        printf("PASS\n");
+        return 0;
+    } else {
+        printf("FAIL\n");
+        return 1;
+    }
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/pipepong.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/pipepong.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,92 @@
+/* -*- 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 ***** */
+
+/*
+ * File: pipepong.c
+ *
+ * Description:
+ * This test runs in conjunction with the pipeping test.
+ * The pipeping test creates two pipes and redirects the
+ * stdin and stdout of this test to the pipes.  Then the
+ * pipeping test writes "ping" to this test and this test
+ * writes "pong" back.  Note that this test does not depend
+ * on NSPR at all.  To run this pair of tests, just invoke
+ * pipeping.
+ *
+ * Tested areas: process creation, pipes, file descriptor
+ * inheritance, standard I/O redirection.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUM_ITERATIONS 10
+
+int main()
+{
+    char buf[1024];
+    size_t nBytes;
+    int idx;
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        memset(buf, 0, sizeof(buf));
+        nBytes = fread(buf, 1, 5, stdin);
+        fprintf(stderr, "pong process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "ping") != 0) {
+            fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+
+        strcpy(buf, "pong");
+        fprintf(stderr, "pong process: sending \"%s\"\n", buf);
+        nBytes = fwrite(buf, 1, 5, stdout);
+        if (nBytes != 5) {
+            fprintf(stderr, "pong process: fwrite failed\n");
+            exit(1);
+        }
+        fflush(stdout);
+    }
+
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/pipepong2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/pipepong2.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,130 @@
+/* -*- 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) 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: pipepong2.c
+ *
+ * Description:
+ * This test runs in conjunction with the pipeping2 test.
+ * The pipeping2 test creates two pipes and passes two
+ * pipe fd's to this test.  Then the pipeping2 test writes
+ * "ping" to this test and this test writes "pong" back.
+ * To run this pair of tests, just invoke pipeping2.
+ *
+ * Tested areas: process creation, pipes, file descriptor
+ * inheritance.
+ */
+
+#include "prerror.h"
+#include "prio.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUM_ITERATIONS 10
+
+int main()
+{
+    PRFileDesc *pipe_read, *pipe_write;
+    PRStatus status;
+    char buf[1024];
+    PRInt32 nBytes;
+    int idx;
+
+    pipe_read = PR_GetInheritedFD("PIPE_READ");
+    if (pipe_read == NULL) {
+        fprintf(stderr, "PR_GetInheritedFD failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(pipe_read, PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+    pipe_write = PR_GetInheritedFD("PIPE_WRITE");
+    if (pipe_write == NULL) {
+        fprintf(stderr, "PR_GetInheritedFD failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(pipe_write, PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(pipe_read, buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        printf("pong process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "ping") != 0) {
+            fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+
+        strcpy(buf, "pong");
+        printf("pong process: sending \"%s\"\n", buf);
+        nBytes = PR_Write(pipe_write, buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed\n");
+            exit(1);
+        }
+    }
+
+    status = PR_Close(pipe_read);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(pipe_write);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/pipeself.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/pipeself.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,260 @@
+/* -*- 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 ***** */
+
+/*
+ * File: pipeself.c
+ *
+ * Description:
+ * This test has two threads communicating with each other using
+ * two unidirectional pipes.  The primordial thread is the ping
+ * thread and the other thread is the pong thread.  The ping
+ * thread writes "ping" to the pong thread and the pong thread
+ * writes "pong" back.
+ */
+
+#include "prio.h"
+#include "prerror.h"
+#include "prthread.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NUM_ITERATIONS 10
+
+static PRFileDesc *ping_in, *ping_out;
+static PRFileDesc *pong_in, *pong_out;
+
+static void PongThreadFunc(void *arg)
+{
+    char buf[1024];
+    int idx;
+    PRInt32 nBytes;
+    PRStatus status;
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(pong_in, buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed\n");
+            exit(1);
+        }
+        printf("pong thread: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "pong thread: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "ping") != 0) {
+            fprintf(stderr, "pong thread: expected \"ping\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+        strcpy(buf, "pong");
+        printf("pong thread: sending \"%s\"\n", buf);
+        nBytes = PR_Write(pong_out, buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
+                    PR_GetOSError());
+            exit(1);
+        }
+    }
+
+    status = PR_Close(pong_in);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(pong_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+int main()
+{
+    PRStatus status;
+    PRThread *pongThread;
+    char buf[1024];
+    PRInt32 nBytes;
+    int idx;
+
+    status = PR_CreatePipe(&ping_in, &pong_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+    status = PR_CreatePipe(&pong_in, &ping_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+
+    pongThread = PR_CreateThread(PR_USER_THREAD, PongThreadFunc, NULL,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (pongThread == NULL) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        strcpy(buf, "ping");
+        printf("ping thread: sending \"%s\"\n", buf);
+        nBytes = PR_Write(ping_out, buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
+                    PR_GetOSError());
+            exit(1);
+        }
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(ping_in, buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed\n");
+            exit(1);
+        }
+        printf("ping thread: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "ping thread: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "pong") != 0) {
+            fprintf(stderr, "ping thread: expected \"pong\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+    }
+
+    status = PR_Close(ping_in);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(ping_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_JoinThread(pongThread);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+
+#ifdef XP_UNIX
+	/*
+	 * Test PR_Available for pipes
+	 */
+    status = PR_CreatePipe(&ping_in, &ping_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_CreatePipe failed\n");
+        exit(1);
+    }
+	nBytes = PR_Write(ping_out, buf, 250);
+	if (nBytes == -1) {
+		fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
+				PR_GetOSError());
+		exit(1);
+	}
+	nBytes = PR_Available(ping_in);
+	if (nBytes < 0) {
+		fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
+				PR_GetOSError());
+		exit(1);
+	} else if (nBytes != 250) {
+		fprintf(stderr, "PR_Available: expected 250 bytes but got %d bytes\n",
+				nBytes);
+		exit(1);
+	}
+	printf("PR_Available: expected %d, got %d bytes\n",250, nBytes);
+	/* read some data */
+	nBytes = PR_Read(ping_in, buf, 7);
+	if (nBytes == -1) {
+		fprintf(stderr, "PR_Read failed\n");
+		exit(1);
+	}
+	/* check available data */
+	nBytes = PR_Available(ping_in);
+	if (nBytes < 0) {
+		fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
+				PR_GetOSError());
+		exit(1);
+	} else if (nBytes != (250 - 7)) {
+		fprintf(stderr, "PR_Available: expected 243 bytes but got %d bytes\n",
+				nBytes);
+		exit(1);
+	}
+	printf("PR_Available: expected %d, got %d bytes\n",243, nBytes);
+	/* read all data */
+	nBytes = PR_Read(ping_in, buf, sizeof(buf));
+	if (nBytes == -1) {
+		fprintf(stderr, "PR_Read failed\n");
+		exit(1);
+	} else if (nBytes != 243) {
+		fprintf(stderr, "PR_Read failed: expected %d, got %d bytes\n",
+							243, nBytes);
+		exit(1);
+	}
+	/* check available data */
+	nBytes = PR_Available(ping_in);
+	if (nBytes < 0) {
+		fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
+				PR_GetOSError());
+		exit(1);
+	} else if (nBytes != 0) {
+		fprintf(stderr, "PR_Available: expected 0 bytes but got %d bytes\n",
+				nBytes);
+		exit(1);
+	}
+	printf("PR_Available: expected %d, got %d bytes\n", 0, nBytes);
+
+    status = PR_Close(ping_in);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_Close(ping_out);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+#endif /* XP_UNIX */
+
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/poll_er.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/poll_er.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,244 @@
+/* -*- 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: prpoll_err.c
+**
+** Description: This program tests PR_Poll with sockets.
+**              error reporting operation is tested
+**
+** 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.
+***********************************************************************/
+
+#ifdef XP_BEOS
+#include <stdio.h>
+int main()
+{
+    printf( "This test is not ported to the BeOS\n" );
+    return 0;
+}
+#else
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "primpl.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+static void
+ClientThreadFunc(void *arg)
+{
+    PRFileDesc *badFD = (PRFileDesc *) arg;
+    /*
+     * Make the fd invalid
+     */
+#if defined(XP_UNIX)
+    close(PR_FileDesc2NativeHandle(badFD));
+#elif defined(XP_OS2)
+    soclose(PR_FileDesc2NativeHandle(badFD));
+#elif defined(WIN32) || defined(WIN16)
+    closesocket(PR_FileDesc2NativeHandle(badFD));
+#elif defined(XP_MAC)
+    _PR_MD_CLOSE_SOCKET(PR_FileDesc2NativeHandle(badFD));
+#else
+#error "Unknown architecture"
+#endif
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRFileDesc *badFD;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    char buf[128];
+    PRPollDesc pds0[10], pds1[10], *pds, *other_pds;
+    PRIntn npds;
+    PRInt32 retVal;
+
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Poll with sockets.\n");
+		printf("error reporting is  tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    /* Set up the poll descriptor array */
+    pds = pds0;
+    other_pds = pds1;
+    memset(pds, 0, sizeof(pds));
+    pds[0].fd = listenSock1;
+    pds[0].in_flags = PR_POLL_READ;
+    pds[1].fd = listenSock2;
+    pds[1].in_flags = PR_POLL_READ;
+    npds = 2;
+
+
+    /* Testing bad fd */
+    if (debug_mode) printf("PR_Poll should detect a bad file descriptor\n");
+    if ((badFD = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a TCP socket\n");
+	goto exit_now;
+    }
+
+    pds[2].fd = badFD;
+    pds[2].in_flags = PR_POLL_READ;
+    npds = 3;
+
+    if (PR_CreateThread(PR_USER_THREAD, ClientThreadFunc,
+            badFD, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+            PR_UNJOINABLE_THREAD, 0) == NULL) {
+        fprintf(stderr, "cannot create thread\n");
+        exit(1);
+    }
+
+    retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT);
+    if (retVal != 1 || (unsigned short) pds[2].out_flags != PR_POLL_NVAL) {
+	fprintf(stderr, "Failed to detect the bad fd: "
+		"PR_Poll returns %d, out_flags is 0x%hx\n",
+		retVal, pds[2].out_flags);
+	failed_already=1;	
+	goto exit_now;
+    }
+    if (debug_mode) printf("PR_Poll detected the bad fd.  Test passed.\n\n");
+    PR_Cleanup();
+	goto exit_now;
+exit_now:
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}
+
+#endif /* XP_BEOS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/poll_nm.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/poll_nm.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,399 @@
+/* -*- 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: prpoll_norm.c
+**
+** Description: This program tests PR_Poll with sockets.
+**              Normal operation are tested
+**
+** 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prnetdb.h"
+#ifndef XP_MAC
+#include "obsolete/probslet.h"
+#else
+#include "probslet.h"
+#endif
+
+#ifndef XP_MAC
+#include "private/pprio.h"
+#else
+#include "pprio.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+#define NUM_ITERATIONS 5
+
+#ifdef XP_MAC
+int fprintf(FILE *stream, const char *fmt, ...)
+{
+PR_LogPrint(fmt);
+return 0;
+}
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+static void PR_CALLBACK
+clientThreadFunc(void *arg)
+{
+    PRUintn port = (PRUintn) arg;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    char buf[128];
+    int i;
+    PRStatus sts;
+    PRInt32 n;
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons((PRUint16)port);
+    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    memset(buf, 0, sizeof(buf));
+    PR_snprintf(buf, sizeof(buf), "%hu", port);
+
+    for (i = 0; i < NUM_ITERATIONS; i++) {
+	sock = PR_NewTCPSocket();
+	PR_ASSERT(sock != NULL);
+	
+    sts = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(sts == PR_SUCCESS);
+
+	n = PR_Write(sock, buf, sizeof(buf));
+	PR_ASSERT(n >= 0);
+
+	sts = PR_Close(sock);
+	PR_ASSERT(sts == PR_SUCCESS);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    char buf[128];
+    PRThread *clientThread;
+    PRPollDesc pds0[20], pds1[20], *pds, *other_pds;
+    PRIntn npds;
+    PRInt32 retVal;
+    PRIntn i, j;
+    PRSocketOptionData optval;
+
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+	debug_mode = 1;
+	SetupMacPrintfLog("poll_nm.log");
+#endif
+
+    if (debug_mode) {
+		printf("This program tests PR_Poll with sockets.\n");
+		printf("Normal operation are tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    memset(&addr, 0, sizeof(addr));
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    optval.option = PR_SockOpt_Nonblocking;
+    optval.value.non_blocking = PR_TRUE;
+    PR_SetSocketOption(listenSock1, &optval);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    PR_SetSocketOption(listenSock2, &optval);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    /* Set up the poll descriptor array */
+    pds = pds0;
+    other_pds = pds1;
+    memset(pds, 0, sizeof(pds));
+    pds[0].fd = listenSock1;
+    pds[0].in_flags = PR_POLL_READ;
+    pds[1].fd = listenSock2;
+    pds[1].in_flags = PR_POLL_READ;
+    /* Add some unused entries to test if they are ignored by PR_Poll() */
+    memset(&pds[2], 0, sizeof(pds[2]));
+    memset(&pds[3], 0, sizeof(pds[3]));
+    memset(&pds[4], 0, sizeof(pds[4]));
+    npds = 5;
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort1,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	failed_already=1;	
+	goto exit_now;
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort2,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	failed_already=1;		
+	goto exit_now;
+    }
+
+    if (debug_mode) {
+		printf("Two client threads are created.  Each of them will\n");
+		printf("send data to one of the two ports the server is listening on.\n");
+		printf("The data they send is the port number.  Each of them send\n");
+		printf("the data five times, so you should see ten lines below,\n");
+		printf("interleaved in an arbitrary order.\n");
+	}
+
+    /* two clients, three events per iteration: accept, read, close */
+    i = 0;
+    while (i < 2 * 3 * NUM_ITERATIONS) {
+	PRPollDesc *tmp;
+	int nextIndex;
+	int nEvents = 0;
+
+	retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(retVal != 0);  /* no timeout */
+	if (retVal == -1) {
+	    fprintf(stderr, "PR_Poll failed\n");
+		failed_already=1;			
+	    goto exit_now;
+	}
+
+	nextIndex = 2;
+	/* the two listening sockets */
+	for (j = 0; j < 2; j++) {
+	    other_pds[j] = pds[j];
+	    PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0
+		    && (pds[j].out_flags & PR_POLL_EXCEPT) == 0);
+	    if (pds[j].out_flags & PR_POLL_READ) {
+		PRFileDesc *sock;
+
+		nEvents++;
+		sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT);
+		if (sock == NULL) {
+		    fprintf(stderr, "PR_Accept() failed\n");
+			failed_already=1;	
+		    goto exit_now;
+		}
+		other_pds[nextIndex].fd = sock;
+		other_pds[nextIndex].in_flags = PR_POLL_READ;
+		nextIndex++;
+	    } else if (pds[j].out_flags & PR_POLL_ERR) {
+		fprintf(stderr, "PR_Poll() indicates that an fd has error\n");
+		failed_already=1;	
+		goto exit_now;
+	    } else if (pds[j].out_flags & PR_POLL_NVAL) {
+		fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n",
+			PR_FileDesc2NativeHandle(pds[j].fd));
+		failed_already=1;	
+		goto exit_now;
+	    }
+	}
+
+	for (j = 2; j < npds; j++) {
+            if (NULL == pds[j].fd) {
+                /*
+                 * Keep the unused entries in the poll descriptor array
+                 * for testing purposes.
+                 */
+                other_pds[nextIndex] = pds[j];
+                nextIndex++;
+                continue;
+            }
+
+	    PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0
+		    && (pds[j].out_flags & PR_POLL_EXCEPT) == 0);
+	    if (pds[j].out_flags & PR_POLL_READ) {
+                PRInt32 nAvail;
+		PRInt32 nRead;
+
+		nEvents++;
+                nAvail = PR_Available(pds[j].fd);
+		nRead = PR_Read(pds[j].fd, buf, sizeof(buf));
+                PR_ASSERT(nAvail == nRead);
+		if (nRead == -1) {
+		    fprintf(stderr, "PR_Read() failed\n");
+			failed_already=1;	
+		    goto exit_now;
+                } else if (nRead == 0) {
+                    PR_Close(pds[j].fd);
+                    continue;
+                } else {
+                    /* Just to be safe */
+                    buf[127] = '\0';
+                    if (debug_mode) printf("The server received \"%s\" from a client\n", buf);
+                }
+	    } else if (pds[j].out_flags & PR_POLL_ERR) {
+		fprintf(stderr, "PR_Poll() indicates that an fd has error\n");
+		failed_already=1;			
+		goto exit_now;
+	    } else if (pds[j].out_flags & PR_POLL_NVAL) {
+		fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n");
+		failed_already=1;			
+		goto exit_now;
+	    }
+            other_pds[nextIndex] = pds[j];
+            nextIndex++;
+	}
+
+	PR_ASSERT(retVal == nEvents);
+	/* swap */
+	tmp = pds;
+	pds = other_pds;
+	other_pds = tmp;
+	npds = nextIndex;
+	i += nEvents;
+    }
+
+    if (debug_mode) printf("Tests passed\n");
+
+exit_now:
+
+    if (listenSock1) {
+        PR_Close(listenSock1);
+    }
+    if (listenSock2) {
+        PR_Close(listenSock2);
+    }
+
+    PR_Cleanup();
+	
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/poll_to.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/poll_to.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,216 @@
+/* -*- 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: prpoll_to.c
+**
+** Description: This program tests PR_Poll with sockets.
+**              Timeout operation is tested
+**
+** Modification History:
+** 14-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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prnetdb.h"
+
+#ifndef XP_MAC
+#include "private/pprio.h"
+#else
+#include "pprio.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1 = NULL, *listenSock2 = NULL;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    char buf[128];
+    PRPollDesc pds0[10], pds1[10], *pds, *other_pds;
+    PRIntn npds;
+    PRInt32 retVal;
+
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Poll with sockets.\n");
+		printf("Timeout is tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	if (!debug_mode)  failed_already=1;
+	goto exit_now;
+    }
+    memset(&addr, 0, sizeof(addr));
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	if (!debug_mode)  failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	if (!debug_mode)  failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	if (!debug_mode)  failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	if (!debug_mode)  failed_already=1;	
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	if (!debug_mode)  failed_already=1;	
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	if (!debug_mode)  failed_already=1;	
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	if (!debug_mode)  failed_already=1;	
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    /* Set up the poll descriptor array */
+    pds = pds0;
+    other_pds = pds1;
+    memset(pds, 0, sizeof(pds));
+    pds[0].fd = listenSock1;
+    pds[0].in_flags = PR_POLL_READ;
+    pds[1].fd = listenSock2;
+    pds[1].in_flags = PR_POLL_READ;
+    npds = 2;
+
+    /* Testing timeout */
+    if (debug_mode) printf("PR_Poll should time out in 5 seconds\n");
+    retVal = PR_Poll(pds, npds, PR_SecondsToInterval(5));
+    if (retVal != 0) {
+	PR_snprintf(buf, sizeof(buf),
+		"PR_Poll should time out and return 0, but it returns %ld\n",
+		retVal);
+	fprintf(stderr, "%s", buf);
+	if (!debug_mode)  failed_already=1;	
+	goto exit_now;
+    }
+    if (debug_mode) printf("PR_Poll timed out.  Test passed.\n\n");
+
+exit_now:
+
+    if (listenSock1) {
+        PR_Close(listenSock1);
+    }
+    if (listenSock2) {
+        PR_Close(listenSock2);
+    }
+
+    PR_Cleanup();
+
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/pollable.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/pollable.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,293 @@
+/* -*- 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 ***** */
+
+/*
+ * A test for the pollable events.
+ *
+ * A number of threads are in a ring configuration, each waiting on
+ * a pollable event that is set by its upstream neighbor.
+ */
+
+#include "prinit.h"
+#include "prio.h"
+#include "prthread.h"
+#include "prerror.h"
+#include "prmem.h"
+#include "prlog.h"
+#include "prprf.h"
+
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+#define DEFAULT_THREADS 10
+#define DEFAULT_LOOPS 100
+
+PRIntn numThreads = DEFAULT_THREADS;
+PRIntn numIterations = DEFAULT_LOOPS;
+PRIntervalTime dally = PR_INTERVAL_NO_WAIT;
+PRFileDesc *debug_out = NULL;
+PRBool debug_mode = PR_FALSE;
+PRBool verbosity = PR_FALSE;
+
+typedef struct ThreadData {
+    PRFileDesc *event;
+    int index;
+    struct ThreadData *next;
+} ThreadData;
+
+void ThreadRoutine(void *arg)
+{
+    ThreadData *data = (ThreadData *) arg;
+    PRIntn i;
+    PRPollDesc pd;
+    PRInt32 rv;
+
+    pd.fd = data->event;
+    pd.in_flags = PR_POLL_READ;
+
+    for (i = 0; i < numIterations; i++) {
+        rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+        if (rv == -1) {
+            PR_fprintf(PR_STDERR, "PR_Poll failed\n");
+            exit(1);
+        }
+        if (verbosity) {
+            PR_fprintf(debug_out, "thread %d awakened\n", data->index);
+        }
+        PR_ASSERT(rv != 0);
+        PR_ASSERT(pd.out_flags & PR_POLL_READ);
+        if (PR_WaitForPollableEvent(data->event) == PR_FAILURE) {
+            PR_fprintf(PR_STDERR, "consume event failed\n");
+            exit(1);
+        }
+        if (dally != PR_INTERVAL_NO_WAIT) {
+            PR_Sleep(dally);
+        }
+        if (verbosity) {
+            PR_fprintf(debug_out, "thread %d posting event\n", data->index);
+        }
+        if (PR_SetPollableEvent(data->next->event) == PR_FAILURE) {
+            PR_fprintf(PR_STDERR, "post event failed\n");
+            exit(1);
+        }
+    }
+}
+
+static void Help(void)
+{
+    debug_out = PR_STDOUT;
+
+    PR_fprintf(
+            debug_out, "Usage: pollable [-c n] [-t n] [-d] [-v] [-G] [-C n] [-D n]\n");
+    PR_fprintf(
+            debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS);
+    PR_fprintf(
+            debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS);
+    PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n");
+    PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n");
+    PR_fprintf(debug_out, "-D n\tdally setting (msecs) (default: 0)\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    ThreadData selfData;
+    ThreadData *data;
+    PRThread **thread;
+    void *block;
+    PRIntn i;
+    PRIntervalTime timeStart, timeEnd;
+    PRPollDesc pd;
+    PRInt32 rv;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+    PRBool help = PR_FALSE;
+    PRUintn concurrency = 1;
+    PRUintn average;
+    PLOptStatus os;
+    PLOptState *opt;
+
+    PR_STDIO_INIT();
+
+    opt = PL_CreateOptState(argc, argv, "hdvc:t:C:GD:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) {
+            continue;
+        }
+        switch (opt->option) {
+            case 'v':  /* verbose mode */
+                verbosity = PR_TRUE;
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'c':  /* loop counter */
+                numIterations = atoi(opt->value);
+                break;
+            case 't':  /* thread limit */
+                numThreads = atoi(opt->value);
+                break;
+            case 'C':  /* Concurrency limit */
+                concurrency = atoi(opt->value);
+                break;
+            case 'G':  /* global threads only */
+                thread_scope = PR_GLOBAL_THREAD;
+                break;
+            case 'D':  /* dally */
+                dally = PR_MillisecondsToInterval(atoi(opt->value));
+                break;
+            case 'h':  /* help message */
+                Help();
+                help = PR_TRUE;
+                break;
+            default:
+                break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (help) {
+        return 1;
+    }
+
+    if (concurrency > 1) {
+        PR_SetConcurrency(concurrency);
+    }
+
+    if (PR_TRUE == debug_mode) {
+        debug_out = PR_STDOUT;
+	PR_fprintf(debug_out, "Test parameters\n");
+        PR_fprintf(debug_out, "\tThreads involved: %d\n", numThreads);
+        PR_fprintf(debug_out, "\tIteration limit: %d\n", numIterations);
+        PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency);
+        PR_fprintf(debug_out, "\tThread type: %s\n",
+                (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
+    }
+
+    /*
+     * Malloc a block of memory and divide it into data and thread.
+     */
+    block = PR_MALLOC(numThreads * (sizeof(ThreadData) + sizeof(PRThread *)));
+    if (block == NULL) {
+        PR_fprintf(PR_STDERR, "cannot malloc, failed\n");
+        exit(1);
+    }
+    data = (ThreadData *) block;
+    thread = (PRThread **) &data[numThreads];
+
+    /* Pollable event */
+    selfData.event = PR_NewPollableEvent();
+    if (selfData.event == NULL) {
+        PR_fprintf(PR_STDERR, "cannot create event: (%ld, %ld)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    selfData.next = &data[0];
+    for (i = 0; i < numThreads; i++) {
+        data[i].event = PR_NewPollableEvent();
+        if (data[i].event == NULL) {
+            PR_fprintf(PR_STDERR, "cannot create event: (%ld, %ld)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        data[i].index = i;
+        if (i != numThreads - 1) {
+            data[i].next = &data[i + 1];
+        } else {
+            data[i].next = &selfData;
+        }
+
+        thread[i] = PR_CreateThread(PR_USER_THREAD,
+                ThreadRoutine, &data[i], PR_PRIORITY_NORMAL,
+                thread_scope, PR_JOINABLE_THREAD, 0);
+        if (thread[i] == NULL) {
+            PR_fprintf(PR_STDERR, "cannot create thread\n");
+            exit(1);
+        }
+    }
+
+    timeStart = PR_IntervalNow();
+    pd.fd = selfData.event;
+    pd.in_flags = PR_POLL_READ;
+    for (i = 0; i < numIterations; i++) {
+        if (dally != PR_INTERVAL_NO_WAIT) {
+            PR_Sleep(dally);
+        }
+        if (verbosity) {
+            PR_fprintf(debug_out, "main thread posting event\n");
+        }
+        if (PR_SetPollableEvent(selfData.next->event) == PR_FAILURE) {
+            PR_fprintf(PR_STDERR, "set event failed\n");
+            exit(1);
+        }
+        rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
+        if (rv == -1) {
+            PR_fprintf(PR_STDERR, "wait failed\n");
+            exit(1);
+        }
+        PR_ASSERT(rv != 0);
+        PR_ASSERT(pd.out_flags & PR_POLL_READ);
+        if (verbosity) {
+            PR_fprintf(debug_out, "main thread awakened\n");
+        }
+	if (PR_WaitForPollableEvent(selfData.event) == PR_FAILURE) {
+            PR_fprintf(PR_STDERR, "consume event failed\n");
+            exit(1);
+        }
+    }
+    timeEnd = PR_IntervalNow();
+
+    if (debug_mode) {
+        average = PR_IntervalToMicroseconds(timeEnd - timeStart)
+                / (numIterations * numThreads);
+        PR_fprintf(debug_out, "Average switch times %d usecs for %d threads\n",
+                average, numThreads);
+    }
+
+    for (i = 0; i < numThreads; i++) {
+        if (PR_JoinThread(thread[i]) == PR_FAILURE) {
+            PR_fprintf(PR_STDERR, "join thread failed\n");
+            exit(1);
+        }
+        PR_DestroyPollableEvent(data[i].event);
+    }
+    PR_DELETE(block);
+	PR_DestroyPollableEvent(selfData.event);
+
+    PR_fprintf(PR_STDOUT, "PASSED\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/prftest.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/prftest.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,97 @@
+/* -*- 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:	prftest.c
+ * Description:
+ *     This is a simple test of the PR_snprintf() function defined
+ *     in prprf.c.
+ */
+
+#include "prlong.h"
+#include "prprf.h"
+
+#include <string.h>
+
+#define BUF_SIZE 128
+
+int main() {
+    PRInt16 i16;
+    PRIntn n;
+    PRInt32 i32;
+    PRInt64 i64;
+    char buf[BUF_SIZE];
+    char answer[BUF_SIZE];
+    int i, rv = 0;
+
+    i16 = -1;
+    n = -1;
+    i32 = -1;
+    LL_I2L(i64, i32);
+
+    PR_snprintf(buf, BUF_SIZE, "%hx %x %lx %llx", i16, n, i32, i64);
+    strcpy(answer, "ffff ");
+    for (i = PR_BYTES_PER_INT * 2; i; i--) {
+		strcat(answer, "f");
+    }
+    strcat(answer, " ffffffff ffffffffffffffff");
+
+    if (!strcmp(buf, answer)) {
+		printf("PR_snprintf test 1 passed\n");
+    } else {
+		printf("PR_snprintf test 1 failed\n");
+		printf("Converted string is %s\n", buf);
+		printf("Should be %s\n", answer);
+		rv = 1;
+    }
+
+    i16 = -32;
+    n = 30;
+    i32 = 64;
+    LL_I2L(i64, 333);
+    PR_snprintf(buf, BUF_SIZE, "%d %hd %lld %ld", n, i16, i64, i32);
+    if (!strcmp(buf, "30 -32 333 64")) {
+		printf("PR_snprintf test 2 passed\n");
+    } else {
+		printf("PR_snprintf test 2 failed\n");
+		printf("Converted string is %s\n", buf);
+		printf("Should be 30 -32 333 64\n");
+		rv = 1;
+    }
+
+    return rv;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/prftest1.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/prftest1.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,152 @@
+/* -*- 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:	prftest1.c
+** Description:
+**     This is a simple test of the PR_snprintf() function defined
+**     in prprf.c.
+**
+** Modification History:
+** 14-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. 
+***********************************************************************/
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+#include "prttools.h"
+
+#include "prinit.h"
+#include "prlong.h"
+#include "prprf.h"
+
+#include <string.h>
+
+#define BUF_SIZE 128
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Test_Result
+** DESCRIPTION: Used in conjunction with the regress tool, prints out the
+**				status of the test case.
+** INPUTS:      PASS/FAIL
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:   Determine what the status is and print accordingly.
+**      
+***********************************************************************/
+
+
+static void Test_Result (int result)
+{
+	if (result == PASS)
+		printf ("PASS\n");
+	else
+		printf ("FAIL\n");
+}
+
+int main(    int     argc,    char   *argv[])
+{
+    PRInt16 i16;
+    PRIntn n;
+    PRInt32 i32;
+    PRInt64 i64;
+    char buf[BUF_SIZE];
+    char answer[BUF_SIZE];
+    int i;
+
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+	/* main test */
+    PR_STDIO_INIT();
+	
+    i16 = -1;
+    n = -1;
+    i32 = -1;
+    LL_I2L(i64, i32);
+
+    PR_snprintf(buf, BUF_SIZE, "%hx %x %lx %llx", i16, n, i32, i64);
+    strcpy(answer, "ffff ");
+    for (i = PR_BYTES_PER_INT * 2; i; i--) {
+	strcat(answer, "f");
+    }
+    strcat(answer, " ffffffff ffffffffffffffff");
+
+    if (!strcmp(buf, answer)) {
+	if (debug_mode) printf("PR_snprintf test 1 passed\n");
+	else Test_Result (PASS);
+    } else {
+		if (debug_mode) {
+			printf("PR_snprintf test 1 failed\n");
+			printf("Converted string is %s\n", buf);
+			printf("Should be %s\n", answer);
+		}
+		else
+			Test_Result (FAIL);
+    }
+
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/prftest2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/prftest2.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+** File:	prftest2.c
+** Description:
+**     This is a simple test of the PR_snprintf() function defined
+**     in prprf.c.
+**
+** Modification History:
+** 14-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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prlong.h"
+#include "prinit.h"
+#include "prprf.h"
+
+#include <string.h>
+
+#define BUF_SIZE 128
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+int main(    int     argc,    char   *argv[])
+{
+    PRInt16 i16;
+    PRIntn n;
+    PRInt32 i32;
+    PRInt64 i64;
+    char buf[BUF_SIZE];
+
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+	/* main test */
+	
+
+    PR_STDIO_INIT();
+    i16 = -32;
+    n = 30;
+    i32 = 64;
+    LL_I2L(i64, 333);
+    PR_snprintf(buf, BUF_SIZE, "%d %hd %lld %ld", n, i16, i64, i32);
+    if (!strcmp(buf, "30 -32 333 64")) {
+		if (debug_mode) printf("PR_snprintf test 2 passed\n");
+    } else {
+		if (debug_mode) {
+			printf("PR_snprintf test 2 failed\n");
+			printf("Converted string is %s\n", buf);
+			printf("Should be 30 -32 333 64\n");
+		}
+		else failed_already=1;
+    }
+	if(failed_already)
+	{
+        printf("FAILED\n");
+		return 1;
+	}
+	else
+	{
+        printf("PASSED\n");
+		return 0;
+	}
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/primblok.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/primblok.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,148 @@
+/* -*- 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) 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:        primblok.c
+ * Purpose:     testing whether the primordial thread can block in a
+ *              native blocking function without affecting the correct
+ *              functioning of NSPR I/O functions (Bugzilla bug #30746)
+ */
+
+#if !defined(WINNT)
+
+#include <stdio.h>
+
+int main()
+{
+    printf("This test is not relevant on this platform\n");
+    return 0;
+}
+
+#else /* WINNT */
+
+#include "nspr.h"
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define TEST_FILE_NAME "primblok.dat"
+
+/* use InterlockedExchange to update this variable */
+static LONG iothread_done;
+
+static void PR_CALLBACK IOThread(void *arg)
+{
+    PRFileDesc *fd;
+    char buf[32];
+    PRInt32 nbytes;
+
+    /* Give the primordial thread one second to block */
+    Sleep(1000);
+
+    /*
+     * See if our PR_Write call will hang when the primordial
+     * thread is blocking in a native blocking function.
+     */
+    fd = PR_Open(TEST_FILE_NAME, PR_WRONLY|PR_CREATE_FILE, 0666);
+    if (NULL == fd) {
+        fprintf(stderr, "PR_Open failed\n");
+        exit(1);
+    }
+    memset(buf, 0xaf, sizeof(buf));
+    fprintf(stderr, "iothread: calling PR_Write\n");
+    nbytes = PR_Write(fd, buf, sizeof(buf));
+    fprintf(stderr, "iothread: PR_Write returned\n");
+    if (nbytes != sizeof(buf)) {
+        fprintf(stderr, "PR_Write returned %d\n", nbytes);
+        exit(1);
+    }
+    if (PR_Close(fd) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) {
+        fprintf(stderr, "PR_Delete failed\n");
+        exit(1);
+    }
+
+    /* Tell the main thread that we are done */
+    InterlockedExchange(&iothread_done, 1);
+}
+
+int main()
+{
+    PRThread *iothread;
+
+    /* Must be a global thread */
+    iothread = PR_CreateThread(
+        PR_USER_THREAD, IOThread, NULL, PR_PRIORITY_NORMAL,
+        PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (iothread == NULL) {
+        fprintf(stderr, "cannot create thread\n");
+        exit(1);
+    }
+
+    /*
+     * Block in a native blocking function.
+     * Give iothread 5 seconds to finish its task.
+     */
+    Sleep(5000);
+
+    /*
+     * Is iothread done or is it hung?
+     *
+     * I'm actually only interested in reading the value
+     * of iothread_done.  I'm using InterlockedExchange as
+     * a thread-safe way to read iothread_done.
+     */
+    if (InterlockedExchange(&iothread_done, 1) == 0) {
+        fprintf(stderr, "iothread is hung\n");
+        fprintf(stderr, "FAILED\n");
+        exit(1);
+    }
+
+    if (PR_JoinThread(iothread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    printf("PASSED\n");
+    return 0;
+}  /* main */
+
+#endif /* WINNT */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/priotest.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/priotest.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,233 @@
+/* -*- 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:        priotest.c
+ * Purpose:     testing priorities
+ */
+
+#ifdef XP_MAC
+#error "This test does not run on Macintosh"
+#else
+
+
+#include "prcmon.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prmon.h"
+#include "prprf.h"
+#include "prthread.h"
+#include "prtypes.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define DEFAULT_DURATION 5
+
+static PRBool failed = PR_FALSE;
+static PRIntervalTime oneSecond;
+static PRFileDesc *debug_out = NULL;
+static PRBool debug_mode = PR_FALSE;
+
+static PRUint32 PerSecond(PRIntervalTime timein)
+{
+    PRUint32 loop = 0;
+    while (((PRIntervalTime)(PR_IntervalNow()) - timein) < oneSecond)
+        loop += 1;
+    return loop;
+}  /* PerSecond */
+
+static void PR_CALLBACK Low(void *arg)
+{
+    PRUint32 t3 = 0, t2 = 0, t1 = 0, t0, *tn = (PRUint32*)arg;
+    while (1)
+    {
+        t0 = PerSecond(PR_IntervalNow());
+        *tn = (t3 + 3 * t2 + 3 * t1 + t0) / 8;
+        t3 = t2; t2 = t1; t1 = t0;
+    }
+}  /* Low */
+
+static void PR_CALLBACK High(void *arg)
+{
+    PRUint32 t3 = 0, t2 = 0, t1 = 0, t0, *tn = (PRUint32*)arg;
+    while (1)
+    {
+        PRIntervalTime timein = PR_IntervalNow();
+        PR_Sleep(oneSecond >> 2);  /* 0.25 seconds */
+        t0 = PerSecond(timein);
+        *tn = (t3 + 3 * t2 + 3 * t1 + t0) / 8;
+        t3 = t2; t2 = t1; t1 = t0;
+    }
+}  /* High */
+
+static void Help(void)
+{
+    PR_fprintf(
+		debug_out, "Usage: priotest [-d] [-c n]\n");
+    PR_fprintf(
+		debug_out, "-c n\tduration of test in seconds (default: %d)\n", DEFAULT_DURATION);
+    PR_fprintf(
+        debug_out, "-d\tturn on debugging output (default: FALSE)\n");
+}  /* Help */
+
+static void RudimentaryTests(void)
+{
+    /*
+    ** Try some rudimentary tests like setting valid priority and
+    ** getting it back, or setting invalid priorities and getting
+    ** back a valid answer.
+    */
+    PRThreadPriority priority;
+    PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
+    priority = PR_GetThreadPriority(PR_GetCurrentThread());
+    failed = ((PR_TRUE == failed) || (PR_PRIORITY_URGENT != priority))
+        ? PR_TRUE : PR_FALSE;
+    if (debug_mode && (PR_PRIORITY_URGENT != priority))
+    {
+        PR_fprintf(debug_out, "PR_[S/G]etThreadPriority() failed\n");
+    }
+
+
+    PR_SetThreadPriority(
+        PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_FIRST - 1));
+    priority = PR_GetThreadPriority(PR_GetCurrentThread());
+    failed = ((PR_TRUE == failed) || (PR_PRIORITY_FIRST != priority))
+        ? PR_TRUE : PR_FALSE;
+    if (debug_mode && (PR_PRIORITY_FIRST != priority))
+    {
+        PR_fprintf(debug_out, "PR_SetThreadPriority(-1) failed\n");
+    }
+
+    PR_SetThreadPriority(
+        PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_LAST + 1));
+    priority = PR_GetThreadPriority(PR_GetCurrentThread());
+    failed = ((PR_TRUE == failed) || (PR_PRIORITY_LAST != priority))
+        ? PR_TRUE : PR_FALSE;
+    if (debug_mode && (PR_PRIORITY_LAST != priority))
+    {
+        PR_fprintf(debug_out, "PR_SetThreadPriority(+1) failed\n");
+    }
+
+}  /* RudimentataryTests */
+
+static void CreateThreads(PRUint32 *lowCount, PRUint32 *highCount)
+{
+    (void)PR_CreateThread(
+        PR_USER_THREAD, Low, lowCount, PR_PRIORITY_LOW,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    (void)PR_CreateThread(
+        PR_USER_THREAD, High, highCount, PR_PRIORITY_HIGH,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+} /* CreateThreads */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PLOptStatus os;
+    PRIntn duration = DEFAULT_DURATION;
+    PRUint32 totalCount, highCount = 0, lowCount = 0;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "hdc:");
+
+    debug_out = PR_STDOUT;
+    oneSecond = PR_SecondsToInterval(1);
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+        case 'c':  /* test duration */
+			duration = atoi(opt->value);
+            break;
+        case 'h':  /* help message */
+         default:
+			Help();
+			return 2;
+        }
+    }
+	PL_DestroyOptState(opt);
+    PR_STDIO_INIT();
+
+    if (duration == 0) duration = DEFAULT_DURATION;
+
+    RudimentaryTests();
+
+    printf("Priority test: running for %d seconds\n\n", duration);
+
+    (void)PerSecond(PR_IntervalNow());
+    totalCount = PerSecond(PR_IntervalNow());
+
+    PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
+
+    if (debug_mode)
+    {
+        PR_fprintf(debug_out,
+		    "The high priority thread should get approximately three\n");
+        PR_fprintf( debug_out,
+		    "times what the low priority thread manages. A maximum of \n");
+        PR_fprintf( debug_out, "%d cycles are available.\n\n", totalCount);
+    }
+
+    duration = (duration + 4) / 5;
+    CreateThreads(&lowCount, &highCount);
+    while (duration--)
+    {
+        PRIntn loop = 5;
+        while (loop--) PR_Sleep(oneSecond);
+        if (debug_mode)
+            PR_fprintf(debug_out, "high : low :: %d : %d\n", highCount, lowCount);
+    }
+
+
+    PR_ProcessExit((failed) ? 1 : 0);
+
+	PR_ASSERT(!"You can't get here -- but you did!");
+	return 1;  /* or here */
+
+}  /* main */
+
+#endif  /* ifdef XP_MAC */
+
+/* priotest.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/provider.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/provider.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1445 @@
+/* -*- 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 ***** */
+
+/*
+ *
+ * Notes:
+ * [1] lth. The call to Sleep() is a hack to get the test case to run
+ * on Windows 95. Without it, the test case fails with an error
+ * WSAECONNRESET following a recv() call. The error is caused by the
+ * server side thread termination without a shutdown() or closesocket()
+ * call. Windows docmunentation suggests that this is predicted
+ * behavior; that other platforms get away with it is ... serindipity.
+ * The test case should shutdown() or closesocket() before
+ * thread termination. I didn't have time to figure out where or how
+ * to do it. The Sleep() call inserts enough delay to allow the
+ * client side to recv() all his data before the server side thread
+ * terminates. Whew! ...
+ *
+ ** Modification History:
+ * 14-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. 
+ */
+
+#include "prclist.h"
+#include "prcvar.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prtime.h"
+#include "prmem.h"
+#include "prnetdb.h"
+#include "prprf.h"
+#include "prthread.h"
+
+#include "pprio.h"
+#include "primpl.h"
+
+#include "plstr.h"
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#if defined(XP_UNIX)
+#include <math.h>
+#endif
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#endif
+
+/*
+** This is the beginning of the test
+*/
+
+#define RECV_FLAGS 0
+#define SEND_FLAGS 0
+#define BUFFER_SIZE 1024
+#define DEFAULT_BACKLOG 5
+#define DEFAULT_PORT 13000
+#define DEFAULT_CLIENTS 1
+#define ALLOWED_IN_ACCEPT 1
+#define DEFAULT_CLIPPING 1000
+#define DEFAULT_WORKERS_MIN 1
+#define DEFAULT_WORKERS_MAX 1
+#define DEFAULT_SERVER "localhost"
+#define DEFAULT_EXECUTION_TIME 10
+#define DEFAULT_CLIENT_TIMEOUT 4000
+#define DEFAULT_SERVER_TIMEOUT 4000
+#define DEFAULT_SERVER_PRIORITY PR_PRIORITY_HIGH
+
+typedef enum CSState_e {cs_init, cs_run, cs_stop, cs_exit} CSState_t;
+
+static void PR_CALLBACK Worker(void *arg);
+typedef struct CSPool_s CSPool_t;
+typedef struct CSWorker_s CSWorker_t;
+typedef struct CSServer_s CSServer_t;
+typedef enum Verbosity
+{
+    TEST_LOG_ALWAYS,
+    TEST_LOG_ERROR,
+    TEST_LOG_WARNING,
+    TEST_LOG_NOTICE,
+    TEST_LOG_INFO,
+    TEST_LOG_STATUS,
+    TEST_LOG_VERBOSE
+} Verbosity;
+
+static enum {
+    thread_nspr, thread_pthread, thread_uithread, thread_sproc, thread_win32
+} thread_provider;
+
+static PRInt32 domain = AF_INET;
+static PRInt32 protocol = 6;  /* TCP */
+static PRFileDesc *debug_out = NULL;
+static PRBool debug_mode = PR_FALSE;
+static PRBool pthread_stats = PR_FALSE;
+static Verbosity verbosity = TEST_LOG_ALWAYS;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+struct CSWorker_s
+{
+    PRCList element;        /* list of the server's workers */
+
+    PRThread *thread;       /* this worker objects thread */
+    CSServer_t *server;     /* back pointer to server structure */
+};
+
+struct CSPool_s
+{
+    PRCondVar *exiting;
+    PRCondVar *acceptComplete;
+    PRUint32 accepting, active, workers;
+};
+
+struct CSServer_s
+{
+    PRCList list;           /* head of worker list */
+
+    PRLock *ml;
+    PRThread *thread;       /* the main server thread */
+    PRCondVar *stateChange;
+
+    PRUint16 port;          /* port we're listening on */
+    PRUint32 backlog;       /* size of our listener backlog */
+    PRFileDesc *listener;   /* the fd accepting connections */
+
+    CSPool_t pool;          /* statistics on worker threads */
+    CSState_t state;        /* the server's state */
+    struct                  /* controlling worker counts */
+    {
+        PRUint32 minimum, maximum, accepting;
+    } workers;
+
+    /* statistics */
+    PRIntervalTime started, stopped;
+    PRUint32 operations, bytesTransferred;
+};
+
+typedef struct CSDescriptor_s
+{
+    PRInt32 size;       /* size of transfer */
+    char filename[60];  /* filename, null padded */
+} CSDescriptor_t;
+
+typedef struct CSClient_s
+{
+    PRLock *ml;
+    PRThread *thread;
+    PRCondVar *stateChange;
+    PRNetAddr serverAddress;
+
+    CSState_t state;
+
+    /* statistics */
+    PRIntervalTime started, stopped;
+    PRUint32 operations, bytesTransferred;
+} CSClient_t;
+
+#define TEST_LOG(l, p, a) \
+    do { \
+        if (debug_mode || (p <= verbosity)) printf a; \
+    } while (0)
+
+PRLogModuleInfo *cltsrv_log_file = NULL;
+
+#define MY_ASSERT(_expr) \
+    ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__))
+
+#define TEST_ASSERT(_expr) \
+    ((_expr)?((void)0):_MY_Assert(# _expr,__FILE__,__LINE__))
+
+static void _MY_Assert(const char *s, const char *file, PRIntn ln)
+{
+    PL_PrintError(NULL);
+#if DEBUG
+    PR_Assert(s, file, ln);
+#endif
+}  /* _MW_Assert */
+
+static PRBool Aborted(PRStatus rv)
+{
+    return ((PR_FAILURE == rv) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) ?
+        PR_TRUE : PR_FALSE;
+}
+
+static void TimeOfDayMessage(const char *msg, PRThread* me)
+{
+    char buffer[100];
+    PRExplodedTime tod;
+    PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &tod);
+    (void)PR_FormatTime(buffer, sizeof(buffer), "%T", &tod);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("%s(0x%p): %s\n", msg, me, buffer));
+}  /* TimeOfDayMessage */
+
+
+static void PR_CALLBACK Client(void *arg)
+{
+    PRStatus rv;
+    PRIntn index;
+    char buffer[1024];
+    PRFileDesc *fd = NULL;
+    PRUintn clipping = DEFAULT_CLIPPING;
+    CSClient_t *client = (CSClient_t*)arg;
+    PRThread *me = client->thread = PR_GetCurrentThread();
+    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);
+    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_CLIENT_TIMEOUT);
+
+
+    for (index = 0; index < sizeof(buffer); ++index)
+        buffer[index] = (char)index;
+
+    client->started = PR_IntervalNow();
+
+    PR_Lock(client->ml);
+    client->state = cs_run;
+    PR_NotifyCondVar(client->stateChange);
+    PR_Unlock(client->ml);
+
+    TimeOfDayMessage("Client started at", me);
+
+    while (cs_run == client->state)
+    {
+        PRInt32 bytes, descbytes, filebytes, netbytes;
+
+        (void)PR_NetAddrToString(&client->serverAddress, buffer, sizeof(buffer));
+        TEST_LOG(cltsrv_log_file, TEST_LOG_INFO, 
+            ("\tClient(0x%p): connecting to server at %s\n", me, buffer));
+
+        fd = PR_Socket(domain, SOCK_STREAM, protocol);
+        TEST_ASSERT(NULL != fd);
+        rv = PR_Connect(fd, &client->serverAddress, timeout);
+        if (PR_FAILURE == rv)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tClient(0x%p): conection failed\n", me));
+            goto aborted;
+        }
+
+        memset(descriptor, 0, sizeof(*descriptor));
+        descriptor->size = PR_htonl(descbytes = rand() % clipping);
+        PR_snprintf(
+            descriptor->filename, sizeof(descriptor->filename),
+            "CS%p%p-%p.dat", client->started, me, client->operations);
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tClient(0x%p): sending descriptor for %u bytes\n", me, descbytes));
+        bytes = PR_Send(
+            fd, descriptor, sizeof(*descriptor), SEND_FLAGS, timeout);
+        if (sizeof(CSDescriptor_t) != bytes)
+        {
+            if (Aborted(PR_FAILURE)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\tClient(0x%p): send descriptor timeout\n", me));
+                goto retry;
+            }
+        }
+        TEST_ASSERT(sizeof(*descriptor) == bytes);
+
+        netbytes = 0;
+        while (netbytes < descbytes)
+        {
+            filebytes = sizeof(buffer);
+            if ((descbytes - netbytes) < filebytes)
+                filebytes = descbytes - netbytes;
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\tClient(0x%p): sending %d bytes\n", me, filebytes));
+            bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);
+            if (filebytes != bytes)
+            {
+                if (Aborted(PR_FAILURE)) goto aborted;
+                if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                {
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): send data timeout\n", me));
+                    goto retry;
+                }
+            }
+            TEST_ASSERT(bytes == filebytes);
+            netbytes += bytes;
+        }
+        filebytes = 0;
+        while (filebytes < descbytes)
+        {
+            netbytes = sizeof(buffer);
+            if ((descbytes - filebytes) < netbytes)
+                netbytes = descbytes - filebytes;
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\tClient(0x%p): receiving %d bytes\n", me, netbytes));
+            bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);
+            if (-1 == bytes)
+            {
+                if (Aborted(PR_FAILURE))
+                {
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive data aborted\n", me));
+                    goto aborted;
+                }
+                else if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive data timeout\n", me));
+				else
+                    TEST_LOG(
+                        cltsrv_log_file, TEST_LOG_ERROR,
+                        ("\tClient(0x%p): receive error (%d, %d)\n",
+						me, PR_GetError(), PR_GetOSError()));
+                goto retry;
+           }
+            if (0 == bytes)
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tClient(0x%p): unexpected end of stream\n",
+                    PR_GetCurrentThread()));
+                break;
+            }
+            filebytes += bytes;
+        }
+
+        rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+        if (Aborted(rv)) goto aborted;
+        TEST_ASSERT(PR_SUCCESS == rv);
+retry:
+        (void)PR_Close(fd); fd = NULL;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_INFO,
+            ("\tClient(0x%p): disconnected from server\n", me));
+
+        PR_Lock(client->ml);
+        client->operations += 1;
+        client->bytesTransferred += 2 * descbytes;
+        rv = PR_WaitCondVar(client->stateChange, rand() % clipping);
+        PR_Unlock(client->ml);
+        if (Aborted(rv)) break;
+    }
+
+aborted:
+    client->stopped = PR_IntervalNow();
+
+    PR_ClearInterrupt();
+    if (NULL != fd) rv = PR_Close(fd);
+
+    PR_Lock(client->ml);
+    client->state = cs_exit;
+    PR_NotifyCondVar(client->stateChange);
+    PR_Unlock(client->ml);
+    PR_DELETE(descriptor);
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("\tClient(0x%p): stopped after %u operations and %u bytes\n",
+        PR_GetCurrentThread(), client->operations, client->bytesTransferred));
+
+}  /* Client */
+
+static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server)
+{
+    PRStatus drv, rv;
+    char buffer[1024];
+    PRFileDesc *file = NULL;
+    PRThread * me = PR_GetCurrentThread();
+    PRInt32 bytes, descbytes, netbytes, filebytes = 0;
+    CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t);
+    PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\tProcessRequest(0x%p): receiving desciptor\n", me));
+    bytes = PR_Recv(
+        fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout);
+    if (-1 == bytes)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto exit;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tProcessRequest(0x%p): receive timeout\n", me));
+        }
+        goto exit;
+    }
+    if (0 == bytes)
+    {
+        rv = PR_FAILURE;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_ERROR,
+            ("\tProcessRequest(0x%p): unexpected end of file\n", me));
+        goto exit;
+    }
+    descbytes = PR_ntohl(descriptor->size);
+    TEST_ASSERT(sizeof(*descriptor) == bytes);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE, 
+        ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n",
+        me, descbytes, descriptor->filename));
+
+    file = PR_Open(
+        descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666);
+    if (NULL == file)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto aborted;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\tProcessRequest(0x%p): open file timeout\n", me));
+            goto aborted;
+        }
+    }
+    TEST_ASSERT(NULL != file);
+
+    filebytes = 0;
+    while (filebytes < descbytes)
+    {
+        netbytes = sizeof(buffer);
+        if ((descbytes - filebytes) < netbytes)
+            netbytes = descbytes - filebytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes));
+        bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout);
+        if (-1 == bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): receive data timeout\n", me));
+                goto aborted;
+            }
+            /*
+             * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED)
+             * on NT here.  This is equivalent to ECONNRESET on Unix.
+             *     -wtc
+             */
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_WARNING,
+                ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n",
+                me, PR_GetError(), PR_GetOSError()));
+            goto aborted;
+        }
+        if(0 == bytes)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_WARNING,
+                ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me));
+            rv = PR_FAILURE;
+            goto aborted;
+        }
+        filebytes += bytes;
+        netbytes = bytes;
+        /* The byte count for PR_Write should be positive */
+        MY_ASSERT(netbytes > 0);
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes));
+        bytes = PR_Write(file, buffer, netbytes);
+        if (netbytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): write file timeout\n", me));
+                goto aborted;
+            }
+        }
+        TEST_ASSERT(bytes > 0);
+    }
+
+    PR_Lock(server->ml);
+    server->operations += 1;
+    server->bytesTransferred += filebytes;
+    PR_Unlock(server->ml);
+
+    rv = PR_Close(file); file = NULL;
+    if (Aborted(rv)) goto aborted;
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename));
+    file = PR_Open(descriptor->filename, PR_RDONLY, 0);
+    if (NULL == file)
+    {
+        rv = PR_FAILURE;
+        if (Aborted(rv)) goto aborted;
+        if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_ERROR,
+                ("\t\tProcessRequest(0x%p): open file timeout\n",
+                PR_GetCurrentThread()));
+            goto aborted;
+        }
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_ERROR,
+            ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n",
+            me, PR_GetError(), PR_GetOSError()));
+        goto aborted;
+    }
+    TEST_ASSERT(NULL != file);
+
+    netbytes = 0;
+    while (netbytes < descbytes)
+    {
+        filebytes = sizeof(buffer);
+        if ((descbytes - netbytes) < filebytes)
+            filebytes = descbytes - netbytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes));
+        bytes = PR_Read(file, buffer, filebytes);
+        if (filebytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): read file timeout\n", me));
+            else
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n",
+                    me, PR_GetError(), PR_GetOSError()));
+            goto aborted;
+        }
+        TEST_ASSERT(bytes > 0);
+        netbytes += bytes;
+        filebytes = bytes;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes));
+        bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout);
+        if (filebytes != bytes)
+        {
+            rv = PR_FAILURE;
+            if (Aborted(rv)) goto aborted;
+            if (PR_IO_TIMEOUT_ERROR == PR_GetError())
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tProcessRequest(0x%p): send data timeout\n", me));
+                goto aborted;
+            }
+            break;
+        }
+       TEST_ASSERT(bytes > 0);
+    }
+    
+    PR_Lock(server->ml);
+    server->bytesTransferred += filebytes;
+    PR_Unlock(server->ml);
+
+    rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+    if (Aborted(rv)) goto aborted;
+
+    rv = PR_Close(file); file = NULL;
+    if (Aborted(rv)) goto aborted;
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+aborted:
+    PR_ClearInterrupt();
+    if (NULL != file) PR_Close(file);
+    drv = PR_Delete(descriptor->filename);
+    TEST_ASSERT(PR_SUCCESS == drv);
+exit:
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\t\tProcessRequest(0x%p): Finished\n", me));
+
+    PR_DELETE(descriptor);
+
+#if defined(WIN95)
+    PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */
+#endif
+    return rv;
+}  /* ProcessRequest */
+
+typedef void (*StartFn)(void*);
+typedef struct StartObject
+{
+    StartFn start;
+    void *arg;
+} StartObject;
+
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include "md/_pth.h"
+#include <pthread.h>
+
+static void *pthread_start(void *arg)
+{
+    StartObject *so = (StartObject*)arg;
+    StartFn start = so->start;
+    void *data = so->arg;
+    PR_Free(so);
+    start(data);
+    return NULL;
+}  /* pthread_start */
+#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
+
+#if defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)
+#include <thread.h>
+
+static void *uithread_start(void *arg)
+{
+    StartObject *so = (StartObject*)arg;
+    StartFn start = so->start;
+    void *data = so->arg;
+    PR_Free(so);
+    start(data);
+    return NULL;
+}  /* uithread_start */
+#endif /* defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) */
+
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+#include <sys/types.h>
+#include <sys/prctl.h>
+static void sproc_start(void *arg, PRSize size)
+{
+    StartObject *so = (StartObject*)arg;
+    StartFn start = so->start;
+    void *data = so->arg;
+    PR_Free(so);
+    start(data);
+}  /* sproc_start */
+#endif  /* defined(IRIX) && !defined(_PR_PTHREADS) */
+
+#if defined(WIN32)
+#include <process.h>  /* for _beginthreadex() */
+
+static PRUintn __stdcall windows_start(void *arg)
+{
+    StartObject *so = (StartObject*)arg;
+    StartFn start = so->start;
+    void *data = so->arg;
+    PR_Free(so);
+    start(data);
+    return 0;
+}  /* windows_start */
+#endif /* defined(WIN32) */
+
+static PRStatus JoinThread(PRThread *thread)
+{
+    PRStatus rv;
+    switch (thread_provider)
+    {
+    case thread_nspr:
+        rv = PR_JoinThread(thread);
+        break;
+    case thread_pthread:
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+        rv = PR_SUCCESS;
+        break;
+#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
+    case thread_uithread:
+#if defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)
+        rv = PR_SUCCESS;
+        break;
+#endif /* defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) */
+    case thread_win32:
+#if defined(WIN32)
+        rv = PR_SUCCESS;
+        break;
+#endif
+    default:
+        rv = PR_FAILURE;
+        break;
+    }
+    return rv;    
+}  /* JoinThread */
+
+static PRStatus NewThread(
+    StartFn start, void *arg, PRThreadPriority prio, PRThreadState state)
+{
+    PRStatus rv;
+
+    switch (thread_provider)
+    {
+    case thread_nspr:
+        {
+            PRThread *thread = PR_CreateThread(
+                PR_USER_THREAD, start, arg,
+                PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+                PR_JOINABLE_THREAD, 0);
+            rv = (NULL == thread) ? PR_FAILURE : PR_SUCCESS;
+        }
+        break;
+    case thread_pthread:
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+        {
+            int rv;
+            pthread_t id;
+            pthread_attr_t tattr;
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+
+            rv = _PT_PTHREAD_ATTR_INIT(&tattr);
+            PR_ASSERT(0 == rv);
+
+            rv = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
+            PR_ASSERT(0 == rv);
+
+            rv = pthread_attr_setstacksize(&tattr, 64 * 1024);
+            PR_ASSERT(0 == rv);
+
+            rv = _PT_PTHREAD_CREATE(&id, tattr, pthread_start, start_object);
+            (void)_PT_PTHREAD_ATTR_DESTROY(&tattr);
+            return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+#endif /* defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS) */
+        break;
+
+    case thread_uithread:
+#if defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)
+        {
+            int rv;
+            thread_t id;
+            long flags;
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+
+            flags = THR_DETACHED;
+
+            rv = thr_create(NULL, NULL, uithread_start, start_object, flags, &id);
+            return (0 == rv) ? PR_SUCCESS : PR_FAILURE;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+#endif /* defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY) */
+        break;
+
+    case thread_sproc:
+#if defined(IRIX) && !defined(_PR_PTHREADS)
+        {
+            PRInt32 pid;
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+            pid = sprocsp(
+                sproc_start, PR_SALL, start_object, NULL, 64 * 1024);
+            rv = (0 < pid) ? PR_SUCCESS : PR_FAILURE;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+#endif  /* defined(IRIX) && !defined(_PR_PTHREADS) */
+        break;
+    case thread_win32:
+#if defined(WIN32)
+        {
+            void *th;
+            PRUintn id;       
+            StartObject *start_object;
+            start_object = PR_NEW(StartObject);
+            PR_ASSERT(NULL != start_object);
+            start_object->start = start;
+            start_object->arg = arg;
+            th = (void*)_beginthreadex(
+                NULL, /* LPSECURITY_ATTRIBUTES - pointer to thread security attributes */  
+                0U, /* DWORD - initial thread stack size, in bytes */
+                windows_start, /* LPTHREAD_START_ROUTINE - pointer to thread function */
+                start_object, /* LPVOID - argument for new thread */
+                0U, /*DWORD dwCreationFlags - creation flags */
+                &id /* LPDWORD - pointer to returned thread identifier */ );
+
+            rv = (NULL == th) ? PR_FAILURE : PR_SUCCESS;
+        }
+#else
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+#endif
+        break;
+    default:
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        rv = PR_FAILURE;
+    }
+    return rv;
+}  /* NewThread */
+
+static PRStatus CreateWorker(CSServer_t *server, CSPool_t *pool)
+{
+    PRStatus rv;
+    CSWorker_t *worker = PR_NEWZAP(CSWorker_t);
+    worker->server = server;
+    PR_INIT_CLIST(&worker->element);
+    rv = NewThread(
+        Worker, worker, DEFAULT_SERVER_PRIORITY, PR_UNJOINABLE_THREAD);
+    if (PR_FAILURE == rv) PR_DELETE(worker);
+
+    TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, 
+        ("\tCreateWorker(0x%p): create new worker (0x%p)\n",
+        PR_GetCurrentThread(), worker->thread));
+
+    return rv;
+}  /* CreateWorker */
+
+static void PR_CALLBACK Worker(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr from;
+    PRFileDesc *fd = NULL;
+    CSWorker_t *worker = (CSWorker_t*)arg;
+    CSServer_t *server = worker->server;
+    CSPool_t *pool = &server->pool;
+
+    PRThread *me = worker->thread = PR_GetCurrentThread();
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_NOTICE,
+        ("\t\tWorker(0x%p): started [%u]\n", me, pool->workers + 1));
+
+    PR_Lock(server->ml);
+    PR_APPEND_LINK(&worker->element, &server->list);
+    pool->workers += 1;  /* define our existance */
+
+    while (cs_run == server->state)
+    {
+        while (pool->accepting >= server->workers.accepting)
+        {
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_VERBOSE,
+                ("\t\tWorker(0x%p): waiting for accept slot[%d]\n",
+                me, pool->accepting));
+            rv = PR_WaitCondVar(pool->acceptComplete, PR_INTERVAL_NO_TIMEOUT);
+            if (Aborted(rv) || (cs_run != server->state))
+            {
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_NOTICE,
+                    ("\tWorker(0x%p): has been %s\n",
+                    me, (Aborted(rv) ? "interrupted" : "stopped")));
+                goto exit;
+            }
+        } 
+        pool->accepting += 1;  /* how many are really in accept */
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\t\tWorker(0x%p): calling accept\n", me));
+        fd = PR_Accept(server->listener, &from, PR_INTERVAL_NO_TIMEOUT);
+
+        PR_Lock(server->ml);        
+        pool->accepting -= 1;
+        PR_NotifyCondVar(pool->acceptComplete);
+
+        if ((NULL == fd) && Aborted(PR_FAILURE))
+        {
+            if (NULL != server->listener)
+            {
+                PR_Close(server->listener);
+                server->listener = NULL;
+            }
+            goto exit;
+        }
+
+        if (NULL != fd)
+        {
+            /*
+            ** Create another worker of the total number of workers is
+            ** less than the minimum specified or we have none left in
+            ** accept() AND we're not over the maximum.
+            ** This sort of presumes that the number allowed in accept
+            ** is at least as many as the minimum. Otherwise we'll keep
+            ** creating new threads and deleting them soon after.
+            */
+            PRBool another =
+                ((pool->workers < server->workers.minimum) ||
+                ((0 == pool->accepting)
+                    && (pool->workers < server->workers.maximum))) ?
+                    PR_TRUE : PR_FALSE;
+            pool->active += 1;
+            PR_Unlock(server->ml);
+
+            if (another) (void)CreateWorker(server, pool);
+
+            rv = ProcessRequest(fd, server);
+            if (PR_SUCCESS != rv)
+                TEST_LOG(
+                    cltsrv_log_file, TEST_LOG_ERROR,
+                    ("\t\tWorker(0x%p): server process ended abnormally\n", me));
+            (void)PR_Close(fd); fd = NULL;
+
+            PR_Lock(server->ml);
+            pool->active -= 1;
+        }
+    }
+
+exit:
+    PR_ClearInterrupt();    
+    PR_Unlock(server->ml);
+
+    if (NULL != fd)
+    {
+        (void)PR_Shutdown(fd, PR_SHUTDOWN_BOTH);
+        (void)PR_Close(fd);
+    }
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_NOTICE,
+        ("\t\tWorker(0x%p): exiting [%u]\n", PR_GetCurrentThread(), pool->workers));
+
+    PR_Lock(server->ml);
+    pool->workers -= 1;  /* undefine our existance */
+    PR_REMOVE_AND_INIT_LINK(&worker->element);
+    PR_NotifyCondVar(pool->exiting);
+    PR_Unlock(server->ml);
+
+    PR_DELETE(worker);  /* destruction of the "worker" object */
+
+}  /* Worker */
+
+static void PR_CALLBACK Server(void *arg)
+{
+    PRStatus rv;
+    PRNetAddr serverAddress;
+    CSServer_t *server = (CSServer_t*)arg;
+    PRThread *me = server->thread = PR_GetCurrentThread();
+    PRSocketOptionData sockOpt;
+
+    server->listener = PR_Socket(domain, SOCK_STREAM, protocol);
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    rv = PR_SetSocketOption(server->listener, &sockOpt);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    memset(&serverAddress, 0, sizeof(serverAddress));
+    rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress);
+
+    rv = PR_Bind(server->listener, &serverAddress);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    rv = PR_Listen(server->listener, server->backlog);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    server->started = PR_IntervalNow();
+    TimeOfDayMessage("Server started at", me);
+
+    PR_Lock(server->ml);
+    server->state = cs_run;
+    PR_NotifyCondVar(server->stateChange);
+    PR_Unlock(server->ml);
+
+    /*
+    ** Create the first worker (actually, a thread that accepts
+    ** connections and then processes the work load as needed).
+    ** From this point on, additional worker threads are created
+    ** as they are needed by existing worker threads.
+    */
+    rv = CreateWorker(server, &server->pool);
+    TEST_ASSERT(PR_SUCCESS == rv);
+
+    /*
+    ** From here on this thread is merely hanging around as the contact
+    ** point for the main test driver. It's just waiting for the driver
+    ** to declare the test complete.
+    */
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_VERBOSE,
+        ("\tServer(0x%p): waiting for state change\n", me));
+
+    PR_Lock(server->ml);
+    while ((cs_run == server->state) && !Aborted(rv))
+    {
+        rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+    }
+    PR_Unlock(server->ml);
+    PR_ClearInterrupt();
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_INFO,
+        ("\tServer(0x%p): shutting down workers\n", me));
+
+    /*
+    ** Get all the worker threads to exit. They know how to
+    ** clean up after themselves, so this is just a matter of
+    ** waiting for clorine in the pool to take effect. During
+    ** this stage we're ignoring interrupts.
+    */
+    server->workers.minimum = server->workers.maximum = 0;
+
+    PR_Lock(server->ml);
+    while (!PR_CLIST_IS_EMPTY(&server->list))
+    {
+        PRCList *head = PR_LIST_HEAD(&server->list);
+        CSWorker_t *worker = (CSWorker_t*)head;
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker));
+        rv = PR_Interrupt(worker->thread);
+        TEST_ASSERT(PR_SUCCESS == rv);
+        PR_REMOVE_AND_INIT_LINK(head);
+    }
+
+    while (server->pool.workers > 0)
+    {
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE,
+            ("\tServer(0x%p): waiting for %u workers to exit\n",
+            me, server->pool.workers));
+        (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+    server->state = cs_exit;
+    PR_NotifyCondVar(server->stateChange);
+    PR_Unlock(server->ml);
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("\tServer(0x%p): stopped after %u operations and %u bytes\n",
+        me, server->operations, server->bytesTransferred));
+
+    if (NULL != server->listener) PR_Close(server->listener);
+    server->stopped = PR_IntervalNow();
+
+}  /* Server */
+
+static void WaitForCompletion(PRIntn execution)
+{
+    while (execution > 0)
+    { 
+        PRIntn dally = (execution > 30) ? 30 : execution;
+        PR_Sleep(PR_SecondsToInterval(dally));
+        if (pthread_stats) PT_FPrintStats(debug_out, "\nPThread Statistics\n");
+        execution -= dally;
+    }
+}  /* WaitForCompletion */
+
+static void Help(void)
+{
+    PR_fprintf(debug_out, "cltsrv test program usage:\n");
+    PR_fprintf(debug_out, "\t-a <n>       threads allowed in accept        (5)\n");
+    PR_fprintf(debug_out, "\t-b <n>       backlock for listen              (5)\n");
+    PR_fprintf(debug_out, "\t-c <threads> number of clients to create      (1)\n");
+    PR_fprintf(debug_out, "\t-w <threads> minimal number of server threads (1)\n");
+    PR_fprintf(debug_out, "\t-W <threads> maximum number of server threads (1)\n");
+    PR_fprintf(debug_out, "\t-e <seconds> duration of the test in seconds  (10)\n");
+    PR_fprintf(debug_out, "\t-s <string>  dsn name of server               (localhost)\n");
+    PR_fprintf(debug_out, "\t-G           use GLOBAL threads               (LOCAL)\n");
+    PR_fprintf(debug_out, "\t-T <string>  thread provider ('n' | 'p' | 'u' | 'w')(n)\n");
+    PR_fprintf(debug_out, "\t-X           use XTP as transport             (TCP)\n");
+    PR_fprintf(debug_out, "\t-6           Use IPv6                         (IPv4)\n");
+    PR_fprintf(debug_out, "\t-v           verbosity (accumulative)         (0)\n");
+    PR_fprintf(debug_out, "\t-p           pthread statistics               (FALSE)\n");
+    PR_fprintf(debug_out, "\t-d           debug mode                       (FALSE)\n");
+    PR_fprintf(debug_out, "\t-h           this message\n");
+}  /* Help */
+
+static Verbosity IncrementVerbosity(void)
+{
+    PRIntn verboge = (PRIntn)verbosity + 1;
+    return (Verbosity)verboge;
+}  /* IncrementVerbosity */
+
+PRIntn main(PRIntn argc, char** argv)
+{
+    PRUintn index;
+    PRBool boolean;
+    CSClient_t *client;
+    PRStatus rv, joinStatus;
+    CSServer_t *server = NULL;
+	char *thread_type;
+
+    PRUintn backlog = DEFAULT_BACKLOG;
+    PRUintn clients = DEFAULT_CLIENTS;
+    const char *serverName = DEFAULT_SERVER;
+    PRBool serverIsLocal = PR_TRUE;
+    PRUintn accepting = ALLOWED_IN_ACCEPT;
+    PRUintn workersMin = DEFAULT_WORKERS_MIN;
+    PRUintn workersMax = DEFAULT_WORKERS_MAX;
+    PRIntn execution = DEFAULT_EXECUTION_TIME;
+
+    /*
+     * -G           use global threads
+     * -a <n>       threads allowed in accept
+     * -b <n>       backlock for listen
+     * -c <threads> number of clients to create
+     * -w <threads> minimal number of server threads
+     * -W <threads> maximum number of server threads
+     * -e <seconds> duration of the test in seconds
+     * -s <string>  dsn name of server (implies no server here)
+     * -v           verbosity
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:w:W:e:s:T:vdhp");
+
+#if defined(WIN32)
+	thread_provider = thread_win32;
+#elif defined(_PR_PTHREADS)
+	thread_provider = thread_pthread;
+#elif defined(SOLARIS) && defined(_PR_GLOBAL_THREADS_ONLY)
+	thread_provider = thread_uithread;
+#elif defined(IRIX)
+	thread_provider = thread_sproc;
+#else
+    thread_provider = thread_nspr;
+#endif
+
+    debug_out = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'X':  /* use XTP as transport */
+            protocol = 36;
+            break;
+		case '6':  /* Use IPv6 */
+            domain = PR_AF_INET6;
+            break;
+        case 'a':  /* the value for accepting */
+            accepting = atoi(opt->value);
+            break;
+        case 'b':  /* the value for backlock */
+            backlog = atoi(opt->value);
+            break;
+        case 'T':  /* the thread provider */
+            if ('n' == *opt->value) thread_provider = thread_nspr;
+            else if ('p' == *opt->value) thread_provider = thread_pthread;
+            else if ('u' == *opt->value) thread_provider = thread_uithread;
+            else if ('w' == *opt->value) thread_provider = thread_win32;
+            else {Help(); return 2; }
+            break;
+        case 'c':  /* number of client threads */
+            clients = atoi(opt->value);
+            break;
+        case 'w':  /* minimum server worker threads */
+            workersMin = atoi(opt->value);
+            break;
+        case 'W':  /* maximum server worker threads */
+            workersMax = atoi(opt->value);
+            break;
+        case 'e':  /* program execution time in seconds */
+            execution = atoi(opt->value);
+            break;
+        case 's':  /* server's address */
+            serverName = opt->value;
+            break;
+        case 'v':  /* verbosity */
+            verbosity = IncrementVerbosity();
+            break;
+        case 'd':  /* debug mode */
+            debug_mode = PR_TRUE;
+            break;
+        case 'p':  /* pthread mode */
+            pthread_stats = PR_TRUE;
+            break;
+        case 'h':
+        default:
+            Help();
+            return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (0 != PL_strcmp(serverName, DEFAULT_SERVER)) serverIsLocal = PR_FALSE;
+    if (0 == execution) execution = DEFAULT_EXECUTION_TIME;
+    if (0 == workersMax) workersMax = DEFAULT_WORKERS_MAX;
+    if (0 == workersMin) workersMin = DEFAULT_WORKERS_MIN;
+    if (0 == accepting) accepting = ALLOWED_IN_ACCEPT;
+    if (0 == backlog) backlog = DEFAULT_BACKLOG;
+
+    if (workersMin > accepting) accepting = workersMin;
+
+    PR_STDIO_INIT();
+    TimeOfDayMessage("Client/Server started at", PR_GetCurrentThread());
+
+    cltsrv_log_file = PR_NewLogModule("cltsrv_log");
+    MY_ASSERT(NULL != cltsrv_log_file);
+    boolean = PR_SetLogFile("cltsrv.log");
+    MY_ASSERT(boolean);
+
+#ifdef XP_MAC
+    debug_mode = PR_TRUE;
+#endif
+
+    if (serverIsLocal)
+    {
+        /* Establish the server */
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_INFO,
+            ("main(0x%p): starting server\n", PR_GetCurrentThread()));
+
+        server = PR_NEWZAP(CSServer_t);
+        PR_INIT_CLIST(&server->list);
+        server->state = cs_init;
+        server->ml = PR_NewLock();
+        server->backlog = backlog;
+        server->port = DEFAULT_PORT;
+        server->workers.minimum = workersMin;
+        server->workers.maximum = workersMax;
+        server->workers.accepting = accepting;
+        server->stateChange = PR_NewCondVar(server->ml);
+        server->pool.exiting = PR_NewCondVar(server->ml);
+        server->pool.acceptComplete = PR_NewCondVar(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE,
+            ("main(0x%p): creating server thread\n", PR_GetCurrentThread()));
+
+        rv = NewThread(
+            Server, server, PR_PRIORITY_HIGH, PR_JOINABLE_THREAD);
+        TEST_ASSERT(PR_SUCCESS == rv);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): waiting for server init\n", PR_GetCurrentThread()));
+
+        PR_Lock(server->ml);
+        while (server->state == cs_init)
+            PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): server init complete (port #%d)\n",
+            PR_GetCurrentThread(), server->port));
+    }
+
+    if (clients != 0)
+    {
+        /* Create all of the clients */
+        PRHostEnt host;
+        char buffer[BUFFER_SIZE];
+        client = (CSClient_t*)PR_CALLOC(clients * sizeof(CSClient_t));
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_VERBOSE,
+            ("main(0x%p): creating %d client threads\n",
+            PR_GetCurrentThread(), clients));
+        
+        if (!serverIsLocal)
+        {
+            rv = PR_GetHostByName(serverName, buffer, BUFFER_SIZE, &host);
+            if (PR_SUCCESS != rv)
+            {
+                PL_FPrintError(PR_STDERR, "PR_GetHostByName");
+                return 2;
+            }
+        }
+
+        for (index = 0; index < clients; ++index)
+        {
+            client[index].state = cs_init;
+            client[index].ml = PR_NewLock();
+            if (serverIsLocal)
+            {
+                (void)PR_InitializeNetAddr(
+                    PR_IpAddrLoopback, DEFAULT_PORT,
+                    &client[index].serverAddress);
+            }
+            else
+            {
+                (void)PR_EnumerateHostEnt(
+                    0, &host, DEFAULT_PORT, &client[index].serverAddress);
+            }
+            client[index].stateChange = PR_NewCondVar(client[index].ml);
+            TEST_LOG(
+                cltsrv_log_file, TEST_LOG_INFO,
+                ("main(0x%p): creating client threads\n", PR_GetCurrentThread()));
+            rv = NewThread(
+                Client, &client[index], PR_PRIORITY_NORMAL, PR_JOINABLE_THREAD);
+            TEST_ASSERT(PR_SUCCESS == rv);
+            PR_Lock(client[index].ml);
+            while (cs_init == client[index].state)
+                PR_WaitCondVar(client[index].stateChange, PR_INTERVAL_NO_TIMEOUT);
+            PR_Unlock(client[index].ml);
+        }
+    }
+
+    /* Then just let them go at it for a bit */
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS,
+        ("main(0x%p): waiting for execution interval (%d seconds)\n",
+        PR_GetCurrentThread(), execution));
+
+    WaitForCompletion(execution);
+
+    TimeOfDayMessage("Shutting down", PR_GetCurrentThread());
+
+    if (clients != 0)
+    {
+        for (index = 0; index < clients; ++index)
+        {
+            TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, 
+                ("main(0x%p): notifying client(0x%p) to stop\n",
+                PR_GetCurrentThread(), client[index].thread));
+
+            PR_Lock(client[index].ml);
+            if (cs_run == client[index].state)
+            {
+                client[index].state = cs_stop;
+                PR_Interrupt(client[index].thread);
+                while (cs_stop == client[index].state)
+                    PR_WaitCondVar(
+                        client[index].stateChange, PR_INTERVAL_NO_TIMEOUT);
+            }
+            PR_Unlock(client[index].ml);
+
+            TEST_LOG(cltsrv_log_file, TEST_LOG_VERBOSE, 
+                ("main(0x%p): joining client(0x%p)\n",
+                PR_GetCurrentThread(), client[index].thread));
+
+		    joinStatus = JoinThread(client[index].thread);
+		    TEST_ASSERT(PR_SUCCESS == joinStatus);
+            PR_DestroyCondVar(client[index].stateChange);
+            PR_DestroyLock(client[index].ml);
+        }
+        PR_DELETE(client);
+    }
+
+    if (NULL != server)
+    {
+        /* All clients joined - retrieve the server */
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE, 
+            ("main(0x%p): notifying server(0x%p) to stop\n",
+            PR_GetCurrentThread(), server->thread));
+
+        PR_Lock(server->ml);
+        server->state = cs_stop;
+        PR_Interrupt(server->thread);
+        while (cs_exit != server->state)
+            PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
+        PR_Unlock(server->ml);
+
+        TEST_LOG(
+            cltsrv_log_file, TEST_LOG_NOTICE, 
+            ("main(0x%p): joining server(0x%p)\n",
+            PR_GetCurrentThread(), server->thread));
+        joinStatus = JoinThread(server->thread);
+        TEST_ASSERT(PR_SUCCESS == joinStatus);
+
+        PR_DestroyCondVar(server->stateChange);
+        PR_DestroyCondVar(server->pool.exiting);
+        PR_DestroyCondVar(server->pool.acceptComplete);
+        PR_DestroyLock(server->ml);
+        PR_DELETE(server);
+    }
+
+    TEST_LOG(
+        cltsrv_log_file, TEST_LOG_ALWAYS, 
+        ("main(0x%p): test complete\n", PR_GetCurrentThread()));
+
+	if (thread_provider == thread_win32)
+		thread_type = "\nWin32 Thread Statistics\n";
+	else if (thread_provider == thread_pthread)
+		thread_type = "\npthread Statistics\n";
+	else if (thread_provider == thread_uithread)
+		thread_type = "\nUnix International (UI) Thread Statistics\n";
+	else if (thread_provider == thread_sproc)
+		thread_type = "\nsproc Statistics\n";
+    else {
+		PR_ASSERT(thread_provider == thread_nspr);
+		thread_type = "\nPRThread Statistics\nn";
+	}
+
+    PT_FPrintStats(debug_out, thread_type);
+
+    TimeOfDayMessage("Test exiting at", PR_GetCurrentThread());
+    PR_Cleanup();
+    return 0;
+}  /* main */
+
+/* cltsrv.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/prpoll.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/prpoll.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,378 @@
+/* -*- 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 ***** */
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#ifdef XP_OS2_VACPP
+#include <io.h>      /* for close() */
+#endif
+
+#ifdef XP_UNIX
+#include <unistd.h>  /* for close() */
+#endif
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prnetdb.h"
+
+#ifndef XP_MAC
+#include "private/pprio.h"
+#else
+#include "pprio.h"
+#endif
+
+#define CLIENT_LOOPS	5
+#define BUF_SIZE		128
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static void
+clientThreadFunc(void *arg)
+{
+    PRUint16 port = (PRUint16) arg;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    char buf[BUF_SIZE];
+    int i;
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons(port);
+    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    PR_snprintf(buf, sizeof(buf), "%hu", port);
+
+    for (i = 0; i < 5; i++) {
+	sock = PR_NewTCPSocket();
+        PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+
+	PR_Write(sock, buf, sizeof(buf));
+	PR_Close(sock);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRFileDesc *badFD;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    char buf[BUF_SIZE];
+    PRThread *clientThread;
+    PRPollDesc pds0[10], pds1[10], *pds, *other_pds;
+    PRIntn npds;
+    PRInt32 retVal;
+    PRInt32 rv;
+    PROsfd sd;
+    struct sockaddr_in saddr;
+    PRIntn saddr_len;
+    PRUint16 listenPort3;
+    PRFileDesc *socket_poll_fd;
+    PRIntn i, j;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    printf("This program tests PR_Poll with sockets.\n");
+    printf("Timeout, error reporting, and normal operation are tested.\n\n");
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	exit(1);
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	exit(1);
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	exit(1);
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	exit(1);
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	exit(1);
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	exit(1);
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	exit(1);
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	exit(1);
+    }
+    /* Set up the poll descriptor array */
+    pds = pds0;
+    other_pds = pds1;
+    memset(pds, 0, sizeof(pds));
+	npds = 0;
+    pds[npds].fd = listenSock1;
+    pds[npds].in_flags = PR_POLL_READ;
+	npds++;
+    pds[npds].fd = listenSock2;
+    pds[npds].in_flags = PR_POLL_READ;
+	npds++;
+
+	sd = socket(AF_INET, SOCK_STREAM, 0);
+	PR_ASSERT(sd >= 0);
+	memset((char *) &saddr, 0, sizeof(saddr));
+	saddr.sin_family = AF_INET;
+	saddr.sin_addr.s_addr = htonl(INADDR_ANY);
+	saddr.sin_port = htons(0);
+
+	rv = bind(sd, (struct sockaddr *)&saddr, sizeof(saddr));
+	PR_ASSERT(rv == 0);
+	saddr_len = sizeof(saddr);
+	rv = getsockname(sd, (struct sockaddr *) &saddr, &saddr_len);
+	PR_ASSERT(rv == 0);
+    listenPort3 = ntohs(saddr.sin_port);
+
+	rv = listen(sd, 5);
+	PR_ASSERT(rv == 0);
+    pds[npds].fd = socket_poll_fd = PR_CreateSocketPollFd(sd);
+	PR_ASSERT(pds[npds].fd);
+    pds[npds].in_flags = PR_POLL_READ;
+    npds++;
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu, %hu and %hu\n\n",
+	    listenPort1, listenPort2, listenPort3);
+    printf("%s", buf);
+
+    /* Testing timeout */
+    printf("PR_Poll should time out in 5 seconds\n");
+    retVal = PR_Poll(pds, npds, PR_SecondsToInterval(5));
+    if (retVal != 0) {
+	PR_snprintf(buf, sizeof(buf),
+		"PR_Poll should time out and return 0, but it returns %ld\n",
+		retVal);
+	fprintf(stderr, "%s", buf);
+	exit(1);
+    }
+    printf("PR_Poll timed out.  Test passed.\n\n");
+
+    /* Testing bad fd */
+    printf("PR_Poll should detect a bad file descriptor\n");
+    if ((badFD = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a TCP socket\n");
+	exit(1);
+    }
+
+    pds[npds].fd = badFD;
+    pds[npds].in_flags = PR_POLL_READ;
+    npds++;
+    PR_Close(badFD);  /* make the fd bad */
+#if 0
+    retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT);
+    if (retVal != 1 || (unsigned short) pds[2].out_flags != PR_POLL_NVAL) {
+	fprintf(stderr, "Failed to detect the bad fd: "
+		"PR_Poll returns %d, out_flags is 0x%hx\n",
+		retVal, pds[npds - 1].out_flags);
+	exit(1);
+    }
+    printf("PR_Poll detected the bad fd.  Test passed.\n\n");
+#endif
+    npds--;
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort1,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort2,
+	    PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort3,
+	    PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+
+    printf("Three client threads are created.  Each of them will\n");
+    printf("send data to one of the three ports the server is listening on.\n");
+    printf("The data they send is the port number.  Each of them send\n");
+    printf("the data five times, so you should see ten lines below,\n");
+    printf("interleaved in an arbitrary order.\n");
+
+    /* 30 events total */
+    i = 0;
+    while (i < 30) {
+		PRPollDesc *tmp;
+		int nextIndex;
+		int nEvents = 0;
+
+		retVal = PR_Poll(pds, npds, PR_INTERVAL_NO_TIMEOUT);
+		PR_ASSERT(retVal != 0);  /* no timeout */
+		if (retVal == -1) {
+			fprintf(stderr, "PR_Poll failed\n");
+			exit(1);
+		}
+
+		nextIndex = 3;
+		/* the three listening sockets */
+		for (j = 0; j < 3; j++) {
+			other_pds[j] = pds[j];
+			PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0
+				&& (pds[j].out_flags & PR_POLL_EXCEPT) == 0);
+			if (pds[j].out_flags & PR_POLL_READ) {
+				PRFileDesc *sock;
+
+				nEvents++;
+				if (j == 2) {
+					PROsfd newsd;
+					newsd = accept(PR_FileDesc2NativeHandle(pds[j].fd), NULL, 0);
+					if (newsd == -1) {
+						fprintf(stderr, "accept() failed\n");
+						exit(1);
+					}
+					other_pds[nextIndex].fd  = PR_CreateSocketPollFd(newsd);
+					PR_ASSERT(other_pds[nextIndex].fd);
+					other_pds[nextIndex].in_flags = PR_POLL_READ;
+				} else {
+					sock = PR_Accept(pds[j].fd, NULL, PR_INTERVAL_NO_TIMEOUT);
+					if (sock == NULL) {
+						fprintf(stderr, "PR_Accept() failed\n");
+						exit(1);
+					}
+					other_pds[nextIndex].fd = sock;
+					other_pds[nextIndex].in_flags = PR_POLL_READ;
+				}
+				nextIndex++;
+			} else if (pds[j].out_flags & PR_POLL_ERR) {
+				fprintf(stderr, "PR_Poll() indicates that an fd has error\n");
+				exit(1);
+			} else if (pds[j].out_flags & PR_POLL_NVAL) {
+				fprintf(stderr, "PR_Poll() indicates that fd %d is invalid\n",
+					PR_FileDesc2NativeHandle(pds[j].fd));
+				exit(1);
+			}
+		}
+
+		for (j = 3; j < npds; j++) {
+			PR_ASSERT((pds[j].out_flags & PR_POLL_WRITE) == 0
+				&& (pds[j].out_flags & PR_POLL_EXCEPT) == 0);
+			if (pds[j].out_flags & PR_POLL_READ) {
+				PRInt32 nBytes;
+
+				nEvents++;
+				/* XXX: This call is a hack and should be fixed */
+				if (PR_GetDescType(pds[j].fd) == (PRDescType) 0) {
+					nBytes = recv(PR_FileDesc2NativeHandle(pds[j].fd), buf,
+										sizeof(buf), 0);
+					if (nBytes == -1) {
+						fprintf(stderr, "recv() failed\n");
+						exit(1);
+					}
+					printf("Server read %d bytes from native fd %d\n",nBytes,
+										PR_FileDesc2NativeHandle(pds[j].fd));
+#ifdef WIN32
+					closesocket((SOCKET)PR_FileDesc2NativeHandle(pds[j].fd));
+#else
+					close(PR_FileDesc2NativeHandle(pds[j].fd));
+#endif
+					PR_DestroySocketPollFd(pds[j].fd);
+				} else {
+					nBytes = PR_Read(pds[j].fd, buf, sizeof(buf));
+					if (nBytes == -1) {
+						fprintf(stderr, "PR_Read() failed\n");
+						exit(1);
+					}
+					PR_Close(pds[j].fd);
+				}
+				/* Just to be safe */
+				buf[BUF_SIZE - 1] = '\0';
+				printf("The server received \"%s\" from a client\n", buf);
+			} else if (pds[j].out_flags & PR_POLL_ERR) {
+				fprintf(stderr, "PR_Poll() indicates that an fd has error\n");
+				exit(1);
+			} else if (pds[j].out_flags & PR_POLL_NVAL) {
+				fprintf(stderr, "PR_Poll() indicates that an fd is invalid\n");
+				exit(1);
+			} else {
+				other_pds[nextIndex] = pds[j];
+				nextIndex++;
+			}
+		}
+
+		PR_ASSERT(retVal == nEvents);
+		/* swap */
+		tmp = pds;
+		pds = other_pds;
+		other_pds = tmp;
+		npds = nextIndex;
+		i += nEvents;
+    }
+    PR_DestroySocketPollFd(socket_poll_fd);
+
+    printf("All tests finished\n");
+    PR_Cleanup();
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/prpollml.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/prpollml.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,162 @@
+/* -*- 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) 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 ***** */
+
+/*
+ * This test exercises the code that allocates and frees the syspoll_list
+ * array of PRThread in the pthreads version.  This test is intended to be
+ * run under Purify to verify that there is no memory leak.
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define POLL_DESC_COUNT 256  /* This should be greater than the
+                              * STACK_POLL_DESC_COUNT macro in
+                              * ptio.c to cause syspoll_list to
+                              * be created. */
+
+static PRPollDesc pd[POLL_DESC_COUNT];
+
+static void Test(void)
+{
+    int i;
+    PRInt32 rv;
+    PRIntervalTime timeout;
+
+    timeout = PR_MillisecondsToInterval(10);
+    /* cause syspoll_list to grow */
+    for (i = 1; i <= POLL_DESC_COUNT; i++) {
+        rv = PR_Poll(pd, i, timeout);
+        if (rv != 0) {
+            fprintf(stderr,
+                "PR_Poll should time out but returns %d (%d, %d)\n",
+                rv, PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+    }
+    /* syspoll_list should be large enough for all these */
+    for (i = POLL_DESC_COUNT; i >= 1; i--) {
+        rv = PR_Poll(pd, i, timeout);
+        if (rv != 0) {
+            fprintf(stderr, "PR_Poll should time out but returns %d\n", rv);
+            exit(1);
+        }
+    }
+}
+
+static void ThreadFunc(void *arg)
+{
+    Test();
+}
+
+int main(int argc, char **argv)
+{
+    int i;
+    PRThread *thread;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+
+    memset(&addr, 0, sizeof(addr));
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons(0);
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    for (i = 0; i < POLL_DESC_COUNT; i++) {
+        sock = PR_NewTCPSocket();
+        if (sock == NULL) {
+            fprintf(stderr, "PR_NewTCPSocket failed\n");
+            exit(1);
+        }
+        if (PR_Bind(sock, &addr) == PR_FAILURE) {
+            fprintf(stderr, "PR_Bind failed\n");
+            exit(1);
+        }
+        if (PR_Listen(sock, 5) == PR_FAILURE) {
+            fprintf(stderr, "PR_Listen failed\n");
+            exit(1);
+        }
+    
+        pd[i].fd = sock;
+        pd[i].in_flags = PR_POLL_READ;
+    }
+
+    /* first run the test on the primordial thread */
+    Test();
+
+    /* then run the test on all three kinds of threads */
+    thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL,
+            PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == thread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(thread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == thread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(thread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    thread = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_BOUND_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == thread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(thread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    for (i = 0; i < POLL_DESC_COUNT; i++) {
+        if (PR_Close(pd[i].fd) == PR_FAILURE) {
+            fprintf(stderr, "PR_Close failed\n");
+            exit(1);
+        }
+    }
+    PR_Cleanup();
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/prselect.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/prselect.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,372 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**  1997 - Netscape Communications Corporation
+**
+** Name: prselect_err.c
+**
+** Description: tests PR_Select with sockets Error condition functions.
+**
+** Modification History:
+** 14-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. 
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+#include "prttools.h"
+
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prerror.h"
+#include "prnetdb.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Test_Result
+** DESCRIPTION: Used in conjunction with the regress tool, prints out the
+**				status of the test case.
+** INPUTS:      PASS/FAIL
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:   Determine what the status is and print accordingly.
+**      
+***********************************************************************/
+
+
+static Test_Result (int result)
+{
+	if (result == PASS)
+		printf ("PASS\n");
+	else
+		printf ("FAIL\n");
+}
+
+static void
+clientThreadFunc(void *arg)
+{
+    PRUint16 port = (PRUint16) arg;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    char buf[128];
+    int i;
+
+    addr.inet.family = AF_INET;
+    addr.inet.port = PR_htons(port);
+    addr.inet.ip = PR_htonl(INADDR_LOOPBACK);
+    PR_snprintf(buf, sizeof(buf), "%hu", port);
+
+    for (i = 0; i < 5; i++) {
+	sock = PR_NewTCPSocket();
+        PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+	PR_Write(sock, buf, sizeof(buf));
+	PR_Close(sock);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRFileDesc *badFD;
+    PRFileDesc *fds0[10], *fds1[10], **fds, **other_fds;
+    PRIntn nfds;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    PR_fd_set readFdSet;
+    char buf[128];
+    PRThread *clientThread;
+    PRInt32 retVal;
+    PRIntn i, j;
+
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Select with sockets.  Timeout, error\n");
+		printf("reporting, and normal operation are tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	if (!debug_mode) Test_Result(FAIL);
+	exit(1);
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    printf("%s", buf);
+
+    /* Set up the fd set */
+    PR_FD_ZERO(&readFdSet);
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+
+    /* Testing timeout */
+    if (debug_mode) printf("PR_Select should time out in 5 seconds\n");
+    retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+	    PR_SecondsToInterval(5));
+    if (retVal != 0) {
+	PR_snprintf(buf, sizeof(buf),
+		"PR_Select should time out and return 0, but it returns %ld\n",
+		retVal);
+	fprintf(stderr, "%s", buf);
+	if (retVal == -1) {
+	    fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(),
+		    PR_GetOSError());
+			if (!debug_mode) Test_Result(FAIL);
+	}
+	exit(1);
+    }
+    if (debug_mode) printf("PR_Select timed out.  Test passed.\n\n");
+	else Test_Result(PASS);
+
+    /* Testing bad fd */
+    printf("PR_Select should detect a bad file descriptor\n");
+    if ((badFD = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a TCP socket\n");
+	exit(1);
+    }
+
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+    PR_FD_SET(badFD, &readFdSet);
+    PR_Close(badFD);  /* make the fd bad */
+    retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+	    PR_INTERVAL_NO_TIMEOUT);
+    if (retVal != -1 || PR_GetError() != PR_BAD_DESCRIPTOR_ERROR) {
+	fprintf(stderr, "Failed to detect the bad fd: "
+		"PR_Select returns %d\n", retVal);
+	if (retVal == -1) {
+	    fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(),
+		    PR_GetOSError());
+	}
+	exit(1);
+    }
+    printf("PR_Select detected a bad fd.  Test passed.\n\n");
+    PR_FD_CLR(badFD, &readFdSet);
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort1,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort2,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	exit(1);
+    }
+
+    printf("Two client threads are created.  Each of them will\n");
+    printf("send data to one of the two ports the server is listening on.\n");
+    printf("The data they send is the port number.  Each of them send\n");
+    printf("the data five times, so you should see ten lines below,\n");
+    printf("interleaved in an arbitrary order.\n");
+
+    /* set up the fd array */
+    fds = fds0;
+    other_fds = fds1;
+    fds[0] = listenSock1;
+    fds[1] = listenSock2;
+    nfds = 2;
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+
+    /* 20 events total */
+    i = 0;
+    while (i < 20) {
+	PRFileDesc **tmp;
+	int nextIndex;
+	int nEvents = 0;
+
+	retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+		PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(retVal != 0);  /* no timeout */
+	if (retVal == -1) {
+	    fprintf(stderr, "PR_Select failed (%d, %d)\n", PR_GetError(),
+		    PR_GetOSError());
+	    exit(1);
+	}
+
+	nextIndex = 2;
+	/* the two listening sockets */
+	for (j = 0; j < 2; j++) {
+	    other_fds[j] = fds[j];
+	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
+		PRFileDesc *sock;
+
+		nEvents++;
+		sock = PR_Accept(fds[j], NULL, PR_INTERVAL_NO_TIMEOUT);
+		if (sock == NULL) {
+		    fprintf(stderr, "PR_Accept() failed\n");
+		    exit(1);
+		}
+		other_fds[nextIndex] = sock;
+		PR_FD_SET(sock, &readFdSet);
+		nextIndex++;
+	    }
+	    PR_FD_SET(fds[j], &readFdSet);
+	}
+
+	for (j = 2; j < nfds; j++) {
+	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
+		PRInt32 nBytes;
+
+		PR_FD_CLR(fds[j], &readFdSet);
+		nEvents++;
+		nBytes = PR_Read(fds[j], buf, sizeof(buf));
+		if (nBytes == -1) {
+		    fprintf(stderr, "PR_Read() failed\n");
+		    exit(1);
+		}
+		/* Just to be safe */
+		buf[127] = '\0';
+		PR_Close(fds[j]);
+		printf("The server received \"%s\" from a client\n", buf);
+	    } else {
+		PR_FD_SET(fds[j], &readFdSet);
+		other_fds[nextIndex] = fds[j];
+		nextIndex++;
+	    }
+	}
+
+	PR_ASSERT(retVal == nEvents);
+	/* swap */
+	tmp = fds;
+	fds = other_fds;
+	other_fds = tmp;
+	nfds = nextIndex;
+	i += nEvents;
+    }
+
+    printf("All tests finished\n");
+    PR_Cleanup();
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/prttools.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/prttools.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,43 @@
+/* -*- 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 ***** */
+
+/* Used in Regress Tool */
+#define NOSTATUS 2
+#define PASS 1
+#define FAIL 0
+
+PRIntn debug_mode=0;

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/randseed.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/randseed.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,163 @@
+/* -*- 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: rngseed.c
+** Description: 
+** Test NSPR's Random Number Seed generator
+**
+** Initial test: Just make sure it outputs some data.
+** 
+** ... more? ... check some iterations to ensure it is random (no dupes)
+** ... more? ... histogram distribution of random numbers
+*/
+
+#include "plgetopt.h"
+#include "nspr.h" 
+#include "prrng.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+** Test harness infrastructure
+*/
+PRLogModuleInfo *lm;
+PRLogModuleLevel msgLevel = PR_LOG_NONE;
+PRIntn  debug = 0;
+PRUint32  failed_already = 0;
+/* end Test harness infrastructure */
+
+PRIntn  optRandCount = 30;
+char    buf[40];
+PRSize  bufSize = sizeof(buf);
+PRSize  rSize;
+PRIntn  i;
+
+/*
+** Emit help text for this test
+*/
+static void Help( void )
+{
+    printf("Template: Help(): display your help message(s) here");
+    exit(1);
+} /* end Help() */
+
+static void PrintRand( void *buf, PRIntn size )
+{
+    PRUint32 *rp = buf;
+    PRIntn   i;
+
+    printf("%4.4d--\n", size );
+    while (size > 0 ) {
+        switch( size )  {
+            case 1 :
+                printf("%2.2X\n", *(rp++) );
+                size -= 4;    
+                break;
+            case 2 :
+                printf("%4.4X\n", *(rp++) );
+                size -= 4;    
+                break;
+            case 3 :
+                printf("%6.6X\n", *(rp++) );
+                size -= 4;    
+                break;
+            default:
+                while ( size >= 4) {
+                    PRIntn i = 3;
+                    do {
+                        printf("%8.8X ", *(rp++) );
+                        size -= 4;    
+                    } while( i-- );
+                    i = 3;
+                    printf("\n");
+                }
+                break;
+        } /* end switch() */
+    } /* end while() */
+} /* end PrintRand() */
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    {
+        /*
+        ** Get command line options
+        */
+        PLOptStatus os;
+        PLOptState *opt = PL_CreateOptState(argc, argv, "hdv");
+
+	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+		    if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug */
+                debug = 1;
+			    msgLevel = PR_LOG_ERROR;
+                break;
+            case 'v':  /* verbose mode */
+			    msgLevel = PR_LOG_DEBUG;
+                break;
+            case 'h':  /* help message */
+			    Help();
+                break;
+             default:
+                break;
+            }
+        }
+	    PL_DestroyOptState(opt);
+    }
+
+    lm = PR_NewLogModule("Test");       /* Initialize logging */
+    for ( i = 0; i < optRandCount ; i++ ) {
+        memset( buf, 0, bufSize );
+        rSize = PR_GetRandomNoise( buf, bufSize );
+        if (!rSize) {
+            fprintf(stderr, "Not implemented\n" );
+            failed_already = PR_TRUE;
+            break;
+        }
+        if (debug) PrintRand( buf, rSize );
+    }
+
+    if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS");
+    return( (failed_already == PR_TRUE )? 1 : 0 );
+}  /* main() */
+/* end template.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/ranfile.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/ranfile.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,433 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**
+** Contact:     AOF<freier at netscape.com>
+**
+** Name: ranfile.c
+**
+** Description: Test to hammer on various components of NSPR
+** Modification History:
+** 20-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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prthread.h"
+#include "prlock.h"
+#include "prcvar.h"
+#include "prmem.h"
+#include "prinrval.h"
+#include "prio.h"
+
+#include <string.h>
+#include <stdio.h>
+
+static PRIntn debug_mode = 0;
+static PRIntn failed_already=0;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+typedef enum {sg_go, sg_stop, sg_done} Action;
+typedef enum {sg_okay, sg_open, sg_close, sg_delete, sg_write, sg_seek} Problem;
+
+typedef struct Hammer_s {
+    PRLock *ml;
+    PRCondVar *cv;
+    PRUint32 id;
+    PRUint32 limit;
+    PRUint32 writes;
+    PRThread *thread;
+    PRIntervalTime timein;
+    Action action;
+    Problem problem;
+} Hammer_t;
+
+#define DEFAULT_LIMIT		10
+#define DEFAULT_THREADS		2
+#define DEFAULT_LOOPS		1
+
+static PRInt32 pageSize = 1024;
+static const char* baseName = "./";
+static const char *programName = "Random File";
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Random
+** DESCRIPTION:
+**   Generate a pseudo-random number
+** INPUTS:      None
+** OUTPUTS:     None
+** RETURN:      A pseudo-random unsigned number, 32-bits wide
+** SIDE EFFECTS:
+**      Updates random seed (a static)
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:
+**      Uses the current interval timer value, promoted to a 64 bit
+**      float as a multiplier for a static residue (which begins
+**      as an uninitialized variable). The result is bits [16..48)
+**      of the product. Seed is then updated with the return value
+**      promoted to a float-64.
+***********************************************************************/
+static PRUint32 Random(void)
+{
+    PRUint32 rv;
+    PRUint64 shift;
+    static PRFloat64 seed = 0x58a9382;  /* Just make sure it isn't 0! */
+    PRFloat64 random = seed * (PRFloat64)PR_IntervalNow();
+    LL_USHR(shift, *((PRUint64*)&random), 16);
+    LL_L2UI(rv, shift);
+    seed = (PRFloat64)rv;
+    return rv;
+}  /* Random */
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Thread
+** DESCRIPTION:
+**   Hammer on the file I/O system
+** INPUTS:      A pointer to the thread's private data
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      Creates, accesses and deletes a file
+** RESTRICTIONS:
+**      (Currently) must have file create permission in "/usr/tmp".
+** MEMORY:      NA
+** ALGORITHM:
+**      This function is a root of a thread
+**      1) Creates a (hopefully) unique file in /usr/tmp/
+**      2) Writes a zero to a random number of sequential pages
+**      3) Closes the file
+**      4) Reopens the file
+**      5) Seeks to a random page within the file
+**      6) Writes a one byte on that page
+**      7) Repeat steps [5..6] for each page in the file
+**      8) Close and delete the file
+**      9) Repeat steps [1..8] until told to stop
+**     10) Notify complete and return
+***********************************************************************/
+static void PR_CALLBACK Thread(void *arg)
+{
+    PRUint32 index;
+    char filename[30];
+    const char zero = 0;
+    PRFileDesc *file = NULL;
+    PRStatus rv = PR_SUCCESS;
+    Hammer_t *cd = (Hammer_t*)arg;
+
+    (void)sprintf(filename, "%ssg%04ld.dat", baseName, cd->id);
+
+    if (debug_mode) printf("Starting work on %s\n", filename);
+
+    while (PR_TRUE)
+    {
+        PRUint32 bytes;
+        PRUint32 minor = (Random() % cd->limit) + 1;
+        PRUint32 random = (Random() % cd->limit) + 1;
+        PRUint32 pages = (Random() % cd->limit) + 10;
+        while (minor-- > 0)
+        {
+            cd->problem = sg_okay;
+            if (cd->action != sg_go) goto finished;
+            cd->problem = sg_open;
+            file = PR_Open(filename, PR_RDWR|PR_CREATE_FILE, 0666);
+            if (file == NULL) goto finished;
+            for (index = 0; index < pages; index++)
+            {
+                cd->problem = sg_okay;
+                if (cd->action != sg_go) goto close;
+                cd->problem = sg_seek;
+                bytes = PR_Seek(file, pageSize * index, PR_SEEK_SET);
+                if (bytes != pageSize * index) goto close;
+                cd->problem = sg_write;
+                bytes = PR_Write(file, &zero, sizeof(zero));
+                if (bytes <= 0) goto close;
+                cd->writes += 1;
+            }
+            cd->problem = sg_close;
+            rv = PR_Close(file);
+            if (rv != PR_SUCCESS) goto purge;
+
+            cd->problem = sg_okay;
+            if (cd->action != sg_go) goto purge;
+
+            cd->problem = sg_open;
+            file = PR_Open(filename, PR_RDWR, 0666);
+            for (index = 0; index < pages; index++)
+            {
+                cd->problem = sg_okay;
+                if (cd->action != sg_go) goto close;
+                cd->problem = sg_seek;
+                bytes = PR_Seek(file, pageSize * index, PR_SEEK_SET);
+                if (bytes != pageSize * index) goto close;
+                cd->problem = sg_write;
+                bytes = PR_Write(file, &zero, sizeof(zero));
+                if (bytes <= 0) goto close;
+                cd->writes += 1;
+                random = (random + 511) % pages;
+            }
+            cd->problem = sg_close;
+            rv = PR_Close(file);
+            if (rv != PR_SUCCESS) goto purge;
+            cd->problem = sg_delete;
+            rv = PR_Delete(filename);
+            if (rv != PR_SUCCESS) goto finished;
+       }
+    }
+
+close:
+    (void)PR_Close(file);
+purge:
+    (void)PR_Delete(filename);
+finished:
+    PR_Lock(cd->ml);
+    cd->action = sg_done;
+    PR_NotifyCondVar(cd->cv);
+    PR_Unlock(cd->ml);
+
+    if (debug_mode) printf("Ending work on %s\n", filename);
+
+    return;
+}  /* Thread */
+
+static Hammer_t hammer[100];
+static PRCondVar *cv;
+/***********************************************************************
+** PRIVATE FUNCTION:    main
+** DESCRIPTION:
+**   Hammer on the file I/O system
+** INPUTS:      The usual argc and argv
+**              argv[0] - program name (not used)
+**              argv[1] - the number of times to execute the major loop
+**              argv[2] - the number of threads to toss into the batch
+**              argv[3] - the clipping number applied to randoms
+**              default values: loops = 2, threads = 10, limit = 57
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      Creates, accesses and deletes lots of files
+** RESTRICTIONS:
+**      (Currently) must have file create permission in "/usr/tmp".
+** MEMORY:      NA
+** ALGORITHM:
+**      1) Fork a "Thread()"
+**      2) Wait for 'interleave' seconds
+**      3) For [0..'threads') repeat [1..2]
+**      4) Mark all objects to stop
+**      5) Collect the threads, accumulating the results
+**      6) For [0..'loops') repeat [1..5]
+**      7) Print accumulated results and exit
+**
+**      Characteristic output (from IRIX)
+**          Random File: Using loops = 2, threads = 10, limit = 57
+**          Random File: [min [avg] max] writes/sec average
+***********************************************************************/
+int main (int argc,      char   *argv[])
+{
+    PRLock *ml;
+    PRUint32 id = 0;
+    int active, poll;
+    PRIntervalTime interleave;
+    PRIntervalTime duration = 0;
+    int limit = 0, loops = 0, threads = 0, times;
+    PRUint32 writes, writesMin = 0x7fffffff, writesTot = 0, durationTot = 0, writesMax = 0;
+
+    const char *where[] = {"okay", "open", "close", "delete", "write", "seek"};
+
+	/* 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, "Gdl:t:i:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'G':  /* global threads */
+			thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'l':  /* limiting number */
+			limit = atoi(opt->value);
+            break;
+        case 't':  /* number of threads */
+			threads = atoi(opt->value);
+            break;
+        case 'i':  /* iteration counter */
+			loops = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    interleave = PR_SecondsToInterval(10);
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("ranfile.log");
+	debug_mode = 1;
+#endif
+
+    ml = PR_NewLock();
+    cv = PR_NewCondVar(ml);
+
+    if (loops == 0) loops = DEFAULT_LOOPS;
+    if (limit == 0) limit = DEFAULT_LIMIT;
+    if (threads == 0) threads = DEFAULT_THREADS;
+
+    if (debug_mode) printf(
+        "%s: Using loops = %d, threads = %d, limit = %d and %s threads\n",
+        programName, loops, threads, limit,
+        (thread_scope == PR_LOCAL_THREAD) ? "LOCAL" : "GLOBAL");
+
+    for (times = 0; times < loops; ++times)
+    {
+        if (debug_mode) printf("%s: Setting concurrency level to %d\n", programName, times + 1);
+        PR_SetConcurrency(times + 1);
+        for (active = 0; active < threads; active++)
+        {
+            hammer[active].ml = ml;
+            hammer[active].cv = cv;
+            hammer[active].id = id++;
+            hammer[active].writes = 0;
+            hammer[active].action = sg_go;
+            hammer[active].problem = sg_okay;
+            hammer[active].limit = (Random() % limit) + 1;
+            hammer[active].timein = PR_IntervalNow();
+            hammer[active].thread = PR_CreateThread(
+                PR_USER_THREAD, Thread, &hammer[active],
+                PR_GetThreadPriority(PR_GetCurrentThread()),
+                thread_scope, PR_JOINABLE_THREAD, 0);
+
+            PR_Lock(ml);
+            PR_WaitCondVar(cv, interleave);  /* start new ones slowly */
+            PR_Unlock(ml);
+        }
+
+        /*
+         * The last thread started has had the opportunity to run for
+         * 'interleave' seconds. Now gather them all back in.
+         */
+        PR_Lock(ml);
+        for (poll = 0; poll < threads; poll++)
+        {
+            if (hammer[poll].action == sg_go)  /* don't overwrite done */
+                hammer[poll].action = sg_stop;  /* ask him to stop */
+        }
+        PR_Unlock(ml);
+
+        while (active > 0)
+        {
+            for (poll = 0; poll < threads; poll++)
+            {
+                PR_Lock(ml);
+                while (hammer[poll].action < sg_done)
+                    PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT);
+                PR_Unlock(ml);
+
+                active -= 1;  /* this is another one down */
+                (void)PR_JoinThread(hammer[poll].thread);
+                hammer[poll].thread = NULL;
+                if (hammer[poll].problem == sg_okay)
+                {
+                    duration = PR_IntervalToMilliseconds(
+                        PR_IntervalNow() - hammer[poll].timein);
+                    writes = hammer[poll].writes * 1000 / duration;
+                    if (writes < writesMin) 
+                        writesMin = writes;
+                    if (writes > writesMax) 
+                        writesMax = writes;
+                    writesTot += hammer[poll].writes;
+                    durationTot += duration;
+                }
+                else
+                    if (debug_mode) printf(
+                        "%s: test failed %s after %ld seconds\n",
+                        programName, where[hammer[poll].problem], duration);
+					else failed_already=1;
+            }
+        }
+    }
+    if (debug_mode) printf(
+        "%s: [%ld [%ld] %ld] writes/sec average\n",
+        programName, writesMin, writesTot * 1000 / durationTot, writesMax);
+
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+
+	if (failed_already) 
+	{
+	    printf("FAIL\n");
+		return 1;
+	}
+    else
+    {
+        printf("PASS\n");
+		return 0;
+    }
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/rmdir.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/rmdir.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,127 @@
+/* -*- 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:        rmdir.c
+** Description: Demonstrate bugzilla 80884. 
+**
+** after fix to unix_errors.c, message should report correct 
+** failure of PR_Rmdir().
+**
+**
+**
+*/
+
+#include <prio.h>
+#include <stdio.h>
+#include <prerror.h>
+#include <prlog.h>
+#include "plgetopt.h"
+
+#define DIRNAME "xxxBug80884/"
+#define FILENAME "file80883"
+
+PRBool  failed_already = PR_FALSE;
+PRBool	debug_mode = PR_FALSE;
+
+PRLogModuleInfo     *lm;
+
+/*
+** Help() -- print Usage information
+*/
+static void Help( void )  {
+    fprintf(stderr, "template usage:\n"
+                    "\t-d     debug mode\n"
+                    );
+} /* --- end Help() */
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dh");
+    PRFileDesc* fd;
+    PRErrorCode err;
+
+    /* parse command line options */
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    lm = PR_NewLogModule( "testcase" );
+
+    (void) PR_MkDir( DIRNAME, 0777);
+    fd = PR_Open( DIRNAME FILENAME, PR_CREATE_FILE|PR_RDWR, 0666);
+    if (fd == 0) {
+        PRErrorCode err = PR_GetError();
+        fprintf(stderr, "create file fails: %d: %s\n", err,
+            PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
+        failed_already = PR_TRUE;
+        goto Finished;
+    }
+ 
+    PR_Close(fd);
+
+    if (PR_RmDir( DIRNAME ) == PR_SUCCESS) {
+        fprintf(stderr, "remove directory succeeds\n");
+        failed_already = PR_TRUE;
+        goto Finished;
+    }
+ 
+    err = PR_GetError();
+    fprintf(stderr, "remove directory fails with: %d: %s\n", err,
+        PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
+
+    (void) PR_Delete( DIRNAME FILENAME);
+    (void) PR_RmDir( DIRNAME );
+
+    return 0;
+
+Finished:
+    if ( debug_mode ) printf("%s\n", ( failed_already ) ? "FAILED" : "PASS" );
+    return( (failed_already)? 1 : 0 );
+}  /* --- end main() */
+/* --- end template.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/runtests.ksh
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/runtests.ksh	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,292 @@
+#!/bin/ksh
+# 
+# ***** 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 *****
+
+#
+# tests.ksh
+#	korn shell script for nspr tests
+#
+
+SYSTEM_INFO=`uname -a`
+OS_ARCH=`uname -s`
+if [ $OS_ARCH = "Windows_NT" ] || [ $OS_ARCH = "OS/2" ]
+then
+	NULL_DEVICE=nul
+else
+	NULL_DEVICE=/dev/null
+fi
+
+#
+# Irrevelant tests
+#
+#bug1test 	- used to demonstrate a bug on NT
+#bigfile2   - requires 4Gig file creation. See BugZilla #5451
+#bigfile3   - requires 4Gig file creation. See BugZilla #5451
+#dbmalloc	- obsolete; originally for testing debug version of nspr's malloc
+#dbmalloc1	- obsolete; originally for testing debug version of nspr's malloc
+#depend		- obsolete; used to test a initial spec for library dependencies
+#dceemu		- used to tests special functions in NSPR for DCE emulation
+#ipv6		- IPV6 not in use by NSPR clients
+#mbcs       - tests use of multi-byte charset for filenames. See BugZilla #25140
+#sproc_ch	- obsolete; sproc-based tests for Irix
+#sproc_p	- obsolete; sproc-based tests for Irix
+#io_timeoutk - obsolete; subsumed in io_timeout
+#io_timeoutu - obsolete; subsumed in io_timeout
+#prftest1	- obsolete; subsumed by prftest
+#prftest2	- obsolete; subsumed by prftest
+#prselect	- obsolete; PR_Select is obsolete
+#select2	- obsolete; PR_Select is obsolete
+#sem		- obsolete; PRSemaphore is obsolete
+#stat		- for OS2?
+#suspend	- private interfaces PR_SuspendAll, PR_ResumeAll, etc..
+#thruput	- needs to be run manually as client/server
+#time		- used to measure time with native calls and nspr calls
+#tmoacc		- should be run with tmocon
+#tmocon		- should be run with tmoacc
+#op_noacc	- limited use
+#yield		- limited use for PR_Yield
+
+#
+# Tests not run (but should)
+#
+
+#forktest (failed on IRIX)
+#nbconn - fails on some platforms 
+#poll_er - fails on some platforms? limited use?
+#prpoll -  the bad-FD test needs to be moved to a different test
+#sleep	-  specific to OS/2
+
+LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE}
+
+#
+# Tests run on all platforms
+#
+
+TESTS="
+accept
+acceptread
+acceptreademu
+affinity
+alarm
+anonfm
+atomic
+attach
+bigfile
+cleanup
+cltsrv
+concur
+cvar
+cvar2
+dlltest
+dtoa
+errcodes
+exit
+fdcach
+fileio
+foreign
+formattm
+fsync
+gethost
+getproto
+i2l
+initclk
+inrval
+instrumt
+intrio
+intrupt
+io_timeout
+ioconthr
+join
+joinkk
+joinku
+joinuk
+joinuu
+layer
+lazyinit
+libfilename
+lltest
+lock
+lockfile
+logger
+many_cv
+multiwait
+nameshm1
+nblayer
+nonblock
+ntioto
+ntoh
+op_2long
+op_excl
+op_filnf
+op_filok
+op_nofil
+parent
+peek
+perf
+pipeping
+pipeping2
+pipeself
+poll_nm
+poll_to
+pollable
+prftest
+primblok
+provider
+prpollml
+ranfile
+randseed
+rwlocktest
+sel_spd
+selct_er
+selct_nm
+selct_to
+selintr
+sema
+semaerr
+semaping
+sendzlf
+server_test
+servr_kk
+servr_uk
+servr_ku
+servr_uu
+short_thread
+sigpipe
+socket
+sockopt
+sockping
+sprintf
+stack
+stdio
+str2addr
+strod
+switch
+system
+testbit
+testfile
+threads
+timemac
+timetest
+tpd
+udpsrv
+vercheck
+version
+writev
+xnotify
+zerolen"
+
+rval=0
+
+
+#
+# When set, value of the environment variable TEST_TIMEOUT is the maximum
+# time (secs) allowed for a test program beyond which it is terminated.
+# If TEST_TIMEOUT is not set or if it's value is 0, then test programs
+# don't timeout.
+#
+# Running runtests.ksh under MKS toolkit on NT, 95, 98 does not cause
+# timeout detection correctly. For these platforms, do not attempt timeout
+# test. (lth).
+#
+#
+
+OS_PLATFORM=`uname`
+OBJDIR=`basename $PWD`
+echo "\nNSPR Test Results - $OBJDIR\n"
+echo "BEGIN\t\t\t`date`"
+echo "NSPR_TEST_LOGFILE\t${LOGFILE}\n"
+echo "Test\t\t\tResult\n"
+if [ $OS_PLATFORM = "Windows_95" ] || [ $OS_PLATFORM = "Windows_98" ] || [ $OS_PLATFORM = "Windows_NT" ] || [ $OS_PLATFORM = "OS/2" ] ; then
+	for prog in $TESTS
+	do
+		echo "$prog\c"
+		echo "\nBEGIN TEST: $prog\n" >> ${LOGFILE} 2>&1
+		./$prog >> ${LOGFILE} 2>&1
+		if [ 0 = $? ] ; then
+			echo "\t\t\tPassed";
+		else
+			echo "\t\t\tFAILED";
+			rval=1
+		fi;
+		echo "\nEND TEST: $prog\n" >> ${LOGFILE} 2>&1
+	done
+else
+	for prog in $TESTS
+	do
+		echo "$prog\c"
+		echo "\nBEGIN TEST: $prog\n" >> ${LOGFILE} 2>&1
+		export test_rval
+		./$prog >> ${LOGFILE} 2>&1 &
+		test_pid=$!
+		sleep_pid=0
+		if [ "$TEST_TIMEOUT" -gt 0 ]
+		then
+		(sleep  $TEST_TIMEOUT; kill $test_pid >/dev/null 2>&1 ) &
+		sleep_pid=$!
+		fi
+		wait $test_pid
+		test_rval=$?
+		[ $sleep_pid -eq 0 ] || kill $sleep_pid >/dev/null 2>&1
+		if [ 0 = $test_rval ] ; then
+			echo "\t\t\tPassed";
+		else
+			echo "\t\t\tFAILED";
+			rval=1
+		fi;
+		echo "\nEND TEST: $prog\n" >> ${LOGFILE} 2>&1
+	done
+fi;
+
+echo "END\t\t\t`date`"
+exit $rval
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/runtests.sh
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/runtests.sh	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,292 @@
+#!/bin/sh
+# 
+# ***** 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 *****
+
+#
+# tests.ksh
+#	korn shell script for nspr tests
+#
+
+SYSTEM_INFO=`uname -a`
+OS_ARCH=`uname -s`
+if [ $OS_ARCH = "Windows_NT" ] || [ $OS_ARCH = "OS/2" ]
+then
+	NULL_DEVICE=nul
+else
+	NULL_DEVICE=/dev/null
+fi
+
+#
+# Irrevelant tests
+#
+#bug1test 	- used to demonstrate a bug on NT
+#bigfile2   - requires 4Gig file creation. See BugZilla #5451
+#bigfile3   - requires 4Gig file creation. See BugZilla #5451
+#dbmalloc	- obsolete; originally for testing debug version of nspr's malloc
+#dbmalloc1	- obsolete; originally for testing debug version of nspr's malloc
+#depend		- obsolete; used to test a initial spec for library dependencies
+#dceemu		- used to tests special functions in NSPR for DCE emulation
+#ipv6		- IPV6 not in use by NSPR clients
+#mbcs       - tests use of multi-byte charset for filenames. See BugZilla #25140
+#sproc_ch	- obsolete; sproc-based tests for Irix
+#sproc_p	- obsolete; sproc-based tests for Irix
+#io_timeoutk - obsolete; subsumed in io_timeout
+#io_timeoutu - obsolete; subsumed in io_timeout
+#prftest1	- obsolete; subsumed by prftest
+#prftest2	- obsolete; subsumed by prftest
+#prselect	- obsolete; PR_Select is obsolete
+#select2	- obsolete; PR_Select is obsolete
+#sem		- obsolete; PRSemaphore is obsolete
+#stat		- for OS2?
+#suspend	- private interfaces PR_SuspendAll, PR_ResumeAll, etc..
+#thruput	- needs to be run manually as client/server
+#time		- used to measure time with native calls and nspr calls
+#tmoacc		- should be run with tmocon
+#tmocon		- should be run with tmoacc
+#op_noacc	- limited use
+#yield		- limited use for PR_Yield
+
+#
+# Tests not run (but should)
+#
+
+#forktest (failed on IRIX)
+#nbconn - fails on some platforms 
+#poll_er - fails on some platforms? limited use?
+#prpoll -  the bad-FD test needs to be moved to a different test
+#sleep	-  specific to OS/2
+
+LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE}
+
+#
+# Tests run on all platforms
+#
+
+TESTS="
+accept
+acceptread
+acceptreademu
+affinity
+alarm
+anonfm
+atomic
+attach
+bigfile
+cleanup
+cltsrv
+concur
+cvar
+cvar2
+dlltest
+dtoa
+errcodes
+exit
+fdcach
+fileio
+foreign
+formattm
+fsync
+gethost
+getproto
+i2l
+initclk
+inrval
+instrumt
+intrio
+intrupt
+io_timeout
+ioconthr
+join
+joinkk
+joinku
+joinuk
+joinuu
+layer
+lazyinit
+libfilename
+lltest
+lock
+lockfile
+logger
+many_cv
+multiwait
+nameshm1
+nblayer
+nonblock
+ntioto
+ntoh
+op_2long
+op_excl
+op_filnf
+op_filok
+op_nofil
+parent
+peek
+perf
+pipeping
+pipeping2
+pipeself
+poll_nm
+poll_to
+pollable
+prftest
+primblok
+provider
+prpollml
+ranfile
+randseed
+rwlocktest
+sel_spd
+selct_er
+selct_nm
+selct_to
+selintr
+sema
+semaerr
+semaping
+sendzlf
+server_test
+servr_kk
+servr_uk
+servr_ku
+servr_uu
+short_thread
+sigpipe
+socket
+sockopt
+sockping
+sprintf
+stack
+stdio
+str2addr
+strod
+switch
+system
+testbit
+testfile
+threads
+timemac
+timetest
+tpd
+udpsrv
+vercheck
+version
+writev
+xnotify
+zerolen"
+
+rval=0
+
+
+#
+# When set, value of the environment variable TEST_TIMEOUT is the maximum
+# time (secs) allowed for a test program beyond which it is terminated.
+# If TEST_TIMEOUT is not set or if it's value is 0, then test programs
+# don't timeout.
+#
+# Running runtests.ksh under MKS toolkit on NT, 95, 98 does not cause
+# timeout detection correctly. For these platforms, do not attempt timeout
+# test. (lth).
+#
+#
+
+OS_PLATFORM=`uname`
+OBJDIR=`basename $PWD`
+printf "\nNSPR Test Results - $OBJDIR\n\n"
+printf "BEGIN\t\t\t`date`\n"
+printf "NSPR_TEST_LOGFILE\t${LOGFILE}\n\n"
+printf "Test\t\t\tResult\n\n"
+if [ $OS_PLATFORM = "Windows_95" ] || [ $OS_PLATFORM = "Windows_98" ] || [ $OS_PLATFORM = "Windows_NT" ] || [ $OS_PLATFORM = "OS/2" ] ; then
+	for prog in $TESTS
+	do
+		printf "$prog"
+		printf "\nBEGIN TEST: $prog\n\n" >> ${LOGFILE} 2>&1
+		./$prog >> ${LOGFILE} 2>&1
+		if [ 0 = $? ] ; then
+			printf "\t\t\tPassed\n";
+		else
+			printf "\t\t\tFAILED\n";
+			rval=1
+		fi;
+		printf "\nEND TEST: $prog\n\n" >> ${LOGFILE} 2>&1
+	done
+else
+	for prog in $TESTS
+	do
+		printf "$prog"
+		printf "\nBEGIN TEST: $prog\n\n" >> ${LOGFILE} 2>&1
+		export test_rval
+		./$prog >> ${LOGFILE} 2>&1 &
+		test_pid=$!
+		sleep_pid=0
+		if test -n "$TEST_TIMEOUT" && test "$TEST_TIMEOUT" -gt 0
+		then
+		(sleep  $TEST_TIMEOUT; kill $test_pid >/dev/null 2>&1 ) &
+		sleep_pid=$!
+		fi
+		wait $test_pid
+		test_rval=$?
+		[ $sleep_pid -eq 0 ] || kill $sleep_pid >/dev/null 2>&1
+		if [ 0 = $test_rval ] ; then
+			printf "\t\t\tPassed\n";
+		else
+			printf "\t\t\tFAILED\n";
+			rval=1
+		fi;
+		printf "\nEND TEST: $prog\n\n" >> ${LOGFILE} 2>&1
+	done
+fi;
+
+printf "END\t\t\t`date`\n"
+exit $rval
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/runy2ktests.ksh
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/runy2ktests.ksh	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,269 @@
+#!/bin/ksh
+# 
+# ***** 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 *****
+
+#
+# runy2ktests.ksh
+#	Set system clock to Y2K dates of interest and run the Y2K tests.
+#	Needs root/administrator privilege
+#
+# WARNING: Because this script needs to be run with root/administrator
+#	privilege, thorough understanding of the script and extreme
+#	caution are urged.
+#
+
+#
+# SECTION I
+#	Define variables
+#
+
+SYSTEM_INFO=`uname -a`
+OS_ARCH=`uname -s`
+if [ $OS_ARCH = "Windows_NT" ] || [ $OS_ARCH = "Windows_95" ]
+then
+	NULL_DEVICE=nul
+else
+	NULL_DEVICE=/dev/null
+fi
+
+#
+# Test dates for NSPR Y2K tests
+#
+Y2KDATES="	123123591998.55
+			090923591999.55
+			123123591999.55
+			022823592000.55
+			022923592000.55
+			123123592000.55"
+
+Y2KDATES_AIX="	12312359.5598
+				09092359.5599
+				12312359.5599
+				02282359.5500
+				02292359.5500
+				12312359.5500"
+
+Y2KDATES_HPUX="	123123591998
+				090923591999
+				123123591999
+				022823592000
+				022923592000
+				123123592000"
+
+Y2KDATES_MKS="	1231235998.55
+				0909235999.55
+				1231235999.55
+				0228235900.55
+				0229235900.55
+				1231235900.55"
+
+#
+# NSPR Y2K tests
+#
+Y2KTESTS="
+y2k		\n
+y2ktmo	\n
+y2k		\n
+../runtests.ksh"
+
+Y2KTESTS_HPUX="
+y2k			\n
+y2ktmo -l 60\n
+y2k			\n
+../runtests.ksh"
+
+#
+# SECTION II
+#	Define functions
+#
+
+save_date()
+{
+	case $OS_ARCH in
+	AIX)
+		SAVED_DATE=`date "+%m%d%H%M.%S%y"`
+	;;
+	HP-UX)
+		SAVED_DATE=`date "+%m%d%H%M%Y"`
+	;;
+	Windows_NT)
+		SAVED_DATE=`date "+%m%d%H%M%y.%S"`
+	;;
+	Windows_95)
+		SAVED_DATE=`date "+%m%d%H%M%y.%S"`
+	;;
+	*)
+		SAVED_DATE=`date "+%m%d%H%M%Y.%S"`
+	;;
+	esac
+}
+
+set_date()
+{
+	case $OS_ARCH in
+	Windows_NT)
+#
+# The date command in MKS Toolkit releases 5.1 and 5.2
+# uses the current DST status for the date we want to
+# set the system clock to.  However, the DST status for
+# that date may be different from the current DST status.
+# We can work around this problem by invoking the date
+# command with the same date twice.
+#
+		date "$1" > $NULL_DEVICE
+		date "$1" > $NULL_DEVICE
+	;;
+	*)
+		date "$1" > $NULL_DEVICE
+	;;
+	esac
+}
+
+restore_date()
+{
+	set_date "$SAVED_DATE"
+}
+
+savedate()
+{
+	case $OS_ARCH in
+	AIX)
+		SAVED_DATE=`date "+%m%d%H%M.%S%y"`
+	;;
+	HP-UX)
+		SAVED_DATE=`date "+%m%d%H%M%Y"`
+	;;
+	Windows_NT)
+		SAVED_DATE=`date "+%m%d%H%M%y.%S"`
+	;;
+	Windows_95)
+		SAVED_DATE=`date "+%m%d%H%M%y.%S"`
+	;;
+	*)
+		SAVED_DATE=`date "+%m%d%H%M%Y.%S"`
+	;;
+	esac
+}
+
+set_y2k_test_parameters()
+{
+#
+# set dates
+#
+	case $OS_ARCH in
+	AIX)
+		DATES=$Y2KDATES_AIX
+	;;
+	HP-UX)
+		DATES=$Y2KDATES_HPUX
+	;;
+	Windows_NT)
+		DATES=$Y2KDATES_MKS
+	;;
+	Windows_95)
+		DATES=$Y2KDATES_MKS
+	;;
+	*)
+		DATES=$Y2KDATES
+	;;
+	esac
+
+#
+# set tests
+#
+	case $OS_ARCH in
+	HP-UX)
+		TESTS=$Y2KTESTS_HPUX
+	;;
+	*)
+		TESTS=$Y2KTESTS
+	;;
+	esac
+}
+
+#
+# runtests:
+#	-	runs each test in $TESTS after setting the
+#		system clock to each date in $DATES
+#
+
+runtests()
+{
+for newdate in ${DATES}
+do
+	set_date $newdate
+	echo $newdate
+	echo "BEGIN\t\t\t`date`"
+	echo "Date\t\t\t\t\tTest\t\t\tResult"
+	echo $TESTS | while read prog
+	do
+		echo "`date`\t\t\c"
+		echo "$prog\c"
+		./$prog >> ${LOGFILE} 2>&1
+		if [ 0 = $? ] ; then
+			echo "\t\t\tPassed";
+		else
+			echo "\t\t\tFAILED";
+		fi;
+	done
+	echo "END\t\t\t`date`\n"
+done
+
+}
+
+#
+# SECTION III
+#	Run tests
+#
+
+LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE}
+OBJDIR=`basename $PWD`
+echo "\nNSPR Year 2000 Test Results - $OBJDIR\n"
+echo "SYSTEM:\t\t\t${SYSTEM_INFO}"
+echo "NSPR_TEST_LOGFILE:\t${LOGFILE}\n"
+
+
+save_date
+
+#
+# Run NSPR Y2k and standard tests
+#
+
+set_y2k_test_parameters
+runtests
+
+restore_date

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/rwlocktest.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/rwlocktest.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,241 @@
+/* ***** 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 ***** */
+
+
+/*
+ *
+ * RWLock tests
+ *
+ *	Several threads are created to access and modify data arrays using
+ * 	PRRWLocks for synchronization. Two data arrays, array_A and array_B, are
+ *	initialized with random data and a third array, array_C, is initialized
+ *	with the sum of the first 2 arrays.
+ *
+ *	Each one of the threads acquires a read lock to verify that the sum of
+ *	the arrays A and B is equal to array C, and acquires a write lock to
+ *	consistently update arrays A and B so that their is equal to array C.
+ *		
+ */
+ 
+#include "nspr.h"
+#include "plgetopt.h"
+#include "prrwlock.h"
+
+static int _debug_on;
+static void rwtest(void *args);
+static PRInt32 *array_A,*array_B,*array_C;
+static void update_array(void);
+static void check_array(void);
+
+typedef struct thread_args {
+	PRRWLock	*rwlock;
+	PRInt32		loop_cnt;
+} thread_args;
+
+PRFileDesc  *output;
+PRFileDesc  *errhandle;
+
+#define	DEFAULT_THREAD_CNT	4
+#define	DEFAULT_LOOP_CNT	100
+#define	TEST_ARRAY_SIZE		100
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRInt32 cnt;
+	PRStatus rc;
+	PRInt32 i;
+
+	PRInt32 thread_cnt = DEFAULT_THREAD_CNT;
+	PRInt32 loop_cnt = DEFAULT_LOOP_CNT;
+	PRThread **threads;
+	thread_args *params;
+	PRRWLock	*rwlock1;
+
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:");
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			_debug_on = 1;
+            break;
+        case 't':  /* thread count */
+            thread_cnt = atoi(opt->value);
+            break;
+        case 'c':  /* loop count */
+            loop_cnt = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+	PR_SetConcurrency(4);
+
+    output = PR_GetSpecialFD(PR_StandardOutput);
+    errhandle = PR_GetSpecialFD(PR_StandardError);
+
+	rwlock1 = PR_NewRWLock(0,"Lock 1");
+	if (rwlock1 == NULL) {
+		PR_fprintf(errhandle, "PR_NewRWLock failed - error %d\n",
+								PR_GetError());
+		return 1;
+	}
+
+	threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt);
+	params = (thread_args *) PR_CALLOC(sizeof(thread_args) * thread_cnt);
+
+	/*
+	 * allocate and initialize data arrays
+	 */
+	array_A =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
+	array_B =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
+	array_C =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
+	cnt = 0;
+	for (i=0; i < TEST_ARRAY_SIZE;i++) {
+		array_A[i] = cnt++;
+		array_B[i] = cnt++;
+		array_C[i] = array_A[i] + array_B[i];
+	}
+
+	if (_debug_on)
+		PR_fprintf(output,"%s: thread_cnt = %d loop_cnt = %d\n", argv[0],
+							thread_cnt, loop_cnt);
+	for(cnt = 0; cnt < thread_cnt; cnt++) {
+		PRThreadScope scope;
+
+		params[cnt].rwlock = rwlock1;
+		params[cnt].loop_cnt = loop_cnt;
+
+		/*
+		 * create LOCAL and GLOBAL threads alternately
+		 */
+		if (cnt & 1)
+			scope = PR_LOCAL_THREAD;
+		else
+			scope = PR_GLOBAL_THREAD;
+
+		threads[cnt] = PR_CreateThread(PR_USER_THREAD,
+						  rwtest, &params[cnt],
+						  PR_PRIORITY_NORMAL,
+						  scope,
+						  PR_JOINABLE_THREAD,
+						  0);
+		if (threads[cnt] == NULL) {
+			PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n",
+								PR_GetError());
+			PR_ProcessExit(2);
+		}
+		if (_debug_on)
+			PR_fprintf(output,"%s: created thread = 0x%x\n", argv[0],
+										threads[cnt]);
+	}
+
+	for(cnt = 0; cnt < thread_cnt; cnt++) {
+    	rc = PR_JoinThread(threads[cnt]);
+		PR_ASSERT(rc == PR_SUCCESS);
+
+	}
+
+	PR_DELETE(threads);
+	PR_DELETE(params);
+
+	PR_DELETE(array_A);	
+	PR_DELETE(array_B);	
+	PR_DELETE(array_C);	
+
+	PR_DestroyRWLock(rwlock1);
+
+	
+	printf("PASS\n");
+	return 0;
+}
+
+static void rwtest(void *args)
+{
+    PRInt32 index;
+	thread_args *arg = (thread_args *) args;
+
+
+	for (index = 0; index < arg->loop_cnt; index++) {
+
+		/*
+		 * verify sum, update arrays and verify sum again
+		 */
+
+		PR_RWLock_Rlock(arg->rwlock);
+		check_array();
+		PR_RWLock_Unlock(arg->rwlock);
+
+		PR_RWLock_Wlock(arg->rwlock);
+		update_array();
+		PR_RWLock_Unlock(arg->rwlock);
+
+		PR_RWLock_Rlock(arg->rwlock);
+		check_array();
+		PR_RWLock_Unlock(arg->rwlock);
+	}
+	if (_debug_on)
+		PR_fprintf(output,
+		"Thread[0x%x] lock = 0x%x exiting\n",
+				PR_GetCurrentThread(), arg->rwlock);
+
+}
+
+static void check_array(void)
+{
+PRInt32 i;
+
+	for (i=0; i < TEST_ARRAY_SIZE;i++)
+		if (array_C[i] != (array_A[i] + array_B[i])) {
+			PR_fprintf(output, "Error - data check failed\n");
+			PR_ProcessExit(1);
+		}
+}
+
+static void update_array(void)
+{
+PRInt32 i;
+
+	for (i=0; i < TEST_ARRAY_SIZE;i++) {
+		array_A[i] += i;
+		array_B[i] -= i;
+	}
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sel_spd.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sel_spd.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,567 @@
+/* -*- 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 ***** */
+
+/*
+ * Test the speed of select within NSPR
+ *
+ */
+
+#include "nspr.h"
+#include "prpriv.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+int fprintf(FILE *stream, const char *fmt, ...)
+{
+PR_LogPrint(fmt);
+return 0;
+}
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+#define PORT_BASE 19000
+
+typedef struct timer_slot_t {
+	unsigned long d_connect;
+	unsigned long d_cl_data;
+	unsigned long d_sv_data;
+	unsigned long d_close;
+	unsigned long d_total;
+	unsigned long requests;
+} timer_slot_t;
+
+static long _iterations = 5;
+static long _client_data = 8192;
+
+#if defined(XP_MAC)
+/*
+ * Mac does not scale well specially the requirement for thread stack
+ * space and buffer allocation space.  It is easy to get into a fragmented
+ * memory and not be able to allocate thread stack or client/server data
+ * buffer.
+*/
+static long _server_data = (8*1024);
+static long _threads_max = 10, _threads = 10;
+#else
+static long _server_data = (128*1024);
+static long _threads_max = 10, _threads = 10;
+#endif
+
+static int verbose=0;
+static PRMonitor *exit_cv;
+static long _thread_exit_count;
+static timer_slot_t *timer_data;
+static PRThreadScope scope1, scope2;
+
+void tally_results(int);
+
+/* return the diff in microseconds */
+unsigned long _delta(PRIntervalTime *start, PRIntervalTime *stop)
+{
+	/*
+	 * Will C do the right thing with unsigned arithemtic?
+	 */
+	return PR_IntervalToMicroseconds(*stop - *start);
+}
+
+int _readn(PRFileDesc *sock, char *buf, int len)
+{
+	int rem;
+	int bytes;
+
+	for (rem=len; rem; rem -= bytes) {
+		bytes = PR_Recv(sock, buf+len-rem, rem, 0, PR_INTERVAL_NO_TIMEOUT);
+		if (bytes <= 0)
+            return -1;
+	}
+	return len;
+}
+
+void
+_thread_exit(int id)
+{
+	PR_EnterMonitor(exit_cv);
+#ifdef DEBUG
+	fprintf(stdout, "Thread %d EXIT\n", id);
+#endif
+
+	_thread_exit_count--;
+	if (_thread_exit_count == 0) {
+#ifdef DEBUG
+	fprintf(stdout, "Thread %d EXIT triggered notify\n", id);
+#endif
+		PR_Notify(exit_cv);
+	}
+	PR_ExitMonitor(exit_cv);
+}
+
+void
+_server_thread(void *arg_id)
+{
+	void _client_thread(void *);
+	PRThread *thread;
+	int *id =  (int *)arg_id;
+	PRFileDesc *sock;
+	PRSocketOptionData sockopt;
+	PRNetAddr sa;
+	PRFileDesc * newsock;
+	char *data_buffer = NULL;
+	int data_buffer_size;
+	int index;
+	PRIntervalTime start,
+	      connect_done,
+	      read_done,
+	      write_done,
+	      close_done;
+	
+
+#ifdef DEBUG
+	fprintf(stdout, "server thread %d alive\n", *id);
+#endif
+
+	data_buffer_size = (_client_data>_server_data?_client_data:_server_data);
+
+	if ( (data_buffer = (char *)PR_Malloc(data_buffer_size * sizeof(char))) == NULL ) {
+		fprintf(stderr, "Error creating buffer in server thread %d\n", *id);
+		goto done;
+	}
+
+
+	if ( (sock = PR_NewTCPSocket()) == NULL) {
+		fprintf(stderr, "Error creating socket in server thread %d\n", *id);
+		goto done;
+	}
+
+	sockopt.option = PR_SockOpt_Reuseaddr;
+	sockopt.value.reuse_addr = PR_TRUE;
+	if ( PR_SetSocketOption(sock, &sockopt) == PR_FAILURE) {
+		fprintf(stderr, "Error setting socket option in server thread %d\n", *id);
+		goto done;
+	}
+
+	memset(&sa, 0 , sizeof(sa));
+	sa.inet.family = PR_AF_INET;
+	sa.inet.port = PR_htons(PORT_BASE + *id);
+	sa.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+	if ( PR_Bind(sock, &sa) < 0) {
+		fprintf(stderr, "Error binding socket in server thread %d errno = %d\n", *id, errno);
+		goto done;
+	}
+
+	if ( PR_Listen(sock, 32) < 0 ) {
+		fprintf(stderr, "Error listening to socket in server thread %d\n", *id);
+		goto done;
+	}
+
+	/* Tell the client to start */
+	if ( (thread = PR_CreateThread(PR_USER_THREAD, 
+                                      _client_thread, 
+                                      id, 
+                                      PR_PRIORITY_NORMAL, 
+                                      scope2, 
+                                      PR_UNJOINABLE_THREAD, 
+                                      0)) == NULL)
+		fprintf(stderr, "Error creating client thread %d\n", *id);
+
+	for (index = 0; index< _iterations; index++) {
+
+#ifdef DEBUG
+	fprintf(stdout, "server thread %d loop %d\n", *id, index);
+#endif
+
+		start = PR_IntervalNow();
+
+		if ( (newsock = PR_Accept(sock, &sa,
+					PR_INTERVAL_NO_TIMEOUT)) == NULL) {
+			fprintf(stderr, "Error accepting connection %d in server thread %d\n",
+				index, *id);
+			goto done;
+		}
+#ifdef DEBUG
+	fprintf(stdout, "server thread %d got connection %d\n", *id, newsock);
+#endif
+
+
+		connect_done = PR_IntervalNow();
+		
+		if ( _readn(newsock, data_buffer, _client_data) < _client_data) {
+			fprintf(stderr, "Error reading client data for iteration %d in server thread %d\n", index, *id );
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "server thread %d read %d bytes\n", *id, _client_data);
+#endif
+		read_done = PR_IntervalNow();
+
+		if ( PR_Send(newsock, data_buffer, _server_data, 0,
+				PR_INTERVAL_NO_TIMEOUT) < _server_data) {
+			fprintf(stderr, "Error sending client data for iteration %d in server thread %d\n", index, *id );
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "server thread %d write %d bytes\n", *id, _server_data);
+#endif
+
+		write_done = PR_IntervalNow();
+
+		PR_Close(newsock);
+
+		close_done = PR_IntervalNow();
+
+		timer_data[2*(*id)].d_connect += _delta(&start, &connect_done);
+		timer_data[2*(*id)].d_cl_data += _delta(&connect_done, &read_done);
+		timer_data[2*(*id)].d_sv_data += _delta(&read_done, &write_done);
+		timer_data[2*(*id)].d_close += _delta(&write_done, &close_done);
+		timer_data[2*(*id)].d_total += _delta(&start, &close_done);
+		timer_data[2*(*id)].requests++;
+
+
+#ifdef DEBUG
+		fprintf(stdout, "server: %d %d %d %d %d\n",
+			 _delta(&start, &connect_done), _delta(&connect_done, &read_done),
+			 _delta(&read_done, &write_done), _delta(&write_done, &close_done),
+			_delta(&start, &close_done));
+#endif
+	}
+
+done:
+	if (data_buffer != NULL) PR_Free (data_buffer);
+	if (sock) PR_Close(sock);
+	_thread_exit(*id);
+	return;
+}
+
+void
+_client_thread(void *arg_id)
+{
+	int *id =  (int *)arg_id;
+	int index;
+	PRNetAddr sa;
+	PRFileDesc *sock_h;
+	char *data_buffer = NULL;
+	int data_buffer_size;
+	int bytes;
+	PRIntervalTime start,
+	      connect_done,
+	      read_done,
+	      write_done,
+	      close_done;
+	PRStatus rv;
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d alive\n", *id);
+#endif
+
+	data_buffer_size = (_client_data>_server_data?_client_data:_server_data);
+
+	if ( (data_buffer = (char *)PR_Malloc(data_buffer_size * sizeof(char))) == NULL) {
+		fprintf(stderr, "Error creating buffer in server thread %d\n", *id);
+		goto done;
+	}
+
+	memset(&sa, 0 , sizeof(sa));
+	rv = PR_InitializeNetAddr(PR_IpAddrLoopback, PORT_BASE + *id, &sa);
+	PR_ASSERT(PR_SUCCESS == rv);
+	
+	for (index = 0; index< _iterations; index++) {
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d loop %d\n", *id, index);
+#endif
+
+		start = PR_IntervalNow();
+		if ( (sock_h = PR_NewTCPSocket()) == NULL) {
+			fprintf(stderr, "Error creating socket %d in client thread %d\n",
+				index, *id);
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d socket created %d\n", *id, sock_h);
+#endif
+
+		if ( PR_Connect(sock_h, &sa,
+				PR_INTERVAL_NO_TIMEOUT) < 0) {
+			fprintf(stderr, "Error accepting connection %d in client thread %d\n",
+				index, *id);
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d socket connected %d\n", *id, sock_h);
+#endif
+
+		connect_done = PR_IntervalNow();
+		if ( PR_Send(sock_h, data_buffer, _client_data, 0,
+				PR_INTERVAL_NO_TIMEOUT) < _client_data) {
+			fprintf(stderr, "Error sending client data for iteration %d in client thread %d\n", index, *id );
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d socket wrote %d\n", *id, _client_data);
+#endif
+
+		write_done = PR_IntervalNow();
+		if ( (bytes = _readn(sock_h, data_buffer, _server_data)) < _server_data) {
+			fprintf(stderr, "Error reading server data for iteration %d in client thread %d (read %d bytes)\n", index, *id, bytes );
+			goto done;
+		}
+
+#ifdef DEBUG
+	fprintf(stdout, "client thread %d socket read %d\n", *id, _server_data);
+#endif
+
+		read_done = PR_IntervalNow();
+		PR_Close(sock_h);
+		close_done = PR_IntervalNow();
+
+		timer_data[2*(*id)+1].d_connect += _delta(&start, &connect_done);
+		timer_data[2*(*id)+1].d_cl_data += _delta(&connect_done, &write_done);
+		timer_data[2*(*id)+1].d_sv_data += _delta(&write_done, &read_done);
+		timer_data[2*(*id)+1].d_close += _delta(&read_done, &close_done);
+		timer_data[2*(*id)+1].d_total += _delta(&start, &close_done);
+		timer_data[2*(*id)+1].requests++;
+	}
+done:
+	if (data_buffer != NULL) PR_Free (data_buffer);
+	_thread_exit(*id);
+
+	return;
+}
+
+static
+void do_work(void)
+{
+    int index;
+
+	_thread_exit_count = _threads * 2;
+	for (index=0; index<_threads; index++) {
+		PRThread *thread;
+		int *id = (int *)PR_Malloc(sizeof(int));
+
+		*id = index;
+
+		if ( (thread = PR_CreateThread(PR_USER_THREAD, 
+                                       _server_thread, 
+                                       id, 
+                                       PR_PRIORITY_NORMAL, 
+                                       scope1, 
+                                       PR_UNJOINABLE_THREAD, 
+                                       0)) == NULL)
+			fprintf(stderr, "Error creating server thread %d\n", index);
+	}
+	
+	PR_EnterMonitor(exit_cv);
+	while (_thread_exit_count > 0)
+		PR_Wait(exit_cv, PR_INTERVAL_NO_TIMEOUT);
+	PR_ExitMonitor(exit_cv);
+
+	fprintf(stdout, "TEST COMPLETE!\n");
+
+	tally_results(verbose);
+
+}
+
+static void do_workUU(void)
+{
+    scope1 = PR_LOCAL_THREAD;
+    scope2 = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workUK(void)
+{
+    scope1 = PR_LOCAL_THREAD;
+    scope2 = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+static void do_workKU(void)
+{
+    scope1 = PR_GLOBAL_THREAD;
+    scope2 = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workKK(void)
+{
+    scope1 = PR_GLOBAL_THREAD;
+    scope2 = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    printf("%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+int main(int argc, char **argv)
+{
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+	int opt;
+	PR_IMPORT_DATA(char *) optarg;
+#endif
+
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+	while ( (opt = getopt(argc, argv, "c:s:i:t:v")) != EOF) {
+		switch(opt) {
+			case 'i':
+				_iterations = atoi(optarg);
+				break;
+			case 't':
+				_threads_max = _threads = atoi(optarg);
+				break;
+			case 'c':
+				_client_data = atoi(optarg);
+				break;
+			case 's':
+				_server_data = atoi(optarg);
+				break;
+			case 'v':
+				verbose = 1;
+				break;
+			default: 
+				break;
+		}
+	}
+#endif
+
+	PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("sel_spd.log");
+#endif
+
+	fprintf(stdout, "Running test for %d iterations with %d simultaneous threads.\n", 
+		_iterations, _threads);
+	fprintf(stdout, "\tWill send %d bytes of client data and %d bytes of server data\n", 
+		_client_data, _server_data);
+
+	if ( (exit_cv = PR_NewMonitor()) == NULL) 
+		fprintf(stderr, "Error creating monitor for exit cv\n");
+	if ( (timer_data = (timer_slot_t *)PR_Malloc(2*_threads * sizeof(timer_slot_t))) == NULL) 
+		fprintf(stderr, "error allocating thread time results array\n");
+	memset(timer_data, 0 , 2*_threads*sizeof(timer_slot_t));
+
+    Measure(do_workUU, "select loop user/user");
+    Measure(do_workUK, "select loop user/kernel");
+    Measure(do_workKU, "select loop kernel/user");
+    Measure(do_workKK, "select loop kernel/kernel");
+
+
+	return 0;
+}
+
+void
+tally_results(int verbose)
+{
+	int index;
+	unsigned long tot_connect = 0;
+	unsigned long tot_cl_data = 0;
+	unsigned long tot_sv_data = 0;
+	unsigned long tot_close = 0;
+	unsigned long tot_all = 0;
+	unsigned long tot_requests = 0;
+
+	fprintf(stdout, "Server results:\n\n");
+	for (index=0; index<_threads_max*2; index+=2) {
+
+		if (verbose)
+			fprintf(stdout, "server thread %u\t%u\t%u\t%u\t%u\t%u\t%u\n",
+				index, timer_data[index].requests, timer_data[index].d_connect,
+				timer_data[index].d_cl_data, timer_data[index].d_sv_data,
+				timer_data[index].d_close, timer_data[index].d_total);
+
+		tot_connect += timer_data[index].d_connect / _threads;
+		tot_cl_data += timer_data[index].d_cl_data / _threads;
+		tot_sv_data += timer_data[index].d_sv_data / _threads;
+		tot_close += timer_data[index].d_close / _threads;
+		tot_all += timer_data[index].d_total / _threads;
+		tot_requests += timer_data[index].requests / _threads;
+	}
+	fprintf(stdout, "----------\n");
+	fprintf(stdout, "server per thread totals %u\t%u\t%u\t%u\t%u\n",
+		tot_requests, tot_connect, tot_cl_data, tot_sv_data, tot_close);
+	fprintf(stdout, "server per thread elapsed time %u\n", tot_all);
+	fprintf(stdout, "----------\n");
+
+	tot_connect = tot_cl_data = tot_sv_data = tot_close = tot_all = tot_requests = 0;
+	fprintf(stdout, "Client results:\n\n");
+	for (index=1; index<_threads_max*2; index+=2) {
+
+		if (verbose)
+			fprintf(stdout, "client thread %u\t%u\t%u\t%u\t%u\t%u\t%u\n",
+				index, timer_data[index].requests, timer_data[index].d_connect,
+				timer_data[index].d_cl_data, timer_data[index].d_sv_data,
+				timer_data[index].d_close, timer_data[index].d_total);
+
+		tot_connect += timer_data[index].d_connect / _threads;
+		tot_cl_data += timer_data[index].d_cl_data / _threads;
+		tot_sv_data += timer_data[index].d_sv_data / _threads;
+		tot_close += timer_data[index].d_close / _threads;
+		tot_all += timer_data[index].d_total / _threads;
+		tot_requests += timer_data[index].requests / _threads;
+	}
+	fprintf(stdout, "----------\n");
+	fprintf(stdout, "client per thread totals %u\t%u\t%u\t%u\t%u\n",
+		tot_requests, tot_connect, tot_cl_data, tot_sv_data, tot_close);
+	fprintf(stdout, "client per thread elapsed time %u\n", tot_all);
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/selct_er.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/selct_er.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,234 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**  1997 - Netscape Communications Corporation
+**
+** Name: prselect_err.c
+**
+** Description: tests PR_Select with sockets Error condition functions.
+**
+** Modification History:
+** 14-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.
+***********************************************************************/
+
+#ifdef XP_BEOS
+#include <stdio.h>
+int main()
+{
+    printf( "This test is not ported to the BeOS\n" );
+    return 0;
+}
+#else
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "primpl.h"
+#include "pprio.h"
+#include "prnetdb.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRFileDesc *badFD;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    PR_fd_set readFdSet;
+    char buf[128];
+    PRInt32 retVal;
+
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Select with sockets.  Error\n");
+		printf("reporting operations are tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = AF_INET;
+    addr.inet.ip = PR_htonl(INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    /* Set up the fd set */
+    PR_FD_ZERO(&readFdSet);
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+
+
+    /* Testing bad fd */
+    if (debug_mode) printf("PR_Select should detect a bad file descriptor\n");
+    if ((badFD = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    PR_FD_SET(badFD, &readFdSet);
+    /*
+     * Make the fd invalid
+     */
+#if defined(XP_UNIX)
+    close(PR_FileDesc2NativeHandle(badFD));
+#elif defined(XP_OS2)
+    soclose(PR_FileDesc2NativeHandle(badFD));
+#elif defined(WIN32) || defined(WIN16)
+    closesocket(PR_FileDesc2NativeHandle(badFD));
+#elif defined(XP_MAC)
+    _PR_MD_CLOSE_SOCKET(PR_FileDesc2NativeHandle(badFD));
+#else
+#error "Unknown architecture"
+#endif
+
+    retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+	    PR_INTERVAL_NO_TIMEOUT);
+    if (retVal != -1 || PR_GetError() != PR_BAD_DESCRIPTOR_ERROR) {
+	fprintf(stderr, "Failed to detect the bad fd: "
+		"PR_Select returns %d\n", retVal);
+	if (retVal == -1) {
+	    fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(),
+		    PR_GetOSError());
+		failed_already=1;
+	}
+	goto exit_now;
+    }
+    if (debug_mode) printf("PR_Select detected a bad fd.  Test passed.\n\n");
+	PR_FD_CLR(badFD, &readFdSet);
+
+	PR_Cleanup();
+	goto exit_now;
+exit_now:
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+
+}
+
+#endif /* XP_BEOS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/selct_nm.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/selct_nm.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,320 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**  1997 - Netscape Communications Corporation
+**
+** Name: prselect_norm.c
+**
+** Description: tests PR_Select with sockets - Normal operations.
+**
+** Modification History:
+** 14-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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prerror.h"
+#include "prnetdb.h"
+
+#ifdef XP_MAC
+#include "probslet.h"
+#else
+#include "obsolete/probslet.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+static void
+clientThreadFunc(void *arg)
+{
+    PRUintn port = (PRUintn) arg;
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    char buf[128];
+    int i;
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons((PRUint16)port);
+    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.port);
+
+    for (i = 0; i < 5; i++) {
+	sock = PR_NewTCPSocket();
+        PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT);
+	PR_Write(sock, buf, sizeof(buf));
+	PR_Close(sock);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRFileDesc *fds0[10], *fds1[10], **fds, **other_fds;
+    PRIntn nfds;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    PR_fd_set readFdSet;
+    char buf[128];
+    PRThread *clientThread;
+    PRInt32 retVal;
+    PRIntn i, j;
+
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Select with sockets.  \n");
+		printf(" Normal operation are tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+failed_already=1;
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort1,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+	    clientThreadFunc, (void *) listenPort2,
+	    PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
+	    PR_UNJOINABLE_THREAD, 0);
+    if (clientThread == NULL) {
+	fprintf(stderr, "can't create thread\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if (debug_mode) {
+		printf("Two client threads are created.  Each of them will\n");
+		printf("send data to one of the two ports the server is listening on.\n");
+		printf("The data they send is the port number.  Each of them send\n");
+		printf("the data five times, so you should see ten lines below,\n");
+		printf("interleaved in an arbitrary order.\n");
+	}
+    /* set up the fd array */
+    fds = fds0;
+    other_fds = fds1;
+    fds[0] = listenSock1;
+    fds[1] = listenSock2;
+    nfds = 2;
+    /* Set up the fd set */
+    PR_FD_ZERO(&readFdSet);
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+
+    /* 20 events total */
+    i = 0;
+    while (i < 20) {
+	PRFileDesc **tmp;
+	int nextIndex;
+	int nEvents = 0;
+
+	retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+		PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(retVal != 0);  /* no timeout */
+	if (retVal == -1) {
+	    fprintf(stderr, "PR_Select failed (%d, %d)\n", PR_GetError(),
+		    PR_GetOSError());
+	failed_already=1;
+	    goto exit_now;
+	}
+
+	nextIndex = 2;
+	/* the two listening sockets */
+	for (j = 0; j < 2; j++) {
+	    other_fds[j] = fds[j];
+	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
+		PRFileDesc *sock;
+
+		nEvents++;
+		sock = PR_Accept(fds[j], NULL, PR_INTERVAL_NO_TIMEOUT);
+		if (sock == NULL) {
+		    fprintf(stderr, "PR_Accept() failed\n");
+		failed_already=1;
+		    goto exit_now;
+		}
+		other_fds[nextIndex] = sock;
+		PR_FD_SET(sock, &readFdSet);
+		nextIndex++;
+	    }
+	    PR_FD_SET(fds[j], &readFdSet);
+	}
+
+	for (j = 2; j < nfds; j++) {
+	    if (PR_FD_ISSET(fds[j], &readFdSet)) {
+		PRInt32 nBytes;
+
+		PR_FD_CLR(fds[j], &readFdSet);
+		nEvents++;
+		nBytes = PR_Read(fds[j], buf, sizeof(buf));
+		if (nBytes == -1) {
+		    fprintf(stderr, "PR_Read() failed\n");
+		failed_already=1;
+		    goto exit_now;
+		}
+		/* Just to be safe */
+		buf[127] = '\0';
+		PR_Close(fds[j]);
+		if (debug_mode) printf("The server received \"%s\" from a client\n", buf);
+	    } else {
+		PR_FD_SET(fds[j], &readFdSet);
+		other_fds[nextIndex] = fds[j];
+		nextIndex++;
+	    }
+	}
+
+	PR_ASSERT(retVal == nEvents);
+	/* swap */
+	tmp = fds;
+	fds = other_fds;
+	other_fds = tmp;
+	nfds = nextIndex;
+	i += nEvents;
+    }
+
+    if (debug_mode) printf("Test passed\n");
+
+    PR_Cleanup();
+	goto exit_now;
+exit_now:
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/selct_to.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/selct_to.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,208 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**  1997 - Netscape Communications Corporation
+**
+** Name: prselect_to.c
+**
+** Description: tests PR_Select with sockets. Time out functions
+**
+** Modification History:
+** 14-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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prio.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prnetdb.h"
+
+#ifdef XP_MAC
+#include "probslet.h"
+#else
+#include "obsolete/probslet.h"
+#endif
+
+#include "prerror.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+int main(int argc, char **argv)
+{
+    PRFileDesc *listenSock1, *listenSock2;
+    PRUint16 listenPort1, listenPort2;
+    PRNetAddr addr;
+    PR_fd_set readFdSet;
+    char buf[128];
+    PRInt32 retVal;
+
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (debug_mode) {
+		printf("This program tests PR_Select with sockets.  Timeout \n");
+		printf("operations are tested.\n\n");
+	}
+
+    /* Create two listening sockets */
+    if ((listenSock1 = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock1, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort1 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock1, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+
+    if ((listenSock2  = PR_NewTCPSocket()) == NULL) {
+	fprintf(stderr, "Can't create a new TCP socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    addr.inet.family = PR_AF_INET;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    addr.inet.port = PR_htons(0);
+    if (PR_Bind(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "Can't bind socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    if (PR_GetSockName(listenSock2, &addr) == PR_FAILURE) {
+	fprintf(stderr, "PR_GetSockName failed\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    listenPort2 = PR_ntohs(addr.inet.port);
+    if (PR_Listen(listenSock2, 5) == PR_FAILURE) {
+	fprintf(stderr, "Can't listen on a socket\n");
+	failed_already=1;
+	goto exit_now;
+    }
+    PR_snprintf(buf, sizeof(buf),
+	    "The server thread is listening on ports %hu and %hu\n\n",
+	    listenPort1, listenPort2);
+    if (debug_mode) printf("%s", buf);
+
+    /* Set up the fd set */
+    PR_FD_ZERO(&readFdSet);
+    PR_FD_SET(listenSock1, &readFdSet);
+    PR_FD_SET(listenSock2, &readFdSet);
+
+    /* Testing timeout */
+    if (debug_mode) printf("PR_Select should time out in 5 seconds\n");
+    retVal = PR_Select(0 /* unused */, &readFdSet, NULL, NULL,
+	    PR_SecondsToInterval(5));
+    if (retVal != 0) {
+	PR_snprintf(buf, sizeof(buf),
+		"PR_Select should time out and return 0, but it returns %ld\n",
+		retVal);
+	fprintf(stderr, "%s", buf);
+	if (retVal == -1) {
+	    fprintf(stderr, "Error %d, oserror %d\n", PR_GetError(),
+		    PR_GetOSError());
+			failed_already=1;
+	}
+	goto exit_now;
+    }
+    if (debug_mode) printf("PR_Select timed out.  Test passed.\n\n");
+
+    PR_Cleanup();
+
+exit_now:
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/select2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/select2.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,354 @@
+/* -*- 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: select2.c
+**
+** Description: Measure PR_Select and Empty_Select performance.
+**
+** Modification History:
+** 20-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. 
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+#include "prttools.h"
+#include "primpl.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(OS2)
+#include <sys/time.h>
+#endif
+
+#define PORT 8000
+#define DEFAULT_COUNT 10
+PRInt32 count;
+
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Test_Result
+** DESCRIPTION: Used in conjunction with the regress tool, prints out the
+**				status of the test case.
+** INPUTS:      PASS/FAIL
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:   Determine what the status is and print accordingly.
+**      
+***********************************************************************/
+
+
+static void Test_Result (int result)
+{
+	switch (result)
+	{
+		case PASS:
+			printf ("PASS\n");
+			break;
+		case FAIL:
+			printf ("FAIL\n");
+			break;
+		default:
+			printf ("NOSTATUS\n");
+			break;
+	}
+}
+
+static void EmptyPRSelect(void)
+{
+    PRInt32 index = count;
+    PRInt32 rv;
+
+    for (; index--;)
+        rv = PR_Select(0, NULL, NULL, NULL, PR_INTERVAL_NO_WAIT);
+}
+
+static void EmptyNativeSelect(void)
+{
+    PRInt32 rv;
+    PRInt32 index = count;
+    struct timeval timeout;
+
+    timeout.tv_sec = timeout.tv_usec = 0;
+    for (; index--;)
+        rv = select(0, NULL, NULL, NULL, &timeout);
+}
+
+static void PRSelectTest(void)
+{
+    PRFileDesc *listenSocket;
+    PRNetAddr serverAddr;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+        return;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address\n");
+        PR_Close(listenSocket);
+        return;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+        PR_Close(listenSocket);
+        return;
+    }
+    if (debug_mode) printf("Listening on port %d\n", PORT);
+
+    {
+        PRFileDesc *newSock;
+        PRNetAddr rAddr;
+        PRInt32 loops = 0;
+        PR_fd_set rdset;
+        PRInt32 rv;
+        PRInt32 bytesRead;
+        char buf[11];
+
+        loops++;
+
+        if (debug_mode) printf("Going into accept\n"); 
+
+        newSock = PR_Accept(listenSocket, 
+                              &rAddr,
+                              PR_INTERVAL_NO_TIMEOUT);
+
+	if (newSock) {
+            if (debug_mode) printf("Got connection!\n");
+        } else {
+	    if (debug_mode) printf("PR_Accept failed: error code %d\n", PR_GetError());
+		else Test_Result (FAIL);
+        }
+
+        PR_FD_ZERO(&rdset);
+        PR_FD_SET(newSock, &rdset);
+
+        if (debug_mode) printf("Going into select \n");
+
+        rv = PR_Select(0, &rdset, 0, 0, PR_INTERVAL_NO_TIMEOUT);
+
+        if (debug_mode) printf("return from select is %d\n", rv);
+
+        if (PR_FD_ISSET(newSock, &rdset)) {
+            if (debug_mode) printf("I can't believe it- the socket is ready okay!\n");
+        } else {
+            if (debug_mode) printf("Damn; the select test failed...\n");
+			else Test_Result (FAIL);
+        }
+
+        strcpy(buf, "XXXXXXXXXX");
+        bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT);
+	buf[10] = '\0';
+
+        if (debug_mode) printf("Recv completed with %d bytes, %s\n", bytesRead, buf);
+
+        PR_Close(newSock);
+    }
+
+}
+
+#if defined(XP_UNIX)
+
+static void NativeSelectTest(void)
+{
+    PRFileDesc *listenSocket;
+    PRNetAddr serverAddr;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+        return;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address\n");
+        PR_Close(listenSocket);
+        return;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+        PR_Close(listenSocket);
+        return;
+    }
+    if (debug_mode) printf("Listening on port %d\n", PORT);
+
+    {
+        PRIntn osfd;
+        char buf[11];
+        fd_set rdset;
+        PRNetAddr rAddr;
+        PRFileDesc *newSock;
+        struct timeval timeout;
+        PRInt32 bytesRead, rv, loops = 0;
+
+        loops++;
+
+        if (debug_mode) printf("Going into accept\n"); 
+
+        newSock = PR_Accept(listenSocket, &rAddr, PR_INTERVAL_NO_TIMEOUT);
+
+	if (newSock) {
+            if (debug_mode) printf("Got connection!\n");
+        } else {
+	    if (debug_mode) printf("PR_Accept failed: error code %d\n", PR_GetError());
+		else Test_Result (FAIL);
+        }
+
+        osfd = PR_FileDesc2NativeHandle(newSock);
+        FD_ZERO(&rdset);
+        FD_SET(osfd, &rdset);
+
+        if (debug_mode) printf("Going into select \n");
+
+
+        timeout.tv_sec = 2; timeout.tv_usec = 0;
+        rv = select(osfd + 1, &rdset, NULL, NULL, &timeout);
+
+        if (debug_mode) printf("return from select is %d\n", rv);
+
+        if (FD_ISSET(osfd, &rdset)) {
+            if (debug_mode)
+                printf("I can't believe it- the socket is ready okay!\n");
+        } else {
+            if (debug_mode) printf("Damn; the select test failed...\n");
+			else Test_Result (FAIL);
+        }
+
+        strcpy(buf, "XXXXXXXXXX");
+        bytesRead = PR_Recv(newSock, buf, 10, 0, PR_INTERVAL_NO_TIMEOUT);
+	buf[10] = '\0';
+
+        if (debug_mode) printf("Recv completed with %d bytes, %s\n", bytesRead, buf);
+
+        PR_Close(newSock);
+    }
+
+}  /* NativeSelectTest */
+
+#endif /* defined(XP_UNIX) */
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+    PRInt32 tot;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+    tot = PR_IntervalToMilliseconds(stop-start);
+
+    if (debug_mode) printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot);
+}
+
+void main(int argc, char **argv)
+{
+	
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (argc > 2) {
+	count = atoi(argv[2]);
+    } else {
+	count = DEFAULT_COUNT;
+    }
+
+#if defined(XP_UNIX)
+    Measure(NativeSelectTest, "time to call 1 element select()");
+#endif
+    Measure(EmptyPRSelect, "time to call Empty PR_select()");
+    Measure(EmptyNativeSelect, "time to call Empty select()");
+    Measure(PRSelectTest, "time to call 1 element PR_select()");
+
+	if (!debug_mode) Test_Result (NOSTATUS);
+    PR_Cleanup();
+
+
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/selintr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/selintr.c	Mon Dec 18 10:53:47 2006
@@ -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) 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 ***** */
+
+/*
+ * Test whether classic NSPR's select() wrapper properly blocks
+ * the periodic SIGALRM clocks.  On some platforms (such as
+ * HP-UX and SINIX) an interrupted select() system call is
+ * restarted with the originally specified timeout, ignoring
+ * the time that has elapsed.  If a select() call is interrupted
+ * repeatedly, it will never time out.  (See Bugzilla bug #39674.)
+ */
+
+#if !defined(XP_UNIX)
+
+/*
+ * This test is applicable to Unix only.
+ */
+
+int main()
+{
+    return 0;
+}
+
+#else /* XP_UNIX */
+
+#include "nspr.h"
+
+#include <sys/time.h>
+#include <stdio.h>
+
+int main()
+{
+    struct timeval timeout;
+    int rv;
+
+    PR_SetError(0, 0);  /* force NSPR to initialize */
+    PR_EnableClockInterrupts();
+
+    /* 2 seconds timeout */
+    timeout.tv_sec = 2;
+    timeout.tv_usec = 0;
+    rv = select(1, NULL, NULL, NULL, &timeout);
+    printf("select returned %d\n", rv);
+    return 0;
+}
+
+#endif /* XP_UNIX */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sem.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sem.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,253 @@
+/* -*- 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: sem.c
+**
+** Description: Tests Semaphonre functions.
+**
+** Modification History:
+** 20-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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "prpriv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+/* 
+	Since we don't have stdin, stdout everywhere, we will fake 
+	it with our in-memory buffers called stdin and stdout.
+*/
+
+#define SBSIZE 1024
+
+#ifdef XP_MAC
+#include "prlog.h"
+#include "prsem.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#else
+#include "obsolete/prsem.h"
+#endif
+
+static char stdinBuf[SBSIZE];
+static char stdoutBuf[SBSIZE];
+
+static PRUintn stdinBufIdx = 0;
+static PRUintn stdoutBufIdx = 0;
+static PRStatus finalResult = PR_SUCCESS;
+
+
+static size_t dread (PRUintn device, char *buf, size_t bufSize)
+{
+	PRUintn	i;
+	
+	/* during first read call, initialize the stdinBuf buffer*/
+	if (stdinBufIdx == 0) {
+		for (i=0; i<SBSIZE; i++)
+			stdinBuf[i] = i;
+	}
+
+	/* now copy data from stdinBuf to the given buffer upto bufSize */
+	for (i=0; i<bufSize; i++) {
+		if (stdinBufIdx == SBSIZE)
+			break;
+		buf[i] = stdinBuf[stdinBufIdx++];
+	}
+
+	return i;
+}
+
+static size_t dwrite (PRUintn device, char *buf, size_t bufSize)
+{
+	PRUintn	i, j;
+	
+	/* copy data from the given buffer upto bufSize to stdoutBuf */
+	for (i=0; i<bufSize; i++) {
+		if (stdoutBufIdx == SBSIZE)
+			break;
+		stdoutBuf[stdoutBufIdx++] = buf[i];
+	}
+
+	/* during last write call, compare the two buffers */
+	if (stdoutBufIdx == SBSIZE)
+		for (j=0; j<SBSIZE; j++)
+			if (stdinBuf[j] != stdoutBuf[j]) {
+				if (debug_mode) printf("data mismatch for index= %d \n", j);
+				finalResult = PR_FAILURE;
+			}
+
+	return i;
+}
+
+/*------------------ Following is the real test program ---------*/
+/*
+	Program to copy standard input to standard output.  The program
+	uses two threads.  One reads the input and puts the data in a 
+	double buffer.  The other reads the buffer contents and writes 
+	it to standard output.
+*/
+
+PRSemaphore	*emptyBufs;	/* number of empty buffers */
+PRSemaphore *fullBufs;	/* number of buffers that are full */
+
+#define BSIZE	100
+
+struct {
+	char data[BSIZE];
+	PRUintn nbytes;		/* number of bytes in this buffer */
+} buf[2];
+
+static void PR_CALLBACK reader(void *arg)
+{
+	PRUintn	i = 0;
+	size_t	nbytes;
+	
+	do {
+		(void) PR_WaitSem(emptyBufs);
+		nbytes = dread(0, buf[i].data, BSIZE);
+		buf[i].nbytes = nbytes;
+		PR_PostSem(fullBufs);
+		i = (i + 1) % 2;
+	} while (nbytes > 0);
+}
+
+static void writer(void)
+{
+	PRUintn	i = 0;
+	size_t	nbytes;
+	
+	do {
+		(void) PR_WaitSem(fullBufs);
+		nbytes = buf[i].nbytes;
+		if (nbytes > 0) {
+			nbytes = dwrite(1, buf[i].data, nbytes);
+			PR_PostSem(emptyBufs);
+			i = (i + 1) % 2;
+		}
+	} while (nbytes > 0);
+}
+
+int main(int argc, char **argv)
+{
+	PRThread *r;
+
+    PR_STDIO_INIT();
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+
+    {
+    	/* 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, "d:");
+    	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+    		if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug mode */
+    			debug_mode = 1;
+                break;
+             default:
+                break;
+            }
+        }
+    	PL_DestroyOptState(opt);
+    }        
+
+ /* main test */
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("sem.log");
+	debug_mode = 1;
+#endif
+
+    emptyBufs = PR_NewSem(2);	/* two empty buffers */
+
+    fullBufs = PR_NewSem(0);	/* zero full buffers */
+
+	/* create the reader thread */
+	
+	r = PR_CreateThread(PR_USER_THREAD,
+				      reader, 0, 
+				      PR_PRIORITY_NORMAL,
+				      PR_LOCAL_THREAD,
+    				  PR_UNJOINABLE_THREAD,
+				      0);
+
+	/* Do the writer operation in this thread */
+	writer();
+
+	PR_DestroySem(emptyBufs);
+	PR_DestroySem(fullBufs);
+
+	if (finalResult == PR_SUCCESS) {
+		if (debug_mode) printf("sem Test Passed.\n");
+	}
+	else{
+		if (debug_mode) printf("sem Test Failed.\n");
+		failed_already=1;
+	}
+    PR_Cleanup();
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sema.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sema.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,180 @@
+/* -*- 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 "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#define SEM_NAME1 "/tmp/foo.sem"
+#define SEM_NAME2 "/tmp/bar.sem"
+#define SEM_MODE  0666
+#define ITERATIONS 1000
+
+static PRBool debug_mode = PR_FALSE;
+static PRIntn iterations = ITERATIONS;
+static PRIntn counter;
+static PRSem *sem1, *sem2;
+
+/*
+ * Thread 2 waits on semaphore 2 and posts to semaphore 1.
+ */
+void ThreadFunc(void *arg)
+{
+    PRIntn i;
+
+    for (i = 0; i < iterations; i++) {
+        if (PR_WaitSemaphore(sem2) == PR_FAILURE) {
+            fprintf(stderr, "PR_WaitSemaphore failed\n");
+            exit(1);
+        }
+        if (counter == 2*i+1) {
+            if (debug_mode) printf("thread 2: counter = %d\n", counter);
+        } else {
+            fprintf(stderr, "thread 2: counter should be %d but is %d\n",
+                    2*i+1, counter);
+            exit(1);
+        }
+        counter++;
+        if (PR_PostSemaphore(sem1) == PR_FAILURE) {
+            fprintf(stderr, "PR_PostSemaphore failed\n");
+            exit(1);
+        }
+    }
+}
+
+static void Help(void)
+{
+    fprintf(stderr, "sema test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-c <count>   loop count         (%d)\n", ITERATIONS);
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PRThread *thred;
+    PRIntn i;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'c':  /* loop count */
+                iterations = atoi(opt->value);
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) {
+        fprintf(stderr, "warning: removed semaphore %s left over "
+                "from previous run\n", SEM_NAME1);
+    }
+    if (PR_DeleteSemaphore(SEM_NAME2) == PR_SUCCESS) {
+        fprintf(stderr, "warning: removed semaphore %s left over "
+                "from previous run\n", SEM_NAME2);
+    }
+
+    sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 1);
+    if (NULL == sem1) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0);
+    if (NULL == sem2) {
+        fprintf(stderr, "PR_OpenSemaphore failed\n");
+        exit(1);
+    }
+    thred = PR_CreateThread(PR_USER_THREAD, ThreadFunc, NULL,
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == thred) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+
+    /*
+     * Thread 1 waits on semaphore 1 and posts to semaphore 2.
+     */
+    for (i = 0; i < iterations; i++) {
+        if (PR_WaitSemaphore(sem1) == PR_FAILURE) {
+            fprintf(stderr, "PR_WaitSemaphore failed\n");
+            exit(1);
+        }
+        if (counter == 2*i) {
+            if (debug_mode) printf("thread 1: counter = %d\n", counter);
+        } else {
+            fprintf(stderr, "thread 1: counter should be %d but is %d\n",
+                    2*i, counter);
+            exit(1);
+        }
+        counter++;
+        if (PR_PostSemaphore(sem2) == PR_FAILURE) {
+            fprintf(stderr, "PR_PostSemaphore failed\n");
+            exit(1);
+        }
+    }
+
+    if (PR_JoinThread(thred) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+
+    if (PR_CloseSemaphore(sem1) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+    if (PR_CloseSemaphore(sem2) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+    }
+    if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+    }
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/semaerr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/semaerr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,142 @@
+/* -*- 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 "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#define NO_SUCH_SEM_NAME "/tmp/nosuchsem.sem"
+#define SEM_NAME1 "/tmp/foo.sem"
+#define SEM_MODE  0666
+
+static PRBool debug_mode = PR_FALSE;
+
+static void Help(void)
+{
+    fprintf(stderr, "semaerr test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dh");
+    PRSem *sem;
+    char *child_argv[32];
+    char **child_arg;
+    PRProcess *proc;
+    PRInt32 exit_code;
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    /*
+     * Open a nonexistent semaphore without the PR_SEM_CREATE
+     * flag should fail with PR_FILE_NOT_FOUND_ERROR.
+     */
+    (void) PR_DeleteSemaphore(NO_SUCH_SEM_NAME);
+    sem = PR_OpenSemaphore(NO_SUCH_SEM_NAME, 0, 0, 0);
+    if (NULL != sem) {
+        fprintf(stderr, "Opening nonexistent semaphore %s "
+                "without the PR_SEM_CREATE flag should fail "
+                "but succeeded\n", NO_SUCH_SEM_NAME);
+        exit(1);
+    }
+    if (PR_GetError() != PR_FILE_NOT_FOUND_ERROR) {
+        fprintf(stderr, "Expected error is %d but got (%d, %d)\n",
+                PR_FILE_NOT_FOUND_ERROR, PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+
+    /*
+     * Create a semaphore and let the another process
+     * try PR_SEM_CREATE and PR_SEM_CREATE|PR_SEM_EXCL.
+     */
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) {
+        fprintf(stderr, "warning: deleted semaphore %s from previous "
+                "run of the test\n", SEM_NAME1);
+    }
+    sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0);
+    if (sem == NULL) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    child_arg = child_argv;
+    *child_arg++ = "semaerr1";
+    if (debug_mode) {
+        *child_arg++ = "-d";
+    }
+    *child_arg = NULL;
+    proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
+    if (proc == NULL) {
+        fprintf(stderr, "PR_CreateProcess failed\n");
+        exit(1);
+    }
+    if (PR_WaitProcess(proc, &exit_code) == PR_FAILURE) {
+        fprintf(stderr, "PR_WaitProcess failed\n");
+        exit(1);
+    }
+    if (exit_code != 0) {
+        fprintf(stderr, "process semaerr1 failed\n");
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+        exit(1);
+    }
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/semaerr1.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/semaerr1.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,137 @@
+/* -*- 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 "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#define SEM_NAME1 "/tmp/foo.sem"
+#define SEM_NAME2 "/tmp/bar.sem"
+#define SEM_MODE  0666
+
+static PRBool debug_mode = PR_FALSE;
+
+static void Help(void)
+{
+    fprintf(stderr, "semaerr1 test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dh");
+    PRSem *sem;
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    /*
+     * PR_SEM_CREATE|PR_SEM_EXCL should be able to
+     * create a nonexistent semaphore.
+     */
+    (void) PR_DeleteSemaphore(SEM_NAME2);
+    sem = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0);
+    if (sem == NULL) {
+        fprintf(stderr, "PR_OpenSemaphore failed\n");
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+        exit(1);
+    }
+    if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+        exit(1);
+    }
+    
+    /*
+     * Opening an existing semaphore with PR_SEM_CREATE|PR_SEM_EXCL.
+     * should fail with PR_FILE_EXISTS_ERROR.
+     */
+    sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0);
+    if (sem != NULL) {
+        fprintf(stderr, "PR_OpenSemaphore should fail but succeeded\n");
+        exit(1);
+    }
+    if (PR_GetError() != PR_FILE_EXISTS_ERROR) {
+        fprintf(stderr, "Expect %d but got %d\n", PR_FILE_EXISTS_ERROR,
+                PR_GetError());
+        exit(1);
+    }
+
+    /*
+     * Try again, with just PR_SEM_CREATE.  This should succeed.
+     */
+    sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0);
+    if (sem == NULL) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+        exit(1);
+    }
+
+    sem = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE|PR_SEM_EXCL, SEM_MODE, 0);
+    if (sem == NULL) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+        exit(1);
+    }
+
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/semaping.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/semaping.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,203 @@
+/* -*- 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 "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#define SHM_NAME "/tmp/counter"
+#define SEM_NAME1 "/tmp/foo.sem"
+#define SEM_NAME2 "/tmp/bar.sem"
+#define SEM_MODE  0666
+#define SHM_MODE  0666
+#define ITERATIONS 1000
+
+static PRBool debug_mode = PR_FALSE;
+static PRIntn iterations = ITERATIONS;
+static PRSem *sem1, *sem2;
+
+static void Help(void)
+{
+    fprintf(stderr, "semaping test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-c <count>   loop count         (%d)\n", ITERATIONS);
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PRProcess *proc;
+    PRIntn i;
+    char *child_argv[32];
+    char **child_arg;
+    char iterations_buf[32];
+    PRSharedMemory *shm;
+    PRIntn *counter_addr;
+    PRInt32 exit_code;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'c':  /* loop count */
+                iterations = atoi(opt->value);
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (PR_DeleteSharedMemory(SHM_NAME) == PR_SUCCESS) {
+        fprintf(stderr, "warning: removed shared memory %s left over "
+                "from previous run\n", SHM_NAME);
+    }
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) {
+        fprintf(stderr, "warning: removed semaphore %s left over "
+                "from previous run\n", SEM_NAME1);
+    }
+    if (PR_DeleteSemaphore(SEM_NAME2) == PR_SUCCESS) {
+        fprintf(stderr, "warning: removed semaphore %s left over "
+                "from previous run\n", SEM_NAME2);
+    }
+
+    shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), PR_SHM_CREATE, SHM_MODE);
+    if (NULL == shm) {
+        fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    counter_addr = PR_AttachSharedMemory(shm, 0);
+    if (NULL == counter_addr) {
+        fprintf(stderr, "PR_AttachSharedMemory failed\n");
+        exit(1);
+    }
+    *counter_addr = 0;
+    sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 1);
+    if (NULL == sem1) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 0);
+    if (NULL == sem2) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+
+    child_arg = &child_argv[0];
+    *child_arg++ = "semapong";
+    if (debug_mode != PR_FALSE) {
+        *child_arg++ = "-d";
+    }
+    if (iterations != ITERATIONS) {
+        *child_arg++ = "-c";
+        PR_snprintf(iterations_buf, sizeof(iterations_buf), "%d", iterations);
+        *child_arg++ = iterations_buf;
+    }
+    *child_arg = NULL;
+    proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
+    if (NULL == proc) {
+        fprintf(stderr, "PR_CreateProcess failed\n");
+        exit(1);
+    }
+
+    /*
+     * Process 1 waits on semaphore 1 and posts to semaphore 2.
+     */
+    for (i = 0; i < iterations; i++) {
+        if (PR_WaitSemaphore(sem1) == PR_FAILURE) {
+            fprintf(stderr, "PR_WaitSemaphore failed\n");
+            exit(1);
+        }
+        if (*counter_addr == 2*i) {
+            if (debug_mode) printf("process 1: counter = %d\n", *counter_addr);
+        } else {
+            fprintf(stderr, "process 1: counter should be %d but is %d\n",
+                    2*i, *counter_addr);
+            exit(1);
+        }
+        (*counter_addr)++;
+        if (PR_PostSemaphore(sem2) == PR_FAILURE) {
+            fprintf(stderr, "PR_PostSemaphore failed\n");
+            exit(1);
+        }
+    }
+    if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_DetachSharedMemory failed\n");
+        exit(1);
+    }
+    if (PR_CloseSharedMemory(shm) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSharedMemory failed\n");
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem1) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+    if (PR_CloseSemaphore(sem2) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+
+    if (PR_WaitProcess(proc, &exit_code) == PR_FAILURE) {
+        fprintf(stderr, "PR_WaitProcess failed\n");
+        exit(1);
+    }
+    if (exit_code != 0) {
+        fprintf(stderr, "process 2 failed with exit code %d\n", exit_code);
+        exit(1);
+    }
+
+    if (PR_DeleteSharedMemory(SHM_NAME) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSharedMemory failed\n");
+    }
+    if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+    }
+    if (PR_DeleteSemaphore(SEM_NAME2) == PR_FAILURE) {
+        fprintf(stderr, "PR_DeleteSemaphore failed\n");
+    }
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/semapong.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/semapong.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,147 @@
+/* -*- 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 "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+
+#define SHM_NAME "/tmp/counter"
+#define SEM_NAME1 "/tmp/foo.sem"
+#define SEM_NAME2 "/tmp/bar.sem"
+#define ITERATIONS 1000
+
+static PRBool debug_mode = PR_FALSE;
+static PRIntn iterations = ITERATIONS;
+static PRSem *sem1, *sem2;
+
+static void Help(void)
+{
+    fprintf(stderr, "semapong test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-c <count>   loop count         (%d)\n", ITERATIONS);
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PRIntn i;
+    PRSharedMemory *shm;
+    PRIntn *counter_addr;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dc:h");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'c':  /* loop count */
+                iterations = atoi(opt->value);
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    shm = PR_OpenSharedMemory(SHM_NAME, sizeof(*counter_addr), 0, 0666);
+    if (NULL == shm) {
+        fprintf(stderr, "PR_OpenSharedMemory failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    sem1 = PR_OpenSemaphore(SEM_NAME1, 0, 0, 0);
+    if (NULL == sem1) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    sem2 = PR_OpenSemaphore(SEM_NAME2, 0, 0, 0);
+    if (NULL == sem2) {
+        fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+
+    counter_addr = PR_AttachSharedMemory(shm, 0);
+    if (NULL == counter_addr) {
+        fprintf(stderr, "PR_AttachSharedMemory failed\n");
+        exit(1);
+    }
+
+    /*
+     * Process 2 waits on semaphore 2 and posts to semaphore 1.
+     */
+    for (i = 0; i < iterations; i++) {
+        if (PR_WaitSemaphore(sem2) == PR_FAILURE) {
+            fprintf(stderr, "PR_WaitSemaphore failed\n");
+            exit(1);
+        }
+        if (*counter_addr == 2*i+1) {
+            if (debug_mode) printf("process 2: counter = %d\n", *counter_addr);
+        } else {
+            fprintf(stderr, "process 2: counter should be %d but is %d\n",
+                    2*i+1, *counter_addr);
+            exit(1);
+        }
+        (*counter_addr)++;
+        if (PR_PostSemaphore(sem1) == PR_FAILURE) {
+            fprintf(stderr, "PR_PostSemaphore failed\n");
+            exit(1);
+        }
+    }
+    if (PR_DetachSharedMemory(shm, counter_addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_DetachSharedMemory failed\n");
+        exit(1);
+    }
+    if (PR_CloseSharedMemory(shm) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSharedMemory failed\n");
+        exit(1);
+    }
+    if (PR_CloseSemaphore(sem1) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+    if (PR_CloseSemaphore(sem2) == PR_FAILURE) {
+        fprintf(stderr, "PR_CloseSemaphore failed\n");
+    }
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sendzlf.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sendzlf.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,246 @@
+/* -*- 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 ***** */
+
+/*
+ * Test: sendzlf.c 
+ *
+ * Description: send a zero-length file with PR_SendFile and
+ * PR_TransmitFile.
+ */
+
+#define ZERO_LEN_FILE_NAME "zerolen.tmp"
+#define HEADER_STR "Header"
+#define HEADER_LEN 6 /* length of HEADER_STR, not counting the null byte */
+#define TRAILER_STR "Trailer"
+#define TRAILER_LEN 7 /* length of TRAILER_STR, not counting the null byte */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void ClientThread(void *arg)
+{
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    PRUint16 port = (PRUint16) arg;
+    char buf[1024];
+    char *bufPtr;
+    PRInt32 nbytes;
+    PRInt32 ntotal;
+    PRInt32 nexpected;
+
+    sock = PR_NewTCPSocket();
+    if (NULL == sock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    if (PR_InitializeNetAddr(PR_IpAddrLoopback, port, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+        fprintf(stderr, "PR_Connect failed\n");
+        exit(1);
+    }
+    ntotal = 0;
+    bufPtr = buf;
+    while ((nbytes = PR_Read(sock, bufPtr, sizeof(buf)-ntotal)) > 0) {
+        ntotal += nbytes;
+        bufPtr += nbytes;
+    }
+    if (-1 == nbytes) {
+        fprintf(stderr, "PR_Read failed\n");
+        exit(1);
+    }
+    nexpected = HEADER_LEN+TRAILER_LEN+TRAILER_LEN+HEADER_LEN+HEADER_LEN;
+    if (ntotal != nexpected) {
+        fprintf(stderr, "total bytes read should be %d but is %d\n",
+                nexpected, ntotal);
+        exit(1);
+    }
+    if (memcmp(buf, HEADER_STR TRAILER_STR TRAILER_STR HEADER_STR HEADER_STR,
+            nexpected) != 0) {
+        fprintf(stderr, "wrong data is received\n");
+        exit(1);
+    }
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+static void ServerThread(void *arg)
+{
+    PRFileDesc *listenSock = (PRFileDesc *) arg;
+    PRFileDesc *acceptSock;
+    PRFileDesc *file;
+    PRSendFileData sfd;
+    char header[1024], trailer[1024];
+    PRInt32 nbytes;
+
+    /* Create a zero-length file */
+    file = PR_Open(ZERO_LEN_FILE_NAME,
+            PR_CREATE_FILE|PR_TRUNCATE|PR_RDWR, 0666);
+    if (NULL == file) {
+        fprintf(stderr, "PR_Open failed\n");
+        exit(1);
+    }
+    sfd.fd = file;
+    sfd.file_offset = 0;
+    sfd.file_nbytes = 0;
+    memcpy(header, HEADER_STR, HEADER_LEN);
+    memcpy(trailer, TRAILER_STR, TRAILER_LEN);
+    sfd.header = header;
+    sfd.hlen = HEADER_LEN;
+    sfd.trailer = trailer;
+    sfd.tlen = TRAILER_LEN;
+    acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == acceptSock) {
+        fprintf(stderr, "PR_Accept failed\n");
+        exit(1);
+    }
+    /* Send both header and trailer */
+    nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+            PR_INTERVAL_NO_TIMEOUT);
+    if (HEADER_LEN+TRAILER_LEN != nbytes) {
+        fprintf(stderr, "PR_SendFile should return %d but returned %d\n",
+                HEADER_LEN+TRAILER_LEN, nbytes);
+        exit(1);
+    }
+    /* Trailer only, no header */
+    sfd.hlen = 0;
+    nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+            PR_INTERVAL_NO_TIMEOUT);
+    if (TRAILER_LEN != nbytes) {
+        fprintf(stderr, "PR_SendFile should return %d but returned %d\n",
+                TRAILER_LEN, nbytes);
+        exit(1);
+    }
+    /* Header only, no trailer */
+    sfd.hlen = HEADER_LEN;
+    sfd.tlen = 0;
+    nbytes = PR_SendFile(acceptSock, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+            PR_INTERVAL_NO_TIMEOUT);
+    if (HEADER_LEN != nbytes) {
+        fprintf(stderr, "PR_SendFile should return %d but returned %d\n",
+                HEADER_LEN, nbytes);
+        exit(1);
+    }
+    /* Try PR_TransmitFile */
+    nbytes = PR_TransmitFile(acceptSock, file, header, HEADER_LEN,
+            PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT);
+    if (HEADER_LEN != nbytes) {
+        fprintf(stderr, "PR_TransmitFile should return %d but returned %d\n",
+                HEADER_LEN, nbytes);
+        exit(1);
+    }
+    if (PR_Close(acceptSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_Close(file) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_Delete(ZERO_LEN_FILE_NAME) == PR_FAILURE) {
+        fprintf(stderr, "PR_Delete failed\n");
+        exit(1);
+    }
+}
+
+int main()
+{
+    PRFileDesc *listenSock;
+    PRThread *clientThread;
+    PRThread *serverThread;
+    PRNetAddr addr;
+    PRThreadScope scope = PR_GLOBAL_THREAD;
+
+    listenSock = PR_NewTCPSocket();
+    if (NULL == listenSock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    /* Find out what port number we are bound to. */
+    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetSockName failed\n");
+        exit(1);
+    }
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+            ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)),
+            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
+    if (NULL == clientThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    serverThread = PR_CreateThread(PR_USER_THREAD,
+            ServerThread, listenSock,
+            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
+    if (NULL == serverThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(clientThread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(serverThread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    if (PR_Close(listenSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/server_test.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/server_test.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,635 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**
+** This server simulates a server running in loopback mode.
+**
+** The idea is that a single server is created.  The server initially creates
+** a number of worker threads.  Then, with the server running, a number of 
+** clients are created which start requesting service from the server.
+**
+**
+** 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. 
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprthred.h"
+
+#include <string.h>
+
+#define PORT 15004
+#define THREAD_STACKSIZE 0
+
+#define PASS 0
+#define FAIL 1
+static int debug_mode = 0;
+
+static int _iterations = 1000;
+static int _clients = 1;
+static int _client_data = 250;
+static int _server_data = (8*1024);
+
+static PRThreadScope ServerScope, ClientScope;
+
+#define SERVER "Server"
+#define MAIN   "Main"
+
+#define SERVER_STATE_STARTUP 0
+#define SERVER_STATE_READY   1
+#define SERVER_STATE_DYING   2
+#define SERVER_STATE_DEAD    4
+int       ServerState;
+PRLock    *ServerStateCVLock;
+PRCondVar *ServerStateCV;
+
+#undef DEBUGPRINTS
+#ifdef DEBUGPRINTS
+#define DPRINTF printf
+#else
+#define DPRINTF
+#endif
+
+
+/***********************************************************************
+** PRIVATE FUNCTION:    Test_Result
+** DESCRIPTION: Used in conjunction with the regress tool, prints out the
+**				status of the test case.
+** INPUTS:      PASS/FAIL
+** OUTPUTS:     None
+** RETURN:      None
+** SIDE EFFECTS:
+**      
+** RESTRICTIONS:
+**      None
+** MEMORY:      NA
+** ALGORITHM:   Determine what the status is and print accordingly.
+**      
+***********************************************************************/
+
+
+static void Test_Result (int result)
+{
+	switch (result)
+	{
+		case PASS:
+			printf ("PASS\n");
+			break;
+		case FAIL:
+			printf ("FAIL\n");
+			break;
+		default:
+			break;
+	}
+}
+
+static void do_work(void);
+
+/* --- Server state functions --------------------------------------------- */
+void
+SetServerState(char *waiter, PRInt32 state)
+{
+    PR_Lock(ServerStateCVLock);
+    ServerState = state;
+    PR_NotifyCondVar(ServerStateCV);
+
+	if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state);
+
+    PR_Unlock(ServerStateCVLock);
+}
+
+int
+WaitServerState(char *waiter, PRInt32 state)
+{
+    PRInt32 rv;
+
+    PR_Lock(ServerStateCVLock);
+
+    if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state);
+
+    while(!(ServerState & state))
+        PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT);
+    rv = ServerState;
+
+    if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", 
+        waiter, state, ServerState);
+    PR_Unlock(ServerStateCVLock);
+
+    return rv;
+}
+
+/* --- Server Functions ------------------------------------------- */
+
+PRLock *workerThreadsLock;
+PRInt32 workerThreads;
+PRInt32 workerThreadsBusy;
+
+void
+WorkerThreadFunc(void *_listenSock)
+{
+    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
+    PRInt32 bytesRead;
+    PRInt32 bytesWritten;
+    char *dataBuf;
+    char *sendBuf;
+
+    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
+            _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
+    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
+    if (!dataBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+
+    if (debug_mode) DPRINTF("\tServer worker thread running\n");
+
+    while(1) {
+        PRInt32 bytesToRead = _client_data;
+        PRInt32 bytesToWrite = _server_data;
+        PRFileDesc *newSock;
+        PRNetAddr *rAddr;
+        PRInt32 loops = 0;
+
+        loops++;
+
+        if (debug_mode) DPRINTF("\tServer thread going into accept\n");
+
+        bytesRead = PR_AcceptRead(listenSock, 
+                                  &newSock,
+                                  &rAddr,
+                                  dataBuf,
+                                  bytesToRead,
+                                  PR_INTERVAL_NO_TIMEOUT);
+
+        if (bytesRead < 0) {
+            if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
+        
+        PR_AtomicIncrement(&workerThreadsBusy);
+        if (workerThreadsBusy == workerThreads) {
+
+            PR_Lock(workerThreadsLock);
+            if (workerThreadsBusy == workerThreads) {
+                PRThread *WorkerThread;
+
+                WorkerThread = PR_CreateThread(
+                                  PR_SYSTEM_THREAD,
+                                  WorkerThreadFunc,
+                                  listenSock,
+                                  PR_PRIORITY_NORMAL,
+                                  ServerScope,
+                                  PR_UNJOINABLE_THREAD,
+                                  THREAD_STACKSIZE);
+
+                if (!WorkerThread) {
+                    if (debug_mode) printf("Error creating client thread %d\n", workerThreads);
+                } else {
+                    PR_AtomicIncrement(&workerThreads);
+                    if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads);
+                }
+            }
+            PR_Unlock(workerThreadsLock);
+        }
+ 
+        bytesToRead -= bytesRead;
+        while (bytesToRead) {
+            bytesRead = PR_Recv(newSock, 
+                                dataBuf, 
+                                bytesToRead, 
+                                0, 
+                                PR_INTERVAL_NO_TIMEOUT);
+            if (bytesRead < 0) {
+                if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead);
+                continue;
+            }
+            if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead);
+        }
+
+        bytesWritten = PR_Send(newSock,
+                               sendBuf, 
+                               bytesToWrite, 
+                               0, 
+                               PR_INTERVAL_NO_TIMEOUT);
+        if (bytesWritten != _server_data) {
+            if (debug_mode) printf("\tError sending data to client (%d, %d)\n", 
+                bytesWritten, PR_GetOSError());
+        } else {
+            if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten);
+        }	
+
+        PR_Close(newSock);
+        PR_AtomicDecrement(&workerThreadsBusy);
+    }
+}
+
+PRFileDesc *
+ServerSetup(void)
+{
+    PRFileDesc *listenSocket;
+    PRNetAddr serverAddr;
+    PRThread *WorkerThread;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+		else Test_Result(FAIL);
+        return NULL;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
+                PR_GetOSError());
+		else Test_Result(FAIL);
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+		else Test_Result(FAIL);
+        PR_Close(listenSocket);
+
+        return NULL;
+    }
+
+    /* Create Clients */
+    workerThreads = 0;
+    workerThreadsBusy = 0;
+
+    workerThreadsLock = PR_NewLock();
+
+    WorkerThread = PR_CreateThread(
+                      PR_SYSTEM_THREAD,
+                      WorkerThreadFunc,
+                      listenSocket,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_UNJOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+
+    if (!WorkerThread) {
+        if (debug_mode) printf("error creating working thread\n");
+        PR_Close(listenSocket);
+        return NULL;
+    }
+    PR_AtomicIncrement(&workerThreads);
+    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");
+
+    return listenSocket;
+}
+
+/* The main server loop */
+void
+ServerThreadFunc(void *unused)
+{
+    PRFileDesc *listenSocket;
+
+    /* Do setup */
+    listenSocket = ServerSetup();
+
+    if (!listenSocket) {
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    } else {
+
+        if (debug_mode) DPRINTF("\tServer up\n");
+
+        /* Tell clients they can start now. */
+        SetServerState(SERVER, SERVER_STATE_READY);
+
+        /* Now wait for server death signal */
+        WaitServerState(SERVER, SERVER_STATE_DYING);
+
+        /* Cleanup */
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    }
+}
+
+/* --- Client Functions ------------------------------------------- */
+
+PRInt32 numRequests;
+PRInt32 numClients;
+PRMonitor *clientMonitor;
+
+void
+ClientThreadFunc(void *unused)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSocket;
+    char *sendBuf;
+    char *recvBuf;
+    PRInt32 rv;
+    PRInt32 bytesNeeded;
+
+    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
+    if (!recvBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    while(numRequests > 0) {
+
+        if ( (numRequests % 10) == 0 )
+            if (debug_mode) printf(".");
+        if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests);
+
+        clientSocket = PR_NewTCPSocket();
+        if (!clientSocket) {
+            if (debug_mode) printf("Client error creating socket: OS error %d\n",
+		    PR_GetOSError());
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connecting\n");
+
+        rv = PR_Connect(clientSocket, 
+                        &serverAddr,
+                        PR_INTERVAL_NO_TIMEOUT);
+        if (!clientSocket) {
+            if (debug_mode) printf("\tClient error connecting\n");
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connected\n");
+
+        rv = PR_Send(clientSocket, 
+                     sendBuf, 
+                     _client_data, 
+                     0, 
+                     PR_INTERVAL_NO_TIMEOUT);
+        if (rv != _client_data) {
+            if (debug_mode) printf("Client error sending data (%d)\n", rv);
+            PR_Close(clientSocket);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv);
+
+        bytesNeeded = _server_data;
+        while(bytesNeeded) {
+            rv = PR_Recv(clientSocket, 
+                         recvBuf, 
+                         bytesNeeded, 
+                         0, 
+                         PR_INTERVAL_NO_TIMEOUT);
+            if (rv <= 0) {
+                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", 
+                    rv, (_server_data - bytesNeeded), _server_data);
+                break;
+            }
+            if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
+            bytesNeeded -= rv;
+        }
+
+        PR_Close(clientSocket);
+ 
+        PR_AtomicDecrement(&numRequests);
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    --numClients;
+    PR_Notify(clientMonitor);
+    PR_ExitMonitor(clientMonitor);
+
+    PR_DELETE(sendBuf);
+    PR_DELETE(recvBuf);
+}
+
+void
+RunClients(void)
+{
+    PRInt32 index;
+
+    numRequests = _iterations;
+    numClients = _clients;
+    clientMonitor = PR_NewMonitor();
+
+    for (index=0; index<_clients; index++) {
+        PRThread *clientThread;
+
+  
+        clientThread = PR_CreateThread(
+                          PR_USER_THREAD,
+                          ClientThreadFunc,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          ClientScope,
+                          PR_UNJOINABLE_THREAD,
+                          THREAD_STACKSIZE);
+
+        if (!clientThread) {
+            if (debug_mode) printf("\terror creating client thread %d\n", index);
+        } else
+            if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients);
+
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    while(numClients)
+        PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT);
+    PR_ExitMonitor(clientMonitor);
+}
+
+/* --- Main Function ---------------------------------------------- */
+
+static
+void do_work()
+{
+    PRThread *ServerThread;
+    PRInt32 state;
+
+    SetServerState(MAIN, SERVER_STATE_STARTUP);
+    ServerThread = PR_CreateThread(
+                      PR_USER_THREAD,
+                      ServerThreadFunc,
+                      NULL,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_JOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+    if (!ServerThread) {
+        if (debug_mode) printf("error creating main server thread\n");
+        return;
+    }
+
+    /* Wait for server to be ready */
+    state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD);
+
+    if (!(state & SERVER_STATE_DEAD)) {
+        /* Run Test Clients */
+        RunClients();
+
+        /* Send death signal to server */
+        SetServerState(MAIN, SERVER_STATE_DYING);
+    }
+
+    PR_JoinThread(ServerThread);
+}
+
+static void do_workUU(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workUK(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+static void do_workKU(void)
+{
+    ServerScope = PR_GLOBAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workKK(void)
+{
+    ServerScope = PR_GLOBAL_THREAD;
+    ClientScope = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+main(int argc, char **argv)
+{
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+    if (debug_mode) {
+		printf("Enter number of iterations: \n");
+		scanf("%d", &_iterations);
+		printf("Enter number of clients   : \n");
+		scanf("%d", &_clients);
+		printf("Enter size of client data : \n");
+		scanf("%d", &_client_data);
+		printf("Enter size of server data : \n");
+		scanf("%d", &_server_data);
+	}
+	else {
+		_iterations = 10;
+	    _clients = 1;
+		_client_data = 10;
+		_server_data = 10;
+	}
+	
+    if (debug_mode) {
+		printf("\n\n%d iterations with %d client threads.\n", 
+        _iterations, _clients);
+		printf("Sending %d bytes of client data and %d bytes of server data\n", 
+        _client_data, _server_data);
+	}
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    ServerStateCVLock = PR_NewLock();
+    ServerStateCV = PR_NewCondVar(ServerStateCVLock);
+
+    Measure(do_workUU, "server loop user/user");
+ #if 0 
+    Measure(do_workUK, "server loop user/kernel");
+    Measure(do_workKU, "server loop kernel/user");
+    Measure(do_workKK, "server loop kernel/kernel");
+ #endif 
+
+    PR_Cleanup();
+
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_kk.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_kk.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,614 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**
+** This server simulates a server running in loopback mode.
+**
+** The idea is that a single server is created.  The server initially creates
+** a number of worker threads.  Then, with the server running, a number of 
+** clients are created which start requesting service from the server.
+**
+**
+** 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprthred.h"
+
+#include <string.h>
+
+#define PORT 15004
+#define THREAD_STACKSIZE 0
+
+static int _iterations = 1000;
+static int _clients = 1;
+static int _client_data = 250;
+static int _server_data = (8*1024);
+
+static PRThreadScope ServerScope, ClientScope;
+
+#define SERVER "Server"
+#define MAIN   "Main"
+
+#define SERVER_STATE_STARTUP 0
+#define SERVER_STATE_READY   1
+#define SERVER_STATE_DYING   2
+#define SERVER_STATE_DEAD    4
+int       ServerState;
+PRLock    *ServerStateCVLock;
+PRCondVar *ServerStateCV;
+
+#ifdef DEBUGPRINTS
+#define DPRINTF printf
+#else
+#define DPRINTF
+#endif
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+static void do_work(void);
+
+/* --- Server state functions --------------------------------------------- */
+void
+SetServerState(char *waiter, PRInt32 state)
+{
+    PR_Lock(ServerStateCVLock);
+    ServerState = state;
+    PR_NotifyCondVar(ServerStateCV);
+
+	if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state);
+
+    PR_Unlock(ServerStateCVLock);
+}
+
+int
+WaitServerState(char *waiter, PRInt32 state)
+{
+    PRInt32 rv;
+
+    PR_Lock(ServerStateCVLock);
+
+    if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state);
+
+    while(!(ServerState & state))
+        PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT);
+    rv = ServerState;
+
+    if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", 
+        waiter, state, ServerState);
+    PR_Unlock(ServerStateCVLock);
+
+    return rv;
+}
+
+/* --- Server Functions ------------------------------------------- */
+
+PRLock *workerThreadsLock;
+PRInt32 workerThreads;
+PRInt32 workerThreadsBusy;
+
+void
+WorkerThreadFunc(void *_listenSock)
+{
+    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
+    PRInt32 bytesRead;
+    PRInt32 bytesWritten;
+    char *dataBuf;
+    char *sendBuf;
+
+    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
+            _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
+    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
+    if (!dataBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+
+    if (debug_mode) DPRINTF("\tServer worker thread running\n");
+
+    while(1) {
+        PRInt32 bytesToRead = _client_data;
+        PRInt32 bytesToWrite = _server_data;
+        PRFileDesc *newSock;
+        PRNetAddr *rAddr;
+        PRInt32 loops = 0;
+
+        loops++;
+
+        if (debug_mode) DPRINTF("\tServer thread going into accept\n");
+
+        bytesRead = PR_AcceptRead(listenSock, 
+                                  &newSock,
+                                  &rAddr,
+                                  dataBuf,
+                                  bytesToRead,
+                                  PR_INTERVAL_NO_TIMEOUT);
+
+        if (bytesRead < 0) {
+            if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
+        
+        PR_AtomicIncrement(&workerThreadsBusy);
+        if (workerThreadsBusy == workerThreads) {
+
+            PR_Lock(workerThreadsLock);
+            if (workerThreadsBusy == workerThreads) {
+                PRThread *WorkerThread;
+
+                WorkerThread = PR_CreateThread(
+                                  PR_SYSTEM_THREAD,
+                                  WorkerThreadFunc,
+                                  listenSock,
+                                  PR_PRIORITY_NORMAL,
+                                  ServerScope,
+                                  PR_UNJOINABLE_THREAD,
+                                  THREAD_STACKSIZE);
+
+                if (!WorkerThread) {
+                    if (debug_mode) printf("Error creating client thread %d\n", workerThreads);
+                } else {
+                    PR_AtomicIncrement(&workerThreads);
+                    if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads);
+                }
+            }
+            PR_Unlock(workerThreadsLock);
+        }
+ 
+        bytesToRead -= bytesRead;
+        while (bytesToRead) {
+            bytesRead = PR_Recv(newSock, 
+                                dataBuf, 
+                                bytesToRead, 
+                                0, 
+                                PR_INTERVAL_NO_TIMEOUT);
+            if (bytesRead < 0) {
+                if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead);
+                continue;
+            }
+            if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead);
+        }
+
+        bytesWritten = PR_Send(newSock,
+                               sendBuf, 
+                               bytesToWrite, 
+                               0, 
+                               PR_INTERVAL_NO_TIMEOUT);
+        if (bytesWritten != _server_data) {
+            if (debug_mode) printf("\tError sending data to client (%d, %d)\n", 
+                bytesWritten, PR_GetOSError());
+        } else {
+            if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten);
+        }
+
+        PR_Close(newSock);
+        PR_AtomicDecrement(&workerThreadsBusy);
+    }
+}
+
+PRFileDesc *
+ServerSetup(void)
+{
+    PRFileDesc *listenSocket;
+    PRSocketOptionData sockOpt;
+    PRNetAddr serverAddr;
+    PRThread *WorkerThread;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+		else failed_already=1;
+        return NULL;
+    }
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error setting socket option: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+		else failed_already=1;
+        PR_Close(listenSocket);
+
+        return NULL;
+    }
+
+    /* Create Clients */
+    workerThreads = 0;
+    workerThreadsBusy = 0;
+
+    workerThreadsLock = PR_NewLock();
+
+    WorkerThread = PR_CreateThread(
+                      PR_SYSTEM_THREAD,
+                      WorkerThreadFunc,
+                      listenSocket,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_UNJOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+
+    if (!WorkerThread) {
+        if (debug_mode) printf("error creating working thread\n");
+        PR_Close(listenSocket);
+        return NULL;
+    }
+    PR_AtomicIncrement(&workerThreads);
+    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");
+
+    return listenSocket;
+}
+
+/* The main server loop */
+void
+ServerThreadFunc(void *unused)
+{
+    PRFileDesc *listenSocket;
+
+    /* Do setup */
+    listenSocket = ServerSetup();
+
+    if (!listenSocket) {
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    } else {
+
+        if (debug_mode) DPRINTF("\tServer up\n");
+
+        /* Tell clients they can start now. */
+        SetServerState(SERVER, SERVER_STATE_READY);
+
+        /* Now wait for server death signal */
+        WaitServerState(SERVER, SERVER_STATE_DYING);
+
+        /* Cleanup */
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    }
+}
+
+/* --- Client Functions ------------------------------------------- */
+
+PRInt32 numRequests;
+PRInt32 numClients;
+PRMonitor *clientMonitor;
+
+void
+ClientThreadFunc(void *unused)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSocket;
+    char *sendBuf;
+    char *recvBuf;
+    PRInt32 rv;
+    PRInt32 bytesNeeded;
+
+    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
+    if (!recvBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    while(numRequests > 0) {
+
+        if ( (numRequests % 10) == 0 )
+            if (debug_mode) printf(".");
+        if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests);
+
+        clientSocket = PR_NewTCPSocket();
+        if (!clientSocket) {
+            if (debug_mode) printf("Client error creating socket: OS error %d\n",
+		    PR_GetOSError());
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connecting\n");
+
+        rv = PR_Connect(clientSocket, 
+                        &serverAddr,
+                        PR_INTERVAL_NO_TIMEOUT);
+        if (!clientSocket) {
+            if (debug_mode) printf("\tClient error connecting\n");
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connected\n");
+
+        rv = PR_Send(clientSocket, 
+                     sendBuf, 
+                     _client_data, 
+                     0, 
+                     PR_INTERVAL_NO_TIMEOUT);
+        if (rv != _client_data) {
+            if (debug_mode) printf("Client error sending data (%d)\n", rv);
+            PR_Close(clientSocket);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv);
+
+        bytesNeeded = _server_data;
+        while(bytesNeeded) {
+            rv = PR_Recv(clientSocket, 
+                         recvBuf, 
+                         bytesNeeded, 
+                         0, 
+                         PR_INTERVAL_NO_TIMEOUT);
+            if (rv <= 0) {
+                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", 
+                    rv, (_server_data - bytesNeeded), _server_data);
+                break;
+            }
+            if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
+            bytesNeeded -= rv;
+        }
+
+        PR_Close(clientSocket);
+ 
+        PR_AtomicDecrement(&numRequests);
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    --numClients;
+    PR_Notify(clientMonitor);
+    PR_ExitMonitor(clientMonitor);
+
+    PR_DELETE(sendBuf);
+    PR_DELETE(recvBuf);
+}
+
+void
+RunClients(void)
+{
+    PRInt32 index;
+
+    numRequests = _iterations;
+    numClients = _clients;
+    clientMonitor = PR_NewMonitor();
+
+    for (index=0; index<_clients; index++) {
+        PRThread *clientThread;
+
+  
+        clientThread = PR_CreateThread(
+                          PR_USER_THREAD,
+                          ClientThreadFunc,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          ClientScope,
+                          PR_UNJOINABLE_THREAD,
+                          THREAD_STACKSIZE);
+
+        if (!clientThread) {
+            if (debug_mode) printf("\terror creating client thread %d\n", index);
+        } else
+            if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients);
+
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    while(numClients)
+        PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT);
+    PR_ExitMonitor(clientMonitor);
+}
+
+/* --- Main Function ---------------------------------------------- */
+
+static
+void do_work()
+{
+    PRThread *ServerThread;
+    PRInt32 state;
+
+    SetServerState(MAIN, SERVER_STATE_STARTUP);
+    ServerThread = PR_CreateThread(
+                      PR_USER_THREAD,
+                      ServerThreadFunc,
+                      NULL,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_JOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+    if (!ServerThread) {
+        if (debug_mode) printf("error creating main server thread\n");
+        return;
+    }
+
+    /* Wait for server to be ready */
+    state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD);
+
+    if (!(state & SERVER_STATE_DEAD)) {
+        /* Run Test Clients */
+        RunClients();
+
+        /* Send death signal to server */
+        SetServerState(MAIN, SERVER_STATE_DYING);
+    }
+
+    PR_JoinThread(ServerThread);
+}
+
+static void do_workUU(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workUK(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+static void do_workKU(void)
+{
+    ServerScope = PR_GLOBAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+static void do_workKK(void)
+{
+    ServerScope = PR_GLOBAL_THREAD;
+    ClientScope = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+int main(int argc, char **argv)
+{
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+    if (debug_mode) {
+		printf("Enter number of iterations: \n");
+		scanf("%d", &_iterations);
+		printf("Enter number of clients   : \n");
+		scanf("%d", &_clients);
+		printf("Enter size of client data : \n");
+		scanf("%d", &_client_data);
+		printf("Enter size of server data : \n");
+		scanf("%d", &_server_data);
+	}
+	else {
+		_iterations = 7;
+		_clients = 7;
+		_client_data = 100;
+		_server_data = 100;
+	}
+
+    if (debug_mode) {
+		printf("\n\n%d iterations with %d client threads.\n", 
+        _iterations, _clients);
+		printf("Sending %d bytes of client data and %d bytes of server data\n", 
+        _client_data, _server_data);
+	}
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    PR_SetThreadRecycleMode(64);
+
+    ServerStateCVLock = PR_NewLock();
+    ServerStateCV = PR_NewCondVar(ServerStateCVLock);
+
+
+    Measure(do_workKK, "server loop kernel/kernel");
+
+	PR_Cleanup();
+
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+    
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_ku.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_ku.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,594 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**
+** This server simulates a server running in loopback mode.
+**
+** The idea is that a single server is created.  The server initially creates
+** a number of worker threads.  Then, with the server running, a number of 
+** clients are created which start requesting service from the server.
+**
+**
+** 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprthred.h"
+
+#include <string.h>
+
+#define PORT 15004
+#define THREAD_STACKSIZE 0
+
+static int _iterations = 1000;
+static int _clients = 1;
+static int _client_data = 250;
+static int _server_data = (8*1024);
+
+static PRThreadScope ServerScope, ClientScope;
+
+#define SERVER "Server"
+#define MAIN   "Main"
+
+#define SERVER_STATE_STARTUP 0
+#define SERVER_STATE_READY   1
+#define SERVER_STATE_DYING   2
+#define SERVER_STATE_DEAD    4
+int       ServerState;
+PRLock    *ServerStateCVLock;
+PRCondVar *ServerStateCV;
+
+#ifdef DEBUGPRINTS
+#define DPRINTF printf
+#else
+#define DPRINTF
+#endif
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+static void do_work(void);
+
+/* --- Server state functions --------------------------------------------- */
+void
+SetServerState(char *waiter, PRInt32 state)
+{
+    PR_Lock(ServerStateCVLock);
+    ServerState = state;
+    PR_NotifyCondVar(ServerStateCV);
+
+	if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state);
+
+    PR_Unlock(ServerStateCVLock);
+}
+
+int
+WaitServerState(char *waiter, PRInt32 state)
+{
+    PRInt32 rv;
+
+    PR_Lock(ServerStateCVLock);
+
+    if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state);
+
+    while(!(ServerState & state))
+        PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT);
+    rv = ServerState;
+
+    if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", 
+        waiter, state, ServerState);
+    PR_Unlock(ServerStateCVLock);
+
+    return rv;
+}
+
+/* --- Server Functions ------------------------------------------- */
+
+PRLock *workerThreadsLock;
+PRInt32 workerThreads;
+PRInt32 workerThreadsBusy;
+
+void
+WorkerThreadFunc(void *_listenSock)
+{
+    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
+    PRInt32 bytesRead;
+    PRInt32 bytesWritten;
+    char *dataBuf;
+    char *sendBuf;
+
+    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
+            _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
+    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
+    if (!dataBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+
+    if (debug_mode) DPRINTF("\tServer worker thread running\n");
+
+    while(1) {
+        PRInt32 bytesToRead = _client_data;
+        PRInt32 bytesToWrite = _server_data;
+        PRFileDesc *newSock;
+        PRNetAddr *rAddr;
+        PRInt32 loops = 0;
+
+        loops++;
+
+        if (debug_mode) DPRINTF("\tServer thread going into accept\n");
+
+        bytesRead = PR_AcceptRead(listenSock, 
+                                  &newSock,
+                                  &rAddr,
+                                  dataBuf,
+                                  bytesToRead,
+                                  PR_INTERVAL_NO_TIMEOUT);
+
+        if (bytesRead < 0) {
+            if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
+        
+        PR_AtomicIncrement(&workerThreadsBusy);
+        if (workerThreadsBusy == workerThreads) {
+
+            PR_Lock(workerThreadsLock);
+            if (workerThreadsBusy == workerThreads) {
+                PRThread *WorkerThread;
+
+                WorkerThread = PR_CreateThread(
+                                  PR_SYSTEM_THREAD,
+                                  WorkerThreadFunc,
+                                  listenSock,
+                                  PR_PRIORITY_NORMAL,
+                                  ServerScope,
+                                  PR_UNJOINABLE_THREAD,
+                                  THREAD_STACKSIZE);
+
+                if (!WorkerThread) {
+                    if (debug_mode) printf("Error creating client thread %d\n", workerThreads);
+                } else {
+                    PR_AtomicIncrement(&workerThreads);
+                    if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads);
+                }
+            }
+            PR_Unlock(workerThreadsLock);
+        }
+ 
+        bytesToRead -= bytesRead;
+        while (bytesToRead) {
+            bytesRead = PR_Recv(newSock, 
+                                dataBuf, 
+                                bytesToRead, 
+                                0, 
+                                PR_INTERVAL_NO_TIMEOUT);
+            if (bytesRead < 0) {
+                if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead);
+                continue;
+            }
+            if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead);
+        }
+
+        bytesWritten = PR_Send(newSock,
+                               sendBuf, 
+                               bytesToWrite, 
+                               0, 
+                               PR_INTERVAL_NO_TIMEOUT);
+        if (bytesWritten != _server_data) {
+            if (debug_mode) printf("\tError sending data to client (%d, %d)\n", 
+                bytesWritten, PR_GetOSError());
+        } else {
+            if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten);
+        }
+
+        PR_Close(newSock);
+        PR_AtomicDecrement(&workerThreadsBusy);
+    }
+}
+
+PRFileDesc *
+ServerSetup(void)
+{
+    PRFileDesc *listenSocket;
+    PRSocketOptionData sockOpt;
+    PRNetAddr serverAddr;
+    PRThread *WorkerThread;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+		else failed_already=1;
+        return NULL;
+    }
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error setting socket option: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+		else failed_already=1;
+        PR_Close(listenSocket);
+
+        return NULL;
+    }
+
+    /* Create Clients */
+    workerThreads = 0;
+    workerThreadsBusy = 0;
+
+    workerThreadsLock = PR_NewLock();
+
+    WorkerThread = PR_CreateThread(
+                      PR_SYSTEM_THREAD,
+                      WorkerThreadFunc,
+                      listenSocket,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_UNJOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+
+    if (!WorkerThread) {
+        if (debug_mode) printf("error creating working thread\n");
+        PR_Close(listenSocket);
+        return NULL;
+    }
+    PR_AtomicIncrement(&workerThreads);
+    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");
+
+    return listenSocket;
+}
+
+/* The main server loop */
+void
+ServerThreadFunc(void *unused)
+{
+    PRFileDesc *listenSocket;
+
+    /* Do setup */
+    listenSocket = ServerSetup();
+
+    if (!listenSocket) {
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    } else {
+
+        if (debug_mode) DPRINTF("\tServer up\n");
+
+        /* Tell clients they can start now. */
+        SetServerState(SERVER, SERVER_STATE_READY);
+
+        /* Now wait for server death signal */
+        WaitServerState(SERVER, SERVER_STATE_DYING);
+
+        /* Cleanup */
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    }
+}
+
+/* --- Client Functions ------------------------------------------- */
+
+PRInt32 numRequests;
+PRInt32 numClients;
+PRMonitor *clientMonitor;
+
+void
+ClientThreadFunc(void *unused)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSocket;
+    char *sendBuf;
+    char *recvBuf;
+    PRInt32 rv;
+    PRInt32 bytesNeeded;
+
+    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
+    if (!recvBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    while(numRequests > 0) {
+
+        if ( (numRequests % 10) == 0 )
+            if (debug_mode) printf(".");
+        if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests);
+
+        clientSocket = PR_NewTCPSocket();
+        if (!clientSocket) {
+            if (debug_mode) printf("Client error creating socket: OS error %d\n",
+		    PR_GetOSError());
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connecting\n");
+
+        rv = PR_Connect(clientSocket, 
+                        &serverAddr,
+                        PR_INTERVAL_NO_TIMEOUT);
+        if (!clientSocket) {
+            if (debug_mode) printf("\tClient error connecting\n");
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connected\n");
+
+        rv = PR_Send(clientSocket, 
+                     sendBuf, 
+                     _client_data, 
+                     0, 
+                     PR_INTERVAL_NO_TIMEOUT);
+        if (rv != _client_data) {
+            if (debug_mode) printf("Client error sending data (%d)\n", rv);
+            PR_Close(clientSocket);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv);
+
+        bytesNeeded = _server_data;
+        while(bytesNeeded) {
+            rv = PR_Recv(clientSocket, 
+                         recvBuf, 
+                         bytesNeeded, 
+                         0, 
+                         PR_INTERVAL_NO_TIMEOUT);
+            if (rv <= 0) {
+                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", 
+                    rv, (_server_data - bytesNeeded), _server_data);
+                break;
+            }
+            if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
+            bytesNeeded -= rv;
+        }
+
+        PR_Close(clientSocket);
+ 
+        PR_AtomicDecrement(&numRequests);
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    --numClients;
+    PR_Notify(clientMonitor);
+    PR_ExitMonitor(clientMonitor);
+
+    PR_DELETE(sendBuf);
+    PR_DELETE(recvBuf);
+}
+
+void
+RunClients(void)
+{
+    PRInt32 index;
+
+    numRequests = _iterations;
+    numClients = _clients;
+    clientMonitor = PR_NewMonitor();
+
+    for (index=0; index<_clients; index++) {
+        PRThread *clientThread;
+
+  
+        clientThread = PR_CreateThread(
+                          PR_USER_THREAD,
+                          ClientThreadFunc,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          ClientScope,
+                          PR_UNJOINABLE_THREAD,
+                          THREAD_STACKSIZE);
+
+        if (!clientThread) {
+            if (debug_mode) printf("\terror creating client thread %d\n", index);
+        } else
+            if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients);
+
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    while(numClients)
+        PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT);
+    PR_ExitMonitor(clientMonitor);
+}
+
+/* --- Main Function ---------------------------------------------- */
+
+static
+void do_work()
+{
+    PRThread *ServerThread;
+    PRInt32 state;
+
+    SetServerState(MAIN, SERVER_STATE_STARTUP);
+    ServerThread = PR_CreateThread(
+                      PR_USER_THREAD,
+                      ServerThreadFunc,
+                      NULL,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_JOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+    if (!ServerThread) {
+        if (debug_mode) printf("error creating main server thread\n");
+        return;
+    }
+
+    /* Wait for server to be ready */
+    state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD);
+
+    if (!(state & SERVER_STATE_DEAD)) {
+        /* Run Test Clients */
+        RunClients();
+
+        /* Send death signal to server */
+        SetServerState(MAIN, SERVER_STATE_DYING);
+    }
+
+    PR_JoinThread(ServerThread);
+}
+
+
+static void do_workKU(void)
+{
+    ServerScope = PR_GLOBAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+main(int argc, char **argv)
+{
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+    if (debug_mode) {
+		printf("Enter number of iterations: \n");
+		scanf("%d", &_iterations);
+		printf("Enter number of clients   : \n");
+		scanf("%d", &_clients);
+		printf("Enter size of client data : \n");
+		scanf("%d", &_client_data);
+		printf("Enter size of server data : \n");
+		scanf("%d", &_server_data);
+	}
+	else {
+		_iterations = 7;
+		_clients = 7;
+		_client_data = 100;
+		_server_data = 100;
+	}
+
+    if (debug_mode) {
+		printf("\n\n%d iterations with %d client threads.\n", 
+        _iterations, _clients);
+		printf("Sending %d bytes of client data and %d bytes of server data\n", 
+        _client_data, _server_data);
+	}
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    PR_SetThreadRecycleMode(64);
+
+    ServerStateCVLock = PR_NewLock();
+    ServerStateCV = PR_NewCondVar(ServerStateCVLock);
+
+    Measure(do_workKU, "server loop kernel/user");
+
+    PR_Cleanup();
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_uk.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_uk.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,596 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**
+** This server simulates a server running in loopback mode.
+**
+** The idea is that a single server is created.  The server initially creates
+** a number of worker threads.  Then, with the server running, a number of 
+** clients are created which start requesting service from the server.
+**
+**
+** 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprthred.h"
+
+#include <string.h>
+
+#define PORT 15004
+#define THREAD_STACKSIZE 0
+
+static int _iterations = 1000;
+static int _clients = 1;
+static int _client_data = 250;
+static int _server_data = (8*1024);
+
+static PRThreadScope ServerScope, ClientScope;
+
+#define SERVER "Server"
+#define MAIN   "Main"
+
+#define SERVER_STATE_STARTUP 0
+#define SERVER_STATE_READY   1
+#define SERVER_STATE_DYING   2
+#define SERVER_STATE_DEAD    4
+int       ServerState;
+PRLock    *ServerStateCVLock;
+PRCondVar *ServerStateCV;
+
+#ifdef DEBUGPRINTS
+#define DPRINTF printf
+#else
+#define DPRINTF
+#endif
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+
+
+static void do_work(void);
+
+/* --- Server state functions --------------------------------------------- */
+void
+SetServerState(char *waiter, PRInt32 state)
+{
+    PR_Lock(ServerStateCVLock);
+    ServerState = state;
+    PR_NotifyCondVar(ServerStateCV);
+
+	if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state);
+
+    PR_Unlock(ServerStateCVLock);
+}
+
+int
+WaitServerState(char *waiter, PRInt32 state)
+{
+    PRInt32 rv;
+
+    PR_Lock(ServerStateCVLock);
+
+    if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state);
+
+    while(!(ServerState & state))
+        PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT);
+    rv = ServerState;
+
+    if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", 
+        waiter, state, ServerState);
+    PR_Unlock(ServerStateCVLock);
+
+    return rv;
+}
+
+/* --- Server Functions ------------------------------------------- */
+
+PRLock *workerThreadsLock;
+PRInt32 workerThreads;
+PRInt32 workerThreadsBusy;
+
+void
+WorkerThreadFunc(void *_listenSock)
+{
+    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
+    PRInt32 bytesRead;
+    PRInt32 bytesWritten;
+    char *dataBuf;
+    char *sendBuf;
+
+    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
+            _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
+    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
+    if (!dataBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+
+    if (debug_mode) DPRINTF("\tServer worker thread running\n");
+
+    while(1) {
+        PRInt32 bytesToRead = _client_data;
+        PRInt32 bytesToWrite = _server_data;
+        PRFileDesc *newSock;
+        PRNetAddr *rAddr;
+        PRInt32 loops = 0;
+
+        loops++;
+
+        if (debug_mode) DPRINTF("\tServer thread going into accept\n");
+
+        bytesRead = PR_AcceptRead(listenSock, 
+                                  &newSock,
+                                  &rAddr,
+                                  dataBuf,
+                                  bytesToRead,
+                                  PR_INTERVAL_NO_TIMEOUT);
+
+        if (bytesRead < 0) {
+            if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
+        
+        PR_AtomicIncrement(&workerThreadsBusy);
+        if (workerThreadsBusy == workerThreads) {
+
+            PR_Lock(workerThreadsLock);
+            if (workerThreadsBusy == workerThreads) {
+                PRThread *WorkerThread;
+
+                WorkerThread = PR_CreateThread(
+                                  PR_SYSTEM_THREAD,
+                                  WorkerThreadFunc,
+                                  listenSock,
+                                  PR_PRIORITY_NORMAL,
+                                  ServerScope,
+                                  PR_UNJOINABLE_THREAD,
+                                  THREAD_STACKSIZE);
+
+                if (!WorkerThread) {
+                    if (debug_mode) printf("Error creating client thread %d\n", workerThreads);
+                } else {
+                    PR_AtomicIncrement(&workerThreads);
+                    if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads);
+                }
+            }
+            PR_Unlock(workerThreadsLock);
+        }
+ 
+        bytesToRead -= bytesRead;
+        while (bytesToRead) {
+            bytesRead = PR_Recv(newSock, 
+                                dataBuf, 
+                                bytesToRead, 
+                                0, 
+                                PR_INTERVAL_NO_TIMEOUT);
+            if (bytesRead < 0) {
+                if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead);
+                continue;
+            }
+            if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead);
+        }
+
+        bytesWritten = PR_Send(newSock,
+                               sendBuf, 
+                               bytesToWrite, 
+                               0, 
+                               PR_INTERVAL_NO_TIMEOUT);
+        if (bytesWritten != _server_data) {
+            if (debug_mode) printf("\tError sending data to client (%d, %d)\n", 
+                bytesWritten, PR_GetOSError());
+        } else {
+            if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten);
+        }
+
+        PR_Close(newSock);
+        PR_AtomicDecrement(&workerThreadsBusy);
+    }
+}
+
+PRFileDesc *
+ServerSetup(void)
+{
+    PRFileDesc *listenSocket;
+    PRSocketOptionData sockOpt;
+    PRNetAddr serverAddr;
+    PRThread *WorkerThread;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+		else 
+        return NULL;
+    }
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error setting socket option: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+		else failed_already=1;
+        PR_Close(listenSocket);
+
+        return NULL;
+    }
+
+    /* Create Clients */
+    workerThreads = 0;
+    workerThreadsBusy = 0;
+
+    workerThreadsLock = PR_NewLock();
+
+    WorkerThread = PR_CreateThread(
+                      PR_SYSTEM_THREAD,
+                      WorkerThreadFunc,
+                      listenSocket,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_UNJOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+
+    if (!WorkerThread) {
+        if (debug_mode) printf("error creating working thread\n");
+        PR_Close(listenSocket);
+        return NULL;
+    }
+    PR_AtomicIncrement(&workerThreads);
+    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");
+
+    return listenSocket;
+}
+
+/* The main server loop */
+void
+ServerThreadFunc(void *unused)
+{
+    PRFileDesc *listenSocket;
+
+    /* Do setup */
+    listenSocket = ServerSetup();
+
+    if (!listenSocket) {
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    } else {
+
+        if (debug_mode) DPRINTF("\tServer up\n");
+
+        /* Tell clients they can start now. */
+        SetServerState(SERVER, SERVER_STATE_READY);
+
+        /* Now wait for server death signal */
+        WaitServerState(SERVER, SERVER_STATE_DYING);
+
+        /* Cleanup */
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    }
+}
+
+/* --- Client Functions ------------------------------------------- */
+
+PRInt32 numRequests;
+PRInt32 numClients;
+PRMonitor *clientMonitor;
+
+void
+ClientThreadFunc(void *unused)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSocket;
+    char *sendBuf;
+    char *recvBuf;
+    PRInt32 rv;
+    PRInt32 bytesNeeded;
+
+    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
+    if (!recvBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    while(numRequests > 0) {
+
+        if ( (numRequests % 10) == 0 )
+            if (debug_mode) printf(".");
+        if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests);
+
+        clientSocket = PR_NewTCPSocket();
+        if (!clientSocket) {
+            if (debug_mode) printf("Client error creating socket: OS error %d\n",
+		    PR_GetOSError());
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connecting\n");
+
+        rv = PR_Connect(clientSocket, 
+                        &serverAddr,
+                        PR_INTERVAL_NO_TIMEOUT);
+        if (!clientSocket) {
+            if (debug_mode) printf("\tClient error connecting\n");
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connected\n");
+
+        rv = PR_Send(clientSocket, 
+                     sendBuf, 
+                     _client_data, 
+                     0, 
+                     PR_INTERVAL_NO_TIMEOUT);
+        if (rv != _client_data) {
+            if (debug_mode) printf("Client error sending data (%d)\n", rv);
+            PR_Close(clientSocket);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv);
+
+        bytesNeeded = _server_data;
+        while(bytesNeeded) {
+            rv = PR_Recv(clientSocket, 
+                         recvBuf, 
+                         bytesNeeded, 
+                         0, 
+                         PR_INTERVAL_NO_TIMEOUT);
+            if (rv <= 0) {
+                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", 
+                    rv, (_server_data - bytesNeeded), _server_data);
+                break;
+            }
+            if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
+            bytesNeeded -= rv;
+        }
+
+        PR_Close(clientSocket);
+ 
+        PR_AtomicDecrement(&numRequests);
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    --numClients;
+    PR_Notify(clientMonitor);
+    PR_ExitMonitor(clientMonitor);
+
+    PR_DELETE(sendBuf);
+    PR_DELETE(recvBuf);
+}
+
+void
+RunClients(void)
+{
+    PRInt32 index;
+
+    numRequests = _iterations;
+    numClients = _clients;
+    clientMonitor = PR_NewMonitor();
+
+    for (index=0; index<_clients; index++) {
+        PRThread *clientThread;
+
+  
+        clientThread = PR_CreateThread(
+                          PR_USER_THREAD,
+                          ClientThreadFunc,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          ClientScope,
+                          PR_UNJOINABLE_THREAD,
+                          THREAD_STACKSIZE);
+
+        if (!clientThread) {
+            if (debug_mode) printf("\terror creating client thread %d\n", index);
+        } else
+            if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients);
+
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    while(numClients)
+        PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT);
+    PR_ExitMonitor(clientMonitor);
+}
+
+/* --- Main Function ---------------------------------------------- */
+
+static
+void do_work()
+{
+    PRThread *ServerThread;
+    PRInt32 state;
+
+    SetServerState(MAIN, SERVER_STATE_STARTUP);
+    ServerThread = PR_CreateThread(
+                      PR_USER_THREAD,
+                      ServerThreadFunc,
+                      NULL,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_JOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+    if (!ServerThread) {
+        if (debug_mode) printf("error creating main server thread\n");
+        return;
+    }
+
+    /* Wait for server to be ready */
+    state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD);
+
+    if (!(state & SERVER_STATE_DEAD)) {
+        /* Run Test Clients */
+        RunClients();
+
+        /* Send death signal to server */
+        SetServerState(MAIN, SERVER_STATE_DYING);
+    }
+
+    PR_JoinThread(ServerThread);
+}
+
+
+static void do_workUK(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_GLOBAL_THREAD;
+    do_work();
+}
+
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+main(int argc, char **argv)
+{
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+    if (debug_mode) {
+		printf("Enter number of iterations: \n");
+		scanf("%d", &_iterations);
+		printf("Enter number of clients   : \n");
+		scanf("%d", &_clients);
+		printf("Enter size of client data : \n");
+		scanf("%d", &_client_data);
+		printf("Enter size of server data : \n");
+		scanf("%d", &_server_data);
+	}
+	else {
+		_iterations = 7;
+		_clients = 7;
+		_client_data = 100;
+		_server_data = 100;
+	}
+
+    if (debug_mode) {
+		printf("\n\n%d iterations with %d client threads.\n", 
+        _iterations, _clients);
+		printf("Sending %d bytes of client data and %d bytes of server data\n", 
+        _client_data, _server_data);
+	}
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    PR_SetThreadRecycleMode(64);
+
+    ServerStateCVLock = PR_NewLock();
+    ServerStateCV = PR_NewCondVar(ServerStateCVLock);
+
+    Measure(do_workUK, "server loop user/kernel");
+
+    PR_Cleanup();
+
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_uu.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/servr_uu.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,594 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**
+** This server simulates a server running in loopback mode.
+**
+** The idea is that a single server is created.  The server initially creates
+** a number of worker threads.  Then, with the server running, a number of 
+** clients are created which start requesting service from the server.
+**
+**
+** 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
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprthred.h"
+
+#include <string.h>
+
+#define PORT 15004
+#define THREAD_STACKSIZE 0
+
+static int _iterations = 1000;
+static int _clients = 1;
+static int _client_data = 250;
+static int _server_data = (8*1024);
+
+static PRThreadScope ServerScope, ClientScope;
+
+#define SERVER "Server"
+#define MAIN   "Main"
+
+#define SERVER_STATE_STARTUP 0
+#define SERVER_STATE_READY   1
+#define SERVER_STATE_DYING   2
+#define SERVER_STATE_DEAD    4
+int       ServerState;
+PRLock    *ServerStateCVLock;
+PRCondVar *ServerStateCV;
+
+#ifdef DEBUGPRINTS
+#define DPRINTF printf
+#else
+#define DPRINTF
+#endif
+
+PRIntn failed_already=0;
+PRIntn debug_mode;
+
+static void do_work(void);
+
+/* --- Server state functions --------------------------------------------- */
+void
+SetServerState(char *waiter, PRInt32 state)
+{
+    PR_Lock(ServerStateCVLock);
+    ServerState = state;
+    PR_NotifyCondVar(ServerStateCV);
+
+	if (debug_mode) DPRINTF("\t%s changed state to %d\n", waiter, state);
+
+    PR_Unlock(ServerStateCVLock);
+}
+
+int
+WaitServerState(char *waiter, PRInt32 state)
+{
+    PRInt32 rv;
+
+    PR_Lock(ServerStateCVLock);
+
+    if (debug_mode) DPRINTF("\t%s waiting for state %d\n", waiter, state);
+
+    while(!(ServerState & state))
+        PR_WaitCondVar(ServerStateCV, PR_INTERVAL_NO_TIMEOUT);
+    rv = ServerState;
+
+    if (debug_mode) DPRINTF("\t%s resuming from wait for state %d; state now %d\n", 
+        waiter, state, ServerState);
+    PR_Unlock(ServerStateCVLock);
+
+    return rv;
+}
+
+/* --- Server Functions ------------------------------------------- */
+
+PRLock *workerThreadsLock;
+PRInt32 workerThreads;
+PRInt32 workerThreadsBusy;
+
+void
+WorkerThreadFunc(void *_listenSock)
+{
+    PRFileDesc *listenSock = (PRFileDesc *)_listenSock;
+    PRInt32 bytesRead;
+    PRInt32 bytesWritten;
+    char *dataBuf;
+    char *sendBuf;
+
+    if (debug_mode) DPRINTF("\tServer buffer is %d bytes; %d data, %d netaddrs\n",
+            _client_data+(2*sizeof(PRNetAddr))+32, _client_data, (2*sizeof(PRNetAddr))+32);
+    dataBuf = (char *)PR_MALLOC(_client_data + 2*sizeof(PRNetAddr) + 32);
+    if (!dataBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+    sendBuf = (char *)PR_MALLOC(_server_data *sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tServer could not malloc space!?\n");
+
+    if (debug_mode) DPRINTF("\tServer worker thread running\n");
+
+    while(1) {
+        PRInt32 bytesToRead = _client_data;
+        PRInt32 bytesToWrite = _server_data;
+        PRFileDesc *newSock;
+        PRNetAddr *rAddr;
+        PRInt32 loops = 0;
+
+        loops++;
+
+        if (debug_mode) DPRINTF("\tServer thread going into accept\n");
+
+        bytesRead = PR_AcceptRead(listenSock, 
+                                  &newSock,
+                                  &rAddr,
+                                  dataBuf,
+                                  bytesToRead,
+                                  PR_INTERVAL_NO_TIMEOUT);
+
+        if (bytesRead < 0) {
+            if (debug_mode) printf("\tServer error in accept (%d)\n", bytesRead);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tServer accepted connection (%d bytes)\n", bytesRead);
+        
+        PR_AtomicIncrement(&workerThreadsBusy);
+        if (workerThreadsBusy == workerThreads) {
+
+            PR_Lock(workerThreadsLock);
+            if (workerThreadsBusy == workerThreads) {
+                PRThread *WorkerThread;
+
+                WorkerThread = PR_CreateThread(
+                                  PR_SYSTEM_THREAD,
+                                  WorkerThreadFunc,
+                                  listenSock,
+                                  PR_PRIORITY_NORMAL,
+                                  ServerScope,
+                                  PR_UNJOINABLE_THREAD,
+                                  THREAD_STACKSIZE);
+
+                if (!WorkerThread) {
+                    if (debug_mode) printf("Error creating client thread %d\n", workerThreads);
+                } else {
+                    PR_AtomicIncrement(&workerThreads);
+                    if (debug_mode) DPRINTF("\tServer creates worker (%d)\n", workerThreads);
+                }
+            }
+            PR_Unlock(workerThreadsLock);
+        }
+ 
+        bytesToRead -= bytesRead;
+        while (bytesToRead) {
+            bytesRead = PR_Recv(newSock, 
+                                dataBuf, 
+                                bytesToRead, 
+                                0, 
+                                PR_INTERVAL_NO_TIMEOUT);
+            if (bytesRead < 0) {
+                if (debug_mode) printf("\tServer error receiving data (%d)\n", bytesRead);
+                continue;
+            }
+            if (debug_mode) DPRINTF("\tServer received %d bytes\n", bytesRead);
+        }
+
+        bytesWritten = PR_Send(newSock,
+                               sendBuf, 
+                               bytesToWrite, 
+                               0, 
+                               PR_INTERVAL_NO_TIMEOUT);
+        if (bytesWritten != _server_data) {
+            if (debug_mode) printf("\tError sending data to client (%d, %d)\n", 
+                bytesWritten, PR_GetOSError());
+        } else {
+            if (debug_mode) DPRINTF("\tServer sent %d bytes\n", bytesWritten);
+        } 
+
+        PR_Close(newSock);
+        PR_AtomicDecrement(&workerThreadsBusy);
+    }
+}
+
+PRFileDesc *
+ServerSetup(void)
+{
+    PRFileDesc *listenSocket;
+    PRSocketOptionData sockOpt;
+    PRNetAddr serverAddr;
+    PRThread *WorkerThread;
+
+    if ( (listenSocket = PR_NewTCPSocket()) == NULL) {
+        if (debug_mode) printf("\tServer error creating listen socket\n");
+		else failed_already=1;
+        return NULL;
+    }
+
+    sockOpt.option = PR_SockOpt_Reuseaddr;
+    sockOpt.value.reuse_addr = PR_TRUE;
+    if ( PR_SetSocketOption(listenSocket, &sockOpt) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error setting socket option: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+
+    if ( PR_Bind(listenSocket, &serverAddr) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error binding to server address: OS error %d\n",
+                PR_GetOSError());
+		else failed_already=1;
+        PR_Close(listenSocket);
+        return NULL;
+    }
+
+    if ( PR_Listen(listenSocket, 128) == PR_FAILURE) {
+        if (debug_mode) printf("\tServer error listening to server socket\n");
+		else failed_already=1;
+        PR_Close(listenSocket);
+
+        return NULL;
+    }
+
+    /* Create Clients */
+    workerThreads = 0;
+    workerThreadsBusy = 0;
+
+    workerThreadsLock = PR_NewLock();
+
+    WorkerThread = PR_CreateThread(
+                      PR_SYSTEM_THREAD,
+                      WorkerThreadFunc,
+                      listenSocket,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_UNJOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+
+    if (!WorkerThread) {
+        if (debug_mode) printf("error creating working thread\n");
+        PR_Close(listenSocket);
+        return NULL;
+    }
+    PR_AtomicIncrement(&workerThreads);
+    if (debug_mode) DPRINTF("\tServer created primordial worker thread\n");
+
+    return listenSocket;
+}
+
+/* The main server loop */
+void
+ServerThreadFunc(void *unused)
+{
+    PRFileDesc *listenSocket;
+
+    /* Do setup */
+    listenSocket = ServerSetup();
+
+    if (!listenSocket) {
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    } else {
+
+        if (debug_mode) DPRINTF("\tServer up\n");
+
+        /* Tell clients they can start now. */
+        SetServerState(SERVER, SERVER_STATE_READY);
+
+        /* Now wait for server death signal */
+        WaitServerState(SERVER, SERVER_STATE_DYING);
+
+        /* Cleanup */
+        SetServerState(SERVER, SERVER_STATE_DEAD);
+    }
+}
+
+/* --- Client Functions ------------------------------------------- */
+
+PRInt32 numRequests;
+PRInt32 numClients;
+PRMonitor *clientMonitor;
+
+void
+ClientThreadFunc(void *unused)
+{
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSocket;
+    char *sendBuf;
+    char *recvBuf;
+    PRInt32 rv;
+    PRInt32 bytesNeeded;
+
+    sendBuf = (char *)PR_MALLOC(_client_data * sizeof(char));
+    if (!sendBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+    recvBuf = (char *)PR_MALLOC(_server_data * sizeof(char));
+    if (!recvBuf)
+        if (debug_mode) printf("\tClient could not malloc space!?\n");
+
+    memset(&serverAddr, 0, sizeof(PRNetAddr));
+    serverAddr.inet.family = PR_AF_INET;
+    serverAddr.inet.port = PR_htons(PORT);
+    serverAddr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+
+    while(numRequests > 0) {
+
+        if ( (numRequests % 10) == 0 )
+            if (debug_mode) printf(".");
+        if (debug_mode) DPRINTF("\tClient starting request %d\n", numRequests);
+
+        clientSocket = PR_NewTCPSocket();
+        if (!clientSocket) {
+            if (debug_mode) printf("Client error creating socket: OS error %d\n",
+		    PR_GetOSError());
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connecting\n");
+
+        rv = PR_Connect(clientSocket, 
+                        &serverAddr,
+                        PR_INTERVAL_NO_TIMEOUT);
+        if (!clientSocket) {
+            if (debug_mode) printf("\tClient error connecting\n");
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient connected\n");
+
+        rv = PR_Send(clientSocket, 
+                     sendBuf, 
+                     _client_data, 
+                     0, 
+                     PR_INTERVAL_NO_TIMEOUT);
+        if (rv != _client_data) {
+            if (debug_mode) printf("Client error sending data (%d)\n", rv);
+            PR_Close(clientSocket);
+            continue;
+        }
+
+        if (debug_mode) DPRINTF("\tClient sent %d bytes\n", rv);
+
+        bytesNeeded = _server_data;
+        while(bytesNeeded) {
+            rv = PR_Recv(clientSocket, 
+                         recvBuf, 
+                         bytesNeeded, 
+                         0, 
+                         PR_INTERVAL_NO_TIMEOUT);
+            if (rv <= 0) {
+                if (debug_mode) printf("Client error receiving data (%d) (%d/%d)\n", 
+                    rv, (_server_data - bytesNeeded), _server_data);
+                break;
+            }
+            if (debug_mode) DPRINTF("\tClient received %d bytes; need %d more\n", rv, bytesNeeded - rv);
+            bytesNeeded -= rv;
+        }
+
+        PR_Close(clientSocket);
+ 
+        PR_AtomicDecrement(&numRequests);
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    --numClients;
+    PR_Notify(clientMonitor);
+    PR_ExitMonitor(clientMonitor);
+
+    PR_DELETE(sendBuf);
+    PR_DELETE(recvBuf);
+}
+
+void
+RunClients(void)
+{
+    PRInt32 index;
+
+    numRequests = _iterations;
+    numClients = _clients;
+    clientMonitor = PR_NewMonitor();
+
+    for (index=0; index<_clients; index++) {
+        PRThread *clientThread;
+
+  
+        clientThread = PR_CreateThread(
+                          PR_USER_THREAD,
+                          ClientThreadFunc,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          ClientScope,
+                          PR_UNJOINABLE_THREAD,
+                          THREAD_STACKSIZE);
+
+        if (!clientThread) {
+            if (debug_mode) printf("\terror creating client thread %d\n", index);
+        } else
+            if (debug_mode) DPRINTF("\tMain created client %d/%d\n", index+1, _clients);
+
+    }
+
+    PR_EnterMonitor(clientMonitor);
+    while(numClients)
+        PR_Wait(clientMonitor, PR_INTERVAL_NO_TIMEOUT);
+    PR_ExitMonitor(clientMonitor);
+}
+
+/* --- Main Function ---------------------------------------------- */
+
+static
+void do_work()
+{
+    PRThread *ServerThread;
+    PRInt32 state;
+
+    SetServerState(MAIN, SERVER_STATE_STARTUP);
+    ServerThread = PR_CreateThread(
+                      PR_USER_THREAD,
+                      ServerThreadFunc,
+                      NULL,
+                      PR_PRIORITY_NORMAL,
+                      ServerScope,
+                      PR_JOINABLE_THREAD,
+                      THREAD_STACKSIZE);
+    if (!ServerThread) {
+        if (debug_mode) printf("error creating main server thread\n");
+        return;
+    }
+
+    /* Wait for server to be ready */
+    state = WaitServerState(MAIN, SERVER_STATE_READY|SERVER_STATE_DEAD);
+
+    if (!(state & SERVER_STATE_DEAD)) {
+        /* Run Test Clients */
+        RunClients();
+
+        /* Send death signal to server */
+        SetServerState(MAIN, SERVER_STATE_DYING);
+    }
+
+    PR_JoinThread(ServerThread);
+}
+
+static void do_workUU(void)
+{
+    ServerScope = PR_LOCAL_THREAD;
+    ClientScope = PR_LOCAL_THREAD;
+    do_work();
+}
+
+
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+
+    if (debug_mode) printf("\n%40s: %6.2f usec\n", msg, d / _iterations);
+}
+
+
+main(int argc, char **argv)
+{
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+    if (debug_mode) {
+		printf("Enter number of iterations: \n");
+		scanf("%d", &_iterations);
+		printf("Enter number of clients   : \n");
+		scanf("%d", &_clients);
+		printf("Enter size of client data : \n");
+		scanf("%d", &_client_data);
+		printf("Enter size of server data : \n");
+		scanf("%d", &_server_data);
+	}
+	else {
+		_iterations = 7;
+		_clients = 7;
+		_client_data = 100;
+		_server_data = 100;
+	}
+
+    if (debug_mode) {
+		printf("\n\n%d iterations with %d client threads.\n", 
+        _iterations, _clients);
+		printf("Sending %d bytes of client data and %d bytes of server data\n", 
+        _client_data, _server_data);
+	}
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    PR_SetThreadRecycleMode(64);
+
+    ServerStateCVLock = PR_NewLock();
+    ServerStateCV = PR_NewCondVar(ServerStateCVLock);
+
+    Measure(do_workUU, "server loop user/user");
+
+    PR_Cleanup();
+	
+	if(failed_already)	
+		return 1;
+	else
+		return 0;
+    
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/short_thread.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/short_thread.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,90 @@
+/* -*- 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 <stdio.h>
+#include "nspr.h"
+#include "plgetopt.h"
+
+/*
+ * Create a thread that exits right away; useful for testing race conditions in thread
+ * creation
+ */
+
+int _debug_on = 0;
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+static void housecleaning(void *cur_time);
+
+int main (int argc, char **argv)
+{
+	static PRIntervalTime thread_start_time;
+	static PRThread *housekeeping_tid = NULL;
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+	{
+		if (PL_OPT_BAD == os) continue;
+		switch (opt->option)
+		{
+			case 'd':  /* debug mode */
+				_debug_on = 1;
+				break;
+			default:
+				break;
+		}
+	}
+	PL_DestroyOptState(opt);
+
+	if (( housekeeping_tid = 
+		PR_CreateThread (PR_USER_THREAD, housecleaning,  (void*)&thread_start_time,
+						 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0)) 
+																		== NULL ) {
+		fprintf(stderr,
+			"simple_test: Error - PR_CreateThread failed: (%ld, %ld)\n",
+									  PR_GetError(), PR_GetOSError());
+		exit( 1 );
+	}
+	PR_Cleanup();
+	return(0);
+}
+
+static void
+housecleaning (void *cur_time) 
+{
+  DPRINTF(("Child Thread exiting\n"));
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sigpipe.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sigpipe.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,131 @@
+/* -*- 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 ***** */
+
+/*
+ *************************************************************************
+ *
+ * Test: sigpipe.c
+ *
+ *     Test the SIGPIPE handler in NSPR.  This test applies to Unix only.
+ *
+ *************************************************************************
+ */
+
+#if !defined(XP_UNIX) && !defined(XP_OS2)
+
+int main(void)
+{
+    /* This test applies to Unix and OS/2 (emx build). */
+    return 0;
+}
+
+#else /* XP_UNIX && OS/2 */
+
+#include "nspr.h"
+
+#ifdef XP_OS2
+#define INCL_DOSQUEUES
+#define INCL_DOSERRORS
+#include <os2.h>
+#endif
+
+#include <stdio.h>
+#ifdef XP_OS2_VACPP
+#define EPIPE EBADF  /* IBM's write() doesn't return EPIPE */
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include <errno.h>
+
+static void Test(void *arg)
+{
+#ifdef XP_OS2
+    HFILE pipefd[2];
+#else
+    int pipefd[2];
+#endif
+    int rv;
+    char c = '\0';
+
+#ifdef XP_OS2
+    if (DosCreatePipe(&pipefd[0], &pipefd[1], 4096) != 0) {
+#else
+    if (pipe(pipefd) == -1) {
+#endif
+        fprintf(stderr, "cannot create pipe: %d\n", errno);
+        exit(1);
+    }
+    close(pipefd[0]);
+
+    rv = write(pipefd[1], &c, 1);
+    if (rv != -1) {
+        fprintf(stderr, "write to broken pipe should have failed with EPIPE but returned %d\n", rv);
+        exit(1);
+    }
+    if (errno != EPIPE) {
+        fprintf(stderr, "write to broken pipe failed but with wrong errno: %d\n", errno);
+        exit(1);
+    }
+    close(pipefd[1]);
+    printf("write to broken pipe failed with EPIPE, as expected\n");
+}
+
+int main(void)
+{
+    PRThread *thread;
+
+    /* This initializes NSPR. */
+    PR_SetError(0, 0);
+
+    thread = PR_CreateThread(PR_USER_THREAD, Test, NULL, PR_PRIORITY_NORMAL,
+            PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (thread == NULL) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(thread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+    Test(NULL);
+
+    printf("PASSED\n");
+    return 0;
+}
+
+#endif /* XP_UNIX */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sleep.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sleep.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,134 @@
+/* -*- 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 "nspr.h"
+
+#if defined(XP_UNIX) || defined(XP_OS2)
+
+#include <stdio.h>
+
+#ifndef XP_OS2
+#include <unistd.h>
+#endif
+#include <sys/time.h>
+
+#if defined(HAVE_SVID_GETTOD)
+#define GTOD(_a) gettimeofday(_a)
+#else
+#define GTOD(_a) gettimeofday((_a), NULL)
+#endif
+
+#if defined (XP_OS2_VACPP)
+#define INCL_DOSPROCESS
+#include <os2.h>
+#endif
+
+static PRIntn rv = 0;
+
+static void Other(void *unused)
+{
+    PRIntn didit = 0;
+    while (PR_SUCCESS == PR_Sleep(PR_MillisecondsToInterval(250)))
+    {
+        fprintf(stderr, ".");
+        didit += 1;
+    }
+    if (didit < 5) rv = 1;
+}
+
+PRIntn main ()
+{
+    PRUint32 elapsed;
+    PRThread *thread;
+	struct timeval timein, timeout;
+    PRInt32 onePercent = 3000000UL / 100UL;
+
+	fprintf (stderr, "First sleep will sleep 3 seconds.\n");
+	fprintf (stderr, "   sleep 1 begin\n");
+    (void)GTOD(&timein);
+	sleep (3);
+    (void)GTOD(&timeout);
+	fprintf (stderr, "   sleep 1 end\n");
+    elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec);
+    elapsed += (timeout.tv_usec - timein.tv_usec);
+    fprintf(stderr, "elapsed %u usecs\n", elapsed);
+    if (labs(elapsed - 3000000UL) > onePercent) rv = 1;
+
+	PR_Init (PR_USER_THREAD, PR_PRIORITY_NORMAL, 100);
+    PR_STDIO_INIT();
+
+	fprintf (stderr, "Second sleep should do the same (does it?).\n");
+	fprintf (stderr, "   sleep 2 begin\n");
+    (void)GTOD(&timein);
+	sleep (3);
+    (void)GTOD(&timeout);
+	fprintf (stderr, "   sleep 2 end\n");
+    elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec);
+    elapsed += (timeout.tv_usec - timein.tv_usec);
+    fprintf(stderr, "elapsed %u usecs\n", elapsed);
+    if (labs(elapsed - 3000000UL) > onePercent) rv = 1;
+
+	fprintf (stderr, "What happens to other threads?\n");
+	fprintf (stderr, "You should see dots every quarter second.\n");
+	fprintf (stderr, "If you don't, you're probably running on classic NSPR.\n");
+    thread = PR_CreateThread(
+        PR_USER_THREAD, Other, NULL, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+	fprintf (stderr, "   sleep 2 begin\n");
+    (void)GTOD(&timein);
+	sleep (3);
+    (void)GTOD(&timeout);
+	fprintf (stderr, "   sleep 2 end\n");
+    PR_Interrupt(thread);
+    PR_JoinThread(thread);
+    elapsed = 1000000UL * (timeout.tv_sec - timein.tv_sec);
+    elapsed += (timeout.tv_usec - timein.tv_usec);
+    fprintf(stderr, "elapsed %u usecs\n", elapsed);
+    if (labs(elapsed - 3000000UL) > onePercent) rv = 1;
+    fprintf(stderr, "%s\n", (0 == rv) ? "PASSED" : "FAILED");
+    return rv;
+}
+
+#else /* defined(XP_UNIX) */
+
+PRIntn main()
+{
+	return 2;
+}
+
+#endif /*  defined(XP_UNIX) */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/socket.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/socket.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2354 @@
+/* -*- 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: socket.c
+**
+** Description: Test socket functionality.
+**
+** Modification History:
+*/
+#include "primpl.h"
+
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#ifdef XP_UNIX
+#include <sys/mman.h>
+#endif
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include <pthread.h>
+#endif
+
+#ifdef WIN32
+#include <process.h>
+#endif
+
+static int _debug_on = 0;
+static int test_cancelio = 0;
+
+#ifdef XP_MAC
+#include "prlog.h"
+#include "prsem.h"
+int fprintf(FILE *stream, const char *fmt, ...)
+{
+    PR_LogPrint(fmt);
+    return 0;
+}
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#else
+#include "obsolete/prsem.h"
+#endif
+
+#ifdef XP_PC
+#define mode_t int
+#endif
+
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+#ifdef XP_PC
+char *TEST_DIR = "prdir";
+char *SMALL_FILE_NAME = "prsmallf";
+char *LARGE_FILE_NAME = "prlargef";
+#else
+char *TEST_DIR = "/tmp/prsocket_test_dir";
+char *SMALL_FILE_NAME = "/tmp/prsocket_test_dir/small_file";
+char *LARGE_FILE_NAME = "/tmp/prsocket_test_dir/large_file";
+#endif
+#define SMALL_FILE_SIZE				(3 * 1024)        /* 3 KB        */
+#define SMALL_FILE_OFFSET_1			(512)
+#define SMALL_FILE_LEN_1			(1 * 1024)        /* 1 KB        */
+#define SMALL_FILE_OFFSET_2			(75)
+#define SMALL_FILE_LEN_2			(758)
+#define SMALL_FILE_OFFSET_3			(1024)
+#define SMALL_FILE_LEN_3			(SMALL_FILE_SIZE - SMALL_FILE_OFFSET_3)
+#define SMALL_FILE_HEADER_SIZE    	(64)            /* 64 bytes    */
+#define SMALL_FILE_TRAILER_SIZE   	(128)           /* 128 bytes    */
+
+#define LARGE_FILE_SIZE				(3 * 1024 * 1024)    /* 3 MB        */
+#define LARGE_FILE_OFFSET_1			(0)
+#define LARGE_FILE_LEN_1			(2 * 1024 * 1024)    /* 2 MB        */
+#define LARGE_FILE_OFFSET_2			(64)
+#define LARGE_FILE_LEN_2			(1 * 1024 * 1024 + 75)
+#define LARGE_FILE_OFFSET_3			(2 * 1024 * 1024 - 128)
+#define LARGE_FILE_LEN_3			(LARGE_FILE_SIZE - LARGE_FILE_OFFSET_3)
+#define LARGE_FILE_OFFSET_4			PR_GetPageSize()
+#define LARGE_FILE_LEN_4			769
+#define LARGE_FILE_HEADER_SIZE    	(512)
+#define LARGE_FILE_TRAILER_SIZE   	(64)
+
+#define    BUF_DATA_SIZE    (2 * 1024)
+#define TCP_MESG_SIZE    1024
+/*
+ * set UDP datagram size small enough that datagrams sent to a port on the
+ * local host will not be lost
+ */
+#define UDP_DGRAM_SIZE            128
+#define NUM_TCP_CLIENTS            5	/* for a listen queue depth of 5 */
+#define NUM_UDP_CLIENTS            10
+
+#ifndef XP_MAC
+#define NUM_TRANSMITFILE_CLIENTS    4
+#else
+/* Mac can't handle more than 2* (3Mb) allocations for large file size buffers */
+#define NUM_TRANSMITFILE_CLIENTS    2
+#endif
+
+#define NUM_TCP_CONNECTIONS_PER_CLIENT    5
+#define NUM_TCP_MESGS_PER_CONNECTION    10
+#define NUM_UDP_DATAGRAMS_PER_CLIENT    5
+#define TCP_SERVER_PORT            10000
+#define UDP_SERVER_PORT            TCP_SERVER_PORT
+#define SERVER_MAX_BIND_COUNT        100
+
+static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS;
+static PRInt32 num_udp_clients = NUM_UDP_CLIENTS;
+static PRInt32 num_transmitfile_clients = NUM_TRANSMITFILE_CLIENTS;
+static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT;
+static PRInt32 tcp_mesg_size = TCP_MESG_SIZE;
+static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION;
+static PRInt32 num_udp_datagrams_per_client = NUM_UDP_DATAGRAMS_PER_CLIENT;
+static PRInt32 udp_datagram_size = UDP_DGRAM_SIZE;
+
+static PRInt32 thread_count;
+PRUint16 server_domain = PR_AF_INET, client_domain = PR_AF_INET;
+
+/* an I/O layer that uses the emulated senfile method */
+static PRDescIdentity emuSendFileIdentity;
+static PRIOMethods emuSendFileMethods;
+
+int failed_already=0;
+typedef struct buffer {
+    char    data[BUF_DATA_SIZE];
+} buffer;
+
+PRNetAddr tcp_server_addr, udp_server_addr;
+
+typedef struct Serve_Client_Param {
+    PRFileDesc *sockfd;    /* socket to read from/write to    */
+    PRInt32    datalen;    /* bytes of data transfered in each read/write */
+} Serve_Client_Param;
+
+typedef struct Server_Param {
+    PRSemaphore *addr_sem;    /* sem to post on, after setting up the address */
+    PRMonitor *exit_mon;    /* monitor to signal on exit            */
+    PRInt32 *exit_counter;    /* counter to decrement, before exit        */
+    PRInt32    datalen;    /* bytes of data transfered in each read/write    */
+} Server_Param;
+
+
+typedef struct Client_Param {
+    PRNetAddr server_addr;
+    PRMonitor *exit_mon;    /* monitor to signal on exit */
+    PRInt32 *exit_counter;    /* counter to decrement, before exit */
+    PRInt32    datalen;
+    PRInt32    udp_connect;    /* if set clients connect udp sockets */
+} Client_Param;
+
+/* the sendfile method in emuSendFileMethods */
+static PRInt32 PR_CALLBACK
+emu_SendFile(PRFileDesc *sd, PRSendFileData *sfd,
+    PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    return PR_EmulateSendFile(sd, sfd, flags, timeout);
+}
+
+/* the transmitfile method in emuSendFileMethods */
+static PRInt32 PR_CALLBACK
+emu_TransmitFile(PRFileDesc *sd, PRFileDesc *fd, const void *headers,
+    PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout)
+{
+    PRSendFileData sfd;
+
+    sfd.fd = fd;
+    sfd.file_offset = 0;
+    sfd.file_nbytes = 0;
+    sfd.header = headers;
+    sfd.hlen = hlen;
+    sfd.trailer = NULL;
+    sfd.tlen = 0;
+    return emu_SendFile(sd, &sfd, flags, timeout);
+}
+
+/*
+ * readn
+ *    read data from sockfd into buf
+ */
+static PRInt32
+readn(PRFileDesc *sockfd, char *buf, int len)
+{
+    int rem;
+    int bytes;
+    int offset = 0;
+	int err;
+	PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
+
+	if (test_cancelio)
+		timeout = PR_SecondsToInterval(2);
+
+    for (rem=len; rem; offset += bytes, rem -= bytes) {
+        DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n",
+            PR_GetCurrentThread(), rem));
+retry:
+        bytes = PR_Recv(sockfd, buf + offset, rem, 0,
+            	timeout);
+        DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n",
+            PR_GetCurrentThread(), bytes));
+        if (bytes < 0) {
+#ifdef WINNT
+			printf("PR_Recv: error = %d oserr = %d\n",(err = PR_GetError()),
+									PR_GetOSError());
+			if ((test_cancelio) && (err == PR_IO_TIMEOUT_ERROR)) {
+				if (PR_NT_CancelIo(sockfd) != PR_SUCCESS)
+					printf("PR_NT_CancelIO: error = %d\n",PR_GetError());
+				timeout = PR_INTERVAL_NO_TIMEOUT;
+				goto retry;
+			}
+#endif
+			return -1;
+		}	
+    }
+    return len;
+}
+
+/*
+ * writen
+ *    write data from buf to sockfd
+ */
+static PRInt32
+writen(PRFileDesc *sockfd, char *buf, int len)
+{
+    int rem;
+    int bytes;
+    int offset = 0;
+
+    for (rem=len; rem; offset += bytes, rem -= bytes) {
+        DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n",
+            PR_GetCurrentThread(), rem));
+        bytes = PR_Send(sockfd, buf + offset, rem, 0,
+            PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n",
+            PR_GetCurrentThread(), bytes));
+        if (bytes <= 0)
+            return -1;
+    }
+    return len;
+}
+
+/*
+ * Serve_Client
+ *    Thread, started by the server, for serving a client connection.
+ *    Reads data from socket and writes it back, unmodified, and
+ *    closes the socket
+ */
+static void PR_CALLBACK
+Serve_Client(void *arg)
+{
+    Serve_Client_Param *scp = (Serve_Client_Param *) arg;
+    PRFileDesc *sockfd;
+    buffer *in_buf;
+    PRInt32 bytes, j;
+
+    sockfd = scp->sockfd;
+    bytes = scp->datalen;
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        goto exit;
+    }
+
+
+    for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
+        /*
+         * Read data from client and send it back to the client unmodified
+         */
+        if (readn(sockfd, in_buf->data, bytes) < bytes) {
+            fprintf(stderr,"prsocket_test: ERROR - Serve_Client:readn\n");
+            failed_already=1;
+            goto exit;
+        }
+        /*
+         * shutdown reads, after the last read
+         */
+        if (j == num_tcp_mesgs_per_connection - 1)
+            if (PR_Shutdown(sockfd, PR_SHUTDOWN_RCV) < 0) {
+                fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
+            }
+        DPRINTF(("Serve_Client [0x%lx]: inbuf[0] = 0x%lx\n",PR_GetCurrentThread(),
+            (*((int *) in_buf->data))));
+        if (writen(sockfd, in_buf->data, bytes) < bytes) {
+            fprintf(stderr,"prsocket_test: ERROR - Serve_Client:writen\n");
+            failed_already=1;
+            goto exit;
+        }
+    }
+    /*
+     * shutdown reads and writes
+     */
+    if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
+        failed_already=1;
+    }
+
+exit:
+    PR_Close(sockfd);
+    if (in_buf) {
+        PR_DELETE(in_buf);
+    }
+}
+
+PRThread* create_new_thread(PRThreadType type,
+							void (*start)(void *arg),
+							void *arg,
+							PRThreadPriority priority,
+							PRThreadScope scope,
+							PRThreadState state,
+							PRUint32 stackSize, PRInt32 index)
+{
+PRInt32 native_thread = 0;
+
+	PR_ASSERT(state == PR_UNJOINABLE_THREAD);
+#if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32)
+	switch(index %  4) {
+		case 0:
+			scope = (PR_LOCAL_THREAD);
+			break;
+		case 1:
+			scope = (PR_GLOBAL_THREAD);
+			break;
+		case 2:
+			scope = (PR_GLOBAL_BOUND_THREAD);
+			break;
+		case 3:
+			native_thread = 1;
+			break;
+		default:
+			PR_ASSERT(!"Invalid scope");
+			break;
+	}
+	if (native_thread) {
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+		pthread_t tid;
+		if (!pthread_create(&tid, NULL, (void * (*)(void *)) start, arg))
+			return((PRThread *) tid);
+		else
+			return (NULL);
+#else
+		HANDLE thandle;
+		unsigned tid;
+		
+		thandle = (HANDLE) _beginthreadex(
+						NULL,
+						stackSize,
+						(unsigned (__stdcall *)(void *))start,
+						arg,
+						0,
+						&tid);		
+		return((PRThread *) thandle);
+#endif
+	} else {
+		return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
+	}
+#else
+	return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
+#endif
+}
+
+/*
+ * TCP Server
+ *    Server Thread
+ *    Bind an address to a socket and listen for incoming connections
+ *    Start a Serve_Client thread for each incoming connection.
+ */
+static void PR_CALLBACK
+TCP_Server(void *arg)
+{
+    PRThread *t;
+    Server_Param *sp = (Server_Param *) arg;
+    Serve_Client_Param *scp;
+    PRFileDesc *sockfd, *newsockfd;
+    PRNetAddr netaddr;
+    PRInt32 i;
+    /*
+     * Create a tcp socket
+     */
+	if ((sockfd = PR_OpenTCPSocket(server_domain)) == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
+        goto exit;
+    }
+    memset(&netaddr, 0 , sizeof(netaddr));
+	
+	if (PR_SetNetAddr(PR_IpAddrAny, server_domain, TCP_SERVER_PORT,
+									&netaddr) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
+        goto exit;
+	}
+    /*
+     * try a few times to bind server's address, if addresses are in
+     * use
+     */
+    i = 0;
+	
+    while (PR_Bind(sockfd, &netaddr) < 0) {
+        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+            netaddr.inet.port += 2;
+            if (i++ < SERVER_MAX_BIND_COUNT)
+                continue;
+        }
+        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
+        perror("PR_Bind");
+        failed_already=1;
+        goto exit;
+    }
+
+    if (PR_Listen(sockfd, 32) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
+        failed_already=1;
+        goto exit;
+    }
+
+    if (PR_GetSockName(sockfd, &netaddr) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
+        failed_already=1;
+        goto exit;
+    }
+
+    DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
+        netaddr.inet.ip, netaddr.inet.port));
+	if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain,
+									PR_ntohs(PR_NetAddrInetPort(&netaddr)),
+									&tcp_server_addr) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
+        goto exit;
+	}
+	if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET))
+		PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK),
+								&tcp_server_addr.ipv6.ip);
+
+    /*
+     * Wake up parent thread because server address is bound and made
+     * available in the global variable 'tcp_server_addr'
+     */
+    PR_PostSem(sp->addr_sem);
+
+    for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) {
+        /* test both null and non-null 'addr' argument to PR_Accept */
+        PRNetAddr *addrp = (i%2 ? &netaddr: NULL);
+
+    DPRINTF(("TCP_Server: Accepting connection\n"));
+        if ((newsockfd = PR_Accept(sockfd, addrp,
+            PR_INTERVAL_NO_TIMEOUT)) == NULL) {
+            fprintf(stderr,"prsocket_test: ERROR - PR_Accept failed\n");
+            goto exit;
+        }
+    DPRINTF(("TCP_Server: Accepted connection\n"));
+        scp = PR_NEW(Serve_Client_Param);
+        if (scp == NULL) {
+            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+            goto exit;
+        }
+
+        /*
+         * Start a Serve_Client thread for each incoming connection
+         */
+        scp->sockfd = newsockfd;
+        scp->datalen = sp->datalen;
+
+        t = create_new_thread(PR_USER_THREAD,
+            Serve_Client, (void *)scp, 
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_UNJOINABLE_THREAD,
+            0, i);
+        if (t == NULL) {
+            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+            failed_already=1;
+            goto exit;
+        }
+        DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t));
+    }
+
+exit:
+    if (sockfd) {
+        PR_Close(sockfd);
+    }
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(sp->exit_mon);
+    --(*sp->exit_counter);
+    PR_Notify(sp->exit_mon);
+    PR_ExitMonitor(sp->exit_mon);
+    DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * UDP Server
+ *    Server Thread
+ *    Bind an address to a socket, read data from clients and send data
+ *    back to clients
+ */
+static void PR_CALLBACK
+UDP_Server(void *arg)
+{
+    Server_Param *sp = (Server_Param *) arg;
+    PRFileDesc *sockfd;
+    buffer *in_buf;
+    PRNetAddr netaddr;
+    PRInt32 bytes, i, rv = 0;
+
+
+    bytes = sp->datalen;
+    /*
+     * Create a udp socket
+     */
+	if ((sockfd = PR_OpenUDPSocket(server_domain)) == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n");
+        failed_already=1;
+        return;
+    }
+    memset(&netaddr, 0 , sizeof(netaddr));
+	if (PR_SetNetAddr(PR_IpAddrAny, server_domain, UDP_SERVER_PORT,
+									&netaddr) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
+        failed_already=1;
+        return;
+	}
+    /*
+     * try a few times to bind server's address, if addresses are in
+     * use
+     */
+    i = 0;
+    while (PR_Bind(sockfd, &netaddr) < 0) {
+        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+            netaddr.inet.port += 2;
+            if (i++ < SERVER_MAX_BIND_COUNT)
+                continue;
+        }
+        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
+        perror("PR_Bind");
+        failed_already=1;
+        return;
+    }
+
+    if (PR_GetSockName(sockfd, &netaddr) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
+        failed_already=1;
+        return;
+    }
+
+    DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
+        netaddr.inet.ip, netaddr.inet.port));
+    /*
+     * We can't use the IP address returned by PR_GetSockName in
+     * netaddr.inet.ip because netaddr.inet.ip is returned
+     * as 0 (= PR_INADDR_ANY).
+     */
+
+	if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain,
+									PR_ntohs(PR_NetAddrInetPort(&netaddr)),
+									&udp_server_addr) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
+        failed_already=1;
+        return;
+	}
+	if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET))
+		PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK),
+								&udp_server_addr.ipv6.ip);
+		
+    /*
+     * Wake up parent thread because server address is bound and made
+     * available in the global variable 'udp_server_addr'
+     */
+    PR_PostSem(sp->addr_sem);
+
+    bytes = sp->datalen;
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        return;
+    }
+    /*
+     * Receive datagrams from clients and send them back, unmodified, to the
+     * clients
+     */
+    memset(&netaddr, 0 , sizeof(netaddr));
+    for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) {
+        DPRINTF(("UDP_Server: calling PR_RecvFrom client  - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
+            netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data,
+            in_buf->data[0]));
+
+        rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
+            PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("UDP_Server: PR_RecvFrom client  - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
+            netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data,
+            in_buf->data[0]));
+        if (rv != bytes) {
+            return;
+        }
+        rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr,
+            PR_INTERVAL_NO_TIMEOUT);
+        if (rv != bytes) {
+            return;
+        }
+    }
+
+    PR_DELETE(in_buf);
+    PR_Close(sockfd);
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+    PR_EnterMonitor(sp->exit_mon);
+    --(*sp->exit_counter);
+    PR_Notify(sp->exit_mon);
+    PR_ExitMonitor(sp->exit_mon);
+    DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * TCP_Client
+ *    Client Thread
+ *    Connect to the server at the address specified in the argument.
+ *    Fill in a buffer, write data to server, read it back and check
+ *    for data corruption.
+ *    Close the socket for server connection
+ */
+static void PR_CALLBACK
+TCP_Client(void *arg)
+{
+    Client_Param *cp = (Client_Param *) arg;
+    PRFileDesc *sockfd;
+    buffer *in_buf, *out_buf;
+    union PRNetAddr netaddr;
+    PRInt32 bytes, i, j;
+
+
+    bytes = cp->datalen;
+    out_buf = PR_NEW(buffer);
+    if (out_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        return;
+    }
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        return;
+    }
+    netaddr = cp->server_addr;
+
+    for (i = 0; i < num_tcp_connections_per_client; i++) {
+        if ((sockfd = PR_OpenTCPSocket(client_domain)) == NULL) {
+            fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n");
+            failed_already=1;
+            return;
+        }
+        if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
+        	fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n",
+            		PR_GetError(), PR_GetOSError());
+            failed_already=1;
+            return;
+        }
+        for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
+            /*
+             * fill in random data
+             */
+            memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes);
+            /*
+             * write to server
+             */
+#ifdef WINNT
+			if (test_cancelio && (j == 0))
+				PR_Sleep(PR_SecondsToInterval(12));
+#endif
+            if (writen(sockfd, out_buf->data, bytes) < bytes) {
+                fprintf(stderr,"prsocket_test: ERROR - TCP_Client:writen\n");
+                failed_already=1;
+                return;
+            }
+            DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",
+                PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))));
+            if (readn(sockfd, in_buf->data, bytes) < bytes) {
+                fprintf(stderr,"prsocket_test: ERROR - TCP_Client:readn\n");
+                failed_already=1;
+                return;
+            }
+            /*
+             * verify the data read
+             */
+            if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
+                fprintf(stderr,"prsocket_test: ERROR - data corruption\n");
+                failed_already=1;
+                return;
+            }
+        }
+        /*
+         * shutdown reads and writes
+         */
+        if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
+            fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
+            failed_already=1;
+        }
+        PR_Close(sockfd);
+    }
+
+    PR_DELETE(out_buf);
+    PR_DELETE(in_buf);
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(cp->exit_mon);
+    --(*cp->exit_counter);
+    PR_Notify(cp->exit_mon);
+    PR_ExitMonitor(cp->exit_mon);
+    DPRINTF(("TCP_Client [0x%x] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * UDP_Client
+ *    Client Thread
+ *    Create a socket and bind an address 
+ *    Communicate with the server at the address specified in the argument.
+ *    Fill in a buffer, write data to server, read it back and check
+ *    for data corruption.
+ *    Close the socket
+ */
+static void PR_CALLBACK
+UDP_Client(void *arg)
+{
+    Client_Param *cp = (Client_Param *) arg;
+    PRFileDesc *sockfd;
+    buffer *in_buf, *out_buf;
+    union PRNetAddr netaddr;
+    PRInt32 bytes, i, rv;
+
+
+    bytes = cp->datalen;
+    out_buf = PR_NEW(buffer);
+    if (out_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        return;
+    }
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
+        failed_already=1;
+        return;
+    }
+    if ((sockfd = PR_OpenUDPSocket(client_domain)) == NULL) {
+        fprintf(stderr,"prsocket_test: PR_OpenUDPSocket failed\n");
+        failed_already=1;
+        return;
+    }
+
+    /*
+     * bind an address for the client, let the system chose the port
+     * number
+     */
+    memset(&netaddr, 0 , sizeof(netaddr));
+	if (PR_SetNetAddr(PR_IpAddrAny, client_domain, 0,
+									&netaddr) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
+        failed_already=1;
+        return;
+	}
+    if (PR_Bind(sockfd, &netaddr) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
+        perror("PR_Bind");
+        return;
+    }
+
+    if (PR_GetSockName(sockfd, &netaddr) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
+        failed_already=1;
+        return;
+    }
+
+    DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
+        netaddr.inet.ip, netaddr.inet.port));
+
+    netaddr = cp->server_addr;
+
+    if (cp->udp_connect) {
+        if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
+            fprintf(stderr,"prsocket_test: PR_Connect failed\n");
+            failed_already=1;
+            return;
+        }
+    }
+
+    for (i = 0; i < num_udp_datagrams_per_client; i++) {
+        /*
+         * fill in random data
+         */
+        DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n",
+            PR_GetCurrentThread(), out_buf->data, bytes));
+        memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes);
+        /*
+         * write to server
+         */
+        if (cp->udp_connect)
+            rv = PR_Send(sockfd, out_buf->data, bytes, 0,
+                PR_INTERVAL_NO_TIMEOUT);
+        else
+            rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr,
+                PR_INTERVAL_NO_TIMEOUT);
+        if (rv != bytes) {
+            return;
+        }
+        DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",
+            PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))));
+        if (cp->udp_connect)
+            rv = PR_Recv(sockfd, in_buf->data, bytes, 0,
+                PR_INTERVAL_NO_TIMEOUT);
+        else
+            rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
+                PR_INTERVAL_NO_TIMEOUT);
+        if (rv != bytes) {
+            return;
+        }
+        DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n",
+            PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data))));
+        /*
+         * verify the data read
+         */
+        if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
+            fprintf(stderr,"prsocket_test: ERROR - UDP data corruption\n");
+            failed_already=1;
+            return;
+        }
+    }
+    PR_Close(sockfd);
+
+    PR_DELETE(in_buf);
+    PR_DELETE(out_buf);
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(cp->exit_mon);
+    --(*cp->exit_counter);
+    PR_Notify(cp->exit_mon);
+    PR_ExitMonitor(cp->exit_mon);
+    PR_DELETE(cp);
+    DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * TCP_Socket_Client_Server_Test    - concurrent server test
+ *    
+ *    One server and several clients are started
+ *    Each client connects to the server and sends a chunk of data
+ *    For each connection, server starts another thread to read the data
+ *    from the client and send it back to the client, unmodified.
+ *    Each client checks that data received from server is same as the
+ *    data it sent to the server.
+ *
+ */
+
+static PRInt32
+TCP_Socket_Client_Server_Test(void)
+{
+    int i;
+    PRThread *t;
+    PRSemaphore *server_sem;
+    Server_Param *sparamp;
+    Client_Param *cparamp;
+    PRMonitor *mon2;
+    PRInt32    datalen;
+
+
+    datalen = tcp_mesg_size;
+    thread_count = 0;
+    /*
+     * start the server thread
+     */
+    sparamp = PR_NEW(Server_Param);
+    if (sparamp == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+        failed_already=1;
+        return -1;
+    }
+    server_sem = PR_NewSem(0);
+    if (server_sem == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
+        failed_already=1;
+        return -1;
+    }
+    mon2 = PR_NewMonitor();
+    if (mon2 == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
+        failed_already=1;
+        return -1;
+    }
+    PR_EnterMonitor(mon2);
+
+    sparamp->addr_sem = server_sem;
+    sparamp->exit_mon = mon2;
+    sparamp->exit_counter = &thread_count;
+    sparamp->datalen = datalen;
+    t = PR_CreateThread(PR_USER_THREAD,
+        TCP_Server, (void *)sparamp, 
+        PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD,
+        PR_UNJOINABLE_THREAD,
+        0);
+    if (t == NULL) {
+        fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+        failed_already=1;
+        return -1;
+    }
+    DPRINTF(("Created TCP server = 0x%lx\n", t));
+    thread_count++;
+
+    /*
+     * wait till the server address is setup
+     */
+    PR_WaitSem(server_sem);
+
+    /*
+     * Now start a bunch of client threads
+     */
+
+    cparamp = PR_NEW(Client_Param);
+    if (cparamp == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+        failed_already=1;
+        return -1;
+    }
+    cparamp->server_addr = tcp_server_addr;
+    cparamp->exit_mon = mon2;
+    cparamp->exit_counter = &thread_count;
+    cparamp->datalen = datalen;
+    for (i = 0; i < num_tcp_clients; i++) {
+        t = create_new_thread(PR_USER_THREAD,
+            TCP_Client, (void *) cparamp,
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_UNJOINABLE_THREAD,
+            0, i);
+        if (t == NULL) {
+            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+            failed_already=1;
+            return -1;
+        }
+        DPRINTF(("Created TCP client = 0x%lx\n", t));
+        thread_count++;
+    }
+    /* Wait for server and client threads to exit */
+    while (thread_count) {
+        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("TCP Server - thread_count  = %d\n", thread_count));
+    }
+    PR_ExitMonitor(mon2);
+    printf("%30s","TCP_Socket_Client_Server_Test:");
+    printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l,
+        num_tcp_clients, num_tcp_connections_per_client);
+    printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":",
+        num_tcp_mesgs_per_connection, tcp_mesg_size);
+
+    return 0;
+}
+
+/*
+ * UDP_Socket_Client_Server_Test    - iterative server test
+ *    
+ *    One server and several clients are started
+ *    Each client connects to the server and sends a chunk of data
+ *    For each connection, server starts another thread to read the data
+ *    from the client and send it back to the client, unmodified.
+ *    Each client checks that data received from server is same as the
+ *    data it sent to the server.
+ *
+ */
+
+static PRInt32
+UDP_Socket_Client_Server_Test(void)
+{
+    int i;
+    PRThread *t;
+    PRSemaphore *server_sem;
+    Server_Param *sparamp;
+    Client_Param *cparamp;
+    PRMonitor *mon2;
+    PRInt32    datalen;
+    PRInt32    udp_connect = 1;
+
+
+    datalen = udp_datagram_size;
+    thread_count = 0;
+    /*
+     * start the server thread
+     */
+    sparamp = PR_NEW(Server_Param);
+    if (sparamp == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+        failed_already=1;
+        return -1;
+    }
+    server_sem = PR_NewSem(0);
+    if (server_sem == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
+        failed_already=1;
+        return -1;
+    }
+    mon2 = PR_NewMonitor();
+    if (mon2 == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
+        failed_already=1;
+        return -1;
+    }
+    PR_EnterMonitor(mon2);
+
+    sparamp->addr_sem = server_sem;
+    sparamp->exit_mon = mon2;
+    sparamp->exit_counter = &thread_count;
+    sparamp->datalen = datalen;
+    DPRINTF(("Creating UDP server"));
+    t = PR_CreateThread(PR_USER_THREAD,
+        UDP_Server, (void *)sparamp, 
+        PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD,
+        PR_UNJOINABLE_THREAD,
+        0);
+    if (t == NULL) {
+        fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+        failed_already=1;
+        return -1;
+    }
+    thread_count++;
+
+    /*
+     * wait till the server address is setup
+     */
+    PR_WaitSem(server_sem);
+
+    /*
+     * Now start a bunch of client threads
+     */
+
+    for (i = 0; i < num_udp_clients; i++) {
+        cparamp = PR_NEW(Client_Param);
+        if (cparamp == NULL) {
+            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+            failed_already=1;
+            return -1;
+        }
+        cparamp->server_addr = udp_server_addr;
+        cparamp->exit_mon = mon2;
+        cparamp->exit_counter = &thread_count;
+        cparamp->datalen = datalen;
+        /*
+         * Cause every other client thread to connect udp sockets
+         */
+#ifndef XP_MAC
+        cparamp->udp_connect = udp_connect;
+#else
+        /* No support for UDP connects on Mac */
+        cparamp->udp_connect = 0;
+#endif
+        if (udp_connect)
+            udp_connect = 0;
+        else
+            udp_connect = 1;
+        DPRINTF(("Creating UDP client %d\n", i));
+        t = PR_CreateThread(PR_USER_THREAD,
+            UDP_Client, (void *) cparamp,
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_UNJOINABLE_THREAD,
+            0);
+        if (t == NULL) {
+            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+            failed_already=1;
+            return -1;
+        }
+        thread_count++;
+    }
+    /* Wait for server and client threads to exit */
+    while (thread_count) {
+        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("UDP Server - thread_count  = %d\n", thread_count));
+    }
+    PR_ExitMonitor(mon2);
+    printf("%30s","UDP_Socket_Client_Server_Test: ");
+    printf("%2ld Server %2ld Clients\n",1l, num_udp_clients);
+    printf("%30s %2ld datagrams_per_client %4ld bytes_per_datagram\n",":",
+        num_udp_datagrams_per_client, udp_datagram_size);
+
+    return 0;
+}
+
+static PRFileDesc *small_file_fd, *large_file_fd;
+static void *small_file_addr, *small_file_header, *large_file_addr;
+static void *small_file_trailer, *large_file_header, *large_file_trailer;
+/*
+ * TransmitFile_Client
+ *    Client Thread
+ */
+static void
+TransmitFile_Client(void *arg)
+{
+    PRFileDesc *sockfd;
+    union PRNetAddr netaddr;
+    char *small_buf, *large_buf;
+    Client_Param *cp = (Client_Param *) arg;
+	PRInt32 rlen;
+
+    small_buf = (char*)PR_Malloc(SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE +
+										SMALL_FILE_TRAILER_SIZE);
+    if (small_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer\n");
+        failed_already=1;
+        return;
+    }
+    large_buf = (char*)PR_Malloc(LARGE_FILE_SIZE + LARGE_FILE_HEADER_SIZE +
+												LARGE_FILE_TRAILER_SIZE);
+    if (large_buf == NULL) {
+        fprintf(stderr,"prsocket_test: failed to alloc buffer\n");
+        failed_already=1;
+        return;
+    }
+    netaddr.inet.family = cp->server_addr.inet.family;
+    netaddr.inet.port = cp->server_addr.inet.port;
+    netaddr.inet.ip = cp->server_addr.inet.ip;
+
+    if ((sockfd = PR_NewTCPSocket()) == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
+        failed_already=1;
+        return;
+    }
+
+    if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
+        fprintf(stderr,"prsocket_test: PR_Connect failed\n");
+        failed_already=1;
+        return;
+    }
+    /*
+     * read the small file and verify the data
+     */
+    if (readn(sockfd, small_buf, SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)
+        != (SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)) {
+        fprintf(stderr,
+            "prsocket_test: TransmitFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#ifdef XP_UNIX
+    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "prsocket_test: TransmitFile_Client ERROR - small file header data corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE,
+        SMALL_FILE_SIZE) != 0) {
+        fprintf(stderr,
+            "prsocket_test: TransmitFile_Client ERROR - small file data corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+    /*
+     * read the large file and verify the data
+     */
+    if (readn(sockfd, large_buf, LARGE_FILE_SIZE) != LARGE_FILE_SIZE) {
+        fprintf(stderr,
+            "prsocket_test: TransmitFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#ifdef XP_UNIX
+    if (memcmp(large_file_addr, large_buf, LARGE_FILE_SIZE) != 0) {
+        fprintf(stderr,
+            "prsocket_test: TransmitFile_Client ERROR - large file data corruption\n");
+        failed_already=1;
+    }
+#endif
+
+
+	/*
+	 * receive data from PR_SendFile
+	 */
+	/*
+	 * case 1: small file with header and trailer
+	 */
+    rlen = SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE +
+									SMALL_FILE_TRAILER_SIZE;
+    if (readn(sockfd, small_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#ifdef XP_UNIX
+    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 1. ERROR - small file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE,
+        								SMALL_FILE_SIZE) != 0) {
+        fprintf(stderr,
+            "SendFile 1. ERROR - small file data corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(small_file_trailer,
+				small_buf + SMALL_FILE_HEADER_SIZE + SMALL_FILE_SIZE,
+        				SMALL_FILE_TRAILER_SIZE) != 0) {
+        fprintf(stderr,
+            "SendFile 1. ERROR - small file trailer corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 2: partial large file at zero offset, file with header and trailer
+	 */
+    rlen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE +
+									LARGE_FILE_TRAILER_SIZE;
+    if (readn(sockfd, large_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#ifdef XP_UNIX
+    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(large_file_addr, large_buf + LARGE_FILE_HEADER_SIZE,
+        								LARGE_FILE_LEN_1) != 0) {
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file data corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(large_file_trailer,
+				large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_1,
+        				LARGE_FILE_TRAILER_SIZE) != 0) {
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file trailer corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 3: partial small file at non-zero offset, with header
+	 */
+    rlen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE;
+    if (readn(sockfd, small_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#ifdef XP_UNIX
+    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 3. ERROR - small file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_1,
+				small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_1) != 0) {
+        fprintf(stderr,
+            "SendFile 3. ERROR - small file data corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 4: partial small file at non-zero offset, with trailer
+	 */
+    rlen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE;
+    if (readn(sockfd, small_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#ifdef XP_UNIX
+    if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_2, small_buf,
+        								SMALL_FILE_LEN_2) != 0) {
+        fprintf(stderr,
+            "SendFile 4. ERROR - small file data corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(small_file_trailer, small_buf + SMALL_FILE_LEN_2,
+        				SMALL_FILE_TRAILER_SIZE) != 0) {
+        fprintf(stderr,
+            "SendFile 4. ERROR - small file trailer corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 5: partial large file at non-zero offset, file with header
+	 */
+    rlen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE;
+    if (readn(sockfd, large_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#ifdef XP_UNIX
+    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 5. ERROR - large file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_2,
+					large_buf + LARGE_FILE_HEADER_SIZE,
+        								LARGE_FILE_LEN_2) != 0) {
+        fprintf(stderr,
+            "SendFile 5. ERROR - large file data corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 6: partial small file at non-zero offset, with header
+	 */
+    rlen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE;
+    if (readn(sockfd, small_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#ifdef XP_UNIX
+    if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 6. ERROR - small file header corruption\n");
+        return;
+    }
+    if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_3,
+				small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_3) != 0) {
+#if 0
+		char *i, *j;
+		int k;
+
+		i = (char *) small_file_addr + SMALL_FILE_OFFSET_3;
+		j = small_buf + SMALL_FILE_HEADER_SIZE;
+		k = SMALL_FILE_LEN_3;
+		while (k-- > 0) {
+			if (*i++ != *j++)
+			printf("i = %d j = %d\n",
+				(int) (i - ((char *) small_file_addr + SMALL_FILE_OFFSET_3)),
+				(int) (j - (small_buf + SMALL_FILE_HEADER_SIZE)));
+		}
+#endif
+        fprintf(stderr,
+            "SendFile 6. ERROR - small file data corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 7: partial large file at non-zero offset, with header
+	 */
+    rlen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE;
+    if (readn(sockfd, large_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#ifdef XP_UNIX
+    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 7. ERROR - large file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_3,
+					large_buf + LARGE_FILE_HEADER_SIZE,
+        								LARGE_FILE_LEN_3) != 0) {
+        fprintf(stderr,
+            "SendFile 7. ERROR - large file data corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+	/*
+	 * case 8: partial large file at non-zero, page-aligned offset, with
+	 * header and trailer
+	 */
+    rlen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE +
+									LARGE_FILE_TRAILER_SIZE;
+    if (readn(sockfd, large_buf, rlen) != rlen) {
+        fprintf(stderr,
+            "prsocket_test: SendFile_Client failed to receive file\n");
+        failed_already=1;
+        return;
+    }
+#ifdef XP_UNIX
+    if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0){
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file header corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_4,
+				large_buf + LARGE_FILE_HEADER_SIZE,
+        								LARGE_FILE_LEN_4) != 0) {
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file data corruption\n");
+        failed_already=1;
+        return;
+    }
+    if (memcmp(large_file_trailer,
+				large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_4,
+        				LARGE_FILE_TRAILER_SIZE) != 0) {
+        fprintf(stderr,
+            "SendFile 2. ERROR - large file trailer corruption\n");
+        failed_already=1;
+        return;
+    }
+#endif
+    PR_DELETE(small_buf);
+    PR_DELETE(large_buf);
+    PR_Close(sockfd);
+
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(cp->exit_mon);
+    --(*cp->exit_counter);
+    PR_Notify(cp->exit_mon);
+    PR_ExitMonitor(cp->exit_mon);
+    DPRINTF(("TransmitFile_Client [0x%lx] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * Serve_TransmitFile_Client
+ *    Thread, started by the server, for serving a client connection.
+ *    Trasmits a small file, with a header, and a large file, without
+ *    a header
+ */
+static void
+Serve_TransmitFile_Client(void *arg)
+{
+    Serve_Client_Param *scp = (Serve_Client_Param *) arg;
+    PRFileDesc *sockfd;
+    PRInt32 bytes;
+    PRFileDesc *local_small_file_fd=NULL;
+    PRFileDesc *local_large_file_fd=NULL;
+	PRSendFileData sfd;
+	PRInt32 slen;
+
+    sockfd = scp->sockfd;
+    local_small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDONLY,0);
+
+    if (local_small_file_fd == NULL) {
+        fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n",
+            SMALL_FILE_NAME);
+        failed_already=1;
+        goto done;
+    }
+    local_large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDONLY,0);
+
+    if (local_large_file_fd == NULL) {
+        fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n",
+            LARGE_FILE_NAME);
+        failed_already=1;
+        goto done;
+    }
+    bytes = PR_TransmitFile(sockfd, local_small_file_fd, small_file_header,
+        SMALL_FILE_HEADER_SIZE, PR_TRANSMITFILE_KEEP_OPEN,
+        PR_INTERVAL_NO_TIMEOUT);
+    if (bytes != (SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE)) {
+        fprintf(stderr,
+            "prsocet_test: PR_TransmitFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+    bytes = PR_TransmitFile(sockfd, local_large_file_fd, NULL, 0,
+        PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT);
+    if (bytes != LARGE_FILE_SIZE) {
+        fprintf(stderr,
+            "prsocket_test: PR_TransmitFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+
+	/*
+	 * PR_SendFile test cases
+	 */
+
+	/*
+	 * case 1: small file with header and trailer
+	 */
+	sfd.fd = local_small_file_fd;
+	sfd.file_offset = 0;
+	sfd.file_nbytes = 0;
+	sfd.header = small_file_header;
+	sfd.hlen = SMALL_FILE_HEADER_SIZE;
+	sfd.trailer = small_file_trailer;
+	sfd.tlen = SMALL_FILE_TRAILER_SIZE;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE +
+						SMALL_FILE_TRAILER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 1. PR_SendFile  send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+
+	/*
+	 * case 2: partial large file at zero offset, file with header and trailer
+	 */
+	sfd.fd = local_large_file_fd;
+	sfd.file_offset = 0;
+	sfd.file_nbytes = LARGE_FILE_LEN_1;
+	sfd.header = large_file_header;
+	sfd.hlen = LARGE_FILE_HEADER_SIZE;
+	sfd.trailer = large_file_trailer;
+	sfd.tlen = LARGE_FILE_TRAILER_SIZE;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE +
+						LARGE_FILE_TRAILER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 3: partial small file at non-zero offset, with header
+	 */
+	sfd.fd = local_small_file_fd;
+	sfd.file_offset = SMALL_FILE_OFFSET_1;
+	sfd.file_nbytes = SMALL_FILE_LEN_1;
+	sfd.header = small_file_header;
+	sfd.hlen = SMALL_FILE_HEADER_SIZE;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 3. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 4: partial small file at non-zero offset, with trailer
+	 */
+	sfd.fd = local_small_file_fd;
+	sfd.file_offset = SMALL_FILE_OFFSET_2;
+	sfd.file_nbytes = SMALL_FILE_LEN_2;
+	sfd.header = NULL;
+	sfd.hlen = 0;
+	sfd.trailer = small_file_trailer;
+	sfd.tlen = SMALL_FILE_TRAILER_SIZE;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 4. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 5: partial large file at non-zero offset, file with header
+	 */
+	sfd.fd = local_large_file_fd;
+	sfd.file_offset = LARGE_FILE_OFFSET_2;
+	sfd.file_nbytes = LARGE_FILE_LEN_2;
+	sfd.header = large_file_header;
+	sfd.hlen = LARGE_FILE_HEADER_SIZE;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 5. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 6: partial small file from non-zero offset till end of file, with header
+	 */
+	sfd.fd = local_small_file_fd;
+	sfd.file_offset = SMALL_FILE_OFFSET_3;
+	sfd.file_nbytes = 0;				/* data from offset to end-of-file */
+	sfd.header = small_file_header;
+	sfd.hlen = SMALL_FILE_HEADER_SIZE;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 6. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 7: partial large file at non-zero offset till end-of-file, with header
+	 */
+	sfd.fd = local_large_file_fd;
+	sfd.file_offset = LARGE_FILE_OFFSET_3;
+	sfd.file_nbytes = 0;				/* data until end-of-file */
+	sfd.header = large_file_header;
+	sfd.hlen = LARGE_FILE_HEADER_SIZE;
+	sfd.trailer = NULL;
+	sfd.tlen = 0;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
+        									PR_INTERVAL_NO_TIMEOUT);
+    slen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 7. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+	/*
+	 * case 8: partial large file at non-zero page-aligned offset,
+	 * with header and trailer
+	 */
+	sfd.fd = local_large_file_fd;
+	sfd.file_offset = LARGE_FILE_OFFSET_4;
+	sfd.file_nbytes = LARGE_FILE_LEN_4;
+	sfd.header = large_file_header;
+	sfd.hlen = LARGE_FILE_HEADER_SIZE;
+	sfd.trailer = large_file_trailer;
+	sfd.tlen = LARGE_FILE_TRAILER_SIZE;
+    bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_CLOSE_SOCKET,
+        				PR_INTERVAL_NO_TIMEOUT);
+    slen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE +
+						LARGE_FILE_TRAILER_SIZE;
+    if (bytes != slen) {
+        fprintf(stderr,
+			"socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
+									slen, bytes);
+        fprintf(stderr,
+            "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
+            PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+done:
+    if (local_small_file_fd != NULL)
+        PR_Close(local_small_file_fd);
+    if (local_large_file_fd != NULL)
+        PR_Close(local_large_file_fd);
+}
+
+/*
+ * TransmitFile Server
+ *    Server Thread
+ *    Bind an address to a socket and listen for incoming connections
+ *    Create worker threads to service clients
+ */
+static void
+TransmitFile_Server(void *arg)
+{
+    PRThread **t = NULL;  /* an array of PRThread pointers */
+    Server_Param *sp = (Server_Param *) arg;
+    Serve_Client_Param *scp;
+    PRFileDesc *sockfd = NULL, *newsockfd;
+    PRNetAddr netaddr;
+    PRInt32 i;
+
+    t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *));
+    if (t == NULL) {
+        fprintf(stderr, "prsocket_test: run out of memory\n");
+        failed_already=1;
+        goto exit;
+    }
+    /*
+     * Create a tcp socket
+     */
+    if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) {
+        fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n");
+        failed_already=1;
+        goto exit;
+    }
+    memset(&netaddr, 0 , sizeof(netaddr));
+    netaddr.inet.family = PR_AF_INET;
+    netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
+    netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    /*
+     * try a few times to bind server's address, if addresses are in
+     * use
+     */
+    i = 0;
+    while (PR_Bind(sockfd, &netaddr) < 0) {
+        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+            netaddr.inet.port += 2;
+            if (i++ < SERVER_MAX_BIND_COUNT)
+                continue;
+        }
+        fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
+        failed_already=1;
+        perror("PR_Bind");
+        goto exit;
+    }
+
+    if (PR_Listen(sockfd, 32) < 0) {
+        fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
+        failed_already=1;
+        goto exit;
+    }
+
+    if (PR_GetSockName(sockfd, &netaddr) < 0) {
+        fprintf(stderr,
+            "prsocket_test: ERROR - PR_GetSockName failed\n");
+        failed_already=1;
+        goto exit;
+    }
+
+    DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
+        netaddr.inet.ip, netaddr.inet.port));
+    tcp_server_addr.inet.family = netaddr.inet.family;
+    tcp_server_addr.inet.port = netaddr.inet.port;
+    tcp_server_addr.inet.ip = netaddr.inet.ip;
+
+    /*
+     * Wake up parent thread because server address is bound and made
+     * available in the global variable 'tcp_server_addr'
+     */
+    PR_PostSem(sp->addr_sem);
+
+    for (i = 0; i < num_transmitfile_clients ; i++) {
+        /* test both null and non-null 'addr' argument to PR_Accept */
+        PRNetAddr *addrp = (i%2 ? &netaddr: NULL);
+
+        if ((newsockfd = PR_Accept(sockfd, addrp,
+            PR_INTERVAL_NO_TIMEOUT)) == NULL) {
+            fprintf(stderr,
+                "prsocket_test: ERROR - PR_Accept failed\n");
+            failed_already=1;
+            goto exit;
+        }
+        /* test both regular and emulated PR_SendFile */
+        if (i%2) {
+            PRFileDesc *layer = PR_CreateIOLayerStub(
+                emuSendFileIdentity, &emuSendFileMethods);
+            if (layer == NULL) {
+                fprintf(stderr,
+                    "prsocket_test: ERROR - PR_CreateIOLayerStub failed\n");
+                failed_already=1;
+                goto exit;
+            }
+            if (PR_PushIOLayer(newsockfd, PR_TOP_IO_LAYER, layer)
+                    == PR_FAILURE) {
+                fprintf(stderr,
+                    "prsocket_test: ERROR - PR_PushIOLayer failed\n");
+                failed_already=1;
+                goto exit;
+            }
+        }
+        scp = PR_NEW(Serve_Client_Param);
+        if (scp == NULL) {
+            fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+            failed_already=1;
+            goto exit;
+        }
+
+        /*
+         * Start a Serve_Client thread for each incoming connection
+         */
+        scp->sockfd = newsockfd;
+        scp->datalen = sp->datalen;
+
+        t[i] = PR_CreateThread(PR_USER_THREAD,
+            Serve_TransmitFile_Client, (void *)scp, 
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_JOINABLE_THREAD,
+            0);
+        if (t[i] == NULL) {
+            fprintf(stderr,
+                "prsocket_test: PR_CreateThread failed\n");
+            failed_already=1;
+            goto exit;
+        }
+        DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t));
+    }
+
+    /*
+     * Wait for all the worker threads to end, so that we know
+     * they are no longer using the small and large file fd's.
+     */
+
+    for (i = 0; i < num_transmitfile_clients; i++) {
+        PR_JoinThread(t[i]);
+    }
+
+exit:
+    if (t) {
+        PR_DELETE(t);
+    }
+    if (sockfd) {
+        PR_Close(sockfd);
+    }
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(sp->exit_mon);
+    --(*sp->exit_counter);
+    PR_Notify(sp->exit_mon);
+    PR_ExitMonitor(sp->exit_mon);
+    DPRINTF(("TransmitFile_Server [0x%lx] exiting\n", PR_GetCurrentThread()));
+}
+
+/*
+ * Socket_Misc_Test    - test miscellaneous functions 
+ *    
+ */
+static PRInt32
+Socket_Misc_Test(void)
+{
+    PRIntn i, rv = 0, bytes, count, len;
+    PRThread *t;
+    PRSemaphore *server_sem;
+    Server_Param *sparamp;
+    Client_Param *cparamp;
+    PRMonitor *mon2;
+    PRInt32    datalen;
+
+    /*
+ * We deliberately pick a buffer size that is not a nice multiple
+ * of 1024.
+ */
+#define TRANSMITFILE_BUF_SIZE    (4 * 1024 - 11)
+
+    typedef struct {
+        char    data[TRANSMITFILE_BUF_SIZE];
+    } file_buf;
+    file_buf *buf = NULL;
+
+    /*
+     * create file(s) to be transmitted
+     */
+    if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
+        printf("prsocket_test failed to create dir %s\n",TEST_DIR);
+        failed_already=1;
+        return -1;
+    }
+
+    small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777);
+
+    if (small_file_fd == NULL) {
+        fprintf(stderr,"prsocket_test failed to create/open file %s\n",
+            SMALL_FILE_NAME);
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    buf = PR_NEW(file_buf);
+    if (buf == NULL) {
+        fprintf(stderr,"prsocket_test failed to allocate buffer\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    /*
+     * fill in random data
+     */
+    for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) {
+        buf->data[i] = i;
+    }
+    count = 0;
+    do {
+        len = (SMALL_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ?
+            TRANSMITFILE_BUF_SIZE : (SMALL_FILE_SIZE - count);
+        bytes = PR_Write(small_file_fd, buf->data, len);
+        if (bytes <= 0) {
+            fprintf(stderr,
+                "prsocket_test failed to write to file %s\n",
+                SMALL_FILE_NAME);
+            failed_already=1;
+            rv = -1;
+            goto done;
+        }
+        count += bytes;
+    } while (count < SMALL_FILE_SIZE);
+#ifdef XP_UNIX
+    /*
+     * map the small file; used in checking for data corruption
+     */
+    small_file_addr = mmap(0, SMALL_FILE_SIZE, PROT_READ,
+        MAP_SHARED, small_file_fd->secret->md.osfd, 0);
+    if (small_file_addr == (void *) -1) {
+        fprintf(stderr,"prsocket_test failed to mmap file %s\n",
+            SMALL_FILE_NAME);
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+#endif
+    /*
+     * header for small file
+     */
+    small_file_header = PR_MALLOC(SMALL_FILE_HEADER_SIZE);
+    if (small_file_header == NULL) {
+        fprintf(stderr,"prsocket_test failed to malloc header file\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    memset(small_file_header, (int) PR_IntervalNow(),
+        SMALL_FILE_HEADER_SIZE);
+    /*
+     * trailer for small file
+     */
+    small_file_trailer = PR_MALLOC(SMALL_FILE_TRAILER_SIZE);
+    if (small_file_trailer == NULL) {
+        fprintf(stderr,"prsocket_test failed to malloc header trailer\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    memset(small_file_trailer, (int) PR_IntervalNow(),
+        SMALL_FILE_TRAILER_SIZE);
+    /*
+     * setup large file
+     */
+    large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777);
+
+    if (large_file_fd == NULL) {
+        fprintf(stderr,"prsocket_test failed to create/open file %s\n",
+            LARGE_FILE_NAME);
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    /*
+     * fill in random data
+     */
+    for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) {
+        buf->data[i] = i;
+    }
+    count = 0;
+    do {
+        len = (LARGE_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ?
+            TRANSMITFILE_BUF_SIZE : (LARGE_FILE_SIZE - count);
+        bytes = PR_Write(large_file_fd, buf->data, len);
+        if (bytes <= 0) {
+            fprintf(stderr,
+                "prsocket_test failed to write to file %s: (%ld, %ld)\n",
+                LARGE_FILE_NAME,
+                PR_GetError(), PR_GetOSError());
+            failed_already=1;
+            rv = -1;
+            goto done;
+        }
+        count += bytes;
+    } while (count < LARGE_FILE_SIZE);
+#ifdef XP_UNIX
+    /*
+     * map the large file; used in checking for data corruption
+     */
+    large_file_addr = mmap(0, LARGE_FILE_SIZE, PROT_READ,
+        MAP_SHARED, large_file_fd->secret->md.osfd, 0);
+    if (large_file_addr == (void *) -1) {
+        fprintf(stderr,"prsocket_test failed to mmap file %s\n",
+            LARGE_FILE_NAME);
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+#endif
+    /*
+     * header for large file
+     */
+    large_file_header = PR_MALLOC(LARGE_FILE_HEADER_SIZE);
+    if (large_file_header == NULL) {
+        fprintf(stderr,"prsocket_test failed to malloc header file\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    memset(large_file_header, (int) PR_IntervalNow(),
+        LARGE_FILE_HEADER_SIZE);
+    /*
+     * trailer for large file
+     */
+    large_file_trailer = PR_MALLOC(LARGE_FILE_TRAILER_SIZE);
+    if (large_file_trailer == NULL) {
+        fprintf(stderr,"prsocket_test failed to malloc header trailer\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    memset(large_file_trailer, (int) PR_IntervalNow(),
+        LARGE_FILE_TRAILER_SIZE);
+
+    datalen = tcp_mesg_size;
+    thread_count = 0;
+    /*
+     * start the server thread
+     */
+    sparamp = PR_NEW(Server_Param);
+    if (sparamp == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    server_sem = PR_NewSem(0);
+    if (server_sem == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    mon2 = PR_NewMonitor();
+    if (mon2 == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    PR_EnterMonitor(mon2);
+
+    sparamp->addr_sem = server_sem;
+    sparamp->exit_mon = mon2;
+    sparamp->exit_counter = &thread_count;
+    sparamp->datalen = datalen;
+    t = PR_CreateThread(PR_USER_THREAD,
+        TransmitFile_Server, (void *)sparamp, 
+        PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD,
+        PR_UNJOINABLE_THREAD,
+        0);
+    if (t == NULL) {
+        fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    DPRINTF(("Created TCP server = 0x%x\n", t));
+    thread_count++;
+
+    /*
+     * wait till the server address is setup
+     */
+    PR_WaitSem(server_sem);
+
+    /*
+     * Now start a bunch of client threads
+     */
+
+    cparamp = PR_NEW(Client_Param);
+    if (cparamp == NULL) {
+        fprintf(stderr,"prsocket_test: PR_NEW failed\n");
+        failed_already=1;
+        rv = -1;
+        goto done;
+    }
+    cparamp->server_addr = tcp_server_addr;
+    cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    cparamp->exit_mon = mon2;
+    cparamp->exit_counter = &thread_count;
+    cparamp->datalen = datalen;
+    for (i = 0; i < num_transmitfile_clients; i++) {
+        t = create_new_thread(PR_USER_THREAD,
+            TransmitFile_Client, (void *) cparamp,
+            PR_PRIORITY_NORMAL,
+            PR_LOCAL_THREAD,
+            PR_UNJOINABLE_THREAD,
+            0, i);
+        if (t == NULL) {
+            fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
+            rv = -1;
+            failed_already=1;
+            goto done;
+        }
+        DPRINTF(("Created TransmitFile client = 0x%lx\n", t));
+        thread_count++;
+    }
+    /* Wait for server and client threads to exit */
+    while (thread_count) {
+        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("Socket_Misc_Test - thread_count  = %d\n", thread_count));
+    }
+    PR_ExitMonitor(mon2);
+done:
+    if (buf) {
+        PR_DELETE(buf);
+    }
+#ifdef XP_UNIX
+    munmap((char*)small_file_addr, SMALL_FILE_SIZE);
+    munmap((char*)large_file_addr, LARGE_FILE_SIZE);
+#endif
+    PR_Close(small_file_fd);
+    PR_Close(large_file_fd);
+    if ((PR_Delete(SMALL_FILE_NAME)) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: failed to unlink file %s\n",
+            SMALL_FILE_NAME);
+        failed_already=1;
+    }
+    if ((PR_Delete(LARGE_FILE_NAME)) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test: failed to unlink file %s\n",
+            LARGE_FILE_NAME);
+        failed_already=1;
+    }
+    if ((PR_RmDir(TEST_DIR)) == PR_FAILURE) {
+        fprintf(stderr,"prsocket_test failed to rmdir %s: (%ld, %ld)\n",
+            TEST_DIR, PR_GetError(), PR_GetOSError());
+        failed_already=1;
+    }
+
+    printf("%-29s%s","Socket_Misc_Test",":");
+    printf("%2d Server %2d Clients\n",1, num_transmitfile_clients);
+    printf("%30s Sizes of Transmitted Files  - %4d KB, %2d MB \n",":",
+        SMALL_FILE_SIZE/1024, LARGE_FILE_SIZE/(1024 * 1024));
+
+
+    return rv;
+}
+/************************************************************************/
+
+/*
+ * Test Socket NSPR APIs
+ */
+
+int
+main(int argc, char **argv)
+{
+    /*
+     * -d           debug mode
+     */
+
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+    SetupMacPrintfLog("socket.log");
+#endif
+    PR_SetConcurrency(4);
+
+    emuSendFileIdentity = PR_GetUniqueIdentity("Emulated SendFile");
+    emuSendFileMethods = *PR_GetDefaultIOMethods();
+    emuSendFileMethods.transmitfile = emu_TransmitFile;
+    emuSendFileMethods.sendfile = emu_SendFile;
+
+    /*
+     * run client-server test with TCP, Ipv4-Ipv4
+     */
+	printf("TCP Client/Server Test - IPv4/Ipv4\n");
+    if (TCP_Socket_Client_Server_Test() < 0) {
+        printf("TCP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("TCP_Socket_Client_Server_Test Passed\n");
+    /*
+     * client-server test, Ipv6-Ipv4
+     */
+	client_domain = PR_AF_INET6;
+	printf("TCP Client/Server Test - IPv6/Ipv4\n");
+    if (TCP_Socket_Client_Server_Test() < 0) {
+        printf("TCP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("TCP_Socket_Client_Server_Test Passed\n");
+    /*
+     * client-server test, Ipv4-Ipv6
+     */
+	client_domain = PR_AF_INET;
+	server_domain = PR_AF_INET6;
+	printf("TCP Client/Server Test - IPv4/Ipv6\n");
+    if (TCP_Socket_Client_Server_Test() < 0) {
+        printf("TCP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("TCP_Socket_Client_Server_Test Passed\n");
+    /*
+     * client-server test, Ipv6-Ipv6
+     */
+	client_domain = PR_AF_INET6;
+	server_domain = PR_AF_INET6;
+	printf("TCP Client/Server Test - IPv6/Ipv6\n");
+    if (TCP_Socket_Client_Server_Test() < 0) {
+        printf("TCP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("TCP_Socket_Client_Server_Test Passed\n");
+	test_cancelio = 0;
+    /*
+     * run client-server test with UDP, IPv4/IPv4
+     */
+	printf("UDP Client/Server Test - IPv4/Ipv4\n");
+	client_domain = PR_AF_INET;
+	server_domain = PR_AF_INET;
+    if (UDP_Socket_Client_Server_Test() < 0) {
+        printf("UDP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("UDP_Socket_Client_Server_Test Passed\n");
+    /*
+     * run client-server test with UDP, IPv6/IPv4
+     */
+	printf("UDP Client/Server Test - IPv6/Ipv4\n");
+	client_domain = PR_AF_INET6;
+	server_domain = PR_AF_INET;
+    if (UDP_Socket_Client_Server_Test() < 0) {
+        printf("UDP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("UDP_Socket_Client_Server_Test Passed\n");
+    /*
+     * run client-server test with UDP,IPv4-IPv6
+     */
+	printf("UDP Client/Server Test - IPv4/Ipv6\n");
+	client_domain = PR_AF_INET;
+	server_domain = PR_AF_INET6;
+    if (UDP_Socket_Client_Server_Test() < 0) {
+        printf("UDP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("UDP_Socket_Client_Server_Test Passed\n");
+    /*
+     * run client-server test with UDP,IPv6-IPv6
+     */
+	printf("UDP Client/Server Test - IPv6/Ipv6\n");
+	client_domain = PR_AF_INET6;
+	server_domain = PR_AF_INET6;
+    if (UDP_Socket_Client_Server_Test() < 0) {
+        printf("UDP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("UDP_Socket_Client_Server_Test Passed\n");
+    /*
+     * Misc socket tests - including transmitfile, etc.
+     */
+
+#if !defined(WIN16)
+    /*
+** The 'transmit file' test does not run because
+** transmit file is not implemented in NSPR yet.
+**
+*/
+    if (Socket_Misc_Test() < 0) {
+        printf("Socket_Misc_Test failed\n");
+        failed_already=1;
+        goto done;
+    } else
+        printf("Socket_Misc_Test passed\n");
+
+    /*
+     * run client-server test with TCP again to test
+     * recycling used sockets from PR_TransmitFile().
+     */
+    if (TCP_Socket_Client_Server_Test() < 0) {
+        printf("TCP_Socket_Client_Server_Test failed\n");
+        goto done;
+    } else
+        printf("TCP_Socket_Client_Server_Test Passed\n");
+#endif
+
+done:
+    PR_Cleanup();
+    if (failed_already) return 1;
+    else return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sockopt.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sockopt.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,213 @@
+/* -*- 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 "nspr.h"
+#include "prio.h"
+#include "prinit.h"
+#include "prprf.h"
+#ifdef XP_MAC
+#include "probslet.h"
+#else
+#include "obsolete/probslet.h"
+#endif
+
+#include "plerror.h"
+
+static PRFileDesc *err = NULL;
+static PRBool failed = PR_FALSE;
+
+#ifndef XP_MAC
+static void Failed(const char *msg1, const char *msg2)
+{
+    if (NULL != msg1) PR_fprintf(err, "%s ", msg1);
+    PL_FPrintError(err, msg2);
+    failed = PR_TRUE;
+}  /* Failed */
+
+#else
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+static void Failed(const char *msg1, const char *msg2)
+{
+    if (NULL != msg1) printf("%s ", msg1);
+    printf (msg2);
+    failed |= PR_TRUE;
+}  /* Failed */
+
+#endif
+
+static PRSockOption Incr(PRSockOption *option)
+{
+    PRIntn val = ((PRIntn)*option) + 1;
+    *option = (PRSockOption)val;
+    return (PRSockOption)val;
+}  /* Incr */
+
+PRIntn main(PRIntn argc, char *argv)
+{
+    PRStatus rv;
+    PRFileDesc *udp = PR_NewUDPSocket();
+    PRFileDesc *tcp = PR_NewTCPSocket();
+    const char *tag[] =
+    {
+        "PR_SockOpt_Nonblocking",     /* nonblocking io */
+        "PR_SockOpt_Linger",          /* linger on close if data present */
+        "PR_SockOpt_Reuseaddr",       /* allow local address reuse */
+        "PR_SockOpt_Keepalive",       /* keep connections alive */
+        "PR_SockOpt_RecvBufferSize",  /* send buffer size */
+        "PR_SockOpt_SendBufferSize",  /* receive buffer size */
+
+        "PR_SockOpt_IpTimeToLive",    /* time to live */
+        "PR_SockOpt_IpTypeOfService", /* type of service and precedence */
+
+        "PR_SockOpt_AddMember",       /* add an IP group membership */
+        "PR_SockOpt_DropMember",      /* drop an IP group membership */
+        "PR_SockOpt_McastInterface",  /* multicast interface address */
+        "PR_SockOpt_McastTimeToLive", /* multicast timetolive */
+        "PR_SockOpt_McastLoopback",   /* multicast loopback */
+
+        "PR_SockOpt_NoDelay",         /* don't delay send to coalesce packets */
+        "PR_SockOpt_MaxSegment",      /* maximum segment size */
+        "PR_SockOpt_Broadcast",       /* Enable broadcast */
+        "PR_SockOpt_Last"
+    };
+
+    err = PR_GetSpecialFD(PR_StandardError);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("sockopt.log");
+#endif
+
+    if (NULL == udp) Failed("PR_NewUDPSocket()", NULL);
+    else if (NULL == tcp) Failed("PR_NewTCPSocket()", NULL);
+    else
+    {
+        PRSockOption option;
+        PRUint32 segment = 1024;
+        PRNetAddr addr;
+
+        rv = PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr);
+        if (PR_FAILURE == rv) Failed("PR_InitializeNetAddr()", NULL);
+        rv = PR_Bind(udp, &addr);
+        if (PR_FAILURE == rv) Failed("PR_Bind()", NULL);
+        for(option = PR_SockOpt_Linger; option < PR_SockOpt_Last; Incr(&option))
+        {
+            PRSocketOptionData data;
+            PRFileDesc *fd = tcp;
+            data.option = option;
+            switch (option)
+            {
+                case PR_SockOpt_Nonblocking:
+                    data.value.non_blocking = PR_TRUE;
+                    break;    
+                case PR_SockOpt_Linger:
+                    data.value.linger.polarity = PR_TRUE;
+                    data.value.linger.linger = PR_SecondsToInterval(2);          
+                    break;    
+                case PR_SockOpt_Reuseaddr:
+                    data.value.reuse_addr = PR_TRUE;      
+                    break;    
+                case PR_SockOpt_Keepalive:       
+                    data.value.keep_alive = PR_TRUE;      
+                    break;    
+                case PR_SockOpt_RecvBufferSize:
+                    data.value.recv_buffer_size = segment;  
+                    break;    
+                case PR_SockOpt_SendBufferSize:  
+                    data.value.send_buffer_size = segment;  
+                    break;    
+                case PR_SockOpt_IpTimeToLive:
+                    data.value.ip_ttl = 64;  
+                    break;    
+                case PR_SockOpt_IpTypeOfService:
+                    data.value.tos = 0; 
+                    break;    
+                case PR_SockOpt_McastTimeToLive:
+                    fd = udp; 
+                    data.value.mcast_ttl = 4; 
+                    break;    
+                case PR_SockOpt_McastLoopback:
+                    fd = udp; 
+                    data.value.mcast_loopback = PR_TRUE; 
+                    break;    
+                case PR_SockOpt_NoDelay:
+                    data.value.no_delay = PR_TRUE;         
+                    break;    
+#ifndef WIN32
+                case PR_SockOpt_MaxSegment:
+                    data.value.max_segment = segment;      
+                    break;    
+#endif
+                case PR_SockOpt_Broadcast:
+                    fd = udp; 
+                    data.value.broadcast = PR_TRUE;         
+                    break;    
+                default: continue;
+            }
+
+			/*
+			 * TCP_MAXSEG can only be read, not set
+			 */
+            if (option != PR_SockOpt_MaxSegment) {
+#ifdef WIN32
+            	if (option != PR_SockOpt_McastLoopback)
+#endif
+				{
+            		rv = PR_SetSocketOption(fd, &data);
+            		if (PR_FAILURE == rv)
+							Failed("PR_SetSocketOption()", tag[option]);
+				}
+			}
+
+            rv = PR_GetSocketOption(fd, &data);
+            if (PR_FAILURE == rv) Failed("PR_GetSocketOption()", tag[option]);
+        }
+        PR_Close(udp);
+        PR_Close(tcp);
+    }
+#ifndef XP_MAC
+    PR_fprintf(err, "%s\n", (failed) ? "FAILED" : "PASSED");
+#else
+   printf("%s\n", (failed) ? "FAILED" : "PASSED");
+#endif
+    return (failed) ? 1 : 0;
+}  /* main */
+
+/* sockopt.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sockping.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sockping.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,164 @@
+/* -*- 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 ***** */
+
+/*
+ * File: sockping.c
+ *
+ * Description:
+ * This test runs in conjunction with the sockpong test.
+ * This test creates a socket pair and passes one socket
+ * to the sockpong test.  Then this test writes "ping" to
+ * to the sockpong test and the sockpong test writes "pong"
+ * back.  To run this pair of tests, just invoke sockping.
+ *
+ * Tested areas: process creation, socket pairs, file
+ * descriptor inheritance.
+ */
+
+#include "prerror.h"
+#include "prio.h"
+#include "prproces.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUM_ITERATIONS 10
+
+static char *child_argv[] = { "sockpong", NULL };
+
+int main()
+{
+    PRFileDesc *sock[2];
+    PRStatus status;
+    PRProcess *process;
+    PRProcessAttr *attr;
+    char buf[1024];
+    PRInt32 nBytes;
+    PRInt32 exitCode;
+    int idx;
+
+    status = PR_NewTCPSocketPair(sock);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_NewTCPSocketPair failed\n");
+        exit(1);
+    }
+
+    status = PR_SetFDInheritable(sock[0], PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+    status = PR_SetFDInheritable(sock[1], PR_TRUE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n",
+                PR_GetError(), PR_GetOSError());
+        exit(1);
+    }
+
+    attr = PR_NewProcessAttr();
+    if (attr == NULL) {
+        fprintf(stderr, "PR_NewProcessAttr failed\n");
+        exit(1);
+    }
+
+    status = PR_ProcessAttrSetInheritableFD(attr, sock[1], "SOCKET");
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n");
+        exit(1);
+    }
+
+    process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr);
+    if (process == NULL) {
+        fprintf(stderr, "PR_CreateProcess failed\n");
+        exit(1);
+    }
+    PR_DestroyProcessAttr(attr);
+    status = PR_Close(sock[1]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        strcpy(buf, "ping");
+        printf("ping process: sending \"%s\"\n", buf);
+        nBytes = PR_Write(sock[0], buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(sock[0], buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        printf("ping process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "pong") != 0) {
+            fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+    }
+
+    status = PR_Close(sock[0]);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    status = PR_WaitProcess(process, &exitCode);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_WaitProcess failed\n");
+        exit(1);
+    }
+    if (exitCode == 0) {
+        printf("PASS\n");
+        return 0;
+    } else {
+        printf("FAIL\n");
+        return 1;
+    }
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sockpong.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sockpong.c	Mon Dec 18 10:53:47 2006
@@ -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) 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 ***** */
+
+/*
+ * File: sockpong.c
+ *
+ * Description:
+ * This test runs in conjunction with the sockping test.
+ * The sockping test creates a socket pair and passes one
+ * socket to this test.  Then the sockping test writes
+ * "ping" to this test and this test writes "pong" back.
+ * To run this pair of tests, just invoke sockping.
+ *
+ * Tested areas: process creation, socket pairs, file
+ * descriptor inheritance.
+ */
+
+#include "prerror.h"
+#include "prio.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NUM_ITERATIONS 10
+
+int main()
+{
+    PRFileDesc *sock;
+    PRStatus status;
+    char buf[1024];
+    PRInt32 nBytes;
+    int idx;
+
+    sock = PR_GetInheritedFD("SOCKET");
+    if (sock == NULL) {
+        fprintf(stderr, "PR_GetInheritedFD failed\n");
+        exit(1);
+    }
+    status = PR_SetFDInheritable(sock, PR_FALSE);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_SetFDInheritable failed\n");
+        exit(1);
+    }
+
+    for (idx = 0; idx < NUM_ITERATIONS; idx++) {
+        memset(buf, 0, sizeof(buf));
+        nBytes = PR_Read(sock, buf, sizeof(buf));
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Read failed: (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+            exit(1);
+        }
+        printf("pong process: received \"%s\"\n", buf);
+        if (nBytes != 5) {
+            fprintf(stderr, "pong process: expected 5 bytes but got %d bytes\n",
+                    nBytes);
+            exit(1);
+        }
+        if (strcmp(buf, "ping") != 0) {
+            fprintf(stderr, "pong process: expected \"ping\" but got \"%s\"\n",
+                    buf);
+            exit(1);
+        }
+
+        strcpy(buf, "pong");
+        printf("pong process: sending \"%s\"\n", buf);
+        nBytes = PR_Write(sock, buf, 5);
+        if (nBytes == -1) {
+            fprintf(stderr, "PR_Write failed\n");
+            exit(1);
+        }
+    }
+
+    status = PR_Close(sock);
+    if (status == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sprintf.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sprintf.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,454 @@
+/* -*- 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:	sprintf.c
+ * Description:
+ *     This is a test program for the PR_snprintf() functions defined
+ *     in prprf.c.  This test program is based on ns/nspr/tests/sprintf.c,
+ *     revision 1.10.
+ * Modification History:
+ *	20-May-1997 AGarcia replaced printf statment to return PASS\n. This is to be used by the
+ *				regress tool parsing routine.
+ ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+ *			recognize the return code from tha main program.
+ */
+
+#include "prinit.h"
+#include "prprf.h"
+#include "prlog.h"
+#include "prlong.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define countof(a) (sizeof(a)/sizeof(a[0]))
+
+static char sbuf[20000];
+
+
+/*
+** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
+** Make sure the results are identical
+*/
+static void test_i(char *pattern, int i)
+{
+    char *s;
+    char buf[200];
+    int n;
+
+    /* try all three routines */
+    s = PR_smprintf(pattern, i);
+    PR_ASSERT(s != 0);
+    n = PR_snprintf(buf, sizeof(buf), pattern, i);
+    PR_ASSERT(n <= sizeof(buf));
+    sprintf(sbuf, pattern, i);
+
+    /* compare results */
+    if ((strncmp(s, buf, sizeof(buf)) != 0) ||
+	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
+	fprintf(stderr,
+	   "pattern='%s' i=%d\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
+	   pattern, i, s, buf, sbuf);
+	   PR_smprintf_free(s);
+	exit(-1);
+    }
+	PR_smprintf_free(s);
+}
+
+static void TestI(void)
+{
+    static int nums[] = {
+	0, 1, -1, 10, -10,
+	32767, -32768,
+    };
+    static char *signs[] = {
+	"",
+	"0",	"-",	"+", " ",
+	"0-",	"0+",	"0 ",	"-0",	"-+",	"- ",
+	"+0",	"+-",	"+ ",	" 0",	" -",	" +",
+	"0-+",	"0- ",	"0+-",	"0+ ",	"0 -",	"0 +",
+	"-0+",	"-0 ",	"-+0",	"-+ ",	"- 0",	"- +",
+	"+0-",	"+0 ",	"+-0",	"+- ",	"+ 0",	"+ -",
+	" 0-",	" 0+",	" -0",	" -+",	" +0",	" +-",
+	"0-+ ",	"0- +",	"0+- ",	"0+ -",	"0 -+",	"0 +-",
+	"-0+ ",	"-0 +",	"-+0 ",	"-+ 0",	"- 0+",	"- +0",
+	"+0- ",	"+0 -",	"+-0 ",	"+- 0",	"+ 0-",	"+ -0",
+	" 0-+",	" 0+-",	" -0+",	" -+0",	" +0-",	" +-0",
+    };
+    static char *precs[] = {
+	"", "3", "5", "43",
+	"7.3", "7.5", "7.11", "7.43",
+    };
+    static char *formats[] = {
+	"d", "o", "x", "u",
+	"hd", "ho", "hx", "hu"
+    };
+    int f, s, n, p;
+    char fmt[20];
+
+    for (f = 0; f < countof(formats); f++) {
+	for (s = 0; s < countof(signs); s++) {
+	    for (p = 0; p < countof(precs); p++) {
+		fmt[0] = '%';
+		fmt[1] = 0;
+		if (signs[s]) strcat(fmt, signs[s]);
+		if (precs[p]) strcat(fmt, precs[p]);
+		if (formats[f]) strcat(fmt, formats[f]);
+		for (n = 0; n < countof(nums); n++) {
+		    test_i(fmt, nums[n]);
+		}
+	    }
+	}
+    }
+}
+
+/************************************************************************/
+
+/*
+** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
+** Make sure the results are identical
+*/
+static void test_l(char *pattern, char *spattern, PRInt32 l)
+{
+    char *s;
+    char buf[200];
+    int n;
+
+    /* try all three routines */
+    s = PR_smprintf(pattern, l);
+    PR_ASSERT(s != 0);
+    n = PR_snprintf(buf, sizeof(buf), pattern, l);
+    PR_ASSERT(n <= sizeof(buf));
+    sprintf(sbuf, spattern, l);
+
+    /* compare results */
+    if ((strncmp(s, buf, sizeof(buf)) != 0) ||
+	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
+	fprintf(stderr,
+	   "pattern='%s' l=%ld\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
+	   pattern, l, s, buf, sbuf);
+	PR_smprintf_free(s);
+	exit(-1);
+    }
+	PR_smprintf_free(s);
+}
+
+static void TestL(void)
+{
+    static PRInt32 nums[] = {
+	0,
+	1,
+	-1,
+	10,
+	-10,
+	32767,
+	-32768,
+	PR_INT32(0x7fffffff), /* 2147483647L */
+	-1 - PR_INT32(0x7fffffff)  /* -2147483648L */
+    };
+    static char *signs[] = {
+	"",
+	"0",	"-",	"+", " ",
+	"0-",	"0+",	"0 ",	"-0",	"-+",	"- ",
+	"+0",	"+-",	"+ ",	" 0",	" -",	" +",
+	"0-+",	"0- ",	"0+-",	"0+ ",	"0 -",	"0 +",
+	"-0+",	"-0 ",	"-+0",	"-+ ",	"- 0",	"- +",
+	"+0-",	"+0 ",	"+-0",	"+- ",	"+ 0",	"+ -",
+	" 0-",	" 0+",	" -0",	" -+",	" +0",	" +-",
+	"0-+ ",	"0- +",	"0+- ",	"0+ -",	"0 -+",	"0 +-",
+	"-0+ ",	"-0 +",	"-+0 ",	"-+ 0",	"- 0+",	"- +0",
+	"+0- ",	"+0 -",	"+-0 ",	"+- 0",	"+ 0-",	"+ -0",
+	" 0-+",	" 0+-",	" -0+",	" -+0",	" +0-",	" +-0",
+    };
+    static char *precs[] = {
+	"", "3", "5", "43",
+	".3", ".43",
+	"7.3", "7.5", "7.11", "7.43",
+    };
+    static char *formats[] = { "ld", "lo", "lx", "lu" };
+
+#if PR_BYTES_PER_INT == 4
+    static char *sformats[] = { "d", "o", "x", "u" };
+#elif PR_BYTES_PER_LONG == 4
+    static char *sformats[] = { "ld", "lo", "lx", "lu" };
+#else
+#error Neither int nor long is 4 bytes on this platform
+#endif
+
+    int f, s, n, p;
+    char fmt[40], sfmt[40];
+
+    for (f = 0; f < countof(formats); f++) {
+	for (s = 0; s < countof(signs); s++) {
+	    for (p = 0; p < countof(precs); p++) {
+		fmt[0] = '%';
+		fmt[1] = 0;
+		if (signs[s]) strcat(fmt, signs[s]);
+		if (precs[p]) strcat(fmt, precs[p]);
+		strcpy(sfmt, fmt);
+		if (formats[f]) strcat(fmt, formats[f]);
+		if (sformats[f]) strcat(sfmt, sformats[f]);
+		for (n = 0; n < countof(nums); n++) {
+		    test_l(fmt, sfmt, nums[n]);
+		}
+	    }
+	}
+    }
+}
+
+/************************************************************************/
+
+/*
+** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
+** Make sure the results are identical
+*/
+static void test_ll(char *pattern, char *spattern, PRInt64 l)
+{
+    char *s;
+    char buf[200];
+    int n;
+
+    /* try all three routines */
+    s = PR_smprintf(pattern, l);
+    PR_ASSERT(s != 0);
+    n = PR_snprintf(buf, sizeof(buf), pattern, l);
+    PR_ASSERT(n <= sizeof(buf));
+#if defined(HAVE_LONG_LONG)
+    sprintf(sbuf, spattern, l);
+
+    /* compare results */
+    if ((strncmp(s, buf, sizeof(buf)) != 0) ||
+	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
+#if PR_BYTES_PER_LONG == 8
+#define FORMAT_SPEC "%ld"
+#elif defined(WIN16)
+#define FORMAT_SPEC "%Ld"
+#elif defined(WIN32)
+#define FORMAT_SPEC "%I64d"
+#else
+#define FORMAT_SPEC "%lld"
+#endif
+	fprintf(stderr,
+	    "pattern='%s' ll=" FORMAT_SPEC "\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
+	    pattern, l, s, buf, sbuf);
+	printf("FAIL\n");
+	PR_smprintf_free(s);
+	exit(-1);
+    }
+	PR_smprintf_free(s);
+#else
+    /* compare results */
+    if ((strncmp(s, buf, sizeof(buf)) != 0)) {
+	fprintf(stderr,
+	    "pattern='%s'\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
+	    pattern, s, buf, sbuf);
+	printf("FAIL\n");
+	PR_smprintf_free(s);
+        exit(-1);
+    }
+	PR_smprintf_free(s);
+#endif
+}
+
+static void TestLL(void)
+{
+    static PRInt64 nums[] = {
+	LL_INIT(0, 0),
+	LL_INIT(0, 1),
+	LL_INIT(0xffffffff, 0xffffffff),  /* -1 */
+	LL_INIT(0, 10),
+	LL_INIT(0xffffffff, 0xfffffff6),  /* -10 */
+	LL_INIT(0, 32767),
+	LL_INIT(0xffffffff, 0xffff8000),  /* -32768 */
+	LL_INIT(0, 0x7fffffff),  /* 2147483647 */
+	LL_INIT(0xffffffff, 0x80000000),  /* -2147483648 */
+	LL_INIT(0x7fffffff, 0xffffffff),  /* 9223372036854775807 */
+	LL_INIT(0x80000000, 0)            /* -9223372036854775808 */
+    };
+
+    static char *signs[] = {
+	"",
+	"0",	"-",	"+", " ",
+	"0-",	"0+",	"0 ",	"-0",	"-+",	"- ",
+	"+0",	"+-",	"+ ",	" 0",	" -",	" +",
+	"0-+",	"0- ",	"0+-",	"0+ ",	"0 -",	"0 +",
+	"-0+",	"-0 ",	"-+0",	"-+ ",	"- 0",	"- +",
+	"+0-",	"+0 ",	"+-0",	"+- ",	"+ 0",	"+ -",
+	" 0-",	" 0+",	" -0",	" -+",	" +0",	" +-",
+	"0-+ ",	"0- +",	"0+- ",	"0+ -",	"0 -+",	"0 +-",
+	"-0+ ",	"-0 +",	"-+0 ",	"-+ 0",	"- 0+",	"- +0",
+	"+0- ",	"+0 -",	"+-0 ",	"+- 0",	"+ 0-",	"+ -0",
+	" 0-+",	" 0+-",	" -0+",	" -+0",	" +0-",	" +-0",
+    };
+    static char *precs[] = {
+	"", "3", "5", "43",
+	".3", ".43",
+	"7.3", "7.5", "7.11", "7.43",
+    };
+    static char *formats[] = { "lld", "llo", "llx", "llu" };
+
+#if PR_BYTES_PER_LONG == 8
+    static char *sformats[] = { "ld", "lo", "lx", "lu" };
+#elif defined(WIN16)
+    /* Watcom uses the format string "%Ld" instead of "%lld". */
+    static char *sformats[] = { "Ld", "Lo", "Lx", "Lu" };
+#elif defined(WIN32)
+    static char *sformats[] = { "I64d", "I64o", "I64x", "I64u" };
+#else
+    static char *sformats[] = { "lld", "llo", "llx", "llu" };
+#endif
+
+    int f, s, n, p;
+    char fmt[40], sfmt[40];
+
+    for (f = 0; f < countof(formats); f++) {
+	for (s = 0; s < countof(signs); s++) {
+	    for (p = 0; p < countof(precs); p++) {
+		fmt[0] = '%';
+		fmt[1] = 0;
+		if (signs[s]) strcat(fmt, signs[s]);
+		if (precs[p]) strcat(fmt, precs[p]);
+		strcpy(sfmt, fmt);
+		if (formats[f]) strcat(fmt, formats[f]);
+		if (sformats[f]) strcat(sfmt, sformats[f]);
+		for (n = 0; n < countof(nums); n++) {
+		    test_ll(fmt, sfmt, nums[n]);
+		}
+	    }
+	}
+    }
+}
+
+/************************************************************************/
+
+/*
+** Perform a three way test against PR_smprintf, PR_snprintf, and sprintf.
+** Make sure the results are identical
+*/
+static void test_s(char *pattern, char *ss)
+{
+    char *s;
+    unsigned char before[8];
+    char buf[200];
+    unsigned char after[8];
+    int n;
+
+    memset(before, 0xBB, 8);
+    memset(after, 0xAA, 8);
+
+    /* try all three routines */
+    s = PR_smprintf(pattern, ss);
+    PR_ASSERT(s != 0);
+    n = PR_snprintf(buf, sizeof(buf), pattern, ss);
+    PR_ASSERT(n <= sizeof(buf));
+    sprintf(sbuf, pattern, ss);
+
+    for (n = 0; n < 8; n++) {
+	PR_ASSERT(before[n] == 0xBB);
+	PR_ASSERT(after[n] == 0xAA);
+    }
+
+    /* compare results */
+    if ((strncmp(s, buf, sizeof(buf)) != 0) ||
+	(strncmp(s, sbuf, sizeof(sbuf)) != 0)) {
+	fprintf(stderr,
+	   "pattern='%s' ss=%.20s\nPR_smprintf='%s'\nPR_snprintf='%s'\n    sprintf='%s'\n",
+	   pattern, ss, s, buf, sbuf);
+	printf("FAIL\n");
+	PR_smprintf_free(s);
+	exit(-1);
+    }
+	PR_smprintf_free(s);
+}
+
+static void TestS(void)
+{
+    static char *strs[] = {
+	"",
+	"a",
+	"abc",
+	"abcde",
+	"abcdefABCDEF",
+	"abcdefghijklmnopqrstuvwxyz0123456789!@#$"
+	    "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$"
+	    "abcdefghijklmnopqrstuvwxyz0123456789!@#$",
+    };
+    /* '0' is not relevant to printing strings */
+    static char *signs[] = {
+	"",
+	"-",	"+",	" ",
+	"-+",	"- ",	"+-",	"+ ",	" -",	" +",
+	"-+ ",	"- +",	"+- ",	"+ -",	" -+",	" +-",
+    };
+    static char *precs[] = {
+	"", "3", "5", "43",
+	".3", ".43",
+	"7.3", "7.5", "7.11", "7.43",
+    };
+    static char *formats[] = { "s" };
+    int f, s, n, p;
+    char fmt[40];
+
+    for (f = 0; f < countof(formats); f++) {
+	for (s = 0; s < countof(signs); s++) {
+	    for (p = 0; p < countof(precs); p++) {
+		fmt[0] = '%';
+		fmt[1] = 0;
+		if (signs[s]) strcat(fmt+strlen(fmt), signs[s]);
+		if (precs[p]) strcat(fmt+strlen(fmt), precs[p]);
+		if (formats[f]) strcat(fmt+strlen(fmt), formats[f]);
+		for (n = 0; n < countof(strs); n++) {
+		    test_s(fmt, strs[n]);
+		}
+	    }
+	}
+    }
+}
+
+/************************************************************************/
+
+int main(int argc, char **argv)
+{
+    PR_STDIO_INIT();
+    TestI();
+    TestL();
+    TestLL();
+    TestS();
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sproc_ch.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sproc_ch.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,119 @@
+/* -*- 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 ***** */
+
+/*
+ * Test sproc_ch.c
+ *
+ * The purpose of this test and the sproc_p.c test is to test the shutdown
+ * of all the IRIX sprocs in a program when one of them dies due to an error.
+ *
+ * There are three sprocs in this test: the parent, the child, and the 
+ * grandchild.  The parent and child sprocs never stop on their own.
+ * The grandchild sproc gets a segmentation fault and dies.  You should
+ * You should use "ps" to see if the parent and child sprocs are killed
+ * after the grandchild dies.
+ */
+
+#include "prinit.h"
+#include <stdio.h>
+
+#if !defined(IRIX)
+
+int main()
+{
+    printf("This test applies to IRIX only.\n");
+    return 0;
+}
+
+#else  /* IRIX */
+
+#include "prthread.h"
+#include <sys/types.h>
+#include <unistd.h>
+
+void SegFault(void *unused)
+{
+    int *p = 0;
+
+    printf("The grandchild sproc has pid %d.\n", getpid());
+    printf("The grandchild sproc will get a segmentation fault and die.\n");
+    printf("The parent and child sprocs should be killed after the "
+            "grandchild sproc dies.\n");
+    printf("Use 'ps' to make sure this is so.\n");
+    fflush(stdout);
+    /* Force a segmentation fault */
+    *p = 0;
+}
+
+void NeverStops(void *unused)
+{
+    int i = 0;
+
+    printf("The child sproc has pid %d.\n", getpid());
+    printf("The child sproc won't stop on its own.\n");
+    fflush(stdout);
+
+    /* create the grandchild sproc */
+    PR_CreateThread(PR_USER_THREAD, SegFault, NULL,
+	    PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+
+    while (1) {
+	i++;
+    }
+}
+
+int main()
+{
+    int i= 0;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+
+    printf("The parent sproc has pid %d.\n", getpid());
+    printf("The parent sproc won't stop on its own.\n");
+    fflush(stdout);
+
+    /* create the child sproc */
+    PR_CreateThread(PR_USER_THREAD, NeverStops, NULL,
+	    PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+
+    while (1) {
+	i++;
+    }
+    return 0;
+}
+
+#endif  /* IRIX */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/sproc_p.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/sproc_p.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,101 @@
+/* -*- 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 ***** */
+
+/*
+ * Test sproc_p.c
+ *
+ * The purpose of this test and the sproc_ch.c test is to test the shutdown
+ * of all the IRIX sprocs in a program when one of them dies due to an error.
+ *
+ * In this test, the parent sproc gets a segmentation fault and dies.
+ * The child sproc never stops on its own.  You should use "ps" to see if
+ * the child sproc is killed after the parent dies.
+ */
+
+#include "prinit.h"
+#include <stdio.h>
+
+#if !defined(IRIX)
+
+int main()
+{
+    printf("This test applies to IRIX only.\n");
+    return 0;
+}
+
+#else  /* IRIX */
+
+#include "prthread.h"
+#include <sys/types.h>
+#include <unistd.h>
+
+void NeverStops(void *unused)
+{
+    int i = 0;
+
+    printf("The child sproc has pid %d.\n", getpid());
+    printf("The child sproc won't stop on its own.\n");
+    fflush(stdout);
+
+    /* I never stop */
+    while (1) {
+	i++;
+    }
+}
+
+int main()
+{
+    int *p = 0;
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+
+    printf("The parent sproc has pid %d.\n", getpid());
+    printf("The parent sproc will first create a child sproc.\n");
+    printf("Then the parent sproc will get a segmentation fault and die.\n");
+    printf("The child sproc should be killed after the parent sproc dies.\n");
+    printf("Use 'ps' to make sure this is so.\n");
+    fflush(stdout);
+
+    PR_CreateThread(PR_USER_THREAD, NeverStops, NULL,
+	    PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+
+    /* Force a segmentation fault */
+    *p = 0;
+    return 0;
+}
+
+#endif /* IRIX */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/stack.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/stack.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,310 @@
+/* -*- 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 ***** */
+
+
+/*
+ *
+ * Test atomic stack operations
+ *		
+ *		Two stacks are created and threads add data items (each containing
+ *		one of the first n integers) to the first stack, remove data items
+ *		from the first stack and add them to the second stack. The primordial
+ *		thread compares the sum of the first n integers to the sum of the
+ *		integers in the data items in the second stack. The test succeeds if
+ *		they are equal.
+ */
+ 
+#include "nspr.h"
+#include "plgetopt.h"
+
+typedef struct _DataRecord {
+	PRInt32	data;
+	PRStackElem	link;
+} DataRecord;
+
+#define RECORD_LINK_PTR(lp) ((DataRecord*) ((char*) (lp) - offsetof(DataRecord,link)))
+
+#define MAX_THREAD_CNT		100
+#define DEFAULT_THREAD_CNT	4
+#define DEFAULT_DATA_CNT	100
+#define DEFAULT_LOOP_CNT	10000
+
+/*
+ * sum of the first n numbers using the formula n*(n+1)/2
+ */
+#define SUM_OF_NUMBERS(n) ((n & 1) ? (((n + 1)/2) * n) : ((n/2) * (n+1)))
+
+typedef struct stack_data {
+	PRStack		*list1;
+	PRStack		*list2;
+	PRInt32		initial_data_value;
+	PRInt32		data_cnt;
+	PRInt32		loops;
+} stack_data;
+
+static void stackop(void *arg);
+
+static int _debug_on;
+
+PRFileDesc  *output;
+PRFileDesc  *errhandle;
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRInt32 rv, cnt, sum;
+	DataRecord	*Item;
+	PRStack		*list1, *list2;
+	PRStackElem	*node;
+	PRStatus rc;
+
+	PRInt32 thread_cnt = DEFAULT_THREAD_CNT;
+	PRInt32 data_cnt = DEFAULT_DATA_CNT;
+	PRInt32 loops = DEFAULT_LOOP_CNT;
+	PRThread **threads;
+	stack_data *thread_args;
+
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:l:");
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			_debug_on = 1;
+            break;
+        case 't':  /* thread count */
+            thread_cnt = atoi(opt->value);
+            break;
+        case 'c':  /* data count */
+            data_cnt = atoi(opt->value);
+            break;
+        case 'l':  /* loop count */
+            loops = atoi(opt->value);
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+	PR_SetConcurrency(4);
+
+    output = PR_GetSpecialFD(PR_StandardOutput);
+    errhandle = PR_GetSpecialFD(PR_StandardError);
+	list1 = PR_CreateStack("Stack_1");
+	if (list1 == NULL) {
+		PR_fprintf(errhandle, "PR_CreateStack failed - error %d\n",
+								PR_GetError());
+		return 1;
+	}
+
+	list2 = PR_CreateStack("Stack_2");
+	if (list2 == NULL) {
+		PR_fprintf(errhandle, "PR_CreateStack failed - error %d\n",
+								PR_GetError());
+		return 1;
+	}
+
+
+	threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt);
+	thread_args = (stack_data *) PR_CALLOC(sizeof(stack_data) * thread_cnt);
+
+	if (_debug_on)
+		PR_fprintf(output,"%s: thread_cnt = %d data_cnt = %d\n", argv[0],
+							thread_cnt, data_cnt);
+	for(cnt = 0; cnt < thread_cnt; cnt++) {
+		PRThreadScope scope;
+
+		thread_args[cnt].list1 = list1;
+		thread_args[cnt].list2 = list2;
+		thread_args[cnt].loops = loops;
+		thread_args[cnt].data_cnt = data_cnt;	
+		thread_args[cnt].initial_data_value = 1 + cnt * data_cnt;
+
+		if (cnt & 1)
+			scope = PR_GLOBAL_THREAD;
+		else
+			scope = PR_LOCAL_THREAD;
+
+
+		threads[cnt] = PR_CreateThread(PR_USER_THREAD,
+						  stackop, &thread_args[cnt],
+						  PR_PRIORITY_NORMAL,
+						  scope,
+						  PR_JOINABLE_THREAD,
+						  0);
+		if (threads[cnt] == NULL) {
+			PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n",
+								PR_GetError());
+			PR_ProcessExit(2);
+		}
+		if (_debug_on)
+			PR_fprintf(output,"%s: created thread = 0x%x\n", argv[0],
+										threads[cnt]);
+	}
+
+	for(cnt = 0; cnt < thread_cnt; cnt++) {
+    	rc = PR_JoinThread(threads[cnt]);
+		PR_ASSERT(rc == PR_SUCCESS);
+	}
+
+	node = PR_StackPop(list1);
+	/*
+	 * list1 should be empty
+	 */
+	if (node != NULL) {
+		PR_fprintf(errhandle, "Error - Stack 1 not empty\n");
+		PR_ASSERT(node == NULL);
+		PR_ProcessExit(4);
+	}
+
+	cnt = data_cnt * thread_cnt;
+	sum = 0;
+	while (cnt-- > 0) {
+		node = PR_StackPop(list2);
+		/*
+		 * There should be at least 'cnt' number of records
+		 */
+		if (node == NULL) {
+			PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n");
+			PR_ProcessExit(3);
+		}
+		Item = RECORD_LINK_PTR(node);
+		sum += Item->data;
+	}
+	node = PR_StackPop(list2);
+	/*
+	 * there should be exactly 'cnt' number of records
+	 */
+	if (node != NULL) {
+		PR_fprintf(errhandle, "Error - Stack 2 not empty\n");
+		PR_ASSERT(node == NULL);
+		PR_ProcessExit(4);
+	}
+	PR_DELETE(threads);
+	PR_DELETE(thread_args);
+
+	PR_DestroyStack(list1);
+	PR_DestroyStack(list2);
+
+	if (sum == SUM_OF_NUMBERS(data_cnt * thread_cnt)) {
+		PR_fprintf(output, "%s successful\n", argv[0]);
+		PR_fprintf(output, "\t\tsum = 0x%x, expected = 0x%x\n", sum,
+							SUM_OF_NUMBERS(thread_cnt * data_cnt));
+		return 0;
+	} else {
+		PR_fprintf(output, "%s failed: sum = 0x%x, expected = 0x%x\n",
+							argv[0], sum,
+								SUM_OF_NUMBERS(data_cnt * thread_cnt));
+		return 2;
+	}
+}
+
+static void stackop(void *thread_arg)
+{
+    PRInt32 val, cnt, index, loops;
+	DataRecord	*Items, *Item;
+	PRStack		*list1, *list2;
+	PRStackElem	*node;
+	stack_data *arg = (stack_data *) thread_arg;
+
+	val = arg->initial_data_value;
+	cnt = arg->data_cnt;
+	loops = arg->loops;
+	list1 = arg->list1;
+	list2 = arg->list2;
+
+	/*
+	 * allocate memory for the data records
+	 */
+	Items = (DataRecord *) PR_CALLOC(sizeof(DataRecord) * cnt);
+	PR_ASSERT(Items != NULL);
+	index = 0;
+
+	if (_debug_on)
+		PR_fprintf(output,
+		"Thread[0x%x] init_val = %d cnt = %d data1 = 0x%x datan = 0x%x\n",
+				PR_GetCurrentThread(), val, cnt, &Items[0], &Items[cnt-1]);
+
+
+	/*
+	 * add the data records to list1
+	 */
+	while (cnt-- > 0) {
+		Items[index].data = val++;
+		PR_StackPush(list1, &Items[index].link);
+		index++;
+	}
+
+	/*
+	 * pop data records from list1 and add them back to list1
+	 * generates contention for the stack accesses
+	 */
+	while (loops-- > 0) {
+		cnt = arg->data_cnt;
+		while (cnt-- > 0) {
+			node = PR_StackPop(list1);
+			if (node == NULL) {
+				PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n");
+				PR_ASSERT(node != NULL);
+				PR_ProcessExit(3);
+			}
+			PR_StackPush(list1, node);
+		}
+	}
+	/*
+	 * remove the data records from list1 and add them to list2
+	 */
+	cnt = arg->data_cnt;
+	while (cnt-- > 0) {
+		node = PR_StackPop(list1);
+		if (node == NULL) {
+			PR_fprintf(errhandle, "Error - PR_StackPop returned NULL\n");
+			PR_ASSERT(node != NULL);
+			PR_ProcessExit(3);
+		}
+		PR_StackPush(list2, node);
+	}
+	if (_debug_on)
+		PR_fprintf(output,
+		"Thread[0x%x] init_val = %d cnt = %d exiting\n",
+				PR_GetCurrentThread(), val, cnt);
+
+}
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/stat.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/stat.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,119 @@
+/* -*- 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 ***** */
+
+/*
+ * Program to test different ways to get file info; right now it 
+ * only works for solaris and OS/2.
+ *
+ */
+#include "nspr.h"
+#include "prpriv.h"
+#include "prinrval.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_OS2
+#include <io.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#define DEFAULT_COUNT 100000
+PRInt32 count;
+
+#ifndef XP_PC
+char *filename = "/etc/passwd";
+#else
+char *filename = "..\\stat.c";
+#endif
+
+static void statPRStat(void)
+{
+    PRFileInfo finfo;
+    PRInt32 index = count;
+ 
+    for (;index--;) {
+         PR_GetFileInfo(filename, &finfo);
+    }
+}
+
+static void statStat(void)
+{
+    struct stat finfo;
+    PRInt32 index = count;
+ 
+    for (;index--;) {
+        stat(filename, &finfo);
+    }
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+    PRInt32 tot;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+    tot = PR_IntervalToMilliseconds(stop-start);
+
+    printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot);
+}
+
+void main(int argc, char **argv)
+{
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (argc > 1) {
+	count = atoi(argv[1]);
+    } else {
+	count = DEFAULT_COUNT;
+    }
+
+    Measure(statPRStat, "time to call PR_GetFileInfo()");
+    Measure(statStat, "time to call stat()");
+
+    PR_Cleanup();
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/stdio.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/stdio.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+ * File:        stdio.c
+ * Description: testing the "special" fds
+ * Modification History:
+ * 20-May-1997 AGarcia - Replace Test succeeded status with PASS. This is used by the
+ *						regress tool parsing code.
+ ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
+**			recognize the return code from tha main program.
+ */
+
+
+#include "prlog.h"
+#include "prinit.h"
+#include "prio.h"
+
+#include <stdio.h>
+#include <string.h>
+
+static PRIntn PR_CALLBACK stdio(PRIntn argc, char **argv)
+{
+    PRInt32 rv;
+
+    PRFileDesc *out = PR_GetSpecialFD(PR_StandardOutput);
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+
+    rv = PR_Write(
+        out, "This to standard out\n",
+        strlen("This to standard out\n"));
+    PR_ASSERT((PRInt32)strlen("This to standard out\n") == rv);
+    rv = PR_Write(
+        err, "This to standard err\n",
+        strlen("This to standard err\n"));
+    PR_ASSERT((PRInt32)strlen("This to standard err\n") == rv);
+
+    return 0;
+
+}  /* stdio */
+
+int main(int argc, char **argv)
+{
+    PR_STDIO_INIT();
+    return PR_Initialize(stdio, argc, argv, 0);
+}  /* main */
+
+
+/* stdio.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/str2addr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/str2addr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,82 @@
+/* -*- 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 ***** */
+
+/*
+ * File: str2addr.c
+ * Description: a test for PR_StringToNetAddr
+ */
+
+#include "nspr.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Address string to convert */
+#define DEFAULT_IPV4_ADDR_STR "207.200.73.41"
+
+/* Expected conversion result, in network byte order */
+static unsigned char default_ipv4_addr[] = {207, 200, 73, 41};
+
+int main(int argc, char **argv)
+{
+    PRNetAddr addr;
+    const char *addrStr;
+    unsigned char *bytes;
+    int idx;
+
+    addrStr = DEFAULT_IPV4_ADDR_STR;
+    if (PR_StringToNetAddr(addrStr, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_StringToNetAddr failed\n");
+        exit(1);
+    }
+    if (addr.inet.family != PR_AF_INET) {
+        fprintf(stderr, "addr.inet.family should be %d but is %d\n",
+                PR_AF_INET, addr.inet.family);
+        exit(1);
+    }
+    bytes = (unsigned char *) &addr.inet.ip;
+    for (idx = 0; idx < 4; idx++) {
+        if (bytes[idx] != default_ipv4_addr[idx]) {
+            fprintf(stderr, "byte %d of IPv4 addr should be %d but is %d\n",
+                    idx, default_ipv4_addr[idx], bytes[idx]);
+            exit(1);
+        }
+    }
+
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/strod.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/strod.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,106 @@
+/* -*- 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 "prio.h"
+#include "prprf.h"
+#include "prdtoa.h"
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+static void Help(void)
+{
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PR_fprintf(err, "Usage: /.strod [-n n] [-l n] [-h]\n");
+    PR_fprintf(err, "\t-n n Number to translate    (default: 1234567890123456789)\n");
+    PR_fprintf(err, "\t-l n Times to loop the test (default: 1)\n");
+    PR_fprintf(err, "\t-h   This message and nothing else\n");
+}  /* Help */
+
+static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv)
+{
+    PLOptStatus os;
+    PRIntn loops = 1;
+    PRFloat64 answer;
+    const char *number = "1234567890123456789";
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hc:l:");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'n':  /* number to translate */
+            number = opt->value;
+            break;
+        case 'l':  /* number of times to run the tests */
+            loops = atoi(opt->value);
+            break;
+        case 'h':  /* user wants some guidance */
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+            break;
+         default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_fprintf(err, "Settings\n");
+    PR_fprintf(err, "\tNumber to translate %s\n", number);
+    PR_fprintf(err, "\tLoops to run test: %d\n", loops);
+
+    while (loops--)
+    {
+        answer = PR_strtod(number, NULL);
+        PR_fprintf(err, "Translation = %20.0f\n", answer);
+    }
+    return 0;
+}
+
+
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/suspend.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/suspend.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,231 @@
+/* -*- 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 ***** */
+
+#ifdef XP_BEOS
+#include <stdio.h>
+int main()
+{
+    printf( "This test is not ported to the BeOS\n" );
+    return 0;
+}
+#else
+
+#include "nspr.h"
+#include "prpriv.h"
+#include "prinrval.h"
+
+#if defined(XP_MAC)
+#include "gcint.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "gcint.h"
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+PRMonitor *mon;
+PRInt32 count;
+PRInt32 alive;
+
+#define SLEEP_TIME    4    /* secs */
+
+void PR_CALLBACK
+Level_2_Thread(void *arg)
+{
+    PR_Sleep(PR_MillisecondsToInterval(4 * 1000));
+    printf("Level_2_Thread[0x%lx] exiting\n",PR_GetCurrentThread());
+    return;
+}
+
+void PR_CALLBACK
+Level_1_Thread(void *arg)
+{
+    PRUint32 tmp = (PRUint32)arg;
+    PRThreadScope scope = (PRThreadScope) tmp;
+    PRThread *thr;
+
+    thr = PR_CreateThreadGCAble(PR_USER_THREAD,
+        Level_2_Thread,
+        NULL,
+        PR_PRIORITY_HIGH,
+        scope,
+        PR_JOINABLE_THREAD,
+        0);
+
+    if (!thr) {
+        printf("Could not create thread!\n");
+    } else {
+        printf("Level_1_Thread[0x%lx] created %15s thread 0x%lx\n",
+            PR_GetCurrentThread(),
+            (scope == PR_GLOBAL_THREAD) ?
+            "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
+            thr);
+        PR_JoinThread(thr);
+    }
+    PR_EnterMonitor(mon);
+    alive--;
+    PR_Notify(mon);
+    PR_ExitMonitor(mon);
+    printf("Thread[0x%lx] exiting\n",PR_GetCurrentThread());
+}
+
+static PRStatus PR_CALLBACK print_thread(PRThread *thread, int i, void *arg)
+{
+    PRInt32 words;
+    PRWord *registers;
+
+    printf(
+        "\nprint_thread[0x%lx]: %-20s - i = %ld\n",thread, 
+        (PR_GLOBAL_THREAD == PR_GetThreadScope(thread)) ?
+        "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD", i);
+    registers = PR_GetGCRegisters(thread, 0, (int *)&words);
+    printf("Regsters R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n",
+        registers[0],registers[1],registers[2],registers[3]);
+    printf("Stack Pointer = 0x%lx\n", PR_GetSP(thread));
+    return PR_SUCCESS;
+}
+
+static void Level_0_Thread(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *thr;
+    PRThread *me = PR_GetCurrentThread();
+    int n;
+    PRInt32 words;
+    PRWord *registers;
+
+    alive = 0;
+    mon = PR_NewMonitor();
+
+    alive = count;
+    for (n=0; n<count; n++) {
+        thr = PR_CreateThreadGCAble(PR_USER_THREAD,
+            Level_1_Thread, 
+            (void *)scope2, 
+            PR_PRIORITY_NORMAL,
+            scope1,
+            PR_UNJOINABLE_THREAD,
+            0);
+        if (!thr) {
+            printf("Could not create thread!\n");
+            alive--;
+        }
+        printf("Level_0_Thread[0x%lx] created %15s thread 0x%lx\n",
+            PR_GetCurrentThread(),
+            (scope1 == PR_GLOBAL_THREAD) ?
+            "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD",
+            thr);
+
+        PR_Sleep(0);
+    }
+    PR_SuspendAll();
+    PR_EnumerateThreads(print_thread, NULL);
+    registers = PR_GetGCRegisters(me, 1, (int *)&words);
+    printf("My Registers: R0 = 0x%x R1 = 0x%x R2 = 0x%x R3 = 0x%x\n",
+        registers[0],registers[1],registers[2],registers[3]);
+    printf("My Stack Pointer = 0x%lx\n", PR_GetSP(me));
+    PR_ResumeAll();
+
+    /* Wait for all threads to exit */
+    PR_EnterMonitor(mon);
+    while (alive) {
+        PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+    PR_ExitMonitor(mon);
+    PR_DestroyMonitor(mon);
+}
+
+static void CreateThreadsUU(void)
+{
+    Level_0_Thread(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void CreateThreadsUK(void)
+{
+    Level_0_Thread(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+static void CreateThreadsKU(void)
+{
+    Level_0_Thread(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void CreateThreadsKK(void)
+{
+    Level_0_Thread(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+
+void
+main(int argc, char **argv)
+{
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+    SetupMacPrintfLog("suspend.log");
+#endif
+
+    if (argc > 1) {
+        count = atoi(argv[1]);
+    } else {
+        count = 5;
+    }
+
+    printf("\n\n%20s%30s\n\n"," ","Suspend_Resume Test");
+    CreateThreadsUU();
+    CreateThreadsUK();
+    CreateThreadsKU();
+    CreateThreadsKK();
+    PR_SetConcurrency(2);
+
+    printf("\n%20s%30s\n\n"," ","Added 2nd CPU\n");
+
+    CreateThreadsUK();
+    CreateThreadsKK();
+    CreateThreadsUU();
+    CreateThreadsKU();
+    PR_Cleanup();
+}
+
+#endif /* XP_BEOS */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/switch.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/switch.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+** File:            switch.c
+** Description:     trying to time context switches
+*/
+
+#include "prinit.h"
+#include "prcvar.h"
+#include "prmem.h"
+#include "prinrval.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prthread.h"
+#include "prprf.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#if defined(XP_MAC)
+#include "pprio.h"
+#define printf PR_LogPrint
+#else
+#include "private/pprio.h"
+#endif
+
+#include <stdlib.h>
+
+#define INNER_LOOPS 100
+#define DEFAULT_LOOPS 100
+#define DEFAULT_THREADS 10
+
+static PRFileDesc *debug_out = NULL;
+static PRBool debug_mode = PR_FALSE, verbosity = PR_FALSE, failed = PR_FALSE;
+
+typedef struct Shared
+{
+    PRLock *ml;
+    PRCondVar *cv;
+    PRBool twiddle;
+    PRThread *thread;
+    struct Shared *next;
+} Shared;
+
+static void Help(void)
+{
+    debug_out = PR_STDOUT;
+
+    PR_fprintf(
+		debug_out, "Usage: >./switch [-c n] [-t n] [-d] [-v] [-G] [-C n]\n");
+    PR_fprintf(
+		debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS);
+    PR_fprintf(
+		debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS);
+    PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n");
+    PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n");
+    PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n");
+}  /* Help */
+
+static void PR_CALLBACK Notified(void *arg)
+{
+    Shared *shared = (Shared*)arg;
+    PRStatus status = PR_SUCCESS;
+    while (PR_SUCCESS == status)
+    {
+        PR_Lock(shared->ml);
+        while (shared->twiddle && (PR_SUCCESS == status))
+            status = PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT);
+		if (verbosity) PR_fprintf(debug_out, "+");
+        shared->twiddle = PR_TRUE;
+        shared->next->twiddle = PR_FALSE;
+        PR_NotifyCondVar(shared->next->cv);
+        PR_Unlock(shared->ml);
+    }
+}  /* Notified */
+
+static Shared home;
+PRIntn PR_CALLBACK Switch(PRIntn argc, char **argv)
+{
+	PLOptStatus os;
+    PRStatus status;
+    PRBool help = PR_FALSE;
+    PRUintn concurrency = 1;
+    Shared *shared, *link;
+    PRIntervalTime timein, timeout;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+    PRUintn thread_count, inner_count, loop_count, average;
+    PRUintn thread_limit = DEFAULT_THREADS, loop_limit = DEFAULT_LOOPS;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'v':  /* verbose mode */
+			verbosity = PR_TRUE;
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+        case 'c':  /* loop counter */
+			loop_limit = atoi(opt->value);
+            break;
+        case 't':  /* thread limit */
+			thread_limit = atoi(opt->value);
+            break;
+        case 'C':  /* Concurrency limit */
+			concurrency = atoi(opt->value);
+            break;
+        case 'G':  /* global threads only */
+			thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'h':  /* help message */
+			Help();
+			help = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    if (help) return -1;
+
+	if (PR_TRUE == debug_mode)
+	{
+		debug_out = PR_STDOUT;
+		PR_fprintf(debug_out, "Test parameters\n");
+		PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit);
+		PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit);
+		PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency);
+		PR_fprintf(
+			debug_out, "\tThread type: %s\n",
+			(PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
+	}
+
+    PR_SetConcurrency(concurrency);
+
+    link = &home;
+    home.ml = PR_NewLock();
+    home.cv = PR_NewCondVar(home.ml);
+    home.twiddle = PR_FALSE;
+    home.next = NULL;
+
+    timeout = 0;
+
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        shared = PR_NEWZAP(Shared);
+
+        shared->ml = home.ml;
+        shared->cv = PR_NewCondVar(home.ml);
+        shared->twiddle = PR_TRUE;
+        shared->next = link;
+        link = shared;
+
+        shared->thread = PR_CreateThread(
+            PR_USER_THREAD, Notified, shared,
+            PR_PRIORITY_HIGH, thread_scope,
+            PR_JOINABLE_THREAD, 0);
+        PR_ASSERT(shared->thread != NULL);
+        if (NULL == shared->thread)
+            failed = PR_TRUE;
+	}
+
+    for (loop_count = 1; loop_count <= loop_limit; ++loop_count)
+    {
+		timein = PR_IntervalNow();
+		for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count)
+		{
+			PR_Lock(home.ml);
+			home.twiddle = PR_TRUE;
+			shared->twiddle = PR_FALSE;
+			PR_NotifyCondVar(shared->cv);
+			while (home.twiddle)
+            {
+				status = PR_WaitCondVar(home.cv, PR_INTERVAL_NO_TIMEOUT);
+				if (PR_FAILURE == status)
+				    failed = PR_TRUE;
+            }
+			PR_Unlock(home.ml);
+		}
+		timeout += (PR_IntervalNow() - timein);
+	}
+
+	if (debug_mode)
+	{
+		average = PR_IntervalToMicroseconds(timeout)
+			/ (INNER_LOOPS * loop_limit * thread_count);
+		PR_fprintf(
+			debug_out, "Average switch times %d usecs for %d threads\n",
+            average, thread_limit);
+	}
+
+    link = shared;
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        if (&home == link) break;
+        status = PR_Interrupt(link->thread);
+		if (PR_SUCCESS != status)
+        {
+            failed = PR_TRUE;
+            if (debug_mode)
+			    PL_FPrintError(debug_out, "Failed to interrupt");
+        }
+		link = link->next; 
+    }
+
+    for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
+    {
+        link = shared->next;
+        status = PR_JoinThread(shared->thread);
+		if (PR_SUCCESS != status)
+		{
+            failed = PR_TRUE;
+            if (debug_mode)
+			    PL_FPrintError(debug_out, "Failed to join");
+        }
+        PR_DestroyCondVar(shared->cv);
+        PR_DELETE(shared);
+        if (&home == link) break;
+        shared = link;
+    }
+    PR_DestroyCondVar(home.cv);
+    PR_DestroyLock(home.ml);
+
+    PR_fprintf(PR_STDOUT, ((failed) ? "FAILED\n" : "PASSED\n"));
+    return ((failed) ? 1 : 0);
+}  /* Switch */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRIntn result;
+    PR_STDIO_INIT();
+    result = PR_Initialize(Switch, argc, argv, 0);
+    return result;
+}  /* main */
+
+/* switch.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/system.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/system.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+#include "prio.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prsystem.h"
+
+#include "plerror.h"
+
+static char *tag[] =
+{
+    "PR_SI_HOSTNAME",
+    "PR_SI_SYSNAME",
+    "PR_SI_RELEASE",
+    "PR_SI_ARCHITECTURE"
+};
+
+static PRSysInfo Incr(PRSysInfo *cmd)
+{
+    PRIntn tmp = (PRIntn)*cmd + 1;
+    *cmd = (PRSysInfo)tmp;
+    return (PRSysInfo)tmp;
+}  /* Incr */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    PRSysInfo cmd;
+    PRFileDesc *output = PR_GetSpecialFD(PR_StandardOutput);
+
+    char *info = (char*)PR_Calloc(SYS_INFO_BUFFER_LENGTH, 1);
+    for (cmd = PR_SI_HOSTNAME; cmd <= PR_SI_ARCHITECTURE; Incr(&cmd))
+    {
+        rv = PR_GetSystemInfo(cmd, info, SYS_INFO_BUFFER_LENGTH);
+        if (PR_SUCCESS == rv) PR_fprintf(output, "%s: %s\n", tag[cmd], info);
+        else PL_FPrintError(output, tag[cmd]);
+    }
+    PR_DELETE(info);
+
+    PR_fprintf(output, "Host page size is %d\n", PR_GetPageSize());
+    PR_fprintf(output, "Page shift is %d\n", PR_GetPageShift());
+    PR_fprintf(output, "Number of processors is: %d\n", PR_GetNumberOfProcessors());
+    PR_fprintf(output, "Physical memory size is: %llu\n", PR_GetPhysicalMemorySize());
+
+    return 0;
+}  /* main */
+
+/* system.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/testbit.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/testbit.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+** File:        lazyinit.c
+** Description: Test the functions and macros declared in prbit.h
+**
+*/
+
+#include "nspr.h"
+
+#define ErrorReport(x) { printf((x)); failed = 1; }
+
+prbitmap_t myMap[512/32] = { 0 };
+
+PRInt32 rc;
+PRInt32 i;
+PRIntn  failed = 0;
+
+PRIntn main(PRIntn argc, char **argv )
+{
+    /*
+    ** Test bitmap things.
+    */
+    if ( PR_TEST_BIT( myMap, 0 ))
+        ErrorReport("Test 0.0: Failed\n");
+
+    if ( PR_TEST_BIT( myMap, 31 ))
+        ErrorReport("Test 0.1: Failed\n");
+
+    if ( PR_TEST_BIT( myMap, 128 ))
+        ErrorReport("Test 0.2: Failed\n");
+
+    if ( PR_TEST_BIT( myMap, 129 ))
+        ErrorReport("Test 0.3: Failed\n");
+
+
+    PR_SET_BIT( myMap, 0 );
+    if ( !PR_TEST_BIT( myMap, 0 ))
+        ErrorReport("Test 1.0: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 0 );
+    if ( PR_TEST_BIT( myMap, 0 ))
+        ErrorReport("Test 1.0.1: Failed\n");
+
+    PR_SET_BIT( myMap, 31 );
+    if ( !PR_TEST_BIT( myMap, 31 ))
+        ErrorReport("Test 1.1: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 31 );
+    if ( PR_TEST_BIT( myMap, 31 ))
+        ErrorReport("Test 1.1.1: Failed\n");
+
+    PR_SET_BIT( myMap, 128 );
+    if ( !PR_TEST_BIT( myMap, 128 ))
+        ErrorReport("Test 1.2: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 128 );
+    if ( PR_TEST_BIT( myMap, 128 ))
+        ErrorReport("Test 1.2.1: Failed\n");
+
+    PR_SET_BIT( myMap, 129 );
+    if ( !PR_TEST_BIT( myMap, 129 ))
+        ErrorReport("Test 1.3: Failed\n");
+
+    PR_CLEAR_BIT( myMap, 129 );
+    if ( PR_TEST_BIT( myMap, 129 ))
+        ErrorReport("Test 1.3.1: Failed\n");
+
+
+    /*
+    ** Test Ceiling and Floor functions and macros
+    */
+    if ((rc = PR_CeilingLog2(32)) != 5 )
+        ErrorReport("Test 10.0: Failed\n");
+
+    if ((rc = PR_FloorLog2(32)) != 5 )
+        ErrorReport("Test 10.1: Failed\n");
+
+
+    /*
+    ** Evaluate results and exit
+    */
+    if (failed)
+      {
+        printf("FAILED\n");
+        return(1);
+      }
+    else
+      {
+        printf("PASSED\n");
+        return(0);
+      }
+}  /* end main() */
+/* end testbit.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/testfile.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/testfile.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1008 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 
+ * 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.
+ */
+
+#include "nspr.h"
+#include "prpriv.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef WIN32
+#include <windows.h>
+#include <process.h>
+#endif
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include <pthread.h>
+#endif
+
+#if defined(XP_OS2)
+#define INCL_DOSFILEMGR
+#include <os2.h>
+#ifdef XP_OS2_EMX
+#include <getopt.h>
+#include <errno.h>
+#endif /* XP_OS2_EMX */
+#endif /* XP_OS2 */
+
+static int _debug_on = 0;
+
+#ifdef XP_MAC
+#include "prlog.h"
+#include "primpl.h"
+#define printf PR_LogPrint
+#define setbuf(x,y)
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+#ifdef XP_WIN
+#define mode_t int
+#endif
+
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+PRLock *lock;
+PRMonitor *mon;
+PRInt32 count;
+int thread_count;
+
+#ifdef WIN16
+#define	BUF_DATA_SIZE	256 * 120
+#else
+#define	BUF_DATA_SIZE	256 * 1024
+#endif
+
+#define NUM_RDWR_THREADS	10
+#define NUM_DIRTEST_THREADS	4
+#define CHUNK_SIZE 512
+
+typedef struct buffer {
+	char	data[BUF_DATA_SIZE];
+} buffer;
+
+typedef struct File_Rdwr_Param {
+	char	*pathname;
+	char	*buf;
+	int	offset;
+	int	len;
+} File_Rdwr_Param;
+
+#ifdef XP_PC
+#ifdef XP_OS2
+char *TEST_DIR = "prdir";
+#else
+char *TEST_DIR = "C:\\temp\\prdir";
+#endif
+char *FILE_NAME = "pr_testfile";
+char *HIDDEN_FILE_NAME = "hidden_pr_testfile";
+#else
+char *TEST_DIR = "/tmp/testfile_dir";
+char *FILE_NAME = "pr_testfile";
+char *HIDDEN_FILE_NAME = ".hidden_pr_testfile";
+#endif
+buffer *in_buf, *out_buf;
+char pathname[256], renamename[256];
+#define TMPDIR_LEN	64
+char testdir[TMPDIR_LEN];
+static PRInt32 PR_CALLBACK DirTest(void *argunused);
+PRInt32 dirtest_failed = 0;
+
+PRThread* create_new_thread(PRThreadType type,
+							void (*start)(void *arg),
+							void *arg,
+							PRThreadPriority priority,
+							PRThreadScope scope,
+							PRThreadState state,
+							PRUint32 stackSize, PRInt32 index)
+{
+PRInt32 native_thread = 0;
+
+	PR_ASSERT(state == PR_UNJOINABLE_THREAD);
+
+#if (defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)) || defined(WIN32) || defined(XP_OS2)
+
+	switch(index %  4) {
+		case 0:
+			scope = (PR_LOCAL_THREAD);
+			break;
+		case 1:
+			scope = (PR_GLOBAL_THREAD);
+			break;
+		case 2:
+			scope = (PR_GLOBAL_BOUND_THREAD);
+			break;
+		case 3:
+			native_thread = 1;
+			break;
+		default:
+			PR_ASSERT(!"Invalid scope");
+			break;
+	}
+	if (native_thread) {
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+		pthread_t tid;
+		if (!pthread_create(&tid, NULL, start, arg))
+			return((PRThread *) tid);
+		else
+			return (NULL);
+#elif defined(XP_OS2)
+        TID tid;
+
+        tid = (TID)_beginthread((void(* _Optlink)(void*))start,
+                                NULL, 32768, arg);
+        if (tid == -1) {
+          printf("_beginthread failed. errno %d\n", errno);
+          return (NULL);
+        }
+        else
+          return((PRThread *) tid);
+#else
+		HANDLE thandle;
+		unsigned tid;
+		
+		thandle = (HANDLE) _beginthreadex(
+						NULL,
+						stackSize,
+						(unsigned (__stdcall *)(void *))start,
+						arg,
+						0,
+						&tid);		
+		return((PRThread *) thandle);
+#endif
+	} else {
+		return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
+	}
+#else
+	return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
+#endif
+}
+
+static void PR_CALLBACK File_Write(void *arg)
+{
+PRFileDesc *fd_file;
+File_Rdwr_Param *fp = (File_Rdwr_Param *) arg;
+char *name, *buf;
+int offset, len;
+
+	setbuf(stdout, NULL);
+	name = fp->pathname;
+	buf = fp->buf;
+	offset = fp->offset;
+	len = fp->len;
+	
+	fd_file = PR_Open(name, PR_RDWR | PR_CREATE_FILE, 0777);
+	if (fd_file == NULL) {
+		printf("testfile failed to create/open file %s\n",name);
+		return;
+	}
+	if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) {
+		printf("testfile failed to seek in file %s\n",name);
+		return;
+	}	
+	if ((PR_Write(fd_file, buf, len)) < 0) {
+		printf("testfile failed to write to file %s\n",name);
+		return;
+	}	
+	DPRINTF(("Write out_buf[0] = 0x%x\n",(*((int *) buf))));
+	PR_Close(fd_file);
+	PR_DELETE(fp);
+
+	PR_EnterMonitor(mon);
+	--thread_count;
+	PR_Notify(mon);
+	PR_ExitMonitor(mon);
+}
+
+static void PR_CALLBACK File_Read(void *arg)
+{
+PRFileDesc *fd_file;
+File_Rdwr_Param *fp = (File_Rdwr_Param *) arg;
+char *name, *buf;
+int offset, len;
+
+	setbuf(stdout, NULL);
+	name = fp->pathname;
+	buf = fp->buf;
+	offset = fp->offset;
+	len = fp->len;
+	
+	fd_file = PR_Open(name, PR_RDONLY, 0);
+	if (fd_file == NULL) {
+		printf("testfile failed to open file %s\n",name);
+		return;
+	}
+	if (PR_Seek(fd_file, offset, PR_SEEK_SET) < 0) {
+		printf("testfile failed to seek in file %s\n",name);
+		return;
+	}	
+	if ((PR_Read(fd_file, buf, len)) < 0) {
+		printf("testfile failed to read to file %s\n",name);
+		return;
+	}	
+	DPRINTF(("Read in_buf[0] = 0x%x\n",(*((int *) buf))));
+	PR_Close(fd_file);
+	PR_DELETE(fp);
+
+	PR_EnterMonitor(mon);
+	--thread_count;
+	PR_Notify(mon);
+	PR_ExitMonitor(mon);
+}
+
+
+static PRInt32 Misc_File_Tests(char *pathname)
+{
+PRFileDesc *fd_file;
+int len, rv = 0;
+PRFileInfo file_info, file_info1;
+char tmpname[1024];
+
+	setbuf(stdout, NULL);
+	/*
+	 * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access
+	 */
+
+	fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
+
+	if (fd_file == NULL) {
+		printf("testfile failed to create/open file %s\n",pathname);
+		return -1;
+	}
+	if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) {
+		printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (PR_Access(pathname, PR_ACCESS_EXISTS) != 0) {
+		printf("testfile PR_Access failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (PR_Access(pathname, PR_ACCESS_WRITE_OK) != 0) {
+		printf("testfile PR_Access failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (PR_Access(pathname, PR_ACCESS_READ_OK) != 0) {
+		printf("testfile PR_Access failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+
+
+	if (PR_GetFileInfo(pathname, &file_info) < 0) {
+		printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (file_info.type != PR_FILE_FILE) {
+	printf(
+	"testfile: Error - PR_GetFileInfo returned incorrect type for file %s\n",
+		pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (file_info.size != 0) {
+		printf(
+		"testfile PR_GetFileInfo returned incorrect size (%d should be 0) for file %s\n",
+		file_info.size, pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	file_info1 = file_info;
+
+	len = PR_Available(fd_file);
+	if (len < 0) {
+		printf("testfile PR_Available failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	} else if (len != 0) {
+		printf(
+		"testfile PR_Available failed: expected/returned = %d/%d bytes\n",
+			0, len);
+		rv = -1;
+		goto cleanup;
+	}
+	if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) {
+		printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
+		goto cleanup;
+	}
+	if (LL_NE(file_info.creationTime , file_info1.creationTime)) {
+		printf(
+		"testfile PR_GetFileInfo returned incorrect status-change time: %s\n",
+		pathname);
+		printf("ft = %lld, ft1 = %lld\n",file_info.creationTime,
+									file_info1.creationTime);
+		rv = -1;
+		goto cleanup;
+	}
+	len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE);
+	if (len < 0) {
+		printf("testfile failed to write to file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (PR_GetOpenFileInfo(fd_file, &file_info) < 0) {
+		printf("testfile PR_GetFileInfo failed on file %s\n",pathname);
+		goto cleanup;
+	}
+	if (file_info.size != CHUNK_SIZE) {
+		printf(
+		"testfile PR_GetFileInfo returned incorrect size (%d should be %d) for file %s\n",
+		file_info.size, CHUNK_SIZE, pathname);
+		rv = -1;
+		goto cleanup;
+	}
+	if (LL_CMP(file_info.modifyTime, < , file_info1.modifyTime)) {
+		printf(
+		"testfile PR_GetFileInfo returned incorrect modify time: %s\n",
+		pathname);
+		printf("ft = %lld, ft1 = %lld\n",file_info.modifyTime,
+									file_info1.modifyTime);
+		rv = -1;
+		goto cleanup;
+	}
+
+	len = PR_Available(fd_file);
+	if (len < 0) {
+		printf("testfile PR_Available failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	} else if (len != 0) {
+		printf(
+		"testfile PR_Available failed: expected/returned = %d/%d bytes\n",
+			0, len);
+		rv = -1;
+		goto cleanup;
+	}
+	
+	PR_Seek(fd_file, 0, PR_SEEK_SET);
+	len = PR_Available(fd_file);
+	if (len < 0) {
+		printf("testfile PR_Available failed on file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	} else if (len != CHUNK_SIZE) {
+		printf(
+		"testfile PR_Available failed: expected/returned = %d/%d bytes\n",
+			CHUNK_SIZE, len);
+		rv = -1;
+		goto cleanup;
+	}
+    PR_Close(fd_file);
+
+	strcpy(tmpname,pathname);
+	strcat(tmpname,".RENAMED");
+	if (PR_FAILURE == PR_Rename(pathname, tmpname)) {
+		printf("testfile failed to rename file %s\n",pathname);
+		rv = -1;
+		goto cleanup;
+	}
+
+	fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
+	len = PR_Write(fd_file, out_buf->data, CHUNK_SIZE);
+    PR_Close(fd_file);
+	if (PR_SUCCESS == PR_Rename(pathname, tmpname)) {
+		printf("testfile renamed to existing file %s\n",pathname);
+	}
+
+	if ((PR_Delete(tmpname)) < 0) {
+		printf("testfile failed to unlink file %s\n",tmpname);
+		rv = -1;
+	}
+
+cleanup:
+	if ((PR_Delete(pathname)) < 0) {
+		printf("testfile failed to unlink file %s\n",pathname);
+		rv = -1;
+	}
+	return rv;
+}
+
+
+static PRInt32 PR_CALLBACK FileTest(void)
+{
+PRDir *fd_dir;
+int i, offset, len, rv = 0;
+PRThread *t;
+PRThreadScope scope = PR_GLOBAL_THREAD;
+File_Rdwr_Param *fparamp;
+
+	/*
+	 * Create Test dir
+	 */
+	if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
+		printf("testfile failed to create dir %s\n",TEST_DIR);
+		return -1;
+	}
+	fd_dir = PR_OpenDir(TEST_DIR);
+	if (fd_dir == NULL) {
+		printf("testfile failed to open dir %s\n",TEST_DIR);
+		rv =  -1;
+		goto cleanup;	
+	}
+
+    PR_CloseDir(fd_dir);
+
+	strcat(pathname, TEST_DIR);
+	strcat(pathname, "/");
+	strcat(pathname, FILE_NAME);
+
+	in_buf = PR_NEW(buffer);
+	if (in_buf == NULL) {
+		printf(
+		"testfile failed to alloc buffer struct\n");
+		rv =  -1;
+		goto cleanup;	
+	}
+	out_buf = PR_NEW(buffer);
+	if (out_buf == NULL) {
+		printf(
+		"testfile failed to alloc buffer struct\n");
+		rv =  -1;
+		goto cleanup;	
+	}
+
+	/*
+	 * Start a bunch of writer threads
+	 */
+	offset = 0;
+	len = CHUNK_SIZE;
+	PR_EnterMonitor(mon);
+	for (i = 0; i < NUM_RDWR_THREADS; i++) {
+		fparamp = PR_NEW(File_Rdwr_Param);
+		if (fparamp == NULL) {
+			printf(
+			"testfile failed to alloc File_Rdwr_Param struct\n");
+			rv =  -1;
+			goto cleanup;	
+		}
+		fparamp->pathname = pathname;
+		fparamp->buf = out_buf->data + offset;
+		fparamp->offset = offset;
+		fparamp->len = len;
+		memset(fparamp->buf, i, len);
+
+		t = create_new_thread(PR_USER_THREAD,
+			      File_Write, (void *)fparamp, 
+			      PR_PRIORITY_NORMAL,
+			      scope,
+			      PR_UNJOINABLE_THREAD,
+			      0, i);
+		offset += len;
+	}
+	thread_count = i;
+	/* Wait for writer threads to exit */
+	while (thread_count) {
+		PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+	}
+	PR_ExitMonitor(mon);
+
+
+	/*
+	 * Start a bunch of reader threads
+	 */
+	offset = 0;
+	len = CHUNK_SIZE;
+	PR_EnterMonitor(mon);
+	for (i = 0; i < NUM_RDWR_THREADS; i++) {
+		fparamp = PR_NEW(File_Rdwr_Param);
+		if (fparamp == NULL) {
+			printf(
+			"testfile failed to alloc File_Rdwr_Param struct\n");
+			rv =  -1;
+			goto cleanup;	
+		}
+		fparamp->pathname = pathname;
+		fparamp->buf = in_buf->data + offset;
+		fparamp->offset = offset;
+		fparamp->len = len;
+
+		t = create_new_thread(PR_USER_THREAD,
+			      File_Read, (void *)fparamp, 
+			      PR_PRIORITY_NORMAL,
+			      scope,
+			      PR_UNJOINABLE_THREAD,
+			      0, i);
+		offset += len;
+		if ((offset + len) > BUF_DATA_SIZE)
+			break;
+	}
+	thread_count = i;
+
+	/* Wait for reader threads to exit */
+	while (thread_count) {
+		PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+	}
+	PR_ExitMonitor(mon);
+
+	if (memcmp(in_buf->data, out_buf->data, offset) != 0) {
+		printf("File Test failed: file data corrupted\n");
+		rv =  -1;
+		goto cleanup;	
+	}
+
+	if ((PR_Delete(pathname)) < 0) {
+		printf("testfile failed to unlink file %s\n",pathname);
+		rv =  -1;
+		goto cleanup;	
+	}
+
+	/*
+	 * Test PR_Available, PR_Seek, PR_GetFileInfo, PR_Rename, PR_Access
+	 */
+	if (Misc_File_Tests(pathname) < 0) {
+		rv = -1;
+	}
+
+cleanup:
+	if ((PR_RmDir(TEST_DIR)) < 0) {
+		printf("testfile failed to rmdir %s\n", TEST_DIR);
+		rv = -1;
+	}
+	return rv;
+}
+
+struct dirtest_arg {
+	PRMonitor	*mon;
+	PRInt32		done;
+};
+
+static PRInt32 RunDirTest(void)
+{
+int i;
+PRThread *t;
+PRMonitor *mon;
+struct dirtest_arg thrarg;
+
+	mon = PR_NewMonitor();
+	if (!mon) {
+		printf("RunDirTest: Error - failed to create monitor\n");
+		dirtest_failed = 1;
+		return -1;
+	}
+	thrarg.mon = mon;
+
+	for (i = 0; i < NUM_DIRTEST_THREADS; i++) {
+
+		thrarg.done= 0;
+		t = create_new_thread(PR_USER_THREAD,
+			      DirTest, &thrarg, 
+			      PR_PRIORITY_NORMAL,
+			      PR_LOCAL_THREAD,
+			      PR_UNJOINABLE_THREAD,
+			      0, i);
+		if (!t) {
+			printf("RunDirTest: Error - failed to create thread\n");
+			dirtest_failed = 1;
+			return -1;
+		}
+		PR_EnterMonitor(mon);
+		while (!thrarg.done)
+			PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+		PR_ExitMonitor(mon);
+
+	}
+	PR_DestroyMonitor(mon);
+	return 0;
+}
+
+static PRInt32 PR_CALLBACK DirTest(void *arg)
+{
+struct dirtest_arg *tinfo = (struct dirtest_arg *) arg;
+PRFileDesc *fd_file;
+PRDir *fd_dir;
+int i;
+int path_len;
+PRDirEntry *dirEntry;
+PRFileInfo info;
+PRInt32 num_files = 0;
+#if defined(XP_PC) && defined(WIN32)
+HANDLE hfile;
+#endif
+
+#define  FILES_IN_DIR 20
+
+	/*
+	 * Create Test dir
+	 */
+	DPRINTF(("Creating test dir %s\n",TEST_DIR));
+	if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
+		printf(
+			"testfile failed to create dir %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	fd_dir = PR_OpenDir(TEST_DIR);
+	if (fd_dir == NULL) {
+		printf(
+			"testfile failed to open dirctory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+	strcpy(pathname, TEST_DIR);
+	strcat(pathname, "/");
+	strcat(pathname, FILE_NAME);
+	path_len = strlen(pathname);
+	
+	for (i = 0; i < FILES_IN_DIR; i++) {
+
+		sprintf(pathname + path_len,"%d%s",i,"");
+
+		DPRINTF(("Creating test file %s\n",pathname));
+
+		fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
+
+		if (fd_file == NULL) {
+			printf(
+					"testfile failed to create/open file %s [%d, %d]\n",
+					pathname, PR_GetError(), PR_GetOSError());
+			return -1;
+		}
+        PR_Close(fd_file);
+	}
+#if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS)
+	/*
+	 * Create a hidden file - a platform-dependent operation
+	 */
+	strcpy(pathname, TEST_DIR);
+	strcat(pathname, "/");
+	strcat(pathname, HIDDEN_FILE_NAME);
+#if defined(XP_UNIX) || defined(XP_MAC) || defined(XP_BEOS)
+	DPRINTF(("Creating hidden test file %s\n",pathname));
+	fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, 0777);
+
+	if (fd_file == NULL) {
+		printf(
+				"testfile failed to create/open hidden file %s [%d, %d]\n",
+				pathname, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+#if defined(XP_MAC)
+	{
+#include <files.h>
+
+	OSErr			err;
+	FCBPBRec		fcbpb;
+	CInfoPBRec		pb;
+	Str255			pascalMacPath;
+
+	fcbpb.ioNamePtr = pascalMacPath;
+	fcbpb.ioVRefNum = 0;
+	fcbpb.ioRefNum = fd_file->secret->md.osfd;
+	fcbpb.ioFCBIndx = 0;
+	
+	err = PBGetFCBInfoSync(&fcbpb);
+	if (err != noErr) {
+    	PR_Close(fd_file);
+    	return -1;
+	}
+	
+	pb.hFileInfo.ioNamePtr = pascalMacPath;
+	pb.hFileInfo.ioVRefNum = fcbpb.ioFCBVRefNum;
+	pb.hFileInfo.ioDirID = fcbpb.ioFCBParID;
+	pb.hFileInfo.ioFDirIndex = 0;
+	
+	err = PBGetCatInfoSync(&pb);
+	if (err != noErr) {
+    	PR_Close(fd_file);
+    	return -1;
+	}
+
+	pb.hFileInfo.ioNamePtr = pascalMacPath;
+	pb.hFileInfo.ioVRefNum = fcbpb.ioFCBVRefNum;
+	pb.hFileInfo.ioDirID = fcbpb.ioFCBParID;
+	pb.hFileInfo.ioFDirIndex = 0;
+	
+	pb.hFileInfo.ioFlFndrInfo.fdFlags |= fInvisible;
+
+	err = PBSetCatInfoSync(&pb);
+	if (err != noErr) {
+    	PR_Close(fd_file);
+    	return -1;
+	}
+
+	}
+#endif
+
+    PR_Close(fd_file);
+
+	
+#elif defined(XP_PC) && defined(WIN32)
+	DPRINTF(("Creating hidden test file %s\n",pathname));
+	hfile = CreateFile(pathname, GENERIC_READ,
+						FILE_SHARE_READ|FILE_SHARE_WRITE,
+						NULL,
+						CREATE_NEW,
+						FILE_ATTRIBUTE_HIDDEN,
+						NULL);
+	if (hfile == INVALID_HANDLE_VALUE) {
+		printf("testfile failed to create/open hidden file %s [0, %d]\n",
+				pathname, GetLastError());
+		return -1;
+	}
+	CloseHandle(hfile);
+						
+#elif defined(OS2)
+	DPRINTF(("Creating hidden test file %s\n",pathname));
+	fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, (int)FILE_HIDDEN);
+
+	if (fd_file == NULL) {
+		printf("testfile failed to create/open hidden file %s [%d, %d]\n",
+				pathname, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	PR_Close(fd_file);
+#endif	/* XP _UNIX || XP_MAC*/
+
+#endif	/* XP_UNIX || XP_MAC ||(XP_PC && WIN32) */
+
+
+	if (PR_FAILURE == PR_CloseDir(fd_dir))
+	{
+		printf(
+			"testfile failed to close dirctory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	fd_dir = PR_OpenDir(TEST_DIR);
+	if (fd_dir == NULL) {
+		printf(
+			"testfile failed to reopen dirctory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+  
+	/*
+	 * List all files, including hidden files
+	 */
+	DPRINTF(("Listing all files in directory %s\n",TEST_DIR));
+#if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS)
+	num_files = FILES_IN_DIR + 1;
+#else
+	num_files = FILES_IN_DIR;
+#endif
+	while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_BOTH)) != NULL) {
+		num_files--;
+		strcpy(pathname, TEST_DIR);
+		strcat(pathname, "/");
+		strcat(pathname, dirEntry->name);
+		DPRINTF(("\t%s\n",dirEntry->name));
+
+		if ((PR_GetFileInfo(pathname, &info)) < 0) {
+			printf(
+				"testfile failed to GetFileInfo file %s [%d, %d]\n",
+				pathname, PR_GetError(), PR_GetOSError());
+			return -1;
+		}
+		
+		if (info.type != PR_FILE_FILE) {
+			printf(
+				"testfile incorrect fileinfo for file %s [%d, %d]\n",
+				pathname, PR_GetError(), PR_GetOSError());
+			return -1;
+		}
+	}
+	if (num_files != 0)
+	{
+		printf(
+			"testfile failed to find all files in directory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+    PR_CloseDir(fd_dir);
+
+#if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2) || defined(XP_BEOS)
+
+	/*
+	 * List all files, except hidden files
+	 */
+
+	fd_dir = PR_OpenDir(TEST_DIR);
+	if (fd_dir == NULL) {
+		printf(
+			"testfile failed to reopen dirctory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+  
+	DPRINTF(("Listing non-hidden files in directory %s\n",TEST_DIR));
+	while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_HIDDEN)) != NULL) {
+		DPRINTF(("\t%s\n",dirEntry->name));
+		if (!strcmp(HIDDEN_FILE_NAME, dirEntry->name)) {
+			printf("testfile found hidden file %s\n", pathname);
+			return -1;
+		}
+
+	}
+	/*
+	 * Delete hidden file
+	 */
+	strcpy(pathname, TEST_DIR);
+	strcat(pathname, "/");
+	strcat(pathname, HIDDEN_FILE_NAME);
+	if (PR_FAILURE == PR_Delete(pathname)) {
+		printf(
+			"testfile failed to delete hidden file %s [%d, %d]\n",
+			pathname, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+    PR_CloseDir(fd_dir);
+#endif	/* XP_UNIX || XP_MAC || (XP_PC && WIN32) */
+
+	strcpy(renamename, TEST_DIR);
+	strcat(renamename, ".RENAMED");
+	if (PR_FAILURE == PR_Rename(TEST_DIR, renamename)) {
+		printf(
+			"testfile failed to rename directory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+    
+	if (PR_FAILURE == PR_MkDir(TEST_DIR, 0777)) {
+		printf(
+			"testfile failed to recreate dir %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	if (PR_SUCCESS == PR_Rename(renamename, TEST_DIR)) {
+		printf(
+			"testfile renamed directory to existing name %s\n",
+			renamename);
+		return -1;
+	}
+
+	if (PR_FAILURE == PR_RmDir(TEST_DIR)) {
+		printf(
+			"testfile failed to rmdir %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+	if (PR_FAILURE == PR_Rename(renamename, TEST_DIR)) {
+		printf(
+			"testfile failed to rename directory %s [%d, %d]\n",
+			renamename, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	fd_dir = PR_OpenDir(TEST_DIR);
+	if (fd_dir == NULL) {
+		printf(
+			"testfile failed to reopen directory %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+
+	strcpy(pathname, TEST_DIR);
+	strcat(pathname, "/");
+	strcat(pathname, FILE_NAME);
+	path_len = strlen(pathname);
+	
+	for (i = 0; i < FILES_IN_DIR; i++) {
+
+		sprintf(pathname + path_len,"%d%s",i,"");
+
+		if (PR_FAILURE == PR_Delete(pathname)) {
+			printf(
+				"testfile failed to delete file %s [%d, %d]\n",
+				pathname, PR_GetError(), PR_GetOSError());
+			return -1;
+		}
+	}
+
+    PR_CloseDir(fd_dir);
+
+	if (PR_FAILURE == PR_RmDir(TEST_DIR)) {
+		printf(
+			"testfile failed to rmdir %s [%d, %d]\n",
+			TEST_DIR, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	PR_EnterMonitor(tinfo->mon);
+	tinfo->done = 1;
+	PR_Notify(tinfo->mon);
+	PR_ExitMonitor(tinfo->mon);
+
+	return 0;
+}
+/************************************************************************/
+
+/*
+ * Test file and directory NSPR APIs
+ */
+
+int main(int argc, char **argv)
+{
+#ifdef WIN32
+	PRUint32 len;
+#endif
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+        int opt;
+        extern char *optarg;
+	extern int optind;
+#endif
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+        while ((opt = getopt(argc, argv, "d")) != EOF) {
+                switch(opt) {
+                        case 'd':
+                                _debug_on = 1;
+                                break;
+                        default:
+                                break;
+                }
+        }
+#endif
+	PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("testfile.log");
+#endif
+
+	mon = PR_NewMonitor();
+	if (mon == NULL) {
+		printf("testfile: PR_NewMonitor failed\n");
+		exit(2);
+	}
+#ifdef WIN32
+	len = GetTempPath(TMPDIR_LEN, testdir);
+	if ((len > 0) && (len < (TMPDIR_LEN - 6))) {
+		/*
+		 * enough space for prdir
+		 */
+		strcpy((testdir + len),"prdir");
+		TEST_DIR = testdir;
+		printf("TEST_DIR = %s\n",TEST_DIR);
+	}
+	
+#endif
+
+	if (FileTest() < 0) {
+		printf("File Test failed\n");
+		exit(2);
+	}
+	printf("File Test passed\n");
+	if ((RunDirTest() < 0) || dirtest_failed) {
+		printf("Dir Test failed\n");
+		exit(2);
+	}
+	printf("Dir Test passed\n");
+
+	PR_DestroyMonitor(mon);
+	PR_Cleanup();
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/threads.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/threads.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,249 @@
+/* -*- 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 "nspr.h"
+#include "prinrval.h"
+#include "plgetopt.h"
+#include "pprthred.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+PRMonitor *mon;
+PRInt32 count, iterations, alive;
+
+PRBool debug_mode = PR_FALSE, passed = PR_TRUE;
+
+void 
+PR_CALLBACK
+ReallyDumbThread(void *arg)
+{
+    return;
+}
+
+void
+PR_CALLBACK
+DumbThread(void *arg)
+{
+    PRInt32 tmp = (PRInt32)arg;
+    PRThreadScope scope = (PRThreadScope)tmp;
+    PRThread *thr;
+
+    thr = PR_CreateThread(PR_USER_THREAD,
+                          ReallyDumbThread,
+                          NULL,
+                          PR_PRIORITY_NORMAL,
+                          scope,
+                          PR_JOINABLE_THREAD,
+                          0);
+
+    if (!thr) {
+        if (debug_mode) {
+            printf("Could not create really dumb thread (%d, %d)!\n",
+                    PR_GetError(), PR_GetOSError());
+        }
+        passed = PR_FALSE;
+    } else {
+        PR_JoinThread(thr);
+    }
+    PR_EnterMonitor(mon);
+    alive--;
+    PR_Notify(mon);
+    PR_ExitMonitor(mon);
+}
+
+static void CreateThreads(PRThreadScope scope1, PRThreadScope scope2)
+{
+    PRThread *thr;
+    int n;
+
+    alive = 0;
+    mon = PR_NewMonitor();
+
+    alive = count;
+    for (n=0; n<count; n++) {
+        thr = PR_CreateThread(PR_USER_THREAD,
+                              DumbThread, 
+                              (void *)scope2, 
+                              PR_PRIORITY_NORMAL,
+                              scope1,
+                              PR_UNJOINABLE_THREAD,
+                              0);
+        if (!thr) {
+            if (debug_mode) {
+                printf("Could not create dumb thread (%d, %d)!\n",
+                        PR_GetError(), PR_GetOSError());
+            }
+            passed = PR_FALSE;
+            alive--;
+        }
+         
+        PR_Sleep(0);
+    }
+
+    /* Wait for all threads to exit */
+    PR_EnterMonitor(mon);
+    while (alive) {
+        PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+    }
+
+    PR_ExitMonitor(mon);
+	PR_DestroyMonitor(mon);
+}
+
+static void CreateThreadsUU(void)
+{
+    CreateThreads(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void CreateThreadsUK(void)
+{
+    CreateThreads(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+static void CreateThreadsKU(void)
+{
+    CreateThreads(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
+}
+
+static void CreateThreadsKK(void)
+{
+    CreateThreads(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    if (debug_mode)
+    {
+        d = (double)PR_IntervalToMicroseconds(stop - start);
+        printf("%40s: %6.2f usec\n", msg, d / count);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    int index;
+
+    PR_STDIO_INIT();
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_HIGH, 0);
+    
+    {
+    	PLOptStatus os;
+    	PLOptState *opt = PL_CreateOptState(argc, argv, "dc:i:");
+    	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+        {
+    		if (PL_OPT_BAD == os) continue;
+            switch (opt->option)
+            {
+            case 'd':  /* debug mode */
+    			debug_mode = PR_TRUE;
+                break;
+            case 'c':  /* loop counter */
+    			count = atoi(opt->value);
+                break;
+            case 'i':  /* loop counter */
+    			iterations = atoi(opt->value);
+                break;
+             default:
+                break;
+            }
+        }
+    	PL_DestroyOptState(opt);
+    }
+
+#ifdef XP_MAC
+	SetupMacPrintfLog("threads.log");
+	count = 10;
+	iterations = 10;
+	debug_mode = PR_TRUE;
+#else
+    if (0 == count) count = 50;
+    if (0 == iterations) iterations = 10;
+
+#endif
+
+    if (debug_mode)
+    {
+    printf("\
+** Tests lots of thread creations.  \n\
+** Create %ld native threads %ld times. \n\
+** Create %ld user threads %ld times \n", iterations,count,iterations,count);
+    }
+
+    for (index=0; index<iterations; index++) {
+        Measure(CreateThreadsUU, "Create user/user threads");
+        Measure(CreateThreadsUK, "Create user/native threads");
+        Measure(CreateThreadsKU, "Create native/user threads");
+        Measure(CreateThreadsKK, "Create native/native threads");
+    }
+
+    if (debug_mode) printf("\nNow switch to recycling threads \n\n");
+    PR_SetThreadRecycleMode(1);
+
+    for (index=0; index<iterations; index++) {
+        Measure(CreateThreadsUU, "Create user/user threads");
+        Measure(CreateThreadsUK, "Create user/native threads");
+        Measure(CreateThreadsKU, "Create native/user threads");
+        Measure(CreateThreadsKK, "Create native/native threads");
+    }
+
+
+    printf("%s\n", ((passed) ? "PASS" : "FAIL"));
+
+    PR_Cleanup();
+
+    if (passed) {
+        return 0;
+    } else {
+        return 1;
+    }
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/thrpool_client.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/thrpool_client.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,392 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**
+** Name: thrpool_client.c
+**
+** Description: Test threadpool functionality.
+**
+** Modification History:
+*/
+#include "primpl.h"
+
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#ifdef XP_UNIX
+#include <sys/mman.h>
+#endif
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include <pthread.h>
+#endif
+
+#ifdef WIN32
+#include <process.h>
+#endif
+
+static int _debug_on = 0;
+static int server_port = -1;
+static char *program_name = NULL;
+
+#ifdef XP_MAC
+#include "prlog.h"
+#include "prsem.h"
+int fprintf(FILE *stream, const char *fmt, ...)
+{
+    PR_LogPrint(fmt);
+    return 0;
+}
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#else
+#include "obsolete/prsem.h"
+#endif
+
+#ifdef XP_PC
+#define mode_t int
+#endif
+
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+#define    BUF_DATA_SIZE    (2 * 1024)
+#define TCP_MESG_SIZE    1024
+#define NUM_TCP_CLIENTS            10	/* for a listen queue depth of 5 */
+
+#define NUM_TCP_CONNECTIONS_PER_CLIENT    10
+#define NUM_TCP_MESGS_PER_CONNECTION    10
+#define TCP_SERVER_PORT            10000
+
+static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS;
+static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT;
+static PRInt32 tcp_mesg_size = TCP_MESG_SIZE;
+static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION;
+
+int failed_already=0;
+
+typedef struct buffer {
+    char    data[BUF_DATA_SIZE];
+} buffer;
+
+PRNetAddr tcp_server_addr, udp_server_addr;
+
+typedef struct Client_Param {
+    PRNetAddr server_addr;
+    PRMonitor *exit_mon;    /* monitor to signal on exit */
+    PRInt32 *exit_counter;    /* counter to decrement, before exit */
+    PRInt32    datalen;
+} Client_Param;
+
+/*
+ * readn
+ *    read data from sockfd into buf
+ */
+static PRInt32
+readn(PRFileDesc *sockfd, char *buf, int len)
+{
+    int rem;
+    int bytes;
+    int offset = 0;
+	PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
+
+    for (rem=len; rem; offset += bytes, rem -= bytes) {
+        DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n",
+            PR_GetCurrentThread(), rem));
+        bytes = PR_Recv(sockfd, buf + offset, rem, 0,
+            	timeout);
+        DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n",
+            PR_GetCurrentThread(), bytes));
+        if (bytes < 0) {
+			return -1;
+		}	
+    }
+    return len;
+}
+
+/*
+ * writen
+ *    write data from buf to sockfd
+ */
+static PRInt32
+writen(PRFileDesc *sockfd, char *buf, int len)
+{
+    int rem;
+    int bytes;
+    int offset = 0;
+
+    for (rem=len; rem; offset += bytes, rem -= bytes) {
+        DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n",
+            PR_GetCurrentThread(), rem));
+        bytes = PR_Send(sockfd, buf + offset, rem, 0,
+            PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n",
+            PR_GetCurrentThread(), bytes));
+        if (bytes <= 0)
+            return -1;
+    }
+    return len;
+}
+
+/*
+ * TCP_Client
+ *    Client job
+ *    Connect to the server at the address specified in the argument.
+ *    Fill in a buffer, write data to server, read it back and check
+ *    for data corruption.
+ *    Close the socket for server connection
+ */
+static void PR_CALLBACK
+TCP_Client(void *arg)
+{
+    Client_Param *cp = (Client_Param *) arg;
+    PRFileDesc *sockfd;
+    buffer *in_buf, *out_buf;
+    union PRNetAddr netaddr;
+    PRInt32 bytes, i, j;
+
+
+    DPRINTF(("TCP client started\n"));
+    bytes = cp->datalen;
+    out_buf = PR_NEW(buffer);
+    if (out_buf == NULL) {
+        fprintf(stderr,"%s: failed to alloc buffer struct\n", program_name);
+        failed_already=1;
+        return;
+    }
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"%s: failed to alloc buffer struct\n", program_name);
+        failed_already=1;
+        return;
+    }
+    netaddr.inet.family = cp->server_addr.inet.family;
+    netaddr.inet.port = cp->server_addr.inet.port;
+    netaddr.inet.ip = cp->server_addr.inet.ip;
+
+    for (i = 0; i < num_tcp_connections_per_client; i++) {
+        if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) {
+            fprintf(stderr,"%s: PR_OpenTCPSocket failed\n", program_name);
+            failed_already=1;
+            return;
+        }
+
+        DPRINTF(("TCP client connecting to server:%d\n", server_port));
+        if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0){
+        	fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n",
+            		PR_GetError(), PR_GetOSError());
+            failed_already=1;
+            return;
+        }
+        for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
+            /*
+             * fill in random data
+             */
+            memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes);
+            /*
+             * write to server
+             */
+            if (writen(sockfd, out_buf->data, bytes) < bytes) {
+                fprintf(stderr,"%s: ERROR - TCP_Client:writen\n", program_name);
+                failed_already=1;
+                return;
+            }
+			/*
+            DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",
+                PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))));
+			*/
+            if (readn(sockfd, in_buf->data, bytes) < bytes) {
+                fprintf(stderr,"%s: ERROR - TCP_Client:readn\n", program_name);
+                failed_already=1;
+                return;
+            }
+            /*
+             * verify the data read
+             */
+            if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
+                fprintf(stderr,"%s: ERROR - data corruption\n", program_name);
+                failed_already=1;
+                return;
+            }
+        }
+        /*
+         * shutdown reads and writes
+         */
+        if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
+            fprintf(stderr,"%s: ERROR - PR_Shutdown\n", program_name);
+            failed_already=1;
+        }
+        PR_Close(sockfd);
+    }
+
+    PR_DELETE(out_buf);
+    PR_DELETE(in_buf);
+
+    /*
+     * Decrement exit_counter and notify parent thread
+     */
+
+    PR_EnterMonitor(cp->exit_mon);
+    --(*cp->exit_counter);
+    PR_Notify(cp->exit_mon);
+    PR_ExitMonitor(cp->exit_mon);
+    DPRINTF(("TCP_Client exiting\n"));
+}
+
+/*
+ * TCP_Socket_Client_Server_Test    - concurrent server test
+ *    
+ *    Each client connects to the server and sends a chunk of data
+ *    For each connection, server reads the data
+ *    from the client and sends it back to the client, unmodified.
+ *    Each client checks that data received from server is same as the
+ *    data it sent to the server.
+ *
+ */
+
+static PRInt32
+TCP_Socket_Client_Server_Test(void)
+{
+    int i;
+    Client_Param *cparamp;
+    PRMonitor *mon2;
+    PRInt32    datalen;
+    PRInt32    connections = 0;
+	PRThread *thr;
+
+    datalen = tcp_mesg_size;
+    connections = 0;
+
+    mon2 = PR_NewMonitor();
+    if (mon2 == NULL) {
+        fprintf(stderr,"%s: PR_NewMonitor failed\n", program_name);
+        failed_already=1;
+        return -1;
+    }
+
+    /*
+     * Start client jobs
+     */
+    cparamp = PR_NEW(Client_Param);
+    if (cparamp == NULL) {
+        fprintf(stderr,"%s: PR_NEW failed\n", program_name);
+        failed_already=1;
+        return -1;
+    }
+    cparamp->server_addr.inet.family = PR_AF_INET;
+    cparamp->server_addr.inet.port = PR_htons(server_port);
+    cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
+    cparamp->exit_mon = mon2;
+    cparamp->exit_counter = &connections;
+    cparamp->datalen = datalen;
+    for (i = 0; i < num_tcp_clients; i++) {
+		thr = PR_CreateThread(PR_USER_THREAD, TCP_Client, (void *)cparamp,
+        		PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
+        if (NULL == thr) {
+            fprintf(stderr,"%s: PR_CreateThread failed\n", program_name);
+            failed_already=1;
+            return -1;
+        }
+    	PR_EnterMonitor(mon2);
+        connections++;
+    	PR_ExitMonitor(mon2);
+        DPRINTF(("Created TCP client = 0x%lx\n", thr));
+    }
+    /* Wait for client jobs to exit */
+    PR_EnterMonitor(mon2);
+    while (0 != connections) {
+        PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("Client job count = %d\n", connections));
+    }
+    PR_ExitMonitor(mon2);
+    printf("%30s","TCP_Socket_Client_Server_Test:");
+    printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l,
+        num_tcp_clients, num_tcp_connections_per_client);
+    printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":",
+        num_tcp_mesgs_per_connection, tcp_mesg_size);
+
+    PR_DELETE(cparamp);
+    return 0;
+}
+
+/************************************************************************/
+
+int
+main(int argc, char **argv)
+{
+    /*
+     * -d           debug mode
+     */
+    PLOptStatus os;
+    PLOptState *opt;
+	program_name = argv[0];
+
+    opt = PL_CreateOptState(argc, argv, "dp:");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        case 'p':
+            server_port = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+    SetupMacPrintfLog("socket.log");
+#endif
+    PR_SetConcurrency(4);
+
+	TCP_Socket_Client_Server_Test();
+
+    PR_Cleanup();
+    if (failed_already)
+		return 1;
+    else
+		return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/thrpool_server.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/thrpool_server.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,607 @@
+/* -*- 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 ***** */
+
+/***********************************************************************
+**
+** Name: thrpool.c
+**
+** Description: Test threadpool functionality.
+**
+** Modification History:
+*/
+#include "primpl.h"
+
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#ifdef XP_UNIX
+#include <sys/mman.h>
+#endif
+#if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)
+#include <pthread.h>
+#endif
+
+/* for getcwd */
+#if defined(XP_UNIX) || defined (XP_OS2_EMX) || defined(XP_BEOS)
+#include <unistd.h>
+#elif defined(XP_PC)
+#include <direct.h>
+#endif
+
+#ifdef WIN32
+#include <process.h>
+#endif
+
+static int _debug_on = 0;
+static char *program_name = NULL;
+static void serve_client_write(void *arg);
+
+#ifdef XP_MAC
+#include "prlog.h"
+#include "prsem.h"
+int fprintf(FILE *stream, const char *fmt, ...)
+{
+    PR_LogPrint(fmt);
+    return 0;
+}
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#else
+#include "obsolete/prsem.h"
+#endif
+
+#ifdef XP_PC
+#define mode_t int
+#endif
+
+#define DPRINTF(arg) if (_debug_on) printf arg
+
+
+#define BUF_DATA_SIZE    (2 * 1024)
+#define TCP_MESG_SIZE    1024
+#define NUM_TCP_CLIENTS  10	/* for a listen queue depth of 5 */
+
+
+#define NUM_TCP_CONNECTIONS_PER_CLIENT  10
+#define NUM_TCP_MESGS_PER_CONNECTION    10
+#define TCP_SERVER_PORT            		10000
+#define SERVER_MAX_BIND_COUNT        	100
+
+static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS;
+static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT;
+static PRInt32 tcp_mesg_size = TCP_MESG_SIZE;
+static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION;
+static void TCP_Server_Accept(void *arg);
+
+
+int failed_already=0;
+typedef struct buffer {
+    char    data[BUF_DATA_SIZE];
+} buffer;
+
+
+typedef struct Server_Param {
+    PRJobIoDesc iod;    /* socket to read from/write to    */
+    PRInt32    	datalen;    /* bytes of data transfered in each read/write */
+    PRNetAddr	netaddr;
+    PRMonitor	*exit_mon;    /* monitor to signal on exit            */
+    PRInt32		*job_counterp;    /* counter to decrement, before exit        */
+    PRInt32		conn_counter;    /* counter to decrement, before exit        */
+	PRThreadPool *tp;
+} Server_Param;
+
+typedef struct Serve_Client_Param {
+    PRJobIoDesc iod;    /* socket to read from/write to    */
+    PRInt32    datalen;    /* bytes of data transfered in each read/write */
+    PRMonitor *exit_mon;    /* monitor to signal on exit            */
+    PRInt32 *job_counterp;    /* counter to decrement, before exit        */
+	PRThreadPool *tp;
+} Serve_Client_Param;
+
+typedef struct Session {
+    PRJobIoDesc iod;    /* socket to read from/write to    */
+	buffer 	*in_buf;
+	PRInt32 bytes;
+	PRInt32 msg_num;
+	PRInt32 bytes_read;
+    PRMonitor *exit_mon;    /* monitor to signal on exit            */
+    PRInt32 *job_counterp;    /* counter to decrement, before exit        */
+	PRThreadPool *tp;
+} Session;
+
+static void
+serve_client_read(void *arg)
+{
+	Session *sp = (Session *) arg;
+    int rem;
+    int bytes;
+    int offset;
+	PRFileDesc *sockfd;
+	char *buf;
+	PRJob *jobp;
+
+	PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
+
+	sockfd = sp->iod.socket;
+	buf = sp->in_buf->data;
+
+    PR_ASSERT(sp->msg_num < num_tcp_mesgs_per_connection);
+	PR_ASSERT(sp->bytes_read < sp->bytes);
+
+	offset = sp->bytes_read;
+	rem = sp->bytes - offset;
+	bytes = PR_Recv(sockfd, buf + offset, rem, 0, timeout);
+	if (bytes < 0) {
+		return;
+	}
+	sp->bytes_read += bytes;
+	sp->iod.timeout = PR_SecondsToInterval(60);
+	if (sp->bytes_read <  sp->bytes) {
+		jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp,
+							PR_FALSE);
+		PR_ASSERT(NULL != jobp);
+		return;
+	}
+	PR_ASSERT(sp->bytes_read == sp->bytes);
+	DPRINTF(("serve_client: read complete, msg(%d) \n", sp->msg_num));
+
+	sp->iod.timeout = PR_SecondsToInterval(60);
+	jobp = PR_QueueJob_Write(sp->tp, &sp->iod, serve_client_write, sp,
+							PR_FALSE);
+	PR_ASSERT(NULL != jobp);
+
+    return;
+}
+
+static void
+serve_client_write(void *arg)
+{
+	Session *sp = (Session *) arg;
+    int bytes;
+	PRFileDesc *sockfd;
+	char *buf;
+	PRJob *jobp;
+
+	sockfd = sp->iod.socket;
+	buf = sp->in_buf->data;
+
+    PR_ASSERT(sp->msg_num < num_tcp_mesgs_per_connection);
+
+	bytes = PR_Send(sockfd, buf, sp->bytes, 0, PR_INTERVAL_NO_TIMEOUT);
+	PR_ASSERT(bytes == sp->bytes);
+
+	if (bytes < 0) {
+		return;
+	}
+	DPRINTF(("serve_client: write complete, msg(%d) \n", sp->msg_num));
+    sp->msg_num++;
+    if (sp->msg_num < num_tcp_mesgs_per_connection) {
+		sp->bytes_read = 0;
+		sp->iod.timeout = PR_SecondsToInterval(60);
+		jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp,
+							PR_FALSE);
+		PR_ASSERT(NULL != jobp);
+		return;
+	}
+
+	DPRINTF(("serve_client: read/write complete, msg(%d) \n", sp->msg_num));
+    if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
+        fprintf(stderr,"%s: ERROR - PR_Shutdown\n", program_name);
+    }
+
+    PR_Close(sockfd);
+    PR_EnterMonitor(sp->exit_mon);
+    --(*sp->job_counterp);
+    PR_Notify(sp->exit_mon);
+    PR_ExitMonitor(sp->exit_mon);
+
+    PR_DELETE(sp->in_buf);
+    PR_DELETE(sp);
+
+    return;
+}
+
+/*
+ * Serve_Client
+ *    Thread, started by the server, for serving a client connection.
+ *    Reads data from socket and writes it back, unmodified, and
+ *    closes the socket
+ */
+static void PR_CALLBACK
+Serve_Client(void *arg)
+{
+    Serve_Client_Param *scp = (Serve_Client_Param *) arg;
+    buffer *in_buf;
+	Session *sp;
+	PRJob *jobp;
+
+	sp = PR_NEW(Session);
+	sp->iod = scp->iod;
+
+    in_buf = PR_NEW(buffer);
+    if (in_buf == NULL) {
+        fprintf(stderr,"%s: failed to alloc buffer struct\n",program_name);
+        failed_already=1;
+        return;
+    }
+
+	sp->in_buf = in_buf;
+	sp->bytes = scp->datalen;
+	sp->msg_num = 0;
+	sp->bytes_read = 0;
+	sp->tp = scp->tp;
+   	sp->exit_mon = scp->exit_mon;
+    sp->job_counterp = scp->job_counterp;
+
+	sp->iod.timeout = PR_SecondsToInterval(60);
+	jobp = PR_QueueJob_Read(sp->tp, &sp->iod, serve_client_read, sp,
+							PR_FALSE);
+	PR_ASSERT(NULL != jobp);
+	PR_DELETE(scp);
+}
+
+static void
+print_stats(void *arg)
+{
+    Server_Param *sp = (Server_Param *) arg;
+    PRThreadPool *tp = sp->tp;
+    PRInt32 counter;
+	PRJob *jobp;
+
+	PR_EnterMonitor(sp->exit_mon);
+	counter = (*sp->job_counterp);
+	PR_ExitMonitor(sp->exit_mon);
+
+	printf("PRINT_STATS: #client connections = %d\n",counter);
+
+
+	jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(500),
+						print_stats, sp, PR_FALSE);
+
+	PR_ASSERT(NULL != jobp);
+}
+
+static int job_counter = 0;
+/*
+ * TCP Server
+ *    Server binds an address to a socket, starts a client process and
+ *	  listens for incoming connections.
+ *    Each client connects to the server and sends a chunk of data
+ *    Starts a Serve_Client job for each incoming connection, to read
+ *    the data from the client and send it back to the client, unmodified.
+ *    Each client checks that data received from server is same as the
+ *    data it sent to the server.
+ *	  Finally, the threadpool is shutdown
+ */
+static void PR_CALLBACK
+TCP_Server(void *arg)
+{
+    PRThreadPool *tp = (PRThreadPool *) arg;
+    Server_Param *sp;
+    PRFileDesc *sockfd;
+    PRNetAddr netaddr;
+	PRMonitor *sc_mon;
+	PRJob *jobp;
+	int i;
+	PRStatus rval;
+
+    /*
+     * Create a tcp socket
+     */
+    if ((sockfd = PR_NewTCPSocket()) == NULL) {
+        fprintf(stderr,"%s: PR_NewTCPSocket failed\n", program_name);
+        return;
+    }
+    memset(&netaddr, 0 , sizeof(netaddr));
+    netaddr.inet.family = PR_AF_INET;
+    netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
+    netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    /*
+     * try a few times to bind server's address, if addresses are in
+     * use
+     */
+	i = 0;
+    while (PR_Bind(sockfd, &netaddr) < 0) {
+        if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
+            netaddr.inet.port += 2;
+            if (i++ < SERVER_MAX_BIND_COUNT)
+                continue;
+        }
+        fprintf(stderr,"%s: ERROR - PR_Bind failed\n", program_name);
+        perror("PR_Bind");
+        failed_already=1;
+        return;
+    }
+
+    if (PR_Listen(sockfd, 32) < 0) {
+        fprintf(stderr,"%s: ERROR - PR_Listen failed\n", program_name);
+        failed_already=1;
+        return;
+    }
+
+    if (PR_GetSockName(sockfd, &netaddr) < 0) {
+        fprintf(stderr,"%s: ERROR - PR_GetSockName failed\n", program_name);
+        failed_already=1;
+        return;
+    }
+
+    DPRINTF((
+	"TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
+        netaddr.inet.ip, netaddr.inet.port));
+
+	sp = PR_NEW(Server_Param);
+	if (sp == NULL) {
+		fprintf(stderr,"%s: PR_NEW failed\n", program_name);
+		failed_already=1;
+		return;
+	}
+	sp->iod.socket = sockfd;
+	sp->iod.timeout = PR_SecondsToInterval(60);
+	sp->datalen = tcp_mesg_size;
+	sp->exit_mon = sc_mon;
+	sp->job_counterp = &job_counter;
+	sp->conn_counter = 0;
+	sp->tp = tp;
+	sp->netaddr = netaddr;
+
+	/* create and cancel an io job */
+	jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp,
+							PR_FALSE);
+	PR_ASSERT(NULL != jobp);
+	rval = PR_CancelJob(jobp);
+	PR_ASSERT(PR_SUCCESS == rval);
+
+	/*
+	 * create the client process
+	 */
+	{
+#define MAX_ARGS 4
+		char *argv[MAX_ARGS + 1];
+		int index = 0;
+		char port[32];
+        char path[1024 + sizeof("/thrpool_client")];
+        (void)getcwd(path, sizeof(path));
+        (void)strcat(path, "/thrpool_client");
+#ifdef XP_PC
+        (void)strcat(path, ".exe");
+#endif
+        argv[index++] = path;
+		sprintf(port,"%d",PR_ntohs(netaddr.inet.port));
+        if (_debug_on)
+        {
+            argv[index++] = "-d";
+            argv[index++] = "-p";
+            argv[index++] = port;
+            argv[index++] = NULL;
+        } else {
+            argv[index++] = "-p";
+            argv[index++] = port;
+			argv[index++] = NULL;
+		}
+		PR_ASSERT(MAX_ARGS >= (index - 1));
+        
+        DPRINTF(("creating client process %s ...\n", path));
+        if (PR_FAILURE == PR_CreateProcessDetached(path, argv, NULL, NULL)) {
+        	fprintf(stderr,
+				"thrpool_server: ERROR - PR_CreateProcessDetached failed\n");
+        	failed_already=1;
+        	return;
+		}
+	}
+
+    sc_mon = PR_NewMonitor();
+    if (sc_mon == NULL) {
+        fprintf(stderr,"%s: PR_NewMonitor failed\n", program_name);
+        failed_already=1;
+        return;
+    }
+
+	sp->iod.socket = sockfd;
+	sp->iod.timeout = PR_SecondsToInterval(60);
+	sp->datalen = tcp_mesg_size;
+	sp->exit_mon = sc_mon;
+	sp->job_counterp = &job_counter;
+	sp->conn_counter = 0;
+	sp->tp = tp;
+	sp->netaddr = netaddr;
+
+	/* create and cancel a timer job */
+	jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(5000),
+						print_stats, sp, PR_FALSE);
+	PR_ASSERT(NULL != jobp);
+	rval = PR_CancelJob(jobp);
+	PR_ASSERT(PR_SUCCESS == rval);
+
+    DPRINTF(("TCP_Server: Accepting connections \n"));
+
+	jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp,
+							PR_FALSE);
+	PR_ASSERT(NULL != jobp);
+	return;
+}
+
+static void
+TCP_Server_Accept(void *arg)
+{
+    Server_Param *sp = (Server_Param *) arg;
+    PRThreadPool *tp = sp->tp;
+    Serve_Client_Param *scp;
+	PRFileDesc *newsockfd;
+	PRJob *jobp;
+
+	if ((newsockfd = PR_Accept(sp->iod.socket, &sp->netaddr,
+		PR_INTERVAL_NO_TIMEOUT)) == NULL) {
+		fprintf(stderr,"%s: ERROR - PR_Accept failed\n", program_name);
+		failed_already=1;
+		goto exit;
+	}
+	scp = PR_NEW(Serve_Client_Param);
+	if (scp == NULL) {
+		fprintf(stderr,"%s: PR_NEW failed\n", program_name);
+		failed_already=1;
+		goto exit;
+	}
+
+	/*
+	 * Start a Serve_Client job for each incoming connection
+	 */
+	scp->iod.socket = newsockfd;
+	scp->iod.timeout = PR_SecondsToInterval(60);
+	scp->datalen = tcp_mesg_size;
+	scp->exit_mon = sp->exit_mon;
+	scp->job_counterp = sp->job_counterp;
+	scp->tp = sp->tp;
+
+	PR_EnterMonitor(sp->exit_mon);
+	(*sp->job_counterp)++;
+	PR_ExitMonitor(sp->exit_mon);
+	jobp = PR_QueueJob(tp, Serve_Client, scp,
+						PR_FALSE);
+
+	PR_ASSERT(NULL != jobp);
+	DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", jobp));
+
+	/*
+	 * single-threaded update; no lock needed
+	 */
+    sp->conn_counter++;
+    if (sp->conn_counter <
+			(num_tcp_clients * num_tcp_connections_per_client)) {
+		jobp = PR_QueueJob_Accept(tp, &sp->iod, TCP_Server_Accept, sp,
+								PR_FALSE);
+		PR_ASSERT(NULL != jobp);
+		return;
+	}
+	jobp = PR_QueueJob_Timer(tp, PR_MillisecondsToInterval(500),
+						print_stats, sp, PR_FALSE);
+
+	PR_ASSERT(NULL != jobp);
+	DPRINTF(("TCP_Server: Created print_stats timer job = 0x%lx\n", jobp));
+
+exit:
+	PR_EnterMonitor(sp->exit_mon);
+    /* Wait for server jobs to finish */
+    while (0 != *sp->job_counterp) {
+        PR_Wait(sp->exit_mon, PR_INTERVAL_NO_TIMEOUT);
+        DPRINTF(("TCP_Server: conn_counter = %d\n",
+												*sp->job_counterp));
+    }
+
+    PR_ExitMonitor(sp->exit_mon);
+    if (sp->iod.socket) {
+        PR_Close(sp->iod.socket);
+    }
+	PR_DestroyMonitor(sp->exit_mon);
+    printf("%30s","TCP_Socket_Client_Server_Test:");
+    printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l,
+        num_tcp_clients, num_tcp_connections_per_client);
+    printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":",
+        num_tcp_mesgs_per_connection, tcp_mesg_size);
+
+	DPRINTF(("%s: calling PR_ShutdownThreadPool\n", program_name));
+	PR_ShutdownThreadPool(sp->tp);
+	PR_DELETE(sp);
+}
+
+/************************************************************************/
+
+#define DEFAULT_INITIAL_THREADS		4
+#define DEFAULT_MAX_THREADS			100
+#define DEFAULT_STACKSIZE			(512 * 1024)
+
+int
+main(int argc, char **argv)
+{
+	PRInt32 initial_threads = DEFAULT_INITIAL_THREADS;
+	PRInt32 max_threads = DEFAULT_MAX_THREADS;
+	PRInt32 stacksize = DEFAULT_STACKSIZE;
+	PRThreadPool *tp = NULL;
+	PRStatus rv;
+	PRJob *jobp;
+
+    /*
+     * -d           debug mode
+     */
+    PLOptStatus os;
+    PLOptState *opt;
+
+	program_name = argv[0];
+    opt = PL_CreateOptState(argc, argv, "d");
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            _debug_on = 1;
+            break;
+        default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+#ifdef XP_MAC
+    SetupMacPrintfLog("socket.log");
+#endif
+    PR_SetConcurrency(4);
+
+	tp = PR_CreateThreadPool(initial_threads, max_threads, stacksize);
+    if (NULL == tp) {
+        printf("PR_CreateThreadPool failed\n");
+        failed_already=1;
+        goto done;
+	}
+	jobp = PR_QueueJob(tp, TCP_Server, tp, PR_TRUE);
+	rv = PR_JoinJob(jobp);		
+	PR_ASSERT(PR_SUCCESS == rv);
+
+	DPRINTF(("%s: calling PR_JoinThreadPool\n", program_name));
+	rv = PR_JoinThreadPool(tp);
+	PR_ASSERT(PR_SUCCESS == rv);
+	DPRINTF(("%s: returning from PR_JoinThreadPool\n", program_name));
+
+done:
+    PR_Cleanup();
+    if (failed_already) return 1;
+    else return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/thruput.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/thruput.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,412 @@
+/* -*- 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:        thruput.c
+** Description: Test server's throughput capability comparing various
+**              implmentation strategies.
+**
+** Note:        Requires a server machine and an aribitrary number of
+**              clients to bang on it. Trust the numbers on the server
+**              more than those being displayed by the various clients.
+*/
+
+#include "prerror.h"
+#include "prinrval.h"
+#include "prinit.h"
+#include "prio.h"
+#include "prlock.h"
+#include "prmem.h"
+#include "prnetdb.h"
+#include "prprf.h"
+#include "prthread.h"
+
+#include "pprio.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#define ADDR_BUFFER 100
+#define PORT_NUMBER 51877
+#define SAMPLING_INTERVAL 10
+#define BUFFER_SIZE (32 * 1024)
+
+static PRInt32 domain = PR_AF_INET;
+static PRInt32 protocol = 6;  /* TCP */
+static PRFileDesc *err = NULL;
+static PRIntn concurrency = 1;
+static PRInt32 xport_buffer = -1;
+static PRUint32 initial_streams = 1;
+static PRInt32 buffer_size = BUFFER_SIZE;
+static PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+typedef struct Shared
+{
+    PRLock *ml;
+    PRUint32 sampled;
+    PRUint32 threads;
+    PRIntervalTime timein;
+    PRNetAddr server_address;
+} Shared;
+
+static Shared *shared = NULL;
+
+static PRStatus PrintAddress(const PRNetAddr* address)
+{
+    char buffer[ADDR_BUFFER];
+    PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
+    if (PR_SUCCESS == rv)
+        PR_fprintf(err, "%s:%u\n", buffer, PR_ntohs(address->inet.port));
+    else PL_FPrintError(err, "PR_NetAddrToString");
+    return rv;
+}  /* PrintAddress */
+
+
+static void PR_CALLBACK Clientel(void *arg)
+{
+    PRStatus rv;
+    PRFileDesc *xport;
+    PRInt32 bytes, sampled;
+    PRIntervalTime now, interval;
+    PRBool do_display = PR_FALSE;
+    Shared *shared = (Shared*)arg;
+    char *buffer = (char*)PR_Malloc(buffer_size);
+    PRNetAddr *server_address = &shared->server_address;
+    PRIntervalTime connect_timeout = PR_SecondsToInterval(5);
+    PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL);
+
+    PR_fprintf(err, "Client connecting to ");
+    (void)PrintAddress(server_address);
+
+    do
+    {
+        xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);
+        if (NULL == xport)
+        {
+            PL_FPrintError(err, "PR_Socket");
+            return;
+        }
+
+        if (xport_buffer != -1)
+        {
+            PRSocketOptionData data;
+            data.option = PR_SockOpt_RecvBufferSize;
+            data.value.recv_buffer_size = (PRSize)xport_buffer;
+            rv = PR_SetSocketOption(xport, &data);
+            if (PR_FAILURE == rv)
+                PL_FPrintError(err, "PR_SetSocketOption - ignored");
+            data.option = PR_SockOpt_SendBufferSize;
+            data.value.send_buffer_size = (PRSize)xport_buffer;
+            rv = PR_SetSocketOption(xport, &data);
+            if (PR_FAILURE == rv)
+                PL_FPrintError(err, "PR_SetSocketOption - ignored");
+        }
+
+        rv = PR_Connect(xport, server_address, connect_timeout);
+        if (PR_FAILURE == rv)
+        {
+            PL_FPrintError(err, "PR_Connect");
+            if (PR_IO_TIMEOUT_ERROR != PR_GetError())
+                PR_Sleep(connect_timeout);
+            PR_Close(xport);  /* delete it and start over */
+        }
+    } while (PR_FAILURE == rv);
+
+    do
+    {
+        bytes = PR_Recv(
+            xport, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT);
+        PR_Lock(shared->ml);
+        now = PR_IntervalNow();
+        shared->sampled += bytes;
+        interval = now - shared->timein;
+        if (interval > sampling_interval)
+        {
+            sampled = shared->sampled;
+            shared->timein = now;
+            shared->sampled = 0;
+            do_display = PR_TRUE;
+        }
+        PR_Unlock(shared->ml);
+
+        if (do_display)
+        {
+            PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval);
+            PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate);
+            do_display = PR_FALSE;
+        }
+
+    } while (bytes > 0);
+}  /* Clientel */
+
+static void Client(const char *server_name)
+{
+    PRStatus rv;
+    PRHostEnt host;
+    char buffer[PR_NETDB_BUF_SIZE];
+    PRIntervalTime dally = PR_SecondsToInterval(60);
+    PR_fprintf(err, "Translating the name %s\n", server_name);
+    rv = PR_GetHostByName(server_name, buffer, sizeof(buffer), &host);
+    if (PR_FAILURE == rv)
+        PL_FPrintError(err, "PR_GetHostByName");
+    else
+    {
+        if (PR_EnumerateHostEnt(
+            0, &host, PORT_NUMBER, &shared->server_address) < 0)
+            PL_FPrintError(err, "PR_EnumerateHostEnt");
+        else
+        {
+            do
+            {
+                shared->threads += 1;
+                (void)PR_CreateThread(
+                    PR_USER_THREAD, Clientel, shared,
+                    PR_PRIORITY_NORMAL, thread_scope,
+                    PR_UNJOINABLE_THREAD, 8 * 1024);
+                if (shared->threads == initial_streams)
+                {
+                    PR_Sleep(dally);
+                    initial_streams += 1;
+                }
+            } while (PR_TRUE);
+        }
+    }
+}
+
+static void PR_CALLBACK Servette(void *arg)
+{
+    PRInt32 bytes, sampled;
+    PRIntervalTime now, interval;
+    PRBool do_display = PR_FALSE;
+    PRFileDesc *client = (PRFileDesc*)arg;
+    char *buffer = (char*)PR_Malloc(buffer_size);
+    PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL);
+
+    if (xport_buffer != -1)
+    {
+        PRStatus rv;
+        PRSocketOptionData data;
+        data.option = PR_SockOpt_RecvBufferSize;
+        data.value.recv_buffer_size = (PRSize)xport_buffer;
+        rv = PR_SetSocketOption(client, &data);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err, "PR_SetSocketOption - ignored");
+        data.option = PR_SockOpt_SendBufferSize;
+        data.value.send_buffer_size = (PRSize)xport_buffer;
+        rv = PR_SetSocketOption(client, &data);
+        if (PR_FAILURE == rv)
+            PL_FPrintError(err, "PR_SetSocketOption - ignored");
+    }
+
+    do
+    {
+        bytes = PR_Send(
+            client, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT);
+
+        PR_Lock(shared->ml);
+        now = PR_IntervalNow();
+        shared->sampled += bytes;
+        interval = now - shared->timein;
+        if (interval > sampling_interval)
+        {
+            sampled = shared->sampled;
+            shared->timein = now;
+            shared->sampled = 0;
+            do_display = PR_TRUE;
+        }
+        PR_Unlock(shared->ml);
+
+        if (do_display)
+        {
+            PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval);
+            PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate);
+            do_display = PR_FALSE;
+        }
+    } while (bytes > 0);
+}  /* Servette */
+
+static void Server(void)
+{
+    PRStatus rv;
+    PRNetAddr server_address, client_address;
+    PRFileDesc *xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);
+
+    if (NULL == xport)
+    {
+        PL_FPrintError(err, "PR_Socket");
+        return;
+    }
+
+    rv = PR_InitializeNetAddr(PR_IpAddrAny, PORT_NUMBER, &server_address);
+    if (PR_FAILURE == rv) PL_FPrintError(err, "PR_InitializeNetAddr");
+    else
+    {
+        rv = PR_Bind(xport, &server_address);
+        if (PR_FAILURE == rv) PL_FPrintError(err, "PR_Bind");
+        else
+        {
+            PRFileDesc *client;
+            rv = PR_Listen(xport, 10);
+            PR_fprintf(err, "Server listening on ");
+            (void)PrintAddress(&server_address);
+            do
+            {
+                client = PR_Accept(
+                    xport, &client_address, PR_INTERVAL_NO_TIMEOUT);
+                if (NULL == client) PL_FPrintError(err, "PR_Accept");
+                else
+                {
+                    PR_fprintf(err, "Server accepting from ");
+                    (void)PrintAddress(&client_address);
+                    shared->threads += 1;
+                    (void)PR_CreateThread(
+                        PR_USER_THREAD, Servette, client,
+                        PR_PRIORITY_NORMAL, thread_scope,
+                        PR_UNJOINABLE_THREAD, 8 * 1024);
+                }
+            } while (PR_TRUE);
+
+        }
+    }
+}  /* Server */
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: [-h] [<server>]\n");
+    PR_fprintf(err, "\t-s <n>   Initial # of connections        (default: 1)\n");
+    PR_fprintf(err, "\t-C <n>   Set 'concurrency'               (default: 1)\n");
+    PR_fprintf(err, "\t-b <nK>  Client buffer size              (default: 32k)\n");
+    PR_fprintf(err, "\t-B <nK>  Transport recv/send buffer size (default: sys)\n");
+    PR_fprintf(err, "\t-G       Use GLOBAL threads              (default: LOCAL)\n");
+    PR_fprintf(err, "\t-X       Use XTP transport               (default: TCP)\n");
+    PR_fprintf(err, "\t-6       Use IPv6                        (default: IPv4)\n");
+    PR_fprintf(err, "\t-h       This message and nothing else\n");
+    PR_fprintf(err, "\t<server> DNS name of server\n");
+    PR_fprintf(err, "\t\tIf <server> is not specified, this host will be\n");
+    PR_fprintf(err, "\t\tthe server and not act as a client.\n");
+}  /* Help */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PLOptStatus os;
+    const char *server_name = NULL;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hGX6C:b:s:B:");
+
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:  /* Name of server */
+            server_name = opt->value;
+            break;
+        case 'G':  /* Globular threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'X':  /* Use XTP as the transport */
+            protocol = 36;
+            break;
+        case '6':  /* Use IPv6 */
+            domain = PR_AF_INET6;
+            break;
+        case 's':  /* initial_streams */
+            initial_streams = atoi(opt->value);
+            break;
+        case 'C':  /* concurrency */
+            concurrency = atoi(opt->value);
+            break;
+        case 'b':  /* buffer size */
+            buffer_size = 1024 * atoi(opt->value);
+            break;
+        case 'B':  /* buffer size */
+            xport_buffer = 1024 * atoi(opt->value);
+            break;
+        case 'h':  /* user wants some guidance */
+        default:
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    shared = PR_NEWZAP(Shared);
+    shared->ml = PR_NewLock();
+
+    PR_fprintf(err,
+        "This machine is %s\n",
+        (NULL == server_name) ? "the SERVER" : "a CLIENT");
+
+    PR_fprintf(err,
+        "Transport being used is %s\n",
+        (6 == protocol) ? "TCP" : "XTP");
+
+    if (PR_GLOBAL_THREAD == thread_scope)
+    {
+        if (1 != concurrency)
+        {
+            PR_fprintf(err, "  **Concurrency > 1 and GLOBAL threads!?!?\n");
+            PR_fprintf(err, "  **Ignoring concurrency\n");
+            concurrency = 1;
+        }
+    }
+
+    if (1 != concurrency)
+    {
+        PR_SetConcurrency(concurrency);
+        PR_fprintf(err, "Concurrency set to %u\n", concurrency);
+    }
+
+    PR_fprintf(err,
+        "All threads will be %s\n",
+        (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
+
+    PR_fprintf(err, "Client buffer size will be %u\n", buffer_size);
+   
+    if (-1 != xport_buffer)
+    PR_fprintf(
+        err, "Transport send & receive buffer size will be %u\n", xport_buffer);
+    
+
+    if (NULL == server_name) Server();
+    else Client(server_name);
+
+}  /* main */
+
+/* thruput.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/time.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/time.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,201 @@
+/* -*- 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 ***** */
+
+/*
+ * Program to test different ways to get the time; right now it is tuned
+ * only for solaris.
+ *   solaris results (100000 iterations):
+ *          time to get time with time():   4.63 usec avg, 463 msec total
+ *     time to get time with gethrtime():   2.17 usec avg, 217 msec total
+ *  time to get time with gettimeofday():   1.25 usec avg, 125 msec total
+ *
+ *
+ */
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "prpriv.h"
+#include "prinrval.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#define DEFAULT_COUNT 100000
+PRInt32 count;
+
+time_t itime;
+hrtime_t ihrtime;
+
+void
+ftime_init()
+{
+   itime = time(NULL);
+   ihrtime = gethrtime();
+}
+
+time_t
+ftime()
+{
+        hrtime_t now = gethrtime();
+
+        return itime + ((now - ihrtime) / 1000000000ll);
+}
+
+static void timeTime(void)
+{
+    PRInt32 index = count;
+    time_t rv;
+ 
+    for (;index--;)
+        rv = time(NULL);
+}
+
+static void timeGethrtime(void)
+{
+    PRInt32 index = count;
+    time_t rv;
+ 
+    for (;index--;)
+        rv = ftime();
+}
+
+static void timeGettimeofday(void)
+{
+    PRInt32 index = count;
+    time_t rv;
+    struct timeval tp;
+ 
+    for (;index--;)
+        rv = gettimeofday(&tp, NULL);
+}
+
+static void timePRTime32(void)
+{
+    PRInt32 index = count;
+    PRInt32 rv32;
+    PRTime q;
+    PRTime rv;
+
+    LL_I2L(q, 1000000);
+ 
+    for (;index--;) {
+        rv = PR_Now();
+        LL_DIV(rv, rv, q);
+        LL_L2I(rv32, rv);
+    }
+}
+
+static void timePRTime64(void)
+{
+    PRInt32 index = count;
+    PRTime rv;
+ 
+    for (;index--;)
+        rv = PR_Now();
+}
+
+/************************************************************************/
+
+static void Measure(void (*func)(void), const char *msg)
+{
+    PRIntervalTime start, stop;
+    double d;
+    PRInt32 tot;
+
+    start = PR_IntervalNow();
+    (*func)();
+    stop = PR_IntervalNow();
+
+    d = (double)PR_IntervalToMicroseconds(stop - start);
+    tot = PR_IntervalToMilliseconds(stop-start);
+
+    if (debug_mode) printf("%40s: %6.2f usec avg, %d msec total\n", msg, d / count, tot);
+}
+
+void main(int argc, char **argv)
+{
+	/* 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, "d:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+
+    if (argc > 1) {
+	count = atoi(argv[1]);
+    } else {
+	count = DEFAULT_COUNT;
+    }
+
+    ftime_init();
+
+    Measure(timeTime, "time to get time with time()");
+    Measure(timeGethrtime, "time to get time with gethrtime()");
+    Measure(timeGettimeofday, "time to get time with gettimeofday()");
+    Measure(timePRTime32, "time to get time with PR_Time() (32bit)");
+    Measure(timePRTime64, "time to get time with PR_Time() (64bit)");
+
+	PR_Cleanup();
+	return 0;
+}
+
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/timemac.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/timemac.c	Mon Dec 18 10:53:47 2006
@@ -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 ***** */
+
+/*
+ * file: timemac.c
+ * description: test time and date routines on the Mac
+ */
+#include <stdio.h>
+#include "prinit.h"
+#include "prtime.h"
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+
+static char *dayOfWeek[] =
+	{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" };
+static char *month[] =
+	{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+	  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" };
+
+static void printExplodedTime(const PRExplodedTime *et) {
+    PRInt32 totalOffset;
+    PRInt32 hourOffset, minOffset;
+    const char *sign;
+
+    /* Print day of the week, month, day, hour, minute, and second */
+    printf( "%s %s %ld %02ld:%02ld:%02ld ",
+	    dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday,
+	    et->tm_hour, et->tm_min, et->tm_sec);
+
+    /* Print time zone */
+    totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset;
+    if (totalOffset == 0) {
+	printf("UTC ");
+    } else {
+        sign = "";
+        if (totalOffset < 0) {
+	    totalOffset = -totalOffset;
+	    sign = "-";
+        }
+        hourOffset = totalOffset / 3600;
+        minOffset = (totalOffset % 3600) / 60;
+        printf("%s%02ld%02ld ", sign, hourOffset, minOffset);
+    }
+
+    /* Print year */
+    printf("%d", et->tm_year);
+}
+
+int main(int argc, char** argv)
+{
+    PR_STDIO_INIT();
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+
+ 
+#ifdef XP_MAC
+	SetupMacPrintfLog("timemac.log");
+#endif
+
+   /*
+     *************************************************************
+     **
+     **  Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime
+     **  on the current time
+     **
+     *************************************************************
+     */
+
+    {
+	PRTime t1, t2;
+	PRExplodedTime et;
+
+	printf("*********************************************\n");
+	printf("**                                         **\n");
+        printf("** Testing PR_Now(), PR_ExplodeTime, and   **\n");
+	printf("** PR_ImplodeTime on the current time      **\n");
+	printf("**                                         **\n");
+	printf("*********************************************\n\n");
+        t1 = PR_Now();
+
+        /* First try converting to UTC */
+
+        PR_ExplodeTime(t1, PR_GMTParameters, &et);
+        if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) {
+	    printf("ERROR: UTC has nonzero gmt or dst offset.\n");
+	    return 1;
+        }
+        printf("Current UTC is ");
+	printExplodedTime(&et);
+	printf("\n");
+
+        t2 = PR_ImplodeTime(&et);
+        if (LL_NE(t1, t2)) {
+	    printf("ERROR: Explode and implode are NOT inverse.\n");
+	    return 1;
+        }
+
+        /* Next, try converting to local (US Pacific) time */
+
+        PR_ExplodeTime(t1, PR_LocalTimeParameters, &et);
+        printf("Current local time is ");
+	printExplodedTime(&et);
+	printf("\n");
+	printf("GMT offset is %ld, DST offset is %ld\n",
+		et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset);
+        t2 = PR_ImplodeTime(&et);
+        if (LL_NE(t1, t2)) {
+	    printf("ERROR: Explode and implode are NOT inverse.\n");
+	    return 1;
+	}
+    }
+
+    printf("Please examine the results\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/timetest.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/timetest.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,782 @@
+/* -*- 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: timetest.c
+ * description: test time and date routines
+ */
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prtime.h"
+#include "prprf.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#include "macstdlibextras.h"
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+int failed_already=0;
+PRBool debug_mode = PR_FALSE;
+
+static char *dayOfWeek[] =
+	{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" };
+static char *month[] =
+	{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+	  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" };
+
+static void PrintExplodedTime(const PRExplodedTime *et) {
+    PRInt32 totalOffset;
+    PRInt32 hourOffset, minOffset;
+    const char *sign;
+
+    /* Print day of the week, month, day, hour, minute, and second */
+    if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ",
+	    dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday,
+	    et->tm_hour, et->tm_min, et->tm_sec);
+
+    /* Print time zone */
+    totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset;
+    if (totalOffset == 0) {
+	if (debug_mode) printf("UTC ");
+    } else {
+        sign = "+";
+        if (totalOffset < 0) {
+	    totalOffset = -totalOffset;
+	    sign = "-";
+        }
+        hourOffset = totalOffset / 3600;
+        minOffset = (totalOffset % 3600) / 60;
+        if (debug_mode) 
+            printf("%s%02ld%02ld ", sign, hourOffset, minOffset);
+    }
+
+    /* Print year */
+    if (debug_mode) printf("%hd", et->tm_year);
+}
+
+static int ExplodedTimeIsEqual(const PRExplodedTime *et1,
+	const PRExplodedTime *et2)
+{
+    if (et1->tm_usec == et2->tm_usec &&
+	    et1->tm_sec == et2->tm_sec &&
+	    et1->tm_min == et2->tm_min &&
+	    et1->tm_hour == et2->tm_hour &&
+	    et1->tm_mday == et2->tm_mday &&
+	    et1->tm_month == et2->tm_month &&
+	    et1->tm_year == et2->tm_year &&
+	    et1->tm_wday == et2->tm_wday &&
+	    et1->tm_yday == et2->tm_yday &&
+	    et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset &&
+	    et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) {
+        return 1;
+    } else {
+	return 0;
+    }
+}
+
+static void
+testParseTimeString(PRTime t)
+{
+    PRExplodedTime et;
+    PRTime t2;
+    char timeString[128];
+    char buf[128];
+    PRInt32 totalOffset;
+    PRInt32 hourOffset, minOffset;
+    const char *sign;
+    PRInt64 usec_per_sec;
+
+    /* Truncate the microsecond part of PRTime */
+    LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
+    LL_DIV(t, t, usec_per_sec);
+    LL_MUL(t, t, usec_per_sec);
+
+    PR_ExplodeTime(t, PR_LocalTimeParameters, &et);
+
+    /* Print day of the week, month, day, hour, minute, and second */
+    PR_snprintf(timeString, 128, "%s %s %ld %02ld:%02ld:%02ld ",
+	    dayOfWeek[et.tm_wday], month[et.tm_month], et.tm_mday,
+	    et.tm_hour, et.tm_min, et.tm_sec);
+    /* Print time zone */
+    totalOffset = et.tm_params.tp_gmt_offset + et.tm_params.tp_dst_offset;
+    if (totalOffset == 0) {
+	strcat(timeString, "GMT ");  /* I wanted to use "UTC" here, but
+                                      * PR_ParseTimeString doesn't 
+                                      * understand "UTC".  */
+    } else {
+        sign = "+";
+        if (totalOffset < 0) {
+	    totalOffset = -totalOffset;
+	    sign = "-";
+        }
+        hourOffset = totalOffset / 3600;
+        minOffset = (totalOffset % 3600) / 60;
+        PR_snprintf(buf, 128, "%s%02ld%02ld ", sign, hourOffset, minOffset);
+	strcat(timeString, buf);
+    }
+    /* Print year */
+    PR_snprintf(buf, 128, "%hd", et.tm_year);
+    strcat(timeString, buf);
+
+    if (PR_ParseTimeString(timeString, PR_FALSE, &t2) == PR_FAILURE) {
+	fprintf(stderr, "PR_ParseTimeString() failed\n");
+	exit(1);
+    }
+    if (LL_NE(t, t2)) {
+	fprintf(stderr, "PR_ParseTimeString() incorrect\n");
+	PR_snprintf(buf, 128, "t is %lld, t2 is %lld, time string is %s\n",
+                t, t2, timeString);
+	fprintf(stderr, "%s\n", buf);
+	exit(1);
+    }
+}
+
+int main(int argc, char** argv)
+{
+	/* 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;
+    
+    PR_STDIO_INIT();
+	opt = PL_CreateOptState(argc, argv, "d");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+
+#ifdef XP_MAC
+	/* Set up the console */
+	InitializeSIOUX(true);
+	debug_mode = PR_TRUE;
+#endif
+    /* Testing zero PRTime (the epoch) */
+    {
+	PRTime t;
+	PRExplodedTime et;
+
+	LL_I2L(t, 0);
+	if (debug_mode) printf("The NSPR epoch is:\n");
+        PR_ExplodeTime(t, PR_LocalTimeParameters, &et);
+	PrintExplodedTime(&et);
+	if (debug_mode) printf("\n");
+	PR_ExplodeTime(t, PR_GMTParameters, &et);
+	PrintExplodedTime(&et);
+	if (debug_mode) printf("\n\n");
+	testParseTimeString(t);
+    }
+
+    /*
+     *************************************************************
+     **
+     **  Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime
+     **  on the current time
+     **
+     *************************************************************
+     */
+
+    {
+	PRTime t1, t2;
+	PRExplodedTime et;
+
+	if (debug_mode) {
+	printf("*********************************************\n");
+	printf("**                                         **\n");
+    printf("** Testing PR_Now(), PR_ExplodeTime, and   **\n");
+	printf("** PR_ImplodeTime on the current time      **\n");
+	printf("**                                         **\n");
+	printf("*********************************************\n\n");
+	}
+	t1 = PR_Now();
+
+        /* First try converting to UTC */
+
+        PR_ExplodeTime(t1, PR_GMTParameters, &et);
+        if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) {
+	    if (debug_mode) printf("ERROR: UTC has nonzero gmt or dst offset.\n");
+		else failed_already=1;
+	    return 1;
+        }
+        if (debug_mode) printf("Current UTC is ");
+	PrintExplodedTime(&et);
+	if (debug_mode) printf("\n");
+
+        t2 = PR_ImplodeTime(&et);
+        if (LL_NE(t1, t2)) {
+	    if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
+		else printf("FAIL\n");
+	    return 1;
+        }
+
+        /* Next, try converting to local (US Pacific) time */
+
+        PR_ExplodeTime(t1, PR_LocalTimeParameters, &et);
+        if (debug_mode) printf("Current local time is ");
+	PrintExplodedTime(&et);
+	if (debug_mode) printf("\n");
+	if (debug_mode) printf("GMT offset is %ld, DST offset is %ld\n",
+		et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset);
+        t2 = PR_ImplodeTime(&et);
+        if (LL_NE(t1, t2)) {
+	    if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
+	    return 1;
+	}
+
+	if (debug_mode) printf("Please examine the results\n");
+	testParseTimeString(t1);
+    }
+
+
+    /*
+     *******************************************
+     **
+     ** Testing PR_NormalizeTime()
+     **
+     *******************************************
+     */
+
+    /* July 4, 2001 is Wednesday */
+    {
+	PRExplodedTime et;
+
+	if (debug_mode)  {
+	printf("\n");
+	printf("**********************************\n");
+	printf("**                              **\n");
+	printf("** Testing PR_NormalizeTime()   **\n");
+	printf("**                              **\n");
+	printf("**********************************\n\n");
+	}
+        et.tm_year    = 2001;
+        et.tm_month   = 7 - 1;
+        et.tm_mday    = 4;
+        et.tm_hour    = 0;
+        et.tm_min     = 0;
+        et.tm_sec     = 0;
+	et.tm_usec    = 0;
+        et.tm_params  = PR_GMTParameters(&et);
+
+	PR_NormalizeTime(&et, PR_GMTParameters);
+
+	if (debug_mode) printf("July 4, 2001 is %s.\n", dayOfWeek[et.tm_wday]);
+	if (et.tm_wday == 3) {
+	    if (debug_mode) printf("PASS\n");
+        } else {
+            if (debug_mode) printf("ERROR: It should be Wednesday\n");
+			else failed_already=1;
+	    return 1;
+	}
+	testParseTimeString(PR_ImplodeTime(&et));
+
+        /* June 12, 1997 23:00 PST == June 13, 1997 00:00 PDT */
+        et.tm_year    = 1997;
+        et.tm_month   = 6 - 1;
+        et.tm_mday    = 12;
+        et.tm_hour    = 23;
+        et.tm_min     = 0;
+        et.tm_sec     = 0;
+	et.tm_usec    = 0;
+        et.tm_params.tp_gmt_offset = -8 * 3600;
+	et.tm_params.tp_dst_offset = 0;
+
+	PR_NormalizeTime(&et, PR_USPacificTimeParameters);
+
+	if (debug_mode) {
+	    printf("Thu Jun 12, 1997 23:00:00 PST is ");
+	}
+	PrintExplodedTime(&et);
+	if (debug_mode) printf(".\n");
+	if (et.tm_wday == 5) {
+	    if (debug_mode) printf("PASS\n");
+        } else {
+            if (debug_mode) printf("ERROR: It should be Friday\n");
+			else failed_already=1;
+	    return 1;
+	}
+	testParseTimeString(PR_ImplodeTime(&et));
+
+        /* Feb 14, 1997 00:00:00 PDT == Feb 13, 1997 23:00:00 PST */
+        et.tm_year    = 1997;
+        et.tm_month   = 2 - 1;
+        et.tm_mday    = 14;
+        et.tm_hour    = 0;
+        et.tm_min     = 0;
+        et.tm_sec     = 0;
+	et.tm_usec    = 0;
+        et.tm_params.tp_gmt_offset = -8 * 3600;
+	et.tm_params.tp_dst_offset = 3600;
+
+	PR_NormalizeTime(&et, PR_USPacificTimeParameters);
+
+	if (debug_mode) {
+	    printf("Fri Feb 14, 1997 00:00:00 PDT is ");
+	}
+	PrintExplodedTime(&et);
+	if (debug_mode) printf(".\n");
+	if (et.tm_wday == 4) {
+	    if (debug_mode) printf("PASS\n");
+        } else {
+            if (debug_mode) printf("ERROR: It should be Thursday\n");
+			else failed_already=1;
+	    return 1;
+	}
+	testParseTimeString(PR_ImplodeTime(&et));
+
+        /* What time is Nov. 7, 1996, 18:29:23 PDT? */
+        et.tm_year    = 1996;
+        et.tm_month   = 11 - 1;
+        et.tm_mday    = 7;
+        et.tm_hour    = 18;
+        et.tm_min     = 29;
+        et.tm_sec     = 23;
+	et.tm_usec    = 0;
+        et.tm_params.tp_gmt_offset = -8 * 3600;  /* PDT */
+	et.tm_params.tp_dst_offset = 3600; 
+
+	PR_NormalizeTime(&et, PR_LocalTimeParameters);
+        if (debug_mode) printf("Nov 7 18:29:23 PDT 1996 is ");
+	PrintExplodedTime(&et);
+	if (debug_mode) printf(".\n");
+	testParseTimeString(PR_ImplodeTime(&et));
+
+        /* What time is Oct. 7, 1995, 18:29:23 PST? */
+        et.tm_year    = 1995;
+        et.tm_month   = 10 - 1;
+        et.tm_mday    = 7;
+        et.tm_hour    = 18;
+        et.tm_min     = 29;
+        et.tm_sec     = 23;
+        et.tm_params.tp_gmt_offset = -8 * 3600;  /* PST */
+	et.tm_params.tp_dst_offset = 0;
+
+	PR_NormalizeTime(&et, PR_LocalTimeParameters);
+        if (debug_mode) printf("Oct 7 18:29:23 PST 1995 is ");
+	PrintExplodedTime(&et);
+	if (debug_mode) printf(".\n");
+	testParseTimeString(PR_ImplodeTime(&et));
+
+	if (debug_mode) printf("Please examine the results\n");
+    }
+
+    /*
+     **************************************************************
+     **
+     ** Testing range of years
+     **
+     **************************************************************
+     */
+
+    {
+	PRExplodedTime et1, et2;
+    PRTime  ttt;
+	PRTime secs;
+
+	if (debug_mode) {
+	printf("\n");
+	printf("***************************************\n");
+	printf("**                                   **\n");
+	printf("**  Testing range of years           **\n");
+	printf("**                                   **\n");
+	printf("***************************************\n\n");
+	}
+	/* April 4, 1917 GMT */
+	et1.tm_usec = 0;
+	et1.tm_sec = 0;
+	et1.tm_min = 0;
+	et1.tm_hour = 0;
+	et1.tm_mday = 4;
+	et1.tm_month = 4 - 1;
+	et1.tm_year = 1917;
+	et1.tm_params = PR_GMTParameters(&et1);
+	PR_NormalizeTime(&et1, PR_LocalTimeParameters);
+	secs = PR_ImplodeTime(&et1);
+	if (LL_GE_ZERO(secs)) {
+	    if (debug_mode)
+		printf("ERROR: April 4, 1917 GMT returns a nonnegative second count\n");
+		failed_already = 1;
+	    return 1;
+        }
+	PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
+	if (!ExplodedTimeIsEqual(&et1, &et2)) {
+		if (debug_mode)
+		printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for April 4, 1917 GMT\n");
+		failed_already=1;
+	    return 1;
+        }
+    ttt = PR_ImplodeTime(&et1);
+	testParseTimeString( ttt );
+
+	if (debug_mode) printf("Test passed for April 4, 1917\n");
+
+	/* July 4, 2050 */
+	et1.tm_usec = 0;
+	et1.tm_sec = 0;
+	et1.tm_min = 0;
+	et1.tm_hour = 0;
+	et1.tm_mday = 4;
+	et1.tm_month = 7 - 1;
+	et1.tm_year = 2050;
+	et1.tm_params = PR_GMTParameters(&et1);
+	PR_NormalizeTime(&et1, PR_LocalTimeParameters);
+	secs = PR_ImplodeTime(&et1);
+	if (!LL_GE_ZERO(secs)) {
+	    if (debug_mode)
+			printf("ERROR: July 4, 2050 GMT returns a negative second count\n");
+		failed_already = 1;
+	    return 1;
+        }
+	PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
+	if (!ExplodedTimeIsEqual(&et1, &et2)) {
+	    if (debug_mode)
+		printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for July 4, 2050 GMT\n");
+		failed_already=1;
+	    return 1;
+        }
+	testParseTimeString(PR_ImplodeTime(&et1));
+
+	if (debug_mode) printf("Test passed for July 4, 2050\n");
+
+    }
+
+    /*
+     **************************************************************
+     **
+     **  Stress test
+     *
+     **      Go through four years, starting from
+     **      00:00:00 PST Jan. 1, 1993, incrementing
+     **      every 10 minutes.
+     **
+     **************************************************************
+     */
+
+    {
+	PRExplodedTime et, et1, et2;
+	PRInt64 usecPer10Min;
+	int day, hour, min;
+	PRTime usecs;
+	int dstInEffect = 0;
+
+	if (debug_mode) {
+	printf("\n");
+	printf("*******************************************************\n");
+	printf("**                                                   **\n");
+	printf("**                 Stress test                       **\n");
+	printf("**  Starting from midnight Jan. 1, 1993 PST,         **\n");
+	printf("**  going through four years in 10-minute increment  **\n");
+	printf("**                                                   **\n");
+	printf("*******************************************************\n\n");
+	}
+	LL_I2L(usecPer10Min, 600000000L);
+
+	/* 00:00:00 PST Jan. 1, 1993 */
+	et.tm_usec = 0;
+	et.tm_sec = 0;
+	et.tm_min = 0;
+	et.tm_hour = 0;
+	et.tm_mday = 1;
+	et.tm_month = 0;
+	et.tm_year = 1993;
+	et.tm_params.tp_gmt_offset = -8 * 3600;
+	et.tm_params.tp_dst_offset = 0;
+	usecs = PR_ImplodeTime(&et);
+
+        for (day = 0; day < 4 * 365 + 1; day++) {
+	    for (hour = 0; hour < 24; hour++) {
+		for (min = 0; min < 60; min += 10) {
+	            LL_ADD(usecs, usecs, usecPer10Min);
+		    PR_ExplodeTime(usecs, PR_USPacificTimeParameters, &et1);
+
+		    et2 = et;
+		    et2.tm_usec += 600000000L;
+		    PR_NormalizeTime(&et2, PR_USPacificTimeParameters);
+
+		    if (!ExplodedTimeIsEqual(&et1, &et2)) {
+		        if (debug_mode) printf("ERROR: componentwise comparison failed\n");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf("\n");
+			PrintExplodedTime(&et2);
+			if (debug_mode) printf("\n");
+			failed_already=1;
+		        return 1;
+		    }
+
+		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) { 
+                        if (debug_mode)
+					printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf("\n");
+			failed_already=1;
+		        return 1;
+		    }
+		    testParseTimeString(usecs);
+
+		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 1;
+		        if (debug_mode) printf("DST changeover from ");
+			PrintExplodedTime(&et);
+			if (debug_mode) printf(" to ");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf(".\n");
+                    } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 0;
+			if (debug_mode) printf("DST changeover from ");
+			PrintExplodedTime(&et);
+			if (debug_mode) printf(" to ");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf(".\n");
+                    }
+
+		    et = et1;
+		}
+	    }
+        }
+	if (debug_mode) printf("Test passed\n");
+    }
+
+
+    /* Same stress test, but with PR_LocalTimeParameters */
+
+    {
+	PRExplodedTime et, et1, et2;
+	PRInt64 usecPer10Min;
+	int day, hour, min;
+	PRTime usecs;
+	int dstInEffect = 0;
+
+	if (debug_mode) {
+	printf("\n");
+	printf("*******************************************************\n");
+	printf("**                                                   **\n");
+	printf("**                 Stress test                       **\n");
+	printf("**  Starting from midnight Jan. 1, 1993 PST,         **\n");
+	printf("**  going through four years in 10-minute increment  **\n");
+	printf("**                                                   **\n");
+	printf("*******************************************************\n\n");
+	}
+	
+	LL_I2L(usecPer10Min, 600000000L);
+
+	/* 00:00:00 PST Jan. 1, 1993 */
+	et.tm_usec = 0;
+	et.tm_sec = 0;
+	et.tm_min = 0;
+	et.tm_hour = 0;
+	et.tm_mday = 1;
+	et.tm_month = 0;
+	et.tm_year = 1993;
+	et.tm_params.tp_gmt_offset = -8 * 3600;
+	et.tm_params.tp_dst_offset = 0;
+	usecs = PR_ImplodeTime(&et);
+
+        for (day = 0; day < 4 * 365 + 1; day++) {
+	    for (hour = 0; hour < 24; hour++) {
+		for (min = 0; min < 60; min += 10) {
+	            LL_ADD(usecs, usecs, usecPer10Min);
+		    PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);
+
+		    et2 = et;
+		    et2.tm_usec += 600000000L;
+		    PR_NormalizeTime(&et2, PR_LocalTimeParameters);
+
+		    if (!ExplodedTimeIsEqual(&et1, &et2)) {
+		        if (debug_mode) printf("ERROR: componentwise comparison failed\n");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf("\n");
+			PrintExplodedTime(&et2);
+			if (debug_mode) printf("\n");
+		        return 1;
+		    }
+
+		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
+                        printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf("\n");
+			failed_already=1;
+		        return 1;
+		    }
+		    testParseTimeString(usecs);
+
+		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 1;
+		        if (debug_mode) printf("DST changeover from ");
+			PrintExplodedTime(&et);
+			if (debug_mode) printf(" to ");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf(".\n");
+                    } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 0;
+			if (debug_mode) printf("DST changeover from ");
+			PrintExplodedTime(&et);
+			if (debug_mode) printf(" to ");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf(".\n");
+                    }
+
+		    et = et1;
+		}
+	    }
+        }
+	if (debug_mode) printf("Test passed\n");
+    }
+
+    /* Same stress test, but with PR_LocalTimeParameters and going backward */
+
+    {
+	PRExplodedTime et, et1, et2;
+	PRInt64 usecPer10Min;
+	int day, hour, min;
+	PRTime usecs;
+	int dstInEffect = 0;
+
+	if (debug_mode) {
+	printf("\n");
+	printf("*******************************************************\n");
+	printf("**                                                   **\n");
+	printf("**                 Stress test                       **\n");
+	printf("**  Starting from midnight Jan. 1, 1997 PST,         **\n");
+	printf("**  going back four years in 10-minute increment     **\n");
+	printf("**                                                   **\n");
+	printf("*******************************************************\n\n");
+	}
+
+	LL_I2L(usecPer10Min, 600000000L);
+
+	/* 00:00:00 PST Jan. 1, 1997 */
+	et.tm_usec = 0;
+	et.tm_sec = 0;
+	et.tm_min = 0;
+	et.tm_hour = 0;
+	et.tm_mday = 1;
+	et.tm_month = 0;
+	et.tm_year = 1997;
+	et.tm_params.tp_gmt_offset = -8 * 3600;
+	et.tm_params.tp_dst_offset = 0;
+	usecs = PR_ImplodeTime(&et);
+
+        for (day = 0; day < 4 * 365 + 1; day++) {
+	    for (hour = 0; hour < 24; hour++) {
+		for (min = 0; min < 60; min += 10) {
+	            LL_SUB(usecs, usecs, usecPer10Min);
+		    PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);
+
+		    et2 = et;
+		    et2.tm_usec -= 600000000L;
+		    PR_NormalizeTime(&et2, PR_LocalTimeParameters);
+
+		    if (!ExplodedTimeIsEqual(&et1, &et2)) {
+		        if (debug_mode) printf("ERROR: componentwise comparison failed\n");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf("\n");
+			PrintExplodedTime(&et2);
+			if (debug_mode) printf("\n");
+		        return 1;
+		    }
+
+		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
+                   if (debug_mode)
+					printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf("\n");
+			failed_already=1;
+		        return 1;
+		    }
+		    testParseTimeString(usecs);
+
+		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 1;
+		        if (debug_mode) printf("DST changeover from ");
+			PrintExplodedTime(&et);
+			if (debug_mode) printf(" to ");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf(".\n");
+                    } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
+		        dstInEffect = 0;
+			if (debug_mode) printf("DST changeover from ");
+			PrintExplodedTime(&et);
+			if (debug_mode) printf(" to ");
+			PrintExplodedTime(&et1);
+			if (debug_mode) printf(".\n");
+                    }
+
+		    et = et1;
+		}
+	    }
+        }
+    }
+
+#ifdef XP_MAC
+	if (1)
+	{
+		char dummyChar;
+		
+		printf("Press return to exit\n\n");
+		scanf("%c", &dummyChar);
+	}
+#endif
+
+	if (failed_already) return 1;
+	else return 0;
+
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/tmoacc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/tmoacc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,333 @@
+/* -*- 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 "nspr.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#endif
+
+#define BASE_PORT 9867
+#define DEFAULT_THREADS 1
+#define DEFAULT_BACKLOG 10
+#define DEFAULT_TIMEOUT 10
+#define RANDOM_RANGE 100  /* should be significantly smaller than RAND_MAX */
+
+typedef enum {running, stopped} Status;
+
+typedef struct Shared
+{
+    PRLock *ml;
+    PRCondVar *cv;
+    PRBool passed;
+    PRBool random;
+    PRFileDesc *debug;
+    PRIntervalTime timeout;
+    PRFileDesc *listenSock;
+    Status status;
+} Shared;
+
+static PRIntervalTime Timeout(const Shared *shared)
+{
+    PRIntervalTime timeout = shared->timeout;
+    if (shared->random)
+    {
+        PRIntervalTime half = timeout >> 1;  /* one half of the interval */
+        PRIntervalTime quarter = half >> 1;  /* one quarter of the interval */
+        /* something in [0..timeout / 2) */
+        PRUint32 random = (rand() % RANDOM_RANGE) * half / RANDOM_RANGE;
+        timeout = (3 * quarter) + random;  /* [75..125)% */
+    }
+    return timeout;
+}  /* Timeout */
+
+static void Accept(void *arg)
+{
+    PRStatus rv;
+    char *buffer = NULL;
+    PRNetAddr clientAddr;
+    Shared *shared = (Shared*)arg;
+    PRInt32 recv_length = 0, flags = 0;
+    PRFileDesc *clientSock;
+    PRIntn toread, byte, bytes, loop = 0;
+    struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor;
+
+    do
+    {
+        PRUint32 checksum = 0;
+        if (NULL != shared->debug)
+            PR_fprintf(shared->debug, "[%d]accepting ... ", loop++);
+        clientSock = PR_Accept(
+            shared->listenSock, &clientAddr, Timeout(shared));
+        if (clientSock != NULL)
+        {
+            if (NULL != shared->debug)
+                PR_fprintf(shared->debug, "reading length ... ");
+            bytes = PR_Recv(
+                clientSock, &descriptor, sizeof(descriptor),
+                flags, Timeout(shared));
+            if (sizeof(descriptor) == bytes)
+            {
+                /* and, before doing something stupid ... */
+                descriptor.length = PR_ntohl(descriptor.length);
+                descriptor.checksum = PR_ntohl(descriptor.checksum);
+                if (NULL != shared->debug)
+                    PR_fprintf(shared->debug, "%d bytes ... ", descriptor.length);
+                toread = descriptor.length;
+                if (recv_length < descriptor.length)
+                {
+                    if (NULL != buffer) PR_DELETE(buffer);
+                    buffer = (char*)PR_MALLOC(descriptor.length);
+                    recv_length = descriptor.length;
+                }
+                for (toread = descriptor.length; toread > 0; toread -= bytes)
+                {
+                    bytes = PR_Recv(
+                        clientSock, &buffer[descriptor.length - toread],
+                        toread, flags, Timeout(shared));
+                    if (-1 == bytes)
+                    {
+                        if (NULL != shared->debug)
+                            PR_fprintf(shared->debug, "read data failed...");
+                        bytes = 0;
+                    }
+                }
+            }
+            else if (NULL != shared->debug)
+            {
+                PR_fprintf(shared->debug, "read desciptor failed...");
+                descriptor.length = -1;
+            }
+            if (NULL != shared->debug)
+                PR_fprintf(shared->debug, "closing");
+            rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH);
+            if ((PR_FAILURE == rv) && (NULL != shared->debug))
+            {
+                PR_fprintf(shared->debug, " failed");
+                shared->passed = PR_FALSE;
+            }
+            rv = PR_Close(clientSock);
+            if (PR_FAILURE == rv) if (NULL != shared->debug)
+            {
+                PR_fprintf(shared->debug, " failed");
+                shared->passed = PR_FALSE;
+            }
+            if (descriptor.length > 0)
+            {
+                for (byte = 0; byte < descriptor.length; ++byte)
+                {
+                    PRUint32 overflow = checksum & 0x80000000;
+                    checksum = (checksum << 1);
+                    if (0x00000000 != overflow) checksum += 1;
+                    checksum += buffer[byte];
+                }
+                if ((descriptor.checksum != checksum) && (NULL != shared->debug))
+                {
+                    PR_fprintf(shared->debug, " ... data mismatch");
+                    shared->passed = PR_FALSE;
+                }
+            }
+            else if (0 == descriptor.length)
+            {
+                PR_Lock(shared->ml);
+                shared->status = stopped;
+                PR_NotifyCondVar(shared->cv);
+                PR_Unlock(shared->ml);
+            }
+            if (NULL != shared->debug)
+                PR_fprintf(shared->debug, "\n");
+        }
+        else
+        {
+            if (PR_PENDING_INTERRUPT_ERROR != PR_GetError())
+            {
+                if (NULL != shared->debug) PL_PrintError("Accept");
+                shared->passed = PR_FALSE;
+            }
+        }        
+    } while (running == shared->status);
+    if (NULL != buffer) PR_DELETE(buffer);
+}  /* Accept */
+
+PRIntn Tmoacc(PRIntn argc, char **argv)
+{
+    PRStatus rv;
+    PRIntn exitStatus;
+    PRIntn index;
+	Shared *shared;
+	PLOptStatus os;
+	PRThread **thread;
+    PRNetAddr listenAddr;
+    PRSocketOptionData sockOpt;
+    PRIntn timeout = DEFAULT_TIMEOUT;
+    PRIntn threads = DEFAULT_THREADS;
+    PRIntn backlog = DEFAULT_BACKLOG;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dGb:t:T:R");
+
+    shared = PR_NEWZAP(Shared);
+
+    shared->debug = NULL;
+    shared->passed = PR_TRUE;
+    shared->random = PR_TRUE;
+    shared->status = running;
+    shared->ml = PR_NewLock();
+    shared->cv = PR_NewCondVar(shared->ml);
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+            shared->debug = PR_GetSpecialFD(PR_StandardError);
+            break;
+        case 'G':  /* use global threads */
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'b':  /* size of listen backlog */
+            backlog = atoi(opt->value);
+            break;
+        case 't':  /* number of threads doing accept */
+            threads = atoi(opt->value);
+            break;
+        case 'T':  /* timeout used for network operations */
+            timeout = atoi(opt->value);
+            break;
+        case 'R':  /* randomize the timeout values */
+            shared->random = PR_TRUE;
+            break;
+        default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+    if (0 == threads) threads = DEFAULT_THREADS;
+    if (0 == backlog) backlog = DEFAULT_BACKLOG;
+    if (0 == timeout) timeout = DEFAULT_TIMEOUT;
+    
+    PR_STDIO_INIT();
+    memset(&listenAddr, 0, sizeof(listenAddr));
+    rv = PR_InitializeNetAddr(PR_IpAddrAny, BASE_PORT, &listenAddr);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+    shared->timeout = PR_SecondsToInterval(timeout);
+
+    /* First bind to the socket */
+    shared->listenSock = PR_NewTCPSocket();
+    if (shared->listenSock)
+    {
+        sockOpt.option = PR_SockOpt_Reuseaddr;
+        sockOpt.value.reuse_addr = PR_TRUE;
+        rv = PR_SetSocketOption(shared->listenSock, &sockOpt);
+        PR_ASSERT(PR_SUCCESS == rv);
+        rv = PR_Bind(shared->listenSock, &listenAddr);
+        if (rv != PR_FAILURE)
+        {
+            rv = PR_Listen(shared->listenSock, threads + backlog);
+            if (PR_SUCCESS == rv)
+            {
+                thread = (PRThread**)PR_CALLOC(threads * sizeof(PRThread*));
+                for (index = 0; index < threads; ++index)
+                {
+                    thread[index] = PR_CreateThread(
+                        PR_USER_THREAD, Accept, shared,
+                        PR_PRIORITY_NORMAL, thread_scope,
+                        PR_JOINABLE_THREAD, 0);
+                    PR_ASSERT(NULL != thread[index]);
+                }
+
+                PR_Lock(shared->ml);
+                while (shared->status == running)
+                    PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT);
+                PR_Unlock(shared->ml);
+                for (index = 0; index < threads; ++index)
+                {
+                    rv = PR_Interrupt(thread[index]);
+                    PR_ASSERT(PR_SUCCESS== rv);
+                    rv = PR_JoinThread(thread[index]);
+                    PR_ASSERT(PR_SUCCESS== rv);
+                }
+                PR_DELETE(thread);
+            }
+            else
+            {
+                if (shared->debug) PL_PrintError("Listen");
+                shared->passed = PR_FALSE;
+            }
+        }
+        else
+        {
+            if (shared->debug) PL_PrintError("Bind");
+            shared->passed = PR_FALSE;
+        }
+
+        PR_Close(shared->listenSock);
+    }
+    else
+    {
+        if (shared->debug) PL_PrintError("Create");
+        shared->passed = PR_FALSE;
+    }
+
+    PR_DestroyCondVar(shared->cv);
+    PR_DestroyLock(shared->ml);
+
+    PR_fprintf(
+        PR_GetSpecialFD(PR_StandardError), "%s\n",
+        ((shared->passed) ? "PASSED" : "FAILED"));
+
+    exitStatus = (shared->passed) ? 0 : 1;
+    PR_DELETE(shared);
+    return exitStatus;
+}
+
+int main(int argc, char **argv)
+{
+    return (PR_VersionCheck(PR_VERSION)) ?
+        PR_Initialize(Tmoacc, argc, argv, 4) : -1;
+}  /* main */
+
+/* tmoacc */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/tmocon.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/tmocon.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,401 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 
+ * 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.
+ */
+
+/***********************************************************************
+**
+** Name: tmocon.c
+**
+** Description: test client socket connection.
+**
+** 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. 
+***********************************************************************/
+
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "nspr.h"
+#include "pprio.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* for getcwd */
+#if defined(XP_UNIX) || defined (XP_OS2_EMX) || defined(XP_BEOS)
+#include <unistd.h>
+#elif defined(XP_PC)
+#include <direct.h>
+#endif
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#endif
+
+
+#define BASE_PORT 9867
+
+#define DEFAULT_DALLY 1
+#define DEFAULT_THREADS 1
+#define DEFAULT_TIMEOUT 10
+#define DEFAULT_MESSAGES 100
+#define DEFAULT_MESSAGESIZE 100
+
+static PRFileDesc *debug_out = NULL;
+
+typedef struct Shared
+{
+    PRBool random;
+    PRBool failed;
+    PRBool intermittant;
+    PRIntn debug;
+    PRInt32 messages;
+    PRIntervalTime dally;
+    PRIntervalTime timeout;
+    PRInt32 message_length;
+    PRNetAddr serverAddress;
+} Shared;
+
+static PRIntervalTime Timeout(const Shared *shared)
+{
+    PRIntervalTime timeout = shared->timeout;
+    if (shared->random)
+    {
+        PRIntervalTime quarter = timeout >> 2;  /* one quarter of the interval */
+        PRUint32 random = rand() % quarter;  /* something in[0..timeout / 4) */
+        timeout = (((3 * quarter) + random) >> 2) + quarter;  /* [75..125)% */
+    }
+    return timeout;
+}  /* Timeout */
+
+static void CauseTimeout(const Shared *shared)
+{
+    if (shared->intermittant) PR_Sleep(Timeout(shared));
+}  /* CauseTimeout */
+
+static PRStatus MakeReceiver(Shared *shared)
+{
+    PRStatus rv = PR_FAILURE;
+    if (PR_IsNetAddrType(&shared->serverAddress, PR_IpAddrLoopback))
+    {
+        char *argv[3];
+        char path[1024 + sizeof("/tmoacc")];
+        (void)getcwd(path, sizeof(path));
+        (void)strcat(path, "/tmoacc");
+#ifdef XP_PC
+        (void)strcat(path, ".exe");
+#endif
+        argv[0] = path;
+        if (shared->debug > 0)
+        {
+            argv[1] = "-d";
+            argv[2] = NULL;
+        }
+        else argv[1] = NULL;
+        if (shared->debug > 1)
+            PR_fprintf(debug_out, " creating accept process %s ...", path);
+        fflush(stdout);
+        rv = PR_CreateProcessDetached(path, argv, NULL, NULL);
+        if (PR_SUCCESS == rv)
+        {
+            if (shared->debug > 1)
+                PR_fprintf(debug_out, " wait 5 seconds");
+            if (shared->debug > 1)
+                PR_fprintf(debug_out, " before connecting to accept process ...");
+            fflush(stdout);
+            PR_Sleep(PR_SecondsToInterval(5));
+            return rv;
+        }
+        shared->failed = PR_TRUE;
+        if (shared->debug > 0)
+            PL_FPrintError(debug_out, "PR_CreateProcessDetached failed");
+    }
+    return rv;
+}  /* MakeReceiver */
+
+static void Connect(void *arg)
+{
+    PRStatus rv;
+    char *buffer = NULL;
+    PRFileDesc *clientSock;
+    Shared *shared = (Shared*)arg;
+    PRInt32 loop, bytes, flags = 0;
+    struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor;
+    debug_out = (0 == shared->debug) ? NULL : PR_GetSpecialFD(PR_StandardError);
+
+    buffer = (char*)PR_MALLOC(shared->message_length);
+
+    for (bytes = 0; bytes < shared->message_length; ++bytes)
+        buffer[bytes] = (char)bytes;
+
+    descriptor.checksum = 0;
+    for (bytes = 0; bytes < shared->message_length; ++bytes)
+    {
+        PRUint32 overflow = descriptor.checksum & 0x80000000;
+        descriptor.checksum = (descriptor.checksum << 1);
+        if (0x00000000 != overflow) descriptor.checksum += 1;
+        descriptor.checksum += buffer[bytes];
+    }
+    descriptor.checksum = PR_htonl(descriptor.checksum);
+
+    for (loop = 0; loop < shared->messages; ++loop)
+    {
+        if (shared->debug > 1)
+            PR_fprintf(debug_out, "[%d]socket ... ", loop);
+        clientSock = PR_NewTCPSocket();
+        if (clientSock)
+        {
+            /*
+             * We need to slow down the rate of generating connect requests,
+             * otherwise the listen backlog queue on the accept side may
+             * become full and we will get connection refused or timeout
+             * error.
+             */
+
+            PR_Sleep(shared->dally);
+            if (shared->debug > 1)
+            {
+                char buf[128];
+                PR_NetAddrToString(&shared->serverAddress, buf, sizeof(buf));
+                PR_fprintf(debug_out, "connecting to %s ... ", buf);
+            }
+            rv = PR_Connect(
+                clientSock, &shared->serverAddress, Timeout(shared));
+            if (PR_SUCCESS == rv)
+            {
+                PRInt32 descriptor_length = (loop < (shared->messages - 1)) ?
+                    shared->message_length : 0;
+                descriptor.length = PR_htonl(descriptor_length);
+                if (shared->debug > 1)
+                    PR_fprintf(
+                        debug_out, "sending %d bytes ... ", descriptor_length);
+                CauseTimeout(shared);  /* might cause server to timeout */
+                bytes = PR_Send(
+                    clientSock, &descriptor, sizeof(descriptor),
+                    flags, Timeout(shared));
+                if (bytes != sizeof(descriptor))
+                {
+                    shared->failed = PR_TRUE;
+                    if (shared->debug > 0)
+                        PL_FPrintError(debug_out, "PR_Send failed");
+                }
+                if (0 != descriptor_length)
+                {
+                    CauseTimeout(shared);
+                    bytes = PR_Send(
+                        clientSock, buffer, descriptor_length,
+                        flags, Timeout(shared));
+                    if (bytes != descriptor_length)
+                    {
+                        shared->failed = PR_TRUE;
+                        if (shared->debug > 0)
+                            PL_FPrintError(debug_out, "PR_Send failed");
+                    }
+                }
+                if (shared->debug > 1) PR_fprintf(debug_out, "closing ... ");
+                rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH);
+                rv = PR_Close(clientSock);
+                if (shared->debug > 1)
+                {
+                    if (PR_SUCCESS == rv) PR_fprintf(debug_out, "\n");
+                    else PL_FPrintError(debug_out, "shutdown failed");
+                }
+            }
+            else
+            {
+                if (shared->debug > 1) PL_FPrintError(debug_out, "connect failed");
+                PR_Close(clientSock);
+                if ((loop == 0) && (PR_GetError() == PR_CONNECT_REFUSED_ERROR))
+                {
+                    if (MakeReceiver(shared) == PR_FAILURE) break;
+                }
+                else
+                {
+                    if (shared->debug > 1) PR_fprintf(debug_out, " exiting\n");
+                    break;
+                }
+            }
+        }
+        else
+        {
+            shared->failed = PR_TRUE;
+            if (shared->debug > 0) PL_FPrintError(debug_out, "create socket");
+            break;
+        }
+    }
+
+    PR_DELETE(buffer);
+}  /* Connect */
+
+int Tmocon(int argc, char **argv)
+{
+    /*
+     * USAGE
+     * -d       turn on debugging output                (default = off)
+     * -v       turn on verbose output                  (default = off)
+     * -h <n>   dns name of host serving the connection (default = self)
+     * -i       dally intermittantly to cause timeouts  (default = off)
+     * -m <n>   number of messages to send              (default = 100)
+     * -s <n>   size of each message                    (default = 100)
+     * -t <n>   number of threads sending               (default = 1)
+     * -G       use global threads                      (default = local)
+     * -T <n>   timeout on I/O operations (seconds)     (default = 10)
+     * -D <n>   dally between connect requests (seconds)(default = 0)
+     * -R       randomize the dally types around 'T'    (default = no)
+     */
+
+    PRStatus rv;
+    int exitStatus;
+    PLOptStatus os;
+    Shared *shared = NULL;
+    PRThread **thread = NULL;
+    PRIntn index, threads = DEFAULT_THREADS;
+    PRThreadScope thread_scope = PR_LOCAL_THREAD;
+    PRInt32 dally = DEFAULT_DALLY, timeout = DEFAULT_TIMEOUT;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "divGRh:m:s:t:T:D:");
+
+    shared = PR_NEWZAP(Shared);
+
+    shared->debug = 0;
+    shared->failed = PR_FALSE;
+    shared->random = PR_FALSE;
+    shared->messages = DEFAULT_MESSAGES;
+    shared->message_length = DEFAULT_MESSAGESIZE;
+
+    PR_STDIO_INIT();
+    memset(&shared->serverAddress, 0, sizeof(shared->serverAddress));
+    rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &shared->serverAddress);
+    PR_ASSERT(PR_SUCCESS == rv);
+    
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':
+            if (0 == shared->debug) shared->debug = 1;
+            break;
+        case 'v':
+            if (0 == shared->debug) shared->debug = 2;
+            break;
+        case 'i':
+            shared->intermittant = PR_TRUE;
+            break;
+        case 'R':
+            shared->random = PR_TRUE;
+            break;
+        case 'G':
+            thread_scope = PR_GLOBAL_THREAD;
+            break;
+        case 'h':  /* the value for backlock */
+            {
+                PRIntn es = 0;
+                PRHostEnt host;
+                char buffer[1024];
+                (void)PR_GetHostByName(
+                    opt->value, buffer, sizeof(buffer), &host);
+                es = PR_EnumerateHostEnt(
+                    es, &host, BASE_PORT, &shared->serverAddress);
+                PR_ASSERT(es > 0);
+            }
+            break;
+        case 'm':  /* number of messages to send */
+            shared->messages = atoi(opt->value);
+            break;
+        case 't':  /* number of threads sending */
+            threads = atoi(opt->value);
+            break;
+        case 'D':  /* dally time between transmissions */
+            dally = atoi(opt->value);
+            break;
+        case 'T':  /* timeout on I/O operations */
+            timeout = atoi(opt->value);
+            break;
+        case 's':  /* total size of each message */
+            shared->message_length = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+        PL_DestroyOptState(opt);
+
+    if (0 == timeout) timeout = DEFAULT_TIMEOUT;
+    if (0 == threads) threads = DEFAULT_THREADS;
+    if (0 == shared->messages) shared->messages = DEFAULT_MESSAGES;
+    if (0 == shared->message_length) shared->message_length = DEFAULT_MESSAGESIZE;
+
+    shared->dally = PR_SecondsToInterval(dally);
+    shared->timeout = PR_SecondsToInterval(timeout);
+
+    thread = (PRThread**)PR_CALLOC(threads * sizeof(PRThread*));
+
+    for (index = 0; index < threads; ++index)
+        thread[index] = PR_CreateThread(
+            PR_USER_THREAD, Connect, shared,
+            PR_PRIORITY_NORMAL, thread_scope,
+            PR_JOINABLE_THREAD, 0);
+    for (index = 0; index < threads; ++index)
+        rv = PR_JoinThread(thread[index]);
+
+    PR_DELETE(thread);
+
+    PR_fprintf(
+        PR_GetSpecialFD(PR_StandardError), "%s\n",
+        ((shared->failed) ? "FAILED" : "PASSED"));
+    exitStatus = (shared->failed) ? 1 : 0;
+    PR_DELETE(shared);
+    return exitStatus;
+}
+
+int main(int argc, char **argv)
+{
+    return (PR_VersionCheck(PR_VERSION)) ?
+        PR_Initialize(Tmocon, argc, argv, 4) : -1;
+}  /* main */
+
+/* tmocon.c */
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/tpd.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/tpd.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,334 @@
+/* -*- 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:        tpd.c
+** Description: Exercising the thread private data bailywick.
+*/
+
+#include "prmem.h"
+#include "prinit.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "prthread.h"
+#include "prtypes.h"
+
+#if defined(XP_MAC)
+#include "pprio.h"
+#else
+#include "private/pprio.h"
+#endif
+
+#include "plgetopt.h"
+
+static PRUintn key[128];
+static PRIntn debug = 0;
+static PRBool failed = PR_FALSE;
+static PRBool should = PR_TRUE;
+static PRBool did = PR_TRUE;
+static PRFileDesc *fout = NULL;
+
+static void PrintProgress(PRIntn line)
+{
+    failed = failed || (should && !did);
+    failed = failed || (!should && did);
+    if (debug > 0)
+    {
+#if defined(WIN16)
+        printf(
+            "@ line %d destructor should%s have been called and was%s\n",
+            line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT"));
+#else    
+        PR_fprintf(
+            fout, "@ line %d destructor should%s have been called and was%s\n",
+            line, ((should) ? "" : " NOT"), ((did) ? "" : " NOT"));
+#endif
+    }
+}  /* PrintProgress */
+
+static void MyAssert(const char *expr, const char *file, PRIntn line)
+{
+    if (debug > 0)
+        (void)PR_fprintf(fout, "'%s' in file: %s: %d\n", expr, file, line);
+}  /* MyAssert */
+
+#define MY_ASSERT(_expr) \
+    ((_expr)?((void)0):MyAssert(# _expr,__FILE__,__LINE__))
+
+
+static void PR_CALLBACK Destructor(void *data)
+{
+    MY_ASSERT(NULL != data);
+    if (should) did = PR_TRUE;
+    else failed = PR_TRUE;
+    /*
+     * We don't actually free the storage since it's actually allocated
+     * on the stack. Normally, this would not be the case and this is
+     * the opportunity to free whatever.
+    PR_Free(data);
+     */
+}  /* Destructor */
+
+static void PR_CALLBACK Thread(void *null)
+{
+    void *pd;
+    PRStatus rv;
+    PRUintn keys;
+    char *key_string[] = {
+        "Key #0", "Key #1", "Key #2", "Key #3",
+        "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
+    
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 8; ++keys)
+    {
+        pd = PR_GetThreadPrivate(key[keys]);
+        MY_ASSERT(NULL == pd);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 4; keys < 8; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_FAILURE == rv);
+    }
+    PrintProgress(__LINE__);
+    
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], "EXTENSION");
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+
+    /* put in keys and leave them there for thread exit */
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+    did = PR_FALSE; should = PR_TRUE;
+
+}  /* Thread */
+
+static PRIntn PR_CALLBACK Tpd(PRIntn argc, char **argv)
+{
+    void *pd;
+    PRStatus rv;
+    PRUintn keys;
+    PRThread *thread;
+    char *key_string[] = {
+        "Key #0", "Key #1", "Key #2", "Key #3",
+        "Bogus #5", "Bogus #6", "Bogus #7", "Bogus #8"};
+    
+    fout = PR_STDOUT;
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_NewThreadPrivateIndex(&key[keys], Destructor);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 8; ++keys)
+    {
+        pd = PR_GetThreadPrivate(key[keys]);
+        MY_ASSERT(NULL == pd);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    for (keys = 4; keys < 8; ++keys)
+		key[keys] = 4096;		/* set to invalid value */
+    did = should = PR_FALSE;
+    for (keys = 4; keys < 8; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_FAILURE == rv);
+    }
+    PrintProgress(__LINE__);
+    
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], key_string[keys]);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 0; keys < 4; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_NewThreadPrivateIndex(&key[keys], Destructor);
+        MY_ASSERT(PR_SUCCESS == rv);
+        rv = PR_SetThreadPrivate(key[keys], "EXTENSION");
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = PR_FALSE; should = PR_TRUE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+    PrintProgress(__LINE__);
+
+    did = should = PR_FALSE;
+    for (keys = 8; keys < 127; ++keys)
+    {
+        rv = PR_SetThreadPrivate(key[keys], NULL);
+        MY_ASSERT(PR_SUCCESS == rv);
+    }
+
+    thread = PR_CreateThread(
+        PR_USER_THREAD, Thread, NULL, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    (void)PR_JoinThread(thread);
+
+    PrintProgress(__LINE__);
+
+#if defined(WIN16)
+    printf(
+        "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
+#else
+    (void)PR_fprintf(
+        fout, "%s\n",((PR_TRUE == failed) ? "FAILED" : "PASSED"));
+#endif    
+
+    return 0;
+
+}  /* Tpd */
+
+PRIntn main(PRIntn argc, char *argv[])
+{
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dl:r:");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+    PR_STDIO_INIT();
+    return PR_Initialize(Tpd, argc, argv, 0);
+}  /* main */
+
+/* tpd.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/udpsrv.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/udpsrv.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,566 @@
+/* -*- 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 ***** */
+
+/*******************************************************************
+** udpsrc.c -- Test basic function of UDP server
+**
+** udpsrv operates on the same machine with program udpclt.
+** udpsrv is the server side of a udp sockets application.
+** udpclt is the client side of a udp sockets application.
+**
+** The test is designed to assist developers in porting/debugging
+** the UDP socket functions of NSPR.
+**
+** This test is not a stress test.
+**
+** main() starts two threads: UDP_Server() and UDP_Client();
+** main() uses PR_JoinThread() to wait for the threads to complete.
+**
+** UDP_Server() does repeated recvfrom()s from a socket.
+** He detects an EOF condition set by UDP_Client(). For each
+** packet received by UDP_Server(), he checks its content for
+** expected content, then sends the packet back to UDP_Client().
+** 
+** UDP_Client() sends packets to UDP_Server() using sendto()
+** he recieves packets back from the server via recvfrom().
+** After he sends enough packets containing UDP_AMOUNT_TO_WRITE
+** bytes of data, he sends an EOF message.
+** 
+** The test issues a pass/fail message at end.
+** 
+** Notes:
+** The variable "_debug_on" can be set to 1 to cause diagnostic
+** messages related to client/server synchronization. Useful when
+** the test hangs.
+** 
+** Error messages are written to stdout.
+** 
+********************************************************************
+*/
+/* --- include files --- */
+#include "nspr.h"
+#include "prpriv.h"
+
+#include "plgetopt.h"
+#include "prttools.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef XP_PC
+#define mode_t int
+#endif
+
+#define UDP_BUF_SIZE            4096
+#define UDP_DGRAM_SIZE          128
+#define UDP_AMOUNT_TO_WRITE     (PRInt32)((UDP_DGRAM_SIZE * 1000l) +1)
+#define NUM_UDP_CLIENTS         1
+#define NUM_UDP_DATAGRAMS_PER_CLIENT    5
+#define UDP_SERVER_PORT         9050
+#define UDP_CLIENT_PORT         9053
+#define MY_INADDR               PR_INADDR_ANY
+#define PEER_INADDR             PR_INADDR_LOOPBACK
+
+#define UDP_TIMEOUT             400000
+/* #define UDP_TIMEOUT             PR_INTERVAL_NO_TIMEOUT */
+
+/* --- static data --- */
+static PRIntn _debug_on      = 0;
+static PRBool passed         = PR_TRUE;
+static PRUint32 cltBytesRead = 0;
+static PRUint32 srvBytesRead = 0;
+static PRFileDesc *output    = NULL;
+
+/* --- static function declarations --- */
+#define DPRINTF(arg) if (_debug_on) PR_fprintf(output, arg)
+
+
+
+/*******************************************************************
+** ListNetAddr() -- Display the Net Address on stdout
+**
+** Description: displays the component parts of a PRNetAddr struct
+**
+** Arguments:   address of PRNetAddr structure to display
+**
+** Returns: void
+**
+** Notes:
+**
+********************************************************************
+*/
+void ListNetAddr( char *msg, PRNetAddr *na )
+{
+    char    mbuf[256];
+    
+    sprintf( mbuf, "ListNetAddr: %s family: %d, port: %d, ip: %8.8X\n",
+            msg, na->inet.family, PR_ntohs( na->inet.port), PR_ntohl(na->inet.ip) );
+#if 0            
+    DPRINTF( mbuf );            
+#endif
+} /* --- end ListNetAddr() --- */
+
+/********************************************************************
+** UDP_Server() -- Test a UDP server application
+**
+** Description: The Server side of a UDP Client/Server application.
+**
+** Arguments: none
+**
+** Returns: void
+**
+** Notes:
+**
+**
+********************************************************************
+*/
+static void PR_CALLBACK UDP_Server( void *arg )
+{
+    static char     svrBuf[UDP_BUF_SIZE];
+    PRFileDesc      *svrSock;
+    PRInt32         rv;
+    PRNetAddr       netaddr;
+    PRBool          bound = PR_FALSE;
+    PRBool          endOfInput = PR_FALSE;
+    PRInt32         numBytes = UDP_DGRAM_SIZE;
+    
+    DPRINTF("udpsrv: UDP_Server(): starting\n" );
+
+    /* --- Create the socket --- */
+    DPRINTF("udpsrv: UDP_Server(): Creating UDP Socket\n" );
+    svrSock = PR_NewUDPSocket();
+    if ( svrSock == NULL )
+    {
+        passed = PR_FALSE;
+        if (debug_mode)
+            PR_fprintf(output,
+                "udpsrv: UDP_Server(): PR_NewUDPSocket() returned NULL\n" );
+        return;
+    }
+    
+    /* --- Initialize the sockaddr_in structure --- */
+    memset( &netaddr, 0, sizeof( netaddr )); 
+    netaddr.inet.family = PR_AF_INET;
+    netaddr.inet.port   = PR_htons( UDP_SERVER_PORT );
+    netaddr.inet.ip     = PR_htonl( MY_INADDR );
+    
+    /* --- Bind the socket --- */
+    while ( !bound )
+    {
+        DPRINTF("udpsrv: UDP_Server(): Binding socket\n" );
+        rv = PR_Bind( svrSock, &netaddr );
+        if ( rv < 0 )
+        {
+            if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR )
+            {
+                if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \
+						PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n");
+                PR_Sleep( PR_MillisecondsToInterval( 2000 ));
+                continue;
+            }
+            else
+            {
+                passed = PR_FALSE;
+                if (debug_mode) PR_fprintf(output, "udpsrv: UDP_Server(): \
+						PR_Bind(): failed: %ld with error: %ld\n",
+                        rv, PR_GetError() );
+                PR_Close( svrSock );
+                return;
+            }
+        }
+        else
+            bound = PR_TRUE;
+    }
+    ListNetAddr( "UDP_Server: after bind", &netaddr );
+    
+    /* --- Recv the socket --- */
+    while( !endOfInput )
+    {
+        DPRINTF("udpsrv: UDP_Server(): RecvFrom() socket\n" );
+        rv = PR_RecvFrom( svrSock, svrBuf, numBytes, 0, &netaddr, UDP_TIMEOUT );
+        if ( rv == -1 )
+        {
+            passed = PR_FALSE;
+            if (debug_mode)
+                PR_fprintf(output,
+                    "udpsrv: UDP_Server(): PR_RecvFrom(): failed with error: %ld\n",
+                    PR_GetError() );
+            PR_Close( svrSock );
+            return;
+        }
+        ListNetAddr( "UDP_Server after RecvFrom", &netaddr );
+        
+        srvBytesRead += rv;
+        
+        if ( svrBuf[0] == 'E' )
+        {
+            DPRINTF("udpsrv: UDP_Server(): EOF on input detected\n" );
+            endOfInput = PR_TRUE;
+        }
+            
+        /* --- Send the socket --- */
+        DPRINTF("udpsrv: UDP_Server(): SendTo(): socket\n" );
+        rv = PR_SendTo( svrSock, svrBuf, rv, 0, &netaddr, PR_INTERVAL_NO_TIMEOUT );
+        if ( rv == -1 )
+        {
+            passed = PR_FALSE;
+            if (debug_mode)
+                PR_fprintf(output,
+                    "udpsrv: UDP_Server(): PR_SendTo(): failed with error: %ld\n",
+                    PR_GetError() );
+            PR_Close( svrSock );
+            return;
+        }
+        ListNetAddr( "UDP_Server after SendTo", &netaddr );
+    }
+    
+    /* --- Close the socket --- */
+    DPRINTF("udpsrv: UDP_Server(): Closing socket\n" );
+    rv = PR_Close( svrSock );
+    if ( rv != PR_SUCCESS )
+    {
+        passed = PR_FALSE;
+        if (debug_mode)
+            PR_fprintf(output,
+                "udpsrv: UDP_Server(): PR_Close(): failed to close socket\n" );
+        return;
+    }
+    
+    DPRINTF("udpsrv: UDP_Server(): Normal end\n" );
+} /* --- end UDP_Server() --- */
+
+
+static char         cltBuf[UDP_BUF_SIZE];
+static char         cltBufin[UDP_BUF_SIZE];
+/********************************************************************
+** UDP_Client() -- Test a UDP client application
+**
+** Description:
+**
+** Arguments:
+**
+**
+** Returns:
+** 0 -- Successful execution
+** 1 -- Test failed.
+**
+** Notes:
+**
+**
+********************************************************************
+*/
+static void PR_CALLBACK UDP_Client( void *arg )
+{
+    PRFileDesc   *cltSock;
+    PRInt32      rv;
+    PRBool       bound = PR_FALSE;
+    PRNetAddr    netaddr;
+    PRNetAddr    netaddrx;
+    PRBool       endOfInput = PR_FALSE;
+    PRInt32      numBytes = UDP_DGRAM_SIZE;
+    PRInt32      writeThisMany = UDP_AMOUNT_TO_WRITE;
+    int          i;
+    
+    
+    DPRINTF("udpsrv: UDP_Client(): starting\n" );
+    
+    /* --- Create the socket --- */
+    cltSock = PR_NewUDPSocket();
+    if ( cltSock == NULL )
+    {
+        passed = PR_FALSE;
+        if (debug_mode)
+            PR_fprintf(output,
+                "udpsrv: UDP_Client(): PR_NewUDPSocket() returned NULL\n" );
+        return;
+    }
+    
+    /* --- Initialize the sockaddr_in structure --- */
+    memset( &netaddr, 0, sizeof( netaddr )); 
+    netaddr.inet.family = PR_AF_INET;
+    netaddr.inet.ip     = PR_htonl( MY_INADDR );
+    netaddr.inet.port   = PR_htons( UDP_CLIENT_PORT );
+    
+    /* --- Initialize the write buffer --- */    
+    for ( i = 0; i < UDP_BUF_SIZE ; i++ )
+        cltBuf[i] = i;
+    
+    /* --- Bind the socket --- */
+    while ( !bound )
+    {
+        DPRINTF("udpsrv: UDP_Client(): Binding socket\n" );
+        rv = PR_Bind( cltSock, &netaddr );
+        if ( rv < 0 )
+        {
+            if ( PR_GetError() == PR_ADDRESS_IN_USE_ERROR )
+            {
+                if (debug_mode)
+                    PR_fprintf(output,
+                        "udpsrv: UDP_Client(): PR_Bind(): reports: PR_ADDRESS_IN_USE_ERROR\n");
+                PR_Sleep( PR_MillisecondsToInterval( 2000 ));
+                continue;
+            }
+            else
+            {
+                passed = PR_FALSE;
+                if (debug_mode)
+                    PR_fprintf(output,
+                        "udpsrv: UDP_Client(): PR_Bind(): failed: %ld with error: %ld\n",
+                        rv, PR_GetError() );
+                PR_Close( cltSock );
+                return;
+            }
+        }
+        else
+            bound = PR_TRUE;
+    }
+    ListNetAddr( "UDP_Client after Bind", &netaddr );
+    
+    /* --- Initialize the sockaddr_in structure --- */
+    memset( &netaddr, 0, sizeof( netaddr )); 
+    netaddr.inet.family = PR_AF_INET;
+    netaddr.inet.ip     = PR_htonl( PEER_INADDR );
+    netaddr.inet.port   = PR_htons( UDP_SERVER_PORT );
+    
+    /* --- send and receive packets until no more data left */    
+    while( !endOfInput )
+    {
+        /*
+        ** Signal EOF in the data stream on the last packet
+        */        
+        if ( writeThisMany <= UDP_DGRAM_SIZE )
+        {
+            DPRINTF("udpsrv: UDP_Client(): Send EOF packet\n" );
+            cltBuf[0] = 'E';
+            endOfInput = PR_TRUE;
+        }
+        
+        /* --- SendTo the socket --- */
+        if ( writeThisMany > UDP_DGRAM_SIZE )
+            numBytes = UDP_DGRAM_SIZE;
+        else
+            numBytes = writeThisMany;
+        writeThisMany -= numBytes;
+        {
+            char   mbuf[256];
+            sprintf( mbuf, "udpsrv: UDP_Client(): write_this_many: %d, numbytes: %d\n", 
+                writeThisMany, numBytes );
+            DPRINTF( mbuf );
+        }
+        
+        DPRINTF("udpsrv: UDP_Client(): SendTo(): socket\n" );
+        rv = PR_SendTo( cltSock, cltBuf, numBytes, 0, &netaddr, UDP_TIMEOUT );
+        if ( rv == -1 )
+        {
+            passed = PR_FALSE;
+            if (debug_mode)
+                PR_fprintf(output,
+                    "udpsrv: UDP_Client(): PR_SendTo(): failed with error: %ld\n",
+                        PR_GetError() );
+            PR_Close( cltSock );
+            return;
+        }
+        ListNetAddr( "UDP_Client after SendTo", &netaddr );
+
+        /* --- RecvFrom the socket --- */
+        memset( cltBufin, 0, UDP_BUF_SIZE );
+        DPRINTF("udpsrv: UDP_Client(): RecvFrom(): socket\n" );
+        rv = PR_RecvFrom( cltSock, cltBufin, numBytes, 0, &netaddrx, UDP_TIMEOUT );
+        if ( rv == -1 )
+        {
+            passed = PR_FALSE;
+            if (debug_mode) PR_fprintf(output,
+                "udpsrv: UDP_Client(): PR_RecvFrom(): failed with error: %ld\n",
+                   PR_GetError() );
+            PR_Close( cltSock );
+            return;
+        }
+        ListNetAddr( "UDP_Client after RecvFrom()", &netaddr );
+        cltBytesRead += rv;
+        
+        /* --- verify buffer --- */
+        for ( i = 0; i < rv ; i++ )
+        {
+            if ( cltBufin[i] != i )
+            {
+                /* --- special case, end of input --- */
+                if ( endOfInput && i == 0 && cltBufin[0] == 'E' )
+                    continue;
+                passed = PR_FALSE;
+                if (debug_mode) PR_fprintf(output,
+                    "udpsrv: UDP_Client(): return data mismatch\n" );
+                PR_Close( cltSock );
+                return;
+            }
+        }
+        if (debug_mode) PR_fprintf(output, ".");
+    }
+    
+    /* --- Close the socket --- */
+    DPRINTF("udpsrv: UDP_Server(): Closing socket\n" );
+    rv = PR_Close( cltSock );
+    if ( rv != PR_SUCCESS )
+    {
+        passed = PR_FALSE;
+        if (debug_mode) PR_fprintf(output,
+            "udpsrv: UDP_Client(): PR_Close(): failed to close socket\n" );
+        return;
+    }
+    DPRINTF("udpsrv: UDP_Client(): ending\n" );
+} /* --- end UDP_Client() --- */
+
+/********************************************************************
+** main() -- udpsrv
+**
+** arguments:
+**
+** Returns:
+** 0 -- Successful execution
+** 1 -- Test failed.
+**
+** Description:
+**
+** Standard test case setup.
+**
+** Calls the function UDP_Server()
+**
+********************************************************************
+*/
+
+int main(int argc, char **argv)
+{
+    PRThread    *srv, *clt;
+/* 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 -v
+	*/
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dv");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = 1;
+            break;
+        case 'v':  /* verbose mode */
+			_debug_on = 1;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+		
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    PR_STDIO_INIT();
+    output = PR_STDERR;
+
+#ifdef XP_MAC
+    SetupMacPrintfLog("udpsrv.log");
+#endif
+
+    PR_SetConcurrency(4);
+    
+    /*
+    ** Create the Server thread
+    */    
+    DPRINTF( "udpsrv: Creating Server Thread\n" );
+    srv =  PR_CreateThread( PR_USER_THREAD,
+            UDP_Server,
+            (void *) 0,
+            PR_PRIORITY_LOW,
+            PR_LOCAL_THREAD,
+            PR_JOINABLE_THREAD,
+            0 );
+    if ( srv == NULL )
+    {
+        if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" );
+        passed = PR_FALSE;
+    }
+    
+    /*
+    ** Give the Server time to Start
+    */    
+    DPRINTF( "udpsrv: Pausing to allow Server to start\n" );
+    PR_Sleep( PR_MillisecondsToInterval(200) );
+    
+    /*
+    ** Create the Client thread
+    */    
+    DPRINTF( "udpsrv: Creating Client Thread\n" );
+    clt = PR_CreateThread( PR_USER_THREAD,
+            UDP_Client,
+            (void *) 0,
+            PR_PRIORITY_LOW,
+            PR_LOCAL_THREAD,
+            PR_JOINABLE_THREAD,
+            0 );
+    if ( clt == NULL )
+    {
+        if (debug_mode) PR_fprintf(output, "udpsrv: Cannot create server thread\n" );
+        passed = PR_FALSE;
+    }
+    
+    /*
+    **
+    */
+    DPRINTF("udpsrv: Waiting to join Server & Client Threads\n" );
+    PR_JoinThread( srv );
+    PR_JoinThread( clt );    
+    
+    /*
+    ** Evaluate test results
+    */
+    if (debug_mode) PR_fprintf(output, "\n\nudpsrv: main(): cltBytesRead(%ld), \
+		srvBytesRead(%ld), expected(%ld)\n",
+         cltBytesRead, srvBytesRead, UDP_AMOUNT_TO_WRITE );
+    if ( cltBytesRead != srvBytesRead || cltBytesRead != UDP_AMOUNT_TO_WRITE )
+    {
+        passed = PR_FALSE;
+    }
+    PR_Cleanup();
+    if ( passed )
+        return 0;
+    else
+		return 1;
+} /* --- end main() --- */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/ut_ttools.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/ut_ttools.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,43 @@
+/* -*- 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 ***** */
+
+/* Used in Regress Tool */
+#define NOSTATUS 2
+#define PASS 1
+#define FAIL 0
+
+PRIntn debug_mode=0;

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/vercheck.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/vercheck.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,109 @@
+/* -*- 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 ***** */
+
+/*
+ * File: vercheck.c
+ *
+ * Description:
+ * This test tests the PR_VersionCheck() function.  The
+ * compatible_version and incompatible_version arrays
+ * need to be updated for each patch or release.
+ *
+ * Tested areas: library version compatibility check.
+ */
+
+#include "prinit.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * This release (4.7) is backward compatible with the
+ * 4.0.x, 4.1.x, 4.2.x, 4.3.x, 4.4.x, 4.5.x, and 4.6.x releases.
+ * It, of course, is compatible with itself.
+ */
+static char *compatible_version[] = {
+    "4.0", "4.0.1", "4.1", "4.1.1", "4.1.2", "4.1.3",
+    "4.2", "4.2.1", "4.2.2", "4.3", "4.4", "4.4.1",
+    "4.5", "4.5.1", "4.6", "4.6.1", PR_VERSION
+};
+
+/*
+ * This release is not backward compatible with the old
+ * NSPR 2.1 and 3.x releases.
+ *
+ * Any release is incompatible with future releases and
+ * patches.
+ */
+static char *incompatible_version[] = {
+    "2.1 19980529",
+    "3.0", "3.0.1",
+    "3.1", "3.1.1", "3.1.2", "3.1.3",
+    "3.5", "3.5.1",
+    "4.7.3",
+    "4.8", "4.8.1",
+    "10.0", "11.1", "12.14.20"
+};
+
+int main()
+{
+    int idx;
+    int num_compatible = sizeof(compatible_version) / sizeof(char *);
+    int num_incompatible = sizeof(incompatible_version) / sizeof(char *);
+
+    printf("NSPR release %s:\n", PR_VERSION);
+    for (idx = 0; idx < num_compatible; idx++) {
+        if (PR_VersionCheck(compatible_version[idx]) == PR_FALSE) {
+            fprintf(stderr, "Should be compatible with version %s\n",
+                    compatible_version[idx]);
+            exit(1);
+        }
+        printf("Compatible with version %s\n", compatible_version[idx]);
+    }
+
+    for (idx = 0; idx < num_incompatible; idx++) {
+        if (PR_VersionCheck(incompatible_version[idx]) == PR_TRUE) {
+            fprintf(stderr, "Should be incompatible with version %s\n",
+                    incompatible_version[idx]);
+            exit(1);
+        }
+        printf("Incompatible with version %s\n", incompatible_version[idx]);
+    }
+
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/version.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/version.c	Mon Dec 18 10:53:47 2006
@@ -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 "prio.h"
+#include "prprf.h"
+#include "prlink.h"
+#include "prvrsion.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+PR_IMPORT(const PRVersionDescription *) libVersionPoint(void);
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRIntn rv = 1;
+    PLOptStatus os;
+    PRIntn verbosity = 0;
+    PRLibrary *runtime = NULL;
+    const char *library_name = NULL;
+    const PRVersionDescription *version_info;
+	char buffer[100];
+	PRExplodedTime exploded;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "d");
+
+    PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 0:  /* fully qualified library name */
+            library_name = opt->value;
+            break;
+        case 'd':  /* verbodity */
+            verbosity += 1;
+            break;
+         default:
+            PR_fprintf(err, "Usage: version [-d] {fully qualified library name}\n");
+            return 2;  /* but not a lot else */
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (NULL != library_name)
+    {
+        runtime = PR_LoadLibrary(library_name);
+        if (NULL == runtime) {
+			PL_FPrintError(err, "PR_LoadLibrary");
+			return 3;
+		} else {
+            versionEntryPointType versionPoint = (versionEntryPointType)
+                PR_FindSymbol(runtime, "libVersionPoint");
+            if (NULL == versionPoint) {
+				PL_FPrintError(err, "PR_FindSymbol");
+				return 4;
+			}	
+			version_info = versionPoint();
+		}
+	} else
+		version_info = libVersionPoint();	/* NSPR's version info */
+
+	(void)PR_fprintf(err, "Runtime library version information\n");
+	PR_ExplodeTime(
+		version_info->buildTime, PR_GMTParameters, &exploded);
+	(void)PR_FormatTime(
+		buffer, sizeof(buffer), "%d %b %Y %H:%M:%S", &exploded);
+	(void)PR_fprintf(err, "  Build time: %s GMT\n", buffer);
+	(void)PR_fprintf(
+		err, "  Build time: %s\n", version_info->buildTimeString);
+	(void)PR_fprintf(
+		err, "  %s V%u.%u.%u (%s%s%s)\n",
+		version_info->description,
+		version_info->vMajor,
+		version_info->vMinor,
+		version_info->vPatch,
+		(version_info->beta ? " beta " : ""),
+		(version_info->debug ? " debug " : ""),
+		(version_info->special ? " special" : ""));
+	(void)PR_fprintf(err, "  filename: %s\n", version_info->filename);
+	(void)PR_fprintf(err, "  security: %s\n", version_info->security);
+	(void)PR_fprintf(err, "  copyright: %s\n", version_info->copyright);
+	(void)PR_fprintf(err, "  comment: %s\n", version_info->comment);
+	rv = 0;
+    return rv;
+}
+
+/* version.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,12 @@
+/.cvsignore/1.2/Sat May 12 05:09:00 2001//
+/Makefile.in/1.10/Sun Apr 25 15:01:03 2004//
+/popfile.c/3.5/Sun Apr 25 15:01:03 2004//
+/popfind.c/3.5/Sun Apr 25 15:01:03 2004//
+/popfont.c/3.5/Sun Apr 25 15:01:03 2004//
+/poppad.c/3.5/Sun Apr 25 15:01:03 2004//
+/poppad.h/3.5/Sun Apr 25 15:01:03 2004//
+/poppad.ico/3.1/Sat Mar 28 03:38:30 1998/-kb/
+/poppad.rc/3.6/Sun Apr 25 15:01:03 2004//
+/popprnt0.c/3.5/Sun Apr 25 15:01:03 2004//
+/readme.1st/3.1/Sat Mar 28 03:38:32 1998//
+D

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/pr/tests/w16gui

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,99 @@
+# 
+# ***** 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
+
+W16STDIO = $(MOD_DEPTH)/pr/src/md/windows/$(OBJDIR)/w16stdio.$(OBJ_SUFFIX)
+
+CSRCS = poppad.c \
+       popfile.c \
+       popfont.c \
+       popfind.c \
+       popprnt0.c
+          
+
+INCLUDES = -I$(dist_includedir) 
+LIBPR = $(dist_libdir)/nspr$(MOD_MAJOR_VERSION).lib
+LIBPLDS = $(dist_libdir)/plds$(MOD_MAJOR_VERSION).lib
+TARGETS = $(OBJDIR)/poppad.exe
+OS_CFLAGS = $(OS_EXE_CFLAGS)
+
+include $(topsrcdir)/config/rules.mk
+
+
+ifeq ($(OS_TARGET),WIN16)    
+$(OBJDIR)/poppad.exe: $(OBJS)
+	@$(MAKE_OBJDIR)
+	echo system windows >w16link
+	echo name $@  >>w16link
+	echo option map >>w16link
+	echo option stack=16K >>w16link
+	echo debug $(DEBUGTYPE) all >>w16link
+	echo file >>w16link
+	echo $(OBJDIR)\\poppad.$(OBJ_SUFFIX), >>w16link
+	echo $(OBJDIR)\\popfile.$(OBJ_SUFFIX), >>w16link
+	echo $(OBJDIR)\\popfont.$(OBJ_SUFFIX), >>w16link
+	echo $(OBJDIR)\\popfind.$(OBJ_SUFFIX), >>w16link
+	echo $(OBJDIR)\\popprnt0.$(OBJ_SUFFIX), >>w16link
+	echo $(W16STDIO) >>w16link
+	echo library $(LIBPR)      >>w16link
+	echo library $(LIBPLDS)	   >>w16link
+	echo library clibl, commdlg >>w16link
+	echo library winsock.lib   >>w16link
+	wlink @w16link.
+	wrc -bt=windows poppad.rc $(OBJDIR)\\poppad.exe
+else    
+$(OBJDIR)/poppad.exe: $(OBJS)
+	link $(LDOPTS) $< $(LIBPLC) $(LIBPR) wsock32.lib -out:$@
+endif
+
+export:: $(TARGETS)
+
+
+clean::
+	rm -rf $(TARGETS)

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popfile.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popfile.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,167 @@
+/* -*- 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 ***** */
+
+/*------------------------------------------
+   POPFILE.C -- Popup Editor File Functions
+   (c) Charles Petzold, 1992
+  ------------------------------------------*/
+
+#include <windows.h>
+#include <commdlg.h>
+#include <stdlib.h>
+
+static OPENFILENAME ofn ;
+
+void PopFileInitialize (HWND hwnd)
+     {
+     static char *szFilter[] = { "Text Files (*.TXT)",  "*.txt",
+                                 "ASCII Files (*.ASC)", "*.asc",
+                                 "All Files (*.*)",     "*.*",
+                                 "" } ;
+
+     ofn.lStructSize       = sizeof (OPENFILENAME) ;
+     ofn.hwndOwner         = hwnd ;
+     ofn.hInstance         = NULL ;
+     ofn.lpstrFilter       = szFilter [0] ;
+     ofn.lpstrCustomFilter = NULL ;
+     ofn.nMaxCustFilter    = 0 ;
+     ofn.nFilterIndex      = 0 ;
+     ofn.lpstrFile         = NULL ;          // Set in Open and Close functions
+     ofn.nMaxFile          = _MAX_PATH ;
+     ofn.lpstrFileTitle    = NULL ;          // Set in Open and Close functions
+     ofn.nMaxFileTitle     = _MAX_FNAME + _MAX_EXT ;
+     ofn.lpstrInitialDir   = NULL ;
+     ofn.lpstrTitle        = NULL ;
+     ofn.Flags             = 0 ;             // Set in Open and Close functions
+     ofn.nFileOffset       = 0 ;
+     ofn.nFileExtension    = 0 ;
+     ofn.lpstrDefExt       = "txt" ;
+     ofn.lCustData         = 0L ;
+     ofn.lpfnHook          = NULL ;
+     ofn.lpTemplateName    = NULL ;
+     }
+
+BOOL PopFileOpenDlg (HWND hwnd, LPSTR lpstrFileName, LPSTR lpstrTitleName)
+     {
+     ofn.hwndOwner         = hwnd ;
+     ofn.lpstrFile         = lpstrFileName ;
+     ofn.lpstrFileTitle    = lpstrTitleName ;
+     ofn.Flags             = OFN_CREATEPROMPT ;
+
+     return GetOpenFileName (&ofn) ;
+     }
+
+BOOL PopFileSaveDlg (HWND hwnd, LPSTR lpstrFileName, LPSTR lpstrTitleName)
+     {
+     ofn.hwndOwner         = hwnd ;
+     ofn.lpstrFile         = lpstrFileName ;
+     ofn.lpstrFileTitle    = lpstrTitleName ;
+     ofn.Flags             = OFN_OVERWRITEPROMPT ;
+
+     return GetSaveFileName (&ofn) ;
+     }
+
+static long PopFileLength (int hFile)
+     {
+     long lCurrentPos = _llseek (hFile, 0L, 1) ;
+     long lFileLength = _llseek (hFile, 0L, 2) ;
+     
+     _llseek (hFile, lCurrentPos, 0) ;
+
+     return lFileLength ;
+     }
+
+BOOL PopFileRead (HWND hwndEdit, LPSTR lpstrFileName)
+     {
+     long   lLength ;
+     HANDLE hBuffer ;
+     int    hFile ;
+     LPSTR  lpstrBuffer ;
+
+     if (-1 == (hFile = _lopen (lpstrFileName, OF_READ | OF_SHARE_DENY_WRITE)))
+          return FALSE ;
+
+     if ((lLength = PopFileLength (hFile)) >= 32000)
+          {
+          _lclose (hFile) ;
+          return FALSE ;
+          }
+
+     if (NULL == (hBuffer = GlobalAlloc (GHND, lLength + 1)))
+          {
+          _lclose (hFile) ;
+          return FALSE ;
+          }
+
+     lpstrBuffer = GlobalLock (hBuffer) ;
+     _lread (hFile, lpstrBuffer, (WORD) lLength) ;
+     _lclose (hFile) ;
+     lpstrBuffer [(WORD) lLength] = '\0' ;
+
+     SetWindowText (hwndEdit, lpstrBuffer) ;
+     GlobalUnlock (hBuffer) ;
+     GlobalFree (hBuffer) ;
+
+     return TRUE ;
+     }
+
+BOOL PopFileWrite (HWND hwndEdit, LPSTR lpstrFileName)
+     {
+     HANDLE hBuffer ;
+     int    hFile ;
+     LPSTR  lpstrBuffer ;
+     WORD   wLength ;
+
+     if (-1 == (hFile = _lopen (lpstrFileName, OF_WRITE | OF_SHARE_EXCLUSIVE)))
+          if (-1 == (hFile = _lcreat (lpstrFileName, 0)))
+               return FALSE ;
+
+     wLength = GetWindowTextLength (hwndEdit) ;
+     hBuffer = (HANDLE) SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L) ;
+     lpstrBuffer = (LPSTR) LocalLock (hBuffer) ;
+
+     if (wLength != _lwrite (hFile, lpstrBuffer, wLength))
+          {
+          _lclose (hFile) ;
+          return FALSE ;
+          }
+
+     _lclose (hFile) ;
+     LocalUnlock (hBuffer) ;
+
+     return TRUE ;
+     }

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popfind.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popfind.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,149 @@
+/* -*- 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 ***** */
+
+/*--------------------------------------------------------
+   POPFIND.C -- Popup Editor Search and Replace Functions
+   (c) Charles Petzold, 1992
+  --------------------------------------------------------*/
+
+#include <windows.h>
+#include <commdlg.h>
+#include <string.h>
+#define MAX_STRING_LEN   256
+
+static char szFindText [MAX_STRING_LEN] ;
+static char szReplText [MAX_STRING_LEN] ;
+
+HWND PopFindFindDlg (HWND hwnd)
+     {
+     static FINDREPLACE fr ;       // must be static for modeless dialog!!!
+
+     fr.lStructSize      = sizeof (FINDREPLACE) ;
+     fr.hwndOwner        = hwnd ;
+     fr.hInstance        = NULL ;
+     fr.Flags            = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD ;
+     fr.lpstrFindWhat    = szFindText ;
+     fr.lpstrReplaceWith = NULL ;
+     fr.wFindWhatLen     = sizeof (szFindText) ;
+     fr.wReplaceWithLen  = 0 ;
+     fr.lCustData        = 0 ;
+     fr.lpfnHook         = NULL ;
+     fr.lpTemplateName   = NULL ;
+
+     return FindText (&fr) ;
+     }
+
+HWND PopFindReplaceDlg (HWND hwnd)
+     {
+     static FINDREPLACE fr ;       // must be static for modeless dialog!!!
+
+     fr.lStructSize      = sizeof (FINDREPLACE) ;
+     fr.hwndOwner        = hwnd ;
+     fr.hInstance        = NULL ;
+     fr.Flags            = FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD ;
+     fr.lpstrFindWhat    = szFindText ;
+     fr.lpstrReplaceWith = szReplText ;
+     fr.wFindWhatLen     = sizeof (szFindText) ;
+     fr.wReplaceWithLen  = sizeof (szReplText) ;
+     fr.lCustData        = 0 ;
+     fr.lpfnHook         = NULL ;
+     fr.lpTemplateName   = NULL ;
+
+     return ReplaceText (&fr) ;
+     }
+
+BOOL PopFindFindText (HWND hwndEdit, int *piSearchOffset, LPFINDREPLACE lpfr)
+     {
+     int         iPos ;
+     LOCALHANDLE hLocal ;
+     LPSTR       lpstrDoc, lpstrPos ;
+
+               // Get a pointer to the edit document
+
+     hLocal   = (HWND) SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L) ;
+     lpstrDoc = (LPSTR) LocalLock (hLocal) ;
+
+               // Search the document for the find string
+
+     lpstrPos = _fstrstr (lpstrDoc + *piSearchOffset, lpfr->lpstrFindWhat) ;
+     LocalUnlock (hLocal) ;
+
+               // Return an error code if the string cannot be found
+
+     if (lpstrPos == NULL)
+          return FALSE ;
+
+               // Find the position in the document and the new start offset
+
+     iPos = lpstrPos - lpstrDoc ;
+     *piSearchOffset = iPos + _fstrlen (lpfr->lpstrFindWhat) ;
+
+               // Select the found text
+
+     SendMessage (hwndEdit, EM_SETSEL, 0,
+                  MAKELONG (iPos, *piSearchOffset)) ;
+
+     return TRUE ;
+     }
+
+BOOL PopFindNextText (HWND hwndEdit, int *piSearchOffset)
+     {
+     FINDREPLACE fr ;
+
+     fr.lpstrFindWhat = szFindText ;
+
+     return PopFindFindText (hwndEdit, piSearchOffset, &fr) ;
+     }
+
+BOOL PopFindReplaceText (HWND hwndEdit, int *piSearchOffset, LPFINDREPLACE lpfr)
+     {
+               // Find the text
+
+     if (!PopFindFindText (hwndEdit, piSearchOffset, lpfr))
+          return FALSE ;
+
+               // Replace it
+
+     SendMessage (hwndEdit, EM_REPLACESEL, 0, (long) lpfr->lpstrReplaceWith) ;
+
+     return TRUE ;
+     }
+
+BOOL PopFindValidFind (void)
+     {
+     return *szFindText != '\0' ;
+     }

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popfont.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popfont.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,94 @@
+/* -*- 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 ***** */
+
+/*------------------------------------------
+   POPFONT.C -- Popup Editor Font Functions
+   (c) Charles Petzold, 1992
+  ------------------------------------------*/
+
+#include <windows.h>
+#include <commdlg.h>
+
+static LOGFONT logfont ;
+static HFONT   hFont ;
+
+BOOL PopFontChooseFont (HWND hwnd)
+     {
+     CHOOSEFONT cf ;
+
+     cf.lStructSize      = sizeof (CHOOSEFONT) ;
+     cf.hwndOwner        = hwnd ;
+     cf.hDC              = NULL ;
+     cf.lpLogFont        = &logfont ;
+     cf.iPointSize       = 0 ;
+     cf.Flags            = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS
+                                                  | CF_EFFECTS ;
+     cf.rgbColors        = 0L ;
+     cf.lCustData        = 0L ;
+     cf.lpfnHook         = NULL ;
+     cf.lpTemplateName   = NULL ;
+     cf.hInstance        = NULL ;
+     cf.lpszStyle        = NULL ;
+     cf.nFontType        = 0 ;               // Returned from ChooseFont
+     cf.nSizeMin         = 0 ;
+     cf.nSizeMax         = 0 ;
+
+     return ChooseFont (&cf) ;
+     }
+
+void PopFontInitialize (HWND hwndEdit)
+     {
+     GetObject (GetStockObject (SYSTEM_FONT), sizeof (LOGFONT),
+                                              (LPSTR) &logfont) ;
+     hFont = CreateFontIndirect (&logfont) ;
+     SendMessage (hwndEdit, WM_SETFONT, hFont, 0L) ;
+     }
+
+void PopFontSetFont (HWND hwndEdit)
+     {
+     HFONT hFontNew ;
+
+     hFontNew = CreateFontIndirect (&logfont) ;
+     SendMessage (hwndEdit, WM_SETFONT, hFontNew, 0L) ;
+     DeleteObject (hFont) ;
+     hFont = hFontNew ;
+     }
+
+void PopFontDeinitialize (void)
+     {
+     DeleteObject (hFont) ;
+     }

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/poppad.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/poppad.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,672 @@
+/* -*- 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 ***** */
+
+/*---------------------------------------
+   POPPAD.C -- Popup Editor
+   (c) Charles Petzold, 1992
+  ---------------------------------------*/
+
+#include "nspr.h"
+#include "plevent.h"
+#include <windows.h>
+#include <commdlg.h>
+#include <stdlib.h>
+#include "poppad.h"
+#include <time.h>
+
+#define EDITID   1
+#define UNTITLED "(untitled)"
+
+long FAR PASCAL _export WndProc      (HWND, UINT, UINT, LONG) ;
+BOOL FAR PASCAL _export AboutDlgProc (HWND, UINT, UINT, LONG) ;
+
+/* 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 int  quitSwitch = 0;
+static long ThreadSleepTime = 1000;
+static long timerCount = 0;
+static char *startMessage = "Poppad: NSPR GUI and event test program.\n"
+                            "You should see lines of 50 characters\n"
+                            "with a new character appearing at 1 second intervals.\n"
+                            "Every 10 seconds gets a '+'; every 5 seconds gets a '_';\n"
+                            "every 1 second gets a '.'.\n\n"
+                            "You should be able to type in the window.\n\n\n";
+
+
+          // Functions in POPFILE.C
+
+void PopFileInitialize (HWND) ;
+BOOL PopFileOpenDlg    (HWND, LPSTR, LPSTR) ;
+BOOL PopFileSaveDlg    (HWND, LPSTR, LPSTR) ;
+BOOL PopFileRead       (HWND, LPSTR) ;
+BOOL PopFileWrite      (HWND, LPSTR) ;
+
+          // Functions in POPFIND.C
+
+HWND PopFindFindDlg     (HWND) ;
+HWND PopFindReplaceDlg  (HWND) ;
+BOOL PopFindFindText    (HWND, int *, LPFINDREPLACE) ;
+BOOL PopFindReplaceText (HWND, int *, LPFINDREPLACE) ;
+BOOL PopFindNextText    (HWND, int *) ;
+BOOL PopFindValidFind   (void) ;
+
+          // Functions in POPFONT.C
+
+void PopFontInitialize   (HWND) ;
+BOOL PopFontChooseFont   (HWND) ;
+void PopFontSetFont      (HWND) ;
+void PopFontDeinitialize (void) ;
+
+          // Functions in POPPRNT.C
+
+BOOL PopPrntPrintFile (HANDLE, HWND, HWND, LPSTR) ;
+
+          // Global variables
+
+static char szAppName [] = "PopPad" ;
+static HWND hDlgModeless ;
+static HWND hwndEdit ;
+
+int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
+                    LPSTR lpszCmdLine, int nCmdShow)
+    {
+    MSG      msg;
+    HWND     hwnd ;
+    HANDLE   hAccel ;
+    WNDCLASS wndclass ;
+
+    PR_STDIO_INIT();
+    PR_Init(0, 0, 0);
+          
+    if (!hPrevInstance) 
+          {
+          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
+          wndclass.lpfnWndProc   = WndProc ;
+          wndclass.cbClsExtra    = 0 ;
+          wndclass.cbWndExtra    = 0 ;
+          wndclass.hInstance     = hInstance ;
+          wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
+          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
+          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
+          wndclass.lpszMenuName  = szAppName ;
+          wndclass.lpszClassName = szAppName ;
+
+          RegisterClass (&wndclass) ;
+          }
+
+     hwnd = CreateWindow (szAppName, NULL,
+                          WS_OVERLAPPEDWINDOW,
+                          CW_USEDEFAULT, CW_USEDEFAULT,
+                          CW_USEDEFAULT, CW_USEDEFAULT,
+                          NULL, NULL, hInstance, lpszCmdLine) ;
+
+     ShowWindow (hwnd, nCmdShow) ;
+     UpdateWindow (hwnd); 
+
+     hAccel = LoadAccelerators (hInstance, szAppName) ;
+     
+     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 ;
+     }
+
+void DoCaption (HWND hwnd, char *szTitleName)
+     {
+     char szCaption [64 + _MAX_FNAME + _MAX_EXT] ;
+
+     wsprintf (szCaption, "%s - %s", (LPSTR) szAppName,
+               (LPSTR) (szTitleName [0] ? szTitleName : UNTITLED)) ;
+
+     SetWindowText (hwnd, szCaption) ;
+     }
+
+void OkMessage (HWND hwnd, char *szMessage, char *szTitleName)
+     {
+     char szBuffer [64 + _MAX_FNAME + _MAX_EXT] ;
+
+     wsprintf (szBuffer, szMessage,
+               (LPSTR) (szTitleName [0] ? szTitleName : UNTITLED)) ;
+
+     MessageBox (hwnd, szBuffer, szAppName, MB_OK | MB_ICONEXCLAMATION) ;
+     }
+
+short AskAboutSave (HWND hwnd, char *szTitleName)
+     {
+     char  szBuffer [64 + _MAX_FNAME + _MAX_EXT] ;
+     short nReturn ;
+
+     wsprintf (szBuffer, "Save current changes in %s?",
+               (LPSTR) (szTitleName [0] ? szTitleName : UNTITLED)) ;
+
+     nReturn = MessageBox (hwnd, szBuffer, szAppName,
+                           MB_YESNOCANCEL | MB_ICONQUESTION) ;
+
+     if (nReturn == IDYES)
+          if (!SendMessage (hwnd, WM_COMMAND, IDM_SAVE, 0L))
+               nReturn = IDCANCEL ;
+
+     return nReturn ;
+     }
+
+long FAR PASCAL _export WndProc (HWND hwnd, UINT message, UINT wParam,
+                                                          LONG lParam)
+     {
+     static BOOL    bNeedSave = FALSE ;
+     static char    szFileName  [_MAX_PATH] ;
+     static char    szTitleName [_MAX_FNAME + _MAX_EXT] ;
+     static FARPROC lpfnAboutDlgProc ;
+     static HANDLE  hInst ;
+     static int     iOffset ;
+     static UINT    messageFindReplace ;
+     LONG           lSelect ;
+     LPFINDREPLACE  lpfr ;
+     WORD           wEnable ;
+
+     switch (message)
+          {
+          case WM_CREATE:
+                         // Get About dialog instance address
+
+               hInst = ((LPCREATESTRUCT) lParam)->hInstance ;
+               lpfnAboutDlgProc = MakeProcInstance ((FARPROC) AboutDlgProc,
+                                                    hInst) ;
+
+                         // Create the edit control child window
+
+               hwndEdit = CreateWindow ("edit", NULL,
+                         WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
+                              WS_BORDER | ES_LEFT | ES_MULTILINE |
+                              ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
+                         0, 0, 0, 0,
+                         hwnd, EDITID, hInst, NULL) ;
+
+               SendMessage (hwndEdit, EM_LIMITTEXT, 32000, 0L) ;
+
+                         // Initialize common dialog box stuff
+
+               PopFileInitialize (hwnd) ;
+               PopFontInitialize (hwndEdit) ;
+
+               messageFindReplace = RegisterWindowMessage (FINDMSGSTRING) ;
+
+                         // Process command line
+
+               lstrcpy (szFileName, (LPSTR)
+                        (((LPCREATESTRUCT) lParam)->lpCreateParams)) ;
+
+               if (lstrlen (szFileName) > 0)
+                    {
+                    GetFileTitle (szFileName, szTitleName,
+                                  sizeof (szTitleName)) ;
+
+                    if (!PopFileRead (hwndEdit, szFileName))
+                         OkMessage (hwnd, "File %s cannot be read!",
+                                          szTitleName) ;
+                    }
+
+               DoCaption (hwnd, szTitleName) ;
+
+               /* Initialize Event Processing for NSPR
+               ** Retrieve the event queue just created
+               ** Create the TimerThread
+               */               
+               PL_InitializeEventsLib("someName");
+               padQueue = PL_GetMainEventQueue();
+               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_INITMENUPOPUP:
+               switch (lParam)
+                    {
+                    case 1:        // Edit menu
+
+                              // Enable Undo if edit control can do it
+
+                         EnableMenuItem (wParam, IDM_UNDO,
+                              SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?
+                                   MF_ENABLED : MF_GRAYED) ;
+
+                              // Enable Paste if text is in the clipboard
+
+                         EnableMenuItem (wParam, IDM_PASTE,
+                              IsClipboardFormatAvailable (CF_TEXT) ?
+                                   MF_ENABLED : MF_GRAYED) ;
+
+                              // Enable Cut, Copy, and Del if text is selected
+
+                         lSelect = SendMessage (hwndEdit, EM_GETSEL, 0, 0L) ;
+                         wEnable = HIWORD (lSelect) != LOWORD (lSelect) ?
+                                        MF_ENABLED : MF_GRAYED ;
+
+                         EnableMenuItem (wParam, IDM_CUT,  wEnable) ;
+                         EnableMenuItem (wParam, IDM_COPY, wEnable) ;
+                         EnableMenuItem (wParam, IDM_DEL,  wEnable) ;
+                         break ;
+
+                    case 2:        // Search menu
+
+                              // Enable Find, Next, and Replace if modeless
+                              //   dialogs are not already active
+
+                         wEnable = hDlgModeless == NULL ?
+                                        MF_ENABLED : MF_GRAYED ;
+
+                         EnableMenuItem (wParam, IDM_FIND,    wEnable) ;
+                         EnableMenuItem (wParam, IDM_NEXT,    wEnable) ;
+                         EnableMenuItem (wParam, IDM_REPLACE, wEnable) ;
+                         break ;
+                    }
+               return 0 ;
+
+          case WM_COMMAND :
+                              // Messages from edit control
+
+               if (LOWORD (lParam) && wParam == EDITID)
+                    {
+                    switch (HIWORD (lParam))
+                         {
+                         case EN_UPDATE:
+                              bNeedSave = TRUE ;
+                              return 0 ;
+
+                         case EN_ERRSPACE:
+                         case EN_MAXTEXT:
+                              MessageBox (hwnd, "Edit control out of space.",
+                                        szAppName, MB_OK | MB_ICONSTOP) ;
+                              return 0 ;
+                         }
+                    break ;
+                    }
+
+               switch (wParam)
+                    {
+                              // Messages from File menu
+
+                    case IDM_NEW:
+                         if (bNeedSave && IDCANCEL ==
+                                   AskAboutSave (hwnd, szTitleName))
+                              return 0 ;
+
+                         SetWindowText (hwndEdit, "\0") ;
+                         szFileName [0]  = '\0' ;
+                         szTitleName [0] = '\0' ;
+                         DoCaption (hwnd, szTitleName) ;
+                         bNeedSave = FALSE ;
+                         return 0 ;
+
+                    case IDM_OPEN:
+                         if (bNeedSave && IDCANCEL ==
+                                   AskAboutSave (hwnd, szTitleName))
+                              return 0 ;
+
+                         if (PopFileOpenDlg (hwnd, szFileName, szTitleName))
+                              {
+                              if (!PopFileRead (hwndEdit, szFileName))
+                                   {
+                                   OkMessage (hwnd, "Could not read file %s!",
+                                                    szTitleName) ;
+                                   szFileName  [0] = '\0' ;
+                                   szTitleName [0] = '\0' ;
+                                   }
+                              }
+
+                         DoCaption (hwnd, szTitleName) ;
+                         bNeedSave = FALSE ;
+                         return 0 ;
+
+                    case IDM_SAVE:
+                         if (szFileName [0])
+                              {
+                              if (PopFileWrite (hwndEdit, szFileName))
+                                   {
+                                   bNeedSave = FALSE ;
+                                   return 1 ;
+                                   }
+                              else
+                                   OkMessage (hwnd, "Could not write file %s",
+                                                    szTitleName) ;
+                              return 0 ;
+                              }
+                                                  // fall through
+                    case IDM_SAVEAS:
+                         if (PopFileSaveDlg (hwnd, szFileName, szTitleName))
+                              {
+                              DoCaption (hwnd, szTitleName) ;
+
+                              if (PopFileWrite (hwndEdit, szFileName))
+                                   {
+                                   bNeedSave = FALSE ;
+                                   return 1 ;
+                                   }
+                              else
+                                   OkMessage (hwnd, "Could not write file %s",
+                                                    szTitleName) ;
+                              }
+                         return 0 ;
+
+                    case IDM_PRINT:
+                         if (!PopPrntPrintFile (hInst, hwnd, hwndEdit,
+                                                szTitleName))
+                              OkMessage (hwnd, "Could not print file %s",
+                                         szTitleName) ;
+                         return 0 ;
+
+                    case IDM_EXIT:
+                         SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
+                         return 0 ;
+
+                              // Messages from Edit menu
+
+                    case IDM_UNDO:
+                         SendMessage (hwndEdit, WM_UNDO, 0, 0L) ;
+                         return 0 ;
+
+                    case IDM_CUT:
+                         SendMessage (hwndEdit, WM_CUT, 0, 0L) ;
+                         return 0 ;
+
+                    case IDM_COPY:
+                         SendMessage (hwndEdit, WM_COPY, 0, 0L) ;
+                         return 0 ;
+
+                    case IDM_PASTE:
+                         SendMessage (hwndEdit, WM_PASTE, 0, 0L) ;
+                         return 0 ;
+
+                    case IDM_DEL:
+                         SendMessage (hwndEdit, WM_CLEAR, 0, 0L) ;
+                         return 0 ;
+
+                    case IDM_SELALL:
+                         SendMessage (hwndEdit, EM_SETSEL, 0,
+                                        MAKELONG (0, 32767)) ;
+                         return 0 ;
+
+                              // Messages from Search menu
+
+                    case IDM_FIND:
+                         iOffset = HIWORD (
+                              SendMessage (hwndEdit, EM_GETSEL, 0, 0L)) ;
+                         hDlgModeless = PopFindFindDlg (hwnd) ;
+                         return 0 ;
+
+                    case IDM_NEXT:
+                         iOffset = HIWORD (
+                              SendMessage (hwndEdit, EM_GETSEL, 0, 0L)) ;
+
+                         if (PopFindValidFind ())
+                              PopFindNextText (hwndEdit, &iOffset) ;
+                         else
+                              hDlgModeless = PopFindFindDlg (hwnd) ;
+
+                         return 0 ;
+
+                    case IDM_REPLACE:
+                         iOffset = HIWORD (
+                              SendMessage (hwndEdit, EM_GETSEL, 0, 0L)) ;
+
+                         hDlgModeless = PopFindReplaceDlg (hwnd) ;
+                         return 0 ;
+
+                    case IDM_FONT:
+                         if (PopFontChooseFont (hwnd))
+                              PopFontSetFont (hwndEdit) ;
+
+                         return 0 ;
+
+                              // Messages from Help menu
+
+                    case IDM_HELP:
+                         OkMessage (hwnd, "Help not yet implemented!", NULL) ;
+                         return 0 ;
+
+                    case IDM_ABOUT:
+                         DialogBox (hInst, "AboutBox", hwnd, lpfnAboutDlgProc);
+                         return 0 ;
+                    }
+               break ;
+
+          case WM_CLOSE:
+               if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName))
+                    DestroyWindow (hwnd) ;
+
+               return 0 ;
+
+          case WM_QUERYENDSESSION:
+               if (!bNeedSave || IDCANCEL != AskAboutSave (hwnd, szTitleName))
+                    return 1L ;
+
+               return 0 ;
+
+          case WM_DESTROY:
+               PopFontDeinitialize () ;
+               PostQuitMessage (0) ;
+               quitSwitch = 1;
+               return 0 ;
+
+          default:
+                         // Process "Find-Replace" messages
+
+               if (message == messageFindReplace)
+                    {
+                    lpfr = (LPFINDREPLACE) lParam ;
+
+                    if (lpfr->Flags & FR_DIALOGTERM)
+                         hDlgModeless = NULL ;
+
+                    if (lpfr->Flags & FR_FINDNEXT)
+                         if (!PopFindFindText (hwndEdit, &iOffset, lpfr))
+                              OkMessage (hwnd, "Text not found!", NULL) ;
+
+                    if (lpfr->Flags & FR_REPLACE ||
+                        lpfr->Flags & FR_REPLACEALL)
+                         if (!PopFindReplaceText (hwndEdit, &iOffset, lpfr))
+                              OkMessage (hwnd, "Text not found!", NULL) ;
+
+                    if (lpfr->Flags & FR_REPLACEALL)
+                         while (PopFindReplaceText (hwndEdit, &iOffset, lpfr));
+
+                    return 0 ;
+                    }
+               break ;
+          }
+     return DefWindowProc (hwnd, message, wParam, lParam) ;
+     }
+
+BOOL FAR PASCAL _export AboutDlgProc (HWND hDlg, UINT message, UINT wParam,
+                                                               LONG lParam)
+     {
+     switch (message)
+          {
+          case WM_INITDIALOG:
+               return TRUE ;
+
+          case WM_COMMAND:
+               switch (wParam)
+                    {
+                    case IDOK:
+                         EndDialog (hDlg, 0) ;
+                         return TRUE ;
+                    }
+               break ;
+          }
+     return FALSE ;
+     }
+/*
+** TimerThread() -- The Main function of the timer pop thread
+**
+*/
+static void PR_CALLBACK TimerThread( void *arg)
+{
+    do {
+        PadEvent   *ev;
+        
+        /*
+        ** Should we quit now?
+        */
+        if ( quitSwitch )
+            break;
+        /*
+        ** 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( ThreadSleepTime );
+    } while(1);
+    return;
+}    
+
+/*
+** HandlePadEvent() -- gets called because of PostEvent
+*/
+static void PR_CALLBACK HandlePadEvent( PadEvent *padEvent )
+{
+    if ( timerCount++ == 0 )
+    {
+        char *cp;
+        
+        for ( cp = startMessage; *cp != 0 ; cp++ )
+        {
+            SendMessage( hwndEdit, WM_CHAR, *cp, MAKELONG( *cp, 1 ));
+        }
+    }
+    /* 
+    ** Send a WM_CHAR event the edit Window
+    */
+    if ((timerCount % 10) == 0)
+    {
+        SendMessage( hwndEdit, WM_CHAR, '+', MAKELONG( '+', 1 ));
+    }
+    else if ((timerCount % 5) == 0)
+    {
+        SendMessage( hwndEdit, WM_CHAR, '_', MAKELONG( '_', 1 ));
+    }
+    else
+    {
+        SendMessage( hwndEdit, WM_CHAR, '.', MAKELONG( '.', 1 ));
+    }
+    
+    if ( (timerCount % 50) == 0)
+    {
+        SendMessage( hwndEdit, WM_CHAR, '\n', MAKELONG( '\n', 1 ));
+    }
+
+    /*
+    ** PL_RevokeEvents() is broken. Test to fix it.
+    */
+    {
+        static long revokeCounter = 0;
+
+        if (revokeCounter++ > 10 )
+        {
+            PR_Sleep( ThreadSleepTime * 10 );
+            SendMessage( hwndEdit, WM_CHAR, '*', MAKELONG( '\n', 1 ));
+            PL_RevokeEvents( padQueue, NULL );
+            revokeCounter = 0;
+        }
+    }
+    return;
+}
+
+/*
+** DestroyPadEvent() -- Called after HandlePadEvent()
+*/
+static void PR_CALLBACK DestroyPadEvent( PadEvent *padevent )
+{
+   PR_Free( padevent );
+   return;
+}    

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/poppad.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/poppad.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,66 @@
+/* -*- 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 ***** */
+ 
+/*----------------------
+   POPPAD.H header file
+   (c) Charles Petzold, 1992
+  ----------------------*/
+
+#define IDM_NEW          10
+#define IDM_OPEN         11
+#define IDM_SAVE         12
+#define IDM_SAVEAS       13
+#define IDM_PRINT        14
+#define IDM_EXIT         15
+
+#define IDM_UNDO         20
+#define IDM_CUT          21
+#define IDM_COPY         22
+#define IDM_PASTE        23
+#define IDM_DEL          24
+#define IDM_SELALL       25
+
+#define IDM_FIND         30
+#define IDM_NEXT         31
+#define IDM_REPLACE      32
+
+#define IDM_FONT         40
+
+#define IDM_HELP         50
+#define IDM_ABOUT        51
+
+#define IDD_FNAME        10

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/poppad.ico
==============================================================================
Binary file. No diff available.

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/poppad.rc
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/poppad.rc	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,121 @@
+/* -*- 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 ***** */
+
+/*---------------------------
+   POPPAD.RC resource script
+  ---------------------------*/
+
+#include <windows.h>
+#include "poppad.h"
+
+PopPad ICON "poppad.ico"
+
+PopPad MENU
+     {
+     POPUP "&File"
+          {
+          MENUITEM "&New",              IDM_NEW
+          MENUITEM "&Open...",          IDM_OPEN
+          MENUITEM "&Save",             IDM_SAVE
+          MENUITEM "Save &As...",       IDM_SAVEAS
+          MENUITEM SEPARATOR
+          MENUITEM "&Print...",         IDM_PRINT
+          MENUITEM SEPARATOR
+          MENUITEM "E&xit",             IDM_EXIT
+          }
+     POPUP "&Edit"
+          {
+          MENUITEM "&Undo\tCtrl+Z",     IDM_UNDO
+          MENUITEM SEPARATOR
+          MENUITEM "Cu&t\tCtrl+X",      IDM_CUT
+          MENUITEM "&Copy\tCtrl+C",     IDM_COPY
+          MENUITEM "&Paste\tCtrl+V",    IDM_PASTE
+          MENUITEM "De&lete\tDel",      IDM_DEL
+          MENUITEM SEPARATOR
+          MENUITEM "&Select All",       IDM_SELALL
+          }
+     POPUP "&Search"
+          {
+          MENUITEM "&Find...",          IDM_FIND
+          MENUITEM "Find &Next\tF3",    IDM_NEXT
+          MENUITEM "&Replace...",       IDM_REPLACE
+          }
+     POPUP "&Character"
+          {
+          MENUITEM "&Font...",          IDM_FONT
+          }
+     POPUP "&Help"
+          {
+          MENUITEM "&Help",             IDM_HELP
+          MENUITEM "&About PopPad...",  IDM_ABOUT
+          }
+     }
+
+PopPad ACCELERATORS
+     {
+     "^Z",      IDM_UNDO
+     VK_BACK,   IDM_UNDO,  VIRTKEY, ALT
+     "^X",      IDM_CUT
+     VK_DELETE, IDM_CUT,   VIRTKEY, SHIFT
+     "^C",      IDM_COPY
+     VK_INSERT, IDM_COPY,  VIRTKEY, CONTROL
+     "^V",      IDM_PASTE
+     VK_INSERT, IDM_PASTE, VIRTKEY, SHIFT
+     VK_DELETE, IDM_DEL,   VIRTKEY
+     VK_F3,     IDM_NEXT,  VIRTKEY
+     VK_F1,     IDM_HELP,  VIRTKEY
+     }
+
+AboutBox DIALOG  20, 20, 160, 80
+     STYLE WS_POPUP | WS_DLGFRAME
+     {
+     CTEXT "PopPad"                              -1,   0, 12, 160,  8
+     ICON  "PopPad"                              -1,   8,  8,   0,  0
+     CTEXT "Popup Editor for Microsoft Windows"  -1,   0, 36, 160,  8
+     CTEXT "Copyright (c) Charles Petzold, 1992" -1,   0, 48, 160,  8
+     DEFPUSHBUTTON "OK"                        IDOK,  64, 60,  32, 14, WS_GROUP
+     } 
+
+PrintDlgBox DIALOG 20, 20, 100, 76
+     STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
+     CAPTION "PopPad"
+     {
+     CTEXT "Sending",                  -1,  0, 10, 100,  8
+     CTEXT "",                  IDD_FNAME,  0, 20, 100,  8
+     CTEXT "to print spooler.",        -1,  0, 30, 100,  8
+     DEFPUSHBUTTON  "Cancel",    IDCANCEL, 34, 50,  32, 14, WS_GROUP
+     }

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popprnt0.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/popprnt0.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,49 @@
+/* -*- 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 ***** */
+
+/*---------------------------------------------------------------
+   POPPRNT0.C -- Popup Editor Printing Functions (dummy version)
+   (c) Charles Petzold, 1992
+  ---------------------------------------------------------------*/
+
+#include <windows.h>
+
+BOOL PopPrntPrintFile (HANDLE hInst, HWND hwnd, HWND hwndEdit,
+                                     LPSTR lpstrTitleName)
+     {
+     return FALSE ;
+     }

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/readme.1st
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/w16gui/readme.1st	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,37 @@
+readme.1st.
+
+The files in the pr/tests/w16gui 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.
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/writev.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/writev.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,234 @@
+/* -*- 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 "nspr.h"
+
+#include "plgetopt.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#define printf PR_LogPrint
+#endif
+
+
+#ifndef IOV_MAX
+#define IOV_MAX 16
+#endif
+
+#define BASE_PORT 9867
+
+int PR_CALLBACK Writev(int argc, char **argv)
+{
+
+    PRStatus rv;
+    PRNetAddr serverAddr;
+    PRFileDesc *clientSock, *debug = NULL;
+
+    char *buffer = NULL;
+    PRIOVec *iov = NULL;
+    PRBool passed = PR_TRUE;
+    PRIntervalTime timein, elapsed, timeout;
+    PRIntervalTime tmo_min = 0x7fffffff, tmo_max = 0, tmo_elapsed = 0;
+    PRInt32 tmo_counted = 0, iov_index, loop, bytes, number_fragments;
+    PRInt32 message_length = 100, fragment_length = 100, messages = 100;
+    struct Descriptor { PRInt32 length; PRUint32 checksum; } descriptor;
+
+    /*
+     * USAGE
+     * -h       dns name of host serving the connection (default = self)
+     * -m       number of messages to send              (default = 100)
+     * -s       size of each message                    (default = 100)
+     * -f       size of each message fragment           (default = 100)
+     */
+
+	PLOptStatus os;
+	PLOptState *opt = PL_CreateOptState(argc, argv, "dh:m:s:f:");
+
+    PR_STDIO_INIT();
+    rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &serverAddr);
+    PR_ASSERT(PR_SUCCESS == rv);
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'h':  /* the remote host */
+            {
+                PRIntn es = 0;
+                PRHostEnt host;
+                char buffer[1024];
+                (void)PR_GetHostByName(opt->value, buffer, sizeof(buffer), &host);
+                es = PR_EnumerateHostEnt(es, &host, BASE_PORT, &serverAddr);
+                PR_ASSERT(es > 0);
+            }
+            break;
+        case 'd':  /* debug mode */
+            debug = PR_GetSpecialFD(PR_StandardError);
+            break;
+        case 'm':  /* number of messages to send */
+            messages = atoi(opt->value);
+            break;
+        case 's':  /* total size of each message */
+            message_length = atoi(opt->value);
+            break;
+        case 'f':  /* size of each message fragment */
+            fragment_length = atoi(opt->value);
+            break;
+        default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    buffer = (char*)malloc(message_length);
+
+    number_fragments = (message_length + fragment_length - 1) / fragment_length + 1;
+    while (IOV_MAX < number_fragments)
+    {
+        fragment_length = message_length / (IOV_MAX - 2);
+        number_fragments = (message_length + fragment_length - 1) /
+            fragment_length + 1;
+        if (NULL != debug) PR_fprintf(debug, 
+            "Too many fragments - reset fragment length to %ld\n", fragment_length);
+    }
+    iov = (PRIOVec*)malloc(number_fragments * sizeof(PRIOVec));
+
+    iov[0].iov_base = (char*)&descriptor;
+    iov[0].iov_len = sizeof(descriptor);
+    for (iov_index = 1; iov_index < number_fragments; ++iov_index)
+    {
+        iov[iov_index].iov_base = buffer + (iov_index - 1) * fragment_length;
+        iov[iov_index].iov_len = fragment_length;
+    }
+
+    for (bytes = 0; bytes < message_length; ++bytes)
+        buffer[bytes] = (char)bytes;
+
+    timeout = PR_SecondsToInterval(1);
+
+    for (loop = 0; loop < messages; ++loop)
+    {
+        if (NULL != debug)
+            PR_fprintf(debug, "[%d]socket ... ", loop);
+        clientSock = PR_NewTCPSocket();
+        if (clientSock)
+        {
+            timein = PR_IntervalNow();
+            if (NULL != debug)
+                PR_fprintf(debug, "connecting ... ");
+            rv = PR_Connect(clientSock, &serverAddr, timeout);
+            if (PR_SUCCESS == rv)
+            {
+                descriptor.checksum = 0;
+                descriptor.length = (loop < (messages - 1)) ? message_length : 0;
+                if (0 == descriptor.length) number_fragments = 1;
+                else
+                    for (iov_index = 0; iov_index < descriptor.length; ++iov_index)
+                    {
+                        PRUint32 overflow = descriptor.checksum & 0x80000000;
+                        descriptor.checksum = (descriptor.checksum << 1);
+                        if (0x00000000 != overflow) descriptor.checksum += 1;
+                        descriptor.checksum += buffer[iov_index];
+                    }
+                if (NULL != debug) PR_fprintf(
+                    debug, "sending %d bytes ... ", descriptor.length);
+
+                /* then, at the last moment ... */
+                descriptor.length = PR_ntohl(descriptor.length);
+                descriptor.checksum = PR_ntohl(descriptor.checksum);
+
+                bytes = PR_Writev(clientSock, iov, number_fragments, timeout);
+                if (NULL != debug)
+                    PR_fprintf(debug, "closing ... ");
+                rv = PR_Shutdown(clientSock, PR_SHUTDOWN_BOTH);
+                rv = PR_Close(clientSock);
+                if (NULL != debug) PR_fprintf(
+                    debug, "%s\n", ((PR_SUCCESS == rv) ? "good" : "bad"));
+                elapsed = PR_IntervalNow() - timein;
+                if (elapsed < tmo_min) tmo_min = elapsed;
+                else if (elapsed > tmo_max) tmo_max = elapsed;
+                tmo_elapsed += elapsed;
+                tmo_counted += 1;
+            }
+            else
+            {
+                if (NULL != debug) PR_fprintf(
+                    debug, "failed - retrying (%d, %d)\n",
+                    PR_GetError(), PR_GetOSError());
+                PR_Close(clientSock);
+            }
+        }
+        else if (NULL != debug)
+        {
+            PR_fprintf(debug, "unable to create client socket\n");
+            passed = PR_FALSE;
+        }
+    }
+    if (NULL != debug) {
+        if (0 == tmo_counted) {
+            PR_fprintf(debug, "No connection made\n");
+        } else {
+        PR_fprintf(
+            debug, "\nTimings: %d [%d] %d (microseconds)\n",
+            PR_IntervalToMicroseconds(tmo_min),
+            PR_IntervalToMicroseconds(tmo_elapsed / tmo_counted),
+            PR_IntervalToMicroseconds(tmo_max));
+	}
+    }
+
+    PR_DELETE(buffer);
+    PR_DELETE(iov);
+
+    PR_fprintf(
+        PR_GetSpecialFD(PR_StandardError),
+        "%s\n", (passed) ? "PASSED" : "FAILED");
+    return (passed) ? 0 : 1;
+}
+
+int main(int argc, char **argv)
+{
+    return (PR_VersionCheck(PR_VERSION)) ?
+        PR_Initialize(Writev, argc, argv, 4) : -1;
+}  /* main */
+
+/* writev.c */
+
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/xnotify.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/xnotify.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,389 @@
+/* -*- 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 "plerror.h"
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prprf.h"
+#include "prio.h"
+#include "prcvar.h"
+#include "prmon.h"
+#include "prcmon.h"
+#include "prlock.h"
+#include "prerror.h"
+#include "prinit.h"
+#include "prinrval.h"
+#include "prthread.h"
+
+static PRLock *ml = NULL;
+static PRIntervalTime base;
+static PRFileDesc *err = NULL;
+
+typedef struct CMonShared
+{
+    PRInt32 o1, o2;
+} CMonShared;
+
+typedef struct MonShared
+{
+    PRMonitor *o1, *o2;
+} MonShared;
+
+typedef struct LockShared
+{
+    PRLock *o1, *o2;
+    PRCondVar *cv1, *cv2;
+} LockShared;
+
+static void LogNow(const char *msg, PRStatus rv)
+{
+    PRIntervalTime now = PR_IntervalNow();
+    PR_Lock(ml);
+    PR_fprintf(err, "%6ld: %s", (now - base), msg);
+    if (PR_FAILURE == rv) PL_FPrintError(err, " ");
+    else PR_fprintf(err, "\n");
+    PR_Unlock(ml);
+}  /* LogNow */
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: [-[d][l][m][c]] [-h]\n");
+    PR_fprintf(err, "\t-d   debug mode                  (default: FALSE)\n");
+    PR_fprintf(err, "\t-l   test with locks             (default: FALSE)\n");
+    PR_fprintf(err, "\t-m   tests with monitors         (default: FALSE)\n");
+    PR_fprintf(err, "\t-c   tests with cmonitors        (default: FALSE)\n");
+    PR_fprintf(err, "\t-h   help\n");
+}  /* Help */
+
+static void PR_CALLBACK T2CMon(void *arg)
+{
+    PRStatus rv;
+    CMonShared *shared = (CMonShared*)arg;
+
+    PR_CEnterMonitor(&shared->o1);
+    LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS);
+    rv = PR_CWait(&shared->o1, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv);
+    else LogNow("T2 wait failed on o1", rv);
+
+    rv = PR_CNotify(&shared->o1);
+    if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv);
+    else LogNow("T2 notify on o1 failed", rv);
+
+    PR_CExitMonitor(&shared->o1);
+}  /* T2CMon */
+
+static void PR_CALLBACK T3CMon(void *arg)
+{
+    PRStatus rv;
+    CMonShared *shared = (CMonShared*)arg;
+
+    PR_CEnterMonitor(&shared->o2);
+    LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS);
+    rv = PR_CWait(&shared->o2, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv);
+    else LogNow("T3 wait failed on o2", rv);
+    rv = PR_CNotify(&shared->o2);
+    LogNow("T3 notify on o2", rv);
+    PR_CExitMonitor(&shared->o2);
+
+}  /* T3CMon */
+
+static CMonShared sharedCM;
+
+static void T1CMon(void)
+{
+    PRStatus rv;
+    PRThread *t2, *t3;
+
+    PR_fprintf(err, "\n**********************************\n");
+    PR_fprintf(err, "         CACHED MONITORS\n");
+    PR_fprintf(err, "**********************************\n");
+
+    base =  PR_IntervalNow();
+
+    PR_CEnterMonitor(&sharedCM.o1);
+    LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS);
+    rv = PR_CWait(&sharedCM.o1, PR_SecondsToInterval(3));
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv);
+    else LogNow("T1 wait on o1 failed", rv);
+    PR_CExitMonitor(&sharedCM.o1);
+
+    LogNow("T1 creating T2", PR_SUCCESS);
+    t2 = PR_CreateThread(
+        PR_USER_THREAD, T2CMon, &sharedCM, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    LogNow("T1 creating T3", PR_SUCCESS);
+    t3 = PR_CreateThread(
+        PR_USER_THREAD, T3CMon, &sharedCM, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    PR_CEnterMonitor(&sharedCM.o2);
+    LogNow("T1 waiting forever on o2", PR_SUCCESS);
+    rv = PR_CWait(&sharedCM.o2, PR_INTERVAL_NO_TIMEOUT);
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv);
+    else LogNow("T1 wait on o2 failed", rv);
+    PR_CExitMonitor(&sharedCM.o2);
+
+    (void)PR_JoinThread(t2);
+    (void)PR_JoinThread(t3);
+
+}  /* T1CMon */
+
+static void PR_CALLBACK T2Mon(void *arg)
+{
+    PRStatus rv;
+    MonShared *shared = (MonShared*)arg;
+
+    PR_EnterMonitor(shared->o1);
+    LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS);
+    rv = PR_Wait(shared->o1, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv);
+    else LogNow("T2 wait failed on o1", rv);
+
+    rv = PR_Notify(shared->o1);
+    if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv);
+    else LogNow("T2 notify on o1 failed", rv);
+
+    PR_ExitMonitor(shared->o1);
+}  /* T2Mon */
+
+static void PR_CALLBACK T3Mon(void *arg)
+{
+    PRStatus rv;
+    MonShared *shared = (MonShared*)arg;
+
+    PR_EnterMonitor(shared->o2);
+    LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS);
+    rv = PR_Wait(shared->o2, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv);
+    else LogNow("T3 wait failed on o2", rv);
+    rv = PR_Notify(shared->o2);
+    LogNow("T3 notify on o2", rv);
+    PR_ExitMonitor(shared->o2);
+
+}  /* T3Mon */
+
+static MonShared sharedM;
+static void T1Mon(void)
+{
+    PRStatus rv;
+    PRThread *t2, *t3;
+
+    PR_fprintf(err, "\n**********************************\n");
+    PR_fprintf(err, "            MONITORS\n");
+    PR_fprintf(err, "**********************************\n");
+
+    sharedM.o1 = PR_NewMonitor();
+    sharedM.o2 = PR_NewMonitor();
+
+    base =  PR_IntervalNow();
+
+    PR_EnterMonitor(sharedM.o1);
+    LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS);
+    rv = PR_Wait(sharedM.o1, PR_SecondsToInterval(3));
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv);
+    else LogNow("T1 wait on o1 failed", rv);
+    PR_ExitMonitor(sharedM.o1);
+
+    LogNow("T1 creating T2", PR_SUCCESS);
+    t2 = PR_CreateThread(
+        PR_USER_THREAD, T2Mon, &sharedM, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    LogNow("T1 creating T3", PR_SUCCESS);
+    t3 = PR_CreateThread(
+        PR_USER_THREAD, T3Mon, &sharedM, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    PR_EnterMonitor(sharedM.o2);
+    LogNow("T1 waiting forever on o2", PR_SUCCESS);
+    rv = PR_Wait(sharedM.o2, PR_INTERVAL_NO_TIMEOUT);
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv);
+    else LogNow("T1 wait on o2 failed", rv);
+    PR_ExitMonitor(sharedM.o2);
+
+    (void)PR_JoinThread(t2);
+    (void)PR_JoinThread(t3);
+
+    PR_DestroyMonitor(sharedM.o1);
+    PR_DestroyMonitor(sharedM.o2);
+
+}  /* T1Mon */
+
+static void PR_CALLBACK T2Lock(void *arg)
+{
+    PRStatus rv;
+    LockShared *shared = (LockShared*)arg;
+
+    PR_Lock(shared->o1);
+    LogNow("T2 waiting 5 seconds on o1", PR_SUCCESS);
+    rv = PR_WaitCondVar(shared->cv1, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T2 resuming on o1", rv);
+    else LogNow("T2 wait failed on o1", rv);
+
+    rv = PR_NotifyCondVar(shared->cv1);
+    if (PR_SUCCESS == rv) LogNow("T2 notified o1", rv);
+    else LogNow("T2 notify on o1 failed", rv);
+
+    PR_Unlock(shared->o1);
+}  /* T2Lock */
+
+static void PR_CALLBACK T3Lock(void *arg)
+{
+    PRStatus rv;
+    LockShared *shared = (LockShared*)arg;
+
+    PR_Lock(shared->o2);
+    LogNow("T3 waiting 5 seconds on o2", PR_SUCCESS);
+    rv = PR_WaitCondVar(shared->cv2, PR_SecondsToInterval(5));
+    if (PR_SUCCESS == rv) LogNow("T3 resuming on o2", rv);
+    else LogNow("T3 wait failed on o2", rv);
+    rv = PR_NotifyCondVar(shared->cv2);
+    LogNow("T3 notify on o2", rv);
+    PR_Unlock(shared->o2);
+
+}  /* T3Lock */
+
+/*
+** Make shared' a static variable for Win16
+*/
+static LockShared sharedL;
+
+static void T1Lock(void)
+{
+    PRStatus rv;
+    PRThread *t2, *t3;
+    sharedL.o1 = PR_NewLock();
+    sharedL.o2 = PR_NewLock();
+    sharedL.cv1 = PR_NewCondVar(sharedL.o1);
+    sharedL.cv2 = PR_NewCondVar(sharedL.o2);
+
+    PR_fprintf(err, "\n**********************************\n");
+    PR_fprintf(err, "             LOCKS\n");
+    PR_fprintf(err, "**********************************\n");
+
+    base =  PR_IntervalNow();
+
+    PR_Lock(sharedL.o1);
+    LogNow("T1 waiting 3 seconds on o1", PR_SUCCESS);
+    rv = PR_WaitCondVar(sharedL.cv1, PR_SecondsToInterval(3));
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o1", rv);
+    else LogNow("T1 wait on o1 failed", rv);
+    PR_Unlock(sharedL.o1);
+
+    LogNow("T1 creating T2", PR_SUCCESS);
+    t2 = PR_CreateThread(
+        PR_USER_THREAD, T2Lock, &sharedL, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    LogNow("T1 creating T3", PR_SUCCESS);
+    t3 = PR_CreateThread(
+        PR_USER_THREAD, T3Lock, &sharedL, PR_PRIORITY_NORMAL,
+        PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
+
+    PR_Lock(sharedL.o2);
+    LogNow("T1 waiting forever on o2", PR_SUCCESS);
+    rv = PR_WaitCondVar(sharedL.cv2, PR_INTERVAL_NO_TIMEOUT);
+    if (PR_SUCCESS == rv) LogNow("T1 resuming on o2", rv);
+    else LogNow("T1 wait on o2 failed", rv);
+    PR_Unlock(sharedL.o2);
+
+    (void)PR_JoinThread(t2);
+    (void)PR_JoinThread(t3);
+
+    PR_DestroyLock(sharedL.o1);
+    PR_DestroyLock(sharedL.o2);
+    PR_DestroyCondVar(sharedL.cv1);
+    PR_DestroyCondVar(sharedL.cv2);
+}  /* T1Lock */
+
+static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv )
+{
+	PLOptStatus os;
+  	PLOptState *opt = PL_CreateOptState(argc, argv, "dhlmc");
+	PRBool locks = PR_FALSE, monitors = PR_FALSE, cmonitors = PR_FALSE;
+
+    err = PR_GetSpecialFD(PR_StandardError);
+
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode (noop) */
+            break;
+        case 'l':  /* locks */
+			locks = PR_TRUE;
+            break;
+        case 'm':  /* monitors */
+			monitors = PR_TRUE;
+            break;
+        case 'c':  /* cached monitors */
+			cmonitors = PR_TRUE;
+            break;
+        case 'h':  /* needs guidance */
+         default:
+            Help();
+            return 2;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+    ml = PR_NewLock();
+    if (locks) T1Lock();
+    if (monitors) T1Mon();
+    if (cmonitors) T1CMon();
+
+    PR_DestroyLock(ml);
+
+    PR_fprintf(err, "Done!\n");    
+    return 0;
+}  /* main */
+
+
+PRIntn main(PRIntn argc, char **argv)
+{
+    PRIntn rv;
+    
+    PR_STDIO_INIT();
+    rv = PR_Initialize(RealMain, argc, argv, 0);
+    return rv;
+}  /* main */
+/* xnotify.c */

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/y2k.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/y2k.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,840 @@
+/* -*- 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: y2k.c
+ * description: Test for y2k compliance for NSPR.
+ *
+ * Sep 1999. lth. Added "Sun" specified dates to the test data.
+ */
+/***********************************************************************
+** Includes
+***********************************************************************/
+/* Used to get the command line option */
+#include "plgetopt.h"
+
+#include "prinit.h"
+#include "prtime.h"
+#include "prprf.h"
+#include "prlog.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef XP_MAC
+#include "prlog.h"
+#include "macstdlibextras.h"
+extern void SetupMacPrintfLog(char *logFile);
+#endif
+
+#define PRINT_DETAILS
+
+int failed_already=0;
+PRBool debug_mode = PR_FALSE;
+
+static char *dayOfWeek[] =
+	{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" };
+static char *month[] =
+	{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+	  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" };
+
+PRLogModuleInfo *lm;
+
+static void PrintExplodedTime(const PRExplodedTime *et) {
+    PRInt32 totalOffset;
+    PRInt32 hourOffset, minOffset;
+    const char *sign;
+
+    /* Print day of the week, month, day, hour, minute, and second */
+    printf("%s %s %2ld %02ld:%02ld:%02ld ",
+	    dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday,
+	    et->tm_hour, et->tm_min, et->tm_sec);
+
+    /* Print year */
+    printf("%hd ", et->tm_year);
+
+    /* Print time zone */
+    totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset;
+    if (totalOffset == 0) {
+	printf("UTC ");
+    } else {
+        sign = "+";
+        if (totalOffset < 0) {
+	    totalOffset = -totalOffset;
+	    sign = "-";
+        }
+        hourOffset = totalOffset / 3600;
+        minOffset = (totalOffset % 3600) / 60;
+        printf("%s%02ld%02ld ", sign, hourOffset, minOffset);
+    }
+#ifdef PRINT_DETAILS
+	printf("{%d, %d, %d, %d, %d, %d, %d, %d, %d, { %d, %d}}\n",et->tm_usec,
+											et->tm_sec,
+											et->tm_min,
+											et->tm_hour,
+											et->tm_mday,
+											et->tm_month,
+											et->tm_year,
+											et->tm_wday,
+											et->tm_yday,
+											et->tm_params.tp_gmt_offset,
+											et->tm_params.tp_dst_offset);
+#endif
+}
+
+static int ExplodedTimeIsEqual(const PRExplodedTime *et1,
+	const PRExplodedTime *et2)
+{
+    if (et1->tm_usec == et2->tm_usec &&
+	    et1->tm_sec == et2->tm_sec &&
+	    et1->tm_min == et2->tm_min &&
+	    et1->tm_hour == et2->tm_hour &&
+	    et1->tm_mday == et2->tm_mday &&
+	    et1->tm_month == et2->tm_month &&
+	    et1->tm_year == et2->tm_year &&
+	    et1->tm_wday == et2->tm_wday &&
+	    et1->tm_yday == et2->tm_yday &&
+	    et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset &&
+	    et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) {
+        return 1;
+    } else {
+	return 0;
+    }
+}
+
+/*
+ * TEST 1: TestExplodeImplodeTime
+ * Description:
+ * For each given timestamp T (a PRTime value), call PR_ExplodeTime
+ * with GMT, US Pacific, and local time parameters.  Compare the
+ * resulting calendar (exploded) time values with the expected
+ * values.
+ *
+ * Note: the expected local time values depend on the local time
+ * zone.  The local time values stored in this test are for the US
+ * Pacific Time Zone.  If you are running this test in a different
+ * time zone, you need to modify the values in the localt array.
+ * An example is provided below.
+ *
+ * Call PR_ImplodeTime for each of the exploded values and compare
+ * the resulting PRTime values with the original input.
+ * 
+ * This test is run for the values of time T corresponding to the
+ * following dates:
+ * - 12/31/99 - before 2000 
+ * - 01/01/00 - after 2000 
+ * - Leap year - Feb 29, 2000 
+ * - March 1st, 2001 (after 1 year) 
+ * - March 1st, 2005 (after second leap year) 
+ * - 09/09/99 (used by some programs as an end of file marker)
+ *
+ * Call PR_Now, convert to calendar time using PR_ExplodeTime and
+ * manually check the result for correctness. The time should match
+ * the system clock.
+ *
+ * Tested functions: PR_Now, PR_ExplodeTime, PR_ImplodeTime,
+ * PR_LocalTimeParameters, PR_GMTParameters. 
+ */
+
+static PRTime prt[] = {
+    LL_INIT(220405, 2133125120),  /* 946634400000000 */
+    LL_INIT(220425, 2633779200),  /* 946720800000000 */
+    LL_INIT(221612, 2107598848),  /* 951818400000000 */
+    LL_INIT(228975, 663398400),  /* 983440800000000 */
+    LL_INIT(258365, 1974568960),  /* 1109671200000000 */
+    LL_INIT(218132, 1393788928),  /* 936871200000000 */
+    /* Sun's dates follow */
+    LL_INIT( 213062, 4077979648 ), /* Dec 31 1998 10:00:00 */
+    LL_INIT( 218152, 1894443008 ), /* Sep 10 1999 10:00:00 */
+    LL_INIT( 221592, 1606944768 ), /* Feb 28 2000 10:00:00 */
+    LL_INIT( 227768, 688924672 ), /* Dec 31 2000 10:00:00 */
+    LL_INIT( 227788, 1189578752 ), /* Jan 1  2001 10:00:00 */
+};
+
+static PRExplodedTime gmt[] = {
+    { 0, 0, 0, 10, 31, 11, 1999, 5, 364, {0, 0}}, /* 1999/12/31 10:00:00 GMT */
+    { 0, 0, 0, 10, 1, 0, 2000, 6, 0, {0, 0}}, /* 2000/01/01 10:00:00 GMT */
+    { 0, 0, 0, 10, 29, 1, 2000, 2, 59, {0, 0}}, /* 2000/02/29 10:00:00 GMT */
+    { 0, 0, 0, 10, 1, 2, 2001, 4, 59, {0, 0}}, /* 2001/3/1 10:00:00 GMT */
+    { 0, 0, 0, 10, 1, 2, 2005, 2, 59, {0, 0}}, /* 2005/3/1 10:00:00 GMT */
+    { 0, 0, 0, 10, 9, 8, 1999, 4, 251, {0, 0}},  /* 1999/9/9 10:00:00 GMT */
+    /* Sun's dates follow */
+    { 0, 0, 0, 10, 31, 11, 1998, 4, 364, {0, 0}},  /* 12/31/1998 10:00:00 GMT */
+    { 0, 0, 0, 10, 10, 8, 1999, 5, 252, {0, 0}},  /* 9/10/1999 10:00:00 GMT */
+    { 0, 0, 0, 10, 28, 1, 2000, 1, 58, {0, 0}},  /* 2/28/2000 10:00:00 GMT */
+    { 0, 0, 0, 10, 31, 11, 2000, 0, 365, {0, 0}},  /* 12/31/2000 10:00:00 GMT */
+    { 0, 0, 0, 10, 1, 0, 2001, 1, 0, {0, 0}}  /* 1/1/2001 10:00:00 GMT */
+};
+
+static PRExplodedTime uspt[] = {
+{ 0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}}, /* 2000/01/01 2:00:00 PST */
+{ 0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}}, /* 2001/3/1 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}}, /* 2005/3/1 2:00:00 PST */
+{ 0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}},  /* 1999/9/9 3:00:00 PDT */
+    /* Sun's dates follow */
+    { 0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}},  /* 12/31/1998 00:00:00 GMT */
+    { 0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}},  /* 9/10/1999 00:00:00 GMT */
+    { 0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}},  /* 2/28/2000 00:00:00 GMT */
+    { 0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}},  /* 12/31/2000 00:00:00 GMT */
+    { 0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}}  /* 1/1/2001 00:00:00 GMT */
+};
+
+/*
+ * This test assumes that we are in US Pacific Time Zone.
+ * If you are running this test in a different time zone,
+ * you need to modify the localt array and fill in the
+ * expected results.  The localt array for US Eastern Time
+ * Zone is provided as an example.
+ */
+static PRExplodedTime localt[] = {
+{ 0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}}, /* 2000/01/01 2:00:00 PST */
+{ 0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}}, /* 2001/3/1 2:00:00 PST */
+{ 0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}}, /* 2005/3/1 2:00:00 PST */
+{ 0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}},  /* 1999/9/9 3:00:00 PDT */
+    /* Sun's dates follow */
+    { 0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}},  /* 12/31/1998 00:00:00 GMT */
+    { 0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}},  /* 9/10/1999 00:00:00 GMT */
+    { 0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}},  /* 2/28/2000 00:00:00 GMT */
+    { 0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}},  /* 12/31/2000 00:00:00 GMT */
+    { 0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}}  /* 1/1/2001 00:00:00 GMT */
+};
+
+#ifdef US_EASTERN_TIME
+static PRExplodedTime localt[] = {
+{ 0, 0, 0, 5, 31, 11, 1999, 5, 364, {-18000, 0}}, /* 1999/12/31 2:00:00 EST */
+{ 0, 0, 0, 5, 1, 0, 2000, 6, 0, {-18000, 0}}, /* 2000/01/01 2:00:00 EST */
+{ 0, 0, 0, 5, 29, 1, 2000, 2, 59, {-18000, 0}}, /* 2000/02/29 2:00:00 EST */
+{ 0, 0, 0, 5, 1, 2, 2001, 4, 59, {-18000, 0}}, /* 2001/3/1 2:00:00 EST */
+{ 0, 0, 0, 5, 1, 2, 2005, 2, 59, {-18000, 0}}, /* 2005/3/1 2:00:00 EST */
+{ 0, 0, 0, 6, 9, 8, 1999, 4, 251, {-18000, 3600}},  /* 1999/9/9 3:00:00 EDT */
+    /* Sun's dates follow */
+    { 0, 0, 0, 5, 31, 11, 1998, 4, 364, {-18000 0}},  /* 12/31/1998 00:00:00 GMT */
+    { 0, 0, 0, 6, 10, 8, 1999, 5, 252, {-18000 3600}},  /* 9/10/1999 00:00:00 GMT */
+    { 0, 0, 0, 5, 28, 1, 2000, 1, 58, {-18000 0}},  /* 2/28/2000 00:00:00 GMT */
+    { 0, 0, 0, 5, 31, 11, 2000, 0, 365, {-18000 0}},  /* 12/31/2000 00:00:00 GMT */
+    { 0, 0, 0, 5, 1, 0, 2001, 1, 0, {-18000 0}}  /* 1/1/2001 00:00:00 GMT */
+};
+#endif
+
+static PRStatus TestExplodeImplodeTime(void)
+{
+    PRTime prt_tmp;
+    PRTime now;
+    int idx;
+    int array_size = sizeof(prt) / sizeof(PRTime);
+    PRExplodedTime et_tmp;
+    char buf[1024];
+
+    for (idx = 0; idx < array_size; idx++) {
+        PR_snprintf(buf, sizeof(buf), "%lld", prt[idx]);
+        if (debug_mode) printf("Time stamp %s\n", buf); 
+        PR_ExplodeTime(prt[idx], PR_GMTParameters, &et_tmp);
+        if (!ExplodedTimeIsEqual(&et_tmp, &gmt[idx])) {
+            fprintf(stderr, "GMT not equal\n");
+            PrintExplodedTime(&et_tmp);
+            PrintExplodedTime(&gmt[idx]);
+            exit(1);
+        }
+        prt_tmp = PR_ImplodeTime(&et_tmp);
+        if (LL_NE(prt_tmp, prt[idx])) {
+            fprintf(stderr, "PRTime not equal\n");
+            exit(1);
+        }
+        if (debug_mode) {
+            printf("GMT: ");
+            PrintExplodedTime(&et_tmp);
+            printf("\n");
+        }
+
+        PR_ExplodeTime(prt[idx], PR_USPacificTimeParameters, &et_tmp);
+        if (!ExplodedTimeIsEqual(&et_tmp, &uspt[idx])) {
+            fprintf(stderr, "US Pacific Time not equal\n");
+            PrintExplodedTime(&et_tmp);
+            PrintExplodedTime(&uspt[idx]);
+            exit(1);
+        }
+        prt_tmp = PR_ImplodeTime(&et_tmp);
+        if (LL_NE(prt_tmp, prt[idx])) {
+            fprintf(stderr, "PRTime not equal\n");
+            exit(1);
+        }
+        if (debug_mode) {
+            printf("US Pacific Time: ");
+            PrintExplodedTime(&et_tmp);
+            printf("\n");
+        }
+
+        PR_ExplodeTime(prt[idx], PR_LocalTimeParameters, &et_tmp);
+        if (!ExplodedTimeIsEqual(&et_tmp, &localt[idx])) {
+            fprintf(stderr, "not equal\n");
+            PrintExplodedTime(&et_tmp);
+            PrintExplodedTime(&localt[idx]);
+            exit(1);
+        }
+        prt_tmp = PR_ImplodeTime(&et_tmp);
+        if (LL_NE(prt_tmp, prt[idx])) {
+            fprintf(stderr, "not equal\n");
+            exit(1);
+        }
+        if (debug_mode) {
+            printf("Local time:");
+            PrintExplodedTime(&et_tmp);
+            printf("\n\n");
+        }
+    }
+
+    now = PR_Now();
+    PR_ExplodeTime(now, PR_GMTParameters, &et_tmp);
+    printf("Current GMT is ");
+    PrintExplodedTime(&et_tmp);
+    printf("\n");
+    prt_tmp = PR_ImplodeTime(&et_tmp);
+    if (LL_NE(prt_tmp, now)) {
+        fprintf(stderr, "not equal\n");
+        exit(1);
+    }
+    PR_ExplodeTime(now, PR_USPacificTimeParameters, &et_tmp);
+    printf("Current US Pacific Time is ");
+    PrintExplodedTime(&et_tmp);
+    printf("\n");
+    prt_tmp = PR_ImplodeTime(&et_tmp);
+    if (LL_NE(prt_tmp, now)) {
+        fprintf(stderr, "not equal\n");
+        exit(1);
+    }
+    PR_ExplodeTime(now, PR_LocalTimeParameters, &et_tmp);
+    printf("Current local time is ");
+    PrintExplodedTime(&et_tmp);
+    printf("\n");
+    prt_tmp = PR_ImplodeTime(&et_tmp);
+    if (LL_NE(prt_tmp, now)) {
+        fprintf(stderr, "not equal\n");
+        exit(1);
+    }
+    printf("Please verify the results\n\n");
+
+    if (debug_mode) printf("Test 1 passed\n");
+    return PR_SUCCESS;
+}
+/* End of Test 1: TestExplodeImplodeTime */
+
+/*
+ * Test 2: Normalize Time
+ */
+
+/*
+ * time increment for addition to PRExplodeTime
+ */
+typedef struct time_increment {
+	PRInt32 ti_usec;
+	PRInt32 ti_sec;
+	PRInt32 ti_min;
+	PRInt32 ti_hour;
+} time_increment_t;
+
+/*
+ * Data for testing PR_Normalize
+ *		Add the increment to base_time, normalize it to GMT and US Pacific
+ *		Time zone.
+ */
+typedef struct normalize_test_data {
+    PRExplodedTime		base_time; 
+    time_increment_t  	increment;
+    PRExplodedTime		expected_gmt_time;
+    PRExplodedTime		expected_uspt_time;
+} normalize_test_data_t;
+
+
+/*
+ * Test data -	the base time values cover dates of interest including y2k - 1,
+ *				y2k + 1, y2k leap year, y2k leap date + 1year,
+ *				y2k leap date + 4 years
+ */
+normalize_test_data_t normalize_test_array[] = {
+  /*usec sec min hour  mday  mo  year  wday yday {gmtoff, dstoff }*/
+
+	/* Fri 12/31/1999 19:32:48 PST */
+	{{0, 48, 32, 19, 31, 11, 1999, 5, 364, { -28800, 0}},
+    {0, 0, 30, 20},
+	{0, 48, 2, 0, 2, 0, 2000, 0, 1, { 0, 0}},	/*Sun Jan 2 00:02:48 UTC 2000*/
+	{0, 48, 2, 16, 1, 0, 2000, 6, 0, { -28800, 0}},/* Sat Jan 1 16:02:48
+														PST 2000*/
+	},
+	/* Fri 99-12-31 23:59:02 GMT */
+	{{0, 2, 59, 23, 31, 11, 1999, 5, 364, { 0, 0}},
+    {0, 0, 45, 0},
+	{0, 2, 44, 0, 1, 0, 2000, 6, 0, { 0, 0}},/* Sat Jan 1 00:44:02 UTC 2000*/
+	{0, 2, 44, 16, 31, 11, 1999, 5, 364, { -28800, 0}}/*Fri Dec 31 16:44:02
+														PST 1999*/
+	},
+	/* 99-12-25 12:00:00 GMT */
+	{{0, 0, 0, 12, 25, 11, 1999, 6, 358, { 0, 0}},
+    {0, 0, 0, 364 * 24},
+	{0, 0, 0, 12, 23, 11, 2000, 6, 357, { 0, 0}},/*Sat Dec 23 12:00:00
+													2000 UTC*/
+	{0, 0, 0, 4, 23, 11, 2000, 6, 357, { -28800, 0}}/*Sat Dec 23 04:00:00
+														2000 -0800*/
+	},
+	/* 00-01-1 00:00:00 PST */
+    {{0, 0, 0, 0, 1, 0, 2000, 6, 0, { -28800, 0}},
+    {0, 0, 0, 48},
+    {0, 0, 0, 8, 3, 0, 2000, 1, 2, { 0, 0}},/*Mon Jan  3 08:00:00 2000 UTC*/
+    {0, 0, 0, 0, 3, 0, 2000, 1, 2, { -28800, 0}}/*Mon Jan  3 00:00:00 2000
+																-0800*/
+	},
+	/* 00-01-10 12:00:00 PST */
+    {{0, 0, 0, 12, 10, 0, 2000, 1, 9, { -28800, 0}},
+    {0, 0, 0, 364 * 5 * 24},
+    {0, 0, 0, 20, 3, 0, 2005, 1, 2, { 0, 0}},/*Mon Jan  3 20:00:00 2005 UTC */
+    {0, 0, 0, 12, 3, 0, 2005, 1, 2, { -28800, 0}}/*Mon Jan  3 12:00:00
+														2005 -0800*/
+	},
+	/* 00-02-28 15:39 GMT */
+	{{0, 0, 39, 15, 28, 1, 2000, 1, 58, { 0, 0}},
+    {0,  0, 0, 24},
+	{0, 0, 39, 15, 29, 1, 2000, 2, 59, { 0, 0}}, /*Tue Feb 29 15:39:00 2000
+														UTC*/
+	{0, 0, 39, 7, 29, 1, 2000, 2, 59, { -28800, 0}}/*Tue Feb 29 07:39:00
+														2000 -0800*/
+	},
+	/* 01-03-01 12:00 PST */
+    {{0, 0, 0, 12, 3, 0, 2001, 3, 2, { -28800, 0}},/*Wed Jan 3 12:00:00
+													-0800 2001*/
+    {0, 30, 30,45},
+    {0, 30, 30, 17, 5, 0, 2001, 5, 4, { 0, 0}}, /*Fri Jan  5 17:30:30 2001
+													UTC*/
+    {0, 30, 30, 9, 5, 0, 2001, 5, 4, { -28800, 0}} /*Fri Jan  5 09:30:30
+														2001 -0800*/
+	},
+	/* 2004-04-26 12:00 GMT */
+	{{0, 0, 0, 20, 3, 0, 2001, 3, 2, { 0, 0}},
+    {0, 0, 30,0},
+	{0, 0, 30, 20, 3, 0, 2001, 3, 2, { 0, 0}},/*Wed Jan  3 20:30:00 2001 UTC*/ 
+    {0, 0, 30, 12, 3, 0, 2001, 3, 2, { -28800, 0}}/*Wed Jan  3 12:30:00
+														2001 -0800*/
+	},
+	/* 99-09-09 00:00 GMT */
+	{{0, 0, 0, 0, 9, 8, 1999, 4, 251, { 0, 0}},
+    {0, 0, 0, 12},
+    {0, 0, 0, 12, 9, 8, 1999, 4, 251, { 0, 0}},/*Thu Sep  9 12:00:00 1999 UTC*/
+    {0, 0, 0, 5, 9, 8, 1999, 4, 251, { -28800, 3600}}/*Thu Sep  9 05:00:00
+														1999 -0700*/
+	}
+};
+
+void add_time_increment(PRExplodedTime *et1, time_increment_t *it)
+{
+	et1->tm_usec += it->ti_usec;
+	et1->tm_sec	+= it->ti_sec;
+	et1->tm_min += it->ti_min;
+	et1->tm_hour += it->ti_hour;
+}
+
+/*
+** TestNormalizeTime() -- Test PR_NormalizeTime()
+**		For each data item, add the time increment to the base_time and then
+**		normalize it for GMT and local time zones. This test assumes that
+**		the local time zone is the Pacific Time Zone. The normalized values
+**		should match the expected values in the data item.
+**
+*/
+PRStatus TestNormalizeTime(void)
+{
+int idx, count;
+normalize_test_data_t *itemp;
+time_increment_t *itp;
+
+	count = sizeof(normalize_test_array)/sizeof(normalize_test_array[0]);
+	for (idx = 0; idx < count; idx++) {
+		itemp = &normalize_test_array[idx];
+		if (debug_mode) {
+			printf("%2d. %15s",idx +1,"Base time: ");
+			PrintExplodedTime(&itemp->base_time);
+			printf("\n");
+		}
+		itp = &itemp->increment;
+		if (debug_mode) {
+			printf("%20s %2d hrs %2d min %3d sec\n","Add",itp->ti_hour,
+												itp->ti_min, itp->ti_sec);
+		}
+		add_time_increment(&itemp->base_time, &itemp->increment);
+		PR_NormalizeTime(&itemp->base_time, PR_LocalTimeParameters);
+		if (debug_mode) {
+			printf("%19s","PST time: ");
+			PrintExplodedTime(&itemp->base_time);
+			printf("\n");
+		}
+		if (!ExplodedTimeIsEqual(&itemp->base_time,
+									&itemp->expected_uspt_time)) {
+			printf("PR_NormalizeTime failed\n");
+			if (debug_mode)
+				PrintExplodedTime(&itemp->expected_uspt_time);
+			return PR_FAILURE;
+		}
+		PR_NormalizeTime(&itemp->base_time, PR_GMTParameters);
+		if (debug_mode) {
+			printf("%19s","GMT time: ");
+			PrintExplodedTime(&itemp->base_time);
+			printf("\n");
+		}
+
+		if (!ExplodedTimeIsEqual(&itemp->base_time,
+									&itemp->expected_gmt_time)) {
+			printf("PR_NormalizeTime failed\n");
+			return PR_FAILURE;
+		}
+	}
+	return PR_SUCCESS;
+}
+
+
+/*
+** ParseTest. Structure defining a string time and a matching exploded time
+**
+*/
+typedef struct ParseTest
+{
+    char            *sDate;     /* string to be converted using PR_ParseTimeString() */
+    PRExplodedTime  et;         /* expected result of the conversion */
+} ParseTest;
+
+static ParseTest parseArray[] = 
+{
+    /*                                  |<----- expected result ------------------------------------------->| */
+    /* "string to test"                   usec     sec min hour   day  mo  year  wday julian {gmtoff, dstoff }*/
+    { "Thursday 1 Jan 1970 00:00:00",   { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "1 Jan 1970 00:00:00",            { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "1-Jan-1970 00:00:00",            { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "01-Jan-1970 00:00:00",           { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "January 1, 1970",                { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "January 1, 1970 00:00",          { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "January 01, 1970 00:00",         { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "January 01 1970 00:00",          { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "January 01 1970 00:00:00",       { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "01-01-1970",                     { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "01/01/1970",                     { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "01/01/70",                       { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "01/01/70 00:00:00",              { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "70/01/01 00:00:00",              { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "70/1/1 00:00:",                  { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "00:00 Thursday, January 1, 1970",{ 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "1-Jan-70 00:00:00",              { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "70-01-01 00:00:00",              { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+    { "70/01/01 00:00:00",              { 000000,  00, 00, 00,     1,   0, 1970, 4,     0,   {-28800, 0 }}},
+
+    /* 31-Dec-1969 */
+    { "Wed 31 Dec 1969 00:00:00",       { 000000,  00, 00, 00,    31,  11, 1969, 3,   364,   {-28800, 0 }}},
+    { "31 Dec 1969 00:00:00",           { 000000,  00, 00, 00,    31,  11, 1969, 3,   364,   {-28800, 0 }}},
+    { "12/31/69    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2069, 2,   364,   {-28800, 0 }}},
+    { "12/31/1969  00:00:00",           { 000000,  00, 00, 00,    31,  11, 1969, 3,   364,   {-28800, 0 }}},
+    { "12-31-69    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2069, 2,   364,   {-28800, 0 }}},
+    { "12-31-1969  00:00:00",           { 000000,  00, 00, 00,    31,  11, 1969, 3,   364,   {-28800, 0 }}},
+    { "69-12-31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2069, 2,   364,   {-28800, 0 }}},
+    { "69/12/31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2069, 2,   364,   {-28800, 0 }}},
+
+    /* "Sun". 31-Dec-1998 (?) */ 
+    { "Thu 31 Dec 1998 00:00:00",        { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "12/31/98    00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "12/31/1998  00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "12-31-98    00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "12-31-1998  00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "98-12-31    00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+    { "98/12/31    00:00:00",            { 00000,  00, 00, 00,    31,  11, 1998, 4,   364,    {-28800, 0 }}},
+
+    /* 09-Sep-1999. Interesting because of its use as an eof marker? */
+    { "09 Sep 1999 00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "9/9/99      00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "9/9/1999    00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "9-9-99      00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "9-9-1999    00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "09-09-99    00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "09-09-1999  00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    { "99-09-09    00:00:00",           { 000000,  00, 00, 00,     9,   8, 1999, 4,   251,   {-28800, 3600 }}},
+    
+    /* "Sun". 10-Sep-1999. Because Sun said so. */
+    { "10 Sep 1999 00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "9/10/99     00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "9/10/1999   00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "9-10-99     00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "9-10-1999   00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "09-10-99    00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "09-10-1999  00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+    { "99-09-10    00:00:00",           { 000000,  00, 00, 00,    10,   8, 1999, 5,   252,   {-28800, 3600 }}},
+
+    /* 31-Dec-1999 */
+    { "31 Dec 1999 00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "12/31/99    00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "12/31/1999  00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "12-31-99    00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "12-31-1999  00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "99-12-31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+    { "99/12/31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 1999, 5,   364,   {-28800, 0 }}},
+
+    /* 01-Jan-2000 */
+    { "01 Jan 2000 00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "1/1/00      00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "1/1/2000    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "1-1-00      00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "1-1-2000    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "01-01-00    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+    { "Saturday 01-01-2000  00:00:00",  { 000000,  00, 00, 00,     1,   0, 2000, 6,     0,   {-28800, 0 }}},
+
+    /* "Sun". 28-Feb-2000 */
+    { "28 Feb 2000 00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "2/28/00     00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "2/28/2000   00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "2-28-00     00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "2-28-2000   00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "02-28-00    00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+    { "02-28-2000  00:00:00",           { 000000,  00, 00, 00,    28,   1, 2000, 1,    58,   {-28800, 0 }}},
+
+    /* 29-Feb-2000 */
+    { "29 Feb 2000 00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "2/29/00     00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "2/29/2000   00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "2-29-00     00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "2-29-2000   00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "02-29-00    00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+    { "02-29-2000  00:00:00",           { 000000,  00, 00, 00,    29,   1, 2000, 2,    59,   {-28800, 0 }}},
+
+    /* 01-Mar-2000 */
+    { "01 Mar 2000 00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+    { "3/1/00      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+    { "3/1/2000    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+    { "3-1-00      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+    { "03-01-00    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+    { "03-01-2000  00:00:00",           { 000000,  00, 00, 00,     1,   2, 2000, 3,    60,   {-28800, 0 }}},
+
+    /* "Sun". 31-Dec-2000 */
+    { "31 Dec 2000 00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "12/31/00    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "12/31/2000  00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "12-31-00    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "12-31-2000  00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "00-12-31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+    { "00/12/31    00:00:00",           { 000000,  00, 00, 00,    31,  11, 2000, 0,   365,   {-28800, 0 }}},
+
+    /* "Sun". 01-Jan-2001 */
+    { "01 Jan 2001 00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "1/1/01      00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "1/1/2001    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "1-1-01      00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "1-1-2001    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "01-01-01    00:00:00",           { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+    { "Saturday 01-01-2001  00:00:00",  { 000000,  00, 00, 00,     1,   0, 2001, 1,     0,   {-28800, 0 }}},
+
+    /* 01-Mar-2001 */
+    { "01 Mar 2001 00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "3/1/01      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "3/1/2001    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "3-1-01      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "3-1-2001    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "03-01-01    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+    { "03-01-2001  00:00:00",           { 000000,  00, 00, 00,     1,   2, 2001, 4,    59,   {-28800, 0 }}},
+
+    /* 29-Feb-2004 */
+    { "29 Feb 2004 00:00:00",           { 000000,  00, 00, 00,    29,   1, 2004, 0,    59,   {-28800, 0 }}},
+    { "2/29/04     00:00:00",           { 000000,  00, 00, 00,    29,   1, 2004, 0,    59,   {-28800, 0 }}},
+    { "2/29/2004   00:00:00",           { 000000,  00, 00, 00,    29,   1, 2004, 0,    59,   {-28800, 0 }}},
+    { "2-29-04     00:00:00",           { 000000,  00, 00, 00,    29,   1, 2004, 0,    59,   {-28800, 0 }}},
+    { "2-29-2004   00:00:00",           { 000000,  00, 00, 00,    29,   1, 2004, 0,    59,   {-28800, 0 }}},
+
+    /* 01-Mar-2004 */
+    { "01 Mar 2004 00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "3/1/04      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "3/1/2004    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "3-1-04      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "3-1-2004    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "03-01-04    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+    { "03-01-2004  00:00:00",           { 000000,  00, 00, 00,     1,   2, 2004, 1,    60,   {-28800, 0 }}},
+
+    /* 01-Mar-2005 */
+    { "01 Mar 2005 00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "3/1/05      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "3/1/2005    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "3-1-05      00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "3-1-2005    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "03-01-05    00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+    { "03-01-2005  00:00:00",           { 000000,  00, 00, 00,     1,   2, 2005, 2,    59,   {-28800, 0 }}},
+
+    /* last element. string must be null */
+    { NULL }        
+}; /* end array of ParseTest */
+
+/*
+** TestParseTime() -- Test PR_ParseTimeString() for y2k compliance
+**
+** TestParseTime() loops thru the array parseArray. For each element in
+** the array, he calls PR_ParseTimeString() with sDate as the conversion
+** argument. The result (ct) is then converted to a PRExplodedTime structure
+** and compared with the exploded time value (parseArray[n].et) in the
+** array element; if equal, the element passes the test.
+**
+** The array parseArray[] contains entries that are interesting to the
+** y2k problem.
+**
+**
+*/
+static PRStatus TestParseTime( void )
+{
+    ParseTest       *ptp = parseArray;
+    PRTime          ct;
+    PRExplodedTime  cet;
+    char            *sp = ptp->sDate;
+    PRStatus        rc;
+    PRStatus        rv = PR_SUCCESS;
+
+    while ( sp != NULL)
+    {
+        rc = PR_ParseTimeString( sp, PR_FALSE, &ct );
+        if ( PR_FAILURE == rc )
+        {
+            printf("TestParseTime(): PR_ParseTimeString() failed to convert: %s\n", sp );
+            rv = PR_FAILURE;
+            failed_already = 1;
+        }
+        else
+        {
+            PR_ExplodeTime( ct, PR_LocalTimeParameters , &cet );
+
+            if ( !ExplodedTimeIsEqual( &cet, &ptp->et ))
+            {
+                printf("TestParseTime(): Exploded time compare failed: %s\n", sp );
+                if ( debug_mode )
+                {
+                    PrintExplodedTime( &cet );
+                    printf("\n");
+                    PrintExplodedTime( &ptp->et );
+                    printf("\n");
+                }
+                
+                rv = PR_FAILURE;
+                failed_already = 1;
+            }
+        }
+                
+        /* point to next element in array, keep going */
+        ptp++;
+        sp = ptp->sDate;
+    } /* end while() */
+
+    return( rv );
+} /* end TestParseTime() */
+
+int main(int argc, char** argv)
+{
+	/* 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;
+    
+    PR_STDIO_INIT();
+	opt = PL_CreateOptState(argc, argv, "d");
+	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+		if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+        case 'd':  /* debug mode */
+			debug_mode = PR_TRUE;
+            break;
+         default:
+            break;
+        }
+    }
+	PL_DestroyOptState(opt);
+
+ /* main test */
+	
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
+    lm = PR_NewLogModule("test");
+
+#ifdef XP_MAC
+	/* Set up the console */
+	InitializeSIOUX(true);
+	debug_mode = PR_TRUE;
+#endif
+
+    if ( PR_FAILURE == TestExplodeImplodeTime())
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("TestExplodeImplodeTime() failed"));
+    }
+    else
+    	printf("Test 1: Calendar Time Test passed\n");
+
+    if ( PR_FAILURE == TestNormalizeTime())
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("TestNormalizeTime() failed"));
+    }
+    else
+    	printf("Test 2: Normalize Time Test passed\n");
+
+    if ( PR_FAILURE == TestParseTime())
+    {
+        PR_LOG( lm, PR_LOG_ERROR,
+            ("TestParseTime() failed"));
+    }
+    else
+    	printf("Test 3: Parse Time Test passed\n");
+
+#ifdef XP_MAC
+	if (1)
+	{
+		char dummyChar;
+		
+		printf("Press return to exit\n\n");
+		scanf("%c", &dummyChar);
+	}
+#endif
+
+	if (failed_already) 
+	    return 1;
+	else 
+	    return 0;
+} /* end main() y2k.c */
+

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/y2ktmo.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/y2ktmo.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,546 @@
+/* -*- 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 ***** */
+
+/*
+ * Test: y2ktmo
+ *
+ * Description:
+ *   This test tests the interval time facilities in NSPR for Y2K
+ *   compliance.  All the functions that take a timeout argument
+ *   are tested: PR_Sleep, socket I/O (PR_Accept is taken as a
+ *   representative), PR_Poll, PR_WaitCondVar, PR_Wait, and
+ *   PR_CWait.  A thread of each thread scope (local, global, and
+ *   global bound) is created to call each of these functions.
+ *   The test should be started at the specified number of seconds
+ *   (called the lead time) before a Y2K rollover test date.  The
+ *   timeout values for these threads will span over the rollover
+ *   date by at least the specified number of seconds.  For
+ *   example, if the lead time is 5 seconds, the test should
+ *   be started at time (D - 5), where D is a rollover date, and
+ *   the threads will time out at or after time (D + 5).  The
+ *   timeout values for the threads are spaced one second apart.
+ *
+ *   When a thread times out, it calls PR_IntervalNow() to verify
+ *   that it did wait for the specified time.  In addition, it
+ *   calls a platform-native function to verify the actual elapsed
+ *   time again, to rule out the possibility that PR_IntervalNow()
+ *   is broken.  We allow the actual elapsed time to deviate from
+ *   the specified timeout by a certain tolerance (in milliseconds).
+ */ 
+
+#include "nspr.h"
+#include "plgetopt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(XP_UNIX)
+#include <sys/time.h> /* for gettimeofday */
+#endif
+#if defined(WIN32)
+#include <sys/types.h>
+#include <sys/timeb.h>  /* for _ftime */
+#endif
+
+#define DEFAULT_LEAD_TIME_SECS 5
+#define DEFAULT_TOLERANCE_MSECS 500
+
+static PRBool debug_mode = PR_FALSE;
+static PRInt32 lead_time_secs = DEFAULT_LEAD_TIME_SECS;
+static PRInt32 tolerance_msecs = DEFAULT_TOLERANCE_MSECS;
+static PRIntervalTime start_time;
+static PRIntervalTime tolerance;
+
+#if defined(XP_UNIX)
+static struct timeval start_time_tv;
+#endif
+#if defined(WIN32)
+static struct _timeb start_time_tb;
+#endif
+
+static void SleepThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32)
+    struct _timeb end_time_tb;
+#endif
+
+    if (PR_Sleep(timeout) == PR_FAILURE) {
+        fprintf(stderr, "PR_Sleep failed\n");
+        exit(1);
+    }
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    if (debug_mode) {
+        fprintf(stderr, "Sleep thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+static void AcceptThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32)
+    struct _timeb end_time_tb;
+#endif
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    PRFileDesc *accepted;
+
+    sock = PR_NewTCPSocket();
+    if (sock == NULL) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&addr, 0, sizeof(addr));
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = 0;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    if (PR_Bind(sock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    if (PR_Listen(sock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+    accepted = PR_Accept(sock, NULL, timeout);
+    if (accepted != NULL || PR_GetError() != PR_IO_TIMEOUT_ERROR) {
+        fprintf(stderr, "PR_Accept did not time out\n");
+        exit(1);
+    }
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (debug_mode) {
+        fprintf(stderr, "Accept thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+static void PollThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32)
+    struct _timeb end_time_tb;
+#endif
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    PRPollDesc pd;
+    PRIntn rv;
+
+    sock = PR_NewTCPSocket();
+    if (sock == NULL) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    memset(&addr, 0, sizeof(addr));
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = 0;
+    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
+    if (PR_Bind(sock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    if (PR_Listen(sock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+    pd.fd = sock;
+    pd.in_flags = PR_POLL_READ;
+    rv = PR_Poll(&pd, 1, timeout);
+    if (rv != 0) {
+        fprintf(stderr, "PR_Poll did not time out\n");
+        exit(1);
+    }
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (debug_mode) {
+        fprintf(stderr, "Poll thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+static void WaitCondVarThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32)
+    struct _timeb end_time_tb;
+#endif
+    PRLock *ml;
+    PRCondVar *cv;
+
+    ml = PR_NewLock();
+    if (ml == NULL) {
+        fprintf(stderr, "PR_NewLock failed\n");
+        exit(1);
+    }
+    cv = PR_NewCondVar(ml);
+    if (cv == NULL) {
+        fprintf(stderr, "PR_NewCondVar failed\n");
+        exit(1);
+    }
+    PR_Lock(ml);
+    PR_WaitCondVar(cv, timeout);
+    PR_Unlock(ml);
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    PR_DestroyCondVar(cv);
+    PR_DestroyLock(ml);
+    if (debug_mode) {
+        fprintf(stderr, "wait cond var thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+static void WaitMonitorThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32)
+    struct _timeb end_time_tb;
+#endif
+    PRMonitor *mon;
+
+    mon = PR_NewMonitor();
+    if (mon == NULL) {
+        fprintf(stderr, "PR_NewMonitor failed\n");
+        exit(1);
+    }
+    PR_EnterMonitor(mon);
+    PR_Wait(mon, timeout);
+    PR_ExitMonitor(mon);
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    PR_DestroyMonitor(mon);
+    if (debug_mode) {
+        fprintf(stderr, "wait monitor thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+static void WaitCMonitorThread(void *arg)
+{
+    PRIntervalTime timeout = (PRIntervalTime) arg;
+    PRIntervalTime elapsed;
+#if defined(XP_UNIX) || defined(WIN32)
+    PRInt32 timeout_msecs = PR_IntervalToMilliseconds(timeout);
+    PRInt32 elapsed_msecs;
+#endif
+#if defined(XP_UNIX)
+    struct timeval end_time_tv;
+#endif
+#if defined(WIN32)
+    struct _timeb end_time_tb;
+#endif
+    int dummy;
+
+    PR_CEnterMonitor(&dummy);
+    PR_CWait(&dummy, timeout);
+    PR_CExitMonitor(&dummy);
+    elapsed = (PRIntervalTime)(PR_IntervalNow() - start_time);
+    if (elapsed + tolerance < timeout || elapsed > timeout + tolerance) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#if defined(XP_UNIX)
+    gettimeofday(&end_time_tv, NULL);
+    elapsed_msecs = 1000*(end_time_tv.tv_sec - start_time_tv.tv_sec)
+            + (end_time_tv.tv_usec - start_time_tv.tv_usec)/1000;
+#endif
+#if defined(WIN32)
+    _ftime(&end_time_tb);
+    elapsed_msecs = 1000*(end_time_tb.time - start_time_tb.time)
+            + (end_time_tb.millitm - start_time_tb.millitm);
+#endif
+#if defined(XP_UNIX) || defined(WIN32)
+    if (elapsed_msecs + tolerance_msecs < timeout_msecs
+            || elapsed_msecs > timeout_msecs + tolerance_msecs) {
+        fprintf(stderr, "timeout wrong\n");
+        exit(1);
+    }
+#endif
+    if (debug_mode) {
+        fprintf(stderr, "wait cached monitor thread (scope %d) done\n",
+                PR_GetThreadScope(PR_GetCurrentThread()));
+    }
+}
+
+typedef void (*NSPRThreadFunc)(void*);
+
+static NSPRThreadFunc threadFuncs[] = {
+    SleepThread, AcceptThread, PollThread,
+    WaitCondVarThread, WaitMonitorThread, WaitCMonitorThread};
+
+static PRThreadScope threadScopes[] = {
+    PR_LOCAL_THREAD, PR_GLOBAL_THREAD, PR_GLOBAL_BOUND_THREAD};
+
+static void Help(void)
+{
+    fprintf(stderr, "y2ktmo test program usage:\n");
+    fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
+    fprintf(stderr, "\t-l <secs>    lead time          (%d)\n",
+            DEFAULT_LEAD_TIME_SECS);
+    fprintf(stderr, "\t-t <msecs>   tolerance          (%d)\n",
+            DEFAULT_TOLERANCE_MSECS);
+    fprintf(stderr, "\t-h           this message\n");
+}  /* Help */
+
+int main(int argc, char **argv)
+{
+    PRThread **threads;
+    int num_thread_funcs = sizeof(threadFuncs)/sizeof(NSPRThreadFunc);
+    int num_thread_scopes = sizeof(threadScopes)/sizeof(PRThreadScope);
+    int i, j;
+    int idx;
+    PRInt32 secs;
+    PLOptStatus os;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "dl:t:h");
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option) {
+            case 'd':  /* debug mode */
+                debug_mode = PR_TRUE;
+                break;
+            case 'l':  /* lead time */
+                lead_time_secs = atoi(opt->value);
+                break;
+            case 't':  /* tolerance */
+                tolerance_msecs = atoi(opt->value);
+                break;
+            case 'h':
+            default:
+                Help();
+                return 2;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+    if (debug_mode) {
+        fprintf(stderr, "lead time: %d secs\n", lead_time_secs);
+        fprintf(stderr, "tolerance: %d msecs\n", tolerance_msecs);
+    }
+
+    start_time = PR_IntervalNow();
+#if defined(XP_UNIX)
+    gettimeofday(&start_time_tv, NULL);
+#endif
+#if defined(WIN32)
+    _ftime(&start_time_tb);
+#endif
+    tolerance = PR_MillisecondsToInterval(tolerance_msecs);
+
+    threads = PR_Malloc(
+            num_thread_scopes * num_thread_funcs * sizeof(PRThread*));
+    if (threads == NULL) {
+        fprintf(stderr, "PR_Malloc failed\n");
+        exit(1);
+    }
+
+    /* start to time out 5 seconds after a rollover date */
+    secs = lead_time_secs + 5;
+    idx = 0;
+    for (i = 0; i < num_thread_scopes; i++) { 
+        for (j = 0; j < num_thread_funcs; j++) {
+            threads[idx] = PR_CreateThread(PR_USER_THREAD, threadFuncs[j],
+                (void*)PR_SecondsToInterval(secs), PR_PRIORITY_NORMAL,
+                threadScopes[i], PR_JOINABLE_THREAD, 0);
+            if (threads[idx] == NULL) {
+                fprintf(stderr, "PR_CreateThread failed\n");
+                exit(1);
+            }
+            secs++;
+            idx++;
+        }
+    }
+    for (idx = 0; idx < num_thread_scopes*num_thread_funcs; idx++) {
+        if (PR_JoinThread(threads[idx]) == PR_FAILURE) {
+            fprintf(stderr, "PR_JoinThread failed\n");
+            exit(1);
+        }
+    }
+    PR_Free(threads);
+    printf("PASS\n");
+    return 0;
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/yield.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/yield.c	Mon Dec 18 10:53:47 2006
@@ -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 <stdio.h>
+#include "prthread.h"
+#include "prinit.h"
+#ifndef XP_OS2
+#include "private/pprmisc.h"
+#include <windows.h>
+#else
+#include "primpl.h"
+#include <os2.h>
+#endif
+
+#define THREADS 10
+
+
+void 
+threadmain(void *_id)
+{
+    int id = (int)_id;
+    int index;
+
+    printf("thread %d alive\n", id);
+    for (index=0; index<10; index++) {
+        printf("thread %d yielding\n", id);
+        PR_Sleep(0);
+        printf("thread %d awake\n", id);
+    }
+    printf("thread %d dead\n", id);
+
+}
+
+main()
+{
+    int index;
+    PRThread *a[THREADS];
+
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 5);
+    PR_STDIO_INIT();
+
+    for (index=0; index<THREADS; index++) {
+        a[index] = PR_CreateThread(PR_USER_THREAD,
+                              threadmain,
+                              (void *)index,
+                              PR_PRIORITY_NORMAL,
+                              index%2?PR_LOCAL_THREAD:PR_GLOBAL_THREAD,
+                              PR_JOINABLE_THREAD,
+                              0);
+    }
+    for(index=0; index<THREADS; index++)
+        PR_JoinThread(a[index]);
+    printf("main dying\n");
+}

Added: freeswitch/trunk/libs/js/nsprpub/pr/tests/zerolen.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/pr/tests/zerolen.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,282 @@
+/* -*- 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 ***** */
+
+/*
+ * Test: zerolen.c 
+ *
+ * Description: a test for Bugzilla bug #17699.  We perform
+ * the same test for PR_Writev, PR_Write, and PR_Send.  In
+ * each test the server thread first fills up the connection
+ * to the client so that the next write operation will fail
+ * with EAGAIN.  Then it calls PR_Writev, PR_Write, or PR_Send
+ * with a zero-length buffer.  The client thread initially
+ * does not read so that the connection can be filled up.
+ * Then it empties the connection so that the server thread's
+ * PR_Writev, PR_Write, or PR_Send call can succeed.
+ *
+ * Bug #17699 is specific to the pthreads version on Unix,
+ * so on other platforms this test does nothing.
+ */
+
+#ifndef XP_UNIX
+
+#include <stdio.h>
+
+int main()
+{
+    printf("PASS\n");
+    return 0;
+}
+
+#else /* XP_UNIX */
+
+#include "nspr.h"
+#include "private/pprio.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+static void ClientThread(void *arg)
+{
+    PRFileDesc *sock;
+    PRNetAddr addr;
+    PRUint16 port = (PRUint16) arg;
+    char buf[1024];
+    PRInt32 nbytes;
+
+    sock = PR_NewTCPSocket();
+    if (NULL == sock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    if (PR_InitializeNetAddr(PR_IpAddrLoopback, port, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+        fprintf(stderr, "PR_Connect failed\n");
+        exit(1);
+    }
+    /*
+     * Sleep 5 seconds to force the server thread to get EAGAIN.
+     */
+    if (PR_Sleep(PR_SecondsToInterval(5)) == PR_FAILURE) {
+        fprintf(stderr, "PR_Sleep failed\n");
+        exit(1);
+    }
+    /*
+     * Then start reading.
+     */
+    while ((nbytes = PR_Read(sock, buf, sizeof(buf))) > 0) {
+        /* empty loop body */
+    }
+    if (-1 == nbytes) {
+        fprintf(stderr, "PR_Read failed\n");
+        exit(1);
+    }
+    if (PR_Close(sock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+}
+
+int main()
+{
+    PRFileDesc *listenSock;
+    PRFileDesc *acceptSock;
+    int osfd;
+    PRThread *clientThread;
+    PRNetAddr addr;
+    char buf[1024];
+    PRInt32 nbytes;
+    PRIOVec iov;
+
+    memset(buf, 0, sizeof(buf)); /* Initialize the buffer. */
+    listenSock = PR_NewTCPSocket();
+    if (NULL == listenSock) {
+        fprintf(stderr, "PR_NewTCPSocket failed\n");
+        exit(1);
+    }
+    if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_InitializeNetAddr failed\n");
+        exit(1);
+    }
+    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_Bind failed\n");
+        exit(1);
+    }
+    /* Find out what port number we are bound to. */
+    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
+        fprintf(stderr, "PR_GetSockName failed\n");
+        exit(1);
+    }
+    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
+        fprintf(stderr, "PR_Listen failed\n");
+        exit(1);
+    }
+
+    /*
+     * First test PR_Writev.
+     */
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+            ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)),
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == clientThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == acceptSock) {
+        fprintf(stderr, "PR_Accept failed\n");
+        exit(1);
+    }
+    osfd = PR_FileDesc2NativeHandle(acceptSock);
+    while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) {
+        /* empty loop body */
+    }
+    if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) {
+        fprintf(stderr, "write failed\n");
+        exit(1);
+    }
+    iov.iov_base = buf;
+    iov.iov_len = 0;
+    printf("calling PR_Writev with a zero-length buffer\n");
+    fflush(stdout);
+    nbytes = PR_Writev(acceptSock, &iov, 1, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes != 0) {
+        fprintf(stderr, "PR_Writev should return 0 but returns %d\n", nbytes);
+        exit(1);
+    }
+    if (PR_Close(acceptSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(clientThread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+
+    /*
+     * Then test PR_Write.
+     */
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+            ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)),
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == clientThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == acceptSock) {
+        fprintf(stderr, "PR_Accept failed\n");
+        exit(1);
+    }
+    osfd = PR_FileDesc2NativeHandle(acceptSock);
+    while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) {
+        /* empty loop body */
+    }
+    if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) {
+        fprintf(stderr, "write failed\n");
+        exit(1);
+    }
+    printf("calling PR_Write with a zero-length buffer\n");
+    fflush(stdout);
+    nbytes = PR_Write(acceptSock, buf, 0);
+    if (nbytes != 0) {
+        fprintf(stderr, "PR_Write should return 0 but returns %d\n", nbytes);
+        exit(1);
+    }
+    if (PR_Close(acceptSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(clientThread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+
+    /*
+     * Finally test PR_Send.
+     */
+    clientThread = PR_CreateThread(PR_USER_THREAD,
+            ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)),
+            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
+    if (NULL == clientThread) {
+        fprintf(stderr, "PR_CreateThread failed\n");
+        exit(1);
+    }
+    acceptSock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT);
+    if (NULL == acceptSock) {
+        fprintf(stderr, "PR_Accept failed\n");
+        exit(1);
+    }
+    osfd = PR_FileDesc2NativeHandle(acceptSock);
+    while ((nbytes = write(osfd, buf, sizeof(buf))) != -1) {
+        /* empty loop body */
+    }
+    if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) {
+        fprintf(stderr, "write failed\n");
+        exit(1);
+    }
+    printf("calling PR_Send with a zero-length buffer\n");
+    fflush(stdout);
+    nbytes = PR_Send(acceptSock, buf, 0, 0, PR_INTERVAL_NO_TIMEOUT);
+    if (nbytes != 0) {
+        fprintf(stderr, "PR_Send should return 0 but returns %d\n", nbytes);
+        exit(1);
+    }
+    if (PR_Close(acceptSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    if (PR_JoinThread(clientThread) == PR_FAILURE) {
+        fprintf(stderr, "PR_JoinThread failed\n");
+        exit(1);
+    }
+
+    if (PR_Close(listenSock) == PR_FAILURE) {
+        fprintf(stderr, "PR_Close failed\n");
+        exit(1);
+    }
+    printf("PASS\n");
+    return 0;
+}
+
+#endif /* XP_UNIX */

Added: freeswitch/trunk/libs/js/nsprpub/tools/.cvsignore
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/tools/.cvsignore	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+Makefile

Added: freeswitch/trunk/libs/js/nsprpub/tools/CVS/Entries
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/tools/CVS/Entries	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5 @@
+/.cvsignore/1.2/Sat May 12 05:12:57 2001//
+/Makefile.in/1.12/Mon Nov  8 02:52:56 2004//
+/httpget.c/3.7/Wed Feb  8 07:12:04 2006//
+/tail.c/3.5/Sun Apr 25 15:01:03 2004//
+D

Added: freeswitch/trunk/libs/js/nsprpub/tools/CVS/Repository
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/tools/CVS/Repository	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+mozilla/nsprpub/tools

Added: freeswitch/trunk/libs/js/nsprpub/tools/CVS/Root
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/tools/CVS/Root	Mon Dec 18 10:53:47 2006
@@ -0,0 +1 @@
+:pserver:anonymous at cvs-mirror.mozilla.org:/cvsroot

Added: freeswitch/trunk/libs/js/nsprpub/tools/Makefile.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/tools/Makefile.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,249 @@
+# 
+# ***** 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
+
+
+DIRS =
+
+CSRCS =             \
+	httpget.c	    \
+	tail.c		    \
+	$(NULL)
+
+ifeq (,$(filter-out WINNT OS2,$(OS_ARCH)))
+PROG_SUFFIX = .exe
+else
+PROG_SUFFIX =
+endif
+
+PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX)))
+
+TARGETS = $(PROGS)
+
+INCLUDES = -I$(dist_includedir) 
+
+NSPR_VERSION = 3
+
+# 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$(NSPR_VERSION)
+LIBPLC = -lplc$(NSPR_VERSION)
+
+ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET), WIN16)
+  LIBPR = $(dist_libdir)/nspr$(NSPR_VERSION).lib
+  LIBPLC= $(dist_libdir)/plc$(NSPR_VERSION).lib
+else
+LDOPTS = -NOLOGO -DEBUG -INCREMENTAL:NO
+LIBPR = $(dist_libdir)/libnspr$(NSPR_VERSION).$(LIB_SUFFIX)
+LIBPLC= $(dist_libdir)/libplc$(NSPR_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
+  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), 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$(NSPR_VERSION)_shr
+LIBPLC = -lplc$(NSPR_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)
+# 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
+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
+
+#####################################################
+#
+# 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 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) $< $(LIBPR) $(LIBPLC) wsock32.lib -out:$@
+endif
+else
+ifeq ($(OS_ARCH),OS2)
+	$(LINK) $(LDOPTS) $< $(LIBPR) $(LIBPLC) $(OS_LIBS) $(EXTRA_LIBS) -o $@
+else
+	$(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPR) $(LIBPLC) $(EXTRA_LIBS) -o $@
+endif
+endif
+endif
+
+export:: $(TARGETS)
+clean::
+	rm -f $(TARGETS)
+

Added: freeswitch/trunk/libs/js/nsprpub/tools/httpget.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/tools/httpget.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,466 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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 ***** */
+
+
+/*
+ * Author: Wan-Teh Chang
+ *
+ * Given an HTTP URL, httpget uses the GET method to fetch the file.
+ * The fetched file is written to stdout by default, or can be
+ * saved in an output file.
+ *
+ * This is a single-threaded program.
+ */
+
+#include "prio.h"
+#include "prnetdb.h"
+#include "prlog.h"
+#include "prerror.h"
+#include "prprf.h"
+#include "prinit.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>  /* for atoi */
+
+#define FCOPY_BUFFER_SIZE (16 * 1024)
+#define INPUT_BUFFER_SIZE 1024
+#define LINE_SIZE 512
+#define HOST_SIZE 256
+#define PORT_SIZE 32
+#define PATH_SIZE 512
+
+/*
+ * A buffer for storing the excess input data for ReadLine.
+ * The data in the buffer starts from (including) the element pointed to
+ * by inputHead, and ends just before (not including) the element pointed
+ * to by inputTail.  The buffer is empty if inputHead == inputTail.
+ */
+
+static char inputBuf[INPUT_BUFFER_SIZE];
+/*
+ * inputBufEnd points just past the end of inputBuf
+ */
+static char *inputBufEnd = inputBuf + sizeof(inputBuf);
+static char *inputHead = inputBuf;
+static char *inputTail = inputBuf;
+
+static PRBool endOfStream = PR_FALSE;
+
+/*
+ * ReadLine --
+ *
+ * Read in a line of text, terminated by CRLF or LF, from fd into buf.
+ * The terminating CRLF or LF is included (always as '\n').  The text
+ * in buf is terminated by a null byte.  The excess bytes are stored in
+ * inputBuf for use in the next ReadLine call or FetchFile call.
+ * Returns the number of bytes in buf.  0 means end of stream.  Returns
+ * -1 if read fails.
+ */
+
+PRInt32 ReadLine(PRFileDesc *fd, char *buf, PRUint32 bufSize)
+{
+    char *dst = buf;
+    char *bufEnd = buf + bufSize;  /* just past the end of buf */
+    PRBool lineFound = PR_FALSE;
+    char *crPtr = NULL;  /* points to the CR ('\r') character */
+    PRInt32 nRead;
+
+loop:
+    PR_ASSERT(inputBuf <= inputHead && inputHead <= inputTail
+	    && inputTail <= inputBufEnd);
+    while (lineFound == PR_FALSE && inputHead != inputTail
+	    && dst < bufEnd - 1) {
+	if (*inputHead == '\r') {
+	    crPtr = dst;
+	} else if (*inputHead == '\n') {
+	    lineFound = PR_TRUE;
+	    if (crPtr == dst - 1) {
+		dst--; 
+	    }
+	}
+	*(dst++) = *(inputHead++);
+    }
+    if (lineFound == PR_TRUE || dst == bufEnd - 1 || endOfStream == PR_TRUE) {
+	*dst = '\0';
+	return dst - buf;
+    }
+
+    /*
+     * The input buffer should be empty now
+     */
+    PR_ASSERT(inputHead == inputTail);
+
+    nRead = PR_Read(fd, inputBuf, sizeof(inputBuf));
+    if (nRead == -1) {
+	*dst = '\0';
+	return -1;
+    } else if (nRead == 0) {
+	endOfStream = PR_TRUE;
+	*dst = '\0';
+	return dst - buf;
+    }
+    inputHead = inputBuf;
+    inputTail = inputBuf + nRead;
+    goto loop;
+}
+
+PRInt32 DrainInputBuffer(char *buf, PRUint32 bufSize)
+{
+    PRInt32 nBytes = inputTail - inputHead;
+
+    if (nBytes == 0) {
+	if (endOfStream) {
+	    return -1;
+	} else {
+	    return 0;
+	}
+    }
+    if ((PRInt32) bufSize < nBytes) {
+	nBytes = bufSize;
+    }
+    memcpy(buf, inputHead, nBytes);
+    inputHead += nBytes;
+    return nBytes;
+}
+
+PRStatus FetchFile(PRFileDesc *in, PRFileDesc *out)
+{
+    char buf[FCOPY_BUFFER_SIZE];
+    PRInt32 nBytes;
+
+    while ((nBytes = DrainInputBuffer(buf, sizeof(buf))) > 0) {
+	if (PR_Write(out, buf, nBytes) != nBytes) {
+            fprintf(stderr, "httpget: cannot write to file\n");
+	    return PR_FAILURE;
+	}
+    }
+    if (nBytes < 0) {
+	/* Input buffer is empty and end of stream */
+	return PR_SUCCESS;
+    }
+    while ((nBytes = PR_Read(in, buf, sizeof(buf))) > 0) {
+	if (PR_Write(out, buf, nBytes) != nBytes) {
+	    fprintf(stderr, "httpget: cannot write to file\n");
+	    return PR_FAILURE;
+        }
+    }
+    if (nBytes < 0) {
+	fprintf(stderr, "httpget: cannot read from socket\n");
+	return PR_FAILURE;
+    }
+    return PR_SUCCESS;
+}
+
+PRStatus FastFetchFile(PRFileDesc *in, PRFileDesc *out, PRUint32 size)
+{
+    PRInt32 nBytes;
+    PRFileMap *outfMap;
+    void *addr;
+    char *start;
+    PRUint32 rem;
+    PRUint32 bytesToRead;
+    PRStatus rv;
+    PRInt64 sz64;
+
+    LL_UI2L(sz64, size);
+    outfMap = PR_CreateFileMap(out, sz64, PR_PROT_READWRITE);
+    PR_ASSERT(outfMap);
+    addr = PR_MemMap(outfMap, LL_ZERO, size);
+    if (addr == (void *) -1) {
+	fprintf(stderr, "cannot memory-map file: (%d, %d)\n", PR_GetError(),
+		PR_GetOSError());
+
+	PR_CloseFileMap(outfMap);
+	return PR_FAILURE;
+    }
+    PR_ASSERT(addr != (void *) -1);
+    start = (char *) addr;
+    rem = size;
+    while ((nBytes = DrainInputBuffer(start, rem)) > 0) {
+	start += nBytes;
+	rem -= nBytes;
+    }
+    if (nBytes < 0) {
+	/* Input buffer is empty and end of stream */
+	return PR_SUCCESS;
+    }
+    bytesToRead = (rem < FCOPY_BUFFER_SIZE) ? rem : FCOPY_BUFFER_SIZE;
+    while (rem > 0 && (nBytes = PR_Read(in, start, bytesToRead)) > 0) {
+	start += nBytes;
+	rem -= nBytes;
+        bytesToRead = (rem < FCOPY_BUFFER_SIZE) ? rem : FCOPY_BUFFER_SIZE;
+    }
+    if (nBytes < 0) {
+	fprintf(stderr, "httpget: cannot read from socket\n");
+	return PR_FAILURE;
+    }
+    rv = PR_MemUnmap(addr, size);
+    PR_ASSERT(rv == PR_SUCCESS);
+    rv = PR_CloseFileMap(outfMap);
+    PR_ASSERT(rv == PR_SUCCESS);
+    return PR_SUCCESS;
+}
+
+PRStatus ParseURL(char *url, char *host, PRUint32 hostSize,
+    char *port, PRUint32 portSize, char *path, PRUint32 pathSize)
+{
+    char *start, *end;
+    char *dst;
+    char *hostEnd;
+    char *portEnd;
+    char *pathEnd;
+
+    if (strncmp(url, "http", 4)) {
+	fprintf(stderr, "httpget: the protocol must be http\n");
+	return PR_FAILURE;
+    }
+    if (strncmp(url + 4, "://", 3) || url[7] == '\0') {
+	fprintf(stderr, "httpget: malformed URL: %s\n", url);
+	return PR_FAILURE;
+    }
+
+    start = end = url + 7;
+    dst = host;
+    hostEnd = host + hostSize;
+    while (*end && *end != ':' && *end != '/') {
+	if (dst == hostEnd - 1) {
+	    fprintf(stderr, "httpget: host name too long\n");
+	    return PR_FAILURE;
+	}
+	*(dst++) = *(end++);
+    }
+    *dst = '\0';
+
+    if (*end == '\0') {
+	PR_snprintf(port, portSize, "%d", 80);
+	PR_snprintf(path, pathSize, "%s", "/");
+	return PR_SUCCESS;
+    }
+
+    if (*end == ':') {
+	end++;
+	dst = port;
+	portEnd = port + portSize;
+	while (*end && *end != '/') {
+	    if (dst == portEnd - 1) {
+		fprintf(stderr, "httpget: port number too long\n");
+		return PR_FAILURE;
+	    }
+	    *(dst++) = *(end++);
+        }
+	*dst = '\0';
+	if (*end == '\0') {
+	    PR_snprintf(path, pathSize, "%s", "/");
+	    return PR_SUCCESS;
+        }
+    } else {
+	PR_snprintf(port, portSize, "%d", 80);
+    }
+
+    dst = path;
+    pathEnd = path + pathSize;
+    while (*end) {
+	if (dst == pathEnd - 1) {
+	    fprintf(stderr, "httpget: file pathname too long\n");
+	    return PR_FAILURE;
+	}
+	*(dst++) = *(end++);
+    }
+    *dst = '\0';
+    return PR_SUCCESS;
+}
+
+void PrintUsage(void) {
+    fprintf(stderr, "usage: httpget url\n"
+		    "       httpget -o outputfile url\n"
+		    "       httpget url -o outputfile\n");
+}
+
+int main(int argc, char **argv)
+{
+    PRHostEnt hostentry;
+    char buf[PR_NETDB_BUF_SIZE];
+    PRNetAddr addr;
+    PRFileDesc *socket = NULL, *file = NULL;
+    PRIntn cmdSize;
+    char host[HOST_SIZE];
+    char port[PORT_SIZE];
+    char path[PATH_SIZE];
+    char line[LINE_SIZE];
+    int exitStatus = 0;
+    PRBool endOfHeader = PR_FALSE;
+    char *url;
+    char *fileName = NULL;
+    PRUint32 fileSize;
+
+    if (argc != 2 && argc != 4) {
+	PrintUsage();
+	exit(1);
+    }
+
+    if (argc == 2) {
+	/*
+	 * case 1: httpget url
+	 */
+	url = argv[1];
+    } else {
+	if (strcmp(argv[1], "-o") == 0) {
+	    /*
+	     * case 2: httpget -o outputfile url
+	     */
+	    fileName = argv[2];
+	    url = argv[3];
+        } else {
+	    /*
+	     * case 3: httpget url -o outputfile
+	     */
+	    url = argv[1];
+	    if (strcmp(argv[2], "-o") != 0) {
+		PrintUsage();
+		exit(1);
+            }
+	    fileName = argv[3];
+	}
+    }
+
+    if (ParseURL(url, host, sizeof(host), port, sizeof(port),
+	    path, sizeof(path)) == PR_FAILURE) {
+	exit(1);
+    }
+
+    if (PR_GetHostByName(host, buf, sizeof(buf), &hostentry)
+	    == PR_FAILURE) {
+        fprintf(stderr, "httpget: unknown host name: %s\n", host);
+	exit(1);
+    }
+
+    addr.inet.family = PR_AF_INET;
+    addr.inet.port = PR_htons((short) atoi(port));
+    addr.inet.ip = *((PRUint32 *) hostentry.h_addr_list[0]);
+
+    socket = PR_NewTCPSocket();
+    if (socket == NULL) {
+	fprintf(stderr, "httpget: cannot create new tcp socket\n");
+	exit(1);
+    }
+
+    if (PR_Connect(socket, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
+	fprintf(stderr, "httpget: cannot connect to http server\n");
+	exitStatus = 1;
+	goto done;
+    }
+
+    if (fileName == NULL) {
+	file = PR_STDOUT;
+    } else {
+        file = PR_Open(fileName, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE,
+		00777);
+        if (file == NULL) {
+	    fprintf(stderr, "httpget: cannot open file %s: (%d, %d)\n",
+		    fileName, PR_GetError(), PR_GetOSError());
+	    exitStatus = 1;
+	    goto done;
+	}
+    }
+
+    cmdSize = PR_snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\n\r\n", path);
+    PR_ASSERT(cmdSize == (PRIntn) strlen("GET  HTTP/1.0\r\n\r\n")
+            + (PRIntn) strlen(path));
+    if (PR_Write(socket, buf, cmdSize) != cmdSize) {
+	fprintf(stderr, "httpget: cannot write to http server\n");
+	exitStatus = 1;
+	goto done;
+    }
+
+    if (ReadLine(socket, line, sizeof(line)) <= 0) {
+	fprintf(stderr, "httpget: cannot read line from http server\n");
+	exitStatus = 1;
+	goto done;
+    }
+
+    /* HTTP response: 200 == OK */
+    if (strstr(line, "200") == NULL) {
+	fprintf(stderr, "httpget: %s\n", line);
+	exitStatus = 1;
+	goto done;
+    }
+
+    while (ReadLine(socket, line, sizeof(line)) > 0) {
+	if (line[0] == '\n') {
+	    endOfHeader = PR_TRUE;
+	    break;
+	}
+	if (strncmp(line, "Content-Length", 14) == 0
+		|| strncmp(line, "Content-length", 14) == 0) {
+	    char *p = line + 14;
+
+	    while (*p == ' ' || *p == '\t') {
+		p++;
+	    }
+	    if (*p != ':') {
+		continue;
+            }
+	    p++;
+	    while (*p == ' ' || *p == '\t') {
+		p++;
+	    }
+	    fileSize = 0;
+	    while ('0' <= *p && *p <= '9') {
+		fileSize = 10 * fileSize + (*p - '0');
+		p++;
+            }
+	}
+    }
+    if (endOfHeader == PR_FALSE) {
+	fprintf(stderr, "httpget: cannot read line from http server\n");
+	exitStatus = 1;
+	goto done;
+    }
+
+    if (fileName == NULL || fileSize == 0) {
+        FetchFile(socket, file);
+    } else {
+	FastFetchFile(socket, file, fileSize);
+    }
+
+done:
+    if (socket) PR_Close(socket);
+    if (file) PR_Close(file);
+    PR_Cleanup();
+    return exitStatus;
+}

Added: freeswitch/trunk/libs/js/nsprpub/tools/tail.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/nsprpub/tools/tail.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,166 @@
+/* -*- 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 "prio.h"
+#include "prprf.h"
+#include "prinit.h"
+#include "prthread.h"
+#include "prinrval.h"
+
+#include "plerror.h"
+#include "plgetopt.h"
+
+#include <stdlib.h>
+
+#define BUFFER_SIZE 500
+
+static PRFileDesc *out = NULL, *err = NULL;
+
+static void Help(void)
+{
+    PR_fprintf(err, "Usage: tail [-n <n>] [-f] [-h] <filename>\n");
+    PR_fprintf(err, "\t-t <n>	Dally time in milliseconds\n");
+    PR_fprintf(err, "\t-n <n>	Number of bytes before <eof>\n");
+    PR_fprintf(err, "\t-f   	Follow the <eof>\n");
+    PR_fprintf(err, "\t-h   	This message and nothing else\n");
+}  /* Help */
+
+PRIntn main(PRIntn argc, char **argv)
+{
+	PRIntn rv = 0;
+    PLOptStatus os;
+	PRStatus status;
+	PRFileDesc *file;
+	PRFileInfo fileInfo;
+	PRIntervalTime dally;
+	char buffer[BUFFER_SIZE];
+	PRBool follow = PR_FALSE;
+	const char *filename = NULL;
+	PRUint32 position = 0, seek = 0, time = 0;
+    PLOptState *opt = PL_CreateOptState(argc, argv, "hfn:");
+
+    out = PR_GetSpecialFD(PR_StandardOutput);
+    err = PR_GetSpecialFD(PR_StandardError);
+
+    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+    {
+        if (PL_OPT_BAD == os) continue;
+        switch (opt->option)
+        {
+		case 0:  /* it's the filename */
+			filename = opt->value;
+			break;
+        case 'n':  /* bytes before end of file */
+            seek = atoi(opt->value);
+            break;
+        case 't':  /* dally time */
+            time = atoi(opt->value);
+            break;
+        case 'f':  /* follow the end of file */
+            follow = PR_TRUE;
+            break;
+        case 'h':  /* user wants some guidance */
+            Help();  /* so give him an earful */
+            return 2;  /* but not a lot else */
+            break;
+         default:
+            break;
+        }
+    }
+    PL_DestroyOptState(opt);
+
+	if (0 == time) time = 1000;
+	dally = PR_MillisecondsToInterval(time);
+
+    if (NULL == filename)
+    {
+        (void)PR_fprintf(out, "Input file not specified\n");
+        rv = 1; goto done;
+    }
+	file = PR_Open(filename, PR_RDONLY, 0);
+	if (NULL == file)
+	{
+		PL_FPrintError(err, "File cannot be opened for reading");
+		return 1;
+	}
+
+	status = PR_GetOpenFileInfo(file, &fileInfo);
+	if (PR_FAILURE == status)
+	{
+		PL_FPrintError(err, "Cannot acquire status of file");
+		rv = 1; goto done;
+	}
+	if (seek > 0)
+	{
+	    if (seek > fileInfo.size) seek = 0;
+		position = PR_Seek(file, (fileInfo.size - seek), PR_SEEK_SET);
+		if (-1 == (PRInt32)position)
+			PL_FPrintError(err, "Cannot seek to starting position");
+	}
+
+	do
+	{
+		while (position < fileInfo.size)
+		{
+			PRInt32 read, bytes = fileInfo.size - position;
+			if (bytes > sizeof(buffer)) bytes = sizeof(buffer);
+			read = PR_Read(file, buffer, bytes);
+			if (read != bytes)
+				PL_FPrintError(err, "Cannot read to eof");
+			position += read;
+			PR_Write(out, buffer, read);
+		}
+
+		if (follow)
+		{
+			PR_Sleep(dally);
+			status = PR_GetOpenFileInfo(file, &fileInfo);
+			if (PR_FAILURE == status)
+			{
+				PL_FPrintError(err, "Cannot acquire status of file");
+				rv = 1; goto done;
+			}
+		}
+	} while (follow);
+
+done:
+	PR_Close(file);
+
+	return rv;
+}  /* main */
+
+/* tail.c */

Added: freeswitch/trunk/libs/js/shtool
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/shtool	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3990 @@
+#!/bin/sh
+##
+##  GNU shtool -- The GNU Portable Shell Tool
+##  Copyright (c) 1994-2006 Ralf S. Engelschall <rse at engelschall.com>
+##
+##  See http://www.gnu.org/software/shtool/ for more information.
+##  See ftp://ftp.gnu.org/gnu/shtool/ for latest version.
+##
+##  Version:  2.0.6 (19-Apr-2006)
+##  Contents: all available modules
+##
+
+##
+##  This program is free software; you can redistribute it and/or modify
+##  it under the terms of the GNU General Public License as published by
+##  the Free Software Foundation; either version 2 of the License, or
+##  (at your option) any later version.
+##
+##  This program is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+##  General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, write to the Free Software
+##  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+##  USA, or contact Ralf S. Engelschall <rse at engelschall.com>.
+##
+##  NOTICE: Given that you include this file verbatim into your own
+##  source tree, you are justified in saying that it remains separate
+##  from your package, and that this way you are simply just using GNU
+##  shtool. So, in this situation, there is no requirement that your
+##  package itself is licensed under the GNU General Public License in
+##  order to take advantage of GNU shtool.
+##
+
+##
+##  Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]
+##
+##  Available commands:
+##    echo       Print string with optional construct expansion
+##    mdate      Pretty-print modification time of a file or dir
+##    table      Pretty-print a field-separated list as a table
+##    prop       Display progress with a running propeller
+##    move       Move files with simultaneous substitution
+##    install    Install a program, script or datafile
+##    mkdir      Make one or more directories
+##    mkln       Make link with calculation of relative paths
+##    mkshadow   Make a shadow tree through symbolic links
+##    fixperm    Fix file permissions inside a source tree
+##    rotate     Logfile rotation
+##    tarball    Roll distribution tarballs
+##    subst      Apply sed(1) substitution operations
+##    platform   Platform Identification Utility
+##    arx        Extended archive command
+##    slo        Separate linker options by library class
+##    scpp       Sharing C Pre-Processor
+##    version    Maintain a version information file
+##    path       Deal with program paths
+##
+
+#   maximum Bourne-Shell compatibility
+if [ ".$ZSH_VERSION" != . ] && (emulate sh) >/dev/null 2>&1; then
+    #   reconfigure zsh(1)
+    emulate sh
+    NULLCMD=:
+    alias -g '${1+"$@"}'='"$@"'
+elif [ ".$BASH_VERSION" != . ] && (set -o posix) >/dev/null 2>&1; then
+    #   reconfigure bash(1)
+    set -o posix
+fi
+
+#   maximum independence of NLS nuisances
+for var in \
+    LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+    LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+    LC_TELEPHONE LC_TIME
+do
+    if (set +x; test -z "`(eval $var=C; export $var) 2>&1`"); then
+        eval $var=C; export $var
+    else
+        unset $var
+    fi
+done
+
+#   initial command line handling
+if [ $# -eq 0 ]; then
+    echo "$0:Error: invalid command line" 1>&2
+    echo "$0:Hint:  run \`$0 -h' for usage" 1>&2
+    exit 1
+fi
+if [ ".$1" = ".-h" ] || [ ".$1" = ".--help" ]; then
+    echo "This is GNU shtool, version 2.0.6 (19-Apr-2006)"
+    echo 'Copyright (c) 1994-2006 Ralf S. Engelschall <rse at engelschall.com>'
+    echo 'Report bugs to <bug-shtool at gnu.org>'
+    echo ''
+    echo 'Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]'
+    echo ''
+    echo 'Available global <options>:'
+    echo '  -v, --version   display shtool version information'
+    echo '  -h, --help      display shtool usage help page (this one)'
+    echo '  -d, --debug     display shell trace information'
+    echo '  -r, --recreate  recreate this shtool script via shtoolize'
+    echo ''
+    echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:'
+    echo '  echo     [-n|--newline] [-e|--expand] [<string> ...]'
+    echo '  mdate    [-n|--newline] [-z|--zero] [-s|--shorten] [-d|--digits]'
+    echo '           [-f|--field-sep <str>] [-o|--order <spec>] <path>'
+    echo '  table    [-F|--field-sep <sep>] [-w|--width <width>] [-c|--columns'
+    echo '           <cols>] [-s|--strip <strip>] <str><sep><str>...'
+    echo '  prop     [-p|--prefix <str>]'
+    echo '  move     [-v|--verbose] [-t|--trace] [-e|--expand] [-p|--preserve]'
+    echo '           <src-file> <dst-file>'
+    echo '  install  [-v|--verbose] [-t|--trace] [-d|--mkdir] [-c|--copy]'
+    echo '           [-C|--compare-copy] [-s|--strip] [-m|--mode <mode>]'
+    echo '           [-o|--owner <owner>] [-g|--group <group>] [-e|--exec'
+    echo '           <sed-cmd>] <file> [<file> ...] <path>'
+    echo '  mkdir    [-t|--trace] [-f|--force] [-p|--parents] [-m|--mode'
+    echo '           <mode>] [-o|--owner <owner>] [-g|--group <group>] <dir>'
+    echo '           [<dir> ...]'
+    echo '  mkln     [-t|--trace] [-f|--force] [-s|--symbolic] <src-path>'
+    echo '           [<src-path> ...] <dst-path>'
+    echo '  mkshadow [-v|--verbose] [-t|--trace] [-a|--all] <src-dir> <dst-dir>'
+    echo '  fixperm  [-v|--verbose] [-t|--trace] <path> [<path> ...]'
+    echo '  rotate   [-v|--verbose] [-t|--trace] [-f|--force] [-n|--num-files'
+    echo '           <count>] [-s|--size <size>] [-c|--copy] [-r|--remove]'
+    echo '           [-a|--archive-dir <dir>] [-z|--compress [<tool>:]<level>]'
+    echo '           [-b|--background] [-d|--delay] [-p|--pad <len>] [-m|--mode'
+    echo '           <mode>] [-o|--owner <owner>] [-g|--group <group>] [-M|--migrate'
+    echo '           <cmd>] [-P|--prolog <cmd>] [-E|--epilog <cmd>] <file> [...]'
+    echo '  tarball  [-t|--trace] [-v|--verbose] [-o|--output <tarball>]'
+    echo '           [-c|--compress <prog>] [-d|--directory <dir>] [-u|--user'
+    echo '           <user>] [-g|--group <group>] [-e|--exclude <pattern>]'
+    echo '           <path> [<path> ...]'
+    echo '  subst    [-v|--verbose] [-t|--trace] [-n|--nop] [-w|--warning]'
+    echo '           [-q|--quiet] [-s|--stealth] [-i|--interactive] [-b|--backup'
+    echo '           <ext>] [-e|--exec <cmd>] [-f|--file <cmd-file>] [<file>]'
+    echo '           [...]'
+    echo '  platform [-F|--format <format>] [-S|--sep <string>] [-C|--conc'
+    echo '           <string>] [-L|--lower] [-U|--upper] [-v|--verbose]'
+    echo '           [-c|--concise] [-n|--no-newline] [-t|--type <type>]'
+    echo '           [-V|--version] [-h|--help]'
+    echo '  arx      [-t|--trace] [-C|--command <cmd>] <op> <archive> [<file>'
+    echo '           ...]'
+    echo '  slo      [-p|--prefix <str>] -- -L<dir> -l<lib> [-L<dir> -l<lib>'
+    echo '           ...]'
+    echo '  scpp     [-v|--verbose] [-p|--preserve] [-f|--filter <filter>]'
+    echo '           [-o|--output <ofile>] [-t|--template <tfile>] [-M|--mark'
+    echo '           <mark>] [-D|--define <dname>] [-C|--class <cname>]'
+    echo '           <file> [<file> ...]'
+    echo '  version  [-l|--language <lang>] [-n|--name <name>] [-p|--prefix'
+    echo '           <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase'
+    echo '           <knob>] [-d|--display <type>] <file>'
+    echo '  path     [-s|--suppress] [-r|--reverse] [-d|--dirname] [-b|--basename]'
+    echo '           [-m|--magic] [-p|--path <path>] <str> [<str> ...]'
+    echo ''
+    exit 0
+fi
+if [ ".$1" = ".-v" ] || [ ".$1" = ".--version" ]; then
+    echo "GNU shtool 2.0.6 (19-Apr-2006)"
+    exit 0
+fi
+if [ ".$1" = ".-r" ] || [ ".$1" = ".--recreate" ]; then
+    shtoolize -oshtool all
+    exit 0
+fi
+if [ ".$1" = ".-d" ] || [ ".$1" = ".--debug" ]; then
+    shift
+    set -x
+fi
+name=`echo "$0" | sed -e 's;.*/\([^/]*\)$;\1;' -e 's;-sh$;;' -e 's;\.sh$;;'`
+case "$name" in
+    echo|mdate|table|prop|move|install|mkdir|mkln|mkshadow|fixperm|rotate|tarball|subst|platform|arx|slo|scpp|version|path )
+        #   implicit tool command selection
+        tool="$name"
+        ;;
+    * )
+        #   explicit tool command selection
+        tool="$1"
+        shift
+        ;;
+esac
+arg_spec=""
+opt_spec=""
+gen_tmpfile=no
+
+##
+##  DISPATCH INTO SCRIPT PROLOG
+##
+
+case $tool in
+    echo )
+        str_tool="echo"
+        str_usage="[-n|--newline] [-e|--expand] [<string> ...]"
+        arg_spec="0+"
+        opt_spec="n.e."
+        opt_alias="n:newline,e:expand"
+        opt_n=no
+        opt_e=no
+        ;;
+    mdate )
+        str_tool="mdate"
+        str_usage="[-n|--newline] [-z|--zero] [-s|--shorten] [-d|--digits] [-f|--field-sep <str>] [-o|--order <spec>] <path>"
+        arg_spec="1="
+        opt_spec="n.z.s.d.f:o:"
+        opt_alias="n:newline,z:zero,s:shorten,d:digits,f:field-sep,o:order"
+        opt_n=no
+        opt_z=no
+        opt_s=no
+        opt_d=no
+        opt_f=" "
+        opt_o="dmy"
+        ;;
+    table )
+        str_tool="table"
+        str_usage="[-F|--field-sep <sep>] [-w|--width <width>] [-c|--columns <cols>] [-s|--strip <strip>] <str><sep><str>..."
+        arg_spec="1+"
+        opt_spec="F:w:c:s:"
+        opt_alias="F:field-sep,w:width,c:columns,s:strip"
+        opt_F=":"
+        opt_w=15
+        opt_c=3
+        opt_s=79
+        ;;
+    prop )
+        str_tool="prop"
+        str_usage="[-p|--prefix <str>]"
+        arg_spec="0="
+        opt_spec="p:"
+        opt_alias="p:prefix"
+        opt_p=""
+        ;;
+    move )
+        str_tool="move"
+        str_usage="[-v|--verbose] [-t|--trace] [-e|--expand] [-p|--preserve] <src-file> <dst-file>"
+        arg_spec="2="
+        opt_spec="v.t.e.p."
+        opt_alias="v:verbose,t:trace,e:expand,p:preserve"
+        opt_v=no
+        opt_t=no
+        opt_e=no
+        opt_p=no
+        ;;
+    install )
+        str_tool="install"
+        str_usage="[-v|--verbose] [-t|--trace] [-d|--mkdir] [-c|--copy] [-C|--compare-copy] [-s|--strip] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] [-e|--exec <sed-cmd>] <file> [<file> ...] <path>"
+        arg_spec="1+"
+        opt_spec="v.t.d.c.C.s.m:o:g:e+"
+        opt_alias="v:verbose,t:trace,d:mkdir,c:copy,C:compare-copy,s:strip,m:mode,o:owner,g:group,e:exec"
+        opt_v=no
+        opt_t=no
+        opt_d=no
+        opt_c=no
+        opt_C=no
+        opt_s=no
+        opt_m="0755"
+        opt_o=""
+        opt_g=""
+        opt_e=""
+        ;;
+    mkdir )
+        str_tool="mkdir"
+        str_usage="[-t|--trace] [-f|--force] [-p|--parents] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] <dir> [<dir> ...]"
+        arg_spec="1+"
+        opt_spec="t.f.p.m:o:g:"
+        opt_alias="t:trace,f:force,p:parents,m:mode,o:owner,g:group"
+        opt_t=no
+        opt_f=no
+        opt_p=no
+        opt_m=""
+        opt_o=""
+        opt_g=""
+        ;;
+    mkln )
+        str_tool="mkln"
+        str_usage="[-t|--trace] [-f|--force] [-s|--symbolic] <src-path> [<src-path> ...] <dst-path>"
+        arg_spec="2+"
+        opt_spec="t.f.s."
+        opt_alias="t:trace,f:force,s:symbolic"
+        opt_t=no
+        opt_f=no
+        opt_s=no
+        ;;
+    mkshadow )
+        str_tool="mkshadow"
+        str_usage="[-v|--verbose] [-t|--trace] [-a|--all] <src-dir> <dst-dir>"
+        arg_spec="2="
+        opt_spec="v.t.a."
+        opt_alias="v:verbose,t:trace,a:all"
+        opt_v=no
+        opt_t=no
+        opt_a=no
+        ;;
+    fixperm )
+        str_tool="fixperm"
+        str_usage="[-v|--verbose] [-t|--trace] <path> [<path> ...]"
+        arg_spec="1+"
+        opt_spec="v.t."
+        opt_alias="v:verbose,t:trace"
+        opt_v=no
+        opt_t=no
+        ;;
+    rotate )
+        str_tool="rotate"
+        str_usage="[-v|--verbose] [-t|--trace] [-f|--force] [-n|--num-files <count>] [-s|--size <size>] [-c|--copy] [-r|--remove] [-a|--archive-dir <dir>] [-z|--compress [<tool>:]<level>] [-b|--background] [-d|--delay] [-p|--pad <len>] [-m|--mode <mode>] [-o|--owner <owner>] [-g|--group <group>] [-M|--migrate <cmd>] [-P|--prolog <cmd>] [-E|--epilog <cmd>] <file> [...]"
+        arg_spec="1+"
+        opt_spec="v.t.f.n:s:c.r.a:z:b.d.p:o:g:m:M:P:E:"
+        opt_alias="v:verbose,t:trace,f:force,n:num-files,s:size,c:copy,r:remove,a:archive-dir,z:compress,b:background,d:delay,p:pad,o:owner,g:group,m:mode,M:migrate,P:prolog,E:epilog"
+        opt_v=no
+        opt_t=no
+        opt_f=no
+        opt_n=10
+        opt_s=""
+        opt_c=no
+        opt_r=no
+        opt_a=""
+        opt_z=""
+        opt_b=no
+        opt_d=no
+        opt_p=1
+        opt_o=""
+        opt_g=""
+        opt_m=""
+        opt_M=""
+        opt_P=""
+        opt_E=""
+        ;;
+    tarball )
+        str_tool="tarball"
+        str_usage="[-t|--trace] [-v|--verbose] [-o|--output <tarball>] [-c|--compress <prog>] [-d|--directory <dir>] [-u|--user <user>] [-g|--group <group>] [-e|--exclude <pattern>] <path> [<path> ...]"
+        gen_tmpfile=yes
+        arg_spec="1+"
+        opt_spec="t.v.o:c:d:u:g:e:"
+        opt_alias="t:trace,v:verbose,o:output,c:compress,d:directory,u:user,g:group,e:exclude"
+        opt_t=no
+        opt_v=no
+        opt_o=""
+        opt_c=""
+        opt_d=""
+        opt_u=""
+        opt_g=""
+        opt_e="CVS,\\.cvsignore,\\.svn,\\.[oa]\$"
+        ;;
+    subst )
+        str_tool="subst"
+        str_usage="[-v|--verbose] [-t|--trace] [-n|--nop] [-w|--warning] [-q|--quiet] [-s|--stealth] [-i|--interactive] [-b|--backup <ext>] [-e|--exec <cmd>] [-f|--file <cmd-file>] [<file>] [...]"
+        gen_tmpfile=yes
+        arg_spec="0+"
+        opt_spec="v.t.n.w.q.s.i.b:e+f:"
+        opt_alias="v:verbose,t:trace,n:nop,w:warning,q:quiet,s:stealth,i:interactive,b:backup,e:exec,f:file"
+        opt_v=no
+        opt_t=no
+        opt_n=no
+        opt_w=no
+        opt_q=no
+        opt_s=no
+        opt_i=no
+        opt_b=""
+        opt_e=""
+        opt_f=""
+        ;;
+    platform )
+        str_tool="platform"
+        str_usage="[-F|--format <format>] [-S|--sep <string>] [-C|--conc <string>] [-L|--lower] [-U|--upper] [-v|--verbose] [-c|--concise] [-n|--no-newline] [-t|--type <type>] [-V|--version] [-h|--help]"
+        arg_spec="0="
+        opt_spec="F:S:C:L.U.v.c.n.t:d.V.h."
+        opt_alias="F:format,S:sep,C:conc,L:lower,U:upper,v:verbose,c:consise,t:type,n:no-newline,V:version,h:help"
+        opt_F="%{sp} (%{ap})"
+        opt_S=" "
+        opt_C="/"
+        opt_L=no
+        opt_U=no
+        opt_t=""
+        opt_v=no
+        opt_c=no
+        opt_n=no
+        opt_V=no
+        opt_h=no
+        ;;
+    arx )
+        str_tool="arx"
+        str_usage="[-t|--trace] [-C|--command <cmd>] <op> <archive> [<file> ...]"
+        arg_spec="2+"
+        opt_spec="t.C:"
+        opt_alias="t:trace,C:command"
+        opt_t=no
+        opt_C="ar"
+        ;;
+    slo )
+        str_tool="slo"
+        str_usage="[-p|--prefix <str>] -- -L<dir> -l<lib> [-L<dir> -l<lib> ...]"
+        arg_spec="1+"
+        opt_spec="p:"
+        opt_alias="p:prefix"
+        opt_p="SLO_"
+        ;;
+    scpp )
+        str_tool="scpp"
+        str_usage="[-v|--verbose] [-p|--preserve] [-f|--filter <filter>] [-o|--output <ofile>] [-t|--template <tfile>] [-M|--mark <mark>] [-D|--define <dname>] [-C|--class <cname>] <file> [<file> ...]"
+        gen_tmpfile=yes
+        arg_spec="1+"
+        opt_spec="v.p.f+o:t:M:D:C:"
+        opt_alias="v:verbose,p:preserve,f:filter,o:output,t:template,M:mark,D:define,C:class"
+        opt_v=no
+        opt_p=no
+        opt_f=""
+        opt_o="lib.h"
+        opt_t="lib.h.in"
+        opt_M="%%MARK%%"
+        opt_D="cpp"
+        opt_C="intern"
+        ;;
+    version )
+        str_tool="version"
+        str_usage="[-l|--language <lang>] [-n|--name <name>] [-p|--prefix <prefix>] [-s|--set <version>] [-e|--edit] [-i|--increase <knob>] [-d|--display <type>] <file>"
+        arg_spec="1="
+        opt_spec="l:n:p:s:i:e.d:"
+        opt_alias="l:language,n:name,p:prefix,s:set,e:edit,i:increase,d:display"
+        opt_l="txt"
+        opt_n="unknown"
+        opt_p=""
+        opt_s=""
+        opt_e="no"
+        opt_i=""
+        opt_d="short"
+        ;;
+    path )
+        str_tool="path"
+        str_usage="[-s|--suppress] [-r|--reverse] [-d|--dirname] [-b|--basename] [-m|--magic] [-p|--path <path>] <str> [<str> ...]"
+        gen_tmpfile=yes
+        arg_spec="1+"
+        opt_spec="s.r.d.b.m.p:"
+        opt_alias="s:suppress,r:reverse,d:dirname,b:basename,m:magic,p:path"
+        opt_s=no
+        opt_r=no
+        opt_d=no
+        opt_b=no
+        opt_m=no
+        opt_p="$PATH"
+        ;;
+    -* )
+        echo "$0:Error: unknown option \`$tool'" 2>&1
+        echo "$0:Hint:  run \`$0 -h' for usage" 2>&1
+        exit 1
+        ;;
+    * )
+        echo "$0:Error: unknown command \`$tool'" 2>&1
+        echo "$0:Hint:  run \`$0 -h' for usage" 2>&1
+        exit 1
+        ;;
+esac
+
+##
+##  COMMON UTILITY CODE
+##
+
+#   commonly used ASCII values
+ASC_TAB="	"
+ASC_NL="
+"
+
+#   determine name of tool
+if [ ".$tool" != . ]; then
+    #   used inside shtool script
+    toolcmd="$0 $tool"
+    toolcmdhelp="shtool $tool"
+    msgprefix="shtool:$tool"
+else
+    #   used as standalone script
+    toolcmd="$0"
+    toolcmdhelp="sh $0"
+    msgprefix="$str_tool"
+fi
+
+#   parse argument specification string
+eval `echo $arg_spec |\
+      sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
+
+#   parse option specification string
+eval `echo h.$opt_spec |\
+      sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
+
+#   parse option alias string
+eval `echo h:help,$opt_alias |\
+      sed -e 's/-/_/g' -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
+
+#   interate over argument line
+opt_PREV=''
+while [ $# -gt 0 ]; do
+    #   special option stops processing
+    if [ ".$1" = ".--" ]; then
+        shift
+        break
+    fi
+
+    #   determine option and argument
+    opt_ARG_OK=no
+    if [ ".$opt_PREV" != . ]; then
+        #   merge previous seen option with argument
+        opt_OPT="$opt_PREV"
+        opt_ARG="$1"
+        opt_ARG_OK=yes
+        opt_PREV=''
+    else
+        #   split argument into option and argument
+        case "$1" in
+            --[a-zA-Z0-9]*=*)
+                eval `echo "x$1" |\
+                      sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
+                opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
+                eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
+                ;;
+            --[a-zA-Z0-9]*)
+                opt_OPT=`echo "x$1" | cut -c4-`
+                opt_STR=`echo $opt_OPT | sed -e 's/-/_/g'`
+                eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
+                opt_ARG=''
+                ;;
+            -[a-zA-Z0-9]*)
+                eval `echo "x$1" |\
+                      sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
+                          -e 's/";\(.*\)$/"; opt_ARG="\1"/'`
+                ;;
+            -[a-zA-Z0-9])
+                opt_OPT=`echo "x$1" | cut -c3-`
+                opt_ARG=''
+                ;;
+            *)
+                break
+                ;;
+        esac
+    fi
+
+    #   eat up option
+    shift
+
+    #   determine whether option needs an argument
+    eval "opt_MODE=\$opt_MODE_${opt_OPT}"
+    if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
+        if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
+            opt_PREV="$opt_OPT"
+            continue
+        fi
+    fi
+
+    #   process option
+    case $opt_MODE in
+        '.' )
+            #   boolean option
+            eval "opt_${opt_OPT}=yes"
+            ;;
+        ':' )
+            #   option with argument (multiple occurances override)
+            eval "opt_${opt_OPT}=\"\$opt_ARG\""
+            ;;
+        '+' )
+            #   option with argument (multiple occurances append)
+            eval "opt_${opt_OPT}=\"\$opt_${opt_OPT}\${ASC_NL}\$opt_ARG\""
+            ;;
+        * )
+            echo "$msgprefix:Error: unknown option: \`$opt_OPT'" 1>&2
+            echo "$msgprefix:Hint:  run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
+            exit 1
+            ;;
+    esac
+done
+if [ ".$opt_PREV" != . ]; then
+    echo "$msgprefix:Error: missing argument to option \`$opt_PREV'" 1>&2
+    echo "$msgprefix:Hint:  run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
+    exit 1
+fi
+
+#   process help option
+if [ ".$opt_h" = .yes ]; then
+    echo "Usage: $toolcmdhelp $str_usage"
+    exit 0
+fi
+
+#   complain about incorrect number of arguments
+case $arg_MODE in
+    '=' )
+        if [ $# -ne $arg_NUMS ]; then
+            echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
+            echo "$msgprefix:Hint:  run \`$toolcmd -h' or \`man shtool' for details" 1>&2
+            exit 1
+        fi
+        ;;
+    '+' )
+        if [ $# -lt $arg_NUMS ]; then
+            echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
+            echo "$msgprefix:Hint:  run \`$toolcmd -h' or \`man shtool' for details" 1>&2
+            exit 1
+        fi
+        ;;
+esac
+
+#   establish a temporary file on request
+if [ ".$gen_tmpfile" = .yes ]; then
+    #   create (explicitly) secure temporary directory
+    if [ ".$TMPDIR" != . ]; then
+        tmpdir="$TMPDIR"
+    elif [ ".$TEMPDIR" != . ]; then
+        tmpdir="$TEMPDIR"
+    else
+        tmpdir="/tmp"
+    fi
+    tmpdir="$tmpdir/.shtool.$$"
+    ( umask 077
+      rm -rf "$tmpdir" >/dev/null 2>&1 || true
+      mkdir  "$tmpdir" >/dev/null 2>&1
+      if [ $? -ne 0 ]; then
+          echo "$msgprefix:Error: failed to create temporary directory \`$tmpdir'" 1>&2
+          exit 1
+      fi
+    )
+
+    #   create (implicitly) secure temporary file
+    tmpfile="$tmpdir/shtool.tmp"
+    touch "$tmpfile"
+fi
+
+#   utility function: map string to lower case
+util_lower () {
+    echo "$1" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
+}
+
+#   utility function: map string to upper case
+util_upper () {
+    echo "$1" | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+}
+
+#   cleanup procedure
+shtool_exit () {
+    rc="$1"
+    if [ ".$gen_tmpfile" = .yes ]; then
+        rm -rf "$tmpdir" >/dev/null 2>&1 || true
+    fi
+    exit $rc
+}
+
+##
+##  DISPATCH INTO SCRIPT BODY
+##
+
+case $tool in
+
+echo )
+    ##
+    ##  echo -- Print string with optional construct expansion
+    ##  Copyright (c) 1998-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    text="$*"
+
+    #   check for broken escape sequence expansion
+    seo=''
+    bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'`
+    if [ ".$bytes" != .3 ]; then
+        bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'`
+        if [ ".$bytes" = .3 ]; then
+            seo='-E'
+        fi
+    fi
+
+    #   check for existing -n option (to suppress newline)
+    minusn=''
+    bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'`
+    if [ ".$bytes" = .3 ]; then
+        minusn='-n'
+    fi
+
+    #   determine terminal bold sequence
+    term_bold=''
+    term_norm=''
+    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[Bb]'`" != . ]; then
+        case $TERM in
+            #   for the most important terminal types we directly know the sequences
+            xterm|xterm*|vt220|vt220*)
+                term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
+                term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
+                ;;
+            vt100|vt100*|cygwin)
+                term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
+                term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
+                ;;
+            #   for all others, we try to use a possibly existing `tput' or `tcout' utility
+            * )
+                paths=`echo $PATH | sed -e 's/:/ /g'`
+                for tool in tput tcout; do
+                    for dir in $paths; do
+                        if [ -r "$dir/$tool" ]; then
+                            for seq in bold md smso; do # 'smso' is last
+                                bold="`$dir/$tool $seq 2>/dev/null`"
+                                if [ ".$bold" != . ]; then
+                                    term_bold="$bold"
+                                    break
+                                fi
+                            done
+                            if [ ".$term_bold" != . ]; then
+                                for seq in sgr0 me rmso init reset; do # 'reset' is last
+                                    norm="`$dir/$tool $seq 2>/dev/null`"
+                                    if [ ".$norm" != . ]; then
+                                        term_norm="$norm"
+                                        break
+                                    fi
+                                done
+                            fi
+                            break
+                        fi
+                    done
+                    if [ ".$term_bold" != . ] && [ ".$term_norm" != . ]; then
+                        break;
+                    fi
+                done
+                ;;
+        esac
+        if [ ".$term_bold" = . ] || [ ".$term_norm" = . ]; then
+            echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2
+            term_bold=''
+            term_norm=''
+        fi
+    fi
+
+    #   determine user name
+    username=''
+    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[uUgG]'`" != . ]; then
+        username="`(id -un) 2>/dev/null`"
+        if [ ".$username" = . ]; then
+            str="`(id) 2>/dev/null`"
+            if [ ".`echo $str | grep '^uid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
+                username=`echo $str | sed -e 's/^uid[ 	]*=[ 	]*[0-9]*(//' -e 's/).*$//'`
+            fi
+            if [ ".$username" = . ]; then
+                username="$LOGNAME"
+                if [ ".$username" = . ]; then
+                    username="$USER"
+                    if [ ".$username" = . ]; then
+                        username="`(whoami) 2>/dev/null |\
+                                   awk '{ printf("%s", $1); }'`"
+                        if [ ".$username" = . ]; then
+                            username="`(who am i) 2>/dev/null |\
+                                       awk '{ printf("%s", $1); }'`"
+                            if [ ".$username" = . ]; then
+                                username='unknown'
+                            fi
+                        fi
+                    fi
+                fi
+            fi
+        fi
+    fi
+
+    #   determine user id
+    userid=''
+    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%U'`" != . ]; then
+        userid="`(id -u) 2>/dev/null`"
+        if [ ".$userid" = . ]; then
+            userid="`(id -u ${username}) 2>/dev/null`"
+            if [ ".$userid" = . ]; then
+                str="`(id) 2>/dev/null`"
+                if [ ".`echo $str | grep '^uid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
+                    userid=`echo $str | sed -e 's/^uid[ 	]*=[ 	]*//' -e 's/(.*$//'`
+                fi
+                if [ ".$userid" = . ]; then
+                    userid=`(getent passwd ${username}) 2>/dev/null | \
+                            sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
+                    if [ ".$userid" = . ]; then
+                        userid=`grep "^${username}:" /etc/passwd 2>/dev/null | \
+                                sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
+                        if [ ".$userid" = . ]; then
+                            userid=`(ypcat passwd) 2>/dev/null |
+                                    grep "^${username}:" | \
+                                    sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
+                            if [ ".$userid" = . ]; then
+                                userid='?'
+                            fi
+                        fi
+                    fi
+                fi
+            fi
+        fi
+    fi
+
+    #   determine (primary) group id
+    groupid=''
+    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[gG]'`" != . ]; then
+        groupid="`(id -g ${username}) 2>/dev/null`"
+        if [ ".$groupid" = . ]; then
+            str="`(id) 2>/dev/null`"
+            if [ ".`echo $str | grep 'gid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
+                groupid=`echo $str | sed -e 's/^.*gid[ 	]*=[ 	]*//' -e 's/(.*$//'`
+            fi
+            if [ ".$groupid" = . ]; then
+                groupid=`(getent passwd ${username}) 2>/dev/null | \
+                         sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
+                if [ ".$groupid" = . ]; then
+                    groupid=`grep "^${username}:" /etc/passwd 2>/dev/null | \
+                             sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
+                    if [ ".$groupid" = . ]; then
+                        groupid=`(ypcat passwd) 2>/dev/null | grep "^${username}:" | \
+                                 sed -e 's/[^:]*:[^:]*:[^:]*://' -e 's/:.*$//'`
+                        if [ ".$groupid" = . ]; then
+                            groupid='?'
+                        fi
+                    fi
+                fi
+            fi
+        fi
+    fi
+
+    #   determine (primary) group name
+    groupname=''
+    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%g'`" != . ]; then
+        groupname="`(id -gn ${username}) 2>/dev/null`"
+        if [ ".$groupname" = . ]; then
+            str="`(id) 2>/dev/null`"
+            if [ ".`echo $str | grep 'gid[ 	]*=[ 	]*[0-9]*('`" != . ]; then
+                groupname=`echo $str | sed -e 's/^.*gid[ 	]*=[ 	]*[0-9]*(//' -e 's/).*$//'`
+            fi
+            if [ ".$groupname" = . ]; then
+                groupname=`(getent group) 2>/dev/null | \
+                           grep "^[^:]*:[^:]*:${groupid}:" | \
+                           sed -e 's/:.*$//'`
+                if [ ".$groupname" = . ]; then
+                    groupname=`grep "^[^:]*:[^:]*:${groupid}:" /etc/group 2>/dev/null | \
+                               sed -e 's/:.*$//'`
+                    if [ ".$groupname" = . ]; then
+                        groupname=`(ypcat group) 2>/dev/null | \
+                                   grep "^[^:]*:[^:]*:${groupid}:" | \
+                                   sed -e 's/:.*$//'`
+                        if [ ".$groupname" = . ]; then
+                            groupname='?'
+                        fi
+                    fi
+                fi
+            fi
+        fi
+    fi
+
+    #   determine host and domain name
+    hostname=''
+    domainname=''
+    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%h'`" != . ]; then
+        hostname="`(uname -n) 2>/dev/null |\
+                   awk '{ printf("%s", $1); }'`"
+        if [ ".$hostname" = . ]; then
+            hostname="`(hostname) 2>/dev/null |\
+                       awk '{ printf("%s", $1); }'`"
+            if [ ".$hostname" = . ]; then
+                hostname='unknown'
+            fi
+        fi
+        case $hostname in
+            *.* )
+                domainname=".`echo $hostname | cut -d. -f2-`"
+                hostname="`echo $hostname | cut -d. -f1`"
+                ;;
+        esac
+    fi
+    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%d'`" != . ]; then
+        if [ ".$domainname" = . ]; then
+            if [ -f /etc/resolv.conf ]; then
+                domainname="`grep '^[ 	]*domain' /etc/resolv.conf | sed -e 'q' |\
+                             sed -e 's/.*domain//' \
+                                 -e 's/^[ 	]*//' -e 's/^ *//' -e 's/^	*//' \
+                                 -e 's/^\.//' -e 's/^/./' |\
+                             awk '{ printf("%s", $1); }'`"
+                if [ ".$domainname" = . ]; then
+                    domainname="`grep '^[ 	]*search' /etc/resolv.conf | sed -e 'q' |\
+                                 sed -e 's/.*search//' \
+                                     -e 's/^[ 	]*//' -e 's/^ *//' -e 's/^	*//' \
+                                     -e 's/ .*//' -e 's/	.*//' \
+                                     -e 's/^\.//' -e 's/^/./' |\
+                                 awk '{ printf("%s", $1); }'`"
+                fi
+            fi
+        fi
+    fi
+
+    #   determine current time
+    time_day=''
+    time_month=''
+    time_year=''
+    time_monthname=''
+    if [ ".$opt_e" = .yes ] && [ ".`echo $text | grep '%[DMYm]'`" != . ]; then
+        time_day=`date '+%d'`
+        time_month=`date '+%m'`
+        time_year=`date '+%Y' 2>/dev/null`
+        if [ ".$time_year" = . ]; then
+            time_year=`date '+%y'`
+            case $time_year in
+                [5-9][0-9]) time_year="19$time_year" ;;
+                [0-4][0-9]) time_year="20$time_year" ;;
+            esac
+        fi
+        case $time_month in
+            1|01) time_monthname='Jan' ;;
+            2|02) time_monthname='Feb' ;;
+            3|03) time_monthname='Mar' ;;
+            4|04) time_monthname='Apr' ;;
+            5|05) time_monthname='May' ;;
+            6|06) time_monthname='Jun' ;;
+            7|07) time_monthname='Jul' ;;
+            8|08) time_monthname='Aug' ;;
+            9|09) time_monthname='Sep' ;;
+              10) time_monthname='Oct' ;;
+              11) time_monthname='Nov' ;;
+              12) time_monthname='Dec' ;;
+        esac
+    fi
+
+    #   expand special ``%x'' constructs
+    if [ ".$opt_e" = .yes ]; then
+        text=`echo $seo "$text" |\
+              sed -e "s/%B/${term_bold}/g" \
+                  -e "s/%b/${term_norm}/g" \
+                  -e "s/%u/${username}/g" \
+                  -e "s/%U/${userid}/g" \
+                  -e "s/%g/${groupname}/g" \
+                  -e "s/%G/${groupid}/g" \
+                  -e "s/%h/${hostname}/g" \
+                  -e "s/%d/${domainname}/g" \
+                  -e "s/%D/${time_day}/g" \
+                  -e "s/%M/${time_month}/g" \
+                  -e "s/%Y/${time_year}/g" \
+                  -e "s/%m/${time_monthname}/g" 2>/dev/null`
+    fi
+
+    #   create output
+    if [ .$opt_n = .no ]; then
+        echo $seo "$text"
+    else
+        #   the harder part: echo -n is best, because
+        #   awk may complain about some \xx sequences.
+        if [ ".$minusn" != . ]; then
+            echo $seo $minusn "$text"
+        else
+            echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text"
+        fi
+    fi
+
+    shtool_exit 0
+    ;;
+
+mdate )
+    ##
+    ##  mdate -- Pretty-print modification time of a file or dir
+    ##  Copyright (c) 1995-1997 Free Software Foundation, Inc.
+    ##  Copyright (c) 1998-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    fod="$1"
+    case "$opt_o" in
+        [dmy][dmy][dmy] )
+            ;;
+        * ) echo "$msgprefix:Error: invalid argument to option \`-o': $opt_o" 1>&2
+            shtool_exit 1
+            ;;
+    esac
+    if [ ! -r "$fod" ]; then
+        echo "$msgprefix:Error: file or directory not found: $fod" 1>&2
+        shtool_exit 1
+    fi
+
+    #   GNU ls changes its time format in response to the TIME_STYLE
+    #   variable. Since we cannot assume "unset" works, revert this
+    #   variable to its documented default.
+    if [ ".$TIME_STYLE" != . ]; then
+        TIME_STYLE=posix-long-iso
+        export TIME_STYLE
+    fi
+
+    #   get the extended ls output of the file or directory.
+    if /bin/ls -L /dev/null >/dev/null 2>&1; then
+        set - x`/bin/ls -L -l -d $fod`
+    else
+        set - x`/bin/ls -l -d $fod`
+    fi
+
+    #   The month is at least the fourth argument
+    #   (3 shifts here, the next inside the loop).
+    shift; shift; shift
+
+    #   Find the month. Next argument is day, followed by the year or time.
+    month=""
+    while [ ".$month" = . ]; do
+        shift
+        case $1 in
+            Jan) month=January;   nummonth=1  ;;
+            Feb) month=February;  nummonth=2  ;;
+            Mar) month=March;     nummonth=3  ;;
+            Apr) month=April;     nummonth=4  ;;
+            May) month=May;       nummonth=5  ;;
+            Jun) month=June;      nummonth=6  ;;
+            Jul) month=July;      nummonth=7  ;;
+            Aug) month=August;    nummonth=8  ;;
+            Sep) month=September; nummonth=9  ;;
+            Oct) month=October;   nummonth=10 ;;
+            Nov) month=November;  nummonth=11 ;;
+            Dec) month=December;  nummonth=12 ;;
+        esac
+    done
+    day="$2"
+    year="$3"
+
+    #   We finally have to deal with the problem that the "ls" output
+    #   gives either the time of the day or the year.
+    case $year in
+        *:*)
+            this_year=`date '+%Y' 2>/dev/null`
+            if [ ".$this_year" = . ]; then
+                this_year=`date '+%y'`
+                case $this_year in
+                    [5-9][0-9]) this_year="19$this_year" ;;
+                    [0-4][0-9]) this_year="20$this_year" ;;
+                esac
+            fi
+            #   for the following months of the last year the time notation
+            #   is usually also used for files modified in the last year.
+            this_month=`date '+%m'`
+            if (expr $nummonth \> $this_month) >/dev/null; then
+                this_year=`expr $this_year - 1`
+            fi
+            year="$this_year"
+            ;;
+    esac
+
+    #   Optionally fill day and month with leeding zeros
+    if [ ".$opt_z" = .yes ]; then
+        case $day in
+            [0-9][0-9] ) ;;
+                 [0-9] ) day="0$day" ;;
+        esac
+        case $nummonth in
+            [0-9][0-9] ) ;;
+                 [0-9] ) nummonth="0$nummonth" ;;
+        esac
+    fi
+
+    #   Optionally use digits for month
+    if [ ".$opt_d" = .yes ]; then
+        month="$nummonth"
+    fi
+
+    #   Optionally shorten the month name to three characters
+    if [ ".$opt_s" = .yes ]; then
+        month=`echo $month | cut -c1-3`
+    fi
+
+    #   Output the resulting date string
+    echo dummy | awk '{
+        for (i = 0; i < 3; i++) {
+            now = substr(order, 1, 1);
+            order = substr(order, 2);
+            if (now == "d")
+                out = day;
+            else if (now == "m")
+                out = month;
+            else if (now == "y")
+                out = year;
+            if (i < 2)
+                printf("%s%s", out, field);
+            else
+                printf("%s", out);
+        }
+        if (newline != "yes")
+            printf("\n");
+    }' "day=$day" "month=$month" "year=$year" \
+       "field=$opt_f" "order=$opt_o" "newline=$opt_n"
+
+    shtool_exit 0
+    ;;
+
+table )
+    ##
+    ##  table -- Pretty-print a field-separated list as a table
+    ##  Copyright (c) 1998-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    if [ $opt_c -gt 4 ]; then
+        echo "$msgprefix:Error: Invalid number of colums (1..4 allowed only)" 1>&2
+        shtool_exit 1
+    fi
+    case "x$opt_F" in
+        x? ) ;;
+        *  ) echo "$msgprefix:Error: Invalid separator (one char allowed only)" 1>&2; shtool_exit 1 ;;
+    esac
+
+    #   split the list into a table
+    list=`
+        IFS="$opt_F"
+        for entry in $*; do
+            if [ ".$entry" != . ]; then
+                echo "$entry"
+            fi
+        done |\
+        awk "
+            BEGIN { list = \"\"; n = 0; }
+            {
+                list = list \\$1;
+                n = n + 1;
+                if (n < $opt_c) {
+                    list = list \":\";
+                }
+                if (n == $opt_c) {
+                    list = list \"\\n\";
+                    n = 0;
+                }
+            }
+            END { print list; }
+         "
+    `
+
+    #   format table cells and make sure table
+    #   doesn't exceed maximum width
+    OIFS="$IFS"
+    IFS='
+'
+    for entry in $list; do
+        case $opt_c in
+            1 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s\\n\", \$1); }'" ;;
+            2 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s %-${opt_w}s\\n\", \$1, \$2); }'" ;;
+            3 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s %-${opt_w}s %-${opt_w}s\\n\", \$1, \$2, \$3); }'" ;;
+            4 ) eval "echo \"\${entry}\" | awk -F: '{ printf(\"%-${opt_w}s %-${opt_w}s %-${opt_w}s %-${opt_w}s\\n\", \$1, \$2, \$3, \$4); }'" ;;
+        esac
+    done |\
+    awk "{
+        if (length(\$0) > $opt_s) {
+            printf(\"%s\\n\", substr(\$0, 0, $opt_s-1));
+        } else {
+            print \$0;
+        }
+    }"
+    IFS="$OIFS"
+
+    shtool_exit 0
+    ;;
+
+prop )
+    ##
+    ##  prop -- Display progress with a running propeller
+    ##  Copyright (c) 1998-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    perl=''
+    for dir in `echo $PATH | sed -e 's/:/ /g'` .; do
+        if [ -f "$dir/perl" ]; then
+            perl="$dir/perl"
+            break
+        fi
+    done
+    if [ ".$perl" != . ]; then
+        #   Perl is preferred because writing to STDERR in
+        #   Perl really writes immediately as one would expect
+        $perl -e '
+            @p = ("|","/","-","\\");
+            $i = 0;
+            while (<STDIN>) {
+                printf(STDERR "\r%s...%s\b", $ARGV[0], $p[$i++]);
+                $i = 0 if ($i > 3);
+            }
+            printf(STDERR "\r%s    \n", $ARGV[0]);
+        ' "$opt_p"
+    else
+        #   But if Perl doesn't exists we use Awk even
+        #   some Awk's buffer even the /dev/stderr writing :-(
+        awk '
+            BEGIN {
+                split("|#/#-#\\", p, "#");
+                i = 1;
+            }
+            {
+                printf("\r%s%c\b", prefix, p[i++]) > "/dev/stderr";
+                if (i > 4) { i = 1; }
+            }
+            END {
+                printf("\r%s    \n", prefix) > "/dev/stderr";
+            }
+        ' "prefix=$opt_p"
+    fi
+
+    shtool_exit 0
+    ;;
+
+move )
+    ##
+    ##  move -- Move files with simultaneous substitution
+    ##  Copyright (c) 1999-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    src="$1"
+    dst="$2"
+
+    #   consistency checks
+    if [ ".$src" = . ] || [ ".$dst" = . ]; then
+        echo "$msgprefix:Error: Invalid arguments" 1>&2
+        shtool_exit 1
+    fi
+    if [ ".$src" = ".$dst" ]; then
+        echo "$msgprefix:Error: Source and destination files are the same" 1>&2
+        shtool_exit 1
+    fi
+    expsrc="$src"
+    if [ ".$opt_e" = .yes ]; then
+        expsrc="`echo $expsrc`"
+    fi
+    if [ ".$opt_e" = .yes ]; then
+        if [ ".`echo "$src" | sed -e 's;^.*\\*.*$;;'`" = ".$src" ]; then
+            echo "$msgprefix:Error: Source doesn't contain wildcard ('*'): $dst" 1>&2
+            shtool_exit 1
+        fi
+        if [ ".`echo "$dst" | sed -e 's;^.*%[1-9].*$;;'`" = ".$dst" ]; then
+            echo "$msgprefix:Error: Destination doesn't contain substitution ('%N'): $dst" 1>&2
+            shtool_exit 1
+        fi
+        if [ ".$expsrc" = ".$src" ]; then
+            echo "$msgprefix:Error: Sources not found or no asterisk : $src" 1>&2
+            shtool_exit 1
+        fi
+    else
+        if [ ! -r "$src" ]; then
+            echo "$msgprefix:Error: Source not found: $src" 1>&2
+            shtool_exit 1
+        fi
+    fi
+
+    #   determine substitution patterns
+    if [ ".$opt_e" = .yes ]; then
+        srcpat=`echo "$src" | sed -e 's/\\./\\\\./g' -e 's/;/\\;/g' -e 's;\\*;\\\\(.*\\\\);g'`
+        dstpat=`echo "$dst" | sed -e 's;%\([1-9]\);\\\\\1;g'`
+    fi
+
+    #   iterate over source(s)
+    for onesrc in $expsrc; do
+        if [ .$opt_e = .yes ]; then
+            onedst=`echo $onesrc | sed -e "s;$srcpat;$dstpat;"`
+        else
+            onedst="$dst"
+        fi
+        errorstatus=0
+        if [ ".$opt_v" = .yes ]; then
+            echo "$onesrc -> $onedst"
+        fi
+        if [ ".$opt_p" = .yes ]; then
+            if [ -r $onedst ]; then
+                if cmp -s $onesrc $onedst; then
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "rm -f $onesrc" 1>&2
+                    fi
+                    rm -f $onesrc || errorstatus=$?
+                else
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "mv -f $onesrc $onedst" 1>&2
+                    fi
+                    mv -f $onesrc $onedst || errorstatus=$?
+                fi
+            else
+                if [ ".$opt_t" = .yes ]; then
+                    echo "mv -f $onesrc $onedst" 1>&2
+                fi
+                mv -f $onesrc $onedst || errorstatus=$?
+            fi
+        else
+            if [ ".$opt_t" = .yes ]; then
+                echo "mv -f $onesrc $onedst" 1>&2
+            fi
+            mv -f $onesrc $onedst || errorstatus=$?
+        fi
+        if [ $errorstatus -ne 0 ]; then
+            break;
+        fi
+    done
+
+    shtool_exit $errorstatus
+    ;;
+
+install )
+    ##
+    ##  install -- Install a program, script or datafile
+    ##  Copyright (c) 1997-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    #   special case: "shtool install -d <dir> [...]" internally
+    #   maps to "shtool mkdir -f -p -m 755 <dir> [...]"
+    if [ "$opt_d" = yes ]; then
+        cmd="$0 mkdir -f -p -m 755"
+        if [ ".$opt_o" != . ]; then
+            cmd="$cmd -o '$opt_o'"
+        fi
+        if [ ".$opt_g" != . ]; then
+            cmd="$cmd -g '$opt_g'"
+        fi
+        if [ ".$opt_v" = .yes ]; then
+            cmd="$cmd -v"
+        fi
+        if [ ".$opt_t" = .yes ]; then
+            cmd="$cmd -t"
+        fi
+        for dir in "$@"; do
+            eval "$cmd $dir" || shtool_exit $?
+        done
+        shtool_exit 0
+    fi
+
+    #   determine source(s) and destination
+    argc=$#
+    srcs=""
+    while [ $# -gt 1 ]; do
+        srcs="$srcs $1"
+        shift
+    done
+    dstpath="$1"
+
+    #   type check for destination
+    dstisdir=0
+    if [ -d $dstpath ]; then
+        dstpath=`echo "$dstpath" | sed -e 's:/$::'`
+        dstisdir=1
+    fi
+
+    #   consistency check for destination
+    if [ $argc -gt 2 ] && [ $dstisdir = 0 ]; then
+        echo "$msgprefix:Error: multiple sources require destination to be directory" 1>&2
+        shtool_exit 1
+    fi
+
+    #   iterate over all source(s)
+    for src in $srcs; do
+        dst=$dstpath
+
+        #   if destination is a directory, append the input filename
+        if [ $dstisdir = 1 ]; then
+            dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'`
+            dst="$dst/$dstfile"
+        fi
+
+        #   check for correct arguments
+        if [ ".$src" = ".$dst" ]; then
+            echo "$msgprefix:Warning: source and destination are the same - skipped" 1>&2
+            continue
+        fi
+        if [ -d "$src" ]; then
+            echo "$msgprefix:Warning: source \`$src' is a directory - skipped" 1>&2
+            continue
+        fi
+
+        #   make a temp file name in the destination directory
+        dsttmp=`echo $dst |\
+                sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;' \
+                    -e "s;\$;/#INST@$$#;"`
+
+        #   verbosity
+        if [ ".$opt_v" = .yes ]; then
+            echo "$src -> $dst" 1>&2
+        fi
+
+        #   copy or move the file name to the temp name
+        #   (because we might be not allowed to change the source)
+        if [ ".$opt_C" = .yes ]; then
+            opt_c=yes
+        fi
+        if [ ".$opt_c" = .yes ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "cp $src $dsttmp" 1>&2
+            fi
+            cp $src $dsttmp || shtool_exit $?
+        else
+            if [ ".$opt_t" = .yes ]; then
+                echo "mv $src $dsttmp" 1>&2
+            fi
+            mv $src $dsttmp || shtool_exit $?
+        fi
+
+        #   adjust the target file
+        if [ ".$opt_e" != . ]; then
+            sed='sed'
+            OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
+            for e
+            do
+                sed="$sed -e '$e'"
+            done
+            cp $dsttmp $dsttmp.old
+            chmod u+w $dsttmp
+            eval "$sed <$dsttmp.old >$dsttmp" || shtool_exit $?
+            rm -f $dsttmp.old
+        fi
+        if [ ".$opt_s" = .yes ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "strip $dsttmp" 1>&2
+            fi
+            strip $dsttmp || shtool_exit $?
+        fi
+        if [ ".$opt_o" != . ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "chown $opt_o $dsttmp" 1>&2
+            fi
+            chown $opt_o $dsttmp || shtool_exit $?
+        fi
+        if [ ".$opt_g" != . ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "chgrp $opt_g $dsttmp" 1>&2
+            fi
+            chgrp $opt_g $dsttmp || shtool_exit $?
+        fi
+        if [ ".$opt_m" != ".-" ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "chmod $opt_m $dsttmp" 1>&2
+            fi
+            chmod $opt_m $dsttmp || shtool_exit $?
+        fi
+
+        #   determine whether to do a quick install
+        #   (has to be done _after_ the strip was already done)
+        quick=no
+        if [ ".$opt_C" = .yes ]; then
+            if [ -r $dst ]; then
+                if cmp -s $src $dst; then
+                    quick=yes
+                fi
+            fi
+        fi
+
+        #   finally, install the file to the real destination
+        if [ $quick = yes ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "rm -f $dsttmp" 1>&2
+            fi
+            rm -f $dsttmp
+        else
+            if [ ".$opt_t" = .yes ]; then
+                echo "rm -f $dst && mv $dsttmp $dst" 1>&2
+            fi
+            rm -f $dst && mv $dsttmp $dst
+        fi
+    done
+
+    shtool_exit 0
+    ;;
+
+mkdir )
+    ##
+    ##  mkdir -- Make one or more directories
+    ##  Copyright (c) 1996-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    errstatus=0
+    for p in ${1+"$@"}; do
+        #   if the directory already exists...
+        if [ -d "$p" ]; then
+            if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then
+                echo "$msgprefix:Error: directory already exists: $p" 1>&2
+                errstatus=1
+                break
+            else
+                continue
+            fi
+        fi
+        #   if the directory has to be created...
+        if [ ".$opt_p" = .no ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "mkdir $p" 1>&2
+            fi
+            mkdir $p || errstatus=$?
+            if [ ".$opt_o" != . ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "chown $opt_o $p" 1>&2
+                fi
+                chown $opt_o $p || errstatus=$?
+            fi
+            if [ ".$opt_g" != . ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "chgrp $opt_g $p" 1>&2
+                fi
+                chgrp $opt_g $p || errstatus=$?
+            fi
+            if [ ".$opt_m" != . ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "chmod $opt_m $p" 1>&2
+                fi
+                chmod $opt_m $p || errstatus=$?
+            fi
+        else
+            #   the smart situation
+            set fnord `echo ":$p" |\
+                       sed -e 's/^:\//%/' \
+                           -e 's/^://' \
+                           -e 's/\// /g' \
+                           -e 's/^%/\//'`
+            shift
+            pathcomp=''
+            for d in ${1+"$@"}; do
+                pathcomp="$pathcomp$d"
+                case "$pathcomp" in
+                    -* ) pathcomp="./$pathcomp" ;;
+                esac
+                if [ ! -d "$pathcomp" ]; then
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "mkdir $pathcomp" 1>&2
+                    fi
+                    mkdir $pathcomp || errstatus=$?
+                    if [ ".$opt_o" != . ]; then
+                        if [ ".$opt_t" = .yes ]; then
+                            echo "chown $opt_o $pathcomp" 1>&2
+                        fi
+                        chown $opt_o $pathcomp || errstatus=$?
+                    fi
+                    if [ ".$opt_g" != . ]; then
+                        if [ ".$opt_t" = .yes ]; then
+                            echo "chgrp $opt_g $pathcomp" 1>&2
+                        fi
+                        chgrp $opt_g $pathcomp || errstatus=$?
+                    fi
+                    if [ ".$opt_m" != . ]; then
+                        if [ ".$opt_t" = .yes ]; then
+                            echo "chmod $opt_m $pathcomp" 1>&2
+                        fi
+                        chmod $opt_m $pathcomp || errstatus=$?
+                    fi
+                fi
+                pathcomp="$pathcomp/"
+            done
+        fi
+    done
+
+    shtool_exit $errstatus
+    ;;
+
+mkln )
+    ##
+    ##  mkln -- Make link with calculation of relative paths
+    ##  Copyright (c) 1998-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    #   determine source(s) and destination
+    args=$?
+    srcs=""
+    while [ $# -gt 1 ]; do
+        srcs="$srcs $1"
+        shift
+    done
+    dst="$1"
+    if [ ! -d $dst ]; then
+        if [ $args -gt 2 ]; then
+            echo "$msgprefix:Error: multiple sources not allowed when target isn't a directory" 1>&2
+            shtool_exit 1
+        fi
+    fi
+
+    #   determine link options
+    lnopt=""
+    if [ ".$opt_f" = .yes ]; then
+        lnopt="$lnopt -f"
+    fi
+    if [ ".$opt_s" = .yes ]; then
+        lnopt="$lnopt -s"
+    fi
+
+    #   iterate over sources
+    for src in $srcs; do
+        #   determine if one of the paths is an absolute path,
+        #   because then we _have_ to use an absolute symlink
+        oneisabs=0
+        srcisabs=0
+        dstisabs=0
+        case $src in
+            /* ) oneisabs=1; srcisabs=1 ;;
+        esac
+        case $dst in
+            /* ) oneisabs=1; dstisabs=1 ;;
+        esac
+
+        #   split source and destination into dir and base name
+        if [ -d $src ]; then
+            srcdir=`echo $src | sed -e 's;/*$;;'`
+            srcbase=""
+        else
+            srcdir=`echo  $src | sed -e 's;^[^/]*$;;' -e 's;^\(.*/\)[^/]*$;\1;' -e 's;\(.\)/$;\1;'`
+            srcbase=`echo $src | sed -e 's;.*/\([^/]*\)$;\1;'`
+        fi
+        if [ -d $dst ]; then
+            dstdir=`echo $dst | sed -e 's;/*$;;'`
+            dstbase=""
+        else
+            dstdir=`echo  $dst | sed -e 's;^[^/]*$;;' -e 's;^\(.*/\)[^/]*$;\1;' -e 's;\(.\)/$;\1;'`
+            dstbase=`echo $dst | sed -e 's;.*/\([^/]*\)$;\1;'`
+        fi
+
+        #   consistency check
+        if [ ".$dstdir" != . ]; then
+            if [ ! -d $dstdir ]; then
+                echo "$msgprefix:Error: destination directory not found: $dstdir" 1>&2
+                shtool_exit 1
+            fi
+        fi
+
+        #   make sure the source is reachable from the destination
+        if [ $dstisabs = 1 ]; then
+            if [ $srcisabs = 0 ]; then
+                if [ ".$srcdir" = . ]; then
+                    srcdir="`pwd | sed -e 's;/*$;;'`"
+                    srcisabs=1
+                    oneisabs=1
+                elif [ -d $srcdir ]; then
+                    srcdir="`cd $srcdir; pwd | sed -e 's;/*$;;'`"
+                    srcisabs=1
+                    oneisabs=1
+                fi
+            fi
+        fi
+
+        #   split away a common prefix
+        prefix=""
+        if [ ".$srcdir" = ".$dstdir" ] && [ ".$srcdir" != . ]; then
+            prefix="$srcdir/"
+            srcdir=""
+            dstdir=""
+        else
+            while [ ".$srcdir" != . ] && [ ".$dstdir" != . ]; do
+                presrc=`echo $srcdir | sed -e 's;^\([^/]*\)/.*;\1;'`
+                predst=`echo $dstdir | sed -e 's;^\([^/]*\)/.*;\1;'`
+                if [ ".$presrc" != ".$predst" ]; then
+                    break
+                fi
+                prefix="$prefix$presrc/"
+                srcdir=`echo $srcdir | sed -e 's;^[^/]*/*;;'`
+                dstdir=`echo $dstdir | sed -e 's;^[^/]*/*;;'`
+            done
+        fi
+
+        #   destination prefix is just the common prefix
+        dstpre="$prefix"
+
+        #   determine source prefix which is the reverse directory
+        #   step-up corresponding to the destination directory
+        srcpre=""
+
+        isroot=0
+        if [ ".$prefix" = . ] || [ ".$prefix" = ./ ]; then
+            isroot=1
+        fi
+        if [ $oneisabs = 0 ] || [ $isroot = 0 ]; then
+            pl="$dstdir/"
+            OIFS="$IFS"; IFS='/'
+            for pe in $pl; do
+                [ ".$pe" = .  ] && continue
+                [ ".$pe" = .. ] && continue
+                srcpre="../$srcpre"
+            done
+            IFS="$OIFS"
+        else
+            if [ $srcisabs = 1 ]; then
+                srcpre="$prefix"
+            fi
+        fi
+
+        #   determine destination symlink name
+        if [ ".$dstbase" = . ]; then
+            if [ ".$srcbase" != . ]; then
+                dstbase="$srcbase"
+            else
+                dstbase=`echo "$prefix$srcdir" | sed -e 's;/*$;;' -e 's;.*/\([^/]*\)$;\1;'`
+            fi
+        fi
+
+        #   now finalize source and destination directory paths
+        srcdir=`echo $srcdir | sed -e 's;\([^/]\)$;\1/;'`
+        dstdir=`echo $dstdir | sed -e 's;\([^/]\)$;\1/;'`
+
+        #   run the final link command
+        if [ ".$opt_t" = .yes ]; then
+            echo "ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase"
+        fi
+        eval ln$lnopt $srcpre$srcdir$srcbase $dstpre$dstdir$dstbase
+    done
+
+    shtool_exit 0
+    ;;
+
+mkshadow )
+    ##
+    ##  mkshadow -- Make a shadow tree through symbolic links
+    ##  Copyright (c) 1998-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    #   source and destination directory
+    src=`echo "$1" | sed -e 's:/$::' -e 's:^\./\(.\):\1:'`
+    dst=`echo "$2" | sed -e 's:/$::' -e 's:^\./\(.\):\1:'`
+
+    #   check whether source exists
+    if [ ! -d $src ]; then
+        echo "$msgprefix:Error: source directory not found: \`$src'" 1>&2
+        shtool_exit 1
+    fi
+
+    #   determine if one of the paths is an absolute path,
+    #   because then we have to use an absolute symlink
+    oneisabs=0
+    case $src in
+        /* ) oneisabs=1 ;;
+    esac
+    case $dst in
+        /* ) oneisabs=1 ;;
+    esac
+
+    #   determine reverse directory for destination directory
+    dstrevdir=''
+    if [ $oneisabs = 0 ]; then
+        #   derive reverse path from forward path
+        pwd=`pwd`
+        OIFS="$IFS"; IFS='/'
+        for pe in $dst; do
+            if [ "x$pe" = "x.." ]; then
+                OIFS2="$IFS"; IFS="$DIFS"
+                eval `echo "$pwd" |\
+                      sed -e 's:\([^/]*\)$:; dir="\1":' \
+                          -e 's:^\(.*\)/[^/]*;:pwd="\1";:'\
+                          -e 's:^;:pwd="";:'`
+                dstrevdir="$dir/$dstrevdir"
+                IFS="$OIFS2"
+            else
+                dstrevdir="../$dstrevdir"
+            fi
+        done
+        IFS="$OIFS"
+    else
+        src="`cd $src; pwd`";
+    fi
+
+    #   create directory tree at destination
+    if [ ! -d $dst ]; then
+        if [ ".$opt_t" = .yes ]; then
+            echo "mkdir $dst" 1>&2
+        fi
+        mkdir $dst
+    fi
+    if [ ".$opt_a" = .yes ]; then
+        DIRS=`cd $src; find . -type d -print |\
+              sed -e '/^\.$/d' -e 's:^\./::'`
+    else
+        DIRS=`cd $src; find . -type d -print |\
+              sed -e '/\/CVS/d' -e '/^\.$/d' -e 's:^\./::'`
+    fi
+    for dir in $DIRS; do
+        if [ ".$opt_t" = .yes ]; then
+            echo "mkdir $dst/$dir" 1>&2
+        fi
+        mkdir $dst/$dir
+    done
+
+    #   fill directory tree with symlinks to files
+    if [ ".$opt_a" = .yes ]; then
+        FILES="`cd $src; find . -depth -print |\
+                sed -e 's/^\.\///'`"
+    else
+        FILES="`cd $src; find . -depth -print |\
+                sed -e '/\.o$/d' -e '/\.a$/d' -e '/\.so$/d' \
+                    -e '/\.cvsignore$/d' -e '/\/CVS/d' \
+                    -e '/\/\.#/d' -e '/\.orig$/d' \
+                    -e 's/^\.\///'`"
+    fi
+    for file in $FILES; do
+         #  don't use `-type f' above for find because of symlinks
+         if [ -d "$src/$file" ]; then
+             continue
+         fi
+         basename=`echo $file | sed -e 's:^.*/::'`
+         dir=`echo $file | sed -e 's:[^/]*$::' -e 's:/$::' -e 's:$:/:' -e 's:^/$::'`
+         from=`echo "$src/$file" | sed -e 's/^\.\///'`
+         to="$dst/$dir$basename"
+         if [ $oneisabs = 0 ]; then
+             if [ ".$dir" != . ]; then
+                 subdir=`echo $dir | sed -e 's:/$::'`
+                 #   derive reverse path from forward path
+                 revdir=''
+                 OIFS="$IFS"; IFS='/'
+                 for pe in $subdir; do
+                     revdir="../$revdir"
+                 done
+                 IFS="$OIFS"
+                 #   finalize from
+                 from="$revdir$from"
+             fi
+             from="$dstrevdir$from"
+         fi
+         if [ ".$opt_v" = .yes ]; then
+             echo "    $to" 1>&2
+         fi
+         if [ ".$opt_t" = .yes ]; then
+             echo "ln -s $from $to" 1>&2
+         fi
+         ln -s $from $to
+    done
+
+    shtool_exit 0
+    ;;
+
+fixperm )
+    ##
+    ##  fixperm -- Fix file permissions inside a source tree
+    ##  Copyright (c) 1996-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    paths="$*"
+
+    #   check whether the test command supports the -x option
+    if [ -x /bin/sh ] 2>/dev/null; then
+        minusx="-x"
+    else
+        minusx="-r"
+    fi
+
+    #   iterate over paths
+    for p in $paths; do
+        for file in `find $p -depth -print`; do
+            if [ -f $file ]; then
+                if [ $minusx $file ]; then
+                    if [ ".$opt_v" = .yes ]; then
+                        echo "-rwxr-xr-x $file" 2>&1
+                    fi
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "chmod 755 $file" 2>&1
+                    fi
+                    chmod 755 $file
+                else
+                    if [ ".$opt_v" = .yes ]; then
+                        echo "-rw-r--r-- $file" 2>&1
+                    fi
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "chmod 644 $file" 2>&1
+                    fi
+                    chmod 644 $file
+                fi
+                continue
+            fi
+            if [ -d $file ]; then
+                if [ ".$opt_v" = .yes ]; then
+                    echo "drwxr-xr-x $file" 2>&1
+                fi
+                if [ ".$opt_t" = .yes ]; then
+                    echo "chmod 755 $file" 2>&1
+                fi
+                chmod 755 $file
+                continue
+            fi
+            if [ ".$opt_v" = .yes ]; then
+                echo "?????????? $file" 2>&1
+            fi
+        done
+    done
+
+    shtool_exit 0
+    ;;
+
+rotate )
+    ##
+    ##  rotate -- Logfile rotation
+    ##  Copyright (c) 2001-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    #   make sure we have at least one file to rotate
+    if [ ".$opt_n" = .0 ]; then
+        echo "$msgprefix:Error: invalid argument \`$opt_n' to option -n." 1>&2
+        shtool_exit 1
+    fi
+
+    #   canonicalize -s option argument
+    if [ ".$opt_s" != . ]; then
+        if [ ".`expr $opt_s : '[0-9]*$'`" != .0 ]; then
+            :
+        elif [ ".`expr $opt_s : '[0-9]*[Kk]$'`" != .0 ]; then
+            opt_s=`expr $opt_s : '\([0-9]*\)[Kk]$'`
+            opt_s=`expr $opt_s \* 1024`
+        elif [ ".`expr $opt_s : '[0-9]*[Mm]$'`" != .0 ]; then
+            opt_s=`expr $opt_s : '\([0-9]*\)[Mm]$'`
+            opt_s=`expr $opt_s \* 1048576` # 1024*1024
+        elif [ ".`expr $opt_s : '[0-9]*[Gg]$'`" != .0 ]; then
+            opt_s=`expr $opt_s : '\([0-9]*\)[Gg]$'`
+            opt_s=`expr $opt_s \* 1073741824` # 1024*1024*1024
+        else
+            echo "$msgprefix:Error: invalid argument \`$opt_s' to option -s." 1>&2
+            shtool_exit 1
+        fi
+    fi
+
+    #   option -d/-z consistency
+    if [ ".$opt_d" = .yes ] && [ ".$opt_z" = . ]; then
+        echo "$msgprefix:Error: option -d requires option -z." 1>&2
+        shtool_exit 1
+    fi
+
+    #   make sure target directory exists
+    if [ ".$opt_a" != . ]; then
+        if [ ! -d $opt_a ]; then
+            if [ ".$opt_f" = .no ]; then
+                echo "$msgprefix:Error: archive directory \`$opt_a' does not exist." 1>&2
+                shtool_exit 1
+            fi
+            mkdir $opt_a || shtool_exit $?
+            chmod 755 $opt_a
+        fi
+        if [ ! -w $opt_a ]; then
+            echo "$msgprefix:Error: archive directory \`$opt_a' not writable." 1>&2
+            shtool_exit 1
+        fi
+    fi
+
+    #   determine compression approach
+    if [ ".$opt_z" != . ]; then
+        comp_lvl="$opt_z"
+        comp_prg=""
+        case $comp_lvl in
+            *:* ) eval `echo $comp_lvl |\
+                        sed -e 's%^\(.*\):\(.*\)$%comp_prg="\1"; comp_lvl="\2"%'` ;;
+        esac
+
+        #   compression level consistency
+        case $comp_lvl in
+            [0-9] )
+                ;;
+            * ) echo "$msgprefix:Error: invalid compression level \`$comp_lvl'" 1>&2
+                shtool_exit 1
+                ;;
+        esac
+
+        #   determine a suitable compression tool
+        if [ ".$comp_prg" = . ]; then
+            #   check whether the test command supports the -x option
+            if [ -x /bin/sh ] 2>/dev/null; then
+                minusx="-x"
+            else
+                minusx="-r"
+            fi
+            #   search for tools in $PATH
+            paths="`echo $PATH |\
+                    sed -e 's%/*:%:%g' -e 's%/*$%%' \
+                        -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
+                        -e 's/:/ /g'`"
+            for prg in bzip2 gzip compress; do
+                for path in $paths; do
+                    if [ $minusx "$path/$prg" ] && [ ! -d "$path/$prg" ]; then
+                        comp_prg="$prg"
+                        break
+                    fi
+                done
+                if [ ".$comp_prg" != . ]; then
+                    break
+                fi
+            done
+            if [ ".$comp_prg" = . ]; then
+                echo "$msgprefix:Error: no suitable compression tool found in \$PATH" 1>&2
+                shtool_exit 1
+            fi
+        fi
+
+        #   determine standard compression extension
+        #   and make sure it is a known tool
+        case $comp_prg in
+            */bzip2    | bzip2    ) comp_ext="bz2" comp_lvl="-$comp_lvl" ;;
+            */gzip     | gzip     ) comp_ext="gz"  comp_lvl="-$comp_lvl" ;;
+            */compress | compress ) comp_ext="Z";  comp_lvl=""           ;;
+            * ) echo "$msgprefix:Error: tool \`$comp_prg' is not a known compression tool" 1>&2
+                shtool_exit 1
+                ;;
+        esac
+        comp_suf=".$comp_ext"
+    fi
+
+    #   iterate over all given logfile arguments
+    for file in $*; do
+        #   make sure the logfile exists
+        if [ ! -f $file ]; then
+            if [ ".$opt_f" = .yes ]; then
+                continue
+            fi
+            echo "$msgprefix:Error: logfile \`$file' not found" 1>&2
+            shtool_exit 1
+        fi
+
+        #   determine log directory (where original logfile is placed)
+        ldir="."
+        case $file in
+            */* ) eval `echo $file | sed -e 's%^\(.*\)/\([^/]*\)$%ldir="\1"; file="\2";%'` ;;
+        esac
+
+        #   determine archive directory (where rotated logfiles are placed)
+        adir="$ldir"
+        if [ ".$opt_a" != . ]; then
+            case "$opt_a" in
+                /* | ./* ) adir="$opt_a" ;;
+                * ) adir="$ldir/$opt_a"  ;;
+            esac
+        fi
+
+        #   optionally take logfile size into account
+        if [ ".$opt_s" != . ]; then
+            #   determine size of logfile
+            set -- `env -i /bin/ls -l "$ldir/$file" | sed -e "s;$ldir/$file;;" |\
+                    sed -e 's; -> .*$;;' -e 's;[ 	][ 	]*; ;g'`
+            n=`expr $# - 3`
+            eval "size=\`echo \${$n}\`"
+
+            #   skip logfile if size is still too small
+            if [ $size -lt $opt_s ]; then
+                if [ ".$opt_v" = .yes ]; then
+                    echo "$ldir/$file: still too small in size -- skipping"
+                fi
+                continue
+            fi
+        fi
+
+        #   verbosity
+        if [ ".$opt_v" = .yes ]; then
+            echo "rotating $ldir/$file"
+        fi
+
+        #   execute prolog
+        if [ ".$opt_P" != . ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "$opt_P"
+            fi
+            eval $opt_P
+            [ $? -ne 0 ] && shtool_exit $?
+        fi
+
+        #   kick away out-rotated logfile
+        n=`expr $opt_n - 1`
+        n=`echo dummy | awk "{ printf(\"%0${opt_p}d\", n); }" n=$n`
+        if [ -f "${adir}/${file}.${n}${comp_suf}" ]; then
+            #   optionally migrate away the out-rotated logfile
+            if [ ".$opt_M" != . ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "$opt_M ${adir}/${file}.${n}${comp_suf}"
+                fi
+                eval "$opt_M ${adir}/${file}.${n}${comp_suf}"
+                [ $? -ne 0 ] && shtool_exit $?
+            fi
+            #   finally get rid of the out-rotated logfile
+            if [ ".$opt_t" = .yes ]; then
+                echo "rm -f ${adir}/${file}.${n}${comp_suf}"
+            fi
+            rm -f ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
+        fi
+
+        #   rotate already archived logfiles
+        while [ $n -gt 0 ]; do
+            m=$n
+            n=`expr $n - 1`
+            n=`echo dummy | awk "{ printf(\"%0${opt_p}d\", n); }" n=$n`
+            if [ $n -eq 0 ] && [ ".$opt_d" = .yes ]; then
+                #   special case: first rotation file under delayed compression situation
+                if [ ! -f "${adir}/${file}.${n}" ]; then
+                    continue
+                fi
+
+                #   compress file (delayed)
+                if [ ".$opt_b" = .yes ]; then
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "mv ${adir}/${file}.${n} ${adir}/${file}.${m}"
+                    fi
+                    mv ${adir}/${file}.${n} ${adir}/${file}.${m} || shtool_exit $?
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "(${comp_prg} ${comp_lvl} <${adir}/${file}.${m} >${adir}/${file}.${m}${comp_suf}; rm -f ${adir}/${file}.${m}) &"
+                    fi
+                    ( ${comp_prg} ${comp_lvl} \
+                          <${adir}/${file}.${m} \
+                          >${adir}/${file}.${m}${comp_suf} || shtool_exit $?
+                      rm -f ${adir}/${file}.${m} || shtool_exit $?
+                    ) </dev/null >/dev/null 2>&1 &
+                else
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${m}${comp_suf}"
+                    fi
+                    ${comp_prg} ${comp_lvl} \
+                        <${adir}/${file}.${n} \
+                        >${adir}/${file}.${m}${comp_suf} || shtool_exit $?
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "rm -f ${adir}/${file}.${n}"
+                    fi
+                    rm -f ${adir}/${file}.${n} || shtool_exit $?
+                fi
+
+                #   fix file attributes
+                if [ ".$opt_o" != . ]; then
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "chown $opt_o ${adir}/${file}.${m}${comp_suf}"
+                    fi
+                    chown $opt_o ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
+                fi
+                if [ ".$opt_g" != . ]; then
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "chgrp $opt_g ${adir}/${file}.${m}${comp_suf}"
+                    fi
+                    chgrp $opt_g ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
+                fi
+                if [ ".$opt_m" != . ]; then
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "chmod $opt_m ${adir}/${file}.${m}${comp_suf}"
+                    fi
+                    chmod $opt_m ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
+                fi
+            else
+                #   standard case: second and following rotation file
+                if [ ! -f "${adir}/${file}.${n}${comp_suf}" ]; then
+                    continue
+                fi
+                if [ ".$opt_t" = .yes ]; then
+                    echo "mv ${adir}/${file}.${n}${comp_suf} ${adir}/${file}.${m}${comp_suf}"
+                fi
+                mv ${adir}/${file}.${n}${comp_suf} ${adir}/${file}.${m}${comp_suf} || shtool_exit $?
+            fi
+        done
+
+        #   move away current logfile
+        if [ ".$opt_c" = .yes ]; then
+            #   approach: copy[+truncate]
+            if [ ".$opt_t" = .yes ]; then
+                echo "cp -p ${ldir}/${file} ${adir}/${file}.${n}"
+            fi
+            cp -p ${ldir}/${file} ${adir}/${file}.${n} || shtool_exit $?
+            if [ ".$opt_r" = .no ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "cp /dev/null ${ldir}/${file}"
+                fi
+                cp /dev/null ${ldir}/${file} || shtool_exit $?
+            fi
+        else
+            #   approach: move[+touch]
+            if [ ".$opt_t" = .yes ]; then
+                echo "mv ${ldir}/${file} ${adir}/${file}.${n}"
+            fi
+            mv ${ldir}/${file} ${adir}/${file}.${n} || shtool_exit $?
+            if [ ".$opt_r" = .no ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "touch ${ldir}/${file}"
+                fi
+                touch ${ldir}/${file} || shtool_exit $?
+                #   fix file attributes
+                if [ ".$opt_o" != . ]; then
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "chown $opt_o ${ldir}/${file}"
+                    fi
+                    chown $opt_o ${ldir}/${file} || shtool_exit $?
+                fi
+                if [ ".$opt_g" != . ]; then
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "chgrp $opt_g ${ldir}/${file}"
+                    fi
+                    chgrp $opt_g ${ldir}/${file} || shtool_exit $?
+                fi
+                if [ ".$opt_m" != . ]; then
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "chmod $opt_m ${ldir}/${file}"
+                    fi
+                    chmod $opt_m ${ldir}/${file} || shtool_exit $?
+                fi
+            fi
+        fi
+
+        #   regular compression step
+        if [ ".$opt_z" != . ] && [ ".$opt_d" = .no ]; then
+            #   compress file
+            if [ ".$opt_b" = .yes ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "(${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${n}${comp_suf}; rm -f ${adir}/${file}.${n}) &"
+                fi
+                ( ${comp_prg} ${comp_lvl} \
+                      <${adir}/${file}.${n} \
+                      >${adir}/${file}.${n}${comp_suf} || shtool_exit $?
+                  rm -f ${adir}/${file}.${n} || shtool_exit $?
+                ) </dev/null >/dev/null 2>&1 &
+            else
+                if [ ".$opt_t" = .yes ]; then
+                    echo "${comp_prg} ${comp_lvl} <${adir}/${file}.${n} >${adir}/${file}.${n}${comp_suf}"
+                fi
+                ${comp_prg} ${comp_lvl} \
+                    <${adir}/${file}.${n} \
+                    >${adir}/${file}.${n}${comp_suf} || shtool_exit $?
+                if [ ".$opt_t" = .yes ]; then
+                    echo "rm -f ${opt_a}${file}.${n}"
+                fi
+                rm -f ${adir}/${file}.${n} || shtool_exit $?
+            fi
+
+            #   fix file attributes
+            if [ ".$opt_o" != . ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "chown $opt_o ${adir}/${file}.${n}${comp_suf}"
+                fi
+                chown $opt_o ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
+            fi
+            if [ ".$opt_g" != . ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "chgrp $opt_g ${adir}/${file}.${n}${comp_suf}"
+                fi
+                chgrp $opt_g ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
+            fi
+            if [ ".$opt_m" != . ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "chmod $opt_m ${adir}/${file}.${n}${comp_suf}"
+                fi
+                chmod $opt_m ${adir}/${file}.${n}${comp_suf} || shtool_exit $?
+            fi
+        fi
+
+        #   execute epilog
+        if [ ".$opt_E" != . ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "$opt_E"
+            fi
+            eval $opt_E
+            [ $? -ne 0 ] && shtool_exit $?
+        fi
+    done
+
+    shtool_exit 0
+    ;;
+
+tarball )
+    ##
+    ##  tarball -- Roll distribution tarballs
+    ##  Copyright (c) 1999-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    srcs="$*"
+
+    #   check whether the test command supports the -x option
+    if [ -x /bin/sh ] 2>/dev/null; then
+        minusx="-x"
+    else
+        minusx="-r"
+    fi
+
+    #   find the tools
+    paths="`echo $PATH |\
+            sed -e 's%/*:%:%g' -e 's%/*$%%' \
+                -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
+                -e 's/:/ /g'`"
+    for spec in find:gfind,find tar:gtar,tar tardy:tardy,tarcust; do
+        prg=`echo $spec | sed -e 's/:.*$//'`
+        tools=`echo $spec | sed -e 's/^.*://'`
+        eval "prg_${prg}=''"
+        #   iterate over tools
+        for tool in `echo $tools | sed -e 's/,/ /g'`; do
+            #   iterate over paths
+            for path in $paths; do
+                if [ $minusx "$path/$tool" ] && [ ! -d "$path/$tool" ]; then
+                    eval "prg_${prg}=\"$path/$tool\""
+                    break
+                fi
+            done
+            eval "val=\$prg_${prg}"
+            if [ ".$val" != . ]; then
+                break
+            fi
+        done
+    done
+
+    #   expand source paths
+    exclude=''
+    for pat in `echo $opt_e | sed 's/,/ /g'`; do
+        exclude="$exclude | grep -v '$pat'"
+    done
+    if [ ".$opt_t" = .yes ]; then
+        echo "cp /dev/null $tmpfile.lst" 1>&2
+    fi
+    cp /dev/null $tmpfile.lst
+    for src in $srcs; do
+        if [ -d $src ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "(cd $src && $prg_find . -type f -depth -print) | sed -e 's:^\\.\$::' -e 's:^\\./::' | cat $exclude >>$tmpfile.lst" 1>&2
+            fi
+            (cd $src && $prg_find . -type f -depth -print) |\
+            sed -e 's:^\.$::' -e 's:^\./::' | eval cat $exclude >>$tmpfile.lst
+        else
+            if [ ".$opt_t" = .yes ]; then
+                echo "echo $src >>$tmpfile.lst" 1>&2
+            fi
+            echo $src >>$tmpfile.lst
+        fi
+    done
+    sort <$tmpfile.lst >$tmpfile.lst.n
+    mv $tmpfile.lst.n $tmpfile.lst
+    if [ ".$opt_v" = .yes ]; then
+        cat $tmpfile.lst | sed -e 's/^/  /' 1>&2
+    fi
+
+    #   determine tarball file and directory name
+    if [ ".$opt_o" != . ]; then
+        tarfile="$opt_o"
+        if [ ".$opt_d" != . ]; then
+            tarname="$opt_d"
+        else
+            tarname=`echo $tarfile | sed -e 's/\.tar.*$//' -e 's;.*/\([^/]*\)$;\1;'`
+        fi
+    else
+        if [ ".$opt_d" != . ]; then
+            tarname="$opt_d"
+        elif [ -d "$from" ]; then
+            tarname=`echo $from | sed -e 's;.*/\([^/]*\)$;\1;'`
+        else
+            tarname="out"
+        fi
+        tarfile="$tarname.tar"
+    fi
+
+    #   roll the tarball
+    compress=''
+    if [ ".$opt_c" != . ]; then
+        compress="| $opt_c"
+    fi
+    if [ ".$prg_tardy" != . ]; then
+        #   the elegant hackers way
+        tardy_opt="--prefix=$tarname"
+        tardy_opt="$tardy_opt --user_number=0 --group_number=0" # security!
+        if [ ".$opt_u" != . ]; then
+            tardy_opt="$tardy_opt --user_name=$opt_u"
+        fi
+        if [ ".$opt_g" != . ]; then
+            tardy_opt="$tardy_opt --group_name=$opt_g"
+        fi
+        if [ ".$opt_t" = .yes ]; then
+            echo "cat $tmpfile.lst | xargs $prg_tar cf - | $prg_tardy $tardy_opt | cat $compress >$tmpfile.out" 1>&2
+        fi
+        cat $tmpfile.lst |\
+        xargs $prg_tar cf - |\
+        $prg_tardy $tardy_opt |\
+        eval cat $compress >$tmpfile.out
+        if [ ".$opt_t" = .yes ]; then
+            echo "cp $tmpfile.out $tarfile" 1>&2
+        fi
+        cp $tmpfile.out $tarfile
+    else
+        #  the portable standard way
+        if [ ".$opt_t" = .yes ]; then
+            echo "mkdir $tmpdir/$tarname" 1>&2
+        fi
+        mkdir $tmpdir/$tarname || shtool_exit 1
+        if [ ".$opt_t" = .yes ]; then
+            echo "cat $tmpfile.lst | xargs $prg_tar cf - | (cd $tmpdir/$tarname && $prg_tar xf -)" 1>&2
+        fi
+        cat $tmpfile.lst |\
+        xargs $prg_tar cf - |\
+        (cd $tmpdir/$tarname && $prg_tar xf -)
+        if [ ".$opt_u" != . ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1" 2>&1
+            fi
+            chown -R $opt_u $tmpdir/$tarname >/dev/null 2>&1 ||\
+            echo "$msgprefix:Warning: cannot set user name \`$opt_u' (would require root privileges)"
+        fi
+        if [ ".$opt_g" != . ]; then
+            if [ ".$opt_t" = .yes ]; then
+                echo "chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1" 2>&1
+            fi
+            chgrp -R $opt_g $tmpdir/$tarname >/dev/null 2>&1 ||\
+            echo "$msgprefix:Warning: cannot set group name \`$opt_g' (would require root privileges)"
+        fi
+        if [ ".$opt_t" = .yes ]; then
+            echo "(cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) | cat $compress >$tmpfile.out" 1>&2
+        fi
+        (cd $tmpdir && $prg_find $tarname -type f -depth -print | sort | xargs $prg_tar cf -) |\
+        eval cat $compress >$tmpfile.out
+        if [ ".$opt_t" = .yes ]; then
+            echo "cp $tmpfile.out $tarfile" 1>&2
+        fi
+        cp $tmpfile.out $tarfile
+        if [ ".$opt_t" = .yes ]; then
+            echo "rm -rf $tmpdir/$tarname" 1>&2
+        fi
+        rm -rf $tmpdir/$tarname
+    fi
+
+    #   cleanup
+    if [ ".$opt_t" = .yes ]; then
+        echo "rm -f $tmpfile.lst $tmpfile.out" 1>&2
+    fi
+    rm -f $tmpfile.lst $tmpfile.out
+
+    shtool_exit 0
+    ;;
+
+subst )
+    ##
+    ##  subst -- Apply sed(1) substitution operations
+    ##  Copyright (c) 2001-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    #   remember optional list of file(s)
+    files="$*"
+    files_num="$#"
+
+    #   parameter consistency check
+    if [ $# -eq 0 ] && [ ".$opt_b" != . ]; then
+        echo "$msgprefix:Error: option -b cannot be applied to stdin" 1>&2
+        shtool_exit 1
+    fi
+    if [ $# -eq 0 ] && [ ".$opt_s" = .yes ]; then
+        echo "$msgprefix:Error: option -s cannot be applied to stdin" 1>&2
+        shtool_exit 1
+    fi
+
+    #   build underlying sed(1) command
+    sedcmd='sed'
+    if [ ".$opt_e" != . ]; then
+        OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_e; IFS="$OIFS"
+        for e
+        do
+            sedcmd="$sedcmd -e '$e'"
+        done
+    elif [ ".$opt_f" != . ]; then
+        if [ ! -f $opt_f ]; then
+            echo "$msgprefix:Error: command file \`$opt_f' not found or not a regular file" 1>&2
+            shtool_exit 1
+        fi
+        sedcmd="$sedcmd -f '$opt_f'"
+    else
+        echo "$msgprefix:Error: either -e option(s) or -f option required" 1>&2
+        shtool_exit 1
+    fi
+
+    #   determine extension for original file
+    orig=".orig"
+    if [ ".$opt_b" != . ]; then
+        orig="$opt_b"
+    fi
+
+    #   apply sed(1) operation(s)
+    if [ ".$files" != . ]; then
+        #   apply operation(s) to files
+        substdone=no
+        for file in $files; do
+            test ".$file" = . && continue
+            if [ ! -f $file ]; then
+                echo "$msgprefix:Warning: file \`$file' not found or not a regular file" 1>&2
+                continue
+            fi
+
+            #   handle interactive mode
+            if [ ".$opt_i" = .yes ]; then
+                eval "$sedcmd <$file >$file.new"
+                skip=no
+                if cmp $file $file.new >/dev/null 2>&1; then
+                    rm -f $file.new
+                    skip=yes
+                else
+                    (diff -U1 $file $file.new >$tmpfile) 2>/dev/null
+                    if [ ".`cat $tmpfile`" = . ]; then
+                        (diff -C1 $file $file.new >$tmpfile) 2>/dev/null
+                        if [ ".`cat $tmpfile`" = . ]; then
+                            echo "$msgprefix:Warning: unable to show difference for file \`$file'" 1>&2
+                            cp /dev/null $tmpfile
+                        fi
+                    fi
+                    rm -f $file.new
+                    cat $tmpfile
+                    echo dummy | awk '{ printf("%s", TEXT); }' TEXT=">>> Apply [Y/n]: "
+                    read input
+                    if [ ".$input" != .Y ] &&\
+                       [ ".$input" != .y ] &&\
+                       [ ".$input" != . ]; then
+                       skip=yes
+                    fi
+                fi
+                if [ ".$skip" = .yes ]; then
+                    if [ ".$opt_v" = .yes ]; then
+                        echo "file \`$file' -- skipped" 1>&2
+                    fi
+                    continue
+                fi
+            fi
+
+            #   apply sed(1) operation(s)
+            if [ ".$opt_v" = .yes ]; then
+                echo "patching \`$file'" 1>&2
+            fi
+            if [ ".$opt_t" = .yes ]; then
+                echo "\$ cp -p $file $file$orig"
+                echo "\$ chmod u+w $file"
+                echo "\$ $sedcmd <$file$orig >$file"
+            fi
+            if [ ".$opt_n" = .no ]; then
+                cp -p $file $file$orig
+                chmod u+w $file >/dev/null 2>&1 || true
+                eval "$sedcmd <$file$orig >$file"
+            fi
+
+            #   optionally fix timestamp
+            if [ ".$opt_s" = .yes ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "\$ touch -r $file$orig $file"
+                fi
+                if [ ".$opt_n" = .no ]; then
+                    touch -r $file$orig $file
+                fi
+            fi
+
+            #   optionally check whether any content change actually occurred 
+            if [ ".$opt_q" = .no ]; then
+                if cmp $file$orig $file >/dev/null 2>&1; then
+                    if [ ".$opt_w" = .yes ]; then
+                        echo "$msgprefix:Warning: substitution resulted in no content change on file \"$file\"" 1>&2
+                    fi
+                else
+                    substdone=yes
+                fi
+            fi
+
+            #   optionally remove preserved original file
+            if [ ".$opt_b" = . ]; then
+                if [ ".$opt_t" = .yes ]; then
+                    echo "\$ rm -f $file$orig"
+                fi
+                if [ ".$opt_n" = .no ]; then
+                    rm -f $file$orig
+                fi
+            fi
+        done
+        if [ ".$opt_q" = .no ] && [ ".$opt_w" = .no ]; then
+            if [ ".$substdone" = .no ]; then
+                if [ ".$files_num" = .1 ]; then
+                    echo "$msgprefix:Warning: substitution resulted in no content change on file \"$file\"" 1>&2
+                else
+                    echo "$msgprefix:Warning: substitution resulted in no content change on any file" 1>&2
+                fi
+            fi
+        fi
+    else
+        #   apply operation(s) to stdin/stdout
+        if [ ".$opt_v" = .yes ]; then
+            echo "patching <stdin>" 1>&2
+        fi
+        if [ ".$opt_t" = .yes ]; then
+            echo "\$ $sedcmd"
+        fi
+        if [ ".$opt_n" = .no ]; then
+            eval "$sedcmd"
+        fi
+    fi
+
+    shtool_exit 0
+    ;;
+
+platform )
+    ##
+    ##  platform -- Platform Identification Utility
+    ##  Copyright (c) 2003-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    #   option post-processing
+    if [ ".$opt_t" != . ]; then
+        case "$opt_t" in
+            binary )
+                #   binary package id (OpenPKG RPM)
+                opt_F="%<ap>-%<sp>"
+                opt_L=yes
+                opt_S=""
+                opt_C="+"
+                ;;
+            build )
+                #   build time checking (OpenPKG RPM)
+                opt_F="%<at>-%<st>"
+                opt_L=yes
+                opt_S=""
+                opt_C="+"
+                ;;
+            gnu )
+                #   GNU config.guess style <arch>-<vendor>-<os><osversion>
+                opt_F="%<at>-unknown-%<st>"
+                opt_L=yes
+                opt_S=""
+                opt_C="+"
+                ;;
+            web )
+                #   non-whitespace HTTP Server-header id
+                opt_F="%<sp>-%<ap>"
+                opt_S="/"
+                opt_C="+"
+                ;;
+            summary)
+                #   human readable verbose summary information
+                opt_F="Class:      %[sc] (%[ac])\\nProduct:    %[sp] (%[ap])\\nTechnology: %[st] (%[at])"
+                opt_S=" "
+                opt_C="/"
+                ;;
+            all-in-one )
+                #   full-table all-in-one information
+                opt_F=""
+                opt_F="${opt_F}concise architecture class:      %<ac>\\n"
+                opt_F="${opt_F}regular architecture class:      %{ac}\\n"
+                opt_F="${opt_F}verbose architecture class:      %[ac]\\n"
+                opt_F="${opt_F}concise architecture product:    %<ap>\\n"
+                opt_F="${opt_F}regular architecture product:    %{ap}\\n"
+                opt_F="${opt_F}verbose architecture product:    %[ap]\\n"
+                opt_F="${opt_F}concise architecture technology: %<at>\\n"
+                opt_F="${opt_F}regular architecture technology: %{at}\\n"
+                opt_F="${opt_F}verbose architecture technology: %[at]\\n"
+                opt_F="${opt_F}concise system class:            %<sc>\\n"
+                opt_F="${opt_F}regular system class:            %{sc}\\n"
+                opt_F="${opt_F}verbose system class:            %[sc]\\n"
+                opt_F="${opt_F}concise system product:          %<sp>\\n"
+                opt_F="${opt_F}regular system product:          %{sp}\\n"
+                opt_F="${opt_F}verbose system product:          %[sp]\\n"
+                opt_F="${opt_F}concise system technology:       %<st>\\n"
+                opt_F="${opt_F}regular system technology:       %{st}\\n"
+                opt_F="${opt_F}verbose system technology:       %[st]"
+                ;;
+            * )
+                echo "$msgprefix:Error: invalid type \`$opt_t'" 1>&2
+                exit 1
+                ;;
+        esac
+    fi
+
+    #   assemble initial platform information
+    UNAME_MACHINE=`(uname -m) 2>/dev/null` ||\
+    UNAME_MACHINE=`(uname -p) 2>/dev/null` ||\
+    UNAME_MACHINE='unknown'
+    UNAME_SYSTEM=`(uname -s) 2>/dev/null`  ||\
+    UNAME_SYSTEM='unknown'
+    UNAME_RELEASE=`(uname -r) 2>/dev/null` ||\
+    UNAME_RELEASE=`(uname -v) 2>/dev/null` ||\
+    UNAME_RELEASE='unknown'
+
+    UNAME="${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}"
+
+    AC=""; AP=""; AT=""
+    SC=""; SP=""; ST=""
+
+    #    dispatch into platform specific sections
+    case "${UNAME}" in
+
+        #   FreeBSD
+        *:FreeBSD:* )
+            #   determine architecture
+            AC="${UNAME_MACHINE}"
+            case "${AC}" in
+                i386 ) AC="iX86" ;;
+            esac
+            AP="${AC}"
+            AT="${AP}"
+            if [ ".${AT}" = ".iX86" ]; then
+                case "`(/sbin/sysctl -n hw.model) 2>&1`" in
+                    *"Xeon"* | *"Pentium Pro"* | *"Cyrix 6x86MX"* | *"Pentium II"* | *"Pentium III"* | *"Pentium 4"* | *"Celeron"* ) AT="i686" ;;
+                    *"Pentium"* ) AT="i586" ;; *"i486[SD]X"* | *"Cyrix 486"* | *"Cyrix [56]x86"* | *"Blue Lightning" | *"Cyrix 486S/DX" ) AT="i486" ;;
+                    *"i386[SD]X"* | *"NexGen 586"* ) AT="i386" ;;
+                esac
+            fi
+            #   determine system
+            r=`echo "${UNAME_RELEASE}" |\
+               sed -e 's;[()];;' -e 's/\(-.*\)$/[\1]/'`
+            ST="FreeBSD ${r}"
+            SP="${ST}"
+            case "${r}" in
+                1.* ) SC="4.3BSD" ;;
+                *   ) SC="4.4BSD" ;;
+            esac
+            ;;
+
+        #   NetBSD
+        *:NetBSD:* )
+            #   determine architecture
+            AT="${UNAME_MACHINE}"
+            AP="${AT}"
+            case "${AP}" in
+                i[3-6]86 ) AP="iX86" ;;
+            esac
+            AC="${AP}"
+            #   determine system
+            r=`echo "${UNAME_RELEASE}" | sed -e 's/\([-_].*\)$/[\1]/'`
+            ST="NetBSD ${r}"
+            SP="${ST}"
+            case "${r}" in
+                0.* ) SC="4.3BSD" ;;
+                *   ) SC="4.4BSD" ;;
+            esac
+            ;;
+
+        #   OpenBSD
+        *:OpenBSD:* )
+            #   determine architecture
+            AT="${UNAME_MACHINE}"
+            AP="${AT}"
+            case "${AP}" in
+                i[3-6]86 ) AP="iX86" ;;
+            esac
+            AC="${AP}"
+            #   determine system
+            r=`echo "${UNAME_RELEASE}" | sed -e 's/\([-_].*\)$/[\1]/'`
+            ST="OpenBSD ${r}"
+            SP="${ST}"
+            SC="4.4BSD"
+            ;;
+
+        #   GNU/Linux
+        *:Linux:* )
+            #   determine architecture
+            AT="${UNAME_MACHINE}"
+            case "${AT}" in
+               ia64     ) AT="IA64"   ;;
+               x86_64   ) AT='AMD64'  ;;
+               parisc   ) AT="HPPA32" ;;
+               parisc64 ) AT="HPPA64" ;;
+            esac
+            AP="${AT}"
+            case "${AP}" in
+               i[3-6]86 ) AP='iX86' ;;
+            esac
+            AC="${AP}"
+            #   determine system
+            v_kern=`echo "${UNAME_RELEASE}" |\
+                sed -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/'`
+            v_libc=`(strings /lib/libc.so.* | grep '^GLIBC_' | sed -e 's/^GLIBC_//' |\
+                env -i sort -n | sed -n -e '$p' | sed -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/') 2>/dev/null`
+            ST="GNU/<Linux >${v_libc}/<${v_kern}>"
+            if [ -f /etc/lsb-release ]; then
+                eval `( . /etc/lsb-release
+                    echo "SC=\"LSB${LSB_VERSION}\""
+                    if [ ".${DISTRIB_ID}" != . -a ".${DISTRIB_RELEASE}" != . ]; then
+                        echo "SP=\"${DISTRIB_ID} ${DISTRIB_RELEASE}\""
+                    fi
+                ) 2>/dev/null`
+            fi
+            if [ ".$SP" = . ]; then
+                for tagfile in x \
+                    `cd /etc && \
+                    /bin/ls *[_-]release *[_-]version 2>/dev/null | env -i sort | \
+                    sed -e '/^redhat-release$/d' -e '/^lsb-release$/d'; \
+                    echo redhat-release lsb-release`
+                do
+                    [ ".${tagfile}" = .x ] && continue
+                    [ ! -f "/etc/${tagfile}" ] && continue
+                    n=`echo ${tagfile} | sed -e 's/[_-]release$//' -e 's/[_-]version$//'`
+                    v=`(grep VERSION /etc/${tagfile}; cat /etc/${tagfile}) | grep '[0-9]' | sed -e 'q' |\
+                       sed -e 's/^/#/' \
+                           -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
+                           -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
+                           -e 's/^#[^0-9]*\([0-9][0-9]*\).*$/\1/' \
+                           -e 's/^#.*$//'`
+                    case "`util_lower ${n}`" in
+                        redhat )
+                            if [ ".`grep 'Red Hat Enterprise Linux' /etc/${tagfile}`" != . ]; then
+                                n="<R>ed <H>at <E>nterprise <L>inux"
+                            else
+                                n="<R>ed <H>at <L>inux"
+                            fi
+                            ;;
+                        debian             ) n="Debian[ GNU/Linux]"        ;;
+                        ubuntu             ) n="Ubuntu[ GNU/Linux]"        ;;
+                        fedora             ) n="<Fedora> Core[ GNU/Linux]" ;;
+                        suse               ) n="SuSE[ Linux]"              ;;
+                        mandrake*|mandriva ) n="Mandriva[ Linux]"          ;;
+                        gentoo             ) n="Gentoo[ GNU/Linux]"        ;;
+                        slackware          ) n="Slackware[ Linux]"         ;;
+                        turbolinux         ) n="TurboLinux"                ;;
+                        unitedlinux        ) n="UnitedLinux"               ;;
+                        *                  ) n="${n}[ GNU/Linux]"          ;;
+                    esac
+                    case "$n" in
+                        *"<"*">"* ) SP="$n <$v>" ;;
+                        *         ) SP="$n $v"   ;;
+                    esac
+                    break
+                done
+            fi
+            [ ".$SP" = . ] && SP="${ST}"
+            [ ".$SC" = . ] && SC="LSB"
+            ;;
+
+        #   Sun Solaris
+        *:SunOS:* )
+            #   determine architecture
+            AT="${UNAME_MACHINE}"
+            case "${AT}" in
+                i86pc )
+                    AT="iX86"
+                    case "`(/bin/isainfo -k) 2>&1`" in
+                        amd64 ) AT="AMD64" ;;
+                    esac
+                    ;;
+            esac
+            AP="${AT}"
+            case "${AP}" in
+                sun4[cdm] ) AP="SPARC32" ;;
+                sun4[uv]  ) AP="SPARC64" ;;
+                sun4*     ) AP="SPARC"   ;;
+            esac
+            AC="${AP}"
+            case "${AC}" in
+                SPARC* ) AC="SPARC" ;;
+            esac
+            #   determine system
+            ST="[Sun ]SunOS ${UNAME_RELEASE}"
+            v=`echo "${UNAME_RELEASE}" |\
+               sed -e 's;^4\.;1.;' \
+                   -e 's;^5\.\([0-6]\)[^0-9]*$;2.\1;' \
+                   -e 's;^5\.\([0-9][0-9]*\).*;\1;'`
+            SP="[Sun ]Solaris $v"
+            case "${UNAME_RELEASE}" in
+                4.* ) SC="4.3BSD" ;;
+                5.* ) SC="SVR4"   ;;
+            esac
+            ;;
+
+        #   SCO UnixWare
+        *:UnixWare:* )
+            #   determine architecture
+            AT="${UNAME_MACHINE}"
+            case "${AT}" in
+                i[3-6]86 | ix86at ) AT="iX86" ;;
+            esac
+            AP="${AT}"
+            #   determine system
+            v=`/sbin/uname -v`
+            ST="[SCO ]UnixWare ${v}"
+            SP="${ST}"
+            SC="SVR${UNAME_RELEASE}"
+            ;;
+
+        #   QNX
+        *:QNX:* )
+            #   determine architecture
+            AT="${UNAME_MACHINE}"
+            case "${AT}" in
+                x86pc ) AT="iX86" ;;
+            esac
+            AP="${AT}"
+            #   determine system
+            v="${UNAME_RELEASE}"
+            ST="QNX[ Neutrino RTOS] ${v}"
+            v=`echo "${v}" | sed -e 's;^\([0-9][0-9]*\.[0-9][0-9]*\).*$;\1;'`
+            SP="QNX[ Neutrino RTOS] ${v}"
+            SC="QNX"
+            ;;
+
+        #   SGI IRIX
+        *:IRIX*:* )
+            #   determine architecture
+            AT="${UNAME_MACHINE}"
+            AP="${AT}"
+            case "${AP}:${UNAME_SYSTEM}" in
+                IP*:IRIX64 ) AP="MIPS64" ;;
+                IP*:*      ) AP="MIPS"   ;;
+            esac
+            AC="${AP}"
+            #   determine system
+            v=`(/bin/uname -R || /bin/uname -r) 2>/dev/null | sed -e 's;[0-9.]* ;;'`
+            ST="[SGI ]IRIX ${v}"
+            v="${UNAME_RELEASE}"
+            SP="[SGI ]IRIX ${v}"
+            SC="4.2BSD/SVR3"
+            ;;
+
+        #   HP HP-UX
+        *:HP-UX:* )
+            #   determine architecture
+            AT="${UNAME_MACHINE}"
+            case "${AT}" in
+                ia64 ) AT="IA64" ;;
+                9000/[34]?? ) AT=M68K ;;
+                9000/[678][0-9][0-9])
+                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                        523 ) AT="HPPA1.0" ;;
+                        528 ) AT="HPPA1.1" ;;
+                        532 ) AT="HPPA2.0"
+                            case "${sc_kernel_bits}" in
+                                32 ) AT="${AT}n" ;;
+                                64 ) AT="${AT}w" ;;
+                            esac
+                            ;;
+                    esac
+                    ;;
+            esac
+            AP="${AT}"
+            case "${AP}" in
+                HPPA* ) AP="HPPA" ;;
+            esac
+            AC="${AP}"
+            #   determine system
+            v=`echo "${UNAME_RELEASE}" | sed -e 's;^[^0-9]*;;'`
+            ST="[HP ]<HP>-<UX ${v}>"
+            SP="${ST}"
+            case "${v}" in
+                10.*   ) SC="SVR4.2" ;;
+                [7-9]* ) SC="SVR4"   ;;
+            esac
+            ;;
+
+        #   HP Tru64 (OSF1)
+        *:OSF1:* )
+            #   determine architecture
+            AP="${UNAME_MACHINE}"
+            case "${AP}" in
+                alpha ) AP="Alpha" ;;
+            esac
+            alpha_type=`(/usr/sbin/psrinfo -v) 2>/dev/null |\
+                sed -n -e 's/^.*The alpha \([^ ][^ ]*\).*processor.*$/\1/p' | sed -e 'q'`
+            AT="${AP}${alpha_type}"
+            AC="${AP}"
+            #   determine system
+            v=`echo "${UNAME_RELEASE}" | sed -e 's;^[VTX];;'`
+            ST="[HP ]Tru64 ${v}"
+            SP="${ST}"
+            SC="OSF1"
+            ;;
+
+        #   IBM AIX
+        *:AIX:* )
+            cpu_arch=rs6000
+            if [ -x /usr/sbin/lsdev -a -x /usr/sbin/lsattr ]; then
+                cpu_id=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+                if [ ".`/usr/sbin/lsattr -El ${cpu_id} | grep -i powerpc`" != . ]; then
+                    cpu_arch=powerpc
+                fi
+            elif [ -d /QOpenSys ]; then
+                #   IBM i5/OS (aka OS/400) with PASE (Portable Application Solutions Environment)
+                cpu_arch=powerpc
+            fi
+            if [ -x /usr/bin/oslevel ]; then
+                os_level=`/usr/bin/oslevel`
+            else
+                os_level="`uname -v`.`uname -r`"
+            fi
+            os_level=`echo "${os_level}" |\
+                      sed -e 's;^\([0-9][0-9]*\.[0-9][0-9]*\)\(\.[0-9][0-9]*\)\(.*\)$;<\1>\2[\3];' \
+                          -e 's;^\([0-9][0-9]*\.[0-9][0-9]*\)\(.*\)$;<\1>\2;'`
+            AT="${cpu_arch}"
+            AP="${AT}"
+            AC="${AP}"
+            ST="[IBM ]<AIX >${os_level}"
+            SP="${ST}"
+            case "${os_level}" in
+                [12]* ) SC="SVR2" ;;
+                *     ) SC="SVR4" ;;
+            esac
+            ;;
+
+        #   Apple MacOS X Darwin
+        *:Darwin:* )
+            AT=`uname -p`
+            case "${AT}" in
+                powerpc ) AT="PPC" ;;
+            esac
+            AP="${AT}"
+            AC="${AP}"
+            case "${AC}" in
+                i?86 ) AC="iX86" ;;
+            esac
+            ST="[Apple ]${UNAME_SYSTEM} ${UNAME_RELEASE}"
+            SP="${ST}"
+            SC="4.4BSD/Mach3"
+            ;;
+
+        #   TODO ...ADD YOUR NEW PLATFORM CHECK HERE... TODO
+        # *:XXX:* )
+        #   ...
+        #   ;;
+
+        #   ...A STILL UNKNOWN PLATFORM...
+        * )
+            AT=`echo "${UNAME_MACHINE}" | sed -e "s; ;${opt_C};g"`
+            AP="${AT}"
+            AC="${AP}"
+            v=`echo "${UNAME_RELEASE}" |\
+               sed -e 's/^/#/' \
+                   -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
+                   -e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
+                   -e 's/^#[^0-9]*\([0-9][0-9]*\).*$/\1/' \
+                   -e 's/^#.*$/?/'`
+            ST="${UNAME_SYSTEM} ${v}"
+            SP="${ST}"
+            SC="${SP}"
+            ;;
+
+    esac
+
+    #   provide fallback values
+    [ ".$AT" = . ] && AT="${AP:-${AC}}"
+    [ ".$AP" = . ] && AP="${AT:-${AC}}"
+    [ ".$AC" = . ] && AC="${AP:-${AT}}"
+    [ ".$ST" = . ] && ST="${SP:-${SC}}"
+    [ ".$SP" = . ] && SP="${ST:-${SC}}"
+    [ ".$SC" = . ] && SC="${SP:-${ST}}"
+
+    #   support explicit enforced verbose/concise output
+    if [ ".$opt_v" = .yes ]; then
+        opt_F=`echo ":$opt_F" | sed -e 's/^://' -e 's/%\([as][cpt]\)/%[\1]/g'`
+    elif [ ".$opt_c" = .yes ]; then
+        opt_F=`echo ":$opt_F" | sed -e 's/^://' -e 's/%\([as][cpt]\)/%<\1>/g'`
+    fi
+
+    #   provide verbose and concise variants
+    AC_V=""; AC_N=""; AC_C=""
+    AP_V=""; AP_N=""; AP_C=""
+    AT_V=""; AT_N=""; AT_C=""
+    SC_V=""; SC_N=""; SC_C=""
+    SP_V=""; SP_N=""; SP_C=""
+    ST_V=""; ST_N=""; ST_C=""
+    for var_lc in at ap ac st sp sc; do
+        case "$opt_F" in
+            *"%[${val_lc}]"* | *"%{${val_lc}}"* | *"%${val_lc}"* | *"%<${val_lc}>"* )
+            var_uc=`util_upper "$var_lc"`
+            eval "val=\"\$${var_uc}\""
+            val_V=""; val_N=""; val_C=""
+            case "$opt_F" in
+                *"%[${var_lc}]"* )
+                    val_V=`echo ":$val" | \
+                           sed -e 's/^://' \
+                               -e 's;\[\([^]]*\)\];\1;g' \
+                               -e 's;<\([^>]*\)>;\1;g' \
+                               -e "s; ;§§;g" \
+                               -e "s;/;%%;g" \
+                               -e "s;§§;${opt_S};g" \
+                               -e "s;%%;${opt_C};g"`
+                    eval "${var_uc}_V=\"\${val_V}\""
+                    ;;
+            esac
+            case "$opt_F" in
+                *"%{${var_lc}}"* | *"%${var_lc}"* )
+                    val_N=`echo ":$val" | \
+                           sed -e 's/^://' \
+                               -e 's;\[\([^]]*\)\];;g' \
+                               -e 's;<\([^>]*\)>;\1;g' \
+                               -e "s; ;§§;g" \
+                               -e "s;/;%%;g" \
+                               -e "s;§§;${opt_S};g" \
+                               -e "s;%%;${opt_C};g"`
+                    eval "${var_uc}_N=\"\${val_N}\""
+                    ;;
+            esac
+            case "$opt_F" in
+                *"%<${var_lc}>"* )
+                    val_C=`echo ":$val" | \
+                           sed -e 's/^://' \
+                               -e 's;\[\([^]]*\)\];;g' \
+                               -e 's;[^<]*<\([^>]*\)>[^<]*;\1;g' \
+                               -e "s; ;§§;g" \
+                               -e "s;/;%%;g" \
+                               -e "s;§§;${opt_S};g" \
+                               -e "s;%%;${opt_C};g"`
+                    eval "${var_uc}_C=\"\${val_C}\""
+                    ;;
+            esac
+            ;;
+        esac
+    done
+
+    #   create output string
+    output=`echo ":$opt_F" |\
+            sed -e "s/^://" \
+                -e "s;%\\[ac\\];${AC_V};g" \
+                -e "s;%{ac};${AC_N};g" \
+                -e "s;%ac;${AC_N};g" \
+                -e "s;%<ac>;${AC_C};g" \
+                -e "s;%\\[ap\\];${AP_V};g" \
+                -e "s;%{ap};${AP_N};g" \
+                -e "s;%ap;${AP_N};g" \
+                -e "s;%<ap>;${AP_C};g" \
+                -e "s;%\\[at\\];${AT_V};g" \
+                -e "s;%{at};${AT_N};g" \
+                -e "s;%at;${AT_N};g" \
+                -e "s;%<at>;${AT_C};g" \
+                -e "s;%\\[sc\\];${SC_V};g" \
+                -e "s;%{sc};${SC_N};g" \
+                -e "s;%sc;${SC_N};g" \
+                -e "s;%<sc>;${SC_C};g" \
+                -e "s;%\\[sp\\];${SP_V};g" \
+                -e "s;%{sp};${SP_N};g" \
+                -e "s;%sp;${SP_N};g" \
+                -e "s;%<sp>;${SP_C};g" \
+                -e "s;%\\[st\\];${ST_V};g" \
+                -e "s;%{st};${ST_N};g" \
+                -e "s;%st;${ST_N};g" \
+                -e "s;%<st>;${ST_C};g" \
+                -e 's/\\\\n/^/g' |\
+             tr '^' '\012'`
+
+    #   support lower/upper-case mapping
+    if [ ".$opt_L" = .yes ]; then
+        output=`util_lower "$output"`
+    elif [ ".$opt_U" = .yes ]; then
+        output=`util_upper "$output"`
+    fi
+
+    #   display output string
+    if [ ".$opt_n" = .yes ]; then
+        echo . | awk '{ printf("%s", output); }' output="$output"
+    else
+        echo "$output"
+    fi
+
+    shtool_exit 0
+    ;;
+
+arx )
+    ##
+    ##  arx -- Extended archive command
+    ##  Copyright (c) 1999-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    ar_prg="$opt_C"
+    ar_cmd="$1"; shift
+    archive="$1"; shift
+    files="$*"
+
+    #   walk through the file list and expand archives members
+    ar_tmpdir=`echo $archive | sed -e 's;[^/]*$;.arx;'`
+    nfiles=''
+    if [ ".$files" != . ]; then
+        for file in $files; do
+            if [ ! -f $file ]; then
+                echo "$msgprefix:Error: input file not found: $file" 1>&2
+                shtool_exit 1
+            fi
+            case $file in
+                *.a )
+                    if [ ! -d $ar_tmpdir ]; then
+                        if [ ".$opt_t" = .yes ]; then
+                            echo "mkdir $ar_tmpdir" 1>&2
+                        fi
+                        mkdir $ar_tmpdir
+                    fi
+                    case $ar_tmpdir in
+                         .arx )
+                             from="../$file"
+                             ;;
+                         * )
+                             dir=`echo $file | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;'`
+                             base=`echo $file | sed -e 's;.*/\([^/]*\)$;\1;'`
+                             from="`cd $dir; pwd`/$base"
+                             ;;
+                    esac
+                    if [ ".$opt_t" = .yes ]; then
+                        echo "(cd $ar_tmpdir && $ar_prg x $from)" 1>&2
+                    fi
+                    (cd $ar_tmpdir && eval $ar_prg x $from)
+                    if [ $? -ne 0 ]; then
+                        echo "$msgprefix:Error: member extraction failed for archive: $file" 1>&2
+                        shtool_exit 1
+                    fi
+                    for member in - `eval $ar_prg t $file | sed -e '/_\.SYMDEF/d'`; do
+                        [ ".$member" = .- ] && continue
+                        nfiles="$nfiles $ar_tmpdir/$member"
+                    done
+                    ;;
+                * )
+                    nfiles="$nfiles $file"
+                    ;;
+            esac
+        done
+    fi
+
+    #   run the final archive command
+    if [ ".$opt_t" = .yes ]; then
+        echo "$ar_prg $ar_cmd $archive $nfiles" 1>&2
+    fi
+    eval $ar_prg $ar_cmd $archive $nfiles
+    if [ $? -ne 0 ]; then
+        echo "$msgprefix:Error: archive command failed" 1>&2
+        shtool_exit $?
+    fi
+
+    #   cleanup and die gracefully
+    if [ -d $ar_tmpdir ]; then
+        if [ ".$opt_t" = .yes ]; then
+            echo "rm -rf $ar_tmpdir" 1>&2
+        fi
+        rm -rf $ar_tmpdir
+    fi
+
+    shtool_exit 0
+    ;;
+
+slo )
+    ##
+    ##  slo -- Separate linker options by library class
+    ##  Copyright (c) 1998-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    DIFS="$IFS"
+
+    #   parse out -L and -l options from command line
+    DIRS=''
+    LIBS=''
+    ARGV=''
+    optprev=''
+    for opt
+    do
+        #   concatenate with previous option if exists
+        if [ ".$optprev" != . ]; then
+            opt="${optprev}${opt}";
+            optprev=''
+        fi
+        #   remember options for arg if used stand-alone
+        if [ ".$opt" = ".-L" ] || [ ".$opt" = ".-l" ]; then
+            optprev="$opt"
+            continue;
+        fi
+        #   split argument into option plus option argument
+        arg="`echo $opt | cut -c3-`"
+        opt="`echo $opt | cut -c1-2`"
+        #   store into containers
+        case $opt in
+            -L) DIRS="$DIRS:$arg" ;;
+            -l) LIBS="$LIBS:$arg" ;;
+             *) ARGV="$ARGV $opt" ;;
+        esac
+    done
+
+    #   set linker default directories
+    DIRS_DEFAULT='/lib:/usr/lib'
+    if [ ".$LD_LIBRARY_PATH" != . ]; then
+        DIRS_DEFAULT="$DIRS_DEFAULT:$LD_LIBRARY_PATH"
+    fi
+
+    #   sort options by class
+    DIRS_OBJ=''
+    LIBS_OBJ=''
+    DIRS_PIC=''
+    LIBS_PIC=''
+    DIRS_DSO=''
+    LIBS_DSO=''
+
+    #    for each library...
+    OIFS="$IFS"; IFS=':'
+    for lib in $LIBS; do
+        [ ".$lib" = . ] && continue
+
+        found='no'
+        found_indefdir='no'
+        found_type=''
+        found_dir=''
+
+        #    for each directory...
+        OIFS2="$IFS"; IFS=":$DIFS"
+        for dir in ${DIRS} switch-to-defdirs ${DIRS_DEFAULT}; do
+            [ ".$dir" = . ] && continue
+            [ ".$dir" = .switch-to-defdirs ] && found_indefdir=yes
+            [ ! -d $dir ] && continue
+
+            #    search the file
+            OIFS3="$IFS"; IFS="$DIFS"
+            for file in '' `cd $dir && env -i /bin/ls lib${lib}.* 2>/dev/null`; do
+                 [ ".$file" = . ] && continue
+                 case $file in
+                     *.so|*.so.[0-9]*|*.sl|*.sl.[0-9]* )
+                          found=yes;
+                          found_type=DSO;
+                          break
+                          ;;
+                     *.lo|*.la )
+                          found=yes;
+                          found_type=PIC
+                          ;;
+                     *.a )
+                          if [ ".$found_type" = . ]; then
+                              found=yes
+                              found_type=OBJ
+                          fi
+                          ;;
+                 esac
+            done
+            IFS="$OIFS3"
+            if [ ".$found" = .yes ]; then
+                found_dir="$dir"
+                break
+            fi
+        done
+        IFS="$OIFS2"
+
+        if [ ".$found" = .yes ]; then
+            if [ ".$found_indefdir" != .yes ]; then
+                eval "dirlist=\"\${DIRS_${found_type}}:\""
+                case "$dirlist" in
+                    *:$found_dir:* ) ;;
+                    * ) eval "DIRS_${found_type}=\"\$DIRS_${found_type}:${found_dir}\"" ;;
+                esac
+                eval "LIBS_${found_type}=\"\$LIBS_${found_type}:$lib\""
+            else
+                eval "LIBS_${found_type}=\"\$LIBS_${found_type}:$lib\""
+            fi
+        else
+            LIBS_OBJ="$LIBS_OBJ:$lib"
+            #dirlist="`echo $DIRS $DIRS_DEFAULT | sed -e 's/:/ /g'`"
+            #echo "slo:Warning: library \"$lib\" not found in any of the following dirs:" 2>&1
+            #echo "slo:Warning: $dirlist" 1>&1
+        fi
+    done
+    IFS="$OIFS"
+
+    #   also pass-through unused dirs even if it's useless
+    OIFS="$IFS"; IFS=':'
+    for dir in $DIRS; do
+        dirlist="${DIRS_OBJ}:${DIRS_PIC}:${DIRS_DSO}:"
+        case "$dirlist" in
+            *:$dir:* ) ;;
+            * ) DIRS_OBJ="$DIRS_OBJ:$dir" ;;
+        esac
+    done
+    IFS="$OIFS"
+
+    #   reassemble the options but separated by type
+    for type in OBJ PIC DSO; do
+        OIFS="$IFS"; IFS=':'
+        eval "libs=\"\$LIBS_${type}\""
+        opts=''
+        for lib in $libs; do
+            [ ".$lib" = . ] && continue
+            opts="$opts -l$lib"
+        done
+        eval "LIBS_${type}=\"$opts\""
+
+        eval "dirs=\"\$DIRS_${type}\""
+        opts=''
+        for dir in $dirs; do
+            [ ".$dir" = . ] && continue
+            opts="$opts -L$dir"
+        done
+        eval "DIRS_${type}=\"$opts\""
+        IFS="$OIFS"
+    done
+
+    #   give back results
+    for var in ARGV DIRS_OBJ LIBS_OBJ DIRS_PIC LIBS_PIC DIRS_DSO LIBS_DSO; do
+        eval "val=\"\$${var}\""
+        val="`echo $val | sed -e 's/^ *//'`"
+        echo "${opt_p}${var}=\"${val}\""
+    done
+
+    shtool_exit 0
+    ;;
+
+scpp )
+    ##
+    ##  scpp -- Sharing C Pre-Processor
+    ##  Copyright (c) 1999-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    srcs="$*"
+    output="${opt_o}.n"
+
+    #   find a reasonable Awk
+    awk=''
+    paths=`echo $PATH |\
+           sed -e 's%/*:%:%g' -e 's%/$%%' \
+               -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \
+               -e 's/:/ /g'`
+    for name in gawk nawk awk; do
+        for path in $paths; do
+            if [ -r "$path/$name" ]; then
+                awk="$path/$name"
+                break
+            fi
+        done
+        if [ ".$awk" != . ]; then
+            break
+        fi
+    done
+    if [ ".$awk" = . ]; then
+        echo "$msgprefix:Error: cannot find a reasonable Awk" 1>&2
+        shtool_exit 1
+    fi
+
+    #   parse source file(s)
+    if [ ".$opt_v" = .yes ]; then
+        echo "Parsing:" | $awk '{ printf("%s", $0); }' 1>&2
+    fi
+    for src in $srcs; do
+        if [ ".$opt_v" = .yes ]; then
+            echo $src | $awk '{ printf(" %s", $0); }' 1>&2
+        fi
+        if [ ".$opt_f" != . ]; then
+            inputcmd="sed"
+            OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_f; IFS="$OIFS"
+            for e
+            do
+                inputcmd="$inputcmd -e '$e'"
+            done
+            inputcmd="$inputcmd '$src'"
+        else
+            inputcmd="cat '$src'"
+        fi
+        eval $inputcmd |\
+        $awk '
+           BEGIN {
+               ln    = 0;
+               fln   = 0;
+               level = 0;
+               mode  = "";
+               store = "";
+           }
+           {
+               ln++;
+           }
+           /^#if.*/ {
+               level++;
+           }
+           /^#if [a-zA-Z_][a-zA-Z0-9_]* *$/ {
+               if ($2 == define) {
+                   mode = "D";
+                   printf("D:#line %d \"%s\"\n", ln, src);
+                   next;
+               }
+           }
+           /^#endif.*/ {
+               level--;
+               if (mode == "D" && level == 0) {
+                   mode = "";
+                   next;
+               }
+           }
+           /^[a-zA-Z_][a-zA-Z0-9_].*;.*/ {
+               if ($1 == class) {
+                   printf("V:#line %d \"%s\"\n", ln, src);
+                   printf("V:%s\n", $0);
+                   printf("J:%s\n", $0);
+                   next;
+               }
+           }
+           /^[a-zA-Z_][a-zA-Z0-9_].*=.*/ {
+               if ($1 == class) {
+                   printf("V:#line %d \"%s\"\n", ln, src);
+                   printf("V:%s\n", $0);
+                   printf("J:%s\n", $0);
+                   next;
+               }
+           }
+           /^[a-zA-Z_][a-zA-Z0-9_]*/ {
+               if ($1 == class) {
+                   fln = ln;
+                   store = $0;
+                   mode = "F";
+                   next;
+               }
+           }
+           /^\{ *$/ {
+               if (mode == "F") {
+                   printf("F:#line %d \"%s\"\n", fln, src);
+                   printf("F:%s;\n", store);
+                   printf("I:%s;\n", store);
+                   store = "";
+                   mode = "";
+                   next;
+               }
+           }
+           {
+               if (mode == "D")
+                   printf("D:%s\n", $0);
+               else if (mode == "F")
+                   store = store " " $0;
+           }
+        ' "src=$src" "define=$opt_D" "class=$opt_C" >>$tmpfile
+    done
+    if [ ".$opt_v" = .yes ]; then
+        echo "" 1>&2
+    fi
+
+    #   start generating output header
+    echo "/* $opt_o -- autogenerated from $opt_t, DO NOT EDIT! */" >$output
+    echo "#line 1 \"$opt_t\"" >>$output
+    sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd' |\
+    sed -e "/^${opt_M} *\$/d" >>$output
+
+    #   merge in the define blocks
+    grep '^D:' $tmpfile | sed -e 's/^D://' >>$output
+
+    #   generate standard prolog
+    echo "#line 1 \"_ON_THE_FLY_\"" >>$output
+    echo "" >>$output
+    echo "/* make sure the scpp source extensions are skipped */" >>$output
+    echo "#define $opt_D 0" >>$output
+    echo "#define $opt_C /**/" >>$output
+
+    #   generate namespace hiding for variables
+    echo "" >>$output
+    echo "/* move intern variables to hidden namespace */" >>$output
+    grep '^J:' $tmpfile | sed >>$output \
+        -e 's/^J://' \
+        -e 's/  */ /g' \
+        -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\];.*$/#define \1 __\1/' \
+        -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\] =.*$/#define \1 __\1/' \
+        -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\);.*$/#define \1 __\1/' \
+        -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\) =.*$/#define \1 __\1/'
+
+    #   generate namespace hiding for functions
+    echo "" >>$output
+    echo "/* move intern functions to hidden namespace */" >>$output
+    grep '^I:' $tmpfile | sed >>$output \
+        -e 's/^I://' \
+        -e 's/\([ (]\) */\1/g' \
+        -e 's/ *\([),]\)/\1/g' \
+        -e 's/^[^(]*[ *]\([a-zA-Z0-9_]*\)(.*$/#define \1 __\1/'
+
+    #   generate prototypes for variables
+    echo "" >>$output
+    echo "/* prototypes for intern variables */" >>$output
+    grep '^V:' $tmpfile | sed >>$output \
+        -e 's/^V://' \
+        -e 's/  */ /g' \
+        -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\);.*$/\1;/' \
+        -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\) =.*$/\1;/' \
+        -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\);.*$/\1;/' \
+        -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\) =.*$/\1;/' \
+        -e 's/ ;/;/g' \
+        -e "s/^$opt_C /extern /"
+
+    #   generate prototypes for functions
+    echo "" >>$output
+    echo "/* prototypes for intern functions */" >>$output
+    grep '^F:' $tmpfile | sed >>$output \
+        -e 's/^F://' \
+        -e 's/\([ (]\) */\1/g' \
+        -e 's/ *\([),]\)/\1/g' \
+        -e 's/\([* ]\)[a-zA-Z0-9_]*,/\1,/g' \
+        -e 's/\([* ]\)[a-zA-Z0-9_]*);/\1);/g' \
+        -e 's/(\*[a-zA-Z0-9_]*)(/(*)(/g' \
+        -e 's/\([ (]\) */\1/g' \
+        -e 's/ *\([),]\)/\1/g' \
+        -e "s/^$opt_C /extern /"
+
+    #   finish generating output header
+    n=`(echo ''; sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd') |\
+       wc -l | sed -e 's;^ *\([0-9]*\) *$;\1;'`
+    echo "#line $n \"$opt_t\"" >>$output
+    sed <$opt_t -e "/^${opt_M} *\$/,\$p" -e 'd' |\
+    sed -e "/^${opt_M} *\$/d" >>$output
+
+    #   create final output file
+    if [ -f $opt_o ]; then
+        if [ ".$opt_p" = .yes ]; then
+            grep -v '^#line' $opt_o  >$tmpfile.o
+            grep -v '^#line' $output >$tmpfile.n
+            out_old="$tmpfile.o"
+            out_new="$tmpfile.n"
+        else
+            out_old="$opt_o"
+            out_new="$output"
+        fi
+        if cmp -s $out_old $out_new; then
+            :
+        else
+            cp $output $opt_o
+        fi
+    else
+        cp $output $opt_o
+    fi
+    rm -f $output
+    rm -f $tmpfile $tmpfile.* >/dev/null 2>&1
+
+    shtool_exit 0
+    ;;
+
+version )
+    ##
+    ##  version -- Maintain a version information file
+    ##  Copyright (c) 1994-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    file="$1"
+
+    #   determine prefix and name
+    name="$opt_n"
+    prefix="$opt_p"
+
+    #   determine current version
+    triple="$opt_s"
+    if [ ".$triple" != . ]; then
+        #   use given triple
+        if [ ".`echo $triple | grep '[0-9]*.[0-9]*[sabp.][0-9]*'`" = . ]; then
+            echo "$msgprefix:Error: invalid argument to option \`-s': \`$opt_s'" 1>&2
+            shtool_exit 1
+        fi
+        eval `echo $triple |\
+              sed -e 's%\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\).*%\
+              ver="\1";rev="\2";typ="\3";lev="\4"%'`
+        tim=calc
+    elif [ -r $file ]; then
+        #   determine triple from given file
+        eval `grep 'Version [0-9]*.[0-9]*[sabp.][0-9]* ([0-9]*-[a-zA-Z]*-[0-9]*)' $file |\
+              sed -e 's%.*Version \([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\) (\([0-9]*-[a-zA-Z]*-[0-9]*\)).*%\
+              ver="\1";rev="\2";typ="\3";lev="\4";tim="\5"%' -e 'q'`
+    else
+        #   intialise to first version
+        ver=0
+        rev=1
+        typ=.
+        lev=0
+        tim=calc
+    fi
+
+    #   determine new version in batch
+    if [ ".$opt_i" != . ]; then
+        case $opt_i in
+            v ) ver=`expr $ver + 1`
+                rev=0
+                lev=0
+                ;;
+            r ) rev=`expr $rev + 1`
+                lev=0
+                ;;
+            l ) lev=`expr $lev + 1`
+                ;;
+            * ) echo "$msgprefix:Error: invalid argument to option \`-i': \`$opt_i'" 1>&2
+                shtool_exit 1
+                ;;
+        esac
+        tim=calc
+    fi
+
+    #   determine new version interactively
+    if [ ".$opt_e" = .yes ]; then
+        echo "old version: ${ver}.${rev}${typ}${lev}"
+        while [ 1 ]; do
+            echo dummy | awk '{ printf("new version: "); }'
+            read triple
+            case $triple in
+                [0-9]*.[0-9]*[sabp.][0-9]* )
+                    ;;
+                * ) echo "$msgprefix:Error: invalid version string entered: \`$triple'" 1>&2
+                    continue
+                    ;;
+            esac
+            break
+        done
+        eval `echo $triple |\
+              sed -e 's%^\([0-9]*\)\.\([0-9]*\)\([sabp.]\)\([0-9]*\)$%\
+              ver="\1";rev="\2";typ="\3";lev="\4"%'`
+        tim=calc
+    fi
+
+    #   determine hexadecimal and libtool value of version
+    case $typ in
+        a     ) typnum=0;  levnum=$lev ;;
+        b     ) typnum=1;  levnum=$lev ;;
+        p | . ) typnum=2;  levnum=$lev ;;
+        s     ) typnum=15; levnum=255  ;; # snapshots are special
+    esac
+    hex=`echo "$ver:$rev:$typnum:$levnum" |\
+         awk -F: '{ printf("0x%x%02x%1x%02x", $1, $2, $3, $4); }' |\
+         tr 'abcdef' 'ABCDEF'`
+    ltv=`echo "$ver:$rev:$typnum:$levnum" |\
+         awk -F: '{ printf("%d:%d", $1*10 + $2, $3*10 + $4); }'`
+
+    #   determine date
+    if [ ".$tim" = .calc ]; then
+        day=`date '+%d'`
+        month=`date '+%m'`
+        year=`date '+%Y' 2>/dev/null`
+        if [ ".$time_year" = . ]; then
+            year=`date '+%y'`
+            case $year in
+                [5-9][0-9]) year="19$year" ;;
+                [0-4][0-9]) year="20$year" ;;
+            esac
+        fi
+        case $month in
+            1|01) month='Jan' ;;
+            2|02) month='Feb' ;;
+            3|03) month='Mar' ;;
+            4|04) month='Apr' ;;
+            5|05) month='May' ;;
+            6|06) month='Jun' ;;
+            7|07) month='Jul' ;;
+            8|08) month='Aug' ;;
+            9|09) month='Sep' ;;
+              10) month='Oct' ;;
+              11) month='Nov' ;;
+              12) month='Dec' ;;
+        esac
+        tim="${day}-${month}-${year}"
+    fi
+
+    #   perform result actions
+    mode=show
+    if [ ".$opt_i" != . ]; then
+        mode=edit
+    elif [ ".$opt_e" = .yes ]; then
+        mode=edit
+    elif [ ".$opt_s" != . ]; then
+        mode=edit
+    fi
+    if [ ".$mode" = .show ]; then
+        #   just display the current version
+        case $opt_d in
+            short )
+                echo "${ver}.${rev}${typ}${lev}"
+                ;;
+            long )
+                echo "${ver}.${rev}${typ}${lev} ($tim)"
+                ;;
+            libtool )
+                echo "${ltv}"
+                ;;
+            hex )
+                echo "${hex}"
+                ;;
+            * ) echo "$msgprefix:Error: invalid argument to option \`-d': \`$opt_d'" 1>&2
+                shtool_exit 1
+                ;;
+        esac
+    else
+        #   update the version file
+
+        #   pre-generate various strings
+        triple="${ver}.${rev}${typ}${lev}"
+        vHex="$hex"
+        vShort="${triple}"
+        vLong="${triple} (${tim})"
+        vTeX="This is ${name}, Version ${triple} (${tim})"
+        vGNU="${name} ${triple} (${tim})"
+        vWeb="${name}/${triple}"
+        vSCCS="@(#)${name} ${triple} (${tim})"
+        vRCS="\$Id: ${name} ${triple} (${tim}) \$"
+
+        #   determine string out of filename
+        #   (do NOT try to optimize this in any way because of portability)
+        filestr=`util_upper "$file" | tr './%+' '____' | sed -e 's/-/_/g'`
+
+        #   generate uppercase prefix
+        prefixupper=`util_upper "$prefix"`
+
+        #   create the version file according the the selected language
+        echo "new version: ${vLong}"
+
+        cp /dev/null $file
+        case $opt_l in
+            txt )
+                echo >>$file ""
+                echo >>$file "  ${file} -- Version Information for ${name} (syntax: Text)"
+                echo >>$file "  [automatically generated and maintained by GNU shtool]"
+                echo >>$file ""
+                echo >>$file "  $vTeX"
+                echo >>$file ""
+                ;;
+            c )
+                echo >>$file "/*"
+                echo >>$file "**  ${file} -- Version Information for ${name} (syntax: C/C++)"
+                echo >>$file "**  [automatically generated and maintained by GNU shtool]"
+                echo >>$file "*/"
+                echo >>$file ""
+                echo >>$file "#ifdef _${filestr}_AS_HEADER_"
+                echo >>$file ""
+                echo >>$file "#ifndef _${filestr}_"
+                echo >>$file "#define _${filestr}_"
+                echo >>$file ""
+                echo >>$file "#define ${prefixupper}VERSION ${vHex}"
+                echo >>$file ""
+                echo >>$file "typedef struct {"
+                echo >>$file "    const int   v_hex;"
+                echo >>$file "    const char *v_short;"
+                echo >>$file "    const char *v_long;"
+                echo >>$file "    const char *v_tex;"
+                echo >>$file "    const char *v_gnu;"
+                echo >>$file "    const char *v_web;"
+                echo >>$file "    const char *v_sccs;"
+                echo >>$file "    const char *v_rcs;"
+                echo >>$file "} ${prefix}version_t;"
+                echo >>$file ""
+                echo >>$file "extern ${prefix}version_t ${prefix}version;"
+                echo >>$file ""
+                echo >>$file "#endif /* _${filestr}_ */"
+                echo >>$file ""
+                echo >>$file "#else /* _${filestr}_AS_HEADER_ */"
+                echo >>$file ""
+                echo >>$file "#define _${filestr}_AS_HEADER_"
+                echo >>$file "#include \"${file}\""
+                echo >>$file "#undef  _${filestr}_AS_HEADER_"
+                echo >>$file ""
+                echo >>$file "${prefix}version_t ${prefix}version = {"
+                echo >>$file "    ${vHex},"
+                echo >>$file "    \"${vShort}\","
+                echo >>$file "    \"${vLong}\","
+                echo >>$file "    \"${vTeX}\","
+                echo >>$file "    \"${vGNU}\","
+                echo >>$file "    \"${vWeb}\","
+                echo >>$file "    \"${vSCCS}\","
+                echo >>$file "    \"${vRCS}\""
+                echo >>$file "};"
+                echo >>$file ""
+                echo >>$file "#endif /* _${filestr}_AS_HEADER_ */"
+                echo >>$file ""
+                ;;
+            m4 )
+                echo >>$file "##"
+                echo >>$file "##  ${file} -- Version Information for ${name} (syntax: M4)"
+                echo >>$file "##  [automatically generated and maintained by GNU shtool]"
+                echo >>$file "##"
+                echo >>$file ""
+                echo >>$file "m4_define([v_hex],   [${vHex}])"
+                echo >>$file "m4_define([v_short], [${vShort}])"
+                echo >>$file "m4_define([v_long],  [${vLong}])"
+                echo >>$file "m4_define([v_tex],   [${vTeX}])"
+                echo >>$file "m4_define([v_gnu],   [${vGNU}])"
+                echo >>$file "m4_define([v_web],   [${vWeb}])"
+                echo >>$file "m4_define([v_sccs],  [${vSCCS}])"
+                echo >>$file "m4_define([v_rcs],   [${vRCS}])"
+                echo >>$file ""
+                ;;
+            perl )
+                echo >>$file "##"
+                echo >>$file "##  ${file} -- Version Information for ${name} (syntax: Perl)"
+                echo >>$file "##  [automatically generated and maintained by GNU shtool]"
+                echo >>$file "##"
+                echo >>$file ""
+                echo >>$file "our \$${prefix}version = {"
+                echo >>$file "    'v_hex'   => ${vHex},"
+                echo >>$file "    'v_short' => \"${vShort}\","
+                echo >>$file "    'v_long'  => \"${vLong}\","
+                echo >>$file "    'v_tex'   => \"${vTeX}\","
+                echo >>$file "    'v_gnu'   => \"${vGNU}\","
+                echo >>$file "    'v_web'   => \"${vWeb}\","
+                echo >>$file "    'v_sccs'  => \"${vSCCS}\","
+                echo >>$file "    'v_rcs'   => \"\\${vRCS}/\""
+                echo >>$file "};"
+                echo >>$file ""
+                echo >>$file "1;"
+                echo >>$file ""
+                ;;
+            python )
+                echo >>$file "##"
+                echo >>$file "##  ${file} -- Version Information for ${name} (syntax: Python)"
+                echo >>$file "##  [automatically generated and maintained by GNU shtool]"
+                echo >>$file "##"
+                echo >>$file ""
+                echo >>$file "class ${prefix}version:"
+                echo >>$file "    v_hex       = ${vHex}"
+                echo >>$file "    v_short     = \"${vShort}\""
+                echo >>$file "    v_long      = \"${vLong}\""
+                echo >>$file "    v_tex       = \"${vTeX}\""
+                echo >>$file "    v_gnu       = \"${vGNU}\""
+                echo >>$file "    v_web       = \"${vWeb}\""
+                echo >>$file "    v_sccs      = \"${vSCCS}\""
+                echo >>$file "    v_rcs       = \"${vRCS}\""
+                echo >>$file ""
+                ;;
+            * ) echo "$msgprefix:Error: invalid argument to option \`-l': \`$opt_l'" 1>&2
+                shtool_exit 1
+                ;;
+        esac
+    fi
+
+    shtool_exit 0
+    ;;
+
+path )
+    ##
+    ##  path -- Deal with program paths
+    ##  Copyright (c) 1998-2006 Ralf S. Engelschall <rse at engelschall.com>
+    ##
+
+    namelist="$*"
+
+    #   check whether the test command supports the -x option
+    if [ -x /bin/sh ] 2>/dev/null; then
+        minusx="-x"
+    else
+        minusx="-r"
+    fi
+
+    #   split path string
+    paths="`echo $opt_p |\
+            sed -e 's/^:/.:/' \
+                -e 's/::/:.:/g' \
+                -e 's/:$/:./' \
+                -e 's/:/ /g'`"
+
+    #   SPECIAL REQUEST
+    #   translate forward to reverse path
+    if [ ".$opt_r" = .yes ]; then
+        if [ "x$namelist" = "x." ]; then
+            rp='.'
+        else
+            rp=''
+            for pe in `IFS="$IFS/"; echo $namelist`; do
+                rp="../$rp"
+            done
+        fi
+        echo $rp | sed -e 's:/$::'
+        shtool_exit 0
+    fi
+
+    #   SPECIAL REQUEST
+    #   strip out directory or base name
+    if [ ".$opt_d" = .yes ]; then
+        echo "$namelist" |\
+        sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;'
+        shtool_exit 0
+    fi
+    if [ ".$opt_b" = .yes ]; then
+        echo "$namelist" |\
+        sed -e 's;.*/\([^/]*\)$;\1;'
+        shtool_exit 0
+    fi
+
+    #   MAGIC SITUATION
+    #   Perl Interpreter (perl)
+    if [ ".$opt_m" = .yes ] && [ ".$namelist" = .perl ]; then
+        rm -f $tmpfile >/dev/null 2>&1
+        touch $tmpfile
+        found=0
+        pc=99
+        for dir in $paths; do
+            dir=`echo $dir | sed -e 's;/*$;;'`
+            nc=99
+            for name in perl perl5 miniperl; do
+                 if [ $minusx "$dir/$name" ] && [ ! -d "$dir/$name" ]; then
+                     perl="$dir/$name"
+                     pv=`$perl -e 'printf("%.3f", $]);'`
+                     echo "$pv:$pc:$nc:$perl" >>$tmpfile
+                     found=1
+                 fi
+                 nc=`expr $nc - 1`
+            done
+            pc=`expr $pc - 1`
+        done
+        if [ $found = 1 ]; then
+            perl="`cat $tmpfile | sort -r -u | sed -e 'q' | cut -d: -f4`"
+            rm -f $tmpfile >/dev/null 2>&1
+            echo "$perl"
+            shtool_exit 0
+        fi
+        rm -f $tmpfile >/dev/null 2>&1
+        shtool_exit 1
+    fi
+
+    #   MAGIC SITUATION
+    #   C pre-processor (cpp)
+    if [ ".$opt_m" = .yes ] && [ ".$namelist" = .cpp ]; then
+        echo >$tmpfile.c "#include <assert.h>"
+        echo >>$tmpfile.c "Syntax Error"
+        #   1. try the standard cc -E approach
+        cpp="${CC-cc} -E"
+        (eval "$cpp $tmpfile.c >/dev/null") 2>$tmpfile.out
+        my_error=`grep -v '^ *+' $tmpfile.out`
+        if [ ".$my_error" != . ]; then
+            #   2. try the cc -E approach and GCC's -traditional-ccp option
+            cpp="${CC-cc} -E -traditional-cpp"
+            (eval "$cpp $tmpfile.c >/dev/null") 2>$tmpfile.out
+            my_error=`grep -v '^ *+' $tmpfile.out`
+            if [ ".$my_error" != . ]; then
+                #   3. try a standalone cpp command in path and lib dirs
+                for path in $paths /lib /usr/lib /usr/local/lib; do
+                    path=`echo $path | sed -e 's;/*$;;'`
+                    if [ $minusx "$path/cpp" ] && [ ! -d "$path/cpp" ]; then
+                        cpp="$path/cpp"
+                        break
+                    fi
+                done
+                if [ ".$cpp" != . ]; then
+                    (eval "$cpp $tmpfile.c >/dev/null") 2>$tmpfile.out
+                    my_error=`grep -v '^ *+' $tmpfile.out`
+                    if [ ".$my_error" != . ]; then
+                        #   ok, we gave up...
+                        cpp=''
+                    fi
+                fi
+            fi
+        fi
+        rm -f $tmpfile >/dev/null 2>&1
+        rm -f $tmpfile.c $tmpfile.out >/dev/null 2>&1
+        if [ ".$cpp" != . ]; then
+            echo "$cpp"
+            shtool_exit 0
+        fi
+        shtool_exit 1
+    fi
+
+    #   STANDARD SITUATION
+    #   iterate over names
+    for name in $namelist; do
+        #   iterate over paths
+        for path in $paths; do
+            path=`echo $path | sed -e 's;/*$;;'`
+            if [ $minusx "$path/$name" ] && [ ! -d "$path/$name" ]; then
+                if [ ".$opt_s" != .yes ]; then
+                    echo "$path/$name"
+                fi
+                shtool_exit 0
+            fi
+        done
+    done
+
+    shtool_exit 1
+    ;;
+
+esac
+
+shtool_exit 0
+

Added: freeswitch/trunk/libs/js/src/fdlibm/e_acos.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_acos.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,147 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_acos.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_acos(x)
+ * Method :                  
+ *	acos(x)  = pi/2 - asin(x)
+ *	acos(-x) = pi/2 + asin(x)
+ * For |x|<=0.5
+ *	acos(x) = pi/2 - (x + x*x^2*R(x^2))	(see asin.c)
+ * For x>0.5
+ * 	acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
+ *		= 2asin(sqrt((1-x)/2))  
+ *		= 2s + 2s*z*R(z) 	...z=(1-x)/2, s=sqrt(z)
+ *		= 2f + (2c + 2s*z*R(z))
+ *     where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
+ *     for f so that f+c ~ sqrt(z).
+ * For x<-0.5
+ *	acos(x) = pi - 2asin(sqrt((1-|x|)/2))
+ *		= pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
+ *
+ * Special cases:
+ *	if x is NaN, return x itself;
+ *	if |x|>1, return NaN with invalid signal.
+ *
+ * Function needed: sqrt
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+one=  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pi =  3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
+pio2_hi =  1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo =  6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pS0 =  1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 =  2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 =  7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 =  3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 =  2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+#ifdef __STDC__
+	double __ieee754_acos(double x)
+#else
+	double __ieee754_acos(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+        double df;
+	double z,p,q,r,w,s,c;
+	int hx,ix;
+        u.d = x;
+	hx = __HI(u);
+	ix = hx&0x7fffffff;
+	if(ix>=0x3ff00000) {	/* |x| >= 1 */
+	    if(((ix-0x3ff00000)|__LO(u))==0) {	/* |x|==1 */
+		if(hx>0) return 0.0;		/* acos(1) = 0  */
+		else return pi+2.0*pio2_lo;	/* acos(-1)= pi */
+	    }
+	    return (x-x)/(x-x);		/* acos(|x|>1) is NaN */
+	}
+	if(ix<0x3fe00000) {	/* |x| < 0.5 */
+	    if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
+	    z = x*x;
+	    p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+	    q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+	    r = p/q;
+	    return pio2_hi - (x - (pio2_lo-x*r));
+	} else  if (hx<0) {		/* x < -0.5 */
+	    z = (one+x)*0.5;
+	    p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+	    q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+	    s = fd_sqrt(z);
+	    r = p/q;
+	    w = r*s-pio2_lo;
+	    return pi - 2.0*(s+w);
+	} else {			/* x > 0.5 */
+	    z = (one-x)*0.5;
+	    s = fd_sqrt(z);
+	    u.d = s;
+	    __LO(u) = 0;
+            df = u.d;
+	    c  = (z-df*df)/(s+df);
+	    p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
+	    q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
+	    r = p/q;
+	    w = r*s+c;
+	    return 2.0*(df+w);
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_acosh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_acosh.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,105 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_acosh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* __ieee754_acosh(x)
+ * Method :
+ *	Based on 
+ *		acosh(x) = log [ x + sqrt(x*x-1) ]
+ *	we have
+ *		acosh(x) := log(x)+ln2,	if x is large; else
+ *		acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else
+ *		acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1.
+ *
+ * Special cases:
+ *	acosh(x) is NaN with signal if x<1.
+ *	acosh(NaN) is NaN without signal.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+one	= 1.0,
+ln2	= 6.93147180559945286227e-01;  /* 0x3FE62E42, 0xFEFA39EF */
+
+#ifdef __STDC__
+	double __ieee754_acosh(double x)
+#else
+	double __ieee754_acosh(x)
+	double x;
+#endif
+{	
+        fd_twoints u;
+	double t;
+	int hx;
+        u.d = x;
+	hx = __HI(u);
+	if(hx<0x3ff00000) {		/* x < 1 */
+	    return (x-x)/(x-x);
+	} else if(hx >=0x41b00000) {	/* x > 2**28 */
+	    if(hx >=0x7ff00000) {	/* x is inf of NaN */
+	        return x+x;
+	    } else 
+		return __ieee754_log(x)+ln2;	/* acosh(huge)=log(2x) */
+	} else if(((hx-0x3ff00000)|__LO(u))==0) {
+	    return 0.0;			/* acosh(1) = 0 */
+	} else if (hx > 0x40000000) {	/* 2**28 > x > 2 */
+	    t=x*x;
+	    return __ieee754_log(2.0*x-one/(x+fd_sqrt(t-one)));
+	} else {			/* 1<x<2 */
+	    t = x-one;
+	    return fd_log1p(t+fd_sqrt(2.0*t+t*t));
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_asin.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_asin.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,156 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_asin.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_asin(x)
+ * Method :                  
+ *	Since  asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
+ *	we approximate asin(x) on [0,0.5] by
+ *		asin(x) = x + x*x^2*R(x^2)
+ *	where
+ *		R(x^2) is a rational approximation of (asin(x)-x)/x^3 
+ *	and its remez error is bounded by
+ *		|(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
+ *
+ *	For x in [0.5,1]
+ *		asin(x) = pi/2-2*asin(sqrt((1-x)/2))
+ *	Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
+ *	then for x>0.98
+ *		asin(x) = pi/2 - 2*(s+s*z*R(z))
+ *			= pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
+ *	For x<=0.98, let pio4_hi = pio2_hi/2, then
+ *		f = hi part of s;
+ *		c = sqrt(z) - f = (z-f*f)/(s+f) 	...f+c=sqrt(z)
+ *	and
+ *		asin(x) = pi/2 - 2*(s+s*z*R(z))
+ *			= pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
+ *			= pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
+ *
+ * Special cases:
+ *	if x is NaN, return x itself;
+ *	if |x|>1, return NaN with invalid signal.
+ *
+ */
+
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+really_big =  1.000e+300,
+pio2_hi =  1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
+pio2_lo =  6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
+pio4_hi =  7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
+	/* coefficient for R(x^2) */
+pS0 =  1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
+pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
+pS2 =  2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
+pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
+pS4 =  7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
+pS5 =  3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
+qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
+qS2 =  2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
+qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
+qS4 =  7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
+
+#ifdef __STDC__
+	double __ieee754_asin(double x)
+#else
+	double __ieee754_asin(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	double w,t,p,q,c,r,s;
+	int hx,ix;
+        u.d = x;
+	hx = __HI(u);
+        x = u.d;
+	ix = hx&0x7fffffff;
+	if(ix>= 0x3ff00000) {		/* |x|>= 1 */
+	    if(((ix-0x3ff00000)|__LO(u))==0)
+		    /* asin(1)=+-pi/2 with inexact */
+		return x*pio2_hi+x*pio2_lo;	
+	    return (x-x)/(x-x);		/* asin(|x|>1) is NaN */   
+	} else if (ix<0x3fe00000) {	/* |x|<0.5 */
+	    if(ix<0x3e400000) {		/* if |x| < 2**-27 */
+		if(really_big+x>one) return x;/* return x with inexact if x!=0*/
+	    } else 
+		t = x*x;
+		p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+		q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+		w = p/q;
+		return x+x*w;
+	}
+	/* 1> |x|>= 0.5 */
+	w = one-fd_fabs(x);
+	t = w*0.5;
+	p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
+	q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
+	s = fd_sqrt(t);
+	if(ix>=0x3FEF3333) { 	/* if |x| > 0.975 */
+	    w = p/q;
+	    t = pio2_hi-(2.0*(s+s*w)-pio2_lo);
+	} else {
+	    u.d  = s;
+	    __LO(u) = 0;
+            w = u.d;
+	    c  = (t-w*w)/(s+w);
+	    r  = p/q;
+	    p  = 2.0*s*r-(pio2_lo-2.0*c);
+	    q  = pio4_hi-2.0*w;
+	    t  = pio4_hi-(p-q);
+	}    
+	if(hx>0) return t; else return -t;    
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_atan2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_atan2.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,165 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_atan2.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* __ieee754_atan2(y,x)
+ * Method :
+ *	1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
+ *	2. Reduce x to positive by (if x and y are unexceptional): 
+ *		ARG (x+iy) = arctan(y/x)   	   ... if x > 0,
+ *		ARG (x+iy) = pi - arctan[y/(-x)]   ... if x < 0,
+ *
+ * Special cases:
+ *
+ *	ATAN2((anything), NaN ) is NaN;
+ *	ATAN2(NAN , (anything) ) is NaN;
+ *	ATAN2(+-0, +(anything but NaN)) is +-0  ;
+ *	ATAN2(+-0, -(anything but NaN)) is +-pi ;
+ *	ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
+ *	ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
+ *	ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
+ *	ATAN2(+-INF,+INF ) is +-pi/4 ;
+ *	ATAN2(+-INF,-INF ) is +-3pi/4;
+ *	ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough 
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+tiny  = 1.0e-300,
+zero  = 0.0,
+pi_o_4  = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
+pi_o_2  = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
+pi      = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
+pi_lo   = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
+
+#ifdef __STDC__
+	double __ieee754_atan2(double y, double x)
+#else
+	double __ieee754_atan2(y,x)
+	double  y,x;
+#endif
+{  
+        fd_twoints ux, uy, uz;
+	double z;
+	int k,m,hx,hy,ix,iy;
+	unsigned lx,ly;
+
+        ux.d = x; uy.d = y;
+	hx = __HI(ux); ix = hx&0x7fffffff;
+	lx = __LO(ux);
+	hy = __HI(uy); iy = hy&0x7fffffff;
+	ly = __LO(uy);
+	if(((ix|((lx|-(int)lx)>>31))>0x7ff00000)||
+	   ((iy|((ly|-(int)ly)>>31))>0x7ff00000))	/* x or y is NaN */
+	   return x+y;
+	if(((hx-0x3ff00000)|lx)==0) return fd_atan(y);   /* x=1.0 */
+	m = ((hy>>31)&1)|((hx>>30)&2);	/* 2*sign(x)+sign(y) */
+
+    /* when y = 0 */
+	if((iy|ly)==0) {
+	    switch(m) {
+		case 0: 
+		case 1: return y; 	/* atan(+-0,+anything)=+-0 */
+		case 2: return  pi+tiny;/* atan(+0,-anything) = pi */
+		case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
+	    }
+	}
+    /* when x = 0 */
+	if((ix|lx)==0) return (hy<0)?  -pi_o_2-tiny: pi_o_2+tiny;
+	    
+    /* when x is INF */
+	if(ix==0x7ff00000) {
+	    if(iy==0x7ff00000) {
+		switch(m) {
+		    case 0: return  pi_o_4+tiny;/* atan(+INF,+INF) */
+		    case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
+		    case 2: return  3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
+		    case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
+		}
+	    } else {
+		switch(m) {
+		    case 0: return  zero  ;	/* atan(+...,+INF) */
+		    case 1: return -zero  ;	/* atan(-...,+INF) */
+		    case 2: return  pi+tiny  ;	/* atan(+...,-INF) */
+		    case 3: return -pi-tiny  ;	/* atan(-...,-INF) */
+		}
+	    }
+	}
+    /* when y is INF */
+	if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+
+    /* compute y/x */
+	k = (iy-ix)>>20;
+	if(k > 60) z=pi_o_2+0.5*pi_lo; 	/* |y/x| >  2**60 */
+	else if(hx<0&&k<-60) z=0.0; 	/* |y|/x < -2**60 */
+	else z=fd_atan(fd_fabs(y/x));		/* safe to do y/x */
+	switch (m) {
+	    case 0: return       z  ;	/* atan(+,+) */
+	    case 1: uz.d = z;
+                    __HI(uz) ^= 0x80000000;
+                    z = uz.d;
+		    return       z  ;	/* atan(-,+) */
+	    case 2: return  pi-(z-pi_lo);/* atan(+,-) */
+	    default: /* case 3 */
+	    	    return  (z-pi_lo)-pi;/* atan(-,-) */
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_atanh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_atanh.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,110 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_atanh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* __ieee754_atanh(x)
+ * Method :
+ *    1.Reduced x to positive by atanh(-x) = -atanh(x)
+ *    2.For x>=0.5
+ *                  1              2x                          x
+ *	atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ *                  2             1 - x                      1 - x
+ *	
+ * 	For x<0.5
+ *	atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
+ *
+ * Special cases:
+ *	atanh(x) is NaN if |x| > 1 with signal;
+ *	atanh(NaN) is that NaN with no signal;
+ *	atanh(+-1) is +-INF with signal.
+ *
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double one = 1.0, really_big = 1e300;
+#else
+static double one = 1.0, really_big = 1e300;
+#endif
+
+static double zero = 0.0;
+
+#ifdef __STDC__
+	double __ieee754_atanh(double x)
+#else
+	double __ieee754_atanh(x)
+	double x;
+#endif
+{
+	double t;
+	int hx,ix;
+	unsigned lx;
+        fd_twoints u;
+        u.d = x;
+	hx = __HI(u);		/* high word */
+	lx = __LO(u);		/* low word */
+	ix = hx&0x7fffffff;
+	if ((ix|((lx|(-(int)lx))>>31))>0x3ff00000) /* |x|>1 */
+	    return (x-x)/(x-x);
+	if(ix==0x3ff00000) 
+	    return x/zero;
+	if(ix<0x3e300000&&(really_big+x)>zero) return x;	/* x<2**-28 */
+        u.d = x;
+	__HI(u) = ix;		/* x <- |x| */
+        x = u.d;
+	if(ix<0x3fe00000) {		/* x < 0.5 */
+	    t = x+x;
+	    t = 0.5*fd_log1p(t+t*x/(one-x));
+	} else 
+	    t = 0.5*fd_log1p((x+x)/(one-x));
+	if(hx>=0) return t; else return -t;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_cosh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_cosh.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,133 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_cosh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_cosh(x)
+ * Method : 
+ * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
+ *	1. Replace x by |x| (cosh(x) = cosh(-x)). 
+ *	2. 
+ *		                                        [ exp(x) - 1 ]^2 
+ *	    0        <= x <= ln2/2  :  cosh(x) := 1 + -------------------
+ *			       			           2*exp(x)
+ *
+ *		                                  exp(x) +  1/exp(x)
+ *	    ln2/2    <= x <= 22     :  cosh(x) := -------------------
+ *			       			          2
+ *	    22       <= x <= lnovft :  cosh(x) := exp(x)/2 
+ *	    lnovft   <= x <= ln2ovft:  cosh(x) := exp(x/2)/2 * exp(x/2)
+ *	    ln2ovft  <  x	    :  cosh(x) := huge*huge (overflow)
+ *
+ * Special cases:
+ *	cosh(x) is |x| if x is +INF, -INF, or NaN.
+ *	only cosh(0)=1 is exact for finite x.
+ */
+
+#include "fdlibm.h"
+
+#ifdef _WIN32
+#define huge myhuge
+#endif
+
+#ifdef __STDC__
+static const double one = 1.0, half=0.5, really_big = 1.0e300;
+#else
+static double one = 1.0, half=0.5, really_big = 1.0e300;
+#endif
+
+#ifdef __STDC__
+	double __ieee754_cosh(double x)
+#else
+	double __ieee754_cosh(x)
+	double x;
+#endif
+{	
+        fd_twoints u;
+	double t,w;
+	int ix;
+	unsigned lx;
+        
+    /* High word of |x|. */
+        u.d = x;
+	ix = __HI(u);
+	ix &= 0x7fffffff;
+
+    /* x is INF or NaN */
+	if(ix>=0x7ff00000) return x*x;	
+
+    /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
+	if(ix<0x3fd62e43) {
+	    t = fd_expm1(fd_fabs(x));
+	    w = one+t;
+	    if (ix<0x3c800000) return w;	/* cosh(tiny) = 1 */
+	    return one+(t*t)/(w+w);
+	}
+
+    /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
+	if (ix < 0x40360000) {
+		t = __ieee754_exp(fd_fabs(x));
+		return half*t+half/t;
+	}
+
+    /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
+	if (ix < 0x40862E42)  return half*__ieee754_exp(fd_fabs(x));
+
+    /* |x| in [log(maxdouble), overflowthresold] */
+	lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x);
+	if (ix<0x408633CE || 
+	      (ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d)) {
+	    w = __ieee754_exp(half*fd_fabs(x));
+	    t = half*w;
+	    return t*w;
+	}
+
+    /* |x| > overflowthresold, cosh(x) overflow */
+	return really_big*really_big;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_exp.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_exp.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,202 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_exp.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_exp(x)
+ * Returns the exponential of x.
+ *
+ * Method
+ *   1. Argument reduction:
+ *      Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
+ *	Given x, find r and integer k such that
+ *
+ *               x = k*ln2 + r,  |r| <= 0.5*ln2.  
+ *
+ *      Here r will be represented as r = hi-lo for better 
+ *	accuracy.
+ *
+ *   2. Approximation of exp(r) by a special rational function on
+ *	the interval [0,0.34658]:
+ *	Write
+ *	    R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
+ *      We use a special Reme algorithm on [0,0.34658] to generate 
+ * 	a polynomial of degree 5 to approximate R. The maximum error 
+ *	of this polynomial approximation is bounded by 2**-59. In
+ *	other words,
+ *	    R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
+ *  	(where z=r*r, and the values of P1 to P5 are listed below)
+ *	and
+ *	    |                  5          |     -59
+ *	    | 2.0+P1*z+...+P5*z   -  R(z) | <= 2 
+ *	    |                             |
+ *	The computation of exp(r) thus becomes
+ *                             2*r
+ *		exp(r) = 1 + -------
+ *		              R - r
+ *                                 r*R1(r)	
+ *		       = 1 + r + ----------- (for better accuracy)
+ *		                  2 - R1(r)
+ *	where
+ *			         2       4             10
+ *		R1(r) = r - (P1*r  + P2*r  + ... + P5*r   ).
+ *	
+ *   3. Scale back to obtain exp(x):
+ *	From step 1, we have
+ *	   exp(x) = 2^k * exp(r)
+ *
+ * Special cases:
+ *	exp(INF) is INF, exp(NaN) is NaN;
+ *	exp(-INF) is 0, and
+ *	for finite argument, only exp(0)=1 is exact.
+ *
+ * Accuracy:
+ *	according to an error analysis, the error is always less than
+ *	1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ *	For IEEE double 
+ *	    if x >  7.09782712893383973096e+02 then exp(x) overflow
+ *	    if x < -7.45133219101941108420e+02 then exp(x) underflow
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one	= 1.0,
+halF[2]	= {0.5,-0.5,},
+really_big	= 1.0e+300,
+twom1000= 9.33263618503218878990e-302,     /* 2**-1000=0x01700000,0*/
+o_threshold=  7.09782712893383973096e+02,  /* 0x40862E42, 0xFEFA39EF */
+u_threshold= -7.45133219101941108420e+02,  /* 0xc0874910, 0xD52D3051 */
+ln2HI[2]   ={ 6.93147180369123816490e-01,  /* 0x3fe62e42, 0xfee00000 */
+	     -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */
+ln2LO[2]   ={ 1.90821492927058770002e-10,  /* 0x3dea39ef, 0x35793c76 */
+	     -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */
+invln2 =  1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
+P1   =  1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2   = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3   =  6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4   = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5   =  4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
+
+
+#ifdef __STDC__
+	double __ieee754_exp(double x)	/* default IEEE double exp */
+#else
+	double __ieee754_exp(x)	/* default IEEE double exp */
+	double x;
+#endif
+{
+        fd_twoints u;
+	double y,hi,lo,c,t;
+	int k, xsb;
+	unsigned hx;
+
+        u.d = x;
+	hx  = __HI(u);	/* high word of x */
+	xsb = (hx>>31)&1;		/* sign bit of x */
+	hx &= 0x7fffffff;		/* high word of |x| */
+
+    /* filter out non-finite argument */
+	if(hx >= 0x40862E42) {			/* if |x|>=709.78... */
+            if(hx>=0x7ff00000) {
+                u.d = x;
+		if(((hx&0xfffff)|__LO(u))!=0)
+		     return x+x; 		/* NaN */
+		else return (xsb==0)? x:0.0;	/* exp(+-inf)={inf,0} */
+	    }
+	    if(x > o_threshold) return really_big*really_big; /* overflow */
+	    if(x < u_threshold) return twom1000*twom1000; /* underflow */
+	}
+
+    /* argument reduction */
+	if(hx > 0x3fd62e42) {		/* if  |x| > 0.5 ln2 */ 
+	    if(hx < 0x3FF0A2B2) {	/* and |x| < 1.5 ln2 */
+		hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
+	    } else {
+		k  = (int)(invln2*x+halF[xsb]);
+		t  = k;
+		hi = x - t*ln2HI[0];	/* t*ln2HI is exact here */
+		lo = t*ln2LO[0];
+	    }
+	    x  = hi - lo;
+	} 
+	else if(hx < 0x3e300000)  {	/* when |x|<2**-28 */
+	    if(really_big+x>one) return one+x;/* trigger inexact */
+	}
+	else k = 0;
+
+    /* x is now in primary range */
+	t  = x*x;
+	c  = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+	if(k==0) 	return one-((x*c)/(c-2.0)-x); 
+	else 		y = one-((lo-(x*c)/(2.0-c))-hi);
+	if(k >= -1021) {
+            u.d = y;
+	    __HI(u) += (k<<20);	/* add k to y's exponent */
+            y = u.d;
+	    return y;
+	} else {
+            u.d = y;
+	    __HI(u) += ((k+1000)<<20);/* add k to y's exponent */
+            y = u.d;
+	    return y*twom1000;
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_fmod.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_fmod.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,184 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_fmod.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * __ieee754_fmod(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double one = 1.0, Zero[] = {0.0, -0.0,};
+#else
+static double one = 1.0, Zero[] = {0.0, -0.0,};
+#endif
+
+#ifdef __STDC__
+	double __ieee754_fmod(double x, double y)
+#else
+	double __ieee754_fmod(x,y)
+	double x,y ;
+#endif
+{
+        fd_twoints ux, uy;
+	int n,hx,hy,hz,ix,iy,sx,i;
+	unsigned lx,ly,lz;
+
+        ux.d = x; uy.d = y;
+	hx = __HI(ux);		/* high word of x */
+	lx = __LO(ux);		/* low  word of x */
+	hy = __HI(uy);		/* high word of y */
+	ly = __LO(uy);		/* low  word of y */
+	sx = hx&0x80000000;		/* sign of x */
+	hx ^=sx;		/* |x| */
+	hy &= 0x7fffffff;	/* |y| */
+
+    /* purge off exception values */
+	if((hy|ly)==0||(hx>=0x7ff00000)||	/* y=0,or x not finite */
+	  ((hy|((ly|-(int)ly)>>31))>0x7ff00000))	/* or y is NaN */
+	    return (x*y)/(x*y);
+	if(hx<=hy) {
+	    if((hx<hy)||(lx<ly)) return x;	/* |x|<|y| return x */
+	    if(lx==ly) 
+		return Zero[(unsigned)sx>>31];	/* |x|=|y| return x*0*/
+	}
+
+    /* determine ix = ilogb(x) */
+	if(hx<0x00100000) {	/* subnormal x */
+	    if(hx==0) {
+		for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
+	    } else {
+		for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
+	    }
+	} else ix = (hx>>20)-1023;
+
+    /* determine iy = ilogb(y) */
+	if(hy<0x00100000) {	/* subnormal y */
+	    if(hy==0) {
+		for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
+	    } else {
+		for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
+	    }
+	} else iy = (hy>>20)-1023;
+
+    /* set up {hx,lx}, {hy,ly} and align y to x */
+	if(ix >= -1022) 
+	    hx = 0x00100000|(0x000fffff&hx);
+	else {		/* subnormal x, shift x to normal */
+	    n = -1022-ix;
+	    if(n<=31) {
+	        hx = (hx<<n)|(lx>>(32-n));
+	        lx <<= n;
+	    } else {
+		hx = lx<<(n-32);
+		lx = 0;
+	    }
+	}
+	if(iy >= -1022) 
+	    hy = 0x00100000|(0x000fffff&hy);
+	else {		/* subnormal y, shift y to normal */
+	    n = -1022-iy;
+	    if(n<=31) {
+	        hy = (hy<<n)|(ly>>(32-n));
+	        ly <<= n;
+	    } else {
+		hy = ly<<(n-32);
+		ly = 0;
+	    }
+	}
+
+    /* fix point fmod */
+	n = ix - iy;
+	while(n--) {
+	    hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+	    if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
+	    else {
+	    	if((hz|lz)==0) 		/* return sign(x)*0 */
+		    return Zero[(unsigned)sx>>31];
+	    	hx = hz+hz+(lz>>31); lx = lz+lz;
+	    }
+	}
+	hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+	if(hz>=0) {hx=hz;lx=lz;}
+
+    /* convert back to floating value and restore the sign */
+	if((hx|lx)==0) 			/* return sign(x)*0 */
+	    return Zero[(unsigned)sx>>31];	
+	while(hx<0x00100000) {		/* normalize x */
+	    hx = hx+hx+(lx>>31); lx = lx+lx;
+	    iy -= 1;
+	}
+	if(iy>= -1022) {	/* normalize output */
+	    hx = ((hx-0x00100000)|((iy+1023)<<20));
+            ux.d = x;
+	    __HI(ux) = hx|sx;
+	    __LO(ux) = lx;
+            x = ux.d;
+	} else {		/* subnormal output */
+	    n = -1022 - iy;
+	    if(n<=20) {
+		lx = (lx>>n)|((unsigned)hx<<(32-n));
+		hx >>= n;
+	    } else if (n<=31) {
+		lx = (hx<<(32-n))|(lx>>n); hx = sx;
+	    } else {
+		lx = hx>>(n-32); hx = sx;
+	    }
+            ux.d = x;
+	    __HI(ux) = hx|sx;
+	    __LO(ux) = lx;
+            x = ux.d;
+	    x *= one;		/* create necessary signal */
+	}
+	return x;		/* exact output */
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_gamma.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_gamma.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_gamma.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* __ieee754_gamma(x)
+ * Return the logarithm of the Gamma function of x.
+ *
+ * Method: call __ieee754_gamma_r
+ */
+
+#include "fdlibm.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+	double __ieee754_gamma(double x)
+#else
+	double __ieee754_gamma(x)
+	double x;
+#endif
+{
+	return __ieee754_gamma_r(x,&signgam);
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_gamma_r.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_gamma_r.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_gamma_r.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* __ieee754_gamma_r(x, signgamp)
+ * Reentrant version of the logarithm of the Gamma function 
+ * with user provide pointer for the sign of Gamma(x). 
+ *
+ * Method: See __ieee754_lgamma_r
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double __ieee754_gamma_r(double x, int *signgamp)
+#else
+	double __ieee754_gamma_r(x,signgamp)
+	double x; int *signgamp;
+#endif
+{
+	return __ieee754_lgamma_r(x,signgamp);
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_hypot.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_hypot.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,173 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_hypot.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_hypot(x,y)
+ *
+ * Method :                  
+ *	If (assume round-to-nearest) z=x*x+y*y 
+ *	has error less than sqrt(2)/2 ulp, than 
+ *	sqrt(z) has error less than 1 ulp (exercise).
+ *
+ *	So, compute sqrt(x*x+y*y) with some care as 
+ *	follows to get the error below 1 ulp:
+ *
+ *	Assume x>y>0;
+ *	(if possible, set rounding to round-to-nearest)
+ *	1. if x > 2y  use
+ *		x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y
+ *	where x1 = x with lower 32 bits cleared, x2 = x-x1; else
+ *	2. if x <= 2y use
+ *		t1*y1+((x-y)*(x-y)+(t1*y2+t2*y))
+ *	where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1, 
+ *	y1= y with lower 32 bits chopped, y2 = y-y1.
+ *		
+ *	NOTE: scaling may be necessary if some argument is too 
+ *	      large or too tiny
+ *
+ * Special cases:
+ *	hypot(x,y) is INF if x or y is +INF or -INF; else
+ *	hypot(x,y) is NAN if x or y is NAN.
+ *
+ * Accuracy:
+ * 	hypot(x,y) returns sqrt(x^2+y^2) with error less 
+ * 	than 1 ulps (units in the last place) 
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double __ieee754_hypot(double x, double y)
+#else
+	double __ieee754_hypot(x,y)
+	double x, y;
+#endif
+{
+        fd_twoints ux, uy;
+	double a=x,b=y,t1,t2,y1,y2,w;
+	int j,k,ha,hb;
+        
+        ux.d = x; uy.d = y;
+	ha = __HI(ux)&0x7fffffff;	/* high word of  x */
+	hb = __HI(uy)&0x7fffffff;	/* high word of  y */
+	if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
+        ux.d = a; uy.d = b;
+	__HI(ux) = ha;	/* a <- |a| */
+	__HI(uy) = hb;	/* b <- |b| */
+        a = ux.d; b = uy.d;
+	if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
+	k=0;
+	if(ha > 0x5f300000) {	/* a>2**500 */
+	   if(ha >= 0x7ff00000) {	/* Inf or NaN */
+	       w = a+b;			/* for sNaN */
+               ux.d = a; uy.d = b;
+	       if(((ha&0xfffff)|__LO(ux))==0) w = a;
+	       if(((hb^0x7ff00000)|__LO(uy))==0) w = b;
+	       return w;
+	   }
+	   /* scale a and b by 2**-600 */
+	   ha -= 0x25800000; hb -= 0x25800000;	k += 600;
+           ux.d = a; uy.d = b;
+	   __HI(ux) = ha;
+	   __HI(uy) = hb;
+           a = ux.d; b = uy.d;
+	}
+	if(hb < 0x20b00000) {	/* b < 2**-500 */
+	    if(hb <= 0x000fffff) {	/* subnormal b or 0 */	
+                uy.d = b;
+		if((hb|(__LO(uy)))==0) return a;
+		t1=0;
+                ux.d = t1;
+		__HI(ux) = 0x7fd00000;	/* t1=2^1022 */
+                t1 = ux.d;
+		b *= t1;
+		a *= t1;
+		k -= 1022;
+	    } else {		/* scale a and b by 2^600 */
+	        ha += 0x25800000; 	/* a *= 2^600 */
+		hb += 0x25800000;	/* b *= 2^600 */
+		k -= 600;
+                ux.d = a; uy.d = b;
+	   	__HI(ux) = ha;
+	   	__HI(uy) = hb;
+                a = ux.d; b = uy.d;
+	    }
+	}
+    /* medium size a and b */
+	w = a-b;
+	if (w>b) {
+	    t1 = 0;
+            ux.d = t1;
+	    __HI(ux) = ha;
+            t1 = ux.d;
+	    t2 = a-t1;
+	    w  = fd_sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
+	} else {
+	    a  = a+a;
+	    y1 = 0;
+            ux.d = y1;
+	    __HI(ux) = hb;
+            y1 = ux.d;
+	    y2 = b - y1;
+	    t1 = 0;
+            ux.d = t1;
+	    __HI(ux) = ha+0x00100000;
+            t1 = ux.d;
+	    t2 = a - t1;
+	    w  = fd_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
+	}
+	if(k!=0) {
+	    t1 = 1.0;
+            ux.d = t1;
+	    __HI(ux) += (k<<20);
+            t1 = ux.d;
+	    return t1*w;
+	} else return w;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_j0.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_j0.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,524 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_j0.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_j0(x), __ieee754_y0(x)
+ * Bessel function of the first and second kinds of order zero.
+ * Method -- j0(x):
+ *	1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ...
+ *	2. Reduce x to |x| since j0(x)=j0(-x),  and
+ *	   for x in (0,2)
+ *		j0(x) = 1-z/4+ z^2*R0/S0,  where z = x*x;
+ *	   (precision:  |j0-1+z/4-z^2R0/S0 |<2**-63.67 )
+ *	   for x in (2,inf)
+ * 		j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0))
+ * 	   where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ *	   as follow:
+ *		cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+ *			= 1/sqrt(2) * (cos(x) + sin(x))
+ *		sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4)
+ *			= 1/sqrt(2) * (sin(x) - cos(x))
+ * 	   (To avoid cancellation, use
+ *		sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * 	    to compute the worse one.)
+ *	   
+ *	3 Special cases
+ *		j0(nan)= nan
+ *		j0(0) = 1
+ *		j0(inf) = 0
+ *		
+ * Method -- y0(x):
+ *	1. For x<2.
+ *	   Since 
+ *		y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...)
+ *	   therefore y0(x)-2/pi*j0(x)*ln(x) is an even function.
+ *	   We use the following function to approximate y0,
+ *		y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2
+ *	   where 
+ *		U(z) = u00 + u01*z + ... + u06*z^6
+ *		V(z) = 1  + v01*z + ... + v04*z^4
+ *	   with absolute approximation error bounded by 2**-72.
+ *	   Note: For tiny x, U/V = u0 and j0(x)~1, hence
+ *		y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27)
+ *	2. For x>=2.
+ * 		y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0))
+ * 	   where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
+ *	   by the method mentioned above.
+ *	3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static double pzero(double), qzero(double);
+#else
+static double pzero(), qzero();
+#endif
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+really_big 	= 1e300,
+one	= 1.0,
+invsqrtpi=  5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+tpi      =  6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+ 		/* R0/S0 on [0, 2.00] */
+R02  =  1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */
+R03  = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */
+R04  =  1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */
+R05  = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */
+S01  =  1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */
+S02  =  1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */
+S03  =  5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */
+S04  =  1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */
+
+static double zero = 0.0;
+
+#ifdef __STDC__
+	double __ieee754_j0(double x) 
+#else
+	double __ieee754_j0(x) 
+	double x;
+#endif
+{
+        fd_twoints un;
+	double z, s,c,ss,cc,r,u,v;
+	int hx,ix;
+
+        un.d = x;
+	hx = __HI(un);
+	ix = hx&0x7fffffff;
+	if(ix>=0x7ff00000) return one/(x*x);
+	x = fd_fabs(x);
+	if(ix >= 0x40000000) {	/* |x| >= 2.0 */
+		s = fd_sin(x);
+		c = fd_cos(x);
+		ss = s-c;
+		cc = s+c;
+		if(ix<0x7fe00000) {  /* make sure x+x not overflow */
+		    z = -fd_cos(x+x);
+		    if ((s*c)<zero) cc = z/ss;
+		    else 	    ss = z/cc;
+		}
+	/*
+	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+	 */
+		if(ix>0x48000000) z = (invsqrtpi*cc)/fd_sqrt(x);
+		else {
+		    u = pzero(x); v = qzero(x);
+		    z = invsqrtpi*(u*cc-v*ss)/fd_sqrt(x);
+		}
+		return z;
+	}
+	if(ix<0x3f200000) {	/* |x| < 2**-13 */
+	    if(really_big+x>one) {	/* raise inexact if x != 0 */
+	        if(ix<0x3e400000) return one;	/* |x|<2**-27 */
+	        else 	      return one - 0.25*x*x;
+	    }
+	}
+	z = x*x;
+	r =  z*(R02+z*(R03+z*(R04+z*R05)));
+	s =  one+z*(S01+z*(S02+z*(S03+z*S04)));
+	if(ix < 0x3FF00000) {	/* |x| < 1.00 */
+	    return one + z*(-0.25+(r/s));
+	} else {
+	    u = 0.5*x;
+	    return((one+u)*(one-u)+z*(r/s));
+	}
+}
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+u00  = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */
+u01  =  1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */
+u02  = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */
+u03  =  3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */
+u04  = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */
+u05  =  1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */
+u06  = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */
+v01  =  1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */
+v02  =  7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */
+v03  =  2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */
+v04  =  4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */
+
+#ifdef __STDC__
+	double __ieee754_y0(double x) 
+#else
+	double __ieee754_y0(x) 
+	double x;
+#endif
+{
+        fd_twoints un;
+	double z, s,c,ss,cc,u,v;
+	int hx,ix,lx;
+
+        un.d = x;
+        hx = __HI(un);
+        ix = 0x7fffffff&hx;
+        lx = __LO(un);
+    /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0  */
+	if(ix>=0x7ff00000) return  one/(x+x*x); 
+        if((ix|lx)==0) return -one/zero;
+        if(hx<0) return zero/zero;
+        if(ix >= 0x40000000) {  /* |x| >= 2.0 */
+        /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
+         * where x0 = x-pi/4
+         *      Better formula:
+         *              cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
+         *                      =  1/sqrt(2) * (sin(x) + cos(x))
+         *              sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+         *                      =  1/sqrt(2) * (sin(x) - cos(x))
+         * To avoid cancellation, use
+         *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+         * to compute the worse one.
+         */
+                s = fd_sin(x);
+                c = fd_cos(x);
+                ss = s-c;
+                cc = s+c;
+	/*
+	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
+	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
+	 */
+                if(ix<0x7fe00000) {  /* make sure x+x not overflow */
+                    z = -fd_cos(x+x);
+                    if ((s*c)<zero) cc = z/ss;
+                    else            ss = z/cc;
+                }
+                if(ix>0x48000000) z = (invsqrtpi*ss)/fd_sqrt(x);
+                else {
+                    u = pzero(x); v = qzero(x);
+                    z = invsqrtpi*(u*ss+v*cc)/fd_sqrt(x);
+                }
+                return z;
+	}
+	if(ix<=0x3e400000) {	/* x < 2**-27 */
+	    return(u00 + tpi*__ieee754_log(x));
+	}
+	z = x*x;
+	u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
+	v = one+z*(v01+z*(v02+z*(v03+z*v04)));
+	return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x)));
+}
+
+/* The asymptotic expansions of pzero is
+ *	1 - 9/128 s^2 + 11025/98304 s^4 - ...,	where s = 1/x.
+ * For x >= 2, We approximate pzero by
+ * 	pzero(x) = 1 + (R/S)
+ * where  R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10
+ * 	  S = 1 + pS0*s^2 + ... + pS4*s^10
+ * and
+ *	| pzero(x)-1-R/S | <= 2  ** ( -60.26)
+ */
+#ifdef __STDC__
+static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */
+ -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */
+ -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */
+ -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */
+ -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */
+};
+#ifdef __STDC__
+static const double pS8[5] = {
+#else
+static double pS8[5] = {
+#endif
+  1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */
+  3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */
+  4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */
+  1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */
+  4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */
+};
+
+#ifdef __STDC__
+static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */
+ -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */
+ -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */
+ -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */
+ -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */
+ -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */
+};
+#ifdef __STDC__
+static const double pS5[5] = {
+#else
+static double pS5[5] = {
+#endif
+  6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */
+  1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */
+  5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */
+  9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */
+  2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */
+};
+
+#ifdef __STDC__
+static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#else
+static double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */
+ -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */
+ -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */
+ -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */
+ -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */
+ -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */
+};
+#ifdef __STDC__
+static const double pS3[5] = {
+#else
+static double pS3[5] = {
+#endif
+  3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */
+  3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */
+  1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */
+  1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */
+  1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */
+};
+
+#ifdef __STDC__
+static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */
+ -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */
+ -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */
+ -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */
+ -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */
+ -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */
+};
+#ifdef __STDC__
+static const double pS2[5] = {
+#else
+static double pS2[5] = {
+#endif
+  2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */
+  1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */
+  2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */
+  1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */
+  1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */
+};
+
+#ifdef __STDC__
+	static double pzero(double x)
+#else
+	static double pzero(x)
+	double x;
+#endif
+{
+#ifdef __STDC__
+	const double *p,*q;
+#else
+	double *p,*q;
+#endif
+        fd_twoints u;
+	double z,r,s;
+	int ix;
+        u.d = x;
+	ix = 0x7fffffff&__HI(u);
+	if(ix>=0x40200000)     {p = pR8; q= pS8;}
+	else if(ix>=0x40122E8B){p = pR5; q= pS5;}
+	else if(ix>=0x4006DB6D){p = pR3; q= pS3;}
+	else if(ix>=0x40000000){p = pR2; q= pS2;}
+	z = one/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+	return one+ r/s;
+}
+		
+
+/* For x >= 8, the asymptotic expansions of qzero is
+ *	-1/8 s + 75/1024 s^3 - ..., where s = 1/x.
+ * We approximate pzero by
+ * 	qzero(x) = s*(-1.25 + (R/S))
+ * where  R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10
+ * 	  S = 1 + qS0*s^2 + ... + qS5*s^12
+ * and
+ *	| qzero(x)/s +1.25-R/S | <= 2  ** ( -61.22)
+ */
+#ifdef __STDC__
+static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+  7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */
+  1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */
+  5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */
+  8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */
+  3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */
+};
+#ifdef __STDC__
+static const double qS8[6] = {
+#else
+static double qS8[6] = {
+#endif
+  1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */
+  8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */
+  1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */
+  8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */
+  8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */
+ -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */
+};
+
+#ifdef __STDC__
+static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+  1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */
+  7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */
+  5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */
+  1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */
+  1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */
+  1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */
+};
+#ifdef __STDC__
+static const double qS5[6] = {
+#else
+static double qS5[6] = {
+#endif
+  8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */
+  2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */
+  1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */
+  5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */
+  3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */
+ -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */
+};
+
+#ifdef __STDC__
+static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#else
+static double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+  4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */
+  7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */
+  3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */
+  4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */
+  1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */
+  1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */
+};
+#ifdef __STDC__
+static const double qS3[6] = {
+#else
+static double qS3[6] = {
+#endif
+  4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */
+  7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */
+  3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */
+  6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */
+  2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */
+ -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */
+};
+
+#ifdef __STDC__
+static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+  1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */
+  7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */
+  1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */
+  1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */
+  3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */
+  1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */
+};
+#ifdef __STDC__
+static const double qS2[6] = {
+#else
+static double qS2[6] = {
+#endif
+  3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */
+  2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */
+  8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */
+  8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */
+  2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */
+ -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */
+};
+
+#ifdef __STDC__
+	static double qzero(double x)
+#else
+	static double qzero(x)
+	double x;
+#endif
+{
+#ifdef __STDC__
+	const double *p,*q;
+#else
+	double *p,*q;
+#endif
+        fd_twoints u;
+	double s,r,z;
+	int ix;
+        u.d = x;
+	ix = 0x7fffffff&__HI(u);
+	if(ix>=0x40200000)     {p = qR8; q= qS8;}
+	else if(ix>=0x40122E8B){p = qR5; q= qS5;}
+	else if(ix>=0x4006DB6D){p = qR3; q= qS3;}
+	else if(ix>=0x40000000){p = qR2; q= qS2;}
+	z = one/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+	return (-.125 + r/s)/x;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_j1.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_j1.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,523 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_j1.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_j1(x), __ieee754_y1(x)
+ * Bessel function of the first and second kinds of order zero.
+ * Method -- j1(x):
+ *	1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ...
+ *	2. Reduce x to |x| since j1(x)=-j1(-x),  and
+ *	   for x in (0,2)
+ *		j1(x) = x/2 + x*z*R0/S0,  where z = x*x;
+ *	   (precision:  |j1/x - 1/2 - R0/S0 |<2**-61.51 )
+ *	   for x in (2,inf)
+ * 		j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))
+ * 		y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ * 	   where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ *	   as follow:
+ *		cos(x1) =  cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+ *			=  1/sqrt(2) * (sin(x) - cos(x))
+ *		sin(x1) =  sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+ *			= -1/sqrt(2) * (sin(x) + cos(x))
+ * 	   (To avoid cancellation, use
+ *		sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+ * 	    to compute the worse one.)
+ *	   
+ *	3 Special cases
+ *		j1(nan)= nan
+ *		j1(0) = 0
+ *		j1(inf) = 0
+ *		
+ * Method -- y1(x):
+ *	1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN 
+ *	2. For x<2.
+ *	   Since 
+ *		y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...)
+ *	   therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function.
+ *	   We use the following function to approximate y1,
+ *		y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2
+ *	   where for x in [0,2] (abs err less than 2**-65.89)
+ *		U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4
+ *		V(z) = 1  + v0[0]*z + ... + v0[4]*z^5
+ *	   Note: For tiny x, 1/x dominate y1 and hence
+ *		y1(tiny) = -2/pi/tiny, (choose tiny<2**-54)
+ *	3. For x>=2.
+ * 		y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
+ * 	   where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
+ *	   by method mentioned above.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static double pone(double), qone(double);
+#else
+static double pone(), qone();
+#endif
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+really_big    = 1e300,
+one	= 1.0,
+invsqrtpi=  5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+tpi      =  6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+	/* R0/S0 on [0,2] */
+r00  = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */
+r01  =  1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */
+r02  = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */
+r03  =  4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */
+s01  =  1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */
+s02  =  1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */
+s03  =  1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */
+s04  =  5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */
+s05  =  1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */
+
+static double zero    = 0.0;
+
+#ifdef __STDC__
+	double __ieee754_j1(double x) 
+#else
+	double __ieee754_j1(x) 
+	double x;
+#endif
+{
+        fd_twoints un;
+	double z, s,c,ss,cc,r,u,v,y;
+	int hx,ix;
+
+        un.d = x;
+	hx = __HI(un);
+	ix = hx&0x7fffffff;
+	if(ix>=0x7ff00000) return one/x;
+	y = fd_fabs(x);
+	if(ix >= 0x40000000) {	/* |x| >= 2.0 */
+		s = fd_sin(y);
+		c = fd_cos(y);
+		ss = -s-c;
+		cc = s-c;
+		if(ix<0x7fe00000) {  /* make sure y+y not overflow */
+		    z = fd_cos(y+y);
+		    if ((s*c)>zero) cc = z/ss;
+		    else 	    ss = z/cc;
+		}
+	/*
+	 * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
+	 * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
+	 */
+		if(ix>0x48000000) z = (invsqrtpi*cc)/fd_sqrt(y);
+		else {
+		    u = pone(y); v = qone(y);
+		    z = invsqrtpi*(u*cc-v*ss)/fd_sqrt(y);
+		}
+		if(hx<0) return -z;
+		else  	 return  z;
+	}
+	if(ix<0x3e400000) {	/* |x|<2**-27 */
+	    if(really_big+x>one) return 0.5*x;/* inexact if x!=0 necessary */
+	}
+	z = x*x;
+	r =  z*(r00+z*(r01+z*(r02+z*r03)));
+	s =  one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
+	r *= x;
+	return(x*0.5+r/s);
+}
+
+#ifdef __STDC__
+static const double U0[5] = {
+#else
+static double U0[5] = {
+#endif
+ -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */
+  5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */
+ -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */
+  2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */
+ -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */
+};
+#ifdef __STDC__
+static const double V0[5] = {
+#else
+static double V0[5] = {
+#endif
+  1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */
+  2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */
+  1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */
+  6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */
+  1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */
+};
+
+#ifdef __STDC__
+	double __ieee754_y1(double x) 
+#else
+	double __ieee754_y1(x) 
+	double x;
+#endif
+{
+        fd_twoints un;
+	double z, s,c,ss,cc,u,v;
+	int hx,ix,lx;
+
+        un.d = x;
+        hx = __HI(un);
+        ix = 0x7fffffff&hx;
+        lx = __LO(un);
+    /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
+	if(ix>=0x7ff00000) return  one/(x+x*x); 
+        if((ix|lx)==0) return -one/zero;
+        if(hx<0) return zero/zero;
+        if(ix >= 0x40000000) {  /* |x| >= 2.0 */
+                s = fd_sin(x);
+                c = fd_cos(x);
+                ss = -s-c;
+                cc = s-c;
+                if(ix<0x7fe00000) {  /* make sure x+x not overflow */
+                    z = fd_cos(x+x);
+                    if ((s*c)>zero) cc = z/ss;
+                    else            ss = z/cc;
+                }
+        /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0))
+         * where x0 = x-3pi/4
+         *      Better formula:
+         *              cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
+         *                      =  1/sqrt(2) * (sin(x) - cos(x))
+         *              sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
+         *                      = -1/sqrt(2) * (cos(x) + sin(x))
+         * To avoid cancellation, use
+         *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
+         * to compute the worse one.
+         */
+                if(ix>0x48000000) z = (invsqrtpi*ss)/fd_sqrt(x);
+                else {
+                    u = pone(x); v = qone(x);
+                    z = invsqrtpi*(u*ss+v*cc)/fd_sqrt(x);
+                }
+                return z;
+        } 
+        if(ix<=0x3c900000) {    /* x < 2**-54 */
+            return(-tpi/x);
+        } 
+        z = x*x;
+        u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
+        v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
+        return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x));
+}
+
+/* For x >= 8, the asymptotic expansions of pone is
+ *	1 + 15/128 s^2 - 4725/2^15 s^4 - ...,	where s = 1/x.
+ * We approximate pone by
+ * 	pone(x) = 1 + (R/S)
+ * where  R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
+ * 	  S = 1 + ps0*s^2 + ... + ps4*s^10
+ * and
+ *	| pone(x)-1-R/S | <= 2  ** ( -60.06)
+ */
+
+#ifdef __STDC__
+static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+  1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */
+  1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */
+  4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */
+  3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */
+  7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */
+};
+#ifdef __STDC__
+static const double ps8[5] = {
+#else
+static double ps8[5] = {
+#endif
+  1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */
+  3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */
+  3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */
+  9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */
+  3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */
+};
+
+#ifdef __STDC__
+static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+  1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */
+  1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */
+  6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */
+  1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */
+  5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */
+  5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */
+};
+#ifdef __STDC__
+static const double ps5[5] = {
+#else
+static double ps5[5] = {
+#endif
+  5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */
+  9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */
+  5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */
+  7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */
+  1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */
+};
+
+#ifdef __STDC__
+static const double pr3[6] = {
+#else
+static double pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+  3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */
+  1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */
+  3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */
+  3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */
+  9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */
+  4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */
+};
+#ifdef __STDC__
+static const double ps3[5] = {
+#else
+static double ps3[5] = {
+#endif
+  3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */
+  3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */
+  1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */
+  8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */
+  1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */
+};
+
+#ifdef __STDC__
+static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+  1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */
+  1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */
+  2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */
+  1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */
+  1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */
+  5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */
+};
+#ifdef __STDC__
+static const double ps2[5] = {
+#else
+static double ps2[5] = {
+#endif
+  2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */
+  1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */
+  2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */
+  1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */
+  8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */
+};
+
+#ifdef __STDC__
+	static double pone(double x)
+#else
+	static double pone(x)
+	double x;
+#endif
+{
+#ifdef __STDC__
+	const double *p,*q;
+#else
+	double *p,*q;
+#endif
+        fd_twoints un;
+	double z,r,s;
+        int ix;
+        un.d = x;
+        ix = 0x7fffffff&__HI(un);
+        if(ix>=0x40200000)     {p = pr8; q= ps8;}
+        else if(ix>=0x40122E8B){p = pr5; q= ps5;}
+        else if(ix>=0x4006DB6D){p = pr3; q= ps3;}
+        else if(ix>=0x40000000){p = pr2; q= ps2;}
+        z = one/(x*x);
+        r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+        s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
+        return one+ r/s;
+}
+		
+
+/* For x >= 8, the asymptotic expansions of qone is
+ *	3/8 s - 105/1024 s^3 - ..., where s = 1/x.
+ * We approximate pone by
+ * 	qone(x) = s*(0.375 + (R/S))
+ * where  R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10
+ * 	  S = 1 + qs1*s^2 + ... + qs6*s^12
+ * and
+ *	| qone(x)/s -0.375-R/S | <= 2  ** ( -61.13)
+ */
+
+#ifdef __STDC__
+static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#else
+static double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
+#endif
+  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+ -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */
+ -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */
+ -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */
+ -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */
+ -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */
+};
+#ifdef __STDC__
+static const double qs8[6] = {
+#else
+static double qs8[6] = {
+#endif
+  1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */
+  7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */
+  1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */
+  7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */
+  6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */
+ -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */
+};
+
+#ifdef __STDC__
+static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#else
+static double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
+#endif
+ -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */
+ -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */
+ -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */
+ -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */
+ -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */
+ -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */
+};
+#ifdef __STDC__
+static const double qs5[6] = {
+#else
+static double qs5[6] = {
+#endif
+  8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */
+  1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */
+  1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */
+  4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */
+  2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */
+ -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */
+};
+
+#ifdef __STDC__
+static const double qr3[6] = {
+#else
+static double qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
+#endif
+ -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */
+ -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */
+ -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */
+ -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */
+ -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */
+ -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */
+};
+#ifdef __STDC__
+static const double qs3[6] = {
+#else
+static double qs3[6] = {
+#endif
+  4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */
+  6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */
+  3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */
+  5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */
+  1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */
+ -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */
+};
+
+#ifdef __STDC__
+static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#else
+static double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
+#endif
+ -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */
+ -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */
+ -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */
+ -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */
+ -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */
+ -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */
+};
+#ifdef __STDC__
+static const double qs2[6] = {
+#else
+static double qs2[6] = {
+#endif
+  2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */
+  2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */
+  7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */
+  7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */
+  1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */
+ -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */
+};
+
+#ifdef __STDC__
+	static double qone(double x)
+#else
+	static double qone(x)
+	double x;
+#endif
+{
+#ifdef __STDC__
+	const double *p,*q;
+#else
+	double *p,*q;
+#endif
+        fd_twoints un;
+	double  s,r,z;
+	int ix;
+        un.d = x;
+	ix = 0x7fffffff&__HI(un);
+	if(ix>=0x40200000)     {p = qr8; q= qs8;}
+	else if(ix>=0x40122E8B){p = qr5; q= qs5;}
+	else if(ix>=0x4006DB6D){p = qr3; q= qs3;}
+	else if(ix>=0x40000000){p = qr2; q= qs2;}
+	z = one/(x*x);
+	r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
+	s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
+	return (.375 + r/s)/x;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_jn.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_jn.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,315 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_jn.c 1.4 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * __ieee754_jn(n, x), __ieee754_yn(n, x)
+ * floating point Bessel's function of the 1st and 2nd kind
+ * of order n
+ *          
+ * Special cases:
+ *	y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
+ *	y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
+ * Note 2. About jn(n,x), yn(n,x)
+ *	For n=0, j0(x) is called,
+ *	for n=1, j1(x) is called,
+ *	for n<x, forward recursion us used starting
+ *	from values of j0(x) and j1(x).
+ *	for n>x, a continued fraction approximation to
+ *	j(n,x)/j(n-1,x) is evaluated and then backward
+ *	recursion is used starting from a supposed value
+ *	for j(n,x). The resulting value of j(0,x) is
+ *	compared with the actual value to correct the
+ *	supposed value of j(n,x).
+ *
+ *	yn(n,x) is similar in all respects, except
+ *	that forward recursion is used for all
+ *	values of n>1.
+ *	
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+invsqrtpi=  5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
+two   =  2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
+one   =  1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */
+
+static double zero  =  0.00000000000000000000e+00;
+
+#ifdef __STDC__
+	double __ieee754_jn(int n, double x)
+#else
+	double __ieee754_jn(n,x)
+	int n; double x;
+#endif
+{
+        fd_twoints u;
+	int i,hx,ix,lx, sgn;
+	double a, b, temp, di;
+	double z, w;
+
+    /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
+     * Thus, J(-n,x) = J(n,-x)
+     */
+        u.d = x;
+	hx = __HI(u);
+	ix = 0x7fffffff&hx;
+	lx = __LO(u);
+    /* if J(n,NaN) is NaN */
+	if((ix|((unsigned)(lx|-lx))>>31)>0x7ff00000) return x+x;
+	if(n<0){		
+		n = -n;
+		x = -x;
+		hx ^= 0x80000000;
+	}
+	if(n==0) return(__ieee754_j0(x));
+	if(n==1) return(__ieee754_j1(x));
+	sgn = (n&1)&(hx>>31);	/* even n -- 0, odd n -- sign(x) */
+	x = fd_fabs(x);
+	if((ix|lx)==0||ix>=0x7ff00000) 	/* if x is 0 or inf */
+	    b = zero;
+	else if((double)n<=x) {   
+		/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
+	    if(ix>=0x52D00000) { /* x > 2**302 */
+    /* (x >> n**2) 
+     *	    Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+     *	    Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+     *	    Let s=sin(x), c=cos(x), 
+     *		xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+     *
+     *		   n	sin(xn)*sqt2	cos(xn)*sqt2
+     *		----------------------------------
+     *		   0	 s-c		 c+s
+     *		   1	-s-c 		-c+s
+     *		   2	-s+c		-c-s
+     *		   3	 s+c		 c-s
+     */
+		switch(n&3) {
+		    case 0: temp =  fd_cos(x)+fd_sin(x); break;
+		    case 1: temp = -fd_cos(x)+fd_sin(x); break;
+		    case 2: temp = -fd_cos(x)-fd_sin(x); break;
+		    case 3: temp =  fd_cos(x)-fd_sin(x); break;
+		}
+		b = invsqrtpi*temp/fd_sqrt(x);
+	    } else {	
+	        a = __ieee754_j0(x);
+	        b = __ieee754_j1(x);
+	        for(i=1;i<n;i++){
+		    temp = b;
+		    b = b*((double)(i+i)/x) - a; /* avoid underflow */
+		    a = temp;
+	        }
+	    }
+	} else {
+	    if(ix<0x3e100000) {	/* x < 2**-29 */
+    /* x is tiny, return the first Taylor expansion of J(n,x) 
+     * J(n,x) = 1/n!*(x/2)^n  - ...
+     */
+		if(n>33)	/* underflow */
+		    b = zero;
+		else {
+		    temp = x*0.5; b = temp;
+		    for (a=one,i=2;i<=n;i++) {
+			a *= (double)i;		/* a = n! */
+			b *= temp;		/* b = (x/2)^n */
+		    }
+		    b = b/a;
+		}
+	    } else {
+		/* use backward recurrence */
+		/* 			x      x^2      x^2       
+		 *  J(n,x)/J(n-1,x) =  ----   ------   ------   .....
+		 *			2n  - 2(n+1) - 2(n+2)
+		 *
+		 * 			1      1        1       
+		 *  (for large x)   =  ----  ------   ------   .....
+		 *			2n   2(n+1)   2(n+2)
+		 *			-- - ------ - ------ - 
+		 *			 x     x         x
+		 *
+		 * Let w = 2n/x and h=2/x, then the above quotient
+		 * is equal to the continued fraction:
+		 *		    1
+		 *	= -----------------------
+		 *		       1
+		 *	   w - -----------------
+		 *			  1
+		 * 	        w+h - ---------
+		 *		       w+2h - ...
+		 *
+		 * To determine how many terms needed, let
+		 * Q(0) = w, Q(1) = w(w+h) - 1,
+		 * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
+		 * When Q(k) > 1e4	good for single 
+		 * When Q(k) > 1e9	good for double 
+		 * When Q(k) > 1e17	good for quadruple 
+		 */
+	    /* determine k */
+		double t,v;
+		double q0,q1,h,tmp; int k,m;
+		w  = (n+n)/(double)x; h = 2.0/(double)x;
+		q0 = w;  z = w+h; q1 = w*z - 1.0; k=1;
+		while(q1<1.0e9) {
+			k += 1; z += h;
+			tmp = z*q1 - q0;
+			q0 = q1;
+			q1 = tmp;
+		}
+		m = n+n;
+		for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t);
+		a = t;
+		b = one;
+		/*  estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
+		 *  Hence, if n*(log(2n/x)) > ...
+		 *  single 8.8722839355e+01
+		 *  double 7.09782712893383973096e+02
+		 *  long double 1.1356523406294143949491931077970765006170e+04
+		 *  then recurrent value may overflow and the result is 
+		 *  likely underflow to zero
+		 */
+		tmp = n;
+		v = two/x;
+		tmp = tmp*__ieee754_log(fd_fabs(v*tmp));
+		if(tmp<7.09782712893383973096e+02) {
+	    	    for(i=n-1,di=(double)(i+i);i>0;i--){
+		        temp = b;
+			b *= di;
+			b  = b/x - a;
+		        a = temp;
+			di -= two;
+	     	    }
+		} else {
+	    	    for(i=n-1,di=(double)(i+i);i>0;i--){
+		        temp = b;
+			b *= di;
+			b  = b/x - a;
+		        a = temp;
+			di -= two;
+		    /* scale b to avoid spurious overflow */
+			if(b>1e100) {
+			    a /= b;
+			    t /= b;
+			    b  = one;
+			}
+	     	    }
+		}
+	    	b = (t*__ieee754_j0(x)/b);
+	    }
+	}
+	if(sgn==1) return -b; else return b;
+}
+
+#ifdef __STDC__
+	double __ieee754_yn(int n, double x) 
+#else
+	double __ieee754_yn(n,x) 
+	int n; double x;
+#endif
+{
+        fd_twoints u;
+	int i,hx,ix,lx;
+	int sign;
+	double a, b, temp;
+
+        u.d = x;
+	hx = __HI(u);
+	ix = 0x7fffffff&hx;
+	lx = __LO(u);
+    /* if Y(n,NaN) is NaN */
+	if((ix|((unsigned)(lx|-lx))>>31)>0x7ff00000) return x+x;
+	if((ix|lx)==0) return -one/zero;
+	if(hx<0) return zero/zero;
+	sign = 1;
+	if(n<0){
+		n = -n;
+		sign = 1 - ((n&1)<<1);
+	}
+	if(n==0) return(__ieee754_y0(x));
+	if(n==1) return(sign*__ieee754_y1(x));
+	if(ix==0x7ff00000) return zero;
+	if(ix>=0x52D00000) { /* x > 2**302 */
+    /* (x >> n**2) 
+     *	    Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+     *	    Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
+     *	    Let s=sin(x), c=cos(x), 
+     *		xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
+     *
+     *		   n	sin(xn)*sqt2	cos(xn)*sqt2
+     *		----------------------------------
+     *		   0	 s-c		 c+s
+     *		   1	-s-c 		-c+s
+     *		   2	-s+c		-c-s
+     *		   3	 s+c		 c-s
+     */
+		switch(n&3) {
+		    case 0: temp =  fd_sin(x)-fd_cos(x); break;
+		    case 1: temp = -fd_sin(x)-fd_cos(x); break;
+		    case 2: temp = -fd_sin(x)+fd_cos(x); break;
+		    case 3: temp =  fd_sin(x)+fd_cos(x); break;
+		}
+		b = invsqrtpi*temp/fd_sqrt(x);
+	} else {
+	    a = __ieee754_y0(x);
+	    b = __ieee754_y1(x);
+	/* quit if b is -inf */
+            u.d = b;
+	    for(i=1;i<n&&(__HI(u) != 0xfff00000);i++){ 
+		temp = b;
+		b = ((double)(i+i)/x)*b - a;
+		a = temp;
+	    }
+	}
+	if(sign>0) return b; else return -b;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_lgamma.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_lgamma.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_lgamma.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* __ieee754_lgamma(x)
+ * Return the logarithm of the Gamma function of x.
+ *
+ * Method: call __ieee754_lgamma_r
+ */
+
+#include "fdlibm.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+	double __ieee754_lgamma(double x)
+#else
+	double __ieee754_lgamma(x)
+	double x;
+#endif
+{
+	return __ieee754_lgamma_r(x,&signgam);
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_lgamma_r.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_lgamma_r.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,347 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_lgamma_r.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* __ieee754_lgamma_r(x, signgamp)
+ * Reentrant version of the logarithm of the Gamma function 
+ * with user provide pointer for the sign of Gamma(x). 
+ *
+ * Method:
+ *   1. Argument Reduction for 0 < x <= 8
+ * 	Since gamma(1+s)=s*gamma(s), for x in [0,8], we may 
+ * 	reduce x to a number in [1.5,2.5] by
+ * 		lgamma(1+s) = log(s) + lgamma(s)
+ *	for example,
+ *		lgamma(7.3) = log(6.3) + lgamma(6.3)
+ *			    = log(6.3*5.3) + lgamma(5.3)
+ *			    = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
+ *   2. Polynomial approximation of lgamma around its
+ *	minimun ymin=1.461632144968362245 to maintain monotonicity.
+ *	On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
+ *		Let z = x-ymin;
+ *		lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
+ *	where
+ *		poly(z) is a 14 degree polynomial.
+ *   2. Rational approximation in the primary interval [2,3]
+ *	We use the following approximation:
+ *		s = x-2.0;
+ *		lgamma(x) = 0.5*s + s*P(s)/Q(s)
+ *	with accuracy
+ *		|P/Q - (lgamma(x)-0.5s)| < 2**-61.71
+ *	Our algorithms are based on the following observation
+ *
+ *                             zeta(2)-1    2    zeta(3)-1    3
+ * lgamma(2+s) = s*(1-Euler) + --------- * s  -  --------- * s  + ...
+ *                                 2                 3
+ *
+ *	where Euler = 0.5771... is the Euler constant, which is very
+ *	close to 0.5.
+ *
+ *   3. For x>=8, we have
+ *	lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
+ *	(better formula:
+ *	   lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
+ *	Let z = 1/x, then we approximation
+ *		f(z) = lgamma(x) - (x-0.5)(log(x)-1)
+ *	by
+ *	  			    3       5             11
+ *		w = w0 + w1*z + w2*z  + w3*z  + ... + w6*z
+ *	where 
+ *		|w - f(z)| < 2**-58.74
+ *		
+ *   4. For negative x, since (G is gamma function)
+ *		-x*G(-x)*G(x) = pi/sin(pi*x),
+ * 	we have
+ * 		G(x) = pi/(sin(pi*x)*(-x)*G(-x))
+ *	since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
+ *	Hence, for x<0, signgam = sign(sin(pi*x)) and 
+ *		lgamma(x) = log(|Gamma(x)|)
+ *			  = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
+ *	Note: one should avoid compute pi*(-x) directly in the 
+ *	      computation of sin(pi*(-x)).
+ *		
+ *   5. Special Cases
+ *		lgamma(2+s) ~ s*(1-Euler) for tiny s
+ *		lgamma(1)=lgamma(2)=0
+ *		lgamma(x) ~ -log(x) for tiny x
+ *		lgamma(0) = lgamma(inf) = inf
+ *	 	lgamma(-integer) = +-inf
+ *	
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+two52=  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+half=  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pi  =  3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
+a0  =  7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */
+a1  =  3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */
+a2  =  6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */
+a3  =  2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */
+a4  =  7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */
+a5  =  2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */
+a6  =  1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */
+a7  =  5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */
+a8  =  2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */
+a9  =  1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */
+a10 =  2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */
+a11 =  4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */
+tc  =  1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */
+tf  = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */
+/* tt = -(tail of tf) */
+tt  = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */
+t0  =  4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */
+t1  = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */
+t2  =  6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */
+t3  = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */
+t4  =  1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */
+t5  = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */
+t6  =  6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */
+t7  = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */
+t8  =  2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */
+t9  = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */
+t10 =  8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */
+t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */
+t12 =  3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */
+t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */
+t14 =  3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */
+u0  = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
+u1  =  6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */
+u2  =  1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */
+u3  =  9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */
+u4  =  2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */
+u5  =  1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */
+v1  =  2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */
+v2  =  2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */
+v3  =  7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */
+v4  =  1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */
+v5  =  3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */
+s0  = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
+s1  =  2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */
+s2  =  3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */
+s3  =  1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */
+s4  =  2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */
+s5  =  1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */
+s6  =  3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */
+r1  =  1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */
+r2  =  7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */
+r3  =  1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */
+r4  =  1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */
+r5  =  7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */
+r6  =  7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */
+w0  =  4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */
+w1  =  8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */
+w2  = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */
+w3  =  7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */
+w4  = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */
+w5  =  8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */
+w6  = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */
+
+static double zero=  0.00000000000000000000e+00;
+
+#ifdef __STDC__
+	static double sin_pi(double x)
+#else
+	static double sin_pi(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	double y,z;
+	int n,ix;
+
+        u.d = x;
+	ix = 0x7fffffff&__HI(u);
+
+	if(ix<0x3fd00000) return __kernel_sin(pi*x,zero,0);
+	y = -x;		/* x is assume negative */
+
+    /*
+     * argument reduction, make sure inexact flag not raised if input
+     * is an integer
+     */
+	z = fd_floor(y);
+	if(z!=y) {				/* inexact anyway */
+	    y  *= 0.5;
+	    y   = 2.0*(y - fd_floor(y));		/* y = |x| mod 2.0 */
+	    n   = (int) (y*4.0);
+	} else {
+            if(ix>=0x43400000) {
+                y = zero; n = 0;                 /* y must be even */
+            } else {
+                if(ix<0x43300000) z = y+two52;	/* exact */
+                u.d = z;
+                n   = __LO(u)&1;        /* lower word of z */
+                y  = n;
+                n<<= 2;
+            }
+        }
+	switch (n) {
+	    case 0:   y =  __kernel_sin(pi*y,zero,0); break;
+	    case 1:   
+	    case 2:   y =  __kernel_cos(pi*(0.5-y),zero); break;
+	    case 3:  
+	    case 4:   y =  __kernel_sin(pi*(one-y),zero,0); break;
+	    case 5:
+	    case 6:   y = -__kernel_cos(pi*(y-1.5),zero); break;
+	    default:  y =  __kernel_sin(pi*(y-2.0),zero,0); break;
+	    }
+	return -y;
+}
+
+
+#ifdef __STDC__
+	double __ieee754_lgamma_r(double x, int *signgamp)
+#else
+	double __ieee754_lgamma_r(x,signgamp)
+	double x; int *signgamp;
+#endif
+{
+        fd_twoints u;
+	double t,y,z,nadj,p,p1,p2,p3,q,r,w;
+	int i,hx,lx,ix;
+
+        u.d = x;
+	hx = __HI(u);
+	lx = __LO(u);
+
+    /* purge off +-inf, NaN, +-0, and negative arguments */
+	*signgamp = 1;
+	ix = hx&0x7fffffff;
+	if(ix>=0x7ff00000) return x*x;
+	if((ix|lx)==0) return one/zero;
+	if(ix<0x3b900000) {	/* |x|<2**-70, return -log(|x|) */
+	    if(hx<0) {
+	        *signgamp = -1;
+	        return -__ieee754_log(-x);
+	    } else return -__ieee754_log(x);
+	}
+	if(hx<0) {
+	    if(ix>=0x43300000) 	/* |x|>=2**52, must be -integer */
+		return one/zero;
+	    t = sin_pi(x);
+	    if(t==zero) return one/zero; /* -integer */
+	    nadj = __ieee754_log(pi/fd_fabs(t*x));
+	    if(t<zero) *signgamp = -1;
+	    x = -x;
+	}
+
+    /* purge off 1 and 2 */
+	if((((ix-0x3ff00000)|lx)==0)||(((ix-0x40000000)|lx)==0)) r = 0;
+    /* for x < 2.0 */
+	else if(ix<0x40000000) {
+	    if(ix<=0x3feccccc) { 	/* lgamma(x) = lgamma(x+1)-log(x) */
+		r = -__ieee754_log(x);
+		if(ix>=0x3FE76944) {y = one-x; i= 0;}
+		else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;}
+	  	else {y = x; i=2;}
+	    } else {
+	  	r = zero;
+	        if(ix>=0x3FFBB4C3) {y=2.0-x;i=0;} /* [1.7316,2] */
+	        else if(ix>=0x3FF3B4C4) {y=x-tc;i=1;} /* [1.23,1.73] */
+		else {y=x-one;i=2;}
+	    }
+	    switch(i) {
+	      case 0:
+		z = y*y;
+		p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
+		p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
+		p  = y*p1+p2;
+		r  += (p-0.5*y); break;
+	      case 1:
+		z = y*y;
+		w = z*y;
+		p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12)));	/* parallel comp */
+		p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
+		p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
+		p  = z*p1-(tt-w*(p2+y*p3));
+		r += (tf + p); break;
+	      case 2:	
+		p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
+		p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
+		r += (-0.5*y + p1/p2);
+	    }
+	}
+	else if(ix<0x40200000) { 			/* x < 8.0 */
+	    i = (int)x;
+	    t = zero;
+	    y = x-(double)i;
+	    p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
+	    q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
+	    r = half*y+p/q;
+	    z = one;	/* lgamma(1+s) = log(s) + lgamma(s) */
+	    switch(i) {
+	    case 7: z *= (y+6.0);	/* FALLTHRU */
+	    case 6: z *= (y+5.0);	/* FALLTHRU */
+	    case 5: z *= (y+4.0);	/* FALLTHRU */
+	    case 4: z *= (y+3.0);	/* FALLTHRU */
+	    case 3: z *= (y+2.0);	/* FALLTHRU */
+		    r += __ieee754_log(z); break;
+	    }
+    /* 8.0 <= x < 2**58 */
+	} else if (ix < 0x43900000) {
+	    t = __ieee754_log(x);
+	    z = one/x;
+	    y = z*z;
+	    w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
+	    r = (x-half)*(t-one)+w;
+	} else 
+    /* 2**58 <= x <= inf */
+	    r =  x*(__ieee754_log(x)-one);
+	if(hx<0) r = nadj - r;
+	return r;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_log.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_log.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,184 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_log.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_log(x)
+ * Return the logrithm of x
+ *
+ * Method :                  
+ *   1. Argument Reduction: find k and f such that 
+ *			x = 2^k * (1+f), 
+ *	   where  sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ *   2. Approximation of log(1+f).
+ *	Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ *		 = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ *	     	 = 2s + s*R
+ *      We use a special Reme algorithm on [0,0.1716] to generate 
+ * 	a polynomial of degree 14 to approximate R The maximum error 
+ *	of this polynomial approximation is bounded by 2**-58.45. In
+ *	other words,
+ *		        2      4      6      8      10      12      14
+ *	    R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s  +Lg6*s  +Lg7*s
+ *  	(the values of Lg1 to Lg7 are listed in the program)
+ *	and
+ *	    |      2          14          |     -58.45
+ *	    | Lg1*s +...+Lg7*s    -  R(z) | <= 2 
+ *	    |                             |
+ *	Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ *	In order to guarantee error in log below 1ulp, we compute log
+ *	by
+ *		log(1+f) = f - s*(f - R)	(if f is not too large)
+ *		log(1+f) = f - (hfsq - s*(hfsq+R)).	(better accuracy)
+ *	
+ *	3. Finally,  log(x) = k*ln2 + log(1+f).  
+ *			    = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ *	   Here ln2 is split into two floating point number: 
+ *			ln2_hi + ln2_lo,
+ *	   where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ *	log(x) is NaN with signal if x < 0 (including -INF) ; 
+ *	log(+INF) is +INF; log(0) is -INF with signal;
+ *	log(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ *	according to an error analysis, the error is always less than
+ *	1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough 
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+ln2_hi  =  6.93147180369123816490e-01,	/* 3fe62e42 fee00000 */
+ln2_lo  =  1.90821492927058770002e-10,	/* 3dea39ef 35793c76 */
+two54   =  1.80143985094819840000e+16,  /* 43500000 00000000 */
+Lg1 = 6.666666666666735130e-01,  /* 3FE55555 55555593 */
+Lg2 = 3.999999999940941908e-01,  /* 3FD99999 9997FA04 */
+Lg3 = 2.857142874366239149e-01,  /* 3FD24924 94229359 */
+Lg4 = 2.222219843214978396e-01,  /* 3FCC71C5 1D8E78AF */
+Lg5 = 1.818357216161805012e-01,  /* 3FC74664 96CB03DE */
+Lg6 = 1.531383769920937332e-01,  /* 3FC39A09 D078C69F */
+Lg7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
+
+static double zero   =  0.0;
+
+#ifdef __STDC__
+	double __ieee754_log(double x)
+#else
+	double __ieee754_log(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	double hfsq,f,s,z,R,w,t1,t2,dk;
+	int k,hx,i,j;
+	unsigned lx;
+
+        u.d = x;
+	hx = __HI(u);		/* high word of x */
+	lx = __LO(u);		/* low  word of x */
+
+	k=0;
+	if (hx < 0x00100000) {			/* x < 2**-1022  */
+	    if (((hx&0x7fffffff)|lx)==0) 
+		return -two54/zero;		/* log(+-0)=-inf */
+	    if (hx<0) return (x-x)/zero;	/* log(-#) = NaN */
+	    k -= 54; x *= two54; /* subnormal number, scale up x */
+            u.d = x;
+	    hx = __HI(u);		/* high word of x */
+	} 
+	if (hx >= 0x7ff00000) return x+x;
+	k += (hx>>20)-1023;
+	hx &= 0x000fffff;
+	i = (hx+0x95f64)&0x100000;
+        u.d = x;
+	__HI(u) = hx|(i^0x3ff00000);	/* normalize x or x/2 */
+        x = u.d;
+	k += (i>>20);
+	f = x-1.0;
+	if((0x000fffff&(2+hx))<3) {	/* |f| < 2**-20 */
+	    if(f==zero) { 
+                if(k==0) return zero; else {dk=(double)k;
+                                            return dk*ln2_hi+dk*ln2_lo;} 
+            }
+	    R = f*f*(0.5-0.33333333333333333*f);
+	    if(k==0) return f-R; else {dk=(double)k;
+	    	     return dk*ln2_hi-((R-dk*ln2_lo)-f);}
+	}
+ 	s = f/(2.0+f); 
+	dk = (double)k;
+	z = s*s;
+	i = hx-0x6147a;
+	w = z*z;
+	j = 0x6b851-hx;
+	t1= w*(Lg2+w*(Lg4+w*Lg6)); 
+	t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); 
+	i |= j;
+	R = t2+t1;
+	if(i>0) {
+	    hfsq=0.5*f*f;
+	    if(k==0) return f-(hfsq-s*(hfsq+R)); else
+		     return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
+	} else {
+	    if(k==0) return f-s*(f-R); else
+		     return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_log10.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_log10.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,134 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_log10.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_log10(x)
+ * Return the base 10 logarithm of x
+ * 
+ * Method :
+ *	Let log10_2hi = leading 40 bits of log10(2) and
+ *	    log10_2lo = log10(2) - log10_2hi,
+ *	    ivln10   = 1/log(10) rounded.
+ *	Then
+ *		n = ilogb(x), 
+ *		if(n<0)  n = n+1;
+ *		x = scalbn(x,-n);
+ *		log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x))
+ *
+ * Note 1:
+ *	To guarantee log10(10**n)=n, where 10**n is normal, the rounding 
+ *	mode must set to Round-to-Nearest.
+ * Note 2:
+ *	[1/log(10)] rounded to 53 bits has error  .198   ulps;
+ *	log10 is monotonic at all binary break points.
+ *
+ * Special cases:
+ *	log10(x) is NaN with signal if x < 0; 
+ *	log10(+INF) is +INF with no signal; log10(0) is -INF with signal;
+ *	log10(NaN) is that NaN with no signal;
+ *	log10(10**N) = N  for N=0,1,...,22.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54      =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+ivln10     =  4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */
+log10_2hi  =  3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
+log10_2lo  =  3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */
+
+static double zero   =  0.0;
+
+#ifdef __STDC__
+	double __ieee754_log10(double x)
+#else
+	double __ieee754_log10(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	double y,z;
+	int i,k,hx;
+	unsigned lx;
+
+        u.d = x;
+	hx = __HI(u);	/* high word of x */
+	lx = __LO(u);	/* low word of x */
+
+        k=0;
+        if (hx < 0x00100000) {                  /* x < 2**-1022  */
+            if (((hx&0x7fffffff)|lx)==0)
+                return -two54/zero;             /* log(+-0)=-inf */
+            if (hx<0) return (x-x)/zero;        /* log(-#) = NaN */
+            k -= 54; x *= two54; /* subnormal number, scale up x */
+            u.d = x;
+            hx = __HI(u);                /* high word of x */
+        }
+	if (hx >= 0x7ff00000) return x+x;
+	k += (hx>>20)-1023;
+	i  = ((unsigned)k&0x80000000)>>31;
+        hx = (hx&0x000fffff)|((0x3ff-i)<<20);
+        y  = (double)(k+i);
+        u.d = x;
+        __HI(u) = hx;
+        x = u.d;
+	z  = y*log10_2lo + ivln10*__ieee754_log(x);
+	return  z+y*log10_2hi;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_pow.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_pow.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,386 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_pow.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_pow(x,y) return x**y
+ *
+ *		      n
+ * Method:  Let x =  2   * (1+f)
+ *	1. Compute and return log2(x) in two pieces:
+ *		log2(x) = w1 + w2,
+ *	   where w1 has 53-24 = 29 bit trailing zeros.
+ *	2. Perform y*log2(x) = n+y' by simulating muti-precision 
+ *	   arithmetic, where |y'|<=0.5.
+ *	3. Return x**y = 2**n*exp(y'*log2)
+ *
+ * Special cases:
+ *	1.  (anything) ** 0  is 1
+ *	2.  (anything) ** 1  is itself
+ *	3.  (anything) ** NAN is NAN
+ *	4.  NAN ** (anything except 0) is NAN
+ *	5.  +-(|x| > 1) **  +INF is +INF
+ *	6.  +-(|x| > 1) **  -INF is +0
+ *	7.  +-(|x| < 1) **  +INF is +0
+ *	8.  +-(|x| < 1) **  -INF is +INF
+ *	9.  +-1         ** +-INF is NAN
+ *	10. +0 ** (+anything except 0, NAN)               is +0
+ *	11. -0 ** (+anything except 0, NAN, odd integer)  is +0
+ *	12. +0 ** (-anything except 0, NAN)               is +INF
+ *	13. -0 ** (-anything except 0, NAN, odd integer)  is +INF
+ *	14. -0 ** (odd integer) = -( +0 ** (odd integer) )
+ *	15. +INF ** (+anything except 0,NAN) is +INF
+ *	16. +INF ** (-anything except 0,NAN) is +0
+ *	17. -INF ** (anything)  = -0 ** (-anything)
+ *	18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
+ *	19. (-anything except 0 and inf) ** (non-integer) is NAN
+ *
+ * Accuracy:
+ *	pow(x,y) returns x**y nearly rounded. In particular
+ *			pow(integer,integer)
+ *	always returns the correct integer provided it is 
+ *	representable.
+ *
+ * Constants :
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough 
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#if defined(_MSC_VER)
+/* Microsoft Compiler */
+#pragma warning( disable : 4723 ) /* disables potential divide by 0 warning */
+#endif
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+bp[] = {1.0, 1.5,},
+dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
+dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
+zero    =  0.0,
+one	=  1.0,
+two	=  2.0,
+two53	=  9007199254740992.0,	/* 0x43400000, 0x00000000 */
+really_big	=  1.0e300,
+tiny    =  1.0e-300,
+	/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
+L1  =  5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
+L2  =  4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
+L3  =  3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
+L4  =  2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
+L5  =  2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
+L6  =  2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
+P1   =  1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
+P2   = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
+P3   =  6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
+P4   = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
+P5   =  4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
+lg2  =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+lg2_h  =  6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
+lg2_l  = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
+ovt =  8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
+cp    =  9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
+cp_h  =  9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
+cp_l  = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
+ivln2    =  1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
+ivln2_h  =  1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
+ivln2_l  =  1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
+
+#ifdef __STDC__
+	double __ieee754_pow(double x, double y)
+#else
+	double __ieee754_pow(x,y)
+	double x, y;
+#endif
+{
+        fd_twoints ux, uy, uz;
+        double y1,t1,p_h,t,z,ax;
+	double z_h,z_l,p_l;
+	double t2,r,s,u,v,w;
+	int i,j,k,yisint,n;
+	int hx,hy,ix,iy;
+	unsigned lx,ly;
+
+        ux.d = x; uy.d = y;
+	hx = __HI(ux); lx = __LO(ux);
+	hy = __HI(uy); ly = __LO(uy);
+	ix = hx&0x7fffffff;  iy = hy&0x7fffffff;
+
+    /* y==zero: x**0 = 1 */
+	if((iy|ly)==0) return one; 	
+
+    /* +-NaN return x+y */
+	if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
+	   iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) 
+		return x+y;	
+
+    /* determine if y is an odd int when x < 0
+     * yisint = 0	... y is not an integer
+     * yisint = 1	... y is an odd int
+     * yisint = 2	... y is an even int
+     */
+	yisint  = 0;
+	if(hx<0) {	
+	    if(iy>=0x43400000) yisint = 2; /* even integer y */
+	    else if(iy>=0x3ff00000) {
+		k = (iy>>20)-0x3ff;	   /* exponent */
+		if(k>20) {
+		    j = ly>>(52-k);
+		    if((j<<(52-k))==(int)ly) yisint = 2-(j&1);
+		} else if(ly==0) {
+		    j = iy>>(20-k);
+		    if((j<<(20-k))==iy) yisint = 2-(j&1);
+		}
+	    }		
+	} 
+
+    /* special value of y */
+	if(ly==0) { 	
+	    if (iy==0x7ff00000) {	/* y is +-inf */
+	        if(((ix-0x3ff00000)|lx)==0)
+#ifdef _WIN32
+/* VC++ optimizer reduces y - y to 0 */ 
+                    return y / y;
+#else
+		    return  y - y;	/* inf**+-1 is NaN */
+#endif
+	        else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
+		    return (hy>=0)? y: zero;
+	        else			/* (|x|<1)**-,+inf = inf,0 */
+		    return (hy<0)?-y: zero;
+	    } 
+	    if(iy==0x3ff00000) {	/* y is  +-1 */
+		if(hy<0) return one/x; else return x;
+	    }
+	    if(hy==0x40000000) return x*x; /* y is  2 */
+	    if(hy==0x3fe00000) {	/* y is  0.5 */
+		if(hx>=0)	/* x >= +0 */
+		return fd_sqrt(x);	
+	    }
+	}
+
+	ax   = fd_fabs(x);
+    /* special value of x */
+	if(lx==0) {
+	    if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
+		z = ax;			/*x is +-0,+-inf,+-1*/
+		if(hy<0) z = one/z;	/* z = (1/|x|) */
+		if(hx<0) {
+		    if(((ix-0x3ff00000)|yisint)==0) {
+			z = (z-z)/(z-z); /* (-1)**non-int is NaN */
+		    } else if(yisint==1) {
+#ifdef HPUX
+                        uz.d = z;
+			__HI(uz) ^= 1<<31; /* some HPUXes cannot negate 0.. */
+                        z = uz.d;
+#else
+			z = -z;		/* (x<0)**odd = -(|x|**odd) */
+#endif
+			}
+		}
+		return z;
+	    }
+	}
+    
+    /* (x<0)**(non-int) is NaN */
+	if((((hx>>31)+1)|yisint)==0) return (x-x)/(x-x);
+
+    /* |y| is really_big */
+	if(iy>0x41e00000) { /* if |y| > 2**31 */
+	    if(iy>0x43f00000){	/* if |y| > 2**64, must o/uflow */
+		if(ix<=0x3fefffff) return (hy<0)? really_big*really_big:tiny*tiny;
+		if(ix>=0x3ff00000) return (hy>0)? really_big*really_big:tiny*tiny;
+	    }
+	/* over/underflow if x is not close to one */
+	    if(ix<0x3fefffff) return (hy<0)? really_big*really_big:tiny*tiny;
+	    if(ix>0x3ff00000) return (hy>0)? really_big*really_big:tiny*tiny;
+	/* now |1-x| is tiny <= 2**-20, suffice to compute 
+	   log(x) by x-x^2/2+x^3/3-x^4/4 */
+	    t = x-1;		/* t has 20 trailing zeros */
+	    w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
+	    u = ivln2_h*t;	/* ivln2_h has 21 sig. bits */
+	    v = t*ivln2_l-w*ivln2;
+	    t1 = u+v;
+            uz.d = t1;
+	    __LO(uz) = 0;
+            t1 = uz.d;
+	    t2 = v-(t1-u);
+	} else {
+	    double s_h,t_h;
+	    double s2,s_l,t_l;
+	    n = 0;
+	/* take care subnormal number */
+	    if(ix<0x00100000) 
+		{ax *= two53; n -= 53; uz.d = ax; ix = __HI(uz); }
+	    n  += ((ix)>>20)-0x3ff;
+	    j  = ix&0x000fffff;
+	/* determine interval */
+	    ix = j|0x3ff00000;		/* normalize ix */
+	    if(j<=0x3988E) k=0;		/* |x|<sqrt(3/2) */
+	    else if(j<0xBB67A) k=1;	/* |x|<sqrt(3)   */
+	    else {k=0;n+=1;ix -= 0x00100000;}
+            uz.d = ax;
+	    __HI(uz) = ix;
+            ax = uz.d;
+
+	/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
+	    u = ax-bp[k];		/* bp[0]=1.0, bp[1]=1.5 */
+	    v = one/(ax+bp[k]);
+	    s = u*v;
+	    s_h = s;
+            uz.d = s_h;
+	    __LO(uz) = 0;
+            s_h = uz.d;
+	/* t_h=ax+bp[k] High */
+	    t_h = zero;
+            uz.d = t_h;
+	    __HI(uz)=((ix>>1)|0x20000000)+0x00080000+(k<<18); 
+            t_h = uz.d;
+	    t_l = ax - (t_h-bp[k]);
+	    s_l = v*((u-s_h*t_h)-s_h*t_l);
+	/* compute log(ax) */
+	    s2 = s*s;
+	    r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
+	    r += s_l*(s_h+s);
+	    s2  = s_h*s_h;
+	    t_h = 3.0+s2+r;
+            uz.d = t_h;
+	    __LO(uz) = 0;
+            t_h = uz.d;
+	    t_l = r-((t_h-3.0)-s2);
+	/* u+v = s*(1+...) */
+	    u = s_h*t_h;
+	    v = s_l*t_h+t_l*s;
+	/* 2/(3log2)*(s+...) */
+	    p_h = u+v;
+            uz.d = p_h;
+	    __LO(uz) = 0;
+            p_h = uz.d;
+	    p_l = v-(p_h-u);
+	    z_h = cp_h*p_h;		/* cp_h+cp_l = 2/(3*log2) */
+	    z_l = cp_l*p_h+p_l*cp+dp_l[k];
+	/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
+	    t = (double)n;
+	    t1 = (((z_h+z_l)+dp_h[k])+t);
+            uz.d = t1;
+	    __LO(uz) = 0;
+            t1 = uz.d;
+	    t2 = z_l-(((t1-t)-dp_h[k])-z_h);
+	}
+
+	s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
+	if((((hx>>31)+1)|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */
+
+    /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
+	y1  = y;
+        uy.d = y1;
+	__LO(uy) = 0;
+        y1 = uy.d;
+	p_l = (y-y1)*t1+y*t2;
+	p_h = y1*t1;
+	z = p_l+p_h;
+        uz.d = z;
+	j = __HI(uz);
+	i = __LO(uz);
+
+	if (j>=0x40900000) {				/* z >= 1024 */
+	    if(((j-0x40900000)|i)!=0)			/* if z > 1024 */
+		return s*really_big*really_big;			/* overflow */
+	    else {
+		if(p_l+ovt>z-p_h) return s*really_big*really_big;	/* overflow */
+	    }
+	} else if((j&0x7fffffff)>=0x4090cc00 ) {	/* z <= -1075 */
+	    if(((j-0xc090cc00)|i)!=0) 		/* z < -1075 */
+		return s*tiny*tiny;		/* underflow */
+	    else {
+		if(p_l<=z-p_h) return s*tiny*tiny;	/* underflow */
+	    }
+	}
+    /*
+     * compute 2**(p_h+p_l)
+     */
+	i = j&0x7fffffff;
+	k = (i>>20)-0x3ff;
+	n = 0;
+	if(i>0x3fe00000) {		/* if |z| > 0.5, set n = [z+0.5] */
+	    n = j+(0x00100000>>(k+1));
+	    k = ((n&0x7fffffff)>>20)-0x3ff;	/* new k for n */
+	    t = zero;
+            uz.d = t;
+	    __HI(uz) = (n&~(0x000fffff>>k));
+            t = uz.d;
+	    n = ((n&0x000fffff)|0x00100000)>>(20-k);
+	    if(j<0) n = -n;
+	    p_h -= t;
+	} 
+	t = p_l+p_h;
+        uz.d = t;
+	__LO(uz) = 0;
+        t = uz.d;
+	u = t*lg2_h;
+	v = (p_l-(t-p_h))*lg2+t*lg2_l;
+	z = u+v;
+	w = v-(z-u);
+	t  = z*z;
+	t1  = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
+	r  = (z*t1)/(t1-two)-(w+z*w);
+	z  = one-(r-z);
+        uz.d = z;
+	j  = __HI(uz);
+	j += (n<<20);
+	if((j>>20)<=0) z = fd_scalbn(z,n);	/* subnormal output */
+	else { uz.d = z; __HI(uz) += (n<<20); z = uz.d; }
+	return s*z;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_rem_pio2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_rem_pio2.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,222 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_rem_pio2.c 1.4 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* __ieee754_rem_pio2(x,y)
+ * 
+ * return the remainder of x rem pi/2 in y[0]+y[1] 
+ * use __kernel_rem_pio2()
+ */
+
+#include "fdlibm.h"
+
+/*
+ * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi 
+ */
+#ifdef __STDC__
+static const int two_over_pi[] = {
+#else
+static int two_over_pi[] = {
+#endif
+0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 
+0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, 
+0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 
+0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, 
+0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, 
+0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, 
+0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, 
+0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 
+0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 
+0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 
+0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, 
+};
+
+#ifdef __STDC__
+static const int npio2_hw[] = {
+#else
+static int npio2_hw[] = {
+#endif
+0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
+0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
+0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
+0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
+0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
+0x404858EB, 0x404921FB,
+};
+
+/*
+ * invpio2:  53 bits of 2/pi
+ * pio2_1:   first  33 bit of pi/2
+ * pio2_1t:  pi/2 - pio2_1
+ * pio2_2:   second 33 bit of pi/2
+ * pio2_2t:  pi/2 - (pio2_1+pio2_2)
+ * pio2_3:   third  33 bit of pi/2
+ * pio2_3t:  pi/2 - (pio2_1+pio2_2+pio2_3)
+ */
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+zero =  0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
+half =  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+two24 =  1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+invpio2 =  6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
+pio2_1  =  1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
+pio2_1t =  6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
+pio2_2  =  6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
+pio2_2t =  2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
+pio2_3  =  2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
+pio2_3t =  8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
+
+#ifdef __STDC__
+	int __ieee754_rem_pio2(double x, double *y)
+#else
+	int __ieee754_rem_pio2(x,y)
+	double x,y[];
+#endif
+{
+        fd_twoints u, ux, uz;
+        double z = 0;
+	double w,t,r,fn;
+	double tx[3];
+	int e0,i,j,nx,n,ix,hx;
+
+        u.d = x;
+	hx = __HI(u);		/* high word of x */
+	ix = hx&0x7fffffff;
+	if(ix<=0x3fe921fb)   /* |x| ~<= pi/4 , no need for reduction */
+	    {y[0] = x; y[1] = 0; return 0;}
+	if(ix<0x4002d97c) {  /* |x| < 3pi/4, special case with n=+-1 */
+	    if(hx>0) { 
+		z = x - pio2_1;
+		if(ix!=0x3ff921fb) { 	/* 33+53 bit pi is good enough */
+		    y[0] = z - pio2_1t;
+		    y[1] = (z-y[0])-pio2_1t;
+		} else {		/* near pi/2, use 33+33+53 bit pi */
+		    z -= pio2_2;
+		    y[0] = z - pio2_2t;
+		    y[1] = (z-y[0])-pio2_2t;
+		}
+		return 1;
+	    } else {	/* negative x */
+		z = x + pio2_1;
+		if(ix!=0x3ff921fb) { 	/* 33+53 bit pi is good enough */
+		    y[0] = z + pio2_1t;
+		    y[1] = (z-y[0])+pio2_1t;
+		} else {		/* near pi/2, use 33+33+53 bit pi */
+		    z += pio2_2;
+		    y[0] = z + pio2_2t;
+		    y[1] = (z-y[0])+pio2_2t;
+		}
+		return -1;
+	    }
+	}
+	if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
+	    t  = fd_fabs(x);
+	    n  = (int) (t*invpio2+half);
+	    fn = (double)n;
+	    r  = t-fn*pio2_1;
+	    w  = fn*pio2_1t;	/* 1st round good to 85 bit */
+	    if(n<32&&ix!=npio2_hw[n-1]) {	
+		y[0] = r-w;	/* quick check no cancellation */
+	    } else {
+	        j  = ix>>20;
+	        y[0] = r-w;
+                u.d = y[0];
+	        i = j-(((__HI(u))>>20)&0x7ff);
+	        if(i>16) {  /* 2nd iteration needed, good to 118 */
+		    t  = r;
+		    w  = fn*pio2_2;	
+		    r  = t-w;
+		    w  = fn*pio2_2t-((t-r)-w);	
+		    y[0] = r-w;
+                    u.d = y[0];
+		    i = j-(((__HI(u))>>20)&0x7ff);
+		    if(i>49)  {	/* 3rd iteration need, 151 bits acc */
+		    	t  = r;	/* will cover all possible cases */
+		    	w  = fn*pio2_3;	
+		    	r  = t-w;
+		    	w  = fn*pio2_3t-((t-r)-w);	
+		    	y[0] = r-w;
+		    }
+		}
+	    }
+	    y[1] = (r-y[0])-w;
+	    if(hx<0) 	{y[0] = -y[0]; y[1] = -y[1]; return -n;}
+	    else	 return n;
+	}
+    /* 
+     * all other (large) arguments
+     */
+	if(ix>=0x7ff00000) {		/* x is inf or NaN */
+	    y[0]=y[1]=x-x; return 0;
+	}
+    /* set z = scalbn(|x|,ilogb(x)-23) */
+        ux.d = x; uz.d = z;
+	__LO(uz) = __LO(ux);
+        z = uz.d;
+	e0 	= (ix>>20)-1046;	/* e0 = ilogb(z)-23; */
+        uz.d = z;
+	__HI(uz) = ix - (e0<<20);
+        z = uz.d;
+	for(i=0;i<2;i++) {
+		tx[i] = (double)((int)(z));
+		z     = (z-tx[i])*two24;
+	}
+	tx[2] = z;
+	nx = 3;
+	while(tx[nx-1]==zero) nx--;	/* skip zero term */
+	n  =  __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
+	if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
+	return n;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_remainder.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_remainder.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,120 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_remainder.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_remainder(x,p)
+ * Return :                  
+ * 	returns  x REM p  =  x - [x/p]*p as if in infinite 
+ * 	precise arithmetic, where [x/p] is the (infinite bit) 
+ *	integer nearest x/p (in half way case choose the even one).
+ * Method : 
+ *	Based on fmod() return x-[x/p]chopped*p exactlp.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double zero = 0.0;
+#else
+static double zero = 0.0;
+#endif
+
+
+#ifdef __STDC__
+	double __ieee754_remainder(double x, double p)
+#else
+	double __ieee754_remainder(x,p)
+	double x,p;
+#endif
+{
+        fd_twoints u;
+	int hx,hp;
+	unsigned sx,lx,lp;
+	double p_half;
+
+        u.d = x;
+	hx = __HI(u);		/* high word of x */
+	lx = __LO(u);		/* low  word of x */
+        u.d = p;
+	hp = __HI(u);		/* high word of p */
+	lp = __LO(u);		/* low  word of p */
+	sx = hx&0x80000000;
+	hp &= 0x7fffffff;
+	hx &= 0x7fffffff;
+
+    /* purge off exception values */
+	if((hp|lp)==0) return (x*p)/(x*p); 	/* p = 0 */
+	if((hx>=0x7ff00000)||			/* x not finite */
+	  ((hp>=0x7ff00000)&&			/* p is NaN */
+	  (((hp-0x7ff00000)|lp)!=0)))
+	    return (x*p)/(x*p);
+
+
+	if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p);	/* now x < 2p */
+	if (((hx-hp)|(lx-lp))==0) return zero*x;
+	x  = fd_fabs(x);
+	p  = fd_fabs(p);
+	if (hp<0x00200000) {
+	    if(x+x>p) {
+		x-=p;
+		if(x+x>=p) x -= p;
+	    }
+	} else {
+	    p_half = 0.5*p;
+	    if(x>p_half) {
+		x-=p;
+		if(x>=p_half) x -= p;
+	    }
+	}
+        u.d = x;
+	__HI(u) ^= sx;
+        x = u.d;
+	return x;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_scalb.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_scalb.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,89 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_scalb.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * __ieee754_scalb(x, fn) is provide for
+ * passing various standard test suite. One 
+ * should use scalbn() instead.
+ */
+
+#include "fdlibm.h"
+
+#ifdef _SCALB_INT
+#ifdef __STDC__
+	double __ieee754_scalb(double x, int fn)
+#else
+	double __ieee754_scalb(x,fn)
+	double x; int fn;
+#endif
+#else
+#ifdef __STDC__
+	double __ieee754_scalb(double x, double fn)
+#else
+	double __ieee754_scalb(x,fn)
+	double x, fn;
+#endif
+#endif
+{
+#ifdef _SCALB_INT
+	return fd_scalbn(x,fn);
+#else
+	if (fd_isnan(x)||fd_isnan(fn)) return x*fn;
+	if (!fd_finite(fn)) {
+	    if(fn>0.0) return x*fn;
+	    else       return x/(-fn);
+	}
+	if (fd_rint(fn)!=fn) return (fn-fn)/(fn-fn);
+	if ( fn > 65000.0) return fd_scalbn(x, 65000);
+	if (-fn > 65000.0) return fd_scalbn(x,-65000);
+	return fd_scalbn(x,(int)fn);
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_sinh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_sinh.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,122 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)e_sinh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_sinh(x)
+ * Method : 
+ * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+ *	1. Replace x by |x| (sinh(-x) = -sinh(x)). 
+ *	2. 
+ *		                                    E + E/(E+1)
+ *	    0        <= x <= 22     :  sinh(x) := --------------, E=expm1(x)
+ *			       			        2
+ *
+ *	    22       <= x <= lnovft :  sinh(x) := exp(x)/2 
+ *	    lnovft   <= x <= ln2ovft:  sinh(x) := exp(x/2)/2 * exp(x/2)
+ *	    ln2ovft  <  x	    :  sinh(x) := x*shuge (overflow)
+ *
+ * Special cases:
+ *	sinh(x) is |x| if x is +INF, -INF, or NaN.
+ *	only sinh(0)=0 is exact for finite x.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double one = 1.0, shuge = 1.0e307;
+#else
+static double one = 1.0, shuge = 1.0e307;
+#endif
+
+#ifdef __STDC__
+	double __ieee754_sinh(double x)
+#else
+	double __ieee754_sinh(x)
+	double x;
+#endif
+{	
+        fd_twoints u;
+	double t,w,h;
+	int ix,jx;
+	unsigned lx;
+
+    /* High word of |x|. */
+        u.d = x;
+	jx = __HI(u);
+	ix = jx&0x7fffffff;
+
+    /* x is INF or NaN */
+	if(ix>=0x7ff00000) return x+x;	
+
+	h = 0.5;
+	if (jx<0) h = -h;
+    /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
+	if (ix < 0x40360000) {		/* |x|<22 */
+	    if (ix<0x3e300000) 		/* |x|<2**-28 */
+		if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
+	    t = fd_expm1(fd_fabs(x));
+	    if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one));
+	    return h*(t+t/(t+one));
+	}
+
+    /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
+	if (ix < 0x40862E42)  return h*__ieee754_exp(fd_fabs(x));
+
+    /* |x| in [log(maxdouble), overflowthresold] */
+	lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x);
+	if (ix<0x408633CE || (ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d)) {
+	    w = __ieee754_exp(0.5*fd_fabs(x));
+	    t = h*w;
+	    return t*w;
+	}
+
+    /* |x| > overflowthresold, sinh(x) overflow */
+	return x*shuge;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/e_sqrt.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/e_sqrt.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,497 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/* @(#)e_sqrt.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __ieee754_sqrt(x)
+ * Return correctly rounded sqrt.
+ *           ------------------------------------------
+ *	     |  Use the hardware sqrt if you have one |
+ *           ------------------------------------------
+ * Method: 
+ *   Bit by bit method using integer arithmetic. (Slow, but portable) 
+ *   1. Normalization
+ *	Scale x to y in [1,4) with even powers of 2: 
+ *	find an integer k such that  1 <= (y=x*2^(2k)) < 4, then
+ *		sqrt(y) = 2^k * sqrt(x)
+ *   2. Bit by bit computation
+ *	Let q  = sqrt(y) truncated to i bit after binary point (q = 1),
+ *	     i							 0
+ *                                     i+1         2
+ *	    s  = 2*q , and	y  =  2   * ( y - q  ).		(1)
+ *	     i      i            i                 i
+ *                                                        
+ *	To compute q    from q , one checks whether 
+ *		    i+1       i                       
+ *
+ *			      -(i+1) 2
+ *			(q + 2      ) <= y.			(2)
+ *     			  i
+ *							      -(i+1)
+ *	If (2) is false, then q   = q ; otherwise q   = q  + 2      .
+ *		 	       i+1   i             i+1   i
+ *
+ *	With some algebric manipulation, it is not difficult to see
+ *	that (2) is equivalent to 
+ *                             -(i+1)
+ *			s  +  2       <= y			(3)
+ *			 i                i
+ *
+ *	The advantage of (3) is that s  and y  can be computed by 
+ *				      i      i
+ *	the following recurrence formula:
+ *	    if (3) is false
+ *
+ *	    s     =  s  ,	y    = y   ;			(4)
+ *	     i+1      i		 i+1    i
+ *
+ *	    otherwise,
+ *                         -i                     -(i+1)
+ *	    s	  =  s  + 2  ,  y    = y  -  s  - 2  		(5)
+ *           i+1      i          i+1    i     i
+ *				
+ *	One may easily use induction to prove (4) and (5). 
+ *	Note. Since the left hand side of (3) contain only i+2 bits,
+ *	      it does not necessary to do a full (53-bit) comparison 
+ *	      in (3).
+ *   3. Final rounding
+ *	After generating the 53 bits result, we compute one more bit.
+ *	Together with the remainder, we can decide whether the
+ *	result is exact, bigger than 1/2ulp, or less than 1/2ulp
+ *	(it will never equal to 1/2ulp).
+ *	The rounding mode can be detected by checking whether
+ *	huge + tiny is equal to huge, and whether huge - tiny is
+ *	equal to huge for some floating point number "huge" and "tiny".
+ *		
+ * Special cases:
+ *	sqrt(+-0) = +-0 	... exact
+ *	sqrt(inf) = inf
+ *	sqrt(-ve) = NaN		... with invalid signal
+ *	sqrt(NaN) = NaN		... with invalid signal for signaling NaN
+ *
+ * Other methods : see the appended file at the end of the program below.
+ *---------------
+ */
+
+#include "fdlibm.h"
+
+#if defined(_MSC_VER)
+/* Microsoft Compiler */
+#pragma warning( disable : 4723 ) /* disables potential divide by 0 warning */
+#endif
+
+#ifdef __STDC__
+static	const double	one	= 1.0, tiny=1.0e-300;
+#else
+static	double	one	= 1.0, tiny=1.0e-300;
+#endif
+
+#ifdef __STDC__
+	double __ieee754_sqrt(double x)
+#else
+	double __ieee754_sqrt(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	double z;
+	int 	sign = (int)0x80000000; 
+	unsigned r,t1,s1,ix1,q1;
+	int ix0,s0,q,m,t,i;
+
+        u.d = x;
+	ix0 = __HI(u);			/* high word of x */
+	ix1 = __LO(u);		/* low word of x */
+
+    /* take care of Inf and NaN */
+	if((ix0&0x7ff00000)==0x7ff00000) {			
+	    return x*x+x;		/* sqrt(NaN)=NaN, sqrt(+inf)=+inf
+					   sqrt(-inf)=sNaN */
+	} 
+    /* take care of zero */
+	if(ix0<=0) {
+	    if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
+	    else if(ix0<0)
+		return (x-x)/(x-x);		/* sqrt(-ve) = sNaN */
+	}
+    /* normalize x */
+	m = (ix0>>20);
+	if(m==0) {				/* subnormal x */
+	    while(ix0==0) {
+		m -= 21;
+		ix0 |= (ix1>>11); ix1 <<= 21;
+	    }
+	    for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
+	    m -= i-1;
+	    ix0 |= (ix1>>(32-i));
+	    ix1 <<= i;
+	}
+	m -= 1023;	/* unbias exponent */
+	ix0 = (ix0&0x000fffff)|0x00100000;
+	if(m&1){	/* odd m, double x to make it even */
+	    ix0 += ix0 + ((ix1&sign)>>31);
+	    ix1 += ix1;
+	}
+	m >>= 1;	/* m = [m/2] */
+
+    /* generate sqrt(x) bit by bit */
+	ix0 += ix0 + ((ix1&sign)>>31);
+	ix1 += ix1;
+	q = q1 = s0 = s1 = 0;	/* [q,q1] = sqrt(x) */
+	r = 0x00200000;		/* r = moving bit from right to left */
+
+	while(r!=0) {
+	    t = s0+r; 
+	    if(t<=ix0) { 
+		s0   = t+r; 
+		ix0 -= t; 
+		q   += r; 
+	    } 
+	    ix0 += ix0 + ((ix1&sign)>>31);
+	    ix1 += ix1;
+	    r>>=1;
+	}
+
+	r = sign;
+	while(r!=0) {
+	    t1 = s1+r; 
+	    t  = s0;
+	    if((t<ix0)||((t==ix0)&&(t1<=ix1))) { 
+		s1  = t1+r;
+		if(((int)(t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
+		ix0 -= t;
+		if (ix1 < t1) ix0 -= 1;
+		ix1 -= t1;
+		q1  += r;
+	    }
+	    ix0 += ix0 + ((ix1&sign)>>31);
+	    ix1 += ix1;
+	    r>>=1;
+	}
+
+    /* use floating add to find out rounding direction */
+	if((ix0|ix1)!=0) {
+	    z = one-tiny; /* trigger inexact flag */
+	    if (z>=one) {
+	        z = one+tiny;
+	        if (q1==(unsigned)0xffffffff) { q1=0; q += 1;}
+		else if (z>one) {
+		    if (q1==(unsigned)0xfffffffe) q+=1;
+		    q1+=2; 
+		} else
+	            q1 += (q1&1);
+	    }
+	}
+	ix0 = (q>>1)+0x3fe00000;
+	ix1 =  q1>>1;
+	if ((q&1)==1) ix1 |= sign;
+	ix0 += (m <<20);
+        u.d = z;
+	__HI(u) = ix0;
+	__LO(u) = ix1;
+        z = u.d;
+	return z;
+}
+
+/*
+Other methods  (use floating-point arithmetic)
+-------------
+(This is a copy of a drafted paper by Prof W. Kahan 
+and K.C. Ng, written in May, 1986)
+
+	Two algorithms are given here to implement sqrt(x) 
+	(IEEE double precision arithmetic) in software.
+	Both supply sqrt(x) correctly rounded. The first algorithm (in
+	Section A) uses newton iterations and involves four divisions.
+	The second one uses reciproot iterations to avoid division, but
+	requires more multiplications. Both algorithms need the ability
+	to chop results of arithmetic operations instead of round them, 
+	and the INEXACT flag to indicate when an arithmetic operation
+	is executed exactly with no roundoff error, all part of the 
+	standard (IEEE 754-1985). The ability to perform shift, add,
+	subtract and logical AND operations upon 32-bit words is needed
+	too, though not part of the standard.
+
+A.  sqrt(x) by Newton Iteration
+
+   (1)	Initial approximation
+
+	Let x0 and x1 be the leading and the trailing 32-bit words of
+	a floating point number x (in IEEE double format) respectively 
+
+	    1    11		     52				  ...widths
+	   ------------------------------------------------------
+	x: |s|	  e     |	      f				|
+	   ------------------------------------------------------
+	      msb    lsb  msb				      lsb ...order
+
+ 
+	     ------------------------  	     ------------------------
+	x0:  |s|   e    |    f1     |	 x1: |          f2           |
+	     ------------------------  	     ------------------------
+
+	By performing shifts and subtracts on x0 and x1 (both regarded
+	as integers), we obtain an 8-bit approximation of sqrt(x) as
+	follows.
+
+		k  := (x0>>1) + 0x1ff80000;
+		y0 := k - T1[31&(k>>15)].	... y ~ sqrt(x) to 8 bits
+	Here k is a 32-bit integer and T1[] is an integer array containing
+	correction terms. Now magically the floating value of y (y's
+	leading 32-bit word is y0, the value of its trailing word is 0)
+	approximates sqrt(x) to almost 8-bit.
+
+	Value of T1:
+	static int T1[32]= {
+	0,	1024,	3062,	5746,	9193,	13348,	18162,	23592,
+	29598,	36145,	43202,	50740,	58733,	67158,	75992,	85215,
+	83599,	71378,	60428,	50647,	41945,	34246,	27478,	21581,
+	16499,	12183,	8588,	5674,	3403,	1742,	661,	130,};
+
+    (2)	Iterative refinement
+
+	Apply Heron's rule three times to y, we have y approximates 
+	sqrt(x) to within 1 ulp (Unit in the Last Place):
+
+		y := (y+x/y)/2		... almost 17 sig. bits
+		y := (y+x/y)/2		... almost 35 sig. bits
+		y := y-(y-x/y)/2	... within 1 ulp
+
+
+	Remark 1.
+	    Another way to improve y to within 1 ulp is:
+
+		y := (y+x/y)		... almost 17 sig. bits to 2*sqrt(x)
+		y := y - 0x00100006	... almost 18 sig. bits to sqrt(x)
+
+				2
+			    (x-y )*y
+		y := y + 2* ----------	...within 1 ulp
+			       2
+			     3y  + x
+
+
+	This formula has one division fewer than the one above; however,
+	it requires more multiplications and additions. Also x must be
+	scaled in advance to avoid spurious overflow in evaluating the
+	expression 3y*y+x. Hence it is not recommended uless division
+	is slow. If division is very slow, then one should use the 
+	reciproot algorithm given in section B.
+
+    (3) Final adjustment
+
+	By twiddling y's last bit it is possible to force y to be 
+	correctly rounded according to the prevailing rounding mode
+	as follows. Let r and i be copies of the rounding mode and
+	inexact flag before entering the square root program. Also we
+	use the expression y+-ulp for the next representable floating
+	numbers (up and down) of y. Note that y+-ulp = either fixed
+	point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+	mode.
+
+		I := FALSE;	... reset INEXACT flag I
+		R := RZ;	... set rounding mode to round-toward-zero
+		z := x/y;	... chopped quotient, possibly inexact
+		If(not I) then {	... if the quotient is exact
+		    if(z=y) {
+		        I := i;	 ... restore inexact flag
+		        R := r;  ... restore rounded mode
+		        return sqrt(x):=y.
+		    } else {
+			z := z - ulp;	... special rounding
+		    }
+		}
+		i := TRUE;		... sqrt(x) is inexact
+		If (r=RN) then z=z+ulp	... rounded-to-nearest
+		If (r=RP) then {	... round-toward-+inf
+		    y = y+ulp; z=z+ulp;
+		}
+		y := y+z;		... chopped sum
+		y0:=y0-0x00100000;	... y := y/2 is correctly rounded.
+	        I := i;	 		... restore inexact flag
+	        R := r;  		... restore rounded mode
+	        return sqrt(x):=y.
+		    
+    (4)	Special cases
+
+	Square root of +inf, +-0, or NaN is itself;
+	Square root of a negative number is NaN with invalid signal.
+
+
+B.  sqrt(x) by Reciproot Iteration
+
+   (1)	Initial approximation
+
+	Let x0 and x1 be the leading and the trailing 32-bit words of
+	a floating point number x (in IEEE double format) respectively
+	(see section A). By performing shifs and subtracts on x0 and y0,
+	we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
+
+	    k := 0x5fe80000 - (x0>>1);
+	    y0:= k - T2[63&(k>>14)].	... y ~ 1/sqrt(x) to 7.8 bits
+
+	Here k is a 32-bit integer and T2[] is an integer array 
+	containing correction terms. Now magically the floating
+	value of y (y's leading 32-bit word is y0, the value of
+	its trailing word y1 is set to zero) approximates 1/sqrt(x)
+	to almost 7.8-bit.
+
+	Value of T2:
+	static int T2[64]= {
+	0x1500,	0x2ef8,	0x4d67,	0x6b02,	0x87be,	0xa395,	0xbe7a,	0xd866,
+	0xf14a,	0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
+	0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
+	0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
+	0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
+	0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
+	0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
+	0x1527f,0x1334a,0x11051,0xe951,	0xbe01,	0x8e0d,	0x5924,	0x1edd,};
+
+    (2)	Iterative refinement
+
+	Apply Reciproot iteration three times to y and multiply the
+	result by x to get an approximation z that matches sqrt(x)
+	to about 1 ulp. To be exact, we will have 
+		-1ulp < sqrt(x)-z<1.0625ulp.
+	
+	... set rounding mode to Round-to-nearest
+	   y := y*(1.5-0.5*x*y*y)	... almost 15 sig. bits to 1/sqrt(x)
+	   y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
+	... special arrangement for better accuracy
+	   z := x*y			... 29 bits to sqrt(x), with z*y<1
+	   z := z + 0.5*z*(1-z*y)	... about 1 ulp to sqrt(x)
+
+	Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
+	(a) the term z*y in the final iteration is always less than 1; 
+	(b) the error in the final result is biased upward so that
+		-1 ulp < sqrt(x) - z < 1.0625 ulp
+	    instead of |sqrt(x)-z|<1.03125ulp.
+
+    (3)	Final adjustment
+
+	By twiddling y's last bit it is possible to force y to be 
+	correctly rounded according to the prevailing rounding mode
+	as follows. Let r and i be copies of the rounding mode and
+	inexact flag before entering the square root program. Also we
+	use the expression y+-ulp for the next representable floating
+	numbers (up and down) of y. Note that y+-ulp = either fixed
+	point y+-1, or multiply y by nextafter(1,+-inf) in chopped
+	mode.
+
+	R := RZ;		... set rounding mode to round-toward-zero
+	switch(r) {
+	    case RN:		... round-to-nearest
+	       if(x<= z*(z-ulp)...chopped) z = z - ulp; else
+	       if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
+	       break;
+	    case RZ:case RM:	... round-to-zero or round-to--inf
+	       R:=RP;		... reset rounding mod to round-to-+inf
+	       if(x<z*z ... rounded up) z = z - ulp; else
+	       if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
+	       break;
+	    case RP:		... round-to-+inf
+	       if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
+	       if(x>z*z ...chopped) z = z+ulp;
+	       break;
+	}
+
+	Remark 3. The above comparisons can be done in fixed point. For
+	example, to compare x and w=z*z chopped, it suffices to compare
+	x1 and w1 (the trailing parts of x and w), regarding them as
+	two's complement integers.
+
+	...Is z an exact square root?
+	To determine whether z is an exact square root of x, let z1 be the
+	trailing part of z, and also let x0 and x1 be the leading and
+	trailing parts of x.
+
+	If ((z1&0x03ffffff)!=0)	... not exact if trailing 26 bits of z!=0
+	    I := 1;		... Raise Inexact flag: z is not exact
+	else {
+	    j := 1 - [(x0>>20)&1]	... j = logb(x) mod 2
+	    k := z1 >> 26;		... get z's 25-th and 26-th 
+					    fraction bits
+	    I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
+	}
+	R:= r		... restore rounded mode
+	return sqrt(x):=z.
+
+	If multiplication is cheaper then the foregoing red tape, the 
+	Inexact flag can be evaluated by
+
+	    I := i;
+	    I := (z*z!=x) or I.
+
+	Note that z*z can overwrite I; this value must be sensed if it is 
+	True.
+
+	Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
+	zero.
+
+		    --------------------
+		z1: |        f2        | 
+		    --------------------
+		bit 31		   bit 0
+
+	Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
+	or even of logb(x) have the following relations:
+
+	-------------------------------------------------
+	bit 27,26 of z1		bit 1,0 of x1	logb(x)
+	-------------------------------------------------
+	00			00		odd and even
+	01			01		even
+	10			10		odd
+	10			00		even
+	11			01		even
+	-------------------------------------------------
+
+    (4)	Special cases (see (4) of Section A).	
+ 
+ */
+ 

Added: freeswitch/trunk/libs/js/src/fdlibm/fdlibm.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/fdlibm.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,364 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)fdlibm.h 1.5 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+#ifdef OSSP
+/* select functionality */
+#define _IEEE_LIBM
+/* avoid namespace pollution */
+#define __ieee754_acos          js___ieee754_acos
+#define __ieee754_acosh         js___ieee754_acosh
+#define __ieee754_asin          js___ieee754_asin
+#define __ieee754_atan2         js___ieee754_atan2
+#define __ieee754_atanh         js___ieee754_atanh
+#define __ieee754_cosh          js___ieee754_cosh
+#define __ieee754_exp           js___ieee754_exp
+#define __ieee754_fmod          js___ieee754_fmod
+#define __ieee754_gamma         js___ieee754_gamma
+#define __ieee754_gamma_r       js___ieee754_gamma_r
+#define __ieee754_hypot         js___ieee754_hypot
+#define __ieee754_j0            js___ieee754_j0
+#define __ieee754_j1            js___ieee754_j1
+#define __ieee754_jn            js___ieee754_jn
+#define __ieee754_lgamma        js___ieee754_lgamma
+#define __ieee754_lgamma_r      js___ieee754_lgamma_r
+#define __ieee754_log           js___ieee754_log
+#define __ieee754_log10         js___ieee754_log10
+#define __ieee754_pow           js___ieee754_pow
+#define __ieee754_rem_pio2      js___ieee754_rem_pio2
+#define __ieee754_remainder     js___ieee754_remainder
+#define __ieee754_scalb         js___ieee754_scalb
+#define __ieee754_sinh          js___ieee754_sinh
+#define __ieee754_sqrt          js___ieee754_sqrt
+#define __ieee754_y0            js___ieee754_y0
+#define __ieee754_y1            js___ieee754_y1
+#define __ieee754_yn            js___ieee754_yn
+#define __kernel_cos            js___kernel_cos
+#define __kernel_rem_pio2       js___kernel_rem_pio2
+#define __kernel_sin            js___kernel_sin
+#define __kernel_standard       js___kernel_standard
+#define __kernel_tan            js___kernel_tan
+#define fd_acos                 js_fd_acos
+#define fd_acosh                js_fd_acosh
+#define fd_asin                 js_fd_asin
+#define fd_asinh                js_fd_asinh
+#define fd_atan                 js_fd_atan
+#define fd_atan2                js_fd_atan2
+#define fd_atanh                js_fd_atanh
+#define fd_cbrt                 js_fd_cbrt
+#define fd_ceil                 js_fd_ceil
+#define fd_copysign             js_fd_copysign
+#define fd_cos                  js_fd_cos
+#define fd_cosh                 js_fd_cosh
+#define fd_erf                  js_fd_erf
+#define fd_erfc                 js_fd_erfc
+#define fd_exp                  js_fd_exp
+#define fd_expm1                js_fd_expm1
+#define fd_fabs                 js_fd_fabs
+#define fd_finite               js_fd_finite
+#define fd_floor                js_fd_floor
+#define fd_fmod                 js_fd_fmod
+#define fd_frexp                js_fd_frexp
+#define fd_gamma                js_fd_gamma
+#define fd_hypot                js_fd_hypot
+#define fd_ilogb                js_fd_ilogb
+#define fd_isnan                js_fd_isnan
+#define fd_j0                   js_fd_j0
+#define fd_j1                   js_fd_j1
+#define fd_jn                   js_fd_jn
+#define fd_ldexp                js_fd_ldexp
+#define fd_lgamma               js_fd_lgamma
+#define fd_log                  js_fd_log
+#define fd_log10                js_fd_log10
+#define fd_log1p                js_fd_log1p
+#define fd_logb                 js_fd_logb
+#define fd_matherr              js_fd_matherr
+#define fd_modf                 js_fd_modf
+#define fd_nextafter            js_fd_nextafter
+#define fd_pow                  js_fd_pow
+#define fd_remainder            js_fd_remainder
+#define fd_rint                 js_fd_rint
+#define fd_scalb                js_fd_scalb
+#define fd_scalbn               js_fd_scalbn
+#define fd_sin                  js_fd_sin
+#define fd_sinh                 js_fd_sinh
+#define fd_sqrt                 js_fd_sqrt
+#define fd_tan                  js_fd_tan
+#define fd_tanh                 js_fd_tanh
+#define fd_y0                   js_fd_y0
+#define fd_y1                   js_fd_y1
+#define fd_yn                   js_fd_yn
+#define gamma_r                 js_gamma_r
+#define lgamma_r                js_lgamma_r
+#define significand             js_significand
+#endif
+
+/* Modified defines start here.. */
+#undef __LITTLE_ENDIAN
+
+#ifdef _WIN32
+#define huge myhuge
+#define __LITTLE_ENDIAN
+#endif
+
+#ifdef XP_OS2
+#define __LITTLE_ENDIAN
+#endif
+
+#if defined(linux) && (defined(__i386__) || defined(__x86_64__) || defined(__ia64))
+#define __LITTLE_ENDIAN
+#endif
+
+/* End here. The rest is the standard file. */
+
+#ifdef SOLARIS	/* special setup for Sun test regime */
+#if defined(i386) || defined(i486) || \
+	defined(intel) || defined(x86) || defined(i86pc)
+#define __LITTLE_ENDIAN
+#endif
+#endif
+
+typedef union {
+#ifdef __LITTLE_ENDIAN
+    struct { int lo, hi; } ints;
+#else
+    struct { int hi, lo; } ints;
+#endif
+    double d;
+} fd_twoints;
+
+#define __HI(x) x.ints.hi
+#define __LO(x) x.ints.lo
+
+#undef __P
+#ifdef __STDC__
+#define	__P(p)	p
+#else
+#define	__P(p)	()
+#endif
+
+/*
+ * ANSI/POSIX
+ */
+
+extern int signgam;
+
+#define	MAXFLOAT	((float)3.40282346638528860e+38)
+
+enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix};
+
+#define _LIB_VERSION_TYPE enum fdversion
+#define _LIB_VERSION _fdlib_version  
+
+/* if global variable _LIB_VERSION is not desirable, one may 
+ * change the following to be a constant by: 
+ *	#define _LIB_VERSION_TYPE const enum version
+ * In that case, after one initializes the value _LIB_VERSION (see
+ * s_lib_version.c) during compile time, it cannot be modified
+ * in the middle of a program
+ */ 
+extern  _LIB_VERSION_TYPE  _LIB_VERSION;
+
+#define _IEEE_  fdlibm_ieee
+#define _SVID_  fdlibm_svid
+#define _XOPEN_ fdlibm_xopen
+#define _POSIX_ fdlibm_posix
+
+struct exception {
+	int type;
+	char *name;
+	double arg1;
+	double arg2;
+	double retval;
+};
+
+#define	HUGE		MAXFLOAT
+
+/* 
+ * set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
+ * (one may replace the following line by "#include <values.h>")
+ */
+
+#define X_TLOSS		1.41484755040568800000e+16 
+
+#define	DOMAIN		1
+#define	SING		2
+#define	OVERFLOW	3
+#define	UNDERFLOW	4
+#define	TLOSS		5
+#define	PLOSS		6
+
+/*
+ * ANSI/POSIX
+ */
+
+extern double fd_acos __P((double));
+extern double fd_asin __P((double));
+extern double fd_atan __P((double));
+extern double fd_atan2 __P((double, double));
+extern double fd_cos __P((double));
+extern double fd_sin __P((double));
+extern double fd_tan __P((double));
+ 
+extern double fd_cosh __P((double));
+extern double fd_sinh __P((double));
+extern double fd_tanh __P((double));
+
+extern double fd_exp __P((double));
+extern double fd_frexp __P((double, int *));
+extern double fd_ldexp __P((double, int));
+extern double fd_log __P((double));
+extern double fd_log10 __P((double));
+extern double fd_modf __P((double, double *));
+
+extern double fd_pow __P((double, double));
+extern double fd_sqrt __P((double));
+
+extern double fd_ceil __P((double));
+extern double fd_fabs __P((double));
+extern double fd_floor __P((double));
+extern double fd_fmod __P((double, double));
+
+extern double fd_erf __P((double));
+extern double fd_erfc __P((double));
+extern double fd_gamma __P((double));
+extern double fd_hypot __P((double, double));
+extern int fd_isnan __P((double));
+extern int fd_finite __P((double));
+extern double fd_j0 __P((double));
+extern double fd_j1 __P((double));
+extern double fd_jn __P((int, double));
+extern double fd_lgamma __P((double));
+extern double fd_y0 __P((double));
+extern double fd_y1 __P((double));
+extern double fd_yn __P((int, double));
+
+extern double fd_acosh __P((double));
+extern double fd_asinh __P((double));
+extern double fd_atanh __P((double));
+extern double fd_cbrt __P((double));
+extern double fd_logb __P((double));
+extern double fd_nextafter __P((double, double));
+extern double fd_remainder __P((double, double));
+#ifdef _SCALB_INT
+extern double fd_scalb __P((double, int));
+#else
+extern double fd_scalb __P((double, double));
+#endif
+
+extern int fd_matherr __P((struct exception *));
+
+/*
+ * IEEE Test Vector
+ */
+extern double significand __P((double));
+
+/*
+ * Functions callable from C, intended to support IEEE arithmetic.
+ */
+extern double fd_copysign __P((double, double));
+extern int fd_ilogb __P((double));
+extern double fd_rint __P((double));
+extern double fd_scalbn __P((double, int));
+
+/*
+ * BSD math library entry points
+ */
+extern double fd_expm1 __P((double));
+extern double fd_log1p __P((double));
+
+/*
+ * Reentrant version of gamma & lgamma; passes signgam back by reference
+ * as the second argument; user must allocate space for signgam.
+ */
+#ifdef _REENTRANT
+extern double gamma_r __P((double, int *));
+extern double lgamma_r __P((double, int *));
+#endif	/* _REENTRANT */
+
+/* ieee style elementary functions */
+extern double __ieee754_sqrt __P((double));			
+extern double __ieee754_acos __P((double));			
+extern double __ieee754_acosh __P((double));			
+extern double __ieee754_log __P((double));			
+extern double __ieee754_atanh __P((double));			
+extern double __ieee754_asin __P((double));			
+extern double __ieee754_atan2 __P((double,double));			
+extern double __ieee754_exp __P((double));
+extern double __ieee754_cosh __P((double));
+extern double __ieee754_fmod __P((double,double));
+extern double __ieee754_pow __P((double,double));
+extern double __ieee754_lgamma_r __P((double,int *));
+extern double __ieee754_gamma_r __P((double,int *));
+extern double __ieee754_lgamma __P((double));
+extern double __ieee754_gamma __P((double));
+extern double __ieee754_log10 __P((double));
+extern double __ieee754_sinh __P((double));
+extern double __ieee754_hypot __P((double,double));
+extern double __ieee754_j0 __P((double));
+extern double __ieee754_j1 __P((double));
+extern double __ieee754_y0 __P((double));
+extern double __ieee754_y1 __P((double));
+extern double __ieee754_jn __P((int,double));
+extern double __ieee754_yn __P((int,double));
+extern double __ieee754_remainder __P((double,double));
+extern int    __ieee754_rem_pio2 __P((double,double*));
+#ifdef _SCALB_INT
+extern double __ieee754_scalb __P((double,int));
+#else
+extern double __ieee754_scalb __P((double,double));
+#endif
+
+/* fdlibm kernel function */
+extern double __kernel_standard __P((double,double,int,int*));
+extern double __kernel_sin __P((double,double,int));
+extern double __kernel_cos __P((double,double));
+extern double __kernel_tan __P((double,double,int));
+extern int    __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*));

Added: freeswitch/trunk/libs/js/src/fdlibm/k_cos.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/k_cos.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,135 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)k_cos.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * __kernel_cos( x,  y )
+ * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x. 
+ *
+ * Algorithm
+ *	1. Since cos(-x) = cos(x), we need only to consider positive x.
+ *	2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
+ *	3. cos(x) is approximated by a polynomial of degree 14 on
+ *	   [0,pi/4]
+ *		  	                 4            14
+ *	   	cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
+ *	   where the remez error is
+ *	
+ * 	|              2     4     6     8     10    12     14 |     -58
+ * 	|cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  )| <= 2
+ * 	|    					               | 
+ * 
+ * 	               4     6     8     10    12     14 
+ *	4. let r = C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  , then
+ *	       cos(x) = 1 - x*x/2 + r
+ *	   since cos(x+y) ~ cos(x) - sin(x)*y 
+ *			  ~ cos(x) - x*y,
+ *	   a correction term is necessary in cos(x) and hence
+ *		cos(x+y) = 1 - (x*x/2 - (r - x*y))
+ *	   For better accuracy when x > 0.3, let qx = |x|/4 with
+ *	   the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
+ *	   Then
+ *		cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)).
+ *	   Note that 1-qx and (x*x/2-qx) is EXACT here, and the
+ *	   magnitude of the latter is at least a quarter of x*x/2,
+ *	   thus, reducing the rounding error in the subtraction.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+C1  =  4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
+C2  = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
+C3  =  2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
+C4  = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
+C5  =  2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
+C6  = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
+
+#ifdef __STDC__
+	double __kernel_cos(double x, double y)
+#else
+	double __kernel_cos(x, y)
+	double x,y;
+#endif
+{
+        fd_twoints u;
+        double qx = 0;
+	double a,hz,z,r;
+	int ix;
+        u.d = x;
+	ix = __HI(u)&0x7fffffff;	/* ix = |x|'s high word*/
+	if(ix<0x3e400000) {			/* if x < 2**27 */
+	    if(((int)x)==0) return one;		/* generate inexact */
+	}
+	z  = x*x;
+	r  = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
+	if(ix < 0x3FD33333) 			/* if |x| < 0.3 */ 
+	    return one - (0.5*z - (z*r - x*y));
+	else {
+	    if(ix > 0x3fe90000) {		/* x > 0.78125 */
+		qx = 0.28125;
+	    } else {
+                u.d = qx;
+	        __HI(u) = ix-0x00200000;	/* x/4 */
+	        __LO(u) = 0;
+                qx = u.d;
+	    }
+	    hz = 0.5*z-qx;
+	    a  = one-qx;
+	    return a - (hz - (z*r-x*y));
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/k_rem_pio2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/k_rem_pio2.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,354 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)k_rem_pio2.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
+ * double x[],y[]; int e0,nx,prec; int ipio2[];
+ * 
+ * __kernel_rem_pio2 return the last three digits of N with 
+ *		y = x - N*pi/2
+ * so that |y| < pi/2.
+ *
+ * The method is to compute the integer (mod 8) and fraction parts of 
+ * (2/pi)*x without doing the full multiplication. In general we
+ * skip the part of the product that are known to be a huge integer (
+ * more accurately, = 0 mod 8 ). Thus the number of operations are
+ * independent of the exponent of the input.
+ *
+ * (2/pi) is represented by an array of 24-bit integers in ipio2[].
+ *
+ * Input parameters:
+ * 	x[]	The input value (must be positive) is broken into nx 
+ *		pieces of 24-bit integers in double precision format.
+ *		x[i] will be the i-th 24 bit of x. The scaled exponent 
+ *		of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 
+ *		match x's up to 24 bits.
+ *
+ *		Example of breaking a double positive z into x[0]+x[1]+x[2]:
+ *			e0 = ilogb(z)-23
+ *			z  = scalbn(z,-e0)
+ *		for i = 0,1,2
+ *			x[i] = floor(z)
+ *			z    = (z-x[i])*2**24
+ *
+ *
+ *	y[]	ouput result in an array of double precision numbers.
+ *		The dimension of y[] is:
+ *			24-bit  precision	1
+ *			53-bit  precision	2
+ *			64-bit  precision	2
+ *			113-bit precision	3
+ *		The actual value is the sum of them. Thus for 113-bit
+ *		precison, one may have to do something like:
+ *
+ *		long double t,w,r_head, r_tail;
+ *		t = (long double)y[2] + (long double)y[1];
+ *		w = (long double)y[0];
+ *		r_head = t+w;
+ *		r_tail = w - (r_head - t);
+ *
+ *	e0	The exponent of x[0]
+ *
+ *	nx	dimension of x[]
+ *
+ *  	prec	an integer indicating the precision:
+ *			0	24  bits (single)
+ *			1	53  bits (double)
+ *			2	64  bits (extended)
+ *			3	113 bits (quad)
+ *
+ *	ipio2[]
+ *		integer array, contains the (24*i)-th to (24*i+23)-th 
+ *		bit of 2/pi after binary point. The corresponding 
+ *		floating value is
+ *
+ *			ipio2[i] * 2^(-24(i+1)).
+ *
+ * External function:
+ *	double scalbn(), floor();
+ *
+ *
+ * Here is the description of some local variables:
+ *
+ * 	jk	jk+1 is the initial number of terms of ipio2[] needed
+ *		in the computation. The recommended value is 2,3,4,
+ *		6 for single, double, extended,and quad.
+ *
+ * 	jz	local integer variable indicating the number of 
+ *		terms of ipio2[] used. 
+ *
+ *	jx	nx - 1
+ *
+ *	jv	index for pointing to the suitable ipio2[] for the
+ *		computation. In general, we want
+ *			( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
+ *		is an integer. Thus
+ *			e0-3-24*jv >= 0 or (e0-3)/24 >= jv
+ *		Hence jv = max(0,(e0-3)/24).
+ *
+ *	jp	jp+1 is the number of terms in PIo2[] needed, jp = jk.
+ *
+ * 	q[]	double array with integral value, representing the
+ *		24-bits chunk of the product of x and 2/pi.
+ *
+ *	q0	the corresponding exponent of q[0]. Note that the
+ *		exponent for q[i] would be q0-24*i.
+ *
+ *	PIo2[]	double precision array, obtained by cutting pi/2
+ *		into 24 bits chunks. 
+ *
+ *	f[]	ipio2[] in floating point 
+ *
+ *	iq[]	integer array by breaking up q[] in 24-bits chunk.
+ *
+ *	fq[]	final product of x*(2/pi) in fq[0],..,fq[jk]
+ *
+ *	ih	integer. If >0 it indicates q[] is >= 0.5, hence
+ *		it also indicates the *sign* of the result.
+ *
+ */
+
+
+/*
+ * Constants:
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough 
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
+#else
+static int init_jk[] = {2,3,4,6}; 
+#endif
+
+#ifdef __STDC__
+static const double PIo2[] = {
+#else
+static double PIo2[] = {
+#endif
+  1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
+  7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
+  5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
+  3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
+  1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
+  1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
+  2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
+  2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
+};
+
+#ifdef __STDC__
+static const double			
+#else
+static double			
+#endif
+zero   = 0.0,
+one    = 1.0,
+two24   =  1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
+twon24  =  5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
+
+#ifdef __STDC__
+	int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2) 
+#else
+	int __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) 	
+	double x[], y[]; int e0,nx,prec; int ipio2[];
+#endif
+{
+	int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
+	double z,fw,f[20],fq[20],q[20];
+
+    /* initialize jk*/
+	jk = init_jk[prec];
+	jp = jk;
+
+    /* determine jx,jv,q0, note that 3>q0 */
+	jx =  nx-1;
+	jv = (e0-3)/24; if(jv<0) jv=0;
+	q0 =  e0-24*(jv+1);
+
+    /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
+	j = jv-jx; m = jx+jk;
+	for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
+
+    /* compute q[0],q[1],...q[jk] */
+	for (i=0;i<=jk;i++) {
+	    for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
+	}
+
+	jz = jk;
+recompute:
+    /* distill q[] into iq[] reversingly */
+	for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
+	    fw    =  (double)((int)(twon24* z));
+	    iq[i] =  (int)(z-two24*fw);
+	    z     =  q[j-1]+fw;
+	}
+
+    /* compute n */
+	z  = fd_scalbn(z,q0);		/* actual value of z */
+	z -= 8.0*fd_floor(z*0.125);		/* trim off integer >= 8 */
+	n  = (int) z;
+	z -= (double)n;
+	ih = 0;
+	if(q0>0) {	/* need iq[jz-1] to determine n */
+	    i  = (iq[jz-1]>>(24-q0)); n += i;
+	    iq[jz-1] -= i<<(24-q0);
+	    ih = iq[jz-1]>>(23-q0);
+	} 
+	else if(q0==0) ih = iq[jz-1]>>23;
+	else if(z>=0.5) ih=2;
+
+	if(ih>0) {	/* q > 0.5 */
+	    n += 1; carry = 0;
+	    for(i=0;i<jz ;i++) {	/* compute 1-q */
+		j = iq[i];
+		if(carry==0) {
+		    if(j!=0) {
+			carry = 1; iq[i] = 0x1000000- j;
+		    }
+		} else  iq[i] = 0xffffff - j;
+	    }
+	    if(q0>0) {		/* rare case: chance is 1 in 12 */
+	        switch(q0) {
+	        case 1:
+	    	   iq[jz-1] &= 0x7fffff; break;
+	    	case 2:
+	    	   iq[jz-1] &= 0x3fffff; break;
+	        }
+	    }
+	    if(ih==2) {
+		z = one - z;
+		if(carry!=0) z -= fd_scalbn(one,q0);
+	    }
+	}
+
+    /* check if recomputation is needed */
+	if(z==zero) {
+	    j = 0;
+	    for (i=jz-1;i>=jk;i--) j |= iq[i];
+	    if(j==0) { /* need recomputation */
+		for(k=1;iq[jk-k]==0;k++);   /* k = no. of terms needed */
+
+		for(i=jz+1;i<=jz+k;i++) {   /* add q[jz+1] to q[jz+k] */
+		    f[jx+i] = (double) ipio2[jv+i];
+		    for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
+		    q[i] = fw;
+		}
+		jz += k;
+		goto recompute;
+	    }
+	}
+
+    /* chop off zero terms */
+	if(z==0.0) {
+	    jz -= 1; q0 -= 24;
+	    while(iq[jz]==0) { jz--; q0-=24;}
+	} else { /* break z into 24-bit if necessary */
+	    z = fd_scalbn(z,-q0);
+	    if(z>=two24) { 
+		fw = (double)((int)(twon24*z));
+		iq[jz] = (int)(z-two24*fw);
+		jz += 1; q0 += 24;
+		iq[jz] = (int) fw;
+	    } else iq[jz] = (int) z ;
+	}
+
+    /* convert integer "bit" chunk to floating-point value */
+	fw = fd_scalbn(one,q0);
+	for(i=jz;i>=0;i--) {
+	    q[i] = fw*(double)iq[i]; fw*=twon24;
+	}
+
+    /* compute PIo2[0,...,jp]*q[jz,...,0] */
+	for(i=jz;i>=0;i--) {
+	    for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
+	    fq[jz-i] = fw;
+	}
+
+    /* compress fq[] into y[] */
+	switch(prec) {
+	    case 0:
+		fw = 0.0;
+		for (i=jz;i>=0;i--) fw += fq[i];
+		y[0] = (ih==0)? fw: -fw; 
+		break;
+	    case 1:
+	    case 2:
+		fw = 0.0;
+		for (i=jz;i>=0;i--) fw += fq[i]; 
+		y[0] = (ih==0)? fw: -fw; 
+		fw = fq[0]-fw;
+		for (i=1;i<=jz;i++) fw += fq[i];
+		y[1] = (ih==0)? fw: -fw; 
+		break;
+	    case 3:	/* painful */
+		for (i=jz;i>0;i--) {
+		    fw      = fq[i-1]+fq[i]; 
+		    fq[i]  += fq[i-1]-fw;
+		    fq[i-1] = fw;
+		}
+		for (i=jz;i>1;i--) {
+		    fw      = fq[i-1]+fq[i]; 
+		    fq[i]  += fq[i-1]-fw;
+		    fq[i-1] = fw;
+		}
+		for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; 
+		if(ih==0) {
+		    y[0] =  fq[0]; y[1] =  fq[1]; y[2] =  fw;
+		} else {
+		    y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
+		}
+	}
+	return n&7;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/k_sin.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/k_sin.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,114 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)k_sin.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __kernel_sin( x, y, iy)
+ * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). 
+ *
+ * Algorithm
+ *	1. Since sin(-x) = -sin(x), we need only to consider positive x. 
+ *	2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0.
+ *	3. sin(x) is approximated by a polynomial of degree 13 on
+ *	   [0,pi/4]
+ *		  	         3            13
+ *	   	sin(x) ~ x + S1*x + ... + S6*x
+ *	   where
+ *	
+ * 	|sin(x)         2     4     6     8     10     12  |     -58
+ * 	|----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x  +S6*x   )| <= 2
+ * 	|  x 					           | 
+ * 
+ *	4. sin(x+y) = sin(x) + sin'(x')*y
+ *		    ~ sin(x) + (1-x*x/2)*y
+ *	   For better accuracy, let 
+ *		     3      2      2      2      2
+ *		r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
+ *	   then                   3    2
+ *		sin(x) = x + (S1*x + (x *(r-y/2)+y))
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+half =  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+S1  = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
+S2  =  8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
+S3  = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
+S4  =  2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
+S5  = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
+S6  =  1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
+
+#ifdef __STDC__
+	double __kernel_sin(double x, double y, int iy)
+#else
+	double __kernel_sin(x, y, iy)
+	double x,y; int iy;		/* iy=0 if y is zero */
+#endif
+{
+        fd_twoints u;
+	double z,r,v;
+	int ix;
+        u.d = x;
+	ix = __HI(u)&0x7fffffff;	/* high word of x */
+	if(ix<0x3e400000)			/* |x| < 2**-27 */
+	   {if((int)x==0) return x;}		/* generate inexact */
+	z	=  x*x;
+	v	=  z*x;
+	r	=  S2+z*(S3+z*(S4+z*(S5+z*S6)));
+	if(iy==0) return x+v*(S1+z*r);
+	else      return x-((z*(half*y-v*r)-y)-v*S1);
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/k_standard.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/k_standard.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,785 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)k_standard.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+#include "fdlibm.h"
+
+/* XXX ugly hack to get msvc to link without error. */
+#if _LIB_VERSION == _IEEE_ && !(defined(DARWIN) || defined(XP_MACOSX))
+   int errno;
+#  define EDOM 0
+#  define ERANGE 0
+#else
+#  include <errno.h>
+#endif
+
+
+#ifndef _USE_WRITE
+#include <stdio.h>			/* fputs(), stderr */
+#define	WRITE2(u,v)	fputs(u, stderr)
+#else	/* !defined(_USE_WRITE) */
+#include <unistd.h>			/* write */
+#define	WRITE2(u,v)	write(2, u, v)
+#undef fflush
+#endif	/* !defined(_USE_WRITE) */
+
+static double zero = 0.0;	/* used as const */
+
+/* 
+ * Standard conformance (non-IEEE) on exception cases.
+ * Mapping:
+ *	1 -- acos(|x|>1)
+ *	2 -- asin(|x|>1)
+ *	3 -- atan2(+-0,+-0)
+ *	4 -- hypot overflow
+ *	5 -- cosh overflow
+ *	6 -- exp overflow
+ *	7 -- exp underflow
+ *	8 -- y0(0)
+ *	9 -- y0(-ve)
+ *	10-- y1(0)
+ *	11-- y1(-ve)
+ *	12-- yn(0)
+ *	13-- yn(-ve)
+ *	14-- lgamma(finite) overflow
+ *	15-- lgamma(-integer)
+ *	16-- log(0)
+ *	17-- log(x<0)
+ *	18-- log10(0)
+ *	19-- log10(x<0)
+ *	20-- pow(0.0,0.0)
+ *	21-- pow(x,y) overflow
+ *	22-- pow(x,y) underflow
+ *	23-- pow(0,negative) 
+ *	24-- pow(neg,non-integral)
+ *	25-- sinh(finite) overflow
+ *	26-- sqrt(negative)
+ *      27-- fmod(x,0)
+ *      28-- remainder(x,0)
+ *	29-- acosh(x<1)
+ *	30-- atanh(|x|>1)
+ *	31-- atanh(|x|=1)
+ *	32-- scalb overflow
+ *	33-- scalb underflow
+ *	34-- j0(|x|>X_TLOSS)
+ *	35-- y0(x>X_TLOSS)
+ *	36-- j1(|x|>X_TLOSS)
+ *	37-- y1(x>X_TLOSS)
+ *	38-- jn(|x|>X_TLOSS, n)
+ *	39-- yn(x>X_TLOSS, n)
+ *	40-- gamma(finite) overflow
+ *	41-- gamma(-integer)
+ *	42-- pow(NaN,0.0)
+ */
+
+
+#ifdef __STDC__
+	double __kernel_standard(double x, double y, int type, int *err)
+#else
+	double __kernel_standard(x,y,type, err)
+     double x,y; int type;int *err;
+#endif
+{
+	struct exception exc;
+#ifndef HUGE_VAL	/* this is the only routine that uses HUGE_VAL */ 
+#define HUGE_VAL inf
+	double inf = 0.0;
+        fd_twoints u;
+
+        u.d = inf;
+	__HI(u) = 0x7ff00000;	/* set inf to infinite */
+        inf = u.d;
+#endif
+
+    *err = 0;
+
+#ifdef _USE_WRITE
+	(void) fflush(stdout);
+#endif
+	exc.arg1 = x;
+	exc.arg2 = y;
+	switch(type) {
+	    case 1:
+		/* acos(|x|>1) */
+		exc.type = DOMAIN;
+		exc.name = "acos";
+		exc.retval = zero;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if(_LIB_VERSION == _SVID_) {
+		    (void) WRITE2("acos: DOMAIN error\n", 19);
+		  }
+		  *err = EDOM;
+		}
+		break;
+	    case 2:
+		/* asin(|x|>1) */
+		exc.type = DOMAIN;
+		exc.name = "asin";
+		exc.retval = zero;
+		if(_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if(_LIB_VERSION == _SVID_) {
+		    	(void) WRITE2("asin: DOMAIN error\n", 19);
+		  }
+		  *err = EDOM;
+		}
+		break;
+	    case 3:
+		/* atan2(+-0,+-0) */
+		exc.arg1 = y;
+		exc.arg2 = x;
+		exc.type = DOMAIN;
+		exc.name = "atan2";
+		exc.retval = zero;
+		if(_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if(_LIB_VERSION == _SVID_) {
+			(void) WRITE2("atan2: DOMAIN error\n", 20);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 4:
+		/* hypot(finite,finite) overflow */
+		exc.type = OVERFLOW;
+		exc.name = "hypot";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = HUGE;
+		else
+		  exc.retval = HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+		else if (!fd_matherr(&exc)) {
+			*err = ERANGE;
+		}
+		break;
+	    case 5:
+		/* cosh(finite) overflow */
+		exc.type = OVERFLOW;
+		exc.name = "cosh";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = HUGE;
+		else
+		  exc.retval = HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+		else if (!fd_matherr(&exc)) {
+			*err = ERANGE;
+		}
+		break;
+	    case 6:
+		/* exp(finite) overflow */
+		exc.type = OVERFLOW;
+		exc.name = "exp";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = HUGE;
+		else
+		  exc.retval = HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+		else if (!fd_matherr(&exc)) {
+			*err = ERANGE;
+		}
+		break;
+	    case 7:
+		/* exp(finite) underflow */
+		exc.type = UNDERFLOW;
+		exc.name = "exp";
+		exc.retval = zero;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+		else if (!fd_matherr(&exc)) {
+			*err = ERANGE;
+		}
+		break;
+	    case 8:
+		/* y0(0) = -inf */
+		exc.type = DOMAIN;	/* should be SING for IEEE */
+		exc.name = "y0";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = -HUGE;
+		else
+		  exc.retval = -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("y0: DOMAIN error\n", 17);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 9:
+		/* y0(x<0) = NaN */
+		exc.type = DOMAIN;
+		exc.name = "y0";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = -HUGE;
+		else
+		  exc.retval = -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("y0: DOMAIN error\n", 17);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 10:
+		/* y1(0) = -inf */
+		exc.type = DOMAIN;	/* should be SING for IEEE */
+		exc.name = "y1";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = -HUGE;
+		else
+		  exc.retval = -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("y1: DOMAIN error\n", 17);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 11:
+		/* y1(x<0) = NaN */
+		exc.type = DOMAIN;
+		exc.name = "y1";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = -HUGE;
+		else
+		  exc.retval = -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("y1: DOMAIN error\n", 17);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 12:
+		/* yn(n,0) = -inf */
+		exc.type = DOMAIN;	/* should be SING for IEEE */
+		exc.name = "yn";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = -HUGE;
+		else
+		  exc.retval = -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("yn: DOMAIN error\n", 17);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 13:
+		/* yn(x<0) = NaN */
+		exc.type = DOMAIN;
+		exc.name = "yn";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = -HUGE;
+		else
+		  exc.retval = -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("yn: DOMAIN error\n", 17);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 14:
+		/* lgamma(finite) overflow */
+		exc.type = OVERFLOW;
+		exc.name = "lgamma";
+                if (_LIB_VERSION == _SVID_)
+                  exc.retval = HUGE;
+                else
+                  exc.retval = HUGE_VAL;
+                if (_LIB_VERSION == _POSIX_)
+			*err = ERANGE;
+                else if (!fd_matherr(&exc)) {
+                        *err = ERANGE;
+		}
+		break;
+	    case 15:
+		/* lgamma(-integer) or lgamma(0) */
+		exc.type = SING;
+		exc.name = "lgamma";
+                if (_LIB_VERSION == _SVID_)
+                  exc.retval = HUGE;
+                else
+                  exc.retval = HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("lgamma: SING error\n", 19);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 16:
+		/* log(0) */
+		exc.type = SING;
+		exc.name = "log";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = -HUGE;
+		else
+		  exc.retval = -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("log: SING error\n", 16);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 17:
+		/* log(x<0) */
+		exc.type = DOMAIN;
+		exc.name = "log";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = -HUGE;
+		else
+		  exc.retval = -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("log: DOMAIN error\n", 18);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 18:
+		/* log10(0) */
+		exc.type = SING;
+		exc.name = "log10";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = -HUGE;
+		else
+		  exc.retval = -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("log10: SING error\n", 18);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 19:
+		/* log10(x<0) */
+		exc.type = DOMAIN;
+		exc.name = "log10";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = -HUGE;
+		else
+		  exc.retval = -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("log10: DOMAIN error\n", 20);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 20:
+		/* pow(0.0,0.0) */
+		/* error only if _LIB_VERSION == _SVID_ */
+		exc.type = DOMAIN;
+		exc.name = "pow";
+		exc.retval = zero;
+		if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
+		else if (!fd_matherr(&exc)) {
+			(void) WRITE2("pow(0,0): DOMAIN error\n", 23);
+			*err = EDOM;
+		}
+		break;
+	    case 21:
+		/* pow(x,y) overflow */
+		exc.type = OVERFLOW;
+		exc.name = "pow";
+		if (_LIB_VERSION == _SVID_) {
+		  exc.retval = HUGE;
+		  y *= 0.5;
+		  if(x<zero&&fd_rint(y)!=y) exc.retval = -HUGE;
+		} else {
+		  exc.retval = HUGE_VAL;
+		  y *= 0.5;
+		  if(x<zero&&fd_rint(y)!=y) exc.retval = -HUGE_VAL;
+		}
+		if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+		else if (!fd_matherr(&exc)) {
+			*err = ERANGE;
+		}
+		break;
+	    case 22:
+		/* pow(x,y) underflow */
+		exc.type = UNDERFLOW;
+		exc.name = "pow";
+		exc.retval =  zero;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+		else if (!fd_matherr(&exc)) {
+			*err = ERANGE;
+		}
+		break;
+	    case 23:
+		/* 0**neg */
+		exc.type = DOMAIN;
+		exc.name = "pow";
+		if (_LIB_VERSION == _SVID_) 
+		  exc.retval = zero;
+		else
+		  exc.retval = -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("pow(0,neg): DOMAIN error\n", 25);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 24:
+		/* neg**non-integral */
+		exc.type = DOMAIN;
+		exc.name = "pow";
+		if (_LIB_VERSION == _SVID_) 
+		    exc.retval = zero;
+		else 
+		    exc.retval = zero/zero;	/* X/Open allow NaN */
+		if (_LIB_VERSION == _POSIX_) 
+		   *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("neg**non-integral: DOMAIN error\n", 32);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 25:
+		/* sinh(finite) overflow */
+		exc.type = OVERFLOW;
+		exc.name = "sinh";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = ( (x>zero) ? HUGE : -HUGE);
+		else
+		  exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL);
+		if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+		else if (!fd_matherr(&exc)) {
+			*err = ERANGE;
+		}
+		break;
+	    case 26:
+		/* sqrt(x<0) */
+		exc.type = DOMAIN;
+		exc.name = "sqrt";
+		if (_LIB_VERSION == _SVID_)
+		  exc.retval = zero;
+		else
+		  exc.retval = zero/zero;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("sqrt: DOMAIN error\n", 19);
+		      }
+		  *err = EDOM;
+		}
+		break;
+            case 27:
+                /* fmod(x,0) */
+                exc.type = DOMAIN;
+                exc.name = "fmod";
+                if (_LIB_VERSION == _SVID_)
+                    exc.retval = x;
+		else
+		    exc.retval = zero/zero;
+                if (_LIB_VERSION == _POSIX_)
+                  *err = EDOM;
+                else if (!fd_matherr(&exc)) {
+                  if (_LIB_VERSION == _SVID_) {
+                    (void) WRITE2("fmod:  DOMAIN error\n", 20);
+                  }
+                  *err = EDOM;
+                }
+                break;
+            case 28:
+                /* remainder(x,0) */
+                exc.type = DOMAIN;
+                exc.name = "remainder";
+                exc.retval = zero/zero;
+                if (_LIB_VERSION == _POSIX_)
+                  *err = EDOM;
+                else if (!fd_matherr(&exc)) {
+                  if (_LIB_VERSION == _SVID_) {
+                    (void) WRITE2("remainder: DOMAIN error\n", 24);
+                  }
+                  *err = EDOM;
+                }
+                break;
+            case 29:
+                /* acosh(x<1) */
+                exc.type = DOMAIN;
+                exc.name = "acosh";
+                exc.retval = zero/zero;
+                if (_LIB_VERSION == _POSIX_)
+                  *err = EDOM;
+                else if (!fd_matherr(&exc)) {
+                  if (_LIB_VERSION == _SVID_) {
+                    (void) WRITE2("acosh: DOMAIN error\n", 20);
+                  }
+                  *err = EDOM;
+                }
+                break;
+            case 30:
+                /* atanh(|x|>1) */
+                exc.type = DOMAIN;
+                exc.name = "atanh";
+                exc.retval = zero/zero;
+                if (_LIB_VERSION == _POSIX_)
+                  *err = EDOM;
+                else if (!fd_matherr(&exc)) {
+                  if (_LIB_VERSION == _SVID_) {
+                    (void) WRITE2("atanh: DOMAIN error\n", 20);
+                  }
+                  *err = EDOM;
+                }
+                break;
+            case 31:
+                /* atanh(|x|=1) */
+                exc.type = SING;
+                exc.name = "atanh";
+		exc.retval = x/zero;	/* sign(x)*inf */
+                if (_LIB_VERSION == _POSIX_)
+                  *err = EDOM;
+                else if (!fd_matherr(&exc)) {
+                  if (_LIB_VERSION == _SVID_) {
+                    (void) WRITE2("atanh: SING error\n", 18);
+                  }
+                  *err = EDOM;
+                }
+                break;
+	    case 32:
+		/* scalb overflow; SVID also returns +-HUGE_VAL */
+		exc.type = OVERFLOW;
+		exc.name = "scalb";
+		exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+		else if (!fd_matherr(&exc)) {
+			*err = ERANGE;
+		}
+		break;
+	    case 33:
+		/* scalb underflow */
+		exc.type = UNDERFLOW;
+		exc.name = "scalb";
+		exc.retval = fd_copysign(zero,x);
+		if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+		else if (!fd_matherr(&exc)) {
+			*err = ERANGE;
+		}
+		break;
+	    case 34:
+		/* j0(|x|>X_TLOSS) */
+                exc.type = TLOSS;
+                exc.name = "j0";
+                exc.retval = zero;
+                if (_LIB_VERSION == _POSIX_)
+                        *err = ERANGE;
+                else if (!fd_matherr(&exc)) {
+                        if (_LIB_VERSION == _SVID_) {
+                                (void) WRITE2(exc.name, 2);
+                                (void) WRITE2(": TLOSS error\n", 14);
+                        }
+                        *err = ERANGE;
+                }        
+		break;
+	    case 35:
+		/* y0(x>X_TLOSS) */
+                exc.type = TLOSS;
+                exc.name = "y0";
+                exc.retval = zero;
+                if (_LIB_VERSION == _POSIX_)
+                        *err = ERANGE;
+                else if (!fd_matherr(&exc)) {
+                        if (_LIB_VERSION == _SVID_) {
+                                (void) WRITE2(exc.name, 2);
+                                (void) WRITE2(": TLOSS error\n", 14);
+                        }
+                        *err = ERANGE;
+                }        
+		break;
+	    case 36:
+		/* j1(|x|>X_TLOSS) */
+                exc.type = TLOSS;
+                exc.name = "j1";
+                exc.retval = zero;
+                if (_LIB_VERSION == _POSIX_)
+                        *err = ERANGE;
+                else if (!fd_matherr(&exc)) {
+                        if (_LIB_VERSION == _SVID_) {
+                                (void) WRITE2(exc.name, 2);
+                                (void) WRITE2(": TLOSS error\n", 14);
+                        }
+                        *err = ERANGE;
+                }        
+		break;
+	    case 37:
+		/* y1(x>X_TLOSS) */
+                exc.type = TLOSS;
+                exc.name = "y1";
+                exc.retval = zero;
+                if (_LIB_VERSION == _POSIX_)
+                        *err = ERANGE;
+                else if (!fd_matherr(&exc)) {
+                        if (_LIB_VERSION == _SVID_) {
+                                (void) WRITE2(exc.name, 2);
+                                (void) WRITE2(": TLOSS error\n", 14);
+                        }
+                        *err = ERANGE;
+                }        
+		break;
+	    case 38:
+		/* jn(|x|>X_TLOSS) */
+                exc.type = TLOSS;
+                exc.name = "jn";
+                exc.retval = zero;
+                if (_LIB_VERSION == _POSIX_)
+                        *err = ERANGE;
+                else if (!fd_matherr(&exc)) {
+                        if (_LIB_VERSION == _SVID_) {
+                                (void) WRITE2(exc.name, 2);
+                                (void) WRITE2(": TLOSS error\n", 14);
+                        }
+                        *err = ERANGE;
+                }        
+		break;
+	    case 39:
+		/* yn(x>X_TLOSS) */
+                exc.type = TLOSS;
+                exc.name = "yn";
+                exc.retval = zero;
+                if (_LIB_VERSION == _POSIX_)
+                        *err = ERANGE;
+                else if (!fd_matherr(&exc)) {
+                        if (_LIB_VERSION == _SVID_) {
+                                (void) WRITE2(exc.name, 2);
+                                (void) WRITE2(": TLOSS error\n", 14);
+                        }
+                        *err = ERANGE;
+                }        
+		break;
+	    case 40:
+		/* gamma(finite) overflow */
+		exc.type = OVERFLOW;
+		exc.name = "gamma";
+                if (_LIB_VERSION == _SVID_)
+                  exc.retval = HUGE;
+                else
+                  exc.retval = HUGE_VAL;
+                if (_LIB_VERSION == _POSIX_)
+		  *err = ERANGE;
+                else if (!fd_matherr(&exc)) {
+                  *err = ERANGE;
+                }
+		break;
+	    case 41:
+		/* gamma(-integer) or gamma(0) */
+		exc.type = SING;
+		exc.name = "gamma";
+                if (_LIB_VERSION == _SVID_)
+                  exc.retval = HUGE;
+                else
+                  exc.retval = HUGE_VAL;
+		if (_LIB_VERSION == _POSIX_)
+		  *err = EDOM;
+		else if (!fd_matherr(&exc)) {
+		  if (_LIB_VERSION == _SVID_) {
+			(void) WRITE2("gamma: SING error\n", 18);
+		      }
+		  *err = EDOM;
+		}
+		break;
+	    case 42:
+		/* pow(NaN,0.0) */
+		/* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
+		exc.type = DOMAIN;
+		exc.name = "pow";
+		exc.retval = x;
+		if (_LIB_VERSION == _IEEE_ ||
+		    _LIB_VERSION == _POSIX_) exc.retval = 1.0;
+		else if (!fd_matherr(&exc)) {
+			*err = EDOM;
+		}
+		break;
+	}
+	return exc.retval; 
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/k_tan.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/k_tan.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,170 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)k_tan.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* __kernel_tan( x, y, k )
+ * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
+ * Input x is assumed to be bounded by ~pi/4 in magnitude.
+ * Input y is the tail of x.
+ * Input k indicates whether tan (if k=1) or 
+ * -1/tan (if k= -1) is returned.
+ *
+ * Algorithm
+ *	1. Since tan(-x) = -tan(x), we need only to consider positive x. 
+ *	2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0.
+ *	3. tan(x) is approximated by a odd polynomial of degree 27 on
+ *	   [0,0.67434]
+ *		  	         3             27
+ *	   	tan(x) ~ x + T1*x + ... + T13*x
+ *	   where
+ *	
+ * 	        |tan(x)         2     4            26   |     -59.2
+ * 	        |----- - (1+T1*x +T2*x +.... +T13*x    )| <= 2
+ * 	        |  x 					| 
+ * 
+ *	   Note: tan(x+y) = tan(x) + tan'(x)*y
+ *		          ~ tan(x) + (1+x*x)*y
+ *	   Therefore, for better accuracy in computing tan(x+y), let 
+ *		     3      2      2       2       2
+ *		r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
+ *	   then
+ *		 		    3    2
+ *		tan(x+y) = x + (T1*x + (x *(r+y)+y))
+ *
+ *      4. For x in [0.67434,pi/4],  let y = pi/4 - x, then
+ *		tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
+ *		       = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
+ */
+
+#include "fdlibm.h"
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+one   =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+pio4  =  7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
+pio4lo=  3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */
+T[] =  {
+  3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */
+  1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */
+  5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */
+  2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */
+  8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */
+  3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */
+  1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */
+  5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */
+  2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */
+  7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */
+  7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */
+ -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */
+  2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */
+};
+
+#ifdef __STDC__
+	double __kernel_tan(double x, double y, int iy)
+#else
+	double __kernel_tan(x, y, iy)
+	double x,y; int iy;
+#endif
+{
+        fd_twoints u;
+	double z,r,v,w,s;
+	int ix,hx;
+        u.d = x;
+	hx = __HI(u);	/* high word of x */
+	ix = hx&0x7fffffff;	/* high word of |x| */
+	if(ix<0x3e300000)			/* x < 2**-28 */
+	    {if((int)x==0) {			/* generate inexact */
+                u.d =x;
+		if(((ix|__LO(u))|(iy+1))==0) return one/fd_fabs(x);
+		else return (iy==1)? x: -one/x;
+	    }
+	    }
+	if(ix>=0x3FE59428) { 			/* |x|>=0.6744 */
+	    if(hx<0) {x = -x; y = -y;}
+	    z = pio4-x;
+	    w = pio4lo-y;
+	    x = z+w; y = 0.0;
+	}
+	z	=  x*x;
+	w 	=  z*z;
+    /* Break x^5*(T[1]+x^2*T[2]+...) into
+     *	  x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
+     *	  x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
+     */
+	r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11]))));
+	v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12])))));
+	s = z*x;
+	r = y + z*(s*(r+v)+y);
+	r += T[0]*s;
+	w = x+r;
+	if(ix>=0x3FE59428) {
+	    v = (double)iy;
+	    return (double)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r)));
+	}
+	if(iy==1) return w;
+	else {		/* if allow error up to 2 ulp, 
+			   simply return -1.0/(x+r) here */
+     /*  compute -1.0/(x+r) accurately */
+	    double a,t;
+	    z  = w;
+            u.d = z;
+	    __LO(u) = 0;
+            z = u.d;
+	    v  = r-(z - x); 	/* z+v = r+x */
+	    t = a  = -1.0/w;	/* a = -1.0/w */
+            u.d = t;
+	    __LO(u) = 0;
+            t = u.d;
+	    s  = 1.0+t*z;
+	    return t+a*(s+t*v);
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_asinh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_asinh.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,101 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_asinh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* asinh(x)
+ * Method :
+ *	Based on 
+ *		asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
+ *	we have
+ *	asinh(x) := x  if  1+x*x=1,
+ *		 := sign(x)*(log(x)+ln2)) for large |x|, else
+ *		 := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
+ *		 := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))  
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double 
+#else
+static double 
+#endif
+one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+ln2 =  6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
+really_big=  1.00000000000000000000e+300; 
+
+#ifdef __STDC__
+	double fd_asinh(double x)
+#else
+	double fd_asinh(x)
+	double x;
+#endif
+{	
+        fd_twoints u;
+	double t,w;
+	int hx,ix;
+        u.d = x;
+	hx = __HI(u);
+	ix = hx&0x7fffffff;
+	if(ix>=0x7ff00000) return x+x;	/* x is inf or NaN */
+	if(ix< 0x3e300000) {	/* |x|<2**-28 */
+	    if(really_big+x>one) return x;	/* return x inexact except 0 */
+	} 
+	if(ix>0x41b00000) {	/* |x| > 2**28 */
+	    w = __ieee754_log(fd_fabs(x))+ln2;
+	} else if (ix>0x40000000) {	/* 2**28 > |x| > 2.0 */
+	    t = fd_fabs(x);
+	    w = __ieee754_log(2.0*t+one/(fd_sqrt(x*x+one)+t));
+	} else {		/* 2.0 > |x| > 2**-28 */
+	    t = x*x;
+	    w =fd_log1p(fd_fabs(x)+t/(one+fd_sqrt(one+t)));
+	}
+	if(hx>0) return w; else return -w;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_atan.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_atan.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,175 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_atan.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* atan(x)
+ * Method
+ *   1. Reduce x to positive by atan(x) = -atan(-x).
+ *   2. According to the integer k=4t+0.25 chopped, t=x, the argument
+ *      is further reduced to one of the following intervals and the
+ *      arctangent of t is evaluated by the corresponding formula:
+ *
+ *      [0,7/16]      atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
+ *      [7/16,11/16]  atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
+ *      [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
+ *      [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
+ *      [39/16,INF]   atan(x) = atan(INF) + atan( -1/t )
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough 
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double atanhi[] = {
+#else
+static double atanhi[] = {
+#endif
+  4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
+  7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
+  9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
+  1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
+};
+
+#ifdef __STDC__
+static const double atanlo[] = {
+#else
+static double atanlo[] = {
+#endif
+  2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
+  3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
+  1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
+  6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
+};
+
+#ifdef __STDC__
+static const double aT[] = {
+#else
+static double aT[] = {
+#endif
+  3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
+ -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
+  1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
+ -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
+  9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
+ -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
+  6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
+ -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
+  4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
+ -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
+  1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
+};
+
+#ifdef __STDC__
+	static const double 
+#else
+	static double 
+#endif
+one   = 1.0,
+really_big   = 1.0e300;
+
+#ifdef __STDC__
+	double fd_atan(double x)
+#else
+	double fd_atan(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	double w,s1,s2,z;
+	int ix,hx,id;
+
+        u.d = x;
+	hx = __HI(u);
+	ix = hx&0x7fffffff;
+	if(ix>=0x44100000) {	/* if |x| >= 2^66 */
+            u.d = x;
+	    if(ix>0x7ff00000||
+		(ix==0x7ff00000&&(__LO(u)!=0)))
+		return x+x;		/* NaN */
+	    if(hx>0) return  atanhi[3]+atanlo[3];
+	    else     return -atanhi[3]-atanlo[3];
+	} if (ix < 0x3fdc0000) {	/* |x| < 0.4375 */
+	    if (ix < 0x3e200000) {	/* |x| < 2^-29 */
+		if(really_big+x>one) return x;	/* raise inexact */
+	    }
+	    id = -1;
+	} else {
+	x = fd_fabs(x);
+	if (ix < 0x3ff30000) {		/* |x| < 1.1875 */
+	    if (ix < 0x3fe60000) {	/* 7/16 <=|x|<11/16 */
+		id = 0; x = (2.0*x-one)/(2.0+x); 
+	    } else {			/* 11/16<=|x|< 19/16 */
+		id = 1; x  = (x-one)/(x+one); 
+	    }
+	} else {
+	    if (ix < 0x40038000) {	/* |x| < 2.4375 */
+		id = 2; x  = (x-1.5)/(one+1.5*x);
+	    } else {			/* 2.4375 <= |x| < 2^66 */
+		id = 3; x  = -1.0/x;
+	    }
+	}}
+    /* end of argument reduction */
+	z = x*x;
+	w = z*z;
+    /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
+	s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
+	s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
+	if (id<0) return x - x*(s1+s2);
+	else {
+	    z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
+	    return (hx<0)? -z:z;
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_cbrt.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_cbrt.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,133 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_cbrt.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+#include "fdlibm.h"
+
+/* cbrt(x)
+ * Return cube root of x
+ */
+#ifdef __STDC__
+static const unsigned 
+#else
+static unsigned 
+#endif
+	B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
+	B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+C =  5.42857142857142815906e-01, /* 19/35     = 0x3FE15F15, 0xF15F15F1 */
+D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
+E =  1.41428571428571436819e+00, /* 99/70     = 0x3FF6A0EA, 0x0EA0EA0F */
+F =  1.60714285714285720630e+00, /* 45/28     = 0x3FF9B6DB, 0x6DB6DB6E */
+G =  3.57142857142857150787e-01; /* 5/14      = 0x3FD6DB6D, 0xB6DB6DB7 */
+
+#ifdef __STDC__
+	double fd_cbrt(double x) 
+#else
+	double fd_cbrt(x) 
+	double x;
+#endif
+{
+        fd_twoints u;
+	int	hx;
+	double r,s,t=0.0,w;
+	unsigned sign;
+
+        u.d = x;
+	hx = __HI(u);		/* high word of x */
+	sign=hx&0x80000000; 		/* sign= sign(x) */
+	hx  ^=sign;
+	if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
+	if((hx|__LO(u))==0) {
+            x = u.d;
+	    return(x);		/* cbrt(0) is itself */
+        }
+        u.d = x;
+	__HI(u) = hx;	/* x <- |x| */
+        x = u.d;
+    /* rough cbrt to 5 bits */
+	if(hx<0x00100000) 		/* subnormal number */
+	  {u.d = t; __HI(u)=0x43500000; t=u.d;		/* set t= 2**54 */
+	   t*=x; __HI(u)=__HI(u)/3+B2;
+	  }
+	else {
+	  u.d = t; __HI(u)=hx/3+B1; t = u.d;
+        }
+
+
+    /* new cbrt to 23 bits, may be implemented in single precision */
+	r=t*t/x;
+	s=C+r*t;
+	t*=G+F/(s+E+D/s);	
+
+    /* chopped to 20 bits and make it larger than cbrt(x) */ 
+        u.d = t;
+	__LO(u)=0; __HI(u)+=0x00000001;
+        t = u.d;
+
+    /* one step newton iteration to 53 bits with error less than 0.667 ulps */
+	s=t*t;		/* t*t is exact */
+	r=x/s;
+	w=t+t;
+	r=(r-t)/(w+r);	/* r-s is exact */
+	t=t+t*r;
+
+    /* retore the sign bit */
+        u.d = t;
+	__HI(u) |= sign;
+        t = u.d;
+	return(t);
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_ceil.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_ceil.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,120 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_ceil.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * ceil(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ *	Bit twiddling.
+ * Exception:
+ *	Inexact flag raised if x not equal to ceil(x).
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double really_big = 1.0e300;
+#else
+static double really_big = 1.0e300;
+#endif
+
+#ifdef __STDC__
+	double fd_ceil(double x)
+#else
+	double fd_ceil(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	int i0,i1,j0;
+	unsigned i,j;
+        u.d = x;
+	i0 =  __HI(u);
+	i1 =  __LO(u);
+	j0 = ((i0>>20)&0x7ff)-0x3ff;
+	if(j0<20) {
+	    if(j0<0) { 	/* raise inexact if x != 0 */
+		if(really_big+x>0.0) {/* return 0*sign(x) if |x|<1 */
+		    if(i0<0) {i0=0x80000000;i1=0;} 
+		    else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
+		}
+	    } else {
+		i = (0x000fffff)>>j0;
+		if(((i0&i)|i1)==0) return x; /* x is integral */
+		if(really_big+x>0.0) {	/* raise inexact flag */
+		    if(i0>0) i0 += (0x00100000)>>j0;
+		    i0 &= (~i); i1=0;
+		}
+	    }
+	} else if (j0>51) {
+	    if(j0==0x400) return x+x;	/* inf or NaN */
+	    else return x;		/* x is integral */
+	} else {
+	    i = ((unsigned)(0xffffffff))>>(j0-20);
+	    if((i1&i)==0) return x;	/* x is integral */
+	    if(really_big+x>0.0) { 		/* raise inexact flag */
+		if(i0>0) {
+		    if(j0==20) i0+=1; 
+		    else {
+			j = i1 + (1<<(52-j0));
+			if((int)j<i1) i0+=1;	/* got a carry */
+			i1 = j;
+		    }
+		}
+		i1 &= (~i);
+	    }
+	}
+        u.d = x;
+	__HI(u) = i0;
+	__LO(u) = i1;
+        x = u.d;
+	return x;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_copysign.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_copysign.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_copysign.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * copysign(double x, double y)
+ * copysign(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_copysign(double x, double y)
+#else
+	double fd_copysign(x,y)
+	double x,y;
+#endif
+{
+        fd_twoints ux, uy;
+        ux.d = x; uy.d = y;
+	__HI(ux) = (__HI(ux)&0x7fffffff)|(__HI(uy)&0x80000000);
+        x = ux.d;
+        return x;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_cos.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_cos.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,118 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_cos.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* cos(x)
+ * Return cosine function of x.
+ *
+ * kernel function:
+ *	__kernel_sin		... sine function on [-pi/4,pi/4]
+ *	__kernel_cos		... cosine function on [-pi/4,pi/4]
+ *	__ieee754_rem_pio2	... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on 
+ *	[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 
+ *	in [-pi/4 , +pi/4], and let n = k mod 4.
+ *	We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *	    0	       S	   C		 T
+ *	    1	       C	  -S		-1/T
+ *	    2	      -S	  -C		 T
+ *	    3	      -C	   S		-1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *	TRIG(x) returns trig(x) nearly rounded 
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_cos(double x)
+#else
+	double fd_cos(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	double y[2],z=0.0;
+	int n, ix;
+
+    /* High word of x. */
+        u.d = x;
+	ix = __HI(u);
+
+    /* |x| ~< pi/4 */
+	ix &= 0x7fffffff;
+	if(ix <= 0x3fe921fb) return __kernel_cos(x,z);
+
+    /* cos(Inf or NaN) is NaN */
+	else if (ix>=0x7ff00000) return x-x;
+
+    /* argument reduction needed */
+	else {
+	    n = __ieee754_rem_pio2(x,y);
+	    switch(n&3) {
+		case 0: return  __kernel_cos(y[0],y[1]);
+		case 1: return -__kernel_sin(y[0],y[1],1);
+		case 2: return -__kernel_cos(y[0],y[1]);
+		default:
+		        return  __kernel_sin(y[0],y[1],1);
+	    }
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_erf.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_erf.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,356 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_erf.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* double erf(double x)
+ * double erfc(double x)
+ *			     x
+ *		      2      |\
+ *     erf(x)  =  ---------  | exp(-t*t)dt
+ *	 	   sqrt(pi) \| 
+ *			     0
+ *
+ *     erfc(x) =  1-erf(x)
+ *  Note that 
+ *		erf(-x) = -erf(x)
+ *		erfc(-x) = 2 - erfc(x)
+ *
+ * Method:
+ *	1. For |x| in [0, 0.84375]
+ *	    erf(x)  = x + x*R(x^2)
+ *          erfc(x) = 1 - erf(x)           if x in [-.84375,0.25]
+ *                  = 0.5 + ((0.5-x)-x*R)  if x in [0.25,0.84375]
+ *	   where R = P/Q where P is an odd poly of degree 8 and
+ *	   Q is an odd poly of degree 10.
+ *						 -57.90
+ *			| R - (erf(x)-x)/x | <= 2
+ *	
+ *
+ *	   Remark. The formula is derived by noting
+ *          erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ *	   and that
+ *          2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ *	   is close to one. The interval is chosen because the fix
+ *	   point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
+ *	   near 0.6174), and by some experiment, 0.84375 is chosen to
+ * 	   guarantee the error is less than one ulp for erf.
+ *
+ *      2. For |x| in [0.84375,1.25], let s = |x| - 1, and
+ *         c = 0.84506291151 rounded to single (24 bits)
+ *         	erf(x)  = sign(x) * (c  + P1(s)/Q1(s))
+ *         	erfc(x) = (1-c)  - P1(s)/Q1(s) if x > 0
+ *			  1+(c+P1(s)/Q1(s))    if x < 0
+ *         	|P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
+ *	   Remark: here we use the taylor series expansion at x=1.
+ *		erf(1+s) = erf(1) + s*Poly(s)
+ *			 = 0.845.. + P1(s)/Q1(s)
+ *	   That is, we use rational approximation to approximate
+ *			erf(1+s) - (c = (single)0.84506291151)
+ *	   Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ *	   where 
+ *		P1(s) = degree 6 poly in s
+ *		Q1(s) = degree 6 poly in s
+ *
+ *      3. For x in [1.25,1/0.35(~2.857143)], 
+ *         	erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
+ *         	erf(x)  = 1 - erfc(x)
+ *	   where 
+ *		R1(z) = degree 7 poly in z, (z=1/x^2)
+ *		S1(z) = degree 8 poly in z
+ *
+ *      4. For x in [1/0.35,28]
+ *         	erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
+ *			= 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
+ *			= 2.0 - tiny		(if x <= -6)
+ *         	erf(x)  = sign(x)*(1.0 - erfc(x)) if x < 6, else
+ *         	erf(x)  = sign(x)*(1.0 - tiny)
+ *	   where
+ *		R2(z) = degree 6 poly in z, (z=1/x^2)
+ *		S2(z) = degree 7 poly in z
+ *
+ *      Note1:
+ *	   To compute exp(-x*x-0.5625+R/S), let s be a single
+ *	   precision number and s := x; then
+ *		-x*x = -s*s + (s-x)*(s+x)
+ *	        exp(-x*x-0.5626+R/S) = 
+ *			exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
+ *      Note2:
+ *	   Here 4 and 5 make use of the asymptotic series
+ *			  exp(-x*x)
+ *		erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
+ *			  x*sqrt(pi)
+ *	   We use rational approximation to approximate
+ *      	g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
+ *	   Here is the error bound for R1/S1 and R2/S2
+ *      	|R1/S1 - f(x)|  < 2**(-62.57)
+ *      	|R2/S2 - f(x)|  < 2**(-61.52)
+ *
+ *      5. For inf > x >= 28
+ *         	erf(x)  = sign(x) *(1 - tiny)  (raise inexact)
+ *         	erfc(x) = tiny*tiny (raise underflow) if x > 0
+ *			= 2 - tiny if x<0
+ *
+ *      7. Special case:
+ *         	erf(0)  = 0, erf(inf)  = 1, erf(-inf) = -1,
+ *         	erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, 
+ *	   	erfc/erf(NaN) is NaN
+ */
+
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+tiny	    = 1e-300,
+half=  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+one =  1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+two =  2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
+	/* c = (float)0.84506291151 */
+erx =  8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */
+/*
+ * Coefficients for approximation to  erf on [0,0.84375]
+ */
+efx =  1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */
+efx8=  1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
+pp0  =  1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
+pp1  = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
+pp2  = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
+pp3  = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */
+pp4  = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */
+qq1  =  3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */
+qq2  =  6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */
+qq3  =  5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */
+qq4  =  1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */
+qq5  = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */
+/*
+ * Coefficients for approximation to  erf  in [0.84375,1.25] 
+ */
+pa0  = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */
+pa1  =  4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */
+pa2  = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */
+pa3  =  3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */
+pa4  = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */
+pa5  =  3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */
+pa6  = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */
+qa1  =  1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */
+qa2  =  5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */
+qa3  =  7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */
+qa4  =  1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */
+qa5  =  1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */
+qa6  =  1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */
+/*
+ * Coefficients for approximation to  erfc in [1.25,1/0.35]
+ */
+ra0  = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */
+ra1  = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */
+ra2  = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */
+ra3  = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */
+ra4  = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */
+ra5  = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */
+ra6  = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */
+ra7  = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */
+sa1  =  1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */
+sa2  =  1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */
+sa3  =  4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */
+sa4  =  6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */
+sa5  =  4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */
+sa6  =  1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */
+sa7  =  6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */
+sa8  = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */
+/*
+ * Coefficients for approximation to  erfc in [1/.35,28]
+ */
+rb0  = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */
+rb1  = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */
+rb2  = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */
+rb3  = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */
+rb4  = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */
+rb5  = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */
+rb6  = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */
+sb1  =  3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */
+sb2  =  3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */
+sb3  =  1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */
+sb4  =  3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */
+sb5  =  2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */
+sb6  =  4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */
+sb7  = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */
+
+#ifdef __STDC__
+	double fd_erf(double x) 
+#else
+	double fd_erf(x) 
+	double x;
+#endif
+{
+        fd_twoints u;
+	int hx,ix,i;
+	double R,S,P,Q,s,y,z,r;
+        u.d = x;
+	hx = __HI(u);
+	ix = hx&0x7fffffff;
+	if(ix>=0x7ff00000) {		/* erf(nan)=nan */
+	    i = ((unsigned)hx>>31)<<1;
+	    return (double)(1-i)+one/x;	/* erf(+-inf)=+-1 */
+	}
+
+	if(ix < 0x3feb0000) {		/* |x|<0.84375 */
+	    if(ix < 0x3e300000) { 	/* |x|<2**-28 */
+	        if (ix < 0x00800000) 
+		    return 0.125*(8.0*x+efx8*x);  /*avoid underflow */
+		return x + efx*x;
+	    }
+	    z = x*x;
+	    r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+	    s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+	    y = r/s;
+	    return x + x*y;
+	}
+	if(ix < 0x3ff40000) {		/* 0.84375 <= |x| < 1.25 */
+	    s = fd_fabs(x)-one;
+	    P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+	    Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+	    if(hx>=0) return erx + P/Q; else return -erx - P/Q;
+	}
+	if (ix >= 0x40180000) {		/* inf>|x|>=6 */
+	    if(hx>=0) return one-tiny; else return tiny-one;
+	}
+	x = fd_fabs(x);
+ 	s = one/(x*x);
+	if(ix< 0x4006DB6E) {	/* |x| < 1/0.35 */
+	    R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+				ra5+s*(ra6+s*ra7))))));
+	    S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+				sa5+s*(sa6+s*(sa7+s*sa8)))))));
+	} else {	/* |x| >= 1/0.35 */
+	    R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+				rb5+s*rb6)))));
+	    S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+				sb5+s*(sb6+s*sb7))))));
+	}
+	z  = x;  
+        u.d = z;
+	__LO(u) = 0;
+        z = u.d;
+	r  =  __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S);
+	if(hx>=0) return one-r/x; else return  r/x-one;
+}
+
+#ifdef __STDC__
+	double erfc(double x) 
+#else
+	double erfc(x) 
+	double x;
+#endif
+{
+        fd_twoints u;
+	int hx,ix;
+	double R,S,P,Q,s,y,z,r;
+        u.d = x;
+	hx = __HI(u);
+	ix = hx&0x7fffffff;
+	if(ix>=0x7ff00000) {			/* erfc(nan)=nan */
+						/* erfc(+-inf)=0,2 */
+	    return (double)(((unsigned)hx>>31)<<1)+one/x;
+	}
+
+	if(ix < 0x3feb0000) {		/* |x|<0.84375 */
+	    if(ix < 0x3c700000)  	/* |x|<2**-56 */
+		return one-x;
+	    z = x*x;
+	    r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+	    s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+	    y = r/s;
+	    if(hx < 0x3fd00000) {  	/* x<1/4 */
+		return one-(x+x*y);
+	    } else {
+		r = x*y;
+		r += (x-half);
+	        return half - r ;
+	    }
+	}
+	if(ix < 0x3ff40000) {		/* 0.84375 <= |x| < 1.25 */
+	    s = fd_fabs(x)-one;
+	    P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+	    Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+	    if(hx>=0) {
+	        z  = one-erx; return z - P/Q; 
+	    } else {
+		z = erx+P/Q; return one+z;
+	    }
+	}
+	if (ix < 0x403c0000) {		/* |x|<28 */
+	    x = fd_fabs(x);
+ 	    s = one/(x*x);
+	    if(ix< 0x4006DB6D) {	/* |x| < 1/.35 ~ 2.857143*/
+	        R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+				ra5+s*(ra6+s*ra7))))));
+	        S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+				sa5+s*(sa6+s*(sa7+s*sa8)))))));
+	    } else {			/* |x| >= 1/.35 ~ 2.857143 */
+		if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */
+	        R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+				rb5+s*rb6)))));
+	        S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+				sb5+s*(sb6+s*sb7))))));
+	    }
+	    z  = x;
+            u.d = z;
+	    __LO(u)  = 0;
+            z = u.d;
+	    r  =  __ieee754_exp(-z*z-0.5625)*
+			__ieee754_exp((z-x)*(z+x)+R/S);
+	    if(hx>0) return r/x; else return two-r/x;
+	} else {
+	    if(hx>0) return tiny*tiny; else return two-tiny;
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_expm1.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_expm1.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,267 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_expm1.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* expm1(x)
+ * Returns exp(x)-1, the exponential of x minus 1.
+ *
+ * Method
+ *   1. Argument reduction:
+ *	Given x, find r and integer k such that
+ *
+ *               x = k*ln2 + r,  |r| <= 0.5*ln2 ~ 0.34658  
+ *
+ *      Here a correction term c will be computed to compensate 
+ *	the error in r when rounded to a floating-point number.
+ *
+ *   2. Approximating expm1(r) by a special rational function on
+ *	the interval [0,0.34658]:
+ *	Since
+ *	    r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
+ *	we define R1(r*r) by
+ *	    r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
+ *	That is,
+ *	    R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
+ *		     = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
+ *		     = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
+ *      We use a special Reme algorithm on [0,0.347] to generate 
+ * 	a polynomial of degree 5 in r*r to approximate R1. The 
+ *	maximum error of this polynomial approximation is bounded 
+ *	by 2**-61. In other words,
+ *	    R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
+ *	where 	Q1  =  -1.6666666666666567384E-2,
+ * 		Q2  =   3.9682539681370365873E-4,
+ * 		Q3  =  -9.9206344733435987357E-6,
+ * 		Q4  =   2.5051361420808517002E-7,
+ * 		Q5  =  -6.2843505682382617102E-9;
+ *  	(where z=r*r, and the values of Q1 to Q5 are listed below)
+ *	with error bounded by
+ *	    |                  5           |     -61
+ *	    | 1.0+Q1*z+...+Q5*z   -  R1(z) | <= 2 
+ *	    |                              |
+ *	
+ *	expm1(r) = exp(r)-1 is then computed by the following 
+ * 	specific way which minimize the accumulation rounding error: 
+ *			       2     3
+ *			      r     r    [ 3 - (R1 + R1*r/2)  ]
+ *	      expm1(r) = r + --- + --- * [--------------------]
+ *		              2     2    [ 6 - r*(3 - R1*r/2) ]
+ *	
+ *	To compensate the error in the argument reduction, we use
+ *		expm1(r+c) = expm1(r) + c + expm1(r)*c 
+ *			   ~ expm1(r) + c + r*c 
+ *	Thus c+r*c will be added in as the correction terms for
+ *	expm1(r+c). Now rearrange the term to avoid optimization 
+ * 	screw up:
+ *		        (      2                                    2 )
+ *		        ({  ( r    [ R1 -  (3 - R1*r/2) ]  )  }    r  )
+ *	 expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
+ *	                ({  ( 2    [ 6 - r*(3 - R1*r/2) ]  )  }    2  )
+ *                      (                                             )
+ *    	
+ *		   = r - E
+ *   3. Scale back to obtain expm1(x):
+ *	From step 1, we have
+ *	   expm1(x) = either 2^k*[expm1(r)+1] - 1
+ *		    = or     2^k*[expm1(r) + (1-2^-k)]
+ *   4. Implementation notes:
+ *	(A). To save one multiplication, we scale the coefficient Qi
+ *	     to Qi*2^i, and replace z by (x^2)/2.
+ *	(B). To achieve maximum accuracy, we compute expm1(x) by
+ *	  (i)   if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
+ *	  (ii)  if k=0, return r-E
+ *	  (iii) if k=-1, return 0.5*(r-E)-0.5
+ *        (iv)	if k=1 if r < -0.25, return 2*((r+0.5)- E)
+ *	       	       else	     return  1.0+2.0*(r-E);
+ *	  (v)   if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
+ *	  (vi)  if k <= 20, return 2^k((1-2^-k)-(E-r)), else
+ *	  (vii) return 2^k(1-((E+2^-k)-r)) 
+ *
+ * Special cases:
+ *	expm1(INF) is INF, expm1(NaN) is NaN;
+ *	expm1(-INF) is -1, and
+ *	for finite argument, only expm1(0)=0 is exact.
+ *
+ * Accuracy:
+ *	according to an error analysis, the error is always less than
+ *	1 ulp (unit in the last place).
+ *
+ * Misc. info.
+ *	For IEEE double 
+ *	    if x >  7.09782712893383973096e+02 then expm1(x) overflow
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough
+ * to produce the hexadecimal values shown.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+one		= 1.0,
+really_big		= 1.0e+300,
+tiny		= 1.0e-300,
+o_threshold	= 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */
+ln2_hi		= 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */
+ln2_lo		= 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */
+invln2		= 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */
+	/* scaled coefficients related to expm1 */
+Q1  =  -3.33333333333331316428e-02, /* BFA11111 111110F4 */
+Q2  =   1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
+Q3  =  -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
+Q4  =   4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
+Q5  =  -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
+
+#ifdef __STDC__
+	double fd_expm1(double x)
+#else
+	double fd_expm1(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	double y,hi,lo,c,t,e,hxs,hfx,r1;
+	int k,xsb;
+	unsigned hx;
+
+        u.d = x;
+	hx  = __HI(u);	/* high word of x */
+	xsb = hx&0x80000000;		/* sign bit of x */
+	if(xsb==0) y=x; else y= -x;	/* y = |x| */
+	hx &= 0x7fffffff;		/* high word of |x| */
+
+    /* filter out huge and non-finite argument */
+	if(hx >= 0x4043687A) {			/* if |x|>=56*ln2 */
+	    if(hx >= 0x40862E42) {		/* if |x|>=709.78... */
+                if(hx>=0x7ff00000) {
+                    u.d = x;
+		    if(((hx&0xfffff)|__LO(u))!=0) 
+		         return x+x; 	 /* NaN */
+		    else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
+	        }
+	        if(x > o_threshold) return really_big*really_big; /* overflow */
+	    }
+	    if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */
+		if(x+tiny<0.0)		/* raise inexact */
+		return tiny-one;	/* return -1 */
+	    }
+	}
+
+    /* argument reduction */
+	if(hx > 0x3fd62e42) {		/* if  |x| > 0.5 ln2 */ 
+	    if(hx < 0x3FF0A2B2) {	/* and |x| < 1.5 ln2 */
+		if(xsb==0)
+		    {hi = x - ln2_hi; lo =  ln2_lo;  k =  1;}
+		else
+		    {hi = x + ln2_hi; lo = -ln2_lo;  k = -1;}
+	    } else {
+		k  = (int)(invln2*x+((xsb==0)?0.5:-0.5));
+		t  = k;
+		hi = x - t*ln2_hi;	/* t*ln2_hi is exact here */
+		lo = t*ln2_lo;
+	    }
+	    x  = hi - lo;
+	    c  = (hi-x)-lo;
+	} 
+	else if(hx < 0x3c900000) {  	/* when |x|<2**-54, return x */
+	    t = really_big+x;	/* return x with inexact flags when x!=0 */
+	    return x - (t-(really_big+x));	
+	}
+	else k = 0;
+
+    /* x is now in primary range */
+	hfx = 0.5*x;
+	hxs = x*hfx;
+	r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
+	t  = 3.0-r1*hfx;
+	e  = hxs*((r1-t)/(6.0 - x*t));
+	if(k==0) return x - (x*e-hxs);		/* c is 0 */
+	else {
+	    e  = (x*(e-c)-c);
+	    e -= hxs;
+	    if(k== -1) return 0.5*(x-e)-0.5;
+	    if(k==1) 
+	       	if(x < -0.25) return -2.0*(e-(x+0.5));
+	       	else 	      return  one+2.0*(x-e);
+	    if (k <= -2 || k>56) {   /* suffice to return exp(x)-1 */
+	        y = one-(e-x);
+                u.d = y;
+	        __HI(u) += (k<<20);	/* add k to y's exponent */
+                y = u.d;
+	        return y-one;
+	    }
+	    t = one;
+	    if(k<20) {
+                u.d = t;
+	       	__HI(u) = 0x3ff00000 - (0x200000>>k);  /* t=1-2^-k */
+                t = u.d;
+	       	y = t-(e-x);
+                u.d = y;
+	       	__HI(u) += (k<<20);	/* add k to y's exponent */
+                y = u.d;
+	   } else {
+               u.d = t;
+	       	__HI(u)  = ((0x3ff-k)<<20);	/* 2^-k */
+                t = u.d;
+	       	y = x-(e+t);
+	       	y += one;
+                u.d = y;
+	       	__HI(u) += (k<<20);	/* add k to y's exponent */
+                y = u.d;
+	    }
+	}
+	return y;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_fabs.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_fabs.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_fabs.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * fabs(x) returns the absolute value of x.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_fabs(double x)
+#else
+	double fd_fabs(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+        u.d = x;
+	__HI(u) &= 0x7fffffff;
+        x = u.d;
+        return x;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_finite.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_finite.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_finite.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * finite(x) returns 1 is x is finite, else 0;
+ * no branching!
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	int fd_finite(double x)
+#else
+	int fd_finite(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	int hx; 
+        u.d = x;
+	hx = __HI(u);
+	return  (unsigned)((hx&0x7fffffff)-0x7ff00000)>>31;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_floor.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_floor.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,121 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_floor.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * floor(x)
+ * Return x rounded toward -inf to integral value
+ * Method:
+ *	Bit twiddling.
+ * Exception:
+ *	Inexact flag raised if x not equal to floor(x).
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double really_big = 1.0e300;
+#else
+static double really_big = 1.0e300;
+#endif
+
+#ifdef __STDC__
+	double fd_floor(double x)
+#else
+	double fd_floor(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	int i0,i1,j0;
+	unsigned i,j;
+        u.d = x;
+	i0 =  __HI(u);
+	i1 =  __LO(u);
+	j0 = ((i0>>20)&0x7ff)-0x3ff;
+	if(j0<20) {
+	    if(j0<0) { 	/* raise inexact if x != 0 */
+		if(really_big+x>0.0) {/* return 0*sign(x) if |x|<1 */
+		    if(i0>=0) {i0=i1=0;} 
+		    else if(((i0&0x7fffffff)|i1)!=0)
+			{ i0=0xbff00000;i1=0;}
+		}
+	    } else {
+		i = (0x000fffff)>>j0;
+		if(((i0&i)|i1)==0) return x; /* x is integral */
+		if(really_big+x>0.0) {	/* raise inexact flag */
+		    if(i0<0) i0 += (0x00100000)>>j0;
+		    i0 &= (~i); i1=0;
+		}
+	    }
+	} else if (j0>51) {
+	    if(j0==0x400) return x+x;	/* inf or NaN */
+	    else return x;		/* x is integral */
+	} else {
+	    i = ((unsigned)(0xffffffff))>>(j0-20);
+	    if((i1&i)==0) return x;	/* x is integral */
+	    if(really_big+x>0.0) { 		/* raise inexact flag */
+		if(i0<0) {
+		    if(j0==20) i0+=1; 
+		    else {
+			j = i1+(1<<(52-j0));
+			if((int)j<i1) i0 +=1 ; 	/* got a carry */
+			i1=j;
+		    }
+		}
+		i1 &= (~i);
+	    }
+	}
+        u.d = x;
+	__HI(u) = i0;
+	__LO(u) = i1;
+        x = u.d;
+	return x;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_frexp.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_frexp.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,99 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_frexp.c 1.4 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * for non-zero x 
+ *	x = frexp(arg,&exp);
+ * return a double fp quantity x such that 0.5 <= |x| <1.0
+ * and the corresponding binary exponent "exp". That is
+ *	arg = x*2^exp.
+ * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg 
+ * with *exp=0. 
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54 =  1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
+
+#ifdef __STDC__
+	double fd_frexp(double x, int *eptr)
+#else
+	double fd_frexp(x, eptr)
+	double x; int *eptr;
+#endif
+{
+	int  hx, ix, lx;
+        fd_twoints u;
+        u.d = x;
+	hx = __HI(u);
+	ix = 0x7fffffff&hx;
+	lx = __LO(u);
+	*eptr = 0;
+	if(ix>=0x7ff00000||((ix|lx)==0)) return x;	/* 0,inf,nan */
+	if (ix<0x00100000) {		/* subnormal */
+	    x *= two54;
+            u.d = x;
+	    hx = __HI(u);
+	    ix = hx&0x7fffffff;
+	    *eptr = -54;
+	}
+	*eptr += (ix>>20)-1022;
+	hx = (hx&0x800fffff)|0x3fe00000;
+        u.d = x;
+	__HI(u) = hx;
+        x = u.d;
+	return x;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_ilogb.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_ilogb.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,85 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_ilogb.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* ilogb(double x)
+ * return the binary exponent of non-zero x
+ * ilogb(0) = 0x80000001
+ * ilogb(inf/NaN) = 0x7fffffff (no signal is raised)
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	int fd_ilogb(double x)
+#else
+	int fd_ilogb(x)
+	double x;
+#endif
+{
+	int hx,lx,ix;
+        fd_twoints u;
+        u.d = x;
+	hx  = (__HI(u))&0x7fffffff;	/* high word of x */
+	if(hx<0x00100000) {
+	    lx = __LO(u);
+	    if((hx|lx)==0) 
+		return 0x80000001;	/* ilogb(0) = 0x80000001 */
+	    else			/* subnormal x */
+		if(hx==0) {
+		    for (ix = -1043; lx>0; lx<<=1) ix -=1;
+		} else {
+		    for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
+		}
+	    return ix;
+	}
+	else if (hx<0x7ff00000) return (hx>>20)-1023;
+	else return 0x7fffffff;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_isnan.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_isnan.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,74 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_isnan.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * isnan(x) returns 1 is x is nan, else 0;
+ * no branching!
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	int fd_isnan(double x)
+#else
+	int fd_isnan(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	int hx,lx;
+        u.d = x;
+	hx = (__HI(u)&0x7fffffff);
+	lx = __LO(u);
+	hx |= (unsigned)(lx|(-lx))>>31;	
+	hx = 0x7ff00000 - hx;
+	return ((unsigned)(hx))>>31;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_ldexp.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_ldexp.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_ldexp.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+#include "fdlibm.h"
+#include <errno.h>
+
+#ifdef __STDC__
+	double fd_ldexp(double value, int exp)
+#else
+	double fd_ldexp(value, exp)
+	double value; int exp;
+#endif
+{
+	if(!fd_finite(value)||value==0.0) return value;
+	value = fd_scalbn(value,exp);
+	if(!fd_finite(value)||value==0.0) errno = ERANGE;
+	return value;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_lib_version.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_lib_version.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,73 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_lib_version.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * MACRO for standards
+ */
+
+#include "fdlibm.h"
+
+/*
+ * define and initialize _LIB_VERSION
+ */
+#ifdef _POSIX_MODE
+_LIB_VERSION_TYPE _LIB_VERSION = _POSIX_;
+#else
+#ifdef _XOPEN_MODE
+_LIB_VERSION_TYPE _LIB_VERSION = _XOPEN_;
+#else
+#ifdef _SVID3_MODE
+_LIB_VERSION_TYPE _LIB_VERSION = _SVID_;
+#else					/* default _IEEE_MODE */
+_LIB_VERSION_TYPE _LIB_VERSION = _IEEE_;
+#endif
+#endif
+#endif

Added: freeswitch/trunk/libs/js/src/fdlibm/s_log1p.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_log1p.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,211 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_log1p.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* double log1p(double x)
+ *
+ * Method :                  
+ *   1. Argument Reduction: find k and f such that 
+ *			1+x = 2^k * (1+f), 
+ *	   where  sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ *      Note. If k=0, then f=x is exact. However, if k!=0, then f
+ *	may not be representable exactly. In that case, a correction
+ *	term is need. Let u=1+x rounded. Let c = (1+x)-u, then
+ *	log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
+ *	and add back the correction term c/u.
+ *	(Note: when x > 2**53, one can simply return log(x))
+ *
+ *   2. Approximation of log1p(f).
+ *	Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ *		 = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ *	     	 = 2s + s*R
+ *      We use a special Reme algorithm on [0,0.1716] to generate 
+ * 	a polynomial of degree 14 to approximate R The maximum error 
+ *	of this polynomial approximation is bounded by 2**-58.45. In
+ *	other words,
+ *		        2      4      6      8      10      12      14
+ *	    R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s  +Lp6*s  +Lp7*s
+ *  	(the values of Lp1 to Lp7 are listed in the program)
+ *	and
+ *	    |      2          14          |     -58.45
+ *	    | Lp1*s +...+Lp7*s    -  R(z) | <= 2 
+ *	    |                             |
+ *	Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+ *	In order to guarantee error in log below 1ulp, we compute log
+ *	by
+ *		log1p(f) = f - (hfsq - s*(hfsq+R)).
+ *	
+ *	3. Finally, log1p(x) = k*ln2 + log1p(f).  
+ *		 	     = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+ *	   Here ln2 is split into two floating point number: 
+ *			ln2_hi + ln2_lo,
+ *	   where n*ln2_hi is always exact for |n| < 2000.
+ *
+ * Special cases:
+ *	log1p(x) is NaN with signal if x < -1 (including -INF) ; 
+ *	log1p(+INF) is +INF; log1p(-1) is -INF with signal;
+ *	log1p(NaN) is that NaN with no signal.
+ *
+ * Accuracy:
+ *	according to an error analysis, the error is always less than
+ *	1 ulp (unit in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following 
+ * constants. The decimal values may be used, provided that the 
+ * compiler will convert from decimal to binary accurately enough 
+ * to produce the hexadecimal values shown.
+ *
+ * Note: Assuming log() return accurate answer, the following
+ * 	 algorithm can be used to compute log1p(x) to within a few ULP:
+ *	
+ *		u = 1+x;
+ *		if(u==1.0) return x ; else
+ *			   return log(u)*(x/(u-1.0));
+ *
+ *	 See HP-15C Advanced Functions Handbook, p.193.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+ln2_hi  =  6.93147180369123816490e-01,	/* 3fe62e42 fee00000 */
+ln2_lo  =  1.90821492927058770002e-10,	/* 3dea39ef 35793c76 */
+two54   =  1.80143985094819840000e+16,  /* 43500000 00000000 */
+Lp1 = 6.666666666666735130e-01,  /* 3FE55555 55555593 */
+Lp2 = 3.999999999940941908e-01,  /* 3FD99999 9997FA04 */
+Lp3 = 2.857142874366239149e-01,  /* 3FD24924 94229359 */
+Lp4 = 2.222219843214978396e-01,  /* 3FCC71C5 1D8E78AF */
+Lp5 = 1.818357216161805012e-01,  /* 3FC74664 96CB03DE */
+Lp6 = 1.531383769920937332e-01,  /* 3FC39A09 D078C69F */
+Lp7 = 1.479819860511658591e-01;  /* 3FC2F112 DF3E5244 */
+
+static double zero = 0.0;
+
+#ifdef __STDC__
+	double fd_log1p(double x)
+#else
+	double fd_log1p(x)
+	double x;
+#endif
+{
+	double hfsq,f,c,s,z,R,u;
+	int k,hx,hu,ax;
+        fd_twoints un;
+
+        un.d = x;
+	hx = __HI(un);		/* high word of x */
+	ax = hx&0x7fffffff;
+
+	k = 1;
+	if (hx < 0x3FDA827A) {			/* x < 0.41422  */
+	    if(ax>=0x3ff00000) {		/* x <= -1.0 */
+		if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */
+		else return (x-x)/(x-x);	/* log1p(x<-1)=NaN */
+	    }
+	    if(ax<0x3e200000) {			/* |x| < 2**-29 */
+		if(two54+x>zero			/* raise inexact */
+	            &&ax<0x3c900000) 		/* |x| < 2**-54 */
+		    return x;
+		else
+		    return x - x*x*0.5;
+	    }
+	    if(hx>0||hx<=((int)0xbfd2bec3)) {
+		k=0;f=x;hu=1;}	/* -0.2929<x<0.41422 */
+	} 
+	if (hx >= 0x7ff00000) return x+x;
+	if(k!=0) {
+	    if(hx<0x43400000) {
+		u  = 1.0+x; 
+                un.d = u;
+	        hu = __HI(un);		/* high word of u */
+	        k  = (hu>>20)-1023;
+	        c  = (k>0)? 1.0-(u-x):x-(u-1.0);/* correction term */
+		c /= u;
+	    } else {
+		u  = x;
+                un.d = u;
+	        hu = __HI(un);		/* high word of u */
+	        k  = (hu>>20)-1023;
+		c  = 0;
+	    }
+	    hu &= 0x000fffff;
+	    if(hu<0x6a09e) {
+                un.d = u;
+	        __HI(un) = hu|0x3ff00000;	/* normalize u */
+                u = un.d;
+	    } else {
+	        k += 1; 
+                un.d = u;
+	        __HI(un) = hu|0x3fe00000;	/* normalize u/2 */
+                u = un.d;
+	        hu = (0x00100000-hu)>>2;
+	    }
+	    f = u-1.0;
+	}
+	hfsq=0.5*f*f;
+	if(hu==0) {	/* |f| < 2**-20 */
+	    if(f==zero) if(k==0) return zero;  
+			else {c += k*ln2_lo; return k*ln2_hi+c;}
+	    R = hfsq*(1.0-0.66666666666666666*f);
+	    if(k==0) return f-R; else
+	    	     return k*ln2_hi-((R-(k*ln2_lo+c))-f);
+	}
+ 	s = f/(2.0+f); 
+	z = s*s;
+	R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7))))));
+	if(k==0) return f-(hfsq-s*(hfsq+R)); else
+		 return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f);
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_logb.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_logb.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,79 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_logb.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * double logb(x)
+ * IEEE 754 logb. Included to pass IEEE test suite. Not recommend.
+ * Use ilogb instead.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_logb(double x)
+#else
+	double fd_logb(x)
+	double x;
+#endif
+{
+	int lx,ix;
+        fd_twoints u;
+
+        u.d = x;
+	ix = (__HI(u))&0x7fffffff;	/* high |x| */
+	lx = __LO(u);			/* low x */
+	if((ix|lx)==0) return -1.0/fd_fabs(x);
+	if(ix>=0x7ff00000) return x*x;
+	if((ix>>=20)==0) 			/* IEEE 754 logb */
+		return -1022.0; 
+	else
+		return (double) (ix-1023); 
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_matherr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_matherr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,64 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_matherr.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	int fd_matherr(struct exception *x)
+#else
+	int fd_matherr(x)
+	struct exception *x;
+#endif
+{
+	int n=0;
+	if(x->arg1!=x->arg1) return 0;
+	return n;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_modf.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_modf.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,132 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_modf.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * modf(double x, double *iptr) 
+ * return fraction part of x, and return x's integral part in *iptr.
+ * Method:
+ *	Bit twiddling.
+ *
+ * Exception:
+ *	No exception.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double one = 1.0;
+#else
+static double one = 1.0;
+#endif
+
+#ifdef __STDC__
+	double fd_modf(double x, double *iptr)
+#else
+	double fd_modf(x, iptr)
+	double x,*iptr;
+#endif
+{
+	int i0,i1,j0;
+	unsigned i;
+        fd_twoints u;
+        u.d = x;
+	i0 =  __HI(u);		/* high x */
+	i1 =  __LO(u);		/* low  x */
+	j0 = ((i0>>20)&0x7ff)-0x3ff;	/* exponent of x */
+	if(j0<20) {			/* integer part in high x */
+	    if(j0<0) {			/* |x|<1 */
+                u.d = *iptr;
+		__HI(u) = i0&0x80000000;
+		__LO(u) = 0;		/* *iptr = +-0 */
+                *iptr = u.d;
+		return x;
+	    } else {
+		i = (0x000fffff)>>j0;
+		if(((i0&i)|i1)==0) {		/* x is integral */
+		    *iptr = x;
+                    u.d = x;
+		    __HI(u) &= 0x80000000;
+		    __LO(u)  = 0;	/* return +-0 */
+                    x = u.d;
+		    return x;
+		} else {
+                    u.d = *iptr;
+		    __HI(u) = i0&(~i);
+		    __LO(u) = 0;
+                    *iptr = u.d;
+		    return x - *iptr;
+		}
+	    }
+	} else if (j0>51) {		/* no fraction part */
+	    *iptr = x*one;
+            u.d = x;
+	    __HI(u) &= 0x80000000;
+	    __LO(u)  = 0;	/* return +-0 */
+            x = u.d;
+	    return x;
+	} else {			/* fraction part in low x */
+	    i = ((unsigned)(0xffffffff))>>(j0-20);
+	    if((i1&i)==0) { 		/* x is integral */
+		*iptr = x;
+                u.d = x;
+		__HI(u) &= 0x80000000;
+		__LO(u)  = 0;	/* return +-0 */
+                x = u.d;
+		return x;
+	    } else {
+                u.d = *iptr;
+		__HI(u) = i0;
+		__LO(u) = i1&(~i);
+                *iptr = u.d;
+		return x - *iptr;
+	    }
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_nextafter.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_nextafter.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,124 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_nextafter.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* IEEE functions
+ *	nextafter(x,y)
+ *	return the next machine floating-point number of x in the
+ *	direction toward y.
+ *   Special cases:
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_nextafter(double x, double y)
+#else
+	double fd_nextafter(x,y)
+	double x,y;
+#endif
+{
+	int	hx,hy,ix,iy;
+	unsigned lx,ly;
+        fd_twoints ux, uy;
+
+        ux.d = x; uy.d = y;
+	hx = __HI(ux);		/* high word of x */
+	lx = __LO(ux);		/* low  word of x */
+	hy = __HI(uy);		/* high word of y */
+	ly = __LO(uy);		/* low  word of y */
+	ix = hx&0x7fffffff;		/* |x| */
+	iy = hy&0x7fffffff;		/* |y| */
+
+	if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */ 
+	   ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     /* y is nan */ 
+	   return x+y;				
+	if(x==y) return x;		/* x=y, return x */
+	if((ix|lx)==0) {			/* x == 0 */
+            ux.d = x;
+	    __HI(ux) = hy&0x80000000;	/* return +-minsubnormal */
+	    __LO(ux) = 1;
+            x = ux.d;
+	    y = x*x;
+	    if(y==x) return y; else return x;	/* raise underflow flag */
+	} 
+	if(hx>=0) {				/* x > 0 */
+	    if(hx>hy||((hx==hy)&&(lx>ly))) {	/* x > y, x -= ulp */
+		if(lx==0) hx -= 1;
+		lx -= 1;
+	    } else {				/* x < y, x += ulp */
+		lx += 1;
+		if(lx==0) hx += 1;
+	    }
+	} else {				/* x < 0 */
+	    if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
+		if(lx==0) hx -= 1;
+		lx -= 1;
+	    } else {				/* x > y, x += ulp */
+		lx += 1;
+		if(lx==0) hx += 1;
+	    }
+	}
+	hy = hx&0x7ff00000;
+	if(hy>=0x7ff00000) return x+x;	/* overflow  */
+	if(hy<0x00100000) {		/* underflow */
+	    y = x*x;
+	    if(y!=x) {		/* raise underflow flag */
+                uy.d = y;
+		__HI(uy) = hx; __LO(uy) = lx;
+                y = uy.d;
+		return y;
+	    }
+	}
+        ux.d = x;
+	__HI(ux) = hx; __LO(ux) = lx;
+        x = ux.d;
+	return x;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_rint.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_rint.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,131 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_rint.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * rint(x)
+ * Return x rounded to integral value according to the prevailing
+ * rounding mode.
+ * Method:
+ *	Using floating addition.
+ * Exception:
+ *	Inexact flag raised if x not equal to rint(x).
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double 
+#endif
+TWO52[2]={
+  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+};
+
+#ifdef __STDC__
+	double fd_rint(double x)
+#else
+	double fd_rint(x)
+	double x;
+#endif
+{
+	int i0,j0,sx;
+	unsigned i,i1;
+	double w,t;
+        fd_twoints u;
+
+        u.d = x;
+	i0 =  __HI(u);
+	sx = (i0>>31)&1;
+	i1 =  __LO(u);
+	j0 = ((i0>>20)&0x7ff)-0x3ff;
+	if(j0<20) {
+	    if(j0<0) { 	
+		if(((i0&0x7fffffff)|i1)==0) return x;
+		i1 |= (i0&0x0fffff);
+		i0 &= 0xfffe0000;
+		i0 |= ((i1|-(int)i1)>>12)&0x80000;
+                u.d = x;
+		__HI(u)=i0;
+                x = u.d;
+	        w = TWO52[sx]+x;
+	        t =  w-TWO52[sx];
+                u.d = t;
+	        i0 = __HI(u);
+	        __HI(u) = (i0&0x7fffffff)|(sx<<31);
+                t = u.d;
+	        return t;
+	    } else {
+		i = (0x000fffff)>>j0;
+		if(((i0&i)|i1)==0) return x; /* x is integral */
+		i>>=1;
+		if(((i0&i)|i1)!=0) {
+		    if(j0==19) i1 = 0x40000000; else
+		    i0 = (i0&(~i))|((0x20000)>>j0);
+		}
+	    }
+	} else if (j0>51) {
+	    if(j0==0x400) return x+x;	/* inf or NaN */
+	    else return x;		/* x is integral */
+	} else {
+	    i = ((unsigned)(0xffffffff))>>(j0-20);
+	    if((i1&i)==0) return x;	/* x is integral */
+	    i>>=1;
+	    if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
+	}
+        u.d = x;
+	__HI(u) = i0;
+	__LO(u) = i1;
+        x = u.d;
+	w = TWO52[sx]+x;
+	return w-TWO52[sx];
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_scalbn.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_scalbn.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,107 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_scalbn.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * scalbn (double x, int n)
+ * scalbn(x,n) returns x* 2**n  computed by  exponent  
+ * manipulation rather than by actually performing an 
+ * exponentiation or a multiplication.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+two54   =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
+twom54  =  5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
+really_big   = 1.0e+300,
+tiny   = 1.0e-300;
+
+#ifdef __STDC__
+	double fd_scalbn (double x, int n)
+#else
+	double fd_scalbn (x,n)
+	double x; int n;
+#endif
+{
+        fd_twoints u;
+	int  k,hx,lx;
+        u.d = x;
+	hx = __HI(u);
+	lx = __LO(u);
+        k = (hx&0x7ff00000)>>20;		/* extract exponent */
+        if (k==0) {				/* 0 or subnormal x */
+            if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
+	    x *= two54;
+            u.d = x;
+	    hx = __HI(u);
+	    k = ((hx&0x7ff00000)>>20) - 54; 
+            if (n< -50000) return tiny*x; 	/*underflow*/
+	    }
+        if (k==0x7ff) return x+x;		/* NaN or Inf */
+        k = k+n; 
+        if (k >  0x7fe) return really_big*fd_copysign(really_big,x); /* overflow  */
+        if (k > 0) 				/* normal result */
+	    {u.d = x; __HI(u) = (hx&0x800fffff)|(k<<20); x = u.d; return x;}
+        if (k <= -54) {
+            if (n > 50000) 	/* in case integer overflow in n+k */
+		return really_big*fd_copysign(really_big,x);	/*overflow*/
+	    else return tiny*fd_copysign(tiny,x); 	/*underflow*/
+        }
+        k += 54;				/* subnormal result */
+        u.d = x;
+        __HI(u) = (hx&0x800fffff)|(k<<20);
+        x = u.d;
+        return x*twom54;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_signgam.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_signgam.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "fdlibm.h"
+int signgam = 0;

Added: freeswitch/trunk/libs/js/src/fdlibm/s_significand.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_significand.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_significand.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * significand(x) computes just
+ * 	scalb(x, (double) -ilogb(x)),
+ * for exercising the fraction-part(F) IEEE 754-1985 test vector.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_significand(double x)
+#else
+	double fd_significand(x)
+	double x;
+#endif
+{
+	return __ieee754_scalb(x,(double) -fd_ilogb(x));
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_sin.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_sin.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,118 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_sin.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* sin(x)
+ * Return sine function of x.
+ *
+ * kernel function:
+ *	__kernel_sin		... sine function on [-pi/4,pi/4]
+ *	__kernel_cos		... cose function on [-pi/4,pi/4]
+ *	__ieee754_rem_pio2	... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on 
+ *	[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 
+ *	in [-pi/4 , +pi/4], and let n = k mod 4.
+ *	We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *	    0	       S	   C		 T
+ *	    1	       C	  -S		-1/T
+ *	    2	      -S	  -C		 T
+ *	    3	      -C	   S		-1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *	TRIG(x) returns trig(x) nearly rounded 
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_sin(double x)
+#else
+	double fd_sin(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	double y[2],z=0.0;
+	int n, ix;
+
+    /* High word of x. */
+        u.d = x;
+	ix = __HI(u);
+
+    /* |x| ~< pi/4 */
+	ix &= 0x7fffffff;
+	if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
+
+    /* sin(Inf or NaN) is NaN */
+	else if (ix>=0x7ff00000) return x-x;
+
+    /* argument reduction needed */
+	else {
+	    n = __ieee754_rem_pio2(x,y);
+	    switch(n&3) {
+		case 0: return  __kernel_sin(y[0],y[1],1);
+		case 1: return  __kernel_cos(y[0],y[1]);
+		case 2: return -__kernel_sin(y[0],y[1],1);
+		default:
+			return -__kernel_cos(y[0],y[1]);
+	    }
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_tan.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_tan.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,112 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_tan.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* tan(x)
+ * Return tangent function of x.
+ *
+ * kernel function:
+ *	__kernel_tan		... tangent function on [-pi/4,pi/4]
+ *	__ieee754_rem_pio2	... argument reduction routine
+ *
+ * Method.
+ *      Let S,C and T denote the sin, cos and tan respectively on 
+ *	[-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 
+ *	in [-pi/4 , +pi/4], and let n = k mod 4.
+ *	We have
+ *
+ *          n        sin(x)      cos(x)        tan(x)
+ *     ----------------------------------------------------------
+ *	    0	       S	   C		 T
+ *	    1	       C	  -S		-1/T
+ *	    2	      -S	  -C		 T
+ *	    3	      -C	   S		-1/T
+ *     ----------------------------------------------------------
+ *
+ * Special cases:
+ *      Let trig be any of sin, cos, or tan.
+ *      trig(+-INF)  is NaN, with signals;
+ *      trig(NaN)    is that NaN;
+ *
+ * Accuracy:
+ *	TRIG(x) returns trig(x) nearly rounded 
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_tan(double x)
+#else
+	double fd_tan(x)
+	double x;
+#endif
+{
+        fd_twoints u;
+	double y[2],z=0.0;
+	int n, ix;
+
+    /* High word of x. */
+        u.d = x;
+	ix = __HI(u);
+
+    /* |x| ~< pi/4 */
+	ix &= 0x7fffffff;
+	if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1);
+
+    /* tan(Inf or NaN) is NaN */
+	else if (ix>=0x7ff00000) return x-x;		/* NaN */
+
+    /* argument reduction needed */
+	else {
+	    n = __ieee754_rem_pio2(x,y);
+	    return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /*   1 -- n even
+							-1 -- n odd */
+	}
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/s_tanh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/s_tanh.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,122 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)s_tanh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* Tanh(x)
+ * Return the Hyperbolic Tangent of x
+ *
+ * Method :
+ *				       x    -x
+ *				      e  - e
+ *	0. tanh(x) is defined to be -----------
+ *				       x    -x
+ *				      e  + e
+ *	1. reduce x to non-negative by tanh(-x) = -tanh(x).
+ *	2.  0      <= x <= 2**-55 : tanh(x) := x*(one+x)
+ *					        -t
+ *	    2**-55 <  x <=  1     : tanh(x) := -----; t = expm1(-2x)
+ *					       t + 2
+ *						     2
+ *	    1      <= x <=  22.0  : tanh(x) := 1-  ----- ; t=expm1(2x)
+ *						   t + 2
+ *	    22.0   <  x <= INF    : tanh(x) := 1.
+ *
+ * Special cases:
+ *	tanh(NaN) is NaN;
+ *	only tanh(0)=0 is exact for finite argument.
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double one=1.0, two=2.0, tiny = 1.0e-300;
+#else
+static double one=1.0, two=2.0, tiny = 1.0e-300;
+#endif
+
+#ifdef __STDC__
+	double fd_tanh(double x)
+#else
+	double fd_tanh(x)
+	double x;
+#endif
+{
+	double t,z;
+	int jx,ix;
+        fd_twoints u;
+
+    /* High word of |x|. */
+        u.d = x;
+	jx = __HI(u);
+	ix = jx&0x7fffffff;
+
+    /* x is INF or NaN */
+	if(ix>=0x7ff00000) { 
+	    if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
+	    else       return one/x-one;    /* tanh(NaN) = NaN */
+	}
+
+    /* |x| < 22 */
+	if (ix < 0x40360000) {		/* |x|<22 */
+	    if (ix<0x3c800000) 		/* |x|<2**-55 */
+		return x*(one+x);    	/* tanh(small) = small */
+	    if (ix>=0x3ff00000) {	/* |x|>=1  */
+		t = fd_expm1(two*fd_fabs(x));
+		z = one - two/(t+two);
+	    } else {
+	        t = fd_expm1(-two*fd_fabs(x));
+	        z= -t/(t+two);
+	    }
+    /* |x| > 22, return +-1 */
+	} else {
+	    z = one - tiny;		/* raised inexact flag */
+	}
+	return (jx>=0)? z: -z;
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_acos.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_acos.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_acos.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * wrap_acos(x)
+ */
+
+#include "fdlibm.h"
+
+
+#ifdef __STDC__
+	double fd_acos(double x)		/* wrapper acos */
+#else
+	double fd_acos(x)			/* wrapper acos */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_acos(x);
+#else
+	double z;
+	z = __ieee754_acos(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
+	if(fd_fabs(x)>1.0) {
+        int err;
+        return __kernel_standard(x,x,1,&err); /* acos(|x|>1) */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_acosh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_acosh.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_acosh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* 
+ * wrapper acosh(x)
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_acosh(double x)		/* wrapper acosh */
+#else
+	double fd_acosh(x)			/* wrapper acosh */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_acosh(x);
+#else
+	double z;
+	z = __ieee754_acosh(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
+	if(x<1.0) {
+        int err;
+        return __kernel_standard(x,x,29,&err); /* acosh(x<1) */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_asin.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_asin.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,80 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_asin.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* 
+ * wrapper asin(x)
+ */
+
+
+#include "fdlibm.h"
+
+
+#ifdef __STDC__
+	double fd_asin(double x)		/* wrapper asin */
+#else
+	double fd_asin(x)			/* wrapper asin */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_asin(x);
+#else
+	double z;
+	z = __ieee754_asin(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
+	if(fd_fabs(x)>1.0) {
+        int err;
+        return __kernel_standard(x,x,2,&err); /* asin(|x|>1) */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_atan2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_atan2.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,79 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_atan2.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* 
+ * wrapper atan2(y,x)
+ */
+
+#include "fdlibm.h"
+
+
+#ifdef __STDC__
+	double fd_atan2(double y, double x)	/* wrapper atan2 */
+#else
+	double fd_atan2(y,x)			/* wrapper atan2 */
+	double y,x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_atan2(y,x);
+#else
+	double z;
+	z = __ieee754_atan2(y,x);
+	if(_LIB_VERSION == _IEEE_||fd_isnan(x)||fd_isnan(y)) return z;
+	if(x==0.0&&y==0.0) {
+        int err;
+        return __kernel_standard(y,x,3,&err); /* atan2(+-0,+-0) */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_atanh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_atanh.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_atanh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+/* 
+ * wrapper atanh(x)
+ */
+
+#include "fdlibm.h"
+
+
+#ifdef __STDC__
+	double fd_atanh(double x)		/* wrapper atanh */
+#else
+	double fd_atanh(x)			/* wrapper atanh */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_atanh(x);
+#else
+	double z,y;
+	z = __ieee754_atanh(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
+	y = fd_fabs(x);
+	if(y>=1.0) {
+        int err;
+	    if(y>1.0)
+	        return __kernel_standard(x,x,30,&err); /* atanh(|x|>1) */
+	    else 
+	        return __kernel_standard(x,x,31,&err); /* atanh(|x|==1) */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_cosh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_cosh.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,77 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_cosh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * wrapper cosh(x)
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_cosh(double x)		/* wrapper cosh */
+#else
+	double fd_cosh(x)			/* wrapper cosh */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_cosh(x);
+#else
+	double z;
+	z = __ieee754_cosh(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
+	if(fd_fabs(x)>7.10475860073943863426e+02) {	
+        int err;
+        return __kernel_standard(x,x,5,&err); /* cosh overflow */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_exp.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_exp.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,88 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_exp.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * wrapper exp(x)
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+static const double
+#else
+static double
+#endif
+o_threshold=  7.09782712893383973096e+02,  /* 0x40862E42, 0xFEFA39EF */
+u_threshold= -7.45133219101941108420e+02;  /* 0xc0874910, 0xD52D3051 */
+
+#ifdef __STDC__
+	double fd_exp(double x)		/* wrapper exp */
+#else
+	double fd_exp(x)			/* wrapper exp */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_exp(x);
+#else
+	double z;
+	z = __ieee754_exp(x);
+	if(_LIB_VERSION == _IEEE_) return z;
+	if(fd_finite(x)) {
+        int err;
+	    if(x>o_threshold)
+	        return __kernel_standard(x,x,6,&err); /* exp overflow */
+	    else if(x<u_threshold)
+	        return __kernel_standard(x,x,7,&err); /* exp underflow */
+	} 
+	return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_fmod.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_fmod.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_fmod.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * wrapper fmod(x,y)
+ */
+
+#include "fdlibm.h"
+
+
+#ifdef __STDC__
+	double fd_fmod(double x, double y)	/* wrapper fmod */
+#else
+	double fd_fmod(x,y)		/* wrapper fmod */
+	double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_fmod(x,y);
+#else
+	double z;
+	z = __ieee754_fmod(x,y);
+	if(_LIB_VERSION == _IEEE_ ||fd_isnan(y)||fd_isnan(x)) return z;
+	if(y==0.0) {
+        int err;
+        return __kernel_standard(x,y,27,&err); /* fmod(x,0) */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_gamma.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_gamma.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,85 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_gamma.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* double gamma(double x)
+ * Return the logarithm of the Gamma function of x.
+ *
+ * Method: call gamma_r
+ */
+
+#include "fdlibm.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+	double fd_gamma(double x)
+#else
+	double fd_gamma(x)
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_gamma_r(x,&signgam);
+#else
+        double y;
+        y = __ieee754_gamma_r(x,&signgam);
+        if(_LIB_VERSION == _IEEE_) return y;
+        if(!fd_finite(y)&&fd_finite(x)) {
+            int err;
+            if(fd_floor(x)==x&&x<=0.0)
+                return __kernel_standard(x,x,41,&err); /* gamma pole */
+            else
+                return __kernel_standard(x,x,40,&err); /* gamma overflow */
+        } else
+            return y;
+#endif
+}             

Added: freeswitch/trunk/libs/js/src/fdlibm/w_gamma_r.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_gamma_r.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_gamma_r.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * wrapper double gamma_r(double x, int *signgamp)
+ */
+
+#include "fdlibm.h"
+
+
+#ifdef __STDC__
+	double fd_gamma_r(double x, int *signgamp) /* wrapper lgamma_r */
+#else
+	double fd_gamma_r(x,signgamp)              /* wrapper lgamma_r */
+        double x; int *signgamp;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_gamma_r(x,signgamp);
+#else
+        double y;
+        y = __ieee754_gamma_r(x,signgamp);
+        if(_LIB_VERSION == _IEEE_) return y;
+        if(!fd_finite(y)&&fd_finite(x)) {
+            int err;
+            if(fd_floor(x)==x&&x<=0.0)
+                return __kernel_standard(x,x,41,&err); /* gamma pole */
+            else
+                return __kernel_standard(x,x,40,&err); /* gamma overflow */
+        } else
+            return y;
+#endif
+}             

Added: freeswitch/trunk/libs/js/src/fdlibm/w_hypot.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_hypot.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_hypot.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * wrapper hypot(x,y)
+ */
+
+#include "fdlibm.h"
+
+
+#ifdef __STDC__
+	double fd_hypot(double x, double y)/* wrapper hypot */
+#else
+	double fd_hypot(x,y)		/* wrapper hypot */
+	double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_hypot(x,y);
+#else
+	double z;
+	z = __ieee754_hypot(x,y);
+	if(_LIB_VERSION == _IEEE_) return z;
+	if((!fd_finite(z))&&fd_finite(x)&&fd_finite(y)) { 
+        int err;
+	    return __kernel_standard(x,y,4,&err); /* hypot overflow */
+    } else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_j0.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_j0.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,105 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_j0.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * wrapper j0(double x), y0(double x)
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_j0(double x)		/* wrapper j0 */
+#else
+	double fd_j0(x)			/* wrapper j0 */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_j0(x);
+#else
+	double z = __ieee754_j0(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
+	if(fd_fabs(x)>X_TLOSS) {
+        int err;
+        return __kernel_standard(x,x,34,&err); /* j0(|x|>X_TLOSS) */
+	} else
+	    return z;
+#endif
+}
+
+#ifdef __STDC__
+	double y0(double x)		/* wrapper y0 */
+#else
+	double y0(x)			/* wrapper y0 */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_y0(x);
+#else
+	double z;
+    int err;
+	z = __ieee754_y0(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z;
+        if(x <= 0.0){
+                if(x==0.0)
+                    /* d= -one/(x-x); */
+                    return __kernel_standard(x,x,8,&err);
+                else
+                    /* d = zero/(x-x); */
+                    return __kernel_standard(x,x,9,&err);
+        }
+	if(x>X_TLOSS) {
+	        return __kernel_standard(x,x,35,&err); /* y0(x>X_TLOSS) */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_j1.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_j1.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,106 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_j1.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * wrapper of j1,y1 
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_j1(double x)		/* wrapper j1 */
+#else
+	double fd_j1(x)			/* wrapper j1 */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_j1(x);
+#else
+	double z;
+	z = __ieee754_j1(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z;
+	if(fd_fabs(x)>X_TLOSS) {
+        int err;
+        return __kernel_standard(x,x,36,&err); /* j1(|x|>X_TLOSS) */
+	} else
+	    return z;
+#endif
+}
+
+#ifdef __STDC__
+	double y1(double x)		/* wrapper y1 */
+#else
+	double y1(x)			/* wrapper y1 */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_y1(x);
+#else
+	double z;
+    int err;
+	z = __ieee754_y1(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z;
+        if(x <= 0.0){
+                if(x==0.0)
+                    /* d= -one/(x-x); */
+                    return __kernel_standard(x,x,10,&err);
+                else
+                    /* d = zero/(x-x); */
+                    return __kernel_standard(x,x,11,&err);
+        }
+	if(x>X_TLOSS) {
+	        return __kernel_standard(x,x,37,&err); /* y1(x>X_TLOSS) */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_jn.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_jn.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,128 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_jn.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * wrapper jn(int n, double x), yn(int n, double x)
+ * floating point Bessel's function of the 1st and 2nd kind
+ * of order n
+ *          
+ * Special cases:
+ *	y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
+ *	y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
+ * Note 2. About jn(n,x), yn(n,x)
+ *	For n=0, j0(x) is called,
+ *	for n=1, j1(x) is called,
+ *	for n<x, forward recursion us used starting
+ *	from values of j0(x) and j1(x).
+ *	for n>x, a continued fraction approximation to
+ *	j(n,x)/j(n-1,x) is evaluated and then backward
+ *	recursion is used starting from a supposed value
+ *	for j(n,x). The resulting value of j(0,x) is
+ *	compared with the actual value to correct the
+ *	supposed value of j(n,x).
+ *
+ *	yn(n,x) is similar in all respects, except
+ *	that forward recursion is used for all
+ *	values of n>1.
+ *	
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_jn(int n, double x)	/* wrapper jn */
+#else
+	double fd_jn(n,x)			/* wrapper jn */
+	double x; int n;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_jn(n,x);
+#else
+	double z;
+	z = __ieee754_jn(n,x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z;
+	if(fd_fabs(x)>X_TLOSS) {
+        int err;
+	    return __kernel_standard((double)n,x,38,&err); /* jn(|x|>X_TLOSS,n) */
+	} else
+	    return z;
+#endif
+}
+
+#ifdef __STDC__
+	double yn(int n, double x)	/* wrapper yn */
+#else
+	double yn(n,x)			/* wrapper yn */
+	double x; int n;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_yn(n,x);
+#else
+	double z;
+    int err;
+	z = __ieee754_yn(n,x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z;
+        if(x <= 0.0){
+                if(x==0.0)
+                    /* d= -one/(x-x); */
+                    return __kernel_standard((double)n,x,12,&err);
+                else
+                    /* d = zero/(x-x); */
+                    return __kernel_standard((double)n,x,13,&err);
+        }
+	if(x>X_TLOSS) {
+	    return __kernel_standard((double)n,x,39,&err); /* yn(x>X_TLOSS,n) */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_lgamma.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_lgamma.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,85 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_lgamma.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ *
+ */
+
+/* double lgamma(double x)
+ * Return the logarithm of the Gamma function of x.
+ *
+ * Method: call __ieee754_lgamma_r
+ */
+
+#include "fdlibm.h"
+
+extern int signgam;
+
+#ifdef __STDC__
+	double fd_lgamma(double x)
+#else
+	double fd_lgamma(x)
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_lgamma_r(x,&signgam);
+#else
+        double y;
+        y = __ieee754_lgamma_r(x,&signgam);
+        if(_LIB_VERSION == _IEEE_) return y;
+        if(!fd_finite(y)&&fd_finite(x)) {
+            int err;
+            if(fd_floor(x)==x&&x<=0.0)
+                return __kernel_standard(x,x,15,&err); /* lgamma pole */
+            else
+                return __kernel_standard(x,x,14,&err); /* lgamma overflow */
+        } else
+            return y;
+#endif
+}             

Added: freeswitch/trunk/libs/js/src/fdlibm/w_lgamma_r.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_lgamma_r.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_lgamma_r.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * wrapper double lgamma_r(double x, int *signgamp)
+ */
+
+#include "fdlibm.h"
+
+
+#ifdef __STDC__
+	double fd_lgamma_r(double x, int *signgamp) /* wrapper lgamma_r */
+#else
+	double fd_lgamma_r(x,signgamp)              /* wrapper lgamma_r */
+        double x; int *signgamp;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_lgamma_r(x,signgamp);
+#else
+        double y;
+        y = __ieee754_lgamma_r(x,signgamp);
+        if(_LIB_VERSION == _IEEE_) return y;
+        if(!fd_finite(y)&&fd_finite(x)) {
+            int err;
+            if(fd_floor(x)==x&&x<=0.0)
+                return __kernel_standard(x,x,15,&err); /* lgamma pole */
+            else
+                return __kernel_standard(x,x,14,&err); /* lgamma overflow */
+        } else
+            return y;
+#endif
+}             

Added: freeswitch/trunk/libs/js/src/fdlibm/w_log.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_log.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_log.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * wrapper log(x)
+ */
+
+#include "fdlibm.h"
+
+
+#ifdef __STDC__
+	double fd_log(double x)		/* wrapper log */
+#else
+	double fd_log(x)			/* wrapper log */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_log(x);
+#else
+	double z;
+    int err;
+	z = __ieee754_log(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x) || x > 0.0) return z;
+	if(x==0.0)
+	    return __kernel_standard(x,x,16,&err); /* log(0) */
+	else 
+	    return __kernel_standard(x,x,17,&err); /* log(x<0) */
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_log10.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_log10.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_log10.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * wrapper log10(X)
+ */
+
+#include "fdlibm.h"
+
+
+#ifdef __STDC__
+	double fd_log10(double x)		/* wrapper log10 */
+#else
+	double fd_log10(x)			/* wrapper log10 */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_log10(x);
+#else
+	double z;
+	z = __ieee754_log10(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
+	if(x<=0.0) {
+        int err;
+	    if(x==0.0)
+	        return __kernel_standard(x,x,18,&err); /* log10(0) */
+	    else 
+	        return __kernel_standard(x,x,19,&err); /* log10(x<0) */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_pow.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_pow.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,99 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/* @(#)w_pow.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * wrapper pow(x,y) return x**y
+ */
+
+#include "fdlibm.h"
+
+
+#ifdef __STDC__
+	double fd_pow(double x, double y)	/* wrapper pow */
+#else
+	double fd_pow(x,y)			/* wrapper pow */
+	double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return  __ieee754_pow(x,y);
+#else
+	double z;
+    int err;
+	z=__ieee754_pow(x,y);
+	if(_LIB_VERSION == _IEEE_|| fd_isnan(y)) return z;
+	if(fd_isnan(x)) {
+	    if(y==0.0) 
+	        return __kernel_standard(x,y,42,&err); /* pow(NaN,0.0) */
+	    else 
+		return z;
+	}
+	if(x==0.0){ 
+	    if(y==0.0)
+	        return __kernel_standard(x,y,20,&err); /* pow(0.0,0.0) */
+	    if(fd_finite(y)&&y<0.0)
+	        return __kernel_standard(x,y,23,&err); /* pow(0.0,negative) */
+	    return z;
+	}
+	if(!fd_finite(z)) {
+	    if(fd_finite(x)&&fd_finite(y)) {
+	        if(fd_isnan(z))
+	            return __kernel_standard(x,y,24,&err); /* pow neg**non-int */
+	        else 
+	            return __kernel_standard(x,y,21,&err); /* pow overflow */
+	    }
+	} 
+	if(z==0.0&&fd_finite(x)&&fd_finite(y))
+	    return __kernel_standard(x,y,22,&err); /* pow underflow */
+	return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_remainder.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_remainder.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,77 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_remainder.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * wrapper remainder(x,p)
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_remainder(double x, double y)	/* wrapper remainder */
+#else
+	double fd_remainder(x,y)			/* wrapper remainder */
+	double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_remainder(x,y);
+#else
+	double z;
+	z = __ieee754_remainder(x,y);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(y)) return z;
+	if(y==0.0) {
+	    int err;
+	    return __kernel_standard(x,y,28,&err); /* remainder(x,0) */
+    } else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_scalb.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_scalb.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,95 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_scalb.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * wrapper scalb(double x, double fn) is provide for
+ * passing various standard test suite. One 
+ * should use scalbn() instead.
+ */
+
+#include "fdlibm.h"
+
+#include <errno.h>
+
+#ifdef __STDC__
+#ifdef _SCALB_INT
+	double fd_scalb(double x, int fn)		/* wrapper scalb */
+#else
+	double fd_scalb(double x, double fn)	/* wrapper scalb */
+#endif
+#else
+	double fd_scalb(x,fn)			/* wrapper scalb */
+#ifdef _SCALB_INT
+	double x; int fn;
+#else
+	double x,fn;
+#endif
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_scalb(x,fn);
+#else
+	double z;
+    int err;
+	z = __ieee754_scalb(x,fn);
+	if(_LIB_VERSION == _IEEE_) return z;
+	if(!(fd_finite(z)||fd_isnan(z))&&fd_finite(x)) {
+	    return __kernel_standard(x,(double)fn,32,&err); /* scalb overflow */
+	}
+	if(z==0.0&&z!=x) {
+	    return __kernel_standard(x,(double)fn,33,&err); /* scalb underflow */
+	} 
+#ifndef _SCALB_INT
+	if(!fd_finite(fn)) errno = ERANGE;
+#endif
+	return z;
+#endif 
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_sinh.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_sinh.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,77 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_sinh.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * wrapper sinh(x)
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_sinh(double x)		/* wrapper sinh */
+#else
+	double fd_sinh(x)			/* wrapper sinh */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_sinh(x);
+#else
+	double z; 
+	z = __ieee754_sinh(x);
+	if(_LIB_VERSION == _IEEE_) return z;
+	if(!fd_finite(z)&&fd_finite(x)) {
+        int err;
+	    return __kernel_standard(x,x,25,&err); /* sinh overflow */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/fdlibm/w_sqrt.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/fdlibm/w_sqrt.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,77 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Sun Microsystems, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* @(#)w_sqrt.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+ * wrapper sqrt(x)
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+	double fd_sqrt(double x)		/* wrapper sqrt */
+#else
+	double fd_sqrt(x)			/* wrapper sqrt */
+	double x;
+#endif
+{
+#ifdef _IEEE_LIBM
+	return __ieee754_sqrt(x);
+#else
+	double z;
+	z = __ieee754_sqrt(x);
+	if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z;
+	if(x<0.0) {
+	    int err;
+	    return __kernel_standard(x,x,26,&err); /* sqrt(negative) */
+	} else
+	    return z;
+#endif
+}

Added: freeswitch/trunk/libs/js/src/js.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/js.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2639 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS shell.
+ */
+#include "jsstddef.h"
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsarena.h"
+#include "jsutil.h"
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsdbgapi.h"
+#include "jsemit.h"
+#include "jsfun.h"
+#include "jsgc.h"
+#include "jslock.h"
+#include "jsobj.h"
+#include "jsparse.h"
+#include "jsscope.h"
+#include "jsscript.h"
+
+#ifdef OSSP
+#if defined(JS_HAS_FILE_OBJECT) && (JS_HAS_FILE_OBJECT - 0) /* OSSP BUGFIX */
+#include "jsfile.h"
+#endif
+#if defined(JS_HAS_DSO_OBJECT) && (JS_HAS_DSO_OBJECT -0)
+#include "jsdso.h"
+#endif
+#endif
+
+#ifdef PERLCONNECT
+#include "perlconnect/jsperl.h"
+#endif
+
+#ifdef LIVECONNECT
+#include "jsjava.h"
+#endif
+
+#ifdef JSDEBUGGER
+#include "jsdebug.h"
+#ifdef JSDEBUGGER_JAVA_UI
+#include "jsdjava.h"
+#endif /* JSDEBUGGER_JAVA_UI */
+#ifdef JSDEBUGGER_C_UI
+#include "jsdb.h"
+#endif /* JSDEBUGGER_C_UI */
+#endif /* JSDEBUGGER */
+
+#ifdef XP_UNIX
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#endif
+
+#if defined(XP_WIN) || defined(XP_OS2)
+#include <io.h>     /* for isatty() */
+#endif
+
+#define EXITCODE_RUNTIME_ERROR 3
+#define EXITCODE_FILE_NOT_FOUND 4
+
+size_t gStackChunkSize = 8192;
+static size_t gMaxStackSize = 0;
+static jsuword gStackBase;
+int gExitCode = 0;
+JSBool gQuitting = JS_FALSE;
+FILE *gErrFile = NULL;
+FILE *gOutFile = NULL;
+
+#ifdef JSDEBUGGER
+static JSDContext *_jsdc;
+#ifdef JSDEBUGGER_JAVA_UI
+static JSDJContext *_jsdjc;
+#endif /* JSDEBUGGER_JAVA_UI */
+#endif /* JSDEBUGGER */
+
+static JSBool reportWarnings = JS_TRUE;
+static JSBool compileOnly = JS_FALSE;
+
+typedef enum JSShellErrNum {
+#define MSG_DEF(name, number, count, exception, format) \
+    name = number,
+#include "jsshell.msg"
+#undef MSG_DEF
+    JSShellErr_Limit
+#undef MSGDEF
+} JSShellErrNum;
+
+static const JSErrorFormatString *
+my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
+
+#ifdef EDITLINE
+extern char     *readline(const char *prompt);
+extern void     add_history(char *line);
+#endif
+
+static JSBool
+GetLine(JSContext *cx, char *bufp, FILE *file, const char *prompt) {
+#ifdef EDITLINE
+    /*
+     * Use readline only if file is stdin, because there's no way to specify
+     * another handle.  Are other filehandles interactive?
+     */
+    if (file == stdin) {
+        char *linep = readline(prompt);
+        if (!linep)
+            return JS_FALSE;
+        if (linep[0] != '\0')
+            add_history(linep);
+        strcpy(bufp, linep);
+        JS_free(cx, linep);
+        bufp += strlen(bufp);
+        *bufp++ = '\n';
+        *bufp = '\0';
+    } else
+#endif
+    {
+        char line[256];
+        fprintf(gOutFile, prompt);
+        fflush(gOutFile);
+        if (!fgets(line, sizeof line, file))
+            return JS_FALSE;
+        strcpy(bufp, line);
+    }
+    return JS_TRUE;
+}
+
+static void
+Process(JSContext *cx, JSObject *obj, char *filename)
+{
+    JSBool ok, hitEOF;
+    JSScript *script;
+    jsval result;
+    JSString *str;
+    char buffer[4096];
+    char *bufp;
+    int lineno;
+    int startline;
+    FILE *file;
+    jsuword stackLimit;
+
+    if (!filename || strcmp(filename, "-") == 0) {
+        file = stdin;
+    } else {
+        file = fopen(filename, "r");
+        if (!file) {
+            JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
+                                 JSSMSG_CANT_OPEN, filename, strerror(errno));
+            gExitCode = EXITCODE_FILE_NOT_FOUND;
+            return;
+        }
+    }
+
+    if (gMaxStackSize == 0) {
+        /*
+         * Disable checking for stack overflow if limit is zero.
+         */
+        stackLimit = 0;
+    } else {
+#if JS_STACK_GROWTH_DIRECTION > 0
+        stackLimit = gStackBase + gMaxStackSize;
+#else
+        stackLimit = gStackBase - gMaxStackSize;
+#endif
+    }
+    JS_SetThreadStackLimit(cx, stackLimit);
+
+#if defined(OSSP) && defined(XP_WIN)
+    if (filename) {
+#else
+    if (!isatty(fileno(file))) {
+#endif
+        /*
+         * It's not interactive - just execute it.
+         *
+         * Support the UNIX #! shell hack; gobble the first line if it starts
+         * with '#'.  TODO - this isn't quite compatible with sharp variables,
+         * as a legal js program (using sharp variables) might start with '#'.
+         * But that would require multi-character lookahead.
+         */
+        int ch = fgetc(file);
+        if (ch == '#') {
+            while((ch = fgetc(file)) != EOF) {
+                if (ch == '\n' || ch == '\r')
+                    break;
+            }
+        }
+        ungetc(ch, file);
+        script = JS_CompileFileHandle(cx, obj, filename, file);
+        if (script) {
+            if (!compileOnly)
+                (void)JS_ExecuteScript(cx, obj, script, &result);
+            JS_DestroyScript(cx, script);
+        }
+        return;
+    }
+
+    /* It's an interactive filehandle; drop into read-eval-print loop. */
+    lineno = 1;
+    hitEOF = JS_FALSE;
+    do {
+        bufp = buffer;
+        *bufp = '\0';
+
+        /*
+         * Accumulate lines until we get a 'compilable unit' - one that either
+         * generates an error (before running out of source) or that compiles
+         * cleanly.  This should be whenever we get a complete statement that
+         * coincides with the end of a line.
+         */
+        startline = lineno;
+        do {
+            if (!GetLine(cx, bufp, file, startline == lineno ? "js> " : "")) {
+                hitEOF = JS_TRUE;
+                break;
+            }
+            bufp += strlen(bufp);
+            lineno++;
+        } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer)));
+
+        /* Clear any pending exception from previous failed compiles.  */
+        JS_ClearPendingException(cx);
+        script = JS_CompileScript(cx, obj, buffer, strlen(buffer), "typein",
+                                  startline);
+        if (script) {
+            if (!compileOnly) {
+                ok = JS_ExecuteScript(cx, obj, script, &result);
+                if (ok && result != JSVAL_VOID) {
+                    str = JS_ValueToString(cx, result);
+                    if (str)
+                        fprintf(gOutFile, "%s\n", JS_GetStringBytes(str));
+                    else
+                        ok = JS_FALSE;
+                }
+            }
+            JS_DestroyScript(cx, script);
+        }
+    } while (!hitEOF && !gQuitting);
+    fprintf(gOutFile, "\n");
+    return;
+}
+
+static int
+usage(void)
+{
+    fprintf(gErrFile, "%s\n", JS_GetImplementationVersion());
+    fprintf(gErrFile, "usage: js [-PswWxC] [-b branchlimit] [-c stackchunksize] [-v version] [-f scriptfile] [-e script] [-S maxstacksize] [scriptfile] [scriptarg...]\n");
+    return 2;
+}
+
+static uint32 gBranchCount;
+static uint32 gBranchLimit;
+
+static JSBool
+my_BranchCallback(JSContext *cx, JSScript *script)
+{
+    if (++gBranchCount == gBranchLimit) {
+        if (script) {
+            if (script->filename)
+                fprintf(gErrFile, "%s:", script->filename);
+            fprintf(gErrFile, "%u: script branch callback (%u callbacks)\n",
+                    script->lineno, gBranchLimit);
+        } else {
+            fprintf(gErrFile, "native branch callback (%u callbacks)\n",
+                    gBranchLimit);
+        }
+        gBranchCount = 0;
+        return JS_FALSE;
+    }
+    if ((gBranchCount & 0x3fff) == 1)
+        JS_MaybeGC(cx);
+    return JS_TRUE;
+}
+
+extern JSClass global_class;
+
+static int
+ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
+{
+    int i, j, length;
+    JSObject *argsObj;
+    char *filename = NULL;
+    JSBool isInteractive = JS_TRUE;
+
+    /*
+     * Scan past all optional arguments so we can create the arguments object
+     * before processing any -f options, which must interleave properly with
+     * -v and -w options.  This requires two passes, and without getopt, we'll
+     * have to keep the option logic here and in the second for loop in sync.
+     */
+    for (i = 0; i < argc; i++) {
+        if (argv[i][0] != '-' || argv[i][1] == '\0') {
+            ++i;
+            break;
+        }
+        switch (argv[i][1]) {
+          case 'b':
+          case 'c':
+          case 'f':
+          case 'e':
+          case 'v':
+          case 'S':
+            ++i;
+            break;
+          default:;
+        }
+    }
+
+    /*
+     * Create arguments early and define it to root it, so it's safe from any
+     * GC calls nested below, and so it is available to -f <file> arguments.
+     */
+    argsObj = JS_NewArrayObject(cx, 0, NULL);
+    if (!argsObj)
+        return 1;
+    if (!JS_DefineProperty(cx, obj, "arguments", OBJECT_TO_JSVAL(argsObj),
+                           NULL, NULL, 0)) {
+        return 1;
+    }
+
+    length = argc - i;
+    for (j = 0; j < length; j++) {
+        JSString *str = JS_NewStringCopyZ(cx, argv[i++]);
+        if (!str)
+            return 1;
+        if (!JS_DefineElement(cx, argsObj, j, STRING_TO_JSVAL(str),
+                              NULL, NULL, JSPROP_ENUMERATE)) {
+            return 1;
+        }
+    }
+
+    for (i = 0; i < argc; i++) {
+        if (argv[i][0] != '-' || argv[i][1] == '\0') {
+            filename = argv[i++];
+            isInteractive = JS_FALSE;
+            break;
+        }
+
+        switch (argv[i][1]) {
+        case 'v':
+            if (++i == argc) {
+                return usage();
+            }
+            JS_SetVersion(cx, (JSVersion) atoi(argv[i]));
+            break;
+
+        case 'w':
+            reportWarnings = JS_TRUE;
+            break;
+
+        case 'W':
+            reportWarnings = JS_FALSE;
+            break;
+
+        case 's':
+            JS_ToggleOptions(cx, JSOPTION_STRICT);
+            break;
+
+        case 'x':
+            JS_ToggleOptions(cx, JSOPTION_XML);
+            break;
+
+        case 'P':
+            if (JS_GET_CLASS(cx, JS_GetPrototype(cx, obj)) != &global_class) {
+                JSObject *gobj;
+
+                if (!JS_SealObject(cx, obj, JS_TRUE))
+                    return JS_FALSE;
+                gobj = JS_NewObject(cx, &global_class, NULL, NULL);
+                if (!gobj)
+                    return JS_FALSE;
+                if (!JS_SetPrototype(cx, gobj, obj))
+                    return JS_FALSE;
+                JS_SetParent(cx, gobj, NULL);
+                JS_SetGlobalObject(cx, gobj);
+                obj = gobj;
+            }
+            break;
+
+        case 'b':
+            gBranchLimit = atoi(argv[++i]);
+            JS_SetBranchCallback(cx, my_BranchCallback);
+            JS_ToggleOptions(cx, JSOPTION_NATIVE_BRANCH_CALLBACK);
+            break;
+
+        case 'c':
+            /* set stack chunk size */
+            gStackChunkSize = atoi(argv[++i]);
+            break;
+
+        case 'f':
+            if (++i == argc) {
+                return usage();
+            }
+            Process(cx, obj, argv[i]);
+            /*
+             * XXX: js -f foo.js should interpret foo.js and then
+             * drop into interactive mode, but that breaks the test
+             * harness. Just execute foo.js for now.
+             */
+            isInteractive = JS_FALSE;
+            break;
+
+        case 'e':
+        {
+            jsval rval;
+
+            if (++i == argc) {
+                return usage();
+            }
+
+            /* Pass a filename of -e to imitate PERL */
+            JS_EvaluateScript(cx, obj, argv[i], strlen(argv[i]),
+                              "-e", 1, &rval);
+
+            isInteractive = JS_FALSE;
+            break;
+
+        }
+        case 'C':
+            compileOnly = JS_TRUE;
+            isInteractive = JS_FALSE;
+            break;
+
+        case 'S':
+            if (++i == argc) {
+                return usage();
+            }
+            /* Set maximum stack size. */
+            gMaxStackSize = atoi(argv[i]);
+            break;
+
+        default:
+            return usage();
+        }
+    }
+
+    if (filename || isInteractive)
+        Process(cx, obj, filename);
+    return gExitCode;
+}
+
+
+static JSBool
+Version(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    if (argc > 0 && JSVAL_IS_INT(argv[0]))
+        *rval = INT_TO_JSVAL(JS_SetVersion(cx, (JSVersion) JSVAL_TO_INT(argv[0])));
+    else
+        *rval = INT_TO_JSVAL(JS_GetVersion(cx));
+    return JS_TRUE;
+}
+
+static struct {
+    const char  *name;
+    uint32      flag;
+} js_options[] = {
+    {"strict",          JSOPTION_STRICT},
+    {"werror",          JSOPTION_WERROR},
+    {"atline",          JSOPTION_ATLINE},
+    {"xml",             JSOPTION_XML},
+    {0,                 0}
+};
+
+static JSBool
+Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    uint32 optset, flag;
+    uintN i, j, found;
+    JSString *str;
+    const char *opt;
+    char *names;
+
+    optset = 0;
+    for (i = 0; i < argc; i++) {
+        str = JS_ValueToString(cx, argv[i]);
+        if (!str)
+            return JS_FALSE;
+        opt = JS_GetStringBytes(str);
+        for (j = 0; js_options[j].name; j++) {
+            if (strcmp(js_options[j].name, opt) == 0) {
+                optset |= js_options[j].flag;
+                break;
+            }
+        }
+    }
+    optset = JS_ToggleOptions(cx, optset);
+
+    names = NULL;
+    found = 0;
+    while (optset != 0) {
+        flag = optset;
+        optset &= optset - 1;
+        flag &= ~optset;
+        for (j = 0; js_options[j].name; j++) {
+            if (js_options[j].flag == flag) {
+                names = JS_sprintf_append(names, "%s%s",
+                                          names ? "," : "", js_options[j].name);
+                found++;
+                break;
+            }
+        }
+    }
+    if (!found)
+        names = strdup("");
+    if (!names) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+
+    str = JS_NewString(cx, names, strlen(names));
+    if (!str) {
+        free(names);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    uintN i;
+    JSString *str;
+    const char *filename;
+    JSScript *script;
+    JSBool ok;
+    jsval result;
+    uint32 oldopts;
+
+    for (i = 0; i < argc; i++) {
+        str = JS_ValueToString(cx, argv[i]);
+        if (!str)
+            return JS_FALSE;
+        argv[i] = STRING_TO_JSVAL(str);
+        filename = JS_GetStringBytes(str);
+        errno = 0;
+        oldopts = JS_GetOptions(cx);
+        JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
+        script = JS_CompileFile(cx, obj, filename);
+        if (!script) {
+            ok = JS_FALSE;
+        } else {
+            ok = !compileOnly
+                 ? JS_ExecuteScript(cx, obj, script, &result)
+                 : JS_TRUE;
+            JS_DestroyScript(cx, script);
+        }
+        JS_SetOptions(cx, oldopts);
+        if (!ok)
+            return JS_FALSE;
+    }
+
+    return JS_TRUE;
+}
+
+/*
+ * function readline()
+ * Provides a hook for scripts to read a line from stdin.
+ */
+static JSBool
+ReadLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+#define BUFSIZE 256
+    FILE *from;
+    char *buf, *tmp;
+    size_t bufsize, buflength, gotlength;
+    JSString *str;
+
+    from = stdin;
+    buflength = 0;
+    bufsize = BUFSIZE;
+    buf = JS_malloc(cx, bufsize);
+    if (!buf)
+        return JS_FALSE;
+
+    while ((gotlength = 
+            js_fgets(buf + buflength, bufsize - buflength, from)) > 0) {
+        buflength += gotlength;
+
+        /* Are we done? */
+        if (buf[buflength - 1] == '\n') {
+            buf[buflength - 1] = '\0';
+            break;
+        }
+
+        /* Else, grow our buffer for another pass. */
+        tmp = JS_realloc(cx, buf, bufsize * 2);
+        if (!tmp) {
+            JS_free(cx, buf);
+            return JS_FALSE;
+        }
+
+        bufsize *= 2;
+        buf = tmp;
+    }
+
+    /* Treat the empty string specially. */
+    if (buflength == 0) {
+        *rval = JS_GetEmptyStringValue(cx);
+        JS_free(cx, buf);
+        return JS_TRUE;
+    }
+
+    /* Shrink the buffer to the real size. */
+    tmp = JS_realloc(cx, buf, buflength);
+    if (!tmp) {
+        JS_free(cx, buf);
+        return JS_FALSE;
+    }
+
+    buf = tmp;
+
+    /* 
+     * Turn buf into a JSString. Note that buflength includes the trailing null
+     * character.
+     */
+    str = JS_NewString(cx, buf, buflength - 1);
+    if (!str) {
+        JS_free(cx, buf);
+        return JS_FALSE;
+    }
+
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    uintN i, n;
+    JSString *str;
+
+    for (i = n = 0; i < argc; i++) {
+        str = JS_ValueToString(cx, argv[i]);
+        if (!str)
+            return JS_FALSE;
+        fprintf(gOutFile, "%s%s", i ? " " : "", JS_GetStringBytes(str));
+    }
+    n++;
+    if (n)
+        fputc('\n', gOutFile);
+    return JS_TRUE;
+}
+
+static JSBool
+Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
+
+static JSBool
+Quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+#ifdef LIVECONNECT
+    JSJ_SimpleShutdown();
+#endif
+
+    JS_ConvertArguments(cx, argc, argv,"/ i", &gExitCode);
+
+    gQuitting = JS_TRUE;
+    return JS_FALSE;
+}
+
+#ifdef GC_MARK_DEBUG
+extern JS_FRIEND_DATA(FILE *) js_DumpGCHeap;
+#endif
+
+static JSBool
+GC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSRuntime *rt;
+    uint32 preBytes;
+
+    rt = cx->runtime;
+    preBytes = rt->gcBytes;
+#ifdef GC_MARK_DEBUG
+    if (argc && JSVAL_IS_STRING(argv[0])) {
+        char *name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
+        FILE *file = fopen(name, "w");
+        if (!file) {
+            fprintf(gErrFile, "gc: can't open %s: %s\n", strerror(errno));
+            return JS_FALSE;
+        }
+        js_DumpGCHeap = file;
+    } else {
+        js_DumpGCHeap = stdout;
+    }
+#endif
+    JS_GC(cx);
+#ifdef GC_MARK_DEBUG
+    if (js_DumpGCHeap != stdout)
+        fclose(js_DumpGCHeap);
+    js_DumpGCHeap = NULL;
+#endif
+    fprintf(gOutFile, "before %lu, after %lu, break %08lx\n",
+            (unsigned long)preBytes, (unsigned long)rt->gcBytes,
+#ifdef XP_UNIX
+            (unsigned long)sbrk(0)
+#else
+            0
+#endif
+            );
+#ifdef JS_GCMETER
+    js_DumpGCStats(rt, stdout);
+#endif
+    return JS_TRUE;
+}
+
+static JSScript *
+ValueToScript(JSContext *cx, jsval v)
+{
+    JSScript *script;
+    JSFunction *fun;
+
+    if (!JSVAL_IS_PRIMITIVE(v) &&
+        JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_ScriptClass) {
+        script = (JSScript *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v));
+    } else {
+        fun = JS_ValueToFunction(cx, v);
+        if (!fun)
+            return NULL;
+        script = FUN_SCRIPT(fun);
+    }
+    return script;
+}
+
+static JSBool
+GetTrapArgs(JSContext *cx, uintN argc, jsval *argv, JSScript **scriptp,
+            int32 *ip)
+{
+    jsval v;
+    uintN intarg;
+    JSScript *script;
+
+    *scriptp = cx->fp->down->script;
+    *ip = 0;
+    if (argc != 0) {
+        v = argv[0];
+        intarg = 0;
+        if (!JSVAL_IS_PRIMITIVE(v) &&
+            (JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass ||
+             JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_ScriptClass)) {
+            script = ValueToScript(cx, v);
+            if (!script)
+                return JS_FALSE;
+            *scriptp = script;
+            intarg++;
+        }
+        if (argc > intarg) {
+            if (!JS_ValueToInt32(cx, argv[intarg], ip))
+                return JS_FALSE;
+        }
+    }
+    return JS_TRUE;
+}
+
+static JSTrapStatus
+TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
+            void *closure)
+{
+    JSString *str;
+    JSStackFrame *caller;
+
+    str = (JSString *) closure;
+    caller = JS_GetScriptedCaller(cx, NULL);
+    if (!JS_EvaluateScript(cx, caller->scopeChain,
+                           JS_GetStringBytes(str), JS_GetStringLength(str),
+                           caller->script->filename, caller->script->lineno,
+                           rval)) {
+        return JSTRAP_ERROR;
+    }
+    if (*rval != JSVAL_VOID)
+        return JSTRAP_RETURN;
+    return JSTRAP_CONTINUE;
+}
+
+static JSBool
+Trap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+    JSScript *script;
+    int32 i;
+
+    if (argc == 0) {
+        JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_TRAP_USAGE);
+        return JS_FALSE;
+    }
+    argc--;
+    str = JS_ValueToString(cx, argv[argc]);
+    if (!str)
+        return JS_FALSE;
+    argv[argc] = STRING_TO_JSVAL(str);
+    if (!GetTrapArgs(cx, argc, argv, &script, &i))
+        return JS_FALSE;
+    return JS_SetTrap(cx, script, script->code + i, TrapHandler, str);
+}
+
+static JSBool
+Untrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSScript *script;
+    int32 i;
+
+    if (!GetTrapArgs(cx, argc, argv, &script, &i))
+        return JS_FALSE;
+    JS_ClearTrap(cx, script, script->code + i, NULL, NULL);
+    return JS_TRUE;
+}
+
+static JSBool
+LineToPC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSScript *script;
+    int32 i;
+    uintN lineno;
+    jsbytecode *pc;
+
+    if (argc == 0) {
+        JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_LINE2PC_USAGE);
+        return JS_FALSE;
+    }
+    script = cx->fp->down->script;
+    if (!GetTrapArgs(cx, argc, argv, &script, &i))
+        return JS_FALSE;
+    lineno = (i == 0) ? script->lineno : (uintN)i;
+    pc = JS_LineNumberToPC(cx, script, lineno);
+    if (!pc)
+        return JS_FALSE;
+    *rval = INT_TO_JSVAL(PTRDIFF(pc, script->code, jsbytecode));
+    return JS_TRUE;
+}
+
+static JSBool
+PCToLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSScript *script;
+    int32 i;
+    uintN lineno;
+
+    if (!GetTrapArgs(cx, argc, argv, &script, &i))
+        return JS_FALSE;
+    lineno = JS_PCToLineNumber(cx, script, script->code + i);
+    if (!lineno)
+        return JS_FALSE;
+    *rval = INT_TO_JSVAL(lineno);
+    return JS_TRUE;
+}
+
+#ifdef DEBUG
+
+static void
+SrcNotes(JSContext *cx, JSScript *script)
+{
+    uintN offset, delta, caseOff;
+    jssrcnote *notes, *sn;
+    JSSrcNoteType type;
+    jsatomid atomIndex;
+    JSAtom *atom;
+
+    fprintf(gOutFile, "\nSource notes:\n");
+    offset = 0;
+    notes = SCRIPT_NOTES(script);
+    for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
+        delta = SN_DELTA(sn);
+        offset += delta;
+        fprintf(gOutFile, "%3u: %5u [%4u] %-8s",
+                PTRDIFF(sn, notes, jssrcnote), offset, delta,
+                js_SrcNoteSpec[SN_TYPE(sn)].name);
+        type = (JSSrcNoteType) SN_TYPE(sn);
+        switch (type) {
+          case SRC_SETLINE:
+            fprintf(gOutFile, " lineno %u", (uintN) js_GetSrcNoteOffset(sn, 0));
+            break;
+          case SRC_FOR:
+            fprintf(gOutFile, " cond %u update %u tail %u",
+                   (uintN) js_GetSrcNoteOffset(sn, 0),
+                   (uintN) js_GetSrcNoteOffset(sn, 1),
+                   (uintN) js_GetSrcNoteOffset(sn, 2));
+            break;
+          case SRC_COND:
+          case SRC_IF_ELSE:
+          case SRC_WHILE:
+          case SRC_PCBASE:
+          case SRC_PCDELTA:
+            fprintf(gOutFile, " offset %u", (uintN) js_GetSrcNoteOffset(sn, 0));
+            break;
+          case SRC_LABEL:
+          case SRC_LABELBRACE:
+          case SRC_BREAK2LABEL:
+          case SRC_CONT2LABEL:
+          case SRC_FUNCDEF: {
+            const char *bytes;
+            JSFunction *fun;
+            JSString *str;
+
+            atomIndex = (jsatomid) js_GetSrcNoteOffset(sn, 0);
+            atom = js_GetAtom(cx, &script->atomMap, atomIndex);
+            if (type != SRC_FUNCDEF) {
+                bytes = js_AtomToPrintableString(cx, atom);
+            } else {
+                fun = (JSFunction *)
+                    JS_GetPrivate(cx, ATOM_TO_OBJECT(atom));
+                str = JS_DecompileFunction(cx, fun, JS_DONT_PRETTY_PRINT);
+                bytes = str ? JS_GetStringBytes(str) : "N/A";
+            }
+            fprintf(gOutFile, " atom %u (%s)", (uintN)atomIndex, bytes);
+            break;
+          }
+          case SRC_SWITCH:
+            fprintf(gOutFile, " length %u", (uintN) js_GetSrcNoteOffset(sn, 0));
+            caseOff = (uintN) js_GetSrcNoteOffset(sn, 1);
+            if (caseOff)
+                fprintf(gOutFile, " first case offset %u", caseOff);
+            break;
+          case SRC_CATCH:
+            delta = (uintN) js_GetSrcNoteOffset(sn, 0);
+            if (delta)
+                fprintf(gOutFile, " guard size %u", delta);
+            break;
+          default:;
+        }
+        fputc('\n', gOutFile);
+    }
+}
+
+static JSBool
+Notes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    uintN i;
+    JSScript *script;
+
+    for (i = 0; i < argc; i++) {
+        script = ValueToScript(cx, argv[i]);
+        if (!script)
+            continue;
+
+        SrcNotes(cx, script);
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+TryNotes(JSContext *cx, JSScript *script)
+{
+    JSTryNote *tn = script->trynotes;
+
+    if (!tn)
+        return JS_TRUE;
+    fprintf(gOutFile, "\nException table:\nstart\tend\tcatch\n");
+    while (tn->start && tn->catchStart) {
+        fprintf(gOutFile, "  %d\t%d\t%d\n",
+               tn->start, tn->start + tn->length, tn->catchStart);
+        tn++;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+Disassemble(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSBool lines;
+    uintN i;
+    JSScript *script;
+
+    if (argc > 0 &&
+        JSVAL_IS_STRING(argv[0]) &&
+        !strcmp(JS_GetStringBytes(JSVAL_TO_STRING(argv[0])), "-l")) {
+        lines = JS_TRUE;
+        argv++, argc--;
+    } else {
+        lines = JS_FALSE;
+    }
+    for (i = 0; i < argc; i++) {
+        script = ValueToScript(cx, argv[i]);
+        if (!script)
+            continue;
+
+        if (JSVAL_IS_FUNCTION(cx, argv[i])) {
+            JSFunction *fun = JS_ValueToFunction(cx, argv[i]);
+            if (fun && (fun->flags & JSFUN_FLAGS_MASK)) {
+                uint8 flags = fun->flags;
+                fputs("flags:", stdout);
+
+#define SHOW_FLAG(flag) if (flags & JSFUN_##flag) fputs(" " #flag, stdout);
+
+                SHOW_FLAG(LAMBDA);
+                SHOW_FLAG(SETTER);
+                SHOW_FLAG(GETTER);
+                SHOW_FLAG(BOUND_METHOD);
+                SHOW_FLAG(HEAVYWEIGHT);
+
+#undef SHOW_FLAG
+                putchar('\n');
+            }
+        }
+
+        if (!js_Disassemble(cx, script, lines, stdout))
+            return JS_FALSE;
+        SrcNotes(cx, script);
+        TryNotes(cx, script);
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+#define LINE_BUF_LEN 512
+    uintN i, len, line1, line2, bupline;
+    JSScript *script;
+    FILE *file;
+    char linebuf[LINE_BUF_LEN];
+    jsbytecode *pc, *end;
+    static char sep[] = ";-------------------------";
+
+    for (i = 0; i < argc; i++) {
+        script = ValueToScript(cx, argv[i]);
+        if (!script)
+            continue;
+
+        if (!script || !script->filename) {
+            JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
+                                            JSSMSG_FILE_SCRIPTS_ONLY);
+            return JS_FALSE;
+        }
+
+        file = fopen(script->filename, "r");
+        if (!file) {
+            JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
+                            JSSMSG_CANT_OPEN,
+                            script->filename, strerror(errno));
+            return JS_FALSE;
+        }
+
+        pc = script->code;
+        end = pc + script->length;
+
+        /* burn the leading lines */
+        line2 = JS_PCToLineNumber(cx, script, pc);
+        for (line1 = 0; line1 < line2 - 1; line1++)
+            fgets(linebuf, LINE_BUF_LEN, file);
+
+        bupline = 0;
+        while (pc < end) {
+            line2 = JS_PCToLineNumber(cx, script, pc);
+
+            if (line2 < line1) {
+                if (bupline != line2) {
+                    bupline = line2;
+                    fprintf(gOutFile, "%s %3u: BACKUP\n", sep, line2);
+                }
+            } else {
+                if (bupline && line1 == line2)
+                    fprintf(gOutFile, "%s %3u: RESTORE\n", sep, line2);
+                bupline = 0;
+                while (line1 < line2) {
+                    if (!fgets(linebuf, LINE_BUF_LEN, file)) {
+                        JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
+                                             JSSMSG_UNEXPECTED_EOF,
+                                             script->filename);
+                        goto bail;
+                    }
+                    line1++;
+                    fprintf(gOutFile, "%s %3u: %s", sep, line1, linebuf);
+                }
+            }
+
+            len = js_Disassemble1(cx, script, pc,
+                                  PTRDIFF(pc, script->code, jsbytecode),
+                                  JS_TRUE, stdout);
+            if (!len)
+                return JS_FALSE;
+            pc += len;
+        }
+
+      bail:
+        fclose(file);
+    }
+    return JS_TRUE;
+#undef LINE_BUF_LEN
+}
+
+static JSBool
+Tracing(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSBool bval;
+    JSString *str;
+
+    if (argc == 0) {
+        *rval = BOOLEAN_TO_JSVAL(cx->tracefp != 0);
+        return JS_TRUE;
+    }
+
+    switch (JS_TypeOfValue(cx, argv[0])) {
+      case JSTYPE_NUMBER:
+        bval = JSVAL_IS_INT(argv[0])
+               ? JSVAL_TO_INT(argv[0])
+               : (jsint) *JSVAL_TO_DOUBLE(argv[0]);
+        break;
+      case JSTYPE_BOOLEAN:
+        bval = JSVAL_TO_BOOLEAN(argv[0]);
+        break;
+      default:
+        str = JS_ValueToString(cx, argv[0]);
+        if (!str)
+            return JS_FALSE;
+        fprintf(gErrFile, "tracing: illegal argument %s\n",
+                JS_GetStringBytes(str));
+        return JS_TRUE;
+    }
+    cx->tracefp = bval ? stderr : NULL;
+    return JS_TRUE;
+}
+
+typedef struct DumpAtomArgs {
+    JSContext   *cx;
+    FILE        *fp;
+} DumpAtomArgs;
+
+static int
+DumpAtom(JSHashEntry *he, int i, void *arg)
+{
+    DumpAtomArgs *args = (DumpAtomArgs *)arg;
+    FILE *fp = args->fp;
+    JSAtom *atom = (JSAtom *)he;
+
+    fprintf(fp, "%3d %08x %5lu ",
+            i, (uintN)he->keyHash, (unsigned long)atom->number);
+    if (ATOM_IS_STRING(atom))
+        fprintf(fp, "\"%s\"\n", js_AtomToPrintableString(args->cx, atom));
+    else if (ATOM_IS_INT(atom))
+        fprintf(fp, "%ld\n", (long)ATOM_TO_INT(atom));
+    else
+        fprintf(fp, "%.16g\n", *ATOM_TO_DOUBLE(atom));
+    return HT_ENUMERATE_NEXT;
+}
+
+static void
+DumpScope(JSContext *cx, JSObject *obj, FILE *fp)
+{
+    uintN i;
+    JSScope *scope;
+    JSScopeProperty *sprop;
+
+    i = 0;
+    scope = OBJ_SCOPE(obj);
+    for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
+        if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop))
+            continue;
+#ifdef OSSP
+        fprintf(fp, "%3u %lx", i, (unsigned long)sprop);
+#else
+        fprintf(fp, "%3u %p", i, sprop);
+#endif
+        if (JSID_IS_INT(sprop->id)) {
+            fprintf(fp, " [%ld]", (long)JSVAL_TO_INT(sprop->id));
+        } else if (JSID_IS_ATOM(sprop->id)) {
+            JSAtom *atom = JSID_TO_ATOM(sprop->id);
+            fprintf(fp, " \"%s\"", js_AtomToPrintableString(cx, atom));
+        } else {
+            jsval v = OBJECT_TO_JSVAL(JSID_TO_OBJECT(sprop->id));
+            fprintf(fp, " \"%s\"", js_ValueToPrintableString(cx, v));
+        }
+
+#define DUMP_ATTR(name) if (sprop->attrs & JSPROP_##name) fputs(" " #name, fp)
+        DUMP_ATTR(ENUMERATE);
+        DUMP_ATTR(READONLY);
+        DUMP_ATTR(PERMANENT);
+        DUMP_ATTR(EXPORTED);
+        DUMP_ATTR(GETTER);
+        DUMP_ATTR(SETTER);
+#undef  DUMP_ATTR
+
+        fprintf(fp, " slot %lu flags %x shortid %d\n",
+#ifdef OSSP
+                (unsigned long)sprop->slot, sprop->flags, sprop->shortid);
+#else
+                sprop->slot, sprop->flags, sprop->shortid);
+#endif
+    }
+}
+
+static JSBool
+DumpStats(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    uintN i;
+    JSString *str;
+    const char *bytes;
+    JSAtom *atom;
+    JSObject *obj2;
+    JSProperty *prop;
+    jsval value;
+
+    for (i = 0; i < argc; i++) {
+        str = JS_ValueToString(cx, argv[i]);
+        if (!str)
+            return JS_FALSE;
+        bytes = JS_GetStringBytes(str);
+        if (strcmp(bytes, "arena") == 0) {
+#ifdef JS_ARENAMETER
+            JS_DumpArenaStats(stdout);
+#endif
+        } else if (strcmp(bytes, "atom") == 0) {
+            DumpAtomArgs args;
+
+            fprintf(gOutFile, "\natom table contents:\n");
+            args.cx = cx;
+            args.fp = stdout;
+            JS_HashTableEnumerateEntries(cx->runtime->atomState.table,
+                                         DumpAtom,
+                                         &args);
+#ifdef HASHMETER
+            JS_HashTableDumpMeter(cx->runtime->atomState.table,
+                                  DumpAtom,
+                                  stdout);
+#endif
+        } else if (strcmp(bytes, "global") == 0) {
+            DumpScope(cx, cx->globalObject, stdout);
+        } else {
+            atom = js_Atomize(cx, bytes, JS_GetStringLength(str), 0);
+            if (!atom)
+                return JS_FALSE;
+            if (!js_FindProperty(cx, ATOM_TO_JSID(atom), &obj, &obj2, &prop))
+                return JS_FALSE;
+            if (prop) {
+                OBJ_DROP_PROPERTY(cx, obj2, prop);
+                if (!OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &value))
+                    return JS_FALSE;
+            }
+            if (!prop || !JSVAL_IS_OBJECT(value)) {
+                fprintf(gErrFile, "js: invalid stats argument %s\n",
+                        bytes);
+                continue;
+            }
+            obj = JSVAL_TO_OBJECT(value);
+            if (obj)
+                DumpScope(cx, obj, stdout);
+        }
+    }
+    return JS_TRUE;
+}
+
+#endif /* DEBUG */
+
+#ifdef TEST_EXPORT
+static JSBool
+DoExport(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSAtom *atom;
+    JSObject *obj2;
+    JSProperty *prop;
+    JSBool ok;
+    uintN attrs;
+
+    if (argc != 2) {
+        JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_DOEXP_USAGE);
+        return JS_FALSE;
+    }
+    if (!JS_ValueToObject(cx, argv[0], &obj))
+        return JS_FALSE;
+    argv[0] = OBJECT_TO_JSVAL(obj);
+    atom = js_ValueToStringAtom(cx, argv[1]);
+    if (!atom)
+        return JS_FALSE;
+    if (!OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &obj2, &prop))
+        return JS_FALSE;
+    if (!prop) {
+        ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, NULL,
+                                 JSPROP_EXPORTED, NULL);
+    } else {
+        ok = OBJ_GET_ATTRIBUTES(cx, obj, ATOM_TO_JSID(atom), prop, &attrs);
+        if (ok) {
+            attrs |= JSPROP_EXPORTED;
+            ok = OBJ_SET_ATTRIBUTES(cx, obj, ATOM_TO_JSID(atom), prop, &attrs);
+        }
+        OBJ_DROP_PROPERTY(cx, obj2, prop);
+    }
+    return ok;
+}
+#endif
+
+#ifdef TEST_CVTARGS
+#include <ctype.h>
+
+static const char *
+EscapeWideString(jschar *w)
+{
+    static char enuf[80];
+    static char hex[] = "0123456789abcdef";
+    jschar u;
+    unsigned char b, c;
+    int i, j;
+
+    if (!w)
+        return "";
+    for (i = j = 0; i < sizeof enuf - 1; i++, j++) {
+        u = w[j];
+        if (u == 0)
+            break;
+        b = (unsigned char)(u >> 8);
+        c = (unsigned char)(u);
+        if (b) {
+            if (i >= sizeof enuf - 6)
+                break;
+            enuf[i++] = '\\';
+            enuf[i++] = 'u';
+            enuf[i++] = hex[b >> 4];
+            enuf[i++] = hex[b & 15];
+            enuf[i++] = hex[c >> 4];
+            enuf[i] = hex[c & 15];
+        } else if (!isprint(c)) {
+            if (i >= sizeof enuf - 4)
+                break;
+            enuf[i++] = '\\';
+            enuf[i++] = 'x';
+            enuf[i++] = hex[c >> 4];
+            enuf[i] = hex[c & 15];
+        } else {
+            enuf[i] = (char)c;
+        }
+    }
+    enuf[i] = 0;
+    return enuf;
+}
+
+#include <stdarg.h>
+
+static JSBool
+ZZ_formatter(JSContext *cx, const char *format, JSBool fromJS, jsval **vpp,
+             va_list *app)
+{
+    jsval *vp;
+    va_list ap;
+    jsdouble re, im;
+
+    printf("entering ZZ_formatter");
+    vp = *vpp;
+    ap = *app;
+    if (fromJS) {
+        if (!JS_ValueToNumber(cx, vp[0], &re))
+            return JS_FALSE;
+        if (!JS_ValueToNumber(cx, vp[1], &im))
+            return JS_FALSE;
+        *va_arg(ap, jsdouble *) = re;
+        *va_arg(ap, jsdouble *) = im;
+    } else {
+        re = va_arg(ap, jsdouble);
+        im = va_arg(ap, jsdouble);
+        if (!JS_NewNumberValue(cx, re, &vp[0]))
+            return JS_FALSE;
+        if (!JS_NewNumberValue(cx, im, &vp[1]))
+            return JS_FALSE;
+    }
+    *vpp = vp + 2;
+    *app = ap;
+    printf("leaving ZZ_formatter");
+    return JS_TRUE;
+}
+
+static JSBool
+ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSBool b = JS_FALSE;
+    jschar c = 0;
+    int32 i = 0, j = 0;
+    uint32 u = 0;
+    jsdouble d = 0, I = 0, re = 0, im = 0;
+    char *s = NULL;
+    JSString *str = NULL;
+    jschar *w = NULL;
+    JSObject *obj2 = NULL;
+    JSFunction *fun = NULL;
+    jsval v = JSVAL_VOID;
+    JSBool ok;
+
+    if (!JS_AddArgumentFormatter(cx, "ZZ", ZZ_formatter))
+        return JS_FALSE;;
+    ok = JS_ConvertArguments(cx, argc, argv, "b/ciujdIsSWofvZZ*",
+                             &b, &c, &i, &u, &j, &d, &I, &s, &str, &w, &obj2,
+                             &fun, &v, &re, &im);
+    JS_RemoveArgumentFormatter(cx, "ZZ");
+    if (!ok)
+        return JS_FALSE;
+    fprintf(gOutFile,
+            "b %u, c %x (%c), i %ld, u %lu, j %ld\n",
+            b, c, (char)c, i, u, j);
+    fprintf(gOutFile,
+            "d %g, I %g, s %s, S %s, W %s, obj %s, fun %s\n"
+            "v %s, re %g, im %g\n",
+            d, I, s, str ? JS_GetStringBytes(str) : "", EscapeWideString(w),
+            JS_GetStringBytes(JS_ValueToString(cx, OBJECT_TO_JSVAL(obj2))),
+            fun ? JS_GetStringBytes(JS_DecompileFunction(cx, fun, 4)) : "",
+            JS_GetStringBytes(JS_ValueToString(cx, v)), re, im);
+    return JS_TRUE;
+}
+#endif
+
+static JSBool
+BuildDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    fprintf(gOutFile, "built on %s at %s\n", __DATE__, __TIME__);
+    return JS_TRUE;
+}
+
+static JSBool
+Clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    if (argc != 0 && !JS_ValueToObject(cx, argv[0], &obj))
+        return JS_FALSE;
+    JS_ClearScope(cx, obj);
+    return JS_TRUE;
+}
+
+static JSBool
+Intern(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+
+    str = JS_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    if (!JS_InternUCStringN(cx, JS_GetStringChars(str),
+                                JS_GetStringLength(str))) {
+        return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+Clone(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFunction *fun;
+    JSObject *funobj, *parent, *clone;
+
+    fun = JS_ValueToFunction(cx, argv[0]);
+    if (!fun)
+        return JS_FALSE;
+    funobj = JS_GetFunctionObject(fun);
+    if (argc > 1) {
+        if (!JS_ValueToObject(cx, argv[1], &parent))
+            return JS_FALSE;
+    } else {
+        parent = JS_GetParent(cx, funobj);
+    }
+    clone = JS_CloneFunctionObject(cx, funobj, parent);
+    if (!clone)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(clone);
+    return JS_TRUE;
+}
+
+static JSBool
+Seal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSObject *target;
+    JSBool deep = JS_FALSE;
+
+    if (!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep))
+        return JS_FALSE;
+    if (!target)
+        return JS_TRUE;
+    return JS_SealObject(cx, target, deep);
+}
+
+static JSBool
+GetPDA(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSObject *vobj, *aobj, *pdobj;
+    JSBool ok;
+    JSPropertyDescArray pda;
+    JSPropertyDesc *pd;
+    uint32 i;
+    jsval v;
+
+    if (!JS_ValueToObject(cx, argv[0], &vobj))
+        return JS_FALSE;
+    if (!vobj)
+        return JS_TRUE;
+
+    aobj = JS_NewArrayObject(cx, 0, NULL);
+    if (!aobj)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(aobj);
+
+    ok = JS_GetPropertyDescArray(cx, vobj, &pda);
+    if (!ok)
+        return JS_FALSE;
+    pd = pda.array;
+    for (i = 0; i < pda.length; i++) {
+        pdobj = JS_NewObject(cx, NULL, NULL, NULL);
+        if (!pdobj) {
+            ok = JS_FALSE;
+            break;
+        }
+
+        ok = JS_SetProperty(cx, pdobj, "id", &pd->id) &&
+             JS_SetProperty(cx, pdobj, "value", &pd->value) &&
+             (v = INT_TO_JSVAL(pd->flags),
+              JS_SetProperty(cx, pdobj, "flags", &v)) &&
+             (v = INT_TO_JSVAL(pd->slot),
+              JS_SetProperty(cx, pdobj, "slot", &v)) &&
+             JS_SetProperty(cx, pdobj, "alias", &pd->alias);
+        if (!ok)
+            break;
+
+        v = OBJECT_TO_JSVAL(pdobj);
+        ok = JS_SetElement(cx, aobj, i, &v);
+        if (!ok)
+            break;
+    }
+    JS_PutPropertyDescArray(cx, &pda);
+    return ok;
+}
+
+static JSBool
+GetSLX(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSScript *script;
+
+    script = ValueToScript(cx, argv[0]);
+    if (!script)
+        return JS_FALSE;
+    *rval = INT_TO_JSVAL(js_GetScriptLineExtent(script));
+    return JS_TRUE;
+}
+
+static JSBool
+ToInt32(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    int32 i;
+
+    if (!JS_ValueToInt32(cx, argv[0], &i))
+        return JS_FALSE;
+    return JS_NewNumberValue(cx, i, rval);
+}
+
+static JSBool
+StringsAreUtf8(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    *rval = JS_CStringsAreUTF8() ? JSVAL_TRUE : JSVAL_FALSE;
+    return JS_TRUE;
+}
+
+static const char* badUtf8 = "...\xC0...";
+static const char* bigUtf8 = "...\xFB\xBF\xBF\xBF\xBF...";
+static const jschar badSurrogate[] = { 'A', 'B', 'C', 0xDEEE, 'D', 'E', 0 };
+
+static JSBool
+TestUtf8(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    intN mode = 1;
+    jschar chars[20];
+    size_t charsLength = 5;
+    char bytes[20];
+    size_t bytesLength = 20;
+    if (argc && !JS_ValueToInt32(cx, *argv, &mode))
+        return JS_FALSE;
+
+    /* The following throw errors if compiled with UTF-8. */
+    switch (mode) {
+      /* mode 1: malformed UTF-8 string. */
+      case 1: 
+        JS_NewStringCopyZ(cx, badUtf8); 
+        break;
+      /* mode 2: big UTF-8 character. */
+      case 2: 
+        JS_NewStringCopyZ(cx, bigUtf8); 
+        break;
+      /* mode 3: bad surrogate character. */
+      case 3: 
+        JS_EncodeCharacters(cx, badSurrogate, 6, bytes, &bytesLength); 
+        break;
+      /* mode 4: use a too small buffer. */
+      case 4: 
+        JS_DecodeBytes(cx, "1234567890", 10, chars, &charsLength); 
+        break;
+      default:
+        JS_ReportError(cx, "invalid mode parameter");
+        return JS_FALSE;
+    }
+    return !JS_IsExceptionPending (cx);
+}
+
+static JSFunctionSpec shell_functions[] = {
+    {"version",         Version,        0},
+    {"options",         Options,        0},
+    {"load",            Load,           1},
+    {"readline",        ReadLine,       0},
+    {"print",           Print,          0},
+    {"help",            Help,           0},
+    {"quit",            Quit,           0},
+    {"gc",              GC,             0},
+    {"trap",            Trap,           3},
+    {"untrap",          Untrap,         2},
+    {"line2pc",         LineToPC,       0},
+    {"pc2line",         PCToLine,       0},
+    {"stringsAreUtf8",  StringsAreUtf8, 0},
+    {"testUtf8",        TestUtf8,       1},
+#ifdef DEBUG
+    {"dis",             Disassemble,    1},
+    {"dissrc",          DisassWithSrc,  1},
+    {"notes",           Notes,          1},
+    {"tracing",         Tracing,        0},
+    {"stats",           DumpStats,      1},
+#endif
+#ifdef TEST_EXPORT
+    {"xport",           DoExport,       2},
+#endif
+#ifdef TEST_CVTARGS
+    {"cvtargs",         ConvertArgs,    0, 0, 12},
+#endif
+    {"build",           BuildDate,      0},
+    {"clear",           Clear,          0},
+    {"intern",          Intern,         1},
+    {"clone",           Clone,          1},
+    {"seal",            Seal,           1, 0, 1},
+    {"getpda",          GetPDA,         1},
+    {"getslx",          GetSLX,         1},
+    {"toint32",         ToInt32,        1},
+    {0}
+};
+
+/* NOTE: These must be kept in sync with the above. */
+
+static char *shell_help_messages[] = {
+    "version([number])      Get or set JavaScript version number",
+    "options([option ...])  Get or toggle JavaScript options",
+    "load(['foo.js' ...])   Load files named by string arguments",
+    "readline()             Read a single line from stdin",
+    "print([exp ...])       Evaluate and print expressions",
+    "help([name ...])       Display usage and help messages",
+    "quit()                 Quit the shell",
+    "gc()                   Run the garbage collector",
+    "trap([fun, [pc,]] exp) Trap bytecode execution",
+    "untrap(fun[, pc])      Remove a trap",
+    "line2pc([fun,] line)   Map line number to PC",
+    "pc2line(fun[, pc])     Map PC to line number",
+    "stringsAreUTF8()       Check if strings are UTF-8 encoded",
+    "testUTF8(mode)         Perform UTF-8 tests (modes are 1 to 4)",
+#ifdef DEBUG
+    "dis([fun])             Disassemble functions into bytecodes",
+    "dissrc([fun])          Disassemble functions with source lines",
+    "notes([fun])           Show source notes for functions",
+    "tracing([toggle])      Turn tracing on or off",
+    "stats([string ...])    Dump 'arena', 'atom', 'global' stats",
+#endif
+#ifdef TEST_EXPORT
+    "xport(obj, id)         Export identified property from object",
+#endif
+#ifdef TEST_CVTARGS
+    "cvtargs(b, c, ...)     Test JS_ConvertArguments",
+#endif
+    "build()                Show build date and time",
+    "clear([obj])           Clear properties of object",
+    "intern(str)            Internalize str in the atom table",
+    "clone(fun[, scope])    Clone function object",
+    "seal(obj[, deep])      Seal object, or object graph if deep",
+    "getpda(obj)            Get the property descriptors for obj",
+    "getslx(obj)            Get script line extent",
+    "toint32(n)             Testing hook for JS_ValueToInt32",
+    0
+};
+
+static void
+ShowHelpHeader(void)
+{
+    fprintf(gOutFile, "%-14s %-22s %s\n", "Command", "Usage", "Description");
+    fprintf(gOutFile, "%-14s %-22s %s\n", "=======", "=====", "===========");
+}
+
+static void
+ShowHelpForCommand(uintN n)
+{
+    fprintf(gOutFile, "%-14.14s %s\n", shell_functions[n].name, shell_help_messages[n]);
+}
+
+static JSBool
+Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    uintN i, j;
+    int did_header, did_something;
+    JSType type;
+    JSFunction *fun;
+    JSString *str;
+    const char *bytes;
+
+    fprintf(gOutFile, "%s\n", JS_GetImplementationVersion());
+    if (argc == 0) {
+        ShowHelpHeader();
+        for (i = 0; shell_functions[i].name; i++)
+            ShowHelpForCommand(i);
+    } else {
+        did_header = 0;
+        for (i = 0; i < argc; i++) {
+            did_something = 0;
+            type = JS_TypeOfValue(cx, argv[i]);
+            if (type == JSTYPE_FUNCTION) {
+                fun = JS_ValueToFunction(cx, argv[i]);
+                str = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
+            } else if (type == JSTYPE_STRING) {
+                str = JSVAL_TO_STRING(argv[i]);
+            } else {
+                str = NULL;
+            }
+            if (str) {
+                bytes = JS_GetStringBytes(str);
+                for (j = 0; shell_functions[j].name; j++) {
+                    if (!strcmp(bytes, shell_functions[j].name)) {
+                        if (!did_header) {
+                            did_header = 1;
+                            ShowHelpHeader();
+                        }
+                        did_something = 1;
+                        ShowHelpForCommand(j);
+                        break;
+                    }
+                }
+            }
+            if (!did_something) {
+                str = JS_ValueToString(cx, argv[i]);
+                if (!str)
+                    return JS_FALSE;
+                fprintf(gErrFile, "Sorry, no help for %s\n",
+                        JS_GetStringBytes(str));
+            }
+        }
+    }
+    return JS_TRUE;
+}
+
+/*
+ * Define a JS object called "it".  Give it class operations that printf why
+ * they're being called for tutorial purposes.
+ */
+enum its_tinyid {
+    ITS_COLOR, ITS_HEIGHT, ITS_WIDTH, ITS_FUNNY, ITS_ARRAY, ITS_RDONLY
+};
+
+static JSPropertySpec its_props[] = {
+    {"color",           ITS_COLOR,      JSPROP_ENUMERATE},
+    {"height",          ITS_HEIGHT,     JSPROP_ENUMERATE},
+    {"width",           ITS_WIDTH,      JSPROP_ENUMERATE},
+    {"funny",           ITS_FUNNY,      JSPROP_ENUMERATE},
+    {"array",           ITS_ARRAY,      JSPROP_ENUMERATE},
+    {"rdonly",          ITS_RDONLY,     JSPROP_READONLY},
+    {0}
+};
+
+static JSBool
+its_item(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    *rval = OBJECT_TO_JSVAL(obj);
+    if (argc != 0)
+        JS_SetCallReturnValue2(cx, argv[0]);
+    return JS_TRUE;
+}
+
+static JSBool
+its_bindMethod(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    char *name;
+    JSObject *method;
+
+    if (!JS_ConvertArguments(cx, argc, argv, "so", &name, &method))
+        return JS_FALSE;
+
+    *rval = OBJECT_TO_JSVAL(method);
+
+    if (JS_TypeOfValue(cx, *rval) != JSTYPE_FUNCTION) {
+        JSString *valstr = JS_ValueToString(cx, *rval);
+        if (valstr) {
+            JS_ReportError(cx, "can't bind method %s to non-callable object %s",
+                           name, JS_GetStringBytes(valstr));
+        }
+        return JS_FALSE;
+    }
+
+    if (!JS_DefineProperty(cx, obj, name, *rval, NULL, NULL, JSPROP_ENUMERATE))
+        return JS_FALSE;
+
+    return JS_SetParent(cx, method, obj);
+}
+
+static JSFunctionSpec its_methods[] = {
+    {"item",            its_item,       0},
+    {"bindMethod",      its_bindMethod, 2},
+    {0}
+};
+
+#ifdef JSD_LOWLEVEL_SOURCE
+/*
+ * This facilitates sending source to JSD (the debugger system) in the shell
+ * where the source is loaded using the JSFILE hack in jsscan. The function
+ * below is used as a callback for the jsdbgapi JS_SetSourceHandler hook.
+ * A more normal embedding (e.g. mozilla) loads source itself and can send
+ * source directly to JSD without using this hook scheme.
+ */
+static void
+SendSourceToJSDebugger(const char *filename, uintN lineno,
+                       jschar *str, size_t length,
+                       void **listenerTSData, JSDContext* jsdc)
+{
+    JSDSourceText *jsdsrc = (JSDSourceText *) *listenerTSData;
+
+    if (!jsdsrc) {
+        if (!filename)
+            filename = "typein";
+        if (1 == lineno) {
+            jsdsrc = JSD_NewSourceText(jsdc, filename);
+        } else {
+            jsdsrc = JSD_FindSourceForURL(jsdc, filename);
+            if (jsdsrc && JSD_SOURCE_PARTIAL !=
+                JSD_GetSourceStatus(jsdc, jsdsrc)) {
+                jsdsrc = NULL;
+            }
+        }
+    }
+    if (jsdsrc) {
+        jsdsrc = JSD_AppendUCSourceText(jsdc,jsdsrc, str, length,
+                                        JSD_SOURCE_PARTIAL);
+    }
+    *listenerTSData = jsdsrc;
+}
+#endif /* JSD_LOWLEVEL_SOURCE */
+
+static JSBool its_noisy;    /* whether to be noisy when finalizing it */
+
+static JSBool
+its_addProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    if (its_noisy) {
+        fprintf(gOutFile, "adding its property %s,",
+               JS_GetStringBytes(JS_ValueToString(cx, id)));
+        fprintf(gOutFile, " initial value %s\n",
+               JS_GetStringBytes(JS_ValueToString(cx, *vp)));
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+its_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    if (its_noisy) {
+        fprintf(gOutFile, "deleting its property %s,",
+               JS_GetStringBytes(JS_ValueToString(cx, id)));
+        fprintf(gOutFile, " current value %s\n",
+               JS_GetStringBytes(JS_ValueToString(cx, *vp)));
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+its_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    if (its_noisy) {
+        fprintf(gOutFile, "getting its property %s,",
+               JS_GetStringBytes(JS_ValueToString(cx, id)));
+        fprintf(gOutFile, " current value %s\n",
+               JS_GetStringBytes(JS_ValueToString(cx, *vp)));
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+its_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    if (its_noisy) {
+        fprintf(gOutFile, "setting its property %s,",
+               JS_GetStringBytes(JS_ValueToString(cx, id)));
+        fprintf(gOutFile, " new value %s\n",
+               JS_GetStringBytes(JS_ValueToString(cx, *vp)));
+    }
+    if (JSVAL_IS_STRING(id) &&
+        !strcmp(JS_GetStringBytes(JSVAL_TO_STRING(id)), "noisy")) {
+        return JS_ValueToBoolean(cx, *vp, &its_noisy);
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+its_enumerate(JSContext *cx, JSObject *obj)
+{
+    if (its_noisy)
+        fprintf(gOutFile, "enumerate its properties\n");
+    return JS_TRUE;
+}
+
+static JSBool
+its_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
+            JSObject **objp)
+{
+    if (its_noisy) {
+        fprintf(gOutFile, "resolving its property %s, flags {%s,%s,%s}\n",
+               JS_GetStringBytes(JS_ValueToString(cx, id)),
+               (flags & JSRESOLVE_QUALIFIED) ? "qualified" : "",
+               (flags & JSRESOLVE_ASSIGNING) ? "assigning" : "",
+               (flags & JSRESOLVE_DETECTING) ? "detecting" : "");
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+its_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
+{
+    if (its_noisy)
+        fprintf(gOutFile, "converting it to %s type\n", JS_GetTypeName(cx, type));
+    return JS_TRUE;
+}
+
+static void
+its_finalize(JSContext *cx, JSObject *obj)
+{
+    if (its_noisy)
+        fprintf(gOutFile, "finalizing it\n");
+}
+
+static JSClass its_class = {
+    "It", JSCLASS_NEW_RESOLVE,
+    its_addProperty,  its_delProperty,  its_getProperty,  its_setProperty,
+    its_enumerate,    (JSResolveOp)its_resolve,
+                                        its_convert,      its_finalize
+};
+
+JSErrorFormatString jsShell_ErrorFormatString[JSErr_Limit] = {
+#if JS_HAS_DFLT_MSG_STRINGS
+#define MSG_DEF(name, number, count, exception, format) \
+    { format, count } ,
+#else
+#define MSG_DEF(name, number, count, exception, format) \
+    { NULL, count } ,
+#endif
+#include "jsshell.msg"
+#undef MSG_DEF
+};
+
+static const JSErrorFormatString *
+my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
+{
+    if ((errorNumber > 0) && (errorNumber < JSShellErr_Limit))
+        return &jsShell_ErrorFormatString[errorNumber];
+    return NULL;
+}
+
+static void
+my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
+{
+    int i, j, k, n;
+    char *prefix, *tmp;
+    const char *ctmp;
+
+    if (!report) {
+        fprintf(gErrFile, "%s\n", message);
+        return;
+    }
+
+    /* Conditionally ignore reported warnings. */
+    if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
+        return;
+
+    prefix = NULL;
+    if (report->filename)
+        prefix = JS_smprintf("%s:", report->filename);
+    if (report->lineno) {
+        tmp = prefix;
+        prefix = JS_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
+        JS_free(cx, tmp);
+    }
+    if (JSREPORT_IS_WARNING(report->flags)) {
+        tmp = prefix;
+        prefix = JS_smprintf("%s%swarning: ",
+                             tmp ? tmp : "",
+                             JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
+        JS_free(cx, tmp);
+    }
+
+    /* embedded newlines -- argh! */
+    while ((ctmp = strchr(message, '\n')) != 0) {
+        ctmp++;
+        if (prefix)
+            fputs(prefix, gErrFile);
+        fwrite(message, 1, ctmp - message, gErrFile);
+        message = ctmp;
+    }
+
+    /* If there were no filename or lineno, the prefix might be empty */
+    if (prefix)
+        fputs(prefix, gErrFile);
+    fputs(message, gErrFile);
+
+    if (!report->linebuf) {
+        fputc('\n', gErrFile);
+        goto out;
+    }
+
+    /* report->linebuf usually ends with a newline. */
+    n = strlen(report->linebuf);
+    fprintf(gErrFile, ":\n%s%s%s%s",
+            prefix,
+            report->linebuf,
+            (n > 0 && report->linebuf[n-1] == '\n') ? "" : "\n",
+            prefix);
+    n = PTRDIFF(report->tokenptr, report->linebuf, char);
+    for (i = j = 0; i < n; i++) {
+        if (report->linebuf[i] == '\t') {
+            for (k = (j + 8) & ~7; j < k; j++) {
+                fputc('.', gErrFile);
+            }
+            continue;
+        }
+        fputc('.', gErrFile);
+        j++;
+    }
+    fputs("^\n", gErrFile);
+ out:
+    if (!JSREPORT_IS_WARNING(report->flags))
+        gExitCode = EXITCODE_RUNTIME_ERROR;
+    JS_free(cx, prefix);
+}
+
+#if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX)
+static JSBool
+Exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFunction *fun;
+    const char *name, **nargv;
+    uintN i, nargc;
+    JSString *str;
+    pid_t pid;
+    int status;
+
+    fun = JS_ValueToFunction(cx, argv[-2]);
+    if (!fun)
+        return JS_FALSE;
+    if (!fun->atom)
+        return JS_TRUE;
+    name = JS_GetStringBytes(ATOM_TO_STRING(fun->atom));
+    nargc = 1 + argc;
+    nargv = JS_malloc(cx, (nargc + 1) * sizeof(char *));
+    if (!nargv)
+        return JS_FALSE;
+    nargv[0] = name;
+    for (i = 1; i < nargc; i++) {
+        str = JS_ValueToString(cx, argv[i-1]);
+        if (!str) {
+            JS_free(cx, nargv);
+            return JS_FALSE;
+        }
+        nargv[i] = JS_GetStringBytes(str);
+    }
+    nargv[nargc] = 0;
+    pid = fork();
+    switch (pid) {
+      case -1:
+        perror("js");
+        break;
+      case 0:
+        (void) execvp(name, (char **)nargv);
+        perror("js");
+        exit(127);
+      default:
+        while (waitpid(pid, &status, 0) < 0 && errno == EINTR)
+            continue;
+        break;
+    }
+    JS_free(cx, nargv);
+    return JS_TRUE;
+}
+#endif
+
+#define LAZY_STANDARD_CLASSES
+
+static JSBool
+global_enumerate(JSContext *cx, JSObject *obj)
+{
+#ifdef LAZY_STANDARD_CLASSES
+    return JS_EnumerateStandardClasses(cx, obj);
+#else
+    return JS_TRUE;
+#endif
+}
+
+static JSBool
+global_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
+               JSObject **objp)
+{
+#ifdef LAZY_STANDARD_CLASSES
+    if ((flags & JSRESOLVE_ASSIGNING) == 0) {
+        JSBool resolved;
+
+        if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
+            return JS_FALSE;
+        if (resolved) {
+            *objp = obj;
+            return JS_TRUE;
+        }
+    }
+#endif
+
+#if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX)
+    if ((flags & (JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING)) == 0) {
+        /*
+         * Do this expensive hack only for unoptimized Unix builds, which are
+         * not used for benchmarking.
+         */
+        char *path, *comp, *full;
+        const char *name;
+        JSBool ok, found;
+        JSFunction *fun;
+
+        if (!JSVAL_IS_STRING(id))
+            return JS_TRUE;
+        path = getenv("PATH");
+        if (!path)
+            return JS_TRUE;
+        path = JS_strdup(cx, path);
+        if (!path)
+            return JS_FALSE;
+        name = JS_GetStringBytes(JSVAL_TO_STRING(id));
+        ok = JS_TRUE;
+        for (comp = strtok(path, ":"); comp; comp = strtok(NULL, ":")) {
+            if (*comp != '\0') {
+                full = JS_smprintf("%s/%s", comp, name);
+                if (!full) {
+                    JS_ReportOutOfMemory(cx);
+                    ok = JS_FALSE;
+                    break;
+                }
+            } else {
+                full = (char *)name;
+            }
+            found = (access(full, X_OK) == 0);
+            if (*comp != '\0')
+                free(full);
+            if (found) {
+                fun = JS_DefineFunction(cx, obj, name, Exec, 0,
+                                        JSPROP_ENUMERATE);
+                ok = (fun != NULL);
+                if (ok)
+                    *objp = obj;
+                break;
+            }
+        }
+        JS_free(cx, path);
+        return ok;
+    }
+#else
+    return JS_TRUE;
+#endif
+}
+
+JSClass global_class = {
+    "global", JSCLASS_NEW_RESOLVE,
+    JS_PropertyStub,  JS_PropertyStub,
+    JS_PropertyStub,  JS_PropertyStub,
+    global_enumerate, (JSResolveOp) global_resolve,
+    JS_ConvertStub,   JS_FinalizeStub
+};
+
+static JSBool
+env_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+/* XXX porting may be easy, but these don't seem to supply setenv by default */
+#if !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS
+    JSString *idstr, *valstr;
+    const char *name, *value;
+    int rv;
+
+    idstr = JS_ValueToString(cx, id);
+    valstr = JS_ValueToString(cx, *vp);
+    if (!idstr || !valstr)
+        return JS_FALSE;
+    name = JS_GetStringBytes(idstr);
+    value = JS_GetStringBytes(valstr);
+#if defined XP_WIN || defined HPUX || defined OSF1 || defined IRIX
+    {
+        char *waste = JS_smprintf("%s=%s", name, value);
+        if (!waste) {
+            JS_ReportOutOfMemory(cx);
+            return JS_FALSE;
+        }
+        rv = putenv(waste);
+#ifdef XP_WIN
+        /*
+         * HPUX9 at least still has the bad old non-copying putenv.
+         *
+         * Per mail from <s.shanmuganathan at digital.com>, OSF1 also has a putenv
+         * that will crash if you pass it an auto char array (so it must place
+         * its argument directly in the char *environ[] array).
+         */
+        free(waste);
+#endif
+    }
+#else
+    rv = setenv(name, value, 1);
+#endif
+    if (rv < 0) {
+        JS_ReportError(cx, "can't set envariable %s to %s", name, value);
+        return JS_FALSE;
+    }
+    *vp = STRING_TO_JSVAL(valstr);
+#endif /* !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS */
+    return JS_TRUE;
+}
+
+static JSBool
+env_enumerate(JSContext *cx, JSObject *obj)
+{
+    static JSBool reflected;
+    char **evp, *name, *value;
+    JSString *valstr;
+    JSBool ok;
+
+    if (reflected)
+        return JS_TRUE;
+
+    for (evp = (char **)JS_GetPrivate(cx, obj); (name = *evp) != NULL; evp++) {
+        value = strchr(name, '=');
+        if (!value)
+            continue;
+        *value++ = '\0';
+        valstr = JS_NewStringCopyZ(cx, value);
+        if (!valstr) {
+            ok = JS_FALSE;
+        } else {
+            ok = JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
+                                   NULL, NULL, JSPROP_ENUMERATE);
+        }
+        value[-1] = '=';
+        if (!ok)
+            return JS_FALSE;
+    }
+
+    reflected = JS_TRUE;
+    return JS_TRUE;
+}
+
+static JSBool
+env_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
+            JSObject **objp)
+{
+    JSString *idstr, *valstr;
+    const char *name, *value;
+
+    if (flags & JSRESOLVE_ASSIGNING)
+        return JS_TRUE;
+
+    idstr = JS_ValueToString(cx, id);
+    if (!idstr)
+        return JS_FALSE;
+    name = JS_GetStringBytes(idstr);
+    value = getenv(name);
+    if (value) {
+        valstr = JS_NewStringCopyZ(cx, value);
+        if (!valstr)
+            return JS_FALSE;
+        if (!JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
+                               NULL, NULL, JSPROP_ENUMERATE)) {
+            return JS_FALSE;
+        }
+        *objp = obj;
+    }
+    return JS_TRUE;
+}
+
+static JSClass env_class = {
+    "environment", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
+    JS_PropertyStub,  JS_PropertyStub,
+    JS_PropertyStub,  env_setProperty,
+    env_enumerate, (JSResolveOp) env_resolve,
+    JS_ConvertStub,   JS_FinalizeStub
+};
+
+#ifdef NARCISSUS
+
+static JSBool
+defineProperty(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    JSString *str;
+    jsval value;
+    JSBool dontDelete, readOnly, dontEnum;
+    const jschar *chars;
+    size_t length;
+    uintN attrs;
+
+    dontDelete = readOnly = dontEnum = JS_FALSE;
+    if (!JS_ConvertArguments(cx, argc, argv, "Sv/bbb",
+                             &str, &value, &dontDelete, &readOnly, &dontEnum)) {
+        return JS_FALSE;
+    }
+    chars = JS_GetStringChars(str);
+    length = JS_GetStringLength(str);
+    attrs = dontEnum ? 0 : JSPROP_ENUMERATE;
+    if (dontDelete)
+        attrs |= JSPROP_PERMANENT;
+    if (readOnly)
+        attrs |= JSPROP_READONLY;
+    return JS_DefineUCProperty(cx, obj, chars, length, value, NULL, NULL,
+                               attrs);
+}
+
+static JSBool
+Evaluate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    /* function evaluate(source, filename, lineno) { ... } */
+    JSString *source;
+    const char *filename = "";
+    jsuint lineno = 0;
+    uint32 oldopts;
+    JSBool ok;
+
+    if (argc == 0) {
+        *rval = JSVAL_VOID;
+        return JS_TRUE;
+    }
+
+    if (!JS_ConvertArguments(cx, argc, argv, "S/su",
+                             &source, &filename, &lineno)) {
+        return JS_FALSE;
+    }
+
+    oldopts = JS_GetOptions(cx);
+    JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
+    ok = JS_EvaluateUCScript(cx, obj, JS_GetStringChars(source),
+                             JS_GetStringLength(source), filename,
+                             lineno, rval);
+    JS_SetOptions(cx, oldopts);
+    
+    return ok;
+}
+
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/*
+ * Returns a JS_malloc'd string (that the caller needs to JS_free)
+ * containing the directory (non-leaf) part of |from| prepended to |leaf|.
+ * If |from| is empty or a leaf, MakeAbsolutePathname returns a copy of leaf.
+ * Returns NULL to indicate an error.
+ */
+static char *
+MakeAbsolutePathname(JSContext *cx, const char *from, const char *leaf)
+{
+    size_t dirlen;
+    char *dir;
+    const char *slash = NULL, *cp;
+
+    cp = from;
+    while (*cp) {
+        if (*cp == '/'
+#ifdef XP_WIN
+            || *cp == '\\'
+#endif
+           ) {
+            slash = cp;
+        }
+
+        ++cp;
+    }
+
+    if (!slash) {
+        /* We were given a leaf or |from| was empty. */
+        return JS_strdup(cx, leaf);
+    }
+
+    /* Else, we were given a real pathname, return that + the leaf. */
+    dirlen = slash - from + 1;
+    dir = JS_malloc(cx, dirlen + strlen(leaf) + 1);
+    if (!dir)
+        return NULL;
+
+    strncpy(dir, from, dirlen);
+    strcpy(dir + dirlen, leaf); /* Note: we can't use strcat here. */
+
+    return dir;
+}
+
+static JSBool
+snarf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+    const char *filename;
+    char *pathname;
+    JSStackFrame *fp;
+    int fd, cc;
+    JSBool ok;
+    size_t len;
+    char *buf;
+    struct stat sb;
+
+    str = JS_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    filename = JS_GetStringBytes(str);
+    
+    /* Get the currently executing script's name. */
+    fp = JS_GetScriptedCaller(cx, NULL);
+    JS_ASSERT(fp && fp->script->filename);
+    pathname = MakeAbsolutePathname(cx, fp->script->filename, filename);
+    if (!pathname)
+        return JS_FALSE;
+
+    fd = open(pathname, O_RDONLY);
+    ok = JS_TRUE;
+    len = 0;
+    buf = NULL;
+    if (fd < 0) {
+        JS_ReportError(cx, "can't open %s: %s", pathname, strerror(errno));
+        ok = JS_FALSE;
+    } else if (fstat(fd, &sb) < 0) {
+        JS_ReportError(cx, "can't stat %s", pathname);
+        ok = JS_FALSE;
+    } else {
+        len = sb.st_size;
+        buf = JS_malloc(cx, len + 1);
+        if (!buf) {
+            ok = JS_FALSE;
+        } else if ((cc = read(fd, buf, len)) != len) {
+            JS_free(cx, buf);
+            JS_ReportError(cx, "can't read %s: %s", pathname,
+                           (cc < 0) ? strerror(errno) : "short read");
+            ok = JS_FALSE;
+        }
+    }
+    close(fd);
+    JS_free(cx, pathname);
+    if (!ok)
+        return ok;
+    buf[len] = '\0';
+    str = JS_NewString(cx, buf, len);
+    if (!str) {
+        JS_free(cx, buf);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+#endif /* NARCISSUS */
+
+int
+main(int argc, char **argv, char **envp)
+{
+    int stackDummy;
+    JSRuntime *rt;
+    JSContext *cx;
+    JSObject *glob, *it, *envobj;
+    int result;
+#ifdef LIVECONNECT
+    JavaVM *java_vm = NULL;
+#endif
+#ifdef JSDEBUGGER_JAVA_UI
+    JNIEnv *java_env;
+#endif
+
+    gStackBase = (jsuword)&stackDummy;
+
+#ifdef XP_OS2
+   /* these streams are normally line buffered on OS/2 and need a \n, *
+    * so we need to unbuffer then to get a reasonable prompt          */
+    setbuf(stdout,0);
+    setbuf(stderr,0);
+#endif
+
+#if defined(OSSP) && defined(XP_WIN)
+    setvbuf(stderr, 0, _IONBF, 0);
+    setvbuf(stdout, 0, _IONBF, 0);
+#endif
+
+    gErrFile = stderr;
+    gOutFile = stdout;
+
+    argc--;
+    argv++;
+
+    rt = JS_NewRuntime(64L * 1024L * 1024L);
+    if (!rt)
+        return 1;
+
+    cx = JS_NewContext(rt, gStackChunkSize);
+    if (!cx)
+        return 1;
+    JS_SetErrorReporter(cx, my_ErrorReporter);
+
+    glob = JS_NewObject(cx, &global_class, NULL, NULL);
+    if (!glob)
+        return 1;
+#ifdef LAZY_STANDARD_CLASSES
+    JS_SetGlobalObject(cx, glob);
+#else
+    if (!JS_InitStandardClasses(cx, glob))
+        return 1;
+#ifdef OSSP
+#if defined(JS_HAS_FILE_OBJECT) && (JS_HAS_FILE_OBJECT - 0) /* OSSP BUGFIX */
+    if (!js_InitFileClass(cx, glob))
+        return 1;
+#endif
+#if defined(JS_HAS_DSO_OBJECT) && (JS_HAS_DSO_OBJECT - 0)
+    if (!js_InitDSOClass(cx, glob))
+        return 1;
+#endif
+#endif
+#endif
+    if (!JS_DefineFunctions(cx, glob, shell_functions))
+        return 1;
+
+    it = JS_DefineObject(cx, glob, "it", &its_class, NULL, 0);
+    if (!it)
+        return 1;
+    if (!JS_DefineProperties(cx, it, its_props))
+        return 1;
+    if (!JS_DefineFunctions(cx, it, its_methods))
+        return 1;
+
+#ifdef PERLCONNECT
+    if (!JS_InitPerlClass(cx, glob))
+        return 1;
+#endif
+
+#ifdef JSDEBUGGER
+    /*
+    * XXX A command line option to enable debugging (or not) would be good
+    */
+    _jsdc = JSD_DebuggerOnForUser(rt, NULL, NULL);
+    if (!_jsdc)
+        return 1;
+    JSD_JSContextInUse(_jsdc, cx);
+#ifdef JSD_LOWLEVEL_SOURCE
+    JS_SetSourceHandler(rt, SendSourceToJSDebugger, _jsdc);
+#endif /* JSD_LOWLEVEL_SOURCE */
+#ifdef JSDEBUGGER_JAVA_UI
+    _jsdjc = JSDJ_CreateContext();
+    if (! _jsdjc)
+        return 1;
+    JSDJ_SetJSDContext(_jsdjc, _jsdc);
+    java_env = JSDJ_CreateJavaVMAndStartDebugger(_jsdjc);
+#ifdef LIVECONNECT
+    if (java_env)
+        (*java_env)->GetJavaVM(java_env, &java_vm);
+#endif
+    /*
+    * XXX This would be the place to wait for the debugger to start.
+    * Waiting would be nice in general, but especially when a js file
+    * is passed on the cmd line.
+    */
+#endif /* JSDEBUGGER_JAVA_UI */
+#ifdef JSDEBUGGER_C_UI
+    JSDB_InitDebugger(rt, _jsdc, 0);
+#endif /* JSDEBUGGER_C_UI */
+#endif /* JSDEBUGGER */
+
+#ifdef LIVECONNECT
+    if (!JSJ_SimpleInit(cx, glob, java_vm, getenv("CLASSPATH")))
+        return 1;
+#endif
+
+    envobj = JS_DefineObject(cx, glob, "environment", &env_class, NULL, 0);
+    if (!envobj || !JS_SetPrivate(cx, envobj, envp))
+        return 1;
+
+#ifdef NARCISSUS
+    {
+        jsval v;
+        static const char Object_prototype[] = "Object.prototype";
+
+        if (!JS_DefineFunction(cx, glob, "snarf", snarf, 1, 0))
+            return 1;
+        if (!JS_DefineFunction(cx, glob, "evaluate", Evaluate, 3, 0))
+            return 1;
+
+        if (!JS_EvaluateScript(cx, glob,
+                               Object_prototype, sizeof Object_prototype - 1,
+                               NULL, 0, &v)) {
+            return 1;
+        }
+        if (!JS_DefineFunction(cx, JSVAL_TO_OBJECT(v), "__defineProperty__",
+                               defineProperty, 5, 0)) {
+            return 1;
+        }
+    }
+#endif
+
+    result = ProcessArgs(cx, glob, argv, argc);
+
+#ifdef JSDEBUGGER
+    if (_jsdc)
+        JSD_DebuggerOff(_jsdc);
+#endif  /* JSDEBUGGER */
+
+    JS_DestroyContext(cx);
+    JS_DestroyRuntime(rt);
+    JS_ShutDown();
+    return result;
+}

Added: freeswitch/trunk/libs/js/src/js.msg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/js.msg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,287 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This is the JavaScript error message file.
+ *
+ * The format for each JS error message is:
+ *
+ * MSG_DEF(<SYMBOLIC_NAME>, <ERROR_NUMBER>, <ARGUMENT_COUNT>, <EXCEPTION_NAME>,
+ *         <FORMAT_STRING>)
+ *
+ * where ;
+ * <SYMBOLIC_NAME> is a legal C identifer that will be used in the
+ * JS engine source.
+ *
+ * <ERROR_NUMBER> is an unique integral value identifying this error.
+ *
+ * <ARGUMENT_COUNT> is an integer literal specifying the total number of
+ * replaceable arguments in the following format string.
+ *
+ * <EXCEPTION_NAME> is an exception index from the enum in jsexn.c;
+ * JSEXN_NONE for none.  The given exception index will be raised by the
+ * engine when the corresponding error occurs.
+ *
+ * <FORMAT_STRING> is a string literal, optionally containing sequences
+ * {X} where X  is an integer representing the argument number that will
+ * be replaced with a string value when the error is reported.
+ *
+ * e.g.
+ *
+ * MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 73, JSEXN_NONE, 2,
+ *         "{0} is not a member of the {1} family")
+ *
+ * can be used:
+ *
+ * JS_ReportErrorNumber(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey");
+ *
+ * to report:
+ *
+ * "Rhino is not a member of the Monkey family"
+ *
+ * Before adding a new MSG_DEF at the end, look for JSMSG_UNUSED<n> free
+ * index placeholders in the middle of the list.
+ */
+
+MSG_DEF(JSMSG_NOT_AN_ERROR,             0, 0, JSEXN_NONE, "<Error #0 is reserved>")
+MSG_DEF(JSMSG_NOT_DEFINED,              1, 1, JSEXN_REFERENCEERR, "{0} is not defined")
+MSG_DEF(JSMSG_NO_REG_EXPS,              2, 1, JSEXN_INTERNALERR, "sorry, regular expression are not supported")
+MSG_DEF(JSMSG_MORE_ARGS_NEEDED,         3, 3, JSEXN_NONE, "{0} requires more than {1} argument{2}")
+MSG_DEF(JSMSG_BAD_CHAR,                 4, 1, JSEXN_NONE, "invalid format character {0}")
+MSG_DEF(JSMSG_BAD_TYPE,                 5, 1, JSEXN_NONE, "unknown type {0}")
+MSG_DEF(JSMSG_CANT_LOCK,                6, 0, JSEXN_NONE, "can't lock memory")
+MSG_DEF(JSMSG_CANT_UNLOCK,              7, 0, JSEXN_NONE, "can't unlock memory")
+MSG_DEF(JSMSG_INCOMPATIBLE_PROTO,       8, 3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}")
+MSG_DEF(JSMSG_NO_CONSTRUCTOR,           9, 1, JSEXN_NONE, "{0} has no constructor")
+MSG_DEF(JSMSG_CANT_ALIAS,              10, 3, JSEXN_NONE, "can't alias {0} to {1} in class {2}")
+MSG_DEF(JSMSG_NOT_SCRIPTED_FUNCTION,   11, 1, JSEXN_TYPEERR, "{0} is not a scripted function")
+MSG_DEF(JSMSG_BAD_SORT_ARG,            12, 0, JSEXN_TYPEERR, "invalid Array.prototype.sort argument")
+MSG_DEF(JSMSG_BAD_ATOMIC_NUMBER,       13, 1, JSEXN_INTERNALERR, "internal error: no index for atom {0}")
+MSG_DEF(JSMSG_TOO_MANY_LITERALS,       14, 0, JSEXN_INTERNALERR, "too many literals")
+MSG_DEF(JSMSG_CANT_WATCH,              15, 1, JSEXN_NONE, "can't watch non-native objects of class {0}")
+MSG_DEF(JSMSG_STACK_UNDERFLOW,         16, 2, JSEXN_INTERNALERR, "internal error compiling {0}: stack underflow at pc {1}")
+MSG_DEF(JSMSG_NEED_DIET,               17, 1, JSEXN_INTERNALERR, "{0} too large")
+MSG_DEF(JSMSG_TOO_MANY_LOCAL_ROOTS,    18, 0, JSEXN_ERR, "out of local root space")
+MSG_DEF(JSMSG_READ_ONLY,               19, 1, JSEXN_ERR, "{0} is read-only")
+MSG_DEF(JSMSG_BAD_FORMAL,              20, 0, JSEXN_SYNTAXERR, "malformed formal parameter")
+MSG_DEF(JSMSG_SAME_FORMAL,             21, 1, JSEXN_NONE, "duplicate formal argument {0}")
+MSG_DEF(JSMSG_NOT_FUNCTION,            22, 1, JSEXN_TYPEERR, "{0} is not a function")
+MSG_DEF(JSMSG_NOT_CONSTRUCTOR,         23, 1, JSEXN_TYPEERR, "{0} is not a constructor")
+MSG_DEF(JSMSG_STACK_OVERFLOW,          24, 1, JSEXN_INTERNALERR, "stack overflow in {0}")
+MSG_DEF(JSMSG_NOT_EXPORTED,            25, 1, JSEXN_NONE, "{0} is not exported")
+MSG_DEF(JSMSG_OVER_RECURSED,           26, 0, JSEXN_INTERNALERR, "too much recursion")
+MSG_DEF(JSMSG_IN_NOT_OBJECT,           27, 1, JSEXN_TYPEERR, "invalid 'in' operand {0}")
+MSG_DEF(JSMSG_BAD_NEW_RESULT,          28, 1, JSEXN_NONE, "invalid new expression result {0}")
+MSG_DEF(JSMSG_BAD_SHARP_DEF,           29, 1, JSEXN_ERR, "invalid sharp variable definition #{0}=")
+MSG_DEF(JSMSG_BAD_SHARP_USE,           30, 1, JSEXN_ERR, "invalid sharp variable use #{0}#")
+MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS,      31, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}")
+MSG_DEF(JSMSG_BAD_BYTECODE,            32, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}")
+MSG_DEF(JSMSG_BAD_RADIX,               33, 1, JSEXN_ERR, "illegal radix {0}")
+MSG_DEF(JSMSG_NAN,                     34, 1, JSEXN_ERR, "{0} is not a number")
+MSG_DEF(JSMSG_CANT_CONVERT,            35, 1, JSEXN_NONE, "can't convert {0} to an integer")
+MSG_DEF(JSMSG_CYCLIC_VALUE,            36, 1, JSEXN_ERR, "cyclic {0} value")
+MSG_DEF(JSMSG_PERMANENT,               37, 1, JSEXN_ERR, "{0} is permanent")
+MSG_DEF(JSMSG_CANT_CONVERT_TO,         38, 2, JSEXN_TYPEERR, "can't convert {0} to {1}")
+MSG_DEF(JSMSG_NO_PROPERTIES,           39, 1, JSEXN_TYPEERR, "{0} has no properties")
+MSG_DEF(JSMSG_CANT_FIND_CLASS,         40, 1, JSEXN_NONE, "can't find class id {0}")
+MSG_DEF(JSMSG_CANT_XDR_CLASS,          41, 1, JSEXN_NONE, "can't XDR class {0}")
+MSG_DEF(JSMSG_BYTECODE_TOO_BIG,        42, 2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})")
+MSG_DEF(JSMSG_UNKNOWN_FORMAT,          43, 1, JSEXN_INTERNALERR, "unknown bytecode format {0}")
+MSG_DEF(JSMSG_TOO_MANY_CON_ARGS,       44, 0, JSEXN_SYNTAXERR, "too many constructor arguments")
+MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS,       45, 0, JSEXN_SYNTAXERR, "too many function arguments")
+MSG_DEF(JSMSG_BAD_QUANTIFIER,          46, 1, JSEXN_SYNTAXERR, "invalid quantifier {0}")
+MSG_DEF(JSMSG_MIN_TOO_BIG,             47, 1, JSEXN_SYNTAXERR, "overlarge minimum {0}")
+MSG_DEF(JSMSG_MAX_TOO_BIG,             48, 1, JSEXN_SYNTAXERR, "overlarge maximum {0}")
+MSG_DEF(JSMSG_OUT_OF_ORDER,            49, 1, JSEXN_SYNTAXERR, "maximum {0} less than minimum")
+MSG_DEF(JSMSG_ZERO_QUANTIFIER,         50, 1, JSEXN_SYNTAXERR, "zero quantifier {0}")
+MSG_DEF(JSMSG_UNTERM_QUANTIFIER,       51, 1, JSEXN_SYNTAXERR, "unterminated quantifier {0}")
+MSG_DEF(JSMSG_EMPTY_BEFORE_STAR,       52, 0, JSEXN_SYNTAXERR, "regular expression before * could be empty")
+MSG_DEF(JSMSG_EMPTY_BEFORE_PLUS,       53, 0, JSEXN_SYNTAXERR, "regular expression before + could be empty")
+MSG_DEF(JSMSG_MISSING_PAREN,           54, 0, JSEXN_SYNTAXERR, "unterminated parenthetical")
+MSG_DEF(JSMSG_UNTERM_CLASS,            55, 1, JSEXN_SYNTAXERR, "unterminated character class {0}")
+MSG_DEF(JSMSG_TRAILING_SLASH,          56, 0, JSEXN_SYNTAXERR, "trailing \\ in regular expression")
+MSG_DEF(JSMSG_BAD_CLASS_RANGE,         57, 0, JSEXN_SYNTAXERR, "invalid range in character class")
+MSG_DEF(JSMSG_BAD_FLAG,                58, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}")
+MSG_DEF(JSMSG_NO_INPUT,                59, 3, JSEXN_SYNTAXERR, "no input for /{0}/{1}{2}")
+MSG_DEF(JSMSG_CANT_OPEN,               60, 2, JSEXN_NONE, "can't open {0}: {1}")
+MSG_DEF(JSMSG_BAD_STRING_MASK,         61, 1, JSEXN_ERR, "invalid string escape mask {0}")
+MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN,   62, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression")
+MSG_DEF(JSMSG_END_OF_DATA,             63, 0, JSEXN_NONE, "unexpected end of data")
+MSG_DEF(JSMSG_SEEK_BEYOND_START,       64, 0, JSEXN_NONE, "illegal seek beyond start")
+MSG_DEF(JSMSG_SEEK_BEYOND_END,         65, 0, JSEXN_NONE, "illegal seek beyond end")
+MSG_DEF(JSMSG_END_SEEK,                66, 0, JSEXN_NONE, "illegal end-based seek")
+MSG_DEF(JSMSG_WHITHER_WHENCE,          67, 1, JSEXN_NONE, "unknown seek whence: {0}")
+MSG_DEF(JSMSG_BAD_SCRIPT_MAGIC,        68, 0, JSEXN_NONE, "bad script XDR magic number")
+MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL,     69, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters")
+MSG_DEF(JSMSG_MISSING_FORMAL,          70, 0, JSEXN_SYNTAXERR, "missing formal parameter")
+MSG_DEF(JSMSG_PAREN_AFTER_FORMAL,      71, 0, JSEXN_SYNTAXERR, "missing ) after formal parameters")
+MSG_DEF(JSMSG_CURLY_BEFORE_BODY,       72, 0, JSEXN_SYNTAXERR, "missing { before function body")
+MSG_DEF(JSMSG_CURLY_AFTER_BODY,        73, 0, JSEXN_SYNTAXERR, "missing } after function body")
+MSG_DEF(JSMSG_PAREN_BEFORE_COND,       74, 0, JSEXN_SYNTAXERR, "missing ( before condition")
+MSG_DEF(JSMSG_PAREN_AFTER_COND,        75, 0, JSEXN_SYNTAXERR, "missing ) after condition")
+MSG_DEF(JSMSG_NO_IMPORT_NAME,          76, 0, JSEXN_SYNTAXERR, "missing name in import statement")
+MSG_DEF(JSMSG_NAME_AFTER_DOT,          77, 0, JSEXN_SYNTAXERR, "missing name after . operator")
+MSG_DEF(JSMSG_BRACKET_IN_INDEX,        78, 0, JSEXN_SYNTAXERR, "missing ] in index expression")
+MSG_DEF(JSMSG_NO_EXPORT_NAME,          79, 0, JSEXN_SYNTAXERR, "missing name in export statement")
+MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH,     80, 0, JSEXN_SYNTAXERR, "missing ( before switch expression")
+MSG_DEF(JSMSG_PAREN_AFTER_SWITCH,      81, 0, JSEXN_SYNTAXERR, "missing ) after switch expression")
+MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH,     82, 0, JSEXN_SYNTAXERR, "missing { before switch body")
+MSG_DEF(JSMSG_COLON_AFTER_CASE,        83, 0, JSEXN_SYNTAXERR, "missing : after case label")
+MSG_DEF(JSMSG_WHILE_AFTER_DO,          84, 0, JSEXN_SYNTAXERR, "missing while after do-loop body")
+MSG_DEF(JSMSG_PAREN_AFTER_FOR,         85, 0, JSEXN_SYNTAXERR, "missing ( after for")
+MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT,     86, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer")
+MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND,     87, 0, JSEXN_SYNTAXERR, "missing ; after for-loop condition")
+MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL,    88, 0, JSEXN_SYNTAXERR, "missing ) after for-loop control")
+MSG_DEF(JSMSG_CURLY_BEFORE_TRY,        89, 0, JSEXN_SYNTAXERR, "missing { before try block")
+MSG_DEF(JSMSG_CURLY_AFTER_TRY,         90, 0, JSEXN_SYNTAXERR, "missing } after try block")
+MSG_DEF(JSMSG_PAREN_BEFORE_CATCH,      91, 0, JSEXN_SYNTAXERR, "missing ( before catch")
+MSG_DEF(JSMSG_CATCH_IDENTIFIER,        92, 0, JSEXN_SYNTAXERR, "missing identifier in catch")
+MSG_DEF(JSMSG_PAREN_AFTER_CATCH,       93, 0, JSEXN_SYNTAXERR, "missing ) after catch")
+MSG_DEF(JSMSG_CURLY_BEFORE_CATCH,      94, 0, JSEXN_SYNTAXERR, "missing { before catch block")
+MSG_DEF(JSMSG_CURLY_AFTER_CATCH,       95, 0, JSEXN_SYNTAXERR, "missing } after catch block")
+MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY,    96, 0, JSEXN_SYNTAXERR, "missing { before finally block")
+MSG_DEF(JSMSG_CURLY_AFTER_FINALLY,     97, 0, JSEXN_SYNTAXERR, "missing } after finally block")
+MSG_DEF(JSMSG_CATCH_OR_FINALLY,        98, 0, JSEXN_SYNTAXERR, "missing catch or finally after try")
+MSG_DEF(JSMSG_PAREN_BEFORE_WITH,       99, 0, JSEXN_SYNTAXERR, "missing ( before with-statement object")
+MSG_DEF(JSMSG_PAREN_AFTER_WITH,       100, 0, JSEXN_SYNTAXERR, "missing ) after with-statement object")
+MSG_DEF(JSMSG_CURLY_IN_COMPOUND,      101, 0, JSEXN_SYNTAXERR, "missing } in compound statement")
+MSG_DEF(JSMSG_NO_VARIABLE_NAME,       102, 0, JSEXN_SYNTAXERR, "missing variable name")
+MSG_DEF(JSMSG_COLON_IN_COND,          103, 0, JSEXN_SYNTAXERR, "missing : in conditional expression")
+MSG_DEF(JSMSG_PAREN_AFTER_ARGS,       104, 0, JSEXN_SYNTAXERR, "missing ) after argument list")
+MSG_DEF(JSMSG_BRACKET_AFTER_LIST,     105, 0, JSEXN_SYNTAXERR, "missing ] after element list")
+MSG_DEF(JSMSG_COLON_AFTER_ID,         106, 0, JSEXN_SYNTAXERR, "missing : after property id")
+MSG_DEF(JSMSG_CURLY_AFTER_LIST,       107, 0, JSEXN_SYNTAXERR, "missing } after property list")
+MSG_DEF(JSMSG_PAREN_IN_PAREN,         108, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical")
+MSG_DEF(JSMSG_SEMI_BEFORE_STMNT,      109, 0, JSEXN_SYNTAXERR, "missing ; before statement")
+MSG_DEF(JSMSG_NO_RETURN_VALUE,        110, 1, JSEXN_TYPEERR, "function {0} does not always return a value")
+MSG_DEF(JSMSG_DUPLICATE_FORMAL,       111, 1, JSEXN_TYPEERR, "duplicate formal argument {0}")
+MSG_DEF(JSMSG_EQUAL_AS_ASSIGN,        112, 1, JSEXN_NONE, "test for equality (==) mistyped as assignment (=)?{0}")
+MSG_DEF(JSMSG_BAD_IMPORT,             113, 0, JSEXN_SYNTAXERR, "invalid import expression")
+MSG_DEF(JSMSG_TOO_MANY_DEFAULTS,      114, 0, JSEXN_SYNTAXERR, "more than one switch default")
+MSG_DEF(JSMSG_TOO_MANY_CASES,         115, 0, JSEXN_INTERNALERR, "too many switch cases")
+MSG_DEF(JSMSG_BAD_SWITCH,             116, 0, JSEXN_SYNTAXERR, "invalid switch statement")
+MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE,       117, 0, JSEXN_SYNTAXERR, "invalid for/in left-hand side")
+MSG_DEF(JSMSG_CATCH_AFTER_GENERAL,    118, 0, JSEXN_SYNTAXERR, "catch after unconditional catch")
+MSG_DEF(JSMSG_CATCH_WITHOUT_TRY,      119, 0, JSEXN_SYNTAXERR, "catch without try")
+MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY,    120, 0, JSEXN_SYNTAXERR, "finally without try")
+MSG_DEF(JSMSG_LABEL_NOT_FOUND,        121, 0, JSEXN_SYNTAXERR, "label not found")
+MSG_DEF(JSMSG_TOUGH_BREAK,            122, 0, JSEXN_SYNTAXERR, "invalid break")
+MSG_DEF(JSMSG_BAD_CONTINUE,           123, 0, JSEXN_SYNTAXERR, "invalid continue")
+MSG_DEF(JSMSG_BAD_RETURN,             124, 0, JSEXN_SYNTAXERR, "invalid return")
+MSG_DEF(JSMSG_BAD_LABEL,              125, 0, JSEXN_SYNTAXERR, "invalid label")
+MSG_DEF(JSMSG_DUPLICATE_LABEL,        126, 0, JSEXN_SYNTAXERR, "duplicate label")
+MSG_DEF(JSMSG_VAR_HIDES_ARG,          127, 1, JSEXN_TYPEERR, "variable {0} hides argument")
+MSG_DEF(JSMSG_BAD_VAR_INIT,           128, 0, JSEXN_SYNTAXERR, "invalid variable initialization")
+MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS,    129, 0, JSEXN_SYNTAXERR, "invalid assignment left-hand side")
+MSG_DEF(JSMSG_BAD_OPERAND,            130, 1, JSEXN_SYNTAXERR, "invalid {0} operand")
+MSG_DEF(JSMSG_BAD_PROP_ID,            131, 0, JSEXN_SYNTAXERR, "invalid property id")
+MSG_DEF(JSMSG_RESERVED_ID,            132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier")
+MSG_DEF(JSMSG_SYNTAX_ERROR,           133, 0, JSEXN_SYNTAXERR, "syntax error")
+MSG_DEF(JSMSG_BAD_SHARP_VAR_DEF,      134, 0, JSEXN_SYNTAXERR, "invalid sharp variable definition")
+MSG_DEF(JSMSG_BAD_PROTOTYPE,          135, 1, JSEXN_TYPEERR,   "'prototype' property of {0} is not an object")
+MSG_DEF(JSMSG_MISSING_EXPONENT,       136, 0, JSEXN_SYNTAXERR, "missing exponent")
+MSG_DEF(JSMSG_OUT_OF_MEMORY,          137, 0, JSEXN_ERR, "out of memory")
+MSG_DEF(JSMSG_UNTERMINATED_STRING,    138, 0, JSEXN_SYNTAXERR, "unterminated string literal")
+MSG_DEF(JSMSG_TOO_MANY_PARENS,        139, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression")
+MSG_DEF(JSMSG_UNTERMINATED_COMMENT,   140, 0, JSEXN_SYNTAXERR, "unterminated comment")
+MSG_DEF(JSMSG_UNTERMINATED_REGEXP,    141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal")
+MSG_DEF(JSMSG_BAD_REGEXP_FLAG,        142, 0, JSEXN_SYNTAXERR, "invalid flag after regular expression")
+MSG_DEF(JSMSG_SHARPVAR_TOO_BIG,       143, 0, JSEXN_SYNTAXERR, "overlarge sharp variable number")
+MSG_DEF(JSMSG_ILLEGAL_CHARACTER,      144, 0, JSEXN_SYNTAXERR, "illegal character")
+MSG_DEF(JSMSG_BAD_OCTAL,              145, 1, JSEXN_SYNTAXERR, "{0} is not a legal ECMA-262 octal constant")
+MSG_DEF(JSMSG_BAD_INDIRECT_CALL,      146, 1, JSEXN_EVALERR, "function {0} must be called directly, and not by way of a function of another name")
+MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION,     147, 1, JSEXN_NONE, "uncaught exception: {0}")
+MSG_DEF(JSMSG_INVALID_BACKREF,        148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference")
+MSG_DEF(JSMSG_BAD_BACKREF,            149, 0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses")
+MSG_DEF(JSMSG_PRECISION_RANGE,        150, 1, JSEXN_RANGEERR, "precision {0} out of range")
+MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER,   151, 1, JSEXN_SYNTAXERR, "invalid {0} usage")
+MSG_DEF(JSMSG_BAD_ARRAY_LENGTH,       152, 0, JSEXN_RANGEERR, "invalid array length")
+MSG_DEF(JSMSG_CANT_DESCRIBE_PROPS,    153, 1, JSEXN_NONE, "can't describe non-native properties of class {0}")
+MSG_DEF(JSMSG_BAD_APPLY_ARGS,         154, 0, JSEXN_TYPEERR, "second argument to Function.prototype.apply must be an array")
+MSG_DEF(JSMSG_REDECLARED_VAR,         155, 2, JSEXN_TYPEERR, "redeclaration of {0} {1}")
+MSG_DEF(JSMSG_UNDECLARED_VAR,         156, 1, JSEXN_TYPEERR, "assignment to undeclared variable {0}")
+MSG_DEF(JSMSG_ANON_NO_RETURN_VALUE,   157, 0, JSEXN_TYPEERR, "anonymous function does not always return a value")
+MSG_DEF(JSMSG_DEPRECATED_USAGE,       158, 1, JSEXN_REFERENCEERR, "deprecated {0} usage")
+MSG_DEF(JSMSG_BAD_URI,                159, 0, JSEXN_URIERR, "malformed URI sequence")
+MSG_DEF(JSMSG_GETTER_ONLY,            160, 0, JSEXN_TYPEERR, "setting a property that has only a getter")
+MSG_DEF(JSMSG_TRAILING_COMMA,         161, 0, JSEXN_SYNTAXERR, "trailing comma is not legal in ECMA-262 object initializers")
+MSG_DEF(JSMSG_UNDEFINED_PROP,         162, 1, JSEXN_TYPEERR, "reference to undefined property {0}")
+MSG_DEF(JSMSG_USELESS_EXPR,           163, 0, JSEXN_TYPEERR, "useless expression")
+MSG_DEF(JSMSG_REDECLARED_PARAM,       164, 1, JSEXN_TYPEERR, "redeclaration of formal parameter {0}")
+MSG_DEF(JSMSG_NEWREGEXP_FLAGGED,      165, 0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another")
+MSG_DEF(JSMSG_RESERVED_SLOT_RANGE,    166, 0, JSEXN_RANGEERR, "reserved slot index out of range")
+MSG_DEF(JSMSG_CANT_DECODE_PRINCIPALS, 167, 0, JSEXN_INTERNALERR, "can't decode JSPrincipals")
+MSG_DEF(JSMSG_CANT_SEAL_OBJECT,       168, 1, JSEXN_ERR, "can't seal {0} objects")
+MSG_DEF(JSMSG_CANT_UNSEAL_OBJECT,     169, 1, JSEXN_ERR, "can't unseal {0} objects")
+MSG_DEF(JSMSG_BAD_XML_MARKUP,         170, 0, JSEXN_SYNTAXERR, "invalid XML markup")
+MSG_DEF(JSMSG_BAD_XML_CHARACTER,      171, 0, JSEXN_SYNTAXERR, "illegal XML character")
+MSG_DEF(JSMSG_BAD_DEFAULT_XML_NAMESPACE,172,0,JSEXN_SYNTAXERR, "invalid default XML namespace")
+MSG_DEF(JSMSG_BAD_XML_NAME_SYNTAX,    173, 0, JSEXN_SYNTAXERR, "invalid XML name")
+MSG_DEF(JSMSG_BRACKET_AFTER_ATTR_EXPR,174, 0, JSEXN_SYNTAXERR, "missing ] after attribute expression")
+MSG_DEF(JSMSG_NAME_AFTER_DBLDOT,      175, 0, JSEXN_SYNTAXERR, "missing name after .. operator")
+MSG_DEF(JSMSG_CURLY_IN_XML_EXPR,      176, 0, JSEXN_SYNTAXERR, "missing } in XML expression")
+MSG_DEF(JSMSG_BAD_XML_NAMESPACE,      177, 1, JSEXN_TYPEERR, "invalid XML namespace {0}")
+MSG_DEF(JSMSG_BAD_XML_ATTR_NAME,      178, 1, JSEXN_TYPEERR, "invalid XML attribute name {0}")
+MSG_DEF(JSMSG_BAD_XML_NAME,           179, 1, JSEXN_TYPEERR, "invalid XML name {0}")
+MSG_DEF(JSMSG_BAD_XML_CONVERSION,     180, 1, JSEXN_TYPEERR, "can't convert {0} to XML")
+MSG_DEF(JSMSG_BAD_XMLLIST_CONVERSION, 181, 1, JSEXN_TYPEERR, "can't convert {0} to XMLList")
+MSG_DEF(JSMSG_IS_NOT_XML_OBJECT,      182, 1, JSEXN_TYPEERR, "{0} is not an XML object")
+MSG_DEF(JSMSG_NO_ASSIGN_IN_XML_ATTR,  183, 0, JSEXN_SYNTAXERR, "missing = in XML attribute")
+MSG_DEF(JSMSG_BAD_XML_ATTR_VALUE,     184, 0, JSEXN_SYNTAXERR, "invalid XML attribute value")
+MSG_DEF(JSMSG_XML_TAG_NAME_MISMATCH,  185, 0, JSEXN_SYNTAXERR, "XML tag name mismatch")
+MSG_DEF(JSMSG_BAD_XML_TAG_SYNTAX,     186, 0, JSEXN_SYNTAXERR, "invalid XML tag syntax")
+MSG_DEF(JSMSG_BAD_XML_LIST_SYNTAX,    187, 0, JSEXN_SYNTAXERR, "invalid XML list syntax")
+MSG_DEF(JSMSG_INCOMPATIBLE_METHOD,    188, 3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}")
+MSG_DEF(JSMSG_CANT_SET_XML_ATTRS,     189, 0, JSEXN_INTERNALERR, "can't set XML property attributes")
+MSG_DEF(JSMSG_END_OF_XML_SOURCE,      190, 0, JSEXN_SYNTAXERR, "unexpected end of XML source")
+MSG_DEF(JSMSG_END_OF_XML_ENTITY,      191, 0, JSEXN_SYNTAXERR, "unexpected end of XML entity")
+MSG_DEF(JSMSG_BAD_XML_QNAME,          192, 0, JSEXN_SYNTAXERR, "invalid XML qualified name")
+MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP,      193, 0, JSEXN_SYNTAXERR, "invalid for each loop")
+MSG_DEF(JSMSG_BAD_XMLLIST_PUT,        194, 1, JSEXN_TYPEERR, "can't set property {0} in XMLList")
+MSG_DEF(JSMSG_UNKNOWN_XML_ENTITY,     195, 1, JSEXN_TYPEERR, "unknown XML entity {0}")
+MSG_DEF(JSMSG_BAD_XML_NCR,            196, 1, JSEXN_TYPEERR, "malformed XML character {0}")
+MSG_DEF(JSMSG_UNDEFINED_XML_NAME,     197, 1, JSEXN_REFERENCEERR, "reference to undefined XML name {0}")
+MSG_DEF(JSMSG_DUPLICATE_XML_ATTR,     198, 1, JSEXN_TYPEERR, "duplicate XML attribute {0}")
+MSG_DEF(JSMSG_TOO_MANY_FUN_VARS,      199, 0, JSEXN_SYNTAXERR, "too many local variables")
+MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG,     200, 0, JSEXN_INTERNALERR, "array initialiser too large")
+MSG_DEF(JSMSG_REGEXP_TOO_COMPLEX,     201, 0, JSEXN_INTERNALERR, "regular expression too complex")
+MSG_DEF(JSMSG_BUFFER_TOO_SMALL,       202, 0, JSEXN_INTERNALERR, "buffer too small")
+MSG_DEF(JSMSG_BAD_SURROGATE_CHAR,     203, 1, JSEXN_TYPEERR, "bad surrogate character {0}")
+MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE,    204, 1, JSEXN_TYPEERR, "UTF-8 character {0} too large")
+MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR,    205, 1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}")

Added: freeswitch/trunk/libs/js/src/jsapi.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsapi.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4857 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JavaScript API.
+ */
+#include "jsstddef.h"
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsclist.h"
+#include "jsdhash.h"
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jsarray.h"
+#include "jsatom.h"
+#include "jsbool.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsdate.h"
+#include "jsdtoa.h"
+#include "jsemit.h"
+#include "jsexn.h"
+#include "jsfun.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsmath.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsopcode.h"
+#include "jsparse.h"
+#include "jsregexp.h"
+#include "jsscan.h"
+#include "jsscope.h"
+#include "jsscript.h"
+#include "jsstr.h"
+#include "prmjtime.h"
+
+#if defined(JS_HAS_FILE_OBJECT) && (JS_HAS_FILE_OBJECT - 0) /* OSSP BUGFIX */
+#include "jsfile.h"
+#endif
+
+#if defined(OSSP) && defined(JS_HAS_DSO_OBJECT) && (JS_HAS_DSO_OBJECT - 0)
+#include "jsdso.h"
+#endif
+
+#if JS_HAS_XML_SUPPORT
+#include "jsxml.h"
+#endif
+
+#ifdef HAVE_VA_LIST_AS_ARRAY
+#define JS_ADDRESSOF_VA_LIST(ap) ((va_list *)(ap))
+#else
+#define JS_ADDRESSOF_VA_LIST(ap) (&(ap))
+#endif
+
+#if defined(JS_PARANOID_REQUEST) && defined(JS_THREADSAFE)
+#define CHECK_REQUEST(cx)       JS_ASSERT(cx->requestDepth)
+#else
+#define CHECK_REQUEST(cx)       ((void)0)
+#endif
+
+JS_PUBLIC_API(int64)
+#ifdef OSSP /* CLEANUP */
+JS_Now(void)
+#else
+JS_Now()
+#endif
+{
+    return PRMJ_Now();
+}
+
+JS_PUBLIC_API(jsval)
+JS_GetNaNValue(JSContext *cx)
+{
+    return DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
+}
+
+JS_PUBLIC_API(jsval)
+JS_GetNegativeInfinityValue(JSContext *cx)
+{
+    return DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
+}
+
+JS_PUBLIC_API(jsval)
+JS_GetPositiveInfinityValue(JSContext *cx)
+{
+    return DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
+}
+
+JS_PUBLIC_API(jsval)
+JS_GetEmptyStringValue(JSContext *cx)
+{
+    return STRING_TO_JSVAL(cx->runtime->emptyString);
+}
+
+static JSBool
+TryArgumentFormatter(JSContext *cx, const char **formatp, JSBool fromJS,
+#ifdef OSSP /* BUGFIX */
+                     jsval **vpp, va_list app)
+#else
+                     jsval **vpp, va_list *app)
+#endif
+{
+    const char *format;
+    JSArgumentFormatMap *map;
+
+    format = *formatp;
+    for (map = cx->argumentFormatMap; map; map = map->next) {
+        if (!strncmp(format, map->format, map->length)) {
+            *formatp = format + map->length;
+            return map->formatter(cx, format, fromJS, vpp, app);
+        }
+    }
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_CHAR, format);
+    return JS_FALSE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
+                    ...)
+{
+    va_list ap;
+    JSBool ok;
+
+    va_start(ap, format);
+    ok = JS_ConvertArgumentsVA(cx, argc, argv, format, ap);
+    va_end(ap);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv,
+                      const char *format, va_list ap)
+{
+    jsval *sp;
+    JSBool required;
+    char c;
+    JSFunction *fun;
+    jsdouble d;
+    JSString *str;
+    JSObject *obj;
+
+    CHECK_REQUEST(cx);
+    sp = argv;
+    required = JS_TRUE;
+    while ((c = *format++) != '\0') {
+        if (isspace(c))
+            continue;
+        if (c == '/') {
+            required = JS_FALSE;
+            continue;
+        }
+        if (sp == argv + argc) {
+            if (required) {
+                fun = js_ValueToFunction(cx, &argv[-2], 0);
+                if (fun) {
+                    char numBuf[12];
+                    JS_snprintf(numBuf, sizeof numBuf, "%u", argc);
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                         JSMSG_MORE_ARGS_NEEDED,
+                                         JS_GetFunctionName(fun), numBuf,
+                                         (argc == 1) ? "" : "s");
+                }
+                return JS_FALSE;
+            }
+            break;
+        }
+        switch (c) {
+          case 'b':
+            if (!js_ValueToBoolean(cx, *sp, va_arg(ap, JSBool *)))
+                return JS_FALSE;
+            break;
+          case 'c':
+            if (!js_ValueToUint16(cx, *sp, va_arg(ap, uint16 *)))
+                return JS_FALSE;
+            break;
+          case 'i':
+            if (!js_ValueToECMAInt32(cx, *sp, va_arg(ap, int32 *)))
+                return JS_FALSE;
+            break;
+          case 'u':
+            if (!js_ValueToECMAUint32(cx, *sp, va_arg(ap, uint32 *)))
+                return JS_FALSE;
+            break;
+          case 'j':
+            if (!js_ValueToInt32(cx, *sp, va_arg(ap, int32 *)))
+                return JS_FALSE;
+            break;
+          case 'd':
+            if (!js_ValueToNumber(cx, *sp, va_arg(ap, jsdouble *)))
+                return JS_FALSE;
+            break;
+          case 'I':
+            if (!js_ValueToNumber(cx, *sp, &d))
+                return JS_FALSE;
+            *va_arg(ap, jsdouble *) = js_DoubleToInteger(d);
+            break;
+          case 's':
+          case 'S':
+          case 'W':
+            str = js_ValueToString(cx, *sp);
+            if (!str)
+                return JS_FALSE;
+            *sp = STRING_TO_JSVAL(str);
+            if (c == 's')
+                *va_arg(ap, char **) = JS_GetStringBytes(str);
+            else if (c == 'W')
+                *va_arg(ap, jschar **) = JS_GetStringChars(str);
+            else
+                *va_arg(ap, JSString **) = str;
+            break;
+          case 'o':
+            if (!js_ValueToObject(cx, *sp, &obj))
+                return JS_FALSE;
+            *sp = OBJECT_TO_JSVAL(obj);
+            *va_arg(ap, JSObject **) = obj;
+            break;
+          case 'f':
+            obj = js_ValueToFunctionObject(cx, sp, 0);
+            if (!obj)
+                return JS_FALSE;
+            *va_arg(ap, JSFunction **) = (JSFunction *) JS_GetPrivate(cx, obj);
+            break;
+          case 'v':
+            *va_arg(ap, jsval *) = *sp;
+            break;
+          case '*':
+            break;
+          default:
+            format--;
+            if (!TryArgumentFormatter(cx, &format, JS_TRUE, &sp,
+#ifdef OSSP /* BUGFIX */
+                                      ap)) {
+#else
+                                      JS_ADDRESSOF_VA_LIST(ap))) {
+#endif
+                return JS_FALSE;
+            }
+            /* NB: the formatter already updated sp, so we continue here. */
+            continue;
+        }
+        sp++;
+    }
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(jsval *)
+JS_PushArguments(JSContext *cx, void **markp, const char *format, ...)
+{
+    va_list ap;
+    jsval *argv;
+
+    va_start(ap, format);
+    argv = JS_PushArgumentsVA(cx, markp, format, ap);
+    va_end(ap);
+    return argv;
+}
+
+JS_PUBLIC_API(jsval *)
+JS_PushArgumentsVA(JSContext *cx, void **markp, const char *format, va_list ap)
+{
+    uintN argc;
+    jsval *argv, *sp;
+    char c;
+    const char *cp;
+    JSString *str;
+    JSFunction *fun;
+    JSStackHeader *sh;
+
+    CHECK_REQUEST(cx);
+    *markp = NULL;
+    argc = 0;
+    for (cp = format; (c = *cp) != '\0'; cp++) {
+        /*
+         * Count non-space non-star characters as individual jsval arguments.
+         * This may over-allocate stack, but we'll fix below.
+         */
+        if (isspace(c) || c == '*')
+            continue;
+        argc++;
+    }
+    sp = js_AllocStack(cx, argc, markp);
+    if (!sp)
+        return NULL;
+    argv = sp;
+    while ((c = *format++) != '\0') {
+        if (isspace(c) || c == '*')
+            continue;
+        switch (c) {
+          case 'b':
+            *sp = BOOLEAN_TO_JSVAL((JSBool) va_arg(ap, int));
+            break;
+          case 'c':
+            *sp = INT_TO_JSVAL((uint16) va_arg(ap, unsigned int));
+            break;
+          case 'i':
+          case 'j':
+            if (!js_NewNumberValue(cx, (jsdouble) va_arg(ap, int32), sp))
+                goto bad;
+            break;
+          case 'u':
+            if (!js_NewNumberValue(cx, (jsdouble) va_arg(ap, uint32), sp))
+                goto bad;
+            break;
+          case 'd':
+          case 'I':
+            if (!js_NewDoubleValue(cx, va_arg(ap, jsdouble), sp))
+                goto bad;
+            break;
+          case 's':
+            str = JS_NewStringCopyZ(cx, va_arg(ap, char *));
+            if (!str)
+                goto bad;
+            *sp = STRING_TO_JSVAL(str);
+            break;
+          case 'W':
+            str = JS_NewUCStringCopyZ(cx, va_arg(ap, jschar *));
+            if (!str)
+                goto bad;
+            *sp = STRING_TO_JSVAL(str);
+            break;
+          case 'S':
+            str = va_arg(ap, JSString *);
+            *sp = STRING_TO_JSVAL(str);
+            break;
+          case 'o':
+            *sp = OBJECT_TO_JSVAL(va_arg(ap, JSObject *));
+            break;
+          case 'f':
+            fun = va_arg(ap, JSFunction *);
+            *sp = fun ? OBJECT_TO_JSVAL(fun->object) : JSVAL_NULL;
+            break;
+          case 'v':
+            *sp = va_arg(ap, jsval);
+            break;
+          default:
+            format--;
+            if (!TryArgumentFormatter(cx, &format, JS_FALSE, &sp,
+#ifdef OSSP /* BUGFIX */
+                                      ap)) {
+#else
+                                      JS_ADDRESSOF_VA_LIST(ap))) {
+#endif
+                goto bad;
+            }
+            /* NB: the formatter already updated sp, so we continue here. */
+            continue;
+        }
+        sp++;
+    }
+
+    /*
+     * We may have overallocated stack due to a multi-character format code
+     * handled by a JSArgumentFormatter.  Give back that stack space!
+     */
+    JS_ASSERT(sp <= argv + argc);
+    if (sp < argv + argc) {
+        /* Return slots not pushed to the current stack arena. */
+        cx->stackPool.current->avail = (jsuword)sp;
+
+        /* Reduce the count of slots the GC will scan in this stack segment. */
+        sh = cx->stackHeaders;
+        JS_ASSERT(JS_STACK_SEGMENT(sh) + sh->nslots == argv + argc);
+        sh->nslots -= argc - (sp - argv);
+    }
+    return argv;
+
+bad:
+    js_FreeStack(cx, *markp);
+    return NULL;
+}
+
+JS_PUBLIC_API(void)
+JS_PopArguments(JSContext *cx, void *mark)
+{
+    CHECK_REQUEST(cx);
+    js_FreeStack(cx, mark);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_AddArgumentFormatter(JSContext *cx, const char *format,
+                        JSArgumentFormatter formatter)
+{
+    size_t length;
+    JSArgumentFormatMap **mpp, *map;
+
+    length = strlen(format);
+    mpp = &cx->argumentFormatMap;
+    while ((map = *mpp) != NULL) {
+        /* Insert before any shorter string to match before prefixes. */
+        if (map->length < length)
+            break;
+        if (map->length == length && !strcmp(map->format, format))
+            goto out;
+        mpp = &map->next;
+    }
+    map = (JSArgumentFormatMap *) JS_malloc(cx, sizeof *map);
+    if (!map)
+        return JS_FALSE;
+    map->format = format;
+    map->length = length;
+    map->next = *mpp;
+    *mpp = map;
+out:
+    map->formatter = formatter;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(void)
+JS_RemoveArgumentFormatter(JSContext *cx, const char *format)
+{
+    size_t length;
+    JSArgumentFormatMap **mpp, *map;
+
+    length = strlen(format);
+    mpp = &cx->argumentFormatMap;
+    while ((map = *mpp) != NULL) {
+        if (map->length == length && !strcmp(map->format, format)) {
+            *mpp = map->next;
+            JS_free(cx, map);
+            return;
+        }
+        mpp = &map->next;
+    }
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp)
+{
+    JSBool ok, b;
+    JSObject *obj;
+    JSString *str;
+    jsdouble d, *dp;
+
+    CHECK_REQUEST(cx);
+    switch (type) {
+      case JSTYPE_VOID:
+        *vp = JSVAL_VOID;
+        ok = JS_TRUE;
+        break;
+      case JSTYPE_OBJECT:
+        ok = js_ValueToObject(cx, v, &obj);
+        if (ok)
+            *vp = OBJECT_TO_JSVAL(obj);
+        break;
+      case JSTYPE_FUNCTION:
+        *vp = v;
+        obj = js_ValueToFunctionObject(cx, vp, JSV2F_SEARCH_STACK);
+        ok = (obj != NULL);
+        break;
+      case JSTYPE_STRING:
+        str = js_ValueToString(cx, v);
+        ok = (str != NULL);
+        if (ok)
+            *vp = STRING_TO_JSVAL(str);
+        break;
+      case JSTYPE_NUMBER:
+        ok = js_ValueToNumber(cx, v, &d);
+        if (ok) {
+            dp = js_NewDouble(cx, d, 0);
+            ok = (dp != NULL);
+            if (ok)
+                *vp = DOUBLE_TO_JSVAL(dp);
+        }
+        break;
+      case JSTYPE_BOOLEAN:
+        ok = js_ValueToBoolean(cx, v, &b);
+        if (ok)
+            *vp = BOOLEAN_TO_JSVAL(b);
+        break;
+      default: {
+        char numBuf[12];
+        JS_snprintf(numBuf, sizeof numBuf, "%d", (int)type);
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_TYPE,
+                             numBuf);
+        ok = JS_FALSE;
+        break;
+      }
+    }
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ValueToObject(JSContext *cx, jsval v, JSObject **objp)
+{
+    CHECK_REQUEST(cx);
+    return js_ValueToObject(cx, v, objp);
+}
+
+JS_PUBLIC_API(JSFunction *)
+JS_ValueToFunction(JSContext *cx, jsval v)
+{
+    CHECK_REQUEST(cx);
+    return js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK);
+}
+
+JS_PUBLIC_API(JSFunction *)
+JS_ValueToConstructor(JSContext *cx, jsval v)
+{
+    CHECK_REQUEST(cx);
+    return js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK);
+}
+
+JS_PUBLIC_API(JSString *)
+JS_ValueToString(JSContext *cx, jsval v)
+{
+    CHECK_REQUEST(cx);
+    return js_ValueToString(cx, v);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
+{
+    CHECK_REQUEST(cx);
+    return js_ValueToNumber(cx, v, dp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
+{
+    CHECK_REQUEST(cx);
+    return js_ValueToECMAInt32(cx, v, ip);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip)
+{
+    CHECK_REQUEST(cx);
+    return js_ValueToECMAUint32(cx, v, ip);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
+{
+    CHECK_REQUEST(cx);
+    return js_ValueToInt32(cx, v, ip);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)
+{
+    CHECK_REQUEST(cx);
+    return js_ValueToUint16(cx, v, ip);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp)
+{
+    CHECK_REQUEST(cx);
+    return js_ValueToBoolean(cx, v, bp);
+}
+
+JS_PUBLIC_API(JSType)
+JS_TypeOfValue(JSContext *cx, jsval v)
+{
+    JSType type;
+    JSObject *obj;
+    JSObjectOps *ops;
+    JSClass *clasp;
+
+    CHECK_REQUEST(cx);
+    if (JSVAL_IS_OBJECT(v)) {
+        type = JSTYPE_OBJECT;           /* XXXbe JSTYPE_NULL for JS2 */
+        obj = JSVAL_TO_OBJECT(v);
+        if (obj) {
+            ops = obj->map->ops;
+#if JS_HAS_XML_SUPPORT
+            if (ops == &js_XMLObjectOps.base) {
+                type = JSTYPE_XML;
+            } else
+#endif
+            {
+                /*
+                 * ECMA 262, 11.4.3 says that any native object that implements
+                 * [[Call]] should be of type "function". Note that RegExp and
+                 * Script are both of type "function" for compatibility with
+                 * older SpiderMonkeys.
+                 */
+                clasp = OBJ_GET_CLASS(cx, obj);
+                if ((ops == &js_ObjectOps)
+                    ? (clasp->call
+                       ? (clasp == &js_RegExpClass || clasp == &js_ScriptClass)
+                       : clasp == &js_FunctionClass)
+                    : ops->call != NULL) {
+                    type = JSTYPE_FUNCTION;
+                } else {
+#ifdef NARCISSUS
+                    if (!OBJ_GET_PROPERTY(cx, obj,
+                                          ATOM_TO_JSID(cx->runtime->atomState
+                                                       .callAtom),
+                                          &v)) {
+                        JS_ClearPendingException(cx);
+                    } else if (JSVAL_IS_FUNCTION(cx, v)) {
+                        type = JSTYPE_FUNCTION;
+                    }
+#endif
+                }
+            }
+        }
+    } else if (JSVAL_IS_NUMBER(v)) {
+        type = JSTYPE_NUMBER;
+    } else if (JSVAL_IS_STRING(v)) {
+        type = JSTYPE_STRING;
+    } else if (JSVAL_IS_BOOLEAN(v)) {
+        type = JSTYPE_BOOLEAN;
+    } else {
+        type = JSTYPE_VOID;
+    }
+    return type;
+}
+
+JS_PUBLIC_API(const char *)
+JS_GetTypeName(JSContext *cx, JSType type)
+{
+    if ((uintN)type >= (uintN)JSTYPE_LIMIT)
+        return NULL;
+    return js_type_str[type];
+}
+
+/************************************************************************/
+
+JS_PUBLIC_API(JSRuntime *)
+JS_NewRuntime(uint32 maxbytes)
+{
+    JSRuntime *rt;
+
+#ifdef DEBUG
+    JS_BEGIN_MACRO
+    /*
+     * This code asserts that the numbers associated with the error names in
+     * jsmsg.def are monotonically increasing.  It uses values for the error
+     * names enumerated in jscntxt.c.  It's not a compiletime check, but it's
+     * better than nothing.
+     */
+    int errorNumber = 0;
+#define MSG_DEF(name, number, count, exception, format) \
+    JS_ASSERT(name == errorNumber++);
+#include "js.msg"
+#undef MSG_DEF
+    JS_END_MACRO;
+#endif /* DEBUG */
+
+    if (!js_InitStringGlobals())
+        return NULL;
+    rt = (JSRuntime *) malloc(sizeof(JSRuntime));
+    if (!rt)
+        return NULL;
+
+    /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
+    memset(rt, 0, sizeof(JSRuntime));
+    JS_INIT_CLIST(&rt->contextList);
+    JS_INIT_CLIST(&rt->trapList);
+    JS_INIT_CLIST(&rt->watchPointList);
+
+    if (!js_InitGC(rt, maxbytes))
+        goto bad;
+#ifdef JS_THREADSAFE
+    rt->gcLock = JS_NEW_LOCK();
+    if (!rt->gcLock)
+        goto bad;
+    rt->gcDone = JS_NEW_CONDVAR(rt->gcLock);
+    if (!rt->gcDone)
+        goto bad;
+    rt->requestDone = JS_NEW_CONDVAR(rt->gcLock);
+    if (!rt->requestDone)
+        goto bad;
+    /* this is asymmetric with JS_ShutDown: */
+    if (!js_SetupLocks(8, 16))
+        goto bad;
+    rt->rtLock = JS_NEW_LOCK();
+    if (!rt->rtLock)
+        goto bad;
+    rt->stateChange = JS_NEW_CONDVAR(rt->gcLock);
+    if (!rt->stateChange)
+        goto bad;
+    rt->setSlotLock = JS_NEW_LOCK();
+    if (!rt->setSlotLock)
+        goto bad;
+    rt->setSlotDone = JS_NEW_CONDVAR(rt->setSlotLock);
+    if (!rt->setSlotDone)
+        goto bad;
+    rt->scopeSharingDone = JS_NEW_CONDVAR(rt->gcLock);
+    if (!rt->scopeSharingDone)
+        goto bad;
+    rt->scopeSharingTodo = NO_SCOPE_SHARING_TODO;
+#endif
+    rt->propertyCache.empty = JS_TRUE;
+    if (!js_InitPropertyTree(rt))
+        goto bad;
+    return rt;
+
+bad:
+    JS_DestroyRuntime(rt);
+    return NULL;
+}
+
+JS_PUBLIC_API(void)
+JS_DestroyRuntime(JSRuntime *rt)
+{
+#ifdef DEBUG
+    /* Don't hurt everyone in leaky ol' Mozilla with a fatal JS_ASSERT! */
+    if (!JS_CLIST_IS_EMPTY(&rt->contextList)) {
+        JSContext *cx, *iter = NULL;
+        uintN cxcount = 0;
+        while ((cx = js_ContextIterator(rt, JS_TRUE, &iter)) != NULL)
+            cxcount++;
+        fprintf(stderr,
+"JS API usage error: %u contexts left in runtime upon JS_DestroyRuntime.\n",
+                cxcount);
+    }
+#endif
+
+    js_FreeRuntimeScriptState(rt);
+    js_FinishAtomState(&rt->atomState);
+    js_FinishGC(rt);
+#ifdef JS_THREADSAFE
+    if (rt->gcLock)
+        JS_DESTROY_LOCK(rt->gcLock);
+    if (rt->gcDone)
+        JS_DESTROY_CONDVAR(rt->gcDone);
+    if (rt->requestDone)
+        JS_DESTROY_CONDVAR(rt->requestDone);
+    if (rt->rtLock)
+        JS_DESTROY_LOCK(rt->rtLock);
+    if (rt->stateChange)
+        JS_DESTROY_CONDVAR(rt->stateChange);
+    if (rt->setSlotLock)
+        JS_DESTROY_LOCK(rt->setSlotLock);
+    if (rt->setSlotDone)
+        JS_DESTROY_CONDVAR(rt->setSlotDone);
+    if (rt->scopeSharingDone)
+        JS_DESTROY_CONDVAR(rt->scopeSharingDone);
+#endif
+    js_FinishPropertyTree(rt);
+    free(rt);
+}
+
+JS_PUBLIC_API(void)
+JS_ShutDown(void)
+{
+    JS_ArenaShutDown();
+    js_FinishDtoa();
+    js_FreeStringGlobals();
+#ifdef JS_THREADSAFE
+    js_CleanupLocks();
+#endif
+}
+
+JS_PUBLIC_API(void *)
+JS_GetRuntimePrivate(JSRuntime *rt)
+{
+    return rt->data;
+}
+
+JS_PUBLIC_API(void)
+JS_SetRuntimePrivate(JSRuntime *rt, void *data)
+{
+    rt->data = data;
+}
+
+#ifdef JS_THREADSAFE
+
+JS_PUBLIC_API(void)
+JS_BeginRequest(JSContext *cx)
+{
+    JSRuntime *rt;
+
+    JS_ASSERT(cx->thread);
+    if (!cx->requestDepth) {
+        /* Wait until the GC is finished. */
+        rt = cx->runtime;
+        JS_LOCK_GC(rt);
+
+        /* NB: we use cx->thread here, not js_CurrentThreadId(). */
+        if (rt->gcThread != cx->thread) {
+            while (rt->gcLevel > 0)
+                JS_AWAIT_GC_DONE(rt);
+        }
+
+        /* Indicate that a request is running. */
+        rt->requestCount++;
+        cx->requestDepth = 1;
+        JS_UNLOCK_GC(rt);
+        return;
+    }
+    cx->requestDepth++;
+}
+
+JS_PUBLIC_API(void)
+JS_EndRequest(JSContext *cx)
+{
+    JSRuntime *rt;
+    JSScope *scope, **todop;
+    uintN nshares;
+
+    CHECK_REQUEST(cx);
+    JS_ASSERT(cx->requestDepth > 0);
+    if (cx->requestDepth == 1) {
+        /* Lock before clearing to interlock with ClaimScope, in jslock.c. */
+        rt = cx->runtime;
+        JS_LOCK_GC(rt);
+        cx->requestDepth = 0;
+
+        /* See whether cx has any single-threaded scopes to start sharing. */
+        todop = &rt->scopeSharingTodo;
+        nshares = 0;
+        while ((scope = *todop) != NO_SCOPE_SHARING_TODO) {
+            if (scope->ownercx != cx) {
+                todop = &scope->u.link;
+                continue;
+            }
+            *todop = scope->u.link;
+            scope->u.link = NULL;       /* null u.link for sanity ASAP */
+
+            /*
+             * If js_DropObjectMap returns null, we held the last ref to scope.
+             * The waiting thread(s) must have been killed, after which the GC
+             * collected the object that held this scope.  Unlikely, because it
+             * requires that the GC ran (e.g., from a branch callback) during
+             * this request, but possible.
+             */
+            if (js_DropObjectMap(cx, &scope->map, NULL)) {
+                js_InitLock(&scope->lock);
+                scope->u.count = 0;                 /* NULL may not pun as 0 */
+                js_FinishSharingScope(rt, scope);   /* set ownercx = NULL */
+                nshares++;
+            }
+        }
+        if (nshares)
+            JS_NOTIFY_ALL_CONDVAR(rt->scopeSharingDone);
+
+        /* Give the GC a chance to run if this was the last request running. */
+        JS_ASSERT(rt->requestCount > 0);
+        rt->requestCount--;
+        if (rt->requestCount == 0)
+            JS_NOTIFY_REQUEST_DONE(rt);
+
+        JS_UNLOCK_GC(rt);
+        return;
+    }
+
+    cx->requestDepth--;
+}
+
+/* Yield to pending GC operations, regardless of request depth */
+JS_PUBLIC_API(void)
+JS_YieldRequest(JSContext *cx)
+{
+    JSRuntime *rt;
+
+    JS_ASSERT(cx->thread);
+    CHECK_REQUEST(cx);
+
+    rt = cx->runtime;
+    JS_LOCK_GC(rt);
+    JS_ASSERT(rt->requestCount > 0);
+    rt->requestCount--;
+    if (rt->requestCount == 0)
+        JS_NOTIFY_REQUEST_DONE(rt);
+    JS_UNLOCK_GC(rt);
+    /* XXXbe give the GC or another request calling it a chance to run here?
+             Assumes FIFO scheduling */
+    JS_LOCK_GC(rt);
+    if (rt->gcThread != cx->thread) {
+        while (rt->gcLevel > 0)
+            JS_AWAIT_GC_DONE(rt);
+    }
+    rt->requestCount++;
+    JS_UNLOCK_GC(rt);
+}
+
+JS_PUBLIC_API(jsrefcount)
+JS_SuspendRequest(JSContext *cx)
+{
+    jsrefcount saveDepth = cx->requestDepth;
+
+    while (cx->requestDepth)
+        JS_EndRequest(cx);
+    return saveDepth;
+}
+
+JS_PUBLIC_API(void)
+JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth)
+{
+    JS_ASSERT(!cx->requestDepth);
+    while (--saveDepth >= 0)
+        JS_BeginRequest(cx);
+}
+
+#endif /* JS_THREADSAFE */
+
+JS_PUBLIC_API(void)
+JS_Lock(JSRuntime *rt)
+{
+    JS_LOCK_RUNTIME(rt);
+}
+
+JS_PUBLIC_API(void)
+JS_Unlock(JSRuntime *rt)
+{
+    JS_UNLOCK_RUNTIME(rt);
+}
+
+JS_PUBLIC_API(JSContext *)
+JS_NewContext(JSRuntime *rt, size_t stackChunkSize)
+{
+    return js_NewContext(rt, stackChunkSize);
+}
+
+JS_PUBLIC_API(void)
+JS_DestroyContext(JSContext *cx)
+{
+    js_DestroyContext(cx, JS_FORCE_GC);
+}
+
+JS_PUBLIC_API(void)
+JS_DestroyContextNoGC(JSContext *cx)
+{
+    js_DestroyContext(cx, JS_NO_GC);
+}
+
+JS_PUBLIC_API(void)
+JS_DestroyContextMaybeGC(JSContext *cx)
+{
+    js_DestroyContext(cx, JS_MAYBE_GC);
+}
+
+JS_PUBLIC_API(void *)
+JS_GetContextPrivate(JSContext *cx)
+{
+    return cx->data;
+}
+
+JS_PUBLIC_API(void)
+JS_SetContextPrivate(JSContext *cx, void *data)
+{
+    cx->data = data;
+}
+
+JS_PUBLIC_API(JSRuntime *)
+JS_GetRuntime(JSContext *cx)
+{
+    return cx->runtime;
+}
+
+JS_PUBLIC_API(JSContext *)
+JS_ContextIterator(JSRuntime *rt, JSContext **iterp)
+{
+    return js_ContextIterator(rt, JS_TRUE, iterp);
+}
+
+JS_PUBLIC_API(JSVersion)
+JS_GetVersion(JSContext *cx)
+{
+    return cx->version & JSVERSION_MASK;
+}
+
+JS_PUBLIC_API(JSVersion)
+JS_SetVersion(JSContext *cx, JSVersion version)
+{
+    JSVersion oldVersion;
+
+    JS_ASSERT(version != JSVERSION_UNKNOWN);
+    JS_ASSERT((version & ~JSVERSION_MASK) == 0);
+
+    oldVersion = cx->version & JSVERSION_MASK;
+    if (version == oldVersion)
+        return oldVersion;
+
+    cx->version = (cx->version & ~JSVERSION_MASK) | version;
+    js_OnVersionChange(cx);
+    return oldVersion;
+}
+
+static struct v2smap {
+    JSVersion   version;
+    const char  *string;
+} v2smap[] = {
+    {JSVERSION_1_0,     "1.0"},
+    {JSVERSION_1_1,     "1.1"},
+    {JSVERSION_1_2,     "1.2"},
+    {JSVERSION_1_3,     "1.3"},
+    {JSVERSION_1_4,     "1.4"},
+    {JSVERSION_ECMA_3,  "ECMAv3"},
+    {JSVERSION_1_5,     "1.5"},
+    {JSVERSION_1_6,     "1.6"},
+    {JSVERSION_DEFAULT, js_default_str},
+    {JSVERSION_UNKNOWN, NULL},          /* must be last, NULL is sentinel */
+};
+
+JS_PUBLIC_API(const char *)
+JS_VersionToString(JSVersion version)
+{
+    int i;
+
+    for (i = 0; v2smap[i].string; i++)
+        if (v2smap[i].version == version)
+            return v2smap[i].string;
+    return "unknown";
+}
+
+JS_PUBLIC_API(JSVersion)
+JS_StringToVersion(const char *string)
+{
+    int i;
+
+    for (i = 0; v2smap[i].string; i++)
+        if (strcmp(v2smap[i].string, string) == 0)
+            return v2smap[i].version;
+    return JSVERSION_UNKNOWN;
+}
+
+JS_PUBLIC_API(uint32)
+JS_GetOptions(JSContext *cx)
+{
+    return cx->options;
+}
+
+#define SYNC_OPTIONS_TO_VERSION(cx)                                           \
+    JS_BEGIN_MACRO                                                            \
+        if ((cx)->options & JSOPTION_XML)                                     \
+            (cx)->version |= JSVERSION_HAS_XML;                               \
+        else                                                                  \
+            (cx)->version &= ~JSVERSION_HAS_XML;                              \
+    JS_END_MACRO
+
+JS_PUBLIC_API(uint32)
+JS_SetOptions(JSContext *cx, uint32 options)
+{
+    uint32 oldopts = cx->options;
+    cx->options = options;
+    SYNC_OPTIONS_TO_VERSION(cx);
+    return oldopts;
+}
+
+JS_PUBLIC_API(uint32)
+JS_ToggleOptions(JSContext *cx, uint32 options)
+{
+    uint32 oldopts = cx->options;
+    cx->options ^= options;
+    SYNC_OPTIONS_TO_VERSION(cx);
+    return oldopts;
+}
+
+JS_PUBLIC_API(const char *)
+JS_GetImplementationVersion(void)
+{
+#ifdef OSSP
+    return "JavaScript-C 1.6 pre-release 1 2006-04-04 (OSSP js 1.6.20060820)";
+#else
+    return "JavaScript-C 1.6 pre-release 1 2006-04-04";
+#endif
+}
+
+
+JS_PUBLIC_API(JSObject *)
+JS_GetGlobalObject(JSContext *cx)
+{
+    return cx->globalObject;
+}
+
+JS_PUBLIC_API(void)
+JS_SetGlobalObject(JSContext *cx, JSObject *obj)
+{
+    cx->globalObject = obj;
+#if JS_HAS_XML_SUPPORT
+    cx->xmlSettingFlags = 0;
+#endif
+}
+
+static JSObject *
+InitFunctionAndObjectClasses(JSContext *cx, JSObject *obj)
+{
+    JSDHashTable *table;
+    JSBool resolving;
+    JSRuntime *rt;
+    JSResolvingKey key;
+    JSResolvingEntry *entry;
+    JSObject *fun_proto, *obj_proto;
+
+    /* If cx has no global object, use obj so prototypes can be found. */
+    if (!cx->globalObject)
+        JS_SetGlobalObject(cx, obj);
+
+    /* Record Function and Object in cx->resolvingTable, if we are resolving. */
+    table = cx->resolvingTable;
+    resolving = (table && table->entryCount);
+    if (resolving) {
+        rt = cx->runtime;
+        key.obj = obj;
+        key.id = ATOM_TO_JSID(rt->atomState.FunctionAtom);
+        entry = (JSResolvingEntry *)
+                JS_DHashTableOperate(table, &key, JS_DHASH_ADD);
+        if (entry && entry->key.obj && (entry->flags & JSRESFLAG_LOOKUP)) {
+            /* Already resolving Function, record Object too. */
+            JS_ASSERT(entry->key.obj == obj);
+            key.id = ATOM_TO_JSID(rt->atomState.ObjectAtom);
+            entry = (JSResolvingEntry *)
+                    JS_DHashTableOperate(table, &key, JS_DHASH_ADD);
+        }
+        if (!entry) {
+            JS_ReportOutOfMemory(cx);
+            return NULL;
+        }
+        JS_ASSERT(!entry->key.obj && entry->flags == 0);
+        entry->key = key;
+        entry->flags = JSRESFLAG_LOOKUP;
+    }
+
+    /* Initialize the function class first so constructors can be made. */
+    fun_proto = js_InitFunctionClass(cx, obj);
+    if (!fun_proto)
+        goto out;
+
+    /* Initialize the object class next so Object.prototype works. */
+    obj_proto = js_InitObjectClass(cx, obj);
+    if (!obj_proto) {
+        fun_proto = NULL;
+        goto out;
+    }
+
+    /* Function.prototype and the global object delegate to Object.prototype. */
+    OBJ_SET_PROTO(cx, fun_proto, obj_proto);
+    if (!OBJ_GET_PROTO(cx, obj))
+        OBJ_SET_PROTO(cx, obj, obj_proto);
+
+out:
+    /* If resolving, remove the other entry (Object or Function) from table. */
+    if (resolving)
+        JS_DHashTableOperate(table, &key, JS_DHASH_REMOVE);
+    return fun_proto;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_InitStandardClasses(JSContext *cx, JSObject *obj)
+{
+    CHECK_REQUEST(cx);
+
+#if JS_HAS_UNDEFINED
+{
+    /* Define a top-level property 'undefined' with the undefined value. */
+    JSAtom *atom = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
+    if (!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), JSVAL_VOID,
+                             NULL, NULL, JSPROP_PERMANENT, NULL)) {
+        return JS_FALSE;
+    }
+}
+#endif
+
+    /* Function and Object require cooperative bootstrapping magic. */
+    if (!InitFunctionAndObjectClasses(cx, obj))
+        return JS_FALSE;
+
+    /* Initialize the rest of the standard objects and functions. */
+    return js_InitArrayClass(cx, obj) &&
+           js_InitBooleanClass(cx, obj) &&
+           js_InitMathClass(cx, obj) &&
+           js_InitNumberClass(cx, obj) &&
+           js_InitStringClass(cx, obj) &&
+#if JS_HAS_CALL_OBJECT
+           js_InitCallClass(cx, obj) &&
+#endif
+#if JS_HAS_REGEXPS
+           js_InitRegExpClass(cx, obj) &&
+#endif
+#if JS_HAS_SCRIPT_OBJECT
+           js_InitScriptClass(cx, obj) &&
+#endif
+#if JS_HAS_ERROR_EXCEPTIONS
+           js_InitExceptionClasses(cx, obj) &&
+#endif
+#if JS_HAS_XML_SUPPORT
+           js_InitXMLClasses(cx, obj) &&
+#endif
+#ifndef OSSP
+#if defined(JS_HAS_FILE_OBJECT) && (JS_HAS_FILE_OBJECT - 0) /* OSSP BUGFIX */
+           js_InitFileClass(cx, obj) &&
+#endif
+#if defined(JS_HAS_DSO_OBJECT) && (JS_HAS_DSO_OBJECT - 0)
+           js_InitDSOClass(cx, obj) &&
+#endif
+#endif
+           js_InitDateClass(cx, obj);
+}
+
+#define ATOM_OFFSET(name)       offsetof(JSAtomState, name##Atom)
+#define OFFSET_TO_ATOM(rt,off)  (*(JSAtom **)((char*)&(rt)->atomState + (off)))
+
+/*
+ * Table of class initializers and their atom offsets in rt->atomState.
+ * If you add a "standard" class, remember to update this table.
+ */
+static struct {
+    JSObjectOp  init;
+    size_t      atomOffset;
+} standard_class_atoms[] = {
+    {InitFunctionAndObjectClasses,  ATOM_OFFSET(Function)},
+    {InitFunctionAndObjectClasses,  ATOM_OFFSET(Object)},
+    {js_InitArrayClass,             ATOM_OFFSET(Array)},
+    {js_InitBooleanClass,           ATOM_OFFSET(Boolean)},
+    {js_InitDateClass,              ATOM_OFFSET(Date)},
+    {js_InitMathClass,              ATOM_OFFSET(Math)},
+    {js_InitNumberClass,            ATOM_OFFSET(Number)},
+    {js_InitStringClass,            ATOM_OFFSET(String)},
+#if JS_HAS_CALL_OBJECT
+    {js_InitCallClass,              ATOM_OFFSET(Call)},
+#endif
+#if JS_HAS_ERROR_EXCEPTIONS
+    {js_InitExceptionClasses,       ATOM_OFFSET(Error)},
+#endif
+#if JS_HAS_REGEXPS
+    {js_InitRegExpClass,            ATOM_OFFSET(RegExp)},
+#endif
+#if JS_HAS_SCRIPT_OBJECT
+    {js_InitScriptClass,            ATOM_OFFSET(Script)},
+#endif
+#if JS_HAS_XML_SUPPORT
+    {js_InitXMLClass,               ATOM_OFFSET(XML)},
+    {js_InitNamespaceClass,         ATOM_OFFSET(Namespace)},
+    {js_InitQNameClass,             ATOM_OFFSET(QName)},
+#endif
+#if defined(JS_HAS_FILE_OBJECT) && (JS_HAS_FILE_OBJECT - 0) /* OSSP BUGFIX */
+    {js_InitFileClass,              ATOM_OFFSET(File)},
+#endif
+#if defined(JS_HAS_DSO_OBJECT) && (JS_HAS_DSO_OBJECT - 0)
+    {js_InitDSOClass,               ATOM_OFFSET(DSO)},
+#endif
+    {NULL,                          0}
+};
+
+/*
+ * Table of top-level function and constant names and their init functions.
+ * If you add a "standard" global function or property, remember to update
+ * this table.
+ */
+typedef struct JSStdName {
+    JSObjectOp  init;
+    size_t      atomOffset;     /* offset of atom pointer in JSAtomState */
+    const char  *name;          /* null if atom is pre-pinned, else name */
+} JSStdName;
+
+static JSAtom *
+StdNameToAtom(JSContext *cx, JSStdName *stdn)
+{
+    size_t offset;
+    JSAtom *atom;
+    const char *name;
+
+    offset = stdn->atomOffset;
+    atom = OFFSET_TO_ATOM(cx->runtime, offset);
+    if (!atom) {
+        name = stdn->name;
+        if (name) {
+            atom = js_Atomize(cx, name, strlen(name), ATOM_PINNED);
+            OFFSET_TO_ATOM(cx->runtime, offset) = atom;
+        }
+    }
+    return atom;
+}
+
+#define EAGERLY_PINNED_ATOM(name)   ATOM_OFFSET(name), NULL
+#define LAZILY_PINNED_ATOM(name)    ATOM_OFFSET(lazy.name), js_##name##_str
+
+static JSStdName standard_class_names[] = {
+    /* ECMA requires that eval be a direct property of the global object. */
+    {js_InitObjectClass,        EAGERLY_PINNED_ATOM(eval)},
+
+    /* Global properties and functions defined by the Number class. */
+    {js_InitNumberClass,        LAZILY_PINNED_ATOM(NaN)},
+    {js_InitNumberClass,        LAZILY_PINNED_ATOM(Infinity)},
+    {js_InitNumberClass,        LAZILY_PINNED_ATOM(isNaN)},
+    {js_InitNumberClass,        LAZILY_PINNED_ATOM(isFinite)},
+    {js_InitNumberClass,        LAZILY_PINNED_ATOM(parseFloat)},
+    {js_InitNumberClass,        LAZILY_PINNED_ATOM(parseInt)},
+
+    /* String global functions. */
+    {js_InitStringClass,        LAZILY_PINNED_ATOM(escape)},
+    {js_InitStringClass,        LAZILY_PINNED_ATOM(unescape)},
+    {js_InitStringClass,        LAZILY_PINNED_ATOM(decodeURI)},
+    {js_InitStringClass,        LAZILY_PINNED_ATOM(encodeURI)},
+    {js_InitStringClass,        LAZILY_PINNED_ATOM(decodeURIComponent)},
+    {js_InitStringClass,        LAZILY_PINNED_ATOM(encodeURIComponent)},
+#if JS_HAS_UNEVAL
+    {js_InitStringClass,        LAZILY_PINNED_ATOM(uneval)},
+#endif
+
+    /* Exception constructors. */
+#if JS_HAS_ERROR_EXCEPTIONS
+    {js_InitExceptionClasses,   EAGERLY_PINNED_ATOM(Error)},
+    {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(InternalError)},
+    {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(EvalError)},
+    {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(RangeError)},
+    {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(ReferenceError)},
+    {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(SyntaxError)},
+    {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(TypeError)},
+    {js_InitExceptionClasses,   LAZILY_PINNED_ATOM(URIError)},
+#endif
+
+#if JS_HAS_XML_SUPPORT
+    {js_InitAnyNameClass,       LAZILY_PINNED_ATOM(AnyName)},
+    {js_InitAttributeNameClass, LAZILY_PINNED_ATOM(AttributeName)},
+    {js_InitXMLClass,           LAZILY_PINNED_ATOM(XMLList)},
+    {js_InitXMLClass,           LAZILY_PINNED_ATOM(isXMLName)},
+#endif
+
+    {NULL,                      0, NULL}
+};
+
+static JSStdName object_prototype_names[] = {
+    /* Object.prototype properties (global delegates to Object.prototype). */
+    {js_InitObjectClass,        EAGERLY_PINNED_ATOM(proto)},
+    {js_InitObjectClass,        EAGERLY_PINNED_ATOM(parent)},
+    {js_InitObjectClass,        EAGERLY_PINNED_ATOM(count)},
+#if JS_HAS_TOSOURCE
+    {js_InitObjectClass,        EAGERLY_PINNED_ATOM(toSource)},
+#endif
+    {js_InitObjectClass,        EAGERLY_PINNED_ATOM(toString)},
+    {js_InitObjectClass,        EAGERLY_PINNED_ATOM(toLocaleString)},
+    {js_InitObjectClass,        EAGERLY_PINNED_ATOM(valueOf)},
+#if JS_HAS_OBJ_WATCHPOINT
+    {js_InitObjectClass,        LAZILY_PINNED_ATOM(watch)},
+    {js_InitObjectClass,        LAZILY_PINNED_ATOM(unwatch)},
+#endif
+#if JS_HAS_NEW_OBJ_METHODS
+    {js_InitObjectClass,        LAZILY_PINNED_ATOM(hasOwnProperty)},
+    {js_InitObjectClass,        LAZILY_PINNED_ATOM(isPrototypeOf)},
+    {js_InitObjectClass,        LAZILY_PINNED_ATOM(propertyIsEnumerable)},
+#endif
+#if JS_HAS_GETTER_SETTER
+    {js_InitObjectClass,        LAZILY_PINNED_ATOM(defineGetter)},
+    {js_InitObjectClass,        LAZILY_PINNED_ATOM(defineSetter)},
+    {js_InitObjectClass,        LAZILY_PINNED_ATOM(lookupGetter)},
+    {js_InitObjectClass,        LAZILY_PINNED_ATOM(lookupSetter)},
+#endif
+
+    {NULL,                      0, NULL}
+};
+
+#undef EAGERLY_PINNED_ATOM
+#undef LAZILY_PINNED_ATOM
+
+JS_PUBLIC_API(JSBool)
+JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id,
+                        JSBool *resolved)
+{
+    JSString *idstr;
+    JSRuntime *rt;
+    JSAtom *atom;
+    JSObjectOp init;
+    uintN i;
+
+    CHECK_REQUEST(cx);
+    *resolved = JS_FALSE;
+
+    if (!JSVAL_IS_STRING(id))
+        return JS_TRUE;
+    idstr = JSVAL_TO_STRING(id);
+    rt = cx->runtime;
+
+#if JS_HAS_UNDEFINED
+    /* Check whether we're resolving 'undefined', and define it if so. */
+    atom = rt->atomState.typeAtoms[JSTYPE_VOID];
+    if (idstr == ATOM_TO_STRING(atom)) {
+        *resolved = JS_TRUE;
+        return OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), JSVAL_VOID,
+                                   NULL, NULL, JSPROP_PERMANENT, NULL);
+    }
+#endif
+
+    /* Try for class constructors/prototypes named by well-known atoms. */
+    init = NULL;
+    for (i = 0; standard_class_atoms[i].init; i++) {
+        atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset);
+        if (idstr == ATOM_TO_STRING(atom)) {
+            init = standard_class_atoms[i].init;
+            break;
+        }
+    }
+
+    if (!init) {
+        /* Try less frequently used top-level functions and constants. */
+        for (i = 0; standard_class_names[i].init; i++) {
+            atom = StdNameToAtom(cx, &standard_class_names[i]);
+            if (!atom)
+                return JS_FALSE;
+            if (idstr == ATOM_TO_STRING(atom)) {
+                init = standard_class_names[i].init;
+                break;
+            }
+        }
+
+        if (!init && !OBJ_GET_PROTO(cx, obj)) {
+            /*
+             * Try even less frequently used names delegated from the global
+             * object to Object.prototype, but only if the Object class hasn't
+             * yet been initialized.
+             */
+            for (i = 0; object_prototype_names[i].init; i++) {
+                atom = StdNameToAtom(cx, &object_prototype_names[i]);
+                if (!atom)
+                    return JS_FALSE;
+                if (idstr == ATOM_TO_STRING(atom)) {
+                    init = standard_class_names[i].init;
+                    break;
+                }
+            }
+        }
+    }
+
+    if (init) {
+        if (!init(cx, obj))
+            return JS_FALSE;
+        *resolved = JS_TRUE;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+AlreadyHasOwnProperty(JSObject *obj, JSAtom *atom)
+{
+    JS_ASSERT(OBJ_IS_NATIVE(obj));
+    return SCOPE_GET_PROPERTY(OBJ_SCOPE(obj), ATOM_TO_JSID(atom)) != NULL;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj)
+{
+    JSRuntime *rt;
+    JSAtom *atom;
+    uintN i;
+
+    CHECK_REQUEST(cx);
+    rt = cx->runtime;
+
+#if JS_HAS_UNDEFINED
+    /* Check whether we need to bind 'undefined' and define it if so. */
+    atom = rt->atomState.typeAtoms[JSTYPE_VOID];
+    if (!AlreadyHasOwnProperty(obj, atom) &&
+        !OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), JSVAL_VOID,
+                             NULL, NULL, JSPROP_PERMANENT, NULL)) {
+        return JS_FALSE;
+    }
+#endif
+
+    /* Initialize any classes that have not been resolved yet. */
+    for (i = 0; standard_class_atoms[i].init; i++) {
+        atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset);
+        if (!AlreadyHasOwnProperty(obj, atom) &&
+            !standard_class_atoms[i].init(cx, obj)) {
+            return JS_FALSE;
+        }
+    }
+
+    return JS_TRUE;
+}
+
+static JSIdArray *
+AddAtomToArray(JSContext *cx, JSAtom *atom, JSIdArray *ida, jsint *ip)
+{
+    jsint i, length;
+
+    i = *ip;
+    length = ida->length;
+    if (i >= length) {
+        ida = js_SetIdArrayLength(cx, ida, JS_MAX(length * 2, 8));
+        if (!ida)
+            return NULL;
+        JS_ASSERT(i < ida->length);
+    }
+    ida->vector[i] = ATOM_TO_JSID(atom);
+    *ip = i + 1;
+    return ida;
+}
+
+static JSIdArray *
+EnumerateIfResolved(JSContext *cx, JSObject *obj, JSAtom *atom, JSIdArray *ida,
+                    jsint *ip, JSBool *foundp)
+{
+    *foundp = AlreadyHasOwnProperty(obj, atom);
+    if (*foundp)
+        ida = AddAtomToArray(cx, atom, ida, ip);
+    return ida;
+}
+
+JS_PUBLIC_API(JSIdArray *)
+JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj,
+                                    JSIdArray *ida)
+{
+    JSRuntime *rt;
+    jsint i, j, k;
+    JSAtom *atom;
+    JSBool found;
+    JSObjectOp init;
+
+    CHECK_REQUEST(cx);
+    rt = cx->runtime;
+    if (ida) {
+        i = ida->length;
+    } else {
+        ida = js_NewIdArray(cx, 8);
+        if (!ida)
+            return NULL;
+        i = 0;
+    }
+
+#if JS_HAS_UNDEFINED
+    /* Check whether 'undefined' has been resolved and enumerate it if so. */
+    atom = rt->atomState.typeAtoms[JSTYPE_VOID];
+    ida = EnumerateIfResolved(cx, obj, atom, ida, &i, &found);
+    if (!ida)
+        return NULL;
+#endif
+
+    /* Enumerate only classes that *have* been resolved. */
+    for (j = 0; standard_class_atoms[j].init; j++) {
+        atom = OFFSET_TO_ATOM(rt, standard_class_atoms[j].atomOffset);
+        ida = EnumerateIfResolved(cx, obj, atom, ida, &i, &found);
+        if (!ida)
+            return NULL;
+
+        if (found) {
+            init = standard_class_atoms[j].init;
+
+            for (k = 0; standard_class_names[k].init; k++) {
+                if (standard_class_names[k].init == init) {
+                    atom = StdNameToAtom(cx, &standard_class_names[k]);
+                    ida = AddAtomToArray(cx, atom, ida, &i);
+                    if (!ida)
+                        return NULL;
+                }
+            }
+
+            if (init == js_InitObjectClass) {
+                for (k = 0; object_prototype_names[k].init; k++) {
+                    atom = StdNameToAtom(cx, &object_prototype_names[k]);
+                    ida = AddAtomToArray(cx, atom, ida, &i);
+                    if (!ida)
+                        return NULL;
+                }
+            }
+        }
+    }
+
+    /* Trim to exact length via js_SetIdArrayLength. */
+    return js_SetIdArrayLength(cx, ida, i);
+}
+
+#undef ATOM_OFFSET
+#undef OFFSET_TO_ATOM
+
+JS_PUBLIC_API(JSObject *)
+JS_GetScopeChain(JSContext *cx)
+{
+    return cx->fp ? cx->fp->scopeChain : NULL;
+}
+
+JS_PUBLIC_API(void *)
+JS_malloc(JSContext *cx, size_t nbytes)
+{
+    void *p;
+
+    JS_ASSERT(nbytes != 0);
+    if (nbytes == 0)
+        nbytes = 1;
+    cx->runtime->gcMallocBytes += nbytes;
+    p = malloc(nbytes);
+    if (!p)
+        JS_ReportOutOfMemory(cx);
+    return p;
+}
+
+JS_PUBLIC_API(void *)
+JS_realloc(JSContext *cx, void *p, size_t nbytes)
+{
+    p = realloc(p, nbytes);
+    if (!p)
+        JS_ReportOutOfMemory(cx);
+    return p;
+}
+
+JS_PUBLIC_API(void)
+JS_free(JSContext *cx, void *p)
+{
+    if (p)
+        free(p);
+}
+
+JS_PUBLIC_API(char *)
+JS_strdup(JSContext *cx, const char *s)
+{
+    size_t n;
+    void *p;
+
+    n = strlen(s) + 1;
+    p = JS_malloc(cx, n);
+    if (!p)
+        return NULL;
+    return (char *)memcpy(p, s, n);
+}
+
+JS_PUBLIC_API(jsdouble *)
+JS_NewDouble(JSContext *cx, jsdouble d)
+{
+    CHECK_REQUEST(cx);
+    return js_NewDouble(cx, d, 0);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval)
+{
+    CHECK_REQUEST(cx);
+    return js_NewDoubleValue(cx, d, rval);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval)
+{
+    CHECK_REQUEST(cx);
+    return js_NewNumberValue(cx, d, rval);
+}
+
+#undef JS_AddRoot
+JS_PUBLIC_API(JSBool)
+JS_AddRoot(JSContext *cx, void *rp)
+{
+    CHECK_REQUEST(cx);
+    return js_AddRoot(cx, rp, NULL);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_AddNamedRootRT(JSRuntime *rt, void *rp, const char *name)
+{
+    return js_AddRootRT(rt, rp, name);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_RemoveRoot(JSContext *cx, void *rp)
+{
+    CHECK_REQUEST(cx);
+    return js_RemoveRoot(cx->runtime, rp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_RemoveRootRT(JSRuntime *rt, void *rp)
+{
+    return js_RemoveRoot(rt, rp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_AddNamedRoot(JSContext *cx, void *rp, const char *name)
+{
+    CHECK_REQUEST(cx);
+    return js_AddRoot(cx, rp, name);
+}
+
+JS_PUBLIC_API(void)
+JS_ClearNewbornRoots(JSContext *cx)
+{
+    uintN i;
+
+    for (i = 0; i < GCX_NTYPES; i++)
+        cx->newborn[i] = NULL;
+    cx->lastAtom = NULL;
+    cx->lastInternalResult = JSVAL_NULL;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_EnterLocalRootScope(JSContext *cx)
+{
+    CHECK_REQUEST(cx);
+    return js_EnterLocalRootScope(cx);
+}
+
+JS_PUBLIC_API(void)
+JS_LeaveLocalRootScope(JSContext *cx)
+{
+    CHECK_REQUEST(cx);
+    js_LeaveLocalRootScope(cx);
+}
+
+JS_PUBLIC_API(void)
+JS_ForgetLocalRoot(JSContext *cx, void *thing)
+{
+    CHECK_REQUEST(cx);
+    js_ForgetLocalRoot(cx, (jsval) thing);
+}
+
+#include "jshash.h" /* Added by JSIFY */
+
+#ifdef DEBUG
+
+typedef struct NamedRootDumpArgs {
+    void (*dump)(const char *name, void *rp, void *data);
+    void *data;
+} NamedRootDumpArgs;
+
+JS_STATIC_DLL_CALLBACK(JSDHashOperator)
+js_named_root_dumper(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number,
+                     void *arg)
+{
+    NamedRootDumpArgs *args = (NamedRootDumpArgs *) arg;
+    JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
+
+    if (rhe->name)
+        args->dump(rhe->name, rhe->root, args->data);
+    return JS_DHASH_NEXT;
+}
+
+JS_PUBLIC_API(void)
+JS_DumpNamedRoots(JSRuntime *rt,
+                  void (*dump)(const char *name, void *rp, void *data),
+                  void *data)
+{
+    NamedRootDumpArgs args;
+
+    args.dump = dump;
+    args.data = data;
+    JS_DHashTableEnumerate(&rt->gcRootsHash, js_named_root_dumper, &args);
+}
+
+#endif /* DEBUG */
+
+typedef struct GCRootMapArgs {
+    JSGCRootMapFun map;
+    void *data;
+} GCRootMapArgs;
+
+JS_STATIC_DLL_CALLBACK(JSDHashOperator)
+js_gcroot_mapper(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number,
+                 void *arg)
+{
+    GCRootMapArgs *args = (GCRootMapArgs *) arg;
+    JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
+    intN mapflags;
+    JSDHashOperator op;
+
+    mapflags = args->map(rhe->root, rhe->name, args->data);
+
+#if JS_MAP_GCROOT_NEXT == JS_DHASH_NEXT &&                                     \
+    JS_MAP_GCROOT_STOP == JS_DHASH_STOP &&                                     \
+    JS_MAP_GCROOT_REMOVE == JS_DHASH_REMOVE
+    op = (JSDHashOperator)mapflags;
+#else
+    op = JS_DHASH_NEXT;
+    if (mapflags & JS_MAP_GCROOT_STOP)
+        op |= JS_DHASH_STOP;
+    if (mapflags & JS_MAP_GCROOT_REMOVE)
+        op |= JS_DHASH_REMOVE;
+#endif
+
+    return op;
+}
+
+JS_PUBLIC_API(uint32)
+JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data)
+{
+    GCRootMapArgs args;
+    uint32 rv;
+
+    args.map = map;
+    args.data = data;
+    JS_LOCK_GC(rt);
+    rv = JS_DHashTableEnumerate(&rt->gcRootsHash, js_gcroot_mapper, &args);
+    JS_UNLOCK_GC(rt);
+    return rv;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_LockGCThing(JSContext *cx, void *thing)
+{
+    JSBool ok;
+
+    CHECK_REQUEST(cx);
+    ok = js_LockGCThing(cx, thing);
+    if (!ok)
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_LOCK);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_LockGCThingRT(JSRuntime *rt, void *thing)
+{
+    return js_LockGCThingRT(rt, thing);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_UnlockGCThing(JSContext *cx, void *thing)
+{
+    JSBool ok;
+
+    CHECK_REQUEST(cx);
+    ok = js_UnlockGCThingRT(cx->runtime, thing);
+    if (!ok)
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_UNLOCK);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_UnlockGCThingRT(JSRuntime *rt, void *thing)
+{
+    return js_UnlockGCThingRT(rt, thing);
+}
+
+JS_PUBLIC_API(void)
+JS_MarkGCThing(JSContext *cx, void *thing, const char *name, void *arg)
+{
+    JS_ASSERT(cx->runtime->gcLevel > 0);
+#ifdef JS_THREADSAFE
+    JS_ASSERT(cx->runtime->gcThread == js_CurrentThreadId());
+#endif
+
+    GC_MARK(cx, thing, name, arg);
+}
+
+JS_PUBLIC_API(void)
+JS_GC(JSContext *cx)
+{
+    /* Don't nuke active arenas if executing or compiling. */
+    if (cx->stackPool.current == &cx->stackPool.first)
+        JS_FinishArenaPool(&cx->stackPool);
+    if (cx->tempPool.current == &cx->tempPool.first)
+        JS_FinishArenaPool(&cx->tempPool);
+    js_ForceGC(cx, 0);
+}
+
+JS_PUBLIC_API(void)
+JS_MaybeGC(JSContext *cx)
+{
+#ifdef WAY_TOO_MUCH_GC
+    JS_GC(cx);
+#else
+    JSRuntime *rt;
+    uint32 bytes, lastBytes;
+
+    rt = cx->runtime;
+    bytes = rt->gcBytes;
+    lastBytes = rt->gcLastBytes;
+    if ((bytes > 8192 && bytes > lastBytes + lastBytes / 2) ||
+        rt->gcMallocBytes > rt->gcMaxBytes) {
+        /*
+         * Run the GC if we have half again as many bytes of GC-things as
+         * the last time we GC'd, or if we have malloc'd more bytes through
+         * JS_malloc than we were told to allocate by JS_NewRuntime.
+         */
+        JS_GC(cx);
+    }
+#endif
+}
+
+JS_PUBLIC_API(JSGCCallback)
+JS_SetGCCallback(JSContext *cx, JSGCCallback cb)
+{
+    return JS_SetGCCallbackRT(cx->runtime, cb);
+}
+
+JS_PUBLIC_API(JSGCCallback)
+JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb)
+{
+    JSGCCallback oldcb;
+
+    oldcb = rt->gcCallback;
+    rt->gcCallback = cb;
+    return oldcb;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_IsAboutToBeFinalized(JSContext *cx, void *thing)
+{
+    JS_ASSERT(thing);
+    return js_IsAboutToBeFinalized(cx, thing);
+}
+
+JS_PUBLIC_API(intN)
+JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer)
+{
+    return js_ChangeExternalStringFinalizer(NULL, finalizer);
+}
+
+JS_PUBLIC_API(intN)
+JS_RemoveExternalStringFinalizer(JSStringFinalizeOp finalizer)
+{
+    return js_ChangeExternalStringFinalizer(finalizer, NULL);
+}
+
+JS_PUBLIC_API(JSString *)
+JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type)
+{
+    JSString *str;
+
+    CHECK_REQUEST(cx);
+    JS_ASSERT(GCX_EXTERNAL_STRING <= type && type < (intN) GCX_NTYPES);
+
+    str = (JSString *) js_NewGCThing(cx, (uintN) type, sizeof(JSString));
+    if (!str)
+        return NULL;
+    str->length = length;
+    str->chars = chars;
+    return str;
+}
+
+JS_PUBLIC_API(intN)
+JS_GetExternalStringGCType(JSRuntime *rt, JSString *str)
+{
+    uint8 type = (uint8) (*js_GetGCThingFlags(str) & GCF_TYPEMASK);
+
+    if (type >= GCX_EXTERNAL_STRING)
+        return (intN)type;
+    JS_ASSERT(type == GCX_STRING || type == GCX_MUTABLE_STRING);
+    return -1;
+}
+
+JS_PUBLIC_API(void)
+JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr)
+{
+#if JS_STACK_GROWTH_DIRECTION > 0
+    if (limitAddr == 0)
+        limitAddr = (jsuword)-1;
+#endif
+    cx->stackLimit = limitAddr;
+}
+
+/************************************************************************/
+
+JS_PUBLIC_API(void)
+JS_DestroyIdArray(JSContext *cx, JSIdArray *ida)
+{
+    JS_free(cx, ida);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ValueToId(JSContext *cx, jsval v, jsid *idp)
+{
+    JSAtom *atom;
+
+    CHECK_REQUEST(cx);
+    if (JSVAL_IS_INT(v)) {
+        *idp = v;
+    } else {
+        atom = js_ValueToStringAtom(cx, v);
+        if (!atom)
+            return JS_FALSE;
+        *idp = ATOM_TO_JSID(atom);
+    }
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_IdToValue(JSContext *cx, jsid id, jsval *vp)
+{
+    CHECK_REQUEST(cx);
+    *vp = ID_TO_VALUE(id);
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_PropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_EnumerateStub(JSContext *cx, JSObject *obj)
+{
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ResolveStub(JSContext *cx, JSObject *obj, jsval id)
+{
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
+{
+#if JS_BUG_EAGER_TOSTRING
+    if (type == JSTYPE_STRING)
+        return JS_TRUE;
+#endif
+    js_TryValueOf(cx, obj, type, vp);
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(void)
+JS_FinalizeStub(JSContext *cx, JSObject *obj)
+{
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
+             JSClass *clasp, JSNative constructor, uintN nargs,
+             JSPropertySpec *ps, JSFunctionSpec *fs,
+             JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
+{
+    JSAtom *atom;
+    JSObject *proto, *ctor;
+    JSTempValueRooter tvr;
+    jsval cval, rval;
+    JSBool named;
+    JSFunction *fun;
+
+    CHECK_REQUEST(cx);
+    atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0);
+    if (!atom)
+        return NULL;
+
+    /* Create a prototype object for this class. */
+    proto = js_NewObject(cx, clasp, parent_proto, obj);
+    if (!proto)
+        return NULL;
+
+    /* After this point, control must exit via label bad or out. */
+    JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(proto), &tvr);
+
+    if (!constructor) {
+        /* Lacking a constructor, name the prototype (e.g., Math). */
+        named = OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom),
+                                    OBJECT_TO_JSVAL(proto),
+                                    NULL, NULL, 0, NULL);
+        if (!named)
+            goto bad;
+        ctor = proto;
+    } else {
+        /* Define the constructor function in obj's scope. */
+        fun = js_DefineFunction(cx, obj, atom, constructor, nargs, 0);
+        named = (fun != NULL);
+        if (!fun)
+            goto bad;
+
+        /*
+         * Remember the class this function is a constructor for so that
+         * we know to create an object of this class when we call the
+         * constructor.
+         */
+        fun->clasp = clasp;
+
+        /*
+         * Optionally construct the prototype object, before the class has
+         * been fully initialized.  Allow the ctor to replace proto with a
+         * different object, as is done for operator new -- and as at least
+         * XML support requires.
+         */
+        ctor = fun->object;
+        if (clasp->flags & JSCLASS_CONSTRUCT_PROTOTYPE) {
+            cval = OBJECT_TO_JSVAL(ctor);
+            if (!js_InternalConstruct(cx, proto, cval, 0, NULL, &rval))
+                goto bad;
+            if (!JSVAL_IS_PRIMITIVE(rval) && JSVAL_TO_OBJECT(rval) != proto)
+                proto = JSVAL_TO_OBJECT(rval);
+        }
+
+        /* Connect constructor and prototype by named properties. */
+        if (!js_SetClassPrototype(cx, ctor, proto,
+                                  JSPROP_READONLY | JSPROP_PERMANENT)) {
+            goto bad;
+        }
+
+        /* Bootstrap Function.prototype (see also JS_InitStandardClasses). */
+        if (OBJ_GET_CLASS(cx, ctor) == clasp) {
+            /* XXXMLM - this fails in framesets that are writing over
+             *           themselves!
+             * JS_ASSERT(!OBJ_GET_PROTO(cx, ctor));
+             */
+            OBJ_SET_PROTO(cx, ctor, proto);
+        }
+    }
+
+    /* Add properties and methods to the prototype and the constructor. */
+    if ((ps && !JS_DefineProperties(cx, proto, ps)) ||
+        (fs && !JS_DefineFunctions(cx, proto, fs)) ||
+        (static_ps && !JS_DefineProperties(cx, ctor, static_ps)) ||
+        (static_fs && !JS_DefineFunctions(cx, ctor, static_fs))) {
+        goto bad;
+    }
+
+out:
+    JS_POP_TEMP_ROOT(cx, &tvr);
+    return proto;
+
+bad:
+    if (named)
+        (void) OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &rval);
+    proto = NULL;
+    goto out;
+}
+
+#ifdef JS_THREADSAFE
+JS_PUBLIC_API(JSClass *)
+JS_GetClass(JSContext *cx, JSObject *obj)
+{
+    return (JSClass *)
+        JSVAL_TO_PRIVATE(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_CLASS));
+}
+#else
+JS_PUBLIC_API(JSClass *)
+JS_GetClass(JSObject *obj)
+{
+    return LOCKED_OBJ_GET_CLASS(obj);
+}
+#endif
+
+JS_PUBLIC_API(JSBool)
+JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv)
+{
+    JSFunction *fun;
+
+    CHECK_REQUEST(cx);
+    if (OBJ_GET_CLASS(cx, obj) == clasp)
+        return JS_TRUE;
+    if (argv) {
+        fun = js_ValueToFunction(cx, &argv[-2], 0);
+        if (fun) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_INCOMPATIBLE_PROTO,
+                                 clasp->name, JS_GetFunctionName(fun),
+                                 OBJ_GET_CLASS(cx, obj)->name);
+        }
+    }
+    return JS_FALSE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
+{
+    return js_HasInstance(cx, obj, v, bp);
+}
+
+JS_PUBLIC_API(void *)
+JS_GetPrivate(JSContext *cx, JSObject *obj)
+{
+    jsval v;
+
+    JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE);
+    v = GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    if (!JSVAL_IS_INT(v))
+        return NULL;
+    return JSVAL_TO_PRIVATE(v);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetPrivate(JSContext *cx, JSObject *obj, void *data)
+{
+    JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE);
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(data));
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(void *)
+JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp,
+                      jsval *argv)
+{
+    if (!JS_InstanceOf(cx, obj, clasp, argv))
+        return NULL;
+    return JS_GetPrivate(cx, obj);
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_GetPrototype(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto;
+
+    CHECK_REQUEST(cx);
+    proto = JSVAL_TO_OBJECT(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PROTO));
+
+    /* Beware ref to dead object (we may be called from obj's finalizer). */
+    return proto && proto->map ? proto : NULL;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto)
+{
+    CHECK_REQUEST(cx);
+    if (obj->map->ops->setProto)
+        return obj->map->ops->setProto(cx, obj, JSSLOT_PROTO, proto);
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto));
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_GetParent(JSContext *cx, JSObject *obj)
+{
+    JSObject *parent;
+
+    parent = JSVAL_TO_OBJECT(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PARENT));
+
+    /* Beware ref to dead object (we may be called from obj's finalizer). */
+    return parent && parent->map ? parent : NULL;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent)
+{
+    CHECK_REQUEST(cx);
+    if (obj->map->ops->setParent)
+        return obj->map->ops->setParent(cx, obj, JSSLOT_PARENT, parent);
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent));
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_GetConstructor(JSContext *cx, JSObject *proto)
+{
+    jsval cval;
+
+    CHECK_REQUEST(cx);
+    if (!OBJ_GET_PROPERTY(cx, proto,
+                          ATOM_TO_JSID(cx->runtime->atomState.constructorAtom),
+                          &cval)) {
+        return NULL;
+    }
+    if (!JSVAL_IS_FUNCTION(cx, cval)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR,
+                             OBJ_GET_CLASS(cx, proto)->name);
+        return NULL;
+    }
+    return JSVAL_TO_OBJECT(cval);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp)
+{
+    JS_ASSERT(((jsid)obj & JSID_TAGMASK) == 0);
+    *idp = OBJECT_TO_JSID(obj);
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
+{
+    CHECK_REQUEST(cx);
+    if (!clasp)
+        clasp = &js_ObjectClass;    /* default class is Object */
+    return js_NewObject(cx, clasp, proto, parent);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep)
+{
+    JSScope *scope;
+    JSIdArray *ida;
+    uint32 nslots;
+    jsval v, *vp, *end;
+
+    if (!OBJ_IS_NATIVE(obj)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_CANT_SEAL_OBJECT,
+                             OBJ_GET_CLASS(cx, obj)->name);
+        return JS_FALSE;
+    }
+
+    scope = OBJ_SCOPE(obj);
+
+#if defined JS_THREADSAFE && defined DEBUG
+    /* Insist on scope being used exclusively by cx's thread. */
+    if (scope->ownercx != cx) {
+        JS_LOCK_OBJ(cx, obj);
+        JS_ASSERT(OBJ_SCOPE(obj) == scope);
+        JS_ASSERT(scope->ownercx == cx);
+        JS_UNLOCK_SCOPE(cx, scope);
+    }
+#endif
+
+    /* Nothing to do if obj's scope is already sealed. */
+    if (SCOPE_IS_SEALED(scope))
+        return JS_TRUE;
+
+    /* XXX Enumerate lazy properties now, as they can't be added later. */
+    ida = JS_Enumerate(cx, obj);
+    if (!ida)
+        return JS_FALSE;
+    JS_DestroyIdArray(cx, ida);
+
+    /* Ensure that obj has its own, mutable scope, and seal that scope. */
+    JS_LOCK_OBJ(cx, obj);
+    scope = js_GetMutableScope(cx, obj);
+    if (scope)
+        SCOPE_SET_SEALED(scope);
+    JS_UNLOCK_OBJ(cx, obj);
+    if (!scope)
+        return JS_FALSE;
+
+    /* If we are not sealing an entire object graph, we're done. */
+    if (!deep)
+        return JS_TRUE;
+
+    /* Walk obj->slots and if any value is a non-null object, seal it. */
+    nslots = JS_MIN(scope->map.freeslot, scope->map.nslots);
+    for (vp = obj->slots, end = vp + nslots; vp < end; vp++) {
+        v = *vp;
+        if (JSVAL_IS_PRIMITIVE(v))
+            continue;
+        if (!JS_SealObject(cx, JSVAL_TO_OBJECT(v), deep))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
+                   JSObject *parent)
+{
+    CHECK_REQUEST(cx);
+    if (!clasp)
+        clasp = &js_ObjectClass;    /* default class is Object */
+    return js_ConstructObject(cx, clasp, proto, parent, 0, NULL);
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *proto,
+                                JSObject *parent, uintN argc, jsval *argv)
+{
+    CHECK_REQUEST(cx);
+    if (!clasp)
+        clasp = &js_ObjectClass;    /* default class is Object */
+    return js_ConstructObject(cx, clasp, proto, parent, argc, argv);
+}
+
+static JSBool
+DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
+               JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
+               uintN flags, intN tinyid)
+{
+    jsid id;
+    JSAtom *atom;
+
+    if (attrs & JSPROP_INDEX) {
+        id = INT_TO_JSID(JS_PTR_TO_INT32(name));
+        atom = NULL;
+        attrs &= ~JSPROP_INDEX;
+    } else {
+        atom = js_Atomize(cx, name, strlen(name), 0);
+        if (!atom)
+            return JS_FALSE;
+        id = ATOM_TO_JSID(atom);
+    }
+    if (flags != 0 && OBJ_IS_NATIVE(obj)) {
+        return js_DefineNativeProperty(cx, obj, id, value, getter, setter,
+                                       attrs, flags, tinyid, NULL);
+    }
+    return OBJ_DEFINE_PROPERTY(cx, obj, id, value, getter, setter, attrs,
+                               NULL);
+}
+
+#define AUTO_NAMELEN(s,n)   (((n) == (size_t)-1) ? js_strlen(s) : (n))
+
+static JSBool
+DefineUCProperty(JSContext *cx, JSObject *obj,
+                 const jschar *name, size_t namelen, jsval value,
+                 JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
+                 uintN flags, intN tinyid)
+{
+    JSAtom *atom;
+
+    atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
+    if (!atom)
+        return JS_FALSE;
+    if (flags != 0 && OBJ_IS_NATIVE(obj)) {
+        return js_DefineNativeProperty(cx, obj, ATOM_TO_JSID(atom), value,
+                                       getter, setter, attrs, flags, tinyid,
+                                       NULL);
+    }
+    return OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), value,
+                               getter, setter, attrs, NULL);
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp,
+                JSObject *proto, uintN attrs)
+{
+    JSObject *nobj;
+
+    CHECK_REQUEST(cx);
+    if (!clasp)
+        clasp = &js_ObjectClass;    /* default class is Object */
+    nobj = js_NewObject(cx, clasp, proto, obj);
+    if (!nobj)
+        return NULL;
+    if (!DefineProperty(cx, obj, name, OBJECT_TO_JSVAL(nobj), NULL, NULL, attrs,
+                        0, 0)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+    return nobj;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds)
+{
+    JSBool ok;
+    jsval value;
+    uintN flags;
+
+    CHECK_REQUEST(cx);
+    for (ok = JS_TRUE; cds->name; cds++) {
+        ok = js_NewNumberValue(cx, cds->dval, &value);
+        if (!ok)
+            break;
+        flags = cds->flags;
+        if (!flags)
+            flags = JSPROP_READONLY | JSPROP_PERMANENT;
+        ok = DefineProperty(cx, obj, cds->name, value, NULL, NULL, flags, 0, 0);
+        if (!ok)
+            break;
+    }
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DefineProperties(JSContext *cx, JSObject *obj, JSPropertySpec *ps)
+{
+    JSBool ok;
+
+    CHECK_REQUEST(cx);
+    for (ok = JS_TRUE; ps->name; ps++) {
+        ok = DefineProperty(cx, obj, ps->name, JSVAL_VOID,
+                            ps->getter, ps->setter, ps->flags,
+                            SPROP_HAS_SHORTID, ps->tinyid);
+        if (!ok)
+            break;
+    }
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
+                  JSPropertyOp getter, JSPropertyOp setter, uintN attrs)
+{
+    CHECK_REQUEST(cx);
+    return DefineProperty(cx, obj, name, value, getter, setter, attrs, 0, 0);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name,
+                            int8 tinyid, jsval value,
+                            JSPropertyOp getter, JSPropertyOp setter,
+                            uintN attrs)
+{
+    CHECK_REQUEST(cx);
+    return DefineProperty(cx, obj, name, value, getter, setter, attrs,
+                          SPROP_HAS_SHORTID, tinyid);
+}
+
+static JSBool
+LookupProperty(JSContext *cx, JSObject *obj, const char *name, JSObject **objp,
+               JSProperty **propp)
+{
+    JSAtom *atom;
+
+    atom = js_Atomize(cx, name, strlen(name), 0);
+    if (!atom)
+        return JS_FALSE;
+    return OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), objp, propp);
+}
+
+static JSBool
+LookupUCProperty(JSContext *cx, JSObject *obj,
+                 const jschar *name, size_t namelen,
+                 JSObject **objp, JSProperty **propp)
+{
+    JSAtom *atom;
+
+    atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
+    if (!atom)
+        return JS_FALSE;
+    return OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), objp, propp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name,
+                 const char *alias)
+{
+    JSObject *obj2;
+    JSProperty *prop;
+    JSAtom *atom;
+    JSBool ok;
+    JSScopeProperty *sprop;
+
+    CHECK_REQUEST(cx);
+    if (!LookupProperty(cx, obj, name, &obj2, &prop))
+        return JS_FALSE;
+    if (!prop) {
+        js_ReportIsNotDefined(cx, name);
+        return JS_FALSE;
+    }
+    if (obj2 != obj || !OBJ_IS_NATIVE(obj)) {
+        OBJ_DROP_PROPERTY(cx, obj2, prop);
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,
+                             alias, name, OBJ_GET_CLASS(cx, obj2)->name);
+        return JS_FALSE;
+    }
+    atom = js_Atomize(cx, alias, strlen(alias), 0);
+    if (!atom) {
+        ok = JS_FALSE;
+    } else {
+        sprop = (JSScopeProperty *)prop;
+        ok = (js_AddNativeProperty(cx, obj, ATOM_TO_JSID(atom),
+                                   sprop->getter, sprop->setter, sprop->slot,
+                                   sprop->attrs, sprop->flags | SPROP_IS_ALIAS,
+                                   sprop->shortid)
+              != NULL);
+    }
+    OBJ_DROP_PROPERTY(cx, obj, prop);
+    return ok;
+}
+
+static jsval
+LookupResult(JSContext *cx, JSObject *obj, JSObject *obj2, JSProperty *prop)
+{
+    JSScopeProperty *sprop;
+    jsval rval;
+
+    if (!prop) {
+        /* XXX bad API: no way to tell "not defined" from "void value" */
+        return JSVAL_VOID;
+    }
+    if (OBJ_IS_NATIVE(obj2)) {
+        /* Peek at the native property's slot value, without doing a Get. */
+        sprop = (JSScopeProperty *)prop;
+        rval = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2))
+               ? LOCKED_OBJ_GET_SLOT(obj2, sprop->slot)
+               : JSVAL_TRUE;
+    } else {
+        /* XXX bad API: no way to return "defined but value unknown" */
+        rval = JSVAL_TRUE;
+    }
+    OBJ_DROP_PROPERTY(cx, obj2, prop);
+    return rval;
+}
+
+static JSBool
+GetPropertyAttributes(JSContext *cx, JSObject *obj, JSAtom *atom,
+                      uintN *attrsp, JSBool *foundp,
+                      JSPropertyOp *getterp, JSPropertyOp *setterp)
+{
+    JSObject *obj2;
+    JSProperty *prop;
+    JSBool ok;
+
+    if (!atom)
+        return JS_FALSE;
+    if (!OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &obj2, &prop))
+        return JS_FALSE;
+
+    if (!prop || obj != obj2) {
+        *attrsp = 0;
+        *foundp = JS_FALSE;
+        if (getterp)
+            *getterp = NULL;
+        if (setterp)
+            *setterp = NULL;
+        if (prop)
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+        return JS_TRUE;
+    }
+
+    *foundp = JS_TRUE;
+    ok = OBJ_GET_ATTRIBUTES(cx, obj, ATOM_TO_JSID(atom), prop, attrsp);
+    if (ok && OBJ_IS_NATIVE(obj)) {
+        JSScopeProperty *sprop = (JSScopeProperty *) prop;
+
+        if (getterp)
+            *getterp = sprop->getter;
+        if (setterp)
+            *setterp = sprop->setter;
+    }
+    OBJ_DROP_PROPERTY(cx, obj, prop);
+    return ok;
+}
+
+static JSBool
+SetPropertyAttributes(JSContext *cx, JSObject *obj, JSAtom *atom,
+                      uintN attrs, JSBool *foundp)
+{
+    JSObject *obj2;
+    JSProperty *prop;
+    JSBool ok;
+
+    if (!atom)
+        return JS_FALSE;
+    if (!OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &obj2, &prop))
+        return JS_FALSE;
+    if (!prop || obj != obj2) {
+        *foundp = JS_FALSE;
+        if (prop)
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+        return JS_TRUE;
+    }
+
+    *foundp = JS_TRUE;
+    ok = OBJ_SET_ATTRIBUTES(cx, obj, ATOM_TO_JSID(atom), prop, &attrs);
+    OBJ_DROP_PROPERTY(cx, obj, prop);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
+                         uintN *attrsp, JSBool *foundp)
+{
+    CHECK_REQUEST(cx);
+    return GetPropertyAttributes(cx, obj,
+                                 js_Atomize(cx, name, strlen(name), 0),
+                                 attrsp, foundp, NULL, NULL);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
+                                   const char *name,
+                                   uintN *attrsp, JSBool *foundp,
+                                   JSPropertyOp *getterp,
+                                   JSPropertyOp *setterp)
+{
+    CHECK_REQUEST(cx);
+    return GetPropertyAttributes(cx, obj,
+                                 js_Atomize(cx, name, strlen(name), 0),
+                                 attrsp, foundp, getterp, setterp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
+                         uintN attrs, JSBool *foundp)
+{
+    CHECK_REQUEST(cx);
+    return SetPropertyAttributes(cx, obj,
+                                 js_Atomize(cx, name, strlen(name), 0),
+                                 attrs, foundp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp)
+{
+    JSBool ok;
+    JSObject *obj2;
+    JSProperty *prop;
+
+    CHECK_REQUEST(cx);
+    ok = LookupProperty(cx, obj, name, &obj2, &prop);
+    if (ok) {
+        *foundp = (prop != NULL);
+        if (prop)
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+    }
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
+{
+    JSBool ok;
+    JSObject *obj2;
+    JSProperty *prop;
+
+    CHECK_REQUEST(cx);
+    ok = LookupProperty(cx, obj, name, &obj2, &prop);
+    if (ok)
+        *vp = LookupResult(cx, obj, obj2, prop);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name,
+                           uintN flags, jsval *vp)
+{
+    JSAtom *atom;
+    JSBool ok;
+    JSObject *obj2;
+    JSProperty *prop;
+
+    CHECK_REQUEST(cx);
+    atom = js_Atomize(cx, name, strlen(name), 0);
+    if (!atom)
+        return JS_FALSE;
+    ok = OBJ_IS_NATIVE(obj)
+         ? js_LookupPropertyWithFlags(cx, obj, ATOM_TO_JSID(atom), flags,
+                                      &obj2, &prop)
+         : OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &obj2, &prop);
+    if (ok)
+        *vp = LookupResult(cx, obj, obj2, prop);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
+{
+    JSAtom *atom;
+
+    CHECK_REQUEST(cx);
+    atom = js_Atomize(cx, name, strlen(name), 0);
+    if (!atom)
+        return JS_FALSE;
+    return OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp,
+             jsval *vp)
+{
+    JSAtom *atom;
+    jsid id;
+
+    CHECK_REQUEST(cx);
+    atom = js_Atomize(cx, name, strlen(name), 0);
+    if (!atom)
+        return JS_FALSE;
+    id = ATOM_TO_JSID(atom);
+
+#if JS_HAS_XML_SUPPORT
+    if (OBJECT_IS_XML(cx, obj)) {
+        JSXMLObjectOps *ops;
+
+        ops = (JSXMLObjectOps *) obj->map->ops;
+        obj = ops->getMethod(cx, obj, id, vp);
+        if (!obj)
+            return JS_FALSE;
+    } else
+#endif
+    {
+        if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
+            return JS_FALSE;
+    }
+
+    *objp = obj;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
+{
+    JSAtom *atom;
+
+    CHECK_REQUEST(cx);
+    atom = js_Atomize(cx, name, strlen(name), 0);
+    if (!atom)
+        return JS_FALSE;
+    return OBJ_SET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DeleteProperty(JSContext *cx, JSObject *obj, const char *name)
+{
+    jsval junk;
+
+    CHECK_REQUEST(cx);
+    return JS_DeleteProperty2(cx, obj, name, &junk);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name,
+                   jsval *rval)
+{
+    JSAtom *atom;
+
+    CHECK_REQUEST(cx);
+    atom = js_Atomize(cx, name, strlen(name), 0);
+    if (!atom)
+        return JS_FALSE;
+    return OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), rval);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DefineUCProperty(JSContext *cx, JSObject *obj,
+                    const jschar *name, size_t namelen, jsval value,
+                    JSPropertyOp getter, JSPropertyOp setter,
+                    uintN attrs)
+{
+    CHECK_REQUEST(cx);
+    return DefineUCProperty(cx, obj, name, namelen, value, getter, setter,
+                            attrs, 0, 0);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj,
+                           const jschar *name, size_t namelen,
+                           uintN *attrsp, JSBool *foundp)
+{
+    CHECK_REQUEST(cx);
+    return GetPropertyAttributes(cx, obj,
+                    js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0),
+                    attrsp, foundp, NULL, NULL);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
+                                     const jschar *name, size_t namelen,
+                                     uintN *attrsp, JSBool *foundp,
+                                     JSPropertyOp *getterp,
+                                     JSPropertyOp *setterp)
+{
+    CHECK_REQUEST(cx);
+    return GetPropertyAttributes(cx, obj,
+                    js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0),
+                    attrsp, foundp, getterp, setterp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj,
+                           const jschar *name, size_t namelen,
+                           uintN attrs, JSBool *foundp)
+{
+    CHECK_REQUEST(cx);
+    return SetPropertyAttributes(cx, obj,
+                    js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0),
+                    attrs, foundp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj,
+                              const jschar *name, size_t namelen,
+                              int8 tinyid, jsval value,
+                              JSPropertyOp getter, JSPropertyOp setter,
+                              uintN attrs)
+{
+    CHECK_REQUEST(cx);
+    return DefineUCProperty(cx, obj, name, namelen, value, getter, setter,
+                            attrs, SPROP_HAS_SHORTID, tinyid);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_HasUCProperty(JSContext *cx, JSObject *obj,
+                 const jschar *name, size_t namelen,
+                 JSBool *vp)
+{
+    JSBool ok;
+    JSObject *obj2;
+    JSProperty *prop;
+
+    CHECK_REQUEST(cx);
+    ok = LookupUCProperty(cx, obj, name, namelen, &obj2, &prop);
+    if (ok) {
+        *vp = (prop != NULL);
+        if (prop)
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+    }
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_LookupUCProperty(JSContext *cx, JSObject *obj,
+                    const jschar *name, size_t namelen,
+                    jsval *vp)
+{
+    JSBool ok;
+    JSObject *obj2;
+    JSProperty *prop;
+
+    CHECK_REQUEST(cx);
+    ok = LookupUCProperty(cx, obj, name, namelen, &obj2, &prop);
+    if (ok)
+        *vp = LookupResult(cx, obj, obj2, prop);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetUCProperty(JSContext *cx, JSObject *obj,
+                 const jschar *name, size_t namelen,
+                 jsval *vp)
+{
+    JSAtom *atom;
+
+    CHECK_REQUEST(cx);
+    atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
+    if (!atom)
+        return JS_FALSE;
+    return OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetUCProperty(JSContext *cx, JSObject *obj,
+                 const jschar *name, size_t namelen,
+                 jsval *vp)
+{
+    JSAtom *atom;
+
+    CHECK_REQUEST(cx);
+    atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
+    if (!atom)
+        return JS_FALSE;
+    return OBJ_SET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DeleteUCProperty2(JSContext *cx, JSObject *obj,
+                     const jschar *name, size_t namelen,
+                     jsval *rval)
+{
+    JSAtom *atom;
+
+    CHECK_REQUEST(cx);
+    atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
+    if (!atom)
+        return JS_FALSE;
+    return OBJ_DELETE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), rval);
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_NewArrayObject(JSContext *cx, jsint length, jsval *vector)
+{
+    CHECK_REQUEST(cx);
+    /* NB: jsuint cast does ToUint32. */
+    return js_NewArrayObject(cx, (jsuint)length, vector);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_IsArrayObject(JSContext *cx, JSObject *obj)
+{
+    return OBJ_GET_CLASS(cx, obj) == &js_ArrayClass;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp)
+{
+    CHECK_REQUEST(cx);
+    return js_GetLengthProperty(cx, obj, lengthp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length)
+{
+    CHECK_REQUEST(cx);
+    return js_SetLengthProperty(cx, obj, length);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp)
+{
+    CHECK_REQUEST(cx);
+    return js_HasLengthProperty(cx, obj, lengthp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value,
+                 JSPropertyOp getter, JSPropertyOp setter, uintN attrs)
+{
+    CHECK_REQUEST(cx);
+    return OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSID(index), value,
+                               getter, setter, attrs, NULL);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias)
+{
+    JSObject *obj2;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+    JSBool ok;
+
+    CHECK_REQUEST(cx);
+    if (!LookupProperty(cx, obj, name, &obj2, &prop))
+        return JS_FALSE;
+    if (!prop) {
+        js_ReportIsNotDefined(cx, name);
+        return JS_FALSE;
+    }
+    if (obj2 != obj || !OBJ_IS_NATIVE(obj)) {
+        char numBuf[12];
+        OBJ_DROP_PROPERTY(cx, obj2, prop);
+        JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)alias);
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,
+                             numBuf, name, OBJ_GET_CLASS(cx, obj2)->name);
+        return JS_FALSE;
+    }
+    sprop = (JSScopeProperty *)prop;
+    ok = (js_AddNativeProperty(cx, obj, INT_TO_JSID(alias),
+                               sprop->getter, sprop->setter, sprop->slot,
+                               sprop->attrs, sprop->flags | SPROP_IS_ALIAS,
+                               sprop->shortid)
+          != NULL);
+    OBJ_DROP_PROPERTY(cx, obj, prop);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp)
+{
+    JSBool ok;
+    JSObject *obj2;
+    JSProperty *prop;
+
+    CHECK_REQUEST(cx);
+    ok = OBJ_LOOKUP_PROPERTY(cx, obj, INT_TO_JSID(index), &obj2, &prop);
+    if (ok) {
+        *foundp = (prop != NULL);
+        if (prop)
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+    }
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
+{
+    JSBool ok;
+    JSObject *obj2;
+    JSProperty *prop;
+
+    CHECK_REQUEST(cx);
+    ok = OBJ_LOOKUP_PROPERTY(cx, obj, INT_TO_JSID(index), &obj2, &prop);
+    if (ok)
+        *vp = LookupResult(cx, obj, obj2, prop);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
+{
+    CHECK_REQUEST(cx);
+    return OBJ_GET_PROPERTY(cx, obj, INT_TO_JSID(index), vp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
+{
+    CHECK_REQUEST(cx);
+    return OBJ_SET_PROPERTY(cx, obj, INT_TO_JSID(index), vp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DeleteElement(JSContext *cx, JSObject *obj, jsint index)
+{
+    jsval junk;
+
+    CHECK_REQUEST(cx);
+    return JS_DeleteElement2(cx, obj, index, &junk);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval)
+{
+    CHECK_REQUEST(cx);
+    return OBJ_DELETE_PROPERTY(cx, obj, INT_TO_JSID(index), rval);
+}
+
+JS_PUBLIC_API(void)
+JS_ClearScope(JSContext *cx, JSObject *obj)
+{
+    CHECK_REQUEST(cx);
+
+    if (obj->map->ops->clear)
+        obj->map->ops->clear(cx, obj);
+}
+
+JS_PUBLIC_API(JSIdArray *)
+JS_Enumerate(JSContext *cx, JSObject *obj)
+{
+    jsint i, n;
+    jsval iter_state, num_properties;
+    jsid id;
+    JSIdArray *ida;
+    jsval *vector;
+
+    CHECK_REQUEST(cx);
+
+    ida = NULL;
+    iter_state = JSVAL_NULL;
+
+    /* Get the number of properties to enumerate. */
+    if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, &num_properties))
+        goto error;
+    if (!JSVAL_IS_INT(num_properties)) {
+        JS_ASSERT(0);
+        goto error;
+    }
+
+    /* Grow as needed if we don't know the exact amount ahead of time. */
+    n = JSVAL_TO_INT(num_properties);
+    if (n <= 0)
+        n = 8;
+
+    /* Create an array of jsids large enough to hold all the properties */
+    ida = js_NewIdArray(cx, n);
+    if (!ida)
+        goto error;
+
+    i = 0;
+    vector = &ida->vector[0];
+    for (;;) {
+        if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_NEXT, &iter_state, &id))
+            goto error;
+
+        /* No more jsid's to enumerate ? */
+        if (iter_state == JSVAL_NULL)
+            break;
+
+        if (i == ida->length) {
+            ida = js_SetIdArrayLength(cx, ida, ida->length * 2);
+            if (!ida)
+                goto error;
+            vector = &ida->vector[0];
+        }
+        vector[i++] = id;
+    }
+    return js_SetIdArrayLength(cx, ida, i);
+
+error:
+    if (iter_state != JSVAL_NULL)
+        OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0);
+    if (ida)
+        JS_DestroyIdArray(cx, ida);
+    return NULL;
+}
+
+/*
+ * XXX reverse iterator for properties, unreverse and meld with jsinterp.c's
+ *     prop_iterator_class somehow...
+ * + preserve the OBJ_ENUMERATE API while optimizing the native object case
+ * + native case here uses a JSScopeProperty *, but that iterates in reverse!
+ * + so we make non-native match, by reverse-iterating after JS_Enumerating
+ */
+#define JSSLOT_ITER_INDEX       (JSSLOT_PRIVATE + 1)
+
+#if JSSLOT_ITER_INDEX >= JS_INITIAL_NSLOTS
+# error "JSSLOT_ITER_INDEX botch!"
+#endif
+
+static void
+prop_iter_finalize(JSContext *cx, JSObject *obj)
+{
+    jsval v;
+    jsint i;
+    JSIdArray *ida;
+
+    v = GC_AWARE_GET_SLOT(cx, obj, JSSLOT_ITER_INDEX);
+    if (JSVAL_IS_VOID(v))
+        return;
+
+    i = JSVAL_TO_INT(v);
+    if (i >= 0) {
+        /* Non-native case: destroy the ida enumerated when obj was created. */
+        ida = (JSIdArray *) JS_GetPrivate(cx, obj);
+        if (ida)
+            JS_DestroyIdArray(cx, ida);
+    }
+}
+
+static uint32
+prop_iter_mark(JSContext *cx, JSObject *obj, void *arg)
+{
+    jsval v;
+    jsint i, n;
+    JSScopeProperty *sprop;
+    JSIdArray *ida;
+    jsid id;
+
+    v = GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    JS_ASSERT(!JSVAL_IS_VOID(v));
+
+    i = JSVAL_TO_INT(OBJ_GET_SLOT(cx, obj, JSSLOT_ITER_INDEX));
+    if (i < 0) {
+        /* Native case: just mark the next property to visit. */
+        sprop = (JSScopeProperty *) JSVAL_TO_PRIVATE(v);
+        if (sprop)
+            MARK_SCOPE_PROPERTY(sprop);
+    } else {
+        /* Non-native case: mark each id in the JSIdArray private. */
+        ida = (JSIdArray *) JSVAL_TO_PRIVATE(v);
+        for (i = 0, n = ida->length; i < n; i++) {
+            id = ida->vector[i];
+            if (JSID_IS_ATOM(id))
+                GC_MARK_ATOM(cx, JSID_TO_ATOM(id), arg);
+            else if (JSID_IS_OBJECT(id))
+                GC_MARK(cx, JSID_TO_OBJECT(id), "id", arg);
+        }
+    }
+    return 0;
+}
+
+static JSClass prop_iter_class = {
+    "PropertyIterator",
+    JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1),
+    JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,  JS_ConvertStub,  prop_iter_finalize,
+    NULL,             NULL,            NULL,            NULL,
+    NULL,             NULL,            prop_iter_mark,  NULL
+};
+
+JS_PUBLIC_API(JSObject *)
+JS_NewPropertyIterator(JSContext *cx, JSObject *obj)
+{
+    JSObject *iterobj;
+    JSScope *scope;
+    void *pdata;
+    jsint index;
+    JSIdArray *ida;
+
+    CHECK_REQUEST(cx);
+    iterobj = js_NewObject(cx, &prop_iter_class, NULL, obj);
+    if (!iterobj)
+        return NULL;
+
+    if (OBJ_IS_NATIVE(obj)) {
+        /* Native case: start with the last property in obj's own scope. */
+        scope = OBJ_SCOPE(obj);
+        pdata = (scope->object == obj) ? scope->lastProp : NULL;
+        index = -1;
+    } else {
+        /* Non-native case: enumerate a JSIdArray and keep it via private. */
+        ida = JS_Enumerate(cx, obj);
+        if (!ida)
+            goto bad;
+        pdata = ida;
+        index = ida->length;
+    }
+
+    if (!JS_SetPrivate(cx, iterobj, pdata))
+        goto bad;
+    OBJ_SET_SLOT(cx, iterobj, JSSLOT_ITER_INDEX, INT_TO_JSVAL(index));
+    return iterobj;
+
+bad:
+    cx->newborn[GCX_OBJECT] = NULL;
+    return NULL;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_NextProperty(JSContext *cx, JSObject *iterobj, jsid *idp)
+{
+    jsint i;
+    JSObject *obj;
+    JSScope *scope;
+    JSScopeProperty *sprop;
+    JSIdArray *ida;
+
+    CHECK_REQUEST(cx);
+    i = JSVAL_TO_INT(OBJ_GET_SLOT(cx, iterobj, JSSLOT_ITER_INDEX));
+    if (i < 0) {
+        /* Native case: private data is a property tree node pointer. */
+        obj = OBJ_GET_PARENT(cx, iterobj);
+        JS_ASSERT(OBJ_IS_NATIVE(obj));
+        scope = OBJ_SCOPE(obj);
+        JS_ASSERT(scope->object == obj);
+        sprop = (JSScopeProperty *) JS_GetPrivate(cx, iterobj);
+
+        /*
+         * If the next property mapped by scope in the property tree ancestor
+         * line is not enumerable, or it's an alias, or one or more properties
+         * were deleted from the "middle" of the scope-mapped ancestor line
+         * and the next property was among those deleted, skip it and keep on
+         * trying to find an enumerable property that is still in scope.
+         */
+        while (sprop &&
+               (!(sprop->attrs & JSPROP_ENUMERATE) ||
+                (sprop->flags & SPROP_IS_ALIAS) ||
+                (SCOPE_HAD_MIDDLE_DELETE(scope) &&
+                 !SCOPE_HAS_PROPERTY(scope, sprop)))) {
+            sprop = sprop->parent;
+        }
+
+        if (!sprop) {
+            *idp = JSVAL_VOID;
+        } else {
+            if (!JS_SetPrivate(cx, iterobj, sprop->parent))
+                return JS_FALSE;
+            *idp = sprop->id;
+        }
+    } else {
+        /* Non-native case: use the ida enumerated when iterobj was created. */
+        ida = (JSIdArray *) JS_GetPrivate(cx, iterobj);
+        JS_ASSERT(i <= ida->length);
+        if (i == 0) {
+            *idp = JSVAL_VOID;
+        } else {
+            *idp = ida->vector[--i];
+            OBJ_SET_SLOT(cx, iterobj, JSSLOT_ITER_INDEX, INT_TO_JSVAL(i));
+        }
+    }
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
+               jsval *vp, uintN *attrsp)
+{
+    CHECK_REQUEST(cx);
+    return OBJ_CHECK_ACCESS(cx, obj, id, mode, vp, attrsp);
+}
+
+JS_PUBLIC_API(JSCheckAccessOp)
+JS_SetCheckObjectAccessCallback(JSRuntime *rt, JSCheckAccessOp acb)
+{
+    JSCheckAccessOp oldacb;
+
+    oldacb = rt->checkObjectAccess;
+    rt->checkObjectAccess = acb;
+    return oldacb;
+}
+
+static JSBool
+ReservedSlotIndexOK(JSContext *cx, JSObject *obj, JSClass *clasp,
+                    uint32 index, uint32 limit)
+{
+    /* Check the computed, possibly per-instance, upper bound. */
+    if (clasp->reserveSlots)
+        JS_LOCK_OBJ_VOID(cx, obj, limit += clasp->reserveSlots(cx, obj));
+    if (index >= limit) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_RESERVED_SLOT_RANGE);
+        return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp)
+{
+    JSClass *clasp;
+    uint32 limit, slot;
+
+    CHECK_REQUEST(cx);
+    clasp = OBJ_GET_CLASS(cx, obj);
+    limit = JSCLASS_RESERVED_SLOTS(clasp);
+    if (index >= limit && !ReservedSlotIndexOK(cx, obj, clasp, index, limit))
+        return JS_FALSE;
+    slot = JSSLOT_START(clasp) + index;
+    *vp = OBJ_GET_REQUIRED_SLOT(cx, obj, slot);
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v)
+{
+    JSClass *clasp;
+    uint32 limit, slot;
+
+    CHECK_REQUEST(cx);
+    clasp = OBJ_GET_CLASS(cx, obj);
+    limit = JSCLASS_RESERVED_SLOTS(clasp);
+    if (index >= limit && !ReservedSlotIndexOK(cx, obj, clasp, index, limit))
+        return JS_FALSE;
+    slot = JSSLOT_START(clasp) + index;
+    return OBJ_SET_REQUIRED_SLOT(cx, obj, slot, v);
+}
+
+#ifdef JS_THREADSAFE
+JS_PUBLIC_API(jsrefcount)
+JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals)
+{
+    return JS_ATOMIC_INCREMENT(&principals->refcount);
+}
+
+JS_PUBLIC_API(jsrefcount)
+JS_DropPrincipals(JSContext *cx, JSPrincipals *principals)
+{
+    jsrefcount rc = JS_ATOMIC_DECREMENT(&principals->refcount);
+    if (rc == 0)
+        principals->destroy(cx, principals);
+    return rc;
+}
+#endif
+
+JS_PUBLIC_API(JSPrincipalsTranscoder)
+JS_SetPrincipalsTranscoder(JSRuntime *rt, JSPrincipalsTranscoder px)
+{
+    JSPrincipalsTranscoder oldpx;
+
+    oldpx = rt->principalsTranscoder;
+    rt->principalsTranscoder = px;
+    return oldpx;
+}
+
+JS_PUBLIC_API(JSObjectPrincipalsFinder)
+JS_SetObjectPrincipalsFinder(JSRuntime *rt, JSObjectPrincipalsFinder fop)
+{
+    JSObjectPrincipalsFinder oldfop;
+
+    oldfop = rt->findObjectPrincipals;
+    rt->findObjectPrincipals = fop;
+    return oldfop;
+}
+
+JS_PUBLIC_API(JSFunction *)
+JS_NewFunction(JSContext *cx, JSNative native, uintN nargs, uintN flags,
+               JSObject *parent, const char *name)
+{
+    JSAtom *atom;
+
+    CHECK_REQUEST(cx);
+
+    if (!name) {
+        atom = NULL;
+    } else {
+        atom = js_Atomize(cx, name, strlen(name), 0);
+        if (!atom)
+            return NULL;
+    }
+    return js_NewFunction(cx, NULL, native, nargs, flags, parent, atom);
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
+{
+    CHECK_REQUEST(cx);
+    if (OBJ_GET_CLASS(cx, funobj) != &js_FunctionClass) {
+        /* Indicate we cannot clone this object. */
+        return funobj;
+    }
+    return js_CloneFunctionObject(cx, funobj, parent);
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_GetFunctionObject(JSFunction *fun)
+{
+    return fun->object;
+}
+
+JS_PUBLIC_API(const char *)
+JS_GetFunctionName(JSFunction *fun)
+{
+    return fun->atom
+           ? JS_GetStringBytes(ATOM_TO_STRING(fun->atom))
+           : js_anonymous_str;
+}
+
+JS_PUBLIC_API(JSString *)
+JS_GetFunctionId(JSFunction *fun)
+{
+    return fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
+}
+
+JS_PUBLIC_API(uintN)
+JS_GetFunctionFlags(JSFunction *fun)
+{
+    return fun->flags;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ObjectIsFunction(JSContext *cx, JSObject *obj)
+{
+    return OBJ_GET_CLASS(cx, obj) == &js_FunctionClass;
+}
+
+JS_STATIC_DLL_CALLBACK(JSBool)
+js_generic_native_method_dispatcher(JSContext *cx, JSObject *obj,
+                                    uintN argc, jsval *argv, jsval *rval)
+{
+    jsval fsv;
+    JSFunctionSpec *fs;
+    JSObject *tmp;
+
+    if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(argv[-2]), 0, &fsv))
+        return JS_FALSE;
+    fs = (JSFunctionSpec *) JSVAL_TO_PRIVATE(fsv);
+
+    /*
+     * We know that argv[0] is valid because JS_DefineFunctions, which is our
+     * only (indirect) referrer, defined us as requiring at least one argument
+     * (notice how it passes fs->nargs + 1 as the next-to-last argument to
+     * JS_DefineFunction).
+     */
+    if (JSVAL_IS_PRIMITIVE(argv[0])) {
+        /*
+         * Make sure that this is an object or null, as required by the generic
+         * functions.
+         */
+        if (!js_ValueToObject(cx, argv[0], &tmp))
+            return JS_FALSE;
+        argv[0] = OBJECT_TO_JSVAL(tmp);
+    }
+
+    /*
+     * Copy all actual (argc) and required but missing (fs->nargs + 1 - argc)
+     * args down over our |this| parameter, argv[-1], which is almost always
+     * the class constructor object, e.g. Array.  Then call the corresponding
+     * prototype native method with our first argument passed as |this|.
+     */
+    memmove(argv - 1, argv, JS_MAX(fs->nargs + 1U, argc) * sizeof(jsval));
+
+    /*
+     * Follow Function.prototype.apply and .call by using the global object as
+     * the 'this' param if no args.
+     */
+    JS_ASSERT(cx->fp->argv == argv);
+    if (!js_ComputeThis(cx, JSVAL_TO_OBJECT(argv[-1]), cx->fp))
+        return JS_FALSE;
+
+    /*
+     * Protect against argc - 1 underflowing below. By calling js_ComputeThis,
+     * we made it as if the static was called with one parameter.
+     */
+    if (argc == 0)
+        argc = 1;
+
+    return fs->call(cx, JSVAL_TO_OBJECT(argv[-1]), argc - 1, argv, rval);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs)
+{
+    uintN flags;
+    JSObject *ctor;
+    JSFunction *fun;
+
+    CHECK_REQUEST(cx);
+    ctor = NULL;
+    for (; fs->name; fs++) {
+        flags = fs->flags;
+
+        /*
+         * Define a generic arity N+1 static method for the arity N prototype
+         * method if flags contains JSFUN_GENERIC_NATIVE.
+         */
+        if (flags & JSFUN_GENERIC_NATIVE) {
+            if (!ctor) {
+                ctor = JS_GetConstructor(cx, obj);
+                if (!ctor)
+                    return JS_FALSE;
+            }
+
+            flags &= ~JSFUN_GENERIC_NATIVE;
+            fun = JS_DefineFunction(cx, ctor, fs->name,
+                                    js_generic_native_method_dispatcher,
+                                    fs->nargs + 1, flags);
+            if (!fun)
+                return JS_FALSE;
+            fun->extra = fs->extra;
+
+            /*
+             * As jsapi.h notes, fs must point to storage that lives as long
+             * as fun->object lives.
+             */
+            if (!JS_SetReservedSlot(cx, fun->object, 0, PRIVATE_TO_JSVAL(fs)))
+                return JS_FALSE;
+        }
+
+        fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs, flags);
+        if (!fun)
+            return JS_FALSE;
+        fun->extra = fs->extra;
+    }
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSFunction *)
+JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call,
+                  uintN nargs, uintN attrs)
+{
+    JSAtom *atom;
+
+    CHECK_REQUEST(cx);
+    atom = js_Atomize(cx, name, strlen(name), 0);
+    if (!atom)
+        return NULL;
+    return js_DefineFunction(cx, obj, atom, call, nargs, attrs);
+}
+
+JS_PUBLIC_API(JSFunction *)
+JS_DefineUCFunction(JSContext *cx, JSObject *obj,
+                    const jschar *name, size_t namelen, JSNative call,
+                    uintN nargs, uintN attrs)
+{
+    JSAtom *atom;
+
+    atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen), 0);
+    if (!atom)
+        return NULL;
+    return js_DefineFunction(cx, obj, atom, call, nargs, attrs);
+}
+
+static JSScript *
+CompileTokenStream(JSContext *cx, JSObject *obj, JSTokenStream *ts,
+                   void *tempMark, JSBool *eofp)
+{
+    JSBool eof;
+    JSArenaPool codePool, notePool;
+    JSCodeGenerator cg;
+    JSScript *script;
+
+    CHECK_REQUEST(cx);
+    eof = JS_FALSE;
+    JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode));
+    JS_InitArenaPool(&notePool, "note", 1024, sizeof(jssrcnote));
+    if (!js_InitCodeGenerator(cx, &cg, &codePool, &notePool,
+                              ts->filename, ts->lineno,
+                              ts->principals)) {
+        script = NULL;
+    } else if (!js_CompileTokenStream(cx, obj, ts, &cg)) {
+        script = NULL;
+        eof = (ts->flags & TSF_EOF) != 0;
+    } else {
+        script = js_NewScriptFromCG(cx, &cg, NULL);
+    }
+    if (eofp)
+        *eofp = eof;
+    if (!js_CloseTokenStream(cx, ts)) {
+        if (script)
+            js_DestroyScript(cx, script);
+        script = NULL;
+    }
+    cg.tempMark = tempMark;
+    js_FinishCodeGenerator(cx, &cg);
+    JS_FinishArenaPool(&codePool);
+    JS_FinishArenaPool(&notePool);
+    return script;
+}
+
+JS_PUBLIC_API(JSScript *)
+JS_CompileScript(JSContext *cx, JSObject *obj,
+                 const char *bytes, size_t length,
+                 const char *filename, uintN lineno)
+{
+    jschar *chars;
+    JSScript *script;
+
+    CHECK_REQUEST(cx);
+    chars = js_InflateString(cx, bytes, &length);
+    if (!chars)
+        return NULL;
+    script = JS_CompileUCScript(cx, obj, chars, length, filename, lineno);
+    JS_free(cx, chars);
+    return script;
+}
+
+JS_PUBLIC_API(JSScript *)
+JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
+                              JSPrincipals *principals,
+                              const char *bytes, size_t length,
+                              const char *filename, uintN lineno)
+{
+    jschar *chars;
+    JSScript *script;
+
+    CHECK_REQUEST(cx);
+    chars = js_InflateString(cx, bytes, &length);
+    if (!chars)
+        return NULL;
+    script = JS_CompileUCScriptForPrincipals(cx, obj, principals,
+                                             chars, length, filename, lineno);
+    JS_free(cx, chars);
+    return script;
+}
+
+JS_PUBLIC_API(JSScript *)
+JS_CompileUCScript(JSContext *cx, JSObject *obj,
+                   const jschar *chars, size_t length,
+                   const char *filename, uintN lineno)
+{
+    CHECK_REQUEST(cx);
+    return JS_CompileUCScriptForPrincipals(cx, obj, NULL, chars, length,
+                                           filename, lineno);
+}
+
+#if JS_HAS_EXCEPTIONS
+# define LAST_FRAME_EXCEPTION_CHECK(cx,result)                                \
+    JS_BEGIN_MACRO                                                            \
+        if (!(result))                                                        \
+            js_ReportUncaughtException(cx);                                   \
+    JS_END_MACRO
+#else
+# define LAST_FRAME_EXCEPTION_CHECK(cx,result)  /* nothing */
+#endif
+
+#define LAST_FRAME_CHECKS(cx,result)                                          \
+    JS_BEGIN_MACRO                                                            \
+        if (!(cx)->fp) {                                                      \
+            (cx)->lastInternalResult = JSVAL_NULL;                            \
+            LAST_FRAME_EXCEPTION_CHECK(cx, result);                           \
+        }                                                                     \
+    JS_END_MACRO
+
+JS_PUBLIC_API(JSScript *)
+JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
+                                JSPrincipals *principals,
+                                const jschar *chars, size_t length,
+                                const char *filename, uintN lineno)
+{
+    void *mark;
+    JSTokenStream *ts;
+    JSScript *script;
+
+    CHECK_REQUEST(cx);
+    mark = JS_ARENA_MARK(&cx->tempPool);
+    ts = js_NewTokenStream(cx, chars, length, filename, lineno, principals);
+    if (!ts)
+        return NULL;
+    script = CompileTokenStream(cx, obj, ts, mark, NULL);
+    LAST_FRAME_CHECKS(cx, script);
+    return script;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj,
+                          const char *bytes, size_t length)
+{
+    jschar *chars;
+    JSBool result;
+    JSExceptionState *exnState;
+    void *tempMark;
+    JSTokenStream *ts;
+    JSErrorReporter older;
+
+    CHECK_REQUEST(cx);
+    chars = js_InflateString(cx, bytes, &length);
+    if (!chars)
+        return JS_TRUE;
+
+    /*
+     * Return true on any out-of-memory error, so our caller doesn't try to
+     * collect more buffered source.
+     */
+    result = JS_TRUE;
+    exnState = JS_SaveExceptionState(cx);
+    tempMark = JS_ARENA_MARK(&cx->tempPool);
+    ts = js_NewTokenStream(cx, chars, length, NULL, 0, NULL);
+    if (ts) {
+        older = JS_SetErrorReporter(cx, NULL);
+        if (!js_ParseTokenStream(cx, obj, ts) &&
+            (ts->flags & TSF_UNEXPECTED_EOF)) {
+            /*
+             * We ran into an error.  If it was because we ran out of source,
+             * we return false, so our caller will know to try to collect more
+             * buffered source.
+             */
+            result = JS_FALSE;
+        }
+
+        JS_SetErrorReporter(cx, older);
+        js_CloseTokenStream(cx, ts);
+        JS_ARENA_RELEASE(&cx->tempPool, tempMark);
+    }
+
+    JS_free(cx, chars);
+    JS_RestoreExceptionState(cx, exnState);
+    return result;
+}
+
+JS_PUBLIC_API(JSScript *)
+JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename)
+{
+    void *mark;
+    JSTokenStream *ts;
+    JSScript *script;
+
+    CHECK_REQUEST(cx);
+    mark = JS_ARENA_MARK(&cx->tempPool);
+    ts = js_NewFileTokenStream(cx, filename, stdin);
+    if (!ts)
+        return NULL;
+    script = CompileTokenStream(cx, obj, ts, mark, NULL);
+    LAST_FRAME_CHECKS(cx, script);
+    return script;
+}
+
+JS_PUBLIC_API(JSScript *)
+JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename,
+                     FILE *file)
+{
+    return JS_CompileFileHandleForPrincipals(cx, obj, filename, file, NULL);
+}
+
+JS_PUBLIC_API(JSScript *)
+JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj,
+                                  const char *filename, FILE *file,
+                                  JSPrincipals *principals)
+{
+    void *mark;
+    JSTokenStream *ts;
+    JSScript *script;
+
+    CHECK_REQUEST(cx);
+    mark = JS_ARENA_MARK(&cx->tempPool);
+    ts = js_NewFileTokenStream(cx, NULL, file);
+    if (!ts)
+        return NULL;
+    ts->filename = filename;
+    /* XXXshaver js_NewFileTokenStream should do this, because it drops */
+    if (principals) {
+        ts->principals = principals;
+        JSPRINCIPALS_HOLD(cx, ts->principals);
+    }
+    script = CompileTokenStream(cx, obj, ts, mark, NULL);
+    LAST_FRAME_CHECKS(cx, script);
+    return script;
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_NewScriptObject(JSContext *cx, JSScript *script)
+{
+    JSObject *obj;
+
+    obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
+    if (!obj)
+        return NULL;
+
+    if (script) {
+        if (!JS_SetPrivate(cx, obj, script))
+            return NULL;
+        script->object = obj;
+    }
+    return obj;
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_GetScriptObject(JSScript *script)
+{
+    return script->object;
+}
+
+JS_PUBLIC_API(void)
+JS_DestroyScript(JSContext *cx, JSScript *script)
+{
+    CHECK_REQUEST(cx);
+    js_DestroyScript(cx, script);
+}
+
+JS_PUBLIC_API(JSFunction *)
+JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name,
+                   uintN nargs, const char **argnames,
+                   const char *bytes, size_t length,
+                   const char *filename, uintN lineno)
+{
+    jschar *chars;
+    JSFunction *fun;
+
+    CHECK_REQUEST(cx);
+    chars = js_InflateString(cx, bytes, &length);
+    if (!chars)
+        return NULL;
+    fun = JS_CompileUCFunction(cx, obj, name, nargs, argnames, chars, length,
+                               filename, lineno);
+    JS_free(cx, chars);
+    return fun;
+}
+
+JS_PUBLIC_API(JSFunction *)
+JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj,
+                                JSPrincipals *principals, const char *name,
+                                uintN nargs, const char **argnames,
+                                const char *bytes, size_t length,
+                                const char *filename, uintN lineno)
+{
+    jschar *chars;
+    JSFunction *fun;
+
+    CHECK_REQUEST(cx);
+    chars = js_InflateString(cx, bytes, &length);
+    if (!chars)
+        return NULL;
+    fun = JS_CompileUCFunctionForPrincipals(cx, obj, principals, name,
+                                            nargs, argnames, chars, length,
+                                            filename, lineno);
+    JS_free(cx, chars);
+    return fun;
+}
+
+JS_PUBLIC_API(JSFunction *)
+JS_CompileUCFunction(JSContext *cx, JSObject *obj, const char *name,
+                     uintN nargs, const char **argnames,
+                     const jschar *chars, size_t length,
+                     const char *filename, uintN lineno)
+{
+    CHECK_REQUEST(cx);
+    return JS_CompileUCFunctionForPrincipals(cx, obj, NULL, name,
+                                             nargs, argnames,
+                                             chars, length,
+                                             filename, lineno);
+}
+
+JS_PUBLIC_API(JSFunction *)
+JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
+                                  JSPrincipals *principals, const char *name,
+                                  uintN nargs, const char **argnames,
+                                  const jschar *chars, size_t length,
+                                  const char *filename, uintN lineno)
+{
+    void *mark;
+    JSTokenStream *ts;
+    JSFunction *fun;
+    JSAtom *funAtom, *argAtom;
+    uintN i;
+
+    CHECK_REQUEST(cx);
+    mark = JS_ARENA_MARK(&cx->tempPool);
+    ts = js_NewTokenStream(cx, chars, length, filename, lineno, principals);
+    if (!ts) {
+        fun = NULL;
+        goto out;
+    }
+    if (!name) {
+        funAtom = NULL;
+    } else {
+        funAtom = js_Atomize(cx, name, strlen(name), 0);
+        if (!funAtom) {
+            fun = NULL;
+            goto out;
+        }
+    }
+    fun = js_NewFunction(cx, NULL, NULL, nargs, 0, obj, funAtom);
+    if (!fun)
+        goto out;
+    if (nargs) {
+        for (i = 0; i < nargs; i++) {
+            argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0);
+            if (!argAtom)
+                break;
+            if (!js_AddHiddenProperty(cx, fun->object, ATOM_TO_JSID(argAtom),
+                                      js_GetArgument, js_SetArgument,
+                                      SPROP_INVALID_SLOT,
+                                      JSPROP_PERMANENT | JSPROP_SHARED,
+                                      SPROP_HAS_SHORTID, i)) {
+                break;
+            }
+        }
+        if (i < nargs) {
+            fun = NULL;
+            goto out;
+        }
+    }
+    if (!js_CompileFunctionBody(cx, ts, fun)) {
+        fun = NULL;
+        goto out;
+    }
+    if (obj && funAtom) {
+        if (!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(funAtom),
+                                 OBJECT_TO_JSVAL(fun->object),
+                                 NULL, NULL, JSPROP_ENUMERATE, NULL)) {
+            return NULL;
+        }
+    }
+out:
+    if (ts)
+        js_CloseTokenStream(cx, ts);
+    JS_ARENA_RELEASE(&cx->tempPool, mark);
+    LAST_FRAME_CHECKS(cx, fun);
+    return fun;
+}
+
+JS_PUBLIC_API(JSString *)
+JS_DecompileScript(JSContext *cx, JSScript *script, const char *name,
+                   uintN indent)
+{
+    JSPrinter *jp;
+    JSString *str;
+
+    CHECK_REQUEST(cx);
+    jp = js_NewPrinter(cx, name,
+                       indent & ~JS_DONT_PRETTY_PRINT,
+                       !(indent & JS_DONT_PRETTY_PRINT));
+    if (!jp)
+        return NULL;
+    if (js_DecompileScript(jp, script))
+        str = js_GetPrinterOutput(jp);
+    else
+        str = NULL;
+    js_DestroyPrinter(jp);
+    return str;
+}
+
+JS_PUBLIC_API(JSString *)
+JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent)
+{
+    JSPrinter *jp;
+    JSString *str;
+
+    CHECK_REQUEST(cx);
+    jp = js_NewPrinter(cx, JS_GetFunctionName(fun),
+                       indent & ~JS_DONT_PRETTY_PRINT,
+                       !(indent & JS_DONT_PRETTY_PRINT));
+    if (!jp)
+        return NULL;
+    if (js_DecompileFunction(jp, fun))
+        str = js_GetPrinterOutput(jp);
+    else
+        str = NULL;
+    js_DestroyPrinter(jp);
+    return str;
+}
+
+JS_PUBLIC_API(JSString *)
+JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent)
+{
+    JSPrinter *jp;
+    JSString *str;
+
+    CHECK_REQUEST(cx);
+    jp = js_NewPrinter(cx, JS_GetFunctionName(fun),
+                       indent & ~JS_DONT_PRETTY_PRINT,
+                       !(indent & JS_DONT_PRETTY_PRINT));
+    if (!jp)
+        return NULL;
+    if (js_DecompileFunctionBody(jp, fun))
+        str = js_GetPrinterOutput(jp);
+    else
+        str = NULL;
+    js_DestroyPrinter(jp);
+    return str;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval)
+{
+    JSBool ok;
+
+    CHECK_REQUEST(cx);
+    ok = js_Execute(cx, obj, script, NULL, 0, rval);
+    LAST_FRAME_CHECKS(cx, ok);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ExecuteScriptPart(JSContext *cx, JSObject *obj, JSScript *script,
+                     JSExecPart part, jsval *rval)
+{
+    JSScript tmp;
+    JSRuntime *rt;
+    JSBool ok;
+
+    /* Make a temporary copy of the JSScript structure and farble it a bit. */
+    tmp = *script;
+    if (part == JSEXEC_PROLOG) {
+        tmp.length = PTRDIFF(tmp.main, tmp.code, jsbytecode);
+    } else {
+        tmp.length -= PTRDIFF(tmp.main, tmp.code, jsbytecode);
+        tmp.code = tmp.main;
+    }
+
+    /* Tell the debugger about our temporary copy of the script structure. */
+    rt = cx->runtime;
+    if (rt->newScriptHook) {
+        rt->newScriptHook(cx, tmp.filename, tmp.lineno, &tmp, NULL,
+                          rt->newScriptHookData);
+    }
+
+    /* Execute the farbled struct and tell the debugger to forget about it. */
+    ok = JS_ExecuteScript(cx, obj, &tmp, rval);
+    if (rt->destroyScriptHook)
+        rt->destroyScriptHook(cx, &tmp, rt->destroyScriptHookData);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_EvaluateScript(JSContext *cx, JSObject *obj,
+                  const char *bytes, uintN length,
+                  const char *filename, uintN lineno,
+                  jsval *rval)
+{
+    jschar *chars;
+    JSBool ok;
+
+    CHECK_REQUEST(cx);
+    chars = js_InflateString(cx, bytes, &length);
+    if (!chars)
+        return JS_FALSE;
+    ok = JS_EvaluateUCScript(cx, obj, chars, length, filename, lineno, rval);
+    JS_free(cx, chars);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj,
+                               JSPrincipals *principals,
+                               const char *bytes, uintN length,
+                               const char *filename, uintN lineno,
+                               jsval *rval)
+{
+    jschar *chars;
+    JSBool ok;
+
+    CHECK_REQUEST(cx);
+    chars = js_InflateString(cx, bytes, &length);
+    if (!chars)
+        return JS_FALSE;
+    ok = JS_EvaluateUCScriptForPrincipals(cx, obj, principals, chars, length,
+                                          filename, lineno, rval);
+    JS_free(cx, chars);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_EvaluateUCScript(JSContext *cx, JSObject *obj,
+                    const jschar *chars, uintN length,
+                    const char *filename, uintN lineno,
+                    jsval *rval)
+{
+    CHECK_REQUEST(cx);
+    return JS_EvaluateUCScriptForPrincipals(cx, obj, NULL, chars, length,
+                                            filename, lineno, rval);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_EvaluateUCScriptForPrincipals(JSContext *cx, JSObject *obj,
+                                 JSPrincipals *principals,
+                                 const jschar *chars, uintN length,
+                                 const char *filename, uintN lineno,
+                                 jsval *rval)
+{
+    uint32 options;
+    JSScript *script;
+    JSBool ok;
+
+    CHECK_REQUEST(cx);
+    options = cx->options;
+    cx->options = options | JSOPTION_COMPILE_N_GO;
+    script = JS_CompileUCScriptForPrincipals(cx, obj, principals, chars, length,
+                                             filename, lineno);
+    cx->options = options;
+    if (!script)
+        return JS_FALSE;
+    ok = js_Execute(cx, obj, script, NULL, 0, rval);
+    LAST_FRAME_CHECKS(cx, ok);
+    JS_DestroyScript(cx, script);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc,
+                jsval *argv, jsval *rval)
+{
+    JSBool ok;
+
+    CHECK_REQUEST(cx);
+    ok = js_InternalCall(cx, obj, OBJECT_TO_JSVAL(fun->object), argc, argv,
+                         rval);
+    LAST_FRAME_CHECKS(cx, ok);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc,
+                    jsval *argv, jsval *rval)
+{
+    JSBool ok;
+    jsval fval;
+
+    CHECK_REQUEST(cx);
+#if JS_HAS_XML_SUPPORT
+    if (OBJECT_IS_XML(cx, obj)) {
+        JSXMLObjectOps *ops;
+        JSAtom *atom;
+
+        ops = (JSXMLObjectOps *) obj->map->ops;
+        atom = js_Atomize(cx, name, strlen(name), 0);
+        if (!atom)
+            return JS_FALSE;
+        obj = ops->getMethod(cx, obj, ATOM_TO_JSID(atom), &fval);
+        if (!obj)
+            return JS_FALSE;
+    } else
+#endif
+    if (!JS_GetProperty(cx, obj, name, &fval))
+        return JS_FALSE;
+    ok = js_InternalCall(cx, obj, fval, argc, argv, rval);
+    LAST_FRAME_CHECKS(cx, ok);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc,
+                     jsval *argv, jsval *rval)
+{
+    JSBool ok;
+
+    CHECK_REQUEST(cx);
+    ok = js_InternalCall(cx, obj, fval, argc, argv, rval);
+    LAST_FRAME_CHECKS(cx, ok);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBranchCallback)
+JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb)
+{
+    JSBranchCallback oldcb;
+
+    oldcb = cx->branchCallback;
+    cx->branchCallback = cb;
+    return oldcb;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_IsRunning(JSContext *cx)
+{
+    return cx->fp != NULL;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_IsConstructing(JSContext *cx)
+{
+    return cx->fp && (cx->fp->flags & JSFRAME_CONSTRUCTING);
+}
+
+JS_FRIEND_API(JSBool)
+JS_IsAssigning(JSContext *cx)
+{
+    JSStackFrame *fp;
+    jsbytecode *pc;
+
+    for (fp = cx->fp; fp && !fp->script; fp = fp->down)
+        continue;
+    if (!fp || !(pc = fp->pc))
+        return JS_FALSE;
+    return (js_CodeSpec[*pc].format & JOF_ASSIGNING) != 0;
+}
+
+JS_PUBLIC_API(void)
+JS_SetCallReturnValue2(JSContext *cx, jsval v)
+{
+#if JS_HAS_LVALUE_RETURN
+    cx->rval2 = v;
+    cx->rval2set = JS_TRUE;
+#endif
+}
+
+/************************************************************************/
+
+JS_PUBLIC_API(JSString *)
+JS_NewString(JSContext *cx, char *bytes, size_t length)
+{
+    jschar *chars;
+    JSString *str;
+    size_t charsLength = length;
+
+    CHECK_REQUEST(cx);
+    /* Make a Unicode vector from the 8-bit char codes in bytes. */
+    chars = js_InflateString(cx, bytes, &charsLength);
+    if (!chars)
+        return NULL;
+
+    /* Free chars (but not bytes, which caller frees on error) if we fail. */
+    str = js_NewString(cx, chars, charsLength, 0);
+    if (!str) {
+        JS_free(cx, chars);
+        return NULL;
+    }
+
+    /* Hand off bytes to the deflated string cache, if possible. */
+    if (!js_SetStringBytes(str, bytes, length))
+        JS_free(cx, bytes);
+    return str;
+}
+
+JS_PUBLIC_API(JSString *)
+JS_NewStringCopyN(JSContext *cx, const char *s, size_t n)
+{
+    jschar *js;
+    JSString *str;
+
+    CHECK_REQUEST(cx);
+    js = js_InflateString(cx, s, &n);
+    if (!js)
+        return NULL;
+    str = js_NewString(cx, js, n, 0);
+    if (!str)
+        JS_free(cx, js);
+    return str;
+}
+
+JS_PUBLIC_API(JSString *)
+JS_NewStringCopyZ(JSContext *cx, const char *s)
+{
+    size_t n;
+    jschar *js;
+    JSString *str;
+
+    CHECK_REQUEST(cx);
+    if (!s)
+        return cx->runtime->emptyString;
+    n = strlen(s);
+    js = js_InflateString(cx, s, &n);
+    if (!js)
+        return NULL;
+    str = js_NewString(cx, js, n, 0);
+    if (!str)
+        JS_free(cx, js);
+    return str;
+}
+
+JS_PUBLIC_API(JSString *)
+JS_InternString(JSContext *cx, const char *s)
+{
+    JSAtom *atom;
+
+    CHECK_REQUEST(cx);
+    atom = js_Atomize(cx, s, strlen(s), ATOM_INTERNED);
+    if (!atom)
+        return NULL;
+    return ATOM_TO_STRING(atom);
+}
+
+JS_PUBLIC_API(JSString *)
+JS_NewUCString(JSContext *cx, jschar *chars, size_t length)
+{
+    CHECK_REQUEST(cx);
+    return js_NewString(cx, chars, length, 0);
+}
+
+JS_PUBLIC_API(JSString *)
+JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n)
+{
+    CHECK_REQUEST(cx);
+    return js_NewStringCopyN(cx, s, n, 0);
+}
+
+JS_PUBLIC_API(JSString *)
+JS_NewUCStringCopyZ(JSContext *cx, const jschar *s)
+{
+    CHECK_REQUEST(cx);
+    if (!s)
+        return cx->runtime->emptyString;
+    return js_NewStringCopyZ(cx, s, 0);
+}
+
+JS_PUBLIC_API(JSString *)
+JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length)
+{
+    JSAtom *atom;
+
+    CHECK_REQUEST(cx);
+    atom = js_AtomizeChars(cx, s, length, ATOM_INTERNED);
+    if (!atom)
+        return NULL;
+    return ATOM_TO_STRING(atom);
+}
+
+JS_PUBLIC_API(JSString *)
+JS_InternUCString(JSContext *cx, const jschar *s)
+{
+    return JS_InternUCStringN(cx, s, js_strlen(s));
+}
+
+JS_PUBLIC_API(char *)
+JS_GetStringBytes(JSString *str)
+{
+    char *bytes;
+
+    bytes = js_GetStringBytes(str);
+    return bytes ? bytes : "";
+}
+
+JS_PUBLIC_API(jschar *)
+JS_GetStringChars(JSString *str)
+{
+    /*
+     * API botch (again, shades of JS_GetStringBytes): we have no cx to pass
+     * to js_UndependString (called by js_GetStringChars) for out-of-memory
+     * error reports, so js_UndependString passes NULL and suppresses errors.
+     * If it fails to convert a dependent string into an independent one, our
+     * caller will not be guaranteed a \u0000 terminator as a backstop.  This
+     * may break some clients who already misbehave on embedded NULs.
+     *
+     * The gain of dependent strings, which cure quadratic and cubic growth
+     * rate bugs in string concatenation, is worth this slight loss in API
+     * compatibility.
+     */
+    jschar *chars;
+
+    chars = js_GetStringChars(str);
+    return chars ? chars : JSSTRING_CHARS(str);
+}
+
+JS_PUBLIC_API(size_t)
+JS_GetStringLength(JSString *str)
+{
+    return JSSTRING_LENGTH(str);
+}
+
+JS_PUBLIC_API(intN)
+JS_CompareStrings(JSString *str1, JSString *str2)
+{
+    return js_CompareStrings(str1, str2);
+}
+
+JS_PUBLIC_API(JSString *)
+JS_NewGrowableString(JSContext *cx, jschar *chars, size_t length)
+{
+    CHECK_REQUEST(cx);
+    return js_NewString(cx, chars, length, GCF_MUTABLE);
+}
+
+JS_PUBLIC_API(JSString *)
+JS_NewDependentString(JSContext *cx, JSString *str, size_t start,
+                      size_t length)
+{
+    CHECK_REQUEST(cx);
+    return js_NewDependentString(cx, str, start, length, 0);
+}
+
+JS_PUBLIC_API(JSString *)
+JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
+{
+    CHECK_REQUEST(cx);
+    return js_ConcatStrings(cx, left, right);
+}
+
+JS_PUBLIC_API(const jschar *)
+JS_UndependString(JSContext *cx, JSString *str)
+{
+    CHECK_REQUEST(cx);
+    return js_UndependString(cx, str);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_MakeStringImmutable(JSContext *cx, JSString *str)
+{
+    CHECK_REQUEST(cx);
+    if (!js_UndependString(cx, str))
+        return JS_FALSE;
+
+    *js_GetGCThingFlags(str) &= ~GCF_MUTABLE;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_EncodeCharacters(JSContext *cx, const jschar *src, size_t srclen, char *dst,
+                    size_t *dstlenp)
+{
+    return js_DeflateStringToBuffer(cx, src, srclen, dst, dstlenp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst,
+               size_t *dstlenp)
+{
+    return js_InflateStringToBuffer(cx, src, srclen, dst, dstlenp);
+}
+
+JS_PUBLIC_API(JSBool)
+#ifdef OSSP /* CLEANUP */
+JS_CStringsAreUTF8(void)
+#else
+JS_CStringsAreUTF8()
+#endif
+{
+#ifdef JS_C_STRINGS_ARE_UTF8
+    return JS_TRUE;
+#else
+    return JS_FALSE;
+#endif
+}
+
+/************************************************************************/
+
+JS_PUBLIC_API(void)
+JS_ReportError(JSContext *cx, const char *format, ...)
+{
+    va_list ap;
+
+    va_start(ap, format);
+    js_ReportErrorVA(cx, JSREPORT_ERROR, format, ap);
+    va_end(ap);
+}
+
+JS_PUBLIC_API(void)
+JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback,
+                     void *userRef, const uintN errorNumber, ...)
+{
+    va_list ap;
+
+    va_start(ap, errorNumber);
+    js_ReportErrorNumberVA(cx, JSREPORT_ERROR, errorCallback, userRef,
+                           errorNumber, JS_TRUE, ap);
+    va_end(ap);
+}
+
+JS_PUBLIC_API(void)
+JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback,
+                     void *userRef, const uintN errorNumber, ...)
+{
+    va_list ap;
+
+    va_start(ap, errorNumber);
+    js_ReportErrorNumberVA(cx, JSREPORT_ERROR, errorCallback, userRef,
+                           errorNumber, JS_FALSE, ap);
+    va_end(ap);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ReportWarning(JSContext *cx, const char *format, ...)
+{
+    va_list ap;
+    JSBool ok;
+
+    va_start(ap, format);
+    ok = js_ReportErrorVA(cx, JSREPORT_WARNING, format, ap);
+    va_end(ap);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ReportErrorFlagsAndNumber(JSContext *cx, uintN flags,
+                             JSErrorCallback errorCallback, void *userRef,
+                             const uintN errorNumber, ...)
+{
+    va_list ap;
+    JSBool ok;
+
+    va_start(ap, errorNumber);
+    ok = js_ReportErrorNumberVA(cx, flags, errorCallback, userRef,
+                                errorNumber, JS_TRUE, ap);
+    va_end(ap);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ReportErrorFlagsAndNumberUC(JSContext *cx, uintN flags,
+                               JSErrorCallback errorCallback, void *userRef,
+                               const uintN errorNumber, ...)
+{
+    va_list ap;
+    JSBool ok;
+
+    va_start(ap, errorNumber);
+    ok = js_ReportErrorNumberVA(cx, flags, errorCallback, userRef,
+                                errorNumber, JS_FALSE, ap);
+    va_end(ap);
+    return ok;
+}
+
+JS_PUBLIC_API(void)
+JS_ReportOutOfMemory(JSContext *cx)
+{
+    js_ReportOutOfMemory(cx);
+}
+
+JS_PUBLIC_API(JSErrorReporter)
+JS_SetErrorReporter(JSContext *cx, JSErrorReporter er)
+{
+    JSErrorReporter older;
+
+    older = cx->errorReporter;
+    cx->errorReporter = er;
+    return older;
+}
+
+/************************************************************************/
+
+/*
+ * Regular Expressions.
+ */
+JS_PUBLIC_API(JSObject *)
+JS_NewRegExpObject(JSContext *cx, char *bytes, size_t length, uintN flags)
+{
+#if JS_HAS_REGEXPS
+    jschar *chars;
+    JSObject *obj;
+
+    CHECK_REQUEST(cx);
+    chars = js_InflateString(cx, bytes, &length);
+    if (!chars)
+        return NULL;
+    obj = js_NewRegExpObject(cx, NULL, chars, length, flags);
+    JS_free(cx, chars);
+    return obj;
+#else
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_REG_EXPS);
+    return NULL;
+#endif
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_NewUCRegExpObject(JSContext *cx, jschar *chars, size_t length, uintN flags)
+{
+    CHECK_REQUEST(cx);
+#if JS_HAS_REGEXPS
+    return js_NewRegExpObject(cx, NULL, chars, length, flags);
+#else
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_REG_EXPS);
+    return NULL;
+#endif
+}
+
+JS_PUBLIC_API(void)
+JS_SetRegExpInput(JSContext *cx, JSString *input, JSBool multiline)
+{
+    JSRegExpStatics *res;
+
+    CHECK_REQUEST(cx);
+    /* No locking required, cx is thread-private and input must be live. */
+    res = &cx->regExpStatics;
+    res->input = input;
+    res->multiline = multiline;
+    cx->runtime->gcPoke = JS_TRUE;
+}
+
+JS_PUBLIC_API(void)
+JS_ClearRegExpStatics(JSContext *cx)
+{
+    JSRegExpStatics *res;
+
+    /* No locking required, cx is thread-private and input must be live. */
+    res = &cx->regExpStatics;
+    res->input = NULL;
+    res->multiline = JS_FALSE;
+    res->parenCount = 0;
+    res->lastMatch = res->lastParen = js_EmptySubString;
+    res->leftContext = res->rightContext = js_EmptySubString;
+    cx->runtime->gcPoke = JS_TRUE;
+}
+
+JS_PUBLIC_API(void)
+JS_ClearRegExpRoots(JSContext *cx)
+{
+    JSRegExpStatics *res;
+
+    /* No locking required, cx is thread-private and input must be live. */
+    res = &cx->regExpStatics;
+    res->input = NULL;
+    cx->runtime->gcPoke = JS_TRUE;
+}
+
+/* TODO: compile, execute, get/set other statics... */
+
+/************************************************************************/
+
+JS_PUBLIC_API(void)
+JS_SetLocaleCallbacks(JSContext *cx, JSLocaleCallbacks *callbacks)
+{
+    cx->localeCallbacks = callbacks;
+}
+
+JS_PUBLIC_API(JSLocaleCallbacks *)
+JS_GetLocaleCallbacks(JSContext *cx)
+{
+    return cx->localeCallbacks;
+}
+
+/************************************************************************/
+
+JS_PUBLIC_API(JSBool)
+JS_IsExceptionPending(JSContext *cx)
+{
+#if JS_HAS_EXCEPTIONS
+    return (JSBool) cx->throwing;
+#else
+    return JS_FALSE;
+#endif
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetPendingException(JSContext *cx, jsval *vp)
+{
+#if JS_HAS_EXCEPTIONS
+    CHECK_REQUEST(cx);
+    if (!cx->throwing)
+        return JS_FALSE;
+    *vp = cx->exception;
+    return JS_TRUE;
+#else
+    return JS_FALSE;
+#endif
+}
+
+JS_PUBLIC_API(void)
+JS_SetPendingException(JSContext *cx, jsval v)
+{
+    CHECK_REQUEST(cx);
+#if JS_HAS_EXCEPTIONS
+    cx->throwing = JS_TRUE;
+    cx->exception = v;
+#endif
+}
+
+JS_PUBLIC_API(void)
+JS_ClearPendingException(JSContext *cx)
+{
+#if JS_HAS_EXCEPTIONS
+    cx->throwing = JS_FALSE;
+    cx->exception = JSVAL_VOID;
+#endif
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ReportPendingException(JSContext *cx)
+{
+#if JS_HAS_EXCEPTIONS
+    JSBool save, ok;
+
+    CHECK_REQUEST(cx);
+
+    /*
+     * Set cx->creatingException to suppress the standard error-to-exception
+     * conversion done by all {js,JS}_Report* functions except for OOM.  The
+     * cx->creatingException flag was added to suppress recursive divergence
+     * under js_ErrorToException, but it serves for our purposes here too.
+     */
+    save = cx->creatingException;
+    cx->creatingException = JS_TRUE;
+    ok = js_ReportUncaughtException(cx);
+    cx->creatingException = save;
+    return ok;
+#else
+    return JS_TRUE;
+#endif
+}
+
+#if JS_HAS_EXCEPTIONS
+struct JSExceptionState {
+    JSBool throwing;
+    jsval  exception;
+};
+#endif
+
+JS_PUBLIC_API(JSExceptionState *)
+JS_SaveExceptionState(JSContext *cx)
+{
+#if JS_HAS_EXCEPTIONS
+    JSExceptionState *state;
+
+    CHECK_REQUEST(cx);
+    state = (JSExceptionState *) JS_malloc(cx, sizeof(JSExceptionState));
+    if (state) {
+        state->throwing = JS_GetPendingException(cx, &state->exception);
+        if (state->throwing && JSVAL_IS_GCTHING(state->exception))
+            js_AddRoot(cx, &state->exception, "JSExceptionState.exception");
+    }
+    return state;
+#else
+    return NULL;
+#endif
+}
+
+JS_PUBLIC_API(void)
+JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state)
+{
+#if JS_HAS_EXCEPTIONS
+    CHECK_REQUEST(cx);
+    if (state) {
+        if (state->throwing)
+            JS_SetPendingException(cx, state->exception);
+        else
+            JS_ClearPendingException(cx);
+        JS_DropExceptionState(cx, state);
+    }
+#endif
+}
+
+JS_PUBLIC_API(void)
+JS_DropExceptionState(JSContext *cx, JSExceptionState *state)
+{
+#if JS_HAS_EXCEPTIONS
+    CHECK_REQUEST(cx);
+    if (state) {
+        if (state->throwing && JSVAL_IS_GCTHING(state->exception))
+            JS_RemoveRoot(cx, &state->exception);
+        JS_free(cx, state);
+    }
+#endif
+}
+
+JS_PUBLIC_API(JSErrorReport *)
+JS_ErrorFromException(JSContext *cx, jsval v)
+{
+#if JS_HAS_ERROR_EXCEPTIONS
+    CHECK_REQUEST(cx);
+    return js_ErrorFromException(cx, v);
+#else
+    return NULL;
+#endif
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ThrowReportedError(JSContext *cx, const char *message,
+                      JSErrorReport *reportp)
+{
+    return js_ErrorToException(cx, message, reportp);
+}
+
+#ifdef JS_THREADSAFE
+JS_PUBLIC_API(jsword)
+JS_GetContextThread(JSContext *cx)
+{
+    return cx->thread;
+}
+
+JS_PUBLIC_API(jsword)
+JS_SetContextThread(JSContext *cx)
+{
+    jsword old = cx->thread;
+    cx->thread = js_CurrentThreadId();
+    return old;
+}
+
+JS_PUBLIC_API(jsword)
+JS_ClearContextThread(JSContext *cx)
+{
+    jsword old = cx->thread;
+    cx->thread = 0;
+    return old;
+}
+#endif
+
+/************************************************************************/
+
+#if defined(XP_WIN)
+#include <windows.h>
+/*
+ * Initialization routine for the JS DLL...
+ */
+
+/*
+ * Global Instance handle...
+ * In Win32 this is the module handle of the DLL.
+ *
+ * In Win16 this is the instance handle of the application
+ * which loaded the DLL.
+ */
+
+#ifdef _WIN32
+BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)
+{
+    return TRUE;
+}
+
+#else  /* !_WIN32 */
+
+int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg,
+                      WORD cbHeapSize, LPSTR lpszCmdLine )
+{
+    return TRUE;
+}
+
+BOOL CALLBACK __loadds WEP(BOOL fSystemExit)
+{
+    return TRUE;
+}
+
+#endif /* !_WIN32 */
+#endif /* XP_WIN */

Added: freeswitch/trunk/libs/js/src/jsapi.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsapi.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2030 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsapi_h___
+#define jsapi_h___
+
+#ifndef OSSP
+#define OSSP
+#endif
+#if !defined(XP_UNIX) && !defined(XP_WIN)
+#define XP_UNIX
+#endif
+
+/*
+ * JavaScript API.
+ */
+#include <stddef.h>
+#include <stdio.h>
+#include "jspubtd.h"
+
+JS_BEGIN_EXTERN_C
+
+/*
+ * Type tags stored in the low bits of a jsval.
+ */
+#define JSVAL_OBJECT            0x0     /* untagged reference to object */
+#define JSVAL_INT               0x1     /* tagged 31-bit integer value */
+#define JSVAL_DOUBLE            0x2     /* tagged reference to double */
+#define JSVAL_STRING            0x4     /* tagged reference to string */
+#define JSVAL_BOOLEAN           0x6     /* tagged boolean value */
+
+/* Type tag bitfield length and derived macros. */
+#define JSVAL_TAGBITS           3
+#define JSVAL_TAGMASK           JS_BITMASK(JSVAL_TAGBITS)
+#define JSVAL_TAG(v)            ((v) & JSVAL_TAGMASK)
+#define JSVAL_SETTAG(v,t)       ((v) | (t))
+#define JSVAL_CLRTAG(v)         ((v) & ~(jsval)JSVAL_TAGMASK)
+#define JSVAL_ALIGN             JS_BIT(JSVAL_TAGBITS)
+
+/* Predicates for type testing. */
+#define JSVAL_IS_OBJECT(v)      (JSVAL_TAG(v) == JSVAL_OBJECT)
+#define JSVAL_IS_NUMBER(v)      (JSVAL_IS_INT(v) || JSVAL_IS_DOUBLE(v))
+#define JSVAL_IS_INT(v)         (((v) & JSVAL_INT) && (v) != JSVAL_VOID)
+#define JSVAL_IS_DOUBLE(v)      (JSVAL_TAG(v) == JSVAL_DOUBLE)
+#define JSVAL_IS_STRING(v)      (JSVAL_TAG(v) == JSVAL_STRING)
+#define JSVAL_IS_BOOLEAN(v)     (JSVAL_TAG(v) == JSVAL_BOOLEAN)
+#define JSVAL_IS_NULL(v)        ((v) == JSVAL_NULL)
+#define JSVAL_IS_VOID(v)        ((v) == JSVAL_VOID)
+#define JSVAL_IS_PRIMITIVE(v)   (!JSVAL_IS_OBJECT(v) || JSVAL_IS_NULL(v))
+
+/* Objects, strings, and doubles are GC'ed. */
+#define JSVAL_IS_GCTHING(v)     (!((v) & JSVAL_INT) && !JSVAL_IS_BOOLEAN(v))
+#define JSVAL_TO_GCTHING(v)     ((void *)JSVAL_CLRTAG(v))
+#define JSVAL_TO_OBJECT(v)      ((JSObject *)JSVAL_TO_GCTHING(v))
+#define JSVAL_TO_DOUBLE(v)      ((jsdouble *)JSVAL_TO_GCTHING(v))
+#define JSVAL_TO_STRING(v)      ((JSString *)JSVAL_TO_GCTHING(v))
+#define OBJECT_TO_JSVAL(obj)    ((jsval)(obj))
+#define DOUBLE_TO_JSVAL(dp)     JSVAL_SETTAG((jsval)(dp), JSVAL_DOUBLE)
+#define STRING_TO_JSVAL(str)    JSVAL_SETTAG((jsval)(str), JSVAL_STRING)
+
+/* Lock and unlock the GC thing held by a jsval. */
+#define JSVAL_LOCK(cx,v)        (JSVAL_IS_GCTHING(v)                          \
+                                 ? JS_LockGCThing(cx, JSVAL_TO_GCTHING(v))    \
+                                 : JS_TRUE)
+#define JSVAL_UNLOCK(cx,v)      (JSVAL_IS_GCTHING(v)                          \
+                                 ? JS_UnlockGCThing(cx, JSVAL_TO_GCTHING(v))  \
+                                 : JS_TRUE)
+
+/* Domain limits for the jsval int type. */
+#define JSVAL_INT_BITS          31
+#define JSVAL_INT_POW2(n)       ((jsval)1 << (n))
+#define JSVAL_INT_MIN           ((jsval)1 - JSVAL_INT_POW2(30))
+#define JSVAL_INT_MAX           (JSVAL_INT_POW2(30) - 1)
+#define INT_FITS_IN_JSVAL(i)    ((jsuint)((i)+JSVAL_INT_MAX) <= 2*JSVAL_INT_MAX)
+#define JSVAL_TO_INT(v)         ((jsint)(v) >> 1)
+#define INT_TO_JSVAL(i)         (((jsval)(i) << 1) | JSVAL_INT)
+
+/* Convert between boolean and jsval. */
+#define JSVAL_TO_BOOLEAN(v)     ((JSBool)((v) >> JSVAL_TAGBITS))
+#define BOOLEAN_TO_JSVAL(b)     JSVAL_SETTAG((jsval)(b) << JSVAL_TAGBITS,     \
+                                             JSVAL_BOOLEAN)
+
+/* A private data pointer (2-byte-aligned) can be stored as an int jsval. */
+#define JSVAL_TO_PRIVATE(v)     ((void *)((v) & ~JSVAL_INT))
+#define PRIVATE_TO_JSVAL(p)     ((jsval)(p) | JSVAL_INT)
+
+/* Property attributes, set in JSPropertySpec and passed to API functions. */
+#define JSPROP_ENUMERATE        0x01    /* property is visible to for/in loop */
+#define JSPROP_READONLY         0x02    /* not settable: assignment is no-op */
+#define JSPROP_PERMANENT        0x04    /* property cannot be deleted */
+#define JSPROP_EXPORTED         0x08    /* property is exported from object */
+#define JSPROP_GETTER           0x10    /* property holds getter function */
+#define JSPROP_SETTER           0x20    /* property holds setter function */
+#define JSPROP_SHARED           0x40    /* don't allocate a value slot for this
+                                           property; don't copy the property on
+                                           set of the same-named property in an
+                                           object that delegates to a prototype
+                                           containing this property */
+#define JSPROP_INDEX            0x80    /* name is actually (jsint) index */
+
+/* Function flags, set in JSFunctionSpec and passed to JS_NewFunction etc. */
+#define JSFUN_LAMBDA            0x08    /* expressed, not declared, function */
+#define JSFUN_GETTER            JSPROP_GETTER
+#define JSFUN_SETTER            JSPROP_SETTER
+#define JSFUN_BOUND_METHOD      0x40    /* bind this to fun->object's parent */
+#define JSFUN_HEAVYWEIGHT       0x80    /* activation requires a Call object */
+#define JSFUN_FLAGS_MASK        0xf8    /* overlay JSFUN_* attributes */
+
+/*
+ * Re-use JSFUN_LAMBDA, which applies only to scripted functions, for use in
+ * JSFunctionSpec arrays that specify generic native prototype methods, i.e.,
+ * methods of a class prototype that are exposed as static methods taking an
+ * extra leading argument: the generic |this| parameter.
+ *
+ * If you set this flag in a JSFunctionSpec struct's flags initializer, then
+ * that struct must live at least as long as the native static method object
+ * created due to this flag by JS_DefineFunctions or JS_InitClass.  Typically
+ * JSFunctionSpec structs are allocated in static arrays.
+ */
+#define JSFUN_GENERIC_NATIVE    JSFUN_LAMBDA
+
+/*
+ * Well-known JS values.  The extern'd variables are initialized when the
+ * first JSContext is created by JS_NewContext (see below).
+ */
+#define JSVAL_VOID              INT_TO_JSVAL(0 - JSVAL_INT_POW2(30))
+#define JSVAL_NULL              OBJECT_TO_JSVAL(0)
+#define JSVAL_ZERO              INT_TO_JSVAL(0)
+#define JSVAL_ONE               INT_TO_JSVAL(1)
+#define JSVAL_FALSE             BOOLEAN_TO_JSVAL(JS_FALSE)
+#define JSVAL_TRUE              BOOLEAN_TO_JSVAL(JS_TRUE)
+
+/*
+ * Microseconds since the epoch, midnight, January 1, 1970 UTC.  See the
+ * comment in jstypes.h regarding safe int64 usage.
+ */
+extern JS_PUBLIC_API(int64)
+#ifdef OSSP /* CLEANUP */
+JS_Now(void);
+#else
+JS_Now();
+#endif
+
+/* Don't want to export data, so provide accessors for non-inline jsvals. */
+extern JS_PUBLIC_API(jsval)
+JS_GetNaNValue(JSContext *cx);
+
+extern JS_PUBLIC_API(jsval)
+JS_GetNegativeInfinityValue(JSContext *cx);
+
+extern JS_PUBLIC_API(jsval)
+JS_GetPositiveInfinityValue(JSContext *cx);
+
+extern JS_PUBLIC_API(jsval)
+JS_GetEmptyStringValue(JSContext *cx);
+
+/*
+ * Format is a string of the following characters (spaces are insignificant),
+ * specifying the tabulated type conversions:
+ *
+ *   b      JSBool          Boolean
+ *   c      uint16/jschar   ECMA uint16, Unicode char
+ *   i      int32           ECMA int32
+ *   u      uint32          ECMA uint32
+ *   j      int32           Rounded int32 (coordinate)
+ *   d      jsdouble        IEEE double
+ *   I      jsdouble        Integral IEEE double
+ *   s      char *          C string
+ *   S      JSString *      Unicode string, accessed by a JSString pointer
+ *   W      jschar *        Unicode character vector, 0-terminated (W for wide)
+ *   o      JSObject *      Object reference
+ *   f      JSFunction *    Function private
+ *   v      jsval           Argument value (no conversion)
+ *   *      N/A             Skip this argument (no vararg)
+ *   /      N/A             End of required arguments
+ *
+ * The variable argument list after format must consist of &b, &c, &s, e.g.,
+ * where those variables have the types given above.  For the pointer types
+ * char *, JSString *, and JSObject *, the pointed-at memory returned belongs
+ * to the JS runtime, not to the calling native code.  The runtime promises
+ * to keep this memory valid so long as argv refers to allocated stack space
+ * (so long as the native function is active).
+ *
+ * Fewer arguments than format specifies may be passed only if there is a /
+ * in format after the last required argument specifier and argc is at least
+ * the number of required arguments.  More arguments than format specifies
+ * may be passed without error; it is up to the caller to deal with trailing
+ * unconverted arguments.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
+                    ...);
+
+#ifdef va_start
+extern JS_PUBLIC_API(JSBool)
+JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv,
+                      const char *format, va_list ap);
+#endif
+
+/*
+ * Inverse of JS_ConvertArguments: scan format and convert trailing arguments
+ * into jsvals, GC-rooted if necessary by the JS stack.  Return null on error,
+ * and a pointer to the new argument vector on success.  Also return a stack
+ * mark on success via *markp, in which case the caller must eventually clean
+ * up by calling JS_PopArguments.
+ *
+ * Note that the number of actual arguments supplied is specified exclusively
+ * by format, so there is no argc parameter.
+ */
+extern JS_PUBLIC_API(jsval *)
+JS_PushArguments(JSContext *cx, void **markp, const char *format, ...);
+
+#ifdef va_start
+extern JS_PUBLIC_API(jsval *)
+JS_PushArgumentsVA(JSContext *cx, void **markp, const char *format, va_list ap);
+#endif
+
+extern JS_PUBLIC_API(void)
+JS_PopArguments(JSContext *cx, void *mark);
+
+#ifdef JS_ARGUMENT_FORMATTER_DEFINED
+
+/*
+ * Add and remove a format string handler for JS_{Convert,Push}Arguments{,VA}.
+ * The handler function has this signature (see jspubtd.h):
+ *
+ *   JSBool MyArgumentFormatter(JSContext *cx, const char *format,
+ *                              JSBool fromJS, jsval **vpp, va_list *app);
+ *
+ * It should return true on success, and return false after reporting an error
+ * or detecting an already-reported error.
+ *
+ * For a given format string, for example "AA", the formatter is called from
+ * JS_ConvertArgumentsVA like so:
+ *
+ *   formatter(cx, "AA...", JS_TRUE, &sp, &ap);
+ *
+ * sp points into the arguments array on the JS stack, while ap points into
+ * the stdarg.h va_list on the C stack.  The JS_TRUE passed for fromJS tells
+ * the formatter to convert zero or more jsvals at sp to zero or more C values
+ * accessed via pointers-to-values at ap, updating both sp (via *vpp) and ap
+ * (via *app) to point past the converted arguments and their result pointers
+ * on the C stack.
+ *
+ * When called from JS_PushArgumentsVA, the formatter is invoked thus:
+ *
+ *   formatter(cx, "AA...", JS_FALSE, &sp, &ap);
+ *
+ * where JS_FALSE for fromJS means to wrap the C values at ap according to the
+ * format specifier and store them at sp, updating ap and sp appropriately.
+ *
+ * The "..." after "AA" is the rest of the format string that was passed into
+ * JS_{Convert,Push}Arguments{,VA}.  The actual format trailing substring used
+ * in each Convert or PushArguments call is passed to the formatter, so that
+ * one such function may implement several formats, in order to share code.
+ *
+ * Remove just forgets about any handler associated with format.  Add does not
+ * copy format, it points at the string storage allocated by the caller, which
+ * is typically a string constant.  If format is in dynamic storage, it is up
+ * to the caller to keep the string alive until Remove is called.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_AddArgumentFormatter(JSContext *cx, const char *format,
+                        JSArgumentFormatter formatter);
+
+extern JS_PUBLIC_API(void)
+JS_RemoveArgumentFormatter(JSContext *cx, const char *format);
+
+#endif /* JS_ARGUMENT_FORMATTER_DEFINED */
+
+extern JS_PUBLIC_API(JSBool)
+JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ValueToObject(JSContext *cx, jsval v, JSObject **objp);
+
+extern JS_PUBLIC_API(JSFunction *)
+JS_ValueToFunction(JSContext *cx, jsval v);
+
+extern JS_PUBLIC_API(JSFunction *)
+JS_ValueToConstructor(JSContext *cx, jsval v);
+
+extern JS_PUBLIC_API(JSString *)
+JS_ValueToString(JSContext *cx, jsval v);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp);
+
+/*
+ * Convert a value to a number, then to an int32, according to the ECMA rules
+ * for ToInt32.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip);
+
+/*
+ * Convert a value to a number, then to a uint32, according to the ECMA rules
+ * for ToUint32.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip);
+
+/*
+ * Convert a value to a number, then to an int32 if it fits by rounding to
+ * nearest; but failing with an error report if the double is out of range
+ * or unordered.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip);
+
+/*
+ * ECMA ToUint16, for mapping a jsval to a Unicode point.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp);
+
+extern JS_PUBLIC_API(JSType)
+JS_TypeOfValue(JSContext *cx, jsval v);
+
+extern JS_PUBLIC_API(const char *)
+JS_GetTypeName(JSContext *cx, JSType type);
+
+/************************************************************************/
+
+/*
+ * Initialization, locking, contexts, and memory allocation.
+ */
+#define JS_NewRuntime       JS_Init
+#define JS_DestroyRuntime   JS_Finish
+#define JS_LockRuntime      JS_Lock
+#define JS_UnlockRuntime    JS_Unlock
+
+extern JS_PUBLIC_API(JSRuntime *)
+JS_NewRuntime(uint32 maxbytes);
+
+extern JS_PUBLIC_API(void)
+JS_DestroyRuntime(JSRuntime *rt);
+
+extern JS_PUBLIC_API(void)
+JS_ShutDown(void);
+
+JS_PUBLIC_API(void *)
+JS_GetRuntimePrivate(JSRuntime *rt);
+
+JS_PUBLIC_API(void)
+JS_SetRuntimePrivate(JSRuntime *rt, void *data);
+
+#ifdef JS_THREADSAFE
+
+extern JS_PUBLIC_API(void)
+JS_BeginRequest(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+JS_EndRequest(JSContext *cx);
+
+/* Yield to pending GC operations, regardless of request depth */
+extern JS_PUBLIC_API(void)
+JS_YieldRequest(JSContext *cx);
+
+extern JS_PUBLIC_API(jsrefcount)
+JS_SuspendRequest(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth);
+
+#endif /* JS_THREADSAFE */
+
+extern JS_PUBLIC_API(void)
+JS_Lock(JSRuntime *rt);
+
+extern JS_PUBLIC_API(void)
+JS_Unlock(JSRuntime *rt);
+
+extern JS_PUBLIC_API(JSContext *)
+JS_NewContext(JSRuntime *rt, size_t stackChunkSize);
+
+extern JS_PUBLIC_API(void)
+JS_DestroyContext(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+JS_DestroyContextNoGC(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+JS_DestroyContextMaybeGC(JSContext *cx);
+
+extern JS_PUBLIC_API(void *)
+JS_GetContextPrivate(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+JS_SetContextPrivate(JSContext *cx, void *data);
+
+extern JS_PUBLIC_API(JSRuntime *)
+JS_GetRuntime(JSContext *cx);
+
+extern JS_PUBLIC_API(JSContext *)
+JS_ContextIterator(JSRuntime *rt, JSContext **iterp);
+
+extern JS_PUBLIC_API(JSVersion)
+JS_GetVersion(JSContext *cx);
+
+extern JS_PUBLIC_API(JSVersion)
+JS_SetVersion(JSContext *cx, JSVersion version);
+
+extern JS_PUBLIC_API(const char *)
+JS_VersionToString(JSVersion version);
+
+extern JS_PUBLIC_API(JSVersion)
+JS_StringToVersion(const char *string);
+
+/*
+ * JS options are orthogonal to version, and may be freely composed with one
+ * another as well as with version.
+ *
+ * JSOPTION_VAROBJFIX is recommended -- see the comments associated with the
+ * prototypes for JS_ExecuteScript, JS_EvaluateScript, etc.
+ */
+#define JSOPTION_STRICT         JS_BIT(0)       /* warn on dubious practice */
+#define JSOPTION_WERROR         JS_BIT(1)       /* convert warning to error */
+#define JSOPTION_VAROBJFIX      JS_BIT(2)       /* make JS_EvaluateScript use
+                                                   the last object on its 'obj'
+                                                   param's scope chain as the
+                                                   ECMA 'variables object' */
+#define JSOPTION_PRIVATE_IS_NSISUPPORTS \
+                                JS_BIT(3)       /* context private data points
+                                                   to an nsISupports subclass */
+#define JSOPTION_COMPILE_N_GO   JS_BIT(4)       /* caller of JS_Compile*Script
+                                                   promises to execute compiled
+                                                   script once only; enables
+                                                   compile-time scope chain
+                                                   resolution of consts. */
+#define JSOPTION_ATLINE         JS_BIT(5)       /* //@line number ["filename"]
+                                                   option supported for the
+                                                   XUL preprocessor and kindred
+                                                   beasts. */
+#define JSOPTION_XML            JS_BIT(6)       /* EMCAScript for XML support:
+                                                   parse <!-- --> as a token,
+                                                   not backward compatible with
+                                                   the comment-hiding hack used
+                                                   in HTML script tags. */
+#define JSOPTION_NATIVE_BRANCH_CALLBACK \
+                                JS_BIT(7)       /* the branch callback set by
+                                                   JS_SetBranchCallback may be
+                                                   called with a null script
+                                                   parameter, by native code
+                                                   that loops intensively */
+
+extern JS_PUBLIC_API(uint32)
+JS_GetOptions(JSContext *cx);
+
+extern JS_PUBLIC_API(uint32)
+JS_SetOptions(JSContext *cx, uint32 options);
+
+extern JS_PUBLIC_API(uint32)
+JS_ToggleOptions(JSContext *cx, uint32 options);
+
+extern JS_PUBLIC_API(const char *)
+JS_GetImplementationVersion(void);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_GetGlobalObject(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+JS_SetGlobalObject(JSContext *cx, JSObject *obj);
+
+/*
+ * Initialize standard JS class constructors, prototypes, and any top-level
+ * functions and constants associated with the standard classes (e.g. isNaN
+ * for Number).
+ *
+ * NB: This sets cx's global object to obj if it was null.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_InitStandardClasses(JSContext *cx, JSObject *obj);
+
+/*
+ * Resolve id, which must contain either a string or an int, to a standard
+ * class name in obj if possible, defining the class's constructor and/or
+ * prototype and storing true in *resolved.  If id does not name a standard
+ * class or a top-level property induced by initializing a standard class,
+ * store false in *resolved and just return true.  Return false on error,
+ * as usual for JSBool result-typed API entry points.
+ *
+ * This API can be called directly from a global object class's resolve op,
+ * to define standard classes lazily.  The class's enumerate op should call
+ * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in
+ * loops any classes not yet resolved lazily.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id,
+                        JSBool *resolved);
+
+extern JS_PUBLIC_API(JSBool)
+JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj);
+
+/*
+ * Enumerate any already-resolved standard class ids into ida, or into a new
+ * JSIdArray if ida is null.  Return the augmented array on success, null on
+ * failure with ida (if it was non-null on entry) destroyed.
+ */
+extern JS_PUBLIC_API(JSIdArray *)
+JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj,
+                                    JSIdArray *ida);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_GetScopeChain(JSContext *cx);
+
+extern JS_PUBLIC_API(void *)
+JS_malloc(JSContext *cx, size_t nbytes);
+
+extern JS_PUBLIC_API(void *)
+JS_realloc(JSContext *cx, void *p, size_t nbytes);
+
+extern JS_PUBLIC_API(void)
+JS_free(JSContext *cx, void *p);
+
+extern JS_PUBLIC_API(char *)
+JS_strdup(JSContext *cx, const char *s);
+
+extern JS_PUBLIC_API(jsdouble *)
+JS_NewDouble(JSContext *cx, jsdouble d);
+
+extern JS_PUBLIC_API(JSBool)
+JS_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval);
+
+extern JS_PUBLIC_API(JSBool)
+JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval);
+
+/*
+ * A JS GC root is a pointer to a JSObject *, JSString *, or jsdouble * that
+ * itself points into the GC heap (more recently, we support this extension:
+ * a root may be a pointer to a jsval v for which JSVAL_IS_GCTHING(v) is true).
+ *
+ * Therefore, you never pass JSObject *obj to JS_AddRoot(cx, obj).  You always
+ * call JS_AddRoot(cx, &obj), passing obj by reference.  And later, before obj
+ * or the structure it is embedded within goes out of scope or is freed, you
+ * must call JS_RemoveRoot(cx, &obj).
+ *
+ * Also, use JS_AddNamedRoot(cx, &structPtr->memberObj, "structPtr->memberObj")
+ * in preference to JS_AddRoot(cx, &structPtr->memberObj), in order to identify
+ * roots by their source callsites.  This way, you can find the callsite while
+ * debugging if you should fail to do JS_RemoveRoot(cx, &structPtr->memberObj)
+ * before freeing structPtr's memory.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_AddRoot(JSContext *cx, void *rp);
+
+#ifdef NAME_ALL_GC_ROOTS
+#define JS_DEFINE_TO_TOKEN(def) #def
+#define JS_DEFINE_TO_STRING(def) JS_DEFINE_TO_TOKEN(def)
+#define JS_AddRoot(cx,rp) JS_AddNamedRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
+#endif
+
+extern JS_PUBLIC_API(JSBool)
+JS_AddNamedRoot(JSContext *cx, void *rp, const char *name);
+
+extern JS_PUBLIC_API(JSBool)
+JS_AddNamedRootRT(JSRuntime *rt, void *rp, const char *name);
+
+extern JS_PUBLIC_API(JSBool)
+JS_RemoveRoot(JSContext *cx, void *rp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_RemoveRootRT(JSRuntime *rt, void *rp);
+
+/*
+ * The last GC thing of each type (object, string, double, external string
+ * types) created on a given context is kept alive until another thing of the
+ * same type is created, using a newborn root in the context.  These newborn
+ * roots help native code protect newly-created GC-things from GC invocations
+ * activated before those things can be rooted using local or global roots.
+ *
+ * However, the newborn roots can also entrain great gobs of garbage, so the
+ * JS_GC entry point clears them for the context on which GC is being forced.
+ * Embeddings may need to do likewise for all contexts.
+ *
+ * See the scoped local root API immediately below for a better way to manage
+ * newborns in cases where native hooks (functions, getters, setters, etc.)
+ * create many GC-things, potentially without connecting them to predefined
+ * local roots such as *rval or argv[i] in an active native function.  Using
+ * JS_EnterLocalRootScope disables updating of the context's per-gc-thing-type
+ * newborn roots, until control flow unwinds and leaves the outermost nesting
+ * local root scope.
+ */
+extern JS_PUBLIC_API(void)
+JS_ClearNewbornRoots(JSContext *cx);
+
+/*
+ * Scoped local root management allows native functions, getter/setters, etc.
+ * to avoid worrying about the newborn root pigeon-holes, overloading local
+ * roots allocated in argv and *rval, or ending up having to call JS_Add*Root
+ * and JS_RemoveRoot to manage global roots temporarily.
+ *
+ * Instead, calling JS_EnterLocalRootScope and JS_LeaveLocalRootScope around
+ * the body of the native hook causes the engine to allocate a local root for
+ * each newborn created in between the two API calls, using a local root stack
+ * associated with cx.  For example:
+ *
+ *    JSBool
+ *    my_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+ *    {
+ *        JSBool ok;
+ *
+ *        if (!JS_EnterLocalRootScope(cx))
+ *            return JS_FALSE;
+ *        ok = my_GetPropertyBody(cx, obj, id, vp);
+ *        JS_LeaveLocalRootScope(cx);
+ *        return ok;
+ *    }
+ *
+ * NB: JS_LeaveLocalRootScope must be called once for every prior successful
+ * call to JS_EnterLocalRootScope.  If JS_EnterLocalRootScope fails, you must
+ * not make the matching JS_LeaveLocalRootScope call.
+ *
+ * In case a native hook allocates many objects or other GC-things, but the
+ * native protects some of those GC-things by storing them as property values
+ * in an object that is itself protected, the hook can call JS_ForgetLocalRoot
+ * to free the local root automatically pushed for the now-protected GC-thing.
+ *
+ * JS_ForgetLocalRoot works on any GC-thing allocated in the current local
+ * root scope, but it's more time-efficient when called on references to more
+ * recently created GC-things.  Calling it successively on other than the most
+ * recently allocated GC-thing will tend to average the time inefficiency, and
+ * may risk O(n^2) growth rate, but in any event, you shouldn't allocate too
+ * many local roots if you can root as you go (build a tree of objects from
+ * the top down, forgetting each latest-allocated GC-thing immediately upon
+ * linking it to its parent).
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_EnterLocalRootScope(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+JS_LeaveLocalRootScope(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+JS_ForgetLocalRoot(JSContext *cx, void *thing);
+
+#ifdef DEBUG
+extern JS_PUBLIC_API(void)
+JS_DumpNamedRoots(JSRuntime *rt,
+                  void (*dump)(const char *name, void *rp, void *data),
+                  void *data);
+#endif
+
+/*
+ * Call JS_MapGCRoots to map the GC's roots table using map(rp, name, data).
+ * The root is pointed at by rp; if the root is unnamed, name is null; data is
+ * supplied from the third parameter to JS_MapGCRoots.
+ *
+ * The map function should return JS_MAP_GCROOT_REMOVE to cause the currently
+ * enumerated root to be removed.  To stop enumeration, set JS_MAP_GCROOT_STOP
+ * in the return value.  To keep on mapping, return JS_MAP_GCROOT_NEXT.  These
+ * constants are flags; you can OR them together.
+ *
+ * This function acquires and releases rt's GC lock around the mapping of the
+ * roots table, so the map function should run to completion in as few cycles
+ * as possible.  Of course, map cannot call JS_GC, JS_MaybeGC, JS_BeginRequest,
+ * or any JS API entry point that acquires locks, without double-tripping or
+ * deadlocking on the GC lock.
+ *
+ * JS_MapGCRoots returns the count of roots that were successfully mapped.
+ */
+#define JS_MAP_GCROOT_NEXT      0       /* continue mapping entries */
+#define JS_MAP_GCROOT_STOP      1       /* stop mapping entries */
+#define JS_MAP_GCROOT_REMOVE    2       /* remove and free the current entry */
+
+typedef intN
+(* JS_DLL_CALLBACK JSGCRootMapFun)(void *rp, const char *name, void *data);
+
+extern JS_PUBLIC_API(uint32)
+JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data);
+
+extern JS_PUBLIC_API(JSBool)
+JS_LockGCThing(JSContext *cx, void *thing);
+
+extern JS_PUBLIC_API(JSBool)
+JS_LockGCThingRT(JSRuntime *rt, void *thing);
+
+extern JS_PUBLIC_API(JSBool)
+JS_UnlockGCThing(JSContext *cx, void *thing);
+
+extern JS_PUBLIC_API(JSBool)
+JS_UnlockGCThingRT(JSRuntime *rt, void *thing);
+
+/*
+ * For implementors of JSObjectOps.mark, to mark a GC-thing reachable via a
+ * property or other strong ref identified for debugging purposes by name.
+ * The name argument's storage needs to live only as long as the call to
+ * this routine.
+ *
+ * The final arg is used by GC_MARK_DEBUG code to build a ref path through
+ * the GC's live thing graph.  Implementors of JSObjectOps.mark should pass
+ * its final arg through to this function when marking all GC-things that are
+ * directly reachable from the object being marked.
+ *
+ * See the JSMarkOp typedef in jspubtd.h, and the JSObjectOps struct below.
+ */
+extern JS_PUBLIC_API(void)
+JS_MarkGCThing(JSContext *cx, void *thing, const char *name, void *arg);
+
+extern JS_PUBLIC_API(void)
+JS_GC(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+JS_MaybeGC(JSContext *cx);
+
+extern JS_PUBLIC_API(JSGCCallback)
+JS_SetGCCallback(JSContext *cx, JSGCCallback cb);
+
+extern JS_PUBLIC_API(JSGCCallback)
+JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb);
+
+extern JS_PUBLIC_API(JSBool)
+JS_IsAboutToBeFinalized(JSContext *cx, void *thing);
+
+/*
+ * Add a finalizer for external strings created by JS_NewExternalString (see
+ * below) using a type-code returned from this function, and that understands
+ * how to free or release the memory pointed at by JS_GetStringChars(str).
+ *
+ * Return a nonnegative type index if there is room for finalizer in the
+ * global GC finalizers table, else return -1.  If the engine is compiled
+ * JS_THREADSAFE and used in a multi-threaded environment, this function must
+ * be invoked on the primordial thread only, at startup -- or else the entire
+ * program must single-thread itself while loading a module that calls this
+ * function.
+ */
+extern JS_PUBLIC_API(intN)
+JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer);
+
+/*
+ * Remove finalizer from the global GC finalizers table, returning its type
+ * code if found, -1 if not found.
+ *
+ * As with JS_AddExternalStringFinalizer, there is a threading restriction
+ * if you compile the engine JS_THREADSAFE: this function may be called for a
+ * given finalizer pointer on only one thread; different threads may call to
+ * remove distinct finalizers safely.
+ *
+ * You must ensure that all strings with finalizer's type have been collected
+ * before calling this function.  Otherwise, string data will be leaked by the
+ * GC, for want of a finalizer to call.
+ */
+extern JS_PUBLIC_API(intN)
+JS_RemoveExternalStringFinalizer(JSStringFinalizeOp finalizer);
+
+/*
+ * Create a new JSString whose chars member refers to external memory, i.e.,
+ * memory requiring special, type-specific finalization.  The type code must
+ * be a nonnegative return value from JS_AddExternalStringFinalizer.
+ */
+extern JS_PUBLIC_API(JSString *)
+JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type);
+
+/*
+ * Returns the external-string finalizer index for this string, or -1 if it is
+ * an "internal" (native to JS engine) string.
+ */
+extern JS_PUBLIC_API(intN)
+JS_GetExternalStringGCType(JSRuntime *rt, JSString *str);
+
+/*
+ * Sets maximum (if stack grows upward) or minimum (downward) legal stack byte
+ * address in limitAddr for the thread or process stack used by cx.  To disable
+ * stack size checking, pass 0 for limitAddr.
+ */
+extern JS_PUBLIC_API(void)
+JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr);
+
+/************************************************************************/
+
+/*
+ * Classes, objects, and properties.
+ */
+
+/* For detailed comments on the function pointer types, see jspubtd.h. */
+struct JSClass {
+    const char          *name;
+    uint32              flags;
+
+    /* Mandatory non-null function pointer members. */
+    JSPropertyOp        addProperty;
+    JSPropertyOp        delProperty;
+    JSPropertyOp        getProperty;
+    JSPropertyOp        setProperty;
+    JSEnumerateOp       enumerate;
+    JSResolveOp         resolve;
+    JSConvertOp         convert;
+    JSFinalizeOp        finalize;
+
+    /* Optionally non-null members start here. */
+    JSGetObjectOps      getObjectOps;
+    JSCheckAccessOp     checkAccess;
+    JSNative            call;
+    JSNative            construct;
+    JSXDRObjectOp       xdrObject;
+    JSHasInstanceOp     hasInstance;
+    JSMarkOp            mark;
+    JSReserveSlotsOp    reserveSlots;
+};
+
+struct JSExtendedClass {
+    JSClass             base;
+    JSEqualityOp        equality;
+    JSObjectOp          outerObject;
+    JSObjectOp          innerObject;
+    jsword              reserved0;
+    jsword              reserved1;
+    jsword              reserved2;
+    jsword              reserved3;
+    jsword              reserved4;
+};
+
+#define JSCLASS_HAS_PRIVATE             (1<<0)  /* objects have private slot */
+#define JSCLASS_NEW_ENUMERATE           (1<<1)  /* has JSNewEnumerateOp hook */
+#define JSCLASS_NEW_RESOLVE             (1<<2)  /* has JSNewResolveOp hook */
+#define JSCLASS_PRIVATE_IS_NSISUPPORTS  (1<<3)  /* private is (nsISupports *) */
+#define JSCLASS_SHARE_ALL_PROPERTIES    (1<<4)  /* all properties are SHARED */
+#define JSCLASS_NEW_RESOLVE_GETS_START  (1<<5)  /* JSNewResolveOp gets starting
+                                                   object in prototype chain
+                                                   passed in via *objp in/out
+                                                   parameter */
+#define JSCLASS_CONSTRUCT_PROTOTYPE     (1<<6)  /* call constructor on class
+                                                   prototype */
+#define JSCLASS_DOCUMENT_OBSERVER       (1<<7)  /* DOM document observer */
+
+/*
+ * To reserve slots fetched and stored via JS_Get/SetReservedSlot, bitwise-or
+ * JSCLASS_HAS_RESERVED_SLOTS(n) into the initializer for JSClass.flags, where
+ * n is a constant in [1, 255].  Reserved slots are indexed from 0 to n-1.
+ */
+#define JSCLASS_RESERVED_SLOTS_SHIFT    8       /* room for 8 flags below */
+#define JSCLASS_RESERVED_SLOTS_WIDTH    8       /* and 16 above this field */
+#define JSCLASS_RESERVED_SLOTS_MASK     JS_BITMASK(JSCLASS_RESERVED_SLOTS_WIDTH)
+#define JSCLASS_HAS_RESERVED_SLOTS(n)   (((n) & JSCLASS_RESERVED_SLOTS_MASK)  \
+                                         << JSCLASS_RESERVED_SLOTS_SHIFT)
+#define JSCLASS_RESERVED_SLOTS(clasp)   (((clasp)->flags                      \
+                                          >> JSCLASS_RESERVED_SLOTS_SHIFT)    \
+                                         & JSCLASS_RESERVED_SLOTS_MASK)
+
+#define JSCLASS_HIGH_FLAGS_SHIFT        (JSCLASS_RESERVED_SLOTS_SHIFT +       \
+                                         JSCLASS_RESERVED_SLOTS_WIDTH)
+
+/* True if JSClass is really a JSExtendedClass. */
+#define JSCLASS_IS_EXTENDED             (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0))
+
+/* Initializer for unused members of statically initialized JSClass structs. */
+#define JSCLASS_NO_OPTIONAL_MEMBERS     0,0,0,0,0,0,0,0
+#define JSCLASS_NO_RESERVED_MEMBERS     0,0,0,0,0
+
+/* For detailed comments on these function pointer types, see jspubtd.h. */
+struct JSObjectOps {
+    /* Mandatory non-null function pointer members. */
+    JSNewObjectMapOp    newObjectMap;
+    JSObjectMapOp       destroyObjectMap;
+    JSLookupPropOp      lookupProperty;
+    JSDefinePropOp      defineProperty;
+    JSPropertyIdOp      getProperty;
+    JSPropertyIdOp      setProperty;
+    JSAttributesOp      getAttributes;
+    JSAttributesOp      setAttributes;
+    JSPropertyIdOp      deleteProperty;
+    JSConvertOp         defaultValue;
+    JSNewEnumerateOp    enumerate;
+    JSCheckAccessIdOp   checkAccess;
+
+    /* Optionally non-null members start here. */
+    JSObjectOp          thisObject;
+    JSPropertyRefOp     dropProperty;
+    JSNative            call;
+    JSNative            construct;
+    JSXDRObjectOp       xdrObject;
+    JSHasInstanceOp     hasInstance;
+    JSSetObjectSlotOp   setProto;
+    JSSetObjectSlotOp   setParent;
+    JSMarkOp            mark;
+    JSFinalizeOp        clear;
+    JSGetRequiredSlotOp getRequiredSlot;
+    JSSetRequiredSlotOp setRequiredSlot;
+};
+
+struct JSXMLObjectOps {
+    JSObjectOps         base;
+    JSGetMethodOp       getMethod;
+    JSSetMethodOp       setMethod;
+    JSEnumerateValuesOp enumerateValues;
+    JSEqualityOp        equality;
+    JSConcatenateOp     concatenate;
+};
+
+/*
+ * Classes that expose JSObjectOps via a non-null getObjectOps class hook may
+ * derive a property structure from this struct, return a pointer to it from
+ * lookupProperty and defineProperty, and use the pointer to avoid rehashing
+ * in getAttributes and setAttributes.
+ *
+ * The jsid type contains either an int jsval (see JSVAL_IS_INT above), or an
+ * internal pointer that is opaque to users of this API, but which users may
+ * convert from and to a jsval using JS_ValueToId and JS_IdToValue.
+ */
+struct JSProperty {
+    jsid id;
+};
+
+struct JSIdArray {
+    jsint length;
+    jsid  vector[1];    /* actually, length jsid words */
+};
+
+extern JS_PUBLIC_API(void)
+JS_DestroyIdArray(JSContext *cx, JSIdArray *ida);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ValueToId(JSContext *cx, jsval v, jsid *idp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_IdToValue(JSContext *cx, jsid id, jsval *vp);
+
+/*
+ * The magic XML namespace id is int-tagged, but not a valid integer jsval.
+ * Global object classes in embeddings that enable JS_HAS_XML_SUPPORT (E4X)
+ * should handle this id specially before converting id via JSVAL_TO_INT.
+ */
+#define JS_DEFAULT_XML_NAMESPACE_ID ((jsid) JSVAL_VOID)
+
+/*
+ * JSNewResolveOp flag bits.
+ */
+#define JSRESOLVE_QUALIFIED     0x01    /* resolve a qualified property id */
+#define JSRESOLVE_ASSIGNING     0x02    /* resolve on the left of assignment */
+#define JSRESOLVE_DETECTING     0x04    /* 'if (o.p)...' or '(o.p) ?...:...' */
+#define JSRESOLVE_DECLARING     0x08    /* var, const, or function prolog op */
+#define JSRESOLVE_CLASSNAME     0x10    /* class name used when constructing */
+
+extern JS_PUBLIC_API(JSBool)
+JS_PropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_EnumerateStub(JSContext *cx, JSObject *obj);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ResolveStub(JSContext *cx, JSObject *obj, jsval id);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
+
+extern JS_PUBLIC_API(void)
+JS_FinalizeStub(JSContext *cx, JSObject *obj);
+
+struct JSConstDoubleSpec {
+    jsdouble        dval;
+    const char      *name;
+    uint8           flags;
+    uint8           spare[3];
+};
+
+/*
+ * To define an array element rather than a named property member, cast the
+ * element's index to (const char *) and initialize name with it, and set the
+ * JSPROP_INDEX bit in flags.
+ */
+struct JSPropertySpec {
+    const char      *name;
+    int8            tinyid;
+    uint8           flags;
+    JSPropertyOp    getter;
+    JSPropertyOp    setter;
+};
+
+struct JSFunctionSpec {
+    const char      *name;
+    JSNative        call;
+    uint8           nargs;
+    uint8           flags;
+    uint16          extra;      /* number of arg slots for local GC roots */
+};
+
+extern JS_PUBLIC_API(JSObject *)
+JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
+             JSClass *clasp, JSNative constructor, uintN nargs,
+             JSPropertySpec *ps, JSFunctionSpec *fs,
+             JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
+
+#ifdef JS_THREADSAFE
+extern JS_PUBLIC_API(JSClass *)
+JS_GetClass(JSContext *cx, JSObject *obj);
+
+#define JS_GET_CLASS(cx,obj) JS_GetClass(cx, obj)
+#else
+extern JS_PUBLIC_API(JSClass *)
+JS_GetClass(JSObject *obj);
+
+#define JS_GET_CLASS(cx,obj) JS_GetClass(obj)
+#endif
+
+extern JS_PUBLIC_API(JSBool)
+JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv);
+
+extern JS_PUBLIC_API(JSBool)
+JS_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
+
+extern JS_PUBLIC_API(void *)
+JS_GetPrivate(JSContext *cx, JSObject *obj);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetPrivate(JSContext *cx, JSObject *obj, void *data);
+
+extern JS_PUBLIC_API(void *)
+JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp,
+                      jsval *argv);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_GetPrototype(JSContext *cx, JSObject *obj);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_GetParent(JSContext *cx, JSObject *obj);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_GetConstructor(JSContext *cx, JSObject *proto);
+
+/*
+ * Get a unique identifier for obj, good for the lifetime of obj (even if it
+ * is moved by a copying GC).  Return false on failure (likely out of memory),
+ * and true with *idp containing the unique id on success.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
+                   JSObject *parent);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *proto,
+                                JSObject *parent, uintN argc, jsval *argv);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp,
+                JSObject *proto, uintN attrs);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DefineProperties(JSContext *cx, JSObject *obj, JSPropertySpec *ps);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
+                  JSPropertyOp getter, JSPropertyOp setter, uintN attrs);
+
+/*
+ * Determine the attributes (JSPROP_* flags) of a property on a given object.
+ *
+ * If the object does not have a property by that name, *foundp will be
+ * JS_FALSE and the value of *attrsp is undefined.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
+                         uintN *attrsp, JSBool *foundp);
+
+/*
+ * The same, but if the property is native, return its getter and setter via
+ * *getterp and *setterp, respectively (and only if the out parameter pointer
+ * is not null).
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_GetPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
+                                   const char *name,
+                                   uintN *attrsp, JSBool *foundp,
+                                   JSPropertyOp *getterp,
+                                   JSPropertyOp *setterp);
+
+/*
+ * Set the attributes of a property on a given object.
+ *
+ * If the object does not have a property by that name, *foundp will be
+ * JS_FALSE and nothing will be altered.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
+                         uintN attrs, JSBool *foundp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name,
+                            int8 tinyid, jsval value,
+                            JSPropertyOp getter, JSPropertyOp setter,
+                            uintN attrs);
+
+extern JS_PUBLIC_API(JSBool)
+JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name,
+                 const char *alias);
+
+extern JS_PUBLIC_API(JSBool)
+JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, JSBool *foundp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, const char *name,
+                           uintN flags, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_GetMethod(JSContext *cx, JSObject *obj, const char *name, JSObject **objp,
+             jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DeleteProperty(JSContext *cx, JSObject *obj, const char *name);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name,
+                   jsval *rval);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DefineUCProperty(JSContext *cx, JSObject *obj,
+                    const jschar *name, size_t namelen, jsval value,
+                    JSPropertyOp getter, JSPropertyOp setter,
+                    uintN attrs);
+
+/*
+ * Determine the attributes (JSPROP_* flags) of a property on a given object.
+ *
+ * If the object does not have a property by that name, *foundp will be
+ * JS_FALSE and the value of *attrsp is undefined.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj,
+                           const jschar *name, size_t namelen,
+                           uintN *attrsp, JSBool *foundp);
+
+/*
+ * The same, but if the property is native, return its getter and setter via
+ * *getterp and *setterp, respectively (and only if the out parameter pointer
+ * is not null).
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_GetUCPropertyAttrsGetterAndSetter(JSContext *cx, JSObject *obj,
+                                     const jschar *name, size_t namelen,
+                                     uintN *attrsp, JSBool *foundp,
+                                     JSPropertyOp *getterp,
+                                     JSPropertyOp *setterp);
+
+/*
+ * Set the attributes of a property on a given object.
+ *
+ * If the object does not have a property by that name, *foundp will be
+ * JS_FALSE and nothing will be altered.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj,
+                           const jschar *name, size_t namelen,
+                           uintN attrs, JSBool *foundp);
+
+
+extern JS_PUBLIC_API(JSBool)
+JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj,
+                              const jschar *name, size_t namelen,
+                              int8 tinyid, jsval value,
+                              JSPropertyOp getter, JSPropertyOp setter,
+                              uintN attrs);
+
+extern JS_PUBLIC_API(JSBool)
+JS_HasUCProperty(JSContext *cx, JSObject *obj,
+                 const jschar *name, size_t namelen,
+                 JSBool *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_LookupUCProperty(JSContext *cx, JSObject *obj,
+                    const jschar *name, size_t namelen,
+                    jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_GetUCProperty(JSContext *cx, JSObject *obj,
+                 const jschar *name, size_t namelen,
+                 jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetUCProperty(JSContext *cx, JSObject *obj,
+                 const jschar *name, size_t namelen,
+                 jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DeleteUCProperty2(JSContext *cx, JSObject *obj,
+                     const jschar *name, size_t namelen,
+                     jsval *rval);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_NewArrayObject(JSContext *cx, jsint length, jsval *vector);
+
+extern JS_PUBLIC_API(JSBool)
+JS_IsArrayObject(JSContext *cx, JSObject *obj);
+
+extern JS_PUBLIC_API(JSBool)
+JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length);
+
+extern JS_PUBLIC_API(JSBool)
+JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value,
+                 JSPropertyOp getter, JSPropertyOp setter, uintN attrs);
+
+extern JS_PUBLIC_API(JSBool)
+JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias);
+
+extern JS_PUBLIC_API(JSBool)
+JS_HasElement(JSContext *cx, JSObject *obj, jsint index, JSBool *foundp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DeleteElement(JSContext *cx, JSObject *obj, jsint index);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval);
+
+extern JS_PUBLIC_API(void)
+JS_ClearScope(JSContext *cx, JSObject *obj);
+
+extern JS_PUBLIC_API(JSIdArray *)
+JS_Enumerate(JSContext *cx, JSObject *obj);
+
+/*
+ * Create an object to iterate over enumerable properties of obj, in arbitrary
+ * property definition order.  NB: This differs from longstanding for..in loop
+ * order, which uses order of property definition in obj.
+ */
+extern JS_PUBLIC_API(JSObject *)
+JS_NewPropertyIterator(JSContext *cx, JSObject *obj);
+
+/*
+ * Return true on success with *idp containing the id of the next enumerable
+ * property to visit using iterobj, or JSVAL_VOID if there is no such property
+ * left to visit.  Return false on error.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_NextProperty(JSContext *cx, JSObject *iterobj, jsid *idp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
+               jsval *vp, uintN *attrsp);
+
+extern JS_PUBLIC_API(JSCheckAccessOp)
+JS_SetCheckObjectAccessCallback(JSRuntime *rt, JSCheckAccessOp acb);
+
+extern JS_PUBLIC_API(JSBool)
+JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v);
+
+/************************************************************************/
+
+/*
+ * Security protocol.
+ */
+struct JSPrincipals {
+    char *codebase;
+
+    /* XXX unspecified and unused by Mozilla code -- can we remove these? */
+    void * (* JS_DLL_CALLBACK getPrincipalArray)(JSContext *cx, JSPrincipals *);
+    JSBool (* JS_DLL_CALLBACK globalPrivilegesEnabled)(JSContext *cx, JSPrincipals *);
+
+    /* Don't call "destroy"; use reference counting macros below. */
+    jsrefcount refcount;
+
+    void   (* JS_DLL_CALLBACK destroy)(JSContext *cx, JSPrincipals *);
+    JSBool (* JS_DLL_CALLBACK subsume)(JSPrincipals *, JSPrincipals *);
+};
+
+#ifdef JS_THREADSAFE
+#define JSPRINCIPALS_HOLD(cx, principals)   JS_HoldPrincipals(cx,principals)
+#define JSPRINCIPALS_DROP(cx, principals)   JS_DropPrincipals(cx,principals)
+
+extern JS_PUBLIC_API(jsrefcount)
+JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals);
+
+extern JS_PUBLIC_API(jsrefcount)
+JS_DropPrincipals(JSContext *cx, JSPrincipals *principals);
+
+#else
+#define JSPRINCIPALS_HOLD(cx, principals)   (++(principals)->refcount)
+#define JSPRINCIPALS_DROP(cx, principals)                                     \
+    ((--(principals)->refcount == 0)                                          \
+     ? ((*(principals)->destroy)((cx), (principals)), 0)                      \
+     : (principals)->refcount)
+#endif
+
+extern JS_PUBLIC_API(JSPrincipalsTranscoder)
+JS_SetPrincipalsTranscoder(JSRuntime *rt, JSPrincipalsTranscoder px);
+
+extern JS_PUBLIC_API(JSObjectPrincipalsFinder)
+JS_SetObjectPrincipalsFinder(JSRuntime *rt, JSObjectPrincipalsFinder fop);
+
+/************************************************************************/
+
+/*
+ * Functions and scripts.
+ */
+extern JS_PUBLIC_API(JSFunction *)
+JS_NewFunction(JSContext *cx, JSNative call, uintN nargs, uintN flags,
+               JSObject *parent, const char *name);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_GetFunctionObject(JSFunction *fun);
+
+/*
+ * Deprecated, useful only for diagnostics.  Use JS_GetFunctionId instead for
+ * anonymous vs. "anonymous" disambiguation and Unicode fidelity.
+ */
+extern JS_PUBLIC_API(const char *)
+JS_GetFunctionName(JSFunction *fun);
+
+/*
+ * Return the function's identifier as a JSString, or null if fun is unnamed.
+ * The returned string lives as long as fun, so you don't need to root a saved
+ * reference to it if fun is well-connected or rooted, and provided you bound
+ * the use of the saved reference by fun's lifetime.
+ *
+ * Prefer JS_GetFunctionId over JS_GetFunctionName because it returns null for
+ * truly anonymous functions, and because it doesn't chop to ISO-Latin-1 chars
+ * from UTF-16-ish jschars.
+ */
+extern JS_PUBLIC_API(JSString *)
+JS_GetFunctionId(JSFunction *fun);
+
+/*
+ * Return JSFUN_* flags for fun.
+ */
+extern JS_PUBLIC_API(uintN)
+JS_GetFunctionFlags(JSFunction *fun);
+
+/*
+ * Infallible predicate to test whether obj is a function object (faster than
+ * comparing obj's class name to "Function", but equivalent unless someone has
+ * overwritten the "Function" identifier with a different constructor and then
+ * created instances using that constructor that might be passed in as obj).
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_ObjectIsFunction(JSContext *cx, JSObject *obj);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs);
+
+extern JS_PUBLIC_API(JSFunction *)
+JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call,
+                  uintN nargs, uintN attrs);
+
+extern JS_PUBLIC_API(JSFunction *)
+JS_DefineUCFunction(JSContext *cx, JSObject *obj,
+                    const jschar *name, size_t namelen, JSNative call,
+                    uintN nargs, uintN attrs);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent);
+
+/*
+ * Given a buffer, return JS_FALSE if the buffer might become a valid
+ * javascript statement with the addition of more lines.  Otherwise return
+ * JS_TRUE.  The intent is to support interactive compilation - accumulate
+ * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
+ * the compiler.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj,
+                          const char *bytes, size_t length);
+
+/*
+ * The JSScript objects returned by the following functions refer to string and
+ * other kinds of literals, including doubles and RegExp objects.  These
+ * literals are vulnerable to garbage collection; to root script objects and
+ * prevent literals from being collected, create a rootable object using
+ * JS_NewScriptObject, and root the resulting object using JS_Add[Named]Root.
+ */
+extern JS_PUBLIC_API(JSScript *)
+JS_CompileScript(JSContext *cx, JSObject *obj,
+                 const char *bytes, size_t length,
+                 const char *filename, uintN lineno);
+
+extern JS_PUBLIC_API(JSScript *)
+JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
+                              JSPrincipals *principals,
+                              const char *bytes, size_t length,
+                              const char *filename, uintN lineno);
+
+extern JS_PUBLIC_API(JSScript *)
+JS_CompileUCScript(JSContext *cx, JSObject *obj,
+                   const jschar *chars, size_t length,
+                   const char *filename, uintN lineno);
+
+extern JS_PUBLIC_API(JSScript *)
+JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
+                                JSPrincipals *principals,
+                                const jschar *chars, size_t length,
+                                const char *filename, uintN lineno);
+
+extern JS_PUBLIC_API(JSScript *)
+JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename);
+
+extern JS_PUBLIC_API(JSScript *)
+JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename,
+                     FILE *fh);
+
+extern JS_PUBLIC_API(JSScript *)
+JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj,
+                                  const char *filename, FILE *fh,
+                                  JSPrincipals *principals);
+
+/*
+ * NB: you must use JS_NewScriptObject and root a pointer to its return value
+ * in order to keep a JSScript and its atoms safe from garbage collection after
+ * creating the script via JS_Compile* and before a JS_ExecuteScript* call.
+ * E.g., and without error checks:
+ *
+ *    JSScript *script = JS_CompileFile(cx, global, filename);
+ *    JSObject *scrobj = JS_NewScriptObject(cx, script);
+ *    JS_AddNamedRoot(cx, &scrobj, "scrobj");
+ *    do {
+ *        jsval result;
+ *        JS_ExecuteScript(cx, global, script, &result);
+ *        JS_GC();
+ *    } while (!JSVAL_IS_BOOLEAN(result) || JSVAL_TO_BOOLEAN(result));
+ *    JS_RemoveRoot(cx, &scrobj);
+ */
+extern JS_PUBLIC_API(JSObject *)
+JS_NewScriptObject(JSContext *cx, JSScript *script);
+
+/*
+ * Infallible getter for a script's object.  If JS_NewScriptObject has not been
+ * called on script yet, the return value will be null.
+ */
+extern JS_PUBLIC_API(JSObject *)
+JS_GetScriptObject(JSScript *script);
+
+extern JS_PUBLIC_API(void)
+JS_DestroyScript(JSContext *cx, JSScript *script);
+
+extern JS_PUBLIC_API(JSFunction *)
+JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name,
+                   uintN nargs, const char **argnames,
+                   const char *bytes, size_t length,
+                   const char *filename, uintN lineno);
+
+extern JS_PUBLIC_API(JSFunction *)
+JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj,
+                                JSPrincipals *principals, const char *name,
+                                uintN nargs, const char **argnames,
+                                const char *bytes, size_t length,
+                                const char *filename, uintN lineno);
+
+extern JS_PUBLIC_API(JSFunction *)
+JS_CompileUCFunction(JSContext *cx, JSObject *obj, const char *name,
+                     uintN nargs, const char **argnames,
+                     const jschar *chars, size_t length,
+                     const char *filename, uintN lineno);
+
+extern JS_PUBLIC_API(JSFunction *)
+JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
+                                  JSPrincipals *principals, const char *name,
+                                  uintN nargs, const char **argnames,
+                                  const jschar *chars, size_t length,
+                                  const char *filename, uintN lineno);
+
+extern JS_PUBLIC_API(JSString *)
+JS_DecompileScript(JSContext *cx, JSScript *script, const char *name,
+                   uintN indent);
+
+/*
+ * API extension: OR this into indent to avoid pretty-printing the decompiled
+ * source resulting from JS_DecompileFunction{,Body}.
+ */
+#define JS_DONT_PRETTY_PRINT    ((uintN)0x8000)
+
+extern JS_PUBLIC_API(JSString *)
+JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent);
+
+extern JS_PUBLIC_API(JSString *)
+JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent);
+
+/*
+ * NB: JS_ExecuteScript, JS_ExecuteScriptPart, and the JS_Evaluate*Script*
+ * quadruplets all use the obj parameter as the initial scope chain header,
+ * the 'this' keyword value, and the variables object (ECMA parlance for where
+ * 'var' and 'function' bind names) of the execution context for script.
+ *
+ * Using obj as the variables object is problematic if obj's parent (which is
+ * the scope chain link; see JS_SetParent and JS_NewObject) is not null: in
+ * this case, variables created by 'var x = 0', e.g., go in obj, but variables
+ * created by assignment to an unbound id, 'x = 0', go in the last object on
+ * the scope chain linked by parent.
+ *
+ * ECMA calls that last scoping object the "global object", but note that many
+ * embeddings have several such objects.  ECMA requires that "global code" be
+ * executed with the variables object equal to this global object.  But these
+ * JS API entry points provide freedom to execute code against a "sub-global",
+ * i.e., a parented or scoped object, in which case the variables object will
+ * differ from the last object on the scope chain, resulting in confusing and
+ * non-ECMA explicit vs. implicit variable creation.
+ *
+ * Caveat embedders: unless you already depend on this buggy variables object
+ * binding behavior, you should call JS_SetOptions(cx, JSOPTION_VAROBJFIX) or
+ * JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_VAROBJFIX) -- the latter if
+ * someone may have set other options on cx already -- for each context in the
+ * application, if you pass parented objects as the obj parameter, or may ever
+ * pass such objects in the future.
+ *
+ * Why a runtime option?  The alternative is to add six or so new API entry
+ * points with signatures matching the following six, and that doesn't seem
+ * worth the code bloat cost.  Such new entry points would probably have less
+ * obvious names, too, so would not tend to be used.  The JS_SetOption call,
+ * OTOH, can be more easily hacked into existing code that does not depend on
+ * the bug; such code can continue to use the familiar JS_EvaluateScript,
+ * etc., entry points.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval);
+
+/*
+ * Execute either the function-defining prolog of a script, or the script's
+ * main body, but not both.
+ */
+typedef enum JSExecPart { JSEXEC_PROLOG, JSEXEC_MAIN } JSExecPart;
+
+extern JS_PUBLIC_API(JSBool)
+JS_ExecuteScriptPart(JSContext *cx, JSObject *obj, JSScript *script,
+                     JSExecPart part, jsval *rval);
+
+extern JS_PUBLIC_API(JSBool)
+JS_EvaluateScript(JSContext *cx, JSObject *obj,
+                  const char *bytes, uintN length,
+                  const char *filename, uintN lineno,
+                  jsval *rval);
+
+extern JS_PUBLIC_API(JSBool)
+JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj,
+                               JSPrincipals *principals,
+                               const char *bytes, uintN length,
+                               const char *filename, uintN lineno,
+                               jsval *rval);
+
+extern JS_PUBLIC_API(JSBool)
+JS_EvaluateUCScript(JSContext *cx, JSObject *obj,
+                    const jschar *chars, uintN length,
+                    const char *filename, uintN lineno,
+                    jsval *rval);
+
+extern JS_PUBLIC_API(JSBool)
+JS_EvaluateUCScriptForPrincipals(JSContext *cx, JSObject *obj,
+                                 JSPrincipals *principals,
+                                 const jschar *chars, uintN length,
+                                 const char *filename, uintN lineno,
+                                 jsval *rval);
+
+extern JS_PUBLIC_API(JSBool)
+JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc,
+                jsval *argv, jsval *rval);
+
+extern JS_PUBLIC_API(JSBool)
+JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc,
+                    jsval *argv, jsval *rval);
+
+extern JS_PUBLIC_API(JSBool)
+JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc,
+                     jsval *argv, jsval *rval);
+
+extern JS_PUBLIC_API(JSBranchCallback)
+JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb);
+
+extern JS_PUBLIC_API(JSBool)
+JS_IsRunning(JSContext *cx);
+
+extern JS_PUBLIC_API(JSBool)
+JS_IsConstructing(JSContext *cx);
+
+/*
+ * Returns true if a script is executing and its current bytecode is a set
+ * (assignment) operation, even if there are native (no script) stack frames
+ * between the script and the caller to JS_IsAssigning.
+ */
+extern JS_FRIEND_API(JSBool)
+JS_IsAssigning(JSContext *cx);
+
+/*
+ * Set the second return value, which should be a string or int jsval that
+ * identifies a property in the returned object, to form an ECMA reference
+ * type value (obj, id).  Only native methods can return reference types,
+ * and if the returned value is used on the left-hand side of an assignment
+ * op, the identified property will be set.  If the return value is in an
+ * r-value, the interpreter just gets obj[id]'s value.
+ */
+extern JS_PUBLIC_API(void)
+JS_SetCallReturnValue2(JSContext *cx, jsval v);
+
+/************************************************************************/
+
+/*
+ * Strings.
+ *
+ * NB: JS_NewString takes ownership of bytes on success, avoiding a copy; but
+ * on error (signified by null return), it leaves bytes owned by the caller.
+ * So the caller must free bytes in the error case, if it has no use for them.
+ * In contrast, all the JS_New*StringCopy* functions do not take ownership of
+ * the character memory passed to them -- they copy it.
+ */
+extern JS_PUBLIC_API(JSString *)
+JS_NewString(JSContext *cx, char *bytes, size_t length);
+
+extern JS_PUBLIC_API(JSString *)
+JS_NewStringCopyN(JSContext *cx, const char *s, size_t n);
+
+extern JS_PUBLIC_API(JSString *)
+JS_NewStringCopyZ(JSContext *cx, const char *s);
+
+extern JS_PUBLIC_API(JSString *)
+JS_InternString(JSContext *cx, const char *s);
+
+extern JS_PUBLIC_API(JSString *)
+JS_NewUCString(JSContext *cx, jschar *chars, size_t length);
+
+extern JS_PUBLIC_API(JSString *)
+JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n);
+
+extern JS_PUBLIC_API(JSString *)
+JS_NewUCStringCopyZ(JSContext *cx, const jschar *s);
+
+extern JS_PUBLIC_API(JSString *)
+JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length);
+
+extern JS_PUBLIC_API(JSString *)
+JS_InternUCString(JSContext *cx, const jschar *s);
+
+extern JS_PUBLIC_API(char *)
+JS_GetStringBytes(JSString *str);
+
+extern JS_PUBLIC_API(jschar *)
+JS_GetStringChars(JSString *str);
+
+extern JS_PUBLIC_API(size_t)
+JS_GetStringLength(JSString *str);
+
+extern JS_PUBLIC_API(intN)
+JS_CompareStrings(JSString *str1, JSString *str2);
+
+/*
+ * Mutable string support.  A string's characters are never mutable in this JS
+ * implementation, but a growable string has a buffer that can be reallocated,
+ * and a dependent string is a substring of another (growable, dependent, or
+ * immutable) string.  The direct data members of the (opaque to API clients)
+ * JSString struct may be changed in a single-threaded way for growable and
+ * dependent strings.
+ *
+ * Therefore mutable strings cannot be used by more than one thread at a time.
+ * You may call JS_MakeStringImmutable to convert the string from a mutable
+ * (growable or dependent) string to an immutable (and therefore thread-safe)
+ * string.  The engine takes care of converting growable and dependent strings
+ * to immutable for you if you store strings in multi-threaded objects using
+ * JS_SetProperty or kindred API entry points.
+ *
+ * If you store a JSString pointer in a native data structure that is (safely)
+ * accessible to multiple threads, you must call JS_MakeStringImmutable before
+ * retiring the store.
+ */
+extern JS_PUBLIC_API(JSString *)
+JS_NewGrowableString(JSContext *cx, jschar *chars, size_t length);
+
+/*
+ * Create a dependent string, i.e., a string that owns no character storage,
+ * but that refers to a slice of another string's chars.  Dependent strings
+ * are mutable by definition, so the thread safety comments above apply.
+ */
+extern JS_PUBLIC_API(JSString *)
+JS_NewDependentString(JSContext *cx, JSString *str, size_t start,
+                      size_t length);
+
+/*
+ * Concatenate two strings, resulting in a new growable string.  If you create
+ * the left string and pass it to JS_ConcatStrings on a single thread, try to
+ * use JS_NewGrowableString to create the left string -- doing so helps Concat
+ * avoid allocating a new buffer for the result and copying left's chars into
+ * the new buffer.  See above for thread safety comments.
+ */
+extern JS_PUBLIC_API(JSString *)
+JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right);
+
+/*
+ * Convert a dependent string into an independent one.  This function does not
+ * change the string's mutability, so the thread safety comments above apply.
+ */
+extern JS_PUBLIC_API(const jschar *)
+JS_UndependString(JSContext *cx, JSString *str);
+
+/*
+ * Convert a mutable string (either growable or dependent) into an immutable,
+ * thread-safe one.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_MakeStringImmutable(JSContext *cx, JSString *str);
+
+/*
+ * Return JS_TRUE if C (char []) strings passed via the API and internally
+ * are UTF-8. The source must be compiled with JS_C_STRINGS_ARE_UTF8 defined
+ * to get UTF-8 support.
+ */
+JS_PUBLIC_API(JSBool)
+#ifdef OSSP /* CLEANUP */
+JS_CStringsAreUTF8(void);
+#else
+JS_CStringsAreUTF8();
+#endif
+
+/*
+ * Character encoding support.
+ *
+ * For both JS_EncodeCharacters and JS_DecodeBytes, set *dstlenp to the size
+ * of the destination buffer before the call; on return, *dstlenp contains the
+ * number of bytes (JS_EncodeCharacters) or jschars (JS_DecodeBytes) actually
+ * stored.  To determine the necessary destination buffer size, make a sizing
+ * call that passes NULL for dst.
+ *
+ * On errors, the functions report the error. In that case, *dstlenp contains
+ * the number of characters or bytes transferred so far.  If cx is NULL, no
+ * error is reported on failure, and the functions simply return JS_FALSE.
+ *
+ * NB: Neither function stores an additional zero byte or jschar after the
+ * transcoded string.
+ *
+ * If the source has been compiled with the #define JS_C_STRINGS_ARE_UTF8 to
+ * enable UTF-8 interpretation of C char[] strings, then JS_EncodeCharacters
+ * encodes to UTF-8, and JS_DecodeBytes decodes from UTF-8, which may create
+ * addititional errors if the character sequence is malformed.  If UTF-8
+ * support is disabled, the functions deflate and inflate, respectively.
+ */
+JS_PUBLIC_API(JSBool)
+JS_EncodeCharacters(JSContext *cx, const jschar *src, size_t srclen, char *dst,
+                    size_t *dstlenp);
+
+JS_PUBLIC_API(JSBool)
+JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst,
+               size_t *dstlenp);
+
+/************************************************************************/
+
+/*
+ * Locale specific string conversion and error message callbacks.
+ */
+struct JSLocaleCallbacks {
+    JSLocaleToUpperCase     localeToUpperCase;
+    JSLocaleToLowerCase     localeToLowerCase;
+    JSLocaleCompare         localeCompare;
+    JSLocaleToUnicode       localeToUnicode;
+    JSErrorCallback         localeGetErrorMessage;
+};
+
+/*
+ * Establish locale callbacks. The pointer must persist as long as the
+ * JSContext.  Passing NULL restores the default behaviour.
+ */
+extern JS_PUBLIC_API(void)
+JS_SetLocaleCallbacks(JSContext *cx, JSLocaleCallbacks *callbacks);
+
+/*
+ * Return the address of the current locale callbacks struct, which may
+ * be NULL.
+ */
+extern JS_PUBLIC_API(JSLocaleCallbacks *)
+JS_GetLocaleCallbacks(JSContext *cx);
+
+/************************************************************************/
+
+/*
+ * Error reporting.
+ */
+
+/*
+ * Report an exception represented by the sprintf-like conversion of format
+ * and its arguments.  This exception message string is passed to a pre-set
+ * JSErrorReporter function (set by JS_SetErrorReporter; see jspubtd.h for
+ * the JSErrorReporter typedef).
+ */
+extern JS_PUBLIC_API(void)
+JS_ReportError(JSContext *cx, const char *format, ...);
+
+/*
+ * Use an errorNumber to retrieve the format string, args are char *
+ */
+extern JS_PUBLIC_API(void)
+JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback,
+                     void *userRef, const uintN errorNumber, ...);
+
+/*
+ * Use an errorNumber to retrieve the format string, args are jschar *
+ */
+extern JS_PUBLIC_API(void)
+JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback,
+                     void *userRef, const uintN errorNumber, ...);
+
+/*
+ * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)).
+ * Return true if there was no error trying to issue the warning, and if the
+ * warning was not converted into an error due to the JSOPTION_WERROR option
+ * being set, false otherwise.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_ReportWarning(JSContext *cx, const char *format, ...);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ReportErrorFlagsAndNumber(JSContext *cx, uintN flags,
+                             JSErrorCallback errorCallback, void *userRef,
+                             const uintN errorNumber, ...);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ReportErrorFlagsAndNumberUC(JSContext *cx, uintN flags,
+                               JSErrorCallback errorCallback, void *userRef,
+                               const uintN errorNumber, ...);
+
+/*
+ * Complain when out of memory.
+ */
+extern JS_PUBLIC_API(void)
+JS_ReportOutOfMemory(JSContext *cx);
+
+struct JSErrorReport {
+    const char      *filename;      /* source file name, URL, etc., or null */
+    uintN           lineno;         /* source line number */
+    const char      *linebuf;       /* offending source line without final \n */
+    const char      *tokenptr;      /* pointer to error token in linebuf */
+    const jschar    *uclinebuf;     /* unicode (original) line buffer */
+    const jschar    *uctokenptr;    /* unicode (original) token pointer */
+    uintN           flags;          /* error/warning, etc. */
+    uintN           errorNumber;    /* the error number, e.g. see js.msg */
+    const jschar    *ucmessage;     /* the (default) error message */
+    const jschar    **messageArgs;  /* arguments for the error message */
+};
+
+/*
+ * JSErrorReport flag values.  These may be freely composed.
+ */
+#define JSREPORT_ERROR      0x0     /* pseudo-flag for default case */
+#define JSREPORT_WARNING    0x1     /* reported via JS_ReportWarning */
+#define JSREPORT_EXCEPTION  0x2     /* exception was thrown */
+#define JSREPORT_STRICT     0x4     /* error or warning due to strict option */
+
+/*
+ * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception
+ * has been thrown for this runtime error, and the host should ignore it.
+ * Exception-aware hosts should also check for JS_IsExceptionPending if
+ * JS_ExecuteScript returns failure, and signal or propagate the exception, as
+ * appropriate.
+ */
+#define JSREPORT_IS_WARNING(flags)      (((flags) & JSREPORT_WARNING) != 0)
+#define JSREPORT_IS_EXCEPTION(flags)    (((flags) & JSREPORT_EXCEPTION) != 0)
+#define JSREPORT_IS_STRICT(flags)       (((flags) & JSREPORT_STRICT) != 0)
+
+extern JS_PUBLIC_API(JSErrorReporter)
+JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);
+
+/************************************************************************/
+
+/*
+ * Regular Expressions.
+ */
+#define JSREG_FOLD      0x01    /* fold uppercase to lowercase */
+#define JSREG_GLOB      0x02    /* global exec, creates array of matches */
+#define JSREG_MULTILINE 0x04    /* treat ^ and $ as begin and end of line */
+
+extern JS_PUBLIC_API(JSObject *)
+JS_NewRegExpObject(JSContext *cx, char *bytes, size_t length, uintN flags);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_NewUCRegExpObject(JSContext *cx, jschar *chars, size_t length, uintN flags);
+
+extern JS_PUBLIC_API(void)
+JS_SetRegExpInput(JSContext *cx, JSString *input, JSBool multiline);
+
+extern JS_PUBLIC_API(void)
+JS_ClearRegExpStatics(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+JS_ClearRegExpRoots(JSContext *cx);
+
+/* TODO: compile, exec, get/set other statics... */
+
+/************************************************************************/
+
+extern JS_PUBLIC_API(JSBool)
+JS_IsExceptionPending(JSContext *cx);
+
+extern JS_PUBLIC_API(JSBool)
+JS_GetPendingException(JSContext *cx, jsval *vp);
+
+extern JS_PUBLIC_API(void)
+JS_SetPendingException(JSContext *cx, jsval v);
+
+extern JS_PUBLIC_API(void)
+JS_ClearPendingException(JSContext *cx);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ReportPendingException(JSContext *cx);
+
+/*
+ * Save the current exception state.  This takes a snapshot of cx's current
+ * exception state without making any change to that state.
+ *
+ * The returned state pointer MUST be passed later to JS_RestoreExceptionState
+ * (to restore that saved state, overriding any more recent state) or else to
+ * JS_DropExceptionState (to free the state struct in case it is not correct
+ * or desirable to restore it).  Both Restore and Drop free the state struct,
+ * so callers must stop using the pointer returned from Save after calling the
+ * Release or Drop API.
+ */
+extern JS_PUBLIC_API(JSExceptionState *)
+JS_SaveExceptionState(JSContext *cx);
+
+extern JS_PUBLIC_API(void)
+JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state);
+
+extern JS_PUBLIC_API(void)
+JS_DropExceptionState(JSContext *cx, JSExceptionState *state);
+
+/*
+ * If the given value is an exception object that originated from an error,
+ * the exception will contain an error report struct, and this API will return
+ * the address of that struct.  Otherwise, it returns NULL.  The lifetime of
+ * the error report struct that might be returned is the same as the lifetime
+ * of the exception object.
+ */
+extern JS_PUBLIC_API(JSErrorReport *)
+JS_ErrorFromException(JSContext *cx, jsval v);
+
+/*
+ * Given a reported error's message and JSErrorReport struct pointer, throw
+ * the corresponding exception on cx.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_ThrowReportedError(JSContext *cx, const char *message,
+                      JSErrorReport *reportp);
+
+#ifdef JS_THREADSAFE
+
+/*
+ * Associate the current thread with the given context.  This is done
+ * implicitly by JS_NewContext.
+ *
+ * Returns the old thread id for this context, which should be treated as
+ * an opaque value.  This value is provided for comparison to 0, which
+ * indicates that ClearContextThread has been called on this context
+ * since the last SetContextThread, or non-0, which indicates the opposite.
+ */
+extern JS_PUBLIC_API(jsword)
+JS_GetContextThread(JSContext *cx);
+
+extern JS_PUBLIC_API(jsword)
+JS_SetContextThread(JSContext *cx);
+
+extern JS_PUBLIC_API(jsword)
+JS_ClearContextThread(JSContext *cx);
+
+#endif /* JS_THREADSAFE */
+
+/************************************************************************/
+
+JS_END_EXTERN_C
+
+#endif /* jsapi_h___ */

Added: freeswitch/trunk/libs/js/src/jsarena.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsarena.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,574 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * 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 "jsstddef.h"
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsbit.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+#include "jslock.h"
+
+static JSArena *arena_freelist;
+
+#ifdef JS_THREADSAFE
+static JSLock *arena_freelist_lock;
+#endif
+
+#ifdef JS_ARENAMETER
+static JSArenaStats *arena_stats_list;
+
+#define COUNT(pool,what)  (pool)->stats.what++
+#else
+#define COUNT(pool,what)  /* nothing */
+#endif
+
+#define JS_ARENA_DEFAULT_ALIGN  sizeof(double)
+
+JS_PUBLIC_API(void)
+JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, size_t align)
+{
+#ifdef JS_THREADSAFE
+    /* Must come through here once in primordial thread to init safely! */
+    if (!arena_freelist_lock) {
+        arena_freelist_lock = JS_NEW_LOCK();
+        JS_ASSERT(arena_freelist_lock);
+    }
+#endif
+    if (align == 0)
+        align = JS_ARENA_DEFAULT_ALIGN;
+    pool->mask = JS_BITMASK(JS_CeilingLog2(align));
+    pool->first.next = NULL;
+    pool->first.base = pool->first.avail = pool->first.limit =
+        JS_ARENA_ALIGN(pool, &pool->first + 1);
+    pool->current = &pool->first;
+    pool->arenasize = size;
+#ifdef JS_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
+}
+
+/*
+ * An allocation that consumes more than pool->arenasize also has a header
+ * pointing back to its previous arena's next member.  This header is not
+ * included in [a->base, a->limit), so its space can't be wrongly claimed.
+ *
+ * As the header is a pointer, it must be well-aligned.  If pool->mask is
+ * greater than or equal to POINTER_MASK, the header just preceding a->base
+ * for an oversized arena a is well-aligned, because a->base is well-aligned.
+ * However, we may need to add more space to pad the JSArena ** back-pointer
+ * so that it lies just behind a->base, because a might not be aligned such
+ * that (jsuword)(a + 1) is on a pointer boundary.
+ *
+ * By how much must we pad?  Let M be the alignment modulus for pool and P
+ * the modulus for a pointer.  Given M >= P, the greatest distance between a
+ * pointer aligned on an M boundary and one aligned on a P boundary is M-P.
+ * If M and P are powers of two, then M-P = (pool->mask - POINTER_MASK).
+ *
+ * How much extra padding might spill over unused into the remainder of the
+ * allocation, in the worst case (where M > P)?
+ *
+ * If we add M-P to the nominal back-pointer address and then round down to
+ * align on a P boundary, we will use at most M-P bytes of padding, and at
+ * least P (M > P => M >= 2P; M == 2P gives the least padding, P).  So if we
+ * use P bytes of padding, then we will overallocate a by P+M-1 bytes, as we
+ * also add M-1 to the estimated size in case malloc returns an odd pointer.
+ * a->limit must include this overestimation to satisfy a->avail in [a->base,
+ * a->limit].
+ *
+ * Similarly, if pool->mask is less than POINTER_MASK, we must include enough
+ * space in the header size to align the back-pointer on a P boundary so that
+ * it can be found by subtracting P from a->base.  This means a->base must be
+ * on a P boundary, even though subsequent allocations from a may be aligned
+ * on a lesser (M) boundary.  Given powers of two M and P as above, the extra
+ * space needed when P > M is P-M or POINTER_MASK - pool->mask.
+ *
+ * The size of a header including padding is given by the HEADER_SIZE macro,
+ * below, for any pool (for any value of M).
+ *
+ * The mask to align a->base for any pool is (pool->mask | POINTER_MASK), or
+ * HEADER_BASE_MASK(pool).
+ *
+ * PTR_TO_HEADER computes the address of the back-pointer, given an oversized
+ * allocation at p.  By definition, p must be a->base for the arena a that
+ * contains p.  GET_HEADER and SET_HEADER operate on an oversized arena a, in
+ * the case of SET_HEADER with back-pointer ap.
+ */
+#define POINTER_MASK            ((jsuword)(JS_ALIGN_OF_POINTER - 1))
+#define HEADER_SIZE(pool)       (sizeof(JSArena **)                           \
+                                 + (((pool)->mask < POINTER_MASK)             \
+                                    ? POINTER_MASK - (pool)->mask             \
+                                    : (pool)->mask - POINTER_MASK))
+#define HEADER_BASE_MASK(pool)  ((pool)->mask | POINTER_MASK)
+#define PTR_TO_HEADER(pool,p)   (JS_ASSERT(((jsuword)(p)                      \
+                                            & HEADER_BASE_MASK(pool))         \
+                                           == 0),                             \
+                                 (JSArena ***)(p) - 1)
+#define GET_HEADER(pool,a)      (*PTR_TO_HEADER(pool, (a)->base))
+#define SET_HEADER(pool,a,ap)   (*PTR_TO_HEADER(pool, (a)->base) = (ap))
+
+JS_PUBLIC_API(void *)
+JS_ArenaAllocate(JSArenaPool *pool, size_t nb)
+{
+    JSArena **ap, **bp, *a, *b;
+    jsuword extra, hdrsz, gross, sz;
+    void *p;
+
+    /*
+     * Search pool from current forward till we find or make enough space.
+     *
+     * NB: subtract nb from a->limit in the loop condition, instead of adding
+     * nb to a->avail, to avoid overflowing a 32-bit address space (possible
+     * when running a 32-bit program on a 64-bit system where the kernel maps
+     * the heap up against the top of the 32-bit address space).
+     *
+     * Thanks to Juergen Kreileder <jk at blackdown.de>, who brought this up in
+     * https://bugzilla.mozilla.org/show_bug.cgi?id=279273.
+     */
+    JS_ASSERT((nb & pool->mask) == 0);
+    for (a = pool->current; a->avail > a->limit - nb; pool->current = a) {
+        ap = &a->next;
+        if (!*ap) {
+            /* Not enough space in pool -- try to reclaim a free arena. */
+            extra = (nb > pool->arenasize) ? HEADER_SIZE(pool) : 0;
+            hdrsz = sizeof *a + extra + pool->mask;
+            gross = hdrsz + JS_MAX(nb, pool->arenasize);
+            bp = &arena_freelist;
+            JS_ACQUIRE_LOCK(arena_freelist_lock);
+            while ((b = *bp) != NULL) {
+                /*
+                 * Insist on exact arenasize match to avoid leaving alloc'able
+                 * space after an oversized allocation as it grows.
+                 */
+                sz = JS_UPTRDIFF(b->limit, b);
+                if (sz == gross) {
+                    *bp = b->next;
+                    JS_RELEASE_LOCK(arena_freelist_lock);
+                    b->next = NULL;
+                    COUNT(pool, nreclaims);
+                    goto claim;
+                }
+                bp = &b->next;
+            }
+
+            /* Nothing big enough on the freelist, so we must malloc. */
+            JS_RELEASE_LOCK(arena_freelist_lock);
+            b = (JSArena *) malloc(gross);
+            if (!b)
+                return 0;
+            b->next = NULL;
+            b->limit = (jsuword)b + gross;
+            JS_COUNT_ARENA(pool,++);
+            COUNT(pool, nmallocs);
+
+        claim:
+            /* If oversized, store ap in the header, just before a->base. */
+            *ap = a = b;
+            JS_ASSERT(gross <= JS_UPTRDIFF(a->limit, a));
+            if (extra) {
+                a->base = a->avail =
+                    ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool);
+                SET_HEADER(pool, a, ap);
+            } else {
+                a->base = a->avail = JS_ARENA_ALIGN(pool, a + 1);
+            }
+            continue;
+        }
+        a = *ap;                                /* move to next arena */
+    }
+
+    p = (void *)a->avail;
+    a->avail += nb;
+    JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+    return p;
+}
+
+JS_PUBLIC_API(void *)
+JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr)
+{
+    JSArena **ap, *a, *b;
+    jsuword boff, aoff, extra, hdrsz, gross;
+
+    /*
+     * Use the oversized-single-allocation header to avoid searching for ap.
+     * See JS_ArenaAllocate, the SET_HEADER call.
+     */
+    if (size > pool->arenasize) {
+        ap = *PTR_TO_HEADER(pool, p);
+        a = *ap;
+    } else {
+        ap = &pool->first.next;
+        while ((a = *ap) != pool->current)
+            ap = &a->next;
+    }
+
+    JS_ASSERT(a->base == (jsuword)p);
+    boff = JS_UPTRDIFF(a->base, a);
+    aoff = size + incr;
+    JS_ASSERT(aoff > pool->arenasize);
+    extra = HEADER_SIZE(pool);                  /* oversized header holds ap */
+    hdrsz = sizeof *a + extra + pool->mask;     /* header and alignment slop */
+    gross = hdrsz + aoff;
+    a = (JSArena *) realloc(a, gross);
+    if (!a)
+        return NULL;
+#ifdef JS_ARENAMETER
+    pool->stats.nreallocs++;
+#endif
+
+    if (a != *ap) {
+        /* Oops, realloc moved the allocation: update other pointers to a. */
+        if (pool->current == *ap)
+            pool->current = a;
+        b = a->next;
+        if (b && b->avail - b->base > pool->arenasize) {
+            JS_ASSERT(GET_HEADER(pool, b) == &(*ap)->next);
+            SET_HEADER(pool, b, &a->next);
+        }
+
+        /* Now update *ap, the next link of the arena before a. */
+        *ap = a;
+    }
+
+    a->base = ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool);
+    a->limit = (jsuword)a + gross;
+    a->avail = JS_ARENA_ALIGN(pool, a->base + aoff);
+    JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+
+    /* Check whether realloc aligned differently, and copy if necessary. */
+    if (boff != JS_UPTRDIFF(a->base, a))
+        memmove((void *)a->base, (char *)a + boff, size);
+
+    /* Store ap in the oversized-load arena header. */
+    SET_HEADER(pool, a, ap);
+    return (void *)a->base;
+}
+
+JS_PUBLIC_API(void *)
+JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr)
+{
+    void *newp;
+
+    /*
+     * If p points to an oversized allocation, it owns an entire arena, so we
+     * can simply realloc the arena.
+     */
+    if (size > pool->arenasize)
+        return JS_ArenaRealloc(pool, p, size, incr);
+
+    JS_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(JSArenaPool *pool, JSArena *head, JSBool reallyFree)
+{
+    JSArena **ap, *a;
+
+    ap = &head->next;
+    a = *ap;
+    if (!a)
+        return;
+
+#ifdef DEBUG
+    do {
+        JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+        a->avail = a->base;
+        JS_CLEAR_UNUSED(a);
+    } while ((a = a->next) != NULL);
+    a = *ap;
+#endif
+
+    if (reallyFree) {
+        do {
+            *ap = a->next;
+            JS_CLEAR_ARENA(a);
+            JS_COUNT_ARENA(pool,--);
+            free(a);
+        } while ((a = *ap) != NULL);
+    } else {
+        /* Insert the whole arena chain at the front of the freelist. */
+        do {
+            ap = &(*ap)->next;
+        } while (*ap);
+        JS_ACQUIRE_LOCK(arena_freelist_lock);
+        *ap = arena_freelist;
+        arena_freelist = a;
+        JS_RELEASE_LOCK(arena_freelist_lock);
+        head->next = NULL;
+    }
+
+    pool->current = head;
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaRelease(JSArenaPool *pool, char *mark)
+{
+    JSArena *a;
+
+    for (a = &pool->first; a; a = a->next) {
+        JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+
+        if (JS_UPTRDIFF(mark, a->base) <= JS_UPTRDIFF(a->avail, a->base)) {
+            a->avail = JS_ARENA_ALIGN(pool, mark);
+            JS_ASSERT(a->avail <= a->limit);
+            FreeArenaList(pool, a, JS_TRUE);
+            return;
+        }
+    }
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaFreeAllocation(JSArenaPool *pool, void *p, size_t size)
+{
+    JSArena **ap, *a, *b;
+    jsuword q;
+
+    /*
+     * If the allocation is oversized, it consumes an entire arena, and it has
+     * a header just before the allocation pointing back to its predecessor's
+     * next member.  Otherwise, we have to search pool for a.
+     */
+    if (size > pool->arenasize) {
+        ap = *PTR_TO_HEADER(pool, p);
+        a = *ap;
+    } else {
+        q = (jsuword)p + size;
+        q = JS_ARENA_ALIGN(pool, q);
+        ap = &pool->first.next;
+        while ((a = *ap) != NULL) {
+            JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+
+            if (a->avail == q) {
+                /*
+                 * If a is consumed by the allocation at p, we can free it to
+                 * the malloc heap.
+                 */
+                if (a->base == (jsuword)p)
+                    break;
+
+                /*
+                 * We can't free a, but we can "retract" its avail cursor --
+                 * whether there are others after it in pool.
+                 */
+                a->avail = (jsuword)p;
+                return;
+            }
+            ap = &a->next;
+        }
+    }
+
+    /*
+     * At this point, a is doomed, so ensure that pool->current doesn't point
+     * at it.  We must preserve LIFO order of mark/release cursors, so we use
+     * the oversized-allocation arena's back pointer (or if not oversized, we
+     * use the result of searching the entire pool) to compute the address of
+     * the arena that precedes a.
+     */
+    if (pool->current == a)
+        pool->current = (JSArena *) ((char *)ap - offsetof(JSArena, next));
+
+    /*
+     * This is a non-LIFO deallocation, so take care to fix up a->next's back
+     * pointer in its header, if a->next is oversized.
+     */
+    *ap = b = a->next;
+    if (b && b->avail - b->base > pool->arenasize) {
+        JS_ASSERT(GET_HEADER(pool, b) == &a->next);
+        SET_HEADER(pool, b, ap);
+    }
+    JS_CLEAR_ARENA(a);
+    JS_COUNT_ARENA(pool,--);
+    free(a);
+}
+
+JS_PUBLIC_API(void)
+JS_FreeArenaPool(JSArenaPool *pool)
+{
+    FreeArenaList(pool, &pool->first, JS_FALSE);
+    COUNT(pool, ndeallocs);
+}
+
+JS_PUBLIC_API(void)
+JS_FinishArenaPool(JSArenaPool *pool)
+{
+    FreeArenaList(pool, &pool->first, JS_TRUE);
+#ifdef JS_ARENAMETER
+    {
+        JSArenaStats *stats, **statsp;
+
+        if (pool->stats.name)
+            free(pool->stats.name);
+        for (statsp = &arena_stats_list; (stats = *statsp) != 0;
+             statsp = &stats->next) {
+            if (stats == &pool->stats) {
+                *statsp = stats->next;
+                return;
+            }
+        }
+    }
+#endif
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaFinish()
+{
+    JSArena *a, *next;
+
+    JS_ACQUIRE_LOCK(arena_freelist_lock);
+    a = arena_freelist;
+    arena_freelist = NULL;
+    JS_RELEASE_LOCK(arena_freelist_lock);
+    for (; a; a = next) {
+        next = a->next;
+        free(a);
+    }
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaShutDown(void)
+{
+#ifdef JS_THREADSAFE
+    /* Must come through here once in the process's last thread! */
+    if (arena_freelist_lock) {
+        JS_DESTROY_LOCK(arena_freelist_lock);
+        arena_freelist_lock = NULL;
+    }
+#endif
+}
+
+#ifdef JS_ARENAMETER
+JS_PUBLIC_API(void)
+JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb)
+{
+    pool->stats.nallocs++;
+    pool->stats.nbytes += nb;
+    if (nb > pool->stats.maxalloc)
+        pool->stats.maxalloc = nb;
+    pool->stats.variance += nb * nb;
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr)
+{
+    pool->stats.ninplace++;
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t 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;
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaCountRelease(JSArenaPool *pool, char *mark)
+{
+    pool->stats.nreleases++;
+}
+
+JS_PUBLIC_API(void)
+JS_ArenaCountRetract(JSArenaPool *pool, char *mark)
+{
+    pool->stats.nfastrels++;
+}
+
+#include <math.h>
+#include <stdio.h>
+
+JS_PUBLIC_API(void)
+JS_DumpArenaStats(FILE *fp)
+{
+    JSArenaStats *stats;
+    uint32 nallocs, nbytes;
+    double mean, variance, sigma;
+
+    for (stats = arena_stats_list; stats; stats = stats->next) {
+        nallocs = stats->nallocs;
+        if (nallocs != 0) {
+            nbytes = stats->nbytes;
+            mean = (double)nbytes / nallocs;
+            variance = stats->variance * nallocs - nbytes * nbytes;
+            if (variance < 0 || nallocs == 1)
+                variance = 0;
+            else
+                variance /= nallocs * (nallocs - 1);
+            sigma = sqrt(variance);
+        } else {
+            mean = variance = sigma = 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 realloc'ing growths: %u\n", stats->nreallocs);
+        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", sigma);
+        fprintf(fp, "       maximum allocation size: %u\n", stats->maxalloc);
+    }
+}
+#endif /* JS_ARENAMETER */

Added: freeswitch/trunk/libs/js/src/jsarena.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsarena.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,311 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsarena_h___
+#define jsarena_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 (JS_ARENA_MARK/JS_ARENA_RELEASE).
+ */
+#include <stdlib.h>
+#include "jstypes.h"
+#include "jscompat.h"
+
+JS_BEGIN_EXTERN_C
+
+typedef struct JSArena JSArena;
+typedef struct JSArenaPool JSArenaPool;
+
+struct JSArena {
+    JSArena     *next;          /* next arena for this lifetime */
+    jsuword     base;           /* aligned base address, follows this header */
+    jsuword     limit;          /* one beyond last byte in arena */
+    jsuword     avail;          /* points to next available byte */
+};
+
+#ifdef JS_ARENAMETER
+typedef struct JSArenaStats JSArenaStats;
+
+struct JSArenaStats {
+    JSArenaStats *next;         /* next in arenaStats list */
+    char        *name;          /* name for debugging */
+    uint32      narenas;        /* number of arenas in pool */
+    uint32      nallocs;        /* number of JS_ARENA_ALLOCATE() calls */
+    uint32      nreclaims;      /* number of reclaims from freeArenas */
+    uint32      nmallocs;       /* number of malloc() calls */
+    uint32      ndeallocs;      /* number of lifetime deallocations */
+    uint32      ngrows;         /* number of JS_ARENA_GROW() calls */
+    uint32      ninplace;       /* number of in-place growths */
+    uint32      nreallocs;      /* number of arena grow extending reallocs */
+    uint32      nreleases;      /* number of JS_ARENA_RELEASE() calls */
+    uint32      nfastrels;      /* number of "fast path" releases */
+    size_t      nbytes;         /* total bytes allocated */
+    size_t      maxalloc;       /* maximum allocation size in bytes */
+    double      variance;       /* size variance accumulator */
+};
+#endif
+
+struct JSArenaPool {
+    JSArena     first;          /* first arena in pool list */
+    JSArena     *current;       /* arena from which to allocate space */
+    size_t      arenasize;      /* net exact size of a new arena */
+    jsuword     mask;           /* alignment mask (power-of-2 - 1) */
+#ifdef JS_ARENAMETER
+    JSArenaStats stats;
+#endif
+};
+
+/*
+ * If the including .c file uses only one power-of-2 alignment, it may define
+ * JS_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions
+ * per ALLOCATE and GROW.
+ */
+#ifdef JS_ARENA_CONST_ALIGN_MASK
+#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + JS_ARENA_CONST_ALIGN_MASK)   \
+                                 & ~(jsuword)JS_ARENA_CONST_ALIGN_MASK)
+
+#define JS_INIT_ARENA_POOL(pool, name, size) \
+        JS_InitArenaPool(pool, name, size, JS_ARENA_CONST_ALIGN_MASK + 1)
+#else
+#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->mask)
+#endif
+
+#define JS_ARENA_ALLOCATE(p, pool, nb)                                        \
+    JS_ARENA_ALLOCATE_CAST(p, void *, pool, nb)
+
+#define JS_ARENA_ALLOCATE_TYPE(p, type, pool)                                 \
+    JS_ARENA_ALLOCATE_CAST(p, type *, pool, sizeof(type))
+
+/*
+ *
+ * NB: In JS_ARENA_ALLOCATE_CAST and JS_ARENA_GROW_CAST, always subtract _nb
+ * from a->limit rather than adding _nb to _p, to avoid overflowing a 32-bit
+ * address space (possible when running a 32-bit program on a 64-bit system
+ * where the kernel maps the heap up against the top of the 32-bit address
+ * space).
+ *
+ * Thanks to Juergen Kreileder <jk at blackdown.de>, who brought this up in
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=279273.
+ */
+#define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb)                             \
+    JS_BEGIN_MACRO                                                            \
+        JSArena *_a = (pool)->current;                                        \
+        size_t _nb = JS_ARENA_ALIGN(pool, nb);                                \
+        jsuword _p = _a->avail;                                               \
+        if (_p > _a->limit - _nb)                                             \
+            _p = (jsuword)JS_ArenaAllocate(pool, _nb);                        \
+        else                                                                  \
+            _a->avail = _p + _nb;                                             \
+        p = (type) _p;                                                        \
+        JS_ArenaCountAllocation(pool, nb);                                    \
+    JS_END_MACRO
+
+#define JS_ARENA_GROW(p, pool, size, incr)                                    \
+    JS_ARENA_GROW_CAST(p, void *, pool, size, incr)
+
+#define JS_ARENA_GROW_CAST(p, type, pool, size, incr)                         \
+    JS_BEGIN_MACRO                                                            \
+        JSArena *_a = (pool)->current;                                        \
+        if (_a->avail == (jsuword)(p) + JS_ARENA_ALIGN(pool, size)) {         \
+            size_t _nb = (size) + (incr);                                     \
+            _nb = JS_ARENA_ALIGN(pool, _nb);                                  \
+            if ((jsuword)(p) <= _a->limit - _nb) {                            \
+                _a->avail = (jsuword)(p) + _nb;                               \
+                JS_ArenaCountInplaceGrowth(pool, size, incr);                 \
+            } else if ((jsuword)(p) == _a->base) {                            \
+                p = (type) JS_ArenaRealloc(pool, p, size, incr);              \
+            } else {                                                          \
+                p = (type) JS_ArenaGrow(pool, p, size, incr);                 \
+            }                                                                 \
+        } else {                                                              \
+            p = (type) JS_ArenaGrow(pool, p, size, incr);                     \
+        }                                                                     \
+        JS_ArenaCountGrowth(pool, size, incr);                                \
+    JS_END_MACRO
+
+#define JS_ARENA_MARK(pool)     ((void *) (pool)->current->avail)
+#define JS_UPTRDIFF(p,q)        ((jsuword)(p) - (jsuword)(q))
+
+#ifdef DEBUG
+#define JS_FREE_PATTERN         0xDA
+#define JS_CLEAR_UNUSED(a)      (JS_ASSERT((a)->avail <= (a)->limit),         \
+                                 memset((void*)(a)->avail, JS_FREE_PATTERN,   \
+                                        (a)->limit - (a)->avail))
+#define JS_CLEAR_ARENA(a)       memset((void*)(a), JS_FREE_PATTERN,           \
+                                       (a)->limit - (jsuword)(a))
+#else
+#define JS_CLEAR_UNUSED(a)      /* nothing */
+#define JS_CLEAR_ARENA(a)       /* nothing */
+#endif
+
+#define JS_ARENA_RELEASE(pool, mark)                                          \
+    JS_BEGIN_MACRO                                                            \
+        char *_m = (char *)(mark);                                            \
+        JSArena *_a = (pool)->current;                                        \
+        if (_a != &(pool)->first &&                                           \
+            JS_UPTRDIFF(_m, _a->base) <= JS_UPTRDIFF(_a->avail, _a->base)) {  \
+            _a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m);                    \
+            JS_ASSERT(_a->avail <= _a->limit);                                \
+            JS_CLEAR_UNUSED(_a);                                              \
+            JS_ArenaCountRetract(pool, _m);                                   \
+        } else {                                                              \
+            JS_ArenaRelease(pool, _m);                                        \
+        }                                                                     \
+        JS_ArenaCountRelease(pool, _m);                                       \
+    JS_END_MACRO
+
+#ifdef JS_ARENAMETER
+#define JS_COUNT_ARENA(pool,op) ((pool)->stats.narenas op)
+#else
+#define JS_COUNT_ARENA(pool,op)
+#endif
+
+#define JS_ARENA_DESTROY(pool, a, pnext)                                      \
+    JS_BEGIN_MACRO                                                            \
+        JS_COUNT_ARENA(pool,--);                                              \
+        if ((pool)->current == (a)) (pool)->current = &(pool)->first;         \
+        *(pnext) = (a)->next;                                                 \
+        JS_CLEAR_ARENA(a);                                                    \
+        free(a);                                                              \
+        (a) = NULL;                                                           \
+    JS_END_MACRO
+
+/*
+ * Initialize an arena pool with the given name for debugging and metering,
+ * with a minimum size per arena of size bytes.
+ */
+extern JS_PUBLIC_API(void)
+JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,
+                 size_t align);
+
+/*
+ * Free the arenas in pool.  The user may continue to allocate from pool
+ * after calling this function.  There is no need to call JS_InitArenaPool()
+ * again unless JS_FinishArenaPool(pool) has been called.
+ */
+extern JS_PUBLIC_API(void)
+JS_FreeArenaPool(JSArenaPool *pool);
+
+/*
+ * Free the arenas in pool and finish using it altogether.
+ */
+extern JS_PUBLIC_API(void)
+JS_FinishArenaPool(JSArenaPool *pool);
+
+/*
+ * Finish using arenas, freeing all memory associated with them except for
+ * any locks needed for thread safety.
+ */
+extern JS_PUBLIC_API(void)
+JS_ArenaFinish(void);
+
+/*
+ * Free any locks or other memory needed for thread safety, just before
+ * shutting down.  At that point, we must be called by a single thread.
+ *
+ * After shutting down, the next thread to call JS_InitArenaPool must not
+ * race with any other thread.  Once a pool has been initialized, threads
+ * may safely call jsarena.c functions on thread-local pools.  The upshot
+ * is that pools are per-thread, but the underlying global freelist is
+ * thread-safe, provided that both the first pool initialization and the
+ * shut-down call are single-threaded.
+ */
+extern JS_PUBLIC_API(void)
+JS_ArenaShutDown(void);
+
+/*
+ * Friend functions used by the JS_ARENA_*() macros.
+ */
+extern JS_PUBLIC_API(void *)
+JS_ArenaAllocate(JSArenaPool *pool, size_t nb);
+
+extern JS_PUBLIC_API(void *)
+JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr);
+
+extern JS_PUBLIC_API(void *)
+JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr);
+
+extern JS_PUBLIC_API(void)
+JS_ArenaRelease(JSArenaPool *pool, char *mark);
+
+/*
+ * Function to be used directly when an allocation has likely grown to consume
+ * an entire JSArena, in which case the arena is returned to the malloc heap.
+ */
+extern JS_PUBLIC_API(void)
+JS_ArenaFreeAllocation(JSArenaPool *pool, void *p, size_t size);
+
+#ifdef JS_ARENAMETER
+
+#include <stdio.h>
+
+extern JS_PUBLIC_API(void)
+JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb);
+
+extern JS_PUBLIC_API(void)
+JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr);
+
+extern JS_PUBLIC_API(void)
+JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr);
+
+extern JS_PUBLIC_API(void)
+JS_ArenaCountRelease(JSArenaPool *pool, char *mark);
+
+extern JS_PUBLIC_API(void)
+JS_ArenaCountRetract(JSArenaPool *pool, char *mark);
+
+extern JS_PUBLIC_API(void)
+JS_DumpArenaStats(FILE *fp);
+
+#else  /* !JS_ARENAMETER */
+
+#define JS_ArenaCountAllocation(ap, nb)                 /* nothing */
+#define JS_ArenaCountInplaceGrowth(ap, size, incr)      /* nothing */
+#define JS_ArenaCountGrowth(ap, size, incr)             /* nothing */
+#define JS_ArenaCountRelease(ap, mark)                  /* nothing */
+#define JS_ArenaCountRetract(ap, mark)                  /* nothing */
+
+#endif /* !JS_ARENAMETER */
+
+JS_END_EXTERN_C
+
+#endif /* jsarena_h___ */

Added: freeswitch/trunk/libs/js/src/jsarray.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsarray.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1829 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set sw=4 ts=8 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS array class.
+ */
+#include "jsstddef.h"
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsapi.h"
+#include "jsarray.h"
+#include "jsatom.h"
+#include "jsbool.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsfun.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsstr.h"
+
+/* 2^32 - 1 as a number and a string */
+#define MAXINDEX 4294967295u
+#define MAXSTR   "4294967295"
+
+/* A useful value for identifying a hole in an array */
+#define JSVAL_HOLE BOOLEAN_TO_JSVAL(2)
+
+/*
+ * Determine if the id represents an array index or an XML property index.
+ *
+ * An id is an array index according to ECMA by (15.4):
+ *
+ * "Array objects give special treatment to a certain class of property names.
+ * A property name P (in the form of a string value) is an array index if and
+ * only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal
+ * to 2^32-1."
+ *
+ * In our implementation, it would be sufficient to check for JSVAL_IS_INT(id)
+ * except that by using signed 32-bit integers we miss the top half of the
+ * valid range. This function checks the string representation itself; note
+ * that calling a standard conversion routine might allow strings such as
+ * "08" or "4.0" as array indices, which they are not.
+ */
+JSBool
+js_IdIsIndex(jsval id, jsuint *indexp)
+{
+    JSString *str;
+    jschar *cp;
+
+    if (JSVAL_IS_INT(id)) {
+        jsint i;
+        i = JSVAL_TO_INT(id);
+        if (i < 0)
+            return JS_FALSE;
+        *indexp = (jsuint)i;
+        return JS_TRUE;
+    }
+
+    /* NB: id should be a string, but jsxml.c may call us with an object id. */
+    if (!JSVAL_IS_STRING(id))
+        return JS_FALSE;
+
+    str = JSVAL_TO_STRING(id);
+    cp = JSSTRING_CHARS(str);
+    if (JS7_ISDEC(*cp) && JSSTRING_LENGTH(str) < sizeof(MAXSTR)) {
+        jsuint index = JS7_UNDEC(*cp++);
+        jsuint oldIndex = 0;
+        jsuint c = 0;
+        if (index != 0) {
+            while (JS7_ISDEC(*cp)) {
+                oldIndex = index;
+                c = JS7_UNDEC(*cp);
+                index = 10*index + c;
+                cp++;
+            }
+        }
+
+        /* Ensure that all characters were consumed and we didn't overflow. */
+        if (*cp == 0 &&
+             (oldIndex < (MAXINDEX / 10) ||
+              (oldIndex == (MAXINDEX / 10) && c < (MAXINDEX % 10))))
+        {
+            *indexp = index;
+            return JS_TRUE;
+        }
+    }
+    return JS_FALSE;
+}
+
+static JSBool
+ValueIsLength(JSContext *cx, jsval v, jsuint *lengthp)
+{
+    jsint i;
+    jsdouble d;
+
+    if (JSVAL_IS_INT(v)) {
+        i = JSVAL_TO_INT(v);
+        if (i < 0) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_BAD_ARRAY_LENGTH);
+            return JS_FALSE;
+        }
+        *lengthp = (jsuint) i;
+        return JS_TRUE;
+    }
+
+    if (!js_ValueToNumber(cx, v, &d)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_ARRAY_LENGTH);
+        return JS_FALSE;
+    }
+    if (!js_DoubleToECMAUint32(cx, d, (uint32 *)lengthp)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_ARRAY_LENGTH);
+        return JS_FALSE;
+    }
+    if (JSDOUBLE_IS_NaN(d) || d != *lengthp) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_ARRAY_LENGTH);
+        return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+JSBool
+js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
+{
+    jsid id;
+    jsint i;
+    jsval v;
+
+    id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
+    if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
+        return JS_FALSE;
+
+    /* Short-circuit, because js_ValueToECMAUint32 fails when
+     * called during init time.
+     */
+    if (JSVAL_IS_INT(v)) {
+        i = JSVAL_TO_INT(v);
+        /* jsuint cast does ToUint32. */
+        *lengthp = (jsuint)i;
+        return JS_TRUE;
+    }
+    return js_ValueToECMAUint32(cx, v, (uint32 *)lengthp);
+}
+
+static JSBool
+IndexToValue(JSContext *cx, jsuint index, jsval *vp)
+{
+    if (index <= JSVAL_INT_MAX) {
+        *vp = INT_TO_JSVAL(index);
+        return JS_TRUE;
+    }
+    return js_NewDoubleValue(cx, (jsdouble)index, vp);
+}
+
+static JSBool
+IndexToId(JSContext *cx, jsuint index, jsid *idp)
+{
+    JSString *str;
+    JSAtom *atom;
+
+    if (index <= JSVAL_INT_MAX) {
+        *idp = INT_TO_JSID(index);
+    } else {
+        str = js_NumberToString(cx, (jsdouble)index);
+        if (!str)
+            return JS_FALSE;
+        atom = js_AtomizeString(cx, str, 0);
+        if (!atom)
+            return JS_FALSE;
+        *idp = ATOM_TO_JSID(atom);
+
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+PropertyExists(JSContext *cx, JSObject *obj, jsid id, JSBool *foundp)
+{
+    JSObject *obj2;
+    JSProperty *prop;
+
+    if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
+        return JS_FALSE;
+
+    *foundp = prop != NULL;
+    if (*foundp) {
+        OBJ_DROP_PROPERTY(cx, obj2, prop);
+    }
+
+    return JS_TRUE;
+}
+
+#define JSID_HOLE       JSVAL_NULL
+
+static JSBool
+IndexToExistingId(JSContext *cx, JSObject *obj, jsuint index, jsid *idp)
+{
+    JSBool exists;
+
+    if (!IndexToId(cx, index, idp))
+        return JS_FALSE;
+    if (!PropertyExists(cx, obj, *idp, &exists))
+        return JS_FALSE;
+    if (!exists)
+        *idp = JSID_HOLE;
+    return JS_TRUE;
+}
+
+JSBool
+js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length)
+{
+    jsval v;
+    jsid id;
+
+    if (!IndexToValue(cx, length, &v))
+        return JS_FALSE;
+    id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
+    return OBJ_SET_PROPERTY(cx, obj, id, &v);
+}
+
+JSBool
+js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp)
+{
+    JSErrorReporter older;
+    jsid id;
+    JSBool ok;
+    jsval v;
+
+    older = JS_SetErrorReporter(cx, NULL);
+    id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
+    ok = OBJ_GET_PROPERTY(cx, obj, id, &v);
+    JS_SetErrorReporter(cx, older);
+    if (!ok)
+        return JS_FALSE;
+    return ValueIsLength(cx, v, lengthp);
+}
+
+/*
+ * This get function is specific to Array.prototype.length and other array
+ * instance length properties.  It calls back through the class get function
+ * in case some magic happens there (see call_getProperty in jsfun.c).
+ */
+static JSBool
+array_length_getter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    return OBJ_GET_CLASS(cx, obj)->getProperty(cx, obj, id, vp);
+}
+
+static JSBool
+array_length_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    jsuint newlen, oldlen, slot;
+    jsid id2;
+    jsval junk;
+
+    if (!ValueIsLength(cx, *vp, &newlen))
+        return JS_FALSE;
+    if (!js_GetLengthProperty(cx, obj, &oldlen))
+        return JS_FALSE;
+    slot = oldlen;
+    while (slot > newlen) {
+        --slot;
+        if (!IndexToId(cx, slot, &id2))
+            return JS_FALSE;
+        if (!OBJ_DELETE_PROPERTY(cx, obj, id2, &junk))
+            return JS_FALSE;
+    }
+    return IndexToValue(cx, newlen, vp);
+}
+
+static JSBool
+array_addProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    jsuint index, length;
+
+    if (!js_IdIsIndex(id, &index))
+        return JS_TRUE;
+    if (!js_GetLengthProperty(cx, obj, &length))
+        return JS_FALSE;
+    if (index >= length) {
+        length = index + 1;
+        return js_SetLengthProperty(cx, obj, length);
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+array_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
+{
+    jsuint length;
+
+    if (JS_VERSION_IS_1_2(cx)) {
+        if (!js_GetLengthProperty(cx, obj, &length))
+            return JS_FALSE;
+        switch (type) {
+          case JSTYPE_NUMBER:
+            return IndexToValue(cx, length, vp);
+          case JSTYPE_BOOLEAN:
+            *vp = BOOLEAN_TO_JSVAL(length > 0);
+            return JS_TRUE;
+          default:
+            return JS_TRUE;
+        }
+    }
+    return js_TryValueOf(cx, obj, type, vp);
+}
+
+JSClass js_ArrayClass = {
+    "Array",
+    0,
+    array_addProperty, JS_PropertyStub,   JS_PropertyStub,   JS_PropertyStub,
+    JS_EnumerateStub,  JS_ResolveStub,    array_convert,     JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+static JSBool
+array_join_sub(JSContext *cx, JSObject *obj, JSString *sep, JSBool literalize,
+               jsval *rval, JSBool localeString)
+{
+    JSBool ok;
+    jsuint length, index;
+    jschar *chars, *ochars;
+    size_t nchars, growth, seplen, tmplen;
+    const jschar *sepstr;
+    JSString *str;
+    JSHashEntry *he;
+    JSObject *obj2;
+    int stackDummy;
+
+    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
+        return JS_FALSE;
+    }
+
+    ok = js_GetLengthProperty(cx, obj, &length);
+    if (!ok)
+        return JS_FALSE;
+
+    he = js_EnterSharpObject(cx, obj, NULL, &chars);
+    if (!he)
+        return JS_FALSE;
+    if (literalize) {
+        if (IS_SHARP(he)) {
+#if JS_HAS_SHARP_VARS
+            nchars = js_strlen(chars);
+#else
+            chars[0] = '[';
+            chars[1] = ']';
+            chars[2] = 0;
+            nchars = 2;
+#endif
+            goto make_string;
+        }
+
+        /*
+         * Allocate 1 + 3 + 1 for "[", the worst-case closing ", ]", and the
+         * terminating 0.
+         */
+        growth = (1 + 3 + 1) * sizeof(jschar);
+        if (!chars) {
+            nchars = 0;
+            chars = (jschar *) malloc(growth);
+            if (!chars)
+                goto done;
+        } else {
+            MAKE_SHARP(he);
+            nchars = js_strlen(chars);
+            chars = (jschar *)
+                realloc((ochars = chars), nchars * sizeof(jschar) + growth);
+            if (!chars) {
+                free(ochars);
+                goto done;
+            }
+        }
+        chars[nchars++] = '[';
+    } else {
+        /*
+         * Free any sharp variable definition in chars.  Normally, we would
+         * MAKE_SHARP(he) so that only the first sharp variable annotation is
+         * a definition, and all the rest are references, but in the current
+         * case of (!literalize), we don't need chars at all.
+         */
+        if (chars)
+            JS_free(cx, chars);
+        chars = NULL;
+        nchars = 0;
+
+        /* Return the empty string on a cycle as well as on empty join. */
+        if (IS_BUSY(he) || length == 0) {
+            js_LeaveSharpObject(cx, NULL);
+            *rval = JS_GetEmptyStringValue(cx);
+            return ok;
+        }
+
+        /* Flag he as BUSY so we can distinguish a cycle from a join-point. */
+        MAKE_BUSY(he);
+    }
+    sepstr = NULL;
+    seplen = JSSTRING_LENGTH(sep);
+
+    /* Use rval to locally root each element value as we loop and convert. */
+#define v (*rval)
+
+    v = JSVAL_NULL;
+    for (index = 0; index < length; index++) {
+        ok = JS_GetElement(cx, obj, index, &v);
+        if (!ok)
+            goto done;
+
+        if ((!literalize || JS_VERSION_IS_1_2(cx)) &&
+            (JSVAL_IS_VOID(v) || JSVAL_IS_NULL(v))) {
+            str = cx->runtime->emptyString;
+        } else {
+            if (localeString) {
+                if (!js_ValueToObject(cx, v, &obj2) ||
+                    !js_TryMethod(cx, obj2,
+                                  cx->runtime->atomState.toLocaleStringAtom,
+                                  0, NULL, &v)) {
+                    str = NULL;
+                } else {
+                    str = js_ValueToString(cx, v);
+                }
+            } else {
+                str = (literalize ? js_ValueToSource : js_ValueToString)(cx, v);
+            }
+            if (!str) {
+                ok = JS_FALSE;
+                goto done;
+            }
+        }
+
+        /* Allocate 3 + 1 at end for ", ", closing bracket, and zero. */
+        growth = (nchars + (sepstr ? seplen : 0) +
+                  JSSTRING_LENGTH(str) +
+                  3 + 1) * sizeof(jschar);
+        if (!chars) {
+            chars = (jschar *) malloc(growth);
+            if (!chars)
+                goto done;
+        } else {
+            chars = (jschar *) realloc((ochars = chars), growth);
+            if (!chars) {
+                free(ochars);
+                goto done;
+            }
+        }
+
+        if (sepstr) {
+            js_strncpy(&chars[nchars], sepstr, seplen);
+            nchars += seplen;
+        }
+        sepstr = JSSTRING_CHARS(sep);
+
+        tmplen = JSSTRING_LENGTH(str);
+        js_strncpy(&chars[nchars], JSSTRING_CHARS(str), tmplen);
+        nchars += tmplen;
+    }
+
+  done:
+    if (literalize) {
+        if (chars) {
+            if (JSVAL_IS_VOID(v)) {
+                chars[nchars++] = ',';
+                chars[nchars++] = ' ';
+            }
+            chars[nchars++] = ']';
+        }
+    } else {
+        CLEAR_BUSY(he);
+    }
+    js_LeaveSharpObject(cx, NULL);
+    if (!ok) {
+        if (chars)
+            free(chars);
+        return ok;
+    }
+
+#undef v
+
+  make_string:
+    if (!chars) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+    chars[nchars] = 0;
+    str = js_NewString(cx, chars, nchars, 0);
+    if (!str) {
+        free(chars);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static jschar   comma_space_ucstr[] = {',', ' ', 0};
+static jschar   comma_ucstr[]       = {',', 0};
+static JSString comma_space         = {2, comma_space_ucstr};
+static JSString comma               = {1, comma_ucstr};
+
+#if JS_HAS_TOSOURCE
+static JSBool
+array_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    return array_join_sub(cx, obj, &comma_space, JS_TRUE, rval, JS_FALSE);
+}
+#endif
+
+static JSBool
+array_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    JSBool literalize;
+
+    /*
+     * JS1.2 arrays convert to array literals, with a comma followed by a space
+     * between each element.
+     */
+    literalize = JS_VERSION_IS_1_2(cx);
+    return array_join_sub(cx, obj, literalize ? &comma_space : &comma,
+                          literalize, rval, JS_FALSE);
+}
+
+static JSBool
+array_toLocaleString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    /*
+     *  Passing comma here as the separator. Need a way to get a
+     *  locale-specific version.
+     */
+    return array_join_sub(cx, obj, &comma, JS_FALSE, rval, JS_TRUE);
+}
+
+static JSBool
+InitArrayElements(JSContext *cx, JSObject *obj, jsuint length, jsval *vector)
+{
+    jsuint index;
+    jsid id;
+
+    for (index = 0; index < length; index++) {
+        JS_ASSERT(vector[index] != JSVAL_HOLE);
+
+        if (!IndexToId(cx, index, &id))
+            return JS_FALSE;
+        if (!OBJ_SET_PROPERTY(cx, obj, id, &vector[index]))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector)
+{
+    jsval v;
+    jsid id;
+
+    if (!IndexToValue(cx, length, &v))
+        return JS_FALSE;
+    id = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
+    if (!OBJ_DEFINE_PROPERTY(cx, obj, id, v,
+                             array_length_getter, array_length_setter,
+                             JSPROP_PERMANENT,
+                             NULL)) {
+          return JS_FALSE;
+    }
+    if (!vector)
+        return JS_TRUE;
+    return InitArrayElements(cx, obj, length, vector);
+}
+
+#if JS_HAS_SOME_PERL_FUN
+/*
+ * Perl-inspired join, reverse, and sort.
+ */
+static JSBool
+array_join(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+
+    if (JSVAL_IS_VOID(argv[0]))
+        return array_join_sub(cx, obj, &comma, JS_FALSE, rval, JS_FALSE);
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(str);
+    return array_join_sub(cx, obj, str, JS_FALSE, rval, JS_FALSE);
+}
+
+static JSBool
+array_reverse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    jsuint len, half, i;
+    jsid id, id2;
+    jsval *tmproot, *tmproot2;
+    JSBool idexists, id2exists;
+
+    if (!js_GetLengthProperty(cx, obj, &len))
+        return JS_FALSE;
+
+    /*
+     * Use argv[argc] and argv[argc + 1] as local roots to hold temporarily
+     * array elements for GC-safe swap.
+     */
+    tmproot = argv + argc;
+    tmproot2 = argv + argc + 1;
+    half = len / 2;
+    for (i = 0; i < half; i++) {
+        if (!IndexToId(cx, i, &id))
+            return JS_FALSE;
+        if (!IndexToId(cx, len - i - 1, &id2))
+            return JS_FALSE;
+
+        /* Check for holes to make sure they don't get filled. */
+        if (!PropertyExists(cx, obj, id, &idexists) ||
+            !PropertyExists(cx, obj, id2, &id2exists)) {
+            return JS_FALSE;
+        }
+
+        /*
+         * Get both of the values now. Note that we don't use v, or v2 based on
+         * idexists and id2exists.
+         */
+        if (!OBJ_GET_PROPERTY(cx, obj, id, tmproot) ||
+            !OBJ_GET_PROPERTY(cx, obj, id2, tmproot2)) {
+            return JS_FALSE;
+        }
+
+        if (idexists) {
+            if (!OBJ_SET_PROPERTY(cx, obj, id2, tmproot))
+                return JS_FALSE;
+        } else {
+            if (!OBJ_DELETE_PROPERTY(cx, obj, id2, tmproot))
+                return JS_FALSE;
+        }
+        if (id2exists) {
+            if (!OBJ_SET_PROPERTY(cx, obj, id, tmproot2))
+                return JS_FALSE;
+        } else {
+            if (!OBJ_DELETE_PROPERTY(cx, obj, id, tmproot2))
+                return JS_FALSE;
+        }
+    }
+
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+typedef struct HSortArgs {
+    void         *vec;
+    size_t       elsize;
+    void         *pivot;
+    JSComparator cmp;
+    void         *arg;
+    JSBool       fastcopy;
+} HSortArgs;
+
+static int
+sort_compare(const void *a, const void *b, void *arg);
+
+static int
+sort_compare_strings(const void *a, const void *b, void *arg);
+
+static void
+HeapSortHelper(JSBool building, HSortArgs *hsa, size_t lo, size_t hi)
+{
+    void *pivot, *vec, *vec2, *arg, *a, *b;
+    size_t elsize;
+    JSComparator cmp;
+    JSBool fastcopy;
+    size_t j, hiDiv2;
+
+    pivot = hsa->pivot;
+    vec = hsa->vec;
+    elsize = hsa->elsize;
+    vec2 =  (char *)vec - 2 * elsize;
+    cmp = hsa->cmp;
+    arg = hsa->arg;
+
+    fastcopy = hsa->fastcopy;
+#define MEMCPY(p,q,n) \
+    (fastcopy ? (void)(*(jsval*)(p) = *(jsval*)(q)) : (void)memcpy(p, q, n))
+
+    if (lo == 1) {
+        j = 2;
+        b = (char *)vec + elsize;
+        if (j < hi && cmp(vec, b, arg) < 0)
+            j++;
+        a = (char *)vec + (hi - 1) * elsize;
+        b = (char *)vec2 + j * elsize;
+
+        /*
+         * During sorting phase b points to a member of heap that cannot be
+         * bigger then biggest of vec[0] and vec[1], and cmp(a, b, arg) <= 0
+         * always holds.
+         */
+        if ((building || hi == 2) && cmp(a, b, arg) >= 0)
+            return;
+
+        MEMCPY(pivot, a, elsize);
+        MEMCPY(a, b, elsize);
+        lo = j;
+    } else {
+        a = (char *)vec2 + lo * elsize;
+        MEMCPY(pivot, a, elsize);
+    }
+
+    hiDiv2 = hi/2;
+    while (lo <= hiDiv2) {
+        j = lo + lo;
+        a = (char *)vec2 + j * elsize;
+        b = (char *)vec + (j - 1) * elsize;
+        if (j < hi && cmp(a, b, arg) < 0)
+            j++;
+        b = (char *)vec2 + j * elsize;
+        if (cmp(pivot, b, arg) >= 0)
+            break;
+
+        a = (char *)vec2 + lo * elsize;
+        MEMCPY(a, b, elsize);
+        lo = j;
+    }
+
+    a = (char *)vec2 + lo * elsize;
+    MEMCPY(a, pivot, elsize);
+#undef MEMCPY
+}
+
+void
+js_HeapSort(void *vec, size_t nel, void *pivot, size_t elsize,
+            JSComparator cmp, void *arg)
+{
+    HSortArgs hsa;
+    size_t i;
+
+    hsa.vec = vec;
+    hsa.elsize = elsize;
+    hsa.pivot = pivot;
+    hsa.cmp = cmp;
+    hsa.arg = arg;
+    hsa.fastcopy = (cmp == sort_compare || cmp == sort_compare_strings);
+
+    for (i = nel/2; i != 0; i--)
+        HeapSortHelper(JS_TRUE, &hsa, i, nel);
+    while (nel > 2)
+        HeapSortHelper(JS_FALSE, &hsa, 1, --nel);
+}
+
+typedef struct CompareArgs {
+    JSContext   *context;
+    jsval       fval;
+    jsval       *localroot;     /* need one local root, for sort_compare */
+    JSBool      status;
+} CompareArgs;
+
+static int
+sort_compare(const void *a, const void *b, void *arg)
+{
+    jsval av = *(const jsval *)a, bv = *(const jsval *)b;
+    CompareArgs *ca = (CompareArgs *) arg;
+    JSContext *cx = ca->context;
+    jsdouble cmp = -1;
+    jsval fval, argv[2], rval, special;
+    JSBool ok;
+
+    fval = ca->fval;
+
+    /*
+     * By ECMA 262, 15.4.4.11, existence of the property with value undefined
+     * takes precedence over an undefined property (which we call a "hole").
+     */
+    if (av == JSVAL_HOLE || bv == JSVAL_HOLE)
+        special = JSVAL_HOLE;
+    else if (av == JSVAL_VOID || bv == JSVAL_VOID)
+        special = JSVAL_VOID;
+    else
+        special = JSVAL_NULL;
+
+    if (special != JSVAL_NULL) {
+        if (av == bv)
+            cmp = 0;
+        else if (av != special)
+            cmp = -1;
+        else
+            cmp = 1;
+    } else if (fval == JSVAL_NULL) {
+        JSString *astr, *bstr;
+
+        if (av == bv) {
+            cmp = 0;
+        } else {
+            /*
+             * Set our local root to astr in case the second js_ValueToString
+             * displaces the newborn root in cx, and the GC nests under that
+             * call.  Don't bother guarding the local root store with an astr
+             * non-null test.  If we tag null as a string, the GC will untag,
+             * null-test, and avoid dereferencing null.
+             */
+            astr = js_ValueToString(cx, av);
+            *ca->localroot = STRING_TO_JSVAL(astr);
+            if (astr && (bstr = js_ValueToString(cx, bv)))
+                cmp = js_CompareStrings(astr, bstr);
+            else
+                ca->status = JS_FALSE;
+        }
+    } else {
+        argv[0] = av;
+        argv[1] = bv;
+        ok = js_InternalCall(cx,
+                             OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fval)),
+                             fval, 2, argv, &rval);
+        if (ok) {
+            ok = js_ValueToNumber(cx, rval, &cmp);
+
+            /* Clamp cmp to -1, 0, 1. */
+            if (ok) {
+                if (JSDOUBLE_IS_NaN(cmp)) {
+                    /*
+                     * XXX report some kind of error here?  ECMA talks about
+                     * 'consistent compare functions' that don't return NaN,
+                     * but is silent about what the result should be.  So we
+                     * currently ignore it.
+                     */
+                    cmp = 0;
+                } else if (cmp != 0) {
+                    cmp = cmp > 0 ? 1 : -1;
+                }
+            }
+        }
+        if (!ok)
+            ca->status = ok;
+    }
+    return (int)cmp;
+}
+
+static int
+sort_compare_strings(const void *a, const void *b, void *arg)
+{
+    jsval av = *(const jsval *)a, bv = *(const jsval *)b;
+
+    return (int) js_CompareStrings(JSVAL_TO_STRING(av), JSVAL_TO_STRING(bv));
+}
+
+static JSBool
+array_sort(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval fval, *vec, *pivotroot;
+    CompareArgs ca;
+    jsuint len, newlen, i;
+    JSStackFrame *fp;
+    jsid id;
+    size_t nbytes;
+
+    /*
+     * Optimize the default compare function case if all of obj's elements
+     * have values of type string.
+     */
+    JSBool all_strings;
+
+    if (argc > 0) {
+        if (JSVAL_IS_PRIMITIVE(argv[0])) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_BAD_SORT_ARG);
+            return JS_FALSE;
+        }
+        fval = argv[0];
+        all_strings = JS_FALSE; /* non-default compare function */
+    } else {
+        fval = JSVAL_NULL;
+        all_strings = JS_TRUE;  /* check for all string values */
+    }
+
+    if (!js_GetLengthProperty(cx, obj, &len))
+        return JS_FALSE;
+    if (len == 0) {
+        *rval = OBJECT_TO_JSVAL(obj);
+        return JS_TRUE;
+    }
+
+    /*
+     * We need a temporary array of len jsvals to hold elements of the array.
+     * Check that its size does not overflow size_t, which would allow for
+     * indexing beyond the end of the malloc'd vector.
+     */
+    if (len > ((size_t) -1) / sizeof(jsval)) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+    nbytes = ((size_t) len) * sizeof(jsval);
+
+    vec = (jsval *) JS_malloc(cx, nbytes);
+    if (!vec)
+        return JS_FALSE;
+
+    /* Root vec, clearing it first in case a GC nests while we're filling it. */
+    memset(vec, 0, nbytes);
+    fp = cx->fp;
+    fp->vars = vec;
+    fp->nvars = len;
+
+    newlen = 0;
+    for (i = 0; i < len; i++) {
+        ca.status = IndexToExistingId(cx, obj, i, &id);
+        if (!ca.status)
+            goto out;
+
+        if (id == JSID_HOLE) {
+            vec[i] = JSVAL_HOLE;
+            all_strings = JS_FALSE;
+            continue;
+        }
+        newlen++;
+
+        ca.status = OBJ_GET_PROPERTY(cx, obj, id, &vec[i]);
+        if (!ca.status)
+            goto out;
+
+        /* We know JSVAL_IS_STRING yields 0 or 1, so avoid a branch via &=. */
+        all_strings &= JSVAL_IS_STRING(vec[i]);
+    }
+
+    ca.context = cx;
+    ca.fval = fval;
+    ca.localroot = argv + argc;       /* local GC root for temporary string */
+    pivotroot    = argv + argc + 1;   /* local GC root for pivot val */
+    ca.status = JS_TRUE;
+    js_HeapSort(vec, (size_t) len, pivotroot, sizeof(jsval),
+                all_strings ? sort_compare_strings : sort_compare,
+                &ca);
+
+    if (ca.status) {
+        ca.status = InitArrayElements(cx, obj, newlen, vec);
+        if (ca.status)
+            *rval = OBJECT_TO_JSVAL(obj);
+
+        /* Re-create any holes that sorted to the end of the array. */
+        while (len > newlen) {
+            jsval junk;
+
+            if (!IndexToId(cx, --len, &id))
+                return JS_FALSE;
+            if (!OBJ_DELETE_PROPERTY(cx, obj, id, &junk))
+                return JS_FALSE;
+        }
+    }
+
+out:
+    if (vec)
+        JS_free(cx, vec);
+    return ca.status;
+}
+#endif /* JS_HAS_SOME_PERL_FUN */
+
+#if JS_HAS_MORE_PERL_FUN
+/*
+ * Perl-inspired push, pop, shift, unshift, and splice methods.
+ */
+static JSBool
+array_push(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsuint length;
+    uintN i;
+    jsid id;
+
+    if (!js_GetLengthProperty(cx, obj, &length))
+        return JS_FALSE;
+    for (i = 0; i < argc; i++) {
+        if (!IndexToId(cx, length + i, &id))
+            return JS_FALSE;
+        if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))
+            return JS_FALSE;
+    }
+
+    /*
+     * If JS1.2, follow Perl4 by returning the last thing pushed.  Otherwise,
+     * return the new array length.
+     */
+    length += argc;
+    if (JS_VERSION_IS_1_2(cx)) {
+        *rval = argc ? argv[argc-1] : JSVAL_VOID;
+    } else {
+        if (!IndexToValue(cx, length, rval))
+            return JS_FALSE;
+    }
+    return js_SetLengthProperty(cx, obj, length);
+}
+
+static JSBool
+array_pop(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsuint index;
+    jsid id;
+    jsval junk;
+
+    if (!js_GetLengthProperty(cx, obj, &index))
+        return JS_FALSE;
+    if (index > 0) {
+        index--;
+        if (!IndexToId(cx, index, &id))
+            return JS_FALSE;
+
+        /* Get the to-be-deleted property's value into rval. */
+        if (!OBJ_GET_PROPERTY(cx, obj, id, rval))
+            return JS_FALSE;
+
+        if (!OBJ_DELETE_PROPERTY(cx, obj, id, &junk))
+            return JS_FALSE;
+    }
+    return js_SetLengthProperty(cx, obj, index);
+}
+
+static JSBool
+array_shift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsuint length, i;
+    jsid id, id2;
+    jsval junk;
+
+    if (!js_GetLengthProperty(cx, obj, &length))
+        return JS_FALSE;
+    if (length > 0) {
+        length--;
+        id = JSVAL_ZERO;
+
+        /* Get the to-be-deleted property's value into rval ASAP. */
+        if (!OBJ_GET_PROPERTY(cx, obj, id, rval))
+            return JS_FALSE;
+
+        /*
+         * Slide down the array above the first element.
+         */
+        if (length > 0) {
+            for (i = 1; i <= length; i++) {
+                if (!IndexToId(cx, i, &id))
+                    return JS_FALSE;
+                if (!IndexToId(cx, i - 1, &id2))
+                    return JS_FALSE;
+                if (!OBJ_GET_PROPERTY(cx, obj, id, &argv[0]))
+                    return JS_FALSE;
+                if (!OBJ_SET_PROPERTY(cx, obj, id2, &argv[0]))
+                    return JS_FALSE;
+            }
+        }
+
+        /* Delete the only or last element. */
+        if (!OBJ_DELETE_PROPERTY(cx, obj, id, &junk))
+            return JS_FALSE;
+    }
+    return js_SetLengthProperty(cx, obj, length);
+}
+
+static JSBool
+array_unshift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    jsuint length, last;
+    uintN i;
+    jsid id, id2;
+    jsval *vp, junk;
+
+    if (!js_GetLengthProperty(cx, obj, &length))
+        return JS_FALSE;
+    if (argc > 0) {
+        /* Slide up the array to make room for argc at the bottom. */
+        if (length > 0) {
+            last = length;
+            vp = argv + argc;
+            while (last--) {
+                if (!IndexToExistingId(cx, obj, last, &id))
+                    return JS_FALSE;
+                if (id == JSID_HOLE) {
+                    OBJ_DELETE_PROPERTY(cx, obj, id2, &junk);
+                    continue;
+                }
+                if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
+                    return JS_FALSE;
+                if (!IndexToId(cx, last + argc, &id2))
+                    return JS_FALSE;
+                if (!OBJ_SET_PROPERTY(cx, obj, id2, vp))
+                    return JS_FALSE;
+            }
+        }
+
+        /* Copy from argv to the bottom of the array. */
+        for (i = 0; i < argc; i++) {
+            if (!IndexToId(cx, i, &id))
+                return JS_FALSE;
+            if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))
+                return JS_FALSE;
+        }
+
+        /* Follow Perl by returning the new array length. */
+        length += argc;
+        if (!js_SetLengthProperty(cx, obj, length))
+            return JS_FALSE;
+    }
+    return IndexToValue(cx, length, rval);
+}
+
+static JSBool
+array_splice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval *vp, junk;
+    jsuint length, begin, end, count, delta, last;
+    jsdouble d;
+    jsid id, id2;
+    JSObject *obj2;
+    uintN i;
+
+    /*
+     * Nothing to do if no args.  Otherwise point vp at our one explicit local
+     * root and get length.
+     */
+    if (argc == 0)
+        return JS_TRUE;
+    vp = argv + argc;
+    if (!js_GetLengthProperty(cx, obj, &length))
+        return JS_FALSE;
+
+    /* Convert the first argument into a starting index. */
+    if (!js_ValueToNumber(cx, *argv, &d))
+        return JS_FALSE;
+    d = js_DoubleToInteger(d);
+    if (d < 0) {
+        d += length;
+        if (d < 0)
+            d = 0;
+    } else if (d > length) {
+        d = length;
+    }
+    begin = (jsuint)d; /* d has been clamped to uint32 */
+    argc--;
+    argv++;
+
+    /* Convert the second argument from a count into a fencepost index. */
+    delta = length - begin;
+    if (argc == 0) {
+        count = delta;
+        end = length;
+    } else {
+        if (!js_ValueToNumber(cx, *argv, &d))
+            return JS_FALSE;
+        d = js_DoubleToInteger(d);
+        if (d < 0)
+            d = 0;
+        else if (d > delta)
+            d = delta;
+        count = (jsuint)d;
+        end = begin + count;
+        argc--;
+        argv++;
+    }
+
+    if (count == 1 && JS_VERSION_IS_1_2(cx)) {
+        /*
+         * JS lacks "list context", whereby in Perl one turns the single
+         * scalar that's spliced out into an array just by assigning it to
+         * @single instead of $single, or by using it as Perl push's first
+         * argument, for instance.
+         *
+         * JS1.2 emulated Perl too closely and returned a non-Array for
+         * the single-splice-out case, requiring callers to test and wrap
+         * in [] if necessary.  So JS1.3, default, and other versions all
+         * return an array of length 1 for uniformity.
+         */
+        if (!IndexToId(cx, begin, &id))
+            return JS_FALSE;
+        if (!OBJ_GET_PROPERTY(cx, obj, id, rval))
+            return JS_FALSE;
+    } else {
+        if (!JS_VERSION_IS_1_2(cx) || count > 0) {
+            /*
+             * Create a new array value to return.  Our ECMA v2 proposal specs
+             * that splice always returns an array value, even when given no
+             * arguments.  We think this is best because it eliminates the need
+             * for callers to do an extra test to handle the empty splice case.
+             */
+            obj2 = js_NewArrayObject(cx, 0, NULL);
+            if (!obj2)
+                return JS_FALSE;
+            *rval = OBJECT_TO_JSVAL(obj2);
+
+            /* If there are elements to remove, put them into the return value. */
+            if (count > 0) {
+                for (last = begin; last < end; last++) {
+                    if (!IndexToExistingId(cx, obj, last, &id))
+                        return JS_FALSE;
+                    if (id == JSID_HOLE)
+                        continue;       /* don't fill holes in the new array */
+                    if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
+                        return JS_FALSE;
+                    if (!IndexToId(cx, last - begin, &id2))
+                        return JS_FALSE;
+                    if (!OBJ_SET_PROPERTY(cx, obj2, id2, vp))
+                        return JS_FALSE;
+                }
+
+                if (!js_SetLengthProperty(cx, obj2, end - begin))
+                    return JS_FALSE;
+            }
+        }
+    }
+
+    /* Find the direction (up or down) to copy and make way for argv. */
+    if (argc > count) {
+        delta = (jsuint)argc - count;
+        last = length;
+        /* (uint) end could be 0, so can't use vanilla >= test */
+        while (last-- > end) {
+            if (!IndexToExistingId(cx, obj, last, &id))
+                return JS_FALSE;
+            if (!IndexToId(cx, last + delta, &id2))
+                return JS_FALSE;
+            if (id != JSID_HOLE) {
+                if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
+                    return JS_FALSE;
+                if (!OBJ_SET_PROPERTY(cx, obj, id2, vp))
+                    return JS_FALSE;
+            } else {
+                if (!OBJ_DELETE_PROPERTY(cx, obj, id2, &junk))
+                    return JS_FALSE;
+            }
+        }
+        length += delta;
+    } else if (argc < count) {
+        delta = count - (jsuint)argc;
+        for (last = end; last < length; last++) {
+            if (!IndexToExistingId(cx, obj, last, &id))
+                return JS_FALSE;
+            if (!IndexToId(cx, last - delta, &id2))
+                return JS_FALSE;
+            if (id != JSID_HOLE) {
+                if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
+                    return JS_FALSE;
+                if (!OBJ_SET_PROPERTY(cx, obj, id2, vp))
+                    return JS_FALSE;
+            } else {
+                if (!OBJ_DELETE_PROPERTY(cx, obj, id2, &junk))
+                    return JS_FALSE;
+            }
+        }
+        length -= delta;
+    }
+
+    /* Copy from argv into the hole to complete the splice. */
+    for (i = 0; i < argc; i++) {
+        if (!IndexToId(cx, begin + i, &id))
+            return JS_FALSE;
+        if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i]))
+            return JS_FALSE;
+    }
+
+    /* Update length in case we deleted elements from the end. */
+    return js_SetLengthProperty(cx, obj, length);
+}
+#endif /* JS_HAS_MORE_PERL_FUN */
+
+#if JS_HAS_SEQUENCE_OPS
+/*
+ * Python-esque sequence operations.
+ */
+static JSBool
+array_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval *vp, v;
+    JSObject *nobj, *aobj;
+    jsuint length, alength, slot;
+    uintN i;
+    jsid id, id2;
+
+    /* Hoist the explicit local root address computation. */
+    vp = argv + argc;
+
+    /* Treat obj as the first argument; see ECMA 15.4.4.4. */
+    --argv;
+    JS_ASSERT(obj == JSVAL_TO_OBJECT(argv[0]));
+
+    /* Create a new Array object and store it in the rval local root. */
+    nobj = js_NewArrayObject(cx, 0, NULL);
+    if (!nobj)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(nobj);
+
+    /* Loop over [0, argc] to concat args into nobj, expanding all Arrays. */
+    length = 0;
+    for (i = 0; i <= argc; i++) {
+        v = argv[i];
+        if (JSVAL_IS_OBJECT(v)) {
+            aobj = JSVAL_TO_OBJECT(v);
+            if (aobj && OBJ_GET_CLASS(cx, aobj) == &js_ArrayClass) {
+                if (!OBJ_GET_PROPERTY(cx, aobj,
+                                      ATOM_TO_JSID(cx->runtime->atomState
+                                                   .lengthAtom),
+                                      vp)) {
+                    return JS_FALSE;
+                }
+                if (!ValueIsLength(cx, *vp, &alength))
+                    return JS_FALSE;
+                for (slot = 0; slot < alength; slot++) {
+                    if (!IndexToExistingId(cx, aobj, slot, &id))
+                        return JS_FALSE;
+                    if (id == JSID_HOLE) {
+                        /*
+                         * Per ECMA 262, 15.4.4.4, step 9, ignore non-existent
+                         * properties.
+                         */
+                        continue;
+                    }
+                    if (!OBJ_GET_PROPERTY(cx, aobj, id, vp))
+                        return JS_FALSE;
+                    if (!IndexToId(cx, length + slot, &id2))
+                        return JS_FALSE;
+                    if (!OBJ_SET_PROPERTY(cx, nobj, id2, vp))
+                        return JS_FALSE;
+                }
+                length += alength;
+                continue;
+            }
+        }
+
+        *vp = v;
+        if (!IndexToId(cx, length, &id))
+            return JS_FALSE;
+        if (!OBJ_SET_PROPERTY(cx, nobj, id, vp))
+            return JS_FALSE;
+        length++;
+    }
+
+    return js_SetLengthProperty(cx, nobj, length);
+}
+
+static JSBool
+array_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval *vp;
+    JSObject *nobj;
+    jsuint length, begin, end, slot;
+    jsdouble d;
+    jsid id, id2;
+
+    /* Hoist the explicit local root address computation. */
+    vp = argv + argc;
+
+    /* Create a new Array object and store it in the rval local root. */
+    nobj = js_NewArrayObject(cx, 0, NULL);
+    if (!nobj)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(nobj);
+
+    if (!js_GetLengthProperty(cx, obj, &length))
+        return JS_FALSE;
+    begin = 0;
+    end = length;
+
+    if (argc > 0) {
+        if (!js_ValueToNumber(cx, argv[0], &d))
+            return JS_FALSE;
+        d = js_DoubleToInteger(d);
+        if (d < 0) {
+            d += length;
+            if (d < 0)
+                d = 0;
+        } else if (d > length) {
+            d = length;
+        }
+        begin = (jsuint)d;
+
+        if (argc > 1) {
+            if (!js_ValueToNumber(cx, argv[1], &d))
+                return JS_FALSE;
+            d = js_DoubleToInteger(d);
+            if (d < 0) {
+                d += length;
+                if (d < 0)
+                    d = 0;
+            } else if (d > length) {
+                d = length;
+            }
+            end = (jsuint)d;
+        }
+    }
+
+    if (begin > end)
+        begin = end;
+
+    for (slot = begin; slot < end; slot++) {
+        if (!IndexToExistingId(cx, obj, slot, &id))
+            return JS_FALSE;
+        if (id == JSID_HOLE)
+            continue;
+        if (!OBJ_GET_PROPERTY(cx, obj, id, vp))
+            return JS_FALSE;
+        if (!IndexToId(cx, slot - begin, &id2))
+            return JS_FALSE;
+        if (!OBJ_SET_PROPERTY(cx, nobj, id2, vp))
+            return JS_FALSE;
+    }
+    return js_SetLengthProperty(cx, nobj, end - begin);
+}
+#endif /* JS_HAS_SEQUENCE_OPS */
+
+#if JS_HAS_ARRAY_EXTRAS
+
+static JSBool
+array_indexOfHelper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                    jsval *rval, JSBool isLast)
+{
+    jsuint length, i, stop;
+    jsint direction;
+
+    if (!js_GetLengthProperty(cx, obj, &length))
+        return JS_FALSE;
+    if (length == 0)
+        goto not_found;
+
+    if (argc <= 1) {
+        i = isLast ? length - 1 : 0;
+    } else {
+        jsdouble start;
+
+        if (!js_ValueToNumber(cx, argv[1], &start))
+            return JS_FALSE;
+        start = js_DoubleToInteger(start);
+        if (start < 0) {
+            start += length;
+            i = (start < 0) ? 0 : (jsuint)start;
+        } else if (start >= length) {
+            i = length - 1;
+        } else {
+            i = (jsuint)start;
+        }
+    }
+
+    if (isLast) {
+        stop = 0;
+        direction = -1;
+    } else {
+        stop = length - 1;
+        direction = 1;
+    }
+
+    for (;;) {
+        jsid id;
+        jsval v;
+
+        if (!IndexToExistingId(cx, obj, (jsuint)i, &id))
+            return JS_FALSE;
+        if (id != JSID_HOLE) {
+            if (!OBJ_GET_PROPERTY(cx, obj, id, &v))
+                return JS_FALSE;
+            if (js_StrictlyEqual(v, argv[0]))
+                return js_NewNumberValue(cx, i, rval);
+        }
+
+        if (i == stop)
+            goto not_found;
+        i += direction;
+    }
+
+  not_found:
+    *rval = INT_TO_JSVAL(-1);
+    return JS_TRUE;
+}
+
+static JSBool
+array_indexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    return array_indexOfHelper(cx, obj, argc, argv, rval, JS_FALSE);
+}
+
+static JSBool
+array_lastIndexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                  jsval *rval)
+{
+    return array_indexOfHelper(cx, obj, argc, argv, rval, JS_TRUE);
+}
+
+/* Order is important; extras that use a caller's predicate must follow MAP. */
+typedef enum ArrayExtraMode {
+    FOREACH,
+    MAP,
+    FILTER,
+    SOME,
+    EVERY
+} ArrayExtraMode;
+
+static JSBool
+array_extra(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval,
+            ArrayExtraMode mode)
+{
+    jsval *vp, *sp, *origsp, *oldsp;
+    jsuint length, newlen, i;
+    JSObject *callable, *thisp, *newarr;
+    void *mark;
+    JSStackFrame *fp;
+    JSBool ok, b;
+
+    /* Hoist the explicit local root address computation. */
+    vp = argv + argc;
+
+    if (!js_GetLengthProperty(cx, obj, &length))
+        return JS_FALSE;
+
+    /*
+     * First, get or compute our callee, so that we error out consistently
+     * when passed a non-callable object.
+     */
+    callable = js_ValueToCallableObject(cx, &argv[0], 0);
+    if (!callable)
+        return JS_FALSE;
+
+    /*
+     * Set our initial return condition, used for zero-length array cases
+     * (and pre-size our map return to match our known length, for all cases).
+     */
+#ifdef __GNUC__ /* quell GCC overwarning */
+    newlen = 0;
+    newarr = NULL;
+    ok = JS_TRUE;
+#endif
+    switch (mode) {
+      case MAP:
+      case FILTER:
+        newlen = (mode == MAP) ? length : 0;
+        newarr = js_NewArrayObject(cx, newlen, NULL);
+        if (!newarr)
+            return JS_FALSE;
+        *rval = OBJECT_TO_JSVAL(newarr);
+        break;
+      case SOME:
+        *rval = JSVAL_FALSE;
+        break;
+      case EVERY:
+        *rval = JSVAL_TRUE;
+        break;
+      case FOREACH:
+        break;
+    }
+
+    if (length == 0)
+        return JS_TRUE;
+
+    if (argc > 1) {
+        if (!js_ValueToObject(cx, argv[1], &thisp))
+            return JS_FALSE;
+        argv[1] = OBJECT_TO_JSVAL(thisp);
+    } else {
+        JSObject *tmp;
+        thisp = callable;
+        while ((tmp = OBJ_GET_PARENT(cx, thisp)) != NULL)
+            thisp = tmp;
+    }
+
+    /* We call with 3 args (value, index, array), plus room for rval. */
+    origsp = js_AllocStack(cx, 2 + 3 + 1, &mark);
+    if (!origsp)
+        return JS_FALSE;
+
+    /* Lift current frame to include our args. */
+    fp = cx->fp;
+    oldsp = fp->sp;
+
+    for (i = 0; i < length; i++) {
+        jsid id;
+        jsval rval2;
+
+        ok = IndexToExistingId(cx, obj, i, &id);
+        if (!ok)
+            break;
+        if (id == JSID_HOLE)
+            continue;
+        ok = OBJ_GET_PROPERTY(cx, obj, id, vp);
+        if (!ok)
+            break;
+
+        /* Push callable and 'this', then args. */
+        sp = origsp;
+        *sp++ = OBJECT_TO_JSVAL(callable);
+        *sp++ = OBJECT_TO_JSVAL(thisp);
+        *sp++ = *vp;
+        *sp++ = INT_TO_JSVAL(i);
+        *sp++ = OBJECT_TO_JSVAL(obj);
+
+        /* Do the call. */
+        fp->sp = sp;
+        ok = js_Invoke(cx, 3, JSINVOKE_INTERNAL);
+        rval2 = fp->sp[-1];
+        fp->sp = oldsp;
+        if (!ok)
+            break;
+
+        if (mode > MAP) {
+            if (rval2 == JSVAL_NULL) {
+                b = JS_FALSE;
+            } else if (JSVAL_IS_BOOLEAN(rval2)) {
+                b = JSVAL_TO_BOOLEAN(rval2);
+            } else {
+                ok = js_ValueToBoolean(cx, rval2, &b);
+                if (!ok)
+                    goto out;
+            }
+        }
+
+        switch (mode) {
+          case FOREACH:
+            break;
+          case MAP:
+            ok = OBJ_SET_PROPERTY(cx, newarr, id, &rval2);
+            if (!ok)
+                goto out;
+            break;
+          case FILTER:
+            if (!b)
+                break;
+            /* Filter passed *vp, push as result. */
+            ok = IndexToId(cx, newlen++, &id);
+            if (!ok)
+                goto out;
+            ok = OBJ_SET_PROPERTY(cx, newarr, id, vp);
+            if (!ok)
+                goto out;
+            break;
+          case SOME:
+            if (b) {
+                *rval = JSVAL_TRUE;
+                goto out;
+            }
+            break;
+          case EVERY:
+            if (!b) {
+                *rval = JSVAL_FALSE;
+                goto out;
+            }
+            break;
+        }
+    }
+
+ out:
+    js_FreeStack(cx, mark);
+    if (ok && mode == FILTER)
+        ok = js_SetLengthProperty(cx, newarr, newlen);
+    return ok;
+}
+
+static JSBool
+array_forEach(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    return array_extra(cx, obj, argc, argv, rval, FOREACH);
+}
+
+static JSBool
+array_map(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+          jsval *rval)
+{
+    return array_extra(cx, obj, argc, argv, rval, MAP);
+}
+
+static JSBool
+array_filter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+             jsval *rval)
+{
+    return array_extra(cx, obj, argc, argv, rval, FILTER);
+}
+
+static JSBool
+array_some(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+           jsval *rval)
+{
+    return array_extra(cx, obj, argc, argv, rval, SOME);
+}
+
+static JSBool
+array_every(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+           jsval *rval)
+{
+    return array_extra(cx, obj, argc, argv, rval, EVERY);
+}
+#endif
+
+static JSFunctionSpec array_methods[] = {
+#if JS_HAS_TOSOURCE
+    {js_toSource_str,       array_toSource,         0,0,0},
+#endif
+    {js_toString_str,       array_toString,         0,0,0},
+    {js_toLocaleString_str, array_toLocaleString,   0,0,0},
+
+    /* Perl-ish methods. */
+#if JS_HAS_SOME_PERL_FUN
+    {"join",                array_join,             1,JSFUN_GENERIC_NATIVE,0},
+    {"reverse",             array_reverse,          0,JSFUN_GENERIC_NATIVE,2},
+    {"sort",                array_sort,             1,JSFUN_GENERIC_NATIVE,2},
+#endif
+#if JS_HAS_MORE_PERL_FUN
+    {"push",                array_push,             1,JSFUN_GENERIC_NATIVE,0},
+    {"pop",                 array_pop,              0,JSFUN_GENERIC_NATIVE,0},
+    {"shift",               array_shift,            0,JSFUN_GENERIC_NATIVE,1},
+    {"unshift",             array_unshift,          1,JSFUN_GENERIC_NATIVE,1},
+    {"splice",              array_splice,           2,JSFUN_GENERIC_NATIVE,1},
+#endif
+
+    /* Python-esque sequence methods. */
+#if JS_HAS_SEQUENCE_OPS
+    {"concat",              array_concat,           1,JSFUN_GENERIC_NATIVE,1},
+    {"slice",               array_slice,            2,JSFUN_GENERIC_NATIVE,1},
+#endif
+
+#if JS_HAS_ARRAY_EXTRAS
+    {"indexOf",             array_indexOf,          1,JSFUN_GENERIC_NATIVE,0},
+    {"lastIndexOf",         array_lastIndexOf,      1,JSFUN_GENERIC_NATIVE,0},
+    {"forEach",             array_forEach,          1,JSFUN_GENERIC_NATIVE,1},
+    {"map",                 array_map,              1,JSFUN_GENERIC_NATIVE,1},
+    {"filter",              array_filter,           1,JSFUN_GENERIC_NATIVE,1},
+    {"some",                array_some,             1,JSFUN_GENERIC_NATIVE,1},
+    {"every",               array_every,            1,JSFUN_GENERIC_NATIVE,1},
+#endif
+
+    {0,0,0,0,0}
+};
+
+static JSBool
+Array(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsuint length;
+    jsval *vector;
+
+    /* If called without new, replace obj with a new Array object. */
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL);
+        if (!obj)
+            return JS_FALSE;
+        *rval = OBJECT_TO_JSVAL(obj);
+    }
+
+    if (argc == 0) {
+        length = 0;
+        vector = NULL;
+    } else if (JS_VERSION_IS_1_2(cx)) {
+        length = (jsuint) argc;
+        vector = argv;
+    } else if (argc > 1) {
+        length = (jsuint) argc;
+        vector = argv;
+    } else if (!JSVAL_IS_NUMBER(argv[0])) {
+        length = 1;
+        vector = argv;
+    } else {
+        if (!ValueIsLength(cx, argv[0], &length))
+            return JS_FALSE;
+        vector = NULL;
+    }
+    return InitArrayObject(cx, obj, length, vector);
+}
+
+JSObject *
+js_InitArrayClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto;
+
+    proto = JS_InitClass(cx, obj, NULL, &js_ArrayClass, Array, 1,
+                         NULL, array_methods, NULL, NULL);
+
+    /* Initialize the Array prototype object so it gets a length property. */
+    if (!proto || !InitArrayObject(cx, proto, 0, NULL))
+        return NULL;
+    return proto;
+}
+
+JSObject *
+js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector)
+{
+    JSObject *obj;
+
+    obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL);
+    if (!obj)
+        return NULL;
+    if (!InitArrayObject(cx, obj, length, vector)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+    return obj;
+}

Added: freeswitch/trunk/libs/js/src/jsarray.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsarray.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,81 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsarray_h___
+#define jsarray_h___
+/*
+ * JS Array interface.
+ */
+#include "jsprvtd.h"
+#include "jspubtd.h"
+
+JS_BEGIN_EXTERN_C
+
+extern JSBool
+js_IdIsIndex(jsval id, jsuint *indexp);
+
+extern JSClass js_ArrayClass;
+
+extern JSObject *
+js_InitArrayClass(JSContext *cx, JSObject *obj);
+
+extern JSObject *
+js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector);
+
+extern JSBool
+js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
+
+extern JSBool
+js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length);
+
+extern JSBool
+js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
+
+/*
+ * JS-specific heap sort function.
+ */
+typedef int (*JSComparator)(const void *a, const void *b, void *arg);
+
+extern void
+js_HeapSort(void *vec, size_t nel, void *pivot, size_t elsize,
+            JSComparator cmp, void *arg);
+
+JS_END_EXTERN_C
+
+#endif /* jsarray_h___ */

Added: freeswitch/trunk/libs/js/src/jsatom.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsatom.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,992 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS atom table.
+ */
+#include "jsstddef.h"
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jshash.h" /* Added by JSIFY */
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsgc.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsopcode.h"
+#include "jsstr.h"
+
+JS_FRIEND_API(const char *)
+js_AtomToPrintableString(JSContext *cx, JSAtom *atom)
+{
+    return js_ValueToPrintableString(cx, ATOM_KEY(atom));
+}
+
+#if JS_HAS_ERROR_EXCEPTIONS
+extern const char js_Error_str[];       /* trivial, from jsexn.h */
+#endif
+
+/*
+ * Keep this in sync with jspubtd.h -- an assertion below will insist that
+ * its length match the JSType enum's JSTYPE_LIMIT limit value.
+ */
+const char *js_type_str[] = {
+    "undefined",
+    js_object_str,
+    "function",
+    "string",
+    "number",
+    "boolean",
+    "null",
+    "xml",
+};
+
+const char *js_boolean_str[] = {
+    js_false_str,
+    js_true_str
+};
+
+const char js_Arguments_str[]       = "Arguments";
+const char js_Array_str[]           = "Array";
+const char js_Boolean_str[]         = "Boolean";
+const char js_Call_str[]            = "Call";
+const char js_Date_str[]            = "Date";
+const char js_Function_str[]        = "Function";
+const char js_Math_str[]            = "Math";
+const char js_Namespace_str[]       = "Namespace";
+const char js_Number_str[]          = "Number";
+const char js_Object_str[]          = "Object";
+const char js_QName_str[]           = "QName";
+const char js_RegExp_str[]          = "RegExp";
+const char js_Script_str[]          = "Script";
+const char js_String_str[]          = "String";
+const char js_XML_str[]             = "XML";
+const char js_File_str[]            = "File";
+const char js_anonymous_str[]       = "anonymous";
+const char js_arguments_str[]       = "arguments";
+const char js_arity_str[]           = "arity";
+const char js_callee_str[]          = "callee";
+const char js_caller_str[]          = "caller";
+const char js_class_prototype_str[] = "prototype";
+const char js_constructor_str[]     = "constructor";
+const char js_count_str[]           = "__count__";
+const char js_each_str[]            = "each";
+const char js_eval_str[]            = "eval";
+const char js_getter_str[]          = "getter";
+const char js_get_str[]             = "get";
+const char js_index_str[]           = "index";
+const char js_input_str[]           = "input";
+const char js_length_str[]          = "length";
+const char js_name_str[]            = "name";
+const char js_noSuchMethod_str[]    = "__noSuchMethod__";
+const char js_object_str[]          = "object";
+const char js_parent_str[]          = "__parent__";
+const char js_private_str[]         = "private";
+const char js_proto_str[]           = "__proto__";
+const char js_setter_str[]          = "setter";
+const char js_set_str[]             = "set";
+const char js_toSource_str[]        = "toSource";
+const char js_toString_str[]        = "toString";
+const char js_toLocaleString_str[]  = "toLocaleString";
+const char js_valueOf_str[]         = "valueOf";
+
+#if JS_HAS_XML_SUPPORT
+const char js_etago_str[]           = "</";
+const char js_namespace_str[]       = "namespace";
+const char js_ptagc_str[]           = "/>";
+const char js_qualifier_str[]       = "::";
+const char js_space_str[]           = " ";
+const char js_stago_str[]           = "<";
+const char js_star_str[]            = "*";
+const char js_starQualifier_str[]   = "*::";
+const char js_tagc_str[]            = ">";
+const char js_xml_str[]             = "xml";
+#endif
+
+#if defined(OSSP) && defined(JS_HAS_DSO_OBJECT) && (JS_HAS_DSO_OBJECT - 0)
+const char js_DSO_str[]             = "DSO";
+#endif
+
+#ifdef NARCISSUS
+const char js_call_str[]             = "__call__";
+const char js_construct_str[]        = "__construct__";
+const char js_hasInstance_str[]      = "__hasInstance__";
+const char js_ExecutionContext_str[] = "ExecutionContext";
+const char js_current_str[]          = "current";
+#endif
+
+#define HASH_OBJECT(o)  (JS_PTR_TO_UINT32(o) >> JSVAL_TAGBITS)
+#define HASH_INT(i)     ((JSHashNumber)(i))
+#define HASH_DOUBLE(dp) ((JSDOUBLE_HI32(*dp) ^ JSDOUBLE_LO32(*dp)))
+#define HASH_BOOLEAN(b) ((JSHashNumber)(b))
+
+JS_STATIC_DLL_CALLBACK(JSHashNumber)
+js_hash_atom_key(const void *key)
+{
+    jsval v;
+    jsdouble *dp;
+
+    /* Order JSVAL_IS_* tests by likelihood of success. */
+    v = (jsval)key;
+    if (JSVAL_IS_STRING(v))
+        return js_HashString(JSVAL_TO_STRING(v));
+    if (JSVAL_IS_INT(v))
+        return HASH_INT(JSVAL_TO_INT(v));
+    if (JSVAL_IS_DOUBLE(v)) {
+        dp = JSVAL_TO_DOUBLE(v);
+        return HASH_DOUBLE(dp);
+    }
+    if (JSVAL_IS_OBJECT(v))
+        return HASH_OBJECT(JSVAL_TO_OBJECT(v));
+    if (JSVAL_IS_BOOLEAN(v))
+        return HASH_BOOLEAN(JSVAL_TO_BOOLEAN(v));
+    return (JSHashNumber)v;
+}
+
+JS_STATIC_DLL_CALLBACK(intN)
+js_compare_atom_keys(const void *k1, const void *k2)
+{
+    jsval v1, v2;
+
+    v1 = (jsval)k1, v2 = (jsval)k2;
+    if (JSVAL_IS_STRING(v1) && JSVAL_IS_STRING(v2))
+        return !js_CompareStrings(JSVAL_TO_STRING(v1), JSVAL_TO_STRING(v2));
+    if (JSVAL_IS_DOUBLE(v1) && JSVAL_IS_DOUBLE(v2)) {
+        double d1 = *JSVAL_TO_DOUBLE(v1);
+        double d2 = *JSVAL_TO_DOUBLE(v2);
+        if (JSDOUBLE_IS_NaN(d1))
+            return JSDOUBLE_IS_NaN(d2);
+#if defined(XP_WIN)
+        /* XXX MSVC miscompiles such that (NaN == 0) */
+        if (JSDOUBLE_IS_NaN(d2))
+            return JS_FALSE;
+#endif
+        return d1 == d2;
+    }
+    return v1 == v2;
+}
+
+JS_STATIC_DLL_CALLBACK(int)
+js_compare_stub(const void *v1, const void *v2)
+{
+    return 1;
+}
+
+/* These next two are exported to jsscript.c and used similarly there. */
+#ifdef OSSP /* CLEANUP */
+void * JS_DLL_CALLBACK js_alloc_table_space(void *, size_t);
+void   JS_DLL_CALLBACK js_free_table_space(void *, void *);
+#endif
+void * JS_DLL_CALLBACK
+js_alloc_table_space(void *priv, size_t size)
+{
+    return malloc(size);
+}
+
+void JS_DLL_CALLBACK
+js_free_table_space(void *priv, void *item)
+{
+    free(item);
+}
+
+JS_STATIC_DLL_CALLBACK(JSHashEntry *)
+js_alloc_atom(void *priv, const void *key)
+{
+    JSAtomState *state = (JSAtomState *) priv;
+    JSAtom *atom;
+
+    atom = (JSAtom *) malloc(sizeof(JSAtom));
+    if (!atom)
+        return NULL;
+#ifdef JS_THREADSAFE
+    state->tablegen++;
+#endif
+    atom->entry.key = key;
+    atom->entry.value = NULL;
+    atom->flags = 0;
+    atom->number = state->number++;
+    return &atom->entry;
+}
+
+JS_STATIC_DLL_CALLBACK(void)
+js_free_atom(void *priv, JSHashEntry *he, uintN flag)
+{
+    if (flag != HT_FREE_ENTRY)
+        return;
+#ifdef JS_THREADSAFE
+    ((JSAtomState *)priv)->tablegen++;
+#endif
+    free(he);
+}
+
+static JSHashAllocOps atom_alloc_ops = {
+    js_alloc_table_space,   js_free_table_space,
+    js_alloc_atom,          js_free_atom
+};
+
+#define JS_ATOM_HASH_SIZE   1024
+
+JSBool
+js_InitAtomState(JSContext *cx, JSAtomState *state)
+{
+    state->table = JS_NewHashTable(JS_ATOM_HASH_SIZE, js_hash_atom_key,
+                                   js_compare_atom_keys, js_compare_stub,
+                                   &atom_alloc_ops, state);
+    if (!state->table) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+
+    state->runtime = cx->runtime;
+#ifdef JS_THREADSAFE
+    js_InitLock(&state->lock);
+    state->tablegen = 0;
+#endif
+
+    if (!js_InitPinnedAtoms(cx, state)) {
+        js_FreeAtomState(cx, state);
+        return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+JSBool
+js_InitPinnedAtoms(JSContext *cx, JSAtomState *state)
+{
+    uintN i;
+
+#define FROB(lval,str)                                                        \
+    JS_BEGIN_MACRO                                                            \
+        if (!(state->lval = js_Atomize(cx, str, strlen(str), ATOM_PINNED)))   \
+            return JS_FALSE;                                                  \
+    JS_END_MACRO
+
+    JS_ASSERT(sizeof js_type_str / sizeof js_type_str[0] == JSTYPE_LIMIT);
+    for (i = 0; i < JSTYPE_LIMIT; i++)
+        FROB(typeAtoms[i],        js_type_str[i]);
+
+    FROB(booleanAtoms[0],         js_false_str);
+    FROB(booleanAtoms[1],         js_true_str);
+    FROB(nullAtom,                js_null_str);
+
+    FROB(ArgumentsAtom,           js_Arguments_str);
+    FROB(ArrayAtom,               js_Array_str);
+    FROB(BooleanAtom,             js_Boolean_str);
+    FROB(CallAtom,                js_Call_str);
+    FROB(DateAtom,                js_Date_str);
+#if JS_HAS_ERROR_EXCEPTIONS
+    FROB(ErrorAtom,               js_Error_str);
+#endif
+    FROB(FunctionAtom,            js_Function_str);
+    FROB(MathAtom,                js_Math_str);
+    FROB(NamespaceAtom,           js_Namespace_str);
+    FROB(NumberAtom,              js_Number_str);
+    FROB(ObjectAtom,              js_Object_str);
+    FROB(QNameAtom,               js_QName_str);
+    FROB(RegExpAtom,              js_RegExp_str);
+    FROB(ScriptAtom,              js_Script_str);
+    FROB(StringAtom,              js_String_str);
+    FROB(XMLAtom,                 js_XML_str);
+    FROB(FileAtom,                js_File_str);
+    FROB(anonymousAtom,           js_anonymous_str);
+    FROB(argumentsAtom,           js_arguments_str);
+    FROB(arityAtom,               js_arity_str);
+    FROB(calleeAtom,              js_callee_str);
+    FROB(callerAtom,              js_caller_str);
+    FROB(classPrototypeAtom,      js_class_prototype_str);
+    FROB(constructorAtom,         js_constructor_str);
+    FROB(countAtom,               js_count_str);
+    FROB(eachAtom,                js_each_str);
+    FROB(evalAtom,                js_eval_str);
+    FROB(getAtom,                 js_get_str);
+    FROB(getterAtom,              js_getter_str);
+    FROB(indexAtom,               js_index_str);
+    FROB(inputAtom,               js_input_str);
+    FROB(lengthAtom,              js_length_str);
+    FROB(nameAtom,                js_name_str);
+    FROB(noSuchMethodAtom,        js_noSuchMethod_str);
+    FROB(parentAtom,              js_parent_str);
+    FROB(protoAtom,               js_proto_str);
+    FROB(setAtom,                 js_set_str);
+    FROB(setterAtom,              js_setter_str);
+    FROB(toSourceAtom,            js_toSource_str);
+    FROB(toStringAtom,            js_toString_str);
+    FROB(toLocaleStringAtom,      js_toLocaleString_str);
+    FROB(valueOfAtom,             js_valueOf_str);
+
+#if JS_HAS_XML_SUPPORT
+    FROB(etagoAtom,               js_etago_str);
+    FROB(namespaceAtom,           js_namespace_str);
+    FROB(ptagcAtom,               js_ptagc_str);
+    FROB(qualifierAtom,           js_qualifier_str);
+    FROB(spaceAtom,               js_space_str);
+    FROB(stagoAtom,               js_stago_str);
+    FROB(starAtom,                js_star_str);
+    FROB(starQualifierAtom,       js_starQualifier_str);
+    FROB(tagcAtom,                js_tagc_str);
+    FROB(xmlAtom,                 js_xml_str);
+#endif
+    
+#if defined(OSSP) && defined(JS_HAS_DSO_OBJECT) && (JS_HAS_DSO_OBJECT - 0)
+    FROB(DSOAtom,                 js_DSO_str);
+#endif
+
+#ifdef NARCISSUS
+    FROB(callAtom,                js_call_str);
+    FROB(constructAtom,           js_construct_str);
+    FROB(hasInstanceAtom,         js_hasInstance_str);
+    FROB(ExecutionContextAtom,    js_ExecutionContext_str);
+    FROB(currentAtom,             js_current_str);
+#endif
+
+#undef FROB
+
+    memset(&state->lazy, 0, sizeof state->lazy);
+    return JS_TRUE;
+}
+
+/* NB: cx unused; js_FinishAtomState calls us with null cx. */
+void
+js_FreeAtomState(JSContext *cx, JSAtomState *state)
+{
+    if (state->table)
+        JS_HashTableDestroy(state->table);
+#ifdef JS_THREADSAFE
+    js_FinishLock(&state->lock);
+#endif
+    memset(state, 0, sizeof *state);
+}
+
+typedef struct UninternArgs {
+    JSRuntime   *rt;
+    jsatomid    leaks;
+} UninternArgs;
+
+JS_STATIC_DLL_CALLBACK(intN)
+js_atom_uninterner(JSHashEntry *he, intN i, void *arg)
+{
+    JSAtom *atom;
+    UninternArgs *args;
+
+    atom = (JSAtom *)he;
+    args = (UninternArgs *)arg;
+    if (ATOM_IS_STRING(atom))
+        js_FinalizeStringRT(args->rt, ATOM_TO_STRING(atom));
+    else if (ATOM_IS_OBJECT(atom))
+        args->leaks++;
+    return HT_ENUMERATE_NEXT;
+}
+
+void
+js_FinishAtomState(JSAtomState *state)
+{
+    UninternArgs args;
+
+    if (!state->table)
+        return;
+    args.rt = state->runtime;
+    args.leaks = 0;
+    JS_HashTableEnumerateEntries(state->table, js_atom_uninterner, &args);
+#ifdef DEBUG
+    if (args.leaks != 0) {
+        fprintf(stderr,
+"JS engine warning: %lu atoms remain after destroying the JSRuntime.\n"
+"                   These atoms may point to freed memory. Things reachable\n"
+"                   through them have not been finalized.\n",
+                (unsigned long) args.leaks);
+    }
+#endif
+    js_FreeAtomState(NULL, state);
+}
+
+typedef struct MarkArgs {
+    uintN           gcflags;
+    JSGCThingMarker mark;
+    void            *data;
+} MarkArgs;
+
+JS_STATIC_DLL_CALLBACK(intN)
+js_atom_marker(JSHashEntry *he, intN i, void *arg)
+{
+    JSAtom *atom;
+    MarkArgs *args;
+    jsval key;
+
+    atom = (JSAtom *)he;
+    args = (MarkArgs *)arg;
+    if ((atom->flags & (ATOM_PINNED | ATOM_INTERNED)) ||
+        (args->gcflags & GC_KEEP_ATOMS)) {
+        atom->flags |= ATOM_MARK;
+        key = ATOM_KEY(atom);
+        if (JSVAL_IS_GCTHING(key))
+            args->mark(JSVAL_TO_GCTHING(key), args->data);
+    }
+    return HT_ENUMERATE_NEXT;
+}
+
+void
+js_MarkAtomState(JSAtomState *state, uintN gcflags, JSGCThingMarker mark,
+                 void *data)
+{
+    MarkArgs args;
+
+    if (!state->table)
+        return;
+    args.gcflags = gcflags;
+    args.mark = mark;
+    args.data = data;
+    JS_HashTableEnumerateEntries(state->table, js_atom_marker, &args);
+}
+
+JS_STATIC_DLL_CALLBACK(intN)
+js_atom_sweeper(JSHashEntry *he, intN i, void *arg)
+{
+    JSAtom *atom;
+    JSAtomState *state;
+
+    atom = (JSAtom *)he;
+    if (atom->flags & ATOM_MARK) {
+        atom->flags &= ~ATOM_MARK;
+        state = (JSAtomState *)arg;
+        state->liveAtoms++;
+        return HT_ENUMERATE_NEXT;
+    }
+    JS_ASSERT((atom->flags & (ATOM_PINNED | ATOM_INTERNED)) == 0);
+    atom->entry.key = atom->entry.value = NULL;
+    atom->flags = 0;
+    return HT_ENUMERATE_REMOVE;
+}
+
+void
+js_SweepAtomState(JSAtomState *state)
+{
+    state->liveAtoms = 0;
+    if (state->table)
+        JS_HashTableEnumerateEntries(state->table, js_atom_sweeper, state);
+}
+
+JS_STATIC_DLL_CALLBACK(intN)
+js_atom_unpinner(JSHashEntry *he, intN i, void *arg)
+{
+    JSAtom *atom;
+
+    atom = (JSAtom *)he;
+    atom->flags &= ~ATOM_PINNED;
+    return HT_ENUMERATE_NEXT;
+}
+
+void
+js_UnpinPinnedAtoms(JSAtomState *state)
+{
+    if (state->table)
+        JS_HashTableEnumerateEntries(state->table, js_atom_unpinner, NULL);
+}
+
+static JSAtom *
+js_AtomizeHashedKey(JSContext *cx, jsval key, JSHashNumber keyHash, uintN flags)
+{
+    JSAtomState *state;
+    JSHashTable *table;
+    JSHashEntry *he, **hep;
+    JSAtom *atom;
+
+    state = &cx->runtime->atomState;
+    JS_LOCK(&state->lock, cx);
+    table = state->table;
+    hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
+    if ((he = *hep) == NULL) {
+        he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
+        if (!he) {
+            JS_ReportOutOfMemory(cx);
+            atom = NULL;
+            goto out;
+        }
+    }
+
+    atom = (JSAtom *)he;
+    atom->flags |= flags;
+    cx->lastAtom = atom;
+out:
+    JS_UNLOCK(&state->lock,cx);
+    return atom;
+}
+
+JSAtom *
+js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags)
+{
+    jsval key;
+    JSHashNumber keyHash;
+
+    /* XXX must be set in the following order or MSVC1.52 will crash */
+    keyHash = HASH_OBJECT(obj);
+    key = OBJECT_TO_JSVAL(obj);
+    return js_AtomizeHashedKey(cx, key, keyHash, flags);
+}
+
+JSAtom *
+js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags)
+{
+    jsval key;
+    JSHashNumber keyHash;
+
+    key = BOOLEAN_TO_JSVAL(b);
+    keyHash = HASH_BOOLEAN(b);
+    return js_AtomizeHashedKey(cx, key, keyHash, flags);
+}
+
+JSAtom *
+js_AtomizeInt(JSContext *cx, jsint i, uintN flags)
+{
+    jsval key;
+    JSHashNumber keyHash;
+
+    key = INT_TO_JSVAL(i);
+    keyHash = HASH_INT(i);
+    return js_AtomizeHashedKey(cx, key, keyHash, flags);
+}
+
+/* Worst-case alignment grain and aligning macro for 2x-sized buffer. */
+#define ALIGNMENT(t)    JS_MAX(JSVAL_ALIGN, sizeof(t))
+#define ALIGN(b,t)      ((t*) &(b)[ALIGNMENT(t) - (jsuword)(b) % ALIGNMENT(t)])
+
+JSAtom *
+js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags)
+{
+    jsdouble *dp;
+    JSHashNumber keyHash;
+    jsval key;
+    JSAtomState *state;
+    JSHashTable *table;
+    JSHashEntry *he, **hep;
+    JSAtom *atom;
+    char buf[2 * ALIGNMENT(double)];
+
+    dp = ALIGN(buf, double);
+    *dp = d;
+    keyHash = HASH_DOUBLE(dp);
+    key = DOUBLE_TO_JSVAL(dp);
+    state = &cx->runtime->atomState;
+    JS_LOCK(&state->lock, cx);
+    table = state->table;
+    hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
+    if ((he = *hep) == NULL) {
+#ifdef JS_THREADSAFE
+        uint32 gen = state->tablegen;
+#endif
+        JS_UNLOCK(&state->lock,cx);
+        if (!js_NewDoubleValue(cx, d, &key))
+            return NULL;
+        JS_LOCK(&state->lock, cx);
+#ifdef JS_THREADSAFE
+        if (state->tablegen != gen) {
+            hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
+            if ((he = *hep) != NULL) {
+                atom = (JSAtom *)he;
+                goto out;
+            }
+        }
+#endif
+        he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
+        if (!he) {
+            JS_ReportOutOfMemory(cx);
+            atom = NULL;
+            goto out;
+        }
+    }
+
+    atom = (JSAtom *)he;
+    atom->flags |= flags;
+    cx->lastAtom = atom;
+out:
+    JS_UNLOCK(&state->lock,cx);
+    return atom;
+}
+
+/*
+ * To put an atom into the hidden subspace. XOR its keyHash with this value,
+ * which is (sqrt(2)-1) in 32-bit fixed point.
+ */
+#define HIDDEN_ATOM_SUBSPACE_KEYHASH    0x6A09E667
+
+JSAtom *
+js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
+{
+    JSHashNumber keyHash;
+    jsval key;
+    JSAtomState *state;
+    JSHashTable *table;
+    JSHashEntry *he, **hep;
+    JSAtom *atom;
+
+    keyHash = js_HashString(str);
+    if (flags & ATOM_HIDDEN)
+        keyHash ^= HIDDEN_ATOM_SUBSPACE_KEYHASH;
+    key = STRING_TO_JSVAL(str);
+    state = &cx->runtime->atomState;
+    JS_LOCK(&state->lock, cx);
+    table = state->table;
+    hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
+    if ((he = *hep) == NULL) {
+#ifdef JS_THREADSAFE
+        uint32 gen = state->tablegen;
+        JS_UNLOCK(&state->lock, cx);
+#endif
+
+        if (flags & ATOM_TMPSTR) {
+            str = (flags & ATOM_NOCOPY)
+                  ? js_NewString(cx, str->chars, str->length, 0)
+                  : js_NewStringCopyN(cx, str->chars, str->length, 0);
+            if (!str)
+                return NULL;
+            key = STRING_TO_JSVAL(str);
+        } else {
+            if (!JS_MakeStringImmutable(cx, str))
+                return NULL;
+        }
+
+#ifdef JS_THREADSAFE
+        JS_LOCK(&state->lock, cx);
+        if (state->tablegen != gen) {
+            hep = JS_HashTableRawLookup(table, keyHash, (void *)key);
+            if ((he = *hep) != NULL) {
+                atom = (JSAtom *)he;
+                if (flags & ATOM_NOCOPY)
+                    str->chars = NULL;
+                goto out;
+            }
+        }
+#endif
+
+        he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
+        if (!he) {
+            JS_ReportOutOfMemory(cx);
+            atom = NULL;
+            goto out;
+        }
+    }
+
+    atom = (JSAtom *)he;
+    atom->flags |= flags & (ATOM_PINNED | ATOM_INTERNED | ATOM_HIDDEN);
+    cx->lastAtom = atom;
+out:
+    JS_UNLOCK(&state->lock,cx);
+    return atom;
+}
+
+JS_FRIEND_API(JSAtom *)
+js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags)
+{
+    jschar *chars;
+    JSString *str;
+    JSAtom *atom;
+    char buf[2 * ALIGNMENT(JSString)];
+
+    /*
+     * Avoiding the malloc in js_InflateString on shorter strings saves us
+     * over 20,000 malloc calls on mozilla browser startup. This compares to
+     * only 131 calls where the string is longer than a 31 char (net) buffer.
+     * The vast majority of atomized strings are already in the hashtable. So
+     * js_AtomizeString rarely has to copy the temp string we make.
+     */
+#define ATOMIZE_BUF_MAX 32
+    jschar inflated[ATOMIZE_BUF_MAX];
+    size_t inflatedLength = ATOMIZE_BUF_MAX - 1;
+
+    if (length < ATOMIZE_BUF_MAX) {
+        js_InflateStringToBuffer(cx, bytes, length, inflated, &inflatedLength);
+        inflated[inflatedLength] = 0;
+        chars = inflated;
+    } else {
+        inflatedLength = length;
+        chars = js_InflateString(cx, bytes, &inflatedLength);
+        if (!chars)
+            return NULL;
+        flags |= ATOM_NOCOPY;
+    }
+
+    str = ALIGN(buf, JSString);
+
+    str->chars = chars;
+    str->length = inflatedLength;
+    atom = js_AtomizeString(cx, str, ATOM_TMPSTR | flags);
+    if (chars != inflated && (!atom || ATOM_TO_STRING(atom)->chars != chars))
+        JS_free(cx, chars);
+    return atom;
+}
+
+JS_FRIEND_API(JSAtom *)
+js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags)
+{
+    JSString *str;
+    char buf[2 * ALIGNMENT(JSString)];
+
+    str = ALIGN(buf, JSString);
+    str->chars = (jschar *)chars;
+    str->length = length;
+    return js_AtomizeString(cx, str, ATOM_TMPSTR | flags);
+}
+
+JSAtom *
+js_AtomizeValue(JSContext *cx, jsval value, uintN flags)
+{
+    if (JSVAL_IS_STRING(value))
+        return js_AtomizeString(cx, JSVAL_TO_STRING(value), flags);
+    if (JSVAL_IS_INT(value))
+        return js_AtomizeInt(cx, JSVAL_TO_INT(value), flags);
+    if (JSVAL_IS_DOUBLE(value))
+        return js_AtomizeDouble(cx, *JSVAL_TO_DOUBLE(value), flags);
+    if (JSVAL_IS_OBJECT(value))
+        return js_AtomizeObject(cx, JSVAL_TO_OBJECT(value), flags);
+    if (JSVAL_IS_BOOLEAN(value))
+        return js_AtomizeBoolean(cx, JSVAL_TO_BOOLEAN(value), flags);
+    return js_AtomizeHashedKey(cx, value, (JSHashNumber)value, flags);
+}
+
+JSAtom *
+js_ValueToStringAtom(JSContext *cx, jsval v)
+{
+    JSString *str;
+
+    str = js_ValueToString(cx, v);
+    if (!str)
+        return NULL;
+    return js_AtomizeString(cx, str, 0);
+}
+
+JS_STATIC_DLL_CALLBACK(JSHashNumber)
+js_hash_atom_ptr(const void *key)
+{
+    const JSAtom *atom = key;
+    return atom->number;
+}
+
+JS_STATIC_DLL_CALLBACK(void *)
+js_alloc_temp_space(void *priv, size_t size)
+{
+    JSContext *cx = priv;
+    void *space;
+
+    JS_ARENA_ALLOCATE(space, &cx->tempPool, size);
+    if (!space)
+        JS_ReportOutOfMemory(cx);
+    return space;
+}
+
+JS_STATIC_DLL_CALLBACK(void)
+js_free_temp_space(void *priv, void *item)
+{
+}
+
+JS_STATIC_DLL_CALLBACK(JSHashEntry *)
+js_alloc_temp_entry(void *priv, const void *key)
+{
+    JSContext *cx = priv;
+    JSAtomListElement *ale;
+
+    JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool);
+    if (!ale) {
+        JS_ReportOutOfMemory(cx);
+        return NULL;
+    }
+    return &ale->entry;
+}
+
+JS_STATIC_DLL_CALLBACK(void)
+js_free_temp_entry(void *priv, JSHashEntry *he, uintN flag)
+{
+}
+
+static JSHashAllocOps temp_alloc_ops = {
+    js_alloc_temp_space,    js_free_temp_space,
+    js_alloc_temp_entry,    js_free_temp_entry
+};
+
+JSAtomListElement *
+js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al)
+{
+    JSAtomListElement *ale, *ale2, *next;
+    JSHashEntry **hep;
+
+    ATOM_LIST_LOOKUP(ale, hep, al, atom);
+    if (!ale) {
+        if (al->count < 10) {
+            /* Few enough for linear search, no hash table needed. */
+            JS_ASSERT(!al->table);
+            ale = (JSAtomListElement *)js_alloc_temp_entry(cx, atom);
+            if (!ale)
+                return NULL;
+            ALE_SET_ATOM(ale, atom);
+            ALE_SET_NEXT(ale, al->list);
+            al->list = ale;
+        } else {
+            /* We want to hash.  Have we already made a hash table? */
+            if (!al->table) {
+                /* No hash table yet, so hep had better be null! */
+                JS_ASSERT(!hep);
+                al->table = JS_NewHashTable(al->count + 1, js_hash_atom_ptr,
+                                            JS_CompareValues, JS_CompareValues,
+                                            &temp_alloc_ops, cx);
+                if (!al->table)
+                    return NULL;
+
+                /*
+                 * Set ht->nentries explicitly, because we are moving entries
+                 * from al to ht, not calling JS_HashTable(Raw|)Add.
+                 */
+                al->table->nentries = al->count;
+
+                /* Insert each ale on al->list into the new hash table. */
+                for (ale2 = al->list; ale2; ale2 = next) {
+                    next = ALE_NEXT(ale2);
+                    ale2->entry.keyHash = ALE_ATOM(ale2)->number;
+                    hep = JS_HashTableRawLookup(al->table, ale2->entry.keyHash,
+                                                ale2->entry.key);
+                    ALE_SET_NEXT(ale2, *hep);
+                    *hep = &ale2->entry;
+                }
+                al->list = NULL;
+
+                /* Set hep for insertion of atom's ale, immediately below. */
+                hep = JS_HashTableRawLookup(al->table, atom->number, atom);
+            }
+
+            /* Finally, add an entry for atom into the hash bucket at hep. */
+            ale = (JSAtomListElement *)
+                  JS_HashTableRawAdd(al->table, hep, atom->number, atom, NULL);
+            if (!ale)
+                return NULL;
+        }
+
+        ALE_SET_INDEX(ale, al->count++);
+    }
+    return ale;
+}
+
+JS_FRIEND_API(JSAtom *)
+js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i)
+{
+    JSAtom *atom;
+    static JSAtom dummy;
+
+    JS_ASSERT(map->vector && i < map->length);
+    if (!map->vector || i >= map->length) {
+        char numBuf[12];
+        JS_snprintf(numBuf, sizeof numBuf, "%lu", (unsigned long)i);
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_ATOMIC_NUMBER, numBuf);
+        return &dummy;
+    }
+    atom = map->vector[i];
+    JS_ASSERT(atom);
+    return atom;
+}
+
+JS_STATIC_DLL_CALLBACK(intN)
+js_map_atom(JSHashEntry *he, intN i, void *arg)
+{
+    JSAtomListElement *ale = (JSAtomListElement *)he;
+    JSAtom **vector = arg;
+
+    vector[ALE_INDEX(ale)] = ALE_ATOM(ale);
+    return HT_ENUMERATE_NEXT;
+}
+
+#ifdef DEBUG
+jsrefcount js_atom_map_count;
+jsrefcount js_atom_map_hash_table_count;
+#endif
+
+JS_FRIEND_API(JSBool)
+js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al)
+{
+    JSAtom **vector;
+    JSAtomListElement *ale;
+    uint32 count;
+
+#ifdef DEBUG
+    JS_ATOMIC_INCREMENT(&js_atom_map_count);
+#endif
+    ale = al->list;
+    if (!ale && !al->table) {
+        map->vector = NULL;
+        map->length = 0;
+        return JS_TRUE;
+    }
+
+    count = al->count;
+    if (count >= ATOM_INDEX_LIMIT) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_TOO_MANY_LITERALS);
+        return JS_FALSE;
+    }
+    vector = (JSAtom **) JS_malloc(cx, (size_t) count * sizeof *vector);
+    if (!vector)
+        return JS_FALSE;
+
+    if (al->table) {
+#ifdef DEBUG
+        JS_ATOMIC_INCREMENT(&js_atom_map_hash_table_count);
+#endif
+        JS_HashTableEnumerateEntries(al->table, js_map_atom, vector);
+    } else {
+        do {
+            vector[ALE_INDEX(ale)] = ALE_ATOM(ale);
+        } while ((ale = ALE_NEXT(ale)) != NULL);
+    }
+    ATOM_LIST_INIT(al);
+
+    map->vector = vector;
+    map->length = (jsatomid)count;
+    return JS_TRUE;
+}
+
+JS_FRIEND_API(void)
+js_FreeAtomMap(JSContext *cx, JSAtomMap *map)
+{
+    if (map->vector) {
+        JS_free(cx, map->vector);
+        map->vector = NULL;
+    }
+    map->length = 0;
+}

Added: freeswitch/trunk/libs/js/src/jsatom.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsatom.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,471 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsatom_h___
+#define jsatom_h___
+/*
+ * JS atom table.
+ */
+#include <stddef.h>
+#include "jstypes.h"
+#include "jshash.h" /* Added by JSIFY */
+#include "jsapi.h"
+#include "jsprvtd.h"
+#include "jspubtd.h"
+
+#ifdef JS_THREADSAFE
+#include "jslock.h"
+#endif
+
+JS_BEGIN_EXTERN_C
+
+#define ATOM_PINNED     0x01            /* atom is pinned against GC */
+#define ATOM_INTERNED   0x02            /* pinned variant for JS_Intern* API */
+#define ATOM_MARK       0x04            /* atom is reachable via GC */
+#define ATOM_HIDDEN     0x08            /* atom is in special hidden subspace */
+#define ATOM_NOCOPY     0x40            /* don't copy atom string bytes */
+#define ATOM_TMPSTR     0x80            /* internal, to avoid extra string */
+
+struct JSAtom {
+    JSHashEntry         entry;          /* key is jsval, value keyword info or
+                                           unhidden atom if ATOM_HIDDEN */
+    uint32              flags;          /* pinned, interned, and mark flags */
+    jsatomid            number;         /* atom serial number and hash code */
+};
+
+#define ATOM_KEY(atom)            ((jsval)(atom)->entry.key)
+#define ATOM_IS_OBJECT(atom)      JSVAL_IS_OBJECT(ATOM_KEY(atom))
+#define ATOM_TO_OBJECT(atom)      JSVAL_TO_OBJECT(ATOM_KEY(atom))
+#define ATOM_IS_INT(atom)         JSVAL_IS_INT(ATOM_KEY(atom))
+#define ATOM_TO_INT(atom)         JSVAL_TO_INT(ATOM_KEY(atom))
+#define ATOM_IS_DOUBLE(atom)      JSVAL_IS_DOUBLE(ATOM_KEY(atom))
+#define ATOM_TO_DOUBLE(atom)      JSVAL_TO_DOUBLE(ATOM_KEY(atom))
+#define ATOM_IS_STRING(atom)      JSVAL_IS_STRING(ATOM_KEY(atom))
+#define ATOM_TO_STRING(atom)      JSVAL_TO_STRING(ATOM_KEY(atom))
+#define ATOM_IS_BOOLEAN(atom)     JSVAL_IS_BOOLEAN(ATOM_KEY(atom))
+#define ATOM_TO_BOOLEAN(atom)     JSVAL_TO_BOOLEAN(ATOM_KEY(atom))
+
+/*
+ * Return a printable, lossless char[] representation of a string-type atom.
+ * The lifetime of the result extends at least until the next GC activation,
+ * longer if cx's string newborn root is not overwritten.
+ */
+extern JS_FRIEND_API(const char *)
+js_AtomToPrintableString(JSContext *cx, JSAtom *atom);
+
+#define ATOM_KEYWORD(atom)        ((struct keyword *)(atom)->entry.value)
+#define ATOM_SET_KEYWORD(atom,kw) ((atom)->entry.value = (kw))
+
+struct JSAtomListElement {
+    JSHashEntry         entry;
+};
+
+#define ALE_ATOM(ale)   ((JSAtom *) (ale)->entry.key)
+#define ALE_INDEX(ale)  ((jsatomid) JS_PTR_TO_UINT32((ale)->entry.value))
+#define ALE_JSOP(ale)   ((JSOp) (ale)->entry.value)
+#define ALE_VALUE(ale)  ((jsval) (ale)->entry.value)
+#define ALE_NEXT(ale)   ((JSAtomListElement *) (ale)->entry.next)
+
+#define ALE_SET_ATOM(ale,atom)  ((ale)->entry.key = (const void *)(atom))
+#define ALE_SET_INDEX(ale,index)((ale)->entry.value = JS_UINT32_TO_PTR(index))
+#define ALE_SET_JSOP(ale,op)    ((ale)->entry.value = JS_UINT32_TO_PTR(op))
+#define ALE_SET_VALUE(ale,val)  ((ale)->entry.value = (JSHashEntry *)(val))
+#define ALE_SET_NEXT(ale,link)  ((ale)->entry.next = (JSHashEntry *)(link))
+
+struct JSAtomList {
+    JSAtomListElement   *list;          /* literals indexed for mapping */
+    JSHashTable         *table;         /* hash table if list gets too long */
+    jsuint              count;          /* count of indexed literals */
+};
+
+#define ATOM_LIST_INIT(al)  ((al)->list = NULL, (al)->table = NULL,           \
+                             (al)->count = 0)
+
+#define ATOM_LIST_SEARCH(_ale,_al,_atom)                                      \
+    JS_BEGIN_MACRO                                                            \
+        JSHashEntry **_hep;                                                   \
+        ATOM_LIST_LOOKUP(_ale, _hep, _al, _atom);                             \
+    JS_END_MACRO
+
+#define ATOM_LIST_LOOKUP(_ale,_hep,_al,_atom)                                 \
+    JS_BEGIN_MACRO                                                            \
+        if ((_al)->table) {                                                   \
+            _hep = JS_HashTableRawLookup((_al)->table, _atom->number, _atom); \
+            _ale = *_hep ? (JSAtomListElement *) *_hep : NULL;                \
+        } else {                                                              \
+            JSAtomListElement **_alep = &(_al)->list;                         \
+            _hep = NULL;                                                      \
+            while ((_ale = *_alep) != NULL) {                                 \
+                if (ALE_ATOM(_ale) == (_atom)) {                              \
+                    /* Hit, move atom's element to the front of the list. */  \
+                    *_alep = ALE_NEXT(_ale);                                  \
+                    ALE_SET_NEXT(_ale, (_al)->list);                          \
+                    (_al)->list = _ale;                                       \
+                    break;                                                    \
+                }                                                             \
+                _alep = (JSAtomListElement **)&_ale->entry.next;              \
+            }                                                                 \
+        }                                                                     \
+    JS_END_MACRO
+
+struct JSAtomMap {
+    JSAtom              **vector;       /* array of ptrs to indexed atoms */
+    jsatomid            length;         /* count of (to-be-)indexed atoms */
+};
+
+struct JSAtomState {
+    JSRuntime           *runtime;       /* runtime that owns us */
+    JSHashTable         *table;         /* hash table containing all atoms */
+    jsatomid            number;         /* one beyond greatest atom number */
+    jsatomid            liveAtoms;      /* number of live atoms after last GC */
+
+    /* The rt->emptyString atom, see jsstr.c's js_InitRuntimeStringState. */
+    JSAtom              *emptyAtom;
+
+    /* Type names and value literals. */
+    JSAtom              *typeAtoms[JSTYPE_LIMIT];
+    JSAtom              *booleanAtoms[2];
+    JSAtom              *nullAtom;
+
+    /* Various built-in or commonly-used atoms, pinned on first context. */
+    JSAtom              *ArgumentsAtom;
+    JSAtom              *ArrayAtom;
+    JSAtom              *BooleanAtom;
+    JSAtom              *CallAtom;
+    JSAtom              *DateAtom;
+    JSAtom              *ErrorAtom;
+    JSAtom              *FunctionAtom;
+    JSAtom              *MathAtom;
+    JSAtom              *NamespaceAtom;
+    JSAtom              *NumberAtom;
+    JSAtom              *ObjectAtom;
+    JSAtom              *QNameAtom;
+    JSAtom              *RegExpAtom;
+    JSAtom              *ScriptAtom;
+    JSAtom              *StringAtom;
+    JSAtom              *XMLAtom;
+    JSAtom              *FileAtom;
+    JSAtom              *anonymousAtom;
+    JSAtom              *argumentsAtom;
+    JSAtom              *arityAtom;
+    JSAtom              *calleeAtom;
+    JSAtom              *callerAtom;
+    JSAtom              *classPrototypeAtom;
+    JSAtom              *constructorAtom;
+    JSAtom              *countAtom;
+    JSAtom              *eachAtom;
+    JSAtom              *etagoAtom;
+    JSAtom              *evalAtom;
+    JSAtom              *getAtom;
+    JSAtom              *getterAtom;
+    JSAtom              *indexAtom;
+    JSAtom              *inputAtom;
+    JSAtom              *lengthAtom;
+    JSAtom              *nameAtom;
+    JSAtom              *namespaceAtom;
+    JSAtom              *noSuchMethodAtom;
+    JSAtom              *parentAtom;
+    JSAtom              *protoAtom;
+    JSAtom              *ptagcAtom;
+    JSAtom              *qualifierAtom;
+    JSAtom              *setAtom;
+    JSAtom              *setterAtom;
+    JSAtom              *spaceAtom;
+    JSAtom              *stagoAtom;
+    JSAtom              *starAtom;
+    JSAtom              *starQualifierAtom;
+    JSAtom              *tagcAtom;
+    JSAtom              *toLocaleStringAtom;
+    JSAtom              *toSourceAtom;
+    JSAtom              *toStringAtom;
+    JSAtom              *valueOfAtom;
+    JSAtom              *xmlAtom;
+#ifdef OSSP
+    JSAtom              *DSOAtom;
+#endif
+
+    /* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass. */
+    struct {
+        JSAtom          *AnyNameAtom;
+        JSAtom          *AttributeNameAtom;
+        JSAtom          *EvalErrorAtom;
+        JSAtom          *InfinityAtom;
+        JSAtom          *InternalErrorAtom;
+        JSAtom          *NaNAtom;
+        JSAtom          *RangeErrorAtom;
+        JSAtom          *ReferenceErrorAtom;
+        JSAtom          *SyntaxErrorAtom;
+        JSAtom          *TypeErrorAtom;
+        JSAtom          *URIErrorAtom;
+        JSAtom          *XMLListAtom;
+        JSAtom          *decodeURIAtom;
+        JSAtom          *decodeURIComponentAtom;
+        JSAtom          *defineGetterAtom;
+        JSAtom          *defineSetterAtom;
+        JSAtom          *encodeURIAtom;
+        JSAtom          *encodeURIComponentAtom;
+        JSAtom          *escapeAtom;
+        JSAtom          *functionNamespaceURIAtom;
+        JSAtom          *hasOwnPropertyAtom;
+        JSAtom          *isFiniteAtom;
+        JSAtom          *isNaNAtom;
+        JSAtom          *isPrototypeOfAtom;
+        JSAtom          *isXMLNameAtom;
+        JSAtom          *lookupGetterAtom;
+        JSAtom          *lookupSetterAtom;
+        JSAtom          *parseFloatAtom;
+        JSAtom          *parseIntAtom;
+        JSAtom          *propertyIsEnumerableAtom;
+        JSAtom          *unescapeAtom;
+        JSAtom          *unevalAtom;
+        JSAtom          *unwatchAtom;
+        JSAtom          *watchAtom;
+    } lazy;
+
+#ifdef JS_THREADSAFE
+    JSThinLock          lock;
+    volatile uint32     tablegen;
+#endif
+#ifdef NARCISSUS
+    JSAtom              *callAtom;
+    JSAtom              *constructAtom;
+    JSAtom              *hasInstanceAtom;
+    JSAtom              *ExecutionContextAtom;
+    JSAtom              *currentAtom;
+#endif
+};
+
+/* Well-known predefined strings and their atoms. */
+extern const char   *js_type_str[];
+extern const char   *js_boolean_str[];
+
+extern const char   js_Arguments_str[];
+extern const char   js_Array_str[];
+extern const char   js_Boolean_str[];
+extern const char   js_Call_str[];
+extern const char   js_Date_str[];
+extern const char   js_Function_str[];
+extern const char   js_Math_str[];
+extern const char   js_Namespace_str[];
+extern const char   js_Number_str[];
+extern const char   js_Object_str[];
+extern const char   js_QName_str[];
+extern const char   js_RegExp_str[];
+extern const char   js_Script_str[];
+extern const char   js_String_str[];
+extern const char   js_XML_str[];
+extern const char   js_File_str[];
+extern const char   js_anonymous_str[];
+extern const char   js_arguments_str[];
+extern const char   js_arity_str[];
+extern const char   js_callee_str[];
+extern const char   js_caller_str[];
+extern const char   js_class_prototype_str[];
+extern const char   js_constructor_str[];
+extern const char   js_count_str[];
+extern const char   js_etago_str[];
+extern const char   js_each_str[];
+extern const char   js_eval_str[];
+extern const char   js_getter_str[];
+extern const char   js_get_str[];
+extern const char   js_index_str[];
+extern const char   js_input_str[];
+extern const char   js_length_str[];
+extern const char   js_name_str[];
+extern const char   js_namespace_str[];
+extern const char   js_noSuchMethod_str[];
+extern const char   js_object_str[];
+extern const char   js_parent_str[];
+extern const char   js_private_str[];
+extern const char   js_proto_str[];
+extern const char   js_ptagc_str[];
+extern const char   js_qualifier_str[];
+extern const char   js_setter_str[];
+extern const char   js_set_str[];
+extern const char   js_space_str[];
+extern const char   js_stago_str[];
+extern const char   js_star_str[];
+extern const char   js_starQualifier_str[];
+extern const char   js_tagc_str[];
+extern const char   js_toSource_str[];
+extern const char   js_toString_str[];
+extern const char   js_toLocaleString_str[];
+extern const char   js_valueOf_str[];
+extern const char   js_xml_str[];
+
+#ifdef NARCISSUS
+extern const char   js_call_str[];
+extern const char   js_construct_str[];
+extern const char   js_hasInstance_str[];
+extern const char   js_ExecutionContext_str[];
+extern const char   js_current_str[];
+#endif
+
+/*
+ * Initialize atom state.  Return true on success, false with an out of
+ * memory error report on failure.
+ */
+extern JSBool
+js_InitAtomState(JSContext *cx, JSAtomState *state);
+
+/*
+ * Free and clear atom state (except for any interned string atoms).
+ */
+extern void
+js_FreeAtomState(JSContext *cx, JSAtomState *state);
+
+/*
+ * Interned strings are atoms that live until state's runtime is destroyed.
+ * This function frees all interned string atoms, and then frees and clears
+ * state's members (just as js_FreeAtomState does), unless there aren't any
+ * interned strings in state -- in which case state must be "free" already.
+ *
+ * NB: js_FreeAtomState is called for each "last" context being destroyed in
+ * a runtime, where there may yet be another context created in the runtime;
+ * whereas js_FinishAtomState is called from JS_DestroyRuntime, when we know
+ * that no more contexts will be created.  Thus we minimize garbage during
+ * context-free episodes on a runtime, while preserving atoms created by the
+ * JS_Intern*String APIs for the life of the runtime.
+ */
+extern void
+js_FinishAtomState(JSAtomState *state);
+
+/*
+ * Atom garbage collection hooks.
+ */
+typedef void
+(*JSGCThingMarker)(void *thing, void *data);
+
+extern void
+js_MarkAtomState(JSAtomState *state, uintN gcflags, JSGCThingMarker mark,
+                 void *data);
+
+extern void
+js_SweepAtomState(JSAtomState *state);
+
+extern JSBool
+js_InitPinnedAtoms(JSContext *cx, JSAtomState *state);
+
+extern void
+js_UnpinPinnedAtoms(JSAtomState *state);
+
+/*
+ * Find or create the atom for an object.  If we create a new atom, give it the
+ * type indicated in flags.  Return 0 on failure to allocate memory.
+ */
+extern JSAtom *
+js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags);
+
+/*
+ * Find or create the atom for a Boolean value.  If we create a new atom, give
+ * it the type indicated in flags.  Return 0 on failure to allocate memory.
+ */
+extern JSAtom *
+js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags);
+
+/*
+ * Find or create the atom for an integer value.  If we create a new atom, give
+ * it the type indicated in flags.  Return 0 on failure to allocate memory.
+ */
+extern JSAtom *
+js_AtomizeInt(JSContext *cx, jsint i, uintN flags);
+
+/*
+ * Find or create the atom for a double value.  If we create a new atom, give
+ * it the type indicated in flags.  Return 0 on failure to allocate memory.
+ */
+extern JSAtom *
+js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags);
+
+/*
+ * Find or create the atom for a string.  If we create a new atom, give it the
+ * type indicated in flags.  Return 0 on failure to allocate memory.
+ */
+extern JSAtom *
+js_AtomizeString(JSContext *cx, JSString *str, uintN flags);
+
+extern JS_FRIEND_API(JSAtom *)
+js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags);
+
+extern JS_FRIEND_API(JSAtom *)
+js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags);
+
+/*
+ * This variant handles all value tag types.
+ */
+extern JSAtom *
+js_AtomizeValue(JSContext *cx, jsval value, uintN flags);
+
+/*
+ * Convert v to an atomized string.
+ */
+extern JSAtom *
+js_ValueToStringAtom(JSContext *cx, jsval v);
+
+/*
+ * Assign atom an index and insert it on al.
+ */
+extern JSAtomListElement *
+js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al);
+
+/*
+ * Get the atom with index i from map.
+ */
+extern JS_FRIEND_API(JSAtom *)
+js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i);
+
+/*
+ * For all unmapped atoms recorded in al, add a mapping from the atom's index
+ * to its address.  The GC must not run until all indexed atoms in atomLists
+ * have been mapped by scripts connected to live objects (Function and Script
+ * class objects have scripts as/in their private data -- the GC knows about
+ * these two classes).
+ */
+extern JS_FRIEND_API(JSBool)
+js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al);
+
+/*
+ * Free map->vector and clear map.
+ */
+extern JS_FRIEND_API(void)
+js_FreeAtomMap(JSContext *cx, JSAtomMap *map);
+
+JS_END_EXTERN_C
+
+#endif /* jsatom_h___ */

Added: freeswitch/trunk/libs/js/src/jsautocfg.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsautocfg.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,52 @@
+#ifndef js_cpucfg___
+#define js_cpucfg___
+
+/* AUTOMATICALLY GENERATED - DO NOT EDIT */
+
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define JS_BYTES_PER_BYTE   1L
+#define JS_BYTES_PER_SHORT  2L
+#define JS_BYTES_PER_INT    4L
+#define JS_BYTES_PER_INT64  8L
+#define JS_BYTES_PER_LONG   4L
+#define JS_BYTES_PER_FLOAT  4L
+#define JS_BYTES_PER_DOUBLE 8L
+#define JS_BYTES_PER_WORD   4L
+#define JS_BYTES_PER_DWORD  8L
+
+#define JS_BITS_PER_BYTE    8L
+#define JS_BITS_PER_SHORT   16L
+#define JS_BITS_PER_INT     32L
+#define JS_BITS_PER_INT64   64L
+#define JS_BITS_PER_LONG    32L
+#define JS_BITS_PER_FLOAT   32L
+#define JS_BITS_PER_DOUBLE  64L
+#define JS_BITS_PER_WORD    32L
+
+#define JS_BITS_PER_BYTE_LOG2   3L
+#define JS_BITS_PER_SHORT_LOG2  4L
+#define JS_BITS_PER_INT_LOG2    5L
+#define JS_BITS_PER_INT64_LOG2  6L
+#define JS_BITS_PER_LONG_LOG2   5L
+#define JS_BITS_PER_FLOAT_LOG2  5L
+#define JS_BITS_PER_DOUBLE_LOG2 6L
+#define JS_BITS_PER_WORD_LOG2   5L
+
+#define JS_ALIGN_OF_SHORT   2L
+#define JS_ALIGN_OF_INT     4L
+#define JS_ALIGN_OF_LONG    4L
+#define JS_ALIGN_OF_INT64   4L
+#define JS_ALIGN_OF_FLOAT   4L
+#define JS_ALIGN_OF_DOUBLE  4L
+#define JS_ALIGN_OF_POINTER 4L
+#define JS_ALIGN_OF_WORD    4L
+
+#define JS_BYTES_PER_WORD_LOG2   2L
+#define JS_BYTES_PER_DWORD_LOG2  3L
+#define JS_WORDS_PER_DWORD_LOG2  1L
+
+#define JS_STACK_GROWTH_DIRECTION (-1)
+
+#endif /* js_cpucfg___ */

Added: freeswitch/trunk/libs/js/src/jsbit.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsbit.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,113 @@
+/* -*- 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 Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsbit_h___
+#define jsbit_h___
+
+#include "jstypes.h"
+JS_BEGIN_EXTERN_C
+
+/*
+** A jsbitmap_t is a long integer that can be used for bitmaps
+*/
+typedef JSUword     jsbitmap_t;     /* NSPR name, a la Unix system types */
+typedef jsbitmap_t  jsbitmap;       /* JS-style scalar typedef name */
+
+#define JS_TEST_BIT(_map,_bit) \
+    ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] & (1L << ((_bit) & (JS_BITS_PER_WORD-1))))
+#define JS_SET_BIT(_map,_bit) \
+    ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |= (1L << ((_bit) & (JS_BITS_PER_WORD-1))))
+#define JS_CLEAR_BIT(_map,_bit) \
+    ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &= ~(1L << ((_bit) & (JS_BITS_PER_WORD-1))))
+
+/*
+** Compute the log of the least power of 2 greater than or equal to n
+*/
+extern JS_PUBLIC_API(JSIntn) JS_CeilingLog2(JSUint32 i);
+
+/*
+** Compute the log of the greatest power of 2 less than or equal to n
+*/
+extern JS_PUBLIC_API(JSIntn) JS_FloorLog2(JSUint32 i);
+
+/*
+** Macro version of JS_CeilingLog2: Compute the log of the least power of
+** 2 greater than or equal to _n. The result is returned in _log2.
+*/
+#define JS_CEILING_LOG2(_log2,_n)                                             \
+    JS_BEGIN_MACRO                                                            \
+        JSUint32 j_ = (JSUint32)(_n);                                         \
+        (_log2) = 0;                                                          \
+        if ((j_) & ((j_)-1))                                                  \
+            (_log2) += 1;                                                     \
+        if ((j_) >> 16)                                                       \
+            (_log2) += 16, (j_) >>= 16;                                       \
+        if ((j_) >> 8)                                                        \
+            (_log2) += 8, (j_) >>= 8;                                         \
+        if ((j_) >> 4)                                                        \
+            (_log2) += 4, (j_) >>= 4;                                         \
+        if ((j_) >> 2)                                                        \
+            (_log2) += 2, (j_) >>= 2;                                         \
+        if ((j_) >> 1)                                                        \
+            (_log2) += 1;                                                     \
+    JS_END_MACRO
+
+/*
+** Macro version of JS_FloorLog2: Compute the log of the greatest power of
+** 2 less than or equal to _n. The result is returned in _log2.
+**
+** This is equivalent to finding the highest set bit in the word.
+*/
+#define JS_FLOOR_LOG2(_log2,_n)                                               \
+    JS_BEGIN_MACRO                                                            \
+        JSUint32 j_ = (JSUint32)(_n);                                         \
+        (_log2) = 0;                                                          \
+        if ((j_) >> 16)                                                       \
+            (_log2) += 16, (j_) >>= 16;                                       \
+        if ((j_) >> 8)                                                        \
+            (_log2) += 8, (j_) >>= 8;                                         \
+        if ((j_) >> 4)                                                        \
+            (_log2) += 4, (j_) >>= 4;                                         \
+        if ((j_) >> 2)                                                        \
+            (_log2) += 2, (j_) >>= 2;                                         \
+        if ((j_) >> 1)                                                        \
+            (_log2) += 1;                                                     \
+    JS_END_MACRO
+
+JS_END_EXTERN_C
+#endif /* jsbit_h___ */

Added: freeswitch/trunk/libs/js/src/jsbool.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsbool.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,215 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS boolean implementation.
+ */
+#include "jsstddef.h"
+#include "jstypes.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jsbool.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsstr.h"
+
+JSClass js_BooleanClass = {
+    "Boolean",
+    JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+#if JS_HAS_TOSOURCE
+#include "jsprf.h"
+
+static JSBool
+bool_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    jsval v;
+    char buf[32];
+    JSString *str;
+
+    if (!JS_InstanceOf(cx, obj, &js_BooleanClass, argv))
+        return JS_FALSE;
+    v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    if (!JSVAL_IS_BOOLEAN(v))
+        return js_obj_toSource(cx, obj, argc, argv, rval);
+    JS_snprintf(buf, sizeof buf, "(new %s(%s))",
+                js_BooleanClass.name,
+                js_boolean_str[JSVAL_TO_BOOLEAN(v) ? 1 : 0]);
+    str = JS_NewStringCopyZ(cx, buf);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+#endif
+
+static JSBool
+bool_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    jsval v;
+    JSAtom *atom;
+    JSString *str;
+
+    if (!JS_InstanceOf(cx, obj, &js_BooleanClass, argv))
+        return JS_FALSE;
+    v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    if (!JSVAL_IS_BOOLEAN(v))
+        return js_obj_toString(cx, obj, argc, argv, rval);
+    atom = cx->runtime->atomState.booleanAtoms[JSVAL_TO_BOOLEAN(v) ? 1 : 0];
+    str = ATOM_TO_STRING(atom);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+bool_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    if (!JS_InstanceOf(cx, obj, &js_BooleanClass, argv))
+        return JS_FALSE;
+    *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    return JS_TRUE;
+}
+
+static JSFunctionSpec boolean_methods[] = {
+#if JS_HAS_TOSOURCE
+    {js_toSource_str,   bool_toSource,          0,0,0},
+#endif
+    {js_toString_str,   bool_toString,          0,0,0},
+    {js_valueOf_str,    bool_valueOf,           0,0,0},
+    {0,0,0,0,0}
+};
+
+static JSBool
+Boolean(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSBool b;
+    jsval bval;
+
+    if (argc != 0) {
+        if (!js_ValueToBoolean(cx, argv[0], &b))
+            return JS_FALSE;
+        bval = BOOLEAN_TO_JSVAL(b);
+    } else {
+        bval = JSVAL_FALSE;
+    }
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        *rval = bval;
+        return JS_TRUE;
+    }
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, bval);
+    return JS_TRUE;
+}
+
+JSObject *
+js_InitBooleanClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto;
+
+    proto = JS_InitClass(cx, obj, NULL, &js_BooleanClass, Boolean, 1,
+                        NULL, boolean_methods, NULL, NULL);
+    if (!proto)
+        return NULL;
+    OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, JSVAL_FALSE);
+    return proto;
+}
+
+JSObject *
+js_BooleanToObject(JSContext *cx, JSBool b)
+{
+    JSObject *obj;
+
+    obj = js_NewObject(cx, &js_BooleanClass, NULL, NULL);
+    if (!obj)
+        return NULL;
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, BOOLEAN_TO_JSVAL(b));
+    return obj;
+}
+
+JSString *
+js_BooleanToString(JSContext *cx, JSBool b)
+{
+    return ATOM_TO_STRING(cx->runtime->atomState.booleanAtoms[b ? 1 : 0]);
+}
+
+JSBool
+js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp)
+{
+    JSBool b;
+    jsdouble d;
+
+    if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) {
+        b = JS_FALSE;
+    } else if (JSVAL_IS_OBJECT(v)) {
+        if (!JS_VERSION_IS_ECMA(cx)) {
+            if (!OBJ_DEFAULT_VALUE(cx, JSVAL_TO_OBJECT(v), JSTYPE_BOOLEAN, &v))
+                return JS_FALSE;
+            if (!JSVAL_IS_BOOLEAN(v))
+                v = JSVAL_TRUE;         /* non-null object is true */
+            b = JSVAL_TO_BOOLEAN(v);
+        } else {
+            b = JS_TRUE;
+        }
+    } else if (JSVAL_IS_STRING(v)) {
+        b = JSSTRING_LENGTH(JSVAL_TO_STRING(v)) ? JS_TRUE : JS_FALSE;
+    } else if (JSVAL_IS_INT(v)) {
+        b = JSVAL_TO_INT(v) ? JS_TRUE : JS_FALSE;
+    } else if (JSVAL_IS_DOUBLE(v)) {
+        d = *JSVAL_TO_DOUBLE(v);
+        b = (!JSDOUBLE_IS_NaN(d) && d != 0) ? JS_TRUE : JS_FALSE;
+    } else {
+        JS_ASSERT(JSVAL_IS_BOOLEAN(v));
+        b = JSVAL_TO_BOOLEAN(v);
+    }
+
+    *bp = b;
+    return JS_TRUE;
+}

Added: freeswitch/trunk/libs/js/src/jsbool.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsbool.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,64 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsbool_h___
+#define jsbool_h___
+/*
+ * JS boolean interface.
+ */
+
+JS_BEGIN_EXTERN_C
+
+extern JSClass js_BooleanClass;
+
+extern JSObject *
+js_InitBooleanClass(JSContext *cx, JSObject *obj);
+
+extern JSObject *
+js_BooleanToObject(JSContext *cx, JSBool b);
+
+extern JSString *
+js_BooleanToString(JSContext *cx, JSBool b);
+
+extern JSBool
+js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp);
+
+JS_END_EXTERN_C
+
+#endif /* jsbool_h___ */

Added: freeswitch/trunk/libs/js/src/jsclist.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsclist.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,139 @@
+/* -*- 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 Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsclist_h___
+#define jsclist_h___
+
+#include "jstypes.h"
+
+/*
+** Circular linked list
+*/
+typedef struct JSCListStr {
+    struct JSCListStr *next;
+    struct JSCListStr *prev;
+} JSCList;
+
+/*
+** Insert element "_e" into the list, before "_l".
+*/
+#define JS_INSERT_BEFORE(_e,_l)  \
+    JS_BEGIN_MACRO               \
+        (_e)->next = (_l);       \
+        (_e)->prev = (_l)->prev; \
+        (_l)->prev->next = (_e); \
+        (_l)->prev = (_e);       \
+    JS_END_MACRO
+
+/*
+** Insert element "_e" into the list, after "_l".
+*/
+#define JS_INSERT_AFTER(_e,_l)   \
+    JS_BEGIN_MACRO               \
+        (_e)->next = (_l)->next; \
+        (_e)->prev = (_l);       \
+        (_l)->next->prev = (_e); \
+        (_l)->next = (_e);       \
+    JS_END_MACRO
+
+/*
+** Return the element following element "_e"
+*/
+#define JS_NEXT_LINK(_e)         \
+        ((_e)->next)
+/*
+** Return the element preceding element "_e"
+*/
+#define JS_PREV_LINK(_e)         \
+        ((_e)->prev)
+
+/*
+** Append an element "_e" to the end of the list "_l"
+*/
+#define JS_APPEND_LINK(_e,_l) JS_INSERT_BEFORE(_e,_l)
+
+/*
+** Insert an element "_e" at the head of the list "_l"
+*/
+#define JS_INSERT_LINK(_e,_l) JS_INSERT_AFTER(_e,_l)
+
+/* Return the head/tail of the list */
+#define JS_LIST_HEAD(_l) (_l)->next
+#define JS_LIST_TAIL(_l) (_l)->prev
+
+/*
+** Remove the element "_e" from it's circular list.
+*/
+#define JS_REMOVE_LINK(_e)             \
+    JS_BEGIN_MACRO                     \
+        (_e)->prev->next = (_e)->next; \
+        (_e)->next->prev = (_e)->prev; \
+    JS_END_MACRO
+
+/*
+** Remove the element "_e" from it's circular list. Also initializes the
+** linkage.
+*/
+#define JS_REMOVE_AND_INIT_LINK(_e)    \
+    JS_BEGIN_MACRO                     \
+        (_e)->prev->next = (_e)->next; \
+        (_e)->next->prev = (_e)->prev; \
+        (_e)->next = (_e);             \
+        (_e)->prev = (_e);             \
+    JS_END_MACRO
+
+/*
+** Return non-zero if the given circular list "_l" is empty, zero if the
+** circular list is not empty
+*/
+#define JS_CLIST_IS_EMPTY(_l) \
+    ((_l)->next == (_l))
+
+/*
+** Initialize a circular list
+*/
+#define JS_INIT_CLIST(_l)  \
+    JS_BEGIN_MACRO         \
+        (_l)->next = (_l); \
+        (_l)->prev = (_l); \
+    JS_END_MACRO
+
+#define JS_INIT_STATIC_CLIST(_l) \
+    {(_l), (_l)}
+
+#endif /* jsclist_h___ */

Added: freeswitch/trunk/libs/js/src/jscntxt.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jscntxt.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1091 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS execution context.
+ */
+#include "jsstddef.h"
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsclist.h"
+#include "jsprf.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsdbgapi.h"
+#include "jsexn.h"
+#include "jsgc.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsopcode.h"
+#include "jsscan.h"
+#include "jsscript.h"
+#include "jsstr.h"
+
+void
+js_OnVersionChange(JSContext *cx)
+{
+#if !JS_BUG_FALLIBLE_EQOPS
+    if (JS_VERSION_IS_1_2(cx)) {
+        cx->jsop_eq = JSOP_NEW_EQ;
+        cx->jsop_ne = JSOP_NEW_NE;
+    } else {
+        cx->jsop_eq = JSOP_EQ;
+        cx->jsop_ne = JSOP_NE;
+    }
+#endif /* !JS_BUG_FALLIBLE_EQOPS */
+}
+
+void
+js_SetVersion(JSContext *cx, JSVersion version)
+{
+    cx->version = version;
+    js_OnVersionChange(cx);
+}
+
+JSContext *
+js_NewContext(JSRuntime *rt, size_t stackChunkSize)
+{
+    JSContext *cx;
+    JSBool ok, first;
+
+    cx = (JSContext *) malloc(sizeof *cx);
+    if (!cx)
+        return NULL;
+    memset(cx, 0, sizeof *cx);
+
+    cx->runtime = rt;
+#if JS_STACK_GROWTH_DIRECTION > 0
+    cx->stackLimit = (jsuword)-1;
+#endif
+#ifdef JS_THREADSAFE
+    js_InitContextForLocking(cx);
+#endif
+
+    JS_LOCK_GC(rt);
+    for (;;) {
+        first = (rt->contextList.next == &rt->contextList);
+        if (rt->state == JSRTS_UP) {
+            JS_ASSERT(!first);
+            break;
+        }
+        if (rt->state == JSRTS_DOWN) {
+            JS_ASSERT(first);
+            rt->state = JSRTS_LAUNCHING;
+            break;
+        }
+        JS_WAIT_CONDVAR(rt->stateChange, JS_NO_TIMEOUT);
+    }
+    JS_APPEND_LINK(&cx->links, &rt->contextList);
+    JS_UNLOCK_GC(rt);
+
+    /*
+     * First we do the infallible, every-time per-context initializations.
+     * Should a later, fallible initialization (js_InitRegExpStatics, e.g.,
+     * or the stuff under 'if (first)' below) fail, at least the version
+     * and arena-pools will be valid and safe to use (say, from the last GC
+     * done by js_DestroyContext).
+     */
+    cx->version = JSVERSION_DEFAULT;
+    cx->jsop_eq = JSOP_EQ;
+    cx->jsop_ne = JSOP_NE;
+    JS_InitArenaPool(&cx->stackPool, "stack", stackChunkSize, sizeof(jsval));
+    JS_InitArenaPool(&cx->tempPool, "temp", 1024, sizeof(jsdouble));
+
+#if JS_HAS_REGEXPS
+    if (!js_InitRegExpStatics(cx, &cx->regExpStatics)) {
+        js_DestroyContext(cx, JS_NO_GC);
+        return NULL;
+    }
+#endif
+#if JS_HAS_EXCEPTIONS
+    cx->throwing = JS_FALSE;
+#endif
+
+    /*
+     * If cx is the first context on this runtime, initialize well-known atoms,
+     * keywords, numbers, and strings.  If one of these steps should fail, the
+     * runtime will be left in a partially initialized state, with zeroes and
+     * nulls stored in the default-initialized remainder of the struct.  We'll
+     * clean the runtime up under js_DestroyContext, because cx will be "last"
+     * as well as "first".
+     */
+    if (first) {
+        /*
+         * Both atomState and the scriptFilenameTable may be left over from a
+         * previous episode of non-zero contexts alive in rt, so don't re-init
+         * either table if it's not necessary.  Just repopulate atomState with
+         * well-known internal atoms, and with the reserved identifiers added
+         * by the scanner.
+         */
+        ok = (rt->atomState.liveAtoms == 0)
+             ? js_InitAtomState(cx, &rt->atomState)
+             : js_InitPinnedAtoms(cx, &rt->atomState);
+        if (ok)
+            ok = js_InitScanner(cx);
+        if (ok && !rt->scriptFilenameTable)
+            ok = js_InitRuntimeScriptState(rt);
+        if (ok)
+            ok = js_InitRuntimeNumberState(cx);
+        if (ok)
+            ok = js_InitRuntimeStringState(cx);
+        if (!ok) {
+            js_DestroyContext(cx, JS_NO_GC);
+            return NULL;
+        }
+
+        JS_LOCK_GC(rt);
+        rt->state = JSRTS_UP;
+        JS_NOTIFY_ALL_CONDVAR(rt->stateChange);
+        JS_UNLOCK_GC(rt);
+    }
+
+    return cx;
+}
+
+void
+js_DestroyContext(JSContext *cx, JSGCMode gcmode)
+{
+    JSRuntime *rt;
+    JSBool last;
+    JSArgumentFormatMap *map;
+    JSLocalRootStack *lrs;
+    JSLocalRootChunk *lrc;
+
+    rt = cx->runtime;
+
+    /* Remove cx from context list first. */
+    JS_LOCK_GC(rt);
+    JS_ASSERT(rt->state == JSRTS_UP || rt->state == JSRTS_LAUNCHING);
+    JS_REMOVE_LINK(&cx->links);
+    last = (rt->contextList.next == &rt->contextList);
+    if (last)
+        rt->state = JSRTS_LANDING;
+    JS_UNLOCK_GC(rt);
+
+    if (last) {
+#ifdef JS_THREADSAFE
+        /*
+         * If cx is not in a request already, begin one now so that we wait
+         * for any racing GC started on a not-last context to finish, before
+         * we plow ahead and unpin atoms.  Note that even though we begin a
+         * request here if necessary, we end all requests on cx below before
+         * forcing a final GC.  This lets any not-last context destruction
+         * racing in another thread try to force or maybe run the GC, but by
+         * that point, rt->state will not be JSRTS_UP, and that GC attempt
+         * will return early.
+         */
+        if (cx->requestDepth == 0)
+            JS_BeginRequest(cx);
+#endif
+
+        /* Unpin all pinned atoms before final GC. */
+        js_UnpinPinnedAtoms(&rt->atomState);
+
+        /* Unlock and clear GC things held by runtime pointers. */
+        js_FinishRuntimeNumberState(cx);
+        js_FinishRuntimeStringState(cx);
+
+        /* Clear debugging state to remove GC roots. */
+        JS_ClearAllTraps(cx);
+        JS_ClearAllWatchPoints(cx);
+    }
+
+#if JS_HAS_REGEXPS
+    /*
+     * Remove more GC roots in regExpStatics, then collect garbage.
+     * XXX anti-modularity alert: we rely on the call to js_RemoveRoot within
+     * XXX this function call to wait for any racing GC to complete, in the
+     * XXX case where JS_DestroyContext is called outside of a request on cx
+     */
+    js_FreeRegExpStatics(cx, &cx->regExpStatics);
+#endif
+
+#ifdef JS_THREADSAFE
+    /*
+     * Destroying a context implicitly calls JS_EndRequest().  Also, we must
+     * end our request here in case we are "last" -- in that event, another
+     * js_DestroyContext that was not last might be waiting in the GC for our
+     * request to end.  We'll let it run below, just before we do the truly
+     * final GC and then free atom state.
+     *
+     * At this point, cx must be inaccessible to other threads.  It's off the
+     * rt->contextList, and it should not be reachable via any object private
+     * data structure.
+     */
+    while (cx->requestDepth != 0)
+        JS_EndRequest(cx);
+#endif
+
+    if (last) {
+        /* Always force, so we wait for any racing GC to finish. */
+        js_ForceGC(cx, GC_LAST_CONTEXT);
+
+        /* Iterate until no finalizer removes a GC root or lock. */
+        while (rt->gcPoke)
+            js_GC(cx, GC_LAST_CONTEXT);
+
+        /* Try to free atom state, now that no unrooted scripts survive. */
+        if (rt->atomState.liveAtoms == 0)
+            js_FreeAtomState(cx, &rt->atomState);
+
+        /* Also free the script filename table if it exists and is empty. */
+        if (rt->scriptFilenameTable && rt->scriptFilenameTable->nentries == 0)
+            js_FinishRuntimeScriptState(rt);
+
+        /* Take the runtime down, now that it has no contexts or atoms. */
+        JS_LOCK_GC(rt);
+        rt->state = JSRTS_DOWN;
+        JS_NOTIFY_ALL_CONDVAR(rt->stateChange);
+        JS_UNLOCK_GC(rt);
+    } else {
+        if (gcmode == JS_FORCE_GC)
+            js_ForceGC(cx, 0);
+        else if (gcmode == JS_MAYBE_GC)
+            JS_MaybeGC(cx);
+    }
+
+    /* Free the stuff hanging off of cx. */
+    JS_FinishArenaPool(&cx->stackPool);
+    JS_FinishArenaPool(&cx->tempPool);
+    if (cx->lastMessage)
+        free(cx->lastMessage);
+
+    /* Remove any argument formatters. */
+    map = cx->argumentFormatMap;
+    while (map) {
+        JSArgumentFormatMap *temp = map;
+        map = map->next;
+        JS_free(cx, temp);
+    }
+
+    /* Destroy the resolve recursion damper. */
+    if (cx->resolvingTable) {
+        JS_DHashTableDestroy(cx->resolvingTable);
+        cx->resolvingTable = NULL;
+    }
+
+    lrs = cx->localRootStack;
+    if (lrs) {
+        while ((lrc = lrs->topChunk) != &lrs->firstChunk) {
+            lrs->topChunk = lrc->down;
+            JS_free(cx, lrc);
+        }
+        JS_free(cx, lrs);
+    }
+
+    /* Finally, free cx itself. */
+    free(cx);
+}
+
+JSBool
+js_ValidContextPointer(JSRuntime *rt, JSContext *cx)
+{
+    JSCList *cl;
+
+    for (cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next) {
+        if (cl == &cx->links)
+            return JS_TRUE;
+    }
+    JS_RUNTIME_METER(rt, deadContexts);
+    return JS_FALSE;
+}
+
+JSContext *
+js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp)
+{
+    JSContext *cx = *iterp;
+
+    if (unlocked)
+        JS_LOCK_GC(rt);
+    if (!cx)
+        cx = (JSContext *)&rt->contextList;
+    cx = (JSContext *)cx->links.next;
+    if (&cx->links == &rt->contextList)
+        cx = NULL;
+    *iterp = cx;
+    if (unlocked)
+        JS_UNLOCK_GC(rt);
+    return cx;
+}
+
+JS_STATIC_DLL_CALLBACK(const void *)
+resolving_GetKey(JSDHashTable *table, JSDHashEntryHdr *hdr)
+{
+    JSResolvingEntry *entry = (JSResolvingEntry *)hdr;
+
+    return &entry->key;
+}
+
+JS_STATIC_DLL_CALLBACK(JSDHashNumber)
+resolving_HashKey(JSDHashTable *table, const void *ptr)
+{
+    const JSResolvingKey *key = (const JSResolvingKey *)ptr;
+
+    return ((JSDHashNumber)JS_PTR_TO_UINT32(key->obj) >> JSVAL_TAGBITS) ^ key->id;
+}
+
+#ifdef OSSP /* BUGFIX */
+JS_STATIC_DLL_CALLBACK(JSBool)
+#else
+JS_PUBLIC_API(JSBool)
+#endif
+resolving_MatchEntry(JSDHashTable *table,
+                     const JSDHashEntryHdr *hdr,
+                     const void *ptr)
+{
+    const JSResolvingEntry *entry = (const JSResolvingEntry *)hdr;
+    const JSResolvingKey *key = (const JSResolvingKey *)ptr;
+
+    return entry->key.obj == key->obj && entry->key.id == key->id;
+}
+
+static const JSDHashTableOps resolving_dhash_ops = {
+    JS_DHashAllocTable,
+    JS_DHashFreeTable,
+    resolving_GetKey,
+    resolving_HashKey,
+    resolving_MatchEntry,
+    JS_DHashMoveEntryStub,
+    JS_DHashClearEntryStub,
+    JS_DHashFinalizeStub,
+    NULL
+};
+
+JSBool
+js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
+                  JSResolvingEntry **entryp)
+{
+    JSDHashTable *table;
+    JSResolvingEntry *entry;
+
+    table = cx->resolvingTable;
+    if (!table) {
+        table = JS_NewDHashTable(&resolving_dhash_ops, NULL,
+                                 sizeof(JSResolvingEntry),
+                                 JS_DHASH_MIN_SIZE);
+        if (!table)
+            goto outofmem;
+        cx->resolvingTable = table;
+    }
+
+    entry = (JSResolvingEntry *)
+            JS_DHashTableOperate(table, key, JS_DHASH_ADD);
+    if (!entry)
+        goto outofmem;
+
+    if (entry->flags & flag) {
+        /* An entry for (key, flag) exists already -- dampen recursion. */
+        entry = NULL;
+    } else {
+        /* Fill in key if we were the first to add entry, then set flag. */
+        if (!entry->key.obj)
+            entry->key = *key;
+        entry->flags |= flag;
+    }
+    *entryp = entry;
+    return JS_TRUE;
+
+outofmem:
+    JS_ReportOutOfMemory(cx);
+    return JS_FALSE;
+}
+
+void
+js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
+                 JSResolvingEntry *entry, uint32 generation)
+{
+    JSDHashTable *table;
+
+    /*
+     * Clear flag from entry->flags and return early if other flags remain.
+     * We must take care to re-lookup entry if the table has changed since
+     * it was found by js_StartResolving.
+     */
+    table = cx->resolvingTable;
+    if (!entry || table->generation != generation) {
+        entry = (JSResolvingEntry *)
+                JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP);
+    }
+    JS_ASSERT(JS_DHASH_ENTRY_IS_BUSY(&entry->hdr));
+    entry->flags &= ~flag;
+    if (entry->flags)
+        return;
+
+    /*
+     * Do a raw remove only if fewer entries were removed than would cause
+     * alpha to be less than .5 (alpha is at most .75).  Otherwise, we just
+     * call JS_DHashTableOperate to re-lookup the key and remove its entry,
+     * compressing or shrinking the table as needed.
+     */
+    if (table->removedCount < JS_DHASH_TABLE_SIZE(table) >> 2)
+        JS_DHashTableRawRemove(table, &entry->hdr);
+    else
+        JS_DHashTableOperate(table, key, JS_DHASH_REMOVE);
+}
+
+JSBool
+js_EnterLocalRootScope(JSContext *cx)
+{
+    JSLocalRootStack *lrs;
+    int mark;
+
+    lrs = cx->localRootStack;
+    if (!lrs) {
+        lrs = (JSLocalRootStack *) JS_malloc(cx, sizeof *lrs);
+        if (!lrs)
+            return JS_FALSE;
+        lrs->scopeMark = JSLRS_NULL_MARK;
+        lrs->rootCount = 0;
+        lrs->topChunk = &lrs->firstChunk;
+        lrs->firstChunk.down = NULL;
+        cx->localRootStack = lrs;
+    }
+
+    /* Push lrs->scopeMark to save it for restore when leaving. */
+    mark = js_PushLocalRoot(cx, lrs, INT_TO_JSVAL(lrs->scopeMark));
+    if (mark < 0)
+        return JS_FALSE;
+    lrs->scopeMark = (uint32) mark;
+    return JS_TRUE;
+}
+
+void
+js_LeaveLocalRootScope(JSContext *cx)
+{
+    JSLocalRootStack *lrs;
+    unsigned mark, m, n;
+    JSLocalRootChunk *lrc;
+
+    /* Defend against buggy native callers. */
+    lrs = cx->localRootStack;
+    JS_ASSERT(lrs && lrs->rootCount != 0);
+    if (!lrs || lrs->rootCount == 0)
+        return;
+
+    mark = lrs->scopeMark;
+    JS_ASSERT(mark != JSLRS_NULL_MARK);
+    if (mark == JSLRS_NULL_MARK)
+        return;
+
+    /* Free any chunks being popped by this leave operation. */
+    m = mark >> JSLRS_CHUNK_SHIFT;
+    n = (lrs->rootCount - 1) >> JSLRS_CHUNK_SHIFT;
+    while (n > m) {
+        lrc = lrs->topChunk;
+        JS_ASSERT(lrc != &lrs->firstChunk);
+        lrs->topChunk = lrc->down;
+        JS_free(cx, lrc);
+        --n;
+    }
+
+    /* Pop the scope, restoring lrs->scopeMark. */
+    lrc = lrs->topChunk;
+    m = mark & JSLRS_CHUNK_MASK;
+    lrs->scopeMark = (uint32) JSVAL_TO_INT(lrc->roots[m]);
+    lrc->roots[m] = JSVAL_NULL;
+    lrs->rootCount = (uint32) mark;
+
+    /*
+     * Free the stack eagerly, risking malloc churn.  The alternative would
+     * require an lrs->entryCount member, maintained by Enter and Leave, and
+     * tested by the GC in addition to the cx->localRootStack non-null test.
+     *
+     * That approach would risk hoarding 264 bytes (net) per context.  Right
+     * now it seems better to give fresh (dirty in CPU write-back cache, and
+     * the data is no longer needed) memory back to the malloc heap.
+     */
+    if (mark == 0) {
+        cx->localRootStack = NULL;
+        JS_free(cx, lrs);
+    } else if (m == 0) {
+        lrs->topChunk = lrc->down;
+        JS_free(cx, lrc);
+    }
+}
+
+void
+js_ForgetLocalRoot(JSContext *cx, jsval v)
+{
+    JSLocalRootStack *lrs;
+    unsigned i, j, m, n, mark;
+    JSLocalRootChunk *lrc, *lrc2;
+    jsval top;
+
+    lrs = cx->localRootStack;
+    JS_ASSERT(lrs && lrs->rootCount);
+    if (!lrs || lrs->rootCount == 0)
+        return;
+
+    /* Prepare to pop the top-most value from the stack. */
+    n = lrs->rootCount - 1;
+    m = n & JSLRS_CHUNK_MASK;
+    lrc = lrs->topChunk;
+    top = lrc->roots[m];
+
+    /* Be paranoid about calls on an empty scope. */
+    mark = lrs->scopeMark;
+    JS_ASSERT(mark < n);
+    if (mark >= n)
+        return;
+
+    /* If v was not the last root pushed in the top scope, find it. */
+    if (top != v) {
+        /* Search downward in case v was recently pushed. */
+        i = n;
+        j = m;
+        lrc2 = lrc;
+        while (--i > mark) {
+            if (j == 0)
+                lrc2 = lrc2->down;
+            j = i & JSLRS_CHUNK_MASK;
+            if (lrc2->roots[j] == v)
+                break;
+        }
+
+        /* If we didn't find v in this scope, assert and bail out. */
+        JS_ASSERT(i != mark);
+        if (i == mark)
+            return;
+
+        /* Swap top and v so common tail code can pop v. */
+        lrc2->roots[j] = top;
+    }
+
+    /* Pop the last value from the stack. */
+    lrc->roots[m] = JSVAL_NULL;
+    lrs->rootCount = n;
+    if (m == 0) {
+        JS_ASSERT(n != 0);
+        JS_ASSERT(lrc != &lrs->firstChunk);
+        lrs->topChunk = lrc->down;
+        JS_free(cx, lrc);
+    }
+}
+
+int
+js_PushLocalRoot(JSContext *cx, JSLocalRootStack *lrs, jsval v)
+{
+    unsigned n, m;
+    JSLocalRootChunk *lrc;
+
+    n = lrs->rootCount;
+    m = n & JSLRS_CHUNK_MASK;
+    if (n == 0 || m != 0) {
+        /*
+         * At start of first chunk, or not at start of a non-first top chunk.
+         * Check for lrs->rootCount overflow.
+         */
+        if ((uint32)(n + 1) == 0) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_TOO_MANY_LOCAL_ROOTS);
+            return -1;
+        }
+        lrc = lrs->topChunk;
+        JS_ASSERT(n != 0 || lrc == &lrs->firstChunk);
+    } else {
+        /*
+         * After lrs->firstChunk, trying to index at a power-of-two chunk
+         * boundary: need a new chunk.
+         */
+        lrc = (JSLocalRootChunk *) JS_malloc(cx, sizeof *lrc);
+        if (!lrc)
+            return -1;
+        lrc->down = lrs->topChunk;
+        lrs->topChunk = lrc;
+    }
+    lrs->rootCount = n + 1;
+    lrc->roots[m] = v;
+    return (int) n;
+}
+
+void
+js_MarkLocalRoots(JSContext *cx, JSLocalRootStack *lrs)
+{
+    unsigned n, m, mark;
+    JSLocalRootChunk *lrc;
+
+    n = lrs->rootCount;
+    if (n == 0)
+        return;
+
+    mark = lrs->scopeMark;
+    lrc = lrs->topChunk;
+    do {
+        while (--n > mark) {
+#ifdef GC_MARK_DEBUG
+            char name[22];
+            JS_snprintf(name, sizeof name, "<local root %u>", n);
+#else
+            const char *name = NULL;
+#endif
+            m = n & JSLRS_CHUNK_MASK;
+            JS_ASSERT(JSVAL_IS_GCTHING(lrc->roots[m]));
+            JS_MarkGCThing(cx, JSVAL_TO_GCTHING(lrc->roots[m]), name, NULL);
+            if (m == 0)
+                lrc = lrc->down;
+        }
+        m = n & JSLRS_CHUNK_MASK;
+        mark = JSVAL_TO_INT(lrc->roots[m]);
+        if (m == 0)
+            lrc = lrc->down;
+    } while (n != 0);
+    JS_ASSERT(!lrc);
+}
+
+static void
+ReportError(JSContext *cx, const char *message, JSErrorReport *reportp)
+{
+    /*
+     * Check the error report, and set a JavaScript-catchable exception
+     * if the error is defined to have an associated exception.  If an
+     * exception is thrown, then the JSREPORT_EXCEPTION flag will be set
+     * on the error report, and exception-aware hosts should ignore it.
+     */
+    if (reportp && reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
+        reportp->flags |= JSREPORT_EXCEPTION;
+
+#if JS_HAS_ERROR_EXCEPTIONS
+    /*
+     * Call the error reporter only if an exception wasn't raised.
+     *
+     * If an exception was raised, then we call the debugErrorHook
+     * (if present) to give it a chance to see the error before it
+     * propagates out of scope.  This is needed for compatability
+     * with the old scheme.
+     */
+    if (!js_ErrorToException(cx, message, reportp)) {
+        js_ReportErrorAgain(cx, message, reportp);
+    } else if (cx->runtime->debugErrorHook && cx->errorReporter) {
+        JSDebugErrorHook hook = cx->runtime->debugErrorHook;
+        /* test local in case debugErrorHook changed on another thread */
+        if (hook)
+            hook(cx, message, reportp, cx->runtime->debugErrorHookData);
+    }
+#else
+    js_ReportErrorAgain(cx, message, reportp);
+#endif
+}
+
+/*
+ * We don't post an exception in this case, since doing so runs into
+ * complications of pre-allocating an exception object which required
+ * running the Exception class initializer early etc.
+ * Instead we just invoke the errorReporter with an "Out Of Memory"
+ * type message, and then hope the process ends swiftly.
+ */
+void
+js_ReportOutOfMemory(JSContext *cx)
+{
+    JSStackFrame *fp;
+    JSErrorReport report;
+    JSErrorReporter onError = cx->errorReporter;
+
+    /* Get the message for this error, but we won't expand any arguments. */
+    const JSErrorFormatString *efs = 
+        js_GetLocalizedErrorMessage(cx, NULL, NULL, JSMSG_OUT_OF_MEMORY);
+    const char *msg = efs ? efs->format : "Out of memory";
+
+    /* Fill out the report, but don't do anything that requires allocation. */
+    memset(&report, 0, sizeof (struct JSErrorReport));
+    report.flags = JSREPORT_ERROR;
+    report.errorNumber = JSMSG_OUT_OF_MEMORY;
+
+    /*
+     * Walk stack until we find a frame that is associated with some script
+     * rather than a native frame.
+     */
+    for (fp = cx->fp; fp; fp = fp->down) {
+        if (fp->script && fp->pc) {
+            report.filename = fp->script->filename;
+            report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
+            break;
+        }
+    }
+
+    /*
+     * If debugErrorHook is present then we give it a chance to veto
+     * sending the error on to the regular ErrorReporter.
+     */
+    if (onError) {
+        JSDebugErrorHook hook = cx->runtime->debugErrorHook;
+        if (hook &&
+            !hook(cx, msg, &report, cx->runtime->debugErrorHookData)) {
+            onError = NULL;
+        }
+    }
+
+    if (onError)
+        onError(cx, msg, &report);
+}
+
+JSBool
+js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap)
+{
+    char *last;
+    JSStackFrame *fp;
+    JSErrorReport report;
+    JSBool warning;
+
+    if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))
+        return JS_TRUE;
+
+    last = JS_vsmprintf(format, ap);
+    if (!last)
+        return JS_FALSE;
+
+    memset(&report, 0, sizeof (struct JSErrorReport));
+    report.flags = flags;
+
+    /* Find the top-most active script frame, for best line number blame. */
+    for (fp = cx->fp; fp; fp = fp->down) {
+        if (fp->script && fp->pc) {
+            report.filename = fp->script->filename;
+            report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
+            break;
+        }
+    }
+
+    warning = JSREPORT_IS_WARNING(report.flags);
+    if (warning && JS_HAS_WERROR_OPTION(cx)) {
+        report.flags &= ~JSREPORT_WARNING;
+        warning = JS_FALSE;
+    }
+
+    ReportError(cx, last, &report);
+    free(last);
+    return warning;
+}
+
+/*
+ * The arguments from ap need to be packaged up into an array and stored
+ * into the report struct.
+ *
+ * The format string addressed by the error number may contain operands
+ * identified by the format {N}, where N is a decimal digit. Each of these
+ * is to be replaced by the Nth argument from the va_list. The complete
+ * message is placed into reportp->ucmessage converted to a JSString.
+ *
+ * Returns true if the expansion succeeds (can fail if out of memory).
+ */
+JSBool
+js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
+                        void *userRef, const uintN errorNumber,
+                        char **messagep, JSErrorReport *reportp,
+                        JSBool *warningp, JSBool charArgs, va_list ap)
+{
+    const JSErrorFormatString *efs;
+    int i;
+    int argCount;
+
+    *warningp = JSREPORT_IS_WARNING(reportp->flags);
+    if (*warningp && JS_HAS_WERROR_OPTION(cx)) {
+        reportp->flags &= ~JSREPORT_WARNING;
+        *warningp = JS_FALSE;
+    }
+
+    *messagep = NULL;
+
+    /* Most calls supply js_GetErrorMessage; if this is so, assume NULL. */
+    if (!callback || callback == js_GetErrorMessage)
+        efs = js_GetLocalizedErrorMessage(cx, userRef, NULL, errorNumber);
+    else
+        efs = callback(userRef, NULL, errorNumber);
+    if (efs) {
+        size_t totalArgsLength = 0;
+        size_t argLengths[10]; /* only {0} thru {9} supported */
+        argCount = efs->argCount;
+        JS_ASSERT(argCount <= 10);
+        if (argCount > 0) {
+            /*
+             * Gather the arguments into an array, and accumulate
+             * their sizes. We allocate 1 more than necessary and
+             * null it out to act as the caboose when we free the
+             * pointers later.
+             */
+            reportp->messageArgs = (const jschar **)
+                JS_malloc(cx, sizeof(jschar *) * (argCount + 1));
+            if (!reportp->messageArgs)
+                return JS_FALSE;
+            reportp->messageArgs[argCount] = NULL;
+            for (i = 0; i < argCount; i++) {
+                if (charArgs) {
+                    char *charArg = va_arg(ap, char *);
+                    size_t charArgLength = strlen(charArg);
+                    reportp->messageArgs[i]
+                        = js_InflateString(cx, charArg, &charArgLength);
+                    if (!reportp->messageArgs[i])
+                        goto error;
+                } else {
+                    reportp->messageArgs[i] = va_arg(ap, jschar *);
+                }
+                argLengths[i] = js_strlen(reportp->messageArgs[i]);
+                totalArgsLength += argLengths[i];
+            }
+            /* NULL-terminate for easy copying. */
+            reportp->messageArgs[i] = NULL;
+        }
+        /*
+         * Parse the error format, substituting the argument X
+         * for {X} in the format.
+         */
+        if (argCount > 0) {
+            if (efs->format) {
+                jschar *buffer, *fmt, *out;
+                int expandedArgs = 0;
+                size_t expandedLength;
+                size_t len = strlen(efs->format);
+
+                buffer = fmt = js_InflateString (cx, efs->format, &len);
+                if (!buffer)
+                    goto error;
+                expandedLength = len
+                                 - (3 * argCount)       /* exclude the {n} */
+                                 + totalArgsLength;
+
+                /*
+                * Note - the above calculation assumes that each argument
+                * is used once and only once in the expansion !!!
+                */
+                reportp->ucmessage = out = (jschar *)
+                    JS_malloc(cx, (expandedLength + 1) * sizeof(jschar));
+                if (!out) {
+                    JS_free (cx, buffer);
+                    goto error;
+                }
+                while (*fmt) {
+                    if (*fmt == '{') {
+                        if (isdigit(fmt[1])) {
+                            int d = JS7_UNDEC(fmt[1]);
+                            JS_ASSERT(d < argCount);
+                            js_strncpy(out, reportp->messageArgs[d],
+                                       argLengths[d]);
+                            out += argLengths[d];
+                            fmt += 3;
+                            expandedArgs++;
+                            continue;
+                        }
+                    }
+                    *out++ = *fmt++;
+                }
+                JS_ASSERT(expandedArgs == argCount);
+                *out = 0;
+                JS_free (cx, buffer);
+                *messagep =
+                    js_DeflateString(cx, reportp->ucmessage,
+                                     (size_t)(out - reportp->ucmessage));
+                if (!*messagep)
+                    goto error;
+            }
+        } else {
+            /*
+             * Zero arguments: the format string (if it exists) is the
+             * entire message.
+             */
+            if (efs->format) {
+                size_t len;
+                *messagep = JS_strdup(cx, efs->format);
+                if (!*messagep)
+                    goto error;
+                len = strlen(*messagep);
+                reportp->ucmessage = js_InflateString(cx, *messagep, &len);
+                if (!reportp->ucmessage)
+                    goto error;
+            }
+        }
+    }
+    if (*messagep == NULL) {
+        /* where's the right place for this ??? */
+        const char *defaultErrorMessage
+            = "No error message available for error number %d";
+        size_t nbytes = strlen(defaultErrorMessage) + 16;
+        *messagep = (char *)JS_malloc(cx, nbytes);
+        if (!*messagep)
+            goto error;
+        JS_snprintf(*messagep, nbytes, defaultErrorMessage, errorNumber);
+    }
+    return JS_TRUE;
+
+error:
+    if (reportp->messageArgs) {
+        i = 0;
+        while (reportp->messageArgs[i])
+            JS_free(cx, (void *)reportp->messageArgs[i++]);
+        JS_free(cx, (void *)reportp->messageArgs);
+        reportp->messageArgs = NULL;
+    }
+    if (reportp->ucmessage) {
+        JS_free(cx, (void *)reportp->ucmessage);
+        reportp->ucmessage = NULL;
+    }
+    if (*messagep) {
+        JS_free(cx, (void *)*messagep);
+        *messagep = NULL;
+    }
+    return JS_FALSE;
+}
+
+JSBool
+js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
+                       void *userRef, const uintN errorNumber,
+                       JSBool charArgs, va_list ap)
+{
+    JSStackFrame *fp;
+    JSErrorReport report;
+    char *message;
+    JSBool warning;
+
+    if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))
+        return JS_TRUE;
+
+    memset(&report, 0, sizeof (struct JSErrorReport));
+    report.flags = flags;
+    report.errorNumber = errorNumber;
+
+    /*
+     * If we can't find out where the error was based on the current frame,
+     * see if the next frame has a script/pc combo we can use.
+     */
+    for (fp = cx->fp; fp; fp = fp->down) {
+        if (fp->script && fp->pc) {
+            report.filename = fp->script->filename;
+            report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
+            break;
+        }
+    }
+
+    if (!js_ExpandErrorArguments(cx, callback, userRef, errorNumber,
+                                 &message, &report, &warning, charArgs, ap)) {
+        return JS_FALSE;
+    }
+
+    ReportError(cx, message, &report);
+
+    if (message)
+        JS_free(cx, message);
+    if (report.messageArgs) {
+        /*
+         * js_ExpandErrorArguments owns its messageArgs only if it had to
+         * inflate the arguments (from regular |char *|s).
+         */
+        if (charArgs) {
+            int i = 0;
+            while (report.messageArgs[i])
+                JS_free(cx, (void *)report.messageArgs[i++]);
+        }
+        JS_free(cx, (void *)report.messageArgs);
+    }
+    if (report.ucmessage)
+        JS_free(cx, (void *)report.ucmessage);
+
+    return warning;
+}
+
+JS_FRIEND_API(void)
+js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp)
+{
+    JSErrorReporter onError;
+
+    if (!message)
+        return;
+
+    if (cx->lastMessage)
+        free(cx->lastMessage);
+    cx->lastMessage = JS_strdup(cx, message);
+    if (!cx->lastMessage)
+        return;
+    onError = cx->errorReporter;
+
+    /*
+     * If debugErrorHook is present then we give it a chance to veto
+     * sending the error on to the regular ErrorReporter.
+     */
+    if (onError) {
+        JSDebugErrorHook hook = cx->runtime->debugErrorHook;
+        if (hook &&
+            !hook(cx, cx->lastMessage, reportp,
+                  cx->runtime->debugErrorHookData)) {
+            onError = NULL;
+        }
+    }
+    if (onError)
+        onError(cx, cx->lastMessage, reportp);
+}
+
+void
+js_ReportIsNotDefined(JSContext *cx, const char *name)
+{
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_DEFINED, name);
+}
+
+#if defined DEBUG && defined XP_UNIX
+/* For gdb usage. */
+#ifdef OSSP
+void js_traceon(JSContext *cx);
+void js_traceoff(JSContext *cx);
+#endif
+void js_traceon(JSContext *cx)  { cx->tracefp = stderr; }
+void js_traceoff(JSContext *cx) { cx->tracefp = NULL; }
+#endif
+
+JSErrorFormatString js_ErrorFormatString[JSErr_Limit] = {
+#if JS_HAS_DFLT_MSG_STRINGS
+#define MSG_DEF(name, number, count, exception, format) \
+    { format, count, exception } ,
+#else
+#define MSG_DEF(name, number, count, exception, format) \
+    { NULL, count, exception } ,
+#endif
+#include "js.msg"
+#undef MSG_DEF
+};
+
+const JSErrorFormatString *
+js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
+{
+    if ((errorNumber > 0) && (errorNumber < JSErr_Limit))
+        return &js_ErrorFormatString[errorNumber];
+    return NULL;
+}

Added: freeswitch/trunk/libs/js/src/jscntxt.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jscntxt.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,726 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jscntxt_h___
+#define jscntxt_h___
+/*
+ * JS execution context.
+ */
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsclist.h"
+#include "jslong.h"
+#include "jsatom.h"
+#include "jsconfig.h"
+#include "jsdhash.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jsobj.h"
+#include "jsprvtd.h"
+#include "jspubtd.h"
+#include "jsregexp.h"
+
+JS_BEGIN_EXTERN_C
+
+typedef enum JSGCMode { JS_NO_GC, JS_MAYBE_GC, JS_FORCE_GC } JSGCMode;
+
+typedef enum JSRuntimeState {
+    JSRTS_DOWN,
+    JSRTS_LAUNCHING,
+    JSRTS_UP,
+    JSRTS_LANDING
+} JSRuntimeState;
+
+typedef struct JSPropertyTreeEntry {
+    JSDHashEntryHdr     hdr;
+    JSScopeProperty     *child;
+} JSPropertyTreeEntry;
+
+struct JSRuntime {
+    /* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */
+    JSRuntimeState      state;
+
+    /* Garbage collector state, used by jsgc.c. */
+    JSArenaPool         gcArenaPool[GC_NUM_FREELISTS];
+    JSGCThing           *gcFreeList[GC_NUM_FREELISTS];
+    JSDHashTable        gcRootsHash;
+    JSDHashTable        *gcLocksHash;
+    jsrefcount          gcKeepAtoms;
+    uint32              gcBytes;
+    uint32              gcLastBytes;
+    uint32              gcMaxBytes;
+    uint32              gcLevel;
+    uint32              gcNumber;
+    JSPackedBool        gcPoke;
+    JSPackedBool        gcRunning;
+    JSGCCallback        gcCallback;
+    uint32              gcMallocBytes;
+
+    /*
+     * API compatibility requires keeping GCX_PRIVATE bytes separate from the
+     * original GC types' byte tally.  Otherwise embeddings that configure a
+     * good limit for pre-GCX_PRIVATE versions of the engine will see memory
+     * over-pressure too often, possibly leading to failed last-ditch GCs.
+     *
+     * The new XML GC-thing types do add to gcBytes, and they're larger than
+     * the original GC-thing type size (8 bytes on most architectures).  So a
+     * user who enables E4X may want to increase the maxbytes value passed to
+     * JS_NewRuntime.  TODO: Note this in the API docs.
+     */
+    uint32              gcPrivateBytes;
+
+#if JS_HAS_XML_SUPPORT
+    /* Lists of JSXML private data structures to be finalized. */
+    JSXMLNamespace      *gcDoomedNamespaces;
+    JSXMLQName          *gcDoomedQNames;
+    JSXML               *gcDoomedXML;
+#endif
+#ifdef JS_GCMETER
+    JSGCStats           gcStats;
+#endif
+
+    /* Literal table maintained by jsatom.c functions. */
+    JSAtomState         atomState;
+
+    /* Random number generator state, used by jsmath.c. */
+    JSBool              rngInitialized;
+    int64               rngMultiplier;
+    int64               rngAddend;
+    int64               rngMask;
+    int64               rngSeed;
+    jsdouble            rngDscale;
+
+    /* Well-known numbers held for use by this runtime's contexts. */
+    jsdouble            *jsNaN;
+    jsdouble            *jsNegativeInfinity;
+    jsdouble            *jsPositiveInfinity;
+
+    /* Empty string held for use by this runtime's contexts. */
+    JSString            *emptyString;
+
+    /* List of active contexts sharing this runtime; protected by gcLock. */
+    JSCList             contextList;
+
+    /* These are used for debugging -- see jsprvtd.h and jsdbgapi.h. */
+    JSTrapHandler       interruptHandler;
+    void                *interruptHandlerData;
+    JSNewScriptHook     newScriptHook;
+    void                *newScriptHookData;
+    JSDestroyScriptHook destroyScriptHook;
+    void                *destroyScriptHookData;
+    JSTrapHandler       debuggerHandler;
+    void                *debuggerHandlerData;
+    JSSourceHandler     sourceHandler;
+    void                *sourceHandlerData;
+    JSInterpreterHook   executeHook;
+    void                *executeHookData;
+    JSInterpreterHook   callHook;
+    void                *callHookData;
+    JSObjectHook        objectHook;
+    void                *objectHookData;
+    JSTrapHandler       throwHook;
+    void                *throwHookData;
+    JSDebugErrorHook    debugErrorHook;
+    void                *debugErrorHookData;
+
+    /* More debugging state, see jsdbgapi.c. */
+    JSCList             trapList;
+    JSCList             watchPointList;
+
+    /* Weak links to properties, indexed by quickened get/set opcodes. */
+    /* XXX must come after JSCLists or MSVC alignment bug bites empty lists */
+    JSPropertyCache     propertyCache;
+
+    /* Client opaque pointer */
+    void                *data;
+
+#ifdef JS_THREADSAFE
+    /* These combine to interlock the GC and new requests. */
+    PRLock              *gcLock;
+    PRCondVar           *gcDone;
+    PRCondVar           *requestDone;
+    uint32              requestCount;
+    jsword              gcThread;
+
+    /* Lock and owning thread pointer for JS_LOCK_RUNTIME. */
+    PRLock              *rtLock;
+#ifdef DEBUG
+    jsword              rtLockOwner;
+#endif
+
+    /* Used to synchronize down/up state change; protected by gcLock. */
+    PRCondVar           *stateChange;
+
+    /* Used to serialize cycle checks when setting __proto__ or __parent__. */
+    PRLock              *setSlotLock;
+    PRCondVar           *setSlotDone;
+    JSBool              setSlotBusy;
+    JSScope             *setSlotScope;  /* deadlock avoidance, see jslock.c */
+
+    /*
+     * State for sharing single-threaded scopes, once a second thread tries to
+     * lock a scope.  The scopeSharingDone condvar is protected by rt->gcLock,
+     * to minimize number of locks taken in JS_EndRequest.
+     *
+     * The scopeSharingTodo linked list is likewise "global" per runtime, not
+     * one-list-per-context, to conserve space over all contexts, optimizing
+     * for the likely case that scopes become shared rarely, and among a very
+     * small set of threads (contexts).
+     */
+    PRCondVar           *scopeSharingDone;
+    JSScope             *scopeSharingTodo;
+
+/*
+ * Magic terminator for the rt->scopeSharingTodo linked list, threaded through
+ * scope->u.link.  This hack allows us to test whether a scope is on the list
+ * by asking whether scope->u.link is non-null.  We use a large, likely bogus
+ * pointer here to distinguish this value from any valid u.count (small int)
+ * value.
+ */
+#define NO_SCOPE_SHARING_TODO   ((JSScope *) 0xfeedbeef)
+#endif /* JS_THREADSAFE */
+
+    /*
+     * Check property accessibility for objects of arbitrary class.  Used at
+     * present to check f.caller accessibility for any function object f.
+     */
+    JSCheckAccessOp     checkObjectAccess;
+
+    /* Security principals serialization support. */
+    JSPrincipalsTranscoder principalsTranscoder;
+
+    /* Optional hook to find principals for an object in this runtime. */
+    JSObjectPrincipalsFinder findObjectPrincipals;
+
+    /* Shared scope property tree, and allocator for its nodes. */
+    JSDHashTable        propertyTreeHash;
+    JSScopeProperty     *propertyFreeList;
+    JSArenaPool         propertyArenaPool;
+
+    /* Script filename table. */
+    struct JSHashTable  *scriptFilenameTable;
+    JSCList             scriptFilenamePrefixes;
+#ifdef JS_THREADSAFE
+    PRLock              *scriptFilenameTableLock;
+#endif
+
+    /* Number localization, used by jsnum.c */
+    const char          *thousandsSeparator;
+    const char          *decimalSeparator;
+    const char          *numGrouping;
+
+    /*
+     * Weak references to lazily-created, well-known XML singletons.
+     *
+     * NB: Singleton objects must be carefully disconnected from the rest of
+     * the object graph usually associated with a JSContext's global object,
+     * including the set of standard class objects.  See jsxml.c for details.
+     */
+    JSObject            *anynameObject;
+    JSObject            *functionNamespaceObject;
+
+#ifdef DEBUG
+    /* Function invocation metering. */
+    jsrefcount          inlineCalls;
+    jsrefcount          nativeCalls;
+    jsrefcount          nonInlineCalls;
+    jsrefcount          constructs;
+
+    /* Scope lock and property metering. */
+    jsrefcount          claimAttempts;
+    jsrefcount          claimedScopes;
+    jsrefcount          deadContexts;
+    jsrefcount          deadlocksAvoided;
+    jsrefcount          liveScopes;
+    jsrefcount          sharedScopes;
+    jsrefcount          totalScopes;
+    jsrefcount          badUndependStrings;
+    jsrefcount          liveScopeProps;
+    jsrefcount          totalScopeProps;
+    jsrefcount          livePropTreeNodes;
+    jsrefcount          duplicatePropTreeNodes;
+    jsrefcount          totalPropTreeNodes;
+    jsrefcount          propTreeKidsChunks;
+    jsrefcount          middleDeleteFixups;
+
+    /* String instrumentation. */
+    jsrefcount          liveStrings;
+    jsrefcount          totalStrings;
+    jsrefcount          liveDependentStrings;
+    jsrefcount          totalDependentStrings;
+    double              lengthSum;
+    double              lengthSquaredSum;
+    double              strdepLengthSum;
+    double              strdepLengthSquaredSum;
+#endif
+};
+
+#ifdef DEBUG
+# define JS_RUNTIME_METER(rt, which)    JS_ATOMIC_INCREMENT(&(rt)->which)
+# define JS_RUNTIME_UNMETER(rt, which)  JS_ATOMIC_DECREMENT(&(rt)->which)
+#else
+# define JS_RUNTIME_METER(rt, which)    /* nothing */
+# define JS_RUNTIME_UNMETER(rt, which)  /* nothing */
+#endif
+
+#define JS_KEEP_ATOMS(rt)   JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms);
+#define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms);
+
+#ifdef JS_ARGUMENT_FORMATTER_DEFINED
+/*
+ * Linked list mapping format strings for JS_{Convert,Push}Arguments{,VA} to
+ * formatter functions.  Elements are sorted in non-increasing format string
+ * length order.
+ */
+struct JSArgumentFormatMap {
+    const char          *format;
+    size_t              length;
+    JSArgumentFormatter formatter;
+    JSArgumentFormatMap *next;
+};
+#endif
+
+struct JSStackHeader {
+    uintN               nslots;
+    JSStackHeader       *down;
+};
+
+#define JS_STACK_SEGMENT(sh)    ((jsval *)(sh) + 2)
+
+/*
+ * Key and entry types for the JSContext.resolvingTable hash table, typedef'd
+ * here because all consumers need to see these declarations (and not just the
+ * typedef names, as would be the case for an opaque pointer-to-typedef'd-type
+ * declaration), along with cx->resolvingTable.
+ */
+typedef struct JSResolvingKey {
+    JSObject            *obj;
+    jsid                id;
+} JSResolvingKey;
+
+typedef struct JSResolvingEntry {
+    JSDHashEntryHdr     hdr;
+    JSResolvingKey      key;
+    uint32              flags;
+} JSResolvingEntry;
+
+#define JSRESFLAG_LOOKUP        0x1     /* resolving id from lookup */
+#define JSRESFLAG_WATCH         0x2     /* resolving id from watch */
+
+typedef struct JSLocalRootChunk JSLocalRootChunk;
+
+#define JSLRS_CHUNK_SHIFT       8
+#define JSLRS_CHUNK_SIZE        JS_BIT(JSLRS_CHUNK_SHIFT)
+#define JSLRS_CHUNK_MASK        JS_BITMASK(JSLRS_CHUNK_SHIFT)
+
+struct JSLocalRootChunk {
+    jsval               roots[JSLRS_CHUNK_SIZE];
+    JSLocalRootChunk    *down;
+};
+
+typedef struct JSLocalRootStack {
+    uint32              scopeMark;
+    uint32              rootCount;
+    JSLocalRootChunk    *topChunk;
+    JSLocalRootChunk    firstChunk;
+} JSLocalRootStack;
+
+#define JSLRS_NULL_MARK ((uint32) -1)
+
+typedef struct JSTempValueRooter JSTempValueRooter;
+
+/*
+ * If count is -1, then u.value contains the single value to root.  Otherwise
+ * u.array points to a stack-allocated vector of jsvals.  Note that the vector
+ * may have length 0 or 1 for full generality, so we need -1 to discriminate
+ * the union.
+ *
+ * If you need to protect a result value that flows out of a C function across
+ * several layers of other functions, use the js_LeaveLocalRootScopeWithResult
+ * internal API (see further below) instead.
+ */
+struct JSTempValueRooter {
+    JSTempValueRooter   *down;
+    jsint               count;
+    union {
+        jsval           value;
+        jsval           *array;
+    } u;
+};
+
+#define JS_PUSH_TEMP_ROOT_COMMON(cx,tvr)                                      \
+    JS_BEGIN_MACRO                                                            \
+        JS_ASSERT((cx)->tempValueRooters != (tvr));                           \
+        (tvr)->down = (cx)->tempValueRooters;                                 \
+        (cx)->tempValueRooters = (tvr);                                       \
+    JS_END_MACRO
+
+#define JS_PUSH_SINGLE_TEMP_ROOT(cx,val,tvr)                                  \
+    JS_BEGIN_MACRO                                                            \
+        JS_PUSH_TEMP_ROOT_COMMON(cx, tvr);                                    \
+        (tvr)->count = -1;                                                    \
+        (tvr)->u.value = (val);                                               \
+    JS_END_MACRO
+
+#define JS_PUSH_TEMP_ROOT(cx,cnt,arr,tvr)                                     \
+    JS_BEGIN_MACRO                                                            \
+        JS_PUSH_TEMP_ROOT_COMMON(cx, tvr);                                    \
+        (tvr)->count = (cnt);                                                 \
+        (tvr)->u.array = (arr);                                               \
+    JS_END_MACRO
+
+#define JS_POP_TEMP_ROOT(cx,tvr)                                              \
+    JS_BEGIN_MACRO                                                            \
+        JS_ASSERT((cx)->tempValueRooters == (tvr));                           \
+        (cx)->tempValueRooters = (tvr)->down;                                 \
+    JS_END_MACRO
+
+#define JS_TEMP_ROOT_EVAL(cx,cnt,val,expr)                                    \
+    JS_BEGIN_MACRO                                                            \
+        JSTempValueRooter tvr;                                                \
+        JS_PUSH_TEMP_ROOT(cx, cnt, val, &tvr);                                \
+        (expr);                                                               \
+        JS_POP_TEMP_ROOT(cx, &tvr);                                           \
+    JS_END_MACRO
+
+struct JSContext {
+    JSCList             links;
+
+    /* Interpreter activation count. */
+    uintN               interpLevel;
+
+    /* Limit pointer for checking stack consumption during recursion. */
+    jsuword             stackLimit;
+
+    /* Runtime version control identifier and equality operators. */
+    uint16              version;
+    jsbytecode          jsop_eq;
+    jsbytecode          jsop_ne;
+
+    /* Data shared by threads in an address space. */
+    JSRuntime           *runtime;
+
+    /* Stack arena pool and frame pointer register. */
+    JSArenaPool         stackPool;
+    JSStackFrame        *fp;
+
+    /* Temporary arena pool used while compiling and decompiling. */
+    JSArenaPool         tempPool;
+
+    /* Top-level object and pointer to top stack frame's scope chain. */
+    JSObject            *globalObject;
+
+    /* Most recently created things by type, members of the GC's root set. */
+    JSGCThing           *newborn[GCX_NTYPES];
+
+    /* Atom root for the last-looked-up atom on this context. */
+    JSAtom              *lastAtom;
+
+    /* Root for the result of the most recent js_InternalInvoke call. */
+    jsval               lastInternalResult;
+
+    /* Regular expression class statics (XXX not shared globally). */
+    JSRegExpStatics     regExpStatics;
+
+    /* State for object and array toSource conversion. */
+    JSSharpObjectMap    sharpObjectMap;
+
+    /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */
+    JSArgumentFormatMap *argumentFormatMap;
+
+    /* Last message string and trace file for debugging. */
+    char                *lastMessage;
+#ifdef DEBUG
+    void                *tracefp;
+#endif
+
+    /* Per-context optional user callbacks. */
+    JSBranchCallback    branchCallback;
+    JSErrorReporter     errorReporter;
+
+    /* Client opaque pointer */
+    void                *data;
+
+    /* GC and thread-safe state. */
+    JSStackFrame        *dormantFrameChain; /* dormant stack frame to scan */
+#ifdef JS_THREADSAFE
+    jsword              thread;
+    jsrefcount          requestDepth;
+    JSScope             *scopeToShare;      /* weak reference, see jslock.c */
+    JSScope             *lockedSealedScope; /* weak ref, for low-cost sealed
+                                               scope locking */
+#endif
+
+#if JS_HAS_LVALUE_RETURN
+    /*
+     * Secondary return value from native method called on the left-hand side
+     * of an assignment operator.  The native should store the object in which
+     * to set a property in *rval, and return the property's id expressed as a
+     * jsval by calling JS_SetCallReturnValue2(cx, idval).
+     */
+    jsval               rval2;
+    JSPackedBool        rval2set;
+#endif
+
+#if JS_HAS_XML_SUPPORT
+    /*
+     * Bit-set formed from binary exponentials of the XML_* tiny-ids defined
+     * for boolean settings in jsxml.c, plus an XSF_CACHE_VALID bit.  Together
+     * these act as a cache of the boolean XML.ignore* and XML.prettyPrinting
+     * property values associated with this context's global object.
+     */
+    uint8               xmlSettingFlags;
+#endif
+
+    /*
+     * True if creating an exception object, to prevent runaway recursion.
+     * NB: creatingException packs with rval2set, #if JS_HAS_LVALUE_RETURN;
+     * with xmlSettingFlags, #if JS_HAS_XML_SUPPORT; and with throwing below.
+     */
+    JSPackedBool        creatingException;
+
+    /*
+     * Exception state -- the exception member is a GC root by definition.
+     * NB: throwing packs with creatingException and rval2set, above.
+     */
+    JSPackedBool        throwing;           /* is there a pending exception? */
+    jsval               exception;          /* most-recently-thrown exception */
+
+    /* Per-context options. */
+    uint32              options;            /* see jsapi.h for JSOPTION_* */
+
+    /* Locale specific callbacks for string conversion. */
+    JSLocaleCallbacks   *localeCallbacks;
+
+    /*
+     * cx->resolvingTable is non-null and non-empty if we are initializing
+     * standard classes lazily, or if we are otherwise recursing indirectly
+     * from js_LookupProperty through a JSClass.resolve hook.  It is used to
+     * limit runaway recursion (see jsapi.c and jsobj.c).
+     */
+    JSDHashTable        *resolvingTable;
+
+    /* PDL of stack headers describing stack slots not rooted by argv, etc. */
+    JSStackHeader       *stackHeaders;
+
+    /* Optional stack of heap-allocated scoped local GC roots. */
+    JSLocalRootStack    *localRootStack;
+
+    /* Stack of thread-stack-allocated temporary GC roots. */
+    JSTempValueRooter   *tempValueRooters;
+};
+
+/*
+ * Slightly more readable macros for testing per-context option settings (also
+ * to hide bitset implementation detail).
+ *
+ * JSOPTION_XML must be handled specially in order to propagate from compile-
+ * to run-time (from cx->options to script->version/cx->version).  To do that,
+ * we copy JSOPTION_XML from cx->options into cx->version as JSVERSION_HAS_XML
+ * whenever options are set, and preserve this XML flag across version number
+ * changes done via the JS_SetVersion API.
+ *
+ * But when executing a script or scripted function, the interpreter changes
+ * cx->version, including the XML flag, to script->version.  Thus JSOPTION_XML
+ * is a compile-time option that causes a run-time version change during each
+ * activation of the compiled script.  That version change has the effect of
+ * changing JS_HAS_XML_OPTION, so that any compiling done via eval enables XML
+ * support.  If an XML-enabled script or function calls a non-XML function,
+ * the flag bit will be cleared during the callee's activation.
+ *
+ * Note that JS_SetVersion API calls never pass JSVERSION_HAS_XML or'd into
+ * that API's version parameter.
+ * 
+ * Note also that script->version must contain this XML option flag in order
+ * for XDR'ed scripts to serialize and deserialize with that option preserved
+ * for detection at run-time.  We can't copy other compile-time options into
+ * script->version because that would break backward compatibility (certain
+ * other options, e.g. JSOPTION_VAROBJFIX, are analogous to JSOPTION_XML).
+ */
+#define JS_HAS_OPTION(cx,option)        (((cx)->options & (option)) != 0)
+#define JS_HAS_STRICT_OPTION(cx)        JS_HAS_OPTION(cx, JSOPTION_STRICT)
+#define JS_HAS_WERROR_OPTION(cx)        JS_HAS_OPTION(cx, JSOPTION_WERROR)
+#define JS_HAS_COMPILE_N_GO_OPTION(cx)  JS_HAS_OPTION(cx, JSOPTION_COMPILE_N_GO)
+#define JS_HAS_ATLINE_OPTION(cx)        JS_HAS_OPTION(cx, JSOPTION_ATLINE)
+
+#define JSVERSION_MASK                  0x0FFF  /* see JSVersion in jspubtd.h */
+#define JSVERSION_HAS_XML               0x1000  /* flag induced by XML option */
+
+#define JSVERSION_NUMBER(cx)            ((cx)->version & JSVERSION_MASK)
+#define JS_HAS_XML_OPTION(cx)           ((cx)->version & JSVERSION_HAS_XML || \
+                                         JSVERSION_NUMBER(cx) >= JSVERSION_1_6)
+
+#define JS_HAS_NATIVE_BRANCH_CALLBACK_OPTION(cx)                              \
+    JS_HAS_OPTION(cx, JSOPTION_NATIVE_BRANCH_CALLBACK)
+
+/*
+ * Wrappers for the JSVERSION_IS_* macros from jspubtd.h taking JSContext *cx
+ * and masking off the XML flag and any other high order bits.
+ */
+#define JS_VERSION_IS_ECMA(cx)          JSVERSION_IS_ECMA(JSVERSION_NUMBER(cx))
+#define JS_VERSION_IS_1_2(cx)           (JSVERSION_NUMBER(cx) == JSVERSION_1_2)
+
+/*
+ * Common subroutine of JS_SetVersion and js_SetVersion, to update per-context
+ * data that depends on version.
+ */
+extern void
+js_OnVersionChange(JSContext *cx);
+
+/*
+ * Unlike the JS_SetVersion API, this function stores JSVERSION_HAS_XML and
+ * any future non-version-number flags induced by compiler options.
+ */
+extern void
+js_SetVersion(JSContext *cx, JSVersion version);
+
+/*
+ * Create and destroy functions for JSContext, which is manually allocated
+ * and exclusively owned.
+ */
+extern JSContext *
+js_NewContext(JSRuntime *rt, size_t stackChunkSize);
+
+extern void
+js_DestroyContext(JSContext *cx, JSGCMode gcmode);
+
+/*
+ * Return true if cx points to a context in rt->contextList, else return false.
+ * NB: the caller (see jslock.c:ClaimScope) must hold rt->gcLock.
+ */
+extern JSBool
+js_ValidContextPointer(JSRuntime *rt, JSContext *cx);
+
+/*
+ * If unlocked, acquire and release rt->gcLock around *iterp update; otherwise
+ * the caller must be holding rt->gcLock.
+ */
+extern JSContext *
+js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp);
+
+/*
+ * JSClass.resolve and watchpoint recursion damping machinery.
+ */
+extern JSBool
+js_StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
+                  JSResolvingEntry **entryp);
+
+extern void
+js_StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag,
+                 JSResolvingEntry *entry, uint32 generation);
+
+/*
+ * Local root set management.
+ */
+extern JSBool
+js_EnterLocalRootScope(JSContext *cx);
+
+extern void
+js_LeaveLocalRootScope(JSContext *cx);
+
+extern void
+js_ForgetLocalRoot(JSContext *cx, jsval v);
+
+extern int
+js_PushLocalRoot(JSContext *cx, JSLocalRootStack *lrs, jsval v);
+
+extern void
+js_MarkLocalRoots(JSContext *cx, JSLocalRootStack *lrs);
+
+/*
+ * Report an exception, which is currently realized as a printf-style format
+ * string and its arguments.
+ */
+typedef enum JSErrNum {
+#define MSG_DEF(name, number, count, exception, format) \
+    name = number,
+#include "js.msg"
+#undef MSG_DEF
+    JSErr_Limit
+} JSErrNum;
+
+extern const JSErrorFormatString *
+js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
+
+#ifdef va_start
+extern JSBool
+js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap);
+
+extern JSBool
+js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
+                       void *userRef, const uintN errorNumber,
+                       JSBool charArgs, va_list ap);
+
+extern JSBool
+js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
+                        void *userRef, const uintN errorNumber,
+                        char **message, JSErrorReport *reportp,
+                        JSBool *warningp, JSBool charArgs, va_list ap);
+#endif
+
+extern void
+js_ReportOutOfMemory(JSContext *cx);
+
+/*
+ * Report an exception using a previously composed JSErrorReport.
+ * XXXbe remove from "friend" API
+ */
+extern JS_FRIEND_API(void)
+js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report);
+
+extern void
+js_ReportIsNotDefined(JSContext *cx, const char *name);
+
+extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
+
+/*
+ * See JS_SetThreadStackLimit in jsapi.c, where we check that the stack grows
+ * in the expected direction.  On Unix-y systems, JS_STACK_GROWTH_DIRECTION is
+ * computed on the build host by jscpucfg.c and written into jsautocfg.h.  The
+ * macro is hardcoded in jscpucfg.h on Windows and Mac systems (for historical
+ * reasons pre-dating autoconf usage).
+ */
+#if JS_STACK_GROWTH_DIRECTION > 0
+# define JS_CHECK_STACK_SIZE(cx, lval)  ((jsuword)&(lval) < (cx)->stackLimit)
+#else
+# define JS_CHECK_STACK_SIZE(cx, lval)  ((jsuword)&(lval) > (cx)->stackLimit)
+#endif
+
+JS_END_EXTERN_C
+
+#endif /* jscntxt_h___ */

Added: freeswitch/trunk/libs/js/src/jscompat.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jscompat.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,57 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* -*- Mode: C; tab-width: 8 -*-
+ * Copyright (C) 1996-1999 Netscape Communications Corporation, All Rights Reserved.
+ */
+#ifndef jscompat_h___
+#define jscompat_h___
+/*
+ * Compatibility glue for various NSPR versions.  We must always define int8,
+ * int16, jsword, and so on to minimize differences with js/ref, no matter what
+ * the NSPR typedef names may be.
+ */
+#include "jstypes.h"
+#include "jslong.h"
+
+typedef JSIntn intN;
+typedef JSUintn uintN;
+typedef JSUword jsuword;
+typedef JSWord jsword;
+typedef float float32;
+#define allocPriv allocPool
+#endif /* jscompat_h___ */

Added: freeswitch/trunk/libs/js/src/jsconfig.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsconfig.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,563 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS configuration macros.
+ */
+#ifndef JS_VERSION
+#define JS_VERSION 160
+#endif
+
+/*
+ * Compile-time JS version configuration.  The JS version numbers lie on the
+ * number line like so:
+ *
+ *      1.0     1.1     1.2     1.3     1.4     ECMAv3  1.5     1.6
+ *              ^                       ^
+ *              |                       |
+ *              basis for ECMAv1        close to ECMAv2
+ *
+ * where ECMAv3 stands for ECMA-262 Edition 3.  See the runtime version enum
+ * JSVersion in jspubtd.h.  Code in the engine can therefore count on version
+ * <= JSVERSION_1_4 to mean "before the Third Edition of ECMA-262" and version
+ * > JSVERSION_1_4 to mean "at or after the Third Edition".
+ *
+ * In the unlikely event that SpiderMonkey ever implements JavaScript 2.0, or
+ * ECMA-262 Edition 4 (JS2 without certain extensions), the version number to
+ * use would be near 200, or greater.
+ *
+ * The JS_VERSION_ECMA_3 version is the minimal configuration conforming to
+ * the ECMA-262 Edition 3 specification.  Use it for minimal embeddings, where
+ * you're sure you don't need any of the extensions disabled in this version.
+ * In order to facilitate testing, JS_HAS_OBJ_PROTO_PROP is defined as part of
+ * the JS_VERSION_ECMA_3_TEST version.
+ */
+#define JS_VERSION_ECMA_3       148
+#define JS_VERSION_ECMA_3_TEST  149
+
+#if JS_VERSION == JS_VERSION_ECMA_3 ||                                        \
+    JS_VERSION == JS_VERSION_ECMA_3_TEST
+
+#define JS_BUG_NULL_INDEX_PROPS 0       /* o[0] defaults to null, not void */
+#define JS_BUG_EMPTY_INDEX_ZERO 0       /* o[""] is equivalent to o[0] */
+#define JS_BUG_EAGER_TOSTRING   0       /* o.toString() trumps o.valueOf() */
+#define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
+#define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
+#define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
+#define JS_BUG_FALLIBLE_EQOPS   0       /* fallible/intransitive equality ops */
+#define JS_BUG_FALLIBLE_TONUM   0       /* fallible ValueToNumber primitive */
+#define JS_BUG_WITH_CLOSURE     0       /* with(o)function f(){} sets o.f */
+
+#define JS_HAS_PROP_DELETE      1       /* delete o.p removes p from o */
+#define JS_HAS_CALL_OBJECT      1       /* fun.caller is stack frame obj */
+#define JS_HAS_LABEL_STATEMENT  1       /* has break/continue to label: */
+#define JS_HAS_DO_WHILE_LOOP    1       /* has do {...} while (b) */
+#define JS_HAS_SWITCH_STATEMENT 1       /* has switch (v) {case c: ...} */
+#define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
+#define JS_HAS_MORE_PERL_FUN    1       /* has array.push, array.pop, etc */
+#define JS_HAS_STR_HTML_HELPERS 0       /* has str.anchor, str.bold, etc. */
+#define JS_HAS_PERL_SUBSTR      0       /* has str.substr */
+#define JS_HAS_VALUEOF_HINT     1       /* valueOf(hint) where hint is typeof */
+#define JS_HAS_LEXICAL_CLOSURE  1       /* nested functions, lexically closed */
+#define JS_HAS_APPLY_FUNCTION   1       /* has fun.apply(obj, argArray) */
+#define JS_HAS_CALL_FUNCTION    1       /* has fun.call(obj, arg1, ... argN) */
+#if JS_VERSION == JS_VERSION_ECMA_3_TEST
+#define JS_HAS_OBJ_PROTO_PROP   1       /* has o.__proto__ etc. */
+#else
+#define JS_HAS_OBJ_PROTO_PROP   0       /* has o.__proto__ etc. */
+#endif
+#define JS_HAS_REGEXPS          1       /* has perl r.e.s via RegExp, /pat/ */
+#define JS_HAS_SEQUENCE_OPS     1       /* has array.slice, string.concat */
+#define JS_HAS_INITIALIZERS     1       /* has var o = {'foo': 42, 'bar':3} */
+#define JS_HAS_OBJ_WATCHPOINT   0       /* has o.watch and o.unwatch */
+#define JS_HAS_EXPORT_IMPORT    0       /* has export fun; import obj.fun */
+#define JS_HAS_EVAL_THIS_SCOPE  0       /* Math.eval is same as with (Math) */
+#define JS_HAS_TRIPLE_EQOPS     1       /* has === and !== identity eqops */
+#define JS_HAS_SHARP_VARS       0       /* has #n=, #n# for object literals */
+#define JS_HAS_REPLACE_LAMBDA   1       /* has string.replace(re, lambda) */
+#define JS_HAS_SCRIPT_OBJECT    0       /* has (new Script("x++")).exec() */
+#define JS_HAS_XDR              0       /* has XDR API and internal support */
+#define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
+#define JS_HAS_EXCEPTIONS       1       /* has exception handling */
+#define JS_HAS_UNDEFINED        1       /* has global "undefined" property */
+#define JS_HAS_TOSOURCE         0       /* has Object/Array toSource method */
+#define JS_HAS_IN_OPERATOR      1       /* has in operator ('p' in {p:1}) */
+#define JS_HAS_INSTANCEOF       1       /* has {p:1} instanceof Object */
+#define JS_HAS_ARGS_OBJECT      1       /* has minimal ECMA arguments object */
+#define JS_HAS_DEBUGGER_KEYWORD 0       /* has hook for debugger keyword */
+#define JS_HAS_ERROR_EXCEPTIONS 1       /* has error object hierarchy */
+#define JS_HAS_CATCH_GUARD      0       /* has exception handling catch guard */
+#define JS_HAS_NEW_OBJ_METHODS  1       /* has Object.prototype query methods */
+#define JS_HAS_SPARSE_ARRAYS    0       /* array methods preserve empty elems */
+#define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
+#define JS_HAS_NUMBER_FORMATS   1       /* numbers have formatting methods */
+#define JS_HAS_GETTER_SETTER    0       /* has JS2 getter/setter functions */
+#define JS_HAS_UNEVAL           0       /* has uneval() top-level function */
+#define JS_HAS_CONST            0       /* has JS2 const as alternative var */
+#define JS_HAS_FUN_EXPR_STMT    0       /* has function expression statement */
+#define JS_HAS_LVALUE_RETURN    1       /* has o.item(i) = j; for native item */
+#define JS_HAS_NO_SUCH_METHOD   0       /* has o.__noSuchMethod__ handler */
+#define JS_HAS_XML_SUPPORT      0       /* has ECMAScript for XML support */
+#define JS_HAS_ARRAY_EXTRAS     0       /* has indexOf and Lispy extras */
+
+#elif JS_VERSION == 100
+
+#define JS_BUG_NULL_INDEX_PROPS 1       /* o[0] defaults to null, not void */
+#define JS_BUG_EMPTY_INDEX_ZERO 1       /* o[""] is equivalent to o[0] */
+#define JS_BUG_EAGER_TOSTRING   1       /* o.toString() trumps o.valueOf() */
+#define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
+#define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
+#define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
+#define JS_BUG_FALLIBLE_EQOPS   1       /* fallible/intransitive equality ops */
+#define JS_BUG_FALLIBLE_TONUM   1       /* fallible ValueToNumber primitive */
+#define JS_BUG_WITH_CLOSURE     0       /* with(o)function f(){} sets o.f */
+
+#define JS_HAS_PROP_DELETE      0       /* delete o.p removes p from o */
+#define JS_HAS_CALL_OBJECT      0       /* fun.caller is stack frame obj */
+#define JS_HAS_LABEL_STATEMENT  0       /* has break/continue to label: */
+#define JS_HAS_DO_WHILE_LOOP    0       /* has do {...} while (b) */
+#define JS_HAS_SWITCH_STATEMENT 0       /* has switch (v) {case c: ...} */
+#define JS_HAS_SOME_PERL_FUN    0       /* has array.join/reverse/sort */
+#define JS_HAS_MORE_PERL_FUN    0       /* has array.push, str.substr, etc */
+#define JS_HAS_STR_HTML_HELPERS 1       /* has str.anchor, str.bold, etc. */
+#define JS_HAS_PERL_SUBSTR      0       /* has str.substr */
+#define JS_HAS_VALUEOF_HINT     0       /* valueOf(hint) where hint is typeof */
+#define JS_HAS_LEXICAL_CLOSURE  0       /* nested functions, lexically closed */
+#define JS_HAS_APPLY_FUNCTION   0       /* has fun.apply(obj, argArray) */
+#define JS_HAS_CALL_FUNCTION    0       /* has fun.call(obj, arg1, ... argN) */
+#define JS_HAS_OBJ_PROTO_PROP   0       /* has o.__proto__ etc. */
+#define JS_HAS_REGEXPS          0       /* has perl r.e.s via RegExp, /pat/ */
+#define JS_HAS_SEQUENCE_OPS     0       /* has array.slice, string.concat */
+#define JS_HAS_INITIALIZERS     0       /* has var o = {'foo': 42, 'bar':3} */
+#define JS_HAS_OBJ_WATCHPOINT   0       /* has o.watch and o.unwatch */
+#define JS_HAS_EXPORT_IMPORT    0       /* has export fun; import obj.fun */
+#define JS_HAS_EVAL_THIS_SCOPE  0       /* Math.eval is same as with (Math) */
+#define JS_HAS_TRIPLE_EQOPS     0       /* has === and !== identity eqops */
+#define JS_HAS_SHARP_VARS       0       /* has #n=, #n# for object literals */
+#define JS_HAS_REPLACE_LAMBDA   0       /* has string.replace(re, lambda) */
+#define JS_HAS_SCRIPT_OBJECT    0       /* has (new Script("x++")).exec() */
+#define JS_HAS_XDR              0       /* has XDR API and internal support */
+#define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
+#define JS_HAS_EXCEPTIONS       0       /* has exception handling */
+#define JS_HAS_UNDEFINED        0       /* has global "undefined" property */
+#define JS_HAS_TOSOURCE         0       /* has Object/Array toSource method */
+#define JS_HAS_IN_OPERATOR      0       /* has in operator ('p' in {p:1}) */
+#define JS_HAS_INSTANCEOF       0       /* has {p:1} instanceof Object */
+#define JS_HAS_ARGS_OBJECT      0       /* has minimal ECMA arguments object */
+#define JS_HAS_DEBUGGER_KEYWORD 0       /* has hook for debugger keyword */
+#define JS_HAS_ERROR_EXCEPTIONS 0       /* has error object hierarchy */
+#define JS_HAS_CATCH_GUARD      0       /* has exception handling catch guard */
+#define JS_HAS_NEW_OBJ_METHODS  0       /* has Object.prototype query methods */
+#define JS_HAS_SPARSE_ARRAYS    0       /* array methods preserve empty elems */
+#define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
+#define JS_HAS_NUMBER_FORMATS   0       /* numbers have formatting methods */
+#define JS_HAS_GETTER_SETTER    0       /* has JS2 getter/setter functions */
+#define JS_HAS_UNEVAL           0       /* has uneval() top-level function */
+#define JS_HAS_CONST            0       /* has JS2 const as alternative var */
+#define JS_HAS_FUN_EXPR_STMT    0       /* has function expression statement */
+#define JS_HAS_LVALUE_RETURN    0       /* has o.item(i) = j; for native item */
+#define JS_HAS_NO_SUCH_METHOD   0       /* has o.__noSuchMethod__ handler */
+#define JS_HAS_XML_SUPPORT      0       /* has ECMAScript for XML support */
+#define JS_HAS_ARRAY_EXTRAS     0       /* has indexOf and Lispy extras */
+
+#elif JS_VERSION == 110
+
+#define JS_BUG_NULL_INDEX_PROPS 1       /* o[0] defaults to null, not void */
+#define JS_BUG_EMPTY_INDEX_ZERO 1       /* o[""] is equivalent to o[0] */
+#define JS_BUG_EAGER_TOSTRING   1       /* o.toString() trumps o.valueOf() */
+#define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
+#define JS_BUG_EVAL_THIS_FUN    1       /* eval('this') in function f is f */
+#define JS_BUG_EVAL_THIS_SCOPE  1       /* Math.eval('sin(x)') vs. local x */
+#define JS_BUG_FALLIBLE_EQOPS   1       /* fallible/intransitive equality ops */
+#define JS_BUG_FALLIBLE_TONUM   1       /* fallible ValueToNumber primitive */
+#define JS_BUG_WITH_CLOSURE     0       /* with(o)function f(){} sets o.f */
+
+#define JS_HAS_PROP_DELETE      0       /* delete o.p removes p from o */
+#define JS_HAS_CALL_OBJECT      0       /* fun.caller is stack frame obj */
+#define JS_HAS_LABEL_STATEMENT  0       /* has break/continue to label: */
+#define JS_HAS_DO_WHILE_LOOP    0       /* has do {...} while (b) */
+#define JS_HAS_SWITCH_STATEMENT 0       /* has switch (v) {case c: ...} */
+#define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
+#define JS_HAS_MORE_PERL_FUN    0       /* has array.push, str.substr, etc */
+#define JS_HAS_STR_HTML_HELPERS 1       /* has str.anchor, str.bold, etc. */
+#define JS_HAS_PERL_SUBSTR      0       /* has str.substr */
+#define JS_HAS_VALUEOF_HINT     0       /* valueOf(hint) where hint is typeof */
+#define JS_HAS_LEXICAL_CLOSURE  0       /* nested functions, lexically closed */
+#define JS_HAS_APPLY_FUNCTION   0       /* has apply(fun, arg1, ... argN) */
+#define JS_HAS_CALL_FUNCTION    0       /* has fun.call(obj, arg1, ... argN) */
+#define JS_HAS_OBJ_PROTO_PROP   0       /* has o.__proto__ etc. */
+#define JS_HAS_REGEXPS          0       /* has perl r.e.s via RegExp, /pat/ */
+#define JS_HAS_SEQUENCE_OPS     0       /* has array.slice, string.concat */
+#define JS_HAS_INITIALIZERS     0       /* has var o = {'foo': 42, 'bar':3} */
+#define JS_HAS_OBJ_WATCHPOINT   0       /* has o.watch and o.unwatch */
+#define JS_HAS_EXPORT_IMPORT    0       /* has export fun; import obj.fun */
+#define JS_HAS_EVAL_THIS_SCOPE  0       /* Math.eval is same as with (Math) */
+#define JS_HAS_TRIPLE_EQOPS     0       /* has === and !== identity eqops */
+#define JS_HAS_SHARP_VARS       0       /* has #n=, #n# for object literals */
+#define JS_HAS_REPLACE_LAMBDA   0       /* has string.replace(re, lambda) */
+#define JS_HAS_SCRIPT_OBJECT    0       /* has (new Script("x++")).exec() */
+#define JS_HAS_XDR              0       /* has XDR API and internal support */
+#define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
+#define JS_HAS_EXCEPTIONS       0       /* has exception handling */
+#define JS_HAS_UNDEFINED        0       /* has global "undefined" property */
+#define JS_HAS_TOSOURCE         0       /* has Object/Array toSource method */
+#define JS_HAS_IN_OPERATOR      0       /* has in operator ('p' in {p:1}) */
+#define JS_HAS_INSTANCEOF       0       /* has {p:1} instanceof Object */
+#define JS_HAS_ARGS_OBJECT      0       /* has minimal ECMA arguments object */
+#define JS_HAS_DEBUGGER_KEYWORD 0       /* has hook for debugger keyword */
+#define JS_HAS_ERROR_EXCEPTIONS 0       /* has error object hierarchy */
+#define JS_HAS_CATCH_GUARD      0       /* has exception handling catch guard */
+#define JS_HAS_NEW_OBJ_METHODS  0       /* has Object.prototype query methods */
+#define JS_HAS_SPARSE_ARRAYS    0       /* array methods preserve empty elems */
+#define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
+#define JS_HAS_NUMBER_FORMATS   0       /* numbers have formatting methods */
+#define JS_HAS_GETTER_SETTER    0       /* has JS2 getter/setter functions */
+#define JS_HAS_UNEVAL           0       /* has uneval() top-level function */
+#define JS_HAS_CONST            0       /* has JS2 const as alternative var */
+#define JS_HAS_FUN_EXPR_STMT    0       /* has function expression statement */
+#define JS_HAS_LVALUE_RETURN    0       /* has o.item(i) = j; for native item */
+#define JS_HAS_NO_SUCH_METHOD   0       /* has o.__noSuchMethod__ handler */
+#define JS_HAS_XML_SUPPORT      0       /* has ECMAScript for XML support */
+#define JS_HAS_ARRAY_EXTRAS     0       /* has indexOf and Lispy extras */
+
+#elif JS_VERSION == 120
+
+#define JS_BUG_NULL_INDEX_PROPS 0       /* o[0] defaults to null, not void */
+#define JS_BUG_EMPTY_INDEX_ZERO 0       /* o[""] is equivalent to o[0] */
+#define JS_BUG_EAGER_TOSTRING   0       /* o.toString() trumps o.valueOf() */
+#define JS_BUG_VOID_TOSTRING    1       /* void 0 + 0 == "undefined0" */
+#define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
+#define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
+#define JS_BUG_FALLIBLE_EQOPS   0       /* fallible/intransitive equality ops */
+#define JS_BUG_FALLIBLE_TONUM   0       /* fallible ValueToNumber primitive */
+#define JS_BUG_WITH_CLOSURE     1       /* with(o)function f(){} sets o.f */
+
+#define JS_HAS_PROP_DELETE      1       /* delete o.p removes p from o */
+#define JS_HAS_CALL_OBJECT      1       /* fun.caller is stack frame obj */
+#define JS_HAS_LABEL_STATEMENT  1       /* has break/continue to label: */
+#define JS_HAS_DO_WHILE_LOOP    1       /* has do {...} while (b) */
+#define JS_HAS_SWITCH_STATEMENT 1       /* has switch (v) {case c: ...} */
+#define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
+#define JS_HAS_MORE_PERL_FUN    1       /* has array.push, str.substr, etc */
+#define JS_HAS_STR_HTML_HELPERS 1       /* has str.anchor, str.bold, etc. */
+#define JS_HAS_PERL_SUBSTR      1       /* has str.substr */
+#define JS_HAS_VALUEOF_HINT     1       /* valueOf(hint) where hint is typeof */
+#define JS_HAS_LEXICAL_CLOSURE  1       /* nested functions, lexically closed */
+#define JS_HAS_APPLY_FUNCTION   1       /* has apply(fun, arg1, ... argN) */
+#define JS_HAS_CALL_FUNCTION    0       /* has fun.call(obj, arg1, ... argN) */
+#define JS_HAS_OBJ_PROTO_PROP   1       /* has o.__proto__ etc. */
+#define JS_HAS_REGEXPS          1       /* has perl r.e.s via RegExp, /pat/ */
+#define JS_HAS_SEQUENCE_OPS     1       /* has array.slice, string.concat */
+#define JS_HAS_INITIALIZERS     1       /* has var o = {'foo': 42, 'bar':3} */
+#define JS_HAS_OBJ_WATCHPOINT   1       /* has o.watch and o.unwatch */
+#define JS_HAS_EXPORT_IMPORT    1       /* has export fun; import obj.fun */
+#define JS_HAS_EVAL_THIS_SCOPE  1       /* Math.eval is same as with (Math) */
+#define JS_HAS_TRIPLE_EQOPS     0       /* has === and !== identity eqops */
+#define JS_HAS_SHARP_VARS       0       /* has #n=, #n# for object literals */
+#define JS_HAS_REPLACE_LAMBDA   0       /* has string.replace(re, lambda) */
+#define JS_HAS_SCRIPT_OBJECT    0       /* has (new Script("x++")).exec() */
+#define JS_HAS_XDR              0       /* has XDR API and internal support */
+#define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
+#define JS_HAS_EXCEPTIONS       0       /* has exception handling */
+#define JS_HAS_UNDEFINED        0       /* has global "undefined" property */
+#define JS_HAS_TOSOURCE         0       /* has Object/Array toSource method */
+#define JS_HAS_IN_OPERATOR      0       /* has in operator ('p' in {p:1}) */
+#define JS_HAS_INSTANCEOF       0       /* has {p:1} instanceof Object */
+#define JS_HAS_ARGS_OBJECT      0       /* has minimal ECMA arguments object */
+#define JS_HAS_DEBUGGER_KEYWORD 0       /* has hook for debugger keyword */
+#define JS_HAS_ERROR_EXCEPTIONS 0       /* has error object hierarchy */
+#define JS_HAS_CATCH_GUARD      0       /* has exception handling catch guard */
+#define JS_HAS_NEW_OBJ_METHODS  0       /* has Object.prototype query methods */
+#define JS_HAS_SPARSE_ARRAYS    0       /* array methods preserve empty elems */
+#define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
+#define JS_HAS_NUMBER_FORMATS   0       /* numbers have formatting methods */
+#define JS_HAS_GETTER_SETTER    0       /* has JS2 getter/setter functions */
+#define JS_HAS_UNEVAL           0       /* has uneval() top-level function */
+#define JS_HAS_CONST            0       /* has JS2 const as alternative var */
+#define JS_HAS_FUN_EXPR_STMT    0       /* has function expression statement */
+#define JS_HAS_LVALUE_RETURN    0       /* has o.item(i) = j; for native item */
+#define JS_HAS_NO_SUCH_METHOD   0       /* has o.__noSuchMethod__ handler */
+#define JS_HAS_XML_SUPPORT      0       /* has ECMAScript for XML support */
+#define JS_HAS_ARRAY_EXTRAS     0       /* has indexOf and Lispy extras */
+
+#elif JS_VERSION == 130
+
+#define JS_BUG_NULL_INDEX_PROPS 0       /* o[0] defaults to null, not void */
+#define JS_BUG_EMPTY_INDEX_ZERO 0       /* o[""] is equivalent to o[0] */
+#define JS_BUG_EAGER_TOSTRING   0       /* o.toString() trumps o.valueOf() */
+#define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
+#define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
+#define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
+#define JS_BUG_FALLIBLE_EQOPS   0       /* fallible/intransitive equality ops */
+#define JS_BUG_FALLIBLE_TONUM   0       /* fallible ValueToNumber primitive */
+#define JS_BUG_WITH_CLOSURE     1       /* with(o)function f(){} sets o.f */
+
+#define JS_HAS_PROP_DELETE      1       /* delete o.p removes p from o */
+#define JS_HAS_CALL_OBJECT      1       /* fun.caller is stack frame obj */
+#define JS_HAS_LABEL_STATEMENT  1       /* has break/continue to label: */
+#define JS_HAS_DO_WHILE_LOOP    1       /* has do {...} while (b) */
+#define JS_HAS_SWITCH_STATEMENT 1       /* has switch (v) {case c: ...} */
+#define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
+#define JS_HAS_MORE_PERL_FUN    1       /* has array.push, str.substr, etc */
+#define JS_HAS_STR_HTML_HELPERS 1       /* has str.anchor, str.bold, etc. */
+#define JS_HAS_PERL_SUBSTR      1       /* has str.substr */
+#define JS_HAS_VALUEOF_HINT     1       /* valueOf(hint) where hint is typeof */
+#define JS_HAS_LEXICAL_CLOSURE  1       /* nested functions, lexically closed */
+#define JS_HAS_APPLY_FUNCTION   1       /* has apply(fun, arg1, ... argN) */
+#define JS_HAS_CALL_FUNCTION    1       /* has fun.call(obj, arg1, ... argN) */
+#define JS_HAS_OBJ_PROTO_PROP   1       /* has o.__proto__ etc. */
+#define JS_HAS_REGEXPS          1       /* has perl r.e.s via RegExp, /pat/ */
+#define JS_HAS_SEQUENCE_OPS     1       /* has array.slice, string.concat */
+#define JS_HAS_INITIALIZERS     1       /* has var o = {'foo': 42, 'bar':3} */
+#define JS_HAS_OBJ_WATCHPOINT   1       /* has o.watch and o.unwatch */
+#define JS_HAS_EXPORT_IMPORT    1       /* has export fun; import obj.fun */
+#define JS_HAS_EVAL_THIS_SCOPE  1       /* Math.eval is same as with (Math) */
+#define JS_HAS_TRIPLE_EQOPS     1       /* has === and !== identity eqops */
+#define JS_HAS_SHARP_VARS       1       /* has #n=, #n# for object literals */
+#define JS_HAS_REPLACE_LAMBDA   1       /* has string.replace(re, lambda) */
+#define JS_HAS_SCRIPT_OBJECT    1       /* has (new Script("x++")).exec() */
+#define JS_HAS_XDR              1       /* has XDR API and internal support */
+#define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
+#define JS_HAS_EXCEPTIONS       0       /* has exception handling */
+#define JS_HAS_UNDEFINED        1       /* has global "undefined" property */
+#define JS_HAS_TOSOURCE         1       /* has Object/Array toSource method */
+#define JS_HAS_IN_OPERATOR      0       /* has in operator ('p' in {p:1}) */
+#define JS_HAS_INSTANCEOF       0       /* has {p:1} instanceof Object */
+#define JS_HAS_ARGS_OBJECT      1       /* has minimal ECMA arguments object */
+#define JS_HAS_DEBUGGER_KEYWORD 1       /* has hook for debugger keyword */
+#define JS_HAS_ERROR_EXCEPTIONS 0       /* has error object hierarchy */
+#define JS_HAS_CATCH_GUARD      0       /* has exception handling catch guard */
+#define JS_HAS_NEW_OBJ_METHODS  0       /* has Object.prototype query methods */
+#define JS_HAS_SPARSE_ARRAYS    0       /* array methods preserve empty elems */
+#define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
+#define JS_HAS_NUMBER_FORMATS   0       /* numbers have formatting methods */
+#define JS_HAS_GETTER_SETTER    0       /* has JS2 getter/setter functions */
+#define JS_HAS_UNEVAL           0       /* has uneval() top-level function */
+#define JS_HAS_CONST            0       /* has JS2 const as alternative var */
+#define JS_HAS_FUN_EXPR_STMT    0       /* has function expression statement */
+#define JS_HAS_LVALUE_RETURN    0       /* has o.item(i) = j; for native item */
+#define JS_HAS_NO_SUCH_METHOD   0       /* has o.__noSuchMethod__ handler */
+#define JS_HAS_XML_SUPPORT      0       /* has ECMAScript for XML support */
+#define JS_HAS_ARRAY_EXTRAS     0       /* has indexOf and Lispy extras */
+
+#elif JS_VERSION == 140
+
+#define JS_BUG_NULL_INDEX_PROPS 0       /* o[0] defaults to null, not void */
+#define JS_BUG_EMPTY_INDEX_ZERO 0       /* o[""] is equivalent to o[0] */
+#define JS_BUG_EAGER_TOSTRING   0       /* o.toString() trumps o.valueOf() */
+#define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
+#define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
+#define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
+#define JS_BUG_FALLIBLE_EQOPS   0       /* fallible/intransitive equality ops */
+#define JS_BUG_FALLIBLE_TONUM   0       /* fallible ValueToNumber primitive */
+#define JS_BUG_WITH_CLOSURE     1       /* with(o)function f(){} sets o.f */
+
+#define JS_HAS_PROP_DELETE      1       /* delete o.p removes p from o */
+#define JS_HAS_CALL_OBJECT      1       /* fun.caller is stack frame obj */
+#define JS_HAS_LABEL_STATEMENT  1       /* has break/continue to label: */
+#define JS_HAS_DO_WHILE_LOOP    1       /* has do {...} while (b) */
+#define JS_HAS_SWITCH_STATEMENT 1       /* has switch (v) {case c: ...} */
+#define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
+#define JS_HAS_MORE_PERL_FUN    1       /* has array.push, str.substr, etc */
+#define JS_HAS_STR_HTML_HELPERS 1       /* has str.anchor, str.bold, etc. */
+#define JS_HAS_PERL_SUBSTR      1       /* has str.substr */
+#define JS_HAS_VALUEOF_HINT     1       /* valueOf(hint) where hint is typeof */
+#define JS_HAS_LEXICAL_CLOSURE  1       /* nested functions, lexically closed */
+#define JS_HAS_APPLY_FUNCTION   1       /* has apply(fun, arg1, ... argN) */
+#define JS_HAS_CALL_FUNCTION    1       /* has fun.call(obj, arg1, ... argN) */
+#define JS_HAS_OBJ_PROTO_PROP   1       /* has o.__proto__ etc. */
+#define JS_HAS_REGEXPS          1       /* has perl r.e.s via RegExp, /pat/ */
+#define JS_HAS_SEQUENCE_OPS     1       /* has array.slice, string.concat */
+#define JS_HAS_INITIALIZERS     1       /* has var o = {'foo': 42, 'bar':3} */
+#define JS_HAS_OBJ_WATCHPOINT   1       /* has o.watch and o.unwatch */
+#define JS_HAS_EXPORT_IMPORT    1       /* has export fun; import obj.fun */
+#define JS_HAS_EVAL_THIS_SCOPE  1       /* Math.eval is same as with (Math) */
+#define JS_HAS_TRIPLE_EQOPS     1       /* has === and !== identity eqops */
+#define JS_HAS_SHARP_VARS       1       /* has #n=, #n# for object literals */
+#define JS_HAS_REPLACE_LAMBDA   1       /* has string.replace(re, lambda) */
+#define JS_HAS_SCRIPT_OBJECT    1       /* has (new Script("x++")).exec() */
+#define JS_HAS_XDR              1       /* has XDR API and internal support */
+#define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
+#define JS_HAS_EXCEPTIONS       1       /* has exception handling */
+#define JS_HAS_UNDEFINED        1       /* has global "undefined" property */
+#define JS_HAS_TOSOURCE         1       /* has Object/Array toSource method */
+#define JS_HAS_IN_OPERATOR      1       /* has in operator ('p' in {p:1}) */
+#define JS_HAS_INSTANCEOF       1       /* has {p:1} instanceof Object */
+#define JS_HAS_ARGS_OBJECT      1       /* has minimal ECMA arguments object */
+#define JS_HAS_DEBUGGER_KEYWORD 1       /* has hook for debugger keyword */
+#define JS_HAS_ERROR_EXCEPTIONS 0       /* rt errors reflected as exceptions */
+#define JS_HAS_CATCH_GUARD      0       /* has exception handling catch guard */
+#define JS_HAS_NEW_OBJ_METHODS  0       /* has Object.prototype query methods */
+#define JS_HAS_SPARSE_ARRAYS    0       /* array methods preserve empty elems */
+#define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
+#define JS_HAS_NUMBER_FORMATS   0       /* numbers have formatting methods */
+#define JS_HAS_GETTER_SETTER    0       /* has JS2 getter/setter functions */
+#define JS_HAS_UNEVAL           0       /* has uneval() top-level function */
+#define JS_HAS_CONST            0       /* has JS2 const as alternative var */
+#define JS_HAS_FUN_EXPR_STMT    0       /* has function expression statement */
+#define JS_HAS_LVALUE_RETURN    0       /* has o.item(i) = j; for native item */
+#define JS_HAS_NO_SUCH_METHOD   0       /* has o.__noSuchMethod__ handler */
+#define JS_HAS_XML_SUPPORT      0       /* has ECMAScript for XML support */
+#define JS_HAS_ARRAY_EXTRAS     0       /* has indexOf and Lispy extras */
+
+#elif JS_VERSION == 150
+
+#define JS_BUG_NULL_INDEX_PROPS 0       /* o[0] defaults to null, not void */
+#define JS_BUG_EMPTY_INDEX_ZERO 0       /* o[""] is equivalent to o[0] */
+#define JS_BUG_EAGER_TOSTRING   0       /* o.toString() trumps o.valueOf() */
+#define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
+#define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
+#define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
+#define JS_BUG_FALLIBLE_EQOPS   0       /* fallible/intransitive equality ops */
+#define JS_BUG_FALLIBLE_TONUM   0       /* fallible ValueToNumber primitive */
+#define JS_BUG_WITH_CLOSURE     0       /* with(o)function f(){} sets o.f */
+
+#define JS_HAS_PROP_DELETE      1       /* delete o.p removes p from o */
+#define JS_HAS_CALL_OBJECT      1       /* fun.caller is stack frame obj */
+#define JS_HAS_LABEL_STATEMENT  1       /* has break/continue to label: */
+#define JS_HAS_DO_WHILE_LOOP    1       /* has do {...} while (b) */
+#define JS_HAS_SWITCH_STATEMENT 1       /* has switch (v) {case c: ...} */
+#define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
+#define JS_HAS_MORE_PERL_FUN    1       /* has array.push, str.substr, etc */
+#define JS_HAS_STR_HTML_HELPERS 1       /* has str.anchor, str.bold, etc. */
+#define JS_HAS_PERL_SUBSTR      1       /* has str.substr */
+#define JS_HAS_VALUEOF_HINT     1       /* valueOf(hint) where hint is typeof */
+#define JS_HAS_LEXICAL_CLOSURE  1       /* nested functions, lexically closed */
+#define JS_HAS_APPLY_FUNCTION   1       /* has apply(fun, arg1, ... argN) */
+#define JS_HAS_CALL_FUNCTION    1       /* has fun.call(obj, arg1, ... argN) */
+#define JS_HAS_OBJ_PROTO_PROP   1       /* has o.__proto__ etc. */
+#define JS_HAS_REGEXPS          1       /* has perl r.e.s via RegExp, /pat/ */
+#define JS_HAS_SEQUENCE_OPS     1       /* has array.slice, string.concat */
+#define JS_HAS_INITIALIZERS     1       /* has var o = {'foo': 42, 'bar':3} */
+#define JS_HAS_OBJ_WATCHPOINT   1       /* has o.watch and o.unwatch */
+#define JS_HAS_EXPORT_IMPORT    1       /* has export fun; import obj.fun */
+#define JS_HAS_EVAL_THIS_SCOPE  1       /* Math.eval is same as with (Math) */
+#define JS_HAS_TRIPLE_EQOPS     1       /* has === and !== identity eqops */
+#define JS_HAS_SHARP_VARS       1       /* has #n=, #n# for object literals */
+#define JS_HAS_REPLACE_LAMBDA   1       /* has string.replace(re, lambda) */
+#define JS_HAS_SCRIPT_OBJECT    1       /* has (new Script("x++")).exec() */
+#define JS_HAS_XDR              1       /* has XDR API and internal support */
+#define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
+#define JS_HAS_EXCEPTIONS       1       /* has exception handling */
+#define JS_HAS_UNDEFINED        1       /* has global "undefined" property */
+#define JS_HAS_TOSOURCE         1       /* has Object/Array toSource method */
+#define JS_HAS_IN_OPERATOR      1       /* has in operator ('p' in {p:1}) */
+#define JS_HAS_INSTANCEOF       1       /* has {p:1} instanceof Object */
+#define JS_HAS_ARGS_OBJECT      1       /* has minimal ECMA arguments object */
+#define JS_HAS_DEBUGGER_KEYWORD 1       /* has hook for debugger keyword */
+#define JS_HAS_ERROR_EXCEPTIONS 1       /* rt errors reflected as exceptions */
+#define JS_HAS_CATCH_GUARD      1       /* has exception handling catch guard */
+#define JS_HAS_NEW_OBJ_METHODS  1       /* has Object.prototype query methods */
+#define JS_HAS_SPARSE_ARRAYS    0       /* array methods preserve empty elems */
+#define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
+#define JS_HAS_NUMBER_FORMATS   1       /* numbers have formatting methods */
+#define JS_HAS_GETTER_SETTER    1       /* has JS2 getter/setter functions */
+#define JS_HAS_UNEVAL           1       /* has uneval() top-level function */
+#define JS_HAS_CONST            1       /* has JS2 const as alternative var */
+#define JS_HAS_FUN_EXPR_STMT    1       /* has function expression statement */
+#define JS_HAS_LVALUE_RETURN    1       /* has o.item(i) = j; for native item */
+#define JS_HAS_NO_SUCH_METHOD   1       /* has o.__noSuchMethod__ handler */
+#define JS_HAS_XML_SUPPORT      0       /* has ECMAScript for XML support */
+#define JS_HAS_ARRAY_EXTRAS     0       /* has indexOf and Lispy extras */
+
+#elif JS_VERSION == 160
+
+#define JS_BUG_NULL_INDEX_PROPS 0       /* o[0] defaults to null, not void */
+#define JS_BUG_EMPTY_INDEX_ZERO 0       /* o[""] is equivalent to o[0] */
+#define JS_BUG_EAGER_TOSTRING   0       /* o.toString() trumps o.valueOf() */
+#define JS_BUG_VOID_TOSTRING    0       /* void 0 + 0 == "undefined0" */
+#define JS_BUG_EVAL_THIS_FUN    0       /* eval('this') in function f is f */
+#define JS_BUG_EVAL_THIS_SCOPE  0       /* Math.eval('sin(x)') vs. local x */
+#define JS_BUG_FALLIBLE_EQOPS   0       /* fallible/intransitive equality ops */
+#define JS_BUG_FALLIBLE_TONUM   0       /* fallible ValueToNumber primitive */
+#define JS_BUG_WITH_CLOSURE     0       /* with(o)function f(){} sets o.f */
+
+#define JS_HAS_PROP_DELETE      1       /* delete o.p removes p from o */
+#define JS_HAS_CALL_OBJECT      1       /* fun.caller is stack frame obj */
+#define JS_HAS_LABEL_STATEMENT  1       /* has break/continue to label: */
+#define JS_HAS_DO_WHILE_LOOP    1       /* has do {...} while (b) */
+#define JS_HAS_SWITCH_STATEMENT 1       /* has switch (v) {case c: ...} */
+#define JS_HAS_SOME_PERL_FUN    1       /* has array.join/reverse/sort */
+#define JS_HAS_MORE_PERL_FUN    1       /* has array.push, str.substr, etc */
+#define JS_HAS_STR_HTML_HELPERS 1       /* has str.anchor, str.bold, etc. */
+#define JS_HAS_PERL_SUBSTR      1       /* has str.substr */
+#define JS_HAS_VALUEOF_HINT     1       /* valueOf(hint) where hint is typeof */
+#define JS_HAS_LEXICAL_CLOSURE  1       /* nested functions, lexically closed */
+#define JS_HAS_APPLY_FUNCTION   1       /* has apply(fun, arg1, ... argN) */
+#define JS_HAS_CALL_FUNCTION    1       /* has fun.call(obj, arg1, ... argN) */
+#define JS_HAS_OBJ_PROTO_PROP   1       /* has o.__proto__ etc. */
+#define JS_HAS_REGEXPS          1       /* has perl r.e.s via RegExp, /pat/ */
+#define JS_HAS_SEQUENCE_OPS     1       /* has array.slice, string.concat */
+#define JS_HAS_INITIALIZERS     1       /* has var o = {'foo': 42, 'bar':3} */
+#define JS_HAS_OBJ_WATCHPOINT   1       /* has o.watch and o.unwatch */
+#define JS_HAS_EXPORT_IMPORT    1       /* has export fun; import obj.fun */
+#define JS_HAS_EVAL_THIS_SCOPE  1       /* Math.eval is same as with (Math) */
+#define JS_HAS_TRIPLE_EQOPS     1       /* has === and !== identity eqops */
+#define JS_HAS_SHARP_VARS       1       /* has #n=, #n# for object literals */
+#define JS_HAS_REPLACE_LAMBDA   1       /* has string.replace(re, lambda) */
+#define JS_HAS_SCRIPT_OBJECT    1       /* has (new Script("x++")).exec() */
+#define JS_HAS_XDR              1       /* has XDR API and internal support */
+#define JS_HAS_XDR_FREEZE_THAW  0       /* has XDR freeze/thaw script methods */
+#define JS_HAS_EXCEPTIONS       1       /* has exception handling */
+#define JS_HAS_UNDEFINED        1       /* has global "undefined" property */
+#define JS_HAS_TOSOURCE         1       /* has Object/Array toSource method */
+#define JS_HAS_IN_OPERATOR      1       /* has in operator ('p' in {p:1}) */
+#define JS_HAS_INSTANCEOF       1       /* has {p:1} instanceof Object */
+#define JS_HAS_ARGS_OBJECT      1       /* has minimal ECMA arguments object */
+#define JS_HAS_DEBUGGER_KEYWORD 1       /* has hook for debugger keyword */
+#define JS_HAS_ERROR_EXCEPTIONS 1       /* rt errors reflected as exceptions */
+#define JS_HAS_CATCH_GUARD      1       /* has exception handling catch guard */
+#define JS_HAS_NEW_OBJ_METHODS  1       /* has Object.prototype query methods */
+#define JS_HAS_SPARSE_ARRAYS    0       /* array methods preserve empty elems */
+#define JS_HAS_DFLT_MSG_STRINGS 1       /* provides English error messages */
+#define JS_HAS_NUMBER_FORMATS   1       /* numbers have formatting methods */
+#define JS_HAS_GETTER_SETTER    1       /* has JS2 getter/setter functions */
+#define JS_HAS_UNEVAL           1       /* has uneval() top-level function */
+#define JS_HAS_CONST            1       /* has JS2 const as alternative var */
+#define JS_HAS_FUN_EXPR_STMT    1       /* has function expression statement */
+#define JS_HAS_LVALUE_RETURN    1       /* has o.item(i) = j; for native item */
+#define JS_HAS_NO_SUCH_METHOD   1       /* has o.__noSuchMethod__ handler */
+#define JS_HAS_XML_SUPPORT      1       /* has ECMAScript for XML support */
+#define JS_HAS_ARRAY_EXTRAS     1       /* has indexOf and Lispy extras */
+
+#else
+
+#error "unknown JS_VERSION"
+
+#endif

Added: freeswitch/trunk/libs/js/src/jscpucfg.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jscpucfg.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,375 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Roland Mainz <roland.mainz at informatik.med.uni-giessen.de>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Generate CPU-specific bit-size and similar #defines.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef CROSS_COMPILE
+#include <prtypes.h>
+#define INT64 PRInt64
+#else
+
+/************************************************************************/
+
+/* Generate cpucfg.h */
+
+#if defined(XP_WIN) || defined(XP_OS2)
+#ifdef WIN32
+#if defined(__GNUC__)
+#define INT64   long long
+#else
+#define INT64   _int64
+#endif /* __GNUC__ */
+#else
+#define INT64   long
+#endif
+#else
+#if defined(HPUX) || defined(__QNX__) || defined(_SCO_DS) || defined(UNIXWARE)
+#define INT64   long
+#else
+#define INT64   long long
+#endif
+#endif
+
+#endif /* CROSS_COMPILE */
+
+#ifdef __GNUC__
+#define NS_NEVER_INLINE __attribute__((noinline))
+#else
+#define NS_NEVER_INLINE
+#endif
+
+typedef void *prword;
+
+struct align_short {
+    char c;
+    short a;
+};
+struct align_int {
+    char c;
+    int a;
+};
+struct align_long {
+    char c;
+    long a;
+};
+struct align_int64 {
+    char c;
+    INT64 a;
+};
+struct align_fakelonglong {
+    char c;
+    struct {
+        long hi, lo;
+    } a;
+};
+struct align_float {
+    char c;
+    float a;
+};
+struct align_double {
+    char c;
+    double a;
+};
+struct align_pointer {
+    char c;
+    void *a;
+};
+struct align_prword {
+    char c;
+    prword a;
+};
+
+#define ALIGN_OF(type) \
+    (((char*)&(((struct align_##type *)0)->a)) - ((char*)0))
+
+unsigned int bpb;
+
+static int Log2(unsigned int n)
+{
+    int log2 = 0;
+
+    if (n & (n-1))
+        log2++;
+    if (n >> 16)
+        log2 += 16, n >>= 16;
+    if (n >> 8)
+        log2 += 8, n >>= 8;
+    if (n >> 4)
+        log2 += 4, n >>= 4;
+    if (n >> 2)
+        log2 += 2, n >>= 2;
+    if (n >> 1)
+        log2++;
+    return log2;
+}
+
+/*
+ * Conceivably this could actually be used, but there is lots of code out
+ * there with ands and shifts in it that assumes a byte is exactly 8 bits,
+ * so forget about porting THIS code to all those non 8 bit byte machines.
+ */
+static void BitsPerByte(void)
+{
+    bpb = 8;
+}
+
+static int NS_NEVER_INLINE StackGrowthDirection(int *dummy1addr)
+{
+    int dummy2;
+
+    return (&dummy2 < dummy1addr) ? -1 : 1;
+}
+
+int main(int argc, char **argv)
+{
+    int sizeof_char, sizeof_short, sizeof_int, sizeof_int64, sizeof_long,
+        sizeof_float, sizeof_double, sizeof_word, sizeof_dword;
+    int bits_per_int64_log2, align_of_short, align_of_int, align_of_long,
+        align_of_int64, align_of_float, align_of_double, align_of_pointer,
+        align_of_word;
+    int dummy1;
+
+    BitsPerByte();
+
+    printf("#ifndef js_cpucfg___\n");
+    printf("#define js_cpucfg___\n\n");
+
+    printf("/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n");
+
+#ifdef CROSS_COMPILE
+#if defined(IS_LITTLE_ENDIAN)
+    printf("#define IS_LITTLE_ENDIAN 1\n");
+    printf("#undef  IS_BIG_ENDIAN\n\n");
+#elif defined(IS_BIG_ENDIAN)
+    printf("#undef  IS_LITTLE_ENDIAN\n");
+    printf("#define IS_BIG_ENDIAN 1\n\n");
+#else
+#error "Endianess not defined."
+#endif
+
+    sizeof_char         = PR_BYTES_PER_BYTE;
+    sizeof_short        = PR_BYTES_PER_SHORT;
+    sizeof_int          = PR_BYTES_PER_INT;
+    sizeof_int64        = PR_BYTES_PER_INT64;
+    sizeof_long         = PR_BYTES_PER_LONG;
+    sizeof_float        = PR_BYTES_PER_FLOAT;
+    sizeof_double       = PR_BYTES_PER_DOUBLE;
+    sizeof_word         = PR_BYTES_PER_WORD;
+    sizeof_dword        = PR_BYTES_PER_DWORD;
+
+    bits_per_int64_log2 = PR_BITS_PER_INT64_LOG2;
+
+    align_of_short      = PR_ALIGN_OF_SHORT;
+    align_of_int        = PR_ALIGN_OF_INT;
+    align_of_long       = PR_ALIGN_OF_LONG;
+    align_of_int64      = PR_ALIGN_OF_INT64;
+    align_of_float      = PR_ALIGN_OF_FLOAT;
+    align_of_double     = PR_ALIGN_OF_DOUBLE;
+    align_of_pointer    = PR_ALIGN_OF_POINTER;
+    align_of_word       = PR_ALIGN_OF_WORD;
+
+#else /* !CROSS_COMPILE */
+
+    /*
+     * We don't handle PDP-endian or similar orders: if a short is big-endian,
+     * so must int and long be big-endian for us to generate the IS_BIG_ENDIAN
+     * #define and the IS_LITTLE_ENDIAN #undef.
+     */
+    {
+        int big_endian = 0, little_endian = 0, ntests = 0;
+
+        if (sizeof(short) == 2) {
+            /* force |volatile| here to get rid of any compiler optimisations
+             * (var in register etc.) which may be appiled to |auto| vars -
+             * even those in |union|s...
+             * (|static| is used to get the same functionality for compilers
+             * which do not honor |volatile|...).
+             */
+            volatile static union {
+                short i;
+                char c[2];
+            } u;
+
+            u.i = 0x0102;
+            big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02);
+            little_endian += (u.c[0] == 0x02 && u.c[1] == 0x01);
+            ntests++;
+        }
+
+        if (sizeof(int) == 4) {
+            /* force |volatile| here ... */
+            volatile static union {
+                int i;
+                char c[4];
+            } u;
+
+            u.i = 0x01020304;
+            big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02 &&
+                           u.c[2] == 0x03 && u.c[3] == 0x04);
+            little_endian += (u.c[0] == 0x04 && u.c[1] == 0x03 &&
+                              u.c[2] == 0x02 && u.c[3] == 0x01);
+            ntests++;
+        }
+
+        if (sizeof(long) == 8) {
+            /* force |volatile| here ... */
+            volatile static union {
+                long i;
+                char c[8];
+            } u;
+
+            /*
+             * Write this as portably as possible: avoid 0x0102030405060708L
+             * and <<= 32.
+             */
+            u.i = 0x01020304;
+            u.i <<= 16, u.i <<= 16;
+            u.i |= 0x05060708;
+            big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02 &&
+                           u.c[2] == 0x03 && u.c[3] == 0x04 &&
+                           u.c[4] == 0x05 && u.c[5] == 0x06 &&
+                           u.c[6] == 0x07 && u.c[7] == 0x08);
+            little_endian += (u.c[0] == 0x08 && u.c[1] == 0x07 &&
+                              u.c[2] == 0x06 && u.c[3] == 0x05 &&
+                              u.c[4] == 0x04 && u.c[5] == 0x03 &&
+                              u.c[6] == 0x02 && u.c[7] == 0x01);
+            ntests++;
+        }
+
+        if (big_endian && big_endian == ntests) {
+            printf("#undef  IS_LITTLE_ENDIAN\n");
+            printf("#define IS_BIG_ENDIAN 1\n\n");
+        } else if (little_endian && little_endian == ntests) {
+            printf("#define IS_LITTLE_ENDIAN 1\n");
+            printf("#undef  IS_BIG_ENDIAN\n\n");
+        } else {
+            fprintf(stderr, "%s: unknown byte order"
+                    "(big_endian=%d, little_endian=%d, ntests=%d)!\n",
+                    argv[0], big_endian, little_endian, ntests);
+            return EXIT_FAILURE;
+        }
+    }
+
+    sizeof_char         = sizeof(char);
+    sizeof_short        = sizeof(short);
+    sizeof_int          = sizeof(int);
+    sizeof_int64        = 8;
+    sizeof_long         = sizeof(long);
+    sizeof_float        = sizeof(float);
+    sizeof_double       = sizeof(double);
+    sizeof_word         = sizeof(prword);
+    sizeof_dword        = 8;
+
+    bits_per_int64_log2 = 6;
+
+    align_of_short      = ALIGN_OF(short);
+    align_of_int        = ALIGN_OF(int);
+    align_of_long       = ALIGN_OF(long);
+    if (sizeof(INT64) < 8) {
+        /* this machine doesn't actually support int64's */
+        align_of_int64  = ALIGN_OF(fakelonglong);
+    } else {
+        align_of_int64  = ALIGN_OF(int64);
+    }
+    align_of_float      = ALIGN_OF(float);
+    align_of_double     = ALIGN_OF(double);
+    align_of_pointer    = ALIGN_OF(pointer);
+    align_of_word       = ALIGN_OF(prword);
+
+#endif /* CROSS_COMPILE */
+
+    printf("#define JS_BYTES_PER_BYTE   %dL\n", sizeof_char);
+    printf("#define JS_BYTES_PER_SHORT  %dL\n", sizeof_short);
+    printf("#define JS_BYTES_PER_INT    %dL\n", sizeof_int);
+    printf("#define JS_BYTES_PER_INT64  %dL\n", sizeof_int64);
+    printf("#define JS_BYTES_PER_LONG   %dL\n", sizeof_long);
+    printf("#define JS_BYTES_PER_FLOAT  %dL\n", sizeof_float);
+    printf("#define JS_BYTES_PER_DOUBLE %dL\n", sizeof_double);
+    printf("#define JS_BYTES_PER_WORD   %dL\n", sizeof_word);
+    printf("#define JS_BYTES_PER_DWORD  %dL\n", sizeof_dword);
+    printf("\n");
+
+    printf("#define JS_BITS_PER_BYTE    %dL\n", bpb);
+    printf("#define JS_BITS_PER_SHORT   %dL\n", bpb * sizeof_short);
+    printf("#define JS_BITS_PER_INT     %dL\n", bpb * sizeof_int);
+    printf("#define JS_BITS_PER_INT64   %dL\n", bpb * sizeof_int64);
+    printf("#define JS_BITS_PER_LONG    %dL\n", bpb * sizeof_long);
+    printf("#define JS_BITS_PER_FLOAT   %dL\n", bpb * sizeof_float);
+    printf("#define JS_BITS_PER_DOUBLE  %dL\n", bpb * sizeof_double);
+    printf("#define JS_BITS_PER_WORD    %dL\n", bpb * sizeof_word);
+    printf("\n");
+
+    printf("#define JS_BITS_PER_BYTE_LOG2   %dL\n", Log2(bpb));
+    printf("#define JS_BITS_PER_SHORT_LOG2  %dL\n", Log2(bpb * sizeof_short));
+    printf("#define JS_BITS_PER_INT_LOG2    %dL\n", Log2(bpb * sizeof_int));
+    printf("#define JS_BITS_PER_INT64_LOG2  %dL\n", bits_per_int64_log2);
+    printf("#define JS_BITS_PER_LONG_LOG2   %dL\n", Log2(bpb * sizeof_long));
+    printf("#define JS_BITS_PER_FLOAT_LOG2  %dL\n", Log2(bpb * sizeof_float));
+    printf("#define JS_BITS_PER_DOUBLE_LOG2 %dL\n", Log2(bpb * sizeof_double));
+    printf("#define JS_BITS_PER_WORD_LOG2   %dL\n", Log2(bpb * sizeof_word));
+    printf("\n");
+
+    printf("#define JS_ALIGN_OF_SHORT   %dL\n", align_of_short);
+    printf("#define JS_ALIGN_OF_INT     %dL\n", align_of_int);
+    printf("#define JS_ALIGN_OF_LONG    %dL\n", align_of_long);
+    printf("#define JS_ALIGN_OF_INT64   %dL\n", align_of_int64);
+    printf("#define JS_ALIGN_OF_FLOAT   %dL\n", align_of_float);
+    printf("#define JS_ALIGN_OF_DOUBLE  %dL\n", align_of_double);
+    printf("#define JS_ALIGN_OF_POINTER %dL\n", align_of_pointer);
+    printf("#define JS_ALIGN_OF_WORD    %dL\n", align_of_word);
+    printf("\n");
+
+    printf("#define JS_BYTES_PER_WORD_LOG2   %dL\n", Log2(sizeof_word));
+    printf("#define JS_BYTES_PER_DWORD_LOG2  %dL\n", Log2(sizeof_dword));
+    printf("#define JS_WORDS_PER_DWORD_LOG2  %dL\n", Log2(sizeof_dword/sizeof_word));
+    printf("\n");
+
+    printf("#define JS_STACK_GROWTH_DIRECTION (%d)\n", StackGrowthDirection(&dummy1));
+    printf("\n");
+
+    printf("#endif /* js_cpucfg___ */\n");
+
+    return EXIT_SUCCESS;
+}
+

Added: freeswitch/trunk/libs/js/src/jscpucfg.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jscpucfg.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,159 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef js_cpucfg___
+#define js_cpucfg___
+
+#include "jsosdep.h"
+
+#if defined(XP_WIN) || defined(XP_OS2) || defined(WINCE)
+
+#ifdef __WATCOMC__
+#define HAVE_VA_LIST_AS_ARRAY
+#endif
+
+#if defined(_WIN32) || defined(XP_OS2) || defined(WINCE)
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define JS_BYTES_PER_BYTE   1L
+#define JS_BYTES_PER_SHORT  2L
+#define JS_BYTES_PER_INT    4L
+#define JS_BYTES_PER_INT64  8L
+#define JS_BYTES_PER_LONG   4L
+#define JS_BYTES_PER_FLOAT  4L
+#define JS_BYTES_PER_DOUBLE 8L
+#define JS_BYTES_PER_WORD   4L
+#define JS_BYTES_PER_DWORD  8L
+
+#define JS_BITS_PER_BYTE    8L
+#define JS_BITS_PER_SHORT   16L
+#define JS_BITS_PER_INT     32L
+#define JS_BITS_PER_INT64   64L
+#define JS_BITS_PER_LONG    32L
+#define JS_BITS_PER_FLOAT   32L
+#define JS_BITS_PER_DOUBLE  64L
+#define JS_BITS_PER_WORD    32L
+
+#define JS_BITS_PER_BYTE_LOG2   3L
+#define JS_BITS_PER_SHORT_LOG2  4L
+#define JS_BITS_PER_INT_LOG2    5L
+#define JS_BITS_PER_INT64_LOG2  6L
+#define JS_BITS_PER_LONG_LOG2   5L
+#define JS_BITS_PER_FLOAT_LOG2  5L
+#define JS_BITS_PER_DOUBLE_LOG2 6L
+#define JS_BITS_PER_WORD_LOG2   5L
+
+#define JS_ALIGN_OF_SHORT   2L
+#define JS_ALIGN_OF_INT     4L
+#define JS_ALIGN_OF_LONG    4L
+#define JS_ALIGN_OF_INT64   8L
+#define JS_ALIGN_OF_FLOAT   4L
+#define JS_ALIGN_OF_DOUBLE  4L
+#define JS_ALIGN_OF_POINTER 4L
+#define JS_ALIGN_OF_WORD    4L
+
+#define JS_BYTES_PER_WORD_LOG2   2L
+#define JS_BYTES_PER_DWORD_LOG2  3L
+#define PR_WORDS_PER_DWORD_LOG2  1L
+#endif /* _WIN32 || XP_OS2 || WINCE*/
+
+#if defined(_WINDOWS) && !defined(_WIN32) /* WIN16 */
+#define IS_LITTLE_ENDIAN 1
+#undef  IS_BIG_ENDIAN
+
+#define JS_BYTES_PER_BYTE   1L
+#define JS_BYTES_PER_SHORT  2L
+#define JS_BYTES_PER_INT    2L
+#define JS_BYTES_PER_INT64  8L
+#define JS_BYTES_PER_LONG   4L
+#define JS_BYTES_PER_FLOAT  4L
+#define JS_BYTES_PER_DOUBLE 8L
+#define JS_BYTES_PER_WORD   4L
+#define JS_BYTES_PER_DWORD  8L
+
+#define JS_BITS_PER_BYTE    8L
+#define JS_BITS_PER_SHORT   16L
+#define JS_BITS_PER_INT     16L
+#define JS_BITS_PER_INT64   64L
+#define JS_BITS_PER_LONG    32L
+#define JS_BITS_PER_FLOAT   32L
+#define JS_BITS_PER_DOUBLE  64L
+#define JS_BITS_PER_WORD    32L
+
+#define JS_BITS_PER_BYTE_LOG2   3L
+#define JS_BITS_PER_SHORT_LOG2  4L
+#define JS_BITS_PER_INT_LOG2    4L
+#define JS_BITS_PER_INT64_LOG2  6L
+#define JS_BITS_PER_LONG_LOG2   5L
+#define JS_BITS_PER_FLOAT_LOG2  5L
+#define JS_BITS_PER_DOUBLE_LOG2 6L
+#define JS_BITS_PER_WORD_LOG2   5L
+
+#define JS_ALIGN_OF_SHORT   2L
+#define JS_ALIGN_OF_INT     2L
+#define JS_ALIGN_OF_LONG    2L
+#define JS_ALIGN_OF_INT64   2L
+#define JS_ALIGN_OF_FLOAT   2L
+#define JS_ALIGN_OF_DOUBLE  2L
+#define JS_ALIGN_OF_POINTER 2L
+#define JS_ALIGN_OF_WORD    2L
+
+#define JS_BYTES_PER_WORD_LOG2   2L
+#define JS_BYTES_PER_DWORD_LOG2  3L
+#define PR_WORDS_PER_DWORD_LOG2  1L
+#endif /* defined(_WINDOWS) && !defined(_WIN32) */
+
+#elif defined(XP_UNIX) || defined(XP_BEOS)
+
+#error "This file is supposed to be auto-generated on UNIX platforms, but the"
+#error "static version for Mac and Windows platforms is being used."
+#error "Something's probably wrong with paths/headers/dependencies/Makefiles."
+
+#else
+
+#error "Must define one of XP_BEOS, XP_OS2, XP_WIN, or XP_UNIX"
+
+#endif
+
+#ifndef JS_STACK_GROWTH_DIRECTION
+#define JS_STACK_GROWTH_DIRECTION (-1)
+#endif
+
+#endif /* js_cpucfg___ */

Added: freeswitch/trunk/libs/js/src/jsdate.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsdate.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2386 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS date methods.
+ */
+
+/*
+ * "For example, OS/360 devotes 26 bytes of the permanently
+ *  resident date-turnover routine to the proper handling of
+ *  December 31 on leap years (when it is Day 366).  That
+ *  might have been left to the operator."
+ *
+ * Frederick Brooks, 'The Second-System Effect'.
+ */
+
+#include "jsstddef.h"
+#include <ctype.h>
+#include <locale.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsprf.h"
+#include "prmjtime.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsapi.h"
+#include "jsconfig.h"
+#include "jscntxt.h"
+#include "jsdate.h"
+#include "jsinterp.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsstr.h"
+
+/*
+ * The JS 'Date' object is patterned after the Java 'Date' object.
+ * Here is an script:
+ *
+ *    today = new Date();
+ *
+ *    print(today.toLocaleString());
+ *
+ *    weekDay = today.getDay();
+ *
+ *
+ * These Java (and ECMA-262) methods are supported:
+ *
+ *     UTC
+ *     getDate (getUTCDate)
+ *     getDay (getUTCDay)
+ *     getHours (getUTCHours)
+ *     getMinutes (getUTCMinutes)
+ *     getMonth (getUTCMonth)
+ *     getSeconds (getUTCSeconds)
+ *     getMilliseconds (getUTCMilliseconds)
+ *     getTime
+ *     getTimezoneOffset
+ *     getYear
+ *     getFullYear (getUTCFullYear)
+ *     parse
+ *     setDate (setUTCDate)
+ *     setHours (setUTCHours)
+ *     setMinutes (setUTCMinutes)
+ *     setMonth (setUTCMonth)
+ *     setSeconds (setUTCSeconds)
+ *     setMilliseconds (setUTCMilliseconds)
+ *     setTime
+ *     setYear (setFullYear, setUTCFullYear)
+ *     toGMTString (toUTCString)
+ *     toLocaleString
+ *     toString
+ *
+ *
+ * These Java methods are not supported
+ *
+ *     setDay
+ *     before
+ *     after
+ *     equals
+ *     hashCode
+ */
+
+/*
+ * 11/97 - jsdate.c has been rewritten to conform to the ECMA-262 language
+ * definition and reduce dependence on NSPR.  NSPR is used to get the current
+ * time in milliseconds, the time zone offset, and the daylight savings time
+ * offset for a given time.  NSPR is also used for Date.toLocaleString(), for
+ * locale-specific formatting, and to get a string representing the timezone.
+ * (Which turns out to be platform-dependent.)
+ *
+ * To do:
+ * (I did some performance tests by timing how long it took to run what
+ *  I had of the js ECMA conformance tests.)
+ *
+ * - look at saving results across multiple calls to supporting
+ * functions; the toString functions compute some of the same values
+ * multiple times.  Although - I took a quick stab at this, and I lost
+ * rather than gained.  (Fractionally.)  Hard to tell what compilers/processors
+ * are doing these days.
+ *
+ * - look at tweaking function return types to return double instead
+ * of int; this seems to make things run slightly faster sometimes.
+ * (though it could be architecture-dependent.)  It'd be good to see
+ * how this does on win32.  (Tried it on irix.)  Types could use a
+ * general going-over.
+ */
+
+/*
+ * Supporting functions - ECMA 15.9.1.*
+ */
+
+#define HalfTimeDomain  8.64e15
+#define HoursPerDay     24.0
+#define MinutesPerDay   (HoursPerDay * MinutesPerHour)
+#define MinutesPerHour  60.0
+#define SecondsPerDay   (MinutesPerDay * SecondsPerMinute)
+#define SecondsPerHour  (MinutesPerHour * SecondsPerMinute)
+#define SecondsPerMinute 60.0
+
+#if defined(XP_WIN) || defined(XP_OS2)
+/* Work around msvc double optimization bug by making these runtime values; if
+ * they're available at compile time, msvc optimizes division by them by
+ * computing the reciprocal and multiplying instead of dividing - this loses
+ * when the reciprocal isn't representable in a double.
+ */
+static jsdouble msPerSecond = 1000.0;
+static jsdouble msPerDay = SecondsPerDay * 1000.0;
+static jsdouble msPerHour = SecondsPerHour * 1000.0;
+static jsdouble msPerMinute = SecondsPerMinute * 1000.0;
+#else
+#define msPerDay        (SecondsPerDay * msPerSecond)
+#define msPerHour       (SecondsPerHour * msPerSecond)
+#define msPerMinute     (SecondsPerMinute * msPerSecond)
+#define msPerSecond     1000.0
+#endif
+
+#define Day(t)          floor((t) / msPerDay)
+
+static jsdouble
+TimeWithinDay(jsdouble t)
+{
+    jsdouble result;
+    result = fmod(t, msPerDay);
+    if (result < 0)
+        result += msPerDay;
+    return result;
+}
+
+#define DaysInYear(y)   ((y) % 4 == 0 && ((y) % 100 || ((y) % 400 == 0))  \
+                         ? 366 : 365)
+
+/* math here has to be f.p, because we need
+ *  floor((1968 - 1969) / 4) == -1
+ */
+#define DayFromYear(y)  (365 * ((y)-1970) + floor(((y)-1969)/4.0)            \
+                         - floor(((y)-1901)/100.0) + floor(((y)-1601)/400.0))
+#define TimeFromYear(y) (DayFromYear(y) * msPerDay)
+
+static jsint
+YearFromTime(jsdouble t)
+{
+    jsint y = (jsint) floor(t /(msPerDay*365.2425)) + 1970;
+    jsdouble t2 = (jsdouble) TimeFromYear(y);
+
+    if (t2 > t) {
+        y--;
+    } else {
+        if (t2 + msPerDay * DaysInYear(y) <= t)
+            y++;
+    }
+    return y;
+}
+
+#define InLeapYear(t)   (JSBool) (DaysInYear(YearFromTime(t)) == 366)
+
+#define DayWithinYear(t, year) ((intN) (Day(t) - DayFromYear(year)))
+
+/*
+ * The following array contains the day of year for the first day of
+ * each month, where index 0 is January, and day 0 is January 1.
+ */
+static jsdouble firstDayOfMonth[2][12] = {
+    {0.0, 31.0, 59.0, 90.0, 120.0, 151.0, 181.0, 212.0, 243.0, 273.0, 304.0, 334.0},
+    {0.0, 31.0, 60.0, 91.0, 121.0, 152.0, 182.0, 213.0, 244.0, 274.0, 305.0, 335.0}
+};
+
+#define DayFromMonth(m, leap) firstDayOfMonth[leap][(intN)m];
+
+static intN
+MonthFromTime(jsdouble t)
+{
+    intN d, step;
+    jsint year = YearFromTime(t);
+    d = DayWithinYear(t, year);
+
+    if (d < (step = 31))
+        return 0;
+    step += (InLeapYear(t) ? 29 : 28);
+    if (d < step)
+        return 1;
+    if (d < (step += 31))
+        return 2;
+    if (d < (step += 30))
+        return 3;
+    if (d < (step += 31))
+        return 4;
+    if (d < (step += 30))
+        return 5;
+    if (d < (step += 31))
+        return 6;
+    if (d < (step += 31))
+        return 7;
+    if (d < (step += 30))
+        return 8;
+    if (d < (step += 31))
+        return 9;
+    if (d < (step += 30))
+        return 10;
+    return 11;
+}
+
+static intN
+DateFromTime(jsdouble t)
+{
+    intN d, step, next;
+    jsint year = YearFromTime(t);
+    d = DayWithinYear(t, year);
+
+    if (d <= (next = 30))
+        return d + 1;
+    step = next;
+    next += (InLeapYear(t) ? 29 : 28);
+    if (d <= next)
+        return d - step;
+    step = next;
+    if (d <= (next += 31))
+        return d - step;
+    step = next;
+    if (d <= (next += 30))
+        return d - step;
+    step = next;
+    if (d <= (next += 31))
+        return d - step;
+    step = next;
+    if (d <= (next += 30))
+        return d - step;
+    step = next;
+    if (d <= (next += 31))
+        return d - step;
+    step = next;
+    if (d <= (next += 31))
+        return d - step;
+    step = next;
+    if (d <= (next += 30))
+        return d - step;
+    step = next;
+    if (d <= (next += 31))
+        return d - step;
+    step = next;
+    if (d <= (next += 30))
+        return d - step;
+    step = next;
+    return d - step;
+}
+
+static intN
+WeekDay(jsdouble t)
+{
+    jsint result;
+    result = (jsint) Day(t) + 4;
+    result = result % 7;
+    if (result < 0)
+        result += 7;
+    return (intN) result;
+}
+
+#define MakeTime(hour, min, sec, ms) \
+((((hour) * MinutesPerHour + (min)) * SecondsPerMinute + (sec)) * msPerSecond + (ms))
+
+static jsdouble
+MakeDay(jsdouble year, jsdouble month, jsdouble date)
+{
+    JSBool leap;
+    jsdouble yearday;
+    jsdouble monthday;
+
+    year += floor(month / 12);
+
+    month = fmod(month, 12.0);
+    if (month < 0)
+        month += 12;
+
+    leap = (DaysInYear((jsint) year) == 366);
+
+    yearday = floor(TimeFromYear(year) / msPerDay);
+    monthday = DayFromMonth(month, leap);
+
+    return yearday + monthday + date - 1;
+}
+
+#define MakeDate(day, time) ((day) * msPerDay + (time))
+
+/* 
+ * Years and leap years on which Jan 1 is a Sunday, Monday, etc. 
+ *
+ * yearStartingWith[0][i] is an example non-leap year where
+ * Jan 1 appears on Sunday (i == 0), Monday (i == 1), etc.
+ *
+ * yearStartingWith[1][i] is an example leap year where
+ * Jan 1 appears on Sunday (i == 0), Monday (i == 1), etc.
+ */
+static jsint yearStartingWith[2][7] = {
+    {1978, 1973, 1974, 1975, 1981, 1971, 1977},
+    {1984, 1996, 1980, 1992, 1976, 1988, 1972}
+};
+
+/*
+ * Find a year for which any given date will fall on the same weekday.
+ *
+ * This function should be used with caution when used other than
+ * for determining DST; it hasn't been proven not to produce an
+ * incorrect year for times near year boundaries.
+ */
+static jsint
+EquivalentYearForDST(jsint year) {
+    jsint day;
+    JSBool isLeapYear;
+
+    day = (jsint) DayFromYear(year) + 4;
+    day = day % 7;
+    if (day < 0)
+	day += 7;
+
+    isLeapYear = (DaysInYear(year) == 366);
+
+    return yearStartingWith[isLeapYear][day];
+}
+
+/* LocalTZA gets set by js_InitDateClass() */
+static jsdouble LocalTZA;
+
+static jsdouble
+DaylightSavingTA(jsdouble t)
+{
+    volatile int64 PR_t;
+    int64 ms2us;
+    int64 offset;
+    jsdouble result;
+
+    /* abort if NaN */
+    if (JSDOUBLE_IS_NaN(t))
+        return t;
+
+    /*
+     * If earlier than 1970 or after 2038, potentially beyond the ken of
+     * many OSes, map it to an equivalent year before asking.
+     */
+    if (t < 0.0 || t > 2145916800000.0) {
+        jsint year;
+        jsdouble day;
+
+        year = EquivalentYearForDST(YearFromTime(t));
+        day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
+        t = MakeDate(day, TimeWithinDay(t));
+    }
+
+    /* put our t in an LL, and map it to usec for prtime */
+    JSLL_D2L(PR_t, t);
+    JSLL_I2L(ms2us, PRMJ_USEC_PER_MSEC);
+    JSLL_MUL(PR_t, PR_t, ms2us);
+
+    offset = PRMJ_DSTOffset(PR_t);
+
+    JSLL_DIV(offset, offset, ms2us);
+    JSLL_L2D(result, offset);
+    return result;
+}
+
+
+#define AdjustTime(t)   fmod(LocalTZA + DaylightSavingTA(t), msPerDay)
+
+#define LocalTime(t)    ((t) + AdjustTime(t))
+
+static jsdouble
+UTC(jsdouble t)
+{
+    return t - AdjustTime(t - LocalTZA);
+}
+
+static intN
+HourFromTime(jsdouble t)
+{
+    intN result = (intN) fmod(floor(t/msPerHour), HoursPerDay);
+    if (result < 0)
+        result += (intN)HoursPerDay;
+    return result;
+}
+
+static intN
+MinFromTime(jsdouble t)
+{
+    intN result = (intN) fmod(floor(t / msPerMinute), MinutesPerHour);
+    if (result < 0)
+        result += (intN)MinutesPerHour;
+    return result;
+}
+
+static intN
+SecFromTime(jsdouble t)
+{
+    intN result = (intN) fmod(floor(t / msPerSecond), SecondsPerMinute);
+    if (result < 0)
+        result += (intN)SecondsPerMinute;
+    return result;
+}
+
+static intN
+msFromTime(jsdouble t)
+{
+    intN result = (intN) fmod(t, msPerSecond);
+    if (result < 0)
+        result += (intN)msPerSecond;
+    return result;
+}
+
+#define TIMECLIP(d) ((JSDOUBLE_IS_FINITE(d) \
+                      && !((d < 0 ? -d : d) > HalfTimeDomain)) \
+                     ? js_DoubleToInteger(d + (+0.)) : *cx->runtime->jsNaN)
+
+/**
+ * end of ECMA 'support' functions
+ */
+
+/*
+ * Other Support routines and definitions
+ */
+
+static JSClass date_class = {
+    js_Date_str,
+    JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+/* for use by date_parse */
+
+static const char* wtb[] = {
+    "am", "pm",
+    "monday", "tuesday", "wednesday", "thursday", "friday",
+    "saturday", "sunday",
+    "january", "february", "march", "april", "may", "june",
+    "july", "august", "september", "october", "november", "december",
+    "gmt", "ut", "utc",
+    "est", "edt",
+    "cst", "cdt",
+    "mst", "mdt",
+    "pst", "pdt"
+    /* time zone table needs to be expanded */
+};
+
+static int ttb[] = {
+    -1, -2, 0, 0, 0, 0, 0, 0, 0,       /* AM/PM */
+    2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+    10000 + 0, 10000 + 0, 10000 + 0,   /* GMT/UT/UTC */
+    10000 + 5 * 60, 10000 + 4 * 60,    /* EST/EDT */
+    10000 + 6 * 60, 10000 + 5 * 60,    /* CST/CDT */
+    10000 + 7 * 60, 10000 + 6 * 60,    /* MST/MDT */
+    10000 + 8 * 60, 10000 + 7 * 60     /* PST/PDT */
+};
+
+/* helper for date_parse */
+static JSBool
+date_regionMatches(const char* s1, int s1off, const jschar* s2, int s2off,
+                   int count, int ignoreCase)
+{
+    JSBool result = JS_FALSE;
+    /* return true if matches, otherwise, false */
+
+    while (count > 0 && s1[s1off] && s2[s2off]) {
+        if (ignoreCase) {
+            if (JS_TOLOWER((jschar)s1[s1off]) != JS_TOLOWER(s2[s2off])) {
+                break;
+            }
+        } else {
+            if ((jschar)s1[s1off] != s2[s2off]) {
+                break;
+            }
+        }
+        s1off++;
+        s2off++;
+        count--;
+    }
+
+    if (count == 0) {
+        result = JS_TRUE;
+    }
+
+    return result;
+}
+
+/* find UTC time from given date... no 1900 correction! */
+static jsdouble
+date_msecFromDate(jsdouble year, jsdouble mon, jsdouble mday, jsdouble hour,
+                  jsdouble min, jsdouble sec, jsdouble msec)
+{
+    jsdouble day;
+    jsdouble msec_time;
+    jsdouble result;
+
+    day = MakeDay(year, mon, mday);
+    msec_time = MakeTime(hour, min, sec, msec);
+    result = MakeDate(day, msec_time);
+    return result;
+}
+
+/*
+ * See ECMA 15.9.4.[3-10];
+ */
+/* XXX this function must be above date_parseString to avoid a
+   horrid bug in the Win16 1.52 compiler */
+#define MAXARGS        7
+static JSBool
+date_UTC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble array[MAXARGS];
+    uintN loop;
+    jsdouble d;
+
+    for (loop = 0; loop < MAXARGS; loop++) {
+        if (loop < argc) {
+            if (!js_ValueToNumber(cx, argv[loop], &d))
+                return JS_FALSE;
+            /* return NaN if any arg is NaN */
+            if (!JSDOUBLE_IS_FINITE(d)) {
+                return js_NewNumberValue(cx, d, rval);
+            }
+            array[loop] = floor(d);
+        } else {
+            array[loop] = 0;
+        }
+    }
+
+    /* adjust 2-digit years into the 20th century */
+    if (array[0] >= 0 && array[0] <= 99)
+        array[0] += 1900;
+
+    /* if we got a 0 for 'date' (which is out of range)
+     * pretend it's a 1.  (So Date.UTC(1972, 5) works) */
+    if (array[2] < 1)
+        array[2] = 1;
+
+    d = date_msecFromDate(array[0], array[1], array[2],
+                              array[3], array[4], array[5], array[6]);
+    d = TIMECLIP(d);
+
+    return js_NewNumberValue(cx, d, rval);
+}
+
+static JSBool
+date_parseString(JSString *str, jsdouble *result)
+{
+    jsdouble msec;
+
+    const jschar *s = JSSTRING_CHARS(str);
+    size_t limit = JSSTRING_LENGTH(str);
+    size_t i = 0;
+    int year = -1;
+    int mon = -1;
+    int mday = -1;
+    int hour = -1;
+    int min = -1;
+    int sec = -1;
+    int c = -1;
+    int n = -1;
+    jsdouble tzoffset = -1;  /* was an int, overflowed on win16!!! */
+    int prevc = 0;
+    JSBool seenplusminus = JS_FALSE;
+    int temp;
+    JSBool seenmonthname = JS_FALSE;
+
+    if (limit == 0)
+        goto syntax;
+    while (i < limit) {
+        c = s[i];
+        i++;
+        if (c <= ' ' || c == ',' || c == '-') {
+            if (c == '-' && '0' <= s[i] && s[i] <= '9') {
+              prevc = c;
+            }
+            continue;
+        }
+        if (c == '(') { /* comments) */
+            int depth = 1;
+            while (i < limit) {
+                c = s[i];
+                i++;
+                if (c == '(') depth++;
+                else if (c == ')')
+                    if (--depth <= 0)
+                        break;
+            }
+            continue;
+        }
+        if ('0' <= c && c <= '9') {
+            n = c - '0';
+            while (i < limit && '0' <= (c = s[i]) && c <= '9') {
+                n = n * 10 + c - '0';
+                i++;
+            }
+
+            /* allow TZA before the year, so
+             * 'Wed Nov 05 21:49:11 GMT-0800 1997'
+             * works */
+
+            /* uses of seenplusminus allow : in TZA, so Java
+             * no-timezone style of GMT+4:30 works
+             */
+
+            if ((prevc == '+' || prevc == '-')/*  && year>=0 */) {
+                /* make ':' case below change tzoffset */
+                seenplusminus = JS_TRUE;
+
+                /* offset */
+                if (n < 24)
+                    n = n * 60; /* EG. "GMT-3" */
+                else
+                    n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
+                if (prevc == '+')       /* plus means east of GMT */
+                    n = -n;
+                if (tzoffset != 0 && tzoffset != -1)
+                    goto syntax;
+                tzoffset = n;
+            } else if (prevc == '/' && mon >= 0 && mday >= 0 && year < 0) {
+                if (c <= ' ' || c == ',' || c == '/' || i >= limit)
+                    year = n;
+                else
+                    goto syntax;
+            } else if (c == ':') {
+                if (hour < 0)
+                    hour = /*byte*/ n;
+                else if (min < 0)
+                    min = /*byte*/ n;
+                else
+                    goto syntax;
+            } else if (c == '/') {
+                /* until it is determined that mon is the actual
+                   month, keep it as 1-based rather than 0-based */
+                if (mon < 0)
+                    mon = /*byte*/ n;
+                else if (mday < 0)
+                    mday = /*byte*/ n;
+                else
+                    goto syntax;
+            } else if (i < limit && c != ',' && c > ' ' && c != '-' && c != '(') {
+                goto syntax;
+            } else if (seenplusminus && n < 60) {  /* handle GMT-3:30 */
+                if (tzoffset < 0)
+                    tzoffset -= n;
+                else
+                    tzoffset += n;
+            } else if (hour >= 0 && min < 0) {
+                min = /*byte*/ n;
+            } else if (prevc == ':' && min >= 0 && sec < 0) {
+                sec = /*byte*/ n;
+            } else if (mon < 0) {
+                mon = /*byte*/n;
+            } else if (mon >= 0 && mday < 0) {
+                mday = /*byte*/ n;
+            } else if (mon >= 0 && mday >= 0 && year < 0) {
+                year = n;
+            } else {
+                goto syntax;
+            }
+            prevc = 0;
+        } else if (c == '/' || c == ':' || c == '+' || c == '-') {
+            prevc = c;
+        } else {
+            size_t st = i - 1;
+            int k;
+            while (i < limit) {
+                c = s[i];
+                if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
+                    break;
+                i++;
+            }
+            if (i <= st + 1)
+                goto syntax;
+            for (k = (sizeof(wtb)/sizeof(char*)); --k >= 0;)
+                if (date_regionMatches(wtb[k], 0, s, st, i-st, 1)) {
+                    int action = ttb[k];
+                    if (action != 0) {
+                        if (action < 0) {
+                            /*
+                             * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as
+                             * 12:30, instead of blindly adding 12 if PM.
+                             */
+                            JS_ASSERT(action == -1 || action == -2);
+                            if (hour > 12 || hour < 0) {
+                                goto syntax;
+                            } else {
+                                if (action == -1 && hour == 12) { /* am */
+                                    hour = 0;
+                                } else if (action == -2 && hour != 12) { /* pm */
+                                    hour += 12;
+                                }
+                            }
+                        } else if (action <= 13) { /* month! */
+                            /* Adjust mon to be 1-based until the final values
+                               for mon, mday and year are adjusted below */
+                            if (seenmonthname) {
+                                goto syntax;
+                            }
+                            seenmonthname = JS_TRUE;
+                            temp = /*byte*/ (action - 2) + 1;
+
+                            if (mon < 0) {
+                                mon = temp;
+                            } else if (mday < 0) {
+                                mday = mon;
+                                mon = temp;
+                            } else if (year < 0) {
+                                year = mon;
+                                mon = temp;
+                            } else {
+                                goto syntax;
+                            }
+                        } else {
+                            tzoffset = action - 10000;
+                        }
+                    }
+                    break;
+                }
+            if (k < 0)
+                goto syntax;
+            prevc = 0;
+        }
+    }
+    if (year < 0 || mon < 0 || mday < 0)
+        goto syntax;
+    /*
+      Case 1. The input string contains an English month name.
+              The form of the string can be month f l, or f month l, or
+              f l month which each evaluate to the same date. 
+              If f and l are both greater than or equal to 70, or
+              both less than 70, the date is invalid.
+              The year is taken to be the greater of the values f, l.
+              If the year is greater than or equal to 70 and less than 100,
+              it is considered to be the number of years after 1900.
+      Case 2. The input string is of the form "f/m/l" where f, m and l are
+              integers, e.g. 7/16/45.
+              Adjust the mon, mday and year values to achieve 100% MSIE 
+              compatibility.
+              a. If 0 <= f < 70, f/m/l is interpreted as month/day/year.
+                 i.  If year < 100, it is the number of years after 1900
+                 ii. If year >= 100, it is the number of years after 0.
+              b. If 70 <= f < 100
+                 i.  If m < 70, f/m/l is interpreted as
+                     year/month/day where year is the number of years after
+                     1900.
+                 ii. If m >= 70, the date is invalid.
+              c. If f >= 100
+                 i.  If m < 70, f/m/l is interpreted as
+                     year/month/day where year is the number of years after 0.
+                 ii. If m >= 70, the date is invalid.
+    */
+    if (seenmonthname) {
+        if ((mday >= 70 && year >= 70) || (mday < 70 && year < 70)) {
+            goto syntax;
+        }
+        if (mday > year) {
+            temp = year;
+            year = mday;
+            mday = temp;
+        }
+        if (year >= 70 && year < 100) {
+            year += 1900;
+        }
+    } else if (mon < 70) { /* (a) month/day/year */
+        if (year < 100) {
+            year += 1900;
+        }
+    } else if (mon < 100) { /* (b) year/month/day */
+        if (mday < 70) { 
+            temp = year;
+            year = mon + 1900;
+            mon = mday;
+            mday = temp;
+        } else {
+            goto syntax;
+        }
+    } else { /* (c) year/month/day */
+        if (mday < 70) {
+            temp = year;
+            year = mon;
+            mon = mday;
+            mday = temp;
+        } else {
+            goto syntax;
+        }
+    }
+    mon -= 1; /* convert month to 0-based */
+    if (sec < 0)
+        sec = 0;
+    if (min < 0)
+        min = 0;
+    if (hour < 0)
+        hour = 0;
+    if (tzoffset == -1) { /* no time zone specified, have to use local */
+        jsdouble msec_time;
+        msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
+
+        *result = UTC(msec_time);
+        return JS_TRUE;
+    }
+
+    msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
+    msec += tzoffset * msPerMinute;
+    *result = msec;
+    return JS_TRUE;
+
+syntax:
+    /* syntax error */
+    *result = 0;
+    return JS_FALSE;
+}
+
+static JSBool
+date_parse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+    jsdouble result;
+
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    if (!date_parseString(str, &result)) {
+        *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
+        return JS_TRUE;
+    }
+
+    result = TIMECLIP(result);
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_now(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    int64 us, ms, us2ms;
+    jsdouble msec_time;
+
+    us = PRMJ_Now();
+    JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
+    JSLL_DIV(ms, us, us2ms);
+    JSLL_L2D(msec_time, ms);
+
+    return js_NewDoubleValue(cx, msec_time, rval);
+}
+
+/*
+ * Check that obj is an object of class Date, and get the date value.
+ * Return NULL on failure.
+ */
+static jsdouble *
+date_getProlog(JSContext *cx, JSObject *obj, jsval *argv)
+{
+    if (!JS_InstanceOf(cx, obj, &date_class, argv))
+        return NULL;
+    return JSVAL_TO_DOUBLE(OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE));
+}
+
+/*
+ * See ECMA 15.9.5.4 thru 15.9.5.23
+ */
+static JSBool
+date_getTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+
+    return js_NewNumberValue(cx, *date, rval);
+}
+
+static JSBool
+date_getYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble *date;
+    jsdouble result;
+    JSVersion version;
+
+    date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+
+    result = *date;
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = YearFromTime(LocalTime(result));
+
+    /*
+     * During the great date rewrite of 1.3, we tried to track the evolving ECMA
+     * standard, which then had a definition of getYear which always subtracted
+     * 1900.  Which we implemented, not realizing that it was incompatible with
+     * the old behavior...  now, rather than thrash the behavior yet again,
+     * we've decided to leave it with the - 1900 behavior and point people to
+     * the getFullYear method.  But we try to protect existing scripts that
+     * have specified a version...
+     */
+    version = cx->version & JSVERSION_MASK;
+    if (version == JSVERSION_1_0 ||
+        version == JSVERSION_1_1 ||
+        version == JSVERSION_1_2)
+    {
+        if (result >= 1900 && result < 2000)
+            result -= 1900;
+    } else {
+        result -= 1900;
+    }
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getFullYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = YearFromTime(LocalTime(result));
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getUTCFullYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                    jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = YearFromTime(result);
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getMonth(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = MonthFromTime(LocalTime(result));
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getUTCMonth(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = MonthFromTime(result);
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = LocalTime(result);
+    result = DateFromTime(result);
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getUTCDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = DateFromTime(result);
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getDay(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = LocalTime(result);
+    result = WeekDay(result);
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getUTCDay(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = WeekDay(result);
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getHours(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = HourFromTime(LocalTime(result));
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getUTCHours(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = HourFromTime(result);
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getMinutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = MinFromTime(LocalTime(result));
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getUTCMinutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                   jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = MinFromTime(result);
+    return js_NewNumberValue(cx, result, rval);
+}
+
+/* Date.getSeconds is mapped to getUTCSeconds */
+
+static JSBool
+date_getUTCSeconds(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = SecFromTime(result);
+    return js_NewNumberValue(cx, result, rval);
+}
+
+/* Date.getMilliseconds is mapped to getUTCMilliseconds */
+
+static JSBool
+date_getUTCMilliseconds(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                     jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    result = msFromTime(result);
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_getTimezoneOffset(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                       jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    result = *date;
+
+    /*
+     * Return the time zone offset in minutes for the current locale
+     * that is appropriate for this time. This value would be a
+     * constant except for daylight savings time.
+     */
+    result = (result - LocalTime(result)) / msPerMinute;
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_setTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble result;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+
+    if (!js_ValueToNumber(cx, argv[0], &result))
+        return JS_FALSE;
+
+    result = TIMECLIP(result);
+
+    *date = result;
+    return js_NewNumberValue(cx, result, rval);
+}
+
+static JSBool
+date_makeTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              uintN maxargs, JSBool local, jsval *rval)
+{
+    uintN i;
+    jsdouble args[4], *argp, *stop;
+    jsdouble hour, min, sec, msec;
+    jsdouble lorutime; /* Local or UTC version of *date */
+
+    jsdouble msec_time;
+    jsdouble result;
+
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+
+    result = *date;
+
+    /* just return NaN if the date is already NaN */
+    if (!JSDOUBLE_IS_FINITE(result))
+        return js_NewNumberValue(cx, result, rval);
+
+    /* Satisfy the ECMA rule that if a function is called with
+     * fewer arguments than the specified formal arguments, the
+     * remaining arguments are set to undefined.  Seems like all
+     * the Date.setWhatever functions in ECMA are only varargs
+     * beyond the first argument; this should be set to undefined
+     * if it's not given.  This means that "d = new Date();
+     * d.setMilliseconds()" returns NaN.  Blech.
+     */
+    if (argc == 0)
+        argc = 1;   /* should be safe, because length of all setters is 1 */
+    else if (argc > maxargs)
+        argc = maxargs;  /* clamp argc */
+
+    for (i = 0; i < argc; i++) {
+        if (!js_ValueToNumber(cx, argv[i], &args[i]))
+            return JS_FALSE;
+        if (!JSDOUBLE_IS_FINITE(args[i])) {
+            *date = *cx->runtime->jsNaN;
+            return js_NewNumberValue(cx, *date, rval);
+        }
+        args[i] = js_DoubleToInteger(args[i]);
+    }
+
+    if (local)
+        lorutime = LocalTime(result);
+    else
+        lorutime = result;
+
+    argp = args;
+    stop = argp + argc;
+    if (maxargs >= 4 && argp < stop)
+        hour = *argp++;
+    else
+        hour = HourFromTime(lorutime);
+
+    if (maxargs >= 3 && argp < stop)
+        min = *argp++;
+    else
+        min = MinFromTime(lorutime);
+
+    if (maxargs >= 2 && argp < stop)
+        sec = *argp++;
+    else
+        sec = SecFromTime(lorutime);
+
+    if (maxargs >= 1 && argp < stop)
+        msec = *argp;
+    else
+        msec = msFromTime(lorutime);
+
+    msec_time = MakeTime(hour, min, sec, msec);
+    result = MakeDate(Day(lorutime), msec_time);
+
+/*     fprintf(stderr, "%f\n", result); */
+
+    if (local)
+        result = UTC(result);
+
+/*     fprintf(stderr, "%f\n", result); */
+
+    *date = TIMECLIP(result);
+    return js_NewNumberValue(cx, *date, rval);
+}
+
+static JSBool
+date_setMilliseconds(JSContext *cx, JSObject *obj, uintN argc,
+                     jsval *argv, jsval *rval)
+{
+    return date_makeTime(cx, obj, argc, argv, 1, JS_TRUE, rval);
+}
+
+static JSBool
+date_setUTCMilliseconds(JSContext *cx, JSObject *obj, uintN argc,
+                        jsval *argv, jsval *rval)
+{
+    return date_makeTime(cx, obj, argc, argv, 1, JS_FALSE, rval);
+}
+
+static JSBool
+date_setSeconds(JSContext *cx, JSObject *obj, uintN argc,
+                jsval *argv, jsval *rval)
+{
+    return date_makeTime(cx, obj, argc, argv, 2, JS_TRUE, rval);
+}
+
+static JSBool
+date_setUTCSeconds(JSContext *cx, JSObject *obj, uintN argc,
+                   jsval *argv, jsval *rval)
+{
+    return date_makeTime(cx, obj, argc, argv, 2, JS_FALSE, rval);
+}
+
+static JSBool
+date_setMinutes(JSContext *cx, JSObject *obj, uintN argc,
+                jsval *argv, jsval *rval)
+{
+    return date_makeTime(cx, obj, argc, argv, 3, JS_TRUE, rval);
+}
+
+static JSBool
+date_setUTCMinutes(JSContext *cx, JSObject *obj, uintN argc,
+                   jsval *argv, jsval *rval)
+{
+    return date_makeTime(cx, obj, argc, argv, 3, JS_FALSE, rval);
+}
+
+static JSBool
+date_setHours(JSContext *cx, JSObject *obj, uintN argc,
+              jsval *argv, jsval *rval)
+{
+    return date_makeTime(cx, obj, argc, argv, 4, JS_TRUE, rval);
+}
+
+static JSBool
+date_setUTCHours(JSContext *cx, JSObject *obj, uintN argc,
+                 jsval *argv, jsval *rval)
+{
+    return date_makeTime(cx, obj, argc, argv, 4, JS_FALSE, rval);
+}
+
+static JSBool
+date_makeDate(JSContext *cx, JSObject *obj, uintN argc,
+              jsval *argv, uintN maxargs, JSBool local, jsval *rval)
+{
+    uintN i;
+    jsdouble lorutime; /* local or UTC version of *date */
+    jsdouble args[3], *argp, *stop;
+    jsdouble year, month, day;
+    jsdouble result;
+
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+
+    result = *date;
+
+    /* see complaint about ECMA in date_MakeTime */
+    if (argc == 0)
+        argc = 1;   /* should be safe, because length of all setters is 1 */
+    else if (argc > maxargs)
+        argc = maxargs;   /* clamp argc */
+
+    for (i = 0; i < argc; i++) {
+        if (!js_ValueToNumber(cx, argv[i], &args[i]))
+            return JS_FALSE;
+        if (!JSDOUBLE_IS_FINITE(args[i])) {
+            *date = *cx->runtime->jsNaN;
+            return js_NewNumberValue(cx, *date, rval);
+        }
+        args[i] = js_DoubleToInteger(args[i]);
+    }
+
+    /* return NaN if date is NaN and we're not setting the year,
+     * If we are, use 0 as the time. */
+    if (!(JSDOUBLE_IS_FINITE(result))) {
+        if (argc < 3)
+            return js_NewNumberValue(cx, result, rval);
+        else
+            lorutime = +0.;
+    } else {
+        if (local)
+            lorutime = LocalTime(result);
+        else
+            lorutime = result;
+    }
+
+    argp = args;
+    stop = argp + argc;
+    if (maxargs >= 3 && argp < stop)
+        year = *argp++;
+    else
+        year = YearFromTime(lorutime);
+
+    if (maxargs >= 2 && argp < stop)
+        month = *argp++;
+    else
+        month = MonthFromTime(lorutime);
+
+    if (maxargs >= 1 && argp < stop)
+        day = *argp++;
+    else
+        day = DateFromTime(lorutime);
+
+    day = MakeDay(year, month, day); /* day within year */
+    result = MakeDate(day, TimeWithinDay(lorutime));
+
+    if (local)
+        result = UTC(result);
+
+    *date = TIMECLIP(result);
+    return js_NewNumberValue(cx, *date, rval);
+}
+
+static JSBool
+date_setDate(JSContext *cx, JSObject *obj, uintN argc,
+             jsval *argv, jsval *rval)
+{
+    return date_makeDate(cx, obj, argc, argv, 1, JS_TRUE, rval);
+}
+
+static JSBool
+date_setUTCDate(JSContext *cx, JSObject *obj, uintN argc,
+                jsval *argv, jsval *rval)
+{
+    return date_makeDate(cx, obj, argc, argv, 1, JS_FALSE, rval);
+}
+
+static JSBool
+date_setMonth(JSContext *cx, JSObject *obj, uintN argc,
+              jsval *argv, jsval *rval)
+{
+    return date_makeDate(cx, obj, argc, argv, 2, JS_TRUE, rval);
+}
+
+static JSBool
+date_setUTCMonth(JSContext *cx, JSObject *obj, uintN argc,
+                 jsval *argv, jsval *rval)
+{
+    return date_makeDate(cx, obj, argc, argv, 2, JS_FALSE, rval);
+}
+
+static JSBool
+date_setFullYear(JSContext *cx, JSObject *obj, uintN argc,
+                 jsval *argv, jsval *rval)
+{
+    return date_makeDate(cx, obj, argc, argv, 3, JS_TRUE, rval);
+}
+
+static JSBool
+date_setUTCFullYear(JSContext *cx, JSObject *obj, uintN argc,
+                    jsval *argv, jsval *rval)
+{
+    return date_makeDate(cx, obj, argc, argv, 3, JS_FALSE, rval);
+}
+
+static JSBool
+date_setYear(JSContext *cx, JSObject *obj, uintN argc,
+             jsval *argv, jsval *rval)
+{
+    jsdouble t;
+    jsdouble year;
+    jsdouble day;
+    jsdouble result;
+
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+
+    result = *date;
+
+    if (!js_ValueToNumber(cx, argv[0], &year))
+        return JS_FALSE;
+    if (!JSDOUBLE_IS_FINITE(year)) {
+        *date = *cx->runtime->jsNaN;
+        return js_NewNumberValue(cx, *date, rval);
+    }
+
+    year = js_DoubleToInteger(year);
+
+    if (!JSDOUBLE_IS_FINITE(result)) {
+        t = +0.0;
+    } else {
+        t = LocalTime(result);
+    }
+
+    if (year >= 0 && year <= 99)
+        year += 1900;
+
+    day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
+    result = MakeDate(day, TimeWithinDay(t));
+    result = UTC(result);
+
+    *date = TIMECLIP(result);
+    return js_NewNumberValue(cx, *date, rval);
+}
+
+/* constants for toString, toUTCString */
+static char js_NaN_date_str[] = "Invalid Date";
+static const char* days[] =
+{
+   "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
+};
+static const char* months[] =
+{
+   "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static JSBool
+date_toGMTString(JSContext *cx, JSObject *obj, uintN argc,
+                 jsval *argv, jsval *rval)
+{
+    char buf[100];
+    JSString *str;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+
+    if (!JSDOUBLE_IS_FINITE(*date)) {
+        JS_snprintf(buf, sizeof buf, js_NaN_date_str);
+    } else {
+        jsdouble temp = *date;
+
+        /* Avoid dependence on PRMJ_FormatTimeUSEnglish, because it
+         * requires a PRMJTime... which only has 16-bit years.  Sub-ECMA.
+         */
+        JS_snprintf(buf, sizeof buf, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
+                    days[WeekDay(temp)],
+                    DateFromTime(temp),
+                    months[MonthFromTime(temp)],
+                    YearFromTime(temp),
+                    HourFromTime(temp),
+                    MinFromTime(temp),
+                    SecFromTime(temp));
+    }
+    str = JS_NewStringCopyZ(cx, buf);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+/* for Date.toLocaleString; interface to PRMJTime date struct.
+ * If findEquivalent is true, then try to map the year to an equivalent year
+ * that's in range.
+ */
+static void
+new_explode(jsdouble timeval, PRMJTime *split, JSBool findEquivalent)
+{
+    jsint year = YearFromTime(timeval);
+    int16 adjustedYear;
+
+    /* If the year doesn't fit in a PRMJTime, find something to do about it. */
+    if (year > 32767 || year < -32768) {
+        if (findEquivalent) {
+            /* We're really just trying to get a timezone string; map the year
+             * to some equivalent year in the range 0 to 2800.  Borrowed from
+             * A. D. Olsen.
+             */
+            jsint cycles;
+#define CYCLE_YEARS 2800L
+            cycles = (year >= 0) ? year / CYCLE_YEARS
+                                 : -1 - (-1 - year) / CYCLE_YEARS;
+            adjustedYear = (int16)(year - cycles * CYCLE_YEARS);
+        } else {
+            /* Clamp it to the nearest representable year. */
+            adjustedYear = (int16)((year > 0) ? 32767 : - 32768);
+        }
+    } else {
+        adjustedYear = (int16)year;
+    }
+
+    split->tm_usec = (int32) msFromTime(timeval) * 1000;
+    split->tm_sec = (int8) SecFromTime(timeval);
+    split->tm_min = (int8) MinFromTime(timeval);
+    split->tm_hour = (int8) HourFromTime(timeval);
+    split->tm_mday = (int8) DateFromTime(timeval);
+    split->tm_mon = (int8) MonthFromTime(timeval);
+    split->tm_wday = (int8) WeekDay(timeval);
+    split->tm_year = (int16) adjustedYear;
+    split->tm_yday = (int16) DayWithinYear(timeval, year);
+
+    /* not sure how this affects things, but it doesn't seem
+       to matter. */
+    split->tm_isdst = (DaylightSavingTA(timeval) != 0);
+}
+
+typedef enum formatspec {
+    FORMATSPEC_FULL, FORMATSPEC_DATE, FORMATSPEC_TIME
+} formatspec;
+
+/* helper function */
+static JSBool
+date_format(JSContext *cx, jsdouble date, formatspec format, jsval *rval)
+{
+    char buf[100];
+    JSString *str;
+    char tzbuf[100];
+    JSBool usetz;
+    size_t i, tzlen;
+    PRMJTime split;
+
+    if (!JSDOUBLE_IS_FINITE(date)) {
+        JS_snprintf(buf, sizeof buf, js_NaN_date_str);
+    } else {
+        jsdouble local = LocalTime(date);
+
+        /* offset from GMT in minutes.  The offset includes daylight savings,
+           if it applies. */
+        jsint minutes = (jsint) floor(AdjustTime(date) / msPerMinute);
+
+        /* map 510 minutes to 0830 hours */
+        intN offset = (minutes / 60) * 100 + minutes % 60;
+
+        /* print as "Wed Nov 05 19:38:03 GMT-0800 (PST) 1997" The TZA is
+         * printed as 'GMT-0800' rather than as 'PST' to avoid
+         * operating-system dependence on strftime (which
+         * PRMJ_FormatTimeUSEnglish calls, for %Z only.)  win32 prints
+         * PST as 'Pacific Standard Time.'  This way we always know
+         * what we're getting, and can parse it if we produce it.
+         * The OS TZA string is included as a comment.
+         */
+
+        /* get a timezone string from the OS to include as a
+           comment. */
+        new_explode(date, &split, JS_TRUE);
+        if (PRMJ_FormatTime(tzbuf, sizeof tzbuf, "(%Z)", &split) != 0) {
+
+            /* Decide whether to use the resulting timezone string.
+             *
+             * Reject it if it contains any non-ASCII, non-alphanumeric
+             * characters.  It's then likely in some other character
+             * encoding, and we probably won't display it correctly.
+             */
+            usetz = JS_TRUE;
+            tzlen = strlen(tzbuf);
+            if (tzlen > 100) {
+                usetz = JS_FALSE;
+            } else {
+                for (i = 0; i < tzlen; i++) {
+                    jschar c = tzbuf[i];
+                    if (c > 127 ||
+                        !(isalpha(c) || isdigit(c) ||
+                          c == ' ' || c == '(' || c == ')')) {
+                        usetz = JS_FALSE;
+                    }
+                }
+            }
+
+            /* Also reject it if it's not parenthesized or if it's '()'. */
+            if (tzbuf[0] != '(' || tzbuf[1] == ')')
+                usetz = JS_FALSE;
+        } else
+            usetz = JS_FALSE;
+
+        switch (format) {
+          case FORMATSPEC_FULL:
+            /*
+             * Avoid dependence on PRMJ_FormatTimeUSEnglish, because it
+             * requires a PRMJTime... which only has 16-bit years.  Sub-ECMA.
+             */
+            /* Tue Oct 31 2000 09:41:40 GMT-0800 (PST) */
+            JS_snprintf(buf, sizeof buf,
+                        "%s %s %.2d %.4d %.2d:%.2d:%.2d GMT%+.4d%s%s",
+                        days[WeekDay(local)],
+                        months[MonthFromTime(local)],
+                        DateFromTime(local),
+                        YearFromTime(local),
+                        HourFromTime(local),
+                        MinFromTime(local),
+                        SecFromTime(local),
+                        offset,
+                        usetz ? " " : "",
+                        usetz ? tzbuf : "");
+            break;
+          case FORMATSPEC_DATE:
+            /* Tue Oct 31 2000 */
+            JS_snprintf(buf, sizeof buf,
+                        "%s %s %.2d %.4d",
+                        days[WeekDay(local)],
+                        months[MonthFromTime(local)],
+                        DateFromTime(local),
+                        YearFromTime(local));
+            break;
+          case FORMATSPEC_TIME:
+            /* 09:41:40 GMT-0800 (PST) */
+            JS_snprintf(buf, sizeof buf,
+                        "%.2d:%.2d:%.2d GMT%+.4d%s%s",
+                        HourFromTime(local),
+                        MinFromTime(local),
+                        SecFromTime(local),
+                        offset,
+                        usetz ? " " : "",
+                        usetz ? tzbuf : "");
+            break;
+        }
+    }
+
+    str = JS_NewStringCopyZ(cx, buf);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+date_toLocaleHelper(JSContext *cx, JSObject *obj, uintN argc,
+                    jsval *argv, jsval *rval, char *format)
+{
+    char buf[100];
+    JSString *str;
+    PRMJTime split;
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+
+    if (!JSDOUBLE_IS_FINITE(*date)) {
+        JS_snprintf(buf, sizeof buf, js_NaN_date_str);
+    } else {
+        intN result_len;
+        jsdouble local = LocalTime(*date);
+        new_explode(local, &split, JS_FALSE);
+
+        /* let PRMJTime format it.       */
+        result_len = PRMJ_FormatTime(buf, sizeof buf, format, &split);
+
+        /* If it failed, default to toString. */
+        if (result_len == 0)
+            return date_format(cx, *date, FORMATSPEC_FULL, rval);
+
+        /* Hacked check against undesired 2-digit year 00/00/00 form. */
+        if (buf[result_len - 3] == '/' &&
+            isdigit(buf[result_len - 2]) && isdigit(buf[result_len - 1])) {
+            JS_snprintf(buf + (result_len - 2), (sizeof buf) - (result_len - 2),
+                        "%d", js_DateGetYear(cx, obj));
+        }
+
+    }
+
+    if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode)
+        return cx->localeCallbacks->localeToUnicode(cx, buf, rval);
+
+    str = JS_NewStringCopyZ(cx, buf);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+date_toLocaleString(JSContext *cx, JSObject *obj, uintN argc,
+                    jsval *argv, jsval *rval)
+{
+    /* Use '%#c' for windows, because '%c' is
+     * backward-compatible and non-y2k with msvc; '%#c' requests that a
+     * full year be used in the result string.
+     */
+    return date_toLocaleHelper(cx, obj, argc, argv, rval,
+#if defined(_WIN32) && !defined(__MWERKS__)
+                                   "%#c"
+#else
+                                   "%c"
+#endif
+                                   );
+}
+
+static JSBool
+date_toLocaleDateString(JSContext *cx, JSObject *obj, uintN argc,
+                    jsval *argv, jsval *rval)
+{
+    /* Use '%#x' for windows, because '%x' is
+     * backward-compatible and non-y2k with msvc; '%#x' requests that a
+     * full year be used in the result string.
+     */
+    return date_toLocaleHelper(cx, obj, argc, argv, rval,
+#if defined(_WIN32) && !defined(__MWERKS__)
+                                   "%#x"
+#else
+                                   "%x"
+#endif
+                                   );
+}
+
+static JSBool
+date_toLocaleTimeString(JSContext *cx, JSObject *obj, uintN argc,
+                        jsval *argv, jsval *rval)
+{
+    return date_toLocaleHelper(cx, obj, argc, argv, rval, "%X");
+}
+
+static JSBool
+date_toLocaleFormat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                    jsval *rval)
+{
+    JSString *fmt;
+
+    if (argc == 0)
+        return date_toLocaleString(cx, obj, argc, argv, rval);
+
+    fmt = JS_ValueToString(cx, argv[0]);
+    if (!fmt)
+        return JS_FALSE;
+
+    return date_toLocaleHelper(cx, obj, argc, argv, rval,
+                               JS_GetStringBytes(fmt));
+}
+
+static JSBool
+date_toTimeString(JSContext *cx, JSObject *obj, uintN argc,
+                  jsval *argv, jsval *rval)
+{
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    return date_format(cx, *date, FORMATSPEC_TIME, rval);
+}
+
+static JSBool
+date_toDateString(JSContext *cx, JSObject *obj, uintN argc,
+                  jsval *argv, jsval *rval)
+{
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    return date_format(cx, *date, FORMATSPEC_DATE, rval);
+}
+
+#if JS_HAS_TOSOURCE
+#include <string.h>
+#include "jsdtoa.h"
+
+static JSBool
+date_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    jsdouble *date;
+    char buf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr, *bytes;
+    JSString *str;
+
+    date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+
+    numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, *date);
+    if (!numStr) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+
+    bytes = JS_smprintf("(new %s(%s))", date_class.name, numStr);
+    if (!bytes) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+
+    str = JS_NewString(cx, bytes, strlen(bytes));
+    if (!str) {
+        free(bytes);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+#endif
+
+static JSBool
+date_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    jsdouble *date = date_getProlog(cx, obj, argv);
+    if (!date)
+        return JS_FALSE;
+    return date_format(cx, *date, FORMATSPEC_FULL, rval);
+}
+
+#if JS_HAS_VALUEOF_HINT
+static JSBool
+date_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+             jsval *rval)
+{
+    /* It is an error to call date_valueOf on a non-date object, but we don't
+     * need to check for that explicitly here because every path calls
+     * date_getProlog, which does the check.
+     */
+
+    /* If called directly with no arguments, convert to a time number. */
+    if (argc == 0)
+        return date_getTime(cx, obj, argc, argv, rval);
+
+    /* Convert to number only if the hint was given, otherwise favor string. */
+    if (argc == 1) {
+        JSString *str, *str2;
+
+        str = js_ValueToString(cx, argv[0]);
+        if (!str)
+            return JS_FALSE;
+        str2 = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_NUMBER]);
+        if (!js_CompareStrings(str, str2))
+            return date_getTime(cx, obj, argc, argv, rval);
+    }
+    return date_toString(cx, obj, argc, argv, rval);
+}
+#else
+#define date_valueOf date_getTime
+#endif
+
+
+/*
+ * creation and destruction
+ */
+
+static JSFunctionSpec date_static_methods[] = {
+    {"UTC",               date_UTC,               MAXARGS,0,0 },
+    {"parse",             date_parse,             1,0,0 },
+    {"now",               date_now,               0,0,0 },
+    {0,0,0,0,0}
+};
+
+static JSFunctionSpec date_methods[] = {
+    {"getTime",             date_getTime,           0,0,0 },
+    {"getTimezoneOffset",   date_getTimezoneOffset, 0,0,0 },
+    {"getYear",             date_getYear,           0,0,0 },
+    {"getFullYear",         date_getFullYear,       0,0,0 },
+    {"getUTCFullYear",      date_getUTCFullYear,    0,0,0 },
+    {"getMonth",            date_getMonth,          0,0,0 },
+    {"getUTCMonth",         date_getUTCMonth,       0,0,0 },
+    {"getDate",             date_getDate,           0,0,0 },
+    {"getUTCDate",          date_getUTCDate,        0,0,0 },
+    {"getDay",              date_getDay,            0,0,0 },
+    {"getUTCDay",           date_getUTCDay,         0,0,0 },
+    {"getHours",            date_getHours,          0,0,0 },
+    {"getUTCHours",         date_getUTCHours,       0,0,0 },
+    {"getMinutes",          date_getMinutes,        0,0,0 },
+    {"getUTCMinutes",       date_getUTCMinutes,     0,0,0 },
+    {"getSeconds",          date_getUTCSeconds,     0,0,0 },
+    {"getUTCSeconds",       date_getUTCSeconds,     0,0,0 },
+    {"getMilliseconds",     date_getUTCMilliseconds,0,0,0 },
+    {"getUTCMilliseconds",  date_getUTCMilliseconds,0,0,0 },
+    {"setTime",             date_setTime,           1,0,0 },
+    {"setYear",             date_setYear,           1,0,0 },
+    {"setFullYear",         date_setFullYear,       3,0,0 },
+    {"setUTCFullYear",      date_setUTCFullYear,    3,0,0 },
+    {"setMonth",            date_setMonth,          2,0,0 },
+    {"setUTCMonth",         date_setUTCMonth,       2,0,0 },
+    {"setDate",             date_setDate,           1,0,0 },
+    {"setUTCDate",          date_setUTCDate,        1,0,0 },
+    {"setHours",            date_setHours,          4,0,0 },
+    {"setUTCHours",         date_setUTCHours,       4,0,0 },
+    {"setMinutes",          date_setMinutes,        3,0,0 },
+    {"setUTCMinutes",       date_setUTCMinutes,     3,0,0 },
+    {"setSeconds",          date_setSeconds,        2,0,0 },
+    {"setUTCSeconds",       date_setUTCSeconds,     2,0,0 },
+    {"setMilliseconds",     date_setMilliseconds,   1,0,0 },
+    {"setUTCMilliseconds",  date_setUTCMilliseconds,1,0,0 },
+    {"toUTCString",         date_toGMTString,       0,0,0 },
+    {js_toLocaleString_str, date_toLocaleString,    0,0,0 },
+    {"toLocaleDateString",  date_toLocaleDateString,0,0,0 },
+    {"toLocaleTimeString",  date_toLocaleTimeString,0,0,0 },
+    {"toLocaleFormat",      date_toLocaleFormat,    1,0,0 },
+    {"toDateString",        date_toDateString,      0,0,0 },
+    {"toTimeString",        date_toTimeString,      0,0,0 },
+#if JS_HAS_TOSOURCE
+    {js_toSource_str,       date_toSource,          0,0,0 },
+#endif
+    {js_toString_str,       date_toString,          0,0,0 },
+    {js_valueOf_str,        date_valueOf,           0,0,0 },
+    {0,0,0,0,0}
+};
+
+static jsdouble *
+date_constructor(JSContext *cx, JSObject* obj)
+{
+    jsdouble *date;
+
+    date = js_NewDouble(cx, 0.0, 0);
+    if (!date)
+        return NULL;
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, DOUBLE_TO_JSVAL(date));
+    return date;
+}
+
+static JSBool
+Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble *date;
+    JSString *str;
+    jsdouble d;
+
+    /* Date called as function. */
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        int64 us, ms, us2ms;
+        jsdouble msec_time;
+
+        /* NSPR 2.0 docs say 'We do not support PRMJ_NowMS and PRMJ_NowS',
+         * so compute ms from PRMJ_Now.
+         */
+        us = PRMJ_Now();
+        JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
+        JSLL_DIV(ms, us, us2ms);
+        JSLL_L2D(msec_time, ms);
+
+        return date_format(cx, msec_time, FORMATSPEC_FULL, rval);
+    }
+
+    /* Date called as constructor. */
+    if (argc == 0) {
+        int64 us, ms, us2ms;
+        jsdouble msec_time;
+
+        date = date_constructor(cx, obj);
+        if (!date)
+            return JS_FALSE;
+
+        us = PRMJ_Now();
+        JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
+        JSLL_DIV(ms, us, us2ms);
+        JSLL_L2D(msec_time, ms);
+
+        *date = msec_time;
+    } else if (argc == 1) {
+        if (!JSVAL_IS_STRING(argv[0])) {
+            /* the argument is a millisecond number */
+            if (!js_ValueToNumber(cx, argv[0], &d))
+                    return JS_FALSE;
+            date = date_constructor(cx, obj);
+            if (!date)
+                return JS_FALSE;
+            *date = TIMECLIP(d);
+        } else {
+            /* the argument is a string; parse it. */
+            date = date_constructor(cx, obj);
+            if (!date)
+                return JS_FALSE;
+
+            str = js_ValueToString(cx, argv[0]);
+            if (!str)
+                return JS_FALSE;
+
+            if (!date_parseString(str, date))
+                *date = *cx->runtime->jsNaN;
+            *date = TIMECLIP(*date);
+        }
+    } else {
+        jsdouble array[MAXARGS];
+        uintN loop;
+        jsdouble double_arg;
+        jsdouble day;
+        jsdouble msec_time;
+
+        for (loop = 0; loop < MAXARGS; loop++) {
+            if (loop < argc) {
+                if (!js_ValueToNumber(cx, argv[loop], &double_arg))
+                    return JS_FALSE;
+                /* if any arg is NaN, make a NaN date object
+                   and return */
+                if (!JSDOUBLE_IS_FINITE(double_arg)) {
+                    date = date_constructor(cx, obj);
+                    if (!date)
+                        return JS_FALSE;
+                    *date = *cx->runtime->jsNaN;
+                    return JS_TRUE;
+                }
+                array[loop] = js_DoubleToInteger(double_arg);
+            } else {
+                if (loop == 2) {
+                    array[loop] = 1; /* Default the date argument to 1. */
+                } else {
+                    array[loop] = 0;
+                }
+            }
+        }
+
+        date = date_constructor(cx, obj);
+        if (!date)
+            return JS_FALSE;
+
+        /* adjust 2-digit years into the 20th century */
+        if (array[0] >= 0 && array[0] <= 99)
+            array[0] += 1900;
+
+        day = MakeDay(array[0], array[1], array[2]);
+        msec_time = MakeTime(array[3], array[4], array[5], array[6]);
+        msec_time = MakeDate(day, msec_time);
+        msec_time = UTC(msec_time);
+        *date = TIMECLIP(msec_time);
+    }
+    return JS_TRUE;
+}
+
+JSObject *
+js_InitDateClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto;
+    jsdouble *proto_date;
+
+    /* set static LocalTZA */
+    LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
+    proto = JS_InitClass(cx, obj, NULL, &date_class, Date, MAXARGS,
+                         NULL, date_methods, NULL, date_static_methods);
+    if (!proto)
+        return NULL;
+
+    /* Alias toUTCString with toGMTString.  (ECMA B.2.6) */
+    if (!JS_AliasProperty(cx, proto, "toUTCString", "toGMTString"))
+        return NULL;
+
+    /* Set the value of the Date.prototype date to NaN */
+    proto_date = date_constructor(cx, proto);
+    if (!proto_date)
+        return NULL;
+    *proto_date = *cx->runtime->jsNaN;
+
+    return proto;
+}
+
+JS_FRIEND_API(JSObject *)
+js_NewDateObjectMsec(JSContext *cx, jsdouble msec_time)
+{
+    JSObject *obj;
+    jsdouble *date;
+
+    obj = js_NewObject(cx, &date_class, NULL, NULL);
+    if (!obj)
+        return NULL;
+
+    date = date_constructor(cx, obj);
+    if (!date)
+        return NULL;
+
+    *date = msec_time;
+    return obj;
+}
+
+JS_FRIEND_API(JSObject *)
+js_NewDateObject(JSContext* cx, int year, int mon, int mday,
+                 int hour, int min, int sec)
+{
+    JSObject *obj;
+    jsdouble msec_time;
+
+    msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
+    obj = js_NewDateObjectMsec(cx, UTC(msec_time));
+    return obj;
+}
+
+JS_FRIEND_API(JSBool)
+js_DateIsValid(JSContext *cx, JSObject* obj)
+{
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+
+    if (!date || JSDOUBLE_IS_NaN(*date))
+        return JS_FALSE;
+    else
+        return JS_TRUE;
+}
+
+JS_FRIEND_API(int)
+js_DateGetYear(JSContext *cx, JSObject* obj)
+{
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+
+    /* Preserve legacy API behavior of returning 0 for invalid dates. */
+    if (!date || JSDOUBLE_IS_NaN(*date))
+        return 0;
+    return (int) YearFromTime(LocalTime(*date));
+}
+
+JS_FRIEND_API(int)
+js_DateGetMonth(JSContext *cx, JSObject* obj)
+{
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+
+    if (!date || JSDOUBLE_IS_NaN(*date))
+        return 0;
+    return (int) MonthFromTime(LocalTime(*date));
+}
+
+JS_FRIEND_API(int)
+js_DateGetDate(JSContext *cx, JSObject* obj)
+{
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+
+    if (!date || JSDOUBLE_IS_NaN(*date))
+        return 0;
+    return (int) DateFromTime(LocalTime(*date));
+}
+
+JS_FRIEND_API(int)
+js_DateGetHours(JSContext *cx, JSObject* obj)
+{
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+
+    if (!date || JSDOUBLE_IS_NaN(*date))
+        return 0;
+    return (int) HourFromTime(LocalTime(*date));
+}
+
+JS_FRIEND_API(int)
+js_DateGetMinutes(JSContext *cx, JSObject* obj)
+{
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+
+    if (!date || JSDOUBLE_IS_NaN(*date))
+        return 0;
+    return (int) MinFromTime(LocalTime(*date));
+}
+
+JS_FRIEND_API(int)
+js_DateGetSeconds(JSContext *cx, JSObject* obj)
+{
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+
+    if (!date || JSDOUBLE_IS_NaN(*date))
+        return 0;
+    return (int) SecFromTime(*date);
+}
+
+JS_FRIEND_API(void)
+js_DateSetYear(JSContext *cx, JSObject *obj, int year)
+{
+    jsdouble local;
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+    if (!date)
+        return;
+    local = LocalTime(*date);
+    /* reset date if it was NaN */
+    if (JSDOUBLE_IS_NaN(local))
+        local = 0;
+    local = date_msecFromDate(year,
+                              MonthFromTime(local),
+                              DateFromTime(local),
+                              HourFromTime(local),
+                              MinFromTime(local),
+                              SecFromTime(local),
+                              msFromTime(local));
+    *date = UTC(local);
+}
+
+JS_FRIEND_API(void)
+js_DateSetMonth(JSContext *cx, JSObject *obj, int month)
+{
+    jsdouble local;
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+    if (!date)
+        return;
+    local = LocalTime(*date);
+    /* bail if date was NaN */
+    if (JSDOUBLE_IS_NaN(local))
+        return;
+    local = date_msecFromDate(YearFromTime(local),
+                              month,
+                              DateFromTime(local),
+                              HourFromTime(local),
+                              MinFromTime(local),
+                              SecFromTime(local),
+                              msFromTime(local));
+    *date = UTC(local);
+}
+
+JS_FRIEND_API(void)
+js_DateSetDate(JSContext *cx, JSObject *obj, int date)
+{
+    jsdouble local;
+    jsdouble *datep = date_getProlog(cx, obj, NULL);
+    if (!datep)
+        return;
+    local = LocalTime(*datep);
+    if (JSDOUBLE_IS_NaN(local))
+        return;
+    local = date_msecFromDate(YearFromTime(local),
+                              MonthFromTime(local),
+                              date,
+                              HourFromTime(local),
+                              MinFromTime(local),
+                              SecFromTime(local),
+                              msFromTime(local));
+    *datep = UTC(local);
+}
+
+JS_FRIEND_API(void)
+js_DateSetHours(JSContext *cx, JSObject *obj, int hours)
+{
+    jsdouble local;
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+    if (!date)
+        return;
+    local = LocalTime(*date);
+    if (JSDOUBLE_IS_NaN(local))
+        return;
+    local = date_msecFromDate(YearFromTime(local),
+                              MonthFromTime(local),
+                              DateFromTime(local),
+                              hours,
+                              MinFromTime(local),
+                              SecFromTime(local),
+                              msFromTime(local));
+    *date = UTC(local);
+}
+
+JS_FRIEND_API(void)
+js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes)
+{
+    jsdouble local;
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+    if (!date)
+        return;
+    local = LocalTime(*date);
+    if (JSDOUBLE_IS_NaN(local))
+        return;
+    local = date_msecFromDate(YearFromTime(local),
+                              MonthFromTime(local),
+                              DateFromTime(local),
+                              HourFromTime(local),
+                              minutes,
+                              SecFromTime(local),
+                              msFromTime(local));
+    *date = UTC(local);
+}
+
+JS_FRIEND_API(void)
+js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds)
+{
+    jsdouble local;
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+    if (!date)
+        return;
+    local = LocalTime(*date);
+    if (JSDOUBLE_IS_NaN(local))
+        return;
+    local = date_msecFromDate(YearFromTime(local),
+                              MonthFromTime(local),
+                              DateFromTime(local),
+                              HourFromTime(local),
+                              MinFromTime(local),
+                              seconds,
+                              msFromTime(local));
+    *date = UTC(local);
+}
+
+JS_FRIEND_API(jsdouble)
+js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj)
+{
+    jsdouble *date = date_getProlog(cx, obj, NULL);
+    if (!date || JSDOUBLE_IS_NaN(*date))
+        return 0;
+    return (*date);
+}

Added: freeswitch/trunk/libs/js/src/jsdate.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsdate.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,118 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS Date class interface.
+ */
+
+#ifndef jsdate_h___
+#define jsdate_h___
+
+JS_BEGIN_EXTERN_C
+
+extern JSObject *
+js_InitDateClass(JSContext *cx, JSObject *obj);
+
+/*
+ * These functions provide a C interface to the date/time object
+ */
+
+/*
+ * Construct a new Date Object from a time value given in milliseconds UTC
+ * since the epoch.
+ */
+extern JS_FRIEND_API(JSObject*)
+js_NewDateObjectMsec(JSContext* cx, jsdouble msec_time);
+
+/*
+ * Construct a new Date Object from an exploded local time value.
+ */
+extern JS_FRIEND_API(JSObject*)
+js_NewDateObject(JSContext* cx, int year, int mon, int mday,
+                 int hour, int min, int sec);
+
+/*
+ * Detect whether the internal date value is NaN.  (Because failure is
+ * out-of-band for js_DateGet*)
+ */
+extern JS_FRIEND_API(JSBool)
+js_DateIsValid(JSContext *cx, JSObject* obj);
+
+extern JS_FRIEND_API(int)
+js_DateGetYear(JSContext *cx, JSObject* obj);
+
+extern JS_FRIEND_API(int)
+js_DateGetMonth(JSContext *cx, JSObject* obj);
+
+extern JS_FRIEND_API(int)
+js_DateGetDate(JSContext *cx, JSObject* obj);
+
+extern JS_FRIEND_API(int)
+js_DateGetHours(JSContext *cx, JSObject* obj);
+
+extern JS_FRIEND_API(int)
+js_DateGetMinutes(JSContext *cx, JSObject* obj);
+
+extern JS_FRIEND_API(int)
+js_DateGetSeconds(JSContext *cx, JSObject* obj);
+
+extern JS_FRIEND_API(void)
+js_DateSetYear(JSContext *cx, JSObject *obj, int year);
+
+extern JS_FRIEND_API(void)
+js_DateSetMonth(JSContext *cx, JSObject *obj, int year);
+
+extern JS_FRIEND_API(void)
+js_DateSetDate(JSContext *cx, JSObject *obj, int date);
+
+extern JS_FRIEND_API(void)
+js_DateSetHours(JSContext *cx, JSObject *obj, int hours);
+
+extern JS_FRIEND_API(void)
+js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes);
+
+extern JS_FRIEND_API(void)
+js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds);
+
+extern JS_FRIEND_API(jsdouble)
+js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj);
+
+JS_END_EXTERN_C
+
+#endif /* jsdate_h___ */

Added: freeswitch/trunk/libs/js/src/jsdbgapi.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsdbgapi.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1342 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS debugging API.
+ */
+#include "jsstddef.h"
+#include <string.h>
+#include "jstypes.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsclist.h"
+#include "jsapi.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsdbgapi.h"
+#include "jsfun.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsobj.h"
+#include "jsopcode.h"
+#include "jsscope.h"
+#include "jsscript.h"
+#include "jsstr.h"
+
+typedef struct JSTrap {
+    JSCList         links;
+    JSScript        *script;
+    jsbytecode      *pc;
+    JSOp            op;
+    JSTrapHandler   handler;
+    void            *closure;
+} JSTrap;
+
+static JSTrap *
+FindTrap(JSRuntime *rt, JSScript *script, jsbytecode *pc)
+{
+    JSTrap *trap;
+
+    for (trap = (JSTrap *)rt->trapList.next;
+         trap != (JSTrap *)&rt->trapList;
+         trap = (JSTrap *)trap->links.next) {
+        if (trap->script == script && trap->pc == pc)
+            return trap;
+    }
+    return NULL;
+}
+
+void
+js_PatchOpcode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op)
+{
+    JSTrap *trap;
+
+    trap = FindTrap(cx->runtime, script, pc);
+    if (trap)
+        trap->op = op;
+    else
+        *pc = (jsbytecode)op;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
+           JSTrapHandler handler, void *closure)
+{
+    JSRuntime *rt;
+    JSTrap *trap;
+
+    rt = cx->runtime;
+    trap = FindTrap(rt, script, pc);
+    if (trap) {
+        JS_ASSERT(trap->script == script && trap->pc == pc);
+        JS_ASSERT(*pc == JSOP_TRAP);
+    } else {
+        trap = (JSTrap *) JS_malloc(cx, sizeof *trap);
+        if (!trap || !js_AddRoot(cx, &trap->closure, "trap->closure")) {
+            if (trap)
+                JS_free(cx, trap);
+            return JS_FALSE;
+        }
+        JS_APPEND_LINK(&trap->links, &rt->trapList);
+        trap->script = script;
+        trap->pc = pc;
+        trap->op = (JSOp)*pc;
+        *pc = JSOP_TRAP;
+    }
+    trap->handler = handler;
+    trap->closure = closure;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSOp)
+JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc)
+{
+    JSTrap *trap;
+
+    trap = FindTrap(cx->runtime, script, pc);
+    if (!trap) {
+        JS_ASSERT(0);   /* XXX can't happen */
+        return JSOP_LIMIT;
+    }
+    return trap->op;
+}
+
+static void
+DestroyTrap(JSContext *cx, JSTrap *trap)
+{
+    JS_REMOVE_LINK(&trap->links);
+    *trap->pc = (jsbytecode)trap->op;
+    js_RemoveRoot(cx->runtime, &trap->closure);
+    JS_free(cx, trap);
+}
+
+JS_PUBLIC_API(void)
+JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
+             JSTrapHandler *handlerp, void **closurep)
+{
+    JSTrap *trap;
+
+    trap = FindTrap(cx->runtime, script, pc);
+    if (handlerp)
+        *handlerp = trap ? trap->handler : NULL;
+    if (closurep)
+        *closurep = trap ? trap->closure : NULL;
+    if (trap)
+        DestroyTrap(cx, trap);
+}
+
+JS_PUBLIC_API(void)
+JS_ClearScriptTraps(JSContext *cx, JSScript *script)
+{
+    JSRuntime *rt;
+    JSTrap *trap, *next;
+
+    rt = cx->runtime;
+    for (trap = (JSTrap *)rt->trapList.next;
+         trap != (JSTrap *)&rt->trapList;
+         trap = next) {
+        next = (JSTrap *)trap->links.next;
+        if (trap->script == script)
+            DestroyTrap(cx, trap);
+    }
+}
+
+JS_PUBLIC_API(void)
+JS_ClearAllTraps(JSContext *cx)
+{
+    JSRuntime *rt;
+    JSTrap *trap, *next;
+
+    rt = cx->runtime;
+    for (trap = (JSTrap *)rt->trapList.next;
+         trap != (JSTrap *)&rt->trapList;
+         trap = next) {
+        next = (JSTrap *)trap->links.next;
+        DestroyTrap(cx, trap);
+    }
+}
+
+JS_PUBLIC_API(JSTrapStatus)
+JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval)
+{
+    JSTrap *trap;
+    JSTrapStatus status;
+    jsint op;
+
+    trap = FindTrap(cx->runtime, script, pc);
+    if (!trap) {
+        JS_ASSERT(0);   /* XXX can't happen */
+        return JSTRAP_ERROR;
+    }
+    /*
+     * It's important that we not use 'trap->' after calling the callback --
+     * the callback might remove the trap!
+     */
+    op = (jsint)trap->op;
+    status = trap->handler(cx, script, pc, rval, trap->closure);
+    if (status == JSTRAP_CONTINUE) {
+        /* By convention, return the true op to the interpreter in rval. */
+        *rval = INT_TO_JSVAL(op);
+    }
+    return status;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure)
+{
+    rt->interruptHandler = handler;
+    rt->interruptHandlerData = closure;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep)
+{
+    if (handlerp)
+        *handlerp = (JSTrapHandler)rt->interruptHandler;
+    if (closurep)
+        *closurep = rt->interruptHandlerData;
+    rt->interruptHandler = 0;
+    rt->interruptHandlerData = 0;
+    return JS_TRUE;
+}
+
+/************************************************************************/
+
+typedef struct JSWatchPoint {
+    JSCList             links;
+    JSObject            *object;        /* weak link, see js_FinalizeObject */
+    JSScopeProperty     *sprop;
+    JSPropertyOp        setter;
+    JSWatchPointHandler handler;
+    void                *closure;
+    jsrefcount          nrefs;
+} JSWatchPoint;
+
+#define HoldWatchPoint(wp) ((wp)->nrefs++)
+
+static JSBool
+DropWatchPoint(JSContext *cx, JSWatchPoint *wp)
+{
+    JSScopeProperty *sprop;
+
+    if (--wp->nrefs != 0)
+        return JS_TRUE;
+
+    /*
+     * Remove wp from the list, then if there are no other watchpoints for
+     * wp->sprop in any scope, restore wp->sprop->setter from wp.
+     */
+    JS_REMOVE_LINK(&wp->links);
+    sprop = wp->sprop;
+    if (!js_GetWatchedSetter(cx->runtime, NULL, sprop)) {
+        sprop = js_ChangeNativePropertyAttrs(cx, wp->object, sprop,
+                                             0, sprop->attrs,
+                                             sprop->getter, wp->setter);
+        if (!sprop)
+            return JS_FALSE;
+    }
+    js_RemoveRoot(cx->runtime, &wp->closure);
+    JS_free(cx, wp);
+    return JS_TRUE;
+}
+
+void
+js_MarkWatchPoints(JSRuntime *rt)
+{
+    JSWatchPoint *wp;
+
+    for (wp = (JSWatchPoint *)rt->watchPointList.next;
+         wp != (JSWatchPoint *)&rt->watchPointList;
+         wp = (JSWatchPoint *)wp->links.next) {
+        MARK_SCOPE_PROPERTY(wp->sprop);
+    }
+}
+
+static JSWatchPoint *
+FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id)
+{
+    JSWatchPoint *wp;
+
+    for (wp = (JSWatchPoint *)rt->watchPointList.next;
+         wp != (JSWatchPoint *)&rt->watchPointList;
+         wp = (JSWatchPoint *)wp->links.next) {
+        if (wp->object == scope->object && wp->sprop->id == id)
+            return wp;
+    }
+    return NULL;
+}
+
+JSScopeProperty *
+js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id)
+{
+    JSWatchPoint *wp;
+
+    wp = FindWatchPoint(rt, scope, id);
+    if (!wp)
+        return NULL;
+    return wp->sprop;
+}
+
+JSPropertyOp
+js_GetWatchedSetter(JSRuntime *rt, JSScope *scope,
+                    const JSScopeProperty *sprop)
+{
+    JSWatchPoint *wp;
+
+    for (wp = (JSWatchPoint *)rt->watchPointList.next;
+         wp != (JSWatchPoint *)&rt->watchPointList;
+         wp = (JSWatchPoint *)wp->links.next) {
+        if ((!scope || wp->object == scope->object) && wp->sprop == sprop)
+            return wp->setter;
+    }
+    return NULL;
+}
+
+JSBool JS_DLL_CALLBACK
+js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSRuntime *rt;
+    JSWatchPoint *wp;
+    JSScopeProperty *sprop;
+    jsval propid, userid;
+    JSScope *scope;
+    JSBool ok;
+
+    rt = cx->runtime;
+    for (wp = (JSWatchPoint *)rt->watchPointList.next;
+         wp != (JSWatchPoint *)&rt->watchPointList;
+         wp = (JSWatchPoint *)wp->links.next) {
+        sprop = wp->sprop;
+        if (wp->object == obj && SPROP_USERID(sprop) == id) {
+            JS_LOCK_OBJ(cx, obj);
+            propid = ID_TO_VALUE(sprop->id);
+            userid = (sprop->flags & SPROP_HAS_SHORTID)
+                     ? INT_TO_JSVAL(sprop->shortid)
+                     : propid;
+            scope = OBJ_SCOPE(obj);
+            JS_UNLOCK_OBJ(cx, obj);
+            HoldWatchPoint(wp);
+            ok = wp->handler(cx, obj, propid,
+                             SPROP_HAS_VALID_SLOT(sprop, scope)
+                             ? OBJ_GET_SLOT(cx, obj, wp->sprop->slot)
+                             : JSVAL_VOID,
+                             vp, wp->closure);
+            if (ok) {
+                /*
+                 * Create pseudo-frame for call to setter so that any
+                 * stack-walking security code in the setter will correctly
+                 * identify the guilty party.
+                 */
+                JSObject *funobj = (JSObject *) wp->closure;
+                JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, funobj);
+                JSStackFrame frame;
+
+                memset(&frame, 0, sizeof(frame));
+                frame.script = FUN_SCRIPT(fun);
+                frame.fun = fun;
+                frame.down = cx->fp;
+                cx->fp = &frame;
+                ok = !wp->setter ||
+                     ((sprop->attrs & JSPROP_SETTER)
+                      ? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(wp->setter),
+                                        1, vp, vp)
+                      : wp->setter(cx, OBJ_THIS_OBJECT(cx, obj), userid, vp));
+                cx->fp = frame.down;
+            }
+            return DropWatchPoint(cx, wp);
+        }
+    }
+    JS_ASSERT(0);       /* XXX can't happen */
+    return JS_FALSE;
+}
+
+JSBool JS_DLL_CALLBACK
+js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                     jsval *rval)
+{
+    JSObject *funobj;
+    JSFunction *wrapper;
+    jsval userid;
+
+    funobj = JSVAL_TO_OBJECT(argv[-2]);
+    wrapper = (JSFunction *) JS_GetPrivate(cx, funobj);
+    userid = ATOM_KEY(wrapper->atom);
+    *rval = argv[0];
+    return js_watch_set(cx, obj, userid, rval);
+}
+
+JSPropertyOp
+js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter)
+{
+    JSAtom *atom;
+    JSFunction *wrapper;
+
+    if (!(attrs & JSPROP_SETTER))
+        return &js_watch_set;   /* & to silence schoolmarmish MSVC */
+
+    if (JSID_IS_ATOM(id)) {
+        atom = JSID_TO_ATOM(id);
+    } else if (JSID_IS_INT(id)) {
+        atom = js_AtomizeInt(cx, JSID_TO_INT(id), 0);
+        if (!atom)
+            return NULL;
+    } else {
+        atom = NULL;
+    }
+    wrapper = js_NewFunction(cx, NULL, js_watch_set_wrapper, 1, 0,
+                             OBJ_GET_PARENT(cx, (JSObject *)setter),
+                             atom);
+    if (!wrapper)
+        return NULL;
+    return (JSPropertyOp) wrapper->object;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
+                 JSWatchPointHandler handler, void *closure)
+{
+    JSAtom *atom;
+    jsid propid;
+    JSObject *pobj;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+    JSRuntime *rt;
+    JSBool ok;
+    JSWatchPoint *wp;
+    JSPropertyOp watcher;
+
+    if (!OBJ_IS_NATIVE(obj)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH,
+                             OBJ_GET_CLASS(cx, obj)->name);
+        return JS_FALSE;
+    }
+
+    if (JSVAL_IS_INT(id)) {
+        propid = INT_JSVAL_TO_JSID(id);
+        atom = NULL;
+    } else {
+        atom = js_ValueToStringAtom(cx, id);
+        if (!atom)
+            return JS_FALSE;
+        propid = ATOM_TO_JSID(atom);
+    }
+
+    if (!js_LookupProperty(cx, obj, propid, &pobj, &prop))
+        return JS_FALSE;
+    sprop = (JSScopeProperty *) prop;
+    rt = cx->runtime;
+    if (!sprop) {
+        /* Check for a deleted symbol watchpoint, which holds its property. */
+        sprop = js_FindWatchPoint(rt, OBJ_SCOPE(obj), propid);
+        if (!sprop) {
+            /* Make a new property in obj so we can watch for the first set. */
+            if (!js_DefineProperty(cx, obj, propid, JSVAL_VOID,
+                                   NULL, NULL, JSPROP_ENUMERATE,
+                                   &prop)) {
+                return JS_FALSE;
+            }
+            sprop = (JSScopeProperty *) prop;
+        }
+    } else if (pobj != obj) {
+        /* Clone the prototype property so we can watch the right object. */
+        jsval value;
+        JSPropertyOp getter, setter;
+        uintN attrs, flags;
+        intN shortid;
+
+        if (OBJ_IS_NATIVE(pobj)) {
+            value = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj))
+                    ? LOCKED_OBJ_GET_SLOT(pobj, sprop->slot)
+                    : JSVAL_VOID;
+            getter = sprop->getter;
+            setter = sprop->setter;
+            attrs = sprop->attrs;
+            flags = sprop->flags;
+            shortid = sprop->shortid;
+        } else {
+            if (!OBJ_GET_PROPERTY(cx, pobj, id, &value) ||
+                !OBJ_GET_ATTRIBUTES(cx, pobj, id, prop, &attrs)) {
+                OBJ_DROP_PROPERTY(cx, pobj, prop);
+                return JS_FALSE;
+            }
+            getter = setter = NULL;
+            flags = 0;
+            shortid = 0;
+        }
+        OBJ_DROP_PROPERTY(cx, pobj, prop);
+
+        /* Recall that obj is native, whether or not pobj is native. */
+        if (!js_DefineNativeProperty(cx, obj, propid, value, getter, setter,
+                                     attrs, flags, shortid, &prop)) {
+            return JS_FALSE;
+        }
+        sprop = (JSScopeProperty *) prop;
+    }
+
+    /*
+     * At this point, prop/sprop exists in obj, obj is locked, and we must
+     * OBJ_DROP_PROPERTY(cx, obj, prop) before returning.
+     */
+    ok = JS_TRUE;
+    wp = FindWatchPoint(rt, OBJ_SCOPE(obj), propid);
+    if (!wp) {
+        watcher = js_WrapWatchedSetter(cx, propid, sprop->attrs, sprop->setter);
+        if (!watcher) {
+            ok = JS_FALSE;
+            goto out;
+        }
+
+        wp = (JSWatchPoint *) JS_malloc(cx, sizeof *wp);
+        if (!wp) {
+            ok = JS_FALSE;
+            goto out;
+        }
+        wp->handler = NULL;
+        wp->closure = NULL;
+        ok = js_AddRoot(cx, &wp->closure, "wp->closure");
+        if (!ok) {
+            JS_free(cx, wp);
+            goto out;
+        }
+        JS_APPEND_LINK(&wp->links, &rt->watchPointList);
+        wp->object = obj;
+        wp->sprop = sprop;
+        JS_ASSERT(sprop->setter != js_watch_set);
+        wp->setter = sprop->setter;
+        wp->nrefs = 1;
+
+        /* XXXbe nest in obj lock here */
+        sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop, 0, sprop->attrs,
+                                             sprop->getter, watcher);
+        if (!sprop) {
+            DropWatchPoint(cx, wp);
+            ok = JS_FALSE;
+            goto out;
+        }
+    }
+    wp->handler = handler;
+    wp->closure = closure;
+
+out:
+    OBJ_DROP_PROPERTY(cx, obj, prop);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsval id,
+                   JSWatchPointHandler *handlerp, void **closurep)
+{
+    JSRuntime *rt;
+    JSWatchPoint *wp;
+
+    rt = cx->runtime;
+    for (wp = (JSWatchPoint *)rt->watchPointList.next;
+         wp != (JSWatchPoint *)&rt->watchPointList;
+         wp = (JSWatchPoint *)wp->links.next) {
+        if (wp->object == obj && SPROP_USERID(wp->sprop) == id) {
+            if (handlerp)
+                *handlerp = wp->handler;
+            if (closurep)
+                *closurep = wp->closure;
+            return DropWatchPoint(cx, wp);
+        }
+    }
+    if (handlerp)
+        *handlerp = NULL;
+    if (closurep)
+        *closurep = NULL;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj)
+{
+    JSRuntime *rt;
+    JSWatchPoint *wp, *next;
+
+    rt = cx->runtime;
+    for (wp = (JSWatchPoint *)rt->watchPointList.next;
+         wp != (JSWatchPoint *)&rt->watchPointList;
+         wp = next) {
+        next = (JSWatchPoint *)wp->links.next;
+        if (wp->object == obj && !DropWatchPoint(cx, wp))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_ClearAllWatchPoints(JSContext *cx)
+{
+    JSRuntime *rt;
+    JSWatchPoint *wp, *next;
+
+    rt = cx->runtime;
+    for (wp = (JSWatchPoint *)rt->watchPointList.next;
+         wp != (JSWatchPoint *)&rt->watchPointList;
+         wp = next) {
+        next = (JSWatchPoint *)wp->links.next;
+        if (!DropWatchPoint(cx, wp))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+/************************************************************************/
+
+JS_PUBLIC_API(uintN)
+JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
+{
+    return js_PCToLineNumber(cx, script, pc);
+}
+
+JS_PUBLIC_API(jsbytecode *)
+JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno)
+{
+    return js_LineNumberToPC(script, lineno);
+}
+
+JS_PUBLIC_API(JSScript *)
+JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
+{
+    return FUN_SCRIPT(fun);
+}
+
+JS_PUBLIC_API(JSNative)
+JS_GetFunctionNative(JSContext *cx, JSFunction *fun)
+{
+    return FUN_NATIVE(fun);
+}
+
+JS_PUBLIC_API(JSPrincipals *)
+JS_GetScriptPrincipals(JSContext *cx, JSScript *script)
+{
+    return script->principals;
+}
+
+/************************************************************************/
+
+/*
+ *  Stack Frame Iterator
+ */
+JS_PUBLIC_API(JSStackFrame *)
+JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp)
+{
+    *iteratorp = (*iteratorp == NULL) ? cx->fp : (*iteratorp)->down;
+    return *iteratorp;
+}
+
+JS_PUBLIC_API(JSScript *)
+JS_GetFrameScript(JSContext *cx, JSStackFrame *fp)
+{
+    return fp->script;
+}
+
+JS_PUBLIC_API(jsbytecode *)
+JS_GetFramePC(JSContext *cx, JSStackFrame *fp)
+{
+    return fp->pc;
+}
+
+JS_PUBLIC_API(JSStackFrame *)
+JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp)
+{
+    if (!fp)
+        fp = cx->fp;
+    while ((fp = fp->down) != NULL) {
+        if (fp->script)
+            return fp;
+    }
+    return NULL;
+}
+
+JS_PUBLIC_API(JSPrincipals *)
+JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp)
+{
+    if (fp->fun) {
+        JSRuntime *rt = cx->runtime;
+
+        if (rt->findObjectPrincipals) {
+            JSObject *callee = JSVAL_TO_OBJECT(fp->argv[-2]);
+
+            if (fp->fun->object != callee)
+                return rt->findObjectPrincipals(cx, callee);
+            /* FALL THROUGH */
+        }
+    }
+    if (fp->script)
+        return fp->script->principals;
+    return NULL;
+}
+
+JS_PUBLIC_API(JSPrincipals *)
+JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller)
+{
+    JSRuntime *rt;
+    JSObject *callee;
+    JSPrincipals *principals, *callerPrincipals;
+
+    rt = cx->runtime;
+    if (rt->findObjectPrincipals) {
+        callee = JSVAL_TO_OBJECT(fp->argv[-2]);
+        principals = rt->findObjectPrincipals(cx, callee);
+    } else {
+        principals = NULL;
+    }
+    if (!caller)
+        return principals;
+    callerPrincipals = JS_StackFramePrincipals(cx, caller);
+    return (callerPrincipals && principals &&
+            callerPrincipals->subsume(callerPrincipals, principals))
+           ? principals
+           : callerPrincipals;
+}
+
+JS_PUBLIC_API(void *)
+JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp)
+{
+    if (fp->annotation && fp->script) {
+        JSPrincipals *principals = JS_StackFramePrincipals(cx, fp);
+
+        if (principals && principals->globalPrivilegesEnabled(cx, principals)) {
+            /*
+             * Give out an annotation only if privileges have not been revoked
+             * or disabled globally.
+             */
+            return fp->annotation;
+        }
+    }
+
+    return NULL;
+}
+
+JS_PUBLIC_API(void)
+JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation)
+{
+    fp->annotation = annotation;
+}
+
+JS_PUBLIC_API(void *)
+JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp)
+{
+    JSPrincipals *principals;
+
+    principals = JS_StackFramePrincipals(cx, fp);
+    if (!principals)
+        return NULL;
+    return principals->getPrincipalArray(cx, principals);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp)
+{
+    return !fp->script;
+}
+
+/* this is deprecated, use JS_GetFrameScopeChain instead */
+JS_PUBLIC_API(JSObject *)
+JS_GetFrameObject(JSContext *cx, JSStackFrame *fp)
+{
+    return fp->scopeChain;
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp)
+{
+    /* Force creation of argument and call objects if not yet created */
+    (void) JS_GetFrameCallObject(cx, fp);
+    return fp->scopeChain;
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp)
+{
+    if (! fp->fun)
+        return NULL;
+#if JS_HAS_ARGS_OBJECT
+    /* Force creation of argument object if not yet created */
+    (void) js_GetArgsObject(cx, fp);
+#endif
+#if JS_HAS_CALL_OBJECT
+    /*
+     * XXX ill-defined: null return here means error was reported, unlike a
+     *     null returned above or in the #else
+     */
+    return js_GetCallObject(cx, fp, NULL);
+#else
+    return NULL;
+#endif /* JS_HAS_CALL_OBJECT */
+}
+
+
+JS_PUBLIC_API(JSObject *)
+JS_GetFrameThis(JSContext *cx, JSStackFrame *fp)
+{
+    return fp->thisp;
+}
+
+JS_PUBLIC_API(JSFunction *)
+JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp)
+{
+    return fp->fun;
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp)
+{
+    return fp->argv && fp->fun ? JSVAL_TO_OBJECT(fp->argv[-2]) : NULL;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_IsConstructorFrame(JSContext *cx, JSStackFrame *fp)
+{
+    return (fp->flags & JSFRAME_CONSTRUCTING) != 0;
+}
+
+JS_PUBLIC_API(JSObject *)
+JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp)
+{
+    return fp->argv ? JSVAL_TO_OBJECT(fp->argv[-2]) : NULL;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp)
+{
+    return (fp->flags & JSFRAME_DEBUGGER) != 0;
+}
+
+JS_PUBLIC_API(jsval)
+JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp)
+{
+    return fp->rval;
+}
+
+JS_PUBLIC_API(void)
+JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval)
+{
+    fp->rval = rval;
+}
+
+/************************************************************************/
+
+JS_PUBLIC_API(const char *)
+JS_GetScriptFilename(JSContext *cx, JSScript *script)
+{
+    return script->filename;
+}
+
+JS_PUBLIC_API(uintN)
+JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script)
+{
+    return script->lineno;
+}
+
+JS_PUBLIC_API(uintN)
+JS_GetScriptLineExtent(JSContext *cx, JSScript *script)
+{
+    return js_GetScriptLineExtent(script);
+}
+
+JS_PUBLIC_API(JSVersion)
+JS_GetScriptVersion(JSContext *cx, JSScript *script)
+{
+    return script->version & JSVERSION_MASK;
+}
+
+/***************************************************************************/
+
+JS_PUBLIC_API(void)
+JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata)
+{
+    rt->newScriptHook = hook;
+    rt->newScriptHookData = callerdata;
+}
+
+JS_PUBLIC_API(void)
+JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
+                        void *callerdata)
+{
+    rt->destroyScriptHook = hook;
+    rt->destroyScriptHookData = callerdata;
+}
+
+/***************************************************************************/
+
+JS_PUBLIC_API(JSBool)
+JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
+                          const jschar *bytes, uintN length,
+                          const char *filename, uintN lineno,
+                          jsval *rval)
+{
+    uint32 flags, options;
+    JSScript *script;
+    JSBool ok;
+
+    /*
+     * XXX Hack around ancient compiler API to propagate the JSFRAME_SPECIAL
+     * flags to the code generator (see js_EmitTree's TOK_SEMI case).
+     */
+    flags = fp->flags;
+    fp->flags |= JSFRAME_DEBUGGER | JSFRAME_EVAL;
+    options = cx->options;
+    cx->options = options | JSOPTION_COMPILE_N_GO;
+    script = JS_CompileUCScriptForPrincipals(cx, fp->scopeChain,
+                                             JS_StackFramePrincipals(cx, fp),
+                                             bytes, length, filename, lineno);
+    fp->flags = flags;
+    cx->options = options;
+    if (!script)
+        return JS_FALSE;
+
+    ok = js_Execute(cx, fp->scopeChain, script, fp,
+                    JSFRAME_DEBUGGER | JSFRAME_EVAL, rval);
+    js_DestroyScript(cx, script);
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
+                        const char *bytes, uintN length,
+                        const char *filename, uintN lineno,
+                        jsval *rval)
+{
+    jschar *chars;
+    JSBool ok;
+
+    chars = js_InflateString(cx, bytes, &length);
+    if (!chars)
+        return JS_FALSE;
+    ok = JS_EvaluateUCInStackFrame(cx, fp, chars, length, filename, lineno,
+                                   rval);
+    JS_free(cx, chars);
+
+    return ok;
+}
+
+/************************************************************************/
+
+/* XXXbe this all needs to be reworked to avoid requiring JSScope types. */
+
+JS_PUBLIC_API(JSScopeProperty *)
+JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp)
+{
+    JSScopeProperty *sprop;
+    JSScope *scope;
+
+    sprop = *iteratorp;
+    scope = OBJ_SCOPE(obj);
+
+    /* XXXbe minor(?) incompatibility: iterate in reverse definition order */
+    if (!sprop) {
+        sprop = SCOPE_LAST_PROP(scope);
+    } else {
+        while ((sprop = sprop->parent) != NULL) {
+            if (!SCOPE_HAD_MIDDLE_DELETE(scope))
+                break;
+            if (SCOPE_HAS_PROPERTY(scope, sprop))
+                break;
+        }
+    }
+    *iteratorp = sprop;
+    return sprop;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
+                   JSPropertyDesc *pd)
+{
+    JSPropertyOp getter;
+    JSScope *scope;
+    JSScopeProperty *aprop;
+    jsval lastException;
+    JSBool wasThrowing;
+
+    pd->id = ID_TO_VALUE(sprop->id);
+
+    wasThrowing = cx->throwing;
+    if (wasThrowing) {
+        lastException = cx->exception;
+        if (JSVAL_IS_GCTHING(lastException) &&
+            !js_AddRoot(cx, &lastException, "lastException")) {
+                return JS_FALSE;
+        }
+        cx->throwing = JS_FALSE;
+    }
+
+    if (!js_GetProperty(cx, obj, sprop->id, &pd->value)) {
+        if (!cx->throwing) {
+            pd->flags = JSPD_ERROR;
+            pd->value = JSVAL_VOID;
+        } else {
+            pd->flags = JSPD_EXCEPTION;
+            pd->value = cx->exception;
+        }
+    } else {
+        pd->flags = 0;
+    }
+
+    cx->throwing = wasThrowing;
+    if (wasThrowing) {
+        cx->exception = lastException;
+        if (JSVAL_IS_GCTHING(lastException))
+            js_RemoveRoot(cx->runtime, &lastException);
+    }
+
+    getter = sprop->getter;
+    pd->flags |= ((sprop->attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0)
+              | ((sprop->attrs & JSPROP_READONLY)  ? JSPD_READONLY  : 0)
+              | ((sprop->attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0)
+#if JS_HAS_CALL_OBJECT
+              | ((getter == js_GetCallVariable)    ? JSPD_VARIABLE  : 0)
+#endif /* JS_HAS_CALL_OBJECT */
+              | ((getter == js_GetArgument)        ? JSPD_ARGUMENT  : 0)
+              | ((getter == js_GetLocalVariable)   ? JSPD_VARIABLE  : 0);
+#if JS_HAS_CALL_OBJECT
+    /* for Call Object 'real' getter isn't passed in to us */
+    if (OBJ_GET_CLASS(cx, obj) == &js_CallClass &&
+        getter == js_CallClass.getProperty) {
+        /*
+         * Property of a heavyweight function's variable object having the
+         * class-default getter.  It's either an argument if permanent, or a
+         * nested function if impermanent.  Local variables have a special
+         * getter (js_GetCallVariable, tested above) and setter, and not the
+         * class default.
+         */
+        pd->flags |= (sprop->attrs & JSPROP_PERMANENT)
+                     ? JSPD_ARGUMENT
+                     : JSPD_VARIABLE;
+    }
+#endif /* JS_HAS_CALL_OBJECT */
+    pd->spare = 0;
+    pd->slot = (pd->flags & (JSPD_ARGUMENT | JSPD_VARIABLE))
+               ? sprop->shortid
+               : 0;
+    pd->alias = JSVAL_VOID;
+    scope = OBJ_SCOPE(obj);
+    if (SPROP_HAS_VALID_SLOT(sprop, scope)) {
+        for (aprop = SCOPE_LAST_PROP(scope); aprop; aprop = aprop->parent) {
+            if (aprop != sprop && aprop->slot == sprop->slot) {
+                pd->alias = ID_TO_VALUE(aprop->id);
+                break;
+            }
+        }
+    }
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
+{
+    JSClass *clasp;
+    JSScope *scope;
+    uint32 i, n;
+    JSPropertyDesc *pd;
+    JSScopeProperty *sprop;
+
+    clasp = OBJ_GET_CLASS(cx, obj);
+    if (!OBJ_IS_NATIVE(obj) || (clasp->flags & JSCLASS_NEW_ENUMERATE)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_CANT_DESCRIBE_PROPS, clasp->name);
+        return JS_FALSE;
+    }
+    if (!clasp->enumerate(cx, obj))
+        return JS_FALSE;
+
+    /* have no props, or object's scope has not mutated from that of proto */
+    scope = OBJ_SCOPE(obj);
+    if (scope->object != obj || scope->entryCount == 0) {
+        pda->length = 0;
+        pda->array = NULL;
+        return JS_TRUE;
+    }
+
+    n = scope->entryCount;
+    if (n > scope->map.nslots)
+        n = scope->map.nslots;
+    pd = (JSPropertyDesc *) JS_malloc(cx, (size_t)n * sizeof(JSPropertyDesc));
+    if (!pd)
+        return JS_FALSE;
+    i = 0;
+    for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
+        if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop))
+            continue;
+        if (!js_AddRoot(cx, &pd[i].id, NULL))
+            goto bad;
+        if (!js_AddRoot(cx, &pd[i].value, NULL))
+            goto bad;
+        if (!JS_GetPropertyDesc(cx, obj, sprop, &pd[i]))
+            goto bad;
+        if ((pd[i].flags & JSPD_ALIAS) && !js_AddRoot(cx, &pd[i].alias, NULL))
+            goto bad;
+        if (++i == n)
+            break;
+    }
+    pda->length = i;
+    pda->array = pd;
+    return JS_TRUE;
+
+bad:
+    pda->length = i + 1;
+    pda->array = pd;
+    JS_PutPropertyDescArray(cx, pda);
+    return JS_FALSE;
+}
+
+JS_PUBLIC_API(void)
+JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda)
+{
+    JSPropertyDesc *pd;
+    uint32 i;
+
+    pd = pda->array;
+    for (i = 0; i < pda->length; i++) {
+        js_RemoveRoot(cx->runtime, &pd[i].id);
+        js_RemoveRoot(cx->runtime, &pd[i].value);
+        if (pd[i].flags & JSPD_ALIAS)
+            js_RemoveRoot(cx->runtime, &pd[i].alias);
+    }
+    JS_free(cx, pd);
+}
+
+/************************************************************************/
+
+JS_PUBLIC_API(JSBool)
+JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure)
+{
+    rt->debuggerHandler = handler;
+    rt->debuggerHandlerData = closure;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure)
+{
+    rt->sourceHandler = handler;
+    rt->sourceHandlerData = closure;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
+{
+    rt->executeHook = hook;
+    rt->executeHookData = closure;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
+{
+    rt->callHook = hook;
+    rt->callHookData = closure;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure)
+{
+    rt->objectHook = hook;
+    rt->objectHookData = closure;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure)
+{
+    rt->throwHook = hook;
+    rt->throwHookData = closure;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure)
+{
+    rt->debugErrorHook = hook;
+    rt->debugErrorHookData = closure;
+    return JS_TRUE;
+}
+
+/************************************************************************/
+
+JS_PUBLIC_API(size_t)
+JS_GetObjectTotalSize(JSContext *cx, JSObject *obj)
+{
+    size_t nbytes;
+    JSScope *scope;
+
+    nbytes = sizeof *obj + obj->map->nslots * sizeof obj->slots[0];
+    if (OBJ_IS_NATIVE(obj)) {
+        scope = OBJ_SCOPE(obj);
+        if (scope->object == obj) {
+            nbytes += sizeof *scope;
+            nbytes += SCOPE_CAPACITY(scope) * sizeof(JSScopeProperty *);
+        }
+    }
+    return nbytes;
+}
+
+static size_t
+GetAtomTotalSize(JSContext *cx, JSAtom *atom)
+{
+    size_t nbytes;
+
+    nbytes = sizeof *atom;
+    if (ATOM_IS_STRING(atom)) {
+        nbytes += sizeof(JSString);
+        nbytes += (ATOM_TO_STRING(atom)->length + 1) * sizeof(jschar);
+    } else if (ATOM_IS_DOUBLE(atom)) {
+        nbytes += sizeof(jsdouble);
+    } else if (ATOM_IS_OBJECT(atom)) {
+        nbytes += JS_GetObjectTotalSize(cx, ATOM_TO_OBJECT(atom));
+    }
+    return nbytes;
+}
+
+JS_PUBLIC_API(size_t)
+JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun)
+{
+    size_t nbytes, obytes;
+    JSObject *obj;
+    JSAtom *atom;
+
+    nbytes = sizeof *fun;
+    JS_ASSERT(fun->nrefs);
+    obj = fun->object;
+    if (obj) {
+        obytes = JS_GetObjectTotalSize(cx, obj);
+        if (fun->nrefs > 1)
+            obytes = JS_HOWMANY(obytes, fun->nrefs);
+        nbytes += obytes;
+    }
+    if (fun->interpreted)
+        nbytes += JS_GetScriptTotalSize(cx, fun->u.script);
+    atom = fun->atom;
+    if (atom)
+        nbytes += GetAtomTotalSize(cx, atom);
+    return nbytes;
+}
+
+#include "jsemit.h"
+
+JS_PUBLIC_API(size_t)
+JS_GetScriptTotalSize(JSContext *cx, JSScript *script)
+{
+    size_t nbytes, pbytes;
+    JSObject *obj;
+    jsatomid i;
+    jssrcnote *sn, *notes;
+    JSTryNote *tn, *tnotes;
+    JSPrincipals *principals;
+
+    nbytes = sizeof *script;
+    obj = script->object;
+    if (obj)
+        nbytes += JS_GetObjectTotalSize(cx, obj);
+
+    nbytes += script->length * sizeof script->code[0];
+    nbytes += script->atomMap.length * sizeof script->atomMap.vector[0];
+    for (i = 0; i < script->atomMap.length; i++)
+        nbytes += GetAtomTotalSize(cx, script->atomMap.vector[i]);
+
+    if (script->filename)
+        nbytes += strlen(script->filename) + 1;
+
+    notes = SCRIPT_NOTES(script);
+    for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
+        continue;
+    nbytes += (sn - notes + 1) * sizeof *sn;
+
+    tnotes = script->trynotes;
+    if (tnotes) {
+        for (tn = tnotes; tn->catchStart; tn++)
+            continue;
+        nbytes += (tn - tnotes + 1) * sizeof *tn;
+    }
+
+    principals = script->principals;
+    if (principals) {
+        JS_ASSERT(principals->refcount);
+        pbytes = sizeof *principals;
+        if (principals->refcount > 1)
+            pbytes = JS_HOWMANY(pbytes, principals->refcount);
+        nbytes += pbytes;
+    }
+
+    return nbytes;
+}
+
+JS_PUBLIC_API(uint32)
+JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp)
+{
+    if (!fp)
+        fp = cx->fp;
+    while (fp) {
+        if (fp->script) {
+            if (!fp->script->filename)
+                return JSFILENAME_NULL;
+            return js_GetScriptFilenameFlags(fp->script->filename);
+        }
+        fp = fp->down;
+    }
+    return 0;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_FlagScriptFilenamePrefix(JSRuntime *rt, const char *prefix, uint32 flags)
+{
+    if (!js_SaveScriptFilenameRT(rt, prefix, flags))
+        return JS_FALSE;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_IsSystemObject(JSContext *cx, JSObject *obj)
+{
+    return (*js_GetGCThingFlags(obj) & GCF_SYSTEM) != 0;
+}
+
+JS_PUBLIC_API(void)
+JS_FlagSystemObject(JSContext *cx, JSObject *obj)
+{
+    uint8 *flagp;
+    
+    flagp = js_GetGCThingFlags(obj);
+    *flagp |= GCF_SYSTEM;
+}

Added: freeswitch/trunk/libs/js/src/jsdbgapi.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsdbgapi.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,399 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsdbgapi_h___
+#define jsdbgapi_h___
+/*
+ * JS debugger API.
+ */
+#include "jsapi.h"
+#include "jsopcode.h"
+#include "jsprvtd.h"
+
+JS_BEGIN_EXTERN_C
+
+extern void
+js_PatchOpcode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
+           JSTrapHandler handler, void *closure);
+
+extern JS_PUBLIC_API(JSOp)
+JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc);
+
+extern JS_PUBLIC_API(void)
+JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
+             JSTrapHandler *handlerp, void **closurep);
+
+extern JS_PUBLIC_API(void)
+JS_ClearScriptTraps(JSContext *cx, JSScript *script);
+
+extern JS_PUBLIC_API(void)
+JS_ClearAllTraps(JSContext *cx);
+
+extern JS_PUBLIC_API(JSTrapStatus)
+JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep);
+
+/************************************************************************/
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
+                 JSWatchPointHandler handler, void *closure);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsval id,
+                   JSWatchPointHandler *handlerp, void **closurep);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj);
+
+extern JS_PUBLIC_API(JSBool)
+JS_ClearAllWatchPoints(JSContext *cx);
+
+#ifdef JS_HAS_OBJ_WATCHPOINT
+/*
+ * Hide these non-API function prototypes by testing whether the internal
+ * header file "jsconfig.h" has been included.
+ */
+extern void
+js_MarkWatchPoints(JSRuntime *rt);
+
+extern JSScopeProperty *
+js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id);
+
+extern JSPropertyOp
+js_GetWatchedSetter(JSRuntime *rt, JSScope *scope,
+                    const JSScopeProperty *sprop);
+
+extern JSBool JS_DLL_CALLBACK
+js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+extern JSBool JS_DLL_CALLBACK
+js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                     jsval *rval);
+
+extern JSPropertyOp
+js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter);
+
+#endif /* JS_HAS_OBJ_WATCHPOINT */
+
+/************************************************************************/
+
+extern JS_PUBLIC_API(uintN)
+JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
+
+extern JS_PUBLIC_API(jsbytecode *)
+JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno);
+
+extern JS_PUBLIC_API(JSScript *)
+JS_GetFunctionScript(JSContext *cx, JSFunction *fun);
+
+extern JS_PUBLIC_API(JSNative)
+JS_GetFunctionNative(JSContext *cx, JSFunction *fun);
+
+extern JS_PUBLIC_API(JSPrincipals *)
+JS_GetScriptPrincipals(JSContext *cx, JSScript *script);
+
+/*
+ * Stack Frame Iterator
+ *
+ * Used to iterate through the JS stack frames to extract
+ * information from the frames.
+ */
+
+extern JS_PUBLIC_API(JSStackFrame *)
+JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp);
+
+extern JS_PUBLIC_API(JSScript *)
+JS_GetFrameScript(JSContext *cx, JSStackFrame *fp);
+
+extern JS_PUBLIC_API(jsbytecode *)
+JS_GetFramePC(JSContext *cx, JSStackFrame *fp);
+
+/*
+ * Get the closest scripted frame below fp.  If fp is null, start from cx->fp.
+ */
+extern JS_PUBLIC_API(JSStackFrame *)
+JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp);
+
+/*
+ * Return a weak reference to fp's principals.  A null return does not denote
+ * an error, it means there are no principals.
+ */
+extern JS_PUBLIC_API(JSPrincipals *)
+JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp);
+
+/*
+ * This API is like JS_StackFramePrincipals(cx, caller), except that if
+ * cx->runtime->findObjectPrincipals is non-null, it returns the weaker of
+ * the caller's principals and the object principals of fp's callee function
+ * object (fp->argv[-2]), which is eval, Function, or a similar eval-like
+ * method.  The caller parameter should be JS_GetScriptedCaller(cx, fp).
+ *
+ * All eval-like methods must use JS_EvalFramePrincipals to acquire a weak
+ * reference to the correct principals for the eval call to be secure, given
+ * an embedding that calls JS_SetObjectPrincipalsFinder (see jsapi.h).
+ */
+extern JS_PUBLIC_API(JSPrincipals *)
+JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller);
+
+extern JS_PUBLIC_API(void *)
+JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp);
+
+extern JS_PUBLIC_API(void)
+JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation);
+
+extern JS_PUBLIC_API(void *)
+JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp);
+
+/* this is deprecated, use JS_GetFrameScopeChain instead */
+extern JS_PUBLIC_API(JSObject *)
+JS_GetFrameObject(JSContext *cx, JSStackFrame *fp);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_GetFrameThis(JSContext *cx, JSStackFrame *fp);
+
+extern JS_PUBLIC_API(JSFunction *)
+JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp);
+
+extern JS_PUBLIC_API(JSObject *)
+JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp);
+
+/* XXXrginda Initially published with typo */
+#define JS_IsContructorFrame JS_IsConstructorFrame
+extern JS_PUBLIC_API(JSBool)
+JS_IsConstructorFrame(JSContext *cx, JSStackFrame *fp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp);
+
+extern JS_PUBLIC_API(jsval)
+JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp);
+
+extern JS_PUBLIC_API(void)
+JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval);
+
+/**
+ * Return fp's callee function object (fp->argv[-2]) if it has one.
+ */
+extern JS_PUBLIC_API(JSObject *)
+JS_GetFrameCalleeObject(JSContext *cx, JSStackFrame *fp);
+
+/************************************************************************/
+
+extern JS_PUBLIC_API(const char *)
+JS_GetScriptFilename(JSContext *cx, JSScript *script);
+
+extern JS_PUBLIC_API(uintN)
+JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script);
+
+extern JS_PUBLIC_API(uintN)
+JS_GetScriptLineExtent(JSContext *cx, JSScript *script);
+
+extern JS_PUBLIC_API(JSVersion)
+JS_GetScriptVersion(JSContext *cx, JSScript *script);
+
+/************************************************************************/
+
+/*
+ * Hook setters for script creation and destruction, see jsprvtd.h for the
+ * typedefs.  These macros provide binary compatibility and newer, shorter
+ * synonyms.
+ */
+#define JS_SetNewScriptHook     JS_SetNewScriptHookProc
+#define JS_SetDestroyScriptHook JS_SetDestroyScriptHookProc
+
+extern JS_PUBLIC_API(void)
+JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata);
+
+extern JS_PUBLIC_API(void)
+JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
+                        void *callerdata);
+
+/************************************************************************/
+
+extern JS_PUBLIC_API(JSBool)
+JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
+                          const jschar *bytes, uintN length,
+                          const char *filename, uintN lineno,
+                          jsval *rval);
+
+extern JS_PUBLIC_API(JSBool)
+JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
+                        const char *bytes, uintN length,
+                        const char *filename, uintN lineno,
+                        jsval *rval);
+
+/************************************************************************/
+
+typedef struct JSPropertyDesc {
+    jsval           id;         /* primary id, a string or int */
+    jsval           value;      /* property value */
+    uint8           flags;      /* flags, see below */
+    uint8           spare;      /* unused */
+    uint16          slot;       /* argument/variable slot */
+    jsval           alias;      /* alias id if JSPD_ALIAS flag */
+} JSPropertyDesc;
+
+#define JSPD_ENUMERATE  0x01    /* visible to for/in loop */
+#define JSPD_READONLY   0x02    /* assignment is error */
+#define JSPD_PERMANENT  0x04    /* property cannot be deleted */
+#define JSPD_ALIAS      0x08    /* property has an alias id */
+#define JSPD_ARGUMENT   0x10    /* argument to function */
+#define JSPD_VARIABLE   0x20    /* local variable in function */
+#define JSPD_EXCEPTION  0x40    /* exception occurred fetching the property, */
+                                /* value is exception */
+#define JSPD_ERROR      0x80    /* native getter returned JS_FALSE without */
+                                /* throwing an exception */
+
+typedef struct JSPropertyDescArray {
+    uint32          length;     /* number of elements in array */
+    JSPropertyDesc  *array;     /* alloc'd by Get, freed by Put */
+} JSPropertyDescArray;
+
+extern JS_PUBLIC_API(JSScopeProperty *)
+JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
+                   JSPropertyDesc *pd);
+
+extern JS_PUBLIC_API(JSBool)
+JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda);
+
+extern JS_PUBLIC_API(void)
+JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda);
+
+/************************************************************************/
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure);
+
+extern JS_PUBLIC_API(JSBool)
+JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure);
+
+/************************************************************************/
+
+extern JS_PUBLIC_API(size_t)
+JS_GetObjectTotalSize(JSContext *cx, JSObject *obj);
+
+extern JS_PUBLIC_API(size_t)
+JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun);
+
+extern JS_PUBLIC_API(size_t)
+JS_GetScriptTotalSize(JSContext *cx, JSScript *script);
+
+/*
+ * Get the top-most running script on cx starting from fp, or from the top of
+ * cx's frame stack if fp is null, and return its script filename flags.  If
+ * the script has a null filename member, return JSFILENAME_NULL.
+ */
+extern JS_PUBLIC_API(uint32)
+JS_GetTopScriptFilenameFlags(JSContext *cx, JSStackFrame *fp);
+
+/*
+ * Associate flags with a script filename prefix in rt, so that any subsequent
+ * script compilation will inherit those flags if the script's filename is the
+ * same as prefix, or if prefix is a substring of the script's filename.
+ *
+ * The API defines only one flag bit, JSFILENAME_SYSTEM, leaving the remaining
+ * 31 bits up to the API client to define.  The union of all 32 bits must not
+ * be a legal combination, however, in order to preserve JSFILENAME_NULL as a
+ * unique value.  API clients may depend on JSFILENAME_SYSTEM being a set bit
+ * in JSFILENAME_NULL -- a script with a null filename member is presumed to
+ * be a "system" script.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_FlagScriptFilenamePrefix(JSRuntime *rt, const char *prefix, uint32 flags);
+
+#define JSFILENAME_NULL         0xffffffff      /* null script filename */
+#define JSFILENAME_SYSTEM       0x00000001      /* "system" script, see below */
+
+/*
+ * Return true if obj is a "system" object, that is, one flagged by a prior
+ * call to JS_FlagSystemObject(cx, obj).  What "system" means is up to the API
+ * client, but it can be used to coordinate access control policies based on
+ * script filenames and their prefixes, using JS_FlagScriptFilenamePrefix and
+ * JS_GetTopScriptFilenameFlags.
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_IsSystemObject(JSContext *cx, JSObject *obj);
+
+/*
+ * Flag obj as a "system" object.  The API client can flag system objects to
+ * optimize access control checks.  The engine stores but does not interpret
+ * the per-object flag set by this call.
+ */
+extern JS_PUBLIC_API(void)
+JS_FlagSystemObject(JSContext *cx, JSObject *obj);
+
+JS_END_EXTERN_C
+
+#endif /* jsdbgapi_h___ */

Added: freeswitch/trunk/libs/js/src/jsdhash.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsdhash.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,767 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla JavaScript code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brendan Eich <brendan at mozilla.org> (Original Author)
+ *   Chris Waterson <waterson at netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Double hashing implementation.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "jsbit.h"
+#include "jsdhash.h"
+#include "jsutil.h"     /* for JS_ASSERT */
+
+#ifdef JS_DHASHMETER
+# if defined MOZILLA_CLIENT && defined DEBUG_XXXbrendan
+#  include "nsTraceMalloc.h"
+# endif
+# define METER(x)       x
+#else
+# define METER(x)       /* nothing */
+#endif
+
+JS_PUBLIC_API(void *)
+JS_DHashAllocTable(JSDHashTable *table, uint32 nbytes)
+{
+    return malloc(nbytes);
+}
+
+JS_PUBLIC_API(void)
+JS_DHashFreeTable(JSDHashTable *table, void *ptr)
+{
+    free(ptr);
+}
+
+JS_PUBLIC_API(JSDHashNumber)
+JS_DHashStringKey(JSDHashTable *table, const void *key)
+{
+    JSDHashNumber h;
+    const unsigned char *s;
+
+    h = 0;
+    for (s = key; *s != '\0'; s++)
+        h = (h >> (JS_DHASH_BITS - 4)) ^ (h << 4) ^ *s;
+    return h;
+}
+
+JS_PUBLIC_API(const void *)
+JS_DHashGetKeyStub(JSDHashTable *table, JSDHashEntryHdr *entry)
+{
+    JSDHashEntryStub *stub = (JSDHashEntryStub *)entry;
+
+    return stub->key;
+}
+
+JS_PUBLIC_API(JSDHashNumber)
+JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key)
+{
+    return (JSDHashNumber)(unsigned long)key >> 2;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DHashMatchEntryStub(JSDHashTable *table,
+                       const JSDHashEntryHdr *entry,
+                       const void *key)
+{
+    const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry;
+
+    return stub->key == key;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DHashMatchStringKey(JSDHashTable *table,
+                       const JSDHashEntryHdr *entry,
+                       const void *key)
+{
+    const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry;
+
+    /* XXX tolerate null keys on account of sloppy Mozilla callers. */
+    return stub->key == key ||
+           (stub->key && key && strcmp(stub->key, key) == 0);
+}
+
+JS_PUBLIC_API(void)
+JS_DHashMoveEntryStub(JSDHashTable *table,
+                      const JSDHashEntryHdr *from,
+                      JSDHashEntryHdr *to)
+{
+    memcpy(to, from, table->entrySize);
+}
+
+JS_PUBLIC_API(void)
+JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry)
+{
+    memset(entry, 0, table->entrySize);
+}
+
+JS_PUBLIC_API(void)
+JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry)
+{
+    const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry;
+
+    free((void *) stub->key);
+    memset(entry, 0, table->entrySize);
+}
+
+JS_PUBLIC_API(void)
+JS_DHashFinalizeStub(JSDHashTable *table)
+{
+}
+
+static const JSDHashTableOps stub_ops = {
+    JS_DHashAllocTable,
+    JS_DHashFreeTable,
+    JS_DHashGetKeyStub,
+    JS_DHashVoidPtrKeyStub,
+    JS_DHashMatchEntryStub,
+    JS_DHashMoveEntryStub,
+    JS_DHashClearEntryStub,
+    JS_DHashFinalizeStub,
+    NULL
+};
+
+JS_PUBLIC_API(const JSDHashTableOps *)
+JS_DHashGetStubOps(void)
+{
+    return &stub_ops;
+}
+
+JS_PUBLIC_API(JSDHashTable *)
+JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32 entrySize,
+                 uint32 capacity)
+{
+    JSDHashTable *table;
+
+    table = (JSDHashTable *) malloc(sizeof *table);
+    if (!table)
+        return NULL;
+    if (!JS_DHashTableInit(table, ops, data, entrySize, capacity)) {
+        free(table);
+        return NULL;
+    }
+    return table;
+}
+
+JS_PUBLIC_API(void)
+JS_DHashTableDestroy(JSDHashTable *table)
+{
+    JS_DHashTableFinish(table);
+    free(table);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data,
+                  uint32 entrySize, uint32 capacity)
+{
+    int log2;
+    uint32 nbytes;
+
+#ifdef DEBUG
+    if (entrySize > 10 * sizeof(void *)) {
+        fprintf(stderr,
+                "jsdhash: for the table at address %p, the given entrySize"
+                " of %lu %s favors chaining over double hashing.\n",
+                (void *)table,
+                (unsigned long) entrySize,
+                (entrySize > 16 * sizeof(void*)) ? "definitely" : "probably");
+    }
+#endif
+
+    table->ops = ops;
+    table->data = data;
+    if (capacity < JS_DHASH_MIN_SIZE)
+        capacity = JS_DHASH_MIN_SIZE;
+
+    JS_CEILING_LOG2(log2, capacity);
+
+    capacity = JS_BIT(log2);
+    if (capacity >= JS_DHASH_SIZE_LIMIT)
+        return JS_FALSE;
+    table->hashShift = JS_DHASH_BITS - log2;
+    table->maxAlphaFrac = 0xC0;                 /* .75 */
+    table->minAlphaFrac = 0x40;                 /* .25 */
+    table->entrySize = entrySize;
+    table->entryCount = table->removedCount = 0;
+    table->generation = 0;
+    nbytes = capacity * entrySize;
+
+    table->entryStore = ops->allocTable(table, nbytes);
+    if (!table->entryStore)
+        return JS_FALSE;
+    memset(table->entryStore, 0, nbytes);
+    METER(memset(&table->stats, 0, sizeof table->stats));
+    return JS_TRUE;
+}
+
+/*
+ * Compute max and min load numbers (entry counts) from table params.
+ */
+#define MAX_LOAD(table, size)   (((table)->maxAlphaFrac * (size)) >> 8)
+#define MIN_LOAD(table, size)   (((table)->minAlphaFrac * (size)) >> 8)
+
+JS_PUBLIC_API(void)
+JS_DHashTableSetAlphaBounds(JSDHashTable *table,
+                            float maxAlpha,
+                            float minAlpha)
+{
+    uint32 size;
+
+    /*
+     * Reject obviously insane bounds, rather than trying to guess what the
+     * buggy caller intended.
+     */
+    JS_ASSERT(0.5 <= maxAlpha && maxAlpha < 1 && 0 <= minAlpha);
+    if (maxAlpha < 0.5 || 1 <= maxAlpha || minAlpha < 0)
+        return;
+
+    /*
+     * Ensure that at least one entry will always be free.  If maxAlpha at
+     * minimum size leaves no entries free, reduce maxAlpha based on minimum
+     * size and the precision limit of maxAlphaFrac's fixed point format.
+     */
+    JS_ASSERT(JS_DHASH_MIN_SIZE - (maxAlpha * JS_DHASH_MIN_SIZE) >= 1);
+    if (JS_DHASH_MIN_SIZE - (maxAlpha * JS_DHASH_MIN_SIZE) < 1) {
+        maxAlpha = (float)
+                   (JS_DHASH_MIN_SIZE - JS_MAX(JS_DHASH_MIN_SIZE / 256, 1))
+                   / JS_DHASH_MIN_SIZE;
+    }
+
+    /*
+     * Ensure that minAlpha is strictly less than half maxAlpha.  Take care
+     * not to truncate an entry's worth of alpha when storing in minAlphaFrac
+     * (8-bit fixed point format).
+     */
+    JS_ASSERT(minAlpha < maxAlpha / 2);
+    if (minAlpha >= maxAlpha / 2) {
+        size = JS_DHASH_TABLE_SIZE(table);
+        minAlpha = (size * maxAlpha - JS_MAX(size / 256, 1)) / (2 * size);
+    }
+
+    table->maxAlphaFrac = (uint8)(maxAlpha * 256);
+    table->minAlphaFrac = (uint8)(minAlpha * 256);
+}
+
+/*
+ * Double hashing needs the second hash code to be relatively prime to table
+ * size, so we simply make hash2 odd.
+ */
+#define HASH1(hash0, shift)         ((hash0) >> (shift))
+#define HASH2(hash0,log2,shift)     ((((hash0) << (log2)) >> (shift)) | 1)
+
+/*
+ * Reserve keyHash 0 for free entries and 1 for removed-entry sentinels.  Note
+ * that a removed-entry sentinel need be stored only if the removed entry had
+ * a colliding entry added after it.  Therefore we can use 1 as the collision
+ * flag in addition to the removed-entry sentinel value.  Multiplicative hash
+ * uses the high order bits of keyHash, so this least-significant reservation
+ * should not hurt the hash function's effectiveness much.
+ *
+ * If you change any of these magic numbers, also update JS_DHASH_ENTRY_IS_LIVE
+ * in jsdhash.h.  It used to be private to jsdhash.c, but then became public to
+ * assist iterator writers who inspect table->entryStore directly.
+ */
+#define COLLISION_FLAG              ((JSDHashNumber) 1)
+#define MARK_ENTRY_FREE(entry)      ((entry)->keyHash = 0)
+#define MARK_ENTRY_REMOVED(entry)   ((entry)->keyHash = 1)
+#define ENTRY_IS_REMOVED(entry)     ((entry)->keyHash == 1)
+#define ENTRY_IS_LIVE(entry)        JS_DHASH_ENTRY_IS_LIVE(entry)
+#define ENSURE_LIVE_KEYHASH(hash0)  if (hash0 < 2) hash0 -= 2; else (void)0
+
+/* Match an entry's keyHash against an unstored one computed from a key. */
+#define MATCH_ENTRY_KEYHASH(entry,hash0) \
+    (((entry)->keyHash & ~COLLISION_FLAG) == (hash0))
+
+/* Compute the address of the indexed entry in table. */
+#define ADDRESS_ENTRY(table, index) \
+    ((JSDHashEntryHdr *)((table)->entryStore + (index) * (table)->entrySize))
+
+JS_PUBLIC_API(void)
+JS_DHashTableFinish(JSDHashTable *table)
+{
+    char *entryAddr, *entryLimit;
+    uint32 entrySize;
+    JSDHashEntryHdr *entry;
+
+#ifdef DEBUG_XXXbrendan
+    static FILE *dumpfp = NULL;
+    if (!dumpfp) dumpfp = fopen("/tmp/jsdhash.bigdump", "w");
+    if (dumpfp) {
+#ifdef MOZILLA_CLIENT
+        NS_TraceStack(1, dumpfp);
+#endif
+        JS_DHashTableDumpMeter(table, NULL, dumpfp);
+        fputc('\n', dumpfp);
+    }
+#endif
+
+    /* Call finalize before clearing entries, so it can enumerate them. */
+    table->ops->finalize(table);
+
+    /* Clear any remaining live entries. */
+    entryAddr = table->entryStore;
+    entrySize = table->entrySize;
+    entryLimit = entryAddr + JS_DHASH_TABLE_SIZE(table) * entrySize;
+    while (entryAddr < entryLimit) {
+        entry = (JSDHashEntryHdr *)entryAddr;
+        if (ENTRY_IS_LIVE(entry)) {
+            METER(table->stats.removeEnums++);
+            table->ops->clearEntry(table, entry);
+        }
+        entryAddr += entrySize;
+    }
+
+    /* Free entry storage last. */
+    table->ops->freeTable(table, table->entryStore);
+}
+
+static JSDHashEntryHdr * JS_DHASH_FASTCALL
+SearchTable(JSDHashTable *table, const void *key, JSDHashNumber keyHash,
+            JSDHashOperator op)
+{
+    JSDHashNumber hash1, hash2;
+    int hashShift, sizeLog2;
+    JSDHashEntryHdr *entry, *firstRemoved;
+    JSDHashMatchEntry matchEntry;
+    uint32 sizeMask;
+
+    METER(table->stats.searches++);
+    JS_ASSERT(!(keyHash & COLLISION_FLAG));
+
+    /* Compute the primary hash address. */
+    hashShift = table->hashShift;
+    hash1 = HASH1(keyHash, hashShift);
+    entry = ADDRESS_ENTRY(table, hash1);
+
+    /* Miss: return space for a new entry. */
+    if (JS_DHASH_ENTRY_IS_FREE(entry)) {
+        METER(table->stats.misses++);
+        return entry;
+    }
+
+    /* Hit: return entry. */
+    matchEntry = table->ops->matchEntry;
+    if (MATCH_ENTRY_KEYHASH(entry, keyHash) && matchEntry(table, entry, key)) {
+        METER(table->stats.hits++);
+        return entry;
+    }
+
+    /* Collision: double hash. */
+    sizeLog2 = JS_DHASH_BITS - table->hashShift;
+    hash2 = HASH2(keyHash, sizeLog2, hashShift);
+    sizeMask = JS_BITMASK(sizeLog2);
+
+    /* Save the first removed entry pointer so JS_DHASH_ADD can recycle it. */
+    if (ENTRY_IS_REMOVED(entry)) {
+        firstRemoved = entry;
+    } else {
+        firstRemoved = NULL;
+        if (op == JS_DHASH_ADD)
+            entry->keyHash |= COLLISION_FLAG;
+    }
+
+    for (;;) {
+        METER(table->stats.steps++);
+        hash1 -= hash2;
+        hash1 &= sizeMask;
+
+        entry = ADDRESS_ENTRY(table, hash1);
+        if (JS_DHASH_ENTRY_IS_FREE(entry)) {
+            METER(table->stats.misses++);
+            return (firstRemoved && op == JS_DHASH_ADD) ? firstRemoved : entry;
+        }
+
+        if (MATCH_ENTRY_KEYHASH(entry, keyHash) &&
+            matchEntry(table, entry, key)) {
+            METER(table->stats.hits++);
+            return entry;
+        }
+
+        if (ENTRY_IS_REMOVED(entry)) {
+            if (!firstRemoved)
+                firstRemoved = entry;
+        } else {
+            if (op == JS_DHASH_ADD)
+                entry->keyHash |= COLLISION_FLAG;
+        }
+    }
+
+    /* NOTREACHED */
+    return NULL;
+}
+
+static JSBool
+ChangeTable(JSDHashTable *table, int deltaLog2)
+{
+    int oldLog2, newLog2;
+    uint32 oldCapacity, newCapacity;
+    char *newEntryStore, *oldEntryStore, *oldEntryAddr;
+    uint32 entrySize, i, nbytes;
+    JSDHashEntryHdr *oldEntry, *newEntry;
+    JSDHashGetKey getKey;
+    JSDHashMoveEntry moveEntry;
+
+    /* Look, but don't touch, until we succeed in getting new entry store. */
+    oldLog2 = JS_DHASH_BITS - table->hashShift;
+    newLog2 = oldLog2 + deltaLog2;
+    oldCapacity = JS_BIT(oldLog2);
+    newCapacity = JS_BIT(newLog2);
+    if (newCapacity >= JS_DHASH_SIZE_LIMIT)
+        return JS_FALSE;
+    entrySize = table->entrySize;
+    nbytes = newCapacity * entrySize;
+
+    newEntryStore = table->ops->allocTable(table, nbytes);
+    if (!newEntryStore)
+        return JS_FALSE;
+
+    /* We can't fail from here on, so update table parameters. */
+    table->hashShift = JS_DHASH_BITS - newLog2;
+    table->removedCount = 0;
+    table->generation++;
+
+    /* Assign the new entry store to table. */
+    memset(newEntryStore, 0, nbytes);
+    oldEntryAddr = oldEntryStore = table->entryStore;
+    table->entryStore = newEntryStore;
+    getKey = table->ops->getKey;
+    moveEntry = table->ops->moveEntry;
+
+    /* Copy only live entries, leaving removed ones behind. */
+    for (i = 0; i < oldCapacity; i++) {
+        oldEntry = (JSDHashEntryHdr *)oldEntryAddr;
+        if (ENTRY_IS_LIVE(oldEntry)) {
+            oldEntry->keyHash &= ~COLLISION_FLAG;
+            newEntry = SearchTable(table, getKey(table, oldEntry),
+                                   oldEntry->keyHash, JS_DHASH_ADD);
+            JS_ASSERT(JS_DHASH_ENTRY_IS_FREE(newEntry));
+            moveEntry(table, oldEntry, newEntry);
+            newEntry->keyHash = oldEntry->keyHash;
+        }
+        oldEntryAddr += entrySize;
+    }
+
+    table->ops->freeTable(table, oldEntryStore);
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSDHashEntryHdr *) JS_DHASH_FASTCALL
+JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op)
+{
+    JSDHashNumber keyHash;
+    JSDHashEntryHdr *entry;
+    uint32 size;
+    int deltaLog2;
+
+    keyHash = table->ops->hashKey(table, key);
+    keyHash *= JS_DHASH_GOLDEN_RATIO;
+
+    /* Avoid 0 and 1 hash codes, they indicate free and removed entries. */
+    ENSURE_LIVE_KEYHASH(keyHash);
+    keyHash &= ~COLLISION_FLAG;
+
+    switch (op) {
+      case JS_DHASH_LOOKUP:
+        METER(table->stats.lookups++);
+        entry = SearchTable(table, key, keyHash, op);
+        break;
+
+      case JS_DHASH_ADD:
+        /*
+         * If alpha is >= .75, grow or compress the table.  If key is already
+         * in the table, we may grow once more than necessary, but only if we
+         * are on the edge of being overloaded.
+         */
+        size = JS_DHASH_TABLE_SIZE(table);
+        if (table->entryCount + table->removedCount >= MAX_LOAD(table, size)) {
+            /* Compress if a quarter or more of all entries are removed. */
+            if (table->removedCount >= size >> 2) {
+                METER(table->stats.compresses++);
+                deltaLog2 = 0;
+            } else {
+                METER(table->stats.grows++);
+                deltaLog2 = 1;
+            }
+
+            /*
+             * Grow or compress table, returning null if ChangeTable fails and
+             * falling through might claim the last free entry.
+             */
+            if (!ChangeTable(table, deltaLog2) &&
+                table->entryCount + table->removedCount == size - 1) {
+                METER(table->stats.addFailures++);
+                return NULL;
+            }
+        }
+
+        /*
+         * Look for entry after possibly growing, so we don't have to add it,
+         * then skip it while growing the table and re-add it after.
+         */
+        entry = SearchTable(table, key, keyHash, op);
+        if (!ENTRY_IS_LIVE(entry)) {
+            /* Initialize the entry, indicating that it's no longer free. */
+            METER(table->stats.addMisses++);
+            if (ENTRY_IS_REMOVED(entry)) {
+                METER(table->stats.addOverRemoved++);
+                table->removedCount--;
+                keyHash |= COLLISION_FLAG;
+            }
+            if (table->ops->initEntry &&
+                !table->ops->initEntry(table, entry, key)) {
+                /* We haven't claimed entry yet; fail with null return. */
+                memset(entry + 1, 0, table->entrySize - sizeof *entry);
+                return NULL;
+            }
+            entry->keyHash = keyHash;
+            table->entryCount++;
+        }
+        METER(else table->stats.addHits++);
+        break;
+
+      case JS_DHASH_REMOVE:
+        entry = SearchTable(table, key, keyHash, op);
+        if (ENTRY_IS_LIVE(entry)) {
+            /* Clear this entry and mark it as "removed". */
+            METER(table->stats.removeHits++);
+            JS_DHashTableRawRemove(table, entry);
+
+            /* Shrink if alpha is <= .25 and table isn't too small already. */
+            size = JS_DHASH_TABLE_SIZE(table);
+            if (size > JS_DHASH_MIN_SIZE &&
+                table->entryCount <= MIN_LOAD(table, size)) {
+                METER(table->stats.shrinks++);
+                (void) ChangeTable(table, -1);
+            }
+        }
+        METER(else table->stats.removeMisses++);
+        entry = NULL;
+        break;
+
+      default:
+        JS_ASSERT(0);
+        entry = NULL;
+    }
+
+    return entry;
+}
+
+JS_PUBLIC_API(void)
+JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry)
+{
+    JSDHashNumber keyHash;      /* load first in case clearEntry goofs it */
+
+    JS_ASSERT(JS_DHASH_ENTRY_IS_LIVE(entry));
+    keyHash = entry->keyHash;
+    table->ops->clearEntry(table, entry);
+    if (keyHash & COLLISION_FLAG) {
+        MARK_ENTRY_REMOVED(entry);
+        table->removedCount++;
+    } else {
+        METER(table->stats.removeFrees++);
+        MARK_ENTRY_FREE(entry);
+    }
+    table->entryCount--;
+}
+
+JS_PUBLIC_API(uint32)
+JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg)
+{
+    char *entryAddr, *entryLimit;
+    uint32 i, capacity, entrySize, ceiling;
+    JSBool didRemove;
+    JSDHashEntryHdr *entry;
+    JSDHashOperator op;
+
+    entryAddr = table->entryStore;
+    entrySize = table->entrySize;
+    capacity = JS_DHASH_TABLE_SIZE(table);
+    entryLimit = entryAddr + capacity * entrySize;
+    i = 0;
+    didRemove = JS_FALSE;
+    while (entryAddr < entryLimit) {
+        entry = (JSDHashEntryHdr *)entryAddr;
+        if (ENTRY_IS_LIVE(entry)) {
+            op = etor(table, entry, i++, arg);
+            if (op & JS_DHASH_REMOVE) {
+                METER(table->stats.removeEnums++);
+                JS_DHashTableRawRemove(table, entry);
+                didRemove = JS_TRUE;
+            }
+            if (op & JS_DHASH_STOP)
+                break;
+        }
+        entryAddr += entrySize;
+    }
+
+    /*
+     * Shrink or compress if a quarter or more of all entries are removed, or
+     * if the table is underloaded according to the configured minimum alpha,
+     * and is not minimal-size already.  Do this only if we removed above, so
+     * non-removing enumerations can count on stable table->entryStore until
+     * the next non-lookup-Operate or removing-Enumerate.
+     */
+    if (didRemove &&
+        (table->removedCount >= capacity >> 2 ||
+         (capacity > JS_DHASH_MIN_SIZE &&
+          table->entryCount <= MIN_LOAD(table, capacity)))) {
+        METER(table->stats.enumShrinks++);
+        capacity = table->entryCount;
+        capacity += capacity >> 1;
+        if (capacity < JS_DHASH_MIN_SIZE)
+            capacity = JS_DHASH_MIN_SIZE;
+
+        JS_CEILING_LOG2(ceiling, capacity);
+        ceiling -= JS_DHASH_BITS - table->hashShift;
+
+        (void) ChangeTable(table, ceiling);
+    }
+    return i;
+}
+
+#ifdef JS_DHASHMETER
+#include <math.h>
+
+JS_PUBLIC_API(void)
+JS_DHashTableDumpMeter(JSDHashTable *table, JSDHashEnumerator dump, FILE *fp)
+{
+    char *entryAddr;
+    uint32 entrySize, entryCount;
+    int hashShift, sizeLog2;
+    uint32 i, tableSize, sizeMask, chainLen, maxChainLen, chainCount;
+    JSDHashNumber hash1, hash2, saveHash1, maxChainHash1, maxChainHash2;
+    double sqsum, mean, variance, sigma;
+    JSDHashEntryHdr *entry, *probe;
+
+    entryAddr = table->entryStore;
+    entrySize = table->entrySize;
+    hashShift = table->hashShift;
+    sizeLog2 = JS_DHASH_BITS - hashShift;
+    tableSize = JS_DHASH_TABLE_SIZE(table);
+    sizeMask = JS_BITMASK(sizeLog2);
+    chainCount = maxChainLen = 0;
+    hash2 = 0;
+    sqsum = 0;
+
+    for (i = 0; i < tableSize; i++) {
+        entry = (JSDHashEntryHdr *)entryAddr;
+        entryAddr += entrySize;
+        if (!ENTRY_IS_LIVE(entry))
+            continue;
+        hash1 = HASH1(entry->keyHash & ~COLLISION_FLAG, hashShift);
+        saveHash1 = hash1;
+        probe = ADDRESS_ENTRY(table, hash1);
+        chainLen = 1;
+        if (probe == entry) {
+            /* Start of a (possibly unit-length) chain. */
+            chainCount++;
+        } else {
+            hash2 = HASH2(entry->keyHash & ~COLLISION_FLAG, sizeLog2,
+                          hashShift);
+            do {
+                chainLen++;
+                hash1 -= hash2;
+                hash1 &= sizeMask;
+                probe = ADDRESS_ENTRY(table, hash1);
+            } while (probe != entry);
+        }
+        sqsum += chainLen * chainLen;
+        if (chainLen > maxChainLen) {
+            maxChainLen = chainLen;
+            maxChainHash1 = saveHash1;
+            maxChainHash2 = hash2;
+        }
+    }
+
+    entryCount = table->entryCount;
+    if (entryCount && chainCount) {
+        mean = (double)entryCount / chainCount;
+        variance = chainCount * sqsum - entryCount * entryCount;
+        if (variance < 0 || chainCount == 1)
+            variance = 0;
+        else
+            variance /= chainCount * (chainCount - 1);
+        sigma = sqrt(variance);
+    } else {
+        mean = sigma = 0;
+    }
+
+    fprintf(fp, "Double hashing statistics:\n");
+    fprintf(fp, "    table size (in entries): %u\n", tableSize);
+    fprintf(fp, "          number of entries: %u\n", table->entryCount);
+    fprintf(fp, "  number of removed entries: %u\n", table->removedCount);
+    fprintf(fp, "         number of searches: %u\n", table->stats.searches);
+    fprintf(fp, "             number of hits: %u\n", table->stats.hits);
+    fprintf(fp, "           number of misses: %u\n", table->stats.misses);
+    fprintf(fp, "      mean steps per search: %g\n", table->stats.searches ?
+                                                     (double)table->stats.steps
+                                                     / table->stats.searches :
+                                                     0.);
+    fprintf(fp, "     mean hash chain length: %g\n", mean);
+    fprintf(fp, "         standard deviation: %g\n", sigma);
+    fprintf(fp, "  maximum hash chain length: %u\n", maxChainLen);
+    fprintf(fp, "          number of lookups: %u\n", table->stats.lookups);
+    fprintf(fp, " adds that made a new entry: %u\n", table->stats.addMisses);
+    fprintf(fp, "adds that recycled removeds: %u\n", table->stats.addOverRemoved);
+    fprintf(fp, "   adds that found an entry: %u\n", table->stats.addHits);
+    fprintf(fp, "               add failures: %u\n", table->stats.addFailures);
+    fprintf(fp, "             useful removes: %u\n", table->stats.removeHits);
+    fprintf(fp, "            useless removes: %u\n", table->stats.removeMisses);
+    fprintf(fp, "removes that freed an entry: %u\n", table->stats.removeFrees);
+    fprintf(fp, "  removes while enumerating: %u\n", table->stats.removeEnums);
+    fprintf(fp, "            number of grows: %u\n", table->stats.grows);
+    fprintf(fp, "          number of shrinks: %u\n", table->stats.shrinks);
+    fprintf(fp, "       number of compresses: %u\n", table->stats.compresses);
+    fprintf(fp, "number of enumerate shrinks: %u\n", table->stats.enumShrinks);
+
+    if (dump && maxChainLen && hash2) {
+        fputs("Maximum hash chain:\n", fp);
+        hash1 = maxChainHash1;
+        hash2 = maxChainHash2;
+        entry = ADDRESS_ENTRY(table, hash1);
+        i = 0;
+        do {
+            if (dump(table, entry, i++, fp) != JS_DHASH_NEXT)
+                break;
+            hash1 -= hash2;
+            hash1 &= sizeMask;
+            entry = ADDRESS_ENTRY(table, hash1);
+        } while (JS_DHASH_ENTRY_IS_BUSY(entry));
+    }
+}
+#endif /* JS_DHASHMETER */

Added: freeswitch/trunk/libs/js/src/jsdhash.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsdhash.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,579 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla JavaScript code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999-2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Brendan Eich <brendan at mozilla.org> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsdhash_h___
+#define jsdhash_h___
+/*
+ * Double hashing, a la Knuth 6.
+ */
+#include "jstypes.h"
+
+JS_BEGIN_EXTERN_C
+
+#if defined(__GNUC__) && defined(__i386__) && (__GNUC__ >= 3) && !defined(XP_OS2) && !defined(XP_MACOSX)
+#define JS_DHASH_FASTCALL __attribute__ ((regparm (3),stdcall))
+#else
+#define JS_DHASH_FASTCALL
+#endif
+
+#ifdef DEBUG_XXXbrendan
+#define JS_DHASHMETER 1
+#endif
+
+/* Table size limit, do not equal or exceed (see min&maxAlphaFrac, below). */
+#undef JS_DHASH_SIZE_LIMIT
+#define JS_DHASH_SIZE_LIMIT     JS_BIT(24)
+
+/* Minimum table size, or gross entry count (net is at most .75 loaded). */
+#ifndef JS_DHASH_MIN_SIZE
+#define JS_DHASH_MIN_SIZE 16
+#elif (JS_DHASH_MIN_SIZE & (JS_DHASH_MIN_SIZE - 1)) != 0
+#error "JS_DHASH_MIN_SIZE must be a power of two!"
+#endif
+
+/*
+ * Multiplicative hash uses an unsigned 32 bit integer and the golden ratio,
+ * expressed as a fixed-point 32-bit fraction.
+ */
+#define JS_DHASH_BITS           32
+#define JS_DHASH_GOLDEN_RATIO   0x9E3779B9U
+
+/* Primitive and forward-struct typedefs. */
+typedef uint32                  JSDHashNumber;
+typedef struct JSDHashEntryHdr  JSDHashEntryHdr;
+typedef struct JSDHashEntryStub JSDHashEntryStub;
+typedef struct JSDHashTable     JSDHashTable;
+typedef struct JSDHashTableOps  JSDHashTableOps;
+
+/*
+ * Table entry header structure.
+ *
+ * In order to allow in-line allocation of key and value, we do not declare
+ * either here.  Instead, the API uses const void *key as a formal parameter,
+ * and asks each entry for its key when necessary via a getKey callback, used
+ * when growing or shrinking the table.  Other callback types are defined
+ * below and grouped into the JSDHashTableOps structure, for single static
+ * initialization per hash table sub-type.
+ *
+ * Each hash table sub-type should nest the JSDHashEntryHdr structure at the
+ * front of its particular entry type.  The keyHash member contains the result
+ * of multiplying the hash code returned from the hashKey callback (see below)
+ * by JS_DHASH_GOLDEN_RATIO, then constraining the result to avoid the magic 0
+ * and 1 values.  The stored keyHash value is table size invariant, and it is
+ * maintained automatically by JS_DHashTableOperate -- users should never set
+ * it, and its only uses should be via the entry macros below.
+ *
+ * The JS_DHASH_ENTRY_IS_LIVE macro tests whether entry is neither free nor
+ * removed.  An entry may be either busy or free; if busy, it may be live or
+ * removed.  Consumers of this API should not access members of entries that
+ * are not live.
+ *
+ * However, use JS_DHASH_ENTRY_IS_BUSY for faster liveness testing of entries
+ * returned by JS_DHashTableOperate, as JS_DHashTableOperate never returns a
+ * non-live, busy (i.e., removed) entry pointer to its caller.  See below for
+ * more details on JS_DHashTableOperate's calling rules.
+ */
+struct JSDHashEntryHdr {
+    JSDHashNumber       keyHash;        /* every entry must begin like this */
+};
+
+#define JS_DHASH_ENTRY_IS_FREE(entry)   ((entry)->keyHash == 0)
+#define JS_DHASH_ENTRY_IS_BUSY(entry)   (!JS_DHASH_ENTRY_IS_FREE(entry))
+#define JS_DHASH_ENTRY_IS_LIVE(entry)   ((entry)->keyHash >= 2)
+
+/*
+ * A JSDHashTable is currently 8 words (without the JS_DHASHMETER overhead)
+ * on most architectures, and may be allocated on the stack or within another
+ * structure or class (see below for the Init and Finish functions to use).
+ *
+ * To decide whether to use double hashing vs. chaining, we need to develop a
+ * trade-off relation, as follows:
+ *
+ * Let alpha be the load factor, esize the entry size in words, count the
+ * entry count, and pow2 the power-of-two table size in entries.
+ *
+ *   (JSDHashTable overhead)    > (JSHashTable overhead)
+ *   (unused table entry space) > (malloc and .next overhead per entry) +
+ *                                (buckets overhead)
+ *   (1 - alpha) * esize * pow2 > 2 * count + pow2
+ *
+ * Notice that alpha is by definition (count / pow2):
+ *
+ *   (1 - alpha) * esize * pow2 > 2 * alpha * pow2 + pow2
+ *   (1 - alpha) * esize        > 2 * alpha + 1
+ *
+ *   esize > (1 + 2 * alpha) / (1 - alpha)
+ *
+ * This assumes both tables must keep keyHash, key, and value for each entry,
+ * where key and value point to separately allocated strings or structures.
+ * If key and value can be combined into one pointer, then the trade-off is:
+ *
+ *   esize > (1 + 3 * alpha) / (1 - alpha)
+ *
+ * If the entry value can be a subtype of JSDHashEntryHdr, rather than a type
+ * that must be allocated separately and referenced by an entry.value pointer
+ * member, and provided key's allocation can be fused with its entry's, then
+ * k (the words wasted per entry with chaining) is 4.
+ *
+ * To see these curves, feed gnuplot input like so:
+ *
+ *   gnuplot> f(x,k) = (1 + k * x) / (1 - x)
+ *   gnuplot> plot [0:.75] f(x,2), f(x,3), f(x,4)
+ *
+ * For k of 2 and a well-loaded table (alpha > .5), esize must be more than 4
+ * words for chaining to be more space-efficient than double hashing.
+ *
+ * Solving for alpha helps us decide when to shrink an underloaded table:
+ *
+ *   esize                     > (1 + k * alpha) / (1 - alpha)
+ *   esize - alpha * esize     > 1 + k * alpha
+ *   esize - 1                 > (k + esize) * alpha
+ *   (esize - 1) / (k + esize) > alpha
+ *
+ *   alpha < (esize - 1) / (esize + k)
+ *
+ * Therefore double hashing should keep alpha >= (esize - 1) / (esize + k),
+ * assuming esize is not too large (in which case, chaining should probably be
+ * used for any alpha).  For esize=2 and k=3, we want alpha >= .2; for esize=3
+ * and k=2, we want alpha >= .4.  For k=4, esize could be 6, and alpha >= .5
+ * would still obtain.  See the JS_DHASH_MIN_ALPHA macro further below.
+ *
+ * The current implementation uses a configurable lower bound on alpha, which
+ * defaults to .25, when deciding to shrink the table (while still respecting
+ * JS_DHASH_MIN_SIZE).
+ *
+ * Note a qualitative difference between chaining and double hashing: under
+ * chaining, entry addresses are stable across table shrinks and grows.  With
+ * double hashing, you can't safely hold an entry pointer and use it after an
+ * ADD or REMOVE operation, unless you sample table->generation before adding
+ * or removing, and compare the sample after, dereferencing the entry pointer
+ * only if table->generation has not changed.
+ *
+ * The moral of this story: there is no one-size-fits-all hash table scheme,
+ * but for small table entry size, and assuming entry address stability is not
+ * required, double hashing wins.
+ */
+struct JSDHashTable {
+    const JSDHashTableOps *ops;         /* virtual operations, see below */
+    void                *data;          /* ops- and instance-specific data */
+    int16               hashShift;      /* multiplicative hash shift */
+    uint8               maxAlphaFrac;   /* 8-bit fixed point max alpha */
+    uint8               minAlphaFrac;   /* 8-bit fixed point min alpha */
+    uint32              entrySize;      /* number of bytes in an entry */
+    uint32              entryCount;     /* number of entries in table */
+    uint32              removedCount;   /* removed entry sentinels in table */
+    uint32              generation;     /* entry storage generation number */
+    char                *entryStore;    /* entry storage */
+#ifdef JS_DHASHMETER
+    struct JSDHashStats {
+        uint32          searches;       /* total number of table searches */
+        uint32          steps;          /* hash chain links traversed */
+        uint32          hits;           /* searches that found key */
+        uint32          misses;         /* searches that didn't find key */
+        uint32          lookups;        /* number of JS_DHASH_LOOKUPs */
+        uint32          addMisses;      /* adds that miss, and do work */
+        uint32          addOverRemoved; /* adds that recycled a removed entry */
+        uint32          addHits;        /* adds that hit an existing entry */
+        uint32          addFailures;    /* out-of-memory during add growth */
+        uint32          removeHits;     /* removes that hit, and do work */
+        uint32          removeMisses;   /* useless removes that miss */
+        uint32          removeFrees;    /* removes that freed entry directly */
+        uint32          removeEnums;    /* removes done by Enumerate */
+        uint32          grows;          /* table expansions */
+        uint32          shrinks;        /* table contractions */
+        uint32          compresses;     /* table compressions */
+        uint32          enumShrinks;    /* contractions after Enumerate */
+    } stats;
+#endif
+};
+
+/*
+ * Size in entries (gross, not net of free and removed sentinels) for table.
+ * We store hashShift rather than sizeLog2 to optimize the collision-free case
+ * in SearchTable.
+ */
+#define JS_DHASH_TABLE_SIZE(table)  JS_BIT(JS_DHASH_BITS - (table)->hashShift)
+
+/*
+ * Table space at entryStore is allocated and freed using these callbacks.
+ * The allocator should return null on error only (not if called with nbytes
+ * equal to 0; but note that jsdhash.c code will never call with 0 nbytes).
+ */
+typedef void *
+(* JS_DLL_CALLBACK JSDHashAllocTable)(JSDHashTable *table, uint32 nbytes);
+
+typedef void
+(* JS_DLL_CALLBACK JSDHashFreeTable) (JSDHashTable *table, void *ptr);
+
+/*
+ * When a table grows or shrinks, each entry is queried for its key using this
+ * callback.  NB: in that event, entry is not in table any longer; it's in the
+ * old entryStore vector, which is due to be freed once all entries have been
+ * moved via moveEntry callbacks.
+ */
+typedef const void *
+(* JS_DLL_CALLBACK JSDHashGetKey)    (JSDHashTable *table,
+                                      JSDHashEntryHdr *entry);
+
+/*
+ * Compute the hash code for a given key to be looked up, added, or removed
+ * from table.  A hash code may have any JSDHashNumber value.
+ */
+typedef JSDHashNumber
+(* JS_DLL_CALLBACK JSDHashHashKey)   (JSDHashTable *table, const void *key);
+
+/*
+ * Compare the key identifying entry in table with the provided key parameter.
+ * Return JS_TRUE if keys match, JS_FALSE otherwise.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSDHashMatchEntry)(JSDHashTable *table,
+                                      const JSDHashEntryHdr *entry,
+                                      const void *key);
+
+/*
+ * Copy the data starting at from to the new entry storage at to.  Do not add
+ * reference counts for any strong references in the entry, however, as this
+ * is a "move" operation: the old entry storage at from will be freed without
+ * any reference-decrementing callback shortly.
+ */
+typedef void
+(* JS_DLL_CALLBACK JSDHashMoveEntry)(JSDHashTable *table,
+                                     const JSDHashEntryHdr *from,
+                                     JSDHashEntryHdr *to);
+
+/*
+ * Clear the entry and drop any strong references it holds.  This callback is
+ * invoked during a JS_DHASH_REMOVE operation (see below for operation codes),
+ * but only if the given key is found in the table.
+ */
+typedef void
+(* JS_DLL_CALLBACK JSDHashClearEntry)(JSDHashTable *table,
+                                      JSDHashEntryHdr *entry);
+
+/*
+ * Called when a table (whether allocated dynamically by itself, or nested in
+ * a larger structure, or allocated on the stack) is finished.  This callback
+ * allows table->ops-specific code to finalize table->data.
+ */
+typedef void
+(* JS_DLL_CALLBACK JSDHashFinalize)  (JSDHashTable *table);
+
+/*
+ * Initialize a new entry, apart from keyHash.  This function is called when
+ * JS_DHashTableOperate's JS_DHASH_ADD case finds no existing entry for the
+ * given key, and must add a new one.  At that point, entry->keyHash is not
+ * set yet, to avoid claiming the last free entry in a severely overloaded
+ * table.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSDHashInitEntry)(JSDHashTable *table,
+                                     JSDHashEntryHdr *entry,
+                                     const void *key);
+
+/*
+ * Finally, the "vtable" structure for JSDHashTable.  The first eight hooks
+ * must be provided by implementations; they're called unconditionally by the
+ * generic jsdhash.c code.  Hooks after these may be null.
+ *
+ * Summary of allocation-related hook usage with C++ placement new emphasis:
+ *  allocTable          Allocate raw bytes with malloc, no ctors run.
+ *  freeTable           Free raw bytes with free, no dtors run.
+ *  initEntry           Call placement new using default key-based ctor.
+ *                      Return JS_TRUE on success, JS_FALSE on error.
+ *  moveEntry           Call placement new using copy ctor, run dtor on old
+ *                      entry storage.
+ *  clearEntry          Run dtor on entry.
+ *  finalize            Stub unless table->data was initialized and needs to
+ *                      be finalized.
+ *
+ * Note the reason why initEntry is optional: the default hooks (stubs) clear
+ * entry storage:  On successful JS_DHashTableOperate(tbl, key, JS_DHASH_ADD),
+ * the returned entry pointer addresses an entry struct whose keyHash member
+ * has been set non-zero, but all other entry members are still clear (null).
+ * JS_DHASH_ADD callers can test such members to see whether the entry was
+ * newly created by the JS_DHASH_ADD call that just succeeded.  If placement
+ * new or similar initialization is required, define an initEntry hook.  Of
+ * course, the clearEntry hook must zero or null appropriately.
+ *
+ * XXX assumes 0 is null for pointer types.
+ */
+struct JSDHashTableOps {
+    /* Mandatory hooks.  All implementations must provide these. */
+    JSDHashAllocTable   allocTable;
+    JSDHashFreeTable    freeTable;
+    JSDHashGetKey       getKey;
+    JSDHashHashKey      hashKey;
+    JSDHashMatchEntry   matchEntry;
+    JSDHashMoveEntry    moveEntry;
+    JSDHashClearEntry   clearEntry;
+    JSDHashFinalize     finalize;
+
+    /* Optional hooks start here.  If null, these are not called. */
+    JSDHashInitEntry    initEntry;
+};
+
+/*
+ * Default implementations for the above ops.
+ */
+extern JS_PUBLIC_API(void *)
+JS_DHashAllocTable(JSDHashTable *table, uint32 nbytes);
+
+extern JS_PUBLIC_API(void)
+JS_DHashFreeTable(JSDHashTable *table, void *ptr);
+
+extern JS_PUBLIC_API(JSDHashNumber)
+JS_DHashStringKey(JSDHashTable *table, const void *key);
+
+/* A minimal entry contains a keyHash header and a void key pointer. */
+struct JSDHashEntryStub {
+    JSDHashEntryHdr hdr;
+    const void      *key;
+};
+
+extern JS_PUBLIC_API(const void *)
+JS_DHashGetKeyStub(JSDHashTable *table, JSDHashEntryHdr *entry);
+
+extern JS_PUBLIC_API(JSDHashNumber)
+JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DHashMatchEntryStub(JSDHashTable *table,
+                       const JSDHashEntryHdr *entry,
+                       const void *key);
+
+extern JS_PUBLIC_API(JSBool)
+JS_DHashMatchStringKey(JSDHashTable *table,
+                       const JSDHashEntryHdr *entry,
+                       const void *key);
+
+extern JS_PUBLIC_API(void)
+JS_DHashMoveEntryStub(JSDHashTable *table,
+                      const JSDHashEntryHdr *from,
+                      JSDHashEntryHdr *to);
+
+extern JS_PUBLIC_API(void)
+JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry);
+
+extern JS_PUBLIC_API(void)
+JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry);
+
+extern JS_PUBLIC_API(void)
+JS_DHashFinalizeStub(JSDHashTable *table);
+
+/*
+ * If you use JSDHashEntryStub or a subclass of it as your entry struct, and
+ * if your entries move via memcpy and clear via memset(0), you can use these
+ * stub operations.
+ */
+extern JS_PUBLIC_API(const JSDHashTableOps *)
+JS_DHashGetStubOps(void);
+
+/*
+ * Dynamically allocate a new JSDHashTable using malloc, initialize it using
+ * JS_DHashTableInit, and return its address.  Return null on malloc failure.
+ * Note that the entry storage at table->entryStore will be allocated using
+ * the ops->allocTable callback.
+ */
+extern JS_PUBLIC_API(JSDHashTable *)
+JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32 entrySize,
+                 uint32 capacity);
+
+/*
+ * Finalize table's data, free its entry storage (via table->ops->freeTable),
+ * and return the memory starting at table to the malloc heap.
+ */
+extern JS_PUBLIC_API(void)
+JS_DHashTableDestroy(JSDHashTable *table);
+
+/*
+ * Initialize table with ops, data, entrySize, and capacity.  Capacity is a
+ * guess for the smallest table size at which the table will usually be less
+ * than 75% loaded (the table will grow or shrink as needed; capacity serves
+ * only to avoid inevitable early growth from JS_DHASH_MIN_SIZE).
+ */
+extern JS_PUBLIC_API(JSBool)
+JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data,
+                  uint32 entrySize, uint32 capacity);
+
+/*
+ * Set maximum and minimum alpha for table.  The defaults are 0.75 and .25.
+ * maxAlpha must be in [0.5, 0.9375] for the default JS_DHASH_MIN_SIZE; or if
+ * MinSize=JS_DHASH_MIN_SIZE <= 256, in [0.5, (float)(MinSize-1)/MinSize]; or
+ * else in [0.5, 255.0/256].  minAlpha must be in [0, maxAlpha / 2), so that
+ * we don't shrink on the very next remove after growing a table upon adding
+ * an entry that brings entryCount past maxAlpha * tableSize.
+ */
+extern JS_PUBLIC_API(void)
+JS_DHashTableSetAlphaBounds(JSDHashTable *table,
+                            float maxAlpha,
+                            float minAlpha);
+
+/*
+ * Call this macro with k, the number of pointer-sized words wasted per entry
+ * under chaining, to compute the minimum alpha at which double hashing still
+ * beats chaining.
+ */
+#define JS_DHASH_MIN_ALPHA(table, k)                                          \
+    ((float)((table)->entrySize / sizeof(void *) - 1)                         \
+     / ((table)->entrySize / sizeof(void *) + (k)))
+
+/*
+ * Finalize table's data, free its entry storage using table->ops->freeTable,
+ * and leave its members unchanged from their last live values (which leaves
+ * pointers dangling).  If you want to burn cycles clearing table, it's up to
+ * your code to call memset.
+ */
+extern JS_PUBLIC_API(void)
+JS_DHashTableFinish(JSDHashTable *table);
+
+/*
+ * To consolidate keyHash computation and table grow/shrink code, we use a
+ * single entry point for lookup, add, and remove operations.  The operation
+ * codes are declared here, along with codes returned by JSDHashEnumerator
+ * functions, which control JS_DHashTableEnumerate's behavior.
+ */
+typedef enum JSDHashOperator {
+    JS_DHASH_LOOKUP = 0,        /* lookup entry */
+    JS_DHASH_ADD = 1,           /* add entry */
+    JS_DHASH_REMOVE = 2,        /* remove entry, or enumerator says remove */
+    JS_DHASH_NEXT = 0,          /* enumerator says continue */
+    JS_DHASH_STOP = 1           /* enumerator says stop */
+} JSDHashOperator;
+
+/*
+ * To lookup a key in table, call:
+ *
+ *  entry = JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP);
+ *
+ * If JS_DHASH_ENTRY_IS_BUSY(entry) is true, key was found and it identifies
+ * entry.  If JS_DHASH_ENTRY_IS_FREE(entry) is true, key was not found.
+ *
+ * To add an entry identified by key to table, call:
+ *
+ *  entry = JS_DHashTableOperate(table, key, JS_DHASH_ADD);
+ *
+ * If entry is null upon return, then either the table is severely overloaded,
+ * and memory can't be allocated for entry storage via table->ops->allocTable;
+ * Or if table->ops->initEntry is non-null, the table->ops->initEntry op may
+ * have returned false.
+ *
+ * Otherwise, entry->keyHash has been set so that JS_DHASH_ENTRY_IS_BUSY(entry)
+ * is true, and it is up to the caller to initialize the key and value parts
+ * of the entry sub-type, if they have not been set already (i.e. if entry was
+ * not already in the table, and if the optional initEntry hook was not used).
+ *
+ * To remove an entry identified by key from table, call:
+ *
+ *  (void) JS_DHashTableOperate(table, key, JS_DHASH_REMOVE);
+ *
+ * If key's entry is found, it is cleared (via table->ops->clearEntry) and
+ * the entry is marked so that JS_DHASH_ENTRY_IS_FREE(entry).  This operation
+ * returns null unconditionally; you should ignore its return value.
+ */
+extern JS_PUBLIC_API(JSDHashEntryHdr *) JS_DHASH_FASTCALL
+JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op);
+
+/*
+ * Remove an entry already accessed via LOOKUP or ADD.
+ *
+ * NB: this is a "raw" or low-level routine, intended to be used only where
+ * the inefficiency of a full JS_DHashTableOperate (which rehashes in order
+ * to find the entry given its key) is not tolerable.  This function does not
+ * shrink the table if it is underloaded.  It does not update stats #ifdef
+ * JS_DHASHMETER, either.
+ */
+extern JS_PUBLIC_API(void)
+JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry);
+
+/*
+ * Enumerate entries in table using etor:
+ *
+ *   count = JS_DHashTableEnumerate(table, etor, arg);
+ *
+ * JS_DHashTableEnumerate calls etor like so:
+ *
+ *   op = etor(table, entry, number, arg);
+ *
+ * where number is a zero-based ordinal assigned to live entries according to
+ * their order in table->entryStore.
+ *
+ * The return value, op, is treated as a set of flags.  If op is JS_DHASH_NEXT,
+ * then continue enumerating.  If op contains JS_DHASH_REMOVE, then clear (via
+ * table->ops->clearEntry) and free entry.  Then we check whether op contains
+ * JS_DHASH_STOP; if so, stop enumerating and return the number of live entries
+ * that were enumerated so far.  Return the total number of live entries when
+ * enumeration completes normally.
+ *
+ * If etor calls JS_DHashTableOperate on table with op != JS_DHASH_LOOKUP, it
+ * must return JS_DHASH_STOP; otherwise undefined behavior results.
+ *
+ * If any enumerator returns JS_DHASH_REMOVE, table->entryStore may be shrunk
+ * or compressed after enumeration, but before JS_DHashTableEnumerate returns.
+ * Such an enumerator therefore can't safely set aside entry pointers, but an
+ * enumerator that never returns JS_DHASH_REMOVE can set pointers to entries
+ * aside, e.g., to avoid copying live entries into an array of the entry type.
+ * Copying entry pointers is cheaper, and safe so long as the caller of such a
+ * "stable" Enumerate doesn't use the set-aside pointers after any call either
+ * to PL_DHashTableOperate, or to an "unstable" form of Enumerate, which might
+ * grow or shrink entryStore.
+ *
+ * If your enumerator wants to remove certain entries, but set aside pointers
+ * to other entries that it retains, it can use JS_DHashTableRawRemove on the
+ * entries to be removed, returning JS_DHASH_NEXT to skip them.  Likewise, if
+ * you want to remove entries, but for some reason you do not want entryStore
+ * to be shrunk or compressed, you can call JS_DHashTableRawRemove safely on
+ * the entry being enumerated, rather than returning JS_DHASH_REMOVE.
+ */
+typedef JSDHashOperator
+(* JS_DLL_CALLBACK JSDHashEnumerator)(JSDHashTable *table, JSDHashEntryHdr *hdr,
+                                      uint32 number, void *arg);
+
+extern JS_PUBLIC_API(uint32)
+JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg);
+
+#ifdef JS_DHASHMETER
+#include <stdio.h>
+
+extern JS_PUBLIC_API(void)
+JS_DHashTableDumpMeter(JSDHashTable *table, JSDHashEnumerator dump, FILE *fp);
+#endif
+
+JS_END_EXTERN_C
+
+#endif /* jsdhash_h___ */

Added: freeswitch/trunk/libs/js/src/jsdso.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsdso.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,247 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* ATTENTION: This is an OSSP js extension to the Mozilla JavaScript engine.
+   It was implemented by Ralf S. Engelschall <rse at engelschall.com> for OSSP. */
+
+#if defined(OSSP) && defined(JS_HAS_DSO_OBJECT) && JS_HAS_DSO_OBJECT
+
+/* own headers (part 1/2) */
+#include "jsstddef.h"
+
+/* system headers */
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+/* own headers (part 2/2) */
+#include "jstypes.h"
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsobj.h"
+#include "jsdso.h"
+
+/* process local storage of DSO handles */
+static void *dso_handle[10000];
+
+/* type of the DSO load/unload functions */
+typedef JSBool (*dso_func_t)(JSContext *cx);
+
+/* ISO-C type coersion trick */
+typedef union { void *vp; dso_func_t fp; } dso_func_ptr_t;
+
+/* public C API function: DSO loading */
+JS_PUBLIC_API(JSBool)
+JS_DSOLoad(JSContext *cx, int *idp, const char *filename)
+{
+    int id;
+    void *handle;
+    dso_func_ptr_t func;
+    JSBool rc;
+
+    /* determine next free DSO handle slot */
+    for (id = 0; dso_handle[id] != NULL && id < sizeof(dso_handle)/sizeof(dso_handle[0]); id++)
+        ;
+    if (id == sizeof(dso_handle)/sizeof(dso_handle[0])) {
+        JS_ReportError(cx, "no more free DSO handle slots available");
+        return JS_FALSE;
+    }
+
+    /* load DSO into process */
+    if ((handle = dlopen(filename, RTLD_NOW)) == NULL) {
+        JS_ReportError(cx, "unable to load DSO \"%s\": %s", filename, dlerror());
+        return JS_FALSE;
+    }
+
+    /* resolve "js_DSO_load" function, call it and insist on a true return */
+    if ((func.vp = dlsym(handle, "js_DSO_load")) == NULL) {
+        JS_ReportError(cx, "unable to resolve symbol \"js_DSO_load\" in DSO \"%s\"", filename);
+        dlclose(handle);
+        return JS_FALSE;
+    }
+    rc = func.fp(cx);
+    if (!rc) {
+        JS_ReportError(cx, "function \"js_DSO_load\" in DSO \"%s\" returned error", filename);
+        dlclose(handle);
+        return JS_FALSE;
+    }
+
+    /* store DSO handle into process local storage */
+    dso_handle[id] = handle;
+
+    /* return DSO id to caller */
+    if (idp != NULL)
+        *idp = id;
+
+    return JS_TRUE;
+}
+
+/* public C API function: DSO unloading */
+JS_PUBLIC_API(JSBool)
+JS_DSOUnload(JSContext *cx, int id)
+{
+    int idx;
+    void *handle;
+    dso_func_ptr_t func;
+    JSBool rc;
+
+    /* sanity check DSO id */
+    if (id < 0 || id >= sizeof(dso_handle)/sizeof(dso_handle[0])) {
+        JS_ReportError(cx, "invalid argument: DSO id #%d out of range", id);
+        return JS_FALSE;
+    }
+
+    /* determine DSO handle */
+    if ((handle = dso_handle[id]) == NULL) {
+        JS_ReportError(cx, "invalid argument: DSO id #%d currently unused", id);
+        return JS_FALSE;
+    }
+
+    /* resolve "js_DSO_unload" function and (if available only)
+       call it and insist on a true return */
+    if ((func.vp = dlsym(handle, "js_DSO_unload")) != NULL) {
+        rc = func.fp(cx);
+        if (!rc) {
+            JS_ReportError(cx, "function \"js_DSO_unload\" in DSO with id #%d returned error", idx);
+            return JS_FALSE;
+        }
+    }
+
+    /* unload DSO from process */
+    dlclose(handle);
+
+    /* free DSO handle slot */
+    dso_handle[id] = NULL;
+
+    return JS_TRUE;
+}
+
+/* global JavaScript language DSO object method: id = DSO.load("filename.so") */
+static JSBool dso_load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *filename;
+    char *c_filename;
+    int id;
+
+    /* usage sanity checks */
+    if (argc == 0) {
+        JS_ReportError(cx, "usage: id = DSO.load(filename)");
+        return JS_FALSE;
+    }
+    if (argc != 1) {
+        JS_ReportError(cx, "invalid number of arguments: %d received, %d expected", argc, 1);
+        return JS_FALSE;
+    }
+
+    /* determine filename */
+    if ((filename = js_ValueToString(cx, argv[0])) == NULL) {
+        JS_ReportError(cx, "invalid argument");
+        return JS_FALSE;
+    }
+    if ((c_filename = JS_GetStringBytes(filename)) == NULL) {
+        JS_ReportError(cx, "invalid argument");
+        return JS_FALSE;
+    }
+
+    /* load DSO */
+    if (!JS_DSOLoad(cx, &id, c_filename))
+        return JS_FALSE;
+
+    /* return DSO handle id */
+    *rval = INT_TO_JSVAL(id);
+
+    return JS_TRUE;
+}
+
+/* global JavaScript language DSO object method: DSO.unload(id) */
+static JSBool dso_unload(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    int id;
+    JSBool rc;
+
+    /* usage sanity checks */
+    if (argc == 0) {
+        JS_ReportError(cx, "usage: DSO.unload(id)");
+        return JS_FALSE;
+    }
+    if (argc != 1) {
+        JS_ReportError(cx, "invalid number of arguments: %d received, %d expected", argc, 1);
+        return JS_FALSE;
+    }
+
+    /* determine DSO id */
+    id = JSVAL_TO_INT(argv[0]);
+
+    /* unload DSO */
+    if (!JS_DSOUnload(cx, id))
+        return JS_FALSE;
+
+    return JS_TRUE;
+}
+
+/* JavaScript DSO class method definitions */
+static JSFunctionSpec dso_methods[] = {
+    { "load",   dso_load,   1, 0, 0 },
+    { "unload", dso_unload, 1, 0, 0 },
+    { NULL,     NULL,       0, 0, 0 }
+};
+
+/* JavaScript DSO class definition */
+static JSClass dso_class = {
+    "DSO",
+    0,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_PropertyStub,
+    JS_EnumerateStub,
+    JS_ResolveStub,
+    JS_ConvertStub,
+    JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+/* JavaScript DSO class global initializer */
+JSObject *js_InitDSOClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *DSO;
+
+    if ((DSO = JS_DefineObject(cx, obj, "DSO", &dso_class, NULL, 0)) == NULL)
+        return NULL;
+    if (!JS_DefineFunctions(cx, DSO, dso_methods))
+        return NULL;
+    return DSO;
+}
+
+#endif /* JS_HAS_DSO_OBJECT */
+

Added: freeswitch/trunk/libs/js/src/jsdso.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsdso.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,51 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* ATTENTION: This is an OSSP js extension to the Mozilla JavaScript engine.
+   It was implemented by Ralf S. Engelschall <rse at engelschall.com> for OSSP. */
+
+#ifndef jsdso_h___
+#define jsdso_h___
+
+#if defined(OSSP) && defined(JS_HAS_DSO_OBJECT) && JS_HAS_DSO_OBJECT
+
+JS_BEGIN_EXTERN_C
+
+/* public API */
+extern JSBool    JS_DSOLoad      (JSContext *cx, int *id, const char *filename);
+extern JSBool    JS_DSOUnload    (JSContext *cx, int  id);
+
+/* friend API */
+extern JSObject *js_InitDSOClass (JSContext *cx, JSObject *obj);
+
+JS_END_EXTERN_C
+
+#endif
+
+#endif /* jsdso_h___ */

Added: freeswitch/trunk/libs/js/src/jsdtoa.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsdtoa.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3132 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * Portable double to alphanumeric string and back converters.
+ */
+#include "jsstddef.h"
+#include "jslibmath.h"
+#include "jstypes.h"
+#include "jsdtoa.h"
+#include "jsprf.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jspubtd.h"
+#include "jsnum.h"
+
+#ifdef JS_THREADSAFE
+#include "prlock.h"
+#endif
+
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991 by Lucent Technologies.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to
+    David M. Gay
+    Bell Laboratories, Room 2C-463
+    600 Mountain Avenue
+    Murray Hill, NJ 07974-0636
+    U.S.A.
+    dmg at bell-labs.com
+ */
+
+/* On a machine with IEEE extended-precision registers, it is
+ * necessary to specify double-precision (53-bit) rounding precision
+ * before invoking strtod or dtoa.  If the machine uses (the equivalent
+ * of) Intel 80x87 arithmetic, the call
+ *  _control87(PC_53, MCW_PC);
+ * does this with many compilers.  Whether this or another call is
+ * appropriate depends on the compiler; for this to work, it may be
+ * necessary to #include "float.h" or another system-dependent header
+ * file.
+ */
+
+/* strtod for IEEE-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets err to JS_DTOA_ERANGE or JS_DTOA_ENOMEM).  With IEEE
+ * arithmetic, ties are broken by the IEEE round-even rule.  Otherwise
+ * ties are broken by biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ *  1. We only require IEEE double-precision
+ *      arithmetic (not IEEE double-extended).
+ *  2. We get by with floating-point arithmetic in a case that
+ *      Clinger missed -- when we're computing d * 10^n
+ *      for a small integer d and the integer n is not too
+ *      much larger than 22 (the maximum integer k for which
+ *      we can represent 10^k exactly), we may be able to
+ *      compute (d*10^k) * 10^(e-k) with just one roundoff.
+ *  3. Rather than a bit-at-a-time adjustment of the binary
+ *      result in the hard case, we use floating-point
+ *      arithmetic to determine the adjustment to within
+ *      one bit; only in really hard cases do we need to
+ *      compute a second residual.
+ *  4. Because of 3., we don't need a large table of powers of 10
+ *      for ten-to-e (just some small tables, e.g. of 10^k
+ *      for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_8087 for IEEE-arithmetic machines where the least
+ *  significant byte has the lowest address.
+ * #define IEEE_MC68k for IEEE-arithmetic machines where the most
+ *  significant byte has the lowest address.
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
+ * #define Sudden_Underflow for IEEE-format machines without gradual
+ *  underflow (i.e., that flush to zero on underflow).
+ * #define No_leftright to omit left-right logic in fast floating-point
+ *  computation of js_dtoa.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
+ * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
+ *  that use extended-precision instructions to compute rounded
+ *  products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ *  products but inaccurate quotients, e.g., for Intel i860.
+ * #define JS_HAVE_LONG_LONG on machines that have a "long long"
+ *  integer type (of >= 64 bits).  If long long is available and the name is
+ *  something other than "long long", #define Llong to be the name,
+ *  and if "unsigned Llong" does not work as an unsigned version of
+ *  Llong, #define #ULLong to be the corresponding unsigned type.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ *  define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ *  FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ *  if memory is available and otherwise does something you deem
+ *  appropriate.  If MALLOC is undefined, malloc will be invoked
+ *  directly -- and assumed always to succeed.
+ * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
+ *  memory allocations from a private pool of memory when possible.
+ *  When used, the private pool is PRIVATE_MEM bytes long: 2000 bytes,
+ *  unless #defined to be a different length.  This default length
+ *  suffices to get rid of MALLOC calls except for unusual cases,
+ *  such as decimal-to-binary conversion of a very long string of
+ *  digits.
+ * #define INFNAN_CHECK on IEEE systems to cause strtod to check for
+ *  Infinity and NaN (case insensitively).  On some systems (e.g.,
+ *  some HP systems), it may be necessary to #define NAN_WORD0
+ *  appropriately -- to the most significant word of a quiet NaN.
+ *  (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
+ * #define MULTIPLE_THREADS if the system offers preemptively scheduled
+ *  multiple threads.  In this case, you must provide (or suitably
+ *  #define) two locks, acquired by ACQUIRE_DTOA_LOCK() and released
+ *  by RELEASE_DTOA_LOCK().  (The second lock, accessed
+ *  in pow5mult, ensures lazy evaluation of only one copy of high
+ *  powers of 5; omitting this lock would introduce a small
+ *  probability of wasting memory, but would otherwise be harmless.)
+ *  You must also invoke freedtoa(s) to free the value s returned by
+ *  dtoa.  You may do so whether or not MULTIPLE_THREADS is #defined.
+ * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that
+ *  avoids underflows on inputs whose result does not underflow.
+ */
+#ifdef IS_LITTLE_ENDIAN
+#define IEEE_8087
+#else
+#define IEEE_MC68k
+#endif
+
+#ifndef Long
+#define Long int32
+#endif
+
+#ifndef ULong
+#define ULong uint32
+#endif
+
+#define Bug(errorMessageString) JS_ASSERT(!errorMessageString)
+
+#include "stdlib.h"
+#include "string.h"
+
+#ifdef MALLOC
+extern void *MALLOC(size_t);
+#else
+#define MALLOC malloc
+#endif
+
+#define Omit_Private_Memory
+/* Private memory currently doesn't work with JS_THREADSAFE */
+#ifndef Omit_Private_Memory
+#ifndef PRIVATE_MEM
+#define PRIVATE_MEM 2000
+#endif
+#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
+static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
+#endif
+
+#ifdef Bad_float_h
+#undef __STDC__
+
+#define DBL_DIG 15
+#define DBL_MAX_10_EXP 308
+#define DBL_MAX_EXP 1024
+#define FLT_RADIX 2
+#define FLT_ROUNDS 1
+#define DBL_MAX 1.7976931348623157e+308
+
+
+
+#ifndef LONG_MAX
+#define LONG_MAX 2147483647
+#endif
+
+#else /* ifndef Bad_float_h */
+#include "float.h"
+#endif /* Bad_float_h */
+
+#ifndef __MATH_H__
+#include "math.h"
+#endif
+
+#ifndef CONST
+#define CONST const
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) != 1
+Exactly one of IEEE_8087 or IEEE_MC68k should be defined.
+#endif
+
+#define word0(x)        JSDOUBLE_HI32(x)
+#define set_word0(x, y) JSDOUBLE_SET_HI32(x, y)
+#define word1(x)        JSDOUBLE_LO32(x)
+#define set_word1(x, y) JSDOUBLE_SET_LO32(x, y)
+
+#ifdef OSSP /* BUGFIX */
+#define Storeinc(a,b,c) (*(a)++ = (b) << 16 | ((c) & 0xffff))
+#else
+#define Storeinc(a,b,c) (*(a)++ = (b) << 16 | (c) & 0xffff)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#define Exp_shift  20
+#define Exp_shift1 20
+#define Exp_msk1    0x100000
+#define Exp_msk11   0x100000
+#define Exp_mask  0x7ff00000
+#define P 53
+#define Bias 1023
+#define Emin (-1022)
+#define Exp_1  0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask  0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask  0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */
+#ifndef NO_IEEE_Scale
+#define Avoid_Underflow
+#endif
+
+
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#ifndef JS_HAVE_LONG_LONG
+#undef ULLong
+#else   /* long long available */
+#ifndef Llong
+#define Llong JSInt64
+#endif
+#ifndef ULLong
+#define ULLong JSUint64
+#endif
+#endif /* JS_HAVE_LONG_LONG */
+
+#ifdef JS_THREADSAFE
+#define MULTIPLE_THREADS
+static PRLock *freelist_lock;
+#define ACQUIRE_DTOA_LOCK()                                                   \
+    JS_BEGIN_MACRO                                                            \
+        if (!initialized)                                                     \
+            InitDtoa();                                                       \
+        PR_Lock(freelist_lock);                                               \
+    JS_END_MACRO
+#define RELEASE_DTOA_LOCK() PR_Unlock(freelist_lock)
+#else
+#undef MULTIPLE_THREADS
+#define ACQUIRE_DTOA_LOCK()   /*nothing*/
+#define RELEASE_DTOA_LOCK()   /*nothing*/
+#endif
+
+#define Kmax 15
+
+struct Bigint {
+    struct Bigint *next;  /* Free list link */
+    int32 k;              /* lg2(maxwds) */
+    int32 maxwds;         /* Number of words allocated for x */
+    int32 sign;           /* Zero if positive, 1 if negative.  Ignored by most Bigint routines! */
+    int32 wds;            /* Actual number of words.  If value is nonzero, the most significant word must be nonzero. */
+    ULong x[1];           /* wds words of number in little endian order */
+};
+
+#ifdef ENABLE_OOM_TESTING
+/* Out-of-memory testing.  Use a good testcase (over and over) and then use
+ * these routines to cause a memory failure on every possible Balloc allocation,
+ * to make sure that all out-of-memory paths can be followed.  See bug 14044.
+ */
+
+static int allocationNum;               /* which allocation is next? */
+static int desiredFailure;              /* which allocation should fail? */
+
+/**
+ * js_BigintTestingReset
+ *
+ * Call at the beginning of a test run to set the allocation failure position.
+ * (Set to 0 to just have the engine count allocations without failing.)
+ */
+JS_PUBLIC_API(void)
+js_BigintTestingReset(int newFailure)
+{
+    allocationNum = 0;
+    desiredFailure = newFailure;
+}
+
+/**
+ * js_BigintTestingWhere
+ *
+ * Report the current allocation position.  This is really only useful when you
+ * want to learn how many allocations a test run has.
+ */
+JS_PUBLIC_API(int)
+js_BigintTestingWhere()
+{
+    return allocationNum;
+}
+
+
+/*
+ * So here's what you do: Set up a fantastic test case that exercises the
+ * elements of the code you wish.  Set the failure point at 0 and run the test,
+ * then get the allocation position.  This number is the number of allocations
+ * your test makes.  Now loop from 1 to that number, setting the failure point
+ * at each loop count, and run the test over and over, causing failures at each
+ * step.  Any memory failure *should* cause a Out-Of-Memory exception; if it
+ * doesn't, then there's still an error here.
+ */
+#endif
+
+typedef struct Bigint Bigint;
+
+static Bigint *freelist[Kmax+1];
+
+/*
+ * Allocate a Bigint with 2^k words.
+ * This is not threadsafe. The caller must use thread locks
+ */
+static Bigint *Balloc(int32 k)
+{
+    int32 x;
+    Bigint *rv;
+#ifndef Omit_Private_Memory
+    uint32 len;
+#endif
+
+#ifdef ENABLE_OOM_TESTING
+    if (++allocationNum == desiredFailure) {
+        printf("Forced Failing Allocation number %d\n", allocationNum);
+        return NULL;
+    }
+#endif
+
+    if ((rv = freelist[k]) != NULL)
+        freelist[k] = rv->next;
+    if (rv == NULL) {
+        x = 1 << k;
+#ifdef Omit_Private_Memory
+        rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
+#else
+        len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
+            /sizeof(double);
+        if (pmem_next - private_mem + len <= PRIVATE_mem) {
+            rv = (Bigint*)pmem_next;
+            pmem_next += len;
+            }
+        else
+            rv = (Bigint*)MALLOC(len*sizeof(double));
+#endif
+        if (!rv)
+            return NULL;
+        rv->k = k;
+        rv->maxwds = x;
+    }
+    rv->sign = rv->wds = 0;
+    return rv;
+}
+
+static void Bfree(Bigint *v)
+{
+    if (v) {
+        v->next = freelist[v->k];
+        freelist[v->k] = v;
+    }
+}
+
+#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
+                          y->wds*sizeof(Long) + 2*sizeof(int32))
+
+/* Return b*m + a.  Deallocate the old b.  Both a and m must be between 0 and
+ * 65535 inclusive.  NOTE: old b is deallocated on memory failure.
+ */
+static Bigint *multadd(Bigint *b, int32 m, int32 a)
+{
+    int32 i, wds;
+#ifdef ULLong
+    ULong *x;
+    ULLong carry, y;
+#else
+    ULong carry, *x, y;
+    ULong xi, z;
+#endif
+    Bigint *b1;
+
+#ifdef ENABLE_OOM_TESTING
+    if (++allocationNum == desiredFailure) {
+        /* Faux allocation, because I'm not getting all of the failure paths
+         * without it.
+         */
+        printf("Forced Failing Allocation number %d\n", allocationNum);
+        Bfree(b);
+        return NULL;
+    }
+#endif
+
+    wds = b->wds;
+    x = b->x;
+    i = 0;
+    carry = a;
+    do {
+#ifdef ULLong
+        y = *x * (ULLong)m + carry;
+        carry = y >> 32;
+        *x++ = (ULong)(y & 0xffffffffUL);
+#else
+        xi = *x;
+        y = (xi & 0xffff) * m + carry;
+        z = (xi >> 16) * m + (y >> 16);
+        carry = z >> 16;
+        *x++ = (z << 16) + (y & 0xffff);
+#endif
+    }
+    while(++i < wds);
+    if (carry) {
+        if (wds >= b->maxwds) {
+            b1 = Balloc(b->k+1);
+            if (!b1) {
+                Bfree(b);
+                return NULL;
+            }
+            Bcopy(b1, b);
+            Bfree(b);
+            b = b1;
+        }
+        b->x[wds++] = (ULong)carry;
+        b->wds = wds;
+    }
+    return b;
+}
+
+static Bigint *s2b(CONST char *s, int32 nd0, int32 nd, ULong y9)
+{
+    Bigint *b;
+    int32 i, k;
+    Long x, y;
+
+    x = (nd + 8) / 9;
+    for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+    b = Balloc(k);
+    if (!b)
+        return NULL;
+    b->x[0] = y9;
+    b->wds = 1;
+
+    i = 9;
+    if (9 < nd0) {
+        s += 9;
+        do {
+            b = multadd(b, 10, *s++ - '0');
+            if (!b)
+                return NULL;
+        } while(++i < nd0);
+        s++;
+    }
+    else
+        s += 10;
+    for(; i < nd; i++) {
+        b = multadd(b, 10, *s++ - '0');
+        if (!b)
+            return NULL;
+    }
+    return b;
+}
+
+
+/* Return the number (0 through 32) of most significant zero bits in x. */
+static int32 hi0bits(register ULong x)
+{
+    register int32 k = 0;
+
+    if (!(x & 0xffff0000)) {
+        k = 16;
+        x <<= 16;
+    }
+    if (!(x & 0xff000000)) {
+        k += 8;
+        x <<= 8;
+    }
+    if (!(x & 0xf0000000)) {
+        k += 4;
+        x <<= 4;
+    }
+    if (!(x & 0xc0000000)) {
+        k += 2;
+        x <<= 2;
+    }
+    if (!(x & 0x80000000)) {
+        k++;
+        if (!(x & 0x40000000))
+            return 32;
+    }
+    return k;
+}
+
+
+/* Return the number (0 through 32) of least significant zero bits in y.
+ * Also shift y to the right past these 0 through 32 zeros so that y's
+ * least significant bit will be set unless y was originally zero. */
+static int32 lo0bits(ULong *y)
+{
+    register int32 k;
+    register ULong x = *y;
+
+    if (x & 7) {
+        if (x & 1)
+            return 0;
+        if (x & 2) {
+            *y = x >> 1;
+            return 1;
+        }
+        *y = x >> 2;
+        return 2;
+    }
+    k = 0;
+    if (!(x & 0xffff)) {
+        k = 16;
+        x >>= 16;
+    }
+    if (!(x & 0xff)) {
+        k += 8;
+        x >>= 8;
+    }
+    if (!(x & 0xf)) {
+        k += 4;
+        x >>= 4;
+    }
+    if (!(x & 0x3)) {
+        k += 2;
+        x >>= 2;
+    }
+    if (!(x & 1)) {
+        k++;
+        x >>= 1;
+        if (!x & 1)
+            return 32;
+    }
+    *y = x;
+    return k;
+}
+
+/* Return a new Bigint with the given integer value, which must be nonnegative. */
+static Bigint *i2b(int32 i)
+{
+    Bigint *b;
+
+    b = Balloc(1);
+    if (!b)
+        return NULL;
+    b->x[0] = i;
+    b->wds = 1;
+    return b;
+}
+
+/* Return a newly allocated product of a and b. */
+static Bigint *mult(CONST Bigint *a, CONST Bigint *b)
+{
+    CONST Bigint *t;
+    Bigint *c;
+    int32 k, wa, wb, wc;
+    ULong y;
+    ULong *xc, *xc0, *xce;
+    CONST ULong *x, *xa, *xae, *xb, *xbe;
+#ifdef ULLong
+    ULLong carry, z;
+#else
+    ULong carry, z;
+    ULong z2;
+#endif
+
+    if (a->wds < b->wds) {
+        t = a;
+        a = b;
+        b = t;
+    }
+    k = a->k;
+    wa = a->wds;
+    wb = b->wds;
+    wc = wa + wb;
+    if (wc > a->maxwds)
+        k++;
+    c = Balloc(k);
+    if (!c)
+        return NULL;
+    for(xc = c->x, xce = xc + wc; xc < xce; xc++)
+        *xc = 0;
+    xa = a->x;
+    xae = xa + wa;
+    xb = b->x;
+    xbe = xb + wb;
+    xc0 = c->x;
+#ifdef ULLong
+    for(; xb < xbe; xc0++) {
+        if ((y = *xb++) != 0) {
+            x = xa;
+            xc = xc0;
+            carry = 0;
+            do {
+                z = *x++ * (ULLong)y + *xc + carry;
+                carry = z >> 32;
+                *xc++ = (ULong)(z & 0xffffffffUL);
+                }
+                while(x < xae);
+            *xc = (ULong)carry;
+            }
+        }
+#else
+    for(; xb < xbe; xb++, xc0++) {
+        if ((y = *xb & 0xffff) != 0) {
+            x = xa;
+            xc = xc0;
+            carry = 0;
+            do {
+                z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+                carry = z >> 16;
+                z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+                carry = z2 >> 16;
+                Storeinc(xc, z2, z);
+            }
+            while(x < xae);
+            *xc = carry;
+        }
+        if ((y = *xb >> 16) != 0) {
+            x = xa;
+            xc = xc0;
+            carry = 0;
+            z2 = *xc;
+            do {
+                z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+                carry = z >> 16;
+                Storeinc(xc, z, z2);
+                z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+                carry = z2 >> 16;
+            }
+            while(x < xae);
+            *xc = z2;
+        }
+    }
+#endif
+    for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+    c->wds = wc;
+    return c;
+}
+
+/*
+ * 'p5s' points to a linked list of Bigints that are powers of 5.
+ * This list grows on demand, and it can only grow: it won't change
+ * in any other way.  So if we read 'p5s' or the 'next' field of
+ * some Bigint on the list, and it is not NULL, we know it won't
+ * change to NULL or some other value.  Only when the value of
+ * 'p5s' or 'next' is NULL do we need to acquire the lock and add
+ * a new Bigint to the list.
+ */
+
+static Bigint *p5s;
+
+#ifdef JS_THREADSAFE
+static PRLock *p5s_lock;
+#endif
+
+/* Return b * 5^k.  Deallocate the old b.  k must be nonnegative. */
+/* NOTE: old b is deallocated on memory failure. */
+static Bigint *pow5mult(Bigint *b, int32 k)
+{
+    Bigint *b1, *p5, *p51;
+    int32 i;
+    static CONST int32 p05[3] = { 5, 25, 125 };
+
+    if ((i = k & 3) != 0) {
+        b = multadd(b, p05[i-1], 0);
+        if (!b)
+            return NULL;
+    }
+
+    if (!(k >>= 2))
+        return b;
+    if (!(p5 = p5s)) {
+#ifdef JS_THREADSAFE
+        /*
+         * We take great care to not call i2b() and Bfree()
+         * while holding the lock.
+         */
+        Bigint *wasted_effort = NULL;
+        p5 = i2b(625);
+        if (!p5) {
+            Bfree(b);
+            return NULL;
+        }
+        /* lock and check again */
+        PR_Lock(p5s_lock);
+        if (!p5s) {
+            /* first time */
+            p5s = p5;
+            p5->next = 0;
+        } else {
+            /* some other thread just beat us */
+            wasted_effort = p5;
+            p5 = p5s;
+        }
+        PR_Unlock(p5s_lock);
+        if (wasted_effort) {
+            Bfree(wasted_effort);
+        }
+#else
+        /* first time */
+        p5 = p5s = i2b(625);
+        if (!p5) {
+            Bfree(b);
+            return NULL;
+        }
+        p5->next = 0;
+#endif
+    }
+    for(;;) {
+        if (k & 1) {
+            b1 = mult(b, p5);
+            Bfree(b);
+            if (!b1)
+                return NULL;
+            b = b1;
+        }
+        if (!(k >>= 1))
+            break;
+        if (!(p51 = p5->next)) {
+#ifdef JS_THREADSAFE
+            Bigint *wasted_effort = NULL;
+            p51 = mult(p5, p5);
+            if (!p51) {
+                Bfree(b);
+                return NULL;
+            }
+            PR_Lock(p5s_lock);
+            if (!p5->next) {
+                p5->next = p51;
+                p51->next = 0;
+            } else {
+                wasted_effort = p51;
+                p51 = p5->next;
+            }
+            PR_Unlock(p5s_lock);
+            if (wasted_effort) {
+                Bfree(wasted_effort);
+            }
+#else
+            p51 = mult(p5,p5);
+            if (!p51) {
+                Bfree(b);
+                return NULL;
+            }
+            p51->next = 0;
+            p5->next = p51;
+#endif
+        }
+        p5 = p51;
+    }
+    return b;
+}
+
+/* Return b * 2^k.  Deallocate the old b.  k must be nonnegative.
+ * NOTE: on memory failure, old b is deallocated. */
+static Bigint *lshift(Bigint *b, int32 k)
+{
+    int32 i, k1, n, n1;
+    Bigint *b1;
+    ULong *x, *x1, *xe, z;
+
+    n = k >> 5;
+    k1 = b->k;
+    n1 = n + b->wds + 1;
+    for(i = b->maxwds; n1 > i; i <<= 1)
+        k1++;
+    b1 = Balloc(k1);
+    if (!b1)
+        goto done;
+    x1 = b1->x;
+    for(i = 0; i < n; i++)
+        *x1++ = 0;
+    x = b->x;
+    xe = x + b->wds;
+    if (k &= 0x1f) {
+        k1 = 32 - k;
+        z = 0;
+        do {
+            *x1++ = *x << k | z;
+            z = *x++ >> k1;
+        }
+        while(x < xe);
+        if ((*x1 = z) != 0)
+            ++n1;
+    }
+    else do
+        *x1++ = *x++;
+         while(x < xe);
+    b1->wds = n1 - 1;
+done:
+    Bfree(b);
+    return b1;
+}
+
+/* Return -1, 0, or 1 depending on whether a<b, a==b, or a>b, respectively. */
+static int32 cmp(Bigint *a, Bigint *b)
+{
+    ULong *xa, *xa0, *xb, *xb0;
+    int32 i, j;
+
+    i = a->wds;
+    j = b->wds;
+#ifdef DEBUG
+    if (i > 1 && !a->x[i-1])
+        Bug("cmp called with a->x[a->wds-1] == 0");
+    if (j > 1 && !b->x[j-1])
+        Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+    if (i -= j)
+        return i;
+    xa0 = a->x;
+    xa = xa0 + j;
+    xb0 = b->x;
+    xb = xb0 + j;
+    for(;;) {
+        if (*--xa != *--xb)
+            return *xa < *xb ? -1 : 1;
+        if (xa <= xa0)
+            break;
+    }
+    return 0;
+}
+
+static Bigint *diff(Bigint *a, Bigint *b)
+{
+    Bigint *c;
+    int32 i, wa, wb;
+    ULong *xa, *xae, *xb, *xbe, *xc;
+#ifdef ULLong
+    ULLong borrow, y;
+#else
+    ULong borrow, y;
+    ULong z;
+#endif
+
+    i = cmp(a,b);
+    if (!i) {
+        c = Balloc(0);
+        if (!c)
+            return NULL;
+        c->wds = 1;
+        c->x[0] = 0;
+        return c;
+    }
+    if (i < 0) {
+        c = a;
+        a = b;
+        b = c;
+        i = 1;
+    }
+    else
+        i = 0;
+    c = Balloc(a->k);
+    if (!c)
+        return NULL;
+    c->sign = i;
+    wa = a->wds;
+    xa = a->x;
+    xae = xa + wa;
+    wb = b->wds;
+    xb = b->x;
+    xbe = xb + wb;
+    xc = c->x;
+    borrow = 0;
+#ifdef ULLong
+    do {
+        y = (ULLong)*xa++ - *xb++ - borrow;
+        borrow = y >> 32 & 1UL;
+        *xc++ = (ULong)(y & 0xffffffffUL);
+        }
+        while(xb < xbe);
+    while(xa < xae) {
+        y = *xa++ - borrow;
+        borrow = y >> 32 & 1UL;
+        *xc++ = (ULong)(y & 0xffffffffUL);
+        }
+#else
+    do {
+        y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
+        borrow = (y & 0x10000) >> 16;
+        z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
+        borrow = (z & 0x10000) >> 16;
+        Storeinc(xc, z, y);
+        }
+        while(xb < xbe);
+    while(xa < xae) {
+        y = (*xa & 0xffff) - borrow;
+        borrow = (y & 0x10000) >> 16;
+        z = (*xa++ >> 16) - borrow;
+        borrow = (z & 0x10000) >> 16;
+        Storeinc(xc, z, y);
+        }
+#endif
+    while(!*--xc)
+        wa--;
+    c->wds = wa;
+    return c;
+}
+
+/* Return the absolute difference between x and the adjacent greater-magnitude double number (ignoring exponent overflows). */
+static double ulp(double x)
+{
+    register Long L;
+    double a = 0;
+
+    L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Sudden_Underflow
+    if (L > 0) {
+#endif
+        set_word0(a, L);
+        set_word1(a, 0);
+#ifndef Sudden_Underflow
+    }
+    else {
+        L = -L >> Exp_shift;
+        if (L < Exp_shift) {
+            set_word0(a, 0x80000 >> L);
+            set_word1(a, 0);
+        }
+        else {
+            set_word0(a, 0);
+            L -= Exp_shift;
+            set_word1(a, L >= 31 ? 1 : 1 << (31 - L));
+        }
+    }
+#endif
+    return a;
+}
+
+
+static double b2d(Bigint *a, int32 *e)
+{
+    ULong *xa, *xa0, w, y, z;
+    int32 k;
+    double d = 0;
+#define d0 word0(d)
+#define d1 word1(d)
+#define set_d0(x) set_word0(d, x)
+#define set_d1(x) set_word1(d, x)
+
+    xa0 = a->x;
+    xa = xa0 + a->wds;
+    y = *--xa;
+#ifdef DEBUG
+    if (!y) Bug("zero y in b2d");
+#endif
+    k = hi0bits(y);
+    *e = 32 - k;
+    if (k < Ebits) {
+        set_d0(Exp_1 | y >> (Ebits - k));
+        w = xa > xa0 ? *--xa : 0;
+        set_d1(y << (32-Ebits + k) | w >> (Ebits - k));
+        goto ret_d;
+    }
+    z = xa > xa0 ? *--xa : 0;
+    if (k -= Ebits) {
+        set_d0(Exp_1 | y << k | z >> (32 - k));
+        y = xa > xa0 ? *--xa : 0;
+        set_d1(z << k | y >> (32 - k));
+    }
+    else {
+        set_d0(Exp_1 | y);
+        set_d1(z);
+    }
+  ret_d:
+#undef d0
+#undef d1
+#undef set_d0
+#undef set_d1
+    return d;
+}
+
+
+/* Convert d into the form b*2^e, where b is an odd integer.  b is the returned
+ * Bigint and e is the returned binary exponent.  Return the number of significant
+ * bits in b in bits.  d must be finite and nonzero. */
+static Bigint *d2b(double d, int32 *e, int32 *bits)
+{
+    Bigint *b;
+    int32 de, i, k;
+    ULong *x, y, z;
+#define d0 word0(d)
+#define d1 word1(d)
+#define set_d0(x) set_word0(d, x)
+#define set_d1(x) set_word1(d, x)
+
+    b = Balloc(1);
+    if (!b)
+        return NULL;
+    x = b->x;
+
+    z = d0 & Frac_mask;
+    set_d0(d0 & 0x7fffffff);  /* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+    de = (int32)(d0 >> Exp_shift);
+    z |= Exp_msk11;
+#else
+    if ((de = (int32)(d0 >> Exp_shift)) != 0)
+        z |= Exp_msk1;
+#endif
+    if ((y = d1) != 0) {
+        if ((k = lo0bits(&y)) != 0) {
+            x[0] = y | z << (32 - k);
+            z >>= k;
+        }
+        else
+            x[0] = y;
+        i = b->wds = (x[1] = z) ? 2 : 1;
+    }
+    else {
+        JS_ASSERT(z);
+        k = lo0bits(&z);
+        x[0] = z;
+        i = b->wds = 1;
+        k += 32;
+    }
+#ifndef Sudden_Underflow
+    if (de) {
+#endif
+        *e = de - Bias - (P-1) + k;
+        *bits = P - k;
+#ifndef Sudden_Underflow
+    }
+    else {
+        *e = de - Bias - (P-1) + 1 + k;
+        *bits = 32*i - hi0bits(x[i-1]);
+    }
+#endif
+    return b;
+}
+#undef d0
+#undef d1
+#undef set_d0
+#undef set_d1
+
+
+static double ratio(Bigint *a, Bigint *b)
+{
+    double da, db;
+    int32 k, ka, kb;
+
+    da = b2d(a, &ka);
+    db = b2d(b, &kb);
+    k = ka - kb + 32*(a->wds - b->wds);
+    if (k > 0)
+        set_word0(da, word0(da) + k*Exp_msk1);
+    else {
+        k = -k;
+        set_word0(db, word0(db) + k*Exp_msk1);
+    }
+    return da / db;
+}
+
+static CONST double
+tens[] = {
+    1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+    1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+    1e20, 1e21, 1e22
+};
+
+static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
+#ifdef Avoid_Underflow
+        9007199254740992.e-256
+#else
+        1e-256
+#endif
+        };
+/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
+/* flag unnecessarily.  It leads to a song and dance at the end of strtod. */
+#define Scale_Bit 0x10
+#define n_bigtens 5
+
+
+#ifdef INFNAN_CHECK
+
+#ifndef NAN_WORD0
+#define NAN_WORD0 0x7ff80000
+#endif
+
+#ifndef NAN_WORD1
+#define NAN_WORD1 0
+#endif
+
+static int match(CONST char **sp, char *t)
+{
+    int c, d;
+    CONST char *s = *sp;
+
+    while(d = *t++) {
+        if ((c = *++s) >= 'A' && c <= 'Z')
+            c += 'a' - 'A';
+        if (c != d)
+            return 0;
+        }
+    *sp = s + 1;
+    return 1;
+    }
+#endif /* INFNAN_CHECK */
+
+
+#ifdef JS_THREADSAFE
+static JSBool initialized = JS_FALSE;
+
+/* hacked replica of nspr _PR_InitDtoa */
+static void InitDtoa(void)
+{
+    freelist_lock = PR_NewLock();
+        p5s_lock = PR_NewLock();
+    initialized = JS_TRUE;
+}
+#endif
+
+void js_FinishDtoa(void)
+{
+    int count;
+    Bigint *temp;
+
+#ifdef JS_THREADSAFE
+    if (initialized == JS_TRUE) {
+        PR_DestroyLock(freelist_lock);
+        PR_DestroyLock(p5s_lock);
+        initialized = JS_FALSE;
+    }
+#endif
+
+    /* clear down the freelist array and p5s */
+
+    /* static Bigint *freelist[Kmax+1]; */
+    for (count = 0; count <= Kmax; count++) {
+        Bigint **listp = &freelist[count];
+        while ((temp = *listp) != NULL) {
+            *listp = temp->next;
+            free(temp);
+        }
+        freelist[count] = NULL;
+    }
+
+    /* static Bigint *p5s; */
+    while (p5s) {
+        temp = p5s;
+        p5s = p5s->next;
+        free(temp);
+    }
+}
+
+/* nspr2 watcom bug ifdef omitted */
+
+JS_FRIEND_API(double)
+JS_strtod(CONST char *s00, char **se, int *err)
+{
+    int32 scale;
+    int32 bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
+        e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+    CONST char *s, *s0, *s1;
+    double aadj, aadj1, adj, rv, rv0;
+    Long L;
+    ULong y, z;
+    Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+
+    *err = 0;
+
+    bb = bd = bs = delta = NULL;
+    sign = nz0 = nz = 0;
+    rv = 0.;
+
+    /* Locking for Balloc's shared buffers that will be used in this block */
+    ACQUIRE_DTOA_LOCK();
+
+    for(s = s00;;s++) switch(*s) {
+    case '-':
+        sign = 1;
+        /* no break */
+    case '+':
+        if (*++s)
+            goto break2;
+        /* no break */
+    case 0:
+        s = s00;
+        goto ret;
+    case '\t':
+    case '\n':
+    case '\v':
+    case '\f':
+    case '\r':
+    case ' ':
+        continue;
+    default:
+        goto break2;
+    }
+break2:
+
+    if (*s == '0') {
+        nz0 = 1;
+        while(*++s == '0') ;
+        if (!*s)
+            goto ret;
+    }
+    s0 = s;
+    y = z = 0;
+    for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+        if (nd < 9)
+            y = 10*y + c - '0';
+        else if (nd < 16)
+            z = 10*z + c - '0';
+    nd0 = nd;
+    if (c == '.') {
+        c = *++s;
+        if (!nd) {
+            for(; c == '0'; c = *++s)
+                nz++;
+            if (c > '0' && c <= '9') {
+                s0 = s;
+                nf += nz;
+                nz = 0;
+                goto have_dig;
+            }
+            goto dig_done;
+        }
+        for(; c >= '0' && c <= '9'; c = *++s) {
+        have_dig:
+            nz++;
+            if (c -= '0') {
+                nf += nz;
+                for(i = 1; i < nz; i++)
+                    if (nd++ < 9)
+                        y *= 10;
+                    else if (nd <= DBL_DIG + 1)
+                        z *= 10;
+                if (nd++ < 9)
+                    y = 10*y + c;
+                else if (nd <= DBL_DIG + 1)
+                    z = 10*z + c;
+                nz = 0;
+            }
+        }
+    }
+dig_done:
+    e = 0;
+    if (c == 'e' || c == 'E') {
+        if (!nd && !nz && !nz0) {
+            s = s00;
+            goto ret;
+        }
+        s00 = s;
+        esign = 0;
+        switch(c = *++s) {
+        case '-':
+            esign = 1;
+        case '+':
+            c = *++s;
+        }
+        if (c >= '0' && c <= '9') {
+            while(c == '0')
+                c = *++s;
+            if (c > '0' && c <= '9') {
+                L = c - '0';
+                s1 = s;
+                while((c = *++s) >= '0' && c <= '9')
+                    L = 10*L + c - '0';
+                if (s - s1 > 8 || L > 19999)
+                    /* Avoid confusion from exponents
+                     * so large that e might overflow.
+                     */
+                    e = 19999; /* safe for 16 bit ints */
+                else
+                    e = (int32)L;
+                if (esign)
+                    e = -e;
+            }
+            else
+                e = 0;
+        }
+        else
+            s = s00;
+    }
+    if (!nd) {
+        if (!nz && !nz0) {
+#ifdef INFNAN_CHECK
+            /* Check for Nan and Infinity */
+            switch(c) {
+              case 'i':
+              case 'I':
+                if (match(&s,"nfinity")) {
+                    word0(rv) = 0x7ff00000;
+                    word1(rv) = 0;
+                    goto ret;
+                    }
+                break;
+              case 'n':
+              case 'N':
+                if (match(&s, "an")) {
+                    word0(rv) = NAN_WORD0;
+                    word1(rv) = NAN_WORD1;
+                    goto ret;
+                    }
+              }
+#endif /* INFNAN_CHECK */
+            s = s00;
+            }
+        goto ret;
+    }
+    e1 = e -= nf;
+
+    /* Now we have nd0 digits, starting at s0, followed by a
+     * decimal point, followed by nd-nd0 digits.  The number we're
+     * after is the integer represented by those digits times
+     * 10**e */
+
+    if (!nd0)
+        nd0 = nd;
+    k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+    rv = y;
+    if (k > 9)
+        rv = tens[k - 9] * rv + z;
+    bd0 = 0;
+    if (nd <= DBL_DIG
+#ifndef RND_PRODQUOT
+        && FLT_ROUNDS == 1
+#endif
+        ) {
+        if (!e)
+            goto ret;
+        if (e > 0) {
+            if (e <= Ten_pmax) {
+                /* rv = */ rounded_product(rv, tens[e]);
+                goto ret;
+            }
+            i = DBL_DIG - nd;
+            if (e <= Ten_pmax + i) {
+                /* A fancier test would sometimes let us do
+                 * this for larger i values.
+                 */
+                e -= i;
+                rv *= tens[i];
+                /* rv = */ rounded_product(rv, tens[e]);
+                goto ret;
+            }
+        }
+#ifndef Inaccurate_Divide
+        else if (e >= -Ten_pmax) {
+            /* rv = */ rounded_quotient(rv, tens[-e]);
+            goto ret;
+        }
+#endif
+    }
+    e1 += nd - k;
+
+    scale = 0;
+
+    /* Get starting approximation = rv * 10**e1 */
+
+    if (e1 > 0) {
+        if ((i = e1 & 15) != 0)
+            rv *= tens[i];
+        if (e1 &= ~15) {
+            if (e1 > DBL_MAX_10_EXP) {
+            ovfl:
+                *err = JS_DTOA_ERANGE;
+#ifdef __STDC__
+                rv = HUGE_VAL;
+#else
+                /* Can't trust HUGE_VAL */
+                word0(rv) = Exp_mask;
+                word1(rv) = 0;
+#endif
+                if (bd0)
+                    goto retfree;
+                goto ret;
+            }
+            e1 >>= 4;
+            for(j = 0; e1 > 1; j++, e1 >>= 1)
+                if (e1 & 1)
+                    rv *= bigtens[j];
+            /* The last multiplication could overflow. */
+            set_word0(rv, word0(rv) - P*Exp_msk1);
+            rv *= bigtens[j];
+            if ((z = word0(rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+                goto ovfl;
+            if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+                /* set to largest number */
+                /* (Can't trust DBL_MAX) */
+                set_word0(rv, Big0);
+                set_word1(rv, Big1);
+                }
+            else
+                set_word0(rv, word0(rv) + P*Exp_msk1);
+            }
+    }
+    else if (e1 < 0) {
+        e1 = -e1;
+        if ((i = e1 & 15) != 0)
+            rv /= tens[i];
+        if (e1 &= ~15) {
+            e1 >>= 4;
+            if (e1 >= 1 << n_bigtens)
+                goto undfl;
+#ifdef Avoid_Underflow
+            if (e1 & Scale_Bit)
+                scale = P;
+            for(j = 0; e1 > 0; j++, e1 >>= 1)
+                if (e1 & 1)
+                    rv *= tinytens[j];
+            if (scale && (j = P + 1 - ((word0(rv) & Exp_mask)
+                        >> Exp_shift)) > 0) {
+                /* scaled rv is denormal; zap j low bits */
+                if (j >= 32) {
+                    set_word1(rv, 0);
+                    set_word0(rv, word0(rv) & (0xffffffff << (j-32)));
+                    if (!word0(rv))
+                        set_word0(rv, 1);
+                    }
+                else
+                    set_word1(rv, word1(rv) & (0xffffffff << j));
+                }
+#else
+            for(j = 0; e1 > 1; j++, e1 >>= 1)
+                if (e1 & 1)
+                    rv *= tinytens[j];
+            /* The last multiplication could underflow. */
+            rv0 = rv;
+            rv *= tinytens[j];
+            if (!rv) {
+                rv = 2.*rv0;
+                rv *= tinytens[j];
+#endif
+                if (!rv) {
+                undfl:
+                    rv = 0.;
+                    *err = JS_DTOA_ERANGE;
+                    if (bd0)
+                        goto retfree;
+                    goto ret;
+                }
+#ifndef Avoid_Underflow
+                set_word0(rv, Tiny0);
+                set_word1(rv, Tiny1);
+                /* The refinement below will clean
+                 * this approximation up.
+                 */
+            }
+#endif
+        }
+    }
+
+    /* Now the hard part -- adjusting rv to the correct value.*/
+
+    /* Put digits into bd: true value = bd * 10^e */
+
+    bd0 = s2b(s0, nd0, nd, y);
+    if (!bd0)
+        goto nomem;
+
+    for(;;) {
+        bd = Balloc(bd0->k);
+        if (!bd)
+            goto nomem;
+        Bcopy(bd, bd0);
+        bb = d2b(rv, &bbe, &bbbits);    /* rv = bb * 2^bbe */
+        if (!bb)
+            goto nomem;
+        bs = i2b(1);
+        if (!bs)
+            goto nomem;
+
+        if (e >= 0) {
+            bb2 = bb5 = 0;
+            bd2 = bd5 = e;
+        }
+        else {
+            bb2 = bb5 = -e;
+            bd2 = bd5 = 0;
+        }
+        if (bbe >= 0)
+            bb2 += bbe;
+        else
+            bd2 -= bbe;
+        bs2 = bb2;
+#ifdef Sudden_Underflow
+        j = P + 1 - bbbits;
+#else
+#ifdef Avoid_Underflow
+        j = bbe - scale;
+#else
+        j = bbe;
+#endif
+        i = j + bbbits - 1; /* logb(rv) */
+        if (i < Emin)   /* denormal */
+            j += P - Emin;
+        else
+            j = P + 1 - bbbits;
+#endif
+        bb2 += j;
+        bd2 += j;
+#ifdef Avoid_Underflow
+        bd2 += scale;
+#endif
+        i = bb2 < bd2 ? bb2 : bd2;
+        if (i > bs2)
+            i = bs2;
+        if (i > 0) {
+            bb2 -= i;
+            bd2 -= i;
+            bs2 -= i;
+        }
+        if (bb5 > 0) {
+            bs = pow5mult(bs, bb5);
+            if (!bs)
+                goto nomem;
+            bb1 = mult(bs, bb);
+            if (!bb1)
+                goto nomem;
+            Bfree(bb);
+            bb = bb1;
+        }
+        if (bb2 > 0) {
+            bb = lshift(bb, bb2);
+            if (!bb)
+                goto nomem;
+        }
+        if (bd5 > 0) {
+            bd = pow5mult(bd, bd5);
+            if (!bd)
+                goto nomem;
+        }
+        if (bd2 > 0) {
+            bd = lshift(bd, bd2);
+            if (!bd)
+                goto nomem;
+        }
+        if (bs2 > 0) {
+            bs = lshift(bs, bs2);
+            if (!bs)
+                goto nomem;
+        }
+        delta = diff(bb, bd);
+        if (!delta)
+            goto nomem;
+        dsign = delta->sign;
+        delta->sign = 0;
+        i = cmp(delta, bs);
+        if (i < 0) {
+            /* Error is less than half an ulp -- check for
+             * special case of mantissa a power of two.
+             */
+            if (dsign || word1(rv) || word0(rv) & Bndry_mask
+#ifdef Avoid_Underflow
+             || (word0(rv) & Exp_mask) <= Exp_msk1 + P*Exp_msk1
+#else
+             || (word0(rv) & Exp_mask) <= Exp_msk1
+#endif
+                ) {
+#ifdef Avoid_Underflow
+                if (!delta->x[0] && delta->wds == 1)
+                    dsign = 2;
+#endif
+                break;
+                }
+            delta = lshift(delta,Log2P);
+            if (!delta)
+                goto nomem;
+            if (cmp(delta, bs) > 0)
+                goto drop_down;
+            break;
+        }
+        if (i == 0) {
+            /* exactly half-way between */
+            if (dsign) {
+                if ((word0(rv) & Bndry_mask1) == Bndry_mask1
+                    &&  word1(rv) == 0xffffffff) {
+                    /*boundary case -- increment exponent*/
+                    set_word0(rv, (word0(rv) & Exp_mask) + Exp_msk1);
+                    set_word1(rv, 0);
+#ifdef Avoid_Underflow
+                    dsign = 0;
+#endif
+                    break;
+                }
+            }
+            else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+#ifdef Avoid_Underflow
+                dsign = 2;
+#endif
+            drop_down:
+                /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow
+                L = word0(rv) & Exp_mask;
+                if (L <= Exp_msk1)
+                    goto undfl;
+                L -= Exp_msk1;
+#else
+                L = (word0(rv) & Exp_mask) - Exp_msk1;
+#endif
+                set_word0(rv, L | Bndry_mask1);
+                set_word1(rv, 0xffffffff);
+                break;
+            }
+#ifndef ROUND_BIASED
+            if (!(word1(rv) & LSB))
+                break;
+#endif
+            if (dsign)
+                rv += ulp(rv);
+#ifndef ROUND_BIASED
+            else {
+                rv -= ulp(rv);
+#ifndef Sudden_Underflow
+                if (!rv)
+                    goto undfl;
+#endif
+            }
+#ifdef Avoid_Underflow
+            dsign = 1 - dsign;
+#endif
+#endif
+            break;
+        }
+        if ((aadj = ratio(delta, bs)) <= 2.) {
+            if (dsign)
+                aadj = aadj1 = 1.;
+            else if (word1(rv) || word0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+                if (word1(rv) == Tiny1 && !word0(rv))
+                    goto undfl;
+#endif
+                aadj = 1.;
+                aadj1 = -1.;
+            }
+            else {
+                /* special case -- power of FLT_RADIX to be */
+                /* rounded down... */
+
+                if (aadj < 2./FLT_RADIX)
+                    aadj = 1./FLT_RADIX;
+                else
+                    aadj *= 0.5;
+                aadj1 = -aadj;
+            }
+        }
+        else {
+            aadj *= 0.5;
+            aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+            switch(FLT_ROUNDS) {
+            case 2: /* towards +infinity */
+                aadj1 -= 0.5;
+                break;
+            case 0: /* towards 0 */
+            case 3: /* towards -infinity */
+                aadj1 += 0.5;
+            }
+#else
+            if (FLT_ROUNDS == 0)
+                aadj1 += 0.5;
+#endif
+        }
+        y = word0(rv) & Exp_mask;
+
+        /* Check for overflow */
+
+        if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+            rv0 = rv;
+            set_word0(rv, word0(rv) - P*Exp_msk1);
+            adj = aadj1 * ulp(rv);
+            rv += adj;
+            if ((word0(rv) & Exp_mask) >=
+                Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+                if (word0(rv0) == Big0 && word1(rv0) == Big1)
+                    goto ovfl;
+                set_word0(rv, Big0);
+                set_word1(rv, Big1);
+                goto cont;
+            }
+            else
+                set_word0(rv, word0(rv) + P*Exp_msk1);
+        }
+        else {
+#ifdef Sudden_Underflow
+            if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
+                rv0 = rv;
+                set_word0(rv, word0(rv) + P*Exp_msk1);
+                adj = aadj1 * ulp(rv);
+                rv += adj;
+                    if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+                        {
+                            if (word0(rv0) == Tiny0
+                                && word1(rv0) == Tiny1)
+                                goto undfl;
+                            set_word0(rv, Tiny0);
+                            set_word1(rv, Tiny1);
+                            goto cont;
+                        }
+                    else
+                        set_word0(rv, word0(rv) - P*Exp_msk1);
+            }
+            else {
+                adj = aadj1 * ulp(rv);
+                rv += adj;
+            }
+#else
+            /* Compute adj so that the IEEE rounding rules will
+             * correctly round rv + adj in some half-way cases.
+             * If rv * ulp(rv) is denormalized (i.e.,
+             * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+             * trouble from bits lost to denormalization;
+             * example: 1.2e-307 .
+             */
+#ifdef Avoid_Underflow
+            if (y <= P*Exp_msk1 && aadj > 1.)
+#else
+            if (y <= (P-1)*Exp_msk1 && aadj > 1.)
+#endif
+                {
+                aadj1 = (double)(int32)(aadj + 0.5);
+                if (!dsign)
+                    aadj1 = -aadj1;
+            }
+#ifdef Avoid_Underflow
+            if (scale && y <= P*Exp_msk1)
+                set_word0(aadj1, word0(aadj1) + (P+1)*Exp_msk1 - y);
+#endif
+            adj = aadj1 * ulp(rv);
+            rv += adj;
+#endif
+        }
+        z = word0(rv) & Exp_mask;
+#ifdef Avoid_Underflow
+        if (!scale)
+#endif
+        if (y == z) {
+            /* Can we stop now? */
+            L = (Long)aadj;
+            aadj -= L;
+            /* The tolerances below are conservative. */
+            if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+                if (aadj < .4999999 || aadj > .5000001)
+                    break;
+            }
+            else if (aadj < .4999999/FLT_RADIX)
+                break;
+        }
+    cont:
+        Bfree(bb);
+        Bfree(bd);
+        Bfree(bs);
+        Bfree(delta);
+        bb = bd = bs = delta = NULL;
+    }
+#ifdef Avoid_Underflow
+    if (scale) {
+#ifdef OSSP /* CLEANUP */
+        rv0 = 0.; /* calm the compiler warning */
+#endif
+        set_word0(rv0, Exp_1 - P*Exp_msk1);
+        set_word1(rv0, 0);
+        if ((word0(rv) & Exp_mask) <= P*Exp_msk1
+              && word1(rv) & 1
+              && dsign != 2) {
+            if (dsign) {
+#ifdef Sudden_Underflow
+                /* rv will be 0, but this would give the  */
+                /* right result if only rv *= rv0 worked. */
+                set_word0(rv, word0(rv) + P*Exp_msk1);
+                set_word0(rv0, Exp_1 - 2*P*Exp_msk1);
+#endif
+                rv += ulp(rv);
+                }
+            else
+                set_word1(rv, word1(rv) & ~1);
+        }
+        rv *= rv0;
+    }
+#endif /* Avoid_Underflow */
+retfree:
+    Bfree(bb);
+    Bfree(bd);
+    Bfree(bs);
+    Bfree(bd0);
+    Bfree(delta);
+ret:
+    RELEASE_DTOA_LOCK();
+    if (se)
+        *se = (char *)s;
+    return sign ? -rv : rv;
+
+nomem:
+    Bfree(bb);
+    Bfree(bd);
+    Bfree(bs);
+    Bfree(bd0);
+    Bfree(delta);
+    *err = JS_DTOA_ENOMEM;
+    return 0;
+}
+
+
+/* Return floor(b/2^k) and set b to be the remainder.  The returned quotient must be less than 2^32. */
+static uint32 quorem2(Bigint *b, int32 k)
+{
+    ULong mask;
+    ULong result;
+    ULong *bx, *bxe;
+    int32 w;
+    int32 n = k >> 5;
+    k &= 0x1F;
+    mask = (1<<k) - 1;
+
+    w = b->wds - n;
+    if (w <= 0)
+        return 0;
+    JS_ASSERT(w <= 2);
+    bx = b->x;
+    bxe = bx + n;
+    result = *bxe >> k;
+    *bxe &= mask;
+    if (w == 2) {
+        JS_ASSERT(!(bxe[1] & ~mask));
+        if (k)
+            result |= bxe[1] << (32 - k);
+    }
+    n++;
+    while (!*bxe && bxe != bx) {
+        n--;
+        bxe--;
+    }
+    b->wds = n;
+    return result;
+}
+
+/* Return floor(b/S) and set b to be the remainder.  As added restrictions, b must not have
+ * more words than S, the most significant word of S must not start with a 1 bit, and the
+ * returned quotient must be less than 36. */
+static int32 quorem(Bigint *b, Bigint *S)
+{
+    int32 n;
+    ULong *bx, *bxe, q, *sx, *sxe;
+#ifdef ULLong
+    ULLong borrow, carry, y, ys;
+#else
+    ULong borrow, carry, y, ys;
+    ULong si, z, zs;
+#endif
+
+    n = S->wds;
+    JS_ASSERT(b->wds <= n);
+    if (b->wds < n)
+        return 0;
+    sx = S->x;
+    sxe = sx + --n;
+    bx = b->x;
+    bxe = bx + n;
+    JS_ASSERT(*sxe <= 0x7FFFFFFF);
+    q = *bxe / (*sxe + 1);  /* ensure q <= true quotient */
+    JS_ASSERT(q < 36);
+    if (q) {
+        borrow = 0;
+        carry = 0;
+        do {
+#ifdef ULLong
+            ys = *sx++ * (ULLong)q + carry;
+            carry = ys >> 32;
+            y = *bx - (ys & 0xffffffffUL) - borrow;
+            borrow = y >> 32 & 1UL;
+            *bx++ = (ULong)(y & 0xffffffffUL);
+#else
+            si = *sx++;
+            ys = (si & 0xffff) * q + carry;
+            zs = (si >> 16) * q + (ys >> 16);
+            carry = zs >> 16;
+            y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+            borrow = (y & 0x10000) >> 16;
+            z = (*bx >> 16) - (zs & 0xffff) - borrow;
+            borrow = (z & 0x10000) >> 16;
+            Storeinc(bx, z, y);
+#endif
+        }
+        while(sx <= sxe);
+        if (!*bxe) {
+            bx = b->x;
+            while(--bxe > bx && !*bxe)
+                --n;
+            b->wds = n;
+        }
+    }
+    if (cmp(b, S) >= 0) {
+        q++;
+        borrow = 0;
+        carry = 0;
+        bx = b->x;
+        sx = S->x;
+        do {
+#ifdef ULLong
+            ys = *sx++ + carry;
+            carry = ys >> 32;
+            y = *bx - (ys & 0xffffffffUL) - borrow;
+            borrow = y >> 32 & 1UL;
+            *bx++ = (ULong)(y & 0xffffffffUL);
+#else
+            si = *sx++;
+            ys = (si & 0xffff) + carry;
+            zs = (si >> 16) + (ys >> 16);
+            carry = zs >> 16;
+            y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
+            borrow = (y & 0x10000) >> 16;
+            z = (*bx >> 16) - (zs & 0xffff) - borrow;
+            borrow = (z & 0x10000) >> 16;
+            Storeinc(bx, z, y);
+#endif
+        } while(sx <= sxe);
+        bx = b->x;
+        bxe = bx + n;
+        if (!*bxe) {
+            while(--bxe > bx && !*bxe)
+                --n;
+            b->wds = n;
+        }
+    }
+    return (int32)q;
+}
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *  1. Rather than iterating, we use a simple numeric overestimate
+ *     to determine k = floor(log10(d)).  We scale relevant
+ *     quantities using O(log2(k)) rather than O(k) multiplications.
+ *  2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ *     try to generate digits strictly left to right.  Instead, we
+ *     compute with fewer bits and propagate the carry if necessary
+ *     when rounding the final digit up.  This is often faster.
+ *  3. Under the assumption that input will be rounded nearest,
+ *     mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ *     That is, we allow equality in stopping tests when the
+ *     round-nearest rule will give the same floating-point value
+ *     as would satisfaction of the stopping test with strict
+ *     inequality.
+ *  4. We remove common factors of powers of 2 from relevant
+ *     quantities.
+ *  5. When converting floating-point integers less than 1e16,
+ *     we use floating-point arithmetic rather than resorting
+ *     to multiple-precision integers.
+ *  6. When asked to produce fewer than 15 digits, we first try
+ *     to get by with floating-point arithmetic; we resort to
+ *     multiple-precision integer arithmetic only if we cannot
+ *     guarantee that the floating-point calculation has given
+ *     the correctly rounded result.  For k requested digits and
+ *     "uniformly" distributed input, the probability is
+ *     something like 10^(k-15) that we must resort to the Long
+ *     calculation.
+ */
+
+/* Always emits at least one digit. */
+/* If biasUp is set, then rounding in modes 2 and 3 will round away from zero
+ * when the number is exactly halfway between two representable values.  For example,
+ * rounding 2.5 to zero digits after the decimal point will return 3 and not 2.
+ * 2.49 will still round to 2, and 2.51 will still round to 3. */
+/* bufsize should be at least 20 for modes 0 and 1.  For the other modes,
+ * bufsize should be two greater than the maximum number of output characters expected. */
+static JSBool
+js_dtoa(double d, int mode, JSBool biasUp, int ndigits,
+    int *decpt, int *sign, char **rve, char *buf, size_t bufsize)
+{
+    /*  Arguments ndigits, decpt, sign are similar to those
+        of ecvt and fcvt; trailing zeros are suppressed from
+        the returned string.  If not null, *rve is set to point
+        to the end of the return value.  If d is +-Infinity or NaN,
+        then *decpt is set to 9999.
+
+        mode:
+        0 ==> shortest string that yields d when read in
+        and rounded to nearest.
+        1 ==> like 0, but with Steele & White stopping rule;
+        e.g. with IEEE P754 arithmetic , mode 0 gives
+        1e23 whereas mode 1 gives 9.999999999999999e22.
+        2 ==> max(1,ndigits) significant digits.  This gives a
+        return value similar to that of ecvt, except
+        that trailing zeros are suppressed.
+        3 ==> through ndigits past the decimal point.  This
+        gives a return value similar to that from fcvt,
+        except that trailing zeros are suppressed, and
+        ndigits can be negative.
+        4-9 should give the same return values as 2-3, i.e.,
+        4 <= mode <= 9 ==> same return as mode
+        2 + (mode & 1).  These modes are mainly for
+        debugging; often they run slower but sometimes
+        faster than modes 2-3.
+        4,5,8,9 ==> left-to-right digit generation.
+        6-9 ==> don't try fast floating-point estimate
+        (if applicable).
+
+        Values of mode other than 0-9 are treated as mode 0.
+
+        Sufficient space is allocated to the return value
+        to hold the suppressed trailing zeros.
+    */
+
+    int32 bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
+        j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+        spec_case, try_quick;
+    Long L;
+#ifndef Sudden_Underflow
+    int32 denorm;
+    ULong x;
+#endif
+    Bigint *b, *b1, *delta, *mlo, *mhi, *S;
+    double d2, ds, eps;
+    char *s;
+
+    if (word0(d) & Sign_bit) {
+        /* set sign for everything, including 0's and NaNs */
+        *sign = 1;
+        set_word0(d, word0(d) & ~Sign_bit);  /* clear sign bit */
+    }
+    else
+        *sign = 0;
+
+    if ((word0(d) & Exp_mask) == Exp_mask) {
+        /* Infinity or NaN */
+        *decpt = 9999;
+        s = !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN";
+        if ((s[0] == 'I' && bufsize < 9) || (s[0] == 'N' && bufsize < 4)) {
+            JS_ASSERT(JS_FALSE);
+/*          JS_SetError(JS_BUFFER_OVERFLOW_ERROR, 0); */
+            return JS_FALSE;
+        }
+        strcpy(buf, s);
+        if (rve) {
+            *rve = buf[3] ? buf + 8 : buf + 3;
+            JS_ASSERT(**rve == '\0');
+        }
+        return JS_TRUE;
+    }
+
+    b = NULL;                           /* initialize for abort protection */
+    S = NULL;
+    mlo = mhi = NULL;
+
+    if (!d) {
+      no_digits:
+        *decpt = 1;
+        if (bufsize < 2) {
+            JS_ASSERT(JS_FALSE);
+/*          JS_SetError(JS_BUFFER_OVERFLOW_ERROR, 0); */
+            return JS_FALSE;
+        }
+        buf[0] = '0'; buf[1] = '\0';  /* copy "0" to buffer */
+        if (rve)
+            *rve = buf + 1;
+        /* We might have jumped to "no_digits" from below, so we need
+         * to be sure to free the potentially allocated Bigints to avoid
+         * memory leaks. */
+        Bfree(b);
+        Bfree(S);
+        if (mlo != mhi)
+            Bfree(mlo);
+        Bfree(mhi);
+        return JS_TRUE;
+    }
+
+    b = d2b(d, &be, &bbits);
+    if (!b)
+        goto nomem;
+#ifdef Sudden_Underflow
+    i = (int32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+    if ((i = (int32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
+#endif
+        d2 = d;
+        set_word0(d2, word0(d2) & Frac_mask1);
+        set_word0(d2, word0(d2) | Exp_11);
+
+        /* log(x)   ~=~ log(1.5) + (x-1.5)/1.5
+         * log10(x)  =  log(x) / log(10)
+         *      ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+         * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+         *
+         * This suggests computing an approximation k to log10(d) by
+         *
+         * k = (i - Bias)*0.301029995663981
+         *  + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+         *
+         * We want k to be too large rather than too small.
+         * The error in the first-order Taylor series approximation
+         * is in our favor, so we just round up the constant enough
+         * to compensate for any error in the multiplication of
+         * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+         * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+         * adding 1e-13 to the constant term more than suffices.
+         * Hence we adjust the constant term to 0.1760912590558.
+         * (We could get a more accurate k by invoking log10,
+         *  but this is probably not worthwhile.)
+         */
+
+        i -= Bias;
+#ifndef Sudden_Underflow
+        denorm = 0;
+    }
+    else {
+        /* d is denormalized */
+
+        i = bbits + be + (Bias + (P-1) - 1);
+        x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) : word1(d) << (32 - i);
+        d2 = x;
+        set_word0(d2, word0(d2) - 31*Exp_msk1); /* adjust exponent */
+        i -= (Bias + (P-1) - 1) + 1;
+        denorm = 1;
+    }
+#endif
+    /* At this point d = f*2^i, where 1 <= f < 2.  d2 is an approximation of f. */
+    ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+    k = (int32)ds;
+    if (ds < 0. && ds != k)
+        k--;    /* want k = floor(ds) */
+    k_check = 1;
+    if (k >= 0 && k <= Ten_pmax) {
+        if (d < tens[k])
+            k--;
+        k_check = 0;
+    }
+    /* At this point floor(log10(d)) <= k <= floor(log10(d))+1.
+       If k_check is zero, we're guaranteed that k = floor(log10(d)). */
+    j = bbits - i - 1;
+    /* At this point d = b/2^j, where b is an odd integer. */
+    if (j >= 0) {
+        b2 = 0;
+        s2 = j;
+    }
+    else {
+        b2 = -j;
+        s2 = 0;
+    }
+    if (k >= 0) {
+        b5 = 0;
+        s5 = k;
+        s2 += k;
+    }
+    else {
+        b2 -= k;
+        b5 = -k;
+        s5 = 0;
+    }
+    /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer,
+       b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */
+    if (mode < 0 || mode > 9)
+        mode = 0;
+    try_quick = 1;
+    if (mode > 5) {
+        mode -= 4;
+        try_quick = 0;
+    }
+    leftright = 1;
+    ilim = ilim1 = 0;
+    switch(mode) {
+    case 0:
+    case 1:
+        ilim = ilim1 = -1;
+        i = 18;
+        ndigits = 0;
+        break;
+    case 2:
+        leftright = 0;
+        /* no break */
+    case 4:
+        if (ndigits <= 0)
+            ndigits = 1;
+        ilim = ilim1 = i = ndigits;
+        break;
+    case 3:
+        leftright = 0;
+        /* no break */
+    case 5:
+        i = ndigits + k + 1;
+        ilim = i;
+        ilim1 = i - 1;
+        if (i <= 0)
+            i = 1;
+    }
+    /* ilim is the maximum number of significant digits we want, based on k and ndigits. */
+    /* ilim1 is the maximum number of significant digits we want, based on k and ndigits,
+       when it turns out that k was computed too high by one. */
+
+    /* Ensure space for at least i+1 characters, including trailing null. */
+    if (bufsize <= (size_t)i) {
+        Bfree(b);
+        JS_ASSERT(JS_FALSE);
+        return JS_FALSE;
+    }
+    s = buf;
+
+    if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+        /* Try to get by with floating-point arithmetic. */
+
+        i = 0;
+        d2 = d;
+        k0 = k;
+        ilim0 = ilim;
+        ieps = 2; /* conservative */
+        /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */
+        if (k > 0) {
+            ds = tens[k&0xf];
+            j = k >> 4;
+            if (j & Bletch) {
+                /* prevent overflows */
+                j &= Bletch - 1;
+                d /= bigtens[n_bigtens-1];
+                ieps++;
+            }
+            for(; j; j >>= 1, i++)
+                if (j & 1) {
+                    ieps++;
+                    ds *= bigtens[i];
+                }
+            d /= ds;
+        }
+        else if ((j1 = -k) != 0) {
+            d *= tens[j1 & 0xf];
+            for(j = j1 >> 4; j; j >>= 1, i++)
+                if (j & 1) {
+                    ieps++;
+                    d *= bigtens[i];
+                }
+        }
+        /* Check that k was computed correctly. */
+        if (k_check && d < 1. && ilim > 0) {
+            if (ilim1 <= 0)
+                goto fast_failed;
+            ilim = ilim1;
+            k--;
+            d *= 10.;
+            ieps++;
+        }
+        /* eps bounds the cumulative error. */
+        eps = ieps*d + 7.;
+        set_word0(eps, word0(eps) - (P-1)*Exp_msk1);
+        if (ilim == 0) {
+            S = mhi = 0;
+            d -= 5.;
+            if (d > eps)
+                goto one_digit;
+            if (d < -eps)
+                goto no_digits;
+            goto fast_failed;
+        }
+#ifndef No_leftright
+        if (leftright) {
+            /* Use Steele & White method of only
+             * generating digits needed.
+             */
+            eps = 0.5/tens[ilim-1] - eps;
+            for(i = 0;;) {
+                L = (Long)d;
+                d -= L;
+                *s++ = '0' + (char)L;
+                if (d < eps)
+                    goto ret1;
+                if (1. - d < eps)
+                    goto bump_up;
+                if (++i >= ilim)
+                    break;
+                eps *= 10.;
+                d *= 10.;
+            }
+        }
+        else {
+#endif
+            /* Generate ilim digits, then fix them up. */
+            eps *= tens[ilim-1];
+            for(i = 1;; i++, d *= 10.) {
+                L = (Long)d;
+                d -= L;
+                *s++ = '0' + (char)L;
+                if (i == ilim) {
+                    if (d > 0.5 + eps)
+                        goto bump_up;
+                    else if (d < 0.5 - eps) {
+                        while(*--s == '0') ;
+                        s++;
+                        goto ret1;
+                    }
+                    break;
+                }
+            }
+#ifndef No_leftright
+        }
+#endif
+    fast_failed:
+        s = buf;
+        d = d2;
+        k = k0;
+        ilim = ilim0;
+    }
+
+    /* Do we have a "small" integer? */
+
+    if (be >= 0 && k <= Int_max) {
+        /* Yes. */
+        ds = tens[k];
+        if (ndigits < 0 && ilim <= 0) {
+            S = mhi = 0;
+            if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds))
+                goto no_digits;
+            goto one_digit;
+        }
+        for(i = 1;; i++) {
+            L = (Long) (d / ds);
+            d -= L*ds;
+#ifdef Check_FLT_ROUNDS
+            /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+            if (d < 0) {
+                L--;
+                d += ds;
+            }
+#endif
+            *s++ = '0' + (char)L;
+            if (i == ilim) {
+                d += d;
+                if ((d > ds) || (d == ds && (L & 1 || biasUp))) {
+                bump_up:
+                    while(*--s == '9')
+                        if (s == buf) {
+                            k++;
+                            *s = '0';
+                            break;
+                        }
+                    ++*s++;
+                }
+                break;
+            }
+            if (!(d *= 10.))
+                break;
+        }
+        goto ret1;
+    }
+
+    m2 = b2;
+    m5 = b5;
+    if (leftright) {
+        if (mode < 2) {
+            i =
+#ifndef Sudden_Underflow
+                denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+            1 + P - bbits;
+            /* i is 1 plus the number of trailing zero bits in d's significand. Thus,
+               (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */
+        }
+        else {
+            j = ilim - 1;
+            if (m5 >= j)
+                m5 -= j;
+            else {
+                s5 += j -= m5;
+                b5 += j;
+                m5 = 0;
+            }
+            if ((i = ilim) < 0) {
+                m2 -= i;
+                i = 0;
+            }
+            /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */
+        }
+        b2 += i;
+        s2 += i;
+        mhi = i2b(1);
+        if (!mhi)
+            goto nomem;
+        /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or
+           input (when mode < 2) significant digit, divided by 10^k. */
+    }
+    /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5).  Reduce common factors in
+       b2, m2, and s2 without changing the equalities. */
+    if (m2 > 0 && s2 > 0) {
+        i = m2 < s2 ? m2 : s2;
+        b2 -= i;
+        m2 -= i;
+        s2 -= i;
+    }
+
+    /* Fold b5 into b and m5 into mhi. */
+    if (b5 > 0) {
+        if (leftright) {
+            if (m5 > 0) {
+                mhi = pow5mult(mhi, m5);
+                if (!mhi)
+                    goto nomem;
+                b1 = mult(mhi, b);
+                if (!b1)
+                    goto nomem;
+                Bfree(b);
+                b = b1;
+            }
+            if ((j = b5 - m5) != 0) {
+                b = pow5mult(b, j);
+                if (!b)
+                    goto nomem;
+            }
+        }
+        else {
+            b = pow5mult(b, b5);
+            if (!b)
+                goto nomem;
+        }
+    }
+    /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and
+       (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */
+
+    S = i2b(1);
+    if (!S)
+        goto nomem;
+    if (s5 > 0) {
+        S = pow5mult(S, s5);
+        if (!S)
+            goto nomem;
+    }
+    /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and
+       (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */
+
+    /* Check for special case that d is a normalized power of 2. */
+    spec_case = 0;
+    if (mode < 2) {
+        if (!word1(d) && !(word0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+            && word0(d) & (Exp_mask & Exp_mask << 1)
+#endif
+            ) {
+            /* The special case.  Here we want to be within a quarter of the last input
+               significant digit instead of one half of it when the decimal output string's value is less than d.  */
+            b2 += Log2P;
+            s2 += Log2P;
+            spec_case = 1;
+        }
+    }
+
+    /* Arrange for convenient computation of quotients:
+     * shift left if necessary so divisor has 4 leading 0 bits.
+     *
+     * Perhaps we should just compute leading 28 bits of S once
+     * and for all and pass them and a shift to quorem, so it
+     * can do shifts and ors to compute the numerator for q.
+     */
+    if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
+        i = 32 - i;
+    /* i is the number of leading zero bits in the most significant word of S*2^s2. */
+    if (i > 4) {
+        i -= 4;
+        b2 += i;
+        m2 += i;
+        s2 += i;
+    }
+    else if (i < 4) {
+        i += 28;
+        b2 += i;
+        m2 += i;
+        s2 += i;
+    }
+    /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */
+    if (b2 > 0) {
+        b = lshift(b, b2);
+        if (!b)
+            goto nomem;
+    }
+    if (s2 > 0) {
+        S = lshift(S, s2);
+        if (!S)
+            goto nomem;
+    }
+    /* Now we have d/10^k = b/S and
+       (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */
+    if (k_check) {
+        if (cmp(b,S) < 0) {
+            k--;
+            b = multadd(b, 10, 0);  /* we botched the k estimate */
+            if (!b)
+                goto nomem;
+            if (leftright) {
+                mhi = multadd(mhi, 10, 0);
+                if (!mhi)
+                    goto nomem;
+            }
+            ilim = ilim1;
+        }
+    }
+    /* At this point 1 <= d/10^k = b/S < 10. */
+
+    if (ilim <= 0 && mode > 2) {
+        /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode.
+           Output either zero or the minimum nonzero output depending on which is closer to d. */
+        if (ilim < 0)
+            goto no_digits;
+        S = multadd(S,5,0);
+        if (!S)
+            goto nomem;
+        i = cmp(b,S);
+        if (i < 0 || (i == 0 && !biasUp)) {
+        /* Always emit at least one digit.  If the number appears to be zero
+           using the current mode, then emit one '0' digit and set decpt to 1. */
+        /*no_digits:
+            k = -1 - ndigits;
+            goto ret; */
+            goto no_digits;
+        }
+    one_digit:
+        *s++ = '1';
+        k++;
+        goto ret;
+    }
+    if (leftright) {
+        if (m2 > 0) {
+            mhi = lshift(mhi, m2);
+            if (!mhi)
+                goto nomem;
+        }
+
+        /* Compute mlo -- check for special case
+         * that d is a normalized power of 2.
+         */
+
+        mlo = mhi;
+        if (spec_case) {
+            mhi = Balloc(mhi->k);
+            if (!mhi)
+                goto nomem;
+            Bcopy(mhi, mlo);
+            mhi = lshift(mhi, Log2P);
+            if (!mhi)
+                goto nomem;
+        }
+        /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */
+        /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */
+
+        for(i = 1;;i++) {
+            dig = quorem(b,S) + '0';
+            /* Do we yet have the shortest decimal string
+             * that will round to d?
+             */
+            j = cmp(b, mlo);
+            /* j is b/S compared with mlo/S. */
+            delta = diff(S, mhi);
+            if (!delta)
+                goto nomem;
+            j1 = delta->sign ? 1 : cmp(b, delta);
+            Bfree(delta);
+            /* j1 is b/S compared with 1 - mhi/S. */
+#ifndef ROUND_BIASED
+            if (j1 == 0 && !mode && !(word1(d) & 1)) {
+                if (dig == '9')
+                    goto round_9_up;
+                if (j > 0)
+                    dig++;
+                *s++ = (char)dig;
+                goto ret;
+            }
+#endif
+            if ((j < 0) || (j == 0 && !mode
+#ifndef ROUND_BIASED
+                && !(word1(d) & 1)
+#endif
+                )) {
+                if (j1 > 0) {
+                    /* Either dig or dig+1 would work here as the least significant decimal digit.
+                       Use whichever would produce a decimal value closer to d. */
+                    b = lshift(b, 1);
+                    if (!b)
+                        goto nomem;
+                    j1 = cmp(b, S);
+                    if (((j1 > 0) || (j1 == 0 && (dig & 1 || biasUp)))
+                        && (dig++ == '9'))
+                        goto round_9_up;
+                }
+                *s++ = (char)dig;
+                goto ret;
+            }
+            if (j1 > 0) {
+                if (dig == '9') { /* possible if i == 1 */
+                round_9_up:
+                    *s++ = '9';
+                    goto roundoff;
+                }
+                *s++ = (char)dig + 1;
+                goto ret;
+            }
+            *s++ = (char)dig;
+            if (i == ilim)
+                break;
+            b = multadd(b, 10, 0);
+            if (!b)
+                goto nomem;
+            if (mlo == mhi) {
+                mlo = mhi = multadd(mhi, 10, 0);
+                if (!mhi)
+                    goto nomem;
+            }
+            else {
+                mlo = multadd(mlo, 10, 0);
+                if (!mlo)
+                    goto nomem;
+                mhi = multadd(mhi, 10, 0);
+                if (!mhi)
+                    goto nomem;
+            }
+        }
+    }
+    else
+        for(i = 1;; i++) {
+            *s++ = (char)(dig = quorem(b,S) + '0');
+            if (i >= ilim)
+                break;
+            b = multadd(b, 10, 0);
+            if (!b)
+                goto nomem;
+        }
+
+    /* Round off last digit */
+
+    b = lshift(b, 1);
+    if (!b)
+        goto nomem;
+    j = cmp(b, S);
+    if ((j > 0) || (j == 0 && (dig & 1 || biasUp))) {
+    roundoff:
+        while(*--s == '9')
+            if (s == buf) {
+                k++;
+                *s++ = '1';
+                goto ret;
+            }
+        ++*s++;
+    }
+    else {
+        /* Strip trailing zeros */
+        while(*--s == '0') ;
+        s++;
+    }
+  ret:
+    Bfree(S);
+    if (mhi) {
+        if (mlo && mlo != mhi)
+            Bfree(mlo);
+        Bfree(mhi);
+    }
+  ret1:
+    Bfree(b);
+    JS_ASSERT(s < buf + bufsize);
+    *s = '\0';
+    if (rve)
+        *rve = s;
+    *decpt = k + 1;
+    return JS_TRUE;
+
+nomem:
+    Bfree(S);
+    if (mhi) {
+        if (mlo && mlo != mhi)
+            Bfree(mlo);
+        Bfree(mhi);
+    }
+    Bfree(b);
+    return JS_FALSE;
+}
+
+
+/* Mapping of JSDToStrMode -> js_dtoa mode */
+static const int dtoaModes[] = {
+    0,   /* DTOSTR_STANDARD */
+    0,   /* DTOSTR_STANDARD_EXPONENTIAL, */
+    3,   /* DTOSTR_FIXED, */
+    2,   /* DTOSTR_EXPONENTIAL, */
+    2};  /* DTOSTR_PRECISION */
+
+JS_FRIEND_API(char *)
+JS_dtostr(char *buffer, size_t bufferSize, JSDToStrMode mode, int precision, double d)
+{
+    int decPt;                  /* Position of decimal point relative to first digit returned by js_dtoa */
+    int sign;                   /* Nonzero if the sign bit was set in d */
+    int nDigits;                /* Number of significand digits returned by js_dtoa */
+    char *numBegin = buffer+2;  /* Pointer to the digits returned by js_dtoa; the +2 leaves space for */
+                                /* the sign and/or decimal point */
+    char *numEnd;               /* Pointer past the digits returned by js_dtoa */
+    JSBool dtoaRet;
+
+    JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? DTOSTR_STANDARD_BUFFER_SIZE :
+            DTOSTR_VARIABLE_BUFFER_SIZE(precision)));
+
+    if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21))
+        mode = DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */
+
+    /* Locking for Balloc's shared buffers */
+    ACQUIRE_DTOA_LOCK();
+    dtoaRet = js_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, &decPt, &sign, &numEnd, numBegin, bufferSize-2);
+    RELEASE_DTOA_LOCK();
+    if (!dtoaRet)
+        return 0;
+
+    nDigits = numEnd - numBegin;
+
+    /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */
+    if (decPt != 9999) {
+        JSBool exponentialNotation = JS_FALSE;
+        int minNDigits = 0;         /* Minimum number of significand digits required by mode and precision */
+        char *p;
+        char *q;
+
+        switch (mode) {
+            case DTOSTR_STANDARD:
+                if (decPt < -5 || decPt > 21)
+                    exponentialNotation = JS_TRUE;
+                else
+                    minNDigits = decPt;
+                break;
+
+            case DTOSTR_FIXED:
+                if (precision >= 0)
+                    minNDigits = decPt + precision;
+                else
+                    minNDigits = decPt;
+                break;
+
+            case DTOSTR_EXPONENTIAL:
+                JS_ASSERT(precision > 0);
+                minNDigits = precision;
+                /* Fall through */
+            case DTOSTR_STANDARD_EXPONENTIAL:
+                exponentialNotation = JS_TRUE;
+                break;
+
+            case DTOSTR_PRECISION:
+                JS_ASSERT(precision > 0);
+                minNDigits = precision;
+                if (decPt < -5 || decPt > precision)
+                    exponentialNotation = JS_TRUE;
+                break;
+        }
+
+        /* If the number has fewer than minNDigits, pad it with zeros at the end */
+        if (nDigits < minNDigits) {
+            p = numBegin + minNDigits;
+            nDigits = minNDigits;
+            do {
+                *numEnd++ = '0';
+            } while (numEnd != p);
+            *numEnd = '\0';
+        }
+
+        if (exponentialNotation) {
+            /* Insert a decimal point if more than one significand digit */
+            if (nDigits != 1) {
+                numBegin--;
+                numBegin[0] = numBegin[1];
+                numBegin[1] = '.';
+            }
+            JS_snprintf(numEnd, bufferSize - (numEnd - buffer), "e%+d", decPt-1);
+        } else if (decPt != nDigits) {
+            /* Some kind of a fraction in fixed notation */
+            JS_ASSERT(decPt <= nDigits);
+            if (decPt > 0) {
+                /* dd...dd . dd...dd */
+                p = --numBegin;
+                do {
+                    *p = p[1];
+                    p++;
+                } while (--decPt);
+                *p = '.';
+            } else {
+                /* 0 . 00...00dd...dd */
+                p = numEnd;
+                numEnd += 1 - decPt;
+                q = numEnd;
+                JS_ASSERT(numEnd < buffer + bufferSize);
+                *numEnd = '\0';
+                while (p != numBegin)
+                    *--q = *--p;
+                for (p = numBegin + 1; p != q; p++)
+                    *p = '0';
+                *numBegin = '.';
+                *--numBegin = '0';
+            }
+        }
+    }
+
+    /* If negative and neither -0.0 nor NaN, output a leading '-'. */
+    if (sign &&
+            !(word0(d) == Sign_bit && word1(d) == 0) &&
+            !((word0(d) & Exp_mask) == Exp_mask &&
+              (word1(d) || (word0(d) & Frac_mask)))) {
+        *--numBegin = '-';
+    }
+    return numBegin;
+}
+
+
+/* Let b = floor(b / divisor), and return the remainder.  b must be nonnegative.
+ * divisor must be between 1 and 65536.
+ * This function cannot run out of memory. */
+static uint32
+divrem(Bigint *b, uint32 divisor)
+{
+    int32 n = b->wds;
+    uint32 remainder = 0;
+    ULong *bx;
+    ULong *bp;
+
+    JS_ASSERT(divisor > 0 && divisor <= 65536);
+
+    if (!n)
+        return 0; /* b is zero */
+    bx = b->x;
+    bp = bx + n;
+    do {
+        ULong a = *--bp;
+        ULong dividend = remainder << 16 | a >> 16;
+        ULong quotientHi = dividend / divisor;
+        ULong quotientLo;
+
+        remainder = dividend - quotientHi*divisor;
+        JS_ASSERT(quotientHi <= 0xFFFF && remainder < divisor);
+        dividend = remainder << 16 | (a & 0xFFFF);
+        quotientLo = dividend / divisor;
+        remainder = dividend - quotientLo*divisor;
+        JS_ASSERT(quotientLo <= 0xFFFF && remainder < divisor);
+        *bp = quotientHi << 16 | quotientLo;
+    } while (bp != bx);
+    /* Decrease the size of the number if its most significant word is now zero. */
+    if (bx[n-1] == 0)
+        b->wds--;
+    return remainder;
+}
+
+
+/* "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce,
+ * which occurs when printing -5e-324 in binary.  We could compute a better estimate of the size of
+ * the output string and malloc fewer bytes depending on d and base, but why bother? */
+#define DTOBASESTR_BUFFER_SIZE 1078
+#define BASEDIGIT(digit) ((char)(((digit) >= 10) ? 'a' - 10 + (digit) : '0' + (digit)))
+
+JS_FRIEND_API(char *)
+JS_dtobasestr(int base, double d)
+{
+    char *buffer;        /* The output string */
+    char *p;             /* Pointer to current position in the buffer */
+    char *pInt;          /* Pointer to the beginning of the integer part of the string */
+    char *q;
+    uint32 digit;
+    double di;           /* d truncated to an integer */
+    double df;           /* The fractional part of d */
+
+    JS_ASSERT(base >= 2 && base <= 36);
+
+    buffer = (char*) malloc(DTOBASESTR_BUFFER_SIZE);
+    if (buffer) {
+        p = buffer;
+        if (d < 0.0
+#if defined(XP_WIN) || defined(XP_OS2)
+            && !((word0(d) & Exp_mask) == Exp_mask && ((word0(d) & Frac_mask) || word1(d))) /* Visual C++ doesn't know how to compare against NaN */
+#endif
+           ) {
+            *p++ = '-';
+            d = -d;
+        }
+
+        /* Check for Infinity and NaN */
+        if ((word0(d) & Exp_mask) == Exp_mask) {
+            strcpy(p, !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN");
+            return buffer;
+        }
+
+        /* Locking for Balloc's shared buffers */
+        ACQUIRE_DTOA_LOCK();
+
+        /* Output the integer part of d with the digits in reverse order. */
+        pInt = p;
+        di = fd_floor(d);
+        if (di <= 4294967295.0) {
+            uint32 n = (uint32)di;
+            if (n)
+                do {
+                    uint32 m = n / base;
+                    digit = n - m*base;
+                    n = m;
+                    JS_ASSERT(digit < (uint32)base);
+                    *p++ = BASEDIGIT(digit);
+                } while (n);
+            else *p++ = '0';
+        } else {
+            int32 e;
+            int32 bits;  /* Number of significant bits in di; not used. */
+            Bigint *b = d2b(di, &e, &bits);
+            if (!b)
+                goto nomem1;
+            b = lshift(b, e);
+            if (!b) {
+              nomem1:
+                Bfree(b);
+                return NULL;
+            }
+            do {
+                digit = divrem(b, base);
+                JS_ASSERT(digit < (uint32)base);
+                *p++ = BASEDIGIT(digit);
+            } while (b->wds);
+            Bfree(b);
+        }
+        /* Reverse the digits of the integer part of d. */
+        q = p-1;
+        while (q > pInt) {
+            char ch = *pInt;
+            *pInt++ = *q;
+            *q-- = ch;
+        }
+
+        df = d - di;
+        if (df != 0.0) {
+            /* We have a fraction. */
+            int32 e, bbits, s2, done;
+            Bigint *b, *s, *mlo, *mhi;
+
+            b = s = mlo = mhi = NULL;
+
+            *p++ = '.';
+            b = d2b(df, &e, &bbits);
+            if (!b) {
+              nomem2:
+                Bfree(b);
+                Bfree(s);
+                if (mlo != mhi)
+                    Bfree(mlo);
+                Bfree(mhi);
+                return NULL;
+            }
+            JS_ASSERT(e < 0);
+            /* At this point df = b * 2^e.  e must be less than zero because 0 < df < 1. */
+
+            s2 = -(int32)(word0(d) >> Exp_shift1 & Exp_mask>>Exp_shift1);
+#ifndef Sudden_Underflow
+            if (!s2)
+                s2 = -1;
+#endif
+            s2 += Bias + P;
+            /* 1/2^s2 = (nextDouble(d) - d)/2 */
+            JS_ASSERT(-s2 < e);
+            mlo = i2b(1);
+            if (!mlo)
+                goto nomem2;
+            mhi = mlo;
+            if (!word1(d) && !(word0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+                && word0(d) & (Exp_mask & Exp_mask << 1)
+#endif
+                ) {
+                /* The special case.  Here we want to be within a quarter of the last input
+                   significant digit instead of one half of it when the output string's value is less than d.  */
+                s2 += Log2P;
+                mhi = i2b(1<<Log2P);
+                if (!mhi)
+                    goto nomem2;
+            }
+            b = lshift(b, e + s2);
+            if (!b)
+                goto nomem2;
+            s = i2b(1);
+            if (!s)
+                goto nomem2;
+            s = lshift(s, s2);
+            if (!s)
+                goto nomem2;
+            /* At this point we have the following:
+             *   s = 2^s2;
+             *   1 > df = b/2^s2 > 0;
+             *   (d - prevDouble(d))/2 = mlo/2^s2;
+             *   (nextDouble(d) - d)/2 = mhi/2^s2. */
+
+            done = JS_FALSE;
+            do {
+                int32 j, j1;
+                Bigint *delta;
+
+                b = multadd(b, base, 0);
+                if (!b)
+                    goto nomem2;
+                digit = quorem2(b, s2);
+                if (mlo == mhi) {
+                    mlo = mhi = multadd(mlo, base, 0);
+                    if (!mhi)
+                        goto nomem2;
+                }
+                else {
+                    mlo = multadd(mlo, base, 0);
+                    if (!mlo)
+                        goto nomem2;
+                    mhi = multadd(mhi, base, 0);
+                    if (!mhi)
+                        goto nomem2;
+                }
+
+                /* Do we yet have the shortest string that will round to d? */
+                j = cmp(b, mlo);
+                /* j is b/2^s2 compared with mlo/2^s2. */
+                delta = diff(s, mhi);
+                if (!delta)
+                    goto nomem2;
+                j1 = delta->sign ? 1 : cmp(b, delta);
+                Bfree(delta);
+                /* j1 is b/2^s2 compared with 1 - mhi/2^s2. */
+
+#ifndef ROUND_BIASED
+                if (j1 == 0 && !(word1(d) & 1)) {
+                    if (j > 0)
+                        digit++;
+                    done = JS_TRUE;
+                } else
+#endif
+                if (j < 0 || (j == 0
+#ifndef ROUND_BIASED
+                    && !(word1(d) & 1)
+#endif
+                    )) {
+                    if (j1 > 0) {
+                        /* Either dig or dig+1 would work here as the least significant digit.
+                           Use whichever would produce an output value closer to d. */
+                        b = lshift(b, 1);
+                        if (!b)
+                            goto nomem2;
+                        j1 = cmp(b, s);
+                        if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output
+                                     * such as 3.5 in base 3.  */
+                            digit++;
+                    }
+                    done = JS_TRUE;
+                } else if (j1 > 0) {
+                    digit++;
+                    done = JS_TRUE;
+                }
+                JS_ASSERT(digit < (uint32)base);
+                *p++ = BASEDIGIT(digit);
+            } while (!done);
+            Bfree(b);
+            Bfree(s);
+            if (mlo != mhi)
+                Bfree(mlo);
+            Bfree(mhi);
+        }
+        JS_ASSERT(p < buffer + DTOBASESTR_BUFFER_SIZE);
+        *p = '\0';
+        RELEASE_DTOA_LOCK();
+    }
+    return buffer;
+}

Added: freeswitch/trunk/libs/js/src/jsdtoa.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsdtoa.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,130 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsdtoa_h___
+#define jsdtoa_h___
+/*
+ * Public interface to portable double-precision floating point to string
+ * and back conversion package.
+ */
+
+#include "jscompat.h"
+
+JS_BEGIN_EXTERN_C
+
+/*
+ * JS_strtod() returns as a double-precision floating-point number
+ * the  value represented by the character string pointed to by
+ * s00.  The string is scanned up to  the  first  unrecognized
+ * character.
+ * If the value of se is not (char **)NULL,  a  pointer  to
+ * the  character terminating the scan is returned in the location pointed
+ * to by se.  If no number can be  formed, se is set to s00r, and
+ * zero is returned.
+ *
+ * *err is set to zero on success; it's set to JS_DTOA_ERANGE on range
+ * errors and JS_DTOA_ENOMEM on memory failure.
+ */
+#define JS_DTOA_ERANGE 1
+#define JS_DTOA_ENOMEM 2
+JS_FRIEND_API(double)
+JS_strtod(const char *s00, char **se, int *err);
+
+/*
+ * Modes for converting floating-point numbers to strings.
+ *
+ * Some of the modes can round-trip; this means that if the number is converted to
+ * a string using one of these mode and then converted back to a number, the result
+ * will be identical to the original number (except that, due to ECMA, -0 will get converted
+ * to +0).  These round-trip modes return the minimum number of significand digits that
+ * permit the round trip.
+ *
+ * Some of the modes take an integer parameter <precision>.
+ */
+/* NB: Keep this in sync with number_constants[]. */
+typedef enum JSDToStrMode {
+    DTOSTR_STANDARD,              /* Either fixed or exponential format; round-trip */
+    DTOSTR_STANDARD_EXPONENTIAL,  /* Always exponential format; round-trip */
+    DTOSTR_FIXED,                 /* Round to <precision> digits after the decimal point; exponential if number is large */
+    DTOSTR_EXPONENTIAL,           /* Always exponential format; <precision> significant digits */
+    DTOSTR_PRECISION              /* Either fixed or exponential format; <precision> significant digits */
+} JSDToStrMode;
+
+
+/* Maximum number of characters (including trailing null) that a DTOSTR_STANDARD or DTOSTR_STANDARD_EXPONENTIAL
+ * conversion can produce.  This maximum is reached for a number like -0.0000012345678901234567. */
+#define DTOSTR_STANDARD_BUFFER_SIZE 26
+
+/* Maximum number of characters (including trailing null) that one of the other conversions
+ * can produce.  This maximum is reached for TO_FIXED, which can generate up to 21 digits before the decimal point. */
+#define DTOSTR_VARIABLE_BUFFER_SIZE(precision) ((precision)+24 > DTOSTR_STANDARD_BUFFER_SIZE ? (precision)+24 : DTOSTR_STANDARD_BUFFER_SIZE)
+
+/*
+ * Convert dval according to the given mode and return a pointer to the resulting ASCII string.
+ * The result is held somewhere in buffer, but not necessarily at the beginning.  The size of
+ * buffer is given in bufferSize, and must be at least as large as given by the above macros.
+ *
+ * Return NULL if out of memory.
+ */
+JS_FRIEND_API(char *)
+JS_dtostr(char *buffer, size_t bufferSize, JSDToStrMode mode, int precision, double dval);
+
+/*
+ * Convert d to a string in the given base.  The integral part of d will be printed exactly
+ * in that base, regardless of how large it is, because there is no exponential notation for non-base-ten
+ * numbers.  The fractional part will be rounded to as few digits as possible while still preserving
+ * the round-trip property (analogous to that of printing decimal numbers).  In other words, if one were
+ * to read the resulting string in via a hypothetical base-number-reading routine that rounds to the nearest
+ * IEEE double (and to an even significand if there are two equally near doubles), then the result would
+ * equal d (except for -0.0, which converts to "0", and NaN, which is not equal to itself).
+ *
+ * Return NULL if out of memory.  If the result is not NULL, it must be released via free().
+ */
+JS_FRIEND_API(char *)
+JS_dtobasestr(int base, double d);
+
+/*
+ * Clean up any persistent RAM allocated during the execution of DtoA
+ * routines, and remove any locks that might have been created.
+ */
+extern void js_FinishDtoa(void);
+
+JS_END_EXTERN_C
+
+#endif /* jsdtoa_h___ */

Added: freeswitch/trunk/libs/js/src/jsemit.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsemit.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5360 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS bytecode generation.
+ */
+#include "jsstddef.h"
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#include <string.h>
+#include "jstypes.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsbit.h"
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsemit.h"
+#include "jsfun.h"
+#include "jsnum.h"
+#include "jsopcode.h"
+#include "jsparse.h"
+#include "jsregexp.h"
+#include "jsscan.h"
+#include "jsscope.h"
+#include "jsscript.h"
+
+/* Allocation chunk counts, must be powers of two in general. */
+#define BYTECODE_CHUNK  256     /* code allocation increment */
+#define SRCNOTE_CHUNK   64      /* initial srcnote allocation increment */
+#define TRYNOTE_CHUNK   64      /* trynote allocation increment */
+
+/* Macros to compute byte sizes from typed element counts. */
+#define BYTECODE_SIZE(n)        ((n) * sizeof(jsbytecode))
+#define SRCNOTE_SIZE(n)         ((n) * sizeof(jssrcnote))
+#define TRYNOTE_SIZE(n)         ((n) * sizeof(JSTryNote))
+
+JS_FRIEND_API(JSBool)
+js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg,
+                     JSArenaPool *codePool, JSArenaPool *notePool,
+                     const char *filename, uintN lineno,
+                     JSPrincipals *principals)
+{
+    memset(cg, 0, sizeof *cg);
+    TREE_CONTEXT_INIT(&cg->treeContext);
+    cg->treeContext.flags |= TCF_COMPILING;
+    cg->codePool = codePool;
+    cg->notePool = notePool;
+    cg->codeMark = JS_ARENA_MARK(codePool);
+    cg->noteMark = JS_ARENA_MARK(notePool);
+    cg->tempMark = JS_ARENA_MARK(&cx->tempPool);
+    cg->current = &cg->main;
+    cg->filename = filename;
+    cg->firstLine = cg->prolog.currentLine = cg->main.currentLine = lineno;
+    cg->principals = principals;
+    ATOM_LIST_INIT(&cg->atomList);
+    cg->prolog.noteMask = cg->main.noteMask = SRCNOTE_CHUNK - 1;
+    ATOM_LIST_INIT(&cg->constList);
+    return JS_TRUE;
+}
+
+JS_FRIEND_API(void)
+js_FinishCodeGenerator(JSContext *cx, JSCodeGenerator *cg)
+{
+    TREE_CONTEXT_FINISH(&cg->treeContext);
+    JS_ARENA_RELEASE(cg->codePool, cg->codeMark);
+    JS_ARENA_RELEASE(cg->notePool, cg->noteMark);
+    JS_ARENA_RELEASE(&cx->tempPool, cg->tempMark);
+}
+
+static ptrdiff_t
+EmitCheck(JSContext *cx, JSCodeGenerator *cg, JSOp op, ptrdiff_t delta)
+{
+    jsbytecode *base, *limit, *next;
+    ptrdiff_t offset, length;
+    size_t incr, size;
+
+    base = CG_BASE(cg);
+    next = CG_NEXT(cg);
+    limit = CG_LIMIT(cg);
+    offset = PTRDIFF(next, base, jsbytecode);
+    if (next + delta > limit) {
+        length = offset + delta;
+        length = (length <= BYTECODE_CHUNK)
+                 ? BYTECODE_CHUNK
+                 : JS_BIT(JS_CeilingLog2(length));
+        incr = BYTECODE_SIZE(length);
+        if (!base) {
+            JS_ARENA_ALLOCATE_CAST(base, jsbytecode *, cg->codePool, incr);
+        } else {
+            size = BYTECODE_SIZE(PTRDIFF(limit, base, jsbytecode));
+            incr -= size;
+            JS_ARENA_GROW_CAST(base, jsbytecode *, cg->codePool, size, incr);
+        }
+        if (!base) {
+            JS_ReportOutOfMemory(cx);
+            return -1;
+        }
+        CG_BASE(cg) = base;
+        CG_LIMIT(cg) = base + length;
+        CG_NEXT(cg) = base + offset;
+    }
+    return offset;
+}
+
+static void
+UpdateDepth(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t target)
+{
+    jsbytecode *pc;
+    const JSCodeSpec *cs;
+    intN nuses;
+
+    pc = CG_CODE(cg, target);
+    cs = &js_CodeSpec[pc[0]];
+    nuses = cs->nuses;
+    if (nuses < 0)
+        nuses = 2 + GET_ARGC(pc);       /* stack: fun, this, [argc arguments] */
+    cg->stackDepth -= nuses;
+    JS_ASSERT(cg->stackDepth >= 0);
+    if (cg->stackDepth < 0) {
+        char numBuf[12];
+        JS_snprintf(numBuf, sizeof numBuf, "%d", target);
+        JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING,
+                                     js_GetErrorMessage, NULL,
+                                     JSMSG_STACK_UNDERFLOW,
+                                     cg->filename ? cg->filename : "stdin",
+                                     numBuf);
+    }
+    cg->stackDepth += cs->ndefs;
+    if ((uintN)cg->stackDepth > cg->maxStackDepth)
+        cg->maxStackDepth = cg->stackDepth;
+}
+
+ptrdiff_t
+js_Emit1(JSContext *cx, JSCodeGenerator *cg, JSOp op)
+{
+    ptrdiff_t offset = EmitCheck(cx, cg, op, 1);
+
+    if (offset >= 0) {
+        *CG_NEXT(cg)++ = (jsbytecode)op;
+        UpdateDepth(cx, cg, offset);
+    }
+    return offset;
+}
+
+ptrdiff_t
+js_Emit2(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1)
+{
+    ptrdiff_t offset = EmitCheck(cx, cg, op, 2);
+
+    if (offset >= 0) {
+        jsbytecode *next = CG_NEXT(cg);
+        next[0] = (jsbytecode)op;
+        next[1] = op1;
+        CG_NEXT(cg) = next + 2;
+        UpdateDepth(cx, cg, offset);
+    }
+    return offset;
+}
+
+ptrdiff_t
+js_Emit3(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1,
+         jsbytecode op2)
+{
+    ptrdiff_t offset = EmitCheck(cx, cg, op, 3);
+
+    if (offset >= 0) {
+        jsbytecode *next = CG_NEXT(cg);
+        next[0] = (jsbytecode)op;
+        next[1] = op1;
+        next[2] = op2;
+        CG_NEXT(cg) = next + 3;
+        UpdateDepth(cx, cg, offset);
+    }
+    return offset;
+}
+
+ptrdiff_t
+js_EmitN(JSContext *cx, JSCodeGenerator *cg, JSOp op, size_t extra)
+{
+    ptrdiff_t length = 1 + (ptrdiff_t)extra;
+    ptrdiff_t offset = EmitCheck(cx, cg, op, length);
+
+    if (offset >= 0) {
+        jsbytecode *next = CG_NEXT(cg);
+        *next = (jsbytecode)op;
+        memset(next + 1, 0, BYTECODE_SIZE(extra));
+        CG_NEXT(cg) = next + length;
+        UpdateDepth(cx, cg, offset);
+    }
+    return offset;
+}
+
+/* XXX too many "... statement" L10N gaffes below -- fix via js.msg! */
+const char js_with_statement_str[] = "with statement";
+const char js_script_str[]         = "script";
+
+static const char *statementName[] = {
+    "block",                 /* BLOCK */
+    "label statement",       /* LABEL */
+    "if statement",          /* IF */
+    "else statement",        /* ELSE */
+    "switch statement",      /* SWITCH */
+    js_with_statement_str,   /* WITH */
+    "try statement",         /* TRY */
+    "catch block",           /* CATCH */
+    "finally statement",     /* FINALLY */
+    "do loop",               /* DO_LOOP */
+    "for loop",              /* FOR_LOOP */
+    "for/in loop",           /* FOR_IN_LOOP */
+    "while loop",            /* WHILE_LOOP */
+};
+
+static const char *
+StatementName(JSCodeGenerator *cg)
+{
+    if (!cg->treeContext.topStmt)
+        return js_script_str;
+    return statementName[cg->treeContext.topStmt->type];
+}
+
+static void
+ReportStatementTooLarge(JSContext *cx, JSCodeGenerator *cg)
+{
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEED_DIET,
+                         StatementName(cg));
+}
+
+/**
+  Span-dependent instructions in JS bytecode consist of the jump (JOF_JUMP)
+  and switch (JOF_LOOKUPSWITCH, JOF_TABLESWITCH) format opcodes, subdivided
+  into unconditional (gotos and gosubs), and conditional jumps or branches
+  (which pop a value, test it, and jump depending on its value).  Most jumps
+  have just one immediate operand, a signed offset from the jump opcode's pc
+  to the target bytecode.  The lookup and table switch opcodes may contain
+  many jump offsets.
+
+  Mozilla bug #80981 (http://bugzilla.mozilla.org/show_bug.cgi?id=80981) was
+  fixed by adding extended "X" counterparts to the opcodes/formats (NB: X is
+  suffixed to prefer JSOP_ORX thereby avoiding a JSOP_XOR name collision for
+  the extended form of the JSOP_OR branch opcode).  The unextended or short
+  formats have 16-bit signed immediate offset operands, the extended or long
+  formats have 32-bit signed immediates.  The span-dependency problem consists
+  of selecting as few long instructions as possible, or about as few -- since
+  jumps can span other jumps, extending one jump may cause another to need to
+  be extended.
+
+  Most JS scripts are short, so need no extended jumps.  We optimize for this
+  case by generating short jumps until we know a long jump is needed.  After
+  that point, we keep generating short jumps, but each jump's 16-bit immediate
+  offset operand is actually an unsigned index into cg->spanDeps, an array of
+  JSSpanDep structs.  Each struct tells the top offset in the script of the
+  opcode, the "before" offset of the jump (which will be the same as top for
+  simplex jumps, but which will index further into the bytecode array for a
+  non-initial jump offset in a lookup or table switch), the after "offset"
+  adjusted during span-dependent instruction selection (initially the same
+  value as the "before" offset), and the jump target (more below).
+
+  Since we generate cg->spanDeps lazily, from within js_SetJumpOffset, we must
+  ensure that all bytecode generated so far can be inspected to discover where
+  the jump offset immediate operands lie within CG_CODE(cg).  But the bonus is
+  that we generate span-dependency records sorted by their offsets, so we can
+  binary-search when trying to find a JSSpanDep for a given bytecode offset,
+  or the nearest JSSpanDep at or above a given pc.
+
+  To avoid limiting scripts to 64K jumps, if the cg->spanDeps index overflows
+  65534, we store SPANDEP_INDEX_HUGE in the jump's immediate operand.  This
+  tells us that we need to binary-search for the cg->spanDeps entry by the
+  jump opcode's bytecode offset (sd->before).
+
+  Jump targets need to be maintained in a data structure that lets us look
+  up an already-known target by its address (jumps may have a common target),
+  and that also lets us update the addresses (script-relative, a.k.a. absolute
+  offsets) of targets that come after a jump target (for when a jump below
+  that target needs to be extended).  We use an AVL tree, implemented using
+  recursion, but with some tricky optimizations to its height-balancing code
+  (see http://www.cmcrossroads.com/bradapp/ftp/src/libs/C++/AvlTrees.html).
+
+  A final wrinkle: backpatch chains are linked by jump-to-jump offsets with
+  positive sign, even though they link "backward" (i.e., toward lower bytecode
+  address).  We don't want to waste space and search time in the AVL tree for
+  such temporary backpatch deltas, so we use a single-bit wildcard scheme to
+  tag true JSJumpTarget pointers and encode untagged, signed (positive) deltas
+  in JSSpanDep.target pointers, depending on whether the JSSpanDep has a known
+  target, or is still awaiting backpatching.
+
+  Note that backpatch chains would present a problem for BuildSpanDepTable,
+  which inspects bytecode to build cg->spanDeps on demand, when the first
+  short jump offset overflows.  To solve this temporary problem, we emit a
+  proxy bytecode (JSOP_BACKPATCH; JSOP_BACKPATCH_PUSH for jumps that push a
+  result on the interpreter's stack, namely JSOP_GOSUB; or JSOP_BACKPATCH_POP
+  for branch ops) whose nuses/ndefs counts help keep the stack balanced, but
+  whose opcode format distinguishes its backpatch delta immediate operand from
+  a normal jump offset.
+ */
+static int
+BalanceJumpTargets(JSJumpTarget **jtp)
+{
+    JSJumpTarget *jt, *jt2, *root;
+    int dir, otherDir, heightChanged;
+    JSBool doubleRotate;
+
+    jt = *jtp;
+    JS_ASSERT(jt->balance != 0);
+
+    if (jt->balance < -1) {
+        dir = JT_RIGHT;
+        doubleRotate = (jt->kids[JT_LEFT]->balance > 0);
+    } else if (jt->balance > 1) {
+        dir = JT_LEFT;
+        doubleRotate = (jt->kids[JT_RIGHT]->balance < 0);
+    } else {
+        return 0;
+    }
+
+    otherDir = JT_OTHER_DIR(dir);
+    if (doubleRotate) {
+        jt2 = jt->kids[otherDir];
+        *jtp = root = jt2->kids[dir];
+
+        jt->kids[otherDir] = root->kids[dir];
+        root->kids[dir] = jt;
+
+        jt2->kids[dir] = root->kids[otherDir];
+        root->kids[otherDir] = jt2;
+
+        heightChanged = 1;
+        root->kids[JT_LEFT]->balance = -JS_MAX(root->balance, 0);
+        root->kids[JT_RIGHT]->balance = -JS_MIN(root->balance, 0);
+        root->balance = 0;
+    } else {
+        *jtp = root = jt->kids[otherDir];
+        jt->kids[otherDir] = root->kids[dir];
+        root->kids[dir] = jt;
+
+        heightChanged = (root->balance != 0);
+        jt->balance = -((dir == JT_LEFT) ? --root->balance : ++root->balance);
+    }
+
+    return heightChanged;
+}
+
+typedef struct AddJumpTargetArgs {
+    JSContext           *cx;
+    JSCodeGenerator     *cg;
+    ptrdiff_t           offset;
+    JSJumpTarget        *node;
+} AddJumpTargetArgs;
+
+static int
+AddJumpTarget(AddJumpTargetArgs *args, JSJumpTarget **jtp)
+{
+    JSJumpTarget *jt;
+    int balanceDelta;
+
+    jt = *jtp;
+    if (!jt) {
+        JSCodeGenerator *cg = args->cg;
+
+        jt = cg->jtFreeList;
+        if (jt) {
+            cg->jtFreeList = jt->kids[JT_LEFT];
+        } else {
+            JS_ARENA_ALLOCATE_CAST(jt, JSJumpTarget *, &args->cx->tempPool,
+                                   sizeof *jt);
+            if (!jt) {
+                JS_ReportOutOfMemory(args->cx);
+                return 0;
+            }
+        }
+        jt->offset = args->offset;
+        jt->balance = 0;
+        jt->kids[JT_LEFT] = jt->kids[JT_RIGHT] = NULL;
+        cg->numJumpTargets++;
+        args->node = jt;
+        *jtp = jt;
+        return 1;
+    }
+
+    if (jt->offset == args->offset) {
+        args->node = jt;
+        return 0;
+    }
+
+    if (args->offset < jt->offset)
+        balanceDelta = -AddJumpTarget(args, &jt->kids[JT_LEFT]);
+    else
+        balanceDelta = AddJumpTarget(args, &jt->kids[JT_RIGHT]);
+    if (!args->node)
+        return 0;
+
+    jt->balance += balanceDelta;
+    return (balanceDelta && jt->balance)
+           ? 1 - BalanceJumpTargets(jtp)
+           : 0;
+}
+
+#ifdef DEBUG_brendan
+static int AVLCheck(JSJumpTarget *jt)
+{
+    int lh, rh;
+
+    if (!jt) return 0;
+    JS_ASSERT(-1 <= jt->balance && jt->balance <= 1);
+    lh = AVLCheck(jt->kids[JT_LEFT]);
+    rh = AVLCheck(jt->kids[JT_RIGHT]);
+    JS_ASSERT(jt->balance == rh - lh);
+    return 1 + JS_MAX(lh, rh);
+}
+#endif
+
+static JSBool
+SetSpanDepTarget(JSContext *cx, JSCodeGenerator *cg, JSSpanDep *sd,
+                 ptrdiff_t off)
+{
+    AddJumpTargetArgs args;
+
+    if (off < JUMPX_OFFSET_MIN || JUMPX_OFFSET_MAX < off) {
+        ReportStatementTooLarge(cx, cg);
+        return JS_FALSE;
+    }
+
+    args.cx = cx;
+    args.cg = cg;
+    args.offset = sd->top + off;
+    args.node = NULL;
+    AddJumpTarget(&args, &cg->jumpTargets);
+    if (!args.node)
+        return JS_FALSE;
+
+#ifdef DEBUG_brendan
+    AVLCheck(cg->jumpTargets);
+#endif
+
+    SD_SET_TARGET(sd, args.node);
+    return JS_TRUE;
+}
+
+#define SPANDEPS_MIN            256
+#define SPANDEPS_SIZE(n)        ((n) * sizeof(JSSpanDep))
+#define SPANDEPS_SIZE_MIN       SPANDEPS_SIZE(SPANDEPS_MIN)
+
+static JSBool
+AddSpanDep(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc, jsbytecode *pc2,
+           ptrdiff_t off)
+{
+    uintN index;
+    JSSpanDep *sdbase, *sd;
+    size_t size;
+
+    index = cg->numSpanDeps;
+    if (index + 1 == 0) {
+        ReportStatementTooLarge(cx, cg);
+        return JS_FALSE;
+    }
+
+    if ((index & (index - 1)) == 0 &&
+        (!(sdbase = cg->spanDeps) || index >= SPANDEPS_MIN)) {
+        if (!sdbase) {
+            size = SPANDEPS_SIZE_MIN;
+            JS_ARENA_ALLOCATE_CAST(sdbase, JSSpanDep *, &cx->tempPool, size);
+        } else {
+            size = SPANDEPS_SIZE(index);
+            JS_ARENA_GROW_CAST(sdbase, JSSpanDep *, &cx->tempPool, size, size);
+        }
+        if (!sdbase)
+            return JS_FALSE;
+        cg->spanDeps = sdbase;
+    }
+
+    cg->numSpanDeps = index + 1;
+    sd = cg->spanDeps + index;
+    sd->top = PTRDIFF(pc, CG_BASE(cg), jsbytecode);
+    sd->offset = sd->before = PTRDIFF(pc2, CG_BASE(cg), jsbytecode);
+
+    if (js_CodeSpec[*pc].format & JOF_BACKPATCH) {
+        /* Jump offset will be backpatched if off is a non-zero "bpdelta". */
+        if (off != 0) {
+            JS_ASSERT(off >= 1 + JUMP_OFFSET_LEN);
+            if (off > BPDELTA_MAX) {
+                ReportStatementTooLarge(cx, cg);
+                return JS_FALSE;
+            }
+        }
+        SD_SET_BPDELTA(sd, off);
+    } else if (off == 0) {
+        /* Jump offset will be patched directly, without backpatch chaining. */
+        SD_SET_TARGET(sd, NULL);
+    } else {
+        /* The jump offset in off is non-zero, therefore it's already known. */
+        if (!SetSpanDepTarget(cx, cg, sd, off))
+            return JS_FALSE;
+    }
+
+    if (index > SPANDEP_INDEX_MAX)
+        index = SPANDEP_INDEX_HUGE;
+    SET_SPANDEP_INDEX(pc2, index);
+    return JS_TRUE;
+}
+
+static JSBool
+BuildSpanDepTable(JSContext *cx, JSCodeGenerator *cg)
+{
+    jsbytecode *pc, *end;
+    JSOp op;
+    const JSCodeSpec *cs;
+    ptrdiff_t len, off;
+
+    pc = CG_BASE(cg) + cg->spanDepTodo;
+    end = CG_NEXT(cg);
+    while (pc < end) {
+        op = (JSOp)*pc;
+        cs = &js_CodeSpec[op];
+        len = (ptrdiff_t)cs->length;
+
+        switch (cs->format & JOF_TYPEMASK) {
+          case JOF_JUMP:
+            off = GET_JUMP_OFFSET(pc);
+            if (!AddSpanDep(cx, cg, pc, pc, off))
+                return JS_FALSE;
+            break;
+
+#if JS_HAS_SWITCH_STATEMENT
+          case JOF_TABLESWITCH:
+          {
+            jsbytecode *pc2;
+            jsint i, low, high;
+
+            pc2 = pc;
+            off = GET_JUMP_OFFSET(pc2);
+            if (!AddSpanDep(cx, cg, pc, pc2, off))
+                return JS_FALSE;
+            pc2 += JUMP_OFFSET_LEN;
+            low = GET_JUMP_OFFSET(pc2);
+            pc2 += JUMP_OFFSET_LEN;
+            high = GET_JUMP_OFFSET(pc2);
+            pc2 += JUMP_OFFSET_LEN;
+            for (i = low; i <= high; i++) {
+                off = GET_JUMP_OFFSET(pc2);
+                if (!AddSpanDep(cx, cg, pc, pc2, off))
+                    return JS_FALSE;
+                pc2 += JUMP_OFFSET_LEN;
+            }
+            len = 1 + pc2 - pc;
+            break;
+          }
+
+          case JOF_LOOKUPSWITCH:
+          {
+            jsbytecode *pc2;
+            jsint npairs;
+
+            pc2 = pc;
+            off = GET_JUMP_OFFSET(pc2);
+            if (!AddSpanDep(cx, cg, pc, pc2, off))
+                return JS_FALSE;
+            pc2 += JUMP_OFFSET_LEN;
+            npairs = (jsint) GET_ATOM_INDEX(pc2);
+            pc2 += ATOM_INDEX_LEN;
+            while (npairs) {
+                pc2 += ATOM_INDEX_LEN;
+                off = GET_JUMP_OFFSET(pc2);
+                if (!AddSpanDep(cx, cg, pc, pc2, off))
+                    return JS_FALSE;
+                pc2 += JUMP_OFFSET_LEN;
+                npairs--;
+            }
+            len = 1 + pc2 - pc;
+            break;
+          }
+#endif /* JS_HAS_SWITCH_STATEMENT */
+        }
+
+        JS_ASSERT(len > 0);
+        pc += len;
+    }
+
+    return JS_TRUE;
+}
+
+static JSSpanDep *
+GetSpanDep(JSCodeGenerator *cg, jsbytecode *pc)
+{
+    uintN index;
+    ptrdiff_t offset;
+    int lo, hi, mid;
+    JSSpanDep *sd;
+
+    index = GET_SPANDEP_INDEX(pc);
+    if (index != SPANDEP_INDEX_HUGE)
+        return cg->spanDeps + index;
+
+    offset = PTRDIFF(pc, CG_BASE(cg), jsbytecode);
+    lo = 0;
+    hi = cg->numSpanDeps - 1;
+    while (lo <= hi) {
+        mid = (lo + hi) / 2;
+        sd = cg->spanDeps + mid;
+        if (sd->before == offset)
+            return sd;
+        if (sd->before < offset)
+            lo = mid + 1;
+        else
+            hi = mid - 1;
+    }
+
+    JS_ASSERT(0);
+    return NULL;
+}
+
+static JSBool
+SetBackPatchDelta(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc,
+                  ptrdiff_t delta)
+{
+    JSSpanDep *sd;
+
+    JS_ASSERT(delta >= 1 + JUMP_OFFSET_LEN);
+    if (!cg->spanDeps && delta < JUMP_OFFSET_MAX) {
+        SET_JUMP_OFFSET(pc, delta);
+        return JS_TRUE;
+    }
+
+    if (delta > BPDELTA_MAX) {
+        ReportStatementTooLarge(cx, cg);
+        return JS_FALSE;
+    }
+
+    if (!cg->spanDeps && !BuildSpanDepTable(cx, cg))
+        return JS_FALSE;
+
+    sd = GetSpanDep(cg, pc);
+    JS_ASSERT(SD_GET_BPDELTA(sd) == 0);
+    SD_SET_BPDELTA(sd, delta);
+    return JS_TRUE;
+}
+
+static void
+UpdateJumpTargets(JSJumpTarget *jt, ptrdiff_t pivot, ptrdiff_t delta)
+{
+    if (jt->offset > pivot) {
+        jt->offset += delta;
+        if (jt->kids[JT_LEFT])
+            UpdateJumpTargets(jt->kids[JT_LEFT], pivot, delta);
+    }
+    if (jt->kids[JT_RIGHT])
+        UpdateJumpTargets(jt->kids[JT_RIGHT], pivot, delta);
+}
+
+static JSSpanDep *
+FindNearestSpanDep(JSCodeGenerator *cg, ptrdiff_t offset, int lo,
+                   JSSpanDep *guard)
+{
+    int num, hi, mid;
+    JSSpanDep *sdbase, *sd;
+
+    num = cg->numSpanDeps;
+    JS_ASSERT(num > 0);
+    hi = num - 1;
+    sdbase = cg->spanDeps;
+    while (lo <= hi) {
+        mid = (lo + hi) / 2;
+        sd = sdbase + mid;
+        if (sd->before == offset)
+            return sd;
+        if (sd->before < offset)
+            lo = mid + 1;
+        else
+            hi = mid - 1;
+    }
+    if (lo == num)
+        return guard;
+    sd = sdbase + lo;
+    JS_ASSERT(sd->before >= offset && (lo == 0 || sd[-1].before < offset));
+    return sd;
+}
+
+static void
+FreeJumpTargets(JSCodeGenerator *cg, JSJumpTarget *jt)
+{
+    if (jt->kids[JT_LEFT])
+        FreeJumpTargets(cg, jt->kids[JT_LEFT]);
+    if (jt->kids[JT_RIGHT])
+        FreeJumpTargets(cg, jt->kids[JT_RIGHT]);
+    jt->kids[JT_LEFT] = cg->jtFreeList;
+    cg->jtFreeList = jt;
+}
+
+static JSBool
+OptimizeSpanDeps(JSContext *cx, JSCodeGenerator *cg)
+{
+    jsbytecode *pc, *oldpc, *base, *limit, *next;
+    JSSpanDep *sd, *sd2, *sdbase, *sdlimit, *sdtop, guard;
+    ptrdiff_t offset, growth, delta, top, pivot, span, length, target;
+    JSBool done;
+    JSOp op;
+    uint32 type;
+    size_t size, incr;
+    jssrcnote *sn, *snlimit;
+    JSSrcNoteSpec *spec;
+    uintN i, n, noteIndex;
+    JSTryNote *tn, *tnlimit;
+#ifdef DEBUG_brendan
+    int passes = 0;
+#endif
+
+    base = CG_BASE(cg);
+    sdbase = cg->spanDeps;
+    sdlimit = sdbase + cg->numSpanDeps;
+    offset = CG_OFFSET(cg);
+    growth = 0;
+
+    do {
+        done = JS_TRUE;
+        delta = 0;
+        top = pivot = -1;
+        sdtop = NULL;
+        pc = NULL;
+        op = JSOP_NOP;
+        type = 0;
+#ifdef DEBUG_brendan
+        passes++;
+#endif
+
+        for (sd = sdbase; sd < sdlimit; sd++) {
+            JS_ASSERT(JT_HAS_TAG(sd->target));
+            sd->offset += delta;
+
+            if (sd->top != top) {
+                sdtop = sd;
+                top = sd->top;
+                JS_ASSERT(top == sd->before);
+                pivot = sd->offset;
+                pc = base + top;
+                op = (JSOp) *pc;
+                type = (js_CodeSpec[op].format & JOF_TYPEMASK);
+                if (JOF_TYPE_IS_EXTENDED_JUMP(type)) {
+                    /*
+                     * We already extended all the jump offset operands for
+                     * the opcode at sd->top.  Jumps and branches have only
+                     * one jump offset operand, but switches have many, all
+                     * of which are adjacent in cg->spanDeps.
+                     */
+                    continue;
+                }
+
+                JS_ASSERT(type == JOF_JUMP ||
+                          type == JOF_TABLESWITCH ||
+                          type == JOF_LOOKUPSWITCH);
+            }
+
+            if (!JOF_TYPE_IS_EXTENDED_JUMP(type)) {
+                span = SD_SPAN(sd, pivot);
+                if (span < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < span) {
+                    ptrdiff_t deltaFromTop = 0;
+
+                    done = JS_FALSE;
+
+                    switch (op) {
+                      case JSOP_GOTO:         op = JSOP_GOTOX; break;
+                      case JSOP_IFEQ:         op = JSOP_IFEQX; break;
+                      case JSOP_IFNE:         op = JSOP_IFNEX; break;
+                      case JSOP_OR:           op = JSOP_ORX; break;
+                      case JSOP_AND:          op = JSOP_ANDX; break;
+                      case JSOP_GOSUB:        op = JSOP_GOSUBX; break;
+                      case JSOP_CASE:         op = JSOP_CASEX; break;
+                      case JSOP_DEFAULT:      op = JSOP_DEFAULTX; break;
+                      case JSOP_TABLESWITCH:  op = JSOP_TABLESWITCHX; break;
+                      case JSOP_LOOKUPSWITCH: op = JSOP_LOOKUPSWITCHX; break;
+                      default:                JS_ASSERT(0);
+                    }
+                    *pc = (jsbytecode) op;
+
+                    for (sd2 = sdtop; sd2 < sdlimit && sd2->top == top; sd2++) {
+                        if (sd2 <= sd) {
+                            /*
+                             * sd2->offset already includes delta as it stood
+                             * before we entered this loop, but it must also
+                             * include the delta relative to top due to all the
+                             * extended jump offset immediates for the opcode
+                             * starting at top, which we extend in this loop.
+                             *
+                             * If there is only one extended jump offset, then
+                             * sd2->offset won't change and this for loop will
+                             * iterate once only.
+                             */
+                            sd2->offset += deltaFromTop;
+                            deltaFromTop += JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN;
+                        } else {
+                            /*
+                             * sd2 comes after sd, and won't be revisited by
+                             * the outer for loop, so we have to increase its
+                             * offset by delta, not merely by deltaFromTop.
+                             */
+                            sd2->offset += delta;
+                        }
+
+                        delta += JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN;
+                        UpdateJumpTargets(cg->jumpTargets, sd2->offset,
+                                          JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN);
+                    }
+                    sd = sd2 - 1;
+                }
+            }
+        }
+
+        growth += delta;
+    } while (!done);
+
+    if (growth) {
+#ifdef DEBUG_brendan
+        printf("%s:%u: %u/%u jumps extended in %d passes (%d=%d+%d)\n",
+               cg->filename ? cg->filename : "stdin", cg->firstLine,
+               growth / (JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN), cg->numSpanDeps,
+               passes, offset + growth, offset, growth);
+#endif
+
+        /*
+         * Ensure that we have room for the extended jumps, but don't round up
+         * to a power of two -- we're done generating code, so we cut to fit.
+         */
+        limit = CG_LIMIT(cg);
+        length = offset + growth;
+        next = base + length;
+        if (next > limit) {
+            JS_ASSERT(length > BYTECODE_CHUNK);
+            size = BYTECODE_SIZE(PTRDIFF(limit, base, jsbytecode));
+            incr = BYTECODE_SIZE(length) - size;
+            JS_ARENA_GROW_CAST(base, jsbytecode *, cg->codePool, size, incr);
+            if (!base) {
+                JS_ReportOutOfMemory(cx);
+                return JS_FALSE;
+            }
+            CG_BASE(cg) = base;
+            CG_LIMIT(cg) = next = base + length;
+        }
+        CG_NEXT(cg) = next;
+
+        /*
+         * Set up a fake span dependency record to guard the end of the code
+         * being generated.  This guard record is returned as a fencepost by
+         * FindNearestSpanDep if there is no real spandep at or above a given
+         * unextended code offset.
+         */
+        guard.top = -1;
+        guard.offset = offset + growth;
+        guard.before = offset;
+        guard.target = NULL;
+    }
+
+    /*
+     * Now work backwards through the span dependencies, copying chunks of
+     * bytecode between each extended jump toward the end of the grown code
+     * space, and restoring immediate offset operands for all jump bytecodes.
+     * The first chunk of bytecodes, starting at base and ending at the first
+     * extended jump offset (NB: this chunk includes the operation bytecode
+     * just before that immediate jump offset), doesn't need to be copied.
+     */
+    JS_ASSERT(sd == sdlimit);
+    top = -1;
+    while (--sd >= sdbase) {
+        if (sd->top != top) {
+            top = sd->top;
+            op = (JSOp) base[top];
+            type = (js_CodeSpec[op].format & JOF_TYPEMASK);
+
+            for (sd2 = sd - 1; sd2 >= sdbase && sd2->top == top; sd2--)
+                continue;
+            sd2++;
+            pivot = sd2->offset;
+            JS_ASSERT(top == sd2->before);
+        }
+
+        oldpc = base + sd->before;
+        span = SD_SPAN(sd, pivot);
+
+        /*
+         * If this jump didn't need to be extended, restore its span immediate
+         * offset operand now, overwriting the index of sd within cg->spanDeps
+         * that was stored temporarily after *pc when BuildSpanDepTable ran.
+         *
+         * Note that span might fit in 16 bits even for an extended jump op,
+         * if the op has multiple span operands, not all of which overflowed
+         * (e.g. JSOP_LOOKUPSWITCH or JSOP_TABLESWITCH where some cases are in
+         * range for a short jump, but others are not).
+         */
+        if (!JOF_TYPE_IS_EXTENDED_JUMP(type)) {
+            JS_ASSERT(JUMP_OFFSET_MIN <= span && span <= JUMP_OFFSET_MAX);
+            SET_JUMP_OFFSET(oldpc, span);
+            continue;
+        }
+
+        /*
+         * Set up parameters needed to copy the next run of bytecode starting
+         * at offset (which is a cursor into the unextended, original bytecode
+         * vector), down to sd->before (a cursor of the same scale as offset,
+         * it's the index of the original jump pc).  Reuse delta to count the
+         * nominal number of bytes to copy.
+         */
+        pc = base + sd->offset;
+        delta = offset - sd->before;
+        JS_ASSERT(delta >= 1 + JUMP_OFFSET_LEN);
+
+        /*
+         * Don't bother copying the jump offset we're about to reset, but do
+         * copy the bytecode at oldpc (which comes just before its immediate
+         * jump offset operand), on the next iteration through the loop, by
+         * including it in offset's new value.
+         */
+        offset = sd->before + 1;
+        size = BYTECODE_SIZE(delta - (1 + JUMP_OFFSET_LEN));
+        if (size) {
+            memmove(pc + 1 + JUMPX_OFFSET_LEN,
+                    oldpc + 1 + JUMP_OFFSET_LEN,
+                    size);
+        }
+
+        SET_JUMPX_OFFSET(pc, span);
+    }
+
+    if (growth) {
+        /*
+         * Fix source note deltas.  Don't hardwire the delta fixup adjustment,
+         * even though currently it must be JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN
+         * at each sd that moved.  The future may bring different offset sizes
+         * for span-dependent instruction operands.  However, we fix only main
+         * notes here, not prolog notes -- we know that prolog opcodes are not
+         * span-dependent, and aren't likely ever to be.
+         */
+        offset = growth = 0;
+        sd = sdbase;
+        for (sn = cg->main.notes, snlimit = sn + cg->main.noteCount;
+             sn < snlimit;
+             sn = SN_NEXT(sn)) {
+            /*
+             * Recall that the offset of a given note includes its delta, and
+             * tells the offset of the annotated bytecode from the main entry
+             * point of the script.
+             */
+            offset += SN_DELTA(sn);
+            while (sd < sdlimit && sd->before < offset) {
+                /*
+                 * To compute the delta to add to sn, we need to look at the
+                 * spandep after sd, whose offset - (before + growth) tells by
+                 * how many bytes sd's instruction grew.
+                 */
+                sd2 = sd + 1;
+                if (sd2 == sdlimit)
+                    sd2 = &guard;
+                delta = sd2->offset - (sd2->before + growth);
+                if (delta > 0) {
+                    JS_ASSERT(delta == JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN);
+                    sn = js_AddToSrcNoteDelta(cx, cg, sn, delta);
+                    if (!sn)
+                        return JS_FALSE;
+                    snlimit = cg->main.notes + cg->main.noteCount;
+                    growth += delta;
+                }
+                sd++;
+            }
+
+            /*
+             * If sn has span-dependent offset operands, check whether each
+             * covers further span-dependencies, and increase those operands
+             * accordingly.  Some source notes measure offset not from the
+             * annotated pc, but from that pc plus some small bias.  NB: we
+             * assume that spec->offsetBias can't itself span span-dependent
+             * instructions!
+             */
+            spec = &js_SrcNoteSpec[SN_TYPE(sn)];
+            if (spec->isSpanDep) {
+                pivot = offset + spec->offsetBias;
+                n = spec->arity;
+                for (i = 0; i < n; i++) {
+                    span = js_GetSrcNoteOffset(sn, i);
+                    if (span == 0)
+                        continue;
+                    target = pivot + span * spec->isSpanDep;
+                    sd2 = FindNearestSpanDep(cg, target,
+                                             (target >= pivot)
+                                             ? sd - sdbase
+                                             : 0,
+                                             &guard);
+
+                    /*
+                     * Increase target by sd2's before-vs-after offset delta,
+                     * which is absolute (i.e., relative to start of script,
+                     * as is target).  Recompute the span by subtracting its
+                     * adjusted pivot from target.
+                     */
+                    target += sd2->offset - sd2->before;
+                    span = target - (pivot + growth);
+                    span *= spec->isSpanDep;
+                    noteIndex = sn - cg->main.notes;
+                    if (!js_SetSrcNoteOffset(cx, cg, noteIndex, i, span))
+                        return JS_FALSE;
+                    sn = cg->main.notes + noteIndex;
+                    snlimit = cg->main.notes + cg->main.noteCount;
+                }
+            }
+        }
+        cg->main.lastNoteOffset += growth;
+
+        /*
+         * Fix try/catch notes (O(numTryNotes * log2(numSpanDeps)), but it's
+         * not clear how we can beat that).
+         */
+        for (tn = cg->tryBase, tnlimit = cg->tryNext; tn < tnlimit; tn++) {
+            /*
+             * First, look for the nearest span dependency at/above tn->start.
+             * There may not be any such spandep, in which case the guard will
+             * be returned.
+             */
+            offset = tn->start;
+            sd = FindNearestSpanDep(cg, offset, 0, &guard);
+            delta = sd->offset - sd->before;
+            tn->start = offset + delta;
+
+            /*
+             * Next, find the nearest spandep at/above tn->start + tn->length.
+             * Use its delta minus tn->start's delta to increase tn->length.
+             */
+            length = tn->length;
+            sd2 = FindNearestSpanDep(cg, offset + length, sd - sdbase, &guard);
+            if (sd2 != sd)
+                tn->length = length + sd2->offset - sd2->before - delta;
+
+            /*
+             * Finally, adjust tn->catchStart upward only if it is non-zero,
+             * and provided there are spandeps below it that grew.
+             */
+            offset = tn->catchStart;
+            if (offset != 0) {
+                sd = FindNearestSpanDep(cg, offset, sd2 - sdbase, &guard);
+                tn->catchStart = offset + sd->offset - sd->before;
+            }
+        }
+    }
+
+#ifdef DEBUG_brendan
+  {
+    uintN bigspans = 0;
+    top = -1;
+    for (sd = sdbase; sd < sdlimit; sd++) {
+        offset = sd->offset;
+
+        /* NB: sd->top cursors into the original, unextended bytecode vector. */
+        if (sd->top != top) {
+            JS_ASSERT(top == -1 ||
+                      !JOF_TYPE_IS_EXTENDED_JUMP(type) ||
+                      bigspans != 0);
+            bigspans = 0;
+            top = sd->top;
+            JS_ASSERT(top == sd->before);
+            op = (JSOp) base[offset];
+            type = (js_CodeSpec[op].format & JOF_TYPEMASK);
+            JS_ASSERT(type == JOF_JUMP ||
+                      type == JOF_JUMPX ||
+                      type == JOF_TABLESWITCH ||
+                      type == JOF_TABLESWITCHX ||
+                      type == JOF_LOOKUPSWITCH ||
+                      type == JOF_LOOKUPSWITCHX);
+            pivot = offset;
+        }
+
+        pc = base + offset;
+        if (JOF_TYPE_IS_EXTENDED_JUMP(type)) {
+            span = GET_JUMPX_OFFSET(pc);
+            if (span < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < span) {
+                bigspans++;
+            } else {
+                JS_ASSERT(type == JOF_TABLESWITCHX ||
+                          type == JOF_LOOKUPSWITCHX);
+            }
+        } else {
+            span = GET_JUMP_OFFSET(pc);
+        }
+        JS_ASSERT(SD_SPAN(sd, pivot) == span);
+    }
+    JS_ASSERT(!JOF_TYPE_IS_EXTENDED_JUMP(type) || bigspans != 0);
+  }
+#endif
+
+    /*
+     * Reset so we optimize at most once -- cg may be used for further code
+     * generation of successive, independent, top-level statements.  No jump
+     * can span top-level statements, because JS lacks goto.
+     */
+    size = SPANDEPS_SIZE(JS_BIT(JS_CeilingLog2(cg->numSpanDeps)));
+    JS_ArenaFreeAllocation(&cx->tempPool, cg->spanDeps,
+                           JS_MAX(size, SPANDEPS_SIZE_MIN));
+    cg->spanDeps = NULL;
+    FreeJumpTargets(cg, cg->jumpTargets);
+    cg->jumpTargets = NULL;
+    cg->numSpanDeps = cg->numJumpTargets = 0;
+    cg->spanDepTodo = CG_OFFSET(cg);
+    return JS_TRUE;
+}
+
+static JSBool
+EmitJump(JSContext *cx, JSCodeGenerator *cg, JSOp op, ptrdiff_t off)
+{
+    JSBool extend;
+    ptrdiff_t jmp;
+    jsbytecode *pc;
+
+    extend = off < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < off;
+    if (extend && !cg->spanDeps && !BuildSpanDepTable(cx, cg))
+        return JS_FALSE;
+
+    jmp = js_Emit3(cx, cg, op, JUMP_OFFSET_HI(off), JUMP_OFFSET_LO(off));
+    if (jmp >= 0 && (extend || cg->spanDeps)) {
+        pc = CG_CODE(cg, jmp);
+        if (!AddSpanDep(cx, cg, pc, pc, off))
+            return JS_FALSE;
+    }
+    return jmp;
+}
+
+static ptrdiff_t
+GetJumpOffset(JSCodeGenerator *cg, jsbytecode *pc)
+{
+    JSSpanDep *sd;
+    JSJumpTarget *jt;
+    ptrdiff_t top;
+
+    if (!cg->spanDeps)
+        return GET_JUMP_OFFSET(pc);
+
+    sd = GetSpanDep(cg, pc);
+    jt = sd->target;
+    if (!JT_HAS_TAG(jt))
+        return JT_TO_BPDELTA(jt);
+
+    top = sd->top;
+    while (--sd >= cg->spanDeps && sd->top == top)
+        continue;
+    sd++;
+    return JT_CLR_TAG(jt)->offset - sd->offset;
+}
+
+JSBool
+js_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc,
+                 ptrdiff_t off)
+{
+    if (!cg->spanDeps) {
+        if (JUMP_OFFSET_MIN <= off && off <= JUMP_OFFSET_MAX) {
+            SET_JUMP_OFFSET(pc, off);
+            return JS_TRUE;
+        }
+
+        if (!BuildSpanDepTable(cx, cg))
+            return JS_FALSE;
+    }
+
+    return SetSpanDepTarget(cx, cg, GetSpanDep(cg, pc), off);
+}
+
+JSBool
+js_InWithStatement(JSTreeContext *tc)
+{
+    JSStmtInfo *stmt;
+
+    for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
+        if (stmt->type == STMT_WITH)
+            return JS_TRUE;
+    }
+    return JS_FALSE;
+}
+
+JSBool
+js_InCatchBlock(JSTreeContext *tc, JSAtom *atom)
+{
+    JSStmtInfo *stmt;
+
+    for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
+        if (stmt->type == STMT_CATCH && stmt->label == atom)
+            return JS_TRUE;
+    }
+    return JS_FALSE;
+}
+
+void
+js_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type,
+                 ptrdiff_t top)
+{
+    stmt->type = type;
+    SET_STATEMENT_TOP(stmt, top);
+    stmt->label = NULL;
+    stmt->down = tc->topStmt;
+    tc->topStmt = stmt;
+}
+
+/*
+ * Emit a backpatch op with offset pointing to the previous jump of this type,
+ * so that we can walk back up the chain fixing up the op and jump offset.
+ */
+static ptrdiff_t
+EmitBackPatchOp(JSContext *cx, JSCodeGenerator *cg, JSOp op, ptrdiff_t *lastp)
+{
+    ptrdiff_t offset, delta;
+
+    offset = CG_OFFSET(cg);
+    delta = offset - *lastp;
+    *lastp = offset;
+    JS_ASSERT(delta > 0);
+    return EmitJump(cx, cg, op, delta);
+}
+
+/* Emit additional bytecode(s) for non-local jumps. */
+static JSBool
+EmitNonLocalJumpFixup(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *toStmt,
+                      JSOp *returnop)
+{
+    intN depth;
+    JSStmtInfo *stmt;
+    ptrdiff_t jmp;
+
+    /*
+     * Return from within a try block that has a finally clause must be split
+     * into two ops: JSOP_SETRVAL, to pop the r.v. and store it in fp->rval;
+     * and JSOP_RETRVAL, which makes control flow go back to the caller, who
+     * picks up fp->rval as usual.  Otherwise, the stack will be unbalanced
+     * when executing the finally clause.
+     *
+     * We mutate *returnop once only if we find an enclosing try-block (viz,
+     * STMT_FINALLY) to ensure that we emit just one JSOP_SETRVAL before one
+     * or more JSOP_GOSUBs and other fixup opcodes emitted by this function.
+     * Our caller (the TOK_RETURN case of js_EmitTree) then emits *returnop.
+     * The fixup opcodes and gosubs must interleave in the proper order, from
+     * inner statement to outer, so that finally clauses run at the correct
+     * stack depth.
+     */
+    if (returnop) {
+        JS_ASSERT(*returnop == JSOP_RETURN);
+        for (stmt = cg->treeContext.topStmt; stmt != toStmt;
+             stmt = stmt->down) {
+            if (stmt->type == STMT_FINALLY) {
+                if (js_Emit1(cx, cg, JSOP_SETRVAL) < 0)
+                    return JS_FALSE;
+                *returnop = JSOP_RETRVAL;
+                break;
+            }
+        }
+
+        /*
+         * If there are no try-with-finally blocks open around this return
+         * statement, we can generate a return forthwith and skip generating
+         * any fixup code.
+         */
+        if (*returnop == JSOP_RETURN)
+            return JS_TRUE;
+    }
+
+    /*
+     * The non-local jump fixup we emit will unbalance cg->stackDepth, because
+     * the fixup replicates balanced code such as JSOP_LEAVEWITH emitted at the
+     * end of a with statement, so we save cg->stackDepth here and restore it
+     * just before a successful return.
+     */
+    depth = cg->stackDepth;
+    for (stmt = cg->treeContext.topStmt; stmt != toStmt; stmt = stmt->down) {
+        switch (stmt->type) {
+          case STMT_FINALLY:
+            if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
+                return JS_FALSE;
+            jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH_PUSH, &stmt->gosub);
+            if (jmp < 0)
+                return JS_FALSE;
+            break;
+
+          case STMT_WITH:
+          case STMT_CATCH:
+            /* There's a With object on the stack that we need to pop. */
+            if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
+                return JS_FALSE;
+            if (js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0)
+                return JS_FALSE;
+            break;
+
+          case STMT_FOR_IN_LOOP:
+            /*
+             * The iterator and the object being iterated need to be popped.
+             * JSOP_POP2 isn't decompiled, so it doesn't need to be HIDDEN.
+             */
+            if (js_Emit1(cx, cg, JSOP_POP2) < 0)
+                return JS_FALSE;
+            break;
+
+          case STMT_SUBROUTINE:
+            /* There's a retsub pc-offset on the stack that we need to pop. */
+            if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
+                return JS_FALSE;
+            if (js_Emit1(cx, cg, JSOP_POP) < 0)
+                return JS_FALSE;
+            break;
+
+          default:;
+        }
+    }
+
+    cg->stackDepth = depth;
+    return JS_TRUE;
+}
+
+static ptrdiff_t
+EmitGoto(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *toStmt,
+         ptrdiff_t *lastp, JSAtomListElement *label, JSSrcNoteType noteType)
+{
+    intN index;
+
+    if (!EmitNonLocalJumpFixup(cx, cg, toStmt, NULL))
+        return -1;
+
+    if (label) {
+        index = js_NewSrcNote(cx, cg, noteType);
+        if (index < 0)
+            return -1;
+        if (!js_SetSrcNoteOffset(cx, cg, (uintN)index, 0,
+                                 (ptrdiff_t) ALE_INDEX(label))) {
+            return -1;
+        }
+    } else if (noteType != SRC_NULL) {
+        if (js_NewSrcNote(cx, cg, noteType) < 0)
+            return -1;
+    }
+
+    return EmitBackPatchOp(cx, cg, JSOP_BACKPATCH, lastp);
+}
+
+static JSBool
+BackPatch(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t last,
+          jsbytecode *target, jsbytecode op)
+{
+    jsbytecode *pc, *stop;
+    ptrdiff_t delta, span;
+
+    pc = CG_CODE(cg, last);
+    stop = CG_CODE(cg, -1);
+    while (pc != stop) {
+        delta = GetJumpOffset(cg, pc);
+        span = PTRDIFF(target, pc, jsbytecode);
+        CHECK_AND_SET_JUMP_OFFSET(cx, cg, pc, span);
+
+        /*
+         * Set *pc after jump offset in case bpdelta didn't overflow, but span
+         * does (if so, CHECK_AND_SET_JUMP_OFFSET might call BuildSpanDepTable
+         * and need to see the JSOP_BACKPATCH* op at *pc).
+         */
+        *pc = op;
+        pc -= delta;
+    }
+    return JS_TRUE;
+}
+
+void
+js_PopStatement(JSTreeContext *tc)
+{
+    tc->topStmt = tc->topStmt->down;
+}
+
+JSBool
+js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg)
+{
+    JSStmtInfo *stmt;
+
+    stmt = cg->treeContext.topStmt;
+    if (!BackPatch(cx, cg, stmt->breaks, CG_NEXT(cg), JSOP_GOTO) ||
+        !BackPatch(cx, cg, stmt->continues, CG_CODE(cg, stmt->update),
+                   JSOP_GOTO)) {
+        return JS_FALSE;
+    }
+    js_PopStatement(&cg->treeContext);
+    return JS_TRUE;
+}
+
+JSBool
+js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
+                             JSParseNode *pn)
+{
+    jsdouble dval;
+    jsint ival;
+    JSAtom *valueAtom;
+    JSAtomListElement *ale;
+
+    /* XXX just do numbers for now */
+    if (pn->pn_type == TOK_NUMBER) {
+        dval = pn->pn_dval;
+        valueAtom = (JSDOUBLE_IS_INT(dval, ival) && INT_FITS_IN_JSVAL(ival))
+                    ? js_AtomizeInt(cx, ival, 0)
+                    : js_AtomizeDouble(cx, dval, 0);
+        if (!valueAtom)
+            return JS_FALSE;
+        ale = js_IndexAtom(cx, atom, &cg->constList);
+        if (!ale)
+            return JS_FALSE;
+        ALE_SET_VALUE(ale, ATOM_KEY(valueAtom));
+    }
+    return JS_TRUE;
+}
+
+JSBool
+js_LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
+                             jsval *vp)
+{
+    JSBool ok;
+    JSStackFrame *fp;
+    JSAtomListElement *ale;
+    JSObject *obj, *pobj;
+    JSProperty *prop;
+    uintN attrs;
+
+    /*
+     * fp chases cg down the stack, but only until we reach the outermost cg.
+     * This enables propagating consts from top-level into switch cases in a
+     * function compiled along with the top-level script.  All stack frames
+     * with matching code generators should be flagged with JSFRAME_COMPILING;
+     * we check sanity here.
+     */
+    *vp = JSVAL_VOID;
+    ok = JS_TRUE;
+    fp = cx->fp;
+    do {
+        JS_ASSERT(fp->flags & JSFRAME_COMPILING);
+
+        obj = fp->varobj;
+        if (obj == fp->scopeChain &&
+            !js_InWithStatement(&cg->treeContext) &&
+            !js_InCatchBlock(&cg->treeContext, atom)) {
+            ATOM_LIST_SEARCH(ale, &cg->constList, atom);
+            if (ale) {
+                *vp = ALE_VALUE(ale);
+                return JS_TRUE;
+            }
+
+            /*
+             * Try looking in the variable object for a direct property that
+             * is readonly and permanent.  We know such a property can't be
+             * shadowed by another property on obj's prototype chain, or a
+             * with object or catch variable; nor can prop's value be changed,
+             * nor can prop be deleted.
+             */
+            prop = NULL;
+            if (OBJ_IS_NATIVE(obj)) {
+                ok = js_LookupHiddenProperty(cx, obj, ATOM_TO_JSID(atom),
+                                             &pobj, &prop);
+                if (!ok)
+                    break;
+                if (prop) {
+                    /*
+                     * Any hidden property must be a formal arg or local var,
+                     * which will shadow a global const of the same name.
+                     */
+                    OBJ_DROP_PROPERTY(cx, pobj, prop);
+                    break;
+                }
+            }
+
+            ok = OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &pobj, &prop);
+            if (ok) {
+                if (pobj == obj &&
+                    (fp->flags & (JSFRAME_EVAL | JSFRAME_COMPILE_N_GO))) {
+                    /*
+                     * We're compiling code that will be executed immediately,
+                     * not re-executed against a different scope chain and/or
+                     * variable object.  Therefore we can get constant values
+                     * from our variable object here.
+                     */
+                    ok = OBJ_GET_ATTRIBUTES(cx, obj, ATOM_TO_JSID(atom), prop,
+                                            &attrs);
+                    if (ok && !(~attrs & (JSPROP_READONLY | JSPROP_PERMANENT)))
+                        ok = OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp);
+                }
+                if (prop)
+                    OBJ_DROP_PROPERTY(cx, pobj, prop);
+            }
+            if (!ok || prop)
+                break;
+        }
+        fp = fp->down;
+    } while ((cg = cg->parent) != NULL);
+    return ok;
+}
+
+/*
+ * Allocate an index invariant for all activations of the code being compiled
+ * in cg, that can be used to store and fetch a reference to a cloned RegExp
+ * object that shares the same JSRegExp private data created for the object
+ * literal in pn->pn_atom.  We need clones to hold lastIndex and other direct
+ * properties that should not be shared among threads sharing a precompiled
+ * function or script.
+ *
+ * If the code being compiled is function code, allocate a reserved slot in
+ * the cloned function object that shares its precompiled script with other
+ * cloned function objects and with the compiler-created clone-parent.  There
+ * are fun->nregexps such reserved slots in each function object cloned from
+ * fun->object.  NB: during compilation, funobj slots must never be allocated,
+ * because js_AllocSlot could hand out one of the slots that should be given
+ * to a regexp clone.
+ *
+ * If the code being compiled is global code, reserve the fp->vars slot at
+ * ALE_INDEX(ale), by ensuring that cg->treeContext.numGlobalVars is at least
+ * one more than this index.  For global code, fp->vars is parallel to the
+ * global script->atomMap.vector array, but possibly shorter for the common
+ * case (where var declarations and regexp literals cluster toward the front
+ * of the script or function body).
+ *
+ * Global variable name literals in script->atomMap have fast-global slot
+ * numbers (stored as int-tagged jsvals) in the corresponding fp->vars array
+ * element.  The atomIndex for a regexp object literal thus also addresses an
+ * fp->vars element that is not used by any optimized global variable, so we
+ * use that GC-scanned element to keep the regexp object clone alive, as well
+ * as to lazily create and find it at run-time for the JSOP_REGEXP bytecode.
+ *
+ * In no case can cx->fp->varobj be a Call object here, because that implies
+ * we are compiling eval code, in which case (cx->fp->flags & JSFRAME_EVAL)
+ * is true, and js_GetToken will have already selected JSOP_OBJECT instead of
+ * JSOP_REGEXP, to avoid all this RegExp object cloning business.
+ *
+ * Why clone regexp objects?  ECMA specifies that when a regular expression
+ * literal is scanned, a RegExp object is created.  In the spec, compilation
+ * and execution happen indivisibly, but in this implementation and many of
+ * its embeddings, code is precompiled early and re-executed in multiple
+ * threads, or using multiple global objects, or both, for efficiency.
+ *
+ * In such cases, naively following ECMA leads to wrongful sharing of RegExp
+ * objects, which makes for collisions on the lastIndex property (especially
+ * for global regexps) and on any ad-hoc properties.  Also, __proto__ and
+ * __parent__ refer to the pre-compilation prototype and global objects, a
+ * pigeon-hole problem for instanceof tests.
+ */
+static JSBool
+IndexRegExpClone(JSContext *cx, JSParseNode *pn, JSAtomListElement *ale,
+                 JSCodeGenerator *cg)
+{
+    JSObject *varobj, *reobj;
+    JSClass *clasp;
+    JSFunction *fun;
+    JSRegExp *re;
+    uint16 *countPtr;
+    uintN cloneIndex;
+
+    JS_ASSERT(!(cx->fp->flags & (JSFRAME_EVAL | JSFRAME_COMPILE_N_GO)));
+
+    varobj = cx->fp->varobj;
+    clasp = OBJ_GET_CLASS(cx, varobj);
+    if (clasp == &js_FunctionClass) {
+        fun = (JSFunction *) JS_GetPrivate(cx, varobj);
+        countPtr = &fun->nregexps;
+        cloneIndex = *countPtr;
+    } else {
+        JS_ASSERT(clasp != &js_CallClass);
+        countPtr = &cg->treeContext.numGlobalVars;
+        cloneIndex = ALE_INDEX(ale);
+    }
+
+    if ((cloneIndex + 1) >> 16) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_NEED_DIET, js_script_str);
+        return JS_FALSE;
+    }
+    if (cloneIndex >= *countPtr)
+        *countPtr = cloneIndex + 1;
+
+    reobj = ATOM_TO_OBJECT(pn->pn_atom);
+    JS_ASSERT(OBJ_GET_CLASS(cx, reobj) == &js_RegExpClass);
+    re = (JSRegExp *) JS_GetPrivate(cx, reobj);
+    re->cloneIndex = cloneIndex;
+    return JS_TRUE;
+}
+
+/*
+ * Macro to emit a bytecode followed by a uint16 immediate operand stored in
+ * big-endian order, used for arg and var numbers as well as for atomIndexes.
+ * NB: We use cx and cg from our caller's lexical environment, and return
+ * false on error.
+ */
+#define EMIT_UINT16_IMM_OP(op, i)                                             \
+    JS_BEGIN_MACRO                                                            \
+        if (js_Emit3(cx, cg, op, ATOM_INDEX_HI(i), ATOM_INDEX_LO(i)) < 0)     \
+            return JS_FALSE;                                                  \
+    JS_END_MACRO
+
+/*
+ * Emit a bytecode and its 2-byte constant (atom) index immediate operand.
+ * If the atomIndex requires more than 2 bytes, emit a prefix op whose 24-bit
+ * immediate operand indexes the atom in script->atomMap.
+ *
+ * If op has JOF_NAME mode, emit JSOP_FINDNAME to find and push the object in
+ * the scope chain in which the literal name was found, followed by the name
+ * as a string.  This enables us to use the JOF_ELEM counterpart to op.
+ *
+ * Otherwise, if op has JOF_PROP mode, emit JSOP_LITERAL before op, to push
+ * the atom's value key.  For JOF_PROP ops, the object being operated on has
+ * already been pushed, and JSOP_LITERAL will push the id, leaving the stack
+ * in the proper state for a JOF_ELEM counterpart.
+ *
+ * Otherwise, emit JSOP_LITOPX to push the atom index, then perform a special
+ * dispatch on op, but getting op's atom index from the stack instead of from
+ * an unsigned 16-bit immediate operand.
+ */
+static JSBool
+EmitAtomIndexOp(JSContext *cx, JSOp op, jsatomid atomIndex, JSCodeGenerator *cg)
+{
+    uint32 mode;
+    JSOp prefixOp;
+    ptrdiff_t off;
+    jsbytecode *pc;
+
+    if (atomIndex >= JS_BIT(16)) {
+        if (op != JSOP_SETNAME) {
+            mode = (js_CodeSpec[op].format & JOF_MODEMASK);
+            prefixOp = (mode == JOF_NAME)
+                       ? JSOP_FINDNAME
+                       : (mode == JOF_PROP)
+                       ? JSOP_LITERAL
+                       : JSOP_LITOPX;
+            off = js_EmitN(cx, cg, prefixOp, 3);
+            if (off < 0)
+                return JS_FALSE;
+            pc = CG_CODE(cg, off);
+            SET_LITERAL_INDEX(pc, atomIndex);
+        }
+
+        switch (op) {
+          case JSOP_DECNAME:    op = JSOP_DECELEM; break;
+          case JSOP_DECPROP:    op = JSOP_DECELEM; break;
+          case JSOP_DELNAME:    op = JSOP_DELELEM; break;
+          case JSOP_DELPROP:    op = JSOP_DELELEM; break;
+          case JSOP_FORNAME:    op = JSOP_FORELEM; break;
+          case JSOP_FORPROP:    op = JSOP_FORELEM; break;
+          case JSOP_GETPROP:    op = JSOP_GETELEM; break;
+          case JSOP_IMPORTPROP: op = JSOP_IMPORTELEM; break;
+          case JSOP_INCNAME:    op = JSOP_INCELEM; break;
+          case JSOP_INCPROP:    op = JSOP_INCELEM; break;
+          case JSOP_INITPROP:   op = JSOP_INITELEM; break;
+          case JSOP_NAME:       op = JSOP_GETELEM; break;
+          case JSOP_NAMEDEC:    op = JSOP_ELEMDEC; break;
+          case JSOP_NAMEINC:    op = JSOP_ELEMINC; break;
+          case JSOP_PROPDEC:    op = JSOP_ELEMDEC; break;
+          case JSOP_PROPINC:    op = JSOP_ELEMINC; break;
+          case JSOP_BINDNAME:   return JS_TRUE;
+          case JSOP_SETNAME:    op = JSOP_SETELEM; break;
+          case JSOP_SETPROP:    op = JSOP_SETELEM; break;
+          default:              JS_ASSERT(mode == 0); break;
+        }
+
+        return js_Emit1(cx, cg, op) >= 0;
+    }
+
+    EMIT_UINT16_IMM_OP(op, atomIndex);
+    return JS_TRUE;
+}
+
+/*
+ * Slight sugar for EmitAtomIndexOp, again accessing cx and cg from the macro
+ * caller's lexical environment, and embedding a false return on error.
+ * XXXbe hey, who checks for fun->nvars and fun->nargs overflow?!
+ */
+#define EMIT_ATOM_INDEX_OP(op, atomIndex)                                     \
+    JS_BEGIN_MACRO                                                            \
+        if (!EmitAtomIndexOp(cx, op, atomIndex, cg) < 0)                      \
+            return JS_FALSE;                                                  \
+    JS_END_MACRO
+
+static JSBool
+EmitAtomOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
+{
+    JSAtomListElement *ale;
+
+    ale = js_IndexAtom(cx, pn->pn_atom, &cg->atomList);
+    if (!ale)
+        return JS_FALSE;
+    if (op == JSOP_REGEXP && !IndexRegExpClone(cx, pn, ale, cg))
+        return JS_FALSE;
+    return EmitAtomIndexOp(cx, op, ALE_INDEX(ale), cg);
+}
+
+/*
+ * This routine tries to optimize name gets and sets to stack slot loads and
+ * stores, given the variables object and scope chain in cx's top frame, the
+ * compile-time context in tc, and a TOK_NAME node pn.  It returns false on
+ * error, true on success.
+ *
+ * The caller can inspect pn->pn_slot for a non-negative slot number to tell
+ * whether optimization occurred, in which case LookupArgOrVar also updated
+ * pn->pn_op.  If pn->pn_slot is still -1 on return, pn->pn_op nevertheless
+ * may have been optimized, e.g., from JSOP_NAME to JSOP_ARGUMENTS.  Whether
+ * or not pn->pn_op was modified, if this function finds an argument or local
+ * variable name, pn->pn_attrs will contain the property's attributes after a
+ * successful return.
+ */
+static JSBool
+LookupArgOrVar(JSContext *cx, JSTreeContext *tc, JSParseNode *pn)
+{
+    JSStackFrame *fp;
+    JSObject *obj, *pobj;
+    JSClass *clasp;
+    JSBool optimizeGlobals;
+    JSAtom *atom;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+    JSOp op;
+    JSPropertyOp getter;
+    uintN attrs;
+    jsint slot;
+    JSAtomListElement *ale;
+
+    JS_ASSERT(pn->pn_type == TOK_NAME);
+    if (pn->pn_slot >= 0 || pn->pn_op == JSOP_ARGUMENTS)
+        return JS_TRUE;
+
+    /* QNAME references can never be optimized to use arg/var storage. */
+    if (pn->pn_op == JSOP_QNAMEPART)
+        return JS_TRUE;
+
+    /*
+     * A Script object can be used to split an eval into a compile step done
+     * at construction time, and an execute step done separately, possibly in
+     * a different scope altogether.  We therefore cannot do any name-to-slot
+     * optimizations, but must lookup names at runtime.  Note that script_exec
+     * ensures that its caller's frame has a Call object, so arg and var name
+     * lookups will succeed.
+     */
+    if (cx->fp->flags & JSFRAME_SCRIPT_OBJECT)
+        return JS_TRUE;
+
+    /*
+     * We can't optimize if var and closure (a local function not in a larger
+     * expression and not at top-level within another's body) collide.
+     * XXX suboptimal: keep track of colliding names and deoptimize only those
+     */
+    if (tc->flags & TCF_FUN_CLOSURE_VS_VAR)
+        return JS_TRUE;
+
+    /*
+     * We can't optimize if we're not compiling a function body, whether via
+     * eval, or directly when compiling a function statement or expression.
+     */
+    fp = cx->fp;
+    obj = fp->varobj;
+    clasp = OBJ_GET_CLASS(cx, obj);
+    if (clasp != &js_FunctionClass && clasp != &js_CallClass) {
+        /*
+         * Optimize global variable accesses if there are at least 100 uses
+         * in unambiguous contexts, or failing that, if least half of all the
+         * uses of global vars/consts/functions are in loops.
+         */
+        optimizeGlobals = (tc->globalUses >= 100 ||
+                           (tc->loopyGlobalUses &&
+                            tc->loopyGlobalUses >= tc->globalUses / 2));
+        if (!optimizeGlobals)
+            return JS_TRUE;
+    } else {
+        optimizeGlobals = JS_FALSE;
+    }
+
+    /*
+     * We can't optimize if we're in an eval called inside a with statement,
+     * or we're compiling a with statement and its body, or we're in a catch
+     * block whose exception variable has the same name as pn.
+     */
+    atom = pn->pn_atom;
+    if (fp->scopeChain != obj ||
+        js_InWithStatement(tc) ||
+        js_InCatchBlock(tc, atom)) {
+        return JS_TRUE;
+    }
+
+    op = pn->pn_op;
+    getter = NULL;
+#ifdef __GNUC__
+    attrs = slot = 0;   /* quell GCC overwarning */
+#endif
+    if (optimizeGlobals) {
+        /*
+         * We are optimizing global variables, and there is no pre-existing
+         * global property named atom.  If atom was declared via const or var,
+         * optimize pn to access fp->vars using the appropriate JOF_QVAR op.
+         */
+        ATOM_LIST_SEARCH(ale, &tc->decls, atom);
+        if (!ale) {
+            /* Use precedes declaration, or name is never declared. */
+            return JS_TRUE;
+        }
+
+        attrs = (ALE_JSOP(ale) == JSOP_DEFCONST)
+                ? JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT
+                : JSPROP_ENUMERATE | JSPROP_PERMANENT;
+
+        /* Index atom so we can map fast global number to name. */
+        JS_ASSERT(tc->flags & TCF_COMPILING);
+        ale = js_IndexAtom(cx, atom, &((JSCodeGenerator *) tc)->atomList);
+        if (!ale)
+            return JS_FALSE;
+
+        /* Defend against tc->numGlobalVars 16-bit overflow. */
+        slot = ALE_INDEX(ale);
+        if ((slot + 1) >> 16)
+            return JS_TRUE;
+
+        if ((uint16)(slot + 1) > tc->numGlobalVars)
+            tc->numGlobalVars = (uint16)(slot + 1);
+    } else {
+        /*
+         * We may be able to optimize name to stack slot. Look for an argument
+         * or variable property in the function, or its call object, not found
+         * in any prototype object.  Rewrite pn_op and update pn accordingly.
+         * NB: We know that JSOP_DELNAME on an argument or variable evaluates
+         * to false, due to JSPROP_PERMANENT.
+         */
+        if (!js_LookupHiddenProperty(cx, obj, ATOM_TO_JSID(atom), &pobj, &prop))
+            return JS_FALSE;
+        sprop = (JSScopeProperty *) prop;
+        if (sprop) {
+            if (pobj == obj) {
+                getter = sprop->getter;
+                attrs = sprop->attrs;
+                slot = (sprop->flags & SPROP_HAS_SHORTID) ? sprop->shortid : -1;
+            }
+            OBJ_DROP_PROPERTY(cx, pobj, prop);
+        }
+    }
+
+    if (optimizeGlobals || getter) {
+        if (optimizeGlobals) {
+            switch (op) {
+              case JSOP_NAME:     op = JSOP_GETGVAR; break;
+              case JSOP_SETNAME:  op = JSOP_SETGVAR; break;
+              case JSOP_SETCONST: /* NB: no change */ break;
+              case JSOP_INCNAME:  op = JSOP_INCGVAR; break;
+              case JSOP_NAMEINC:  op = JSOP_GVARINC; break;
+              case JSOP_DECNAME:  op = JSOP_DECGVAR; break;
+              case JSOP_NAMEDEC:  op = JSOP_GVARDEC; break;
+              case JSOP_FORNAME:  /* NB: no change */ break;
+              case JSOP_DELNAME:  /* NB: no change */ break;
+              default: JS_ASSERT(0);
+            }
+        } else if (getter == js_GetLocalVariable ||
+                   getter == js_GetCallVariable) {
+            switch (op) {
+              case JSOP_NAME:     op = JSOP_GETVAR; break;
+              case JSOP_SETNAME:  op = JSOP_SETVAR; break;
+              case JSOP_SETCONST: op = JSOP_SETVAR; break;
+              case JSOP_INCNAME:  op = JSOP_INCVAR; break;
+              case JSOP_NAMEINC:  op = JSOP_VARINC; break;
+              case JSOP_DECNAME:  op = JSOP_DECVAR; break;
+              case JSOP_NAMEDEC:  op = JSOP_VARDEC; break;
+              case JSOP_FORNAME:  op = JSOP_FORVAR; break;
+              case JSOP_DELNAME:  op = JSOP_FALSE; break;
+              default: JS_ASSERT(0);
+            }
+        } else if (getter == js_GetArgument ||
+                   (getter == js_CallClass.getProperty &&
+                    fp->fun && (uintN) slot < fp->fun->nargs)) {
+            switch (op) {
+              case JSOP_NAME:     op = JSOP_GETARG; break;
+              case JSOP_SETNAME:  op = JSOP_SETARG; break;
+              case JSOP_INCNAME:  op = JSOP_INCARG; break;
+              case JSOP_NAMEINC:  op = JSOP_ARGINC; break;
+              case JSOP_DECNAME:  op = JSOP_DECARG; break;
+              case JSOP_NAMEDEC:  op = JSOP_ARGDEC; break;
+              case JSOP_FORNAME:  op = JSOP_FORARG; break;
+              case JSOP_DELNAME:  op = JSOP_FALSE; break;
+              default: JS_ASSERT(0);
+            }
+        }
+        if (op != pn->pn_op) {
+            pn->pn_op = op;
+            pn->pn_slot = slot;
+        }
+        pn->pn_attrs = attrs;
+    }
+
+    if (pn->pn_slot < 0) {
+        /*
+         * We couldn't optimize pn, so it's not a global or local slot name.
+         * Now we must check for the predefined arguments variable.  It may be
+         * overridden by assignment, in which case the function is heavyweight
+         * and the interpreter will look up 'arguments' in the function's call
+         * object.
+         */
+        if (pn->pn_op == JSOP_NAME &&
+            atom == cx->runtime->atomState.argumentsAtom) {
+            pn->pn_op = JSOP_ARGUMENTS;
+            return JS_TRUE;
+        }
+
+        tc->flags |= TCF_FUN_USES_NONLOCALS;
+    }
+    return JS_TRUE;
+}
+
+/*
+ * If pn contains a useful expression, return true with *answer set to true.
+ * If pn contains a useless expression, return true with *answer set to false.
+ * Return false on error.
+ *
+ * The caller should initialize *answer to false and invoke this function on
+ * an expression statement or similar subtree to decide whether the tree could
+ * produce code that has any side effects.  For an expression statement, we
+ * define useless code as code with no side effects, because the main effect,
+ * the value left on the stack after the code executes, will be discarded by a
+ * pop bytecode.
+ */
+static JSBool
+CheckSideEffects(JSContext *cx, JSTreeContext *tc, JSParseNode *pn,
+                 JSBool *answer)
+{
+    JSBool ok;
+    JSFunction *fun;
+    JSParseNode *pn2;
+
+    ok = JS_TRUE;
+    if (!pn || *answer)
+        return ok;
+
+    switch (pn->pn_arity) {
+      case PN_FUNC:
+        /*
+         * A named function is presumed useful: we can't yet know that it is
+         * not called.  The side effects are the creation of a scope object
+         * to parent this function object, and the binding of the function's
+         * name in that scope object.  See comments at case JSOP_NAMEDFUNOBJ:
+         * in jsinterp.c.
+         */
+        fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(pn->pn_funAtom));
+        if (fun->atom)
+            *answer = JS_TRUE;
+        break;
+
+      case PN_LIST:
+        if (pn->pn_type == TOK_NEW ||
+            pn->pn_type == TOK_LP ||
+            pn->pn_type == TOK_LB) {
+            /*
+             * All invocation operations (construct: TOK_NEW, call: TOK_LP)
+             * are presumed to be useful, because they may have side effects
+             * even if their main effect (their return value) is discarded.
+             *
+             * TOK_LB binary trees of 3 or more nodes are flattened into lists
+             * to avoid too much recursion.  All such lists must be presumed
+             * to be useful because each index operation could invoke a getter
+             * (the JSOP_ARGUMENTS special case below, in the PN_BINARY case,
+             * does not apply here: arguments[i][j] might invoke a getter).
+             */
+            *answer = JS_TRUE;
+        } else {
+            for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next)
+                ok &= CheckSideEffects(cx, tc, pn2, answer);
+        }
+        break;
+
+      case PN_TERNARY:
+        ok = CheckSideEffects(cx, tc, pn->pn_kid1, answer) &&
+             CheckSideEffects(cx, tc, pn->pn_kid2, answer) &&
+             CheckSideEffects(cx, tc, pn->pn_kid3, answer);
+        break;
+
+      case PN_BINARY:
+        if (pn->pn_type == TOK_ASSIGN) {
+            /*
+             * Assignment is presumed to be useful, even if the next operation
+             * is another assignment overwriting this one's ostensible effect,
+             * because the left operand may be a property with a setter that
+             * has side effects.
+             */
+            *answer = JS_TRUE;
+        } else {
+            if (pn->pn_type == TOK_LB) {
+                pn2 = pn->pn_left;
+                if (pn2->pn_type == TOK_NAME && !LookupArgOrVar(cx, tc, pn2))
+                    return JS_FALSE;
+                if (pn2->pn_op != JSOP_ARGUMENTS) {
+                    /*
+                     * Any indexed property reference could call a getter with
+                     * side effects, except for arguments[i] where arguments is
+                     * unambiguous.
+                     */
+                    *answer = JS_TRUE;
+                }
+            }
+            ok = CheckSideEffects(cx, tc, pn->pn_left, answer) &&
+                 CheckSideEffects(cx, tc, pn->pn_right, answer);
+        }
+        break;
+
+      case PN_UNARY:
+        if (pn->pn_type == TOK_INC || pn->pn_type == TOK_DEC ||
+            pn->pn_type == TOK_DELETE ||
+            pn->pn_type == TOK_THROW ||
+            pn->pn_type == TOK_DEFSHARP) {
+            /* All these operations have effects that we must commit. */
+            *answer = JS_TRUE;
+        } else {
+            ok = CheckSideEffects(cx, tc, pn->pn_kid, answer);
+        }
+        break;
+
+      case PN_NAME:
+        if (pn->pn_type == TOK_NAME) {
+            if (!LookupArgOrVar(cx, tc, pn))
+                return JS_FALSE;
+            if (pn->pn_slot < 0 && pn->pn_op != JSOP_ARGUMENTS) {
+                /*
+                 * Not an argument or local variable use, so this expression
+                 * could invoke a getter that has side effects.
+                 */
+                *answer = JS_TRUE;
+            }
+        }
+        pn2 = pn->pn_expr;
+        if (pn->pn_type == TOK_DOT) {
+            if (pn2->pn_type == TOK_NAME && !LookupArgOrVar(cx, tc, pn2))
+                return JS_FALSE;
+            if (!(pn2->pn_op == JSOP_ARGUMENTS &&
+                  pn->pn_atom == cx->runtime->atomState.lengthAtom)) {
+                /*
+                 * Any dotted property reference could call a getter, except
+                 * for arguments.length where arguments is unambiguous.
+                 */
+                *answer = JS_TRUE;
+            }
+        }
+        ok = CheckSideEffects(cx, tc, pn2, answer);
+        break;
+
+      case PN_NULLARY:
+        if (pn->pn_type == TOK_DEBUGGER)
+            *answer = JS_TRUE;
+        break;
+    }
+    return ok;
+}
+
+/*
+ * Secret handshake with js_EmitTree's TOK_LP/TOK_NEW case logic, to flag all
+ * uses of JSOP_GETMETHOD that implicitly qualify the method-property name with
+ * a function:: prefix.  All other JSOP_GETMETHOD and JSOP_SETMETHOD uses must
+ * be explicit, so need a distinct source note (SRC_PCDELTA rather than PCBASE)
+ * for round-tripping through the beloved decompiler.
+ */
+#define JSPROP_IMPLICIT_FUNCTION_NAMESPACE      0x100
+
+static jssrcnote
+SrcNoteForPropOp(JSParseNode *pn, JSOp op)
+{
+    return ((op == JSOP_GETMETHOD &&
+             !(pn->pn_attrs & JSPROP_IMPLICIT_FUNCTION_NAMESPACE)) ||
+            op == JSOP_SETMETHOD)
+           ? SRC_PCDELTA
+           : SRC_PCBASE;
+}
+
+static JSBool
+EmitPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
+{
+    JSParseNode *pn2, *pndot, *pnup, *pndown;
+    ptrdiff_t top;
+
+    pn2 = pn->pn_expr;
+    if (op == JSOP_GETPROP &&
+        pn->pn_type == TOK_DOT &&
+        pn2->pn_type == TOK_NAME) {
+        /* Try to optimize arguments.length into JSOP_ARGCNT. */
+        if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
+            return JS_FALSE;
+        if (pn2->pn_op == JSOP_ARGUMENTS &&
+            pn->pn_atom == cx->runtime->atomState.lengthAtom) {
+            return js_Emit1(cx, cg, JSOP_ARGCNT) >= 0;
+        }
+    }
+
+    /*
+     * If the object operand is also a dotted property reference, reverse the
+     * list linked via pn_expr temporarily so we can iterate over it from the
+     * bottom up (reversing again as we go), to avoid excessive recursion.
+     */
+    if (pn2->pn_type == TOK_DOT) {
+        pndot = pn2;
+        pnup = NULL;
+        top = CG_OFFSET(cg);
+        for (;;) {
+            /* Reverse pndot->pn_expr to point up, not down. */
+            pndot->pn_offset = top;
+            pndown = pndot->pn_expr;
+            pndot->pn_expr = pnup;
+            if (pndown->pn_type != TOK_DOT)
+                break;
+            pnup = pndot;
+            pndot = pndown;
+        }
+
+        /* pndown is a primary expression, not a dotted property reference. */
+        if (!js_EmitTree(cx, cg, pndown))
+            return JS_FALSE;
+
+        do {
+            /* Walk back up the list, emitting annotated name ops. */
+            if (js_NewSrcNote2(cx, cg, SrcNoteForPropOp(pndot, pndot->pn_op),
+                               CG_OFFSET(cg) - pndown->pn_offset) < 0) {
+                return JS_FALSE;
+            }
+            if (!EmitAtomOp(cx, pndot, pndot->pn_op, cg))
+                return JS_FALSE;
+
+            /* Reverse the pn_expr link again. */
+            pnup = pndot->pn_expr;
+            pndot->pn_expr = pndown;
+            pndown = pndot;
+        } while ((pndot = pnup) != NULL);
+    } else {
+        if (!js_EmitTree(cx, cg, pn2))
+            return JS_FALSE;
+    }
+
+    if (js_NewSrcNote2(cx, cg, SrcNoteForPropOp(pn, op),
+                       CG_OFFSET(cg) - pn2->pn_offset) < 0) {
+        return JS_FALSE;
+    }
+    if (!pn->pn_atom) {
+        JS_ASSERT(op == JSOP_IMPORTALL);
+        if (js_Emit1(cx, cg, op) < 0)
+            return JS_FALSE;
+    } else {
+        if (!EmitAtomOp(cx, pn, op, cg))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
+{
+    ptrdiff_t top;
+    JSParseNode *left, *right, *next, temp;
+    jsint slot;
+
+    top = CG_OFFSET(cg);
+    if (pn->pn_arity == PN_LIST) {
+        /* Left-associative operator chain to avoid too much recursion. */
+        JS_ASSERT(pn->pn_op == JSOP_GETELEM);
+        JS_ASSERT(pn->pn_count >= 3);
+        left = pn->pn_head;
+        right = PN_LAST(pn);
+        next = left->pn_next;
+        JS_ASSERT(next != right);
+
+        /*
+         * Try to optimize arguments[0][j]... into JSOP_ARGSUB<0> followed by
+         * one or more index expression and JSOP_GETELEM op pairs.
+         */
+        if (left->pn_type == TOK_NAME && next->pn_type == TOK_NUMBER) {
+            if (!LookupArgOrVar(cx, &cg->treeContext, left))
+                return JS_FALSE;
+            if (left->pn_op == JSOP_ARGUMENTS &&
+                JSDOUBLE_IS_INT(next->pn_dval, slot) &&
+                (jsuint)slot < JS_BIT(16)) {
+                left->pn_offset = next->pn_offset = top;
+                EMIT_UINT16_IMM_OP(JSOP_ARGSUB, (jsatomid)slot);
+                left = next;
+                next = left->pn_next;
+            }
+        }
+
+        /*
+         * Check whether we generated JSOP_ARGSUB, just above, and have only
+         * one more index expression to emit.  Given arguments[0][j], we must
+         * skip the while loop altogether, falling through to emit code for j
+         * (in the subtree referenced by right), followed by the annotated op,
+         * at the bottom of this function.
+         */
+        JS_ASSERT(next != right || pn->pn_count == 3);
+        if (left == pn->pn_head) {
+            if (!js_EmitTree(cx, cg, left))
+                return JS_FALSE;
+        }
+        while (next != right) {
+            if (!js_EmitTree(cx, cg, next))
+                return JS_FALSE;
+            if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0)
+                return JS_FALSE;
+            if (js_Emit1(cx, cg, JSOP_GETELEM) < 0)
+                return JS_FALSE;
+            next = next->pn_next;
+        }
+    } else {
+        if (pn->pn_arity == PN_NAME) {
+            /*
+             * Set left and right so pn appears to be a TOK_LB node, instead
+             * of a TOK_DOT node (see the TOK_FOR/IN case in js_EmitTree).
+             */
+            left = pn->pn_expr;
+            right = &temp;
+            right->pn_type = TOK_STRING;
+            right->pn_arity = PN_NULLARY;
+            right->pn_op = JSOP_STRING;
+            right->pn_atom = pn->pn_atom;
+        } else {
+            JS_ASSERT(pn->pn_arity == PN_BINARY);
+            left = pn->pn_left;
+            right = pn->pn_right;
+        }
+
+        /* Try to optimize arguments[0] (e.g.) into JSOP_ARGSUB<0>. */
+        if (op == JSOP_GETELEM &&
+            left->pn_type == TOK_NAME &&
+            right->pn_type == TOK_NUMBER) {
+            if (!LookupArgOrVar(cx, &cg->treeContext, left))
+                return JS_FALSE;
+            if (left->pn_op == JSOP_ARGUMENTS &&
+                JSDOUBLE_IS_INT(right->pn_dval, slot) &&
+                (jsuint)slot < JS_BIT(16)) {
+                left->pn_offset = right->pn_offset = top;
+                EMIT_UINT16_IMM_OP(JSOP_ARGSUB, (jsatomid)slot);
+                return JS_TRUE;
+            }
+        }
+
+        if (!js_EmitTree(cx, cg, left))
+            return JS_FALSE;
+    }
+    if (!js_EmitTree(cx, cg, right))
+        return JS_FALSE;
+    if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0)
+        return JS_FALSE;
+    return js_Emit1(cx, cg, op) >= 0;
+}
+
+static JSBool
+EmitNumberOp(JSContext *cx, jsdouble dval, JSCodeGenerator *cg)
+{
+    jsint ival;
+    jsatomid atomIndex;
+    ptrdiff_t off;
+    jsbytecode *pc;
+    JSAtom *atom;
+    JSAtomListElement *ale;
+
+    if (JSDOUBLE_IS_INT(dval, ival) && INT_FITS_IN_JSVAL(ival)) {
+        if (ival == 0)
+            return js_Emit1(cx, cg, JSOP_ZERO) >= 0;
+        if (ival == 1)
+            return js_Emit1(cx, cg, JSOP_ONE) >= 0;
+
+        atomIndex = (jsatomid)ival;
+        if (atomIndex < JS_BIT(16)) {
+            EMIT_UINT16_IMM_OP(JSOP_UINT16, atomIndex);
+            return JS_TRUE;
+        }
+
+        if (atomIndex < JS_BIT(24)) {
+            off = js_EmitN(cx, cg, JSOP_UINT24, 3);
+            if (off < 0)
+                return JS_FALSE;
+            pc = CG_CODE(cg, off);
+            SET_LITERAL_INDEX(pc, atomIndex);
+            return JS_TRUE;
+        }
+
+        atom = js_AtomizeInt(cx, ival, 0);
+    } else {
+        atom = js_AtomizeDouble(cx, dval, 0);
+    }
+    if (!atom)
+        return JS_FALSE;
+
+    ale = js_IndexAtom(cx, atom, &cg->atomList);
+    if (!ale)
+        return JS_FALSE;
+    return EmitAtomIndexOp(cx, JSOP_NUMBER, ALE_INDEX(ale), cg);
+}
+
+#if JS_HAS_SWITCH_STATEMENT
+static JSBool
+EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
+           JSStmtInfo *stmtInfo)
+{
+    JSOp switchOp;
+    JSBool ok, hasDefault, constPropagated;
+    ptrdiff_t top, off, defaultOffset;
+    JSParseNode *pn2, *pn3, *pn4;
+    uint32 caseCount, tableLength;
+    JSParseNode **table;
+    jsdouble d;
+    jsint i, low, high;
+    jsval v;
+    JSAtom *atom;
+    JSAtomListElement *ale;
+    intN noteIndex;
+    size_t switchSize, tableSize;
+    jsbytecode *pc, *savepc;
+
+    /* Try for most optimal, fall back if not dense ints, and per ECMAv2. */
+    switchOp = JSOP_TABLESWITCH;
+    ok = JS_TRUE;
+    hasDefault = constPropagated = JS_FALSE;
+    defaultOffset = -1;
+
+    /* Emit code for the discriminant first. */
+    if (!js_EmitTree(cx, cg, pn->pn_kid1))
+        return JS_FALSE;
+
+    /* Switch bytecodes run from here till end of final case. */
+    top = CG_OFFSET(cg);
+    js_PushStatement(&cg->treeContext, stmtInfo, STMT_SWITCH, top);
+
+    pn2 = pn->pn_kid2;
+    caseCount = pn2->pn_count;
+    tableLength = 0;
+    table = NULL;
+
+    if (caseCount == 0 ||
+        (caseCount == 1 &&
+         (hasDefault = (pn2->pn_head->pn_type == TOK_DEFAULT)))) {
+        caseCount = 0;
+        low = 0;
+        high = -1;
+    } else {
+#define INTMAP_LENGTH   256
+        jsbitmap intmap_space[INTMAP_LENGTH];
+        jsbitmap *intmap = NULL;
+        int32 intmap_bitlen = 0;
+
+        low  = JSVAL_INT_MAX;
+        high = JSVAL_INT_MIN;
+
+        for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
+            if (pn3->pn_type == TOK_DEFAULT) {
+                hasDefault = JS_TRUE;
+                caseCount--;    /* one of the "cases" was the default */
+                continue;
+            }
+
+            JS_ASSERT(pn3->pn_type == TOK_CASE);
+            if (switchOp == JSOP_CONDSWITCH)
+                continue;
+
+            pn4 = pn3->pn_left;
+            switch (pn4->pn_type) {
+              case TOK_NUMBER:
+                d = pn4->pn_dval;
+                if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
+                    pn3->pn_val = INT_TO_JSVAL(i);
+                } else {
+                    atom = js_AtomizeDouble(cx, d, 0);
+                    if (!atom) {
+                        ok = JS_FALSE;
+                        goto release;
+                    }
+                    pn3->pn_val = ATOM_KEY(atom);
+                }
+                break;
+              case TOK_STRING:
+                pn3->pn_val = ATOM_KEY(pn4->pn_atom);
+                break;
+              case TOK_NAME:
+                if (!pn4->pn_expr) {
+                    ok = js_LookupCompileTimeConstant(cx, cg, pn4->pn_atom, &v);
+                    if (!ok)
+                        goto release;
+                    if (!JSVAL_IS_VOID(v)) {
+                        pn3->pn_val = v;
+                        constPropagated = JS_TRUE;
+                        break;
+                    }
+                }
+                /* FALL THROUGH */
+              case TOK_PRIMARY:
+                if (pn4->pn_op == JSOP_TRUE) {
+                    pn3->pn_val = JSVAL_TRUE;
+                    break;
+                }
+                if (pn4->pn_op == JSOP_FALSE) {
+                    pn3->pn_val = JSVAL_FALSE;
+                    break;
+                }
+                /* FALL THROUGH */
+              default:
+                switchOp = JSOP_CONDSWITCH;
+                continue;
+            }
+
+            JS_ASSERT(JSVAL_IS_NUMBER(pn3->pn_val) ||
+                      JSVAL_IS_STRING(pn3->pn_val) ||
+                      JSVAL_IS_BOOLEAN(pn3->pn_val));
+
+            if (switchOp != JSOP_TABLESWITCH)
+                continue;
+            if (!JSVAL_IS_INT(pn3->pn_val)) {
+                switchOp = JSOP_LOOKUPSWITCH;
+                continue;
+            }
+            i = JSVAL_TO_INT(pn3->pn_val);
+            if ((jsuint)(i + (jsint)JS_BIT(15)) >= (jsuint)JS_BIT(16)) {
+                switchOp = JSOP_LOOKUPSWITCH;
+                continue;
+            }
+            if (i < low)
+                low = i;
+            if (high < i)
+                high = i;
+
+            /*
+             * Check for duplicates, which require a JSOP_LOOKUPSWITCH.
+             * We bias i by 65536 if it's negative, and hope that's a rare
+             * case (because it requires a malloc'd bitmap).
+             */
+            if (i < 0)
+                i += JS_BIT(16);
+            if (i >= intmap_bitlen) {
+                if (!intmap &&
+                    i < (INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2)) {
+                    intmap = intmap_space;
+                    intmap_bitlen = INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2;
+                } else {
+                    /* Just grab 8K for the worst-case bitmap. */
+                    intmap_bitlen = JS_BIT(16);
+                    intmap = (jsbitmap *)
+                        JS_malloc(cx,
+                                  (JS_BIT(16) >> JS_BITS_PER_WORD_LOG2)
+                                  * sizeof(jsbitmap));
+                    if (!intmap) {
+                        JS_ReportOutOfMemory(cx);
+                        return JS_FALSE;
+                    }
+                }
+                memset(intmap, 0, intmap_bitlen >> JS_BITS_PER_BYTE_LOG2);
+            }
+            if (JS_TEST_BIT(intmap, i)) {
+                switchOp = JSOP_LOOKUPSWITCH;
+                continue;
+            }
+            JS_SET_BIT(intmap, i);
+        }
+
+      release:
+        if (intmap && intmap != intmap_space)
+            JS_free(cx, intmap);
+        if (!ok)
+            return JS_FALSE;
+
+        /*
+         * Compute table length and select lookup instead if overlarge or
+         * more than half-sparse.
+         */
+        if (switchOp == JSOP_TABLESWITCH) {
+            tableLength = (uint32)(high - low + 1);
+            if (tableLength >= JS_BIT(16) || tableLength > 2 * caseCount)
+                switchOp = JSOP_LOOKUPSWITCH;
+        }
+    }
+
+    /*
+     * Emit a note with two offsets: first tells total switch code length,
+     * second tells offset to first JSOP_CASE if condswitch.
+     */
+    noteIndex = js_NewSrcNote3(cx, cg, SRC_SWITCH, 0, 0);
+    if (noteIndex < 0)
+        return JS_FALSE;
+
+    if (switchOp == JSOP_CONDSWITCH) {
+        /*
+         * 0 bytes of immediate for unoptimized ECMAv2 switch.
+         */
+        switchSize = 0;
+    } else if (switchOp == JSOP_TABLESWITCH) {
+        /*
+         * 3 offsets (len, low, high) before the table, 1 per entry.
+         */
+        switchSize = (size_t)(JUMP_OFFSET_LEN * (3 + tableLength));
+    } else {
+        /*
+         * JSOP_LOOKUPSWITCH:
+         * 1 offset (len) and 1 atom index (npairs) before the table,
+         * 1 atom index and 1 jump offset per entry.
+         */
+        switchSize = (size_t)(JUMP_OFFSET_LEN + ATOM_INDEX_LEN +
+                              (ATOM_INDEX_LEN + JUMP_OFFSET_LEN) * caseCount);
+    }
+
+    /*
+     * Emit switchOp followed by switchSize bytes of jump or lookup table.
+     *
+     * If switchOp is JSOP_LOOKUPSWITCH or JSOP_TABLESWITCH, it is crucial
+     * to emit the immediate operand(s) by which bytecode readers such as
+     * BuildSpanDepTable discover the length of the switch opcode *before*
+     * calling js_SetJumpOffset (which may call BuildSpanDepTable).  It's
+     * also important to zero all unknown jump offset immediate operands,
+     * so they can be converted to span dependencies with null targets to
+     * be computed later (js_EmitN zeros switchSize bytes after switchOp).
+     */
+    if (js_EmitN(cx, cg, switchOp, switchSize) < 0)
+        return JS_FALSE;
+
+    off = -1;
+    if (switchOp == JSOP_CONDSWITCH) {
+        intN caseNoteIndex = -1;
+        JSBool beforeCases = JS_TRUE;
+
+        /* Emit code for evaluating cases and jumping to case statements. */
+        for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
+            pn4 = pn3->pn_left;
+            if (pn4 && !js_EmitTree(cx, cg, pn4))
+                return JS_FALSE;
+            if (caseNoteIndex >= 0) {
+                /* off is the previous JSOP_CASE's bytecode offset. */
+                if (!js_SetSrcNoteOffset(cx, cg, (uintN)caseNoteIndex, 0,
+                                         CG_OFFSET(cg) - off)) {
+                    return JS_FALSE;
+                }
+            }
+            if (!pn4) {
+                JS_ASSERT(pn3->pn_type == TOK_DEFAULT);
+                continue;
+            }
+            caseNoteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);
+            if (caseNoteIndex < 0)
+                return JS_FALSE;
+            off = EmitJump(cx, cg, JSOP_CASE, 0);
+            if (off < 0)
+                return JS_FALSE;
+            pn3->pn_offset = off;
+            if (beforeCases) {
+                /* Switch note's second offset is to first JSOP_CASE. */
+                if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 1,
+                                         off - top)) {
+                    return JS_FALSE;
+                }
+                beforeCases = JS_FALSE;
+            }
+        }
+
+        /* Emit default even if no explicit default statement. */
+        defaultOffset = EmitJump(cx, cg, JSOP_DEFAULT, 0);
+        if (defaultOffset < 0)
+            return JS_FALSE;
+    } else {
+        pc = CG_CODE(cg, top + JUMP_OFFSET_LEN);
+
+        if (switchOp == JSOP_TABLESWITCH) {
+            /* Fill in switch bounds, which we know fit in 16-bit offsets. */
+            SET_JUMP_OFFSET(pc, low);
+            pc += JUMP_OFFSET_LEN;
+            SET_JUMP_OFFSET(pc, high);
+            pc += JUMP_OFFSET_LEN;
+
+            /*
+             * Use malloc to avoid arena bloat for programs with many switches.
+             * We free table if non-null at label out, so all control flow must
+             * exit this function through goto out or goto bad.
+             */
+            if (tableLength != 0) {
+                tableSize = (size_t)tableLength * sizeof *table;
+                table = (JSParseNode **) JS_malloc(cx, tableSize);
+                if (!table)
+                    return JS_FALSE;
+                memset(table, 0, tableSize);
+                for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
+                    if (pn3->pn_type == TOK_DEFAULT)
+                        continue;
+                    i = JSVAL_TO_INT(pn3->pn_val);
+                    i -= low;
+                    JS_ASSERT((uint32)i < tableLength);
+                    table[i] = pn3;
+                }
+            }
+        } else {
+            JS_ASSERT(switchOp == JSOP_LOOKUPSWITCH);
+
+            /* Fill in the number of cases. */
+            SET_ATOM_INDEX(pc, caseCount);
+            pc += ATOM_INDEX_LEN;
+        }
+
+        /*
+         * After this point, all control flow involving JSOP_TABLESWITCH
+         * must set ok and goto out to exit this function.  To keep things
+         * simple, all switchOp cases exit that way.
+         */
+        if (constPropagated) {
+            /*
+             * Skip switchOp, as we are not setting jump offsets in the two
+             * for loops below.  We'll restore CG_NEXT(cg) from savepc after,
+             * unless there was an error.
+             */
+            savepc = CG_NEXT(cg);
+            CG_NEXT(cg) = pc + 1;
+            if (switchOp == JSOP_TABLESWITCH) {
+                for (i = 0; i < (jsint)tableLength; i++) {
+                    pn3 = table[i];
+                    if (pn3 &&
+                        (pn4 = pn3->pn_left) != NULL &&
+                        pn4->pn_type == TOK_NAME) {
+                        /* Note a propagated constant with the const's name. */
+                        JS_ASSERT(!pn4->pn_expr);
+                        ale = js_IndexAtom(cx, pn4->pn_atom, &cg->atomList);
+                        if (!ale)
+                            goto bad;
+                        CG_NEXT(cg) = pc;
+                        if (js_NewSrcNote2(cx, cg, SRC_LABEL, (ptrdiff_t)
+                                           ALE_INDEX(ale)) < 0) {
+                            goto bad;
+                        }
+                    }
+                    pc += JUMP_OFFSET_LEN;
+                }
+            } else {
+                for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
+                    pn4 = pn3->pn_left;
+                    if (pn4 && pn4->pn_type == TOK_NAME) {
+                        /* Note a propagated constant with the const's name. */
+                        JS_ASSERT(!pn4->pn_expr);
+                        ale = js_IndexAtom(cx, pn4->pn_atom, &cg->atomList);
+                        if (!ale)
+                            goto bad;
+                        CG_NEXT(cg) = pc;
+                        if (js_NewSrcNote2(cx, cg, SRC_LABEL, (ptrdiff_t)
+                                           ALE_INDEX(ale)) < 0) {
+                            goto bad;
+                        }
+                    }
+                    pc += ATOM_INDEX_LEN + JUMP_OFFSET_LEN;
+                }
+            }
+            CG_NEXT(cg) = savepc;
+        }
+    }
+
+    /* Emit code for each case's statements, copying pn_offset up to pn3. */
+    for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
+        if (switchOp == JSOP_CONDSWITCH && pn3->pn_type != TOK_DEFAULT)
+            CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, pn3->pn_offset);
+        pn4 = pn3->pn_right;
+        ok = js_EmitTree(cx, cg, pn4);
+        if (!ok)
+            goto out;
+        pn3->pn_offset = pn4->pn_offset;
+        if (pn3->pn_type == TOK_DEFAULT)
+            off = pn3->pn_offset - top;
+    }
+
+    if (!hasDefault) {
+        /* If no default case, offset for default is to end of switch. */
+        off = CG_OFFSET(cg) - top;
+    }
+
+    /* We better have set "off" by now. */
+    JS_ASSERT(off != -1);
+
+    /* Set the default offset (to end of switch if no default). */
+    if (switchOp == JSOP_CONDSWITCH) {
+        pc = NULL;
+        JS_ASSERT(defaultOffset != -1);
+        ok = js_SetJumpOffset(cx, cg, CG_CODE(cg, defaultOffset),
+                              off - (defaultOffset - top));
+        if (!ok)
+            goto out;
+    } else {
+        pc = CG_CODE(cg, top);
+        ok = js_SetJumpOffset(cx, cg, pc, off);
+        if (!ok)
+            goto out;
+        pc += JUMP_OFFSET_LEN;
+    }
+
+    /* Set the SRC_SWITCH note's offset operand to tell end of switch. */
+    off = CG_OFFSET(cg) - top;
+    ok = js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, off);
+    if (!ok)
+        goto out;
+
+    if (switchOp == JSOP_TABLESWITCH) {
+        /* Skip over the already-initialized switch bounds. */
+        pc += 2 * JUMP_OFFSET_LEN;
+
+        /* Fill in the jump table, if there is one. */
+        for (i = 0; i < (jsint)tableLength; i++) {
+            pn3 = table[i];
+            off = pn3 ? pn3->pn_offset - top : 0;
+            ok = js_SetJumpOffset(cx, cg, pc, off);
+            if (!ok)
+                goto out;
+            pc += JUMP_OFFSET_LEN;
+        }
+    } else if (switchOp == JSOP_LOOKUPSWITCH) {
+        /* Skip over the already-initialized number of cases. */
+        pc += ATOM_INDEX_LEN;
+
+        for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
+            if (pn3->pn_type == TOK_DEFAULT)
+                continue;
+            atom = js_AtomizeValue(cx, pn3->pn_val, 0);
+            if (!atom)
+                goto bad;
+            ale = js_IndexAtom(cx, atom, &cg->atomList);
+            if (!ale)
+                goto bad;
+            SET_ATOM_INDEX(pc, ALE_INDEX(ale));
+            pc += ATOM_INDEX_LEN;
+
+            off = pn3->pn_offset - top;
+            ok = js_SetJumpOffset(cx, cg, pc, off);
+            if (!ok)
+                goto out;
+            pc += JUMP_OFFSET_LEN;
+        }
+    }
+
+out:
+    if (table)
+        JS_free(cx, table);
+    return ok && js_PopStatementCG(cx, cg);
+
+bad:
+    ok = JS_FALSE;
+    goto out;
+}
+#endif /* JS_HAS_SWITCH_STATEMENT */
+
+JSBool
+js_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body,
+                    JSFunction *fun)
+{
+    JSStackFrame *fp, frame;
+    JSObject *funobj;
+    JSBool ok;
+
+    if (!js_AllocTryNotes(cx, cg))
+        return JS_FALSE;
+
+    fp = cx->fp;
+    funobj = fun->object;
+    JS_ASSERT(!fp || (fp->fun != fun && fp->varobj != funobj &&
+                      fp->scopeChain != funobj));
+    memset(&frame, 0, sizeof frame);
+    frame.fun = fun;
+    frame.varobj = frame.scopeChain = funobj;
+    frame.down = fp;
+    frame.flags = JS_HAS_COMPILE_N_GO_OPTION(cx)
+                  ? JSFRAME_COMPILING | JSFRAME_COMPILE_N_GO
+                  : JSFRAME_COMPILING;
+    cx->fp = &frame;
+    ok = js_EmitTree(cx, cg, body);
+    cx->fp = fp;
+    if (!ok)
+        return JS_FALSE;
+
+    fun->u.script = js_NewScriptFromCG(cx, cg, fun);
+    if (!fun->u.script)
+        return JS_FALSE;
+    JS_ASSERT(fun->interpreted);
+    if (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT)
+        fun->flags |= JSFUN_HEAVYWEIGHT;
+    return JS_TRUE;
+}
+
+/* A macro for inlining at the top of js_EmitTree (whence it came). */
+#define UPDATE_LINE_NUMBER_NOTES(cx, cg, pn)                                  \
+    JS_BEGIN_MACRO                                                            \
+        uintN line_ = (pn)->pn_pos.begin.lineno;                              \
+        uintN delta_ = line_ - CG_CURRENT_LINE(cg);                           \
+        if (delta_ != 0) {                                                    \
+            /*                                                                \
+             * Encode any change in the current source line number by using   \
+             * either several SRC_NEWLINE notes or just one SRC_SETLINE note, \
+             * whichever consumes less space.                                 \
+             *                                                                \
+             * NB: We handle backward line number deltas (possible with for   \
+             * loops where the update part is emitted after the body, but its \
+             * line number is <= any line number in the body) here by letting \
+             * unsigned delta_ wrap to a very large number, which triggers a  \
+             * SRC_SETLINE.                                                   \
+             */                                                               \
+            CG_CURRENT_LINE(cg) = line_;                                      \
+            if (delta_ >= (uintN)(2 + ((line_ > SN_3BYTE_OFFSET_MASK)<<1))) { \
+                if (js_NewSrcNote2(cx, cg, SRC_SETLINE, (ptrdiff_t)line_) < 0)\
+                    return JS_FALSE;                                          \
+            } else {                                                          \
+                do {                                                          \
+                    if (js_NewSrcNote(cx, cg, SRC_NEWLINE) < 0)               \
+                        return JS_FALSE;                                      \
+                } while (--delta_ != 0);                                      \
+            }                                                                 \
+        }                                                                     \
+    JS_END_MACRO
+
+/* A function, so that we avoid macro-bloating all the other callsites. */
+static JSBool
+UpdateLineNumberNotes(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
+{
+    UPDATE_LINE_NUMBER_NOTES(cx, cg, pn);
+    return JS_TRUE;
+}
+
+JSBool
+js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
+{
+    JSBool ok, useful, wantval;
+    JSStmtInfo *stmt, stmtInfo;
+    ptrdiff_t top, off, tmp, beq, jmp;
+    JSParseNode *pn2, *pn3;
+    JSAtom *atom;
+    JSAtomListElement *ale;
+    jsatomid atomIndex;
+    intN noteIndex;
+    JSSrcNoteType noteType;
+    jsbytecode *pc;
+    JSOp op;
+    uint32 argc;
+    int stackDummy;
+
+    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
+        return JS_FALSE;
+    }
+
+    ok = JS_TRUE;
+    cg->emitLevel++;
+    pn->pn_offset = top = CG_OFFSET(cg);
+
+    /* Emit notes to tell the current bytecode's source line number. */
+    UPDATE_LINE_NUMBER_NOTES(cx, cg, pn);
+
+    switch (pn->pn_type) {
+      case TOK_FUNCTION:
+      {
+        void *cg2mark;
+        JSCodeGenerator *cg2;
+        JSFunction *fun;
+
+#if JS_HAS_XML_SUPPORT
+        if (pn->pn_arity == PN_NULLARY) {
+            if (js_Emit1(cx, cg, JSOP_GETFUNNS) < 0)
+                return JS_FALSE;
+            break;
+        }
+#endif
+
+        /* Generate code for the function's body. */
+        cg2mark = JS_ARENA_MARK(&cx->tempPool);
+        JS_ARENA_ALLOCATE_TYPE(cg2, JSCodeGenerator, &cx->tempPool);
+        if (!cg2) {
+            JS_ReportOutOfMemory(cx);
+            return JS_FALSE;
+        }
+        if (!js_InitCodeGenerator(cx, cg2, cg->codePool, cg->notePool,
+                                  cg->filename, pn->pn_pos.begin.lineno,
+                                  cg->principals)) {
+            return JS_FALSE;
+        }
+        cg2->treeContext.flags = (uint16) (pn->pn_flags | TCF_IN_FUNCTION);
+        cg2->treeContext.tryCount = pn->pn_tryCount;
+        cg2->parent = cg;
+        fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(pn->pn_funAtom));
+        if (!js_EmitFunctionBody(cx, cg2, pn->pn_body, fun))
+            return JS_FALSE;
+
+        /*
+         * We need an activation object if an inner peeks out, or if such
+         * inner-peeking caused one of our inners to become heavyweight.
+         */
+        if (cg2->treeContext.flags &
+            (TCF_FUN_USES_NONLOCALS | TCF_FUN_HEAVYWEIGHT)) {
+            cg->treeContext.flags |= TCF_FUN_HEAVYWEIGHT;
+        }
+        js_FinishCodeGenerator(cx, cg2);
+        JS_ARENA_RELEASE(&cx->tempPool, cg2mark);
+
+        /* Make the function object a literal in the outer script's pool. */
+        ale = js_IndexAtom(cx, pn->pn_funAtom, &cg->atomList);
+        if (!ale)
+            return JS_FALSE;
+        atomIndex = ALE_INDEX(ale);
+
+#if JS_HAS_LEXICAL_CLOSURE
+        /* Emit a bytecode pointing to the closure object in its immediate. */
+        if (pn->pn_op != JSOP_NOP) {
+            EMIT_ATOM_INDEX_OP(pn->pn_op, atomIndex);
+            break;
+        }
+#endif
+
+        /* Top-level named functions need a nop for decompilation. */
+        noteIndex = js_NewSrcNote2(cx, cg, SRC_FUNCDEF, (ptrdiff_t)atomIndex);
+        if (noteIndex < 0 ||
+            js_Emit1(cx, cg, JSOP_NOP) < 0) {
+            return JS_FALSE;
+        }
+
+        /*
+         * Top-levels also need a prolog op to predefine their names in the
+         * variable object, or if local, to fill their stack slots.
+         */
+        CG_SWITCH_TO_PROLOG(cg);
+
+#if JS_HAS_LEXICAL_CLOSURE
+        if (cg->treeContext.flags & TCF_IN_FUNCTION) {
+            JSObject *obj, *pobj;
+            JSProperty *prop;
+            JSScopeProperty *sprop;
+            uintN slot;
+
+            obj = OBJ_GET_PARENT(cx, fun->object);
+            if (!js_LookupHiddenProperty(cx, obj, ATOM_TO_JSID(fun->atom),
+                                         &pobj, &prop)) {
+                return JS_FALSE;
+            }
+
+            JS_ASSERT(prop && pobj == obj);
+            sprop = (JSScopeProperty *) prop;
+            JS_ASSERT(sprop->getter == js_GetLocalVariable);
+            slot = sprop->shortid;
+            OBJ_DROP_PROPERTY(cx, pobj, prop);
+
+            if (atomIndex >= JS_BIT(16)) {
+                /*
+                 * Lots of literals in the outer function, so we have to emit
+                 * [JSOP_LITOPX, atomIndex, JSOP_DEFLOCALFUN, var slot].
+                 */
+                off = js_EmitN(cx, cg, JSOP_LITOPX, 3);
+                if (off < 0)
+                    return JS_FALSE;
+                pc = CG_CODE(cg, off);
+                SET_LITERAL_INDEX(pc, atomIndex);
+                EMIT_UINT16_IMM_OP(JSOP_DEFLOCALFUN, slot);
+            } else {
+                /* Emit [JSOP_DEFLOCALFUN, var slot, atomIndex]. */
+                off = js_EmitN(cx, cg, JSOP_DEFLOCALFUN,
+                               VARNO_LEN + ATOM_INDEX_LEN);
+                if (off < 0)
+                    return JS_FALSE;
+                pc = CG_CODE(cg, off);
+                SET_VARNO(pc, slot);
+                pc += VARNO_LEN;
+                SET_ATOM_INDEX(pc, atomIndex);
+            }
+        } else
+#endif
+            EMIT_ATOM_INDEX_OP(JSOP_DEFFUN, atomIndex);
+
+        CG_SWITCH_TO_MAIN(cg);
+        break;
+      }
+
+#if JS_HAS_EXPORT_IMPORT
+      case TOK_EXPORT:
+        pn2 = pn->pn_head;
+        if (pn2->pn_type == TOK_STAR) {
+            /*
+             * 'export *' must have no other elements in the list (what would
+             * be the point?).
+             */
+            if (js_Emit1(cx, cg, JSOP_EXPORTALL) < 0)
+                return JS_FALSE;
+        } else {
+            /*
+             * If not 'export *', the list consists of NAME nodes identifying
+             * properties of the variables object to flag as exported.
+             */
+            do {
+                ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList);
+                if (!ale)
+                    return JS_FALSE;
+                EMIT_ATOM_INDEX_OP(JSOP_EXPORTNAME, ALE_INDEX(ale));
+            } while ((pn2 = pn2->pn_next) != NULL);
+        }
+        break;
+
+      case TOK_IMPORT:
+        for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
+            /*
+             * Each subtree on an import list is rooted by a DOT or LB node.
+             * A DOT may have a null pn_atom member, in which case pn_op must
+             * be JSOP_IMPORTALL -- see EmitPropOp above.
+             */
+            if (!js_EmitTree(cx, cg, pn2))
+                return JS_FALSE;
+        }
+        break;
+#endif /* JS_HAS_EXPORT_IMPORT */
+
+      case TOK_IF:
+        /* Initialize so we can detect else-if chains and avoid recursion. */
+        stmtInfo.type = STMT_IF;
+        beq = jmp = -1;
+        noteIndex = -1;
+
+      if_again:
+        /* Emit code for the condition before pushing stmtInfo. */
+        if (!js_EmitTree(cx, cg, pn->pn_kid1))
+            return JS_FALSE;
+        if (stmtInfo.type == STMT_IF) {
+            js_PushStatement(&cg->treeContext, &stmtInfo, STMT_IF,
+                             CG_OFFSET(cg));
+        } else {
+            /*
+             * We came here from the goto further below that detects else-if
+             * chains, so we must mutate stmtInfo back into a STMT_IF record.
+             * Also (see below for why) we need a note offset for SRC_IF_ELSE
+             * to help the decompiler.
+             */
+            JS_ASSERT(stmtInfo.type == STMT_ELSE);
+            stmtInfo.type = STMT_IF;
+            if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq))
+                return JS_FALSE;
+        }
+
+        /* Emit an annotated branch-if-false around the then part. */
+        pn3 = pn->pn_kid3;
+        noteIndex = js_NewSrcNote(cx, cg, pn3 ? SRC_IF_ELSE : SRC_IF);
+        if (noteIndex < 0)
+            return JS_FALSE;
+        beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
+        if (beq < 0)
+            return JS_FALSE;
+
+        /* Emit code for the then and optional else parts. */
+        if (!js_EmitTree(cx, cg, pn->pn_kid2))
+            return JS_FALSE;
+        if (pn3) {
+            /* Modify stmtInfo so we know we're in the else part. */
+            stmtInfo.type = STMT_ELSE;
+
+            /*
+             * Emit a JSOP_BACKPATCH op to jump from the end of our then part
+             * around the else part.  The js_PopStatementCG call at the bottom
+             * of this switch case will fix up the backpatch chain linked from
+             * stmtInfo.breaks.
+             */
+            jmp = EmitGoto(cx, cg, &stmtInfo, &stmtInfo.breaks, NULL, SRC_NULL);
+            if (jmp < 0)
+                return JS_FALSE;
+
+            /* Ensure the branch-if-false comes here, then emit the else. */
+            CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
+            if (pn3->pn_type == TOK_IF) {
+                pn = pn3;
+                goto if_again;
+            }
+
+            if (!js_EmitTree(cx, cg, pn3))
+                return JS_FALSE;
+
+            /*
+             * Annotate SRC_IF_ELSE with the offset from branch to jump, for
+             * the decompiler's benefit.  We can't just "back up" from the pc
+             * of the else clause, because we don't know whether an extended
+             * jump was required to leap from the end of the then clause over
+             * the else clause.
+             */
+            if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq))
+                return JS_FALSE;
+        } else {
+            /* No else part, fixup the branch-if-false to come here. */
+            CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
+        }
+        ok = js_PopStatementCG(cx, cg);
+        break;
+
+#if JS_HAS_SWITCH_STATEMENT
+      case TOK_SWITCH:
+        /* Out of line to avoid bloating js_EmitTree's stack frame size. */
+        ok = EmitSwitch(cx, cg, pn, &stmtInfo);
+        break;
+#endif /* JS_HAS_SWITCH_STATEMENT */
+
+      case TOK_WHILE:
+        js_PushStatement(&cg->treeContext, &stmtInfo, STMT_WHILE_LOOP, top);
+        if (!js_EmitTree(cx, cg, pn->pn_left))
+            return JS_FALSE;
+        noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE);
+        if (noteIndex < 0)
+            return JS_FALSE;
+        beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
+        if (beq < 0)
+            return JS_FALSE;
+        if (!js_EmitTree(cx, cg, pn->pn_right))
+            return JS_FALSE;
+        jmp = EmitJump(cx, cg, JSOP_GOTO, top - CG_OFFSET(cg));
+        if (jmp < 0)
+            return JS_FALSE;
+        CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
+        if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq))
+            return JS_FALSE;
+        ok = js_PopStatementCG(cx, cg);
+        break;
+
+#if JS_HAS_DO_WHILE_LOOP
+      case TOK_DO:
+        /* Emit an annotated nop so we know to decompile a 'do' keyword. */
+        if (js_NewSrcNote(cx, cg, SRC_WHILE) < 0 ||
+            js_Emit1(cx, cg, JSOP_NOP) < 0) {
+            return JS_FALSE;
+        }
+
+        /* Compile the loop body. */
+        top = CG_OFFSET(cg);
+        js_PushStatement(&cg->treeContext, &stmtInfo, STMT_DO_LOOP, top);
+        if (!js_EmitTree(cx, cg, pn->pn_left))
+            return JS_FALSE;
+
+        /* Set loop and enclosing label update offsets, for continue. */
+        stmt = &stmtInfo;
+        do {
+            stmt->update = CG_OFFSET(cg);
+        } while ((stmt = stmt->down) != NULL && stmt->type == STMT_LABEL);
+
+        /* Compile the loop condition, now that continues know where to go. */
+        if (!js_EmitTree(cx, cg, pn->pn_right))
+            return JS_FALSE;
+
+        /*
+         * No source note needed, because JSOP_IFNE is used only for do-while.
+         * If we ever use JSOP_IFNE for other purposes, we can still avoid yet
+         * another note here, by storing (jmp - top) in the SRC_WHILE note's
+         * offset, and fetching that delta in order to decompile recursively.
+         */
+        if (EmitJump(cx, cg, JSOP_IFNE, top - CG_OFFSET(cg)) < 0)
+            return JS_FALSE;
+        ok = js_PopStatementCG(cx, cg);
+        break;
+#endif /* JS_HAS_DO_WHILE_LOOP */
+
+      case TOK_FOR:
+        beq = 0;                /* suppress gcc warnings */
+        pn2 = pn->pn_left;
+        js_PushStatement(&cg->treeContext, &stmtInfo, STMT_FOR_LOOP, top);
+
+        if (pn2->pn_type == TOK_IN) {
+            JSBool emitIFEQ;
+
+            /* Set stmtInfo type for later testing. */
+            stmtInfo.type = STMT_FOR_IN_LOOP;
+            noteIndex = -1;
+
+            /*
+             * If the left part is 'var x', emit code to define x if necessary
+             * using a prolog opcode, but do not emit a pop.  If the left part
+             * is 'var x = i', emit prolog code to define x if necessary; then
+             * emit code to evaluate i, assign the result to x, and pop the
+             * result off the stack.
+             *
+             * All the logic to do this is implemented in the outer switch's
+             * TOK_VAR case, conditioned on pn_extra flags set by the parser.
+             *
+             * In the 'for (var x = i in o) ...' case, the js_EmitTree(...pn3)
+             * called here will generate the SRC_VAR note for the assignment
+             * op that sets x = i, hoisting the initialized var declaration
+             * out of the loop: 'var x = i; for (x in o) ...'.
+             *
+             * In the 'for (var x in o) ...' case, nothing but the prolog op
+             * (if needed) should be generated here, we must emit the SRC_VAR
+             * just before the JSOP_FOR* opcode in the switch on pn3->pn_type
+             * a bit below, so nothing is hoisted: 'for (var x in o) ...'.
+             */
+            pn3 = pn2->pn_left;
+            if (pn3->pn_type == TOK_VAR && !js_EmitTree(cx, cg, pn3))
+                return JS_FALSE;
+
+            /* Emit a push to allocate the iterator. */
+            if (js_Emit1(cx, cg, JSOP_PUSH) < 0)
+                return JS_FALSE;
+
+            /* Compile the object expression to the right of 'in'. */
+            if (!js_EmitTree(cx, cg, pn2->pn_right))
+                return JS_FALSE;
+            if (js_Emit1(cx, cg, JSOP_TOOBJECT) < 0)
+                return JS_FALSE;
+
+            top = CG_OFFSET(cg);
+            SET_STATEMENT_TOP(&stmtInfo, top);
+
+#if JS_HAS_XML_SUPPORT
+            /* Emit a prefix opcode if 'for each (... in ...)' was used. */
+            if (pn->pn_op != JSOP_NOP && js_Emit1(cx, cg, pn->pn_op) < 0)
+                return JS_FALSE;
+#endif
+
+            /* Compile a JSOP_FOR* bytecode based on the left hand side. */
+            emitIFEQ = JS_TRUE;
+            switch (pn3->pn_type) {
+              case TOK_VAR:
+                pn3 = pn3->pn_head;
+                JS_ASSERT(pn3->pn_type == TOK_NAME);
+                if (!pn3->pn_expr && js_NewSrcNote(cx, cg, SRC_VAR) < 0)
+                    return JS_FALSE;
+                /* FALL THROUGH */
+              case TOK_NAME:
+                if (pn3->pn_slot >= 0) {
+                    op = pn3->pn_op;
+                    switch (op) {
+                      case JSOP_GETARG:  /* FALL THROUGH */
+                      case JSOP_SETARG:  op = JSOP_FORARG; break;
+                      case JSOP_GETVAR:  /* FALL THROUGH */
+                      case JSOP_SETVAR:  op = JSOP_FORVAR; break;
+                      case JSOP_GETGVAR:
+                      case JSOP_SETGVAR: op = JSOP_FORNAME; break;
+                      default:           JS_ASSERT(0);
+                    }
+                } else {
+                    pn3->pn_op = JSOP_FORNAME;
+                    if (!LookupArgOrVar(cx, &cg->treeContext, pn3))
+                        return JS_FALSE;
+                    op = pn3->pn_op;
+                }
+                if (pn3->pn_slot >= 0) {
+                    if (pn3->pn_attrs & JSPROP_READONLY)
+                        op = JSOP_GETVAR;
+                    atomIndex = (jsatomid) pn3->pn_slot;
+                    EMIT_UINT16_IMM_OP(op, atomIndex);
+                } else {
+                    if (!EmitAtomOp(cx, pn3, op, cg))
+                        return JS_FALSE;
+                }
+                break;
+
+              case TOK_DOT:
+                useful = JS_TRUE;
+                if (!CheckSideEffects(cx, &cg->treeContext, pn3->pn_expr,
+                                      &useful)) {
+                    return JS_FALSE;
+                }
+                if (!useful) {
+                    if (!EmitPropOp(cx, pn3, JSOP_FORPROP, cg))
+                        return JS_FALSE;
+                    break;
+                }
+                /* FALL THROUGH */
+
+#if JS_HAS_XML_SUPPORT
+              case TOK_UNARYOP:
+#endif
+#if JS_HAS_LVALUE_RETURN
+              case TOK_LP:
+#endif
+              case TOK_LB:
+                /*
+                 * We separate the first/next bytecode from the enumerator
+                 * variable binding to avoid any side-effects in the index
+                 * expression (e.g., for (x[i++] in {}) should not bind x[i]
+                 * or increment i at all).
+                 */
+                emitIFEQ = JS_FALSE;
+                if (!js_Emit1(cx, cg, JSOP_FORELEM))
+                    return JS_FALSE;
+
+                /*
+                 * Emit a SRC_WHILE note with offset telling the distance to
+                 * the loop-closing jump (we can't reckon from the branch at
+                 * the top of the loop, because the loop-closing jump might
+                 * need to be an extended jump, independent of whether the
+                 * branch is short or long).
+                 */
+                noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE);
+                if (noteIndex < 0)
+                    return JS_FALSE;
+                beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
+                if (beq < 0)
+                    return JS_FALSE;
+
+#if JS_HAS_LVALUE_RETURN
+                if (pn3->pn_type == TOK_LP) {
+                    JS_ASSERT(pn3->pn_op == JSOP_SETCALL);
+                    if (!js_EmitTree(cx, cg, pn3))
+                        return JS_FALSE;
+                    if (!js_Emit1(cx, cg, JSOP_ENUMELEM))
+                        return JS_FALSE;
+                    break;
+                }
+#endif
+#if JS_HAS_XML_SUPPORT
+                if (pn3->pn_type == TOK_UNARYOP) {
+                    JS_ASSERT(pn3->pn_op == JSOP_BINDXMLNAME);
+                    if (!js_EmitTree(cx, cg, pn3))
+                        return JS_FALSE;
+                    if (!js_Emit1(cx, cg, JSOP_ENUMELEM))
+                        return JS_FALSE;
+                    break;
+                }
+#endif
+
+                /* Now that we're safely past the IFEQ, commit side effects. */
+                if (!EmitElemOp(cx, pn3, JSOP_ENUMELEM, cg))
+                    return JS_FALSE;
+                break;
+
+              default:
+                JS_ASSERT(0);
+            }
+
+            if (emitIFEQ) {
+                /* Annotate so the decompiler can find the loop-closing jump. */
+                noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE);
+                if (noteIndex < 0)
+                    return JS_FALSE;
+
+                /* Pop and test the loop condition generated by JSOP_FOR*. */
+                beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
+                if (beq < 0)
+                    return JS_FALSE;
+            }
+        } else {
+            if (!pn2->pn_kid1) {
+                /* No initializer: emit an annotated nop for the decompiler. */
+                op = JSOP_NOP;
+            } else {
+                if (!js_EmitTree(cx, cg, pn2->pn_kid1))
+                    return JS_FALSE;
+                op = JSOP_POP;
+            }
+            noteIndex = js_NewSrcNote(cx, cg, SRC_FOR);
+            if (noteIndex < 0 ||
+                js_Emit1(cx, cg, op) < 0) {
+                return JS_FALSE;
+            }
+
+            top = CG_OFFSET(cg);
+            SET_STATEMENT_TOP(&stmtInfo, top);
+            if (!pn2->pn_kid2) {
+                /* No loop condition: flag this fact in the source notes. */
+                if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, 0))
+                    return JS_FALSE;
+            } else {
+                if (!js_EmitTree(cx, cg, pn2->pn_kid2))
+                    return JS_FALSE;
+                if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0,
+                                         CG_OFFSET(cg) - top)) {
+                    return JS_FALSE;
+                }
+                beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
+                if (beq < 0)
+                    return JS_FALSE;
+            }
+
+            /* Set pn3 (used below) here to avoid spurious gcc warnings. */
+            pn3 = pn2->pn_kid3;
+        }
+
+        /* Emit code for the loop body. */
+        if (!js_EmitTree(cx, cg, pn->pn_right))
+            return JS_FALSE;
+
+        if (pn2->pn_type != TOK_IN) {
+            /* Set the second note offset so we can find the update part. */
+            JS_ASSERT(noteIndex != -1);
+            if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 1,
+                                     CG_OFFSET(cg) - top)) {
+                return JS_FALSE;
+            }
+
+            if (pn3) {
+                /* Set loop and enclosing "update" offsets, for continue. */
+                stmt = &stmtInfo;
+                do {
+                    stmt->update = CG_OFFSET(cg);
+                } while ((stmt = stmt->down) != NULL &&
+                         stmt->type == STMT_LABEL);
+
+                if (!js_EmitTree(cx, cg, pn3))
+                    return JS_FALSE;
+                if (js_Emit1(cx, cg, JSOP_POP) < 0)
+                    return JS_FALSE;
+
+                /* Restore the absolute line number for source note readers. */
+                off = (ptrdiff_t) pn->pn_pos.end.lineno;
+                if (CG_CURRENT_LINE(cg) != (uintN) off) {
+                    if (js_NewSrcNote2(cx, cg, SRC_SETLINE, off) < 0)
+                        return JS_FALSE;
+                    CG_CURRENT_LINE(cg) = (uintN) off;
+                }
+            }
+
+            /* The third note offset helps us find the loop-closing jump. */
+            if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 2,
+                                     CG_OFFSET(cg) - top)) {
+                return JS_FALSE;
+            }
+        }
+
+        /* Emit the loop-closing jump and fixup all jump offsets. */
+        jmp = EmitJump(cx, cg, JSOP_GOTO, top - CG_OFFSET(cg));
+        if (jmp < 0)
+            return JS_FALSE;
+        if (beq > 0)
+            CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
+        if (pn2->pn_type == TOK_IN) {
+            /* Set the SRC_WHILE note offset so we can find the closing jump. */
+            JS_ASSERT(noteIndex != -1);
+            if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, jmp - beq))
+                return JS_FALSE;
+        }
+
+        /* Now fixup all breaks and continues (before for/in's final POP2). */
+        if (!js_PopStatementCG(cx, cg))
+            return JS_FALSE;
+
+        if (pn2->pn_type == TOK_IN) {
+            if (js_Emit1(cx, cg, JSOP_POP2) < 0)
+                return JS_FALSE;
+        }
+        break;
+
+      case TOK_BREAK:
+        stmt = cg->treeContext.topStmt;
+        atom = pn->pn_atom;
+        if (atom) {
+            ale = js_IndexAtom(cx, atom, &cg->atomList);
+            if (!ale)
+                return JS_FALSE;
+            while (stmt->type != STMT_LABEL || stmt->label != atom)
+                stmt = stmt->down;
+            noteType = SRC_BREAK2LABEL;
+        } else {
+            ale = NULL;
+            while (!STMT_IS_LOOP(stmt) && stmt->type != STMT_SWITCH)
+                stmt = stmt->down;
+            noteType = SRC_NULL;
+        }
+
+        if (EmitGoto(cx, cg, stmt, &stmt->breaks, ale, noteType) < 0)
+            return JS_FALSE;
+        break;
+
+      case TOK_CONTINUE:
+        stmt = cg->treeContext.topStmt;
+        atom = pn->pn_atom;
+        if (atom) {
+            /* Find the loop statement enclosed by the matching label. */
+            JSStmtInfo *loop = NULL;
+            ale = js_IndexAtom(cx, atom, &cg->atomList);
+            if (!ale)
+                return JS_FALSE;
+            while (stmt->type != STMT_LABEL || stmt->label != atom) {
+                if (STMT_IS_LOOP(stmt))
+                    loop = stmt;
+                stmt = stmt->down;
+            }
+            stmt = loop;
+            noteType = SRC_CONT2LABEL;
+        } else {
+            ale = NULL;
+            while (!STMT_IS_LOOP(stmt))
+                stmt = stmt->down;
+            noteType = SRC_CONTINUE;
+        }
+
+        if (EmitGoto(cx, cg, stmt, &stmt->continues, ale, noteType) < 0)
+            return JS_FALSE;
+        break;
+
+      case TOK_WITH:
+        if (!js_EmitTree(cx, cg, pn->pn_left))
+            return JS_FALSE;
+        js_PushStatement(&cg->treeContext, &stmtInfo, STMT_WITH, CG_OFFSET(cg));
+        if (js_Emit1(cx, cg, JSOP_ENTERWITH) < 0)
+            return JS_FALSE;
+        if (!js_EmitTree(cx, cg, pn->pn_right))
+            return JS_FALSE;
+        if (js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0)
+            return JS_FALSE;
+        ok = js_PopStatementCG(cx, cg);
+        break;
+
+#if JS_HAS_EXCEPTIONS
+
+      case TOK_TRY:
+      {
+        ptrdiff_t start, end, catchStart, finallyCatch, catchJump;
+        JSParseNode *iter;
+        intN depth;
+
+        /* Quell GCC overwarnings. */
+        end = catchStart = finallyCatch = catchJump = -1;
+
+        /*
+         * Push stmtInfo to track jumps-over-catches and gosubs-to-finally
+         * for later fixup.
+         *
+         * When a finally block is `active' (STMT_FINALLY on the treeContext),
+         * non-local jumps (including jumps-over-catches) result in a GOSUB
+         * being written into the bytecode stream and fixed-up later (c.f.
+         * EmitBackPatchOp and BackPatch).
+         */
+        js_PushStatement(&cg->treeContext, &stmtInfo,
+                         pn->pn_kid3 ? STMT_FINALLY : STMT_BLOCK,
+                         CG_OFFSET(cg));
+
+        /*
+         * About JSOP_SETSP: an exception can be thrown while the stack is in
+         * an unbalanced state, and this imbalance causes problems with things
+         * like function invocation later on.
+         *
+         * To fix this, we compute the `balanced' stack depth upon try entry,
+         * and then restore the stack to this depth when we hit the first catch
+         * or finally block.  We can't just zero the stack, because things like
+         * for/in and with that are active upon entry to the block keep state
+         * variables on the stack.
+         */
+        depth = cg->stackDepth;
+
+        /* Mark try location for decompilation, then emit try block. */
+        if (js_Emit1(cx, cg, JSOP_TRY) < 0)
+            return JS_FALSE;
+        start = CG_OFFSET(cg);
+        if (!js_EmitTree(cx, cg, pn->pn_kid1))
+            return JS_FALSE;
+
+        /* GOSUB to finally, if present. */
+        if (pn->pn_kid3) {
+            if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
+                return JS_FALSE;
+            jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH_PUSH, &stmtInfo.gosub);
+            if (jmp < 0)
+                return JS_FALSE;
+        }
+
+        /* Emit (hidden) jump over catch and/or finally. */
+        if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
+            return JS_FALSE;
+        jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH, &stmtInfo.catchJump);
+        if (jmp < 0)
+            return JS_FALSE;
+
+        end = CG_OFFSET(cg);
+
+        /* If this try has a catch block, emit it. */
+        iter = pn->pn_kid2;
+        if (iter) {
+            catchStart = end;
+
+            /*
+             * The emitted code for a catch block looks like:
+             *
+             * [ popscope ]                        only if 2nd+ catch block
+             * name Object
+             * pushobj
+             * newinit
+             * exception
+             * initcatchvar <atom>
+             * enterwith
+             * [< catchguard code >]               if there's a catchguard
+             * [ifeq <offset to next catch block>]         " "
+             * < catch block contents >
+             * leavewith
+             * goto <end of catch blocks>          non-local; finally applies
+             *
+             * If there's no catch block without a catchguard, the last
+             * <offset to next catch block> points to rethrow code.  This
+             * code will GOSUB to the finally code if appropriate, and is
+             * also used for the catch-all trynote for capturing exceptions
+             * thrown from catch{} blocks.
+             */
+            for (;;) {
+                JSStmtInfo stmtInfo2;
+                JSParseNode *disc;
+                ptrdiff_t guardnote;
+
+                if (!UpdateLineNumberNotes(cx, cg, iter))
+                    return JS_FALSE;
+
+                if (catchJump != -1) {
+                    /* Fix up and clean up previous catch block. */
+                    CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, catchJump);
+
+                    /* Compensate for the [leavewith]. */
+                    cg->stackDepth++;
+                    JS_ASSERT((uintN) cg->stackDepth <= cg->maxStackDepth);
+
+                    if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
+                        js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) {
+                        return JS_FALSE;
+                    }
+                } else {
+                    /* Set stack to original depth (see SETSP comment above). */
+                    EMIT_UINT16_IMM_OP(JSOP_SETSP, (jsatomid)depth);
+                    cg->stackDepth = depth;
+                }
+
+                /* Non-negative guardnote offset is length of catchguard. */
+                guardnote = js_NewSrcNote2(cx, cg, SRC_CATCH, 0);
+                if (guardnote < 0 ||
+                    js_Emit1(cx, cg, JSOP_NOP) < 0) {
+                    return JS_FALSE;
+                }
+
+                /* Construct the scope holder and push it on. */
+                ale = js_IndexAtom(cx, cx->runtime->atomState.ObjectAtom,
+                                   &cg->atomList);
+                if (!ale)
+                    return JS_FALSE;
+                EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale));
+
+                if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0 ||
+                    js_Emit1(cx, cg, JSOP_NEWINIT) < 0 ||
+                    js_Emit1(cx, cg, JSOP_EXCEPTION) < 0) {
+                    return JS_FALSE;
+                }
+
+                /* initcatchvar <atomIndex> */
+                disc = iter->pn_kid1;
+                ale = js_IndexAtom(cx, disc->pn_atom, &cg->atomList);
+                if (!ale)
+                    return JS_FALSE;
+
+                EMIT_ATOM_INDEX_OP(JSOP_INITCATCHVAR, ALE_INDEX(ale));
+                if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
+                    js_Emit1(cx, cg, JSOP_ENTERWITH) < 0) {
+                    return JS_FALSE;
+                }
+
+                /* boolean_expr */
+                if (disc->pn_expr) {
+                    ptrdiff_t guardstart = CG_OFFSET(cg);
+                    if (!js_EmitTree(cx, cg, disc->pn_expr))
+                        return JS_FALSE;
+                    if (!js_SetSrcNoteOffset(cx, cg, guardnote, 0,
+                                             CG_OFFSET(cg) - guardstart)) {
+                        return JS_FALSE;
+                    }
+                    /* ifeq <next block> */
+                    catchJump = EmitJump(cx, cg, JSOP_IFEQ, 0);
+                    if (catchJump < 0)
+                        return JS_FALSE;
+                }
+
+                /* Emit catch block. */
+                js_PushStatement(&cg->treeContext, &stmtInfo2, STMT_CATCH,
+                                 CG_OFFSET(cg));
+                stmtInfo2.label = disc->pn_atom;
+                if (!js_EmitTree(cx, cg, iter->pn_kid3))
+                    return JS_FALSE;
+                js_PopStatementCG(cx, cg);
+
+                /*
+                 * Jump over the remaining catch blocks.
+                 * This counts as a non-local jump, so do the finally thing.
+                 */
+
+                /* leavewith, annotated so the decompiler knows to pop  */
+                off = cg->stackDepth - 1;
+                if (js_NewSrcNote2(cx, cg, SRC_CATCH, off) < 0 ||
+                    js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) {
+                    return JS_FALSE;
+                }
+
+                /* gosub <finally>, if required */
+                if (pn->pn_kid3) {
+                    jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH_PUSH,
+                                          &stmtInfo.gosub);
+                    if (jmp < 0)
+                        return JS_FALSE;
+                }
+
+                /* This will get fixed up to jump to after catch/finally. */
+                if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)
+                    return JS_FALSE;
+                jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH,
+                                      &stmtInfo.catchJump);
+                if (jmp < 0)
+                    return JS_FALSE;
+                if (!iter->pn_kid2)     /* leave iter at last catch */
+                    break;
+                iter = iter->pn_kid2;
+            }
+        }
+
+        /*
+         * We use a [setsp],[gosub],rethrow block for rethrowing when
+         * there's no unguarded catch, and also for running finally code
+         * while letting an uncaught exception pass through.
+         */
+        if (pn->pn_kid3 ||
+            (catchJump != -1 && iter->pn_kid1->pn_expr)) {
+            /*
+             * Emit another stack fixup, because the catch could itself
+             * throw an exception in an unbalanced state, and the finally
+             * may need to call functions.  If there is no finally, only
+             * guarded catches, the rethrow code below nevertheless needs
+             * stack fixup.
+             */
+            finallyCatch = CG_OFFSET(cg);
+            EMIT_UINT16_IMM_OP(JSOP_SETSP, (jsatomid)depth);
+            cg->stackDepth = depth;
+
+            /* Last discriminant jumps to rethrow if none match. */
+            if (catchJump != -1 && iter->pn_kid1->pn_expr)
+                CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, catchJump);
+
+            if (pn->pn_kid3) {
+                jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH_PUSH,
+                                      &stmtInfo.gosub);
+                if (jmp < 0)
+                    return JS_FALSE;
+                cg->stackDepth = depth;
+            }
+
+            if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
+                js_Emit1(cx, cg, JSOP_EXCEPTION) < 0 ||
+                js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
+                js_Emit1(cx, cg, JSOP_THROW) < 0) {
+                return JS_FALSE;
+            }
+            JS_ASSERT(cg->stackDepth == depth);
+        }
+
+        /*
+         * If we have a finally, it belongs here, and we have to fix up the
+         * gosubs that might have been emitted before non-local jumps.
+         */
+        if (pn->pn_kid3) {
+            if (!BackPatch(cx, cg, stmtInfo.gosub, CG_NEXT(cg), JSOP_GOSUB))
+                return JS_FALSE;
+
+            /*
+             * The stack budget must be balanced at this point, and we need
+             * one more slot for the JSOP_RETSUB return address pushed by a
+             * JSOP_GOSUB opcode that calls this finally clause.
+             */
+            JS_ASSERT(cg->stackDepth == depth);
+            if ((uintN)++cg->stackDepth > cg->maxStackDepth)
+                cg->maxStackDepth = cg->stackDepth;
+
+            /* Now indicate that we're emitting a subroutine body. */
+            stmtInfo.type = STMT_SUBROUTINE;
+            if (!UpdateLineNumberNotes(cx, cg, pn->pn_kid3))
+                return JS_FALSE;
+            if (js_Emit1(cx, cg, JSOP_FINALLY) < 0 ||
+                !js_EmitTree(cx, cg, pn->pn_kid3) ||
+                js_Emit1(cx, cg, JSOP_RETSUB) < 0) {
+                return JS_FALSE;
+            }
+        }
+        js_PopStatementCG(cx, cg);
+
+        if (js_NewSrcNote(cx, cg, SRC_ENDBRACE) < 0 ||
+            js_Emit1(cx, cg, JSOP_NOP) < 0) {
+            return JS_FALSE;
+        }
+
+        /* Fix up the end-of-try/catch jumps to come here. */
+        if (!BackPatch(cx, cg, stmtInfo.catchJump, CG_NEXT(cg), JSOP_GOTO))
+            return JS_FALSE;
+
+        /*
+         * Add the try note last, to let post-order give us the right ordering
+         * (first to last for a given nesting level, inner to outer by level).
+         */
+        if (pn->pn_kid2) {
+            JS_ASSERT(end != -1 && catchStart != -1);
+            if (!js_NewTryNote(cx, cg, start, end, catchStart))
+                return JS_FALSE;
+        }
+
+        /*
+         * If we've got a finally, mark try+catch region with additional
+         * trynote to catch exceptions (re)thrown from a catch block or
+         * for the try{}finally{} case.
+         */
+        if (pn->pn_kid3) {
+            JS_ASSERT(finallyCatch != -1);
+            if (!js_NewTryNote(cx, cg, start, finallyCatch, finallyCatch))
+                return JS_FALSE;
+        }
+        break;
+      }
+
+#endif /* JS_HAS_EXCEPTIONS */
+
+      case TOK_VAR:
+        off = noteIndex = -1;
+        for (pn2 = pn->pn_head; ; pn2 = pn2->pn_next) {
+            JS_ASSERT(pn2->pn_type == TOK_NAME);
+            if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
+                return JS_FALSE;
+            op = pn2->pn_op;
+            if (op == JSOP_ARGUMENTS) {
+                JS_ASSERT(!pn2->pn_expr); /* JSOP_ARGUMENTS => no initializer */
+#ifdef __GNUC__
+                atomIndex = 0;            /* quell GCC overwarning */
+#endif
+            } else {
+                if (pn2->pn_slot >= 0) {
+                    atomIndex = (jsatomid) pn2->pn_slot;
+                } else {
+                    ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList);
+                    if (!ale)
+                        return JS_FALSE;
+                    atomIndex = ALE_INDEX(ale);
+                }
+
+                if ((js_CodeSpec[op].format & JOF_TYPEMASK) == JOF_CONST &&
+                    (!(cg->treeContext.flags & TCF_IN_FUNCTION) ||
+                     (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT))) {
+                    /* Emit a prolog bytecode to predefine the variable. */
+                    CG_SWITCH_TO_PROLOG(cg);
+                    if (!UpdateLineNumberNotes(cx, cg, pn2))
+                        return JS_FALSE;
+                    EMIT_ATOM_INDEX_OP(pn->pn_op, atomIndex);
+                    CG_SWITCH_TO_MAIN(cg);
+                }
+
+                if (pn2->pn_expr) {
+                    if (op == JSOP_SETNAME)
+                        EMIT_ATOM_INDEX_OP(JSOP_BINDNAME, atomIndex);
+                    pn3 = pn2->pn_expr;
+                    if (pn->pn_op == JSOP_DEFCONST &&
+                        !js_DefineCompileTimeConstant(cx, cg, pn2->pn_atom,
+                                                      pn3)) {
+                        return JS_FALSE;
+                    }
+                    if (!js_EmitTree(cx, cg, pn3))
+                        return JS_FALSE;
+                }
+            }
+
+            /*
+             * 'for (var x in o) ...' and 'for (var x = i in o) ...' call the
+             * TOK_VAR case, but only the initialized case (a strange one that
+             * falls out of ECMA-262's grammar) wants to run past this point.
+             * Both cases must conditionally emit a JSOP_DEFVAR, above.  Note
+             * that the parser error-checks to ensure that pn->pn_count is 1.
+             *
+             * XXX Narcissus keeps track of variable declarations in the node
+             * for the script being compiled, so there's no need to share any
+             * conditional prolog code generation there.  We could do likewise,
+             * but it's a big change, requiring extra allocation, so probably
+             * not worth the trouble for SpiderMonkey.
+             */
+            if ((pn->pn_extra & PNX_FORINVAR) && !pn2->pn_expr)
+                break;
+
+            if (pn2 == pn->pn_head &&
+                js_NewSrcNote(cx, cg,
+                              (pn->pn_op == JSOP_DEFCONST)
+                              ? SRC_CONST
+                              : SRC_VAR) < 0) {
+                return JS_FALSE;
+            }
+            if (op == JSOP_ARGUMENTS) {
+                if (js_Emit1(cx, cg, op) < 0)
+                    return JS_FALSE;
+            } else if (pn2->pn_slot >= 0) {
+                EMIT_UINT16_IMM_OP(op, atomIndex);
+            } else {
+                EMIT_ATOM_INDEX_OP(op, atomIndex);
+            }
+            tmp = CG_OFFSET(cg);
+            if (noteIndex >= 0) {
+                if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, tmp-off))
+                    return JS_FALSE;
+            }
+            if (!pn2->pn_next)
+                break;
+            off = tmp;
+            noteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);
+            if (noteIndex < 0 ||
+                js_Emit1(cx, cg, JSOP_POP) < 0) {
+                return JS_FALSE;
+            }
+        }
+        if (pn->pn_extra & PNX_POPVAR) {
+            if (js_Emit1(cx, cg, JSOP_POP) < 0)
+                return JS_FALSE;
+        }
+        break;
+
+      case TOK_RETURN:
+        /* Push a return value */
+        pn2 = pn->pn_kid;
+        if (pn2) {
+            if (!js_EmitTree(cx, cg, pn2))
+                return JS_FALSE;
+        } else {
+            if (js_Emit1(cx, cg, JSOP_PUSH) < 0)
+                return JS_FALSE;
+        }
+
+        /*
+         * EmitNonLocalJumpFixup mutates op to JSOP_RETRVAL after emitting a
+         * JSOP_SETRVAL if there are open try blocks having finally clauses.
+         * We can't simply transfer control flow to our caller in that case,
+         * because we must gosub to those clauses from inner to outer, with
+         * the correct stack pointer (i.e., after popping any with, for/in,
+         * etc., slots nested inside the finally's try).
+         */
+        op = JSOP_RETURN;
+        if (!EmitNonLocalJumpFixup(cx, cg, NULL, &op))
+            return JS_FALSE;
+        if (js_Emit1(cx, cg, op) < 0)
+            return JS_FALSE;
+        break;
+
+      case TOK_LC:
+#if JS_HAS_XML_SUPPORT
+        if (pn->pn_arity == PN_UNARY) {
+            if (!js_EmitTree(cx, cg, pn->pn_kid))
+                return JS_FALSE;
+            if (js_Emit1(cx, cg, pn->pn_op) < 0)
+                return JS_FALSE;
+            break;
+        }
+#endif
+
+        JS_ASSERT(pn->pn_arity == PN_LIST);
+        js_PushStatement(&cg->treeContext, &stmtInfo, STMT_BLOCK, top);
+        for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
+            if (!js_EmitTree(cx, cg, pn2))
+                return JS_FALSE;
+        }
+        ok = js_PopStatementCG(cx, cg);
+        break;
+
+      case TOK_SEMI:
+        pn2 = pn->pn_kid;
+        if (pn2) {
+            /*
+             * Top-level or called-from-a-native JS_Execute/EvaluateScript,
+             * debugger, and eval frames may need the value of the ultimate
+             * expression statement as the script's result, despite the fact
+             * that it appears useless to the compiler.
+             */
+            useful = wantval = !cx->fp->fun ||
+                               !cx->fp->fun->interpreted ||
+                               (cx->fp->flags & JSFRAME_SPECIAL);
+            if (!useful) {
+                if (!CheckSideEffects(cx, &cg->treeContext, pn2, &useful))
+                    return JS_FALSE;
+            }
+            if (!useful) {
+                CG_CURRENT_LINE(cg) = pn2->pn_pos.begin.lineno;
+                if (!js_ReportCompileErrorNumber(cx, cg,
+                                                 JSREPORT_CG |
+                                                 JSREPORT_WARNING |
+                                                 JSREPORT_STRICT,
+                                                 JSMSG_USELESS_EXPR)) {
+                    return JS_FALSE;
+                }
+            } else {
+                if (!js_EmitTree(cx, cg, pn2))
+                    return JS_FALSE;
+                if (js_Emit1(cx, cg, wantval ? JSOP_POPV : JSOP_POP) < 0)
+                    return JS_FALSE;
+            }
+        }
+        break;
+
+      case TOK_COLON:
+        /* Emit an annotated nop so we know to decompile a label. */
+        atom = pn->pn_atom;
+        ale = js_IndexAtom(cx, atom, &cg->atomList);
+        if (!ale)
+            return JS_FALSE;
+        pn2 = pn->pn_expr;
+        noteIndex = js_NewSrcNote2(cx, cg,
+                                   (pn2->pn_type == TOK_LC)
+                                   ? SRC_LABELBRACE
+                                   : SRC_LABEL,
+                                   (ptrdiff_t) ALE_INDEX(ale));
+        if (noteIndex < 0 ||
+            js_Emit1(cx, cg, JSOP_NOP) < 0) {
+            return JS_FALSE;
+        }
+
+        /* Emit code for the labeled statement. */
+        js_PushStatement(&cg->treeContext, &stmtInfo, STMT_LABEL,
+                         CG_OFFSET(cg));
+        stmtInfo.label = atom;
+        if (!js_EmitTree(cx, cg, pn2))
+            return JS_FALSE;
+        if (!js_PopStatementCG(cx, cg))
+            return JS_FALSE;
+
+        /* If the statement was compound, emit a note for the end brace. */
+        if (pn2->pn_type == TOK_LC) {
+            if (js_NewSrcNote(cx, cg, SRC_ENDBRACE) < 0 ||
+                js_Emit1(cx, cg, JSOP_NOP) < 0) {
+                return JS_FALSE;
+            }
+        }
+        break;
+
+      case TOK_COMMA:
+        /*
+         * Emit SRC_PCDELTA notes on each JSOP_POP between comma operands.
+         * These notes help the decompiler bracket the bytecodes generated
+         * from each sub-expression that follows a comma.
+         */
+        off = noteIndex = -1;
+        for (pn2 = pn->pn_head; ; pn2 = pn2->pn_next) {
+            if (!js_EmitTree(cx, cg, pn2))
+                return JS_FALSE;
+            tmp = CG_OFFSET(cg);
+            if (noteIndex >= 0) {
+                if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, tmp-off))
+                    return JS_FALSE;
+            }
+            if (!pn2->pn_next)
+                break;
+            off = tmp;
+            noteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0);
+            if (noteIndex < 0 ||
+                js_Emit1(cx, cg, JSOP_POP) < 0) {
+                return JS_FALSE;
+            }
+        }
+        break;
+
+      case TOK_ASSIGN:
+        /*
+         * Check left operand type and generate specialized code for it.
+         * Specialize to avoid ECMA "reference type" values on the operand
+         * stack, which impose pervasive runtime "GetValue" costs.
+         */
+        pn2 = pn->pn_left;
+        JS_ASSERT(pn2->pn_type != TOK_RP);
+        atomIndex = (jsatomid) -1; /* Suppress warning. */
+        switch (pn2->pn_type) {
+          case TOK_NAME:
+            if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
+                return JS_FALSE;
+            if (pn2->pn_slot >= 0) {
+                atomIndex = (jsatomid) pn2->pn_slot;
+            } else {
+                ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList);
+                if (!ale)
+                    return JS_FALSE;
+                atomIndex = ALE_INDEX(ale);
+                EMIT_ATOM_INDEX_OP(JSOP_BINDNAME, atomIndex);
+            }
+            break;
+          case TOK_DOT:
+            if (!js_EmitTree(cx, cg, pn2->pn_expr))
+                return JS_FALSE;
+            ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList);
+            if (!ale)
+                return JS_FALSE;
+            atomIndex = ALE_INDEX(ale);
+            break;
+          case TOK_LB:
+            JS_ASSERT(pn->pn_arity == PN_BINARY);
+            if (!js_EmitTree(cx, cg, pn2->pn_left))
+                return JS_FALSE;
+            if (!js_EmitTree(cx, cg, pn2->pn_right))
+                return JS_FALSE;
+            break;
+#if JS_HAS_LVALUE_RETURN
+          case TOK_LP:
+            if (!js_EmitTree(cx, cg, pn2))
+                return JS_FALSE;
+            break;
+#endif
+#if JS_HAS_XML_SUPPORT
+          case TOK_UNARYOP:
+            JS_ASSERT(pn2->pn_op == JSOP_SETXMLNAME);
+            if (!js_EmitTree(cx, cg, pn2->pn_kid))
+                return JS_FALSE;
+            if (js_Emit1(cx, cg, JSOP_BINDXMLNAME) < 0)
+                return JS_FALSE;
+            break;
+#endif
+          default:
+            JS_ASSERT(0);
+        }
+
+        op = pn->pn_op;
+#if JS_HAS_GETTER_SETTER
+        if (op == JSOP_GETTER || op == JSOP_SETTER) {
+            /* We'll emit these prefix bytecodes after emitting the r.h.s. */
+        } else
+#endif
+        /* If += or similar, dup the left operand and get its value. */
+        if (op != JSOP_NOP) {
+            switch (pn2->pn_type) {
+              case TOK_NAME:
+                if (pn2->pn_op != JSOP_SETNAME) {
+                    EMIT_UINT16_IMM_OP((pn2->pn_op == JSOP_SETGVAR)
+                                       ? JSOP_GETGVAR
+                                       : (pn2->pn_op == JSOP_SETARG)
+                                       ? JSOP_GETARG
+                                       : JSOP_GETVAR,
+                                       atomIndex);
+                    break;
+                }
+                /* FALL THROUGH */
+              case TOK_DOT:
+                if (js_Emit1(cx, cg, JSOP_DUP) < 0)
+                    return JS_FALSE;
+                EMIT_ATOM_INDEX_OP(JSOP_GETPROP, atomIndex);
+                break;
+              case TOK_LB:
+#if JS_HAS_LVALUE_RETURN
+              case TOK_LP:
+#endif
+#if JS_HAS_XML_SUPPORT
+              case TOK_UNARYOP:
+#endif
+                if (js_Emit1(cx, cg, JSOP_DUP2) < 0)
+                    return JS_FALSE;
+                if (js_Emit1(cx, cg, JSOP_GETELEM) < 0)
+                    return JS_FALSE;
+                break;
+              default:;
+            }
+        }
+
+        /* Now emit the right operand (it may affect the namespace). */
+        if (!js_EmitTree(cx, cg, pn->pn_right))
+            return JS_FALSE;
+
+        /* If += etc., emit the binary operator with a decompiler note. */
+        if (op != JSOP_NOP) {
+            if (js_NewSrcNote(cx, cg, SRC_ASSIGNOP) < 0 ||
+                js_Emit1(cx, cg, op) < 0) {
+                return JS_FALSE;
+            }
+        }
+
+        /* Left parts such as a.b.c and a[b].c need a decompiler note. */
+        if (pn2->pn_type != TOK_NAME &&
+            js_NewSrcNote2(cx, cg, SrcNoteForPropOp(pn2, pn2->pn_op),
+                           CG_OFFSET(cg) - top) < 0) {
+            return JS_FALSE;
+        }
+
+        /* Finally, emit the specialized assignment bytecode. */
+        switch (pn2->pn_type) {
+          case TOK_NAME:
+            if (pn2->pn_slot < 0 || !(pn2->pn_attrs & JSPROP_READONLY)) {
+                if (pn2->pn_slot >= 0) {
+                    EMIT_UINT16_IMM_OP(pn2->pn_op, atomIndex);
+                } else {
+          case TOK_DOT:
+                    EMIT_ATOM_INDEX_OP(pn2->pn_op, atomIndex);
+                }
+            }
+            break;
+          case TOK_LB:
+#if JS_HAS_LVALUE_RETURN
+          case TOK_LP:
+#endif
+            if (js_Emit1(cx, cg, JSOP_SETELEM) < 0)
+                return JS_FALSE;
+            break;
+#if JS_HAS_XML_SUPPORT
+          case TOK_UNARYOP:
+            if (js_Emit1(cx, cg, JSOP_SETXMLNAME) < 0)
+                return JS_FALSE;
+            break;
+#endif
+          default:;
+        }
+        break;
+
+      case TOK_HOOK:
+        /* Emit the condition, then branch if false to the else part. */
+        if (!js_EmitTree(cx, cg, pn->pn_kid1))
+            return JS_FALSE;
+        noteIndex = js_NewSrcNote(cx, cg, SRC_COND);
+        if (noteIndex < 0)
+            return JS_FALSE;
+        beq = EmitJump(cx, cg, JSOP_IFEQ, 0);
+        if (beq < 0 || !js_EmitTree(cx, cg, pn->pn_kid2))
+            return JS_FALSE;
+
+        /* Jump around else, fixup the branch, emit else, fixup jump. */
+        jmp = EmitJump(cx, cg, JSOP_GOTO, 0);
+        if (jmp < 0)
+            return JS_FALSE;
+        CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq);
+        if (!js_EmitTree(cx, cg, pn->pn_kid3))
+            return JS_FALSE;
+        CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, jmp);
+        if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq))
+            return JS_FALSE;
+
+        /*
+         * Because each branch pushes a single value, but our stack budgeting
+         * analysis ignores branches, we now have two values accounted for in
+         * cg->stackDepth.  Execution will follow only one path, so we must
+         * decrement cg->stackDepth here.  Failing to do this will foil code,
+         * such as the try/catch/finally exception handling code generator,
+         * that samples cg->stackDepth for use at runtime (JSOP_SETSP).
+         */
+        JS_ASSERT(cg->stackDepth > 1);
+        cg->stackDepth--;
+        break;
+
+      case TOK_OR:
+      case TOK_AND:
+        /*
+         * JSOP_OR converts the operand on the stack to boolean, and if true,
+         * leaves the original operand value on the stack and jumps; otherwise
+         * it pops and falls into the next bytecode, which evaluates the right
+         * operand.  The jump goes around the right operand evaluation.
+         *
+         * JSOP_AND converts the operand on the stack to boolean, and if false,
+         * leaves the original operand value on the stack and jumps; otherwise
+         * it pops and falls into the right operand's bytecode.
+         *
+         * Avoid tail recursion for long ||...|| expressions and long &&...&&
+         * expressions or long mixtures of ||'s and &&'s that can easily blow
+         * the stack, by forward-linking and then backpatching all the JSOP_OR
+         * and JSOP_AND bytecodes' immediate jump-offset operands.
+         */
+        pn3 = pn;
+        if (!js_EmitTree(cx, cg, pn->pn_left))
+            return JS_FALSE;
+        top = EmitJump(cx, cg, JSOP_BACKPATCH_POP, 0);
+        if (top < 0)
+            return JS_FALSE;
+        jmp = top;
+        pn2 = pn->pn_right;
+        while (pn2->pn_type == TOK_OR || pn2->pn_type == TOK_AND) {
+            pn = pn2;
+            if (!js_EmitTree(cx, cg, pn->pn_left))
+                return JS_FALSE;
+            off = EmitJump(cx, cg, JSOP_BACKPATCH_POP, 0);
+            if (off < 0)
+                return JS_FALSE;
+            if (!SetBackPatchDelta(cx, cg, CG_CODE(cg, jmp), off - jmp))
+                return JS_FALSE;
+            jmp = off;
+            pn2 = pn->pn_right;
+        }
+        if (!js_EmitTree(cx, cg, pn2))
+            return JS_FALSE;
+        off = CG_OFFSET(cg);
+        do {
+            pc = CG_CODE(cg, top);
+            tmp = GetJumpOffset(cg, pc);
+            CHECK_AND_SET_JUMP_OFFSET(cx, cg, pc, off - top);
+            *pc = pn3->pn_op;
+            top += tmp;
+        } while ((pn3 = pn3->pn_right) != pn2);
+        break;
+
+      case TOK_BITOR:
+      case TOK_BITXOR:
+      case TOK_BITAND:
+      case TOK_EQOP:
+      case TOK_RELOP:
+#if JS_HAS_IN_OPERATOR
+      case TOK_IN:
+#endif
+#if JS_HAS_INSTANCEOF
+      case TOK_INSTANCEOF:
+#endif
+      case TOK_SHOP:
+      case TOK_PLUS:
+      case TOK_MINUS:
+      case TOK_STAR:
+      case TOK_DIVOP:
+        if (pn->pn_arity == PN_LIST) {
+            /* Left-associative operator chain: avoid too much recursion. */
+            pn2 = pn->pn_head;
+            if (!js_EmitTree(cx, cg, pn2))
+                return JS_FALSE;
+            op = pn->pn_op;
+            while ((pn2 = pn2->pn_next) != NULL) {
+                if (!js_EmitTree(cx, cg, pn2))
+                    return JS_FALSE;
+                if (js_Emit1(cx, cg, op) < 0)
+                    return JS_FALSE;
+            }
+        } else {
+#if JS_HAS_XML_SUPPORT
+      case TOK_DBLCOLON:
+            if (pn->pn_arity == PN_NAME) {
+                if (!js_EmitTree(cx, cg, pn->pn_expr))
+                    return JS_FALSE;
+                if (!EmitAtomOp(cx, pn, pn->pn_op, cg))
+                    return JS_FALSE;
+                break;
+            }
+#endif
+            /* Binary operators that evaluate both operands unconditionally. */
+            if (!js_EmitTree(cx, cg, pn->pn_left))
+                return JS_FALSE;
+            if (!js_EmitTree(cx, cg, pn->pn_right))
+                return JS_FALSE;
+            if (js_Emit1(cx, cg, pn->pn_op) < 0)
+                return JS_FALSE;
+        }
+        break;
+
+#if JS_HAS_EXCEPTIONS
+      case TOK_THROW:
+#endif
+#if JS_HAS_XML_SUPPORT
+      case TOK_AT:
+      case TOK_DEFAULT:
+        JS_ASSERT(pn->pn_arity == PN_UNARY);
+        /* FALL THROUGH */
+#endif
+      case TOK_UNARYOP:
+        /* Unary op, including unary +/-. */
+        pn2 = pn->pn_kid;
+        if (!js_EmitTree(cx, cg, pn2))
+            return JS_FALSE;
+        op = pn->pn_op;
+#if JS_HAS_XML_SUPPORT
+        if (op == JSOP_XMLNAME &&
+            js_NewSrcNote2(cx, cg, SRC_PCBASE,
+                           CG_OFFSET(cg) - pn2->pn_offset) < 0) {
+            return JS_FALSE;
+        }
+#endif
+        if (js_Emit1(cx, cg, op) < 0)
+            return JS_FALSE;
+        break;
+
+      case TOK_INC:
+      case TOK_DEC:
+        /* Emit lvalue-specialized code for ++/-- operators. */
+        pn2 = pn->pn_kid;
+        JS_ASSERT(pn2->pn_type != TOK_RP);
+        op = pn->pn_op;
+        switch (pn2->pn_type) {
+          case TOK_NAME:
+            pn2->pn_op = op;
+            if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
+                return JS_FALSE;
+            op = pn2->pn_op;
+            if (pn2->pn_slot >= 0) {
+                if (pn2->pn_attrs & JSPROP_READONLY) {
+                    /* Incrementing a declared const: just get its value. */
+                    op = ((js_CodeSpec[op].format & JOF_TYPEMASK) == JOF_CONST)
+                         ? JSOP_GETGVAR
+                         : JSOP_GETVAR;
+                }
+                atomIndex = (jsatomid) pn2->pn_slot;
+                EMIT_UINT16_IMM_OP(op, atomIndex);
+            } else {
+                if (!EmitAtomOp(cx, pn2, op, cg))
+                    return JS_FALSE;
+            }
+            break;
+          case TOK_DOT:
+            if (!EmitPropOp(cx, pn2, op, cg))
+                return JS_FALSE;
+            break;
+          case TOK_LB:
+            if (!EmitElemOp(cx, pn2, op, cg))
+                return JS_FALSE;
+            break;
+#if JS_HAS_LVALUE_RETURN
+          case TOK_LP:
+            if (!js_EmitTree(cx, cg, pn2))
+                return JS_FALSE;
+            if (js_NewSrcNote2(cx, cg, SRC_PCBASE,
+                               CG_OFFSET(cg) - pn2->pn_offset) < 0) {
+                return JS_FALSE;
+            }
+            if (js_Emit1(cx, cg, op) < 0)
+                return JS_FALSE;
+            break;
+#endif
+#if JS_HAS_XML_SUPPORT
+          case TOK_UNARYOP:
+            JS_ASSERT(pn2->pn_op == JSOP_SETXMLNAME);
+            if (!js_EmitTree(cx, cg, pn2->pn_kid))
+                return JS_FALSE;
+            if (js_Emit1(cx, cg, JSOP_BINDXMLNAME) < 0)
+                return JS_FALSE;
+            if (js_Emit1(cx, cg, op) < 0)
+                return JS_FALSE;
+            break;
+#endif
+          default:
+            JS_ASSERT(0);
+        }
+
+        /*
+         * Allocate another stack slot for GC protection in case the initial
+         * value being post-incremented or -decremented is not a number, but
+         * converts to a jsdouble.  In the TOK_NAME cases, op has 0 operand
+         * uses and 1 definition, so we don't need an extra stack slot -- we
+         * can use the one allocated for the def.
+         */
+        if (pn2->pn_type != TOK_NAME &&
+            (js_CodeSpec[op].format & JOF_POST) &&
+            (uintN)cg->stackDepth == cg->maxStackDepth) {
+            ++cg->maxStackDepth;
+        }
+        break;
+
+      case TOK_DELETE:
+        /*
+         * Under ECMA 3, deleting a non-reference returns true -- but alas we
+         * must evaluate the operand if it appears it might have side effects.
+         */
+        pn2 = pn->pn_kid;
+        switch (pn2->pn_type) {
+          case TOK_NAME:
+            pn2->pn_op = JSOP_DELNAME;
+            if (!LookupArgOrVar(cx, &cg->treeContext, pn2))
+                return JS_FALSE;
+            op = pn2->pn_op;
+            if (op == JSOP_FALSE) {
+                if (js_Emit1(cx, cg, op) < 0)
+                    return JS_FALSE;
+            } else {
+                if (!EmitAtomOp(cx, pn2, op, cg))
+                    return JS_FALSE;
+            }
+            break;
+          case TOK_DOT:
+            if (!EmitPropOp(cx, pn2, JSOP_DELPROP, cg))
+                return JS_FALSE;
+            break;
+#if JS_HAS_XML_SUPPORT
+          case TOK_DBLDOT:
+            if (!EmitElemOp(cx, pn2, JSOP_DELDESC, cg))
+                return JS_FALSE;
+            break;
+#endif
+          case TOK_LB:
+            if (!EmitElemOp(cx, pn2, JSOP_DELELEM, cg))
+                return JS_FALSE;
+            break;
+          default:
+            useful = JS_FALSE;
+            if (!CheckSideEffects(cx, &cg->treeContext, pn2, &useful))
+                return JS_FALSE;
+            if (useful) {
+                if (!js_EmitTree(cx, cg, pn2))
+                    return JS_FALSE;
+                if (js_Emit1(cx, cg, JSOP_POP) < 0)
+                    return JS_FALSE;
+            }
+            if (js_Emit1(cx, cg, JSOP_TRUE) < 0)
+                return JS_FALSE;
+        }
+        break;
+
+#if JS_HAS_XML_SUPPORT
+      case TOK_FILTER:
+        if (!js_EmitTree(cx, cg, pn->pn_left))
+            return JS_FALSE;
+        jmp = js_Emit3(cx, cg, JSOP_FILTER, 0, 0);
+        if (jmp < 0)
+            return JS_FALSE;
+        if (!js_EmitTree(cx, cg, pn->pn_right))
+            return JS_FALSE;
+        if (js_Emit1(cx, cg, JSOP_ENDFILTER) < 0)
+            return JS_FALSE;
+        CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, jmp);
+        break;
+#endif
+
+      case TOK_DOT:
+        /*
+         * Pop a stack operand, convert it to object, get a property named by
+         * this bytecode's immediate-indexed atom operand, and push its value
+         * (not a reference to it).  This bytecode sets the virtual machine's
+         * "obj" register to the left operand's ToObject conversion result,
+         * for use by JSOP_PUSHOBJ.
+         */
+        ok = EmitPropOp(cx, pn, pn->pn_op, cg);
+        break;
+
+      case TOK_LB:
+#if JS_HAS_XML_SUPPORT
+      case TOK_DBLDOT:
+#endif
+        /*
+         * Pop two operands, convert the left one to object and the right one
+         * to property name (atom or tagged int), get the named property, and
+         * push its value.  Set the "obj" register to the result of ToObject
+         * on the left operand.
+         */
+        ok = EmitElemOp(cx, pn, pn->pn_op, cg);
+        break;
+
+      case TOK_NEW:
+      case TOK_LP:
+        /*
+         * Emit function call or operator new (constructor call) code.
+         * First, emit code for the left operand to evaluate the callable or
+         * constructable object expression.
+         *
+         * For E4X, if this expression is a dotted member reference, select
+         * JSOP_GETMETHOD instead of JSOP_GETPROP.  ECMA-357 separates XML
+         * method lookup from the normal property id lookup done for native
+         * objects.
+         */
+        pn2 = pn->pn_head;
+#if JS_HAS_XML_SUPPORT
+        if (pn2->pn_type == TOK_DOT && pn2->pn_op != JSOP_GETMETHOD) {
+            JS_ASSERT(pn2->pn_op == JSOP_GETPROP);
+            pn2->pn_op = JSOP_GETMETHOD;
+            pn2->pn_attrs |= JSPROP_IMPLICIT_FUNCTION_NAMESPACE;
+        }
+#endif
+        if (!js_EmitTree(cx, cg, pn2))
+            return JS_FALSE;
+
+        /*
+         * Push the virtual machine's "obj" register, which was set by a
+         * name, property, or element get (or set) bytecode.
+         */
+        if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0)
+            return JS_FALSE;
+
+        /* Remember start of callable-object bytecode for decompilation hint. */
+        off = top;
+
+        /*
+         * Emit code for each argument in order, then emit the JSOP_*CALL* or
+         * JSOP_NEW bytecode with a two-byte immediate telling how many args
+         * were pushed on the operand stack.
+         */
+        for (pn2 = pn2->pn_next; pn2; pn2 = pn2->pn_next) {
+            if (!js_EmitTree(cx, cg, pn2))
+                return JS_FALSE;
+        }
+        if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - off) < 0)
+            return JS_FALSE;
+
+        argc = pn->pn_count - 1;
+        if (js_Emit3(cx, cg, pn->pn_op, ARGC_HI(argc), ARGC_LO(argc)) < 0)
+            return JS_FALSE;
+        break;
+
+#if JS_HAS_INITIALIZERS
+      case TOK_RB:
+        /*
+         * Emit code for [a, b, c] of the form:
+         *   t = new Array; t[0] = a; t[1] = b; t[2] = c; t;
+         * but use a stack slot for t and avoid dup'ing and popping it via
+         * the JSOP_NEWINIT and JSOP_INITELEM bytecodes.
+         */
+        ale = js_IndexAtom(cx, cx->runtime->atomState.ArrayAtom,
+                           &cg->atomList);
+        if (!ale)
+            return JS_FALSE;
+        EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale));
+        if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0)
+            return JS_FALSE;
+        if (js_Emit1(cx, cg, JSOP_NEWINIT) < 0)
+            return JS_FALSE;
+
+        pn2 = pn->pn_head;
+#if JS_HAS_SHARP_VARS
+        if (pn2 && pn2->pn_type == TOK_DEFSHARP) {
+            EMIT_UINT16_IMM_OP(JSOP_DEFSHARP, (jsatomid)pn2->pn_num);
+            pn2 = pn2->pn_next;
+        }
+#endif
+
+        for (atomIndex = 0; pn2; atomIndex++, pn2 = pn2->pn_next) {
+            if (!EmitNumberOp(cx, atomIndex, cg))
+                return JS_FALSE;
+
+            /* FIXME 260106: holes in a sparse initializer are void-filled. */
+            if (pn2->pn_type == TOK_COMMA) {
+                if (js_Emit1(cx, cg, JSOP_PUSH) < 0)
+                    return JS_FALSE;
+            } else {
+                if (!js_EmitTree(cx, cg, pn2))
+                    return JS_FALSE;
+            }
+
+            if (js_Emit1(cx, cg, JSOP_INITELEM) < 0)
+                return JS_FALSE;
+        }
+
+        if (pn->pn_extra & PNX_ENDCOMMA) {
+            /* Emit a source note so we know to decompile an extra comma. */
+            if (js_NewSrcNote(cx, cg, SRC_CONTINUE) < 0)
+                return JS_FALSE;
+        }
+
+        /* Emit an op for sharp array cleanup and decompilation. */
+        if (js_Emit1(cx, cg, JSOP_ENDINIT) < 0)
+            return JS_FALSE;
+        break;
+
+      case TOK_RC:
+        /*
+         * Emit code for {p:a, '%q':b, 2:c} of the form:
+         *   t = new Object; t.p = a; t['%q'] = b; t[2] = c; t;
+         * but use a stack slot for t and avoid dup'ing and popping it via
+         * the JSOP_NEWINIT and JSOP_INITELEM bytecodes.
+         */
+        ale = js_IndexAtom(cx, cx->runtime->atomState.ObjectAtom,
+                           &cg->atomList);
+        if (!ale)
+            return JS_FALSE;
+        EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale));
+
+        if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0)
+            return JS_FALSE;
+        if (js_Emit1(cx, cg, JSOP_NEWINIT) < 0)
+            return JS_FALSE;
+
+        pn2 = pn->pn_head;
+#if JS_HAS_SHARP_VARS
+        if (pn2 && pn2->pn_type == TOK_DEFSHARP) {
+            EMIT_UINT16_IMM_OP(JSOP_DEFSHARP, (jsatomid)pn2->pn_num);
+            pn2 = pn2->pn_next;
+        }
+#endif
+
+        for (; pn2; pn2 = pn2->pn_next) {
+            /* Emit an index for t[2], else map an atom for t.p or t['%q']. */
+            pn3 = pn2->pn_left;
+            switch (pn3->pn_type) {
+              case TOK_NUMBER:
+                if (!EmitNumberOp(cx, pn3->pn_dval, cg))
+                    return JS_FALSE;
+                break;
+              case TOK_NAME:
+              case TOK_STRING:
+                ale = js_IndexAtom(cx, pn3->pn_atom, &cg->atomList);
+                if (!ale)
+                    return JS_FALSE;
+                break;
+              default:
+                JS_ASSERT(0);
+            }
+
+            /* Emit code for the property initializer. */
+            if (!js_EmitTree(cx, cg, pn2->pn_right))
+                return JS_FALSE;
+
+#if JS_HAS_GETTER_SETTER
+            op = pn2->pn_op;
+            if (op == JSOP_GETTER || op == JSOP_SETTER) {
+                if (js_Emit1(cx, cg, op) < 0)
+                    return JS_FALSE;
+            }
+#endif
+            /* Annotate JSOP_INITELEM so we decompile 2:c and not just c. */
+            if (pn3->pn_type == TOK_NUMBER) {
+                if (js_NewSrcNote2(cx, cg, SRC_LABEL, 0) < 0)
+                    return JS_FALSE;
+                if (js_Emit1(cx, cg, JSOP_INITELEM) < 0)
+                    return JS_FALSE;
+            } else {
+                EMIT_ATOM_INDEX_OP(JSOP_INITPROP, ALE_INDEX(ale));
+            }
+        }
+
+        /* Emit an op for sharpArray cleanup and decompilation. */
+        if (js_Emit1(cx, cg, JSOP_ENDINIT) < 0)
+            return JS_FALSE;
+        break;
+
+#if JS_HAS_SHARP_VARS
+      case TOK_DEFSHARP:
+        if (!js_EmitTree(cx, cg, pn->pn_kid))
+            return JS_FALSE;
+        EMIT_UINT16_IMM_OP(JSOP_DEFSHARP, (jsatomid) pn->pn_num);
+        break;
+
+      case TOK_USESHARP:
+        EMIT_UINT16_IMM_OP(JSOP_USESHARP, (jsatomid) pn->pn_num);
+        break;
+#endif /* JS_HAS_SHARP_VARS */
+#endif /* JS_HAS_INITIALIZERS */
+
+      case TOK_RP:
+        /*
+         * The node for (e) has e as its kid, enabling users who want to nest
+         * assignment expressions in conditions to avoid the error correction
+         * done by Condition (from x = y to x == y) by double-parenthesizing.
+         */
+        if (!js_EmitTree(cx, cg, pn->pn_kid))
+            return JS_FALSE;
+        if (js_Emit1(cx, cg, JSOP_GROUP) < 0)
+            return JS_FALSE;
+        break;
+
+      case TOK_NAME:
+        if (!LookupArgOrVar(cx, &cg->treeContext, pn))
+            return JS_FALSE;
+        op = pn->pn_op;
+        if (op == JSOP_ARGUMENTS) {
+            if (js_Emit1(cx, cg, op) < 0)
+                return JS_FALSE;
+            break;
+        }
+        if (pn->pn_slot >= 0) {
+            atomIndex = (jsatomid) pn->pn_slot;
+            EMIT_UINT16_IMM_OP(op, atomIndex);
+            break;
+        }
+        /* FALL THROUGH */
+
+#if JS_HAS_XML_SUPPORT
+      case TOK_XMLATTR:
+      case TOK_XMLSPACE:
+      case TOK_XMLTEXT:
+      case TOK_XMLCDATA:
+      case TOK_XMLCOMMENT:
+#endif
+      case TOK_STRING:
+      case TOK_OBJECT:
+        /*
+         * The scanner and parser associate JSOP_NAME with TOK_NAME, although
+         * other bytecodes may result instead (JSOP_BINDNAME/JSOP_SETNAME,
+         * JSOP_FORNAME, etc.).  Among JSOP_*NAME* variants, only JSOP_NAME
+         * may generate the first operand of a call or new expression, so only
+         * it sets the "obj" virtual machine register to the object along the
+         * scope chain in which the name was found.
+         *
+         * Token types for STRING and OBJECT have corresponding bytecode ops
+         * in pn_op and emit the same format as NAME, so they share this code.
+         */
+        ok = EmitAtomOp(cx, pn, pn->pn_op, cg);
+        break;
+
+      case TOK_NUMBER:
+        ok = EmitNumberOp(cx, pn->pn_dval, cg);
+        break;
+
+#if JS_HAS_XML_SUPPORT
+      case TOK_ANYNAME:
+#endif
+      case TOK_PRIMARY:
+        if (js_Emit1(cx, cg, pn->pn_op) < 0)
+            return JS_FALSE;
+        break;
+
+#if JS_HAS_DEBUGGER_KEYWORD
+      case TOK_DEBUGGER:
+        if (js_Emit1(cx, cg, JSOP_DEBUGGER) < 0)
+            return JS_FALSE;
+        break;
+#endif /* JS_HAS_DEBUGGER_KEYWORD */
+
+#if JS_HAS_XML_SUPPORT
+      case TOK_XMLELEM:
+      case TOK_XMLLIST:
+        if (pn->pn_op == JSOP_XMLOBJECT) {
+            ok = EmitAtomOp(cx, pn, pn->pn_op, cg);
+            break;
+        }
+
+        JS_ASSERT(pn->pn_type == TOK_XMLLIST || pn->pn_count != 0);
+        switch (pn->pn_head ? pn->pn_head->pn_type : TOK_XMLLIST) {
+          case TOK_XMLETAGO:
+            JS_ASSERT(0);
+            /* FALL THROUGH */
+          case TOK_XMLPTAGC:
+          case TOK_XMLSTAGO:
+            break;
+          default:
+            if (js_Emit1(cx, cg, JSOP_STARTXML) < 0)
+                return JS_FALSE;
+        }
+
+        for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
+            if (pn2->pn_type == TOK_LC &&
+                js_Emit1(cx, cg, JSOP_STARTXMLEXPR) < 0) {
+                return JS_FALSE;
+            }
+            if (!js_EmitTree(cx, cg, pn2))
+                return JS_FALSE;
+            if (pn2 != pn->pn_head && js_Emit1(cx, cg, JSOP_ADD) < 0)
+                return JS_FALSE;
+        }
+
+        if (pn->pn_extra & PNX_XMLROOT) {
+            if (pn->pn_count == 0) {
+                JS_ASSERT(pn->pn_type == TOK_XMLLIST);
+                atom = cx->runtime->atomState.emptyAtom;
+                ale = js_IndexAtom(cx, atom, &cg->atomList);
+                if (!ale)
+                    return JS_FALSE;
+                EMIT_ATOM_INDEX_OP(JSOP_STRING, ALE_INDEX(ale));
+            }
+            if (js_Emit1(cx, cg, pn->pn_op) < 0)
+                return JS_FALSE;
+        }
+#ifdef DEBUG
+        else
+            JS_ASSERT(pn->pn_count != 0);
+#endif
+        break;
+
+      case TOK_XMLPTAGC:
+        if (pn->pn_op == JSOP_XMLOBJECT) {
+            ok = EmitAtomOp(cx, pn, pn->pn_op, cg);
+            break;
+        }
+        /* FALL THROUGH */
+
+      case TOK_XMLSTAGO:
+      case TOK_XMLETAGO:
+      {
+        uint32 i;
+
+        if (js_Emit1(cx, cg, JSOP_STARTXML) < 0)
+            return JS_FALSE;
+
+        ale = js_IndexAtom(cx,
+                           (pn->pn_type == TOK_XMLETAGO)
+                           ? cx->runtime->atomState.etagoAtom
+                           : cx->runtime->atomState.stagoAtom,
+                           &cg->atomList);
+        if (!ale)
+            return JS_FALSE;
+        EMIT_ATOM_INDEX_OP(JSOP_STRING, ALE_INDEX(ale));
+
+        JS_ASSERT(pn->pn_count != 0);
+        pn2 = pn->pn_head;
+        if (pn2->pn_type == TOK_LC && js_Emit1(cx, cg, JSOP_STARTXMLEXPR) < 0)
+            return JS_FALSE;
+        if (!js_EmitTree(cx, cg, pn2))
+            return JS_FALSE;
+        if (js_Emit1(cx, cg, JSOP_ADD) < 0)
+            return JS_FALSE;
+
+        for (pn2 = pn2->pn_next, i = 0; pn2; pn2 = pn2->pn_next, i++) {
+            if (pn2->pn_type == TOK_LC &&
+                js_Emit1(cx, cg, JSOP_STARTXMLEXPR) < 0) {
+                return JS_FALSE;
+            }
+            if (!js_EmitTree(cx, cg, pn2))
+                return JS_FALSE;
+            if ((i & 1) && pn2->pn_type == TOK_LC) {
+                if (js_Emit1(cx, cg, JSOP_TOATTRVAL) < 0)
+                    return JS_FALSE;
+            }
+            if (js_Emit1(cx, cg,
+                         (i & 1) ? JSOP_ADDATTRVAL : JSOP_ADDATTRNAME) < 0) {
+                return JS_FALSE;
+            }
+        }
+
+        ale = js_IndexAtom(cx,
+                           (pn->pn_type == TOK_XMLPTAGC)
+                           ? cx->runtime->atomState.ptagcAtom
+                           : cx->runtime->atomState.tagcAtom,
+                           &cg->atomList);
+        if (!ale)
+            return JS_FALSE;
+        EMIT_ATOM_INDEX_OP(JSOP_STRING, ALE_INDEX(ale));
+        if (js_Emit1(cx, cg, JSOP_ADD) < 0)
+            return JS_FALSE;
+
+        if ((pn->pn_extra & PNX_XMLROOT) && js_Emit1(cx, cg, pn->pn_op) < 0)
+            return JS_FALSE;
+        break;
+      }
+
+      case TOK_XMLNAME:
+        if (pn->pn_arity == PN_LIST) {
+            JS_ASSERT(pn->pn_count != 0);
+            for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
+                if (!js_EmitTree(cx, cg, pn2))
+                    return JS_FALSE;
+                if (pn2 != pn->pn_head && js_Emit1(cx, cg, JSOP_ADD) < 0)
+                    return JS_FALSE;
+            }
+        } else {
+            JS_ASSERT(pn->pn_arity == PN_NULLARY);
+            ok = EmitAtomOp(cx, pn, pn->pn_op, cg);
+        }
+        break;
+
+      case TOK_XMLPI:
+        ale = js_IndexAtom(cx, pn->pn_atom2, &cg->atomList);
+        if (!ale)
+            return JS_FALSE;
+        if (!EmitAtomIndexOp(cx, JSOP_STRING, ALE_INDEX(ale), cg))
+            return JS_FALSE;
+        if (!EmitAtomOp(cx, pn, JSOP_XMLPI, cg))
+            return JS_FALSE;
+        break;
+#endif /* JS_HAS_XML_SUPPORT */
+
+      default:
+        JS_ASSERT(0);
+    }
+
+    if (ok && --cg->emitLevel == 0 && cg->spanDeps)
+        ok = OptimizeSpanDeps(cx, cg);
+
+    return ok;
+}
+
+JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[] = {
+    {"null",            0,      0,      0},
+    {"if",              0,      0,      0},
+    {"if-else",         1,      0,      1},
+    {"while",           1,      0,      1},
+    {"for",             3,      1,      1},
+    {"continue",        0,      0,      0},
+    {"var",             0,      0,      0},
+    {"pcdelta",         1,      0,      1},
+    {"assignop",        0,      0,      0},
+    {"cond",            1,      0,      1},
+    {"reserved0",       0,      0,      0},
+    {"hidden",          0,      0,      0},
+    {"pcbase",          1,      0,     -1},
+    {"label",           1,      0,      0},
+    {"labelbrace",      1,      0,      0},
+    {"endbrace",        0,      0,      0},
+    {"break2label",     1,      0,      0},
+    {"cont2label",      1,      0,      0},
+    {"switch",          2,      0,      1},
+    {"funcdef",         1,      0,      0},
+    {"catch",           1,     11,      1},
+    {"const",           0,      0,      0},
+    {"newline",         0,      0,      0},
+    {"setline",         1,      0,      0},
+    {"xdelta",          0,      0,      0},
+};
+
+static intN
+AllocSrcNote(JSContext *cx, JSCodeGenerator *cg)
+{
+    intN index;
+    JSArenaPool *pool;
+    size_t size;
+
+    index = CG_NOTE_COUNT(cg);
+    if (((uintN)index & CG_NOTE_MASK(cg)) == 0) {
+        pool = cg->notePool;
+        size = SRCNOTE_SIZE(CG_NOTE_MASK(cg) + 1);
+        if (!CG_NOTES(cg)) {
+            /* Allocate the first note array lazily; leave noteMask alone. */
+            JS_ARENA_ALLOCATE_CAST(CG_NOTES(cg), jssrcnote *, pool, size);
+        } else {
+            /* Grow by doubling note array size; update noteMask on success. */
+            JS_ARENA_GROW_CAST(CG_NOTES(cg), jssrcnote *, pool, size, size);
+            if (CG_NOTES(cg))
+                CG_NOTE_MASK(cg) = (CG_NOTE_MASK(cg) << 1) | 1;
+        }
+        if (!CG_NOTES(cg)) {
+            JS_ReportOutOfMemory(cx);
+            return -1;
+        }
+    }
+
+    CG_NOTE_COUNT(cg) = index + 1;
+    return index;
+}
+
+intN
+js_NewSrcNote(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type)
+{
+    intN index, n;
+    jssrcnote *sn;
+    ptrdiff_t offset, delta, xdelta;
+
+    /*
+     * Claim a note slot in CG_NOTES(cg) by growing it if necessary and then
+     * incrementing CG_NOTE_COUNT(cg).
+     */
+    index = AllocSrcNote(cx, cg);
+    if (index < 0)
+        return -1;
+    sn = &CG_NOTES(cg)[index];
+
+    /*
+     * Compute delta from the last annotated bytecode's offset.  If it's too
+     * big to fit in sn, allocate one or more xdelta notes and reset sn.
+     */
+    offset = CG_OFFSET(cg);
+    delta = offset - CG_LAST_NOTE_OFFSET(cg);
+    CG_LAST_NOTE_OFFSET(cg) = offset;
+    if (delta >= SN_DELTA_LIMIT) {
+        do {
+            xdelta = JS_MIN(delta, SN_XDELTA_MASK);
+            SN_MAKE_XDELTA(sn, xdelta);
+            delta -= xdelta;
+            index = AllocSrcNote(cx, cg);
+            if (index < 0)
+                return -1;
+            sn = &CG_NOTES(cg)[index];
+        } while (delta >= SN_DELTA_LIMIT);
+    }
+
+    /*
+     * Initialize type and delta, then allocate the minimum number of notes
+     * needed for type's arity.  Usually, we won't need more, but if an offset
+     * does take two bytes, js_SetSrcNoteOffset will grow CG_NOTES(cg).
+     */
+    SN_MAKE_NOTE(sn, type, delta);
+    for (n = (intN)js_SrcNoteSpec[type].arity; n > 0; n--) {
+        if (js_NewSrcNote(cx, cg, SRC_NULL) < 0)
+            return -1;
+    }
+    return index;
+}
+
+intN
+js_NewSrcNote2(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type,
+               ptrdiff_t offset)
+{
+    intN index;
+
+    index = js_NewSrcNote(cx, cg, type);
+    if (index >= 0) {
+        if (!js_SetSrcNoteOffset(cx, cg, index, 0, offset))
+            return -1;
+    }
+    return index;
+}
+
+intN
+js_NewSrcNote3(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type,
+               ptrdiff_t offset1, ptrdiff_t offset2)
+{
+    intN index;
+
+    index = js_NewSrcNote(cx, cg, type);
+    if (index >= 0) {
+        if (!js_SetSrcNoteOffset(cx, cg, index, 0, offset1))
+            return -1;
+        if (!js_SetSrcNoteOffset(cx, cg, index, 1, offset2))
+            return -1;
+    }
+    return index;
+}
+
+static JSBool
+GrowSrcNotes(JSContext *cx, JSCodeGenerator *cg)
+{
+    JSArenaPool *pool;
+    size_t size;
+
+    /* Grow by doubling note array size; update noteMask on success. */
+    pool = cg->notePool;
+    size = SRCNOTE_SIZE(CG_NOTE_MASK(cg) + 1);
+    JS_ARENA_GROW_CAST(CG_NOTES(cg), jssrcnote *, pool, size, size);
+    if (!CG_NOTES(cg)) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+    CG_NOTE_MASK(cg) = (CG_NOTE_MASK(cg) << 1) | 1;
+    return JS_TRUE;
+}
+
+jssrcnote *
+js_AddToSrcNoteDelta(JSContext *cx, JSCodeGenerator *cg, jssrcnote *sn,
+                     ptrdiff_t delta)
+{
+    ptrdiff_t base, limit, newdelta, diff;
+    intN index;
+
+    /*
+     * Called only from OptimizeSpanDeps and js_FinishTakingSrcNotes to add to
+     * main script note deltas, and only by a small positive amount.
+     */
+    JS_ASSERT(cg->current == &cg->main);
+    JS_ASSERT((unsigned) delta < (unsigned) SN_XDELTA_LIMIT);
+
+    base = SN_DELTA(sn);
+    limit = SN_IS_XDELTA(sn) ? SN_XDELTA_LIMIT : SN_DELTA_LIMIT;
+    newdelta = base + delta;
+    if (newdelta < limit) {
+        SN_SET_DELTA(sn, newdelta);
+    } else {
+        index = sn - cg->main.notes;
+        if ((cg->main.noteCount & cg->main.noteMask) == 0) {
+            if (!GrowSrcNotes(cx, cg))
+                return NULL;
+            sn = cg->main.notes + index;
+        }
+        diff = cg->main.noteCount - index;
+        cg->main.noteCount++;
+        memmove(sn + 1, sn, SRCNOTE_SIZE(diff));
+        SN_MAKE_XDELTA(sn, delta);
+        sn++;
+    }
+    return sn;
+}
+
+JS_FRIEND_API(uintN)
+js_SrcNoteLength(jssrcnote *sn)
+{
+    uintN arity;
+    jssrcnote *base;
+
+    arity = (intN)js_SrcNoteSpec[SN_TYPE(sn)].arity;
+    for (base = sn++; arity; sn++, arity--) {
+        if (*sn & SN_3BYTE_OFFSET_FLAG)
+            sn += 2;
+    }
+    return sn - base;
+}
+
+JS_FRIEND_API(ptrdiff_t)
+js_GetSrcNoteOffset(jssrcnote *sn, uintN which)
+{
+    /* Find the offset numbered which (i.e., skip exactly which offsets). */
+    JS_ASSERT(SN_TYPE(sn) != SRC_XDELTA);
+    JS_ASSERT(which < js_SrcNoteSpec[SN_TYPE(sn)].arity);
+    for (sn++; which; sn++, which--) {
+        if (*sn & SN_3BYTE_OFFSET_FLAG)
+            sn += 2;
+    }
+    if (*sn & SN_3BYTE_OFFSET_FLAG) {
+        return (ptrdiff_t)(((uint32)(sn[0] & SN_3BYTE_OFFSET_MASK) << 16)
+                           | (sn[1] << 8)
+                           | sn[2]);
+    }
+    return (ptrdiff_t)*sn;
+}
+
+JSBool
+js_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index,
+                    uintN which, ptrdiff_t offset)
+{
+    jssrcnote *sn;
+    ptrdiff_t diff;
+
+    if ((jsuword)offset >= (jsuword)((ptrdiff_t)SN_3BYTE_OFFSET_FLAG << 16)) {
+        ReportStatementTooLarge(cx, cg);
+        return JS_FALSE;
+    }
+
+    /* Find the offset numbered which (i.e., skip exactly which offsets). */
+    sn = &CG_NOTES(cg)[index];
+    JS_ASSERT(SN_TYPE(sn) != SRC_XDELTA);
+    JS_ASSERT(which < js_SrcNoteSpec[SN_TYPE(sn)].arity);
+    for (sn++; which; sn++, which--) {
+        if (*sn & SN_3BYTE_OFFSET_FLAG)
+            sn += 2;
+    }
+
+    /* See if the new offset requires three bytes. */
+    if (offset > (ptrdiff_t)SN_3BYTE_OFFSET_MASK) {
+        /* Maybe this offset was already set to a three-byte value. */
+        if (!(*sn & SN_3BYTE_OFFSET_FLAG)) {
+            /* Losing, need to insert another two bytes for this offset. */
+            index = PTRDIFF(sn, CG_NOTES(cg), jssrcnote);
+
+            /*
+             * Simultaneously test to see if the source note array must grow to
+             * accomodate either the first or second byte of additional storage
+             * required by this 3-byte offset.
+             */
+            if (((CG_NOTE_COUNT(cg) + 1) & CG_NOTE_MASK(cg)) <= 1) {
+                if (!GrowSrcNotes(cx, cg))
+                    return JS_FALSE;
+                sn = CG_NOTES(cg) + index;
+            }
+            CG_NOTE_COUNT(cg) += 2;
+
+            diff = CG_NOTE_COUNT(cg) - (index + 3);
+            JS_ASSERT(diff >= 0);
+            if (diff > 0)
+                memmove(sn + 3, sn + 1, SRCNOTE_SIZE(diff));
+        }
+        *sn++ = (jssrcnote)(SN_3BYTE_OFFSET_FLAG | (offset >> 16));
+        *sn++ = (jssrcnote)(offset >> 8);
+    }
+    *sn = (jssrcnote)offset;
+    return JS_TRUE;
+}
+
+#ifdef DEBUG_brendan
+#define NBINS 10
+static uint32 hist[NBINS];
+
+void DumpSrcNoteSizeHist()
+{
+    static FILE *fp;
+    int i, n;
+
+    if (!fp) {
+        fp = fopen("/tmp/srcnotes.hist", "w");
+        if (!fp)
+            return;
+        setvbuf(fp, NULL, _IONBF, 0);
+    }
+    fprintf(fp, "SrcNote size histogram:\n");
+    for (i = 0; i < NBINS; i++) {
+        fprintf(fp, "%4u %4u ", JS_BIT(i), hist[i]);
+        for (n = (int) JS_HOWMANY(hist[i], 10); n > 0; --n)
+            fputc('*', fp);
+        fputc('\n', fp);
+    }
+    fputc('\n', fp);
+}
+#endif
+
+/*
+ * Fill in the storage at notes with prolog and main srcnotes; the space at
+ * notes was allocated using the CG_COUNT_FINAL_SRCNOTES macro from jsemit.h.
+ * SO DON'T CHANGE THIS FUNCTION WITHOUT AT LEAST CHECKING WHETHER jsemit.h's
+ * CG_COUNT_FINAL_SRCNOTES MACRO NEEDS CORRESPONDING CHANGES!
+ */
+JSBool
+js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *notes)
+{
+    uintN prologCount, mainCount, totalCount;
+    ptrdiff_t offset, delta;
+    jssrcnote *sn;
+
+    JS_ASSERT(cg->current == &cg->main);
+
+    prologCount = cg->prolog.noteCount;
+    if (prologCount && cg->prolog.currentLine != cg->firstLine) {
+        CG_SWITCH_TO_PROLOG(cg);
+        if (js_NewSrcNote2(cx, cg, SRC_SETLINE, (ptrdiff_t)cg->firstLine) < 0)
+            return JS_FALSE;
+        prologCount = cg->prolog.noteCount;
+        CG_SWITCH_TO_MAIN(cg);
+    } else {
+        /*
+         * Either no prolog srcnotes, or no line number change over prolog.
+         * We don't need a SRC_SETLINE, but we may need to adjust the offset
+         * of the first main note, by adding to its delta and possibly even
+         * prepending SRC_XDELTA notes to it to account for prolog bytecodes
+         * that came at and after the last annotated bytecode.
+         */
+        offset = CG_PROLOG_OFFSET(cg) - cg->prolog.lastNoteOffset;
+        JS_ASSERT(offset >= 0);
+        if (offset > 0) {
+            /* NB: Use as much of the first main note's delta as we can. */
+            sn = cg->main.notes;
+            delta = SN_IS_XDELTA(sn)
+                    ? SN_XDELTA_MASK - (*sn & SN_XDELTA_MASK)
+                    : SN_DELTA_MASK - (*sn & SN_DELTA_MASK);
+            if (offset < delta)
+                delta = offset;
+            for (;;) {
+                if (!js_AddToSrcNoteDelta(cx, cg, sn, delta))
+                    return JS_FALSE;
+                offset -= delta;
+                if (offset == 0)
+                    break;
+                delta = JS_MIN(offset, SN_XDELTA_MASK);
+                sn = cg->main.notes;
+            }
+        }
+    }
+
+    mainCount = cg->main.noteCount;
+    totalCount = prologCount + mainCount;
+    if (prologCount)
+        memcpy(notes, cg->prolog.notes, SRCNOTE_SIZE(prologCount));
+    memcpy(notes + prologCount, cg->main.notes, SRCNOTE_SIZE(mainCount));
+    SN_MAKE_TERMINATOR(&notes[totalCount]);
+
+#ifdef DEBUG_brendan
+  { int bin = JS_CeilingLog2(totalCount);
+    if (bin >= NBINS)
+        bin = NBINS - 1;
+    ++hist[bin];
+  }
+#endif
+    return JS_TRUE;
+}
+
+JSBool
+js_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg)
+{
+    size_t size, incr;
+    ptrdiff_t delta;
+
+    size = TRYNOTE_SIZE(cg->treeContext.tryCount);
+    if (size <= cg->tryNoteSpace)
+        return JS_TRUE;
+
+    /*
+     * Allocate trynotes from cx->tempPool.
+     * XXX Too much growing and we bloat, as other tempPool allocators block
+     * in-place growth, and we never recycle old free space in an arena.
+     * YYY But once we consume an entire arena, we'll realloc it, letting the
+     * malloc heap recycle old space, while still freeing _en masse_ via the
+     * arena pool.
+     */
+    if (!cg->tryBase) {
+        size = JS_ROUNDUP(size, TRYNOTE_SIZE(TRYNOTE_CHUNK));
+        JS_ARENA_ALLOCATE_CAST(cg->tryBase, JSTryNote *, &cx->tempPool, size);
+        if (!cg->tryBase)
+            return JS_FALSE;
+        cg->tryNoteSpace = size;
+        cg->tryNext = cg->tryBase;
+    } else {
+        delta = PTRDIFF((char *)cg->tryNext, (char *)cg->tryBase, char);
+        incr = size - cg->tryNoteSpace;
+        incr = JS_ROUNDUP(incr, TRYNOTE_SIZE(TRYNOTE_CHUNK));
+        size = cg->tryNoteSpace;
+        JS_ARENA_GROW_CAST(cg->tryBase, JSTryNote *, &cx->tempPool, size, incr);
+        if (!cg->tryBase)
+            return JS_FALSE;
+        cg->tryNoteSpace = size + incr;
+        cg->tryNext = (JSTryNote *)((char *)cg->tryBase + delta);
+    }
+    return JS_TRUE;
+}
+
+JSTryNote *
+js_NewTryNote(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t start,
+              ptrdiff_t end, ptrdiff_t catchStart)
+{
+    JSTryNote *tn;
+
+    JS_ASSERT(cg->tryBase <= cg->tryNext);
+    JS_ASSERT(catchStart >= 0);
+    tn = cg->tryNext++;
+    tn->start = start;
+    tn->length = end - start;
+    tn->catchStart = catchStart;
+    return tn;
+}
+
+void
+js_FinishTakingTryNotes(JSContext *cx, JSCodeGenerator *cg, JSTryNote *notes)
+{
+    uintN count;
+
+    count = PTRDIFF(cg->tryNext, cg->tryBase, JSTryNote);
+    if (!count)
+        return;
+
+    memcpy(notes, cg->tryBase, TRYNOTE_SIZE(count));
+    notes[count].start = 0;
+    notes[count].length = CG_OFFSET(cg);
+    notes[count].catchStart = 0;
+}

Added: freeswitch/trunk/libs/js/src/jsemit.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsemit.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,592 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsemit_h___
+#define jsemit_h___
+/*
+ * JS bytecode generation.
+ */
+
+#include "jsstddef.h"
+#include "jstypes.h"
+#include "jsatom.h"
+#include "jsopcode.h"
+#include "jsprvtd.h"
+#include "jspubtd.h"
+
+JS_BEGIN_EXTERN_C
+
+/*
+ * NB: If you add non-loop STMT_* enumerators, do so before STMT_DO_LOOP or
+ * you will break the STMT_IS_LOOP macro, just below this enum.
+ */
+typedef enum JSStmtType {
+    STMT_BLOCK        = 0,      /* compound statement: { s1[;... sN] } */
+    STMT_LABEL        = 1,      /* labeled statement:  L: s */
+    STMT_IF           = 2,      /* if (then) statement */
+    STMT_ELSE         = 3,      /* else clause of if statement */
+    STMT_SWITCH       = 4,      /* switch statement */
+    STMT_WITH         = 5,      /* with statement */
+    STMT_TRY          = 6,      /* try statement */
+    STMT_CATCH        = 7,      /* catch block */
+    STMT_FINALLY      = 8,      /* finally statement */
+    STMT_SUBROUTINE   = 9,      /* gosub-target subroutine body */
+    STMT_DO_LOOP      = 10,     /* do/while loop statement */
+    STMT_FOR_LOOP     = 11,     /* for loop statement */
+    STMT_FOR_IN_LOOP  = 12,     /* for/in loop statement */
+    STMT_WHILE_LOOP   = 13      /* while loop statement */
+} JSStmtType;
+
+#define STMT_IS_LOOP(stmt)      ((stmt)->type >= STMT_DO_LOOP)
+
+typedef struct JSStmtInfo JSStmtInfo;
+
+struct JSStmtInfo {
+    JSStmtType      type;           /* statement type */
+    ptrdiff_t       update;         /* loop update offset (top if none) */
+    ptrdiff_t       breaks;         /* offset of last break in loop */
+    ptrdiff_t       continues;      /* offset of last continue in loop */
+    ptrdiff_t       gosub;          /* offset of last GOSUB for this finally */
+    ptrdiff_t       catchJump;      /* offset of last end-of-catch jump */
+    JSAtom          *label;         /* name of LABEL or CATCH var */
+    JSStmtInfo      *down;          /* info for enclosing statement */
+};
+
+#define SET_STATEMENT_TOP(stmt, top)                                          \
+    ((stmt)->update = (top), (stmt)->breaks =                                 \
+     (stmt)->continues = (stmt)->catchJump = (stmt)->gosub = (-1))
+
+struct JSTreeContext {              /* tree context for semantic checks */
+    uint16          flags;          /* statement state flags, see below */
+    uint16          numGlobalVars;  /* max. no. of global variables/regexps */
+    uint32          tryCount;       /* total count of try statements parsed */
+    uint32          globalUses;     /* optimizable global var uses in total */
+    uint32          loopyGlobalUses;/* optimizable global var uses in loops */
+    JSStmtInfo      *topStmt;       /* top of statement info stack */
+    JSAtomList      decls;          /* function, const, and var declarations */
+    JSParseNode     *nodeList;      /* list of recyclable parse-node structs */
+};
+
+#define TCF_COMPILING          0x01 /* generating bytecode; this tc is a cg */
+#define TCF_IN_FUNCTION        0x02 /* parsing inside function body */
+#define TCF_RETURN_EXPR        0x04 /* function has 'return expr;' */
+#define TCF_RETURN_VOID        0x08 /* function has 'return;' */
+#define TCF_IN_FOR_INIT        0x10 /* parsing init expr of for; exclude 'in' */
+#define TCF_FUN_CLOSURE_VS_VAR 0x20 /* function and var with same name */
+#define TCF_FUN_USES_NONLOCALS 0x40 /* function refers to non-local names */
+#define TCF_FUN_HEAVYWEIGHT    0x80 /* function needs Call object per call */
+#define TCF_FUN_FLAGS          0xE0 /* flags to propagate from FunctionBody */
+#define TCF_HAS_DEFXMLNS      0x100 /* default xml namespace = ...; parsed */
+
+#define TREE_CONTEXT_INIT(tc)                                                 \
+    ((tc)->flags = (tc)->numGlobalVars = 0,                                   \
+     (tc)->tryCount = (tc)->globalUses = (tc)->loopyGlobalUses = 0,           \
+     (tc)->topStmt = NULL, ATOM_LIST_INIT(&(tc)->decls),                      \
+     (tc)->nodeList = NULL)
+
+#define TREE_CONTEXT_FINISH(tc)                                               \
+    ((void)0)
+
+/*
+ * Span-dependent instructions are jumps whose span (from the jump bytecode to
+ * the jump target) may require 2 or 4 bytes of immediate operand.
+ */
+typedef struct JSSpanDep    JSSpanDep;
+typedef struct JSJumpTarget JSJumpTarget;
+
+struct JSSpanDep {
+    ptrdiff_t       top;        /* offset of first bytecode in an opcode */
+    ptrdiff_t       offset;     /* offset - 1 within opcode of jump operand */
+    ptrdiff_t       before;     /* original offset - 1 of jump operand */
+    JSJumpTarget    *target;    /* tagged target pointer or backpatch delta */
+};
+
+/*
+ * Jump targets are stored in an AVL tree, for O(log(n)) lookup with targets
+ * sorted by offset from left to right, so that targets after a span-dependent
+ * instruction whose jump offset operand must be extended can be found quickly
+ * and adjusted upward (toward higher offsets).
+ */
+struct JSJumpTarget {
+    ptrdiff_t       offset;     /* offset of span-dependent jump target */
+    int             balance;    /* AVL tree balance number */
+    JSJumpTarget    *kids[2];   /* left and right AVL tree child pointers */
+};
+
+#define JT_LEFT                 0
+#define JT_RIGHT                1
+#define JT_OTHER_DIR(dir)       (1 - (dir))
+#define JT_IMBALANCE(dir)       (((dir) << 1) - 1)
+#define JT_DIR(imbalance)       (((imbalance) + 1) >> 1)
+
+/*
+ * Backpatch deltas are encoded in JSSpanDep.target if JT_TAG_BIT is clear,
+ * so we can maintain backpatch chains when using span dependency records to
+ * hold jump offsets that overflow 16 bits.
+ */
+#define JT_TAG_BIT              ((jsword) 1)
+#define JT_UNTAG_SHIFT          1
+#define JT_SET_TAG(jt)          ((JSJumpTarget *)((jsword)(jt) | JT_TAG_BIT))
+#define JT_CLR_TAG(jt)          ((JSJumpTarget *)((jsword)(jt) & ~JT_TAG_BIT))
+#define JT_HAS_TAG(jt)          ((jsword)(jt) & JT_TAG_BIT)
+
+#define BITS_PER_PTRDIFF        (sizeof(ptrdiff_t) * JS_BITS_PER_BYTE)
+#define BITS_PER_BPDELTA        (BITS_PER_PTRDIFF - 1 - JT_UNTAG_SHIFT)
+#define BPDELTA_MAX             (((ptrdiff_t)1 << BITS_PER_BPDELTA) - 1)
+#define BPDELTA_TO_JT(bp)       ((JSJumpTarget *)((bp) << JT_UNTAG_SHIFT))
+#define JT_TO_BPDELTA(jt)       ((ptrdiff_t)((jsword)(jt) >> JT_UNTAG_SHIFT))
+
+#define SD_SET_TARGET(sd,jt)    ((sd)->target = JT_SET_TAG(jt))
+#define SD_GET_TARGET(sd)       (JS_ASSERT(JT_HAS_TAG((sd)->target)),         \
+                                 JT_CLR_TAG((sd)->target))
+#define SD_SET_BPDELTA(sd,bp)   ((sd)->target = BPDELTA_TO_JT(bp))
+#define SD_GET_BPDELTA(sd)      (JS_ASSERT(!JT_HAS_TAG((sd)->target)),        \
+                                 JT_TO_BPDELTA((sd)->target))
+
+/* Avoid asserting twice by expanding SD_GET_TARGET in the "then" clause. */
+#define SD_SPAN(sd,pivot)       (SD_GET_TARGET(sd)                            \
+                                 ? JT_CLR_TAG((sd)->target)->offset - (pivot) \
+                                 : 0)
+
+struct JSCodeGenerator {
+    JSTreeContext   treeContext;    /* base state: statement info stack, etc. */
+
+    JSArenaPool     *codePool;      /* pointer to thread code arena pool */
+    JSArenaPool     *notePool;      /* pointer to thread srcnote arena pool */
+    void            *codeMark;      /* low watermark in cg->codePool */
+    void            *noteMark;      /* low watermark in cg->notePool */
+    void            *tempMark;      /* low watermark in cx->tempPool */
+
+    struct {
+        jsbytecode  *base;          /* base of JS bytecode vector */
+        jsbytecode  *limit;         /* one byte beyond end of bytecode */
+        jsbytecode  *next;          /* pointer to next free bytecode */
+        jssrcnote   *notes;         /* source notes, see below */
+        uintN       noteCount;      /* number of source notes so far */
+        uintN       noteMask;       /* growth increment for notes */
+        ptrdiff_t   lastNoteOffset; /* code offset for last source note */
+        uintN       currentLine;    /* line number for tree-based srcnote gen */
+    } prolog, main, *current;
+
+    const char      *filename;      /* null or weak link to source filename */
+    uintN           firstLine;      /* first line, for js_NewScriptFromCG */
+    JSPrincipals    *principals;    /* principals for constant folding eval */
+    JSAtomList      atomList;       /* literals indexed for mapping */
+
+    intN            stackDepth;     /* current stack depth in script frame */
+    uintN           maxStackDepth;  /* maximum stack depth so far */
+
+    JSTryNote       *tryBase;       /* first exception handling note */
+    JSTryNote       *tryNext;       /* next available note */
+    size_t          tryNoteSpace;   /* # of bytes allocated at tryBase */
+
+    JSSpanDep       *spanDeps;      /* span dependent instruction records */
+    JSJumpTarget    *jumpTargets;   /* AVL tree of jump target offsets */
+    JSJumpTarget    *jtFreeList;    /* JT_LEFT-linked list of free structs */
+    uintN           numSpanDeps;    /* number of span dependencies */
+    uintN           numJumpTargets; /* number of jump targets */
+    ptrdiff_t       spanDepTodo;    /* offset from main.base of potentially
+                                       unoptimized spandeps */
+
+    uintN           emitLevel;      /* js_EmitTree recursion level */
+    JSAtomList      constList;      /* compile time constants */
+    JSCodeGenerator *parent;        /* Enclosing function or global context */
+};
+
+#define CG_BASE(cg)             ((cg)->current->base)
+#define CG_LIMIT(cg)            ((cg)->current->limit)
+#define CG_NEXT(cg)             ((cg)->current->next)
+#define CG_CODE(cg,offset)      (CG_BASE(cg) + (offset))
+#define CG_OFFSET(cg)           PTRDIFF(CG_NEXT(cg), CG_BASE(cg), jsbytecode)
+
+#define CG_NOTES(cg)            ((cg)->current->notes)
+#define CG_NOTE_COUNT(cg)       ((cg)->current->noteCount)
+#define CG_NOTE_MASK(cg)        ((cg)->current->noteMask)
+#define CG_LAST_NOTE_OFFSET(cg) ((cg)->current->lastNoteOffset)
+#define CG_CURRENT_LINE(cg)     ((cg)->current->currentLine)
+
+#define CG_PROLOG_BASE(cg)      ((cg)->prolog.base)
+#define CG_PROLOG_LIMIT(cg)     ((cg)->prolog.limit)
+#define CG_PROLOG_NEXT(cg)      ((cg)->prolog.next)
+#define CG_PROLOG_CODE(cg,poff) (CG_PROLOG_BASE(cg) + (poff))
+#define CG_PROLOG_OFFSET(cg)    PTRDIFF(CG_PROLOG_NEXT(cg), CG_PROLOG_BASE(cg),\
+                                        jsbytecode)
+
+#define CG_SWITCH_TO_MAIN(cg)   ((cg)->current = &(cg)->main)
+#define CG_SWITCH_TO_PROLOG(cg) ((cg)->current = &(cg)->prolog)
+
+/*
+ * Initialize cg to allocate bytecode space from codePool, source note space
+ * from notePool, and all other arena-allocated temporaries from cx->tempPool.
+ * Return true on success.  Report an error and return false if the initial
+ * code segment can't be allocated.
+ */
+extern JS_FRIEND_API(JSBool)
+js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg,
+                     JSArenaPool *codePool, JSArenaPool *notePool,
+                     const char *filename, uintN lineno,
+                     JSPrincipals *principals);
+
+/*
+ * Release cg->codePool, cg->notePool, and cx->tempPool to marks set by
+ * js_InitCodeGenerator.  Note that cgs are magic: they own the arena pool
+ * "tops-of-stack" space above their codeMark, noteMark, and tempMark points.
+ * This means you cannot alloc from tempPool and save the pointer beyond the
+ * next JS_FinishCodeGenerator.
+ */
+extern JS_FRIEND_API(void)
+js_FinishCodeGenerator(JSContext *cx, JSCodeGenerator *cg);
+
+/*
+ * Emit one bytecode.
+ */
+extern ptrdiff_t
+js_Emit1(JSContext *cx, JSCodeGenerator *cg, JSOp op);
+
+/*
+ * Emit two bytecodes, an opcode (op) with a byte of immediate operand (op1).
+ */
+extern ptrdiff_t
+js_Emit2(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1);
+
+/*
+ * Emit three bytecodes, an opcode with two bytes of immediate operands.
+ */
+extern ptrdiff_t
+js_Emit3(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1,
+         jsbytecode op2);
+
+/*
+ * Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand.
+ */
+extern ptrdiff_t
+js_EmitN(JSContext *cx, JSCodeGenerator *cg, JSOp op, size_t extra);
+
+/*
+ * Unsafe macro to call js_SetJumpOffset and return false if it does.
+ */
+#define CHECK_AND_SET_JUMP_OFFSET(cx,cg,pc,off)                               \
+    JS_BEGIN_MACRO                                                            \
+        if (!js_SetJumpOffset(cx, cg, pc, off))                               \
+            return JS_FALSE;                                                  \
+    JS_END_MACRO
+
+#define CHECK_AND_SET_JUMP_OFFSET_AT(cx,cg,off)                               \
+    CHECK_AND_SET_JUMP_OFFSET(cx, cg, CG_CODE(cg,off), CG_OFFSET(cg) - (off))
+
+extern JSBool
+js_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc,
+                 ptrdiff_t off);
+
+/* Test whether we're in a with statement. */
+extern JSBool
+js_InWithStatement(JSTreeContext *tc);
+
+/* Test whether we're in a catch block with exception named by atom. */
+extern JSBool
+js_InCatchBlock(JSTreeContext *tc, JSAtom *atom);
+
+/*
+ * Push the C-stack-allocated struct at stmt onto the stmtInfo stack.
+ */
+extern void
+js_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type,
+                 ptrdiff_t top);
+
+/*
+ * Pop tc->topStmt.  If the top JSStmtInfo struct is not stack-allocated, it
+ * is up to the caller to free it.
+ */
+extern void
+js_PopStatement(JSTreeContext *tc);
+
+/*
+ * Like js_PopStatement(&cg->treeContext), also patch breaks and continues.
+ * May fail if a jump offset overflows.
+ */
+extern JSBool
+js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg);
+
+/*
+ * Define and lookup a primitive jsval associated with the const named by atom.
+ * js_DefineCompileTimeConstant analyzes the constant-folded initializer at pn
+ * and saves the const's value in cg->constList, if it can be used at compile
+ * time.  It returns true unless an error occurred.
+ *
+ * If the initializer's value could not be saved, js_LookupCompileTimeConstant
+ * calls will return the undefined value.  js_LookupCompileTimeConstant tries
+ * to find a const value memorized for atom, returning true with *vp set to a
+ * value other than undefined if the constant was found, true with *vp set to
+ * JSVAL_VOID if not found, and false on error.
+ */
+extern JSBool
+js_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
+                             JSParseNode *pn);
+
+extern JSBool
+js_LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
+                             jsval *vp);
+
+/*
+ * Emit code into cg for the tree rooted at pn.
+ */
+extern JSBool
+js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn);
+
+/*
+ * Emit code into cg for the tree rooted at body, then create a persistent
+ * script for fun from cg.
+ */
+extern JSBool
+js_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body,
+                    JSFunction *fun);
+
+/*
+ * Source notes generated along with bytecode for decompiling and debugging.
+ * A source note is a uint8 with 5 bits of type and 3 of offset from the pc of
+ * the previous note.  If 3 bits of offset aren't enough, extended delta notes
+ * (SRC_XDELTA) consisting of 2 set high order bits followed by 6 offset bits
+ * are emitted before the next note.  Some notes have operand offsets encoded
+ * immediately after them, in note bytes or byte-triples.
+ *
+ *                 Source Note               Extended Delta
+ *              +7-6-5-4-3+2-1-0+           +7-6-5+4-3-2-1-0+
+ *              |note-type|delta|           |1 1| ext-delta |
+ *              +---------+-----+           +---+-----------+
+ *
+ * At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE,
+ * SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode.
+ *
+ * NB: the js_SrcNoteSpec array in jsemit.c is indexed by this enum, so its
+ * initializers need to match the order here.
+ */
+typedef enum JSSrcNoteType {
+    SRC_NULL        = 0,        /* terminates a note vector */
+    SRC_IF          = 1,        /* JSOP_IFEQ bytecode is from an if-then */
+    SRC_IF_ELSE     = 2,        /* JSOP_IFEQ bytecode is from an if-then-else */
+    SRC_WHILE       = 3,        /* JSOP_IFEQ is from a while loop */
+    SRC_FOR         = 4,        /* JSOP_NOP or JSOP_POP in for loop head */
+    SRC_CONTINUE    = 5,        /* JSOP_GOTO is a continue, not a break;
+                                   also used on JSOP_ENDINIT if extra comma
+                                   at end of array literal: [1,2,,] */
+    SRC_VAR         = 6,        /* JSOP_NAME/SETNAME/FORNAME in a var decl */
+    SRC_PCDELTA     = 7,        /* distance from comma-operator to next POP,
+                                   or from CONDSWITCH to first CASE opcode --
+                                   or SRC_PCBASE variant for obj.function::foo
+                                   gets and sets */
+    SRC_ASSIGNOP    = 8,        /* += or another assign-op follows */
+    SRC_COND        = 9,        /* JSOP_IFEQ is from conditional ?: operator */
+    SRC_RESERVED0   = 10,       /* reserved for future use */
+    SRC_HIDDEN      = 11,       /* opcode shouldn't be decompiled */
+    SRC_PCBASE      = 12,       /* distance back from annotated get- or setprop
+                                   op to first obj.prop.subprop bytecode */
+    SRC_LABEL       = 13,       /* JSOP_NOP for label: with atomid immediate */
+    SRC_LABELBRACE  = 14,       /* JSOP_NOP for label: {...} begin brace */
+    SRC_ENDBRACE    = 15,       /* JSOP_NOP for label: {...} end brace */
+    SRC_BREAK2LABEL = 16,       /* JSOP_GOTO for 'break label' with atomid */
+    SRC_CONT2LABEL  = 17,       /* JSOP_GOTO for 'continue label' with atomid */
+    SRC_SWITCH      = 18,       /* JSOP_*SWITCH with offset to end of switch,
+                                   2nd off to first JSOP_CASE if condswitch */
+    SRC_FUNCDEF     = 19,       /* JSOP_NOP for function f() with atomid */
+    SRC_CATCH       = 20,       /* catch block has guard */
+    SRC_CONST       = 21,       /* JSOP_SETCONST in a const decl */
+    SRC_NEWLINE     = 22,       /* bytecode follows a source newline */
+    SRC_SETLINE     = 23,       /* a file-absolute source line number note */
+    SRC_XDELTA      = 24        /* 24-31 are for extended delta notes */
+} JSSrcNoteType;
+
+#define SN_TYPE_BITS            5
+#define SN_DELTA_BITS           3
+#define SN_XDELTA_BITS          6
+#define SN_TYPE_MASK            (JS_BITMASK(SN_TYPE_BITS) << SN_DELTA_BITS)
+#define SN_DELTA_MASK           ((ptrdiff_t)JS_BITMASK(SN_DELTA_BITS))
+#define SN_XDELTA_MASK          ((ptrdiff_t)JS_BITMASK(SN_XDELTA_BITS))
+
+#define SN_MAKE_NOTE(sn,t,d)    (*(sn) = (jssrcnote)                          \
+                                          (((t) << SN_DELTA_BITS)             \
+                                           | ((d) & SN_DELTA_MASK)))
+#define SN_MAKE_XDELTA(sn,d)    (*(sn) = (jssrcnote)                          \
+                                          ((SRC_XDELTA << SN_DELTA_BITS)      \
+                                           | ((d) & SN_XDELTA_MASK)))
+
+#define SN_IS_XDELTA(sn)        ((*(sn) >> SN_DELTA_BITS) >= SRC_XDELTA)
+#define SN_TYPE(sn)             (SN_IS_XDELTA(sn) ? SRC_XDELTA                \
+                                                  : *(sn) >> SN_DELTA_BITS)
+#define SN_SET_TYPE(sn,type)    SN_MAKE_NOTE(sn, type, SN_DELTA(sn))
+#define SN_IS_GETTABLE(sn)      (SN_TYPE(sn) < SRC_NEWLINE)
+
+#define SN_DELTA(sn)            ((ptrdiff_t)(SN_IS_XDELTA(sn)                 \
+                                             ? *(sn) & SN_XDELTA_MASK         \
+                                             : *(sn) & SN_DELTA_MASK))
+#define SN_SET_DELTA(sn,delta)  (SN_IS_XDELTA(sn)                             \
+                                 ? SN_MAKE_XDELTA(sn, delta)                  \
+                                 : SN_MAKE_NOTE(sn, SN_TYPE(sn), delta))
+
+#define SN_DELTA_LIMIT          ((ptrdiff_t)JS_BIT(SN_DELTA_BITS))
+#define SN_XDELTA_LIMIT         ((ptrdiff_t)JS_BIT(SN_XDELTA_BITS))
+
+/*
+ * Offset fields follow certain notes and are frequency-encoded: an offset in
+ * [0,0x7f] consumes one byte, an offset in [0x80,0x7fffff] takes three, and
+ * the high bit of the first byte is set.
+ */
+#define SN_3BYTE_OFFSET_FLAG    0x80
+#define SN_3BYTE_OFFSET_MASK    0x7f
+
+typedef struct JSSrcNoteSpec {
+    const char      *name;      /* name for disassembly/debugging output */
+    uint8           arity;      /* number of offset operands */
+    uint8           offsetBias; /* bias of offset(s) from annotated pc */
+    int8            isSpanDep;  /* 1 or -1 if offsets could span extended ops,
+                                   0 otherwise; sign tells span direction */
+} JSSrcNoteSpec;
+
+extern JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[];
+extern JS_FRIEND_API(uintN)          js_SrcNoteLength(jssrcnote *sn);
+
+#define SN_LENGTH(sn)           ((js_SrcNoteSpec[SN_TYPE(sn)].arity == 0) ? 1 \
+                                 : js_SrcNoteLength(sn))
+#define SN_NEXT(sn)             ((sn) + SN_LENGTH(sn))
+
+/* A source note array is terminated by an all-zero element. */
+#define SN_MAKE_TERMINATOR(sn)  (*(sn) = SRC_NULL)
+#define SN_IS_TERMINATOR(sn)    (*(sn) == SRC_NULL)
+
+/*
+ * Append a new source note of the given type (and therefore size) to cg's
+ * notes dynamic array, updating cg->noteCount.  Return the new note's index
+ * within the array pointed at by cg->current->notes.  Return -1 if out of
+ * memory.
+ */
+extern intN
+js_NewSrcNote(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type);
+
+extern intN
+js_NewSrcNote2(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type,
+               ptrdiff_t offset);
+
+extern intN
+js_NewSrcNote3(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type,
+               ptrdiff_t offset1, ptrdiff_t offset2);
+
+/*
+ * NB: this function can add at most one extra extended delta note.
+ */
+extern jssrcnote *
+js_AddToSrcNoteDelta(JSContext *cx, JSCodeGenerator *cg, jssrcnote *sn,
+                     ptrdiff_t delta);
+
+/*
+ * Get and set the offset operand identified by which (0 for the first, etc.).
+ */
+extern JS_FRIEND_API(ptrdiff_t)
+js_GetSrcNoteOffset(jssrcnote *sn, uintN which);
+
+extern JSBool
+js_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index,
+                    uintN which, ptrdiff_t offset);
+
+/*
+ * Finish taking source notes in cx's notePool, copying final notes to the new
+ * stable store allocated by the caller and passed in via notes.  Return false
+ * on malloc failure, which means this function reported an error.
+ *
+ * To compute the number of jssrcnotes to allocate and pass in via notes, use
+ * the CG_COUNT_FINAL_SRCNOTES macro.  This macro knows a lot about details of
+ * js_FinishTakingSrcNotes, SO DON'T CHANGE jsemit.c's js_FinishTakingSrcNotes
+ * FUNCTION WITHOUT CHECKING WHETHER THIS MACRO NEEDS CORRESPONDING CHANGES!
+ */
+#define CG_COUNT_FINAL_SRCNOTES(cg, cnt)                                      \
+    JS_BEGIN_MACRO                                                            \
+        ptrdiff_t diff_ = CG_PROLOG_OFFSET(cg) - (cg)->prolog.lastNoteOffset; \
+        cnt = (cg)->prolog.noteCount + (cg)->main.noteCount + 1;              \
+        if ((cg)->prolog.noteCount &&                                         \
+            (cg)->prolog.currentLine != (cg)->firstLine) {                    \
+            if (diff_ > SN_DELTA_MASK)                                        \
+                cnt += JS_HOWMANY(diff_ - SN_DELTA_MASK, SN_XDELTA_MASK);     \
+            cnt += 2 + (((cg)->firstLine > SN_3BYTE_OFFSET_MASK) << 1);       \
+        } else if (diff_ > 0) {                                               \
+            if (cg->main.noteCount) {                                         \
+                jssrcnote *sn_ = (cg)->main.notes;                            \
+                diff_ -= SN_IS_XDELTA(sn_)                                    \
+                         ? SN_XDELTA_MASK - (*sn_ & SN_XDELTA_MASK)           \
+                         : SN_DELTA_MASK - (*sn_ & SN_DELTA_MASK);            \
+            }                                                                 \
+            if (diff_ > 0)                                                    \
+                cnt += JS_HOWMANY(diff_, SN_XDELTA_MASK);                     \
+        }                                                                     \
+    JS_END_MACRO
+
+extern JSBool
+js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *notes);
+
+/*
+ * Allocate cg->treeContext.tryCount notes (plus one for the end sentinel)
+ * from cx->tempPool and set up cg->tryBase/tryNext for exactly tryCount
+ * js_NewTryNote calls.  The storage is freed by js_FinishCodeGenerator.
+ */
+extern JSBool
+js_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg);
+
+/*
+ * Grab the next trynote slot in cg, filling it in appropriately.
+ */
+extern JSTryNote *
+js_NewTryNote(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t start,
+              ptrdiff_t end, ptrdiff_t catchStart);
+
+/*
+ * Finish generating exception information into the space at notes.  As with
+ * js_FinishTakingSrcNotes, the caller must use CG_COUNT_FINAL_TRYNOTES(cg) to
+ * preallocate enough space in a JSTryNote[] to pass as the notes parameter of
+ * js_FinishTakingTryNotes.
+ */
+#define CG_COUNT_FINAL_TRYNOTES(cg, cnt)                                      \
+    JS_BEGIN_MACRO                                                            \
+        cnt = ((cg)->tryNext > (cg)->tryBase)                                 \
+              ? PTRDIFF(cg->tryNext, cg->tryBase, JSTryNote) + 1              \
+              : 0;                                                            \
+    JS_END_MACRO
+
+extern void
+js_FinishTakingTryNotes(JSContext *cx, JSCodeGenerator *cg, JSTryNote *notes);
+
+JS_END_EXTERN_C
+
+#endif /* jsemit_h___ */

Added: freeswitch/trunk/libs/js/src/jsexn.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsexn.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1164 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS standard exception implementation.
+ */
+
+#include "jsstddef.h"
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsbit.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsdbgapi.h"
+#include "jsexn.h"
+#include "jsfun.h"
+#include "jsinterp.h"
+#include "jsnum.h"
+#include "jsopcode.h"
+#include "jsscript.h"
+
+#if JS_HAS_ERROR_EXCEPTIONS
+#if !JS_HAS_EXCEPTIONS
+# error "JS_HAS_EXCEPTIONS must be defined to use JS_HAS_ERROR_EXCEPTIONS"
+#endif
+
+/* XXX consider adding rt->atomState.messageAtom */
+static char js_message_str[]  = "message";
+static char js_filename_str[] = "fileName";
+static char js_lineno_str[]   = "lineNumber";
+static char js_stack_str[]    = "stack";
+
+/* Forward declarations for ExceptionClass's initializer. */
+static JSBool
+Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
+
+static void
+exn_finalize(JSContext *cx, JSObject *obj);
+
+static JSClass ExceptionClass = {
+    "Error",
+    JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   exn_finalize,
+    NULL,             NULL,             NULL,             Exception,
+    NULL,             NULL,             NULL,             0
+};
+
+/*
+ * A copy of the JSErrorReport originally generated.
+ */
+typedef struct JSExnPrivate {
+    JSErrorReport *errorReport;
+} JSExnPrivate;
+
+/*
+ * Undo all the damage done by exn_newPrivate.
+ */
+static void
+exn_destroyPrivate(JSContext *cx, JSExnPrivate *privateData)
+{
+    JSErrorReport *report;
+    const jschar **args;
+
+    if (!privateData)
+        return;
+    report = privateData->errorReport;
+    if (report) {
+        if (report->uclinebuf)
+            JS_free(cx, (void *)report->uclinebuf);
+        if (report->filename)
+            JS_free(cx, (void *)report->filename);
+        if (report->ucmessage)
+            JS_free(cx, (void *)report->ucmessage);
+        if (report->messageArgs) {
+            args = report->messageArgs;
+            while (*args)
+                JS_free(cx, (void *)*args++);
+            JS_free(cx, (void *)report->messageArgs);
+        }
+        JS_free(cx, report);
+    }
+    JS_free(cx, privateData);
+}
+
+/*
+ * Copy everything interesting about an error into allocated memory.
+ */
+static JSExnPrivate *
+exn_newPrivate(JSContext *cx, JSErrorReport *report)
+{
+    intN i;
+    JSExnPrivate *newPrivate;
+    JSErrorReport *newReport;
+    size_t capacity;
+
+    newPrivate = (JSExnPrivate *)JS_malloc(cx, sizeof (JSExnPrivate));
+    if (!newPrivate)
+        return NULL;
+    memset(newPrivate, 0, sizeof (JSExnPrivate));
+
+    /* Copy the error report */
+    newReport = (JSErrorReport *)JS_malloc(cx, sizeof (JSErrorReport));
+    if (!newReport)
+        goto error;
+    memset(newReport, 0, sizeof (JSErrorReport));
+    newPrivate->errorReport = newReport;
+
+    if (report->filename) {
+        newReport->filename = JS_strdup(cx, report->filename);
+        if (!newReport->filename)
+            goto error;
+    } else {
+        newReport->filename = NULL;
+    }
+
+    newReport->lineno = report->lineno;
+
+    /*
+     * We don't need to copy linebuf and tokenptr, because they
+     * point into the deflated string cache.  (currently?)
+     */
+    newReport->linebuf = report->linebuf;
+    newReport->tokenptr = report->tokenptr;
+
+    /*
+     * But we do need to copy uclinebuf, uctokenptr, because they're
+     * pointers into internal tokenstream structs, and may go away.
+     */
+    if (report->uclinebuf) {
+        capacity = js_strlen(report->uclinebuf) + 1;
+        newReport->uclinebuf =
+            (const jschar *)JS_malloc(cx, capacity * sizeof(jschar));
+        if (!newReport->uclinebuf)
+            goto error;
+        js_strncpy((jschar *)newReport->uclinebuf, report->uclinebuf, capacity);
+        newReport->uctokenptr = newReport->uclinebuf + (report->uctokenptr -
+                                                        report->uclinebuf);
+    } else {
+        newReport->uclinebuf = newReport->uctokenptr = NULL;
+    }
+
+    if (report->ucmessage) {
+        capacity = js_strlen(report->ucmessage) + 1;
+        newReport->ucmessage = (const jschar *)
+            JS_malloc(cx, capacity * sizeof(jschar));
+        if (!newReport->ucmessage)
+            goto error;
+        js_strncpy((jschar *)newReport->ucmessage, report->ucmessage, capacity);
+
+        if (report->messageArgs) {
+            for (i = 0; report->messageArgs[i]; i++)
+                continue;
+            JS_ASSERT(i);
+            newReport->messageArgs =
+                (const jschar **)JS_malloc(cx, (i + 1) * sizeof(jschar *));
+            if (!newReport->messageArgs)
+                goto error;
+            for (i = 0; report->messageArgs[i]; i++) {
+                capacity = js_strlen(report->messageArgs[i]) + 1;
+                newReport->messageArgs[i] =
+                    (const jschar *)JS_malloc(cx, capacity * sizeof(jschar));
+                if (!newReport->messageArgs[i])
+                    goto error;
+                js_strncpy((jschar *)(newReport->messageArgs[i]),
+                           report->messageArgs[i], capacity);
+            }
+            newReport->messageArgs[i] = NULL;
+        } else {
+            newReport->messageArgs = NULL;
+        }
+    } else {
+        newReport->ucmessage = NULL;
+        newReport->messageArgs = NULL;
+    }
+    newReport->errorNumber = report->errorNumber;
+
+    /* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
+    newReport->flags = report->flags;
+
+    return newPrivate;
+error:
+    exn_destroyPrivate(cx, newPrivate);
+    return NULL;
+}
+
+static void
+exn_finalize(JSContext *cx, JSObject *obj)
+{
+    JSExnPrivate *privateData;
+    jsval privateValue;
+
+    privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+
+    if (!JSVAL_IS_VOID(privateValue)) {
+        privateData = (JSExnPrivate*) JSVAL_TO_PRIVATE(privateValue);
+        if (privateData)
+            exn_destroyPrivate(cx, privateData);
+    }
+}
+
+JSErrorReport *
+js_ErrorFromException(JSContext *cx, jsval exn)
+{
+    JSObject *obj;
+    JSExnPrivate *privateData;
+    jsval privateValue;
+
+    if (JSVAL_IS_PRIMITIVE(exn))
+        return NULL;
+    obj = JSVAL_TO_OBJECT(exn);
+    if (OBJ_GET_CLASS(cx, obj) != &ExceptionClass)
+        return NULL;
+    privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    if (JSVAL_IS_VOID(privateValue))
+        return NULL;
+    privateData = (JSExnPrivate*) JSVAL_TO_PRIVATE(privateValue);
+    if (!privateData)
+        return NULL;
+
+    JS_ASSERT(privateData->errorReport);
+    return privateData->errorReport;
+}
+
+struct JSExnSpec {
+    int protoIndex;
+    const char *name;
+    JSNative native;
+};
+
+/*
+ * All *Error constructors share the same JSClass, ExceptionClass.  But each
+ * constructor function for an *Error class must have a distinct native 'call'
+ * function pointer, in order for instanceof to work properly across multiple
+ * standard class sets.  See jsfun.c:fun_hasInstance.
+ */
+#define MAKE_EXCEPTION_CTOR(name)                                             \
+const char js_##name##_str[] = #name;                                         \
+static JSBool                                                                 \
+name(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)      \
+{                                                                             \
+    return Exception(cx, obj, argc, argv, rval);                              \
+}
+
+MAKE_EXCEPTION_CTOR(Error)
+MAKE_EXCEPTION_CTOR(InternalError)
+MAKE_EXCEPTION_CTOR(EvalError)
+MAKE_EXCEPTION_CTOR(RangeError)
+MAKE_EXCEPTION_CTOR(ReferenceError)
+MAKE_EXCEPTION_CTOR(SyntaxError)
+MAKE_EXCEPTION_CTOR(TypeError)
+MAKE_EXCEPTION_CTOR(URIError)
+
+#undef MAKE_EXCEPTION_CTOR
+
+static struct JSExnSpec exceptions[] = {
+    { JSEXN_NONE,       js_Error_str,           Error },
+    { JSEXN_ERR,        js_InternalError_str,   InternalError },
+    { JSEXN_ERR,        js_EvalError_str,       EvalError },
+    { JSEXN_ERR,        js_RangeError_str,      RangeError },
+    { JSEXN_ERR,        js_ReferenceError_str,  ReferenceError },
+    { JSEXN_ERR,        js_SyntaxError_str,     SyntaxError },
+    { JSEXN_ERR,        js_TypeError_str,       TypeError },
+    { JSEXN_ERR,        js_URIError_str,        URIError },
+    {0,NULL,NULL}
+};
+
+static JSBool
+InitExceptionObject(JSContext *cx, JSObject *obj, JSString *message,
+                    JSString *filename, uintN lineno)
+{
+    JSCheckAccessOp checkAccess;
+    JSErrorReporter older;
+    JSExceptionState *state;
+    jschar *stackbuf;
+    size_t stacklen, stackmax;
+    JSStackFrame *fp;
+    jsval callerid, v;
+    JSBool ok;
+    JSString *argsrc, *stack;
+    uintN i, ulineno;
+    const char *cp;
+    char ulnbuf[11];
+
+    if (!JS_DefineProperty(cx, obj, js_message_str, STRING_TO_JSVAL(message),
+                           NULL, NULL, JSPROP_ENUMERATE)) {
+        return JS_FALSE;
+    }
+
+    if (!JS_DefineProperty(cx, obj, js_filename_str,
+                           STRING_TO_JSVAL(filename),
+                           NULL, NULL, JSPROP_ENUMERATE)) {
+        return JS_FALSE;
+    }
+
+    if (!JS_DefineProperty(cx, obj, js_lineno_str,
+                           INT_TO_JSVAL(lineno),
+                           NULL, NULL, JSPROP_ENUMERATE)) {
+        return JS_FALSE;
+    }
+
+    /*
+     * Set the 'stack' property.
+     *
+     * First, set aside any error reporter for cx and save its exception state
+     * so we can suppress any checkAccess failures.  Such failures should stop
+     * the backtrace procedure, not result in a failure of this constructor.
+     */
+    checkAccess = cx->runtime->checkObjectAccess;
+    if (checkAccess) {
+        older = JS_SetErrorReporter(cx, NULL);
+        state = JS_SaveExceptionState(cx);
+    }
+#ifdef __GNUC__         /* suppress bogus gcc warnings */
+    else {
+        older = NULL;
+        state = NULL;
+    }
+#endif
+    callerid = ATOM_KEY(cx->runtime->atomState.callerAtom);
+
+    /*
+     * Prepare to allocate a jschar buffer at stackbuf, where stacklen indexes
+     * the next free jschar slot, and with room for at most stackmax non-null
+     * jschars.  If stackbuf is non-null, it always contains an extra slot for
+     * the null terminator we'll store at the end, as a backstop.
+     *
+     * All early returns must goto done after this point, till the after-loop
+     * cleanup code has run!
+     */
+    stackbuf = NULL;
+    stacklen = stackmax = 0;
+    ok = JS_TRUE;
+
+#define APPEND_CHAR_TO_STACK(c)                                               \
+    JS_BEGIN_MACRO                                                            \
+        if (stacklen == stackmax) {                                           \
+            void *ptr_;                                                       \
+            stackmax = stackmax ? 2 * stackmax : 64;                          \
+            ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar));   \
+            if (!ptr_) {                                                      \
+                ok = JS_FALSE;                                                \
+                goto done;                                                    \
+            }                                                                 \
+            stackbuf = ptr_;                                                  \
+        }                                                                     \
+        stackbuf[stacklen++] = (c);                                           \
+    JS_END_MACRO
+
+#define APPEND_STRING_TO_STACK(str)                                           \
+    JS_BEGIN_MACRO                                                            \
+        JSString *str_ = str;                                                 \
+        size_t length_ = JSSTRING_LENGTH(str_);                               \
+        if (stacklen + length_ > stackmax) {                                  \
+            void *ptr_;                                                       \
+            stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_));            \
+            ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar));   \
+            if (!ptr_) {                                                      \
+                ok = JS_FALSE;                                                \
+                goto done;                                                    \
+            }                                                                 \
+            stackbuf = ptr_;                                                  \
+        }                                                                     \
+        js_strncpy(stackbuf + stacklen, JSSTRING_CHARS(str_), length_);       \
+        stacklen += length_;                                                  \
+    JS_END_MACRO
+
+    for (fp = cx->fp; fp; fp = fp->down) {
+        if (checkAccess) {
+            v = (fp->fun && fp->argv) ? fp->argv[-2] : JSVAL_NULL;
+            if (!JSVAL_IS_PRIMITIVE(v)) {
+                ok = checkAccess(cx, JSVAL_TO_OBJECT(fp->argv[-2]), callerid,
+                                 JSACC_READ, &v /* ignored */);
+                if (!ok) {
+                    ok = JS_TRUE;
+                    break;
+                }
+            }
+        }
+
+        if (fp->fun) {
+            if (fp->fun->atom)
+                APPEND_STRING_TO_STACK(ATOM_TO_STRING(fp->fun->atom));
+
+            APPEND_CHAR_TO_STACK('(');
+            for (i = 0; i < fp->argc; i++) {
+                /* Avoid toSource bloat and fallibility for object types. */
+                v = fp->argv[i];
+                if (JSVAL_IS_PRIMITIVE(v)) {
+                    argsrc = js_ValueToSource(cx, v);
+                } else if (JSVAL_IS_FUNCTION(cx, v)) {
+                    /* XXX Avoid function decompilation bloat for now. */
+                    argsrc = JS_GetFunctionId(JS_ValueToFunction(cx, v));
+                    if (!argsrc)
+                        argsrc = js_ValueToSource(cx, v);
+                } else {
+                    /* XXX Avoid toString on objects, it takes too long and
+                           uses too much memory, for too many classes (see
+                           Mozilla bug 166743). */
+                    char buf[100];
+                    JS_snprintf(buf, sizeof buf, "[object %s]",
+                                OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v))->name);
+                    argsrc = JS_NewStringCopyZ(cx, buf);
+                }
+                if (!argsrc) {
+                    ok = JS_FALSE;
+                    goto done;
+                }
+                if (i > 0)
+                    APPEND_CHAR_TO_STACK(',');
+                APPEND_STRING_TO_STACK(argsrc);
+            }
+            APPEND_CHAR_TO_STACK(')');
+        }
+
+        APPEND_CHAR_TO_STACK('@');
+        if (fp->script && fp->script->filename) {
+            for (cp = fp->script->filename; *cp; cp++)
+                APPEND_CHAR_TO_STACK(*cp);
+        }
+        APPEND_CHAR_TO_STACK(':');
+        if (fp->script && fp->pc) {
+            ulineno = js_PCToLineNumber(cx, fp->script, fp->pc);
+            JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", ulineno);
+            for (cp = ulnbuf; *cp; cp++)
+                APPEND_CHAR_TO_STACK(*cp);
+        } else {
+            APPEND_CHAR_TO_STACK('0');
+        }
+        APPEND_CHAR_TO_STACK('\n');
+    }
+
+#undef APPEND_CHAR_TO_STACK
+#undef APPEND_STRING_TO_STACK
+
+done:
+    if (checkAccess) {
+        if (ok)
+            JS_RestoreExceptionState(cx, state);
+        else
+            JS_DropExceptionState(cx, state);
+        JS_SetErrorReporter(cx, older);
+    }
+    if (!ok) {
+        JS_free(cx, stackbuf);
+        return JS_FALSE;
+    }
+
+    if (!stackbuf) {
+        stack = cx->runtime->emptyString;
+    } else {
+        /* NB: if stackbuf was allocated, it has room for the terminator. */
+        JS_ASSERT(stacklen <= stackmax);
+        if (stacklen < stackmax) {
+            /*
+             * Realloc can fail when shrinking on some FreeBSD versions, so
+             * don't use JS_realloc here; simply let the oversized allocation
+             * be owned by the string in that rare case.
+             */
+            void *shrunk = realloc(stackbuf, (stacklen+1) * sizeof(jschar));
+            if (shrunk)
+                stackbuf = shrunk;
+        }
+        stackbuf[stacklen] = 0;
+        stack = js_NewString(cx, stackbuf, stacklen, 0);
+        if (!stack) {
+            JS_free(cx, stackbuf);
+            return JS_FALSE;
+        }
+    }
+    return JS_DefineProperty(cx, obj, js_stack_str,
+                             STRING_TO_JSVAL(stack),
+                             NULL, NULL, JSPROP_ENUMERATE);
+}
+
+/* XXXbe Consolidate the ugly truth that we don't treat filename as UTF-8
+         with these two functions. */
+static JSString *
+FilenameToString(JSContext *cx, const char *filename)
+{
+    return JS_NewStringCopyZ(cx, filename);
+}
+
+static const char *
+StringToFilename(JSContext *cx, JSString *str)
+{
+    return JS_GetStringBytes(str);
+}
+
+static JSBool
+Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSBool ok;
+    jsval pval;
+    uint32 lineno;
+    JSString *message, *filename;
+    JSStackFrame *fp;
+
+    if (cx->creatingException)
+        return JS_FALSE;
+    cx->creatingException = JS_TRUE;
+
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        /*
+         * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when
+         * called as functions, without operator new.  But as we do not give
+         * each constructor a distinct JSClass, whose .name member is used by
+         * js_NewObject to find the class prototype, we must get the class
+         * prototype ourselves.
+         */
+        ok = OBJ_GET_PROPERTY(cx, JSVAL_TO_OBJECT(argv[-2]),
+                              ATOM_TO_JSID(cx->runtime->atomState
+                                           .classPrototypeAtom),
+                              &pval);
+        if (!ok)
+            goto out;
+        obj = js_NewObject(cx, &ExceptionClass, JSVAL_TO_OBJECT(pval), NULL);
+        if (!obj) {
+            ok = JS_FALSE;
+            goto out;
+        }
+        *rval = OBJECT_TO_JSVAL(obj);
+    }
+
+    /*
+     * If it's a new object of class Exception, then null out the private
+     * data so that the finalizer doesn't attempt to free it.
+     */
+    if (OBJ_GET_CLASS(cx, obj) == &ExceptionClass)
+        OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, JSVAL_VOID);
+
+    /* Set the 'message' property. */
+    if (argc != 0) {
+        message = js_ValueToString(cx, argv[0]);
+        if (!message) {
+            ok = JS_FALSE;
+            goto out;
+        }
+        argv[0] = STRING_TO_JSVAL(message);
+    } else {
+        message = cx->runtime->emptyString;
+    }
+
+    /* Set the 'fileName' property. */
+    if (argc > 1) {
+        filename = js_ValueToString(cx, argv[1]);
+        if (!filename) {
+            ok = JS_FALSE;
+            goto out;
+        }
+        argv[1] = STRING_TO_JSVAL(filename);
+        fp = NULL;
+    } else {
+        fp = JS_GetScriptedCaller(cx, NULL);
+        if (fp) {
+            filename = FilenameToString(cx, fp->script->filename);
+            if (!filename) {
+                ok = JS_FALSE;
+                goto out;
+            }
+        } else {
+            filename = cx->runtime->emptyString;
+        }
+    }
+
+    /* Set the 'lineNumber' property. */
+    if (argc > 2) {
+        ok = js_ValueToECMAUint32(cx, argv[2], &lineno);
+        if (!ok)
+            goto out;
+    } else {
+        if (!fp)
+            fp = JS_GetScriptedCaller(cx, NULL);
+        lineno = (fp && fp->pc) ? js_PCToLineNumber(cx, fp->script, fp->pc) : 0;
+    }
+
+    ok = InitExceptionObject(cx, obj, message, filename, lineno);
+
+out:
+    cx->creatingException = JS_FALSE;
+    return ok;
+}
+
+/*
+ * Convert to string.
+ *
+ * This method only uses JavaScript-modifiable properties name, message.  It
+ * is left to the host to check for private data and report filename and line
+ * number information along with this message.
+ */
+static JSBool
+exn_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval v;
+    JSString *name, *message, *result;
+    jschar *chars, *cp;
+    size_t name_length, message_length, length;
+
+    if (!OBJ_GET_PROPERTY(cx, obj,
+                          ATOM_TO_JSID(cx->runtime->atomState.nameAtom),
+                          &v)) {
+        return JS_FALSE;
+    }
+    name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString;
+    *rval = STRING_TO_JSVAL(name);
+
+    if (!JS_GetProperty(cx, obj, js_message_str, &v))
+        return JS_FALSE;
+    message = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v)
+                                 : cx->runtime->emptyString;
+
+    if (JSSTRING_LENGTH(message) != 0) {
+        name_length = JSSTRING_LENGTH(name);
+        message_length = JSSTRING_LENGTH(message);
+        length = (name_length ? name_length + 2 : 0) + message_length;
+        cp = chars = (jschar*) JS_malloc(cx, (length + 1) * sizeof(jschar));
+        if (!chars)
+            return JS_FALSE;
+
+        if (name_length) {
+            js_strncpy(cp, JSSTRING_CHARS(name), name_length);
+            cp += name_length;
+            *cp++ = ':'; *cp++ = ' ';
+        }
+        js_strncpy(cp, JSSTRING_CHARS(message), message_length);
+        cp += message_length;
+        *cp = 0;
+
+        result = js_NewString(cx, chars, length, 0);
+        if (!result) {
+            JS_free(cx, chars);
+            return JS_FALSE;
+        }
+    } else {
+        result = name;
+    }
+
+    *rval = STRING_TO_JSVAL(result);
+    return JS_TRUE;
+}
+
+#if JS_HAS_TOSOURCE
+/*
+ * Return a string that may eval to something similar to the original object.
+ */
+static JSBool
+exn_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval *vp;
+    JSString *name, *message, *filename, *lineno_as_str, *result;
+    uint32 lineno;
+    size_t lineno_length, name_length, message_length, filename_length, length;
+    jschar *chars, *cp;
+
+    vp = argv + argc;   /* beginning of explicit local roots */
+
+    if (!OBJ_GET_PROPERTY(cx, obj,
+                          ATOM_TO_JSID(cx->runtime->atomState.nameAtom),
+                          rval)) {
+        return JS_FALSE;
+    }
+    name = js_ValueToString(cx, *rval);
+    if (!name)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(name);
+
+    if (!JS_GetProperty(cx, obj, js_message_str, &vp[0]) ||
+        !(message = js_ValueToSource(cx, vp[0]))) {
+        return JS_FALSE;
+    }
+    vp[0] = STRING_TO_JSVAL(message);
+
+    if (!JS_GetProperty(cx, obj, js_filename_str, &vp[1]) ||
+        !(filename = js_ValueToSource(cx, vp[1]))) {
+        return JS_FALSE;
+    }
+    vp[1] = STRING_TO_JSVAL(filename);
+
+    if (!JS_GetProperty(cx, obj, js_lineno_str, &vp[2]) ||
+        !js_ValueToECMAUint32 (cx, vp[2], &lineno)) {
+        return JS_FALSE;
+    }
+
+    if (lineno != 0) {
+        lineno_as_str = js_ValueToString(cx, vp[2]);
+        if (!lineno_as_str)
+            return JS_FALSE;
+        lineno_length = JSSTRING_LENGTH(lineno_as_str);
+    } else {
+        lineno_as_str = NULL;
+        lineno_length = 0;
+    }
+
+    /* Magic 8, for the characters in ``(new ())''. */
+    name_length = JSSTRING_LENGTH(name);
+    message_length = JSSTRING_LENGTH(message);
+    length = 8 + name_length + message_length;
+
+    filename_length = JSSTRING_LENGTH(filename);
+    if (filename_length != 0) {
+        /* append filename as ``, {filename}'' */
+        length += 2 + filename_length;
+        if (lineno_as_str) {
+            /* append lineno as ``, {lineno_as_str}'' */
+            length += 2 + lineno_length;
+        }
+    } else {
+        if (lineno_as_str) {
+            /*
+             * no filename, but have line number,
+             * need to append ``, "", {lineno_as_str}''
+             */
+            length += 6 + lineno_length;
+        }
+    }
+
+    cp = chars = (jschar*) JS_malloc(cx, (length + 1) * sizeof(jschar));
+    if (!chars)
+        return JS_FALSE;
+
+    *cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' ';
+    js_strncpy(cp, JSSTRING_CHARS(name), name_length);
+    cp += name_length;
+    *cp++ = '(';
+    if (message_length != 0) {
+        js_strncpy(cp, JSSTRING_CHARS(message), message_length);
+        cp += message_length;
+    }
+
+    if (filename_length != 0) {
+        /* append filename as ``, {filename}'' */
+        *cp++ = ','; *cp++ = ' ';
+        js_strncpy(cp, JSSTRING_CHARS(filename), filename_length);
+        cp += filename_length;
+    } else {
+        if (lineno_as_str) {
+            /*
+             * no filename, but have line number,
+             * need to append ``, "", {lineno_as_str}''
+             */
+            *cp++ = ','; *cp++ = ' '; *cp++ = '"'; *cp++ = '"';
+        }
+    }
+    if (lineno_as_str) {
+        /* append lineno as ``, {lineno_as_str}'' */
+        *cp++ = ','; *cp++ = ' ';
+        js_strncpy(cp, JSSTRING_CHARS(lineno_as_str), lineno_length);
+        cp += lineno_length;
+    }
+
+    *cp++ = ')'; *cp++ = ')'; *cp = 0;
+
+    result = js_NewString(cx, chars, length, 0);
+    if (!result) {
+        JS_free(cx, chars);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(result);
+    return JS_TRUE;
+}
+#endif
+
+static JSFunctionSpec exception_methods[] = {
+#if JS_HAS_TOSOURCE
+    {js_toSource_str,   exn_toSource,           0,0,3},
+#endif
+    {js_toString_str,   exn_toString,           0,0,0},
+    {0,0,0,0,0}
+};
+
+JSObject *
+js_InitExceptionClasses(JSContext *cx, JSObject *obj)
+{
+    int i;
+    JSObject *protos[JSEXN_LIMIT];
+
+    if (!js_EnterLocalRootScope(cx))
+        return NULL;
+
+    /* Initialize the prototypes first. */
+    for (i = 0; exceptions[i].name != 0; i++) {
+        JSAtom *atom;
+        JSFunction *fun;
+        JSString *nameString;
+        int protoIndex = exceptions[i].protoIndex;
+
+        /* Make the prototype for the current constructor name. */
+        protos[i] = js_NewObject(cx, &ExceptionClass,
+                                 (protoIndex != JSEXN_NONE)
+                                 ? protos[protoIndex]
+                                 : NULL,
+                                 obj);
+        if (!protos[i])
+            break;
+
+        /* So exn_finalize knows whether to destroy private data. */
+        OBJ_SET_SLOT(cx, protos[i], JSSLOT_PRIVATE, JSVAL_VOID);
+
+        atom = js_Atomize(cx, exceptions[i].name, strlen(exceptions[i].name), 0);
+        if (!atom)
+            break;
+
+        /* Make a constructor function for the current name. */
+        fun = js_DefineFunction(cx, obj, atom, exceptions[i].native, 3, 0);
+        if (!fun)
+            break;
+
+        /* Make this constructor make objects of class Exception. */
+        fun->clasp = &ExceptionClass;
+
+        /* Make the prototype and constructor links. */
+        if (!js_SetClassPrototype(cx, fun->object, protos[i],
+                                  JSPROP_READONLY | JSPROP_PERMANENT)) {
+            break;
+        }
+
+        /* proto bootstrap bit from JS_InitClass omitted. */
+        nameString = JS_NewStringCopyZ(cx, exceptions[i].name);
+        if (!nameString)
+            break;
+
+        /* Add the name property to the prototype. */
+        if (!JS_DefineProperty(cx, protos[i], js_name_str,
+                               STRING_TO_JSVAL(nameString),
+                               NULL, NULL,
+                               JSPROP_ENUMERATE)) {
+            break;
+        }
+    }
+
+    js_LeaveLocalRootScope(cx);
+    if (exceptions[i].name)
+        return NULL;
+
+    /*
+     * Add an empty message property.  (To Exception.prototype only,
+     * because this property will be the same for all the exception
+     * protos.)
+     */
+    if (!JS_DefineProperty(cx, protos[0], js_message_str,
+                           STRING_TO_JSVAL(cx->runtime->emptyString),
+                           NULL, NULL, JSPROP_ENUMERATE)) {
+        return NULL;
+    }
+    if (!JS_DefineProperty(cx, protos[0], js_filename_str,
+                           STRING_TO_JSVAL(cx->runtime->emptyString),
+                           NULL, NULL, JSPROP_ENUMERATE)) {
+        return NULL;
+    }
+    if (!JS_DefineProperty(cx, protos[0], js_lineno_str,
+                           INT_TO_JSVAL(0),
+                           NULL, NULL, JSPROP_ENUMERATE)) {
+        return NULL;
+    }
+
+    /*
+     * Add methods only to Exception.prototype, because ostensibly all
+     * exception types delegate to that.
+     */
+    if (!JS_DefineFunctions(cx, protos[0], exception_methods))
+        return NULL;
+
+    return protos[0];
+}
+
+const JSErrorFormatString* 
+js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale, const uintN errorNumber)
+{
+    const JSErrorFormatString *errorString = NULL;
+
+    if (cx->localeCallbacks && cx->localeCallbacks->localeGetErrorMessage) {
+        errorString = cx->localeCallbacks
+                        ->localeGetErrorMessage(userRef, locale, errorNumber);
+    }
+    if (!errorString)
+        errorString = js_GetErrorMessage(userRef, locale, errorNumber);
+    return errorString;
+}
+
+#if defined ( DEBUG_mccabe ) && defined ( PRINTNAMES )
+/* For use below... get character strings for error name and exception name */
+static struct exnname { char *name; char *exception; } errortoexnname[] = {
+#define MSG_DEF(name, number, count, exception, format) \
+    {#name, #exception},
+#include "js.msg"
+#undef MSG_DEF
+};
+#endif /* DEBUG */
+
+JSBool
+js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
+{
+    JSErrNum errorNumber;
+    JSExnType exn;
+    JSBool ok;
+    JSObject *errProto, *errObject;
+    JSString *messageStr, *filenameStr;
+    uintN lineno;
+    JSExnPrivate *privateData;
+    const JSErrorFormatString *errorString;
+
+    /*
+     * Tell our caller to report immediately if cx has no active frames, or if
+     * this report is just a warning.
+     */
+    JS_ASSERT(reportp);
+    if (!cx->fp || JSREPORT_IS_WARNING(reportp->flags))
+        return JS_FALSE;
+
+    /* Find the exception index associated with this error. */
+    errorNumber = (JSErrNum) reportp->errorNumber;
+    errorString = js_GetLocalizedErrorMessage(cx, NULL, NULL, errorNumber);
+    exn = errorString ? errorString->exnType : JSEXN_NONE;
+    JS_ASSERT(exn < JSEXN_LIMIT);
+
+#if defined( DEBUG_mccabe ) && defined ( PRINTNAMES )
+    /* Print the error name and the associated exception name to stderr */
+    fprintf(stderr, "%s\t%s\n",
+            errortoexnname[errorNumber].name,
+            errortoexnname[errorNumber].exception);
+#endif
+
+    /*
+     * Return false (no exception raised) if no exception is associated
+     * with the given error number.
+     */
+    if (exn == JSEXN_NONE)
+        return JS_FALSE;
+
+    /*
+     * Prevent runaway recursion, just as the Exception native constructor
+     * must do, via cx->creatingException.  If an out-of-memory error occurs,
+     * no exception object will be created, but we don't assume that OOM is
+     * the only kind of error that subroutines of this function called below
+     * might raise.
+     */
+    if (cx->creatingException)
+        return JS_FALSE;
+    cx->creatingException = JS_TRUE;
+
+    /* Protect the newly-created strings below from nesting GCs. */
+    ok = js_EnterLocalRootScope(cx);
+    if (!ok)
+        goto out;
+
+    /*
+     * Try to get an appropriate prototype by looking up the corresponding
+     * exception constructor name in the scope chain of the current context's
+     * top stack frame, or in the global object if no frame is active.
+     */
+    ok = js_GetClassPrototype(cx, exceptions[exn].name, &errProto);
+    if (!ok)
+        goto out;
+
+    errObject = js_NewObject(cx, &ExceptionClass, errProto, NULL);
+    if (!errObject) {
+        ok = JS_FALSE;
+        goto out;
+    }
+
+    /*
+     * Set the generated Exception object early, so it won't be GC'd by a last
+     * ditch attempt to collect garbage, or a GC that otherwise nests or races
+     * under any of the following calls.  If one of the following calls fails,
+     * it will overwrite this exception object with one of its own (except in
+     * case of OOM errors, of course).
+     */
+    JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject));
+
+    messageStr = JS_NewStringCopyZ(cx, message);
+    if (!messageStr) {
+        ok = JS_FALSE;
+        goto out;
+    }
+
+    if (reportp) {
+        filenameStr = JS_NewStringCopyZ(cx, reportp->filename);
+        if (!filenameStr) {
+            ok = JS_FALSE;
+            goto out;
+        }
+        lineno = reportp->lineno;
+    } else {
+        filenameStr = cx->runtime->emptyString;
+        lineno = 0;
+    }
+    ok = InitExceptionObject(cx, errObject, messageStr, filenameStr, lineno);
+    if (!ok)
+        goto out;
+
+    /*
+     * Construct a new copy of the error report struct, and store it in the
+     * exception object's private data.  We can't use the error report struct
+     * that was passed in, because it's stack-allocated, and also because it
+     * may point to transient data in the JSTokenStream.
+     */
+    privateData = exn_newPrivate(cx, reportp);
+    if (!privateData) {
+        ok = JS_FALSE;
+        goto out;
+    }
+    OBJ_SET_SLOT(cx, errObject, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(privateData));
+
+    /* Flag the error report passed in to indicate an exception was raised. */
+    reportp->flags |= JSREPORT_EXCEPTION;
+
+out:
+    js_LeaveLocalRootScope(cx);
+    cx->creatingException = JS_FALSE;
+    return ok;
+}
+#endif /* JS_HAS_ERROR_EXCEPTIONS */
+
+#if JS_HAS_EXCEPTIONS
+
+JSBool
+js_ReportUncaughtException(JSContext *cx)
+{
+    jsval exn, *vp;
+    JSObject *exnObject;
+    void *mark;
+    JSErrorReport *reportp, report;
+    JSString *str;
+    const char *bytes;
+    JSBool ok;
+
+    if (!JS_IsExceptionPending(cx))
+        return JS_TRUE;
+
+    if (!JS_GetPendingException(cx, &exn))
+        return JS_FALSE;
+
+    /*
+     * Because js_ValueToString below could error and an exception object
+     * could become unrooted, we must root exnObject.  Later, if exnObject is
+     * non-null, we need to root other intermediates, so allocate an operand
+     * stack segment to protect all of these values.
+     */
+    if (JSVAL_IS_PRIMITIVE(exn)) {
+        exnObject = NULL;
+        vp = NULL;
+#ifdef __GNUC__         /* suppress bogus gcc warnings */
+        mark = NULL;
+#endif
+    } else {
+        exnObject = JSVAL_TO_OBJECT(exn);
+        vp = js_AllocStack(cx, 5, &mark);
+        if (!vp) {
+            ok = JS_FALSE;
+            goto out;
+        }
+        vp[0] = exn;
+    }
+
+#if JS_HAS_ERROR_EXCEPTIONS
+    reportp = js_ErrorFromException(cx, exn);
+#else
+    reportp = NULL;
+#endif
+
+    /* XXX L10N angels cry once again (see also jsemit.c, /L10N gaffes/) */
+    str = js_ValueToString(cx, exn);
+    if (!str) {
+        bytes = "unknown (can't convert to string)";
+    } else {
+        if (vp)
+            vp[1] = STRING_TO_JSVAL(str);
+        bytes = js_GetStringBytes(str);
+    }
+    ok = JS_TRUE;
+
+    if (!reportp &&
+        exnObject &&
+        OBJ_GET_CLASS(cx, exnObject) == &ExceptionClass) {
+        const char *filename;
+        uint32 lineno;
+
+        ok = JS_GetProperty(cx, exnObject, js_message_str, &vp[2]);
+        if (!ok)
+            goto out;
+        if (JSVAL_IS_STRING(vp[2]))
+            bytes = JS_GetStringBytes(JSVAL_TO_STRING(vp[2]));
+
+        ok = JS_GetProperty(cx, exnObject, js_filename_str, &vp[3]);
+        if (!ok)
+            goto out;
+        str = js_ValueToString(cx, vp[3]);
+        if (!str) {
+            ok = JS_FALSE;
+            goto out;
+        }
+        filename = StringToFilename(cx, str);
+
+        ok = JS_GetProperty(cx, exnObject, js_lineno_str, &vp[4]);
+        if (!ok)
+            goto out;
+        ok = js_ValueToECMAUint32 (cx, vp[4], &lineno);
+        if (!ok)
+            goto out;
+
+        reportp = &report;
+        memset(&report, 0, sizeof report);
+        report.filename = filename;
+        report.lineno = (uintN) lineno;
+    }
+
+    if (!reportp) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_UNCAUGHT_EXCEPTION, bytes);
+    } else {
+        /* Flag the error as an exception. */
+        reportp->flags |= JSREPORT_EXCEPTION;
+        js_ReportErrorAgain(cx, bytes, reportp);
+    }
+
+    JS_ClearPendingException(cx);
+out:
+    if (exnObject)
+        js_FreeStack(cx, mark);
+    return ok;
+}
+
+#endif /* JS_HAS_EXCEPTIONS */

Added: freeswitch/trunk/libs/js/src/jsexn.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsexn.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,105 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS runtime exception classes.
+ */
+
+#ifndef jsexn_h___
+#define jsexn_h___
+
+JS_BEGIN_EXTERN_C
+
+/*
+ * Initialize the exception constructor/prototype hierarchy.
+ */
+extern JSObject *
+js_InitExceptionClasses(JSContext *cx, JSObject *obj);
+
+/*
+ * String constants naming the exception classes.
+ */
+extern const char js_Error_str[];
+extern const char js_InternalError_str[];
+extern const char js_EvalError_str[];
+extern const char js_RangeError_str[];
+extern const char js_ReferenceError_str[];
+extern const char js_SyntaxError_str[];
+extern const char js_TypeError_str[];
+extern const char js_URIError_str[];
+
+/*
+ * Given a JSErrorReport, check to see if there is an exception associated with
+ * the error number.  If there is, then create an appropriate exception object,
+ * set it as the pending exception, and set the JSREPORT_EXCEPTION flag on the
+ * error report.  Exception-aware host error reporters should probably ignore
+ * error reports so flagged.  Returns JS_TRUE if an associated exception is
+ * found and set, JS_FALSE otherwise..
+ */
+extern JSBool
+js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp);
+
+/*
+ * Called if a JS API call to js_Execute or js_InternalCall fails; calls the
+ * error reporter with the error report associated with any uncaught exception
+ * that has been raised.  Returns true if there was an exception pending, and
+ * the error reporter was actually called.
+ *
+ * The JSErrorReport * that the error reporter is called with is currently
+ * associated with a JavaScript object, and is not guaranteed to persist after
+ * the object is collected.  Any persistent uses of the JSErrorReport contents
+ * should make their own copy.
+ *
+ * The flags field of the JSErrorReport will have the JSREPORT_EXCEPTION flag
+ * set; embeddings that want to silently propagate JavaScript exceptions to
+ * other contexts may want to use an error reporter that ignores errors with
+ * this flag.
+ */
+extern JSBool
+js_ReportUncaughtException(JSContext *cx);
+
+extern JSErrorReport *
+js_ErrorFromException(JSContext *cx, jsval exn);
+
+extern const JSErrorFormatString* 
+js_GetLocalizedErrorMessage(JSContext* cx, void *userRef, const char *locale, const uintN errorNumber);
+
+JS_END_EXTERN_C
+
+#endif /* jsexn_h___ */

Added: freeswitch/trunk/libs/js/src/jsfile.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsfile.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3111 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS File object
+ */
+#if defined(JS_HAS_FILE_OBJECT) && (JS_HAS_FILE_OBJECT - 0) /* OSSP BUGFIX */
+
+#ifdef OSSP
+#include "../config.h"
+#endif
+
+#include "jsstddef.h"
+
+/* ----------------- Platform-specific includes and defines ----------------- */
+#if defined(XP_WIN) || defined(XP_OS2)
+#   include <direct.h>
+#ifdef OSSP
+#   include <dirent.h>
+#   include <fcntl.h>
+#   include <time.h>
+#endif
+#   include <io.h>
+#   include <sys/types.h>
+#   include <sys/stat.h>
+#   define FILESEPARATOR        '\\'
+#   define FILESEPARATOR2       '/'
+#   define CURRENT_DIR          "c:\\"
+#   define POPEN                _popen
+#   define PCLOSE               _pclose
+#ifdef OSSP
+#   undef mkdir
+#   define mkdir(file, mode)    _mkdir(file)
+#endif
+#elif defined(XP_UNIX) || defined(XP_BEOS)
+#   include <strings.h>
+#   include <stdio.h>
+#   include <stdlib.h>
+#   include <unistd.h>
+#ifdef OSSP
+#   include <sys/types.h>
+#   include <sys/stat.h>
+#   include <dirent.h>
+#   include <fcntl.h>
+#   include <time.h>
+#endif
+#   define FILESEPARATOR        '/'
+#   define FILESEPARATOR2       '\0'
+#   define CURRENT_DIR          "/"
+#   define POPEN                popen
+#   define PCLOSE               pclose
+#endif
+
+/* --------------- Platform-independent includes and defines ---------------- */
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsdate.h"
+#include "jsdbgapi.h"
+#include "jsemit.h"
+#include "jsfun.h"
+#include "jslock.h"
+#include "jsobj.h"
+#include "jsparse.h"
+#include "jsscan.h"
+#include "jsscope.h"
+#include "jsscript.h"
+#include "jsstr.h"
+#include "jsutil.h" /* Added by JSIFY */
+#ifdef OSSP /* CLEANUP */
+#include "jsfile.h"
+#endif
+#include <string.h>
+
+/* NSPR dependencies */
+#ifdef OSSP
+#define PR_RDONLY       0x01
+#define PR_WRONLY       0x02
+#define PR_RDWR         0x04
+#define PR_CREATE_FILE  0x08
+#define PR_APPEND       0x10
+#define PR_TRUNCATE     0x20
+#define PR_SYNC         0x40
+#define PR_EXCL         0x80
+#else
+#include "prio.h"
+#include "prerror.h"
+#endif
+
+#define SPECIAL_FILE_STRING     "Special File"
+#define CURRENTDIR_PROPERTY     "currentDir"
+#define SEPARATOR_PROPERTY      "separator"
+#define FILE_CONSTRUCTOR        "File"
+#define PIPE_SYMBOL             '|'
+
+#define ASCII                   0
+#define UTF8                    1
+#define UCS2                    2
+
+#define asciistring             "text"
+#define utfstring               "binary"
+#define unicodestring           "unicode"
+
+#define MAX_PATH_LENGTH         1024
+#define MODE_SIZE               256
+#define NUMBER_SIZE             32
+#define MAX_LINE_LENGTH         256
+#define URL_PREFIX              "file://"
+
+#define STDINPUT_NAME           "Standard input stream"
+#define STDOUTPUT_NAME          "Standard output stream"
+#define STDERROR_NAME           "Standard error stream"
+
+#define RESOLVE_PATH            js_canonicalPath        /* js_absolutePath */
+
+/* Error handling */
+typedef enum JSFileErrNum {
+#define MSG_DEF(name, number, count, exception, format) \
+    name = number,
+#include "jsfile.msg"
+#undef MSG_DEF
+    JSFileErr_Limit
+#undef MSGDEF
+} JSFileErrNum;
+
+#define JSFILE_HAS_DFLT_MSG_STRINGS 1
+
+JSErrorFormatString JSFile_ErrorFormatString[JSFileErr_Limit] = {
+#if JSFILE_HAS_DFLT_MSG_STRINGS
+#define MSG_DEF(name, number, count, exception, format) \
+    { format, count },
+#else
+#define MSG_DEF(name, number, count, exception, format) \
+    { NULL, count },
+#endif
+#include "jsfile.msg"
+#undef MSG_DEF
+};
+
+#ifdef OSSP
+static
+#endif
+const JSErrorFormatString *
+JSFile_GetErrorMessage(void *userRef, const char *locale,
+                                                        const uintN errorNumber)
+{
+    if ((errorNumber > 0) && (errorNumber < JSFileErr_Limit))
+        return &JSFile_ErrorFormatString[errorNumber];
+    else
+        return NULL;
+}
+
+#define JSFILE_CHECK_NATIVE(op)                                               \
+    if (file->isNative) {                                                     \
+        JS_ReportWarning(cx, "Cannot call or access \"%s\" on native file %s",\
+                         op, file->path);                                     \
+        goto out;                                                             \
+    }
+
+#define JSFILE_CHECK_WRITE                                                    \
+    if (!file->isOpen) {                                                      \
+        JS_ReportWarning(cx,                                                  \
+                "File %s is closed, will open it for writing, proceeding",    \
+                file->path);                                                  \
+        js_FileOpen(cx, obj, file, "write,append,create");                    \
+    }                                                                         \
+    if (!js_canWrite(cx, file)) {                                             \
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,                \
+                             JSFILEMSG_CANNOT_WRITE, file->path);             \
+        goto out;                                                             \
+    }
+
+#define JSFILE_CHECK_READ                                                     \
+    if (!file->isOpen) {                                                      \
+        JS_ReportWarning(cx,                                                  \
+                "File %s is closed, will open it for reading, proceeding",    \
+                file->path);                                                  \
+        js_FileOpen(cx, obj, file, "read");                                   \
+    }                                                                         \
+    if (!js_canRead(cx, file)) {                                              \
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,                \
+                             JSFILEMSG_CANNOT_READ, file->path);              \
+        goto out;                                                             \
+    }
+
+#define JSFILE_CHECK_OPEN(op)                                                 \
+    if (!file->isOpen) {                                                      \
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,                \
+                             JSFILEMSG_FILE_MUST_BE_CLOSED, op);              \
+        goto out;                                                             \
+    }
+
+#define JSFILE_CHECK_CLOSED(op)                                               \
+    if (file->isOpen) {                                                       \
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,                \
+            JSFILEMSG_FILE_MUST_BE_OPEN, op);                                 \
+        goto out;                                                             \
+    }
+
+#define JSFILE_CHECK_ONE_ARG(op)                                              \
+    if (argc != 1) {                                                          \
+        char str[NUMBER_SIZE];                                                \
+        sprintf(str, "%d", argc);                                             \
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,                \
+                             JSFILEMSG_EXPECTS_ONE_ARG_ERROR, op, str);       \
+        goto out;                                                             \
+    }
+
+
+/*
+    Security mechanism, should define a callback for this.
+    The parameters are as follows:
+    SECURITY_CHECK(JSContext *cx, JSPrincipals *ps, char *op_name, JSFile *file)
+    XXX Should this be a real function returning a JSBool result (and getting
+    some typesafety help from the compiler?).
+*/
+#define SECURITY_CHECK(cx, ps, op, file)    \
+        /* Define a callback here... */
+
+
+/* Structure representing the file internally */
+typedef struct JSFile {
+    char        *path;          /* the path to the file. */
+    JSBool      isOpen;
+    int32       mode;           /* mode used to open the file: read, write, append, create, etc.. */
+    int32       type;           /* Asciiz, utf, unicode */
+    char        byteBuffer[3];  /* bytes read in advance by js_FileRead ( UTF8 encoding ) */
+    jsint       nbBytesInBuf;   /* number of bytes stored in the buffer above */
+    jschar      charBuffer;     /* character read in advance by readln ( mac files only ) */
+    JSBool      charBufferUsed; /* flag indicating if the buffer above is being used */
+    JSBool      hasRandomAccess;/* can the file be randomly accessed? false for stdin, and
+                                 UTF-encoded files. */
+    JSBool      hasAutoflush;   /* should we force a flush for each line break? */
+    JSBool      isNative;       /* if the file is using OS-specific file FILE type */
+    /* We can actually put the following two in a union since they should never be used at the same time */
+#ifdef OSSP
+    FILE        *handle;        /* the handle for the file, if open.  */
+#else
+    PRFileDesc  *handle;        /* the handle for the file, if open.  */
+#endif
+    FILE        *nativehandle;  /* native handle, for stuff NSPR doesn't do. */
+    JSBool      isPipe;         /* if the file is really an OS pipe */
+} JSFile;
+
+/* a few forward declarations... */
+static JSClass file_class;
+JS_PUBLIC_API(JSObject*) js_NewFileObject(JSContext *cx, char *filename);
+static JSBool file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
+static JSBool file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
+
+/* New filename manipulation procesures */
+/* assumes we don't have leading/trailing spaces */
+static JSBool
+js_filenameHasAPipe(const char *filename)
+{
+    if (!filename)
+        return JS_FALSE;
+
+    return  filename[0] == PIPE_SYMBOL ||
+            filename[strlen(filename) - 1] == PIPE_SYMBOL;
+}
+
+static JSBool
+js_isAbsolute(const char *name)
+{
+#if defined(XP_WIN) || defined(XP_OS2)
+    return *name && name[1] == ':';
+#else
+    return (name[0]
+#   if defined(XP_UNIX) || defined(XP_BEOS)
+            ==
+#   else
+            !=
+#   endif
+            FILESEPARATOR);
+#endif
+}
+
+/*
+ * Concatinates base and name to produce a valid filename.
+ * Returned string must be freed.
+*/
+static char*
+js_combinePath(JSContext *cx, const char *base, const char *name)
+{
+    int len = strlen(base);
+    char* result = JS_malloc(cx, len + strlen(name) + 2);
+
+    if (!result)
+        return NULL;
+
+    strcpy(result, base);
+
+    if (base[len - 1] != FILESEPARATOR && base[len - 1] != FILESEPARATOR2) {
+        result[len] = FILESEPARATOR;
+        result[len + 1] = '\0';
+    }
+    strcat(result, name);
+    return result;
+}
+
+/* Extract the last component from a path name. Returned string must be freed */
+static char *
+js_fileBaseName(JSContext *cx, const char *pathname)
+{
+    jsint index, aux;
+    char *result;
+
+    index = strlen(pathname)-1;
+
+    /* Chop off trailing seperators. */
+    while (index > 0 && (pathname[index]==FILESEPARATOR ||
+                         pathname[index]==FILESEPARATOR2)) {
+        --index;
+    }
+
+    aux = index;
+
+    /* Now find the next separator. */
+    while (index >= 0 && pathname[index] != FILESEPARATOR &&
+                         pathname[index] != FILESEPARATOR2) {
+        --index;
+    }
+
+    /* Allocate and copy. */
+    result = JS_malloc(cx, aux - index + 1);
+    if (!result)
+        return NULL;
+    strncpy(result, pathname + index + 1, aux - index);
+    result[aux - index] = '\0';
+    return result;
+}
+
+/*
+ * Returns everything but the last component from a path name.
+ * Returned string must be freed.
+ */
+static char *
+js_fileDirectoryName(JSContext *cx, const char *pathname)
+{
+    char *result;
+    const char *cp, *end;
+    size_t pathsize;
+
+    end = pathname + strlen(pathname);
+    cp = end - 1;
+
+    /* If this is already a directory, chop off the trailing /s. */
+    while (cp >= pathname) {
+        if (*cp != FILESEPARATOR && *cp != FILESEPARATOR2)
+            break;
+        --cp;
+    }
+
+    if (cp < pathname && end != pathname) {
+        /* There were just /s, return the root. */
+        result = JS_malloc(cx, 1 + 1); /* The separator + trailing NUL. */
+        result[0] = FILESEPARATOR;
+        result[1] = '\0';
+        return result;
+    }
+
+    /* Now chop off the last portion. */
+    while (cp >= pathname) {
+        if (*cp == FILESEPARATOR || *cp == FILESEPARATOR2)
+            break;
+        --cp;
+    }
+
+    /* Check if this is a leaf. */
+    if (cp < pathname) {
+        /* It is, return "pathname/". */
+        if (end[-1] == FILESEPARATOR || end[-1] == FILESEPARATOR2) {
+            /* Already has its terminating /. */
+            return JS_strdup(cx, pathname);
+        }
+
+        pathsize = end - pathname + 1;
+        result = JS_malloc(cx, pathsize + 1);
+        if (!result)
+            return NULL;
+
+        strcpy(result, pathname);
+        result[pathsize - 1] = FILESEPARATOR;
+        result[pathsize] = '\0';
+
+        return result;
+    }
+
+    /* Return everything up to and including the seperator. */
+    pathsize = cp - pathname + 1;
+    result = JS_malloc(cx, pathsize + 1);
+    if (!result)
+        return NULL;
+
+    strncpy(result, pathname, pathsize);
+    result[pathsize] = '\0';
+
+    return result;
+}
+
+static char *
+js_absolutePath(JSContext *cx, const char * path)
+{
+    JSObject *obj;
+    JSString *str;
+    jsval prop;
+
+    if (js_isAbsolute(path)) {
+        return JS_strdup(cx, path);
+    } else {
+        obj = JS_GetGlobalObject(cx);
+        if (!JS_GetProperty(cx, obj, FILE_CONSTRUCTOR, &prop)) {
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                 JSFILEMSG_FILE_CONSTRUCTOR_UNDEFINED_ERROR);
+            return JS_strdup(cx, path);
+        }
+
+        obj = JSVAL_TO_OBJECT(prop);
+        if (!JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, &prop)) {
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                 JSFILEMSG_FILE_CURRENTDIR_UNDEFINED_ERROR);
+            return JS_strdup(cx, path);
+        }
+
+        str = JS_ValueToString(cx, prop);
+        if (!str)
+            return JS_strdup(cx, path);
+
+        /* should we have an array of curr dirs indexed by drive for windows? */
+        return js_combinePath(cx, JS_GetStringBytes(str), path);
+    }
+}
+
+/* Side effect: will remove spaces in the beginning/end of the filename */
+static char *
+js_canonicalPath(JSContext *cx, char *oldpath)
+{
+    char *tmp;
+    char *path = oldpath;
+    char *base, *dir, *current, *result;
+    jsint c;
+    jsint back = 0;
+    unsigned int i = 0, j = strlen(path)-1;
+
+    /* This is probably optional */
+	/* Remove possible spaces in the beginning and end */
+    while (i < j && path[i] == ' ')
+        i++;
+    while (j >= 0 && path[j] == ' ')
+        j--;
+
+    tmp = JS_malloc(cx, j-i+2);
+    if (!tmp)
+        return NULL;
+
+    strncpy(tmp, path + i, j - i + 1);
+    tmp[j - i + 1] = '\0';
+
+    path = tmp;
+
+    /* Pipe support. */
+    if (js_filenameHasAPipe(path))
+        return path;
+
+    /* file:// support. */
+    if (!strncmp(path, URL_PREFIX, strlen(URL_PREFIX))) {
+        tmp = js_canonicalPath(cx, path + strlen(URL_PREFIX));
+        JS_free(cx, path);
+        return tmp;
+    }
+
+    if (!js_isAbsolute(path)) {
+        tmp = js_absolutePath(cx, path);
+        if (!tmp)
+            return NULL;
+        path = tmp;
+    }
+
+    result = JS_strdup(cx, "");
+
+    current = path;
+
+    base = js_fileBaseName(cx, current);
+    dir = js_fileDirectoryName(cx, current);
+
+    while (strcmp(dir, current)) {
+        if (!strcmp(base, "..")) {
+            back++;
+        } else {
+            if (back > 0) {
+                back--;
+            } else {
+                tmp = result;
+                result = JS_malloc(cx, strlen(base) + 1 + strlen(tmp) + 1);
+                if (!result)
+                    goto out;
+
+                strcpy(result, base);
+                c = strlen(result);
+                if (*tmp) {
+                    result[c] = FILESEPARATOR;
+                    result[c + 1] = '\0';
+                    strcat(result, tmp);
+                }
+                JS_free(cx, tmp);
+            }
+        }
+        JS_free(cx, current);
+        JS_free(cx, base);
+        current = dir;
+        base =  js_fileBaseName(cx, current);
+        dir = js_fileDirectoryName(cx, current);
+    }
+
+    tmp = result;
+    result = JS_malloc(cx, strlen(dir)+1+strlen(tmp)+1);
+    if (!result)
+        goto out;
+
+    strcpy(result, dir);
+    c = strlen(result);
+    if (tmp[0]!='\0') {
+        if ((result[c-1]!=FILESEPARATOR)&&(result[c-1]!=FILESEPARATOR2)) {
+            result[c] = FILESEPARATOR;
+            result[c+1] = '\0';
+        }
+        strcat(result, tmp);
+    }
+
+out:
+    if (tmp)
+        JS_free(cx, tmp);
+    if (dir)
+        JS_free(cx, dir);
+    if (base)
+        JS_free(cx, base);
+    if (current)
+        JS_free(cx, current);
+
+    return result;
+}
+
+/* -------------------------- Text conversion ------------------------------- */
+/* The following is ripped from libi18n/unicvt.c and include files.. */
+
+/*
+ * UTF8 defines and macros
+ */
+#define ONE_OCTET_BASE          0x00    /* 0xxxxxxx */
+#define ONE_OCTET_MASK          0x7F    /* x1111111 */
+#define CONTINUING_OCTET_BASE   0x80    /* 10xxxxxx */
+#define CONTINUING_OCTET_MASK   0x3F    /* 00111111 */
+#define TWO_OCTET_BASE          0xC0    /* 110xxxxx */
+#define TWO_OCTET_MASK          0x1F    /* 00011111 */
+#define THREE_OCTET_BASE        0xE0    /* 1110xxxx */
+#define THREE_OCTET_MASK        0x0F    /* 00001111 */
+#define FOUR_OCTET_BASE         0xF0    /* 11110xxx */
+#define FOUR_OCTET_MASK         0x07    /* 00000111 */
+#define FIVE_OCTET_BASE         0xF8    /* 111110xx */
+#define FIVE_OCTET_MASK         0x03    /* 00000011 */
+#define SIX_OCTET_BASE          0xFC    /* 1111110x */
+#define SIX_OCTET_MASK          0x01    /* 00000001 */
+
+#define IS_UTF8_1ST_OF_1(x) (( (x)&~ONE_OCTET_MASK  ) == ONE_OCTET_BASE)
+#define IS_UTF8_1ST_OF_2(x) (( (x)&~TWO_OCTET_MASK  ) == TWO_OCTET_BASE)
+#define IS_UTF8_1ST_OF_3(x) (( (x)&~THREE_OCTET_MASK) == THREE_OCTET_BASE)
+#define IS_UTF8_1ST_OF_4(x) (( (x)&~FOUR_OCTET_MASK ) == FOUR_OCTET_BASE)
+#define IS_UTF8_1ST_OF_5(x) (( (x)&~FIVE_OCTET_MASK ) == FIVE_OCTET_BASE)
+#define IS_UTF8_1ST_OF_6(x) (( (x)&~SIX_OCTET_MASK  ) == SIX_OCTET_BASE)
+#define IS_UTF8_2ND_THRU_6TH(x) \
+                    (( (x)&~CONTINUING_OCTET_MASK  ) == CONTINUING_OCTET_BASE)
+#define IS_UTF8_1ST_OF_UCS2(x) \
+            IS_UTF8_1ST_OF_1(x) \
+            || IS_UTF8_1ST_OF_2(x) \
+            || IS_UTF8_1ST_OF_3(x)
+
+
+#define MAX_UCS2            0xFFFF
+#define DEFAULT_CHAR        0x003F  /* Default char is "?" */
+#define BYTE_MASK           0xBF
+#define BYTE_MARK           0x80
+
+
+/* Function: one_ucs2_to_utf8_char
+ *
+ * Function takes one UCS-2 char and writes it to a UTF-8 buffer.
+ * We need a UTF-8 buffer because we don't know before this
+ * function how many bytes of utf-8 data will be written. It also
+ * takes a pointer to the end of the UTF-8 buffer so that we don't
+ * overwrite data. This function returns the number of UTF-8 bytes
+ * of data written, or -1 if the buffer would have been overrun.
+ */
+
+#define LINE_SEPARATOR      0x2028
+#define PARAGRAPH_SEPARATOR 0x2029
+static int16 one_ucs2_to_utf8_char(unsigned char *tobufp,
+                                   unsigned char *tobufendp,
+                                   uint16 onechar)
+{
+    int16 numUTF8bytes = 0;
+
+    if (onechar == LINE_SEPARATOR || onechar == PARAGRAPH_SEPARATOR) {
+        strcpy((char*)tobufp, "\n");
+        return strlen((char*)tobufp);
+    }
+
+    if (onechar < 0x80) {
+        numUTF8bytes = 1;
+    } else if (onechar < 0x800) {
+        numUTF8bytes = 2;
+    } else {
+        /* 0x800 >= onechar <= MAX_UCS2 */
+        numUTF8bytes = 3;
+    }
+
+    tobufp += numUTF8bytes;
+
+    /* return error if we don't have space for the whole character */
+    if (tobufp > tobufendp) {
+        return(-1);
+    }
+
+    switch(numUTF8bytes) {
+      case 3: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
+              *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
+              *--tobufp = onechar |  THREE_OCTET_BASE;
+              break;
+
+      case 2: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6;
+              *--tobufp = onechar | TWO_OCTET_BASE;
+              break;
+
+      case 1: *--tobufp = (unsigned char)onechar;
+              break;
+    }
+
+    return numUTF8bytes;
+}
+
+/*
+ * utf8_to_ucs2_char
+ *
+ * Convert a utf8 multibyte character to ucs2
+ *
+ * inputs: pointer to utf8 character(s)
+ *         length of utf8 buffer ("read" length limit)
+ *         pointer to return ucs2 character
+ *
+ * outputs: number of bytes in the utf8 character
+ *          -1 if not a valid utf8 character sequence
+ *          -2 if the buffer is too short
+ */
+static int16
+utf8_to_ucs2_char(const unsigned char *utf8p, int16 buflen, uint16 *ucs2p)
+{
+    uint16 lead, cont1, cont2;
+
+    /*
+     * Check for minimum buffer length
+     */
+    if ((buflen < 1) || (utf8p == NULL)) {
+        return -2;
+    }
+    lead = (uint16) (*utf8p);
+
+    /*
+     * Check for a one octet sequence
+     */
+    if (IS_UTF8_1ST_OF_1(lead)) {
+        *ucs2p = lead & ONE_OCTET_MASK;
+        return 1;
+    }
+
+    /*
+     * Check for a two octet sequence
+     */
+    if (IS_UTF8_1ST_OF_2(*utf8p)) {
+        if (buflen < 2)
+            return -2;
+        cont1 = (uint16) *(utf8p+1);
+        if (!IS_UTF8_2ND_THRU_6TH(cont1))
+            return -1;
+        *ucs2p =  (lead & TWO_OCTET_MASK) << 6;
+        *ucs2p |= cont1 & CONTINUING_OCTET_MASK;
+        return 2;
+    }
+
+    /*
+     * Check for a three octet sequence
+     */
+    else if (IS_UTF8_1ST_OF_3(lead)) {
+        if (buflen < 3)
+            return -2;
+        cont1 = (uint16) *(utf8p+1);
+        cont2 = (uint16) *(utf8p+2);
+        if (   (!IS_UTF8_2ND_THRU_6TH(cont1))
+            || (!IS_UTF8_2ND_THRU_6TH(cont2)))
+            return -1;
+        *ucs2p =  (lead & THREE_OCTET_MASK) << 12;
+        *ucs2p |= (cont1 & CONTINUING_OCTET_MASK) << 6;
+        *ucs2p |= cont2 & CONTINUING_OCTET_MASK;
+        return 3;
+    }
+    else { /* not a valid utf8/ucs2 character */
+        return -1;
+    }
+}
+
+/* ----------------------------- Helper functions --------------------------- */
+/* Ripped off from lm_win.c .. */
+/* where is strcasecmp?.. for now, it's case sensitive..
+ *
+ * strcasecmp is in strings.h, but on windows it's called _stricmp...
+ * will need to #ifdef this
+*/
+
+static int32
+js_FileHasOption(JSContext *cx, const char *oldoptions, const char *name)
+{
+    char *comma, *equal, *current;
+    char *options = JS_strdup(cx, oldoptions);
+    int32 found = 0;
+
+    current = options;
+    for (;;) {
+        comma = strchr(current, ',');
+        if (comma) *comma = '\0';
+        equal = strchr(current, '=');
+        if (equal) *equal = '\0';
+        if (strcmp(current, name) == 0) {
+            if (!equal || strcmp(equal + 1, "yes") == 0)
+                found = 1;
+            else
+                found = atoi(equal + 1);
+        }
+        if (equal) *equal = '=';
+        if (comma) *comma = ',';
+        if (found || !comma)
+            break;
+        current = comma + 1;
+    }
+    JS_free(cx, options);
+    return found;
+}
+
+/* empty the buffer */
+static void
+js_ResetBuffers(JSFile * file)
+{
+    file->charBufferUsed = JS_FALSE;
+    file->nbBytesInBuf = 0;
+}
+
+/* Reset file attributes */
+static void
+js_ResetAttributes(JSFile * file)
+{
+    file->mode = file->type = 0;
+    file->isOpen = JS_FALSE;
+    file->handle = NULL;
+    file->nativehandle = NULL;
+    file->hasRandomAccess = JS_TRUE; /* Innocent until proven guilty. */
+    file->hasAutoflush = JS_FALSE;
+    file->isNative = JS_FALSE;
+    file->isPipe = JS_FALSE;
+
+    js_ResetBuffers(file);
+}
+
+static JSBool
+js_FileOpen(JSContext *cx, JSObject *obj, JSFile *file, char *mode){
+    JSString *type, *mask;
+    jsval v[2];
+    jsval rval;
+
+    type =  JS_InternString(cx, asciistring);
+    mask =  JS_NewStringCopyZ(cx, mode);
+    v[0] = STRING_TO_JSVAL(mask);
+    v[1] = STRING_TO_JSVAL(type);
+
+    if (!file_open(cx, obj, 2, v, &rval))
+        return JS_FALSE;
+    return JS_TRUE;
+}
+
+/* Buffered version of PR_Read. Used by js_FileRead */
+static int32
+#ifdef OSSP
+js_BufferedRead(JSFile * f, unsigned char *buf, int32 len)
+#else
+js_BufferedRead(JSFile * f, char *buf, int32 len)
+#endif
+{
+    int32 count = 0;
+
+    while (f->nbBytesInBuf>0&&len>0) {
+        buf[0] = f->byteBuffer[0];
+        f->byteBuffer[0] = f->byteBuffer[1];
+        f->byteBuffer[1] = f->byteBuffer[2];
+        f->nbBytesInBuf--;
+        len--;
+        buf+=1;
+        count++;
+    }
+
+    if (len>0) {
+#ifdef OSSP
+        count += (!f->isNative)
+                 ? fread(buf, 1, len, f->handle)
+                 : fread(buf, 1, len, f->nativehandle);
+#else
+        count += (!f->isNative)
+                 ? PR_Read(f->handle, buf, len)
+                 : fread(buf, 1, len, f->nativehandle);
+#endif
+    }
+    return count;
+}
+
+static int32
+js_FileRead(JSContext *cx, JSFile *file, jschar *buf, int32 len, int32 mode)
+{
+    unsigned char *aux;
+    int32 count = 0, i;
+    jsint remainder;
+    unsigned char utfbuf[3];
+
+    if (file->charBufferUsed) {
+        buf[0] = file->charBuffer;
+        buf++;
+        len--;
+        file->charBufferUsed = JS_FALSE;
+    }
+
+    switch (mode) {
+      case ASCII:
+        aux = (unsigned char*)JS_malloc(cx, len);
+        if (!aux)
+            return 0;
+
+        count = js_BufferedRead(file, aux, len);
+        if (count == -1) {
+            JS_free(cx, aux);
+            return 0;
+        }
+
+        for (i = 0; i < len; i++)
+            buf[i] = (jschar)aux[i];
+
+        JS_free(cx, aux);
+        break;
+
+      case UTF8:
+        remainder = 0;
+        for (count = 0;count<len;count++) {
+            i = js_BufferedRead(file, utfbuf+remainder, 3-remainder);
+            if (i<=0) {
+                return count;
+            }
+            i = utf8_to_ucs2_char(utfbuf, (int16)i, &buf[count] );
+            if (i<0) {
+                return count;
+            } else {
+                if (i==1) {
+                    utfbuf[0] = utfbuf[1];
+                    utfbuf[1] = utfbuf[2];
+                    remainder = 2;
+                } else if (i==2) {
+                    utfbuf[0] = utfbuf[2];
+                    remainder = 1;
+                } else if (i==3) {
+                    remainder = 0;
+                }
+            }
+        }
+        while (remainder>0) {
+            file->byteBuffer[file->nbBytesInBuf] = utfbuf[0];
+            file->nbBytesInBuf++;
+            utfbuf[0] = utfbuf[1];
+            utfbuf[1] = utfbuf[2];
+            remainder--;
+        }
+        break;
+
+      case UCS2:
+#ifdef OSSP
+        count = js_BufferedRead(file, (unsigned char*)buf, len*2) >> 1;
+#else
+        count = js_BufferedRead(file, (char*)buf, len*2) >> 1;
+#endif
+        if (count == -1)
+            return 0;
+
+        break;
+
+      default:
+        /* Not reached. */
+        JS_ASSERT(0);
+    }
+
+    if(count == -1) {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                             JSFILEMSG_OP_FAILED, "read", file->path);
+    }
+
+    return count;
+}
+
+static int32
+js_FileSeek(JSContext *cx, JSFile *file, int32 len, int32 mode)
+{
+    int32 count = 0, i;
+    jsint remainder;
+    unsigned char utfbuf[3];
+    jschar tmp;
+
+    switch (mode) {
+      case ASCII:
+#ifdef OSSP
+        count = fseek(file->handle, len, SEEK_CUR);
+#else
+        count = PR_Seek(file->handle, len, PR_SEEK_CUR);
+#endif
+        break;
+
+      case UTF8:
+        remainder = 0;
+        for (count = 0;count<len;count++) {
+            i = js_BufferedRead(file, utfbuf+remainder, 3-remainder);
+            if (i<=0) {
+                return 0;
+            }
+            i = utf8_to_ucs2_char(utfbuf, (int16)i, &tmp );
+            if (i<0) {
+                return 0;
+            } else {
+                if (i==1) {
+                    utfbuf[0] = utfbuf[1];
+                    utfbuf[1] = utfbuf[2];
+                    remainder = 2;
+                } else if (i==2) {
+                    utfbuf[0] = utfbuf[2];
+                    remainder = 1;
+                } else if (i==3) {
+                    remainder = 0;
+                }
+            }
+        }
+        while (remainder>0) {
+            file->byteBuffer[file->nbBytesInBuf] = utfbuf[0];
+            file->nbBytesInBuf++;
+            utfbuf[0] = utfbuf[1];
+            utfbuf[1] = utfbuf[2];
+            remainder--;
+        }
+        break;
+
+      case UCS2:
+#ifdef OSSP
+        count = fseek(file->handle, len*2, SEEK_CUR)/2;
+#else
+        count = PR_Seek(file->handle, len*2, PR_SEEK_CUR)/2;
+#endif
+        break;
+
+      default:
+        /* Not reached. */
+        JS_ASSERT(0);
+    }
+
+    if(count == -1) {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                             JSFILEMSG_OP_FAILED, "seek", file->path);
+    }
+
+    return count;
+}
+
+static int32
+js_FileWrite(JSContext *cx, JSFile *file, jschar *buf, int32 len, int32 mode)
+{
+    unsigned char   *aux;
+    int32           count = 0, i, j;
+    unsigned char   *utfbuf;
+
+    switch (mode) {
+      case ASCII:
+        aux = (unsigned char*)JS_malloc(cx, len);
+        if (!aux)
+            return 0;
+
+        for (i = 0; i<len; i++)
+            aux[i] = buf[i] % 256;
+
+#ifdef OSSP
+        count = (!file->isNative)
+                ? fwrite(aux, 1, len, file->handle)
+                : fwrite(aux, 1, len, file->nativehandle);
+#else
+        count = (!file->isNative)
+                ? PR_Write(file->handle, aux, len)
+                : fwrite(aux, 1, len, file->nativehandle);
+#endif
+
+        if (count==-1) {
+            JS_free(cx, aux);
+            return 0;
+        }
+
+        JS_free(cx, aux);
+        break;
+
+      case UTF8:
+        utfbuf = (unsigned char*)JS_malloc(cx, len*3);
+        if (!utfbuf)  return 0;
+        i = 0;
+        for (count = 0;count<len;count++) {
+            j = one_ucs2_to_utf8_char(utfbuf+i, utfbuf+len*3, buf[count]);
+            if (j==-1) {
+                JS_free(cx, utfbuf);
+                return 0;
+            }
+            i+=j;
+        }
+#ifdef OSSP
+        j = (!file->isNative) 
+            ? fwrite(utfbuf, 1, i, file->handle)
+            : fwrite(utfbuf, 1, i, file->nativehandle);
+#else
+        j = (!file->isNative) 
+            ? PR_Write(file->handle, utfbuf, i)
+            : fwrite(utfbuf, 1, i, file->nativehandle);
+#endif
+
+        if (j<i) {
+            JS_free(cx, utfbuf);
+            return 0;
+        }
+        JS_free(cx, utfbuf);
+        break;
+
+      case UCS2:
+#ifdef OSSP
+        count = (!file->isNative) 
+                ? fwrite(buf, 1, len*2, file->handle) >> 1
+                : fwrite(buf, 1, len*2, file->nativehandle) >> 1;
+#else
+        count = (!file->isNative) 
+                ? PR_Write(file->handle, buf, len*2) >> 1
+                : fwrite(buf, 1, len*2, file->nativehandle) >> 1;
+#endif
+
+        if (count == -1)
+            return 0;
+        break;
+
+      default:
+        /* Not reached. */
+        JS_ASSERT(0);
+    }
+
+    if(count == -1) {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                             JSFILEMSG_OP_FAILED, "write", file->path);
+    }
+
+    return count;
+}
+
+/* ----------------------------- Property checkers -------------------------- */
+static JSBool
+js_exists(JSContext *cx, JSFile *file)
+{
+    if (file->isNative) {
+        /* It doesn't make sense for a pipe of stdstream. */
+        return JS_FALSE;
+    }
+
+#ifdef OSSP
+    return access(file->path, F_OK) == 0;
+#else
+    return PR_Access(file->path, PR_ACCESS_EXISTS) == PR_SUCCESS;
+#endif
+}
+
+static JSBool
+js_canRead(JSContext *cx, JSFile *file)
+{
+    if (!file->isNative) {
+        if (file->isOpen && !(file->mode & PR_RDONLY))
+            return JS_FALSE;
+#ifdef OSSP
+        return access(file->path, R_OK) == 0;
+#else
+        return PR_Access(file->path, PR_ACCESS_READ_OK) == PR_SUCCESS;
+#endif
+    }
+
+    if (file->isPipe) {
+        /* Is this pipe open for reading? */
+        return file->path[0] == PIPE_SYMBOL;
+    }
+
+    return !strcmp(file->path, STDINPUT_NAME);
+}
+
+static JSBool
+js_canWrite(JSContext *cx, JSFile *file)
+{
+    if (!file->isNative) {
+        if (file->isOpen && !(file->mode & PR_WRONLY))
+            return JS_FALSE;
+#ifdef OSSP
+        return access(file->path, W_OK) == 0;
+#else
+        return PR_Access(file->path, PR_ACCESS_WRITE_OK) == PR_SUCCESS;
+#endif
+    }
+
+    if(file->isPipe) {
+        /* Is this pipe open for writing? */
+        return file->path[strlen(file->path)-1] == PIPE_SYMBOL;
+    }
+
+    return !strcmp(file->path, STDOUTPUT_NAME) ||
+           !strcmp(file->path, STDERROR_NAME);
+}
+
+static JSBool
+js_isFile(JSContext *cx, JSFile *file)
+{
+    if (!file->isNative) {
+#ifdef OSSP
+        struct stat info;
+
+        if (file->isOpen
+            ? fstat(fileno(file->handle), &info) != 0
+            : stat(file->path, &info) != 0) {
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                 JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
+            return JS_FALSE;
+        }
+
+        return S_ISREG(info.st_mode) != 0;
+#else
+        PRFileInfo info;
+
+        if (file->isOpen
+            ? PR_GetOpenFileInfo(file->handle, &info)
+            : PR_GetFileInfo(file->path, &info) != PR_SUCCESS) {
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                 JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
+            return JS_FALSE;
+        }
+
+        return info.type == PR_FILE_FILE;
+#endif
+    }
+
+    /* This doesn't make sense for a pipe of stdstream. */
+    return JS_FALSE;
+}
+
+static JSBool
+js_isDirectory(JSContext *cx, JSFile *file)
+{
+    if(!file->isNative){
+#ifdef OSSP
+        struct stat info;
+#else
+        PRFileInfo info;
+#endif
+
+        /* Hack needed to get get_property to work. */
+        if (!js_exists(cx, file))
+            return JS_FALSE;
+
+#ifdef OSSP
+        if (file->isOpen
+            ? fstat(fileno(file->handle), &info) != 0
+            : stat(file->path, &info) != 0) {
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                 JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
+            return JS_FALSE;
+        }
+
+        return S_ISDIR(info.st_mode) != 0;
+#else
+        if (file->isOpen
+            ? PR_GetOpenFileInfo(file->handle, &info)
+            : PR_GetFileInfo(file->path, &info) != PR_SUCCESS) {
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                 JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
+            return JS_FALSE;
+        }
+
+        return info.type == PR_FILE_DIRECTORY;
+#endif
+    }
+
+    /* This doesn't make sense for a pipe of stdstream. */
+    return JS_FALSE;
+}
+
+static jsval
+js_size(JSContext *cx, JSFile *file)
+{
+#ifdef OSSP
+    struct stat info;
+#else
+    PRFileInfo info;
+#endif
+
+    JSFILE_CHECK_NATIVE("size");
+
+#ifdef OSSP
+    if (file->isOpen
+        ? fstat(fileno(file->handle), &info) != 0
+        : stat(file->path, &info) != 0) {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                             JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
+        return JS_FALSE;
+    }
+
+    return INT_TO_JSVAL(info.st_size);
+#else
+    if (file->isOpen
+        ? PR_GetOpenFileInfo(file->handle, &info)
+        : PR_GetFileInfo(file->path, &info) != PR_SUCCESS) {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                             JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
+        return JS_FALSE;
+    }
+
+    return INT_TO_JSVAL(info.size);
+#endif
+
+out:
+    return JSVAL_VOID;
+}
+
+/*
+ * Return the parent object
+ */
+static JSBool
+js_parent(JSContext *cx, JSFile *file, jsval *resultp)
+{
+    char *str;
+
+    /* Since we only care about pipes and native files, return NULL. */
+    if (file->isNative) {
+        *resultp = JSVAL_VOID;
+        return JS_TRUE;
+    }
+
+    str = js_fileDirectoryName(cx, file->path);
+    if (!str)
+        return JS_FALSE;
+
+    /* If the directory is equal to the original path, we're at the root. */
+    if (!strcmp(file->path, str)) {
+        *resultp = JSVAL_NULL;
+    } else {
+        JSObject *obj = js_NewFileObject(cx, str);
+        if (!obj) {
+            JS_free(cx, str);
+            return JS_FALSE;
+        }
+        *resultp = OBJECT_TO_JSVAL(obj);
+    }
+
+    JS_free(cx, str);
+    return JS_TRUE;
+}
+
+static JSBool
+js_name(JSContext *cx, JSFile *file, jsval *vp)
+{
+    char *name;
+    JSString *str;
+
+    if (file->isPipe) {
+        *vp = JSVAL_VOID;
+        return JS_TRUE;
+    }
+
+    name = js_fileBaseName(cx, file->path);
+    if (!name)
+        return JS_FALSE;
+
+    str = JS_NewString(cx, name, strlen(name));
+    if (!str) {
+        JS_free(cx, name);
+        return JS_FALSE;
+    }
+
+    *vp = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+/* ------------------------------ File object methods ---------------------------- */
+static JSBool
+file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    JSString	*strmode, *strtype;
+    char        *ctype, *mode;
+    int32       mask, type;
+    int         len;
+
+    mode = NULL;
+
+    SECURITY_CHECK(cx, NULL, "open", file);
+
+    /* A native file that is already open */
+    if(file->isOpen && file->isNative) {
+        JS_ReportWarning(cx, "Native file %s is already open, proceeding",
+                         file->path);
+        goto good;
+    }
+
+    /* Close before proceeding */
+    if (file->isOpen) {
+        JS_ReportWarning(cx, "File %s is already open, we will close it and "
+                         "reopen, proceeding", file->path);
+        if(!file_close(cx, obj, 0, NULL, rval))
+            goto out;
+    }
+
+    if (js_isDirectory(cx, file)) {
+        JS_ReportWarning(cx, "%s seems to be a directory, there is no point in "
+                         "trying to open it, proceeding", file->path);
+        goto good;
+    }
+
+    /* Path must be defined at this point */
+    len = strlen(file->path);
+
+    /* Mode */
+    if (argc >= 1) {
+        strmode = JS_ValueToString(cx, argv[0]);
+        if (!strmode) {
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                 JSFILEMSG_FIRST_ARGUMENT_OPEN_NOT_STRING_ERROR,
+                                 argv[0]);
+            goto out;
+        }
+        mode = JS_strdup(cx, JS_GetStringBytes(strmode));
+    } else {
+        if(file->path[0]==PIPE_SYMBOL) {
+            /* pipe default mode */
+            mode = JS_strdup(cx, "read");
+        } else if(file->path[len-1]==PIPE_SYMBOL) {
+            /* pipe default mode */
+            mode = JS_strdup(cx, "write");
+        } else {
+            /* non-destructive, permissive defaults. */
+            mode = JS_strdup(cx, "readWrite,append,create");
+        }
+    }
+
+    /* Process the mode */
+    mask = 0;
+    /* TODO: this is pretty ugly, we walk thru the string too many times */
+    mask |= js_FileHasOption(cx, mode, "read")     ? PR_RDONLY       :   0;
+    mask |= js_FileHasOption(cx, mode, "write")    ? PR_WRONLY       :   0;
+    mask |= js_FileHasOption(cx, mode, "readWrite")? PR_RDWR         :   0;
+    mask |= js_FileHasOption(cx, mode, "append")   ? PR_APPEND       :   0;
+    mask |= js_FileHasOption(cx, mode, "create")   ? PR_CREATE_FILE  :   0;
+    mask |= js_FileHasOption(cx, mode, "replace")  ? PR_TRUNCATE     :   0;
+
+    if (mask & PR_RDWR)
+        mask |= (PR_RDONLY | PR_WRONLY);
+    if ((mask & PR_RDONLY) && (mask & PR_WRONLY))
+        mask |= PR_RDWR;
+
+    file->hasAutoflush |= js_FileHasOption(cx, mode, "autoflush");
+
+    /* Type */
+    if (argc > 1) {
+        strtype = JS_ValueToString(cx, argv[1]);
+        if (!strtype) {
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                JSFILEMSG_SECOND_ARGUMENT_OPEN_NOT_STRING_ERROR,
+                                 argv[1]);
+            goto out;
+        }
+        ctype = JS_GetStringBytes(strtype);
+
+        if(!strcmp(ctype, utfstring)) {
+            type = UTF8;
+        } else if (!strcmp(ctype, unicodestring)) {
+            type = UCS2;
+        } else {
+            if (strcmp(ctype, asciistring)) {
+                JS_ReportWarning(cx, "File type %s is not supported, using "
+                                 "'text' instead, proceeding", ctype);
+            }
+            type = ASCII;
+        }
+    } else {
+        type = ASCII;
+    }
+
+    /* Save the relevant fields */
+    file->type = type;
+    file->mode = mask;
+    file->nativehandle = NULL;
+    file->hasRandomAccess = (type != UTF8);
+
+    /*
+     * Deal with pipes here. We can't use NSPR for pipes, so we have to use
+     * POPEN.
+     */
+    if (file->path[0]==PIPE_SYMBOL || file->path[len-1]==PIPE_SYMBOL) {
+        if (file->path[0] == PIPE_SYMBOL && file->path[len-1] == PIPE_SYMBOL) {
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                 JSFILEMSG_BIDIRECTIONAL_PIPE_NOT_SUPPORTED);
+            goto out;
+        } else {
+            int i = 0;
+            char pipemode[3];
+            SECURITY_CHECK(cx, NULL, "pipe_open", file);
+
+            if(file->path[0] == PIPE_SYMBOL){
+                if(mask & (PR_WRONLY | PR_APPEND | PR_CREATE_FILE | PR_TRUNCATE)){
+                    JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                   JSFILEMSG_OPEN_MODE_NOT_SUPPORTED_WITH_PIPES,
+                                         mode, file->path);
+                    goto out;
+                }
+                /* open(SPOOLER, "| cat -v | lpr -h 2>/dev/null") -- pipe for writing */
+                pipemode[i++] = 'r';
+#ifndef XP_UNIX
+                pipemode[i++] = file->type==UTF8 ? 'b' : 't';
+#endif
+                pipemode[i++] = '\0';
+                file->nativehandle = POPEN(&file->path[1], pipemode);
+            } else if(file->path[len-1] == PIPE_SYMBOL) {
+                char *command = JS_malloc(cx, len);
+
+                strncpy(command, file->path, len-1);
+                command[len-1] = '\0';
+                /* open(STATUS, "netstat -an 2>&1 |") */
+                pipemode[i++] = 'w';
+#ifndef XP_UNIX
+                pipemode[i++] = file->type==UTF8 ? 'b' : 't';
+#endif
+                pipemode[i++] = '\0';
+                file->nativehandle = POPEN(command, pipemode);
+                JS_free(cx, command);
+            }
+            /* set the flags */
+            file->isNative = JS_TRUE;
+            file->isPipe  = JS_TRUE;
+            file->hasRandomAccess = JS_FALSE;
+        }
+    } else {
+        /* TODO: what about the permissions?? Java ignores the problem... */
+#ifdef OSSP
+        {
+            int my_fd;
+            int my_fd_mode = 0;
+            char *my_fp_mode = "";
+            my_fd_mode |= ((mask & PR_RDONLY)      ? O_RDONLY : 0);
+            my_fd_mode |= ((mask & PR_WRONLY)      ? O_WRONLY : 0);
+            my_fd_mode |= ((mask & PR_RDWR)        ? O_RDWR   : 0);
+            my_fd_mode |= ((mask & PR_APPEND)      ? O_APPEND : 0);
+            my_fd_mode |= ((mask & PR_CREATE_FILE) ? O_CREAT  : 0);
+            my_fd_mode |= ((mask & PR_TRUNCATE)    ? O_TRUNC  : 0);
+            if      ((mask & PR_RDWR))                       my_fp_mode = "r+";
+            else if ((mask & PR_RDONLY))                     my_fp_mode = "r";
+            else if ((mask & PR_WRONLY))                     my_fp_mode = "w";
+            else if ((mask & PR_APPEND) && (mask & PR_RDWR)) my_fp_mode = "a+";
+            else if ((mask & PR_APPEND))                     my_fp_mode = "a";
+            else                                             my_fp_mode = "rw";
+            if ((my_fd = open(file->path, my_fd_mode, 0644)) != -1)
+                file->handle = fdopen(my_fd, my_fp_mode);
+        }
+#else
+        file->handle = PR_Open(file->path, mask, 0644);
+#endif
+    }
+
+    js_ResetBuffers(file);
+    JS_free(cx, mode);
+    mode = NULL;
+
+    /* Set the open flag and return result */
+    if (file->handle == NULL && file->nativehandle == NULL) {
+        file->isOpen = JS_FALSE;
+
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                             JSFILEMSG_OP_FAILED, "open", file->path);
+        goto out;
+    }
+
+good:
+    file->isOpen = JS_TRUE;
+    *rval = JSVAL_TRUE;
+    return JS_TRUE;
+
+out:
+    if(mode)
+        JS_free(cx, mode);
+    return JS_FALSE;
+}
+
+static JSBool
+file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile  *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+
+    SECURITY_CHECK(cx, NULL, "close", file);
+
+    if(!file->isOpen){
+        JS_ReportWarning(cx, "File %s is not open, can't close it, proceeding",
+            file->path);
+        goto out;
+    }
+
+    if(!file->isPipe){
+        if(file->isNative){
+            JS_ReportWarning(cx, "Unable to close a native file, proceeding", file->path);
+            goto out;
+        }else{
+#ifdef OSSP
+            if (file->handle && fclose(file->handle) != 0) {
+#else
+            if(file->handle && PR_Close(file->handle)){
+#endif
+                JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                    JSFILEMSG_OP_FAILED, "close", file->path);
+
+                goto out;
+            }
+        }
+    }else{
+        if(PCLOSE(file->nativehandle)==-1){
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                JSFILEMSG_OP_FAILED, "pclose", file->path);
+            goto out;
+        }
+    }
+
+    js_ResetAttributes(file);
+    *rval = JSVAL_TRUE;
+    return JS_TRUE;
+
+out:
+    return JS_FALSE;
+}
+
+
+static JSBool
+file_remove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+	JSFile  *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+
+    SECURITY_CHECK(cx, NULL, "remove", file);
+    JSFILE_CHECK_NATIVE("remove");
+    JSFILE_CHECK_CLOSED("remove");
+
+#ifdef OSSP
+    if (remove(file->path) == 0) {
+#else
+    if ((js_isDirectory(cx, file) ?
+            PR_RmDir(file->path) : PR_Delete(file->path))==PR_SUCCESS) {
+#endif
+        js_ResetAttributes(file);
+        *rval = JSVAL_TRUE;
+        return JS_TRUE;
+    } else {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_OP_FAILED, "remove", file->path);
+        goto out;
+    }
+out:
+    *rval = JSVAL_FALSE;
+    return JS_FALSE;
+}
+
+/* Raw PR-based function. No text processing. Just raw data copying. */
+static JSBool
+file_copyTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    char        *dest = NULL;
+#ifdef OSSP
+    FILE        *handle = NULL;
+#else
+    PRFileDesc  *handle = NULL;
+#endif
+    char        *buffer;
+    jsval		count, size;
+    JSBool      fileInitiallyOpen=JS_FALSE;
+
+    SECURITY_CHECK(cx, NULL, "copyTo", file);   /* may need a second argument!*/
+    JSFILE_CHECK_ONE_ARG("copyTo");
+    JSFILE_CHECK_NATIVE("copyTo");
+    /* remeber the state */
+    fileInitiallyOpen = file->isOpen;
+    JSFILE_CHECK_READ;
+
+    dest = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+
+    /* make sure we are not reading a file open for writing */
+    if (file->isOpen && !js_canRead(cx, file)) {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                JSFILEMSG_CANNOT_COPY_FILE_OPEN_FOR_WRITING_ERROR, file->path);
+        goto out;
+    }
+
+    if (file->handle==NULL){
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_OP_FAILED, "open", file->path);
+        goto out;
+    }
+
+#ifdef OSSP
+    {
+        int my_fd;
+        if ((my_fd = open(file->path, O_WRONLY|O_CREAT|O_TRUNC, 0644)) != -1)
+            handle = fdopen(my_fd, "w");
+    }
+#else
+    handle = PR_Open(dest, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0644);
+#endif
+
+    if(!handle){
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_OP_FAILED, "open", dest);
+        goto out;
+    }
+
+    if ((size=js_size(cx, file))==JSVAL_VOID) {
+        goto out;
+    }
+
+    buffer = JS_malloc(cx, size);
+
+#ifdef OSSP
+    count = INT_TO_JSVAL((int)fread(buffer, 1, (size_t)size, file->handle));
+#else
+    count = INT_TO_JSVAL(PR_Read(file->handle, buffer, size));
+#endif
+
+    /* reading panic */
+    if (count!=size) {
+        JS_free(cx, buffer);
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+              JSFILEMSG_COPY_READ_ERROR, file->path);
+        goto out;
+    }
+
+#ifdef OSSP
+    count = INT_TO_JSVAL((int)fwrite(buffer, 1, (size_t)JSVAL_TO_INT(size), handle));
+#else
+    count = INT_TO_JSVAL(PR_Write(handle, buffer, JSVAL_TO_INT(size)));
+#endif
+
+    /* writing panic */
+    if (count!=size) {
+        JS_free(cx, buffer);
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+              JSFILEMSG_COPY_WRITE_ERROR, file->path);
+        goto out;
+    }
+
+    JS_free(cx, buffer);
+
+	if(!fileInitiallyOpen){
+		if(!file_close(cx, obj, 0, NULL, rval)) goto out;
+	}
+
+#ifdef OSSP
+    if (fclose(handle) != 0) {
+#else
+    if(PR_Close(handle)!=PR_SUCCESS){
+#endif
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+              JSFILEMSG_OP_FAILED, "close", dest);
+        goto out;
+    }
+
+    *rval = JSVAL_TRUE;
+    return JS_TRUE;
+out:
+    if(file->isOpen && !fileInitiallyOpen){
+#ifdef OSSP
+        if (fclose(file->handle) != 0) {
+#else
+        if(PR_Close(file->handle)!=PR_SUCCESS){
+#endif
+            JS_ReportWarning(cx, "Can't close %s, proceeding", file->path);
+        }
+    }
+
+#ifdef OSSP
+    if (handle && fclose(handle) != 0) {
+#else
+    if(handle && PR_Close(handle)!=PR_SUCCESS){
+#endif
+        JS_ReportWarning(cx, "Can't close %s, proceeding", dest);
+    }
+
+    *rval = JSVAL_FALSE;
+    return JS_FALSE;
+}
+
+static JSBool
+file_renameTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile  *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    char    *dest;
+
+    SECURITY_CHECK(cx, NULL, "renameTo", file); /* may need a second argument!*/
+    JSFILE_CHECK_ONE_ARG("renameTo");
+    JSFILE_CHECK_NATIVE("renameTo");
+    JSFILE_CHECK_CLOSED("renameTo");
+
+    dest = RESOLVE_PATH(cx, JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
+
+#ifdef OSSP
+    if (rename(file->path, dest) == 0){
+#else
+    if (PR_Rename(file->path, dest)==PR_SUCCESS){
+#endif
+        /* copy the new filename */
+        JS_free(cx, file->path);
+        file->path = dest;
+        *rval = JSVAL_TRUE;
+        return JS_TRUE;
+    }else{
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_RENAME_FAILED, file->path, dest);
+        goto out;
+    }
+out:
+    *rval = JSVAL_FALSE;
+    return JS_FALSE;
+}
+
+static JSBool
+file_flush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+
+    SECURITY_CHECK(cx, NULL, "flush", file);
+    JSFILE_CHECK_NATIVE("flush");
+    JSFILE_CHECK_OPEN("flush");
+
+#ifdef OSSP
+    if (fflush(file->handle) == 0){
+#else
+    if (PR_Sync(file->handle)==PR_SUCCESS){
+#endif
+      *rval = JSVAL_TRUE;
+      return JS_TRUE;
+    }else{
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+           JSFILEMSG_OP_FAILED, "flush", file->path);
+       goto out;
+    }
+out:
+    *rval = JSVAL_FALSE;
+    return JS_FALSE;
+}
+
+static JSBool
+file_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    JSString    *str;
+    int32       count;
+    uintN       i;
+
+    SECURITY_CHECK(cx, NULL, "write", file);
+    JSFILE_CHECK_WRITE;
+
+    for (i = 0; i<argc; i++) {
+        str = JS_ValueToString(cx, argv[i]);
+        count = js_FileWrite(cx, file, JS_GetStringChars(str),
+            JS_GetStringLength(str), file->type);
+        if (count==-1){
+          *rval = JSVAL_FALSE;
+          return JS_FALSE;
+        }
+    }
+
+    *rval = JSVAL_TRUE;
+    return JS_TRUE;
+out:
+    *rval = JSVAL_FALSE;
+    return JS_FALSE;
+}
+
+static JSBool
+file_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    JSString    *str;
+
+    SECURITY_CHECK(cx, NULL, "writeln", file);
+    JSFILE_CHECK_WRITE;
+
+    /* don't report an error here */
+    if(!file_write(cx, obj, argc, argv, rval))  return JS_FALSE;
+    /* don't do security here -- we passed the check in file_write */
+    str = JS_NewStringCopyZ(cx, "\n");
+
+    if (js_FileWrite(cx, file, JS_GetStringChars(str), JS_GetStringLength(str),
+            file->type)==-1){
+        *rval = JSVAL_FALSE;
+        return JS_FALSE;
+    }
+
+    /* eol causes flush if hasAutoflush is turned on */
+    if (file->hasAutoflush)
+        file_flush(cx, obj, 0, NULL, rval);
+
+    *rval =  JSVAL_TRUE;
+    return JS_TRUE;
+out:
+    *rval = JSVAL_FALSE;
+    return JS_FALSE;
+}
+
+static JSBool
+file_writeAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    jsuint      i;
+    jsuint      limit;
+    JSObject    *array;
+    JSObject    *elem;
+    jsval       elemval;
+
+    SECURITY_CHECK(cx, NULL, "writeAll", file);
+    JSFILE_CHECK_ONE_ARG("writeAll");
+    JSFILE_CHECK_WRITE;
+
+    if (!JS_IsArrayObject(cx, JSVAL_TO_OBJECT(argv[0]))) {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_FIRST_ARGUMENT_WRITEALL_NOT_ARRAY_ERROR);
+        goto out;
+    }
+
+    array = JSVAL_TO_OBJECT(argv[0]);
+
+    JS_GetArrayLength(cx, array, &limit);
+
+    for (i = 0; i<limit; i++) {
+        if (!JS_GetElement(cx, array, i, &elemval))  return JS_FALSE;
+        elem = JSVAL_TO_OBJECT(elemval);
+        file_writeln(cx, obj, 1, &elemval, rval);
+    }
+
+    *rval = JSVAL_TRUE;
+    return JS_TRUE;
+out:
+    *rval = JSVAL_FALSE;
+    return JS_FALSE;
+}
+
+static JSBool
+file_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    JSString    *str;
+    int32       want, count;
+    jschar      *buf;
+
+    SECURITY_CHECK(cx, NULL, "read", file);
+    JSFILE_CHECK_ONE_ARG("read");
+    JSFILE_CHECK_READ;
+
+    if (!JS_ValueToInt32(cx, argv[0], &want)){
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "read", argv[0]);
+        goto out;
+    }
+
+    /* want = (want>262144)?262144:want; * arbitrary size limitation */
+
+    buf = JS_malloc(cx, want*sizeof buf[0]);
+    if (!buf)  goto out;
+
+    count =  js_FileRead(cx, file, buf, want, file->type);
+    if (count>0) {
+        str = JS_NewUCStringCopyN(cx, buf, count);
+        *rval = STRING_TO_JSVAL(str);
+        JS_free(cx, buf);
+        return JS_TRUE;
+    } else {
+        JS_free(cx, buf);
+        goto out;
+    }
+out:
+    *rval = JSVAL_FALSE;
+    return JS_FALSE;
+}
+
+static JSBool
+file_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    JSString    *str;
+    jschar      *buf = NULL, *tmp;
+    int32       offset, read;
+    intN        room;
+    jschar      data, data2;
+
+    SECURITY_CHECK(cx, NULL, "readln", file);
+    JSFILE_CHECK_READ;
+
+    buf = JS_malloc(cx, MAX_LINE_LENGTH * sizeof data);
+    if (!buf)
+        return JS_FALSE;
+
+    room = MAX_LINE_LENGTH - 1;
+    offset = 0;
+
+    for (;;) {
+        read = js_FileRead(cx, file, &data, 1, file->type);
+        if (read < 0)
+            goto out;
+        if (read == 0)
+            goto eof;
+
+        switch (data) {
+          case '\r':
+            read = js_FileRead(cx, file, &data2, 1, file->type);
+            if (read < 0)
+                goto out;
+
+            if (read == 1 && data2 != '\n') {
+                /* We read one char too far.  Buffer it. */
+                file->charBuffer = data2;
+                file->charBufferUsed = JS_TRUE;
+            }
+
+            /* Fall through. */
+          case '\n':
+            goto done;
+
+          default:
+            if (--room < 0) {
+                tmp = JS_realloc(cx, buf,
+                                 (offset + MAX_LINE_LENGTH) * sizeof data);
+                if (!tmp)
+                    goto out;
+
+                room = MAX_LINE_LENGTH - 1;
+                buf = tmp;
+            }
+
+            buf[offset++] = data;
+            break;
+        }
+    }
+
+eof:
+    if (offset == 0) {
+        *rval = JSVAL_NULL;
+        return JS_TRUE;
+    }
+
+done:
+    buf[offset] = 0;
+    tmp = JS_realloc(cx, buf, (offset + 1) * sizeof data);
+    if (!tmp)
+        goto out;
+
+    str = JS_NewUCString(cx, tmp, offset);
+    if (!str)
+        goto out;
+
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+
+out:
+    if (buf)
+        JS_free(cx, buf);
+
+    return JS_FALSE;
+}
+
+static JSBool
+file_readAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    JSObject    *array;
+    jsint       len;
+    jsval       line;
+    JSBool      lineok = JS_FALSE;
+
+    SECURITY_CHECK(cx, NULL, "readAll", file);
+    JSFILE_CHECK_READ;
+
+    array = JS_NewArrayObject(cx, 0, NULL);
+    if (!array)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(array);
+
+    len = 0;
+
+    lineok = file_readln(cx, obj, 0, NULL, &line);
+    while (lineok && !JSVAL_IS_NULL(line)) {
+        JS_SetElement(cx, array, len++, &line);
+        lineok = file_readln(cx, obj, 0, NULL, &line);
+    }
+
+out:
+    return lineok;
+}
+
+static JSBool
+file_seek(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    int32       toskip;
+    int32       pos;
+
+    SECURITY_CHECK(cx, NULL, "seek", file);
+    JSFILE_CHECK_ONE_ARG("seek");
+    JSFILE_CHECK_NATIVE("seek");
+    JSFILE_CHECK_READ;
+
+    if (!JS_ValueToInt32(cx, argv[0], &toskip)){
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "seek", argv[0]);
+        goto out;
+    }
+
+    if(!file->hasRandomAccess){
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_NO_RANDOM_ACCESS, file->path);
+       goto out;
+    }
+
+    if(js_isDirectory(cx, file)){
+        JS_ReportWarning(cx,"Seek on directories is not supported, proceeding");
+        goto out;
+    }
+
+    pos = js_FileSeek(cx, file, toskip, file->type);
+
+    if (pos!=-1) {
+        *rval = INT_TO_JSVAL(pos);
+        return JS_TRUE;
+    }
+out:
+    *rval = JSVAL_VOID;
+    return JS_FALSE;
+}
+
+static JSBool
+file_list(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+#ifdef OSSP
+    DIR           *dir;
+    struct dirent *entry;
+#else
+    PRDir       *dir;
+    PRDirEntry  *entry;
+#endif
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    JSObject    *array;
+    JSObject    *eachFile;
+    jsint       len;
+    jsval       v;
+    JSRegExp    *re = NULL;
+    JSFunction  *func = NULL;
+    JSString    *str;
+    jsval       args[1];
+    char        *filePath;
+
+    SECURITY_CHECK(cx, NULL, "list", file);
+    JSFILE_CHECK_NATIVE("list");
+
+    if (argc==1) {
+        if (JSVAL_IS_REGEXP(cx, argv[0])) {
+            re = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0]));
+        }else
+        if (JSVAL_IS_FUNCTION(cx, argv[0])) {
+            func = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0]));
+        }else{
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_FUNCTION_OR_REGEX, argv[0]);
+            goto out;
+        }
+    }
+
+    if (!js_isDirectory(cx, file)) {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_CANNOT_DO_LIST_ON_A_FILE, file->path);
+        goto out;
+    }
+
+#ifdef OSSP
+    dir = opendir(file->path);
+#else
+    dir = PR_OpenDir(file->path);
+#endif
+    if(!dir){
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_OP_FAILED, "open", file->path);
+        goto out;
+    }
+
+    /* create JSArray here... */
+    array = JS_NewArrayObject(cx, 0, NULL);
+    len = 0;
+
+#ifdef OSSP
+    while ((entry = readdir(dir))!=NULL) {
+#else
+    while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))!=NULL) {
+#endif
+#ifdef OSSP
+        if (   strcmp(entry->d_name, ".")  == 0
+            || strcmp(entry->d_name, "..") == 0)
+            continue;
+#endif
+        /* first, check if we have a regexp */
+        if (re!=NULL) {
+            size_t index = 0;
+
+#ifdef OSSP
+            str = JS_NewStringCopyZ(cx, entry->d_name);
+#else
+            str = JS_NewStringCopyZ(cx, entry->name);
+#endif
+            if(!js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, &v)){
+                /* don't report anything here */
+                goto out;
+            }
+            /* not matched! */
+            if (JSVAL_IS_NULL(v)) {
+                continue;
+            }
+        }else
+        if (func!=NULL) {
+#ifdef OSSP
+            str = JS_NewStringCopyZ(cx, entry->d_name);
+#else
+            str = JS_NewStringCopyZ(cx, entry->name);
+#endif
+            args[0] = STRING_TO_JSVAL(str);
+            if(!JS_CallFunction(cx, obj, func, 1, args, &v)){
+                goto out;
+            }
+
+            if (v==JSVAL_FALSE) {
+                continue;
+            }
+        }
+
+#ifdef OSSP
+        filePath = js_combinePath(cx, file->path, (char*)entry->d_name);
+#else
+        filePath = js_combinePath(cx, file->path, (char*)entry->name);
+#endif
+
+        eachFile = js_NewFileObject(cx, filePath);
+        JS_free(cx, filePath);
+        if (!eachFile){
+            JS_ReportWarning(cx, "File %s cannot be retrieved", filePath);
+            continue;
+        }
+        v = OBJECT_TO_JSVAL(eachFile);
+        JS_SetElement(cx, array, len, &v);
+#ifdef OSSP
+        JS_SetProperty(cx, array, entry->d_name, &v);
+#else
+        JS_SetProperty(cx, array, entry->name, &v);
+#endif
+        len++;
+    }
+
+#ifdef OSSP
+    if (closedir(dir) != 0) {
+#else
+    if(PR_CloseDir(dir)!=PR_SUCCESS){
+#endif
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_OP_FAILED, "close", file->path);
+        goto out;
+    }
+    *rval = OBJECT_TO_JSVAL(array);
+    return JS_TRUE;
+out:
+    *rval = JSVAL_NULL;
+    return JS_FALSE;
+}
+
+static JSBool
+file_mkdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+
+    SECURITY_CHECK(cx, NULL, "mkdir", file);
+    JSFILE_CHECK_ONE_ARG("mkdir");
+    JSFILE_CHECK_NATIVE("mkdir");
+
+    /* if the current file is not a directory, find out the directory name */
+    if (!js_isDirectory(cx, file)) {
+        char        *dir = js_fileDirectoryName(cx, file->path);
+        JSObject    *dirObj = js_NewFileObject(cx, dir);
+
+        JS_free(cx, dir);
+
+        /* call file_mkdir with the right set of parameters if needed */
+        if (file_mkdir(cx, dirObj, argc, argv, rval))
+			return JS_TRUE;
+		else
+            goto out;
+    }else{
+        char *dirName = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+        char *fullName;
+
+        fullName = js_combinePath(cx, file->path, dirName);
+#ifdef OSSP
+        if (mkdir(fullName, 0755) == 0) {
+#else
+        if (PR_MkDir(fullName, 0755)==PR_SUCCESS){
+#endif
+            *rval = JSVAL_TRUE;
+            JS_free(cx, fullName);
+            return JS_TRUE;
+        }else{
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                JSFILEMSG_OP_FAILED, "mkdir", fullName);
+            JS_free(cx, fullName);
+            goto out;
+        }
+    }
+out:
+    *rval = JSVAL_FALSE;
+    return JS_FALSE;
+}
+
+static JSBool
+file_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*rval)
+{
+    JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+#ifdef OSSP
+    JSString *str;
+
+    if ((str = JS_NewStringCopyZ(cx, file->path)) == NULL)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+#else
+    *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, file->path));
+#endif
+    return JS_TRUE;
+}
+
+static JSBool
+file_toURL(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    char url[MAX_PATH_LENGTH];
+    jschar *urlChars;
+#ifdef OSSP
+    size_t len;
+    JSString *str;
+#endif
+
+	JSFILE_CHECK_NATIVE("toURL");
+
+    sprintf(url, "file://%s", file->path);
+    /* TODO: js_escape in jsstr.h may go away at some point */
+
+#ifdef OSSP /* BUGFIX */
+    len = strlen(url);
+    if ((urlChars = js_InflateString(cx, url, &len)) == NULL)
+        return JS_FALSE;
+    if ((str = js_NewString(cx, urlChars, len, 0)) == NULL) {
+        JS_free(cx, urlChars);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+#else
+    urlChars = js_InflateString(cx, url, strlen(url));
+    if (urlChars == NULL) return JS_FALSE;
+    *rval = STRING_TO_JSVAL(js_NewString(cx, urlChars, strlen(url), 0));
+#endif
+    if (!js_str_escape(cx, obj, 0, rval, rval)) return JS_FALSE;
+
+    return JS_TRUE;
+out:
+    *rval = JSVAL_VOID;
+    return JS_FALSE;
+}
+
+
+static void
+file_finalize(JSContext *cx, JSObject *obj)
+{
+    JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+
+    if(file) {
+        /* Close the file before exiting. */
+        if(file->isOpen && !file->isNative) {
+            jsval vp;
+            file_close(cx, obj, 0, NULL, &vp);
+        }
+
+        if (file->path)
+            JS_free(cx, file->path);
+
+        JS_free(cx, file);
+    }
+}
+
+/*
+    Allocates memory for the file object, sets fields to defaults.
+*/
+static JSFile*
+file_init(JSContext *cx, JSObject *obj, char *bytes)
+{
+    JSFile *file;
+
+    file = JS_malloc(cx, sizeof *file);
+    if (!file)
+        return NULL;
+    memset(file, 0 , sizeof *file);
+
+    js_ResetAttributes(file);
+
+    file->path = RESOLVE_PATH(cx, bytes);
+
+    if (!JS_SetPrivate(cx, obj, file)) {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                             JSFILEMSG_CANNOT_SET_PRIVATE_FILE, file->path);
+        JS_free(cx, file);
+        return NULL;
+    }
+
+    return file;
+}
+
+/* Returns a JSObject. This function is globally visible */
+JS_PUBLIC_API(JSObject*)
+js_NewFileObject(JSContext *cx, char *filename)
+{
+    JSObject    *obj;
+    JSFile      *file;
+
+    obj = JS_NewObject(cx, &file_class, NULL, NULL);
+    if (!obj){
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_OBJECT_CREATION_FAILED, "js_NewFileObject");
+        return NULL;
+    }
+    file = file_init(cx, obj, filename);
+    if(!file) return NULL;
+    return obj;
+}
+
+/* Internal function, used for cases which NSPR file support doesn't cover */
+#ifdef OSSP /* CLEANUP */
+static
+#endif
+JSObject*
+js_NewFileObjectFromFILE(JSContext *cx, FILE *nativehandle, char *filename,
+    int32 mode, JSBool open, JSBool randomAccess)
+{
+    JSObject *obj;
+    JSFile   *file;
+
+    obj = JS_NewObject(cx, &file_class, NULL, NULL);
+    if (!obj){
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_OBJECT_CREATION_FAILED, "js_NewFileObjectFromFILE");
+        return NULL;
+    }
+    file = file_init(cx, obj, filename);
+    if(!file) return NULL;
+
+    file->nativehandle = nativehandle;
+
+    /* free result of RESOLVE_PATH from file_init. */
+    JS_ASSERT(file->path != NULL);
+    JS_free(cx, file->path);
+
+    file->path = strdup(filename);
+    file->isOpen = open;
+    file->mode = mode;
+    file->hasRandomAccess = randomAccess;
+    file->isNative = JS_TRUE;
+    return obj;
+}
+
+/*
+    Real file constructor that is called from JavaScript.
+    Basically, does error processing and calls file_init.
+*/
+static JSBool
+file_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    JSString *str;
+    JSFile   *file;
+
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        /* Replace obj with a new File object. */
+        obj = JS_NewObject(cx, &file_class, NULL, NULL);
+        if (!obj)
+            return JS_FALSE;
+    }
+
+    str = (argc == 0) 
+          ? JS_InternString(cx, "")
+          : JS_ValueToString(cx, argv[0]);
+
+    if (!str) {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                         JSFILEMSG_FIRST_ARGUMENT_CONSTRUCTOR_NOT_STRING_ERROR,
+                             argv[0]);
+        return JS_FALSE;
+    }
+
+    file = file_init(cx, obj, JS_GetStringBytes(str));
+    if (!file)
+        return JS_FALSE;
+
+    SECURITY_CHECK(cx, NULL, "constructor", file);
+
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+/* -------------------- File methods and properties ------------------------- */
+static JSFunctionSpec file_functions[] = {
+    { "open",           file_open, 0},
+    { "close",          file_close, 0},
+    { "remove",         file_remove, 0},
+    { "copyTo",         file_copyTo, 0},
+    { "renameTo",       file_renameTo, 0},
+    { "flush",          file_flush, 0},
+    { "seek",           file_seek, 0},
+    { "read",           file_read, 0},
+    { "readln",         file_readln, 0},
+    { "readAll",        file_readAll, 0},
+    { "write",          file_write, 0},
+    { "writeln",        file_writeln, 0},
+    { "writeAll",       file_writeAll, 0},
+    { "list",           file_list, 0},
+    { "mkdir",          file_mkdir, 0},
+    { "toString",       file_toString, 0},
+    { "toURL",          file_toURL, 0},
+    {0}
+};
+
+enum file_tinyid {
+    FILE_LENGTH             = -2,
+    FILE_PARENT             = -3,
+    FILE_PATH               = -4,
+    FILE_NAME               = -5,
+    FILE_ISDIR              = -6,
+    FILE_ISFILE             = -7,
+    FILE_EXISTS             = -8,
+    FILE_CANREAD            = -9,
+    FILE_CANWRITE           = -10,
+    FILE_OPEN               = -11,
+    FILE_TYPE               = -12,
+    FILE_MODE               = -13,
+    FILE_CREATED            = -14,
+    FILE_MODIFIED           = -15,
+    FILE_SIZE               = -16,
+    FILE_RANDOMACCESS       = -17,
+    FILE_POSITION           = -18,
+    FILE_APPEND             = -19,
+    FILE_REPLACE            = -20,
+    FILE_AUTOFLUSH          = -21,
+#ifdef OSSP /* BUGFIX */
+    FILE_ISNATIVE           = -22
+#else
+    FILE_ISNATIVE           = -22,
+#endif
+};
+
+static JSPropertySpec file_props[] = {
+   {"length",          FILE_LENGTH,        JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"parent",          FILE_PARENT,        JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"path",            FILE_PATH,          JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"name",            FILE_NAME,          JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"isDirectory",     FILE_ISDIR,         JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"isFile",          FILE_ISFILE,        JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"exists",          FILE_EXISTS,        JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"canRead",         FILE_CANREAD,       JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"canWrite",        FILE_CANWRITE,      JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"canAppend",       FILE_APPEND,        JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"canReplace",      FILE_REPLACE,       JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"isOpen",          FILE_OPEN,          JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"type",            FILE_TYPE,          JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"mode",            FILE_MODE,          JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"creationTime",    FILE_CREATED,       JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"lastModified",    FILE_MODIFIED,      JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"size",            FILE_SIZE,          JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"hasRandomAccess", FILE_RANDOMACCESS,  JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"hasAutoFlush",    FILE_AUTOFLUSH,     JSPROP_ENUMERATE | JSPROP_READONLY },
+   {"position",        FILE_POSITION,      JSPROP_ENUMERATE },
+   {"isNative",        FILE_ISNATIVE,      JSPROP_ENUMERATE | JSPROP_READONLY },
+   {0}
+};
+
+/* ------------------------- Property getter/setter ------------------------- */
+static JSBool
+file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSFile      *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    char        *bytes;
+    JSString    *str;
+    jsint       tiny;
+#ifdef OSSP
+    struct stat info;
+#else
+    PRFileInfo  info;
+#endif
+    JSBool      flag;
+#ifdef OSSP
+    struct tm   *tm;
+    time_t      t;
+#else
+    PRExplodedTime expandedTime;
+#endif
+
+    tiny = JSVAL_TO_INT(id);
+    if (!file)
+        return JS_TRUE;
+
+    switch (tiny) {
+    case FILE_PARENT:
+        SECURITY_CHECK(cx, NULL, "parent", file);
+        if (!js_parent(cx, file, vp))
+            return JS_FALSE;
+        break;
+    case FILE_PATH:
+        str = JS_NewStringCopyZ(cx, file->path);
+        if (!str)
+            return JS_FALSE;
+        *vp = STRING_TO_JSVAL(str);
+        break;
+    case FILE_NAME:
+        if (!js_name(cx, file, vp))
+            return JS_FALSE;
+        break;
+    case FILE_ISDIR:
+        SECURITY_CHECK(cx, NULL, "isDirectory", file);
+        *vp = BOOLEAN_TO_JSVAL(js_isDirectory(cx, file));
+        break;
+    case FILE_ISFILE:
+        SECURITY_CHECK(cx, NULL, "isFile", file);
+        *vp = BOOLEAN_TO_JSVAL(js_isFile(cx, file));
+        break;
+    case FILE_EXISTS:
+        SECURITY_CHECK(cx, NULL, "exists", file);
+        *vp = BOOLEAN_TO_JSVAL(js_exists(cx, file));
+        break;
+    case FILE_ISNATIVE:
+        SECURITY_CHECK(cx, NULL, "isNative", file);
+        *vp = BOOLEAN_TO_JSVAL(file->isNative);
+        break;
+    case FILE_CANREAD:
+        SECURITY_CHECK(cx, NULL, "canRead", file);
+        *vp = BOOLEAN_TO_JSVAL(js_canRead(cx, file));
+        break;
+    case FILE_CANWRITE:
+        SECURITY_CHECK(cx, NULL, "canWrite", file);
+        *vp = BOOLEAN_TO_JSVAL(js_canWrite(cx, file));
+        break;
+    case FILE_OPEN:
+        SECURITY_CHECK(cx, NULL, "isOpen", file);
+        *vp = BOOLEAN_TO_JSVAL(file->isOpen);
+        break;
+    case FILE_APPEND :
+        SECURITY_CHECK(cx, NULL, "canAppend", file);
+        JSFILE_CHECK_OPEN("canAppend");
+        *vp = BOOLEAN_TO_JSVAL(!file->isNative &&
+                (file->mode&PR_APPEND)==PR_APPEND);
+        break;
+    case FILE_REPLACE :
+        SECURITY_CHECK(cx, NULL, "canReplace", file);
+        JSFILE_CHECK_OPEN("canReplace");
+        *vp = BOOLEAN_TO_JSVAL(!file->isNative &&
+                (file->mode&PR_TRUNCATE)==PR_TRUNCATE);
+        break;
+    case FILE_AUTOFLUSH :
+        SECURITY_CHECK(cx, NULL, "hasAutoFlush", file);
+        JSFILE_CHECK_OPEN("hasAutoFlush");
+        *vp = BOOLEAN_TO_JSVAL(!file->isNative && file->hasAutoflush);
+        break;
+    case FILE_TYPE:
+        SECURITY_CHECK(cx, NULL, "type", file);
+        JSFILE_CHECK_OPEN("type");
+        if(js_isDirectory(cx, file)){
+            *vp = JSVAL_VOID;
+            break;
+        }
+
+        switch (file->type) {
+        case ASCII:
+            *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, asciistring));
+            break;
+        case UTF8:
+            *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, utfstring));
+            break;
+        case UCS2:
+            *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, unicodestring));
+            break;
+        default:
+            JS_ReportWarning(cx, "Unsupported file type %d, proceeding",
+                file->type);
+        }
+        break;
+    case FILE_MODE:
+        SECURITY_CHECK(cx, NULL, "mode", file);
+        JSFILE_CHECK_OPEN("mode");
+        bytes = JS_malloc(cx, MODE_SIZE);
+        bytes[0] = '\0';
+        flag = JS_FALSE;
+
+        if ((file->mode&PR_RDONLY)==PR_RDONLY) {
+            if (flag) strcat(bytes, ",");
+            strcat(bytes, "read");
+            flag = JS_TRUE;
+        }
+        if ((file->mode&PR_WRONLY)==PR_WRONLY) {
+            if (flag) strcat(bytes, ",");
+            strcat(bytes, "write");
+            flag = JS_TRUE;
+        }
+        if ((file->mode&PR_RDWR)==PR_RDWR) {
+            if (flag) strcat(bytes, ",");
+            strcat(bytes, "readWrite");
+            flag = JS_TRUE;
+        }
+        if ((file->mode&PR_APPEND)==PR_APPEND) {
+            if (flag) strcat(bytes, ",");
+            strcat(bytes, "append");
+            flag = JS_TRUE;
+        }
+        if ((file->mode&PR_CREATE_FILE)==PR_CREATE_FILE) {
+            if (flag) strcat(bytes, ",");
+            strcat(bytes, "create");
+            flag = JS_TRUE;
+        }
+        if ((file->mode&PR_TRUNCATE)==PR_TRUNCATE) {
+            if (flag) strcat(bytes, ",");
+            strcat(bytes, "replace");
+            flag = JS_TRUE;
+        }
+        if (file->hasAutoflush) {
+            if (flag) strcat(bytes, ",");
+            strcat(bytes, "hasAutoFlush");
+            flag = JS_TRUE;
+        }
+        *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, bytes));
+        JS_free(cx, bytes);
+        break;
+    case FILE_CREATED:
+        SECURITY_CHECK(cx, NULL, "creationTime", file);
+        JSFILE_CHECK_NATIVE("creationTime");
+#ifdef OSSP
+        if (file->isOpen
+            ? fstat(fileno(file->handle), &info) != 0
+            : stat(file->path, &info) != 0) {
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                 JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
+            goto out;
+        }
+
+#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME)
+        t = (time_t)(info.st_birthtime);
+#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC)
+        t = (time_t)(info.st_birthtimensec / (1000*1000*1000));
+#else
+        /* not really correct, but the only possible fallback on not
+           fully POSIX compliant platforms. */
+        t = (time_t)(info.st_ctime);
+#endif
+        tm = localtime(&t);
+        *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx, tm->tm_year + 1900,
+                                    tm->tm_mon + 1,
+                                    tm->tm_mday,
+                                    tm->tm_hour,
+                                    tm->tm_min,
+                                    tm->tm_sec));
+#else
+        if(((file->isOpen)?
+                        PR_GetOpenFileInfo(file->handle, &info):
+                        PR_GetFileInfo(file->path, &info))!=PR_SUCCESS){
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
+            goto out;
+        }
+
+        PR_ExplodeTime(info.creationTime, PR_LocalTimeParameters,&expandedTime);
+        *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx,  expandedTime.tm_year,
+                                    expandedTime.tm_month,
+                                    expandedTime.tm_mday,
+                                    expandedTime.tm_hour,
+                                    expandedTime.tm_min,
+                                    expandedTime.tm_sec));
+#endif
+        break;
+    case FILE_MODIFIED:
+        SECURITY_CHECK(cx, NULL, "lastModified", file);
+        JSFILE_CHECK_NATIVE("lastModified");
+#ifdef OSSP
+        if (file->isOpen
+            ? fstat(fileno(file->handle), &info) != 0
+            : stat(file->path, &info) != 0) {
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                                 JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
+            goto out;
+        }
+
+        t = (time_t)(info.st_mtime);
+        tm = localtime(&t);
+        *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx, tm->tm_year + 1900,
+                                    tm->tm_mon + 1,
+                                    tm->tm_mday,
+                                    tm->tm_hour,
+                                    tm->tm_min,
+                                    tm->tm_sec));
+#else
+        if(((file->isOpen)?
+                        PR_GetOpenFileInfo(file->handle, &info):
+                        PR_GetFileInfo(file->path, &info))!=PR_SUCCESS){
+            JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path);
+            goto out;
+        }
+
+        PR_ExplodeTime(info.modifyTime, PR_LocalTimeParameters, &expandedTime);
+        *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx, expandedTime.tm_year,
+                                    expandedTime.tm_month,
+                                    expandedTime.tm_mday,
+                                    expandedTime.tm_hour,
+                                    expandedTime.tm_min,
+                                    expandedTime.tm_sec));
+#endif
+        break;
+    case FILE_SIZE:
+        SECURITY_CHECK(cx, NULL, "size", file);
+        *vp = js_size(cx, file);
+        break;
+    case FILE_LENGTH:
+        SECURITY_CHECK(cx, NULL, "length", file);
+        JSFILE_CHECK_NATIVE("length");
+
+        if (js_isDirectory(cx, file)) { /* XXX debug me */
+#ifdef OSSP
+            DIR           *dir;
+            struct dirent *entry;
+#else
+            PRDir       *dir;
+            PRDirEntry  *entry;
+#endif
+            jsint       count = 0;
+
+#ifdef OSSP
+            if(!(dir = opendir(file->path))){
+#else
+            if(!(dir = PR_OpenDir(file->path))){
+#endif
+                JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                    JSFILEMSG_CANNOT_OPEN_DIR, file->path);
+                goto out;
+            }
+
+#ifdef OSSP
+            while ((entry = readdir(dir))) {
+                if (   strcmp(entry->d_name, ".")  == 0
+                    || strcmp(entry->d_name, "..") == 0)
+                    continue;
+
+#else
+            while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))) {
+#endif
+                count++;
+            }
+
+#ifdef OSSP
+            if(closedir(dir) != 0){
+#else
+            if(!PR_CloseDir(dir)){
+#endif
+                JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                    JSFILEMSG_OP_FAILED, "close", file->path);
+
+                goto out;
+            }
+
+            *vp = INT_TO_JSVAL(count);
+            break;
+        }else{
+            /* return file size */
+            *vp = js_size(cx, file);
+        }
+        break;
+    case FILE_RANDOMACCESS:
+            SECURITY_CHECK(cx, NULL, "hasRandomAccess", file);
+            JSFILE_CHECK_OPEN("hasRandomAccess");
+            *vp = BOOLEAN_TO_JSVAL(file->hasRandomAccess);
+        break;
+    case FILE_POSITION:
+        SECURITY_CHECK(cx, NULL, "position", file);
+        JSFILE_CHECK_NATIVE("position");
+        JSFILE_CHECK_OPEN("position");
+
+        if(!file->hasRandomAccess){
+            JS_ReportWarning(cx, "File %s doesn't support random access, can't report the position, proceeding");
+            *vp = JSVAL_VOID;
+            break;
+        }
+
+        if (file->isOpen && js_isFile(cx, file)) {
+#ifdef OSSP
+            int pos = fseek(file->handle, 0, SEEK_CUR);
+#else
+            int pos = PR_Seek(file->handle, 0, PR_SEEK_CUR);
+#endif
+            if(pos!=-1){
+                *vp = INT_TO_JSVAL(pos);
+            }else{
+                JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                    JSFILEMSG_CANNOT_REPORT_POSITION, file->path);
+                goto out;
+            }
+        }else {
+            JS_ReportWarning(cx, "File %s is closed or not a plain file,"
+                " can't report position, proceeding");
+            goto out;
+        }
+        break;
+    default:
+        SECURITY_CHECK(cx, NULL, "file_access", file);
+
+        /* this is some other property -- try to use the dir["file"] syntax */
+        if (js_isDirectory(cx, file)) {
+#ifdef OSSP
+            DIR *dir = NULL;
+            struct dirent *entry = NULL;
+#else
+            PRDir *dir = NULL;
+            PRDirEntry *entry = NULL;
+#endif
+            char *prop_name;
+
+            str = JS_ValueToString(cx, id);
+            if (!str)
+                return JS_FALSE;
+
+            prop_name = JS_GetStringBytes(str);
+
+            /* no native files past this point */
+#ifdef OSSP
+            dir = opendir(file->path);
+#else
+            dir = PR_OpenDir(file->path);
+#endif
+            if(!dir) {
+                /* This is probably not a directory */
+                JS_ReportWarning(cx, "Can't open directory %s", file->path);
+                return JS_FALSE;
+            }
+
+#ifdef OSSP
+            while ((entry = readdir(dir)) != NULL) {
+                if (   strcmp(entry->d_name, ".")  == 0
+                    || strcmp(entry->d_name, "..") == 0)
+                    continue;
+                if (!strcmp(entry->d_name, prop_name)){
+#else
+            while ((entry = PR_ReadDir(dir, PR_SKIP_NONE)) != NULL) {
+                if (!strcmp(entry->name, prop_name)){
+#endif
+                    bytes = js_combinePath(cx, file->path, prop_name);
+                    *vp = OBJECT_TO_JSVAL(js_NewFileObject(cx, bytes));
+                    JS_free(cx, bytes);
+#ifdef OSSP /* BUGFIX */
+                    closedir(dir);
+#else
+                    PR_CloseDir(dir);
+#endif
+                    return JS_TRUE;
+                }
+            }
+#ifdef OSSP /* BUGFIX */
+            closedir(dir);
+#else
+            PR_CloseDir(dir);
+#endif
+        }
+    }
+    return JS_TRUE;
+
+out:
+    return JS_FALSE;
+}
+
+static JSBool
+file_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSFile  *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+    jsint   slot;
+
+    if (JSVAL_IS_STRING(id)){
+        return JS_TRUE;
+    }
+
+    slot = JSVAL_TO_INT(id);
+
+    switch (slot) {
+    /* File.position  = 10 */
+    case FILE_POSITION:
+        SECURITY_CHECK(cx, NULL, "set_position", file);
+        JSFILE_CHECK_NATIVE("set_position");
+
+        if(!file->hasRandomAccess){
+            JS_ReportWarning(cx, "File %s doesn't support random access, can't "
+                "report the position, proceeding");
+            goto out;
+        }
+
+        if (file->isOpen && js_isFile(cx, file)) {
+            int32 pos;
+		    int32 offset;
+
+			if (!JS_ValueToInt32(cx, *vp, &offset)){
+				JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+					JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "position", *vp);
+				goto out;
+			}
+
+#ifdef OSSP
+			pos = fseek(file->handle, offset, SEEK_SET);
+#else
+			pos = PR_Seek(file->handle, offset, PR_SEEK_SET);
+#endif
+
+            if(pos!=-1){
+                *vp = INT_TO_JSVAL(pos);
+            }else{
+                JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+                    JSFILEMSG_CANNOT_SET_POSITION, file->path);
+                goto out;
+            }
+        } else {
+            JS_ReportWarning(cx, "File %s is closed or not a file, can't set "
+                "position, proceeding", file->path);
+            goto out;
+        }
+    }
+
+    return JS_TRUE;
+out:
+    return JS_FALSE;
+}
+
+/*
+    File.currentDir = new File("D:\") or File.currentDir = "D:\"
+*/
+static JSBool
+file_currentDirSetter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSFile   *file;
+
+    file = JS_GetInstancePrivate(cx, obj, &file_class, NULL);
+
+    /* Look at the rhs and extract a file object from it */
+    if (JSVAL_IS_OBJECT(*vp)) {
+        if (JS_InstanceOf(cx, obj, &file_class, NULL)) {
+            /* Braindamaged rhs -- just return the old value */
+            if (file && (!js_exists(cx, file) || !js_isDirectory(cx, file))) {
+                JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, vp);
+                return JS_FALSE;
+            } else {
+                chdir(file->path);
+                return JS_TRUE;
+            }
+        } else {
+            return JS_FALSE;
+        }
+    } else {
+        JSObject *rhsObject;
+        char     *path;
+
+        path      = JS_GetStringBytes(JS_ValueToString(cx, *vp));
+        rhsObject = js_NewFileObject(cx, path);
+        if (!rhsObject)
+            return JS_FALSE;
+
+        if (!file || !js_exists(cx, file) || !js_isDirectory(cx, file)){
+            JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, vp);
+        } else {
+            *vp = OBJECT_TO_JSVAL(rhsObject);
+            chdir(path);
+        }
+    }
+
+    return JS_TRUE;
+}
+
+/* Declare class */
+static JSClass file_class = {
+    FILE_CONSTRUCTOR, JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub,  JS_PropertyStub,  file_getProperty,  file_setProperty,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,    file_finalize
+};
+
+/* -------------------- Functions exposed to the outside -------------------- */
+JS_PUBLIC_API(JSObject*)
+js_InitFileClass(JSContext *cx, JSObject* obj)
+{
+    JSObject *file, *ctor, *afile;
+    jsval    vp;
+    char     *currentdir;
+    char     separator[2];
+
+    file = JS_InitClass(cx, obj, NULL, &file_class, file_constructor, 1,
+        file_props, file_functions, NULL, NULL);
+    if (!file) {
+        JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL,
+            JSFILEMSG_INIT_FAILED);
+        return NULL;
+    }
+
+    ctor = JS_GetConstructor(cx, file);
+    if (!ctor)  return NULL;
+
+	/* Define CURRENTDIR property. We are doing this to get a
+	slash at the end of the current dir */
+    afile = js_NewFileObject(cx, CURRENT_DIR);
+    currentdir =  JS_malloc(cx, MAX_PATH_LENGTH);
+    currentdir =  getcwd(currentdir, MAX_PATH_LENGTH);
+    afile = js_NewFileObject(cx, currentdir);
+    JS_free(cx, currentdir);
+    vp = OBJECT_TO_JSVAL(afile);
+    JS_DefinePropertyWithTinyId(cx, ctor, CURRENTDIR_PROPERTY, 0, vp,
+                JS_PropertyStub, file_currentDirSetter,
+                JSPROP_ENUMERATE | JSPROP_READONLY );
+
+    /* Define input */
+    vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdin,
+            STDINPUT_NAME, PR_RDONLY, JS_TRUE, JS_FALSE));
+    JS_SetProperty(cx, ctor, "input", &vp);
+
+    /* Define output */
+    vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdout,
+            STDOUTPUT_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
+    JS_SetProperty(cx, ctor, "output", &vp);
+
+    /* Define error */
+    vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stderr,
+            STDERROR_NAME, PR_WRONLY, JS_TRUE, JS_FALSE));
+    JS_SetProperty(cx, ctor, "error", &vp);
+
+    separator[0] = FILESEPARATOR;
+    separator[1] = '\0';
+    vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, separator));
+    JS_DefinePropertyWithTinyId(cx, ctor, SEPARATOR_PROPERTY, 0, vp,
+                JS_PropertyStub, JS_PropertyStub,
+                JSPROP_ENUMERATE | JSPROP_READONLY );
+    return file;
+}
+#endif /* JS_HAS_FILE_OBJECT */

Added: freeswitch/trunk/libs/js/src/jsfile.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsfile.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _jsfile_h__
+#define _jsfile_h__
+
+#if defined(JS_HAS_FILE_OBJECT) && (JS_HAS_FILE_OBJECT - 0) /* OSSP BUGFIX */
+extern JS_PUBLIC_API(JSObject*)
+js_InitFileClass(JSContext *cx, JSObject* obj);
+
+extern JS_PUBLIC_API(JSObject*)
+js_NewFileObject(JSContext *cx, char *bytes);
+#endif /* JS_HAS_FILE_OBJECT */
+#endif /* _jsfile_h__ */

Added: freeswitch/trunk/libs/js/src/jsfile.msg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsfile.msg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,90 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+        Error messages for jsfile.c. See js.msg for format specification.
+*/
+
+MSG_DEF(JSFILEMSG_NOT_AN_ERROR,                                    0, 0, JSEXN_NONE, "<Error #0 is reserved>")
+MSG_DEF(JSFILEMSG_FILE_CONSTRUCTOR_UNDEFINED_ERROR,                1, 0, JSEXN_NONE, "File constructor is undefined")
+MSG_DEF(JSFILEMSG_FILE_CURRENTDIR_UNDEFINED_ERROR,                 2, 0, JSEXN_NONE, "File.currentDir is undefined")
+MSG_DEF(JSFILEMSG_FIRST_ARGUMENT_OPEN_NOT_STRING_ERROR,            3, 1, JSEXN_NONE, "The first argument {0} to file.open must be a string")
+MSG_DEF(JSFILEMSG_SECOND_ARGUMENT_OPEN_NOT_STRING_ERROR,           4, 0, JSEXN_NONE, "The second argument to file.open must be a string")
+MSG_DEF(JSFILEMSG_CANNOT_COPY_FILE_OPEN_FOR_WRITING_ERROR,         5, 1, JSEXN_NONE, "Cannot copy file {0} open for writing")
+MSG_DEF(JSFILEMSG_CANNOT_ACCESS_FILE_INFO_ERROR,                   6, 1, JSEXN_NONE, "Cannot access file information for {0}")
+MSG_DEF(JSFILEMSG_COPY_READ_ERROR,                                 7, 1, JSEXN_NONE, "An error occured while attempting to read a file {0} to copy")
+MSG_DEF(JSFILEMSG_COPY_WRITE_ERROR,                                8, 1, JSEXN_NONE, "An error occured while attempting to copy into file {0}")
+MSG_DEF(JSFILEMSG_EXPECTS_ONE_ARG_ERROR,                           9, 0, JSEXN_NONE, "Operation {0} expects one argument, not {1}")
+MSG_DEF(JSFILEMSG_CANNOT_FLUSH_CLOSE_FILE_ERROR,                  10, 1, JSEXN_NONE, "Cannot flush closed file {0}")
+MSG_DEF(JSFILEMSG_CANNOT_OPEN_WRITING_ERROR,                      11, 1, JSEXN_NONE, "Cannot open file {0} for writing")
+MSG_DEF(JSFILEMSG_WRITEALL_EXPECTS_ONE_ARG_ERROR,                 12, 0, JSEXN_NONE, "writeAll expects one argument")
+MSG_DEF(JSFILEMSG_FIRST_ARGUMENT_WRITEALL_NOT_ARRAY_ERROR,        13, 0, JSEXN_NONE, "writeAll expects an array as an argument")
+MSG_DEF(JSFILEMSG_UNUSED0,                                        14, 0, JSEXN_NONE, "Unused error message slot")
+MSG_DEF(JSFILEMSG_CANNOT_OPEN_FILE_ERROR,                         15, 1, JSEXN_NONE, "Cannot open file {0}")
+MSG_DEF(JSFILEMSG_FIRST_ARGUMENT_CONSTRUCTOR_NOT_STRING_ERROR,    16, 1, JSEXN_NONE, "The argument to the File constructor {0} must be a string")
+MSG_DEF(JSFILEMSG_BIDIRECTIONAL_PIPE_NOT_SUPPORTED,               17, 0, JSEXN_NONE, "Bidirectional pipes are not supported")
+MSG_DEF(JSFILEMSG_OPEN_MODE_NOT_SUPPORTED_WITH_PIPES,             18, 2, JSEXN_NONE, "The opening mode you have chosen {0} is not supported by the pipe you are trying to open: {1}")
+MSG_DEF(JSFILEMSG_OPEN_FAILED,                                    19, 1, JSEXN_NONE, "open on file {0} failed")
+MSG_DEF(JSFILEMSG_CLOSE_FAILED,                                   20, 1, JSEXN_NONE, "close on file {0} failed")
+MSG_DEF(JSFILEMSG_PCLOSE_FAILED,                                  21, 1, JSEXN_NONE, "pclose on file {0} failed")
+MSG_DEF(JSFILEMSG_REMOVE_FAILED,                                  22, 1, JSEXN_NONE, "remove on file {0} failed")
+MSG_DEF(JSFILEMSG_CANNOT_ACCESS_FILE_STATUS,                      23, 1, JSEXN_NONE, "Cannot access file status for {0}")
+MSG_DEF(JSFILEMSG_RENAME_FAILED,                                  24, 2, JSEXN_NONE, "Cannot rename {0} to {1}")
+MSG_DEF(JSFILEMSG_WRITE_FAILED,                                   25, 1, JSEXN_NONE, "Write failed on file {0}")
+MSG_DEF(JSFILEMSG_READ_FAILED,                                    26, 1, JSEXN_NONE, "Read failed on file {0}")
+MSG_DEF(JSFILEMSG_SKIP_FAILED,                                    27, 1, JSEXN_NONE, "Skip failed on file {0}")
+MSG_DEF(JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_FUNCTION_OR_REGEX,     28, 1, JSEXN_NONE, "The first argument to file.list must be a function or a regex")
+MSG_DEF(JSFILEMSG_CANNOT_DO_LIST_ON_A_FILE,                       29, 1, JSEXN_NONE, "{0} must be a directory, cannot do list")
+MSG_DEF(JSFILEMSG_NATIVE_OPERATION_IS_NOT_SUPPORTED,              30, 2, JSEXN_NONE, "Native operation {0} is not supported on {1}")
+MSG_DEF(JSFILEMSG_CANNOT_SET_PRIVATE_FILE,                        31, 1, JSEXN_NONE, "Cannot set private data for file {0}")
+MSG_DEF(JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER,                32, 2, JSEXN_NONE, "First argument to {0} must be a number, not {1}")
+MSG_DEF(JSFILEMSG_CANNOT_WRITE,                                   33, 1, JSEXN_NONE, "Cannot write to {0}, file mode is different")
+MSG_DEF(JSFILEMSG_CANNOT_READ,                                    34, 1, JSEXN_NONE, "Cannot read from {0}, file mode is different")
+MSG_DEF(JSFILEMSG_CANNOT_FLUSH,                                   35, 1, JSEXN_NONE, "Flush failed on {0}")
+MSG_DEF(JSFILEMSG_OP_FAILED,									  36, 1, JSEXN_NONE, "File operation {0} failed")
+MSG_DEF(JSFILEMSG_FILE_MUST_BE_OPEN,							  37, 1, JSEXN_NONE, "File must be open for {0}")
+MSG_DEF(JSFILEMSG_FILE_MUST_BE_CLOSED,							  38, 1, JSEXN_NONE, "File must be closed for {0}")
+MSG_DEF(JSFILEMSG_NO_RANDOM_ACCESS,								  39, 1, JSEXN_NONE, "File {0} doesn't allow random access")
+MSG_DEF(JSFILEMSG_OBJECT_CREATION_FAILED,						  40, 1, JSEXN_NONE, "Couldn't create {0}")
+MSG_DEF(JSFILEMSG_CANNOT_OPEN_DIR,								  41, 1, JSEXN_NONE, "Couldn't open directory {0}")
+MSG_DEF(JSFILEMSG_CANNOT_REPORT_POSITION,						  42, 1, JSEXN_NONE, "Couldn't report position for {0}")
+MSG_DEF(JSFILEMSG_CANNOT_SET_POSITION,							  43, 1, JSEXN_NONE, "Couldn't set position for {0}")
+MSG_DEF(JSFILEMSG_INIT_FAILED,									  44, 0, JSEXN_NONE, "File class initialization failed")
+
+

Added: freeswitch/trunk/libs/js/src/jsfun.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsfun.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2157 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS function support.
+ */
+#include "jsstddef.h"
+#include <string.h>
+#include "jstypes.h"
+#include "jsbit.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsapi.h"
+#include "jsarray.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsdbgapi.h"
+#include "jsfun.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsopcode.h"
+#include "jsparse.h"
+#include "jsscan.h"
+#include "jsscope.h"
+#include "jsscript.h"
+#include "jsstr.h"
+#include "jsexn.h"
+
+/* Generic function/call/arguments tinyids -- also reflected bit numbers. */
+enum {
+    CALL_ARGUMENTS  = -1,       /* predefined arguments local variable */
+    CALL_CALLEE     = -2,       /* reference to active function's object */
+    ARGS_LENGTH     = -3,       /* number of actual args, arity if inactive */
+    ARGS_CALLEE     = -4,       /* reference from arguments to active funobj */
+    FUN_ARITY       = -5,       /* number of formal parameters; desired argc */
+    FUN_NAME        = -6,       /* function name, "" if anonymous */
+    FUN_CALLER      = -7        /* Function.prototype.caller, backward compat */
+};
+
+#if JSFRAME_OVERRIDE_BITS < 8
+# error "not enough override bits in JSStackFrame.flags!"
+#endif
+
+#define TEST_OVERRIDE_BIT(fp, tinyid) \
+    ((fp)->flags & JS_BIT(JSFRAME_OVERRIDE_SHIFT - ((tinyid) + 1)))
+
+#define SET_OVERRIDE_BIT(fp, tinyid) \
+    ((fp)->flags |= JS_BIT(JSFRAME_OVERRIDE_SHIFT - ((tinyid) + 1)))
+
+#if JS_HAS_ARGS_OBJECT
+
+JSBool
+js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp)
+{
+    JSObject *argsobj;
+
+    if (TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
+        JS_ASSERT(fp->callobj);
+        return OBJ_GET_PROPERTY(cx, fp->callobj,
+                                ATOM_TO_JSID(cx->runtime->atomState
+                                             .argumentsAtom),
+                                vp);
+    }
+    argsobj = js_GetArgsObject(cx, fp);
+    if (!argsobj)
+        return JS_FALSE;
+    *vp = OBJECT_TO_JSVAL(argsobj);
+    return JS_TRUE;
+}
+
+static JSBool
+MarkArgDeleted(JSContext *cx, JSStackFrame *fp, uintN slot)
+{
+    JSObject *argsobj;
+    jsval bmapval, bmapint;
+    size_t nbits, nbytes;
+    jsbitmap *bitmap;
+
+    argsobj = fp->argsobj;
+    (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
+    nbits = fp->argc;
+    JS_ASSERT(slot < nbits);
+    if (JSVAL_IS_VOID(bmapval)) {
+        if (nbits <= JSVAL_INT_BITS) {
+            bmapint = 0;
+            bitmap = (jsbitmap *) &bmapint;
+        } else {
+            nbytes = JS_HOWMANY(nbits, JS_BITS_PER_WORD) * sizeof(jsbitmap);
+            bitmap = (jsbitmap *) JS_malloc(cx, nbytes);
+            if (!bitmap)
+                return JS_FALSE;
+            memset(bitmap, 0, nbytes);
+            bmapval = PRIVATE_TO_JSVAL(bitmap);
+            JS_SetReservedSlot(cx, argsobj, 0, bmapval);
+        }
+    } else {
+        if (nbits <= JSVAL_INT_BITS) {
+            bmapint = JSVAL_TO_INT(bmapval);
+            bitmap = (jsbitmap *) &bmapint;
+        } else {
+            bitmap = (jsbitmap *) JSVAL_TO_PRIVATE(bmapval);
+        }
+    }
+    JS_SET_BIT(bitmap, slot);
+    if (bitmap == (jsbitmap *) &bmapint) {
+        bmapval = INT_TO_JSVAL(bmapint);
+        JS_SetReservedSlot(cx, argsobj, 0, bmapval);
+    }
+    return JS_TRUE;
+}
+
+/* NB: Infallible predicate, false does not mean error/exception. */
+static JSBool
+ArgWasDeleted(JSContext *cx, JSStackFrame *fp, uintN slot)
+{
+    JSObject *argsobj;
+    jsval bmapval, bmapint;
+    jsbitmap *bitmap;
+
+    argsobj = fp->argsobj;
+    (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
+    if (JSVAL_IS_VOID(bmapval))
+        return JS_FALSE;
+    if (fp->argc <= JSVAL_INT_BITS) {
+        bmapint = JSVAL_TO_INT(bmapval);
+        bitmap = (jsbitmap *) &bmapint;
+    } else {
+        bitmap = (jsbitmap *) JSVAL_TO_PRIVATE(bmapval);
+    }
+    return JS_TEST_BIT(bitmap, slot) != 0;
+}
+
+JSBool
+js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id,
+                   JSObject **objp, jsval *vp)
+{
+    jsval val;
+    JSObject *obj;
+    uintN slot;
+
+    if (TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) {
+        JS_ASSERT(fp->callobj);
+        if (!OBJ_GET_PROPERTY(cx, fp->callobj,
+                              ATOM_TO_JSID(cx->runtime->atomState
+                                           .argumentsAtom),
+                              &val)) {
+            return JS_FALSE;
+        }
+        if (JSVAL_IS_PRIMITIVE(val)) {
+            obj = js_ValueToNonNullObject(cx, val);
+            if (!obj)
+                return JS_FALSE;
+        } else {
+            obj = JSVAL_TO_OBJECT(val);
+        }
+        *objp = obj;
+        return OBJ_GET_PROPERTY(cx, obj, id, vp);
+    }
+
+    *objp = NULL;
+    *vp = JSVAL_VOID;
+    if (JSID_IS_INT(id)) {
+        slot = (uintN) JSID_TO_INT(id);
+        if (slot < fp->argc) {
+            if (fp->argsobj && ArgWasDeleted(cx, fp, slot))
+                return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);
+            *vp = fp->argv[slot];
+        } else {
+            /*
+             * Per ECMA-262 Ed. 3, 10.1.8, last bulleted item, do not share
+             * storage between the formal parameter and arguments[k] for all
+             * k >= fp->argc && k < fp->fun->nargs.  For example, in
+             *
+             *   function f(x) { x = 42; return arguments[0]; }
+             *   f();
+             *
+             * the call to f should return undefined, not 42.  If fp->argsobj
+             * is null at this point, as it would be in the example, return
+             * undefined in *vp.
+             */
+            if (fp->argsobj)
+                return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);
+        }
+    } else {
+        if (id == ATOM_TO_JSID(cx->runtime->atomState.lengthAtom)) {
+            if (fp->argsobj && TEST_OVERRIDE_BIT(fp, ARGS_LENGTH))
+                return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp);
+            *vp = INT_TO_JSVAL((jsint) fp->argc);
+        }
+    }
+    return JS_TRUE;
+}
+
+JSObject *
+js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
+{
+    JSObject *argsobj;
+
+    /* Skip eval and debugger frames. */
+    while (fp->flags & JSFRAME_SPECIAL)
+        fp = fp->down;
+
+    /* Create an arguments object for fp only if it lacks one. */
+    argsobj = fp->argsobj;
+    if (argsobj)
+        return argsobj;
+
+    /* Link the new object to fp so it can get actual argument values. */
+    argsobj = js_NewObject(cx, &js_ArgumentsClass, NULL, NULL);
+    if (!argsobj || !JS_SetPrivate(cx, argsobj, fp)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+    fp->argsobj = argsobj;
+    return argsobj;
+}
+
+static JSBool
+args_enumerate(JSContext *cx, JSObject *obj);
+
+JSBool
+js_PutArgsObject(JSContext *cx, JSStackFrame *fp)
+{
+    JSObject *argsobj;
+    jsval bmapval, rval;
+    JSBool ok;
+    JSRuntime *rt;
+
+    /*
+     * Reuse args_enumerate here to reflect fp's actual arguments as indexed
+     * elements of argsobj.  Do this first, before clearing and freeing the
+     * deleted argument slot bitmap, because args_enumerate depends on that.
+     */
+    argsobj = fp->argsobj;
+    ok = args_enumerate(cx, argsobj);
+
+    /*
+     * Now clear the deleted argument number bitmap slot and free the bitmap,
+     * if one was actually created due to 'delete arguments[0]' or similar.
+     */
+    (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval);
+    if (!JSVAL_IS_VOID(bmapval)) {
+        JS_SetReservedSlot(cx, argsobj, 0, JSVAL_VOID);
+        if (fp->argc > JSVAL_INT_BITS)
+            JS_free(cx, JSVAL_TO_PRIVATE(bmapval));
+    }
+
+    /*
+     * Now get the prototype properties so we snapshot fp->fun and fp->argc
+     * before fp goes away.
+     */
+    rt = cx->runtime;
+    ok &= js_GetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.calleeAtom),
+                         &rval);
+    ok &= js_SetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.calleeAtom),
+                         &rval);
+    ok &= js_GetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.lengthAtom),
+                         &rval);
+    ok &= js_SetProperty(cx, argsobj, ATOM_TO_JSID(rt->atomState.lengthAtom),
+                         &rval);
+
+    /*
+     * Clear the private pointer to fp, which is about to go away (js_Invoke).
+     * Do this last because the args_enumerate and js_GetProperty calls above
+     * need to follow the private slot to find fp.
+     */
+    ok &= JS_SetPrivate(cx, argsobj, NULL);
+    fp->argsobj = NULL;
+    return ok;
+}
+
+static JSBool
+args_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    jsint slot;
+    JSStackFrame *fp;
+
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+    fp = (JSStackFrame *)
+         JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
+    if (!fp)
+        return JS_TRUE;
+    JS_ASSERT(fp->argsobj);
+
+    slot = JSVAL_TO_INT(id);
+    switch (slot) {
+      case ARGS_CALLEE:
+      case ARGS_LENGTH:
+        SET_OVERRIDE_BIT(fp, slot);
+        break;
+
+      default:
+        if ((uintN)slot < fp->argc && !MarkArgDeleted(cx, fp, slot))
+            return JS_FALSE;
+        break;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+args_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    jsint slot;
+    JSStackFrame *fp;
+
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+    fp = (JSStackFrame *)
+         JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
+    if (!fp)
+        return JS_TRUE;
+    JS_ASSERT(fp->argsobj);
+
+    slot = JSVAL_TO_INT(id);
+    switch (slot) {
+      case ARGS_CALLEE:
+        if (!TEST_OVERRIDE_BIT(fp, slot))
+            *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object);
+        break;
+
+      case ARGS_LENGTH:
+        if (!TEST_OVERRIDE_BIT(fp, slot))
+            *vp = INT_TO_JSVAL((jsint)fp->argc);
+        break;
+
+      default:
+        if ((uintN)slot < fp->argc && !ArgWasDeleted(cx, fp, slot))
+            *vp = fp->argv[slot];
+        break;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+args_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSStackFrame *fp;
+    jsint slot;
+
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+    fp = (JSStackFrame *)
+         JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
+    if (!fp)
+        return JS_TRUE;
+    JS_ASSERT(fp->argsobj);
+
+    slot = JSVAL_TO_INT(id);
+    switch (slot) {
+      case ARGS_CALLEE:
+      case ARGS_LENGTH:
+        SET_OVERRIDE_BIT(fp, slot);
+        break;
+
+      default:
+        if (fp->fun->interpreted &&
+            (uintN)slot < fp->argc &&
+            !ArgWasDeleted(cx, fp, slot)) {
+            fp->argv[slot] = *vp;
+        }
+        break;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+args_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
+             JSObject **objp)
+{
+    JSStackFrame *fp;
+    uintN slot;
+    JSString *str;
+    JSAtom *atom;
+    intN tinyid;
+    jsval value;
+
+    *objp = NULL;
+    fp = (JSStackFrame *)
+         JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
+    if (!fp)
+        return JS_TRUE;
+    JS_ASSERT(fp->argsobj);
+
+    if (JSVAL_IS_INT(id)) {
+        slot = JSVAL_TO_INT(id);
+        if (slot < fp->argc && !ArgWasDeleted(cx, fp, slot)) {
+            /* XXX ECMA specs DontEnum, contrary to other array-like objects */
+            if (!js_DefineProperty(cx, obj, INT_JSVAL_TO_JSID(id),
+                                   fp->argv[slot],
+                                   args_getProperty, args_setProperty,
+                                   JS_VERSION_IS_ECMA(cx)
+                                   ? 0
+                                   : JSPROP_ENUMERATE,
+                                   NULL)) {
+                return JS_FALSE;
+            }
+            *objp = obj;
+        }
+    } else {
+        str = JSVAL_TO_STRING(id);
+        atom = cx->runtime->atomState.lengthAtom;
+        if (str == ATOM_TO_STRING(atom)) {
+            tinyid = ARGS_LENGTH;
+            value = INT_TO_JSVAL(fp->argc);
+        } else {
+            atom = cx->runtime->atomState.calleeAtom;
+            if (str == ATOM_TO_STRING(atom)) {
+                tinyid = ARGS_CALLEE;
+                value = fp->argv ? fp->argv[-2]
+                                 : OBJECT_TO_JSVAL(fp->fun->object);
+            } else {
+                atom = NULL;
+
+                /* Quell GCC overwarnings. */
+                tinyid = 0;
+                value = JSVAL_NULL;
+            }
+        }
+
+        if (atom && !TEST_OVERRIDE_BIT(fp, tinyid)) {
+            if (!js_DefineNativeProperty(cx, obj, ATOM_TO_JSID(atom), value,
+                                         args_getProperty, args_setProperty, 0,
+                                         SPROP_HAS_SHORTID, tinyid, NULL)) {
+                return JS_FALSE;
+            }
+            *objp = obj;
+        }
+    }
+
+    return JS_TRUE;
+}
+
+static JSBool
+args_enumerate(JSContext *cx, JSObject *obj)
+{
+    JSStackFrame *fp;
+    JSObject *pobj;
+    JSProperty *prop;
+    uintN slot, argc;
+
+    fp = (JSStackFrame *)
+         JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL);
+    if (!fp)
+        return JS_TRUE;
+    JS_ASSERT(fp->argsobj);
+
+    /*
+     * Trigger reflection with value snapshot in args_resolve using a series
+     * of js_LookupProperty calls.  We handle length, callee, and the indexed
+     * argument properties.  We know that args_resolve covers all these cases
+     * and creates direct properties of obj, but that it may fail to resolve
+     * length or callee if overridden.
+     */
+    if (!js_LookupProperty(cx, obj,
+                           ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
+                           &pobj, &prop)) {
+        return JS_FALSE;
+    }
+    if (prop)
+        OBJ_DROP_PROPERTY(cx, pobj, prop);
+
+    if (!js_LookupProperty(cx, obj,
+                           ATOM_TO_JSID(cx->runtime->atomState.calleeAtom),
+                           &pobj, &prop)) {
+        return JS_FALSE;
+    }
+    if (prop)
+        OBJ_DROP_PROPERTY(cx, pobj, prop);
+
+    argc = fp->argc;
+    for (slot = 0; slot < argc; slot++) {
+        if (!js_LookupProperty(cx, obj, INT_TO_JSID((jsint)slot), &pobj, &prop))
+            return JS_FALSE;
+        if (prop)
+            OBJ_DROP_PROPERTY(cx, pobj, prop);
+    }
+    return JS_TRUE;
+}
+
+/*
+ * The Arguments class is not initialized via JS_InitClass, and must not be,
+ * because its name is "Object".  Per ECMA, that causes instances of it to
+ * delegate to the object named by Object.prototype.  It also ensures that
+ * arguments.toString() returns "[object Object]".
+ *
+ * The JSClass functions below collaborate to lazily reflect and synchronize
+ * actual argument values, argument count, and callee function object stored
+ * in a JSStackFrame with their corresponding property values in the frame's
+ * arguments object.
+ */
+JSClass js_ArgumentsClass = {
+    js_Object_str,
+    JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1),
+    JS_PropertyStub,  args_delProperty,
+    args_getProperty, args_setProperty,
+    args_enumerate,   (JSResolveOp) args_resolve,
+    JS_ConvertStub,   JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+#endif /* JS_HAS_ARGS_OBJECT */
+
+#if JS_HAS_CALL_OBJECT
+
+JSObject *
+js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent)
+{
+    JSObject *callobj, *funobj;
+
+    /* Create a call object for fp only if it lacks one. */
+    JS_ASSERT(fp->fun);
+    callobj = fp->callobj;
+    if (callobj)
+        return callobj;
+    JS_ASSERT(fp->fun);
+
+    /* The default call parent is its function's parent (static link). */
+    if (!parent) {
+        funobj = fp->argv ? JSVAL_TO_OBJECT(fp->argv[-2]) : fp->fun->object;
+        if (funobj)
+            parent = OBJ_GET_PARENT(cx, funobj);
+    }
+
+    /* Create the call object and link it to its stack frame. */
+    callobj = js_NewObject(cx, &js_CallClass, NULL, parent);
+    if (!callobj || !JS_SetPrivate(cx, callobj, fp)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+    fp->callobj = callobj;
+
+    /* Make callobj be the scope chain and the variables object. */
+    fp->scopeChain = callobj;
+    fp->varobj = callobj;
+    return callobj;
+}
+
+static JSBool
+call_enumerate(JSContext *cx, JSObject *obj);
+
+JSBool
+js_PutCallObject(JSContext *cx, JSStackFrame *fp)
+{
+    JSObject *callobj;
+    JSBool ok;
+    jsid argsid;
+    jsval aval;
+
+    /*
+     * Reuse call_enumerate here to reflect all actual args and vars into the
+     * call object from fp.
+     */
+    callobj = fp->callobj;
+    if (!callobj)
+        return JS_TRUE;
+    ok = call_enumerate(cx, callobj);
+
+    /*
+     * Get the arguments object to snapshot fp's actual argument values.
+     */
+    if (fp->argsobj) {
+        argsid = ATOM_TO_JSID(cx->runtime->atomState.argumentsAtom);
+        ok &= js_GetProperty(cx, callobj, argsid, &aval);
+        ok &= js_SetProperty(cx, callobj, argsid, &aval);
+        ok &= js_PutArgsObject(cx, fp);
+    }
+
+    /*
+     * Clear the private pointer to fp, which is about to go away (js_Invoke).
+     * Do this last because the call_enumerate and js_GetProperty calls above
+     * need to follow the private slot to find fp.
+     */
+    ok &= JS_SetPrivate(cx, callobj, NULL);
+    fp->callobj = NULL;
+    return ok;
+}
+
+static JSPropertySpec call_props[] = {
+    {js_arguments_str,  CALL_ARGUMENTS, JSPROP_PERMANENT,0,0},
+    {"__callee__",      CALL_CALLEE,    0,0,0},
+    {0,0,0,0,0}
+};
+
+static JSBool
+call_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSStackFrame *fp;
+    jsint slot;
+
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+    fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
+    if (!fp)
+        return JS_TRUE;
+    JS_ASSERT(fp->fun);
+
+    slot = JSVAL_TO_INT(id);
+    switch (slot) {
+      case CALL_ARGUMENTS:
+        if (!TEST_OVERRIDE_BIT(fp, slot)) {
+            JSObject *argsobj = js_GetArgsObject(cx, fp);
+            if (!argsobj)
+                return JS_FALSE;
+            *vp = OBJECT_TO_JSVAL(argsobj);
+        }
+        break;
+
+      case CALL_CALLEE:
+        if (!TEST_OVERRIDE_BIT(fp, slot))
+            *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object);
+        break;
+
+      default:
+        if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs))
+            *vp = fp->argv[slot];
+        break;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+call_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSStackFrame *fp;
+    jsint slot;
+
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+    fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
+    if (!fp)
+        return JS_TRUE;
+    JS_ASSERT(fp->fun);
+
+    slot = JSVAL_TO_INT(id);
+    switch (slot) {
+      case CALL_ARGUMENTS:
+      case CALL_CALLEE:
+        SET_OVERRIDE_BIT(fp, slot);
+        break;
+
+      default:
+        if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs))
+            fp->argv[slot] = *vp;
+        break;
+    }
+    return JS_TRUE;
+}
+
+JSBool
+js_GetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSStackFrame *fp;
+
+    JS_ASSERT(JSVAL_IS_INT(id));
+    fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
+    if (fp) {
+        /* XXX no jsint slot commoning here to avoid MSVC1.52 crashes */
+        if ((uintN)JSVAL_TO_INT(id) < fp->nvars)
+            *vp = fp->vars[JSVAL_TO_INT(id)];
+    }
+    return JS_TRUE;
+}
+
+JSBool
+js_SetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSStackFrame *fp;
+
+    JS_ASSERT(JSVAL_IS_INT(id));
+    fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
+    if (fp) {
+        /* XXX jsint slot is block-local here to avoid MSVC1.52 crashes */
+        jsint slot = JSVAL_TO_INT(id);
+        if ((uintN)slot < fp->nvars)
+            fp->vars[slot] = *vp;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+call_enumerate(JSContext *cx, JSObject *obj)
+{
+    JSStackFrame *fp;
+    JSObject *funobj;
+    JSScope *scope;
+    JSScopeProperty *sprop, *cprop;
+    JSPropertyOp getter;
+    jsval *vec;
+    JSAtom *atom;
+    JSProperty *prop;
+
+    fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
+    if (!fp)
+        return JS_TRUE;
+
+    /*
+     * Do not enumerate a cloned function object at fp->argv[-2], it may have
+     * gained its own (mutable) scope (e.g., a brutally-shared XUL script sets
+     * the clone's prototype property).  We must enumerate the function object
+     * that was decorated with parameter and local variable properties by the
+     * compiler when the compiler created fp->fun, namely fp->fun->object.
+     *
+     * Contrast with call_resolve, where we prefer fp->argv[-2], because we'll
+     * use js_LookupProperty to find any overridden properties in that object,
+     * if it was a mutated clone; and if not, we will search its prototype,
+     * fp->fun->object, to find compiler-created params and locals.
+     */
+    funobj = fp->fun->object;
+    if (!funobj)
+        return JS_TRUE;
+
+    /*
+     * Reflect actual args from fp->argv for formal parameters, and local vars
+     * and functions in fp->vars for declared variables and nested-at-top-level
+     * local functions.
+     */
+    scope = OBJ_SCOPE(funobj);
+    for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
+        getter = sprop->getter;
+        if (getter == js_GetArgument)
+            vec = fp->argv;
+        else if (getter == js_GetLocalVariable)
+            vec = fp->vars;
+        else
+            continue;
+
+        /* Trigger reflection by looking up the unhidden atom for sprop->id. */
+        JS_ASSERT(JSID_IS_ATOM(sprop->id));
+        atom = JSID_TO_ATOM(sprop->id);
+        JS_ASSERT(atom->flags & ATOM_HIDDEN);
+        atom = atom->entry.value;
+
+        if (!js_LookupProperty(cx, obj, ATOM_TO_JSID(atom), &obj, &prop))
+            return JS_FALSE;
+        JS_ASSERT(obj && prop);
+        cprop = (JSScopeProperty *)prop;
+        LOCKED_OBJ_SET_SLOT(obj, cprop->slot, vec[(uint16) sprop->shortid]);
+        OBJ_DROP_PROPERTY(cx, obj, prop);
+    }
+
+    return JS_TRUE;
+}
+
+static JSBool
+call_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
+             JSObject **objp)
+{
+    JSStackFrame *fp;
+    JSObject *funobj;
+    JSString *str;
+    JSAtom *atom;
+    JSObject *obj2;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+    JSPropertyOp getter, setter;
+    uintN attrs, slot, nslots, spflags;
+    jsval *vp, value;
+    intN shortid;
+
+    fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
+    if (!fp)
+        return JS_TRUE;
+    JS_ASSERT(fp->fun);
+
+    if (!JSVAL_IS_STRING(id))
+        return JS_TRUE;
+
+    funobj = fp->argv ? JSVAL_TO_OBJECT(fp->argv[-2]) : fp->fun->object;
+    if (!funobj)
+        return JS_TRUE;
+    JS_ASSERT((JSFunction *) JS_GetPrivate(cx, funobj) == fp->fun);
+
+    str = JSVAL_TO_STRING(id);
+    atom = js_AtomizeString(cx, str, 0);
+    if (!atom)
+        return JS_FALSE;
+    if (!js_LookupHiddenProperty(cx, funobj, ATOM_TO_JSID(atom), &obj2, &prop))
+        return JS_FALSE;
+
+    if (prop) {
+        if (!OBJ_IS_NATIVE(obj2)) {
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+            return JS_TRUE;
+        }
+
+        sprop = (JSScopeProperty *) prop;
+        getter = sprop->getter;
+        attrs = sprop->attrs & ~JSPROP_SHARED;
+        slot = (uintN) sprop->shortid;
+        OBJ_DROP_PROPERTY(cx, obj2, prop);
+
+        /* Ensure we found an arg or var property for the same function. */
+        if ((sprop->flags & SPROP_IS_HIDDEN) &&
+            (obj2 == funobj ||
+             (JSFunction *) JS_GetPrivate(cx, obj2) == fp->fun)) {
+            if (getter == js_GetArgument) {
+                vp = fp->argv;
+                nslots = JS_MAX(fp->argc, fp->fun->nargs);
+                getter = setter = NULL;
+            } else {
+                JS_ASSERT(getter == js_GetLocalVariable);
+                vp = fp->vars;
+                nslots = fp->nvars;
+                getter = js_GetCallVariable;
+                setter = js_SetCallVariable;
+            }
+            if (slot < nslots) {
+                value = vp[slot];
+                spflags = SPROP_HAS_SHORTID;
+                shortid = (intN) slot;
+            } else {
+                value = JSVAL_VOID;
+                spflags = 0;
+                shortid = 0;
+            }
+            if (!js_DefineNativeProperty(cx, obj, ATOM_TO_JSID(atom), value,
+                                         getter, setter, attrs,
+                                         spflags, shortid, NULL)) {
+                return JS_FALSE;
+            }
+            *objp = obj;
+        }
+    }
+
+    return JS_TRUE;
+}
+
+static JSBool
+call_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
+{
+    JSStackFrame *fp;
+
+    if (type == JSTYPE_FUNCTION) {
+        fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
+        if (fp) {
+            JS_ASSERT(fp->fun);
+            *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object);
+        }
+    }
+    return JS_TRUE;
+}
+
+JSClass js_CallClass = {
+    js_Call_str,
+    JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
+    JS_PropertyStub,  JS_PropertyStub,
+    call_getProperty, call_setProperty,
+    call_enumerate,   (JSResolveOp)call_resolve,
+    call_convert,     JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+#endif /* JS_HAS_CALL_OBJECT */
+
+/* SHARED because fun_getProperty always computes a new value. */
+#define FUNCTION_PROP_ATTRS (JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED)
+
+static JSPropertySpec function_props[] = {
+    {js_arguments_str, CALL_ARGUMENTS, FUNCTION_PROP_ATTRS,0,0},
+    {js_arity_str,     FUN_ARITY,      FUNCTION_PROP_ATTRS,0,0},
+    {js_length_str,    ARGS_LENGTH,    FUNCTION_PROP_ATTRS,0,0},
+    {js_name_str,      FUN_NAME,       FUNCTION_PROP_ATTRS,0,0},
+    {js_caller_str,    FUN_CALLER,     FUNCTION_PROP_ATTRS,0,0},
+    {0,0,0,0,0}
+};
+
+static JSBool
+fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    jsint slot;
+    JSFunction *fun;
+    JSStackFrame *fp;
+
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+    slot = JSVAL_TO_INT(id);
+
+    /* No valid function object should lack private data, but check anyway. */
+    fun = (JSFunction *)JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL);
+    if (!fun)
+        return JS_TRUE;
+
+    /* Find fun's top-most activation record. */
+    for (fp = cx->fp; fp && (fp->fun != fun || (fp->flags & JSFRAME_SPECIAL));
+         fp = fp->down) {
+        continue;
+    }
+
+    switch (slot) {
+      case CALL_ARGUMENTS:
+#if JS_HAS_ARGS_OBJECT
+        /* Warn if strict about f.arguments or equivalent unqualified uses. */
+        if (!JS_ReportErrorFlagsAndNumber(cx,
+                                          JSREPORT_WARNING | JSREPORT_STRICT,
+                                          js_GetErrorMessage, NULL,
+                                          JSMSG_DEPRECATED_USAGE,
+                                          js_arguments_str)) {
+            return JS_FALSE;
+        }
+        if (fp) {
+            if (!js_GetArgsValue(cx, fp, vp))
+                return JS_FALSE;
+        } else {
+            *vp = JSVAL_NULL;
+        }
+        break;
+#else  /* !JS_HAS_ARGS_OBJECT */
+        *vp = OBJECT_TO_JSVAL(fp ? obj : NULL);
+        break;
+#endif /* !JS_HAS_ARGS_OBJECT */
+
+      case ARGS_LENGTH:
+        if (!JS_VERSION_IS_ECMA(cx))
+            *vp = INT_TO_JSVAL((jsint)(fp && fp->fun ? fp->argc : fun->nargs));
+        else
+      case FUN_ARITY:
+            *vp = INT_TO_JSVAL((jsint)fun->nargs);
+        break;
+
+      case FUN_NAME:
+        *vp = fun->atom
+              ? ATOM_KEY(fun->atom)
+              : STRING_TO_JSVAL(cx->runtime->emptyString);
+        break;
+
+      case FUN_CALLER:
+        while (fp && (fp->flags & JSFRAME_SKIP_CALLER) && fp->down)
+            fp = fp->down;
+        if (fp && fp->down && fp->down->fun && fp->down->argv)
+            *vp = fp->down->argv[-2];
+        else
+            *vp = JSVAL_NULL;
+        if (!JSVAL_IS_PRIMITIVE(*vp) && cx->runtime->checkObjectAccess) {
+            id = ATOM_KEY(cx->runtime->atomState.callerAtom);
+            if (!cx->runtime->checkObjectAccess(cx, obj, id, JSACC_READ, vp))
+                return JS_FALSE;
+        }
+        break;
+
+      default:
+        /* XXX fun[0] and fun.arguments[0] are equivalent. */
+        if (fp && fp->fun && (uintN)slot < fp->fun->nargs)
+            *vp = fp->argv[slot];
+        break;
+    }
+
+    return JS_TRUE;
+}
+
+static JSBool
+fun_enumerate(JSContext *cx, JSObject *obj)
+{
+    jsid prototypeId;
+    JSObject *pobj;
+    JSProperty *prop;
+
+    prototypeId = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
+    if (!OBJ_LOOKUP_PROPERTY(cx, obj, prototypeId, &pobj, &prop))
+        return JS_FALSE;
+    JS_ASSERT(prop);
+    OBJ_DROP_PROPERTY(cx, pobj, prop);
+    return JS_TRUE;
+}
+
+static JSBool
+fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
+            JSObject **objp)
+{
+    JSFunction *fun;
+    JSString *str;
+    JSAtom *prototypeAtom;
+
+    if (!JSVAL_IS_STRING(id))
+        return JS_TRUE;
+
+    /* No valid function object should lack private data, but check anyway. */
+    fun = (JSFunction *)JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL);
+    if (!fun || !fun->object)
+        return JS_TRUE;
+
+    /* No need to reflect fun.prototype in 'fun.prototype = ...'. */
+    if (flags & JSRESOLVE_ASSIGNING)
+        return JS_TRUE;
+
+    /*
+     * Ok, check whether id is 'prototype' and bootstrap the function object's
+     * prototype property.
+     */
+    str = JSVAL_TO_STRING(id);
+    prototypeAtom = cx->runtime->atomState.classPrototypeAtom;
+    if (str == ATOM_TO_STRING(prototypeAtom)) {
+        JSObject *proto, *parentProto;
+        jsval pval;
+
+        proto = parentProto = NULL;
+        if (fun->object != obj && fun->object) {
+            /*
+             * Clone of a function: make its prototype property value have the
+             * same class as the clone-parent's prototype.
+             */
+            if (!OBJ_GET_PROPERTY(cx, fun->object, ATOM_TO_JSID(prototypeAtom),
+                                  &pval)) {
+                return JS_FALSE;
+            }
+            if (!JSVAL_IS_PRIMITIVE(pval)) {
+                /*
+                 * We are about to allocate a new object, so hack the newborn
+                 * root until then to protect pval in case it is figuratively
+                 * up in the air, with no strong refs protecting it.
+                 */
+                cx->newborn[GCX_OBJECT] = JSVAL_TO_GCTHING(pval);
+                parentProto = JSVAL_TO_OBJECT(pval);
+            }
+        }
+
+        /*
+         * Beware of the wacky case of a user function named Object -- trying
+         * to find a prototype for that will recur back here _ad perniciem_.
+         */
+        if (!parentProto && fun->atom == cx->runtime->atomState.ObjectAtom)
+            return JS_TRUE;
+
+        /*
+         * If resolving "prototype" in a clone, clone the parent's prototype.
+         * Pass the constructor's (obj's) parent as the prototype parent, to
+         * avoid defaulting to parentProto.constructor.__parent__.
+         */
+        proto = js_NewObject(cx, &js_ObjectClass, parentProto,
+                             OBJ_GET_PARENT(cx, obj));
+        if (!proto)
+            return JS_FALSE;
+
+        /*
+         * ECMA (15.3.5.2) says that constructor.prototype is DontDelete for
+         * user-defined functions, but DontEnum | ReadOnly | DontDelete for
+         * native "system" constructors such as Object or Function.  So lazily
+         * set the former here in fun_resolve, but eagerly define the latter
+         * in JS_InitClass, with the right attributes.
+         */
+        if (!js_SetClassPrototype(cx, obj, proto,
+                                  JSPROP_ENUMERATE | JSPROP_PERMANENT)) {
+            cx->newborn[GCX_OBJECT] = NULL;
+            return JS_FALSE;
+        }
+        *objp = obj;
+    }
+
+    return JS_TRUE;
+}
+
+static JSBool
+fun_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
+{
+    switch (type) {
+      case JSTYPE_FUNCTION:
+        *vp = OBJECT_TO_JSVAL(obj);
+        return JS_TRUE;
+      default:
+        return js_TryValueOf(cx, obj, type, vp);
+    }
+}
+
+static void
+fun_finalize(JSContext *cx, JSObject *obj)
+{
+    JSFunction *fun;
+
+    /* No valid function object should lack private data, but check anyway. */
+    fun = (JSFunction *) JS_GetPrivate(cx, obj);
+    if (!fun)
+        return;
+    if (fun->object == obj)
+        fun->object = NULL;
+    JS_ATOMIC_DECREMENT(&fun->nrefs);
+    if (fun->nrefs)
+        return;
+
+    /* Null-check required since the parser sets interpreted very early. */
+    if (fun->interpreted && fun->u.script)
+        js_DestroyScript(cx, fun->u.script);
+}
+
+#if JS_HAS_XDR
+
+#include "jsxdrapi.h"
+
+enum {
+    JSXDR_FUNARG = 1,
+    JSXDR_FUNVAR = 2,
+    JSXDR_FUNCONST = 3
+};
+
+/* XXX store parent and proto, if defined */
+static JSBool
+fun_xdrObject(JSXDRState *xdr, JSObject **objp)
+{
+    JSContext *cx;
+    JSFunction *fun;
+    JSString *atomstr;
+    uint32 flagsword;           /* originally only flags was JS_XDRUint8'd */
+    char *propname;
+    JSScopeProperty *sprop;
+    uint32 userid;              /* NB: holds a signed int-tagged jsval */
+    JSAtom *atom;
+    uintN i, n, dupflag;
+    uint32 type;
+#ifdef DEBUG
+    uintN nvars = 0, nargs = 0;
+#endif
+
+    cx = xdr->cx;
+    if (xdr->mode == JSXDR_ENCODE) {
+        /*
+         * No valid function object should lack private data, but fail soft
+         * (return true, no error report) in case one does due to API pilot
+         * or internal error.
+         */
+        fun = (JSFunction *) JS_GetPrivate(cx, *objp);
+        if (!fun)
+            return JS_TRUE;
+        if (!fun->interpreted) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_NOT_SCRIPTED_FUNCTION,
+                                 JS_GetFunctionName(fun));
+            return JS_FALSE;
+        }
+        atomstr = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
+        flagsword = ((uint32)fun->nregexps << 16) | fun->flags;
+    } else {
+        fun = js_NewFunction(cx, NULL, NULL, 0, 0, NULL, NULL);
+        if (!fun)
+            return JS_FALSE;
+        atomstr = NULL;
+    }
+
+    if (!JS_XDRStringOrNull(xdr, &atomstr) ||
+        !JS_XDRUint16(xdr, &fun->nargs) ||
+        !JS_XDRUint16(xdr, &fun->extra) ||
+        !JS_XDRUint16(xdr, &fun->nvars) ||
+        !JS_XDRUint32(xdr, &flagsword)) {
+        return JS_FALSE;
+    }
+
+    /* do arguments and local vars */
+    if (fun->object) {
+        n = fun->nargs + fun->nvars;
+        if (xdr->mode == JSXDR_ENCODE) {
+            JSScope *scope;
+            JSScopeProperty **spvec, *auto_spvec[8];
+            void *mark;
+
+            if (n <= sizeof auto_spvec / sizeof auto_spvec[0]) {
+                spvec = auto_spvec;
+                mark = NULL;
+            } else {
+                mark = JS_ARENA_MARK(&cx->tempPool);
+                JS_ARENA_ALLOCATE_CAST(spvec, JSScopeProperty **, &cx->tempPool,
+                                       n * sizeof(JSScopeProperty *));
+                if (!spvec) {
+                    JS_ReportOutOfMemory(cx);
+                    return JS_FALSE;
+                }
+            }
+            scope = OBJ_SCOPE(fun->object);
+            for (sprop = SCOPE_LAST_PROP(scope); sprop;
+                 sprop = sprop->parent) {
+                if (sprop->getter == js_GetArgument) {
+                    JS_ASSERT(nargs++ <= fun->nargs);
+                    spvec[sprop->shortid] = sprop;
+                } else if (sprop->getter == js_GetLocalVariable) {
+                    JS_ASSERT(nvars++ <= fun->nvars);
+                    spvec[fun->nargs + sprop->shortid] = sprop;
+                }
+            }
+            for (i = 0; i < n; i++) {
+                sprop = spvec[i];
+                JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
+                type = (i < fun->nargs)
+                       ? JSXDR_FUNARG
+                       : (sprop->attrs & JSPROP_READONLY)
+                       ? JSXDR_FUNCONST
+                       : JSXDR_FUNVAR;
+                userid = INT_TO_JSVAL(sprop->shortid);
+                /* XXX lossy conversion, need new XDR version for ECMAv3 */
+                propname = JS_GetStringBytes(ATOM_TO_STRING(JSID_TO_ATOM(sprop->id)));
+                if (!propname ||
+                    !JS_XDRUint32(xdr, &type) ||
+                    !JS_XDRUint32(xdr, &userid) ||
+                    !JS_XDRCString(xdr, &propname)) {
+                    if (mark)
+                        JS_ARENA_RELEASE(&cx->tempPool, mark);
+                    return JS_FALSE;
+                }
+            }
+            if (mark)
+                JS_ARENA_RELEASE(&cx->tempPool, mark);
+        } else {
+            JSPropertyOp getter, setter;
+
+            for (i = n; i != 0; i--) {
+                uintN attrs = JSPROP_PERMANENT;
+
+                if (!JS_XDRUint32(xdr, &type) ||
+                    !JS_XDRUint32(xdr, &userid) ||
+                    !JS_XDRCString(xdr, &propname)) {
+                    return JS_FALSE;
+                }
+                JS_ASSERT(type == JSXDR_FUNARG || type == JSXDR_FUNVAR ||
+                          type == JSXDR_FUNCONST);
+                if (type == JSXDR_FUNARG) {
+                    getter = js_GetArgument;
+                    setter = js_SetArgument;
+                    JS_ASSERT(nargs++ <= fun->nargs);
+                } else if (type == JSXDR_FUNVAR || type == JSXDR_FUNCONST) {
+                    getter = js_GetLocalVariable;
+                    setter = js_SetLocalVariable;
+                    if (type == JSXDR_FUNCONST)
+                        attrs |= JSPROP_READONLY;
+                    JS_ASSERT(nvars++ <= fun->nvars);
+                } else {
+                    getter = NULL;
+                    setter = NULL;
+                }
+                atom = js_Atomize(cx, propname, strlen(propname), 0);
+                JS_free(cx, propname);
+                if (!atom)
+                    return JS_FALSE;
+
+                /* Flag duplicate argument if atom is bound in fun->object. */
+                dupflag = SCOPE_GET_PROPERTY(OBJ_SCOPE(fun->object),
+                                             ATOM_TO_JSID(atom))
+                          ? SPROP_IS_DUPLICATE
+                          : 0;
+
+                if (!js_AddHiddenProperty(cx, fun->object, ATOM_TO_JSID(atom),
+                                          getter, setter, SPROP_INVALID_SLOT,
+                                          attrs | JSPROP_SHARED,
+                                          dupflag | SPROP_HAS_SHORTID,
+                                          JSVAL_TO_INT(userid))) {
+                    return JS_FALSE;
+                }
+            }
+        }
+    }
+
+    if (!js_XDRScript(xdr, &fun->u.script, NULL))
+        return JS_FALSE;
+
+    if (xdr->mode == JSXDR_DECODE) {
+        fun->interpreted = JS_TRUE;
+        fun->flags = (uint8) flagsword;
+        fun->nregexps = (uint16) (flagsword >> 16);
+
+        *objp = fun->object;
+        if (atomstr) {
+            /* XXX only if this was a top-level function! */
+            fun->atom = js_AtomizeString(cx, atomstr, 0);
+            if (!fun->atom)
+                return JS_FALSE;
+        }
+
+        js_CallNewScriptHook(cx, fun->u.script, fun);
+    }
+
+    return JS_TRUE;
+}
+
+#else  /* !JS_HAS_XDR */
+
+#define fun_xdrObject NULL
+
+#endif /* !JS_HAS_XDR */
+
+#if JS_HAS_INSTANCEOF
+
+/*
+ * [[HasInstance]] internal method for Function objects: fetch the .prototype
+ * property of its 'this' parameter, and walks the prototype chain of v (only
+ * if v is an object) returning true if .prototype is found.
+ */
+static JSBool
+fun_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
+{
+    jsval pval;
+    JSString *str;
+
+    if (!OBJ_GET_PROPERTY(cx, obj,
+                          ATOM_TO_JSID(cx->runtime->atomState
+                                       .classPrototypeAtom),
+                          &pval)) {
+        return JS_FALSE;
+    }
+
+    if (JSVAL_IS_PRIMITIVE(pval)) {
+        /*
+         * Throw a runtime error if instanceof is called on a function that
+         * has a non-object as its .prototype value.
+         */
+        str = js_DecompileValueGenerator(cx, -1, OBJECT_TO_JSVAL(obj), NULL);
+        if (str) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_BAD_PROTOTYPE, JS_GetStringBytes(str));
+        }
+        return JS_FALSE;
+    }
+
+    return js_IsDelegate(cx, JSVAL_TO_OBJECT(pval), v, bp);
+}
+
+#else  /* !JS_HAS_INSTANCEOF */
+
+#define fun_hasInstance NULL
+
+#endif /* !JS_HAS_INSTANCEOF */
+
+static uint32
+fun_mark(JSContext *cx, JSObject *obj, void *arg)
+{
+    JSFunction *fun;
+
+    fun = (JSFunction *) JS_GetPrivate(cx, obj);
+    if (fun) {
+        JS_MarkGCThing(cx, fun, js_private_str, arg);
+        if (fun->atom)
+            GC_MARK_ATOM(cx, fun->atom, arg);
+        if (fun->interpreted && fun->u.script)
+            js_MarkScript(cx, fun->u.script, arg);
+    }
+    return 0;
+}
+
+static uint32
+fun_reserveSlots(JSContext *cx, JSObject *obj)
+{
+    JSFunction *fun;
+
+    fun = (JSFunction *) JS_GetPrivate(cx, obj);
+    return fun ? fun->nregexps : 0;
+}
+
+/*
+ * Reserve two slots in all function objects for XPConnect.  Note that this
+ * does not bloat every instance, only those on which reserved slots are set,
+ * and those on which ad-hoc properties are defined.
+ */
+JS_FRIEND_DATA(JSClass) js_FunctionClass = {
+    js_Function_str,
+    JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(2),
+    JS_PropertyStub,  JS_PropertyStub,
+    fun_getProperty,  JS_PropertyStub,
+    fun_enumerate,    (JSResolveOp)fun_resolve,
+    fun_convert,      fun_finalize,
+    NULL,             NULL,
+    NULL,             NULL,
+    fun_xdrObject,    fun_hasInstance,
+    fun_mark,         fun_reserveSlots
+};
+
+JSBool
+js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent,
+                uintN argc, jsval *argv, jsval *rval)
+{
+    jsval fval;
+    JSFunction *fun;
+    JSString *str;
+
+    if (!argv) {
+        JS_ASSERT(JS_ObjectIsFunction(cx, obj));
+    } else {
+        fval = argv[-1];
+        if (!JSVAL_IS_FUNCTION(cx, fval)) {
+            /*
+             * If we don't have a function to start off with, try converting
+             * the object to a function.  If that doesn't work, complain.
+             */
+            if (JSVAL_IS_OBJECT(fval)) {
+                obj = JSVAL_TO_OBJECT(fval);
+                if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, JSTYPE_FUNCTION,
+                                                     &fval)) {
+                    return JS_FALSE;
+                }
+                argv[-1] = fval;
+            }
+            if (!JSVAL_IS_FUNCTION(cx, fval)) {
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_INCOMPATIBLE_PROTO,
+                                     js_Function_str, js_toString_str,
+                                     JS_GetTypeName(cx,
+                                                    JS_TypeOfValue(cx, fval)));
+                return JS_FALSE;
+            }
+        }
+
+        obj = JSVAL_TO_OBJECT(fval);
+    }
+
+    fun = (JSFunction *) JS_GetPrivate(cx, obj);
+    if (!fun)
+        return JS_TRUE;
+    if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
+        return JS_FALSE;
+    str = JS_DecompileFunction(cx, fun, (uintN)indent);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+fun_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return js_fun_toString(cx, obj, 0, argc, argv, rval);
+}
+
+#if JS_HAS_TOSOURCE
+static JSBool
+fun_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return js_fun_toString(cx, obj, JS_DONT_PRETTY_PRINT, argc, argv, rval);
+}
+#endif
+
+static const char call_str[] = "call";
+
+#if JS_HAS_CALL_FUNCTION
+static JSBool
+fun_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval fval, *sp, *oldsp;
+    JSObject *tmp;
+    void *mark;
+    uintN i;
+    JSStackFrame *fp;
+    JSBool ok;
+
+    if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &argv[-1]))
+        return JS_FALSE;
+    fval = argv[-1];
+
+    if (!JSVAL_IS_FUNCTION(cx, fval)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_INCOMPATIBLE_PROTO,
+                             js_Function_str, call_str,
+                             JS_GetStringBytes(JS_ValueToString(cx, fval)));
+        return JS_FALSE;
+    }
+
+    if (argc == 0) {
+        /* Call fun with its global object as the 'this' param if no args. */
+        while ((tmp = OBJ_GET_PARENT(cx, obj)) != NULL)
+            obj = tmp;
+    } else {
+        /* Otherwise convert the first arg to 'this' and skip over it. */
+        if (!js_ValueToObject(cx, argv[0], &obj))
+            return JS_FALSE;
+        argc--;
+        argv++;
+    }
+
+    /* Allocate stack space for fval, obj, and the args. */
+    sp = js_AllocStack(cx, 2 + argc, &mark);
+    if (!sp)
+        return JS_FALSE;
+
+    /* Push fval, obj, and the args. */
+    *sp++ = fval;
+    *sp++ = OBJECT_TO_JSVAL(obj);
+    for (i = 0; i < argc; i++)
+        *sp++ = argv[i];
+
+    /* Lift current frame to include the args and do the call. */
+    fp = cx->fp;
+    oldsp = fp->sp;
+    fp->sp = sp;
+    ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL | JSINVOKE_SKIP_CALLER);
+
+    /* Store rval and pop stack back to our frame's sp. */
+    *rval = fp->sp[-1];
+    fp->sp = oldsp;
+    js_FreeStack(cx, mark);
+    return ok;
+}
+#endif /* JS_HAS_CALL_FUNCTION */
+
+#if JS_HAS_APPLY_FUNCTION
+static JSBool
+fun_apply(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval fval, *sp, *oldsp;
+    JSObject *aobj;
+    jsuint length;
+    void *mark;
+    uintN i;
+    JSBool ok;
+    JSStackFrame *fp;
+
+    if (argc == 0) {
+        /* Will get globalObject as 'this' and no other arguments. */
+        return fun_call(cx, obj, argc, argv, rval);
+    }
+
+    if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &argv[-1]))
+        return JS_FALSE;
+    fval = argv[-1];
+
+    if (!JSVAL_IS_FUNCTION(cx, fval)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_INCOMPATIBLE_PROTO,
+                             js_Function_str, "apply",
+                             JS_GetStringBytes(JS_ValueToString(cx, fval)));
+        return JS_FALSE;
+    }
+
+    /* Quell GCC overwarnings. */
+    aobj = NULL;
+    length = 0;
+
+    if (argc >= 2) {
+        /* If the 2nd arg is null or void, call the function with 0 args. */
+        if (JSVAL_IS_NULL(argv[1]) || JSVAL_IS_VOID(argv[1])) {
+            argc = 0;
+        } else {
+            /* The second arg must be an array (or arguments object). */
+            if (JSVAL_IS_PRIMITIVE(argv[1]) ||
+                (aobj = JSVAL_TO_OBJECT(argv[1]),
+                OBJ_GET_CLASS(cx, aobj) != &js_ArgumentsClass &&
+                OBJ_GET_CLASS(cx, aobj) != &js_ArrayClass))
+            {
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_BAD_APPLY_ARGS);
+                return JS_FALSE;
+            }
+            if (!js_GetLengthProperty(cx, aobj, &length))
+                return JS_FALSE;
+        }
+    }
+
+    /* Convert the first arg to 'this' and skip over it. */
+    if (!js_ValueToObject(cx, argv[0], &obj))
+        return JS_FALSE;
+
+    /* Allocate stack space for fval, obj, and the args. */
+    argc = (uintN)JS_MIN(length, ARGC_LIMIT - 1);
+    sp = js_AllocStack(cx, 2 + argc, &mark);
+    if (!sp)
+        return JS_FALSE;
+
+    /* Push fval, obj, and aobj's elements as args. */
+    *sp++ = fval;
+    *sp++ = OBJECT_TO_JSVAL(obj);
+    for (i = 0; i < argc; i++) {
+        ok = JS_GetElement(cx, aobj, (jsint)i, sp);
+        if (!ok)
+            goto out;
+        sp++;
+    }
+
+    /* Lift current frame to include the args and do the call. */
+    fp = cx->fp;
+    oldsp = fp->sp;
+    fp->sp = sp;
+    ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL | JSINVOKE_SKIP_CALLER);
+
+    /* Store rval and pop stack back to our frame's sp. */
+    *rval = fp->sp[-1];
+    fp->sp = oldsp;
+out:
+    js_FreeStack(cx, mark);
+    return ok;
+}
+#endif /* JS_HAS_APPLY_FUNCTION */
+
+static JSFunctionSpec function_methods[] = {
+#if JS_HAS_TOSOURCE
+    {js_toSource_str,   fun_toSource,   0,0,0},
+#endif
+    {js_toString_str,   fun_toString,   1,0,0},
+#if JS_HAS_APPLY_FUNCTION
+    {"apply",           fun_apply,      2,0,0},
+#endif
+#if JS_HAS_CALL_FUNCTION
+    {call_str,          fun_call,       1,0,0},
+#endif
+    {0,0,0,0,0}
+};
+
+JSBool
+js_IsIdentifier(JSString *str)
+{
+    size_t n;
+    jschar *s, c;
+
+    n = JSSTRING_LENGTH(str);
+    if (n == 0)
+        return JS_FALSE;
+    s = JSSTRING_CHARS(str);
+    c = *s;
+    if (!JS_ISIDSTART(c))
+        return JS_FALSE;
+    for (n--; n != 0; n--) {
+        c = *++s;
+        if (!JS_ISIDENT(c))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSStackFrame *fp, *caller;
+    JSFunction *fun;
+    JSObject *parent;
+    uintN i, n, lineno, dupflag;
+    JSAtom *atom;
+    const char *filename;
+    JSObject *obj2;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+    JSString *str, *arg;
+    void *mark;
+    JSTokenStream *ts;
+    JSPrincipals *principals;
+    jschar *collected_args, *cp;
+    size_t arg_length, args_length;
+    JSTokenType tt;
+    JSBool ok;
+
+    fp = cx->fp;
+    if (fp && !(fp->flags & JSFRAME_CONSTRUCTING)) {
+        obj = js_NewObject(cx, &js_FunctionClass, NULL, NULL);
+        if (!obj)
+            return JS_FALSE;
+        *rval = OBJECT_TO_JSVAL(obj);
+    }
+    fun = (JSFunction *) JS_GetPrivate(cx, obj);
+    if (fun)
+        return JS_TRUE;
+
+#if JS_HAS_CALL_OBJECT
+    /*
+     * NB: (new Function) is not lexically closed by its caller, it's just an
+     * anonymous function in the top-level scope that its constructor inhabits.
+     * Thus 'var x = 42; f = new Function("return x"); print(f())' prints 42,
+     * and so would a call to f from another top-level's script or function.
+     *
+     * In older versions, before call objects, a new Function was adopted by
+     * its running context's globalObject, which might be different from the
+     * top-level reachable from scopeChain (in HTML frames, e.g.).
+     */
+    parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(argv[-2]));
+#else
+    /* Set up for dynamic parenting (see js_Invoke in jsinterp.c). */
+    parent = NULL;
+#endif
+
+    fun = js_NewFunction(cx, obj, NULL, 0, JSFUN_LAMBDA, parent,
+                         JS_VERSION_IS_ECMA(cx)
+                         ? cx->runtime->atomState.anonymousAtom
+                         : NULL);
+
+    if (!fun)
+        return JS_FALSE;
+
+    /*
+     * Function is static and not called directly by other functions in this
+     * file, therefore it is callable only as a native function by js_Invoke.
+     * Find the scripted caller, possibly skipping other native frames such as
+     * are built for Function.prototype.call or .apply activations that invoke
+     * Function indirectly from a script.
+     */
+    JS_ASSERT(!fp->script && fp->fun && fp->fun->u.native == Function);
+    caller = JS_GetScriptedCaller(cx, fp);
+    if (caller) {
+        filename = caller->script->filename;
+        lineno = js_PCToLineNumber(cx, caller->script, caller->pc);
+        principals = JS_EvalFramePrincipals(cx, fp, caller);
+    } else {
+        filename = NULL;
+        lineno = 0;
+        principals = NULL;
+    }
+
+    /* Belt-and-braces: check that the caller has access to parent. */
+    if (!js_CheckPrincipalsAccess(cx, parent, principals, "Function"))
+        return JS_FALSE;
+
+    n = argc ? argc - 1 : 0;
+    if (n > 0) {
+        /*
+         * Collect the function-argument arguments into one string, separated
+         * by commas, then make a tokenstream from that string, and scan it to
+         * get the arguments.  We need to throw the full scanner at the
+         * problem, because the argument string can legitimately contain
+         * comments and linefeeds.  XXX It might be better to concatenate
+         * everything up into a function definition and pass it to the
+         * compiler, but doing it this way is less of a delta from the old
+         * code.  See ECMA 15.3.2.1.
+         */
+        args_length = 0;
+        for (i = 0; i < n; i++) {
+            /* Collect the lengths for all the function-argument arguments. */
+            arg = js_ValueToString(cx, argv[i]);
+            if (!arg)
+                return JS_FALSE;
+            argv[i] = STRING_TO_JSVAL(arg);
+            args_length += JSSTRING_LENGTH(arg);
+        }
+        /* Add 1 for each joining comma. */
+        args_length += n - 1;
+
+        /*
+         * Allocate a string to hold the concatenated arguments, including room
+         * for a terminating 0.  Mark cx->tempPool for later release, to free
+         * collected_args and its tokenstream in one swoop.
+         */
+        mark = JS_ARENA_MARK(&cx->tempPool);
+        JS_ARENA_ALLOCATE_CAST(cp, jschar *, &cx->tempPool,
+                               (args_length+1) * sizeof(jschar));
+        if (!cp)
+            return JS_FALSE;
+        collected_args = cp;
+
+        /*
+         * Concatenate the arguments into the new string, separated by commas.
+         */
+        for (i = 0; i < n; i++) {
+            arg = JSVAL_TO_STRING(argv[i]);
+            arg_length = JSSTRING_LENGTH(arg);
+            (void) js_strncpy(cp, JSSTRING_CHARS(arg), arg_length);
+            cp += arg_length;
+
+            /* Add separating comma or terminating 0. */
+            *cp++ = (i + 1 < n) ? ',' : 0;
+        }
+
+        /*
+         * Make a tokenstream (allocated from cx->tempPool) that reads from
+         * the given string.
+         */
+        ts = js_NewTokenStream(cx, collected_args, args_length, filename,
+                               lineno, principals);
+        if (!ts) {
+            JS_ARENA_RELEASE(&cx->tempPool, mark);
+            return JS_FALSE;
+        }
+
+        /* The argument string may be empty or contain no tokens. */
+        tt = js_GetToken(cx, ts);
+        if (tt != TOK_EOF) {
+            for (;;) {
+                /*
+                 * Check that it's a name.  This also implicitly guards against
+                 * TOK_ERROR, which was already reported.
+                 */
+                if (tt != TOK_NAME)
+                    goto bad_formal;
+
+                /*
+                 * Get the atom corresponding to the name from the tokenstream;
+                 * we're assured at this point that it's a valid identifier.
+                 */
+                atom = CURRENT_TOKEN(ts).t_atom;
+                if (!js_LookupHiddenProperty(cx, obj, ATOM_TO_JSID(atom),
+                                             &obj2, &prop)) {
+                    goto bad_formal;
+                }
+                sprop = (JSScopeProperty *) prop;
+                dupflag = 0;
+                if (sprop) {
+                    ok = JS_TRUE;
+                    if (obj2 == obj) {
+                        const char *name = js_AtomToPrintableString(cx, atom);
+
+                        /*
+                         * A duplicate parameter name. We force a duplicate
+                         * node on the SCOPE_LAST_PROP(scope) list with the
+                         * same id, distinguished by the SPROP_IS_DUPLICATE
+                         * flag, and not mapped by an entry in scope.
+                         */
+                        JS_ASSERT(sprop->getter == js_GetArgument);
+                        ok = name &&
+                             js_ReportCompileErrorNumber(cx, ts,
+                                                         JSREPORT_TS |
+                                                         JSREPORT_WARNING |
+                                                         JSREPORT_STRICT,
+                                                         JSMSG_DUPLICATE_FORMAL,
+                                                         name);
+
+                        dupflag = SPROP_IS_DUPLICATE;
+                    }
+                    OBJ_DROP_PROPERTY(cx, obj2, prop);
+                    if (!ok)
+                        goto bad_formal;
+                    sprop = NULL;
+                }
+                if (!js_AddHiddenProperty(cx, fun->object, ATOM_TO_JSID(atom),
+                                          js_GetArgument, js_SetArgument,
+                                          SPROP_INVALID_SLOT,
+                                          JSPROP_PERMANENT | JSPROP_SHARED,
+                                          dupflag | SPROP_HAS_SHORTID,
+                                          fun->nargs)) {
+                    goto bad_formal;
+                }
+                if (fun->nargs == JS_BITMASK(16)) {
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                         JSMSG_TOO_MANY_FUN_ARGS);
+                    goto bad;
+                }
+                fun->nargs++;
+
+                /*
+                 * Get the next token.  Stop on end of stream.  Otherwise
+                 * insist on a comma, get another name, and iterate.
+                 */
+                tt = js_GetToken(cx, ts);
+                if (tt == TOK_EOF)
+                    break;
+                if (tt != TOK_COMMA)
+                    goto bad_formal;
+                tt = js_GetToken(cx, ts);
+            }
+        }
+
+        /* Clean up. */
+        ok = js_CloseTokenStream(cx, ts);
+        JS_ARENA_RELEASE(&cx->tempPool, mark);
+        if (!ok)
+            return JS_FALSE;
+    }
+
+    if (argc) {
+        str = js_ValueToString(cx, argv[argc-1]);
+    } else {
+        /* Can't use cx->runtime->emptyString because we're called too early. */
+        str = js_NewStringCopyZ(cx, js_empty_ucstr, 0);
+    }
+    if (!str)
+        return JS_FALSE;
+    if (argv) {
+        /* Use the last arg (or this if argc == 0) as a local GC root. */
+        argv[(intN)(argc-1)] = STRING_TO_JSVAL(str);
+    }
+
+    mark = JS_ARENA_MARK(&cx->tempPool);
+    ts = js_NewTokenStream(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
+                           filename, lineno, principals);
+    if (!ts) {
+        ok = JS_FALSE;
+    } else {
+        ok = js_CompileFunctionBody(cx, ts, fun) &&
+             js_CloseTokenStream(cx, ts);
+    }
+    JS_ARENA_RELEASE(&cx->tempPool, mark);
+    return ok;
+
+bad_formal:
+    /*
+     * Report "malformed formal parameter" iff no illegal char or similar
+     * scanner error was already reported.
+     */
+    if (!(ts->flags & TSF_ERROR))
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_FORMAL);
+
+bad:
+    /*
+     * Clean up the arguments string and tokenstream if we failed to parse
+     * the arguments.
+     */
+    (void)js_CloseTokenStream(cx, ts);
+    JS_ARENA_RELEASE(&cx->tempPool, mark);
+    return JS_FALSE;
+}
+
+JSObject *
+js_InitFunctionClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto;
+    JSAtom *atom;
+    JSFunction *fun;
+
+    proto = JS_InitClass(cx, obj, NULL, &js_FunctionClass, Function, 1,
+                         function_props, function_methods, NULL, NULL);
+    if (!proto)
+        return NULL;
+    atom = js_Atomize(cx, js_FunctionClass.name, strlen(js_FunctionClass.name),
+                      0);
+    if (!atom)
+        goto bad;
+    fun = js_NewFunction(cx, proto, NULL, 0, 0, obj, NULL);
+    if (!fun)
+        goto bad;
+    fun->u.script = js_NewScript(cx, 0, 0, 0);
+    if (!fun->u.script)
+        goto bad;
+    fun->interpreted = JS_TRUE;
+    return proto;
+
+bad:
+    cx->newborn[GCX_OBJECT] = NULL;
+    return NULL;
+}
+
+#if JS_HAS_CALL_OBJECT
+JSObject *
+js_InitCallClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto;
+
+    proto = JS_InitClass(cx, obj, NULL, &js_CallClass, NULL, 0,
+                         call_props, NULL, NULL, NULL);
+    if (!proto)
+        return NULL;
+
+    /*
+     * Null Call.prototype's proto slot so that Object.prototype.* does not
+     * pollute the scope of heavyweight functions.
+     */
+    OBJ_SET_PROTO(cx, proto, NULL);
+    return proto;
+}
+#endif
+
+JSFunction *
+js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
+               uintN flags, JSObject *parent, JSAtom *atom)
+{
+    JSFunction *fun;
+
+    /* If funobj is null, allocate an object for it. */
+    if (funobj) {
+        OBJ_SET_PARENT(cx, funobj, parent);
+    } else {
+        funobj = js_NewObject(cx, &js_FunctionClass, NULL, parent);
+        if (!funobj)
+            return NULL;
+    }
+
+    /*
+     * Allocate fun after allocating funobj so slot allocation in js_NewObject
+     * does not wipe out fun from cx->newborn[GCX_PRIVATE].
+     */
+    fun = (JSFunction *) js_NewGCThing(cx, GCX_PRIVATE, sizeof(JSFunction));
+    if (!fun)
+        return NULL;
+
+    /* Initialize all function members. */
+    fun->nrefs = 0;
+    fun->object = NULL;
+    fun->u.native = native;
+    fun->nargs = nargs;
+    fun->extra = 0;
+    fun->nvars = 0;
+    fun->flags = flags & JSFUN_FLAGS_MASK;
+    fun->interpreted = JS_FALSE;
+    fun->nregexps = 0;
+    fun->spare = 0;
+    fun->atom = atom;
+    fun->clasp = NULL;
+
+    /* Link fun to funobj and vice versa. */
+    if (!js_LinkFunctionObject(cx, fun, funobj)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+    return fun;
+}
+
+JSObject *
+js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
+{
+    JSObject *newfunobj;
+    JSFunction *fun;
+
+    JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass);
+    newfunobj = js_NewObject(cx, &js_FunctionClass, funobj, parent);
+    if (!newfunobj)
+        return NULL;
+    fun = (JSFunction *) JS_GetPrivate(cx, funobj);
+    if (!js_LinkFunctionObject(cx, fun, newfunobj)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+    return newfunobj;
+}
+
+JSBool
+js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *funobj)
+{
+    if (!fun->object)
+        fun->object = funobj;
+    if (!JS_SetPrivate(cx, funobj, fun))
+        return JS_FALSE;
+    JS_ATOMIC_INCREMENT(&fun->nrefs);
+    return JS_TRUE;
+}
+
+JSFunction *
+js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
+                  uintN nargs, uintN attrs)
+{
+    JSFunction *fun;
+
+    fun = js_NewFunction(cx, NULL, native, nargs, attrs, obj, atom);
+    if (!fun)
+        return NULL;
+    if (!OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom),
+                             OBJECT_TO_JSVAL(fun->object),
+                             NULL, NULL,
+                             attrs & ~JSFUN_FLAGS_MASK, NULL)) {
+        return NULL;
+    }
+    return fun;
+}
+
+#if (JSV2F_CONSTRUCT & JSV2F_SEARCH_STACK)
+# error "JSINVOKE_CONSTRUCT and JSV2F_SEARCH_STACK are not disjoint!"
+#endif
+
+JSFunction *
+js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags)
+{
+    jsval v;
+    JSObject *obj;
+
+    v = *vp;
+    obj = NULL;
+    if (JSVAL_IS_OBJECT(v)) {
+        obj = JSVAL_TO_OBJECT(v);
+        if (obj && OBJ_GET_CLASS(cx, obj) != &js_FunctionClass) {
+            if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &v))
+                return NULL;
+            obj = JSVAL_IS_FUNCTION(cx, v) ? JSVAL_TO_OBJECT(v) : NULL;
+        }
+    }
+    if (!obj) {
+        js_ReportIsNotFunction(cx, vp, flags);
+        return NULL;
+    }
+    return (JSFunction *) JS_GetPrivate(cx, obj);
+}
+
+JSObject *
+js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags)
+{
+    JSFunction *fun;
+    JSObject *funobj;
+    JSStackFrame *caller;
+
+    if (JSVAL_IS_FUNCTION(cx, *vp))
+        return JSVAL_TO_OBJECT(*vp);
+
+    fun = js_ValueToFunction(cx, vp, flags);
+    if (!fun)
+        return NULL;
+    funobj = fun->object;
+    *vp = OBJECT_TO_JSVAL(funobj);
+
+    caller = JS_GetScriptedCaller(cx, cx->fp);
+    if (caller &&
+        !js_CheckPrincipalsAccess(cx, funobj,
+                                  caller->script->principals,
+                                  JS_GetFunctionName(fun))) {
+        return NULL;
+    }
+    return funobj;
+}
+
+JSObject *
+js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags)
+{
+    JSObject *callable;
+
+    callable = JSVAL_IS_PRIMITIVE(*vp) ? NULL : JSVAL_TO_OBJECT(*vp);
+    if (callable &&
+        ((callable->map->ops == &js_ObjectOps)
+         ? OBJ_GET_CLASS(cx, callable)->call
+         : callable->map->ops->call)) {
+        *vp = OBJECT_TO_JSVAL(callable);
+    } else {
+        callable = js_ValueToFunctionObject(cx, vp, flags);
+    }
+    return callable;
+}
+
+void
+js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags)
+{
+    JSType type;
+    JSString *fallback;
+    JSString *str;
+
+    /*
+     * We provide the typename as the fallback to handle the case when
+     * valueOf is not a function, which prevents ValueToString from being
+     * called as the default case inside js_DecompileValueGenerator (and
+     * so recursing back to here).
+     */
+    type = JS_TypeOfValue(cx, *vp);
+    fallback = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]);
+    str = js_DecompileValueGenerator(cx,
+                                     (flags & JSV2F_SEARCH_STACK)
+                                     ? JSDVG_SEARCH_STACK
+                                     : cx->fp
+                                     ? vp - cx->fp->sp
+                                     : JSDVG_IGNORE_STACK,
+                                     *vp,
+                                     fallback);
+    if (str) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             (uintN)((flags & JSV2F_CONSTRUCT)
+                                     ? JSMSG_NOT_CONSTRUCTOR
+                                     : JSMSG_NOT_FUNCTION),
+                             JS_GetStringBytes(str));
+    }
+}

Added: freeswitch/trunk/libs/js/src/jsfun.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsfun.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,164 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsfun_h___
+#define jsfun_h___
+/*
+ * JS function definitions.
+ */
+#include "jsprvtd.h"
+#include "jspubtd.h"
+
+JS_BEGIN_EXTERN_C
+
+struct JSFunction {
+    jsrefcount   nrefs;         /* number of referencing objects */
+    JSObject     *object;       /* back-pointer to GC'ed object header */
+    union {
+        JSNative native;        /* native method pointer or null */
+        JSScript *script;       /* interpreted bytecode descriptor or null */
+    } u;
+    uint16       nargs;         /* minimum number of actual arguments */
+    uint16       extra;         /* number of arg slots for local GC roots */
+    uint16       nvars;         /* number of local variables */
+    uint8        flags;         /* bound method and other flags, see jsapi.h */
+    JSPackedBool interpreted;   /* use u.script if true, u.native if false */
+    uint16       nregexps;      /* number of regular expressions literals */
+    uint16       spare;         /* reserved for future use */
+    JSAtom       *atom;         /* name for diagnostics and decompiling */
+    JSClass      *clasp;        /* if non-null, constructor for this class */
+};
+
+#define FUN_NATIVE(fun)         ((fun)->interpreted ? NULL : (fun)->u.native)
+#define FUN_SCRIPT(fun)         ((fun)->interpreted ? (fun)->u.script : NULL)
+
+extern JSClass js_ArgumentsClass;
+extern JSClass js_CallClass;
+
+/* JS_FRIEND_DATA so that JSVAL_IS_FUNCTION is callable from outside */
+extern JS_FRIEND_DATA(JSClass) js_FunctionClass;
+
+/*
+ * NB: jsapi.h and jsobj.h must be included before any call to this macro.
+ */
+#define JSVAL_IS_FUNCTION(cx, v)                                              \
+    (!JSVAL_IS_PRIMITIVE(v) &&                                                \
+     OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass)
+
+extern JSBool
+js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent,
+                uintN argc, jsval *argv, jsval *rval);
+
+extern JSBool
+js_IsIdentifier(JSString *str);
+
+extern JSObject *
+js_InitFunctionClass(JSContext *cx, JSObject *obj);
+
+extern JSObject *
+js_InitArgumentsClass(JSContext *cx, JSObject *obj);
+
+extern JSObject *
+js_InitCallClass(JSContext *cx, JSObject *obj);
+
+extern JSFunction *
+js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
+               uintN flags, JSObject *parent, JSAtom *atom);
+
+extern JSObject *
+js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent);
+
+extern JSBool
+js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *object);
+
+extern JSFunction *
+js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native,
+                  uintN nargs, uintN flags);
+
+/*
+ * Flags for js_ValueToFunction and js_ReportIsNotFunction.  We depend on the
+ * fact that JSINVOKE_CONSTRUCT (aka JSFRAME_CONSTRUCTING) is 1, and test that
+ * with #if/#error in jsfun.c.
+ */
+#define JSV2F_CONSTRUCT         JSINVOKE_CONSTRUCT
+#define JSV2F_SEARCH_STACK      2
+
+extern JSFunction *
+js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags);
+
+extern JSObject *
+js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags);
+
+extern JSObject *
+js_ValueToCallableObject(JSContext *cx, jsval *vp, uintN flags);
+
+extern void
+js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags);
+
+extern JSObject *
+js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent);
+
+extern JSBool
+js_PutCallObject(JSContext *cx, JSStackFrame *fp);
+
+extern JSBool
+js_GetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+extern JSBool
+js_SetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+extern JSBool
+js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp);
+
+extern JSBool
+js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id,
+                   JSObject **objp, jsval *vp);
+
+extern JSObject *
+js_GetArgsObject(JSContext *cx, JSStackFrame *fp);
+
+extern JSBool
+js_PutArgsObject(JSContext *cx, JSStackFrame *fp);
+
+extern JSBool
+js_XDRFunction(JSXDRState *xdr, JSObject **objp);
+
+JS_END_EXTERN_C
+
+#endif /* jsfun_h___ */

Added: freeswitch/trunk/libs/js/src/jsgc.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsgc.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1968 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS Mark-and-Sweep Garbage Collector.
+ *
+ * This GC allocates only fixed-sized things big enough to contain two words
+ * (pointers) on any host architecture.  It allocates from an arena pool (see
+ * jsarena.h).  It uses an ideally parallel array of flag bytes to hold the
+ * mark bit, finalizer type index, etc.
+ *
+ * XXX swizzle page to freelist for better locality of reference
+ */
+#include "jsstddef.h"
+#include <stdlib.h>     /* for free, called by JS_ARENA_DESTROY */
+#include <string.h>     /* for memset, called by jsarena.h macros if DEBUG */
+#include "jstypes.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+#include "jshash.h" /* Added by JSIFY */
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsdbgapi.h"
+#include "jsfun.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsscope.h"
+#include "jsscript.h"
+#include "jsstr.h"
+
+#if JS_HAS_XML_SUPPORT
+#include "jsxml.h"
+#endif
+
+/*
+ * GC arena sizing depends on amortizing arena overhead using a large number
+ * of things per arena, and on the thing/flags ratio of 8:1 on most platforms.
+ *
+ * On 64-bit platforms, we would have half as many things per arena because
+ * pointers are twice as big, so we double the bytes for things per arena.
+ * This preserves the 1024 byte flags sub-arena size, which relates to the
+ * GC_PAGE_SIZE (see below for why).
+ */
+#if JS_BYTES_PER_WORD == 8
+# define GC_THINGS_SHIFT 14     /* 16KB for things on Alpha, etc. */
+#else
+# define GC_THINGS_SHIFT 13     /* 8KB for things on most platforms */
+#endif
+#define GC_THINGS_SIZE  JS_BIT(GC_THINGS_SHIFT)
+#define GC_FLAGS_SIZE   (GC_THINGS_SIZE / sizeof(JSGCThing))
+#define GC_ARENA_SIZE   (GC_THINGS_SIZE + GC_FLAGS_SIZE)
+
+/*
+ * A GC arena contains one flag byte for each thing in its heap, and supports
+ * O(1) lookup of a flag given its thing's address.
+ *
+ * To implement this, we take advantage of the thing/flags numerology: given
+ * the 8K bytes worth of GC-things, there are 1K flag bytes.  We mask a thing's
+ * address with ~1023 to find a JSGCPageInfo record at the front of a mythical
+ * "GC page" within the larger 8K thing arena.  That JSGCPageInfo contains a
+ * pointer to the 128 flag bytes corresponding to the things in the page, so we
+ * index into this flags array using the thing's index within its page.
+ *
+ * To align thing pages on 1024-byte boundaries, we must allocate the 9KB of
+ * flags+things arena payload, then find the first 0 mod 1024 boundary after
+ * the first payload address.  That's where things start, with a JSGCPageInfo
+ * taking up the first thing-slot, as usual for 0 mod 1024 byte boundaries.
+ * The effect of this alignment trick is to split the flags into at most 2
+ * discontiguous spans, one before the things and one after (if we're really
+ * lucky, and the arena payload starts on a 0 mod 1024 byte boundary, no need
+ * to split).
+ *
+ * The overhead of this scheme for most platforms is (16+8*(8+1))/(16+9K) or
+ * .95% (assuming 16 byte JSArena header size, and 8 byte JSGCThing size).
+ *
+ * Here's some ASCII art showing an arena:
+ *
+ *   split
+ *     |
+ *     V
+ *  +--+-------+-------+-------+-------+-------+-------+-------+-------+-----+
+ *  |fB|  tp0  |  tp1  |  tp2  |  tp3  |  tp4  |  tp5  |  tp6  |  tp7  | fA  |
+ *  +--+-------+-------+-------+-------+-------+-------+-------+-------+-----+
+ *              ^                                 ^
+ *  tI ---------+                                 |
+ *  tJ -------------------------------------------+
+ *
+ *  - fB are the "before split" flags, fA are the "after split" flags
+ *  - tp0-tp7 are the 8 thing pages
+ *  - thing tI points into tp1, whose flags are below the split, in fB
+ *  - thing tJ points into tp5, clearly above the split
+ *
+ * In general, one of the thing pages will have some of its things' flags on
+ * the low side of the split, and the rest of its things' flags on the high
+ * side.  All the other pages have flags only below or only above.  Therefore
+ * we'll have to test something to decide whether the split divides flags in
+ * a given thing's page.  So we store the split pointer (the pointer to tp0)
+ * in each JSGCPageInfo, along with the flags pointer for the 128 flag bytes
+ * ideally starting, for tp0 things, at the beginning of the arena's payload
+ * (at the start of fB).
+ *
+ * That is, each JSGCPageInfo's flags pointer is 128 bytes from the previous,
+ * or at the start of the arena if there is no previous page in this arena.
+ * Thus these ideal 128-byte flag pages run contiguously from the start of the
+ * arena (right over the split!), and the JSGCPageInfo flags pointers contain
+ * no discontinuities over the split created by the thing pages.  So if, for a
+ * given JSGCPageInfo *pi, we find that
+ *
+ *  pi->flags + ((jsuword)thing % 1024) / sizeof(JSGCThing) >= pi->split
+ *
+ * then we must add GC_THINGS_SIZE to the nominal flags pointer to jump over
+ * all the thing pages that split the flags into two discontiguous spans.
+ *
+ * (If we need to implement card-marking for an incremental GC write barrier,
+ * we can use the low byte of the pi->split pointer as the card-mark, for an
+ * extremely efficient write barrier: when mutating an object obj, just store
+ * a 1 byte at (uint8 *) ((jsuword)obj & ~1023) for little-endian platforms.
+ * When finding flags, we'll of course have to mask split with ~255, but it is
+ * guaranteed to be 1024-byte aligned, so no information is lost by overlaying
+ * the card-mark byte on split's low byte.)
+ */
+#define GC_PAGE_SHIFT   10
+#define GC_PAGE_MASK    ((jsuword) JS_BITMASK(GC_PAGE_SHIFT))
+#define GC_PAGE_SIZE    JS_BIT(GC_PAGE_SHIFT)
+
+typedef struct JSGCPageInfo {
+    uint8       *split;
+    uint8       *flags;
+} JSGCPageInfo;
+
+#define FIRST_THING_PAGE(a)     (((a)->base + GC_FLAGS_SIZE) & ~GC_PAGE_MASK)
+
+/*
+ * Given a jsuword page pointer p and a thing size n, return the address of
+ * the first thing in p.  We know that any n not a power of two packs from
+ * the end of the page leaving at least enough room for one JSGCPageInfo, but
+ * not for another thing, at the front of the page (JS_ASSERTs below insist
+ * on this).
+ *
+ * This works because all allocations are a multiple of sizeof(JSGCThing) ==
+ * sizeof(JSGCPageInfo) in size.
+ */
+#define FIRST_THING(p,n)        (((n) & ((n) - 1))                            \
+                                 ? (p) + (uint32)(GC_PAGE_SIZE % (n))         \
+                                 : (p) + (n))
+
+static JSGCThing *
+gc_new_arena(JSArenaPool *pool, size_t nbytes)
+{
+    uint8 *flagp, *split, *pagep, *limit;
+    JSArena *a;
+    jsuword p;
+    JSGCThing *thing;
+    JSGCPageInfo *pi;
+
+    /* Use JS_ArenaAllocate to grab another 9K-net-size hunk of space. */
+    flagp = (uint8 *) JS_ArenaAllocate(pool, GC_ARENA_SIZE);
+    if (!flagp)
+        return NULL;
+    a = pool->current;
+
+    /* Reset a->avail to start at the flags split, aka the first thing page. */
+    p = FIRST_THING_PAGE(a);
+    split = pagep = (uint8 *) p;
+    a->avail = FIRST_THING(p, nbytes);
+    JS_ASSERT(a->avail >= p + sizeof(JSGCPageInfo));
+    thing = (JSGCThing *) a->avail;
+    JS_ArenaCountAllocation(pool, a->avail - p);
+    a->avail += nbytes;
+
+    /* Initialize the JSGCPageInfo records at the start of every thing page. */
+    limit = pagep + GC_THINGS_SIZE;
+    do {
+        pi = (JSGCPageInfo *) pagep;
+        pi->split = split;
+        pi->flags = flagp;
+        flagp += GC_PAGE_SIZE >> (GC_THINGS_SHIFT -  GC_PAGE_SHIFT);
+        pagep += GC_PAGE_SIZE;
+    } while (pagep < limit);
+    return thing;
+}
+
+uint8 *
+js_GetGCThingFlags(void *thing)
+{
+    JSGCPageInfo *pi;
+    uint8 *flagp;
+
+    pi = (JSGCPageInfo *) ((jsuword)thing & ~GC_PAGE_MASK);
+    flagp = pi->flags + ((jsuword)thing & GC_PAGE_MASK) / sizeof(JSGCThing);
+    if (flagp >= pi->split)
+        flagp += GC_THINGS_SIZE;
+    return flagp;
+}
+
+JSBool
+js_IsAboutToBeFinalized(JSContext *cx, void *thing)
+{
+    uint8 flags = *js_GetGCThingFlags(thing);
+
+    return !(flags & (GCF_MARK | GCF_LOCK | GCF_FINAL));
+}
+
+typedef void (*GCFinalizeOp)(JSContext *cx, JSGCThing *thing);
+
+#ifndef DEBUG
+# define js_FinalizeDouble       NULL
+#endif
+
+#if !JS_HAS_XML_SUPPORT
+# define js_FinalizeXMLNamespace NULL
+# define js_FinalizeXMLQName     NULL
+# define js_FinalizeXML          NULL
+#endif
+
+static GCFinalizeOp gc_finalizers[GCX_NTYPES] = {
+    (GCFinalizeOp) js_FinalizeObject,           /* GCX_OBJECT */
+    (GCFinalizeOp) js_FinalizeString,           /* GCX_STRING */
+    (GCFinalizeOp) js_FinalizeDouble,           /* GCX_DOUBLE */
+    (GCFinalizeOp) js_FinalizeString,           /* GCX_MUTABLE_STRING */
+    NULL,                                       /* GCX_PRIVATE */
+    (GCFinalizeOp) js_FinalizeXMLNamespace,     /* GCX_NAMESPACE */
+    (GCFinalizeOp) js_FinalizeXMLQName,         /* GCX_QNAME */
+    (GCFinalizeOp) js_FinalizeXML,              /* GCX_XML */
+    NULL,                                       /* GCX_EXTERNAL_STRING */
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+#ifdef GC_MARK_DEBUG
+static const char newborn_external_string[] = "newborn external string";
+
+static const char *gc_typenames[GCX_NTYPES] = {
+    "newborn object",
+    "newborn string",
+    "newborn double",
+    "newborn mutable string",
+    "newborn private",
+    "newborn Namespace",
+    "newborn QName",
+    "newborn XML",
+    newborn_external_string,
+    newborn_external_string,
+    newborn_external_string,
+    newborn_external_string,
+    newborn_external_string,
+    newborn_external_string,
+    newborn_external_string,
+    newborn_external_string
+};
+#endif
+
+intN
+js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
+                                 JSStringFinalizeOp newop)
+{
+    uintN i;
+
+    for (i = GCX_EXTERNAL_STRING; i < GCX_NTYPES; i++) {
+        if (gc_finalizers[i] == (GCFinalizeOp) oldop) {
+            gc_finalizers[i] = (GCFinalizeOp) newop;
+            return (intN) i;
+        }
+    }
+    return -1;
+}
+
+#ifdef JS_GCMETER
+#define METER(x) x
+#else
+#define METER(x) /* nothing */
+#endif
+
+/* Initial size of the gcRootsHash table (SWAG, small enough to amortize). */
+#define GC_ROOTS_SIZE   256
+#define GC_FINALIZE_LEN 1024
+
+JSBool
+js_InitGC(JSRuntime *rt, uint32 maxbytes)
+{
+    uintN i;
+
+    JS_ASSERT(sizeof(JSGCThing) == sizeof(JSGCPageInfo));
+    JS_ASSERT(sizeof(JSGCThing) >= sizeof(JSObject));
+    JS_ASSERT(sizeof(JSGCThing) >= sizeof(JSString));
+    JS_ASSERT(sizeof(JSGCThing) >= sizeof(jsdouble));
+    JS_ASSERT(GC_FLAGS_SIZE >= GC_PAGE_SIZE);
+    JS_ASSERT(sizeof(JSStackHeader) >= 2 * sizeof(jsval));
+
+    for (i = 0; i < GC_NUM_FREELISTS; i++)
+        JS_InitArenaPool(&rt->gcArenaPool[i], "gc-arena", GC_ARENA_SIZE, 1);
+    if (!JS_DHashTableInit(&rt->gcRootsHash, JS_DHashGetStubOps(), NULL,
+                           sizeof(JSGCRootHashEntry), GC_ROOTS_SIZE)) {
+        rt->gcRootsHash.ops = NULL;
+        return JS_FALSE;
+    }
+    rt->gcLocksHash = NULL;     /* create lazily */
+    rt->gcMaxBytes = maxbytes;
+    return JS_TRUE;
+}
+
+#ifdef JS_GCMETER
+JS_FRIEND_API(void)
+js_DumpGCStats(JSRuntime *rt, FILE *fp)
+{
+    uintN i;
+
+    fprintf(fp, "\nGC allocation statistics:\n");
+
+#define UL(x)       ((unsigned long)(x))
+#define ULSTAT(x)   UL(rt->gcStats.x)
+    fprintf(fp, "     public bytes allocated: %lu\n", UL(rt->gcBytes));
+    fprintf(fp, "    private bytes allocated: %lu\n", UL(rt->gcPrivateBytes));
+    fprintf(fp, "             alloc attempts: %lu\n", ULSTAT(alloc));
+    for (i = 0; i < GC_NUM_FREELISTS; i++) {
+        fprintf(fp, "       GC freelist %u length: %lu\n",
+                i, ULSTAT(freelen[i]));
+        fprintf(fp, " recycles via GC freelist %u: %lu\n",
+                i, ULSTAT(recycle[i]));
+    }
+    fprintf(fp, "allocation retries after GC: %lu\n", ULSTAT(retry));
+    fprintf(fp, "        allocation failures: %lu\n", ULSTAT(fail));
+    fprintf(fp, "         things born locked: %lu\n", ULSTAT(lockborn));
+    fprintf(fp, "           valid lock calls: %lu\n", ULSTAT(lock));
+    fprintf(fp, "         valid unlock calls: %lu\n", ULSTAT(unlock));
+    fprintf(fp, "       mark recursion depth: %lu\n", ULSTAT(depth));
+    fprintf(fp, "     maximum mark recursion: %lu\n", ULSTAT(maxdepth));
+    fprintf(fp, "     mark C recursion depth: %lu\n", ULSTAT(cdepth));
+    fprintf(fp, "   maximum mark C recursion: %lu\n", ULSTAT(maxcdepth));
+    fprintf(fp, "     mark C stack overflows: %lu\n", ULSTAT(dswmark));
+    fprintf(fp, "   mark DSW recursion depth: %lu\n", ULSTAT(dswdepth));
+    fprintf(fp, " maximum mark DSW recursion: %lu\n", ULSTAT(maxdswdepth));
+    fprintf(fp, "  mark DSW up-tree movement: %lu\n", ULSTAT(dswup));
+    fprintf(fp, "DSW up-tree obj->slot steps: %lu\n", ULSTAT(dswupstep));
+    fprintf(fp, "   maximum GC nesting level: %lu\n", ULSTAT(maxlevel));
+    fprintf(fp, "potentially useful GC calls: %lu\n", ULSTAT(poke));
+    fprintf(fp, "           useless GC calls: %lu\n", ULSTAT(nopoke));
+    fprintf(fp, "  thing arenas freed so far: %lu\n", ULSTAT(afree));
+    fprintf(fp, "     stack segments scanned: %lu\n", ULSTAT(stackseg));
+    fprintf(fp, "stack segment slots scanned: %lu\n", ULSTAT(segslots));
+#undef UL
+#undef US
+
+#ifdef JS_ARENAMETER
+    JS_DumpArenaStats(fp);
+#endif
+}
+#endif
+
+#ifdef DEBUG
+JS_STATIC_DLL_CALLBACK(JSDHashOperator)
+js_root_printer(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 i, void *arg)
+{
+    uint32 *leakedroots = (uint32 *)arg;
+    JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
+
+    (*leakedroots)++;
+    fprintf(stderr,
+            "JS engine warning: leaking GC root \'%s\' at %p\n",
+            rhe->name ? (char *)rhe->name : "", rhe->root);
+
+    return JS_DHASH_NEXT;
+}
+#endif
+
+void
+js_FinishGC(JSRuntime *rt)
+{
+    uintN i;
+
+#ifdef JS_ARENAMETER
+    JS_DumpArenaStats(stdout);
+#endif
+#ifdef JS_GCMETER
+    js_DumpGCStats(rt, stdout);
+#endif
+    for (i = 0; i < GC_NUM_FREELISTS; i++) {
+        JS_FinishArenaPool(&rt->gcArenaPool[i]);
+        rt->gcFreeList[i] = NULL;
+    }
+    JS_ArenaFinish();
+
+    if (rt->gcRootsHash.ops) {
+#ifdef DEBUG
+        uint32 leakedroots = 0;
+
+        /* Warn (but don't assert) debug builds of any remaining roots. */
+        JS_DHashTableEnumerate(&rt->gcRootsHash, js_root_printer,
+                               &leakedroots);
+        if (leakedroots > 0) {
+            if (leakedroots == 1) {
+                fprintf(stderr,
+"JS engine warning: 1 GC root remains after destroying the JSRuntime.\n"
+"                   This root may point to freed memory. Objects reachable\n"
+"                   through it have not been finalized.\n");
+            } else {
+                fprintf(stderr,
+"JS engine warning: %lu GC roots remain after destroying the JSRuntime.\n"
+"                   These roots may point to freed memory. Objects reachable\n"
+"                   through them have not been finalized.\n",
+                        (unsigned long) leakedroots);
+            }
+        }
+#endif
+
+        JS_DHashTableFinish(&rt->gcRootsHash);
+        rt->gcRootsHash.ops = NULL;
+    }
+    if (rt->gcLocksHash) {
+        JS_DHashTableDestroy(rt->gcLocksHash);
+        rt->gcLocksHash = NULL;
+    }
+}
+
+JSBool
+js_AddRoot(JSContext *cx, void *rp, const char *name)
+{
+    JSBool ok = js_AddRootRT(cx->runtime, rp, name);
+    if (!ok)
+        JS_ReportOutOfMemory(cx);
+    return ok;
+}
+
+JSBool
+js_AddRootRT(JSRuntime *rt, void *rp, const char *name)
+{
+    JSBool ok;
+    JSGCRootHashEntry *rhe;
+
+    /*
+     * Due to the long-standing, but now removed, use of rt->gcLock across the
+     * bulk of js_GC, API users have come to depend on JS_AddRoot etc. locking
+     * properly with a racing GC, without calling JS_AddRoot from a request.
+     * We have to preserve API compatibility here, now that we avoid holding
+     * rt->gcLock across the mark phase (including the root hashtable mark).
+     *
+     * If the GC is running and we're called on another thread, wait for this
+     * GC activation to finish.  We can safely wait here (in the case where we
+     * are called within a request on another thread's context) without fear
+     * of deadlock because the GC doesn't set rt->gcRunning until after it has
+     * waited for all active requests to end.
+     */
+    JS_LOCK_GC(rt);
+#ifdef JS_THREADSAFE
+    JS_ASSERT(!rt->gcRunning || rt->gcLevel > 0);
+    if (rt->gcRunning && rt->gcThread != js_CurrentThreadId()) {
+        do {
+            JS_AWAIT_GC_DONE(rt);
+        } while (rt->gcLevel > 0);
+    }
+#endif
+    rhe = (JSGCRootHashEntry *) JS_DHashTableOperate(&rt->gcRootsHash, rp,
+                                                     JS_DHASH_ADD);
+    if (rhe) {
+        rhe->root = rp;
+        rhe->name = name;
+        ok = JS_TRUE;
+    } else {
+        ok = JS_FALSE;
+    }
+    JS_UNLOCK_GC(rt);
+    return ok;
+}
+
+JSBool
+js_RemoveRoot(JSRuntime *rt, void *rp)
+{
+    /*
+     * Due to the JS_RemoveRootRT API, we may be called outside of a request.
+     * Same synchronization drill as above in js_AddRoot.
+     */
+    JS_LOCK_GC(rt);
+#ifdef JS_THREADSAFE
+    JS_ASSERT(!rt->gcRunning || rt->gcLevel > 0);
+    if (rt->gcRunning && rt->gcThread != js_CurrentThreadId()) {
+        do {
+            JS_AWAIT_GC_DONE(rt);
+        } while (rt->gcLevel > 0);
+    }
+#endif
+    (void) JS_DHashTableOperate(&rt->gcRootsHash, rp, JS_DHASH_REMOVE);
+    rt->gcPoke = JS_TRUE;
+    JS_UNLOCK_GC(rt);
+    return JS_TRUE;
+}
+
+#ifdef DEBUG_brendan
+#define NGCHIST 64
+
+static struct GCHist {
+    JSBool      lastDitch;
+    JSGCThing   *freeList;
+} gchist[NGCHIST];
+
+unsigned gchpos;
+#endif
+
+void *
+js_NewGCThing(JSContext *cx, uintN flags, size_t nbytes)
+{
+    JSBool tried_gc;
+    JSRuntime *rt;
+    size_t nflags;
+    uintN i;
+    JSGCThing *thing, **flp;
+    uint8 *flagp;
+    JSLocalRootStack *lrs;
+    uint32 *bytesptr;
+
+    rt = cx->runtime;
+    JS_LOCK_GC(rt);
+    JS_ASSERT(!rt->gcRunning);
+    if (rt->gcRunning) {
+        METER(rt->gcStats.finalfail++);
+        JS_UNLOCK_GC(rt);
+        return NULL;
+    }
+
+#ifdef TOO_MUCH_GC
+#ifdef WAY_TOO_MUCH_GC
+    rt->gcPoke = JS_TRUE;
+#endif
+    js_GC(cx, GC_KEEP_ATOMS | GC_ALREADY_LOCKED);
+    tried_gc = JS_TRUE;
+#else
+    tried_gc = JS_FALSE;
+#endif
+
+    METER(rt->gcStats.alloc++);
+    nbytes = JS_ROUNDUP(nbytes, sizeof(JSGCThing));
+    nflags = nbytes / sizeof(JSGCThing);
+    i = GC_FREELIST_INDEX(nbytes);
+    flp = &rt->gcFreeList[i];
+
+retry:
+    thing = *flp;
+    if (thing) {
+        *flp = thing->next;
+        flagp = thing->flagp;
+        METER(rt->gcStats.freelen[i]--);
+        METER(rt->gcStats.recycle[i]++);
+    } else {
+        if (rt->gcBytes < rt->gcMaxBytes &&
+            (tried_gc || rt->gcMallocBytes < rt->gcMaxBytes))
+        {
+            /*
+             * Inline form of JS_ARENA_ALLOCATE adapted to truncate the current
+             * arena's limit to a GC_PAGE_SIZE boundary, and to skip over every
+             * GC_PAGE_SIZE-byte-aligned thing (which is actually not a thing,
+             * it's a JSGCPageInfo record).
+             */
+            JSArenaPool *pool = &rt->gcArenaPool[i];
+            JSArena *a = pool->current;
+            jsuword p = a->avail;
+            jsuword q = p + nbytes;
+
+            if (q > (a->limit & ~GC_PAGE_MASK)) {
+                thing = gc_new_arena(pool, nbytes);
+            } else {
+                if ((p & GC_PAGE_MASK) == 0) {
+                    /* Beware, p points to a JSGCPageInfo record! */
+                    p = FIRST_THING(p, nbytes);
+                    q = p + nbytes;
+                    JS_ArenaCountAllocation(pool, p & GC_PAGE_MASK);
+                }
+                a->avail = q;
+                thing = (JSGCThing *)p;
+            }
+            JS_ArenaCountAllocation(pool, nbytes);
+        }
+
+        /*
+         * Consider doing a "last ditch" GC if thing couldn't be allocated.
+         *
+         * Keep rt->gcLock across the call into js_GC so we don't starve and
+         * lose to racing threads who deplete the heap just after js_GC has
+         * replenished it (or has synchronized with a racing GC that collected
+         * a bunch of garbage).  This unfair scheduling can happen on certain
+         * operating systems.  For the gory details, see Mozilla bug 162779
+         * (http://bugzilla.mozilla.org/show_bug.cgi?id=162779).
+         */
+        if (!thing) {
+            if (!tried_gc) {
+                rt->gcPoke = JS_TRUE;
+                js_GC(cx, GC_KEEP_ATOMS | GC_ALREADY_LOCKED);
+                if (JS_HAS_NATIVE_BRANCH_CALLBACK_OPTION(cx) &&
+                    cx->branchCallback &&
+                    !cx->branchCallback(cx, NULL)) {
+                    METER(rt->gcStats.retryhalt++);
+                    JS_UNLOCK_GC(rt);
+                    return NULL;
+                }
+                tried_gc = JS_TRUE;
+                METER(rt->gcStats.retry++);
+                goto retry;
+            }
+            goto fail;
+        }
+
+        /* Find the flags pointer given thing's address. */
+        flagp = js_GetGCThingFlags(thing);
+    }
+
+    lrs = cx->localRootStack;
+    if (lrs) {
+        /*
+         * If we're in a local root scope, don't set cx->newborn[type] at all,
+         * to avoid entraining garbage from it for an unbounded amount of time
+         * on this context.  A caller will leave the local root scope and pop
+         * this reference, allowing thing to be GC'd if it has no other refs.
+         * See JS_EnterLocalRootScope and related APIs.
+         */
+        if (js_PushLocalRoot(cx, lrs, (jsval) thing) < 0)
+            goto fail;
+    } else {
+        /*
+         * No local root scope, so we're stuck with the old, fragile model of
+         * depending on a pigeon-hole newborn per type per context.
+         */
+        cx->newborn[flags & GCF_TYPEMASK] = thing;
+    }
+
+    /* We can't fail now, so update flags and rt->gc{,Private}Bytes. */
+    *flagp = (uint8)flags;
+    bytesptr = ((flags & GCF_TYPEMASK) == GCX_PRIVATE)
+               ? &rt->gcPrivateBytes
+               : &rt->gcBytes;
+    *bytesptr += nbytes + nflags;
+
+    /*
+     * Clear thing before unlocking in case a GC run is about to scan it,
+     * finding it via cx->newborn[].
+     */
+    thing->next = NULL;
+    thing->flagp = NULL;
+#ifdef DEBUG_brendan
+    gchist[gchpos].lastDitch = tried_gc;
+    gchist[gchpos].freeList = *flp;
+    if (++gchpos == NGCHIST)
+        gchpos = 0;
+#endif
+    METER(if (flags & GCF_LOCK) rt->gcStats.lockborn++);
+    JS_UNLOCK_GC(rt);
+    return thing;
+
+fail:
+    METER(rt->gcStats.fail++);
+    JS_UNLOCK_GC(rt);
+    JS_ReportOutOfMemory(cx);
+    return NULL;
+}
+
+JSBool
+js_LockGCThing(JSContext *cx, void *thing)
+{
+    JSBool ok = js_LockGCThingRT(cx->runtime, thing);
+    if (!ok)
+        JS_ReportOutOfMemory(cx);
+    return ok;
+}
+
+/*
+ * Deep GC-things can't be locked just by setting the GCF_LOCK bit, because
+ * their descendants must be marked by the GC.  To find them during the mark
+ * phase, they are added to rt->gcLocksHash, which is created lazily.
+ *
+ * NB: we depend on the order of GC-thing type indexes here!
+ */
+#define GC_TYPE_IS_STRING(t)    ((t) == GCX_STRING ||                         \
+                                 (t) >= GCX_EXTERNAL_STRING)
+#define GC_TYPE_IS_XML(t)       ((unsigned)((t) - GCX_NAMESPACE) <=           \
+                                 (unsigned)(GCX_XML - GCX_NAMESPACE))
+#define GC_TYPE_IS_DEEP(t)      ((t) == GCX_OBJECT || GC_TYPE_IS_XML(t))
+
+#define IS_DEEP_STRING(t,o)     (GC_TYPE_IS_STRING(t) &&                      \
+                                 JSSTRING_IS_DEPENDENT((JSString *)(o)))
+
+#define GC_THING_IS_DEEP(t,o)   (GC_TYPE_IS_DEEP(t) || IS_DEEP_STRING(t, o))
+
+JSBool
+js_LockGCThingRT(JSRuntime *rt, void *thing)
+{
+    JSBool ok, deep;
+    uint8 *flagp, flags, lock, type;
+    JSGCLockHashEntry *lhe;
+
+    ok = JS_TRUE;
+    if (!thing)
+        return ok;
+
+    flagp = js_GetGCThingFlags(thing);
+
+    JS_LOCK_GC(rt);
+    flags = *flagp;
+    lock = (flags & GCF_LOCK);
+    type = (flags & GCF_TYPEMASK);
+    deep = GC_THING_IS_DEEP(type, thing);
+
+    /*
+     * Avoid adding a rt->gcLocksHash entry for shallow things until someone
+     * nests a lock -- then start such an entry with a count of 2, not 1.
+     */
+    if (lock || deep) {
+        if (!rt->gcLocksHash) {
+            rt->gcLocksHash =
+                JS_NewDHashTable(JS_DHashGetStubOps(), NULL,
+                                 sizeof(JSGCLockHashEntry),
+                                 GC_ROOTS_SIZE);
+            if (!rt->gcLocksHash) {
+                ok = JS_FALSE;
+                goto done;
+            }
+        } else if (lock == 0) {
+#ifdef DEBUG
+            JSDHashEntryHdr *hdr =
+                JS_DHashTableOperate(rt->gcLocksHash, thing,
+                                     JS_DHASH_LOOKUP);
+            JS_ASSERT(JS_DHASH_ENTRY_IS_FREE(hdr));
+#endif
+        }
+
+        lhe = (JSGCLockHashEntry *)
+            JS_DHashTableOperate(rt->gcLocksHash, thing, JS_DHASH_ADD);
+        if (!lhe) {
+            ok = JS_FALSE;
+            goto done;
+        }
+        if (!lhe->thing) {
+            lhe->thing = thing;
+            lhe->count = deep ? 1 : 2;
+        } else {
+            JS_ASSERT(lhe->count >= 1);
+            lhe->count++;
+        }
+    }
+
+    *flagp = (uint8)(flags | GCF_LOCK);
+    METER(rt->gcStats.lock++);
+    ok = JS_TRUE;
+done:
+    JS_UNLOCK_GC(rt);
+    return ok;
+}
+
+JSBool
+js_UnlockGCThingRT(JSRuntime *rt, void *thing)
+{
+    uint8 *flagp, flags;
+    JSGCLockHashEntry *lhe;
+
+    if (!thing)
+        return JS_TRUE;
+
+    flagp = js_GetGCThingFlags(thing);
+    JS_LOCK_GC(rt);
+    flags = *flagp;
+
+    if (flags & GCF_LOCK) {
+        if (!rt->gcLocksHash ||
+            (lhe = (JSGCLockHashEntry *)
+                   JS_DHashTableOperate(rt->gcLocksHash, thing,
+                                        JS_DHASH_LOOKUP),
+             JS_DHASH_ENTRY_IS_FREE(&lhe->hdr))) {
+            /* Shallow GC-thing with an implicit lock count of 1. */
+            JS_ASSERT(!GC_THING_IS_DEEP(flags & GCF_TYPEMASK, thing));
+        } else {
+            /* Basis or nested unlock of a deep thing, or nested of shallow. */
+            if (--lhe->count != 0)
+                goto out;
+            JS_DHashTableOperate(rt->gcLocksHash, thing, JS_DHASH_REMOVE);
+        }
+        *flagp = (uint8)(flags & ~GCF_LOCK);
+    }
+
+    rt->gcPoke = JS_TRUE;
+out:
+    METER(rt->gcStats.unlock++);
+    JS_UNLOCK_GC(rt);
+    return JS_TRUE;
+}
+
+#ifdef GC_MARK_DEBUG
+
+#include <stdio.h>
+#include "jsprf.h"
+
+JS_FRIEND_DATA(FILE *) js_DumpGCHeap;
+JS_EXPORT_DATA(void *) js_LiveThingToFind;
+
+#ifdef HAVE_XPCONNECT
+#include "dump_xpc.h"
+#endif
+
+static const char *
+gc_object_class_name(void* thing)
+{
+    uint8 *flagp = js_GetGCThingFlags(thing);
+    const char *className = "";
+    static char depbuf[32];
+
+    switch (*flagp & GCF_TYPEMASK) {
+      case GCX_OBJECT: {
+        JSObject  *obj = (JSObject *)thing;
+        JSClass   *clasp = JSVAL_TO_PRIVATE(obj->slots[JSSLOT_CLASS]);
+        className = clasp->name;
+#ifdef HAVE_XPCONNECT
+        if (clasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
+            jsval privateValue = obj->slots[JSSLOT_PRIVATE];
+
+            JS_ASSERT(clasp->flags & JSCLASS_HAS_PRIVATE);
+            if (!JSVAL_IS_VOID(privateValue)) {
+                void  *privateThing = JSVAL_TO_PRIVATE(privateValue);
+                const char *xpcClassName = GetXPCObjectClassName(privateThing);
+
+                if (xpcClassName)
+                    className = xpcClassName;
+            }
+        }
+#endif
+        break;
+      }
+
+      case GCX_STRING:
+      case GCX_MUTABLE_STRING: {
+        JSString *str = (JSString *)thing;
+        if (JSSTRING_IS_DEPENDENT(str)) {
+            JS_snprintf(depbuf, sizeof depbuf, "start:%u, length:%u",
+                        JSSTRDEP_START(str), JSSTRDEP_LENGTH(str));
+            className = depbuf;
+        } else {
+            className = "string";
+        }
+        break;
+      }
+
+      case GCX_DOUBLE:
+        className = "double";
+        break;
+    }
+
+    return className;
+}
+
+static void
+gc_dump_thing(JSGCThing *thing, uint8 flags, GCMarkNode *prev, FILE *fp)
+{
+    GCMarkNode *next = NULL;
+    char *path = NULL;
+
+    while (prev) {
+        next = prev;
+        prev = prev->prev;
+    }
+    while (next) {
+        uint8 nextFlags = *js_GetGCThingFlags(next->thing);
+        if ((nextFlags & GCF_TYPEMASK) == GCX_OBJECT) {
+            path = JS_sprintf_append(path, "%s(%s @ 0x%08p).",
+                                     next->name,
+                                     gc_object_class_name(next->thing),
+                                     (JSObject*)next->thing);
+        } else {
+            path = JS_sprintf_append(path, "%s(%s).",
+                                     next->name,
+                                     gc_object_class_name(next->thing));
+        }
+        next = next->next;
+    }
+    if (!path)
+        return;
+
+    fprintf(fp, "%08lx ", (long)thing);
+    switch (flags & GCF_TYPEMASK) {
+      case GCX_OBJECT:
+      {
+        JSObject  *obj = (JSObject *)thing;
+        jsval     privateValue = obj->slots[JSSLOT_PRIVATE];
+        void      *privateThing = JSVAL_IS_VOID(privateValue)
+                                  ? NULL
+                                  : JSVAL_TO_PRIVATE(privateValue);
+        const char *className = gc_object_class_name(thing);
+        fprintf(fp, "object %8p %s", privateThing, className);
+        break;
+      }
+#if JS_HAS_XML_SUPPORT
+      case GCX_NAMESPACE:
+      {
+        JSXMLNamespace *ns = (JSXMLNamespace *)thing;
+        fprintf(fp, "namespace %s:%s",
+                JS_GetStringBytes(ns->prefix), JS_GetStringBytes(ns->uri));
+        break;
+      }
+      case GCX_QNAME:
+      {
+        JSXMLQName *qn = (JSXMLQName *)thing;
+        fprintf(fp, "qname %s(%s):%s",
+                JS_GetStringBytes(qn->prefix), JS_GetStringBytes(qn->uri),
+                JS_GetStringBytes(qn->localName));
+        break;
+      }
+      case GCX_XML:
+      {
+        extern const char *js_xml_class_str[];
+        JSXML *xml = (JSXML *)thing;
+        fprintf(fp, "xml %8p %s", xml, js_xml_class_str[xml->xml_class]);
+        break;
+      }
+#endif
+      case GCX_DOUBLE:
+        fprintf(fp, "double %g", *(jsdouble *)thing);
+        break;
+      case GCX_PRIVATE:
+        fprintf(fp, "private %8p", (void *)thing);
+        break;
+      default:
+        fprintf(fp, "string %s", JS_GetStringBytes((JSString *)thing));
+        break;
+    }
+    fprintf(fp, " via %s\n", path);
+    free(path);
+}
+
+#endif /* !GC_MARK_DEBUG */
+
+static void
+gc_mark_atom_key_thing(void *thing, void *arg)
+{
+    JSContext *cx = (JSContext *) arg;
+
+    GC_MARK(cx, thing, "atom", NULL);
+}
+
+void
+js_MarkAtom(JSContext *cx, JSAtom *atom, void *arg)
+{
+    jsval key;
+
+    if (atom->flags & ATOM_MARK)
+        return;
+    atom->flags |= ATOM_MARK;
+    key = ATOM_KEY(atom);
+    if (JSVAL_IS_GCTHING(key)) {
+#ifdef GC_MARK_DEBUG
+        char name[32];
+
+        if (JSVAL_IS_STRING(key)) {
+            JS_snprintf(name, sizeof name, "'%s'",
+                        JS_GetStringBytes(JSVAL_TO_STRING(key)));
+        } else {
+            JS_snprintf(name, sizeof name, "<%x>", key);
+        }
+#endif
+        GC_MARK(cx, JSVAL_TO_GCTHING(key), name, arg);
+    }
+    if (atom->flags & ATOM_HIDDEN)
+        js_MarkAtom(cx, atom->entry.value, arg);
+}
+
+/*
+ * These macros help avoid passing the GC_MARK_DEBUG-only |arg| parameter
+ * during recursive calls when GC_MARK_DEBUG is not defined.
+ */
+#ifdef GC_MARK_DEBUG
+# define UNMARKED_GC_THING_FLAGS(thing, arg)                                  \
+    UnmarkedGCThingFlags(thing, arg)
+# define NEXT_UNMARKED_GC_THING(vp, end, thingp, flagpp, arg)                 \
+    NextUnmarkedGCThing(vp, end, thingp, flagpp, arg)
+# define MARK_GC_THING(cx, thing, flagp, arg)                                 \
+    MarkGCThing(cx, thing, flagp, arg)
+# define CALL_GC_THING_MARKER(marker, cx, thing, arg)                         \
+    marker(cx, thing, arg)
+#else
+# define UNMARKED_GC_THING_FLAGS(thing, arg)                                  \
+    UnmarkedGCThingFlags(thing)
+# define NEXT_UNMARKED_GC_THING(vp, end, thingp, flagpp, arg)                 \
+    NextUnmarkedGCThing(vp, end, thingp, flagpp)
+# define MARK_GC_THING(cx, thing, flagp, arg)                                 \
+    MarkGCThing(cx, thing, flagp)
+# define CALL_GC_THING_MARKER(marker, cx, thing, arg)                         \
+    marker(cx, thing, NULL)
+#endif
+
+static uint8 *
+UNMARKED_GC_THING_FLAGS(void *thing, void *arg)
+{
+    uint8 flags, *flagp;
+
+    if (!thing)
+        return NULL;
+
+    flagp = js_GetGCThingFlags(thing);
+    flags = *flagp;
+    JS_ASSERT(flags != GCF_FINAL);
+#ifdef GC_MARK_DEBUG
+    if (js_LiveThingToFind == thing)
+        gc_dump_thing(thing, flags, arg, stderr);
+#endif
+
+    if (flags & GCF_MARK)
+        return NULL;
+
+    return flagp;
+}
+
+static jsval *
+NEXT_UNMARKED_GC_THING(jsval *vp, jsval *end, void **thingp, uint8 **flagpp,
+                       void *arg)
+{
+    jsval v;
+    void *thing;
+    uint8 *flagp;
+
+    while (vp < end) {
+        v = *vp;
+        if (JSVAL_IS_GCTHING(v)) {
+            thing = JSVAL_TO_GCTHING(v);
+            flagp = UNMARKED_GC_THING_FLAGS(thing, arg);
+            if (flagp) {
+                *thingp = thing;
+                *flagpp = flagp;
+                return vp;
+            }
+        }
+        vp++;
+    }
+    return NULL;
+}
+
+static void
+DeutschSchorrWaite(JSContext *cx, void *thing, uint8 *flagp);
+
+static JSBool
+MARK_GC_THING(JSContext *cx, void *thing, uint8 *flagp, void *arg)
+{
+    JSRuntime *rt;
+    JSObject *obj;
+    jsval v, *vp, *end;
+    JSString *str;
+    void *next_thing;
+    uint8 *next_flagp;
+#ifdef JS_GCMETER
+    uint32 tailCallNesting;
+#endif
+#ifdef GC_MARK_DEBUG
+    JSScope *scope;
+    JSScopeProperty *sprop;
+    char name[32];
+#endif
+    int stackDummy;
+
+    rt = cx->runtime;
+    METER(tailCallNesting = 0);
+    METER(if (++rt->gcStats.cdepth > rt->gcStats.maxcdepth)
+              rt->gcStats.maxcdepth = rt->gcStats.cdepth);
+
+#ifndef GC_MARK_DEBUG
+  start:
+#endif
+    JS_ASSERT(flagp);
+    METER(if (++rt->gcStats.depth > rt->gcStats.maxdepth)
+              rt->gcStats.maxdepth = rt->gcStats.depth);
+    if (*flagp & GCF_MARK) {
+        /*
+         * This should happen only if recursive MARK_GC_THING marks flags
+         * already stored in the caller's *next_flagp.
+         */
+        goto out;
+    }
+
+    *flagp |= GCF_MARK;
+
+#ifdef GC_MARK_DEBUG
+    if (js_DumpGCHeap)
+        gc_dump_thing(thing, *flagp, arg, js_DumpGCHeap);
+#endif
+
+    switch (*flagp & GCF_TYPEMASK) {
+      case GCX_OBJECT:
+        /* If obj->slots is null, obj must be a newborn. */
+        obj = (JSObject *) thing;
+        vp = obj->slots;
+        if (!vp)
+            goto out;
+
+        /* Switch to Deutsch-Schorr-Waite if we exhaust our stack quota. */
+        if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
+            METER(rt->gcStats.dswmark++);
+            DeutschSchorrWaite(cx, thing, flagp);
+            goto out;
+        }
+
+        /* Mark slots if they are small enough to be GC-allocated. */
+        if ((vp[-1] + 1) * sizeof(jsval) <= GC_NBYTES_MAX)
+            GC_MARK(cx, vp - 1, "slots", arg);
+
+        /* Set up local variables to loop over unmarked things. */
+        end = vp + ((obj->map->ops->mark)
+                    ? CALL_GC_THING_MARKER(obj->map->ops->mark, cx, obj, arg)
+                    : JS_MIN(obj->map->freeslot, obj->map->nslots));
+
+        vp = NEXT_UNMARKED_GC_THING(vp, end, &thing, &flagp, arg);
+        if (!vp)
+            goto out;
+        v = *vp;
+
+        /*
+         * Here, thing is the first value in obj->slots referring to an
+         * unmarked GC-thing.
+         */
+#ifdef GC_MARK_DEBUG
+        scope = OBJ_IS_NATIVE(obj) ? OBJ_SCOPE(obj) : NULL;
+#endif
+        for (;;) {
+            /* Check loop invariants. */
+            JS_ASSERT(v == *vp && JSVAL_IS_GCTHING(v));
+            JS_ASSERT(thing == JSVAL_TO_GCTHING(v));
+            JS_ASSERT(flagp == js_GetGCThingFlags(thing));
+
+#ifdef GC_MARK_DEBUG
+            if (scope) {
+                uint32 slot;
+                jsval nval;
+
+                slot = vp - obj->slots;
+                for (sprop = SCOPE_LAST_PROP(scope); ; sprop = sprop->parent) {
+                    if (!sprop) {
+                        switch (slot) {
+                          case JSSLOT_PROTO:
+                            strcpy(name, js_proto_str);
+                            break;
+                          case JSSLOT_PARENT:
+                            strcpy(name, js_parent_str);
+                            break;
+                          default:
+                            JS_snprintf(name, sizeof name,
+                                        "**UNKNOWN SLOT %ld**",
+                                        (long)slot);
+                            break;
+                        }
+                        break;
+                    }
+                    if (sprop->slot == slot) {
+                        nval = ID_TO_VALUE(sprop->id);
+                        if (JSVAL_IS_INT(nval)) {
+                            JS_snprintf(name, sizeof name, "%ld",
+                                        (long)JSVAL_TO_INT(nval));
+                        } else if (JSVAL_IS_STRING(nval)) {
+                            JS_snprintf(name, sizeof name, "%s",
+                              JS_GetStringBytes(JSVAL_TO_STRING(nval)));
+                        } else {
+                            strcpy(name, "**FINALIZED ATOM KEY**");
+                        }
+                        break;
+                    }
+                }
+            } else {
+                strcpy(name, "**UNKNOWN OBJECT MAP ENTRY**");
+            }
+#endif
+
+            do {
+                vp = NEXT_UNMARKED_GC_THING(vp+1, end, &next_thing, &next_flagp,
+                                            arg);
+                if (!vp) {
+                    /*
+                     * Here thing came from the last unmarked GC-thing slot.
+                     * We can eliminate tail recursion unless GC_MARK_DEBUG
+                     * is defined.
+                     */
+#ifdef GC_MARK_DEBUG
+                    GC_MARK(cx, thing, name, arg);
+                    goto out;
+#else
+                    METER(++tailCallNesting);
+                    goto start;
+#endif
+                }
+            } while (next_thing == thing);
+            v = *vp;
+
+#ifdef GC_MARK_DEBUG
+            GC_MARK(cx, thing, name, arg);
+#else
+            MARK_GC_THING(cx, thing, flagp, arg);
+#endif
+            thing = next_thing;
+            flagp = next_flagp;
+        }
+        break;
+
+#ifdef DEBUG
+      case GCX_STRING:
+        str = (JSString *)thing;
+        JS_ASSERT(!JSSTRING_IS_DEPENDENT(str));
+        break;
+#endif
+
+      case GCX_MUTABLE_STRING:
+        str = (JSString *)thing;
+        if (JSSTRING_IS_DEPENDENT(str)) {
+            thing = JSSTRDEP_BASE(str);
+            flagp = UNMARKED_GC_THING_FLAGS(thing, arg);
+            if (flagp) {
+#ifdef GC_MARK_DEBUG
+                GC_MARK(cx, thing, "base", arg);
+                goto out;
+#else
+                METER(++tailCallNesting);
+                goto start;
+#endif
+            }
+        }
+        break;
+
+#if JS_HAS_XML_SUPPORT
+      case GCX_NAMESPACE:
+        CALL_GC_THING_MARKER(js_MarkXMLNamespace, cx, (JSXMLNamespace *)thing,
+                             arg);
+        break;
+
+      case GCX_QNAME:
+        CALL_GC_THING_MARKER(js_MarkXMLQName, cx, (JSXMLQName *)thing, arg);
+        break;
+
+      case GCX_XML:
+        CALL_GC_THING_MARKER(js_MarkXML, cx, (JSXML *)thing, arg);
+        break;
+#endif
+    }
+
+out:
+    METER(rt->gcStats.depth -= 1 + tailCallNesting);
+    METER(rt->gcStats.cdepth--);
+    return JS_TRUE;
+}
+
+/*
+ * An invalid object reference that's distinct from JSVAL_TRUE and JSVAL_FALSE
+ * when tagged as a boolean.  Used to indicate empty DSW mark stack.
+ *
+ * Reversed pointers that link the DSW mark stack through obj->slots entries
+ * are also tagged as booleans so we can find each pointer and unreverse it.
+ * Because no object pointer is <= 16, these values can be distinguished from
+ * JSVAL_EMPTY, JSVAL_TRUE, and JSVAL_FALSE.
+ */
+#define JSVAL_EMPTY (2 << JSVAL_TAGBITS)
+
+/*
+ * To optimize native objects to avoid O(n^2) explosion in pathological cases,
+ * we use a dswIndex member of JSScope to tell where in obj->slots to find the
+ * reversed pointer.  Scrounging space in JSScope by packing existing members
+ * tighter yielded 16 bits of index, which we use directly if obj->slots has
+ * 64K or fewer slots.  Otherwise we make scope->dswIndex a fixed-point 16-bit
+ * fraction of the number of slots.
+ */
+static JS_INLINE uint16
+EncodeDSWIndex(jsval *vp, jsval *slots)
+{
+    uint32 nslots, limit, index;
+    jsdouble d;
+
+    nslots = slots[-1];
+    limit = JS_BIT(16);
+    index = PTRDIFF(vp, slots, jsval);
+    JS_ASSERT(index < nslots);
+    if (nslots > limit) {
+        d = ((jsdouble)index / nslots) * limit;
+        JS_ASSERT(0 <= d && d < limit);
+        return (uint16) d;
+    }
+    return (uint16) index;
+}
+
+static JS_INLINE uint32
+DecodeDSWIndex(uint16 dswIndex, jsval *slots)
+{
+    uint32 nslots, limit;
+    jsdouble d;
+
+    nslots = slots[-1];
+    limit = JS_BIT(16);
+    JS_ASSERT(dswIndex < nslots);
+    if (nslots > limit) {
+        d = ((jsdouble)dswIndex * nslots) / limit;
+        JS_ASSERT(0 <= d && d < nslots);
+        return (uint32) d;
+    }
+    return dswIndex;
+}
+
+static void
+DeutschSchorrWaite(JSContext *cx, void *thing, uint8 *flagp)
+{
+    jsval top, parent, v, *vp, *end;
+    JSObject *obj;
+    JSScope *scope;
+#ifdef JS_GCMETER
+    JSRuntime *rt = cx->runtime;
+#endif
+
+    top = JSVAL_EMPTY;
+
+down:
+    METER(if (++rt->gcStats.dswdepth > rt->gcStats.maxdswdepth)
+              rt->gcStats.maxdswdepth = rt->gcStats.dswdepth);
+    obj = (JSObject *) thing;
+    parent = OBJECT_TO_JSVAL(obj);
+
+    /* Precompute for quick testing to set and get scope->dswIndex. */
+    scope = (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->object == obj)
+            ? OBJ_SCOPE(obj)
+            : NULL;
+
+    /* Mark slots if they are small enough to be GC-allocated. */
+    vp = obj->slots;
+    if ((vp[-1] + 1) * sizeof(jsval) <= GC_NBYTES_MAX)
+        GC_MARK(cx, vp - 1, "slots", NULL);
+
+    end = vp + ((obj->map->ops->mark)
+                ? obj->map->ops->mark(cx, obj, NULL)
+                : JS_MIN(obj->map->freeslot, obj->map->nslots));
+
+    *flagp |= GCF_MARK;
+
+    for (;;) {
+        while ((vp = NEXT_UNMARKED_GC_THING(vp, end, &thing, &flagp, NULL))
+               != NULL) {
+            v = *vp;
+            JS_ASSERT(JSVAL_TO_GCTHING(v) == thing);
+
+            if (JSVAL_IS_OBJECT(v)) {
+                *vp = JSVAL_SETTAG(top, JSVAL_BOOLEAN);
+                top = parent;
+                if (scope)
+                    scope->dswIndex = EncodeDSWIndex(vp, obj->slots);
+                goto down;
+            }
+
+            /* Handle string and double GC-things. */
+            MARK_GC_THING(cx, thing, flagp, NULL);
+        }
+
+        /* If we are back at the root (or we never left it), we're done. */
+        METER(rt->gcStats.dswdepth--);
+        if (scope)
+            scope->dswIndex = 0;
+        if (top == JSVAL_EMPTY)
+            return;
+
+        /* Time to go back up the spanning tree. */
+        METER(rt->gcStats.dswup++);
+        obj = JSVAL_TO_OBJECT(top);
+        vp = obj->slots;
+        end = vp + vp[-1];
+
+        /*
+         * If obj is native and owns its own scope, we can minimize the cost
+         * of searching for the reversed pointer.
+         */
+        scope = (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->object == obj)
+                ? OBJ_SCOPE(obj)
+                : NULL;
+        if (scope)
+            vp += DecodeDSWIndex(scope->dswIndex, vp);
+
+        /*
+         * Alas, we must search for the reversed pointer.  If we used the
+         * scope->dswIndex hint, we'll step over a few slots for objects with
+         * a few times 64K slots, etc.  For more typical (that is, far fewer
+         * than 64K slots) native objects that own their own scopes, this loop
+         * won't iterate at all.  The order of complexity for host objects and
+         * unmutated native objects is O(n^2), but n (4 or 5 in most cases) is
+         * low enough that we don't care.
+         *
+         * We cannot use a reversed pointer into obj->slots, because there
+         * is no way to find an object from an address within its slots.
+         */
+        v = *vp;
+        while (v <= JSVAL_TRUE || !JSVAL_IS_BOOLEAN(v)) {
+            METER(rt->gcStats.dswupstep++);
+            JS_ASSERT(vp + 1 < end);
+            v = *++vp;
+        }
+
+        *vp++ = parent;
+        parent = top;
+        top = JSVAL_CLRTAG(v);
+    }
+}
+
+void
+js_MarkGCThing(JSContext *cx, void *thing, void *arg)
+{
+    uint8 *flagp;
+
+    flagp = UNMARKED_GC_THING_FLAGS(thing, arg);
+    if (!flagp)
+        return;
+    MARK_GC_THING(cx, thing, flagp, arg);
+}
+
+JS_STATIC_DLL_CALLBACK(JSDHashOperator)
+gc_root_marker(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num, void *arg)
+{
+    JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr;
+    jsval *rp = (jsval *)rhe->root;
+    jsval v = *rp;
+
+    /* Ignore null object and scalar values. */
+    if (!JSVAL_IS_NULL(v) && JSVAL_IS_GCTHING(v)) {
+        JSContext *cx = (JSContext *)arg;
+#ifdef DEBUG
+        uintN i;
+        JSArena *a;
+        jsuword firstpage;
+        JSBool root_points_to_gcArenaPool = JS_FALSE;
+        void *thing = JSVAL_TO_GCTHING(v);
+
+        for (i = 0; i < GC_NUM_FREELISTS; i++) {
+            for (a = cx->runtime->gcArenaPool[i].first.next; a; a = a->next) {
+                firstpage = FIRST_THING_PAGE(a);
+                if (JS_UPTRDIFF(thing, firstpage) < a->avail - firstpage) {
+                    root_points_to_gcArenaPool = JS_TRUE;
+                    break;
+                }
+            }
+        }
+        if (!root_points_to_gcArenaPool && rhe->name) {
+            fprintf(stderr,
+"JS API usage error: the address passed to JS_AddNamedRoot currently holds an\n"
+"invalid jsval.  This is usually caused by a missing call to JS_RemoveRoot.\n"
+"The root's name is \"%s\".\n",
+                    rhe->name);
+        }
+        JS_ASSERT(root_points_to_gcArenaPool);
+#endif
+
+        GC_MARK(cx, JSVAL_TO_GCTHING(v), rhe->name ? rhe->name : "root", NULL);
+    }
+    return JS_DHASH_NEXT;
+}
+
+JS_STATIC_DLL_CALLBACK(JSDHashOperator)
+gc_lock_marker(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num, void *arg)
+{
+    JSGCLockHashEntry *lhe = (JSGCLockHashEntry *)hdr;
+    void *thing = (void *)lhe->thing;
+    JSContext *cx = (JSContext *)arg;
+
+    GC_MARK(cx, thing, "locked object", NULL);
+    return JS_DHASH_NEXT;
+}
+
+void
+js_ForceGC(JSContext *cx, uintN gcflags)
+{
+    uintN i;
+
+    for (i = 0; i < GCX_NTYPES; i++)
+        cx->newborn[i] = NULL;
+    cx->lastAtom = NULL;
+    cx->runtime->gcPoke = JS_TRUE;
+    js_GC(cx, gcflags);
+    JS_ArenaFinish();
+}
+
+#define GC_MARK_JSVALS(cx, len, vec, name)                                    \
+    JS_BEGIN_MACRO                                                            \
+        jsval _v, *_vp, *_end;                                                \
+                                                                              \
+        for (_vp = vec, _end = _vp + len; _vp < _end; _vp++) {                \
+            _v = *_vp;                                                        \
+            if (JSVAL_IS_GCTHING(_v))                                         \
+                GC_MARK(cx, JSVAL_TO_GCTHING(_v), name, NULL);                \
+        }                                                                     \
+    JS_END_MACRO
+
+void
+js_GC(JSContext *cx, uintN gcflags)
+{
+    JSRuntime *rt;
+    JSContext *iter, *acx;
+    JSStackFrame *fp, *chain;
+    uintN i, depth, nslots, type;
+    JSStackHeader *sh;
+    JSTempValueRooter *tvr;
+    size_t nbytes, nflags;
+    JSArena *a, **ap;
+    uint8 flags, *flagp, *split;
+    JSGCThing *thing, *limit, **flp, **oflp;
+    GCFinalizeOp finalizer;
+    uint32 *bytesptr;
+    JSBool all_clear;
+#ifdef JS_THREADSAFE
+    jsword currentThread;
+    uint32 requestDebit;
+#endif
+
+    rt = cx->runtime;
+#ifdef JS_THREADSAFE
+    /* Avoid deadlock. */
+    JS_ASSERT(!JS_IS_RUNTIME_LOCKED(rt));
+#endif
+
+    /*
+     * Don't collect garbage if the runtime isn't up, and cx is not the last
+     * context in the runtime.  The last context must force a GC, and nothing
+     * should suppress that final collection or there may be shutdown leaks,
+     * or runtime bloat until the next context is created.
+     */
+    if (rt->state != JSRTS_UP && !(gcflags & GC_LAST_CONTEXT))
+        return;
+
+    /*
+     * Let the API user decide to defer a GC if it wants to (unless this
+     * is the last context).  Invoke the callback regardless.
+     */
+    if (rt->gcCallback) {
+        if (!rt->gcCallback(cx, JSGC_BEGIN) && !(gcflags & GC_LAST_CONTEXT))
+            return;
+    }
+
+    /* Lock out other GC allocator and collector invocations. */
+    if (!(gcflags & GC_ALREADY_LOCKED))
+        JS_LOCK_GC(rt);
+
+    /* Do nothing if no mutator has executed since the last GC. */
+    if (!rt->gcPoke) {
+        METER(rt->gcStats.nopoke++);
+        if (!(gcflags & GC_ALREADY_LOCKED))
+            JS_UNLOCK_GC(rt);
+        return;
+    }
+    METER(rt->gcStats.poke++);
+    rt->gcPoke = JS_FALSE;
+
+#ifdef JS_THREADSAFE
+    /* Bump gcLevel and return rather than nest on this thread. */
+    currentThread = js_CurrentThreadId();
+    if (rt->gcThread == currentThread) {
+        JS_ASSERT(rt->gcLevel > 0);
+        rt->gcLevel++;
+        METER(if (rt->gcLevel > rt->gcStats.maxlevel)
+                  rt->gcStats.maxlevel = rt->gcLevel);
+        if (!(gcflags & GC_ALREADY_LOCKED))
+            JS_UNLOCK_GC(rt);
+        return;
+    }
+
+    /*
+     * If we're in one or more requests (possibly on more than one context)
+     * running on the current thread, indicate, temporarily, that all these
+     * requests are inactive.  NB: if cx->thread is 0, then cx is not using
+     * the request model, and does not contribute to rt->requestCount.
+     */
+    requestDebit = 0;
+    if (cx->thread) {
+        /*
+         * Check all contexts for any with the same thread-id.  XXX should we
+         * keep a sub-list of contexts having the same id?
+         */
+        iter = NULL;
+        while ((acx = js_ContextIterator(rt, JS_FALSE, &iter)) != NULL) {
+            if (acx->thread == cx->thread && acx->requestDepth)
+                requestDebit++;
+        }
+    } else {
+        /*
+         * We assert, but check anyway, in case someone is misusing the API.
+         * Avoiding the loop over all of rt's contexts is a win in the event
+         * that the GC runs only on request-less contexts with 0 thread-ids,
+         * in a special thread such as might be used by the UI/DOM/Layout
+         * "mozilla" or "main" thread in Mozilla-the-browser.
+         */
+        JS_ASSERT(cx->requestDepth == 0);
+        if (cx->requestDepth)
+            requestDebit = 1;
+    }
+    if (requestDebit) {
+        JS_ASSERT(requestDebit <= rt->requestCount);
+        rt->requestCount -= requestDebit;
+        if (rt->requestCount == 0)
+            JS_NOTIFY_REQUEST_DONE(rt);
+    }
+
+    /* If another thread is already in GC, don't attempt GC; wait instead. */
+    if (rt->gcLevel > 0) {
+        /* Bump gcLevel to restart the current GC, so it finds new garbage. */
+        rt->gcLevel++;
+        METER(if (rt->gcLevel > rt->gcStats.maxlevel)
+                  rt->gcStats.maxlevel = rt->gcLevel);
+
+        /* Wait for the other thread to finish, then resume our request. */
+        while (rt->gcLevel > 0)
+            JS_AWAIT_GC_DONE(rt);
+        if (requestDebit)
+            rt->requestCount += requestDebit;
+        if (!(gcflags & GC_ALREADY_LOCKED))
+            JS_UNLOCK_GC(rt);
+        return;
+    }
+
+    /* No other thread is in GC, so indicate that we're now in GC. */
+    rt->gcLevel = 1;
+    rt->gcThread = currentThread;
+
+    /* Wait for all other requests to finish. */
+    while (rt->requestCount > 0)
+        JS_AWAIT_REQUEST_DONE(rt);
+
+#else  /* !JS_THREADSAFE */
+
+    /* Bump gcLevel and return rather than nest; the outer gc will restart. */
+    rt->gcLevel++;
+    METER(if (rt->gcLevel > rt->gcStats.maxlevel)
+              rt->gcStats.maxlevel = rt->gcLevel);
+    if (rt->gcLevel > 1)
+        return;
+
+#endif /* !JS_THREADSAFE */
+
+    /*
+     * Set rt->gcRunning here within the GC lock, and after waiting for any
+     * active requests to end, so that new requests that try to JS_AddRoot,
+     * JS_RemoveRoot, or JS_RemoveRootRT block in JS_BeginRequest waiting for
+     * rt->gcLevel to drop to zero, while request-less calls to the *Root*
+     * APIs block in js_AddRoot or js_RemoveRoot (see above in this file),
+     * waiting for GC to finish.
+     */
+    rt->gcRunning = JS_TRUE;
+    JS_UNLOCK_GC(rt);
+
+    /* If a suspended compile is running on another context, keep atoms. */
+    if (rt->gcKeepAtoms)
+        gcflags |= GC_KEEP_ATOMS;
+
+    /* Reset malloc counter. */
+    rt->gcMallocBytes = 0;
+
+    /* Drop atoms held by the property cache, and clear property weak links. */
+    js_DisablePropertyCache(cx);
+    js_FlushPropertyCache(cx);
+#ifdef DEBUG_notme
+  { extern void js_DumpScopeMeters(JSRuntime *rt);
+    js_DumpScopeMeters(rt);
+  }
+#endif
+
+restart:
+    rt->gcNumber++;
+
+    /*
+     * Mark phase.
+     */
+    JS_DHashTableEnumerate(&rt->gcRootsHash, gc_root_marker, cx);
+    if (rt->gcLocksHash)
+        JS_DHashTableEnumerate(rt->gcLocksHash, gc_lock_marker, cx);
+    js_MarkAtomState(&rt->atomState, gcflags, gc_mark_atom_key_thing, cx);
+    js_MarkWatchPoints(rt);
+    js_MarkScriptFilenames(rt, gcflags);
+
+    iter = NULL;
+    while ((acx = js_ContextIterator(rt, JS_TRUE, &iter)) != NULL) {
+        /*
+         * Iterate frame chain and dormant chains. Temporarily tack current
+         * frame onto the head of the dormant list to ease iteration.
+         *
+         * (NB: see comment on this whole "dormant" thing in js_Execute.)
+         */
+        chain = acx->fp;
+        if (chain) {
+            JS_ASSERT(!chain->dormantNext);
+            chain->dormantNext = acx->dormantFrameChain;
+        } else {
+            chain = acx->dormantFrameChain;
+        }
+
+        for (fp = chain; fp; fp = chain = chain->dormantNext) {
+            do {
+                if (fp->callobj)
+                    GC_MARK(cx, fp->callobj, "call object", NULL);
+                if (fp->argsobj)
+                    GC_MARK(cx, fp->argsobj, "arguments object", NULL);
+                if (fp->varobj)
+                    GC_MARK(cx, fp->varobj, "variables object", NULL);
+                if (fp->script) {
+                    js_MarkScript(cx, fp->script, NULL);
+                    if (fp->spbase) {
+                        /*
+                         * Don't mark what has not been pushed yet, or what
+                         * has been popped already.
+                         */
+                        depth = fp->script->depth;
+                        nslots = (JS_UPTRDIFF(fp->sp, fp->spbase)
+                                  < depth * sizeof(jsval))
+                                 ? (uintN)(fp->sp - fp->spbase)
+                                 : depth;
+                        GC_MARK_JSVALS(cx, nslots, fp->spbase, "operand");
+                    }
+                }
+                GC_MARK(cx, fp->thisp, "this", NULL);
+                if (fp->argv) {
+                    nslots = fp->argc;
+                    if (fp->fun) {
+                        if (fp->fun->nargs > nslots)
+                            nslots = fp->fun->nargs;
+                        nslots += fp->fun->extra;
+                    }
+                    GC_MARK_JSVALS(cx, nslots, fp->argv, "arg");
+                }
+                if (JSVAL_IS_GCTHING(fp->rval))
+                    GC_MARK(cx, JSVAL_TO_GCTHING(fp->rval), "rval", NULL);
+                if (fp->vars)
+                    GC_MARK_JSVALS(cx, fp->nvars, fp->vars, "var");
+                GC_MARK(cx, fp->scopeChain, "scope chain", NULL);
+                if (fp->sharpArray)
+                    GC_MARK(cx, fp->sharpArray, "sharp array", NULL);
+
+                if (fp->xmlNamespace)
+                    GC_MARK(cx, fp->xmlNamespace, "xmlNamespace", NULL);
+            } while ((fp = fp->down) != NULL);
+        }
+
+        /* Cleanup temporary "dormant" linkage. */
+        if (acx->fp)
+            acx->fp->dormantNext = NULL;
+
+        /* Mark other roots-by-definition in acx. */
+        GC_MARK(cx, acx->globalObject, "global object", NULL);
+        for (i = 0; i < GCX_NTYPES; i++)
+            GC_MARK(cx, acx->newborn[i], gc_typenames[i], NULL);
+        if (acx->lastAtom)
+            GC_MARK_ATOM(cx, acx->lastAtom, NULL);
+        if (JSVAL_IS_GCTHING(acx->lastInternalResult)) {
+            thing = JSVAL_TO_GCTHING(acx->lastInternalResult);
+            if (thing)
+                GC_MARK(cx, thing, "lastInternalResult", NULL);
+        }
+#if JS_HAS_EXCEPTIONS
+        if (acx->throwing && JSVAL_IS_GCTHING(acx->exception))
+            GC_MARK(cx, JSVAL_TO_GCTHING(acx->exception), "exception", NULL);
+#endif
+#if JS_HAS_LVALUE_RETURN
+        if (acx->rval2set && JSVAL_IS_GCTHING(acx->rval2))
+            GC_MARK(cx, JSVAL_TO_GCTHING(acx->rval2), "rval2", NULL);
+#endif
+
+        for (sh = acx->stackHeaders; sh; sh = sh->down) {
+            METER(rt->gcStats.stackseg++);
+            METER(rt->gcStats.segslots += sh->nslots);
+            GC_MARK_JSVALS(cx, sh->nslots, JS_STACK_SEGMENT(sh), "stack");
+        }
+
+        if (acx->localRootStack)
+            js_MarkLocalRoots(cx, acx->localRootStack);
+        for (tvr = acx->tempValueRooters; tvr; tvr = tvr->down) {
+            if (tvr->count < 0) {
+                if (JSVAL_IS_GCTHING(tvr->u.value)) {
+                    GC_MARK(cx, JSVAL_TO_GCTHING(tvr->u.value), "tvr->u.value",
+                            NULL);
+                }
+            } else {
+                GC_MARK_JSVALS(cx, tvr->count, tvr->u.array, "tvr->u.array");
+            }
+        }
+    }
+#ifdef DUMP_CALL_TABLE
+    js_DumpCallTable(cx);
+#endif
+
+    if (rt->gcCallback)
+        (void) rt->gcCallback(cx, JSGC_MARK_END);
+
+    /*
+     * Sweep phase.
+     *
+     * Finalize as we sweep, outside of rt->gcLock, but with rt->gcRunning set
+     * so that any attempt to allocate a GC-thing from a finalizer will fail,
+     * rather than nest badly and leave the unmarked newborn to be swept.
+     *
+     * Finalize smaller objects before larger, to guarantee finalization of
+     * GC-allocated obj->slots after obj.  See FreeSlots in jsobj.c.
+     */
+    js_SweepAtomState(&rt->atomState);
+    js_SweepScopeProperties(rt);
+    js_SweepScriptFilenames(rt);
+    for (i = 0; i < GC_NUM_FREELISTS; i++) {
+        nbytes = GC_FREELIST_NBYTES(i);
+        nflags = nbytes / sizeof(JSGCThing);
+
+        for (a = rt->gcArenaPool[i].first.next; a; a = a->next) {
+            flagp = (uint8 *) a->base;
+            split = (uint8 *) FIRST_THING_PAGE(a);
+            limit = (JSGCThing *) a->avail;
+            for (thing = (JSGCThing *) split; thing < limit; thing += nflags) {
+                if (((jsuword)thing & GC_PAGE_MASK) == 0) {
+                    thing = (JSGCThing *) FIRST_THING((jsuword)thing, nbytes);
+                    flagp = js_GetGCThingFlags(thing);
+                }
+                flags = *flagp;
+                if (flags & GCF_MARK) {
+                    *flagp &= ~GCF_MARK;
+                } else if (!(flags & (GCF_LOCK | GCF_FINAL))) {
+                    /* Call the finalizer with GCF_FINAL ORed into flags. */
+                    type = flags & GCF_TYPEMASK;
+                    finalizer = gc_finalizers[type];
+                    if (finalizer) {
+                        *flagp = (uint8)(flags | GCF_FINAL);
+                        if (type >= GCX_EXTERNAL_STRING)
+                            js_PurgeDeflatedStringCache((JSString *)thing);
+                        finalizer(cx, thing);
+                    }
+
+                    /* Set flags to GCF_FINAL, signifying that thing is free. */
+                    *flagp = GCF_FINAL;
+
+                    bytesptr = (type == GCX_PRIVATE)
+                               ? &rt->gcPrivateBytes
+                               : &rt->gcBytes;
+                    JS_ASSERT(*bytesptr >= nbytes + nflags);
+                    *bytesptr -= nbytes + nflags;
+                }
+                flagp += nflags;
+                if (JS_UPTRDIFF(flagp, split) < nflags)
+                    flagp += GC_THINGS_SIZE;
+            }
+        }
+    }
+
+    /*
+     * Free phase.
+     * Free any unused arenas and rebuild the JSGCThing freelist.
+     */
+    for (i = 0; i < GC_NUM_FREELISTS; i++) {
+        ap = &rt->gcArenaPool[i].first.next;
+        a = *ap;
+        if (!a)
+            continue;
+
+        all_clear = JS_TRUE;
+        flp = oflp = &rt->gcFreeList[i];
+        *flp = NULL;
+        METER(rt->gcStats.freelen[i] = 0);
+
+        nbytes = GC_FREELIST_NBYTES(i);
+        nflags = nbytes / sizeof(JSGCThing);
+        do {
+            flagp = (uint8 *) a->base;
+            split = (uint8 *) FIRST_THING_PAGE(a);
+            limit = (JSGCThing *) a->avail;
+            for (thing = (JSGCThing *) split; thing < limit; thing += nflags) {
+                if (((jsuword)thing & GC_PAGE_MASK) == 0) {
+                    thing = (JSGCThing *) FIRST_THING((jsuword)thing, nbytes);
+                    flagp = js_GetGCThingFlags(thing);
+                }
+                if (*flagp != GCF_FINAL) {
+                    all_clear = JS_FALSE;
+                } else {
+                    thing->flagp = flagp;
+                    *flp = thing;
+                    flp = &thing->next;
+                    METER(rt->gcStats.freelen[i]++);
+                }
+                flagp += nflags;
+                if (JS_UPTRDIFF(flagp, split) < nflags)
+                    flagp += GC_THINGS_SIZE;
+            }
+
+            if (all_clear) {
+                JS_ARENA_DESTROY(&rt->gcArenaPool[i], a, ap);
+                flp = oflp;
+                METER(rt->gcStats.afree++);
+            } else {
+                ap = &a->next;
+                all_clear = JS_TRUE;
+                oflp = flp;
+            }
+        } while ((a = *ap) != NULL);
+
+        /* Terminate the new freelist. */
+        *flp = NULL;
+    }
+
+    if (rt->gcCallback)
+        (void) rt->gcCallback(cx, JSGC_FINALIZE_END);
+#ifdef DEBUG_notme
+  { extern void DumpSrcNoteSizeHist();
+    DumpSrcNoteSizeHist();
+    printf("GC HEAP SIZE %lu (%lu)\n",
+           (unsigned long)rt->gcBytes, (unsigned long)rt->gcPrivateBytes);
+  }
+#endif
+
+    JS_LOCK_GC(rt);
+    if (rt->gcLevel > 1 || rt->gcPoke) {
+        rt->gcLevel = 1;
+        rt->gcPoke = JS_FALSE;
+        JS_UNLOCK_GC(rt);
+        goto restart;
+    }
+    js_EnablePropertyCache(cx);
+    rt->gcLevel = 0;
+    rt->gcLastBytes = rt->gcBytes;
+    rt->gcRunning = JS_FALSE;
+
+#ifdef JS_THREADSAFE
+    /* If we were invoked during a request, pay back the temporary debit. */
+    if (requestDebit)
+        rt->requestCount += requestDebit;
+    rt->gcThread = 0;
+    JS_NOTIFY_GC_DONE(rt);
+    if (!(gcflags & GC_ALREADY_LOCKED))
+        JS_UNLOCK_GC(rt);
+#endif
+
+    if (rt->gcCallback) {
+        if (gcflags & GC_ALREADY_LOCKED)
+            JS_UNLOCK_GC(rt);
+        (void) rt->gcCallback(cx, JSGC_END);
+        if (gcflags & GC_ALREADY_LOCKED)
+            JS_LOCK_GC(rt);
+    }
+}

Added: freeswitch/trunk/libs/js/src/jsgc.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsgc.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,269 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsgc_h___
+#define jsgc_h___
+/*
+ * JS Garbage Collector.
+ */
+#include "jsprvtd.h"
+#include "jspubtd.h"
+#include "jsdhash.h"
+
+JS_BEGIN_EXTERN_C
+
+/* GC thing type indexes. */
+#define GCX_OBJECT              0               /* JSObject */
+#define GCX_STRING              1               /* JSString */
+#define GCX_DOUBLE              2               /* jsdouble */
+#define GCX_MUTABLE_STRING      3               /* JSString that's mutable --
+                                                   single-threaded only! */
+#define GCX_PRIVATE             4               /* private (unscanned) data */
+#define GCX_NAMESPACE           5               /* JSXMLNamespace */
+#define GCX_QNAME               6               /* JSXMLQName */
+#define GCX_XML                 7               /* JSXML */
+#define GCX_EXTERNAL_STRING     8               /* JSString w/ external chars */
+
+#define GCX_NTYPES_LOG2         4               /* type index bits */
+#define GCX_NTYPES              JS_BIT(GCX_NTYPES_LOG2)
+
+/* GC flag definitions, must fit in 8 bits (type index goes in the low bits). */
+#define GCF_TYPEMASK    JS_BITMASK(GCX_NTYPES_LOG2)
+#define GCF_MARK        JS_BIT(GCX_NTYPES_LOG2)
+#define GCF_FINAL       JS_BIT(GCX_NTYPES_LOG2 + 1)
+#define GCF_SYSTEM      JS_BIT(GCX_NTYPES_LOG2 + 2)
+#define GCF_LOCKSHIFT   (GCX_NTYPES_LOG2 + 3)   /* lock bit shift */
+#define GCF_LOCK        JS_BIT(GCF_LOCKSHIFT)   /* lock request bit in API */
+
+/* Pseudo-flag that modifies GCX_STRING to make GCX_MUTABLE_STRING. */
+#define GCF_MUTABLE     2
+
+#if (GCX_STRING | GCF_MUTABLE) != GCX_MUTABLE_STRING
+# error "mutable string type index botch!"
+#endif
+
+extern uint8 *
+js_GetGCThingFlags(void *thing);
+
+/* These are compatible with JSDHashEntryStub. */
+struct JSGCRootHashEntry {
+    JSDHashEntryHdr hdr;
+    void            *root;
+    const char      *name;
+};
+
+struct JSGCLockHashEntry {
+    JSDHashEntryHdr hdr;
+    const JSGCThing *thing;
+    uint32          count;
+};
+
+#if 1
+/*
+ * Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles
+ * loading oldval.  XXX remove implied force, fix jsinterp.c's "second arg
+ * ignored", etc.
+ */
+#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JS_TRUE)
+#else
+#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JSVAL_IS_GCTHING(oldval))
+#endif
+
+extern intN
+js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
+                                 JSStringFinalizeOp newop);
+
+extern JSBool
+js_InitGC(JSRuntime *rt, uint32 maxbytes);
+
+extern void
+js_FinishGC(JSRuntime *rt);
+
+extern JSBool
+js_AddRoot(JSContext *cx, void *rp, const char *name);
+
+extern JSBool
+js_AddRootRT(JSRuntime *rt, void *rp, const char *name);
+
+extern JSBool
+js_RemoveRoot(JSRuntime *rt, void *rp);
+
+/*
+ * The private JSGCThing struct, which describes a gcFreeList element.
+ */
+struct JSGCThing {
+    JSGCThing   *next;
+    uint8       *flagp;
+};
+
+#define GC_NBYTES_MAX           (10 * sizeof(JSGCThing))
+#define GC_NUM_FREELISTS        (GC_NBYTES_MAX / sizeof(JSGCThing))
+#define GC_FREELIST_NBYTES(i)   (((i) + 1) * sizeof(JSGCThing))
+#define GC_FREELIST_INDEX(n)    (((n) / sizeof(JSGCThing)) - 1)
+
+extern void *
+js_NewGCThing(JSContext *cx, uintN flags, size_t nbytes);
+
+extern JSBool
+js_LockGCThing(JSContext *cx, void *thing);
+
+extern JSBool
+js_LockGCThingRT(JSRuntime *rt, void *thing);
+
+extern JSBool
+js_UnlockGCThingRT(JSRuntime *rt, void *thing);
+
+extern JSBool
+js_IsAboutToBeFinalized(JSContext *cx, void *thing);
+
+extern void
+js_MarkAtom(JSContext *cx, JSAtom *atom, void *arg);
+
+/* We avoid a large number of unnecessary calls by doing the flag check first */
+#define GC_MARK_ATOM(cx, atom, arg)                                           \
+    JS_BEGIN_MACRO                                                            \
+        if (!((atom)->flags & ATOM_MARK))                                     \
+            js_MarkAtom(cx, atom, arg);                                       \
+    JS_END_MACRO
+
+extern void
+js_MarkGCThing(JSContext *cx, void *thing, void *arg);
+
+#ifdef GC_MARK_DEBUG
+
+typedef struct GCMarkNode GCMarkNode;
+
+struct GCMarkNode {
+    void        *thing;
+    const char  *name;
+    GCMarkNode  *next;
+    GCMarkNode  *prev;
+};
+
+#define GC_MARK(cx_, thing_, name_, prev_)                                    \
+    JS_BEGIN_MACRO                                                            \
+        GCMarkNode node_;                                                     \
+        node_.thing = thing_;                                                 \
+        node_.name  = name_;                                                  \
+        node_.next  = NULL;                                                   \
+        node_.prev  = prev_;                                                  \
+        if (prev_) ((GCMarkNode *)(prev_))->next = &node_;                    \
+        js_MarkGCThing(cx_, thing_, &node_);                                  \
+    JS_END_MACRO
+
+#else  /* !GC_MARK_DEBUG */
+
+#define GC_MARK(cx, thing, name, prev)   js_MarkGCThing(cx, thing, NULL)
+
+#endif /* !GC_MARK_DEBUG */
+
+/*
+ * Flags to modify how a GC marks and sweeps:
+ *   GC_KEEP_ATOMS      Don't sweep unmarked atoms, they may be in use by the
+ *                      compiler, or by an API function that calls js_Atomize,
+ *                      when the GC is called from js_NewGCThing, due to a
+ *                      malloc failure or the runtime GC-thing limit.
+ *   GC_LAST_CONTEXT    Called from js_DestroyContext for last JSContext in a
+ *                      JSRuntime, when it is imperative that rt->gcPoke gets
+ *                      cleared early in js_GC, if it is set.
+ *   GC_ALREADY_LOCKED  rt->gcLock is already held on entry to js_GC, and kept
+ *                      on return to its caller.
+ */
+#define GC_KEEP_ATOMS       0x1
+#define GC_LAST_CONTEXT     0x2
+#define GC_ALREADY_LOCKED   0x4
+
+extern void
+js_ForceGC(JSContext *cx, uintN gcflags);
+
+extern void
+js_GC(JSContext *cx, uintN gcflags);
+
+#ifdef DEBUG_notme
+#define JS_GCMETER 1
+#endif
+
+#ifdef JS_GCMETER
+
+typedef struct JSGCStats {
+    uint32  alloc;      /* number of allocation attempts */
+    uint32  freelen[GC_NUM_FREELISTS];
+                        /* gcFreeList lengths */
+    uint32  recycle[GC_NUM_FREELISTS];
+                        /* number of things recycled through gcFreeList */
+    uint32  retry;      /* allocation attempt retries after running the GC */
+    uint32  retryhalt;  /* allocation retries halted by the branch callback */
+    uint32  fail;       /* allocation failures */
+    uint32  finalfail;  /* finalizer calls allocator failures */
+    uint32  lockborn;   /* things born locked */
+    uint32  lock;       /* valid lock calls */
+    uint32  unlock;     /* valid unlock calls */
+    uint32  depth;      /* mark tail recursion depth */
+    uint32  maxdepth;   /* maximum mark tail recursion depth */
+    uint32  cdepth;     /* mark recursion depth of C functions */
+    uint32  maxcdepth;  /* maximum mark recursion depth of C functions */
+    uint32  dswmark;    /* mark C stack overflows => Deutsch-Schorr-Waite */
+    uint32  dswdepth;   /* DSW mark depth */
+    uint32  maxdswdepth;/* maximum DSW mark depth */
+    uint32  dswup;      /* DSW moves up the mark spanning tree */
+    uint32  dswupstep;  /* steps in obj->slots to find DSW-reversed pointer */
+    uint32  maxlevel;   /* maximum GC nesting (indirect recursion) level */
+    uint32  poke;       /* number of potentially useful GC calls */
+    uint32  nopoke;     /* useless GC calls where js_PokeGC was not set */
+    uint32  afree;      /* thing arenas freed so far */
+    uint32  stackseg;   /* total extraordinary stack segments scanned */
+    uint32  segslots;   /* total stack segment jsval slots scanned */
+} JSGCStats;
+
+extern JS_FRIEND_API(void)
+js_DumpGCStats(JSRuntime *rt, FILE *fp);
+
+#endif /* JS_GCMETER */
+
+#ifdef DEBUG_notme
+#define TOO_MUCH_GC 1
+#endif
+
+#ifdef WAY_TOO_MUCH_GC
+#define TOO_MUCH_GC 1
+#endif
+
+JS_END_EXTERN_C
+
+#endif /* jsgc_h___ */

Added: freeswitch/trunk/libs/js/src/jshash.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jshash.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,471 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * PR hash table package.
+ */
+#include "jsstddef.h"
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsbit.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jshash.h" /* Added by JSIFY */
+
+/* Compute the number of buckets in ht */
+#define NBUCKETS(ht)    JS_BIT(JS_HASH_BITS - (ht)->shift)
+
+/* The smallest table has 16 buckets */
+#define MINBUCKETSLOG2  4
+#define MINBUCKETS      JS_BIT(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 *
+DefaultAllocTable(void *pool, size_t size)
+{
+    return malloc(size);
+}
+
+static void
+DefaultFreeTable(void *pool, void *item)
+{
+    free(item);
+}
+
+static JSHashEntry *
+DefaultAllocEntry(void *pool, const void *key)
+{
+    return (JSHashEntry*) malloc(sizeof(JSHashEntry));
+}
+
+static void
+DefaultFreeEntry(void *pool, JSHashEntry *he, uintN flag)
+{
+    if (flag == HT_FREE_ENTRY)
+        free(he);
+}
+
+static JSHashAllocOps defaultHashAllocOps = {
+    DefaultAllocTable, DefaultFreeTable,
+    DefaultAllocEntry, DefaultFreeEntry
+};
+
+JS_PUBLIC_API(JSHashTable *)
+JS_NewHashTable(uint32 n, JSHashFunction keyHash,
+                JSHashComparator keyCompare, JSHashComparator valueCompare,
+                JSHashAllocOps *allocOps, void *allocPriv)
+{
+    JSHashTable *ht;
+    size_t nb;
+
+    if (n <= MINBUCKETS) {
+        n = MINBUCKETSLOG2;
+    } else {
+        n = JS_CeilingLog2(n);
+        if ((int32)n < 0)
+            return NULL;
+    }
+
+    if (!allocOps) allocOps = &defaultHashAllocOps;
+
+    ht = (JSHashTable*) allocOps->allocTable(allocPriv, sizeof *ht);
+    if (!ht)
+        return NULL;
+    memset(ht, 0, sizeof *ht);
+    ht->shift = JS_HASH_BITS - n;
+    n = JS_BIT(n);
+    nb = n * sizeof(JSHashEntry *);
+    ht->buckets = (JSHashEntry**) allocOps->allocTable(allocPriv, nb);
+    if (!ht->buckets) {
+        allocOps->freeTable(allocPriv, ht);
+        return NULL;
+    }
+    memset(ht->buckets, 0, nb);
+
+    ht->keyHash = keyHash;
+    ht->keyCompare = keyCompare;
+    ht->valueCompare = valueCompare;
+    ht->allocOps = allocOps;
+    ht->allocPriv = allocPriv;
+    return ht;
+}
+
+JS_PUBLIC_API(void)
+JS_HashTableDestroy(JSHashTable *ht)
+{
+    uint32 i, n;
+    JSHashEntry *he, **hep;
+    JSHashAllocOps *allocOps = ht->allocOps;
+    void *allocPriv = ht->allocPriv;
+
+    n = NBUCKETS(ht);
+    for (i = 0; i < n; i++) {
+        hep = &ht->buckets[i];
+        while ((he = *hep) != NULL) {
+            *hep = 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.
+*/
+JS_PUBLIC_API(JSHashEntry **)
+JS_HashTableRawLookup(JSHashTable *ht, JSHashNumber keyHash, const void *key)
+{
+    JSHashEntry *he, **hep, **hep0;
+    JSHashNumber h;
+
+#ifdef HASHMETER
+    ht->nlookups++;
+#endif
+    h = keyHash * JS_GOLDEN_RATIO;
+    h >>= ht->shift;
+    hep = hep0 = &ht->buckets[h];
+    while ((he = *hep) != NULL) {
+        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;
+}
+
+JS_PUBLIC_API(JSHashEntry *)
+JS_HashTableRawAdd(JSHashTable *ht, JSHashEntry **hep,
+                   JSHashNumber keyHash, const void *key, void *value)
+{
+    uint32 i, n;
+    JSHashEntry *he, *next, **oldbuckets;
+    size_t nb;
+
+    /* Grow the table if it is overloaded */
+    n = NBUCKETS(ht);
+    if (ht->nentries >= OVERLOADED(n)) {
+        oldbuckets = ht->buckets;
+        nb = 2 * n * sizeof(JSHashEntry *);
+        ht->buckets = (JSHashEntry**)
+            ht->allocOps->allocTable(ht->allocPriv, nb);
+        if (!ht->buckets) {
+            ht->buckets = oldbuckets;
+            return NULL;
+        }
+        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 = JS_HashTableRawLookup(ht, he->keyHash, he->key);
+                JS_ASSERT(*hep == NULL);
+                he->next = NULL;
+                *hep = he;
+            }
+        }
+#ifdef DEBUG
+        memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
+#endif
+        ht->allocOps->freeTable(ht->allocPriv, oldbuckets);
+        hep = JS_HashTableRawLookup(ht, keyHash, key);
+    }
+
+    /* Make a new key value entry */
+    he = ht->allocOps->allocEntry(ht->allocPriv, key);
+    if (!he)
+        return NULL;
+    he->keyHash = keyHash;
+    he->key = key;
+    he->value = value;
+    he->next = *hep;
+    *hep = he;
+    ht->nentries++;
+    return he;
+}
+
+JS_PUBLIC_API(JSHashEntry *)
+JS_HashTableAdd(JSHashTable *ht, const void *key, void *value)
+{
+    JSHashNumber keyHash;
+    JSHashEntry *he, **hep;
+
+    keyHash = ht->keyHash(key);
+    hep = JS_HashTableRawLookup(ht, keyHash, key);
+    if ((he = *hep) != NULL) {
+        /* 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 JS_HashTableRawAdd(ht, hep, keyHash, key, value);
+}
+
+JS_PUBLIC_API(void)
+JS_HashTableRawRemove(JSHashTable *ht, JSHashEntry **hep, JSHashEntry *he)
+{
+    uint32 i, n;
+    JSHashEntry *next, **oldbuckets;
+    size_t 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(JSHashEntry*) / 2;
+        ht->buckets = (JSHashEntry**)
+            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 = JS_HashTableRawLookup(ht, he->keyHash, he->key);
+                JS_ASSERT(*hep == NULL);
+                he->next = NULL;
+                *hep = he;
+            }
+        }
+#ifdef DEBUG
+        memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
+#endif
+        ht->allocOps->freeTable(ht->allocPriv, oldbuckets);
+    }
+}
+
+JS_PUBLIC_API(JSBool)
+JS_HashTableRemove(JSHashTable *ht, const void *key)
+{
+    JSHashNumber keyHash;
+    JSHashEntry *he, **hep;
+
+    keyHash = ht->keyHash(key);
+    hep = JS_HashTableRawLookup(ht, keyHash, key);
+    if ((he = *hep) == NULL)
+        return JS_FALSE;
+
+    /* Hit; remove element */
+    JS_HashTableRawRemove(ht, hep, he);
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(void *)
+JS_HashTableLookup(JSHashTable *ht, const void *key)
+{
+    JSHashNumber keyHash;
+    JSHashEntry *he, **hep;
+
+    keyHash = ht->keyHash(key);
+    hep = JS_HashTableRawLookup(ht, keyHash, key);
+    if ((he = *hep) != NULL) {
+        return he->value;
+    }
+    return NULL;
+}
+
+/*
+** Iterate over the entries in the hash table calling func for each
+** entry found. Stop if "f" says to (return value & JS_ENUMERATE_STOP).
+** Return a count of the number of elements scanned.
+*/
+JS_PUBLIC_API(int)
+JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg)
+{
+    JSHashEntry *he, **hep;
+    uint32 i, nbuckets;
+    int rv, n = 0;
+    JSHashEntry *todo = NULL;
+
+    nbuckets = NBUCKETS(ht);
+    for (i = 0; i < nbuckets; i++) {
+        hep = &ht->buckets[i];
+        while ((he = *hep) != NULL) {
+            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) != NULL) {
+        JS_HashTableRawRemove(ht, hep, he);
+    }
+    return n;
+}
+
+#ifdef HASHMETER
+#include <math.h>
+#include <stdio.h>
+
+JS_PUBLIC_API(void)
+JS_HashTableDumpMeter(JSHashTable *ht, JSHashEnumerator dump, FILE *fp)
+{
+    double sqsum, mean, variance, sigma;
+    uint32 nchains, nbuckets, nentries;
+    uint32 i, n, maxChain, maxChainLen;
+    JSHashEntry *he;
+
+    sqsum = 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++;
+        sqsum += n * n;
+        if (n > maxChainLen) {
+            maxChainLen = n;
+            maxChain = i;
+        }
+    }
+    nentries = ht->nentries;
+    mean = (double)nentries / nchains;
+    variance = nchains * sqsum - nentries * nentries;
+    if (variance < 0 || nchains == 1)
+        variance = 0;
+    else
+        variance /= nchains * (nchains - 1);
+    sigma = sqrt(variance);
+
+    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", sigma);
+    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 */
+
+JS_PUBLIC_API(int)
+JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp)
+{
+    int count;
+
+    count = JS_HashTableEnumerateEntries(ht, dump, fp);
+#ifdef HASHMETER
+    JS_HashTableDumpMeter(ht, dump, fp);
+#endif
+    return count;
+}
+
+JS_PUBLIC_API(JSHashNumber)
+JS_HashString(const void *key)
+{
+    JSHashNumber h;
+    const unsigned char *s;
+
+    h = 0;
+    for (s = (const unsigned char *)key; *s; s++)
+        h = (h >> (JS_HASH_BITS - 4)) ^ (h << 4) ^ *s;
+    return h;
+}
+
+JS_PUBLIC_API(int)
+JS_CompareValues(const void *v1, const void *v2)
+{
+    return v1 == v2;
+}

Added: freeswitch/trunk/libs/js/src/jshash.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jshash.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,152 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jshash_h___
+#define jshash_h___
+/*
+ * API to portable hash table code.
+ */
+#include <stddef.h>
+#include <stdio.h>
+#include "jstypes.h"
+#include "jscompat.h"
+
+JS_BEGIN_EXTERN_C
+
+typedef uint32 JSHashNumber;
+typedef struct JSHashEntry JSHashEntry;
+typedef struct JSHashTable JSHashTable;
+
+#define JS_HASH_BITS 32
+#define JS_GOLDEN_RATIO 0x9E3779B9U
+
+typedef JSHashNumber (* JS_DLL_CALLBACK JSHashFunction)(const void *key);
+typedef intN (* JS_DLL_CALLBACK JSHashComparator)(const void *v1, const void *v2);
+typedef intN (* JS_DLL_CALLBACK JSHashEnumerator)(JSHashEntry *he, intN i, void *arg);
+
+/* Flag bits in JSHashEnumerator'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 JSHashAllocOps {
+    void *              (*allocTable)(void *pool, size_t size);
+    void                (*freeTable)(void *pool, void *item);
+    JSHashEntry *       (*allocEntry)(void *pool, const void *key);
+    void                (*freeEntry)(void *pool, JSHashEntry *he, uintN flag);
+} JSHashAllocOps;
+
+#define HT_FREE_VALUE   0               /* just free the entry's value */
+#define HT_FREE_ENTRY   1               /* free value and entire entry */
+
+struct JSHashEntry {
+    JSHashEntry         *next;          /* hash chain linkage */
+    JSHashNumber        keyHash;        /* key hash function result */
+    const void          *key;           /* ptr to opaque key */
+    void                *value;         /* ptr to opaque value */
+};
+
+struct JSHashTable {
+    JSHashEntry         **buckets;      /* vector of hash buckets */
+    uint32              nentries;       /* number of entries in table */
+    uint32              shift;          /* multiplicative hash shift */
+    JSHashFunction      keyHash;        /* key hash function */
+    JSHashComparator    keyCompare;     /* key comparison function */
+    JSHashComparator    valueCompare;   /* value comparison function */
+    JSHashAllocOps      *allocOps;      /* allocation operations */
+    void                *allocPriv;     /* allocation private data */
+#ifdef HASHMETER
+    uint32              nlookups;       /* total number of lookups */
+    uint32              nsteps;         /* number of hash chains traversed */
+    uint32              ngrows;         /* number of table expansions */
+    uint32              nshrinks;       /* number of table contractions */
+#endif
+};
+
+/*
+ * Create a new hash table.
+ * If allocOps is null, use default allocator ops built on top of malloc().
+ */
+extern JS_PUBLIC_API(JSHashTable *)
+JS_NewHashTable(uint32 n, JSHashFunction keyHash,
+                JSHashComparator keyCompare, JSHashComparator valueCompare,
+                JSHashAllocOps *allocOps, void *allocPriv);
+
+extern JS_PUBLIC_API(void)
+JS_HashTableDestroy(JSHashTable *ht);
+
+/* Low level access methods */
+extern JS_PUBLIC_API(JSHashEntry **)
+JS_HashTableRawLookup(JSHashTable *ht, JSHashNumber keyHash, const void *key);
+
+extern JS_PUBLIC_API(JSHashEntry *)
+JS_HashTableRawAdd(JSHashTable *ht, JSHashEntry **hep, JSHashNumber keyHash,
+                   const void *key, void *value);
+
+extern JS_PUBLIC_API(void)
+JS_HashTableRawRemove(JSHashTable *ht, JSHashEntry **hep, JSHashEntry *he);
+
+/* Higher level access methods */
+extern JS_PUBLIC_API(JSHashEntry *)
+JS_HashTableAdd(JSHashTable *ht, const void *key, void *value);
+
+extern JS_PUBLIC_API(JSBool)
+JS_HashTableRemove(JSHashTable *ht, const void *key);
+
+extern JS_PUBLIC_API(intN)
+JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg);
+
+extern JS_PUBLIC_API(void *)
+JS_HashTableLookup(JSHashTable *ht, const void *key);
+
+extern JS_PUBLIC_API(intN)
+JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp);
+
+/* General-purpose C string hash function. */
+extern JS_PUBLIC_API(JSHashNumber)
+JS_HashString(const void *key);
+
+/* Stub function just returns v1 == v2 */
+extern JS_PUBLIC_API(intN)
+JS_CompareValues(const void *v1, const void *v2);
+
+JS_END_EXTERN_C
+
+#endif /* jshash_h___ */

Added: freeswitch/trunk/libs/js/src/jsinterp.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsinterp.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,5511 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JavaScript bytecode interpreter.
+ */
+#include "jsstddef.h"
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "jstypes.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jsarray.h"
+#include "jsatom.h"
+#include "jsbool.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsdbgapi.h"
+#include "jsfun.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsopcode.h"
+#include "jsscope.h"
+#include "jsscript.h"
+#include "jsstr.h"
+
+#if JS_HAS_JIT
+#include "jsjit.h"
+#endif
+
+#if JS_HAS_XML_SUPPORT
+#include "jsxml.h"
+#endif
+
+#ifdef DEBUG
+#define ASSERT_CACHE_IS_EMPTY(cache)                                          \
+    JS_BEGIN_MACRO                                                            \
+        JSPropertyCacheEntry *end_, *pce_, entry_;                            \
+        JSPropertyCache *cache_ = (cache);                                    \
+        JS_ASSERT(cache_->empty);                                             \
+        end_ = &cache_->table[PROPERTY_CACHE_SIZE];                           \
+        for (pce_ = &cache_->table[0]; pce_ < end_; pce_++) {                 \
+            PCE_LOAD(cache_, pce_, entry_);                                   \
+            JS_ASSERT(!PCE_OBJECT(entry_));                                   \
+            JS_ASSERT(!PCE_PROPERTY(entry_));                                 \
+        }                                                                     \
+    JS_END_MACRO
+#else
+#define ASSERT_CACHE_IS_EMPTY(cache) ((void)0)
+#endif
+
+void
+js_FlushPropertyCache(JSContext *cx)
+{
+    JSPropertyCache *cache;
+
+    cache = &cx->runtime->propertyCache;
+    if (cache->empty) {
+        ASSERT_CACHE_IS_EMPTY(cache);
+        return;
+    }
+    memset(cache->table, 0, sizeof cache->table);
+    cache->empty = JS_TRUE;
+#ifdef JS_PROPERTY_CACHE_METERING
+    cache->flushes++;
+#endif
+}
+
+void
+js_DisablePropertyCache(JSContext *cx)
+{
+    JS_ASSERT(!cx->runtime->propertyCache.disabled);
+    cx->runtime->propertyCache.disabled = JS_TRUE;
+}
+
+void
+js_EnablePropertyCache(JSContext *cx)
+{
+    JS_ASSERT(cx->runtime->propertyCache.disabled);
+    ASSERT_CACHE_IS_EMPTY(&cx->runtime->propertyCache);
+    cx->runtime->propertyCache.disabled = JS_FALSE;
+}
+
+/*
+ * Class for for/in loop property iterator objects.
+ */
+#define JSSLOT_ITER_STATE   JSSLOT_PRIVATE
+
+static void
+prop_iterator_finalize(JSContext *cx, JSObject *obj)
+{
+    jsval iter_state;
+    jsval iteratee;
+
+    /* Protect against stillborn iterators. */
+    iter_state = obj->slots[JSSLOT_ITER_STATE];
+    iteratee = obj->slots[JSSLOT_PARENT];
+    if (!JSVAL_IS_NULL(iter_state) && !JSVAL_IS_PRIMITIVE(iteratee)) {
+        OBJ_ENUMERATE(cx, JSVAL_TO_OBJECT(iteratee), JSENUMERATE_DESTROY,
+                      &iter_state, NULL);
+    }
+    js_RemoveRoot(cx->runtime, &obj->slots[JSSLOT_PARENT]);
+}
+
+static JSClass prop_iterator_class = {
+    "PropertyIterator",
+    0,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   prop_iterator_finalize,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+/*
+ * Stack macros and functions.  These all use a local variable, jsval *sp, to
+ * point to the next free stack slot.  SAVE_SP must be called before any call
+ * to a function that may invoke the interpreter.  RESTORE_SP must be called
+ * only after return from js_Invoke, because only js_Invoke changes fp->sp.
+ */
+#define PUSH(v)         (*sp++ = (v))
+#define POP()           (*--sp)
+#ifdef DEBUG
+#define SAVE_SP(fp)                                                           \
+    (JS_ASSERT((fp)->script || !(fp)->spbase || (sp) == (fp)->spbase),        \
+     (fp)->sp = sp)
+#else
+#define SAVE_SP(fp)     ((fp)->sp = sp)
+#endif
+#define RESTORE_SP(fp)  (sp = (fp)->sp)
+
+/*
+ * Push the generating bytecode's pc onto the parallel pc stack that runs
+ * depth slots below the operands.
+ *
+ * NB: PUSH_OPND uses sp, depth, and pc from its lexical environment.  See
+ * js_Interpret for these local variables' declarations and uses.
+ */
+#define PUSH_OPND(v)    (sp[-depth] = (jsval)pc, PUSH(v))
+#define STORE_OPND(n,v) (sp[(n)-depth] = (jsval)pc, sp[n] = (v))
+#define POP_OPND()      POP()
+#define FETCH_OPND(n)   (sp[n])
+
+/*
+ * Push the jsdouble d using sp, depth, and pc from the lexical environment.
+ * Try to convert d to a jsint that fits in a jsval, otherwise GC-alloc space
+ * for it and push a reference.
+ */
+#define STORE_NUMBER(cx, n, d)                                                \
+    JS_BEGIN_MACRO                                                            \
+        jsint i_;                                                             \
+        jsval v_;                                                             \
+                                                                              \
+        if (JSDOUBLE_IS_INT(d, i_) && INT_FITS_IN_JSVAL(i_)) {                \
+            v_ = INT_TO_JSVAL(i_);                                            \
+        } else {                                                              \
+            ok = js_NewDoubleValue(cx, d, &v_);                               \
+            if (!ok)                                                          \
+                goto out;                                                     \
+        }                                                                     \
+        STORE_OPND(n, v_);                                                    \
+    JS_END_MACRO
+
+#define FETCH_NUMBER(cx, n, d)                                                \
+    JS_BEGIN_MACRO                                                            \
+        jsval v_;                                                             \
+                                                                              \
+        v_ = FETCH_OPND(n);                                                   \
+        VALUE_TO_NUMBER(cx, v_, d);                                           \
+    JS_END_MACRO
+
+#define FETCH_INT(cx, n, i)                                                   \
+    JS_BEGIN_MACRO                                                            \
+        jsval v_ = FETCH_OPND(n);                                             \
+        if (JSVAL_IS_INT(v_)) {                                               \
+            i = JSVAL_TO_INT(v_);                                             \
+        } else {                                                              \
+            SAVE_SP(fp);                                                      \
+            ok = js_ValueToECMAInt32(cx, v_, &i);                             \
+            if (!ok)                                                          \
+                goto out;                                                     \
+        }                                                                     \
+    JS_END_MACRO
+
+#define FETCH_UINT(cx, n, ui)                                                 \
+    JS_BEGIN_MACRO                                                            \
+        jsval v_ = FETCH_OPND(n);                                             \
+        jsint i_;                                                             \
+        if (JSVAL_IS_INT(v_) && (i_ = JSVAL_TO_INT(v_)) >= 0) {               \
+            ui = (uint32) i_;                                                 \
+        } else {                                                              \
+            SAVE_SP(fp);                                                      \
+            ok = js_ValueToECMAUint32(cx, v_, &ui);                           \
+            if (!ok)                                                          \
+                goto out;                                                     \
+        }                                                                     \
+    JS_END_MACRO
+
+/*
+ * Optimized conversion macros that test for the desired type in v before
+ * homing sp and calling a conversion function.
+ */
+#define VALUE_TO_NUMBER(cx, v, d)                                             \
+    JS_BEGIN_MACRO                                                            \
+        if (JSVAL_IS_INT(v)) {                                                \
+            d = (jsdouble)JSVAL_TO_INT(v);                                    \
+        } else if (JSVAL_IS_DOUBLE(v)) {                                      \
+            d = *JSVAL_TO_DOUBLE(v);                                          \
+        } else {                                                              \
+            SAVE_SP(fp);                                                      \
+            ok = js_ValueToNumber(cx, v, &d);                                 \
+            if (!ok)                                                          \
+                goto out;                                                     \
+        }                                                                     \
+    JS_END_MACRO
+
+#define POP_BOOLEAN(cx, v, b)                                                 \
+    JS_BEGIN_MACRO                                                            \
+        v = FETCH_OPND(-1);                                                   \
+        if (v == JSVAL_NULL) {                                                \
+            b = JS_FALSE;                                                     \
+        } else if (JSVAL_IS_BOOLEAN(v)) {                                     \
+            b = JSVAL_TO_BOOLEAN(v);                                          \
+        } else {                                                              \
+            SAVE_SP(fp);                                                      \
+            ok = js_ValueToBoolean(cx, v, &b);                                \
+            if (!ok)                                                          \
+                goto out;                                                     \
+        }                                                                     \
+        sp--;                                                                 \
+    JS_END_MACRO
+
+#define VALUE_TO_OBJECT(cx, v, obj)                                           \
+    JS_BEGIN_MACRO                                                            \
+        if (!JSVAL_IS_PRIMITIVE(v)) {                                         \
+            obj = JSVAL_TO_OBJECT(v);                                         \
+        } else {                                                              \
+            SAVE_SP(fp);                                                      \
+            obj = js_ValueToNonNullObject(cx, v);                             \
+            if (!obj) {                                                       \
+                ok = JS_FALSE;                                                \
+                goto out;                                                     \
+            }                                                                 \
+        }                                                                     \
+    JS_END_MACRO
+
+#define FETCH_OBJECT(cx, n, v, obj)                                           \
+    JS_BEGIN_MACRO                                                            \
+        v = FETCH_OPND(n);                                                    \
+        VALUE_TO_OBJECT(cx, v, obj);                                          \
+        STORE_OPND(n, OBJECT_TO_JSVAL(obj));                                  \
+    JS_END_MACRO
+
+#if JS_BUG_VOID_TOSTRING
+#define CHECK_VOID_TOSTRING(cx, v)                                            \
+    if (JSVAL_IS_VOID(v)) {                                                   \
+        JSString *str_;                                                       \
+        str_ = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]); \
+        v = STRING_TO_JSVAL(str_);                                            \
+    }
+#else
+#define CHECK_VOID_TOSTRING(cx, v)  ((void)0)
+#endif
+
+#if JS_BUG_EAGER_TOSTRING
+#define CHECK_EAGER_TOSTRING(hint)  (hint = JSTYPE_STRING)
+#else
+#define CHECK_EAGER_TOSTRING(hint)  ((void)0)
+#endif
+
+#define VALUE_TO_PRIMITIVE(cx, v, hint, vp)                                   \
+    JS_BEGIN_MACRO                                                            \
+        if (JSVAL_IS_PRIMITIVE(v)) {                                          \
+            CHECK_VOID_TOSTRING(cx, v);                                       \
+            *vp = v;                                                          \
+        } else {                                                              \
+            SAVE_SP(fp);                                                      \
+            CHECK_EAGER_TOSTRING(hint);                                       \
+            ok = OBJ_DEFAULT_VALUE(cx, JSVAL_TO_OBJECT(v), hint, vp);         \
+            if (!ok)                                                          \
+                goto out;                                                     \
+        }                                                                     \
+    JS_END_MACRO
+
+JS_FRIEND_API(jsval *)
+js_AllocRawStack(JSContext *cx, uintN nslots, void **markp)
+{
+    jsval *sp;
+
+    if (markp)
+        *markp = JS_ARENA_MARK(&cx->stackPool);
+    JS_ARENA_ALLOCATE_CAST(sp, jsval *, &cx->stackPool, nslots * sizeof(jsval));
+    if (!sp) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_STACK_OVERFLOW,
+                             (cx->fp && cx->fp->fun)
+                             ? JS_GetFunctionName(cx->fp->fun)
+                             : "script");
+    }
+    return sp;
+}
+
+JS_FRIEND_API(void)
+js_FreeRawStack(JSContext *cx, void *mark)
+{
+    JS_ARENA_RELEASE(&cx->stackPool, mark);
+}
+
+JS_FRIEND_API(jsval *)
+js_AllocStack(JSContext *cx, uintN nslots, void **markp)
+{
+    jsval *sp, *vp, *end;
+    JSArena *a;
+    JSStackHeader *sh;
+    JSStackFrame *fp;
+
+    /* Callers don't check for zero nslots: we do to avoid empty segments. */
+    if (nslots == 0) {
+        *markp = NULL;
+        return JS_ARENA_MARK(&cx->stackPool);
+    }
+
+    /* Allocate 2 extra slots for the stack segment header we'll likely need. */
+    sp = js_AllocRawStack(cx, 2 + nslots, markp);
+    if (!sp)
+        return NULL;
+
+    /* Try to avoid another header if we can piggyback on the last segment. */
+    a = cx->stackPool.current;
+    sh = cx->stackHeaders;
+    if (sh && JS_STACK_SEGMENT(sh) + sh->nslots == sp) {
+        /* Extend the last stack segment, give back the 2 header slots. */
+        sh->nslots += nslots;
+        a->avail -= 2 * sizeof(jsval);
+    } else {
+        /*
+         * Need a new stack segment, so we must initialize unused slots in the
+         * current frame.  See js_GC, just before marking the "operand" jsvals,
+         * where we scan from fp->spbase to fp->sp or through fp->script->depth
+         * (whichever covers fewer slots).
+         */
+        fp = cx->fp;
+        if (fp && fp->script && fp->spbase) {
+#ifdef DEBUG
+            jsuword depthdiff = fp->script->depth * sizeof(jsval);
+            JS_ASSERT(JS_UPTRDIFF(fp->sp, fp->spbase) <= depthdiff);
+            JS_ASSERT(JS_UPTRDIFF(*markp, fp->spbase) >= depthdiff);
+#endif
+            end = fp->spbase + fp->script->depth;
+            for (vp = fp->sp; vp < end; vp++)
+                *vp = JSVAL_VOID;
+        }
+
+        /* Allocate and push a stack segment header from the 2 extra slots. */
+        sh = (JSStackHeader *)sp;
+        sh->nslots = nslots;
+        sh->down = cx->stackHeaders;
+        cx->stackHeaders = sh;
+        sp += 2;
+    }
+
+    /*
+     * Store JSVAL_NULL using memset, to let compilers optimize as they see
+     * fit, in case a caller allocates and pushes GC-things one by one, which
+     * could nest a last-ditch GC that will scan this segment.
+     */
+    memset(sp, 0, nslots * sizeof(jsval));
+    return sp;
+}
+
+JS_FRIEND_API(void)
+js_FreeStack(JSContext *cx, void *mark)
+{
+    JSStackHeader *sh;
+    jsuword slotdiff;
+
+    /* Check for zero nslots allocation special case. */
+    if (!mark)
+        return;
+
+    /* We can assert because js_FreeStack always balances js_AllocStack. */
+    sh = cx->stackHeaders;
+    JS_ASSERT(sh);
+
+    /* If mark is in the current segment, reduce sh->nslots, else pop sh. */
+    slotdiff = JS_UPTRDIFF(mark, JS_STACK_SEGMENT(sh)) / sizeof(jsval);
+    if (slotdiff < (jsuword)sh->nslots)
+        sh->nslots = slotdiff;
+    else
+        cx->stackHeaders = sh->down;
+
+    /* Release the stackPool space allocated since mark was set. */
+    JS_ARENA_RELEASE(&cx->stackPool, mark);
+}
+
+JSBool
+js_GetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    return JS_TRUE;
+}
+
+JSBool
+js_SetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    return JS_TRUE;
+}
+
+JSBool
+js_GetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    return JS_TRUE;
+}
+
+JSBool
+js_SetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    return JS_TRUE;
+}
+
+JSBool
+js_ComputeThis(JSContext *cx, JSObject *thisp, JSStackFrame *fp)
+{
+    JSObject *parent;
+
+    if (thisp && OBJ_GET_CLASS(cx, thisp) != &js_CallClass) {
+        /* Some objects (e.g., With) delegate 'this' to another object. */
+        thisp = OBJ_THIS_OBJECT(cx, thisp);
+        if (!thisp)
+            return JS_FALSE;
+
+        /* Default return value for a constructor is the new object. */
+        if (fp->flags & JSFRAME_CONSTRUCTING)
+            fp->rval = OBJECT_TO_JSVAL(thisp);
+    } else {
+        /*
+         * ECMA requires "the global object", but in the presence of multiple
+         * top-level objects (windows, frames, or certain layers in the client
+         * object model), we prefer fun's parent.  An example that causes this
+         * code to run:
+         *
+         *   // in window w1
+         *   function f() { return this }
+         *   function g() { return f }
+         *
+         *   // in window w2
+         *   var h = w1.g()
+         *   alert(h() == w1)
+         *
+         * The alert should display "true".
+         */
+        JS_ASSERT(!(fp->flags & JSFRAME_CONSTRUCTING));
+        if (JSVAL_IS_PRIMITIVE(fp->argv[-2]) ||
+            !(parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fp->argv[-2])))) {
+            thisp = cx->globalObject;
+        } else {
+            /* walk up to find the top-level object */
+            thisp = parent;
+            while ((parent = OBJ_GET_PARENT(cx, thisp)) != NULL)
+                thisp = parent;
+        }
+    }
+    fp->thisp = thisp;
+    fp->argv[-1] = OBJECT_TO_JSVAL(thisp);
+    return JS_TRUE;
+}
+
+#ifdef DUMP_CALL_TABLE
+
+#include "jsclist.h"
+#include "jshash.h"
+#include "jsdtoa.h"
+
+typedef struct CallKey {
+    jsval               callee;                 /* callee value */
+    const char          *filename;              /* function filename or null */
+    uintN               lineno;                 /* function lineno or 0 */
+} CallKey;
+
+/* Compensate for typeof null == "object" brain damage. */
+#define JSTYPE_NULL     JSTYPE_LIMIT
+#define TYPEOF(cx,v)    (JSVAL_IS_NULL(v) ? JSTYPE_NULL : JS_TypeOfValue(cx,v))
+#define TYPENAME(t)     (((t) == JSTYPE_NULL) ? js_null_str : js_type_str[t])
+#define NTYPEHIST       (JSTYPE_LIMIT + 1)
+
+typedef struct CallValue {
+    uint32              total;                  /* total call count */
+    uint32              recycled;               /* LRU-recycled calls lost */
+    uint16              minargc;                /* minimum argument count */
+    uint16              maxargc;                /* maximum argument count */
+    struct ArgInfo {
+        uint32          typeHist[NTYPEHIST];    /* histogram by type */
+        JSCList         lruList;                /* top 10 values LRU list */
+        struct ArgValCount {
+            JSCList     lruLink;                /* LRU list linkage */
+            jsval       value;                  /* recently passed value */
+            uint32      count;                  /* number of times passed */
+            char        strbuf[112];            /* string conversion buffer */
+        } topValCounts[10];                     /* top 10 value storage */
+    } argInfo[8];
+} CallValue;
+
+typedef struct CallEntry {
+    JSHashEntry         entry;
+    CallKey             key;
+    CallValue           value;
+    char                name[32];               /* function name copy */
+} CallEntry;
+
+static void *
+AllocCallTable(void *pool, size_t size)
+{
+    return malloc(size);
+}
+
+static void
+FreeCallTable(void *pool, void *item)
+{
+    free(item);
+}
+
+static JSHashEntry *
+AllocCallEntry(void *pool, const void *key)
+{
+    return (JSHashEntry*) calloc(1, sizeof(CallEntry));
+}
+
+static void
+FreeCallEntry(void *pool, JSHashEntry *he, uintN flag)
+{
+    JS_ASSERT(flag == HT_FREE_ENTRY);
+    free(he);
+}
+
+static JSHashAllocOps callTableAllocOps = {
+    AllocCallTable, FreeCallTable,
+    AllocCallEntry, FreeCallEntry
+};
+
+JS_STATIC_DLL_CALLBACK(JSHashNumber)
+js_hash_call_key(const void *key)
+{
+    CallKey *ck = (CallKey *) key;
+    JSHashNumber hash = (jsuword)ck->callee >> 3;
+
+    if (ck->filename) {
+        hash = (hash << 4) ^ JS_HashString(ck->filename);
+        hash = (hash << 4) ^ ck->lineno;
+    }
+    return hash;
+}
+
+JS_STATIC_DLL_CALLBACK(intN)
+js_compare_call_keys(const void *k1, const void *k2)
+{
+    CallKey *ck1 = (CallKey *)k1, *ck2 = (CallKey *)k2;
+
+    return ck1->callee == ck2->callee &&
+           ((ck1->filename && ck2->filename)
+            ? strcmp(ck1->filename, ck2->filename) == 0
+            : ck1->filename == ck2->filename) &&
+           ck1->lineno == ck2->lineno;
+}
+
+JSHashTable *js_CallTable;
+size_t      js_LogCallToSourceLimit;
+
+JS_STATIC_DLL_CALLBACK(intN)
+CallTableDumper(JSHashEntry *he, intN k, void *arg)
+{
+    CallEntry *ce = (CallEntry *)he;
+    FILE *fp = (FILE *)arg;
+    uintN argc, i, n;
+    struct ArgInfo *ai;
+    JSType save, type;
+    JSCList *cl;
+    struct ArgValCount *avc;
+    jsval argval;
+
+    if (ce->key.filename) {
+        /* We're called at the end of the mark phase, so mark our filenames. */
+        js_MarkScriptFilename(ce->key.filename);
+        fprintf(fp, "%s:%u ", ce->key.filename, ce->key.lineno);
+    } else {
+        fprintf(fp, "@%p ", (void *) ce->key.callee);
+    }
+
+    if (ce->name[0])
+        fprintf(fp, "name %s ", ce->name);
+    fprintf(fp, "calls %lu (%lu) argc %u/%u\n",
+            (unsigned long) ce->value.total,
+            (unsigned long) ce->value.recycled,
+            ce->value.minargc, ce->value.maxargc);
+
+    argc = JS_MIN(ce->value.maxargc, 8);
+    for (i = 0; i < argc; i++) {
+        ai = &ce->value.argInfo[i];
+
+        n = 0;
+        save = -1;
+        for (type = JSTYPE_VOID; type <= JSTYPE_LIMIT; type++) {
+            if (ai->typeHist[type]) {
+                save = type;
+                ++n;
+            }
+        }
+        if (n == 1) {
+            fprintf(fp, "  arg %u type %s: %lu\n",
+                    i, TYPENAME(save), (unsigned long) ai->typeHist[save]);
+        } else {
+            fprintf(fp, "  arg %u type histogram:\n", i);
+            for (type = JSTYPE_VOID; type <= JSTYPE_LIMIT; type++) {
+                fprintf(fp, "  %9s: %8lu ",
+                       TYPENAME(type), (unsigned long) ai->typeHist[type]);
+                for (n = (uintN) JS_HOWMANY(ai->typeHist[type], 10); n > 0; --n)
+                    fputc('*', fp);
+                fputc('\n', fp);
+            }
+        }
+
+        fprintf(fp, "  arg %u top 10 values:\n", i);
+        n = 1;
+        for (cl = ai->lruList.prev; cl != &ai->lruList; cl = cl->prev) {
+            avc = (struct ArgValCount *)cl;
+            if (!avc->count)
+                break;
+            argval = avc->value;
+            fprintf(fp, "  %9u: %8lu %.*s (%#lx)\n",
+                    n, (unsigned long) avc->count,
+                    sizeof avc->strbuf, avc->strbuf, argval);
+            ++n;
+        }
+    }
+
+    return HT_ENUMERATE_NEXT;
+}
+
+void
+js_DumpCallTable(JSContext *cx)
+{
+    char name[24];
+    FILE *fp;
+    static uintN dumpCount;
+
+    if (!js_CallTable)
+        return;
+
+    JS_snprintf(name, sizeof name, "/tmp/calltable.dump.%u", dumpCount & 7);
+    dumpCount++;
+    fp = fopen(name, "w");
+    if (!fp)
+        return;
+
+    JS_HashTableEnumerateEntries(js_CallTable, CallTableDumper, fp);
+    fclose(fp);
+}
+
+static void
+LogCall(JSContext *cx, jsval callee, uintN argc, jsval *argv)
+{
+    CallKey key;
+    const char *name, *cstr;
+    JSFunction *fun;
+    JSHashNumber keyHash;
+    JSHashEntry **hep, *he;
+    CallEntry *ce;
+    uintN i, j;
+    jsval argval;
+    JSType type;
+    struct ArgInfo *ai;
+    struct ArgValCount *avc;
+    JSString *str;
+
+    if (!js_CallTable) {
+        js_CallTable = JS_NewHashTable(1024, js_hash_call_key,
+                                       js_compare_call_keys, NULL,
+                                       &callTableAllocOps, NULL);
+        if (!js_CallTable)
+            return;
+    }
+
+    key.callee = callee;
+    key.filename = NULL;
+    key.lineno = 0;
+    name = "";
+    if (JSVAL_IS_FUNCTION(cx, callee)) {
+        fun = (JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(callee));
+        if (fun->atom)
+            name = js_AtomToPrintableString(cx, fun->atom);
+        if (fun->interpreted) {
+            key.filename = fun->u.script->filename;
+            key.lineno = fun->u.script->lineno;
+        }
+    }
+    keyHash = js_hash_call_key(&key);
+
+    hep = JS_HashTableRawLookup(js_CallTable, keyHash, &key);
+    he = *hep;
+    if (he) {
+        ce = (CallEntry *) he;
+        JS_ASSERT(strncmp(ce->name, name, sizeof ce->name) == 0);
+    } else {
+        he = JS_HashTableRawAdd(js_CallTable, hep, keyHash, &key, NULL);
+        if (!he)
+            return;
+        ce = (CallEntry *) he;
+        ce->entry.key = &ce->key;
+        ce->entry.value = &ce->value;
+        ce->key = key;
+        for (i = 0; i < 8; i++) {
+            ai = &ce->value.argInfo[i];
+            JS_INIT_CLIST(&ai->lruList);
+            for (j = 0; j < 10; j++)
+                JS_APPEND_LINK(&ai->topValCounts[j].lruLink, &ai->lruList);
+        }
+        strncpy(ce->name, name, sizeof ce->name);
+    }
+
+    ++ce->value.total;
+    if (ce->value.minargc < argc)
+        ce->value.minargc = argc;
+    if (ce->value.maxargc < argc)
+        ce->value.maxargc = argc;
+    if (argc > 8)
+        argc = 8;
+    for (i = 0; i < argc; i++) {
+        ai = &ce->value.argInfo[i];
+        argval = argv[i];
+        type = TYPEOF(cx, argval);
+        ++ai->typeHist[type];
+
+        for (j = 0; ; j++) {
+            if (j == 10) {
+                avc = (struct ArgValCount *) ai->lruList.next;
+                ce->value.recycled += avc->count;
+                avc->value = argval;
+                avc->count = 1;
+                break;
+            }
+            avc = &ai->topValCounts[j];
+            if (avc->value == argval) {
+                ++avc->count;
+                break;
+            }
+        }
+
+        /* Move avc to the back of the LRU list. */
+        JS_REMOVE_LINK(&avc->lruLink);
+        JS_APPEND_LINK(&avc->lruLink, &ai->lruList);
+
+        str = NULL;
+        cstr = "";
+        switch (TYPEOF(cx, argval)) {
+          case JSTYPE_VOID:
+            cstr = js_type_str[JSTYPE_VOID];
+            break;
+          case JSTYPE_NULL:
+            cstr = js_null_str;
+            break;
+          case JSTYPE_BOOLEAN:
+            cstr = js_boolean_str[JSVAL_TO_BOOLEAN(argval)];
+            break;
+          case JSTYPE_NUMBER:
+            if (JSVAL_IS_INT(argval)) {
+                JS_snprintf(avc->strbuf, sizeof avc->strbuf, "%ld",
+                            JSVAL_TO_INT(argval));
+            } else {
+                JS_dtostr(avc->strbuf, sizeof avc->strbuf, DTOSTR_STANDARD, 0,
+                          *JSVAL_TO_DOUBLE(argval));
+            }
+            continue;
+          case JSTYPE_STRING:
+            str = js_QuoteString(cx, JSVAL_TO_STRING(argval), (jschar)'"');
+            break;
+          case JSTYPE_FUNCTION:
+            if (JSVAL_IS_FUNCTION(cx, argval)) {
+                fun = (JSFunction *)JS_GetPrivate(cx, JSVAL_TO_OBJECT(argval));
+                if (fun && fun->atom) {
+                    str = ATOM_TO_STRING(fun->atom);
+                    break;
+                }
+            }
+            /* FALL THROUGH */
+          case JSTYPE_OBJECT:
+            js_LogCallToSourceLimit = sizeof avc->strbuf;
+            cx->options |= JSOPTION_LOGCALL_TOSOURCE;
+            str = js_ValueToSource(cx, argval);
+            cx->options &= ~JSOPTION_LOGCALL_TOSOURCE;
+            break;
+        }
+        if (str)
+            cstr = JS_GetStringBytes(str);
+        strncpy(avc->strbuf, cstr, sizeof avc->strbuf);
+    }
+}
+
+#endif /* DUMP_CALL_TABLE */
+
+/*
+ * Find a function reference and its 'this' object implicit first parameter
+ * under argc arguments on cx's stack, and call the function.  Push missing
+ * required arguments, allocate declared local variables, and pop everything
+ * when done.  Then push the return value.
+ */
+JS_FRIEND_API(JSBool)
+js_Invoke(JSContext *cx, uintN argc, uintN flags)
+{
+    void *mark;
+    JSStackFrame *fp, frame;
+    jsval *sp, *newsp, *limit;
+    jsval *vp, v;
+    JSObject *funobj, *parent, *thisp;
+    JSBool ok;
+    JSClass *clasp;
+    JSObjectOps *ops;
+    JSNative native;
+    JSFunction *fun;
+    JSScript *script;
+    uintN nslots, nvars, nalloc, surplus;
+    JSInterpreterHook hook;
+    void *hookData;
+
+    /* Mark the top of stack and load frequently-used registers. */
+    mark = JS_ARENA_MARK(&cx->stackPool);
+    fp = cx->fp;
+    sp = fp->sp;
+
+    /*
+     * Set vp to the callee value's stack slot (it's where rval goes).
+     * Once vp is set, control should flow through label out2: to return.
+     * Set frame.rval early so native class and object ops can throw and
+     * return false, causing a goto out2 with ok set to false.  Also set
+     * frame.flags to flags so that ComputeThis can test bits in it.
+     */
+    vp = sp - (2 + argc);
+    v = *vp;
+    frame.rval = JSVAL_VOID;
+    frame.flags = flags;
+    thisp = JSVAL_TO_OBJECT(vp[1]);
+
+    /*
+     * A callee must be an object reference, unless its |this| parameter
+     * implements the __noSuchMethod__ method, in which case that method will
+     * be called like so:
+     *
+     *   thisp.__noSuchMethod__(id, args)
+     *
+     * where id is the name of the method that this invocation attempted to
+     * call by name, and args is an Array containing this invocation's actual
+     * parameters.
+     */
+    if (JSVAL_IS_PRIMITIVE(v)) {
+#if JS_HAS_NO_SUCH_METHOD
+        jsid id;
+        jsbytecode *pc;
+        jsatomid atomIndex;
+        JSAtom *atom;
+        JSObject *argsobj;
+        JSArena *a;
+
+        if (!fp->script || (flags & JSINVOKE_INTERNAL))
+            goto bad;
+
+        /*
+         * We must ComputeThis here to censor Call objects; performance hit,
+         * but at least it's idempotent.
+         *
+         * Normally, we call ComputeThis after all frame members have been
+         * set, and in particular, after any revision of the callee value at
+         * *vp  due to clasp->convert (see below).  This matters because
+         * ComputeThis may access *vp via fp->argv[-2], to follow the parent
+         * chain to a global object to use as the |this| parameter.
+         *
+         * Obviously, here in the JSVAL_IS_PRIMITIVE(v) case, there can't be
+         * any such defaulting of |this| to callee (v, *vp) ancestor.
+         */
+        frame.argv = vp + 2;
+        ok = js_ComputeThis(cx, thisp, &frame);
+        if (!ok)
+            goto out2;
+        thisp = frame.thisp;
+
+        id = ATOM_TO_JSID(cx->runtime->atomState.noSuchMethodAtom);
+#if defined(OSSP) /* BUGFIX */ && JS_HAS_XML_SUPPORT
+        if (OBJECT_IS_XML(cx, thisp)) {
+            JSXMLObjectOps *ops;
+
+            ops = (JSXMLObjectOps *) thisp->map->ops;
+            thisp = ops->getMethod(cx, thisp, id, &v);
+            if (!thisp) {
+                ok = JS_FALSE;
+                goto out2;
+            }
+            vp[1] = OBJECT_TO_JSVAL(thisp);
+        } else {
+#endif
+            ok = OBJ_GET_PROPERTY(cx, thisp, id, &v);
+#if defined(OSSP) /* BUGFIX */ && JS_HAS_XML_SUPPORT
+        }
+#endif
+        if (!ok)
+            goto out2;
+        if (JSVAL_IS_PRIMITIVE(v))
+            goto bad;
+
+        pc = (jsbytecode *) vp[-(intN)fp->script->depth];
+        switch ((JSOp) *pc) {
+          case JSOP_NAME:
+          case JSOP_GETPROP:
+#if JS_HAS_XML_SUPPORT
+          case JSOP_GETMETHOD:
+#endif
+            atomIndex = GET_ATOM_INDEX(pc);
+            atom = js_GetAtom(cx, &fp->script->atomMap, atomIndex);
+            argsobj = js_NewArrayObject(cx, argc, vp + 2);
+            if (!argsobj) {
+                ok = JS_FALSE;
+                goto out2;
+            }
+
+            sp = vp + 4;
+            if (argc < 2) {
+                a = cx->stackPool.current;
+                if ((jsuword)sp > a->limit) {
+                    /*
+                     * Arguments must be contiguous, and must include argv[-1]
+                     * and argv[-2], so allocate more stack, advance sp, and
+                     * set newsp[1] to thisp (vp[1]).  The other argv elements
+                     * will be set below, using negative indexing from sp.
+                     */
+                    newsp = js_AllocRawStack(cx, 4, NULL);
+                    if (!newsp) {
+                        ok = JS_FALSE;
+                        goto out2;
+                    }
+                    newsp[1] = OBJECT_TO_JSVAL(thisp);
+                    sp = newsp + 4;
+                } else if ((jsuword)sp > a->avail) {
+                    /*
+                     * Inline, optimized version of JS_ARENA_ALLOCATE to claim
+                     * the small number of words not already allocated as part
+                     * of the caller's operand stack.
+                     */
+                    JS_ArenaCountAllocation(&cx->stackPool,
+                                            (jsuword)sp - a->avail);
+                    a->avail = (jsuword)sp;
+                }
+            }
+
+            sp[-4] = v;
+            JS_ASSERT(sp[-3] == OBJECT_TO_JSVAL(thisp));
+            sp[-2] = ATOM_KEY(atom);
+            sp[-1] = OBJECT_TO_JSVAL(argsobj);
+            fp->sp = sp;
+            argc = 2;
+            break;
+
+          default:
+            goto bad;
+        }
+#else
+        goto bad;
+#endif
+    }
+
+    funobj = JSVAL_TO_OBJECT(v);
+    parent = OBJ_GET_PARENT(cx, funobj);
+    clasp = OBJ_GET_CLASS(cx, funobj);
+    if (clasp != &js_FunctionClass) {
+        /* Function is inlined, all other classes use object ops. */
+        ops = funobj->map->ops;
+
+        /*
+         * XXX this makes no sense -- why convert to function if clasp->call?
+         * XXX better to call that hook without converting
+         * XXX the only thing that needs fixing is liveconnect
+         *
+         * Try converting to function, for closure and API compatibility.
+         * We attempt the conversion under all circumstances for 1.2, but
+         * only if there is a call op defined otherwise.
+         */
+        if (JS_VERSION_IS_1_2(cx) ||
+            ((ops == &js_ObjectOps) ? clasp->call : ops->call)) {
+            ok = clasp->convert(cx, funobj, JSTYPE_FUNCTION, &v);
+            if (!ok)
+                goto out2;
+
+            if (JSVAL_IS_FUNCTION(cx, v)) {
+                /* Make vp refer to funobj to keep it available as argv[-2]. */
+                *vp = v;
+                funobj = JSVAL_TO_OBJECT(v);
+                parent = OBJ_GET_PARENT(cx, funobj);
+                goto have_fun;
+            }
+        }
+        fun = NULL;
+        script = NULL;
+        nslots = nvars = 0;
+
+        /* Try a call or construct native object op. */
+        native = (flags & JSINVOKE_CONSTRUCT) ? ops->construct : ops->call;
+        if (!native)
+            goto bad;
+    } else {
+have_fun:
+        /* Get private data and set derived locals from it. */
+        fun = (JSFunction *) JS_GetPrivate(cx, funobj);
+        if (fun->interpreted) {
+            native = NULL;
+            script = fun->u.script;
+        } else {
+            native = fun->u.native;
+            script = NULL;
+        }
+        nslots = (fun->nargs > argc) ? fun->nargs - argc : 0;
+        nslots += fun->extra;
+        nvars = fun->nvars;
+
+        /* Handle bound method special case. */
+        if (fun->flags & JSFUN_BOUND_METHOD)
+            thisp = parent;
+    }
+
+    /* Initialize the rest of frame, except for sp (set by SAVE_SP later). */
+    frame.varobj = NULL;
+    frame.callobj = frame.argsobj = NULL;
+    frame.script = script;
+    frame.fun = fun;
+    frame.argc = argc;
+    frame.argv = sp - argc;
+    frame.nvars = nvars;
+    frame.vars = sp;
+    frame.down = fp;
+    frame.annotation = NULL;
+    frame.scopeChain = NULL;    /* set below for real, after cx->fp is set */
+    frame.pc = NULL;
+    frame.spbase = NULL;
+    frame.sharpDepth = 0;
+    frame.sharpArray = NULL;
+    frame.dormantNext = NULL;
+    frame.xmlNamespace = NULL;
+
+    /* Compute the 'this' parameter and store it in frame as frame.thisp. */
+    ok = js_ComputeThis(cx, thisp, &frame);
+    if (!ok)
+        goto out2;
+
+    /* From here on, control must flow through label out: to return. */
+    cx->fp = &frame;
+
+    /* Init these now in case we goto out before first hook call. */
+    hook = cx->runtime->callHook;
+    hookData = NULL;
+
+    /* Check for argument slots required by the function. */
+    if (nslots) {
+        /* All arguments must be contiguous, so we may have to copy actuals. */
+        nalloc = nslots;
+        limit = (jsval *) cx->stackPool.current->limit;
+        if (sp + nslots > limit) {
+            /* Hit end of arena: we have to copy argv[-2..(argc+nslots-1)]. */
+            nalloc += 2 + argc;
+        } else {
+            /* Take advantage of surplus slots in the caller's frame depth. */
+            JS_ASSERT((jsval *)mark >= sp);
+            surplus = (jsval *)mark - sp;
+            nalloc -= surplus;
+        }
+
+        /* Check whether we have enough space in the caller's frame. */
+        if ((intN)nalloc > 0) {
+            /* Need space for actuals plus missing formals minus surplus. */
+            newsp = js_AllocRawStack(cx, nalloc, NULL);
+            if (!newsp) {
+                ok = JS_FALSE;
+                goto out;
+            }
+
+            /* If we couldn't allocate contiguous args, copy actuals now. */
+            if (newsp != mark) {
+                JS_ASSERT(sp + nslots > limit);
+                JS_ASSERT(2 + argc + nslots == nalloc);
+                *newsp++ = vp[0];
+                *newsp++ = vp[1];
+                if (argc)
+                    memcpy(newsp, frame.argv, argc * sizeof(jsval));
+                frame.argv = newsp;
+                sp = frame.vars = newsp + argc;
+            }
+        }
+
+        /* Advance frame.vars to make room for the missing args. */
+        frame.vars += nslots;
+
+        /* Push void to initialize missing args. */
+        do {
+            PUSH(JSVAL_VOID);
+        } while (--nslots != 0);
+    }
+    JS_ASSERT(nslots == 0);
+
+    /* Now allocate stack space for local variables. */
+    if (nvars) {
+        JS_ASSERT((jsval *)cx->stackPool.current->avail >= frame.vars);
+        surplus = (jsval *)cx->stackPool.current->avail - frame.vars;
+        if (surplus < nvars) {
+            newsp = js_AllocRawStack(cx, nvars, NULL);
+            if (!newsp) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            if (newsp != sp) {
+                /* NB: Discontinuity between argv and vars. */
+                sp = frame.vars = newsp;
+            }
+        }
+
+        /* Push void to initialize local variables. */
+        do {
+            PUSH(JSVAL_VOID);
+        } while (--nvars != 0);
+    }
+    JS_ASSERT(nvars == 0);
+
+    /* Store the current sp in frame before calling fun. */
+    SAVE_SP(&frame);
+
+    /* call the hook if present */
+    if (hook && (native || script))
+        hookData = hook(cx, &frame, JS_TRUE, 0, cx->runtime->callHookData);
+
+    /* Call the function, either a native method or an interpreted script. */
+    if (native) {
+#if JS_HAS_LVALUE_RETURN
+        /* Set by JS_SetCallReturnValue2, used to return reference types. */
+        cx->rval2set = JS_FALSE;
+#endif
+
+        /* If native, use caller varobj and scopeChain for eval. */
+        frame.varobj = fp->varobj;
+        frame.scopeChain = fp->scopeChain;
+        ok = native(cx, frame.thisp, argc, frame.argv, &frame.rval);
+        JS_RUNTIME_METER(cx->runtime, nativeCalls);
+    } else if (script) {
+#ifdef DUMP_CALL_TABLE
+        LogCall(cx, *vp, argc, frame.argv);
+#endif
+        /* Use parent scope so js_GetCallObject can find the right "Call". */
+        frame.scopeChain = parent;
+        if (fun->flags & JSFUN_HEAVYWEIGHT) {
+#if JS_HAS_CALL_OBJECT
+            /* Scope with a call object parented by the callee's parent. */
+            if (!js_GetCallObject(cx, &frame, parent)) {
+                ok = JS_FALSE;
+                goto out;
+            }
+#else
+            /* Bad old code used the function as a proxy for all calls to it. */
+            frame.scopeChain = funobj;
+#endif
+        }
+        ok = js_Interpret(cx, script->code, &v);
+    } else {
+        /* fun might be onerror trying to report a syntax error in itself. */
+        frame.scopeChain = NULL;
+        ok = JS_TRUE;
+    }
+
+out:
+    if (hookData) {
+        hook = cx->runtime->callHook;
+        if (hook)
+            hook(cx, &frame, JS_FALSE, &ok, hookData);
+    }
+#if JS_HAS_CALL_OBJECT
+    /* If frame has a call object, sync values and clear back-pointer. */
+    if (frame.callobj)
+        ok &= js_PutCallObject(cx, &frame);
+#endif
+#if JS_HAS_ARGS_OBJECT
+    /* If frame has an arguments object, sync values and clear back-pointer. */
+    if (frame.argsobj)
+        ok &= js_PutArgsObject(cx, &frame);
+#endif
+
+    /* Restore cx->fp now that we're done releasing frame objects. */
+    cx->fp = fp;
+
+out2:
+    /* Pop everything we may have allocated off the stack. */
+    JS_ARENA_RELEASE(&cx->stackPool, mark);
+
+    /* Store the return value and restore sp just above it. */
+    *vp = frame.rval;
+    fp->sp = vp + 1;
+
+    /*
+     * Store the location of the JSOP_CALL or JSOP_EVAL that generated the
+     * return value, but only if this is an external (compiled from script
+     * source) call that has stack budget for the generating pc.
+     */
+    if (fp->script && !(flags & JSINVOKE_INTERNAL))
+        vp[-(intN)fp->script->depth] = (jsval)fp->pc;
+    return ok;
+
+bad:
+    js_ReportIsNotFunction(cx, vp, flags & JSINVOKE_CONSTRUCT);
+    ok = JS_FALSE;
+    goto out2;
+}
+
+JSBool
+js_InternalInvoke(JSContext *cx, JSObject *obj, jsval fval, uintN flags,
+                  uintN argc, jsval *argv, jsval *rval)
+{
+    JSStackFrame *fp, *oldfp, frame;
+    jsval *oldsp, *sp;
+    void *mark;
+    uintN i;
+    JSBool ok;
+
+    fp = oldfp = cx->fp;
+    if (!fp) {
+        memset(&frame, 0, sizeof frame);
+        cx->fp = fp = &frame;
+    }
+    oldsp = fp->sp;
+    sp = js_AllocStack(cx, 2 + argc, &mark);
+    if (!sp) {
+        ok = JS_FALSE;
+        goto out;
+    }
+
+    PUSH(fval);
+    PUSH(OBJECT_TO_JSVAL(obj));
+    for (i = 0; i < argc; i++)
+        PUSH(argv[i]);
+    SAVE_SP(fp);
+    ok = js_Invoke(cx, argc, flags | JSINVOKE_INTERNAL);
+    if (ok) {
+        RESTORE_SP(fp);
+
+        /*
+         * Store *rval in the a scoped local root if a scope is open, else in
+         * the cx->lastInternalResult pigeon-hole GC root, solely so users of
+         * js_InternalInvoke and its direct and indirect (js_ValueToString for
+         * example) callers do not need to manage roots for local, temporary
+         * references to such results.
+         */
+        *rval = POP_OPND();
+        if (JSVAL_IS_GCTHING(*rval)) {
+            if (cx->localRootStack) {
+                if (js_PushLocalRoot(cx, cx->localRootStack, *rval) < 0)
+                    ok = JS_FALSE;
+            } else {
+                cx->lastInternalResult = *rval;
+            }
+        }
+    }
+
+    js_FreeStack(cx, mark);
+out:
+    fp->sp = oldsp;
+    if (oldfp != fp)
+        cx->fp = oldfp;
+
+    return ok;
+}
+
+JSBool
+js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval,
+                    JSAccessMode mode, uintN argc, jsval *argv, jsval *rval)
+{
+    /*
+     * Check general (not object-ops/class-specific) access from the running
+     * script to obj.id only if id has a scripted getter or setter that we're
+     * about to invoke.  If we don't check this case, nothing else will -- no
+     * other native code has the chance to check.
+     *
+     * Contrast this non-native (scripted) case with native getter and setter
+     * accesses, where the native itself must do an access check, if security
+     * policies requires it.  We make a checkAccess or checkObjectAccess call
+     * back to the embedding program only in those cases where we're not going
+     * to call an embedding-defined native function, getter, setter, or class
+     * hook anyway.  Where we do call such a native, there's no need for the
+     * engine to impose a separate access check callback on all embeddings --
+     * many embeddings have no security policy at all.
+     */
+    JS_ASSERT(mode == JSACC_READ || mode == JSACC_WRITE);
+    if (cx->runtime->checkObjectAccess &&
+        JSVAL_IS_FUNCTION(cx, fval) &&
+        ((JSFunction *)JS_GetPrivate(cx, JSVAL_TO_OBJECT(fval)))->interpreted &&
+        !cx->runtime->checkObjectAccess(cx, obj, ID_TO_VALUE(id), mode,
+                                        &fval)) {
+        return JS_FALSE;
+    }
+
+    return js_InternalCall(cx, obj, fval, argc, argv, rval);
+}
+
+JSBool
+js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
+           JSStackFrame *down, uintN flags, jsval *result)
+{
+    JSInterpreterHook hook;
+    void *hookData, *mark;
+    JSStackFrame *oldfp, frame;
+    JSObject *obj, *tmp;
+    JSBool ok;
+
+    hook = cx->runtime->executeHook;
+    hookData = mark = NULL;
+    oldfp = cx->fp;
+    frame.callobj = frame.argsobj = NULL;
+    frame.script = script;
+    if (down) {
+        /* Propagate arg/var state for eval and the debugger API. */
+        frame.varobj = down->varobj;
+        frame.fun = down->fun;
+        frame.thisp = down->thisp;
+        frame.argc = down->argc;
+        frame.argv = down->argv;
+        frame.nvars = down->nvars;
+        frame.vars = down->vars;
+        frame.annotation = down->annotation;
+        frame.sharpArray = down->sharpArray;
+    } else {
+        obj = chain;
+        if (cx->options & JSOPTION_VAROBJFIX) {
+            while ((tmp = OBJ_GET_PARENT(cx, obj)) != NULL)
+                obj = tmp;
+        }
+        frame.varobj = obj;
+        frame.fun = NULL;
+        frame.thisp = chain;
+        frame.argc = 0;
+        frame.argv = NULL;
+        frame.nvars = script->numGlobalVars;
+        if (frame.nvars) {
+            frame.vars = js_AllocRawStack(cx, frame.nvars, &mark);
+            if (!frame.vars)
+                return JS_FALSE;
+            memset(frame.vars, 0, frame.nvars * sizeof(jsval));
+        } else {
+            frame.vars = NULL;
+        }
+        frame.annotation = NULL;
+        frame.sharpArray = NULL;
+    }
+    frame.rval = JSVAL_VOID;
+    frame.down = down;
+    frame.scopeChain = chain;
+    frame.pc = NULL;
+    frame.sp = oldfp ? oldfp->sp : NULL;
+    frame.spbase = NULL;
+    frame.sharpDepth = 0;
+    frame.flags = flags;
+    frame.dormantNext = NULL;
+    frame.xmlNamespace = NULL;
+
+    /*
+     * Here we wrap the call to js_Interpret with code to (conditionally)
+     * save and restore the old stack frame chain into a chain of 'dormant'
+     * frame chains.  Since we are replacing cx->fp, we were running into
+     * the problem that if GC was called under this frame, some of the GC
+     * things associated with the old frame chain (available here only in
+     * the C variable 'oldfp') were not rooted and were being collected.
+     *
+     * So, now we preserve the links to these 'dormant' frame chains in cx
+     * before calling js_Interpret and cleanup afterwards.  The GC walks
+     * these dormant chains and marks objects in the same way that it marks
+     * objects in the primary cx->fp chain.
+     */
+    if (oldfp && oldfp != down) {
+        JS_ASSERT(!oldfp->dormantNext);
+        oldfp->dormantNext = cx->dormantFrameChain;
+        cx->dormantFrameChain = oldfp;
+    }
+
+    cx->fp = &frame;
+    if (hook)
+        hookData = hook(cx, &frame, JS_TRUE, 0, cx->runtime->executeHookData);
+
+    /*
+     * Use frame.rval, not result, so the last result stays rooted across any
+     * GC activations nested within this js_Interpret.
+     */
+    ok = js_Interpret(cx, script->code, &frame.rval);
+    *result = frame.rval;
+
+    if (hookData) {
+        hook = cx->runtime->executeHook;
+        if (hook)
+            hook(cx, &frame, JS_FALSE, &ok, hookData);
+    }
+    if (mark)
+        js_FreeRawStack(cx, mark);
+    cx->fp = oldfp;
+
+    if (oldfp && oldfp != down) {
+        JS_ASSERT(cx->dormantFrameChain == oldfp);
+        cx->dormantFrameChain = oldfp->dormantNext;
+        oldfp->dormantNext = NULL;
+    }
+
+    return ok;
+}
+
+#if JS_HAS_EXPORT_IMPORT
+/*
+ * If id is JSVAL_VOID, import all exported properties from obj.
+ */
+static JSBool
+ImportProperty(JSContext *cx, JSObject *obj, jsid id)
+{
+    JSBool ok;
+    JSIdArray *ida;
+    JSProperty *prop;
+    JSObject *obj2, *target, *funobj, *closure;
+    JSString *str;
+    uintN attrs;
+    jsint i;
+    jsval value;
+
+    if (JSVAL_IS_VOID(id)) {
+        ida = JS_Enumerate(cx, obj);
+        if (!ida)
+            return JS_FALSE;
+        ok = JS_TRUE;
+        if (ida->length == 0)
+            goto out;
+    } else {
+        ida = NULL;
+        if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
+            return JS_FALSE;
+        if (!prop) {
+            str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,
+                                             ID_TO_VALUE(id), NULL);
+            if (str)
+                js_ReportIsNotDefined(cx, JS_GetStringBytes(str));
+            return JS_FALSE;
+        }
+        ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs);
+        OBJ_DROP_PROPERTY(cx, obj2, prop);
+        if (!ok)
+            return JS_FALSE;
+        if (!(attrs & JSPROP_EXPORTED)) {
+            str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,
+                                             ID_TO_VALUE(id), NULL);
+            if (str) {
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_NOT_EXPORTED,
+                                     JS_GetStringBytes(str));
+            }
+            return JS_FALSE;
+        }
+    }
+
+    target = cx->fp->varobj;
+    i = 0;
+    do {
+        if (ida) {
+            id = ida->vector[i];
+            ok = OBJ_GET_ATTRIBUTES(cx, obj, id, NULL, &attrs);
+            if (!ok)
+                goto out;
+            if (!(attrs & JSPROP_EXPORTED))
+                continue;
+        }
+        ok = OBJ_CHECK_ACCESS(cx, obj, id, JSACC_IMPORT, &value, &attrs);
+        if (!ok)
+            goto out;
+        if (JSVAL_IS_FUNCTION(cx, value)) {
+            funobj = JSVAL_TO_OBJECT(value);
+            closure = js_CloneFunctionObject(cx, funobj, obj);
+            if (!closure) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            value = OBJECT_TO_JSVAL(closure);
+        }
+
+        /*
+         * Handle the case of importing a property that refers to a local
+         * variable or formal parameter of a function activation.  These
+         * properties are accessed by opcodes using stack slot numbers
+         * generated by the compiler rather than runtime name-lookup.  These
+         * local references, therefore, bypass the normal scope chain lookup.
+         * So, instead of defining a new property in the activation object,
+         * modify the existing value in the stack slot.
+         */
+        if (OBJ_GET_CLASS(cx, target) == &js_CallClass) {
+            ok = OBJ_LOOKUP_PROPERTY(cx, target, id, &obj2, &prop);
+            if (!ok)
+                goto out;
+        } else {
+            prop = NULL;
+        }
+        if (prop && target == obj2) {
+            ok = OBJ_SET_PROPERTY(cx, target, id, &value);
+        } else {
+            ok = OBJ_DEFINE_PROPERTY(cx, target, id, value, NULL, NULL,
+                                     attrs & ~JSPROP_EXPORTED,
+                                     NULL);
+        }
+        if (prop)
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+        if (!ok)
+            goto out;
+    } while (ida && ++i < ida->length);
+
+out:
+    if (ida)
+        JS_DestroyIdArray(cx, ida);
+    return ok;
+}
+#endif /* JS_HAS_EXPORT_IMPORT */
+
+JSBool
+js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs,
+                      JSObject **objp, JSProperty **propp)
+{
+    JSObject *obj2;
+    JSProperty *prop;
+    uintN oldAttrs, report;
+    JSBool isFunction;
+    jsval value;
+    const char *type, *name;
+
+    if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
+        return JS_FALSE;
+    if (propp) {
+        *objp = obj2;
+        *propp = prop;
+    }
+    if (!prop)
+        return JS_TRUE;
+
+    /* From here, return true, or goto bad on failure to drop prop. */
+    if (!OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &oldAttrs))
+        goto bad;
+
+    /* If either property is readonly, we have an error. */
+    report = ((oldAttrs | attrs) & JSPROP_READONLY)
+             ? JSREPORT_ERROR
+             : JSREPORT_WARNING | JSREPORT_STRICT;
+
+    if (report != JSREPORT_ERROR) {
+        /*
+         * Allow redeclaration of variables and functions, but insist that the
+         * new value is not a getter if the old value was, ditto for setters --
+         * unless prop is impermanent (in which case anyone could delete it and
+         * redefine it, willy-nilly).
+         */
+        if (!(attrs & (JSPROP_GETTER | JSPROP_SETTER)))
+            return JS_TRUE;
+        if ((~(oldAttrs ^ attrs) & (JSPROP_GETTER | JSPROP_SETTER)) == 0)
+            return JS_TRUE;
+        if (!(oldAttrs & JSPROP_PERMANENT))
+            return JS_TRUE;
+        report = JSREPORT_ERROR;
+    }
+
+    isFunction = (oldAttrs & (JSPROP_GETTER | JSPROP_SETTER)) != 0;
+    if (!isFunction) {
+        if (!OBJ_GET_PROPERTY(cx, obj, id, &value))
+            goto bad;
+        isFunction = JSVAL_IS_FUNCTION(cx, value);
+    }
+    type = (oldAttrs & attrs & JSPROP_GETTER)
+           ? js_getter_str
+           : (oldAttrs & attrs & JSPROP_SETTER)
+           ? js_setter_str
+           : (oldAttrs & JSPROP_READONLY)
+           ? js_const_str
+           : isFunction
+           ? js_function_str
+           : js_var_str;
+    name = js_AtomToPrintableString(cx, JSID_TO_ATOM(id));
+    if (!name)
+        goto bad;
+    return JS_ReportErrorFlagsAndNumber(cx, report,
+                                        js_GetErrorMessage, NULL,
+                                        JSMSG_REDECLARED_VAR,
+                                        type, name);
+
+bad:
+    if (propp) {
+        *objp = NULL;
+        *propp = NULL;
+    }
+    OBJ_DROP_PROPERTY(cx, obj2, prop);
+    return JS_FALSE;
+}
+
+JSBool
+js_StrictlyEqual(jsval lval, jsval rval)
+{
+    jsval ltag = JSVAL_TAG(lval), rtag = JSVAL_TAG(rval);
+    jsdouble ld, rd;
+
+    if (ltag == rtag) {
+        if (ltag == JSVAL_STRING) {
+            JSString *lstr = JSVAL_TO_STRING(lval),
+                     *rstr = JSVAL_TO_STRING(rval);
+            return js_CompareStrings(lstr, rstr) == 0;
+        }
+        if (ltag == JSVAL_DOUBLE) {
+            ld = *JSVAL_TO_DOUBLE(lval);
+            rd = *JSVAL_TO_DOUBLE(rval);
+            return JSDOUBLE_COMPARE(ld, ==, rd, JS_FALSE);
+        }
+        return lval == rval;
+    }
+    if (ltag == JSVAL_DOUBLE && JSVAL_IS_INT(rval)) {
+        ld = *JSVAL_TO_DOUBLE(lval);
+        rd = JSVAL_TO_INT(rval);
+        return JSDOUBLE_COMPARE(ld, ==, rd, JS_FALSE);
+    }
+    if (JSVAL_IS_INT(lval) && rtag == JSVAL_DOUBLE) {
+        ld = JSVAL_TO_INT(lval);
+        rd = *JSVAL_TO_DOUBLE(rval);
+        return JSDOUBLE_COMPARE(ld, ==, rd, JS_FALSE);
+    }
+    return lval == rval;
+}
+
+static JSBool
+InternStringElementId(JSContext *cx, jsval idval, jsid *idp)
+{
+    JSAtom *atom;
+
+    atom = js_ValueToStringAtom(cx, idval);
+    if (!atom)
+        return JS_FALSE;
+    *idp = ATOM_TO_JSID(atom);
+    return JS_TRUE;
+}
+
+static JSBool
+InternNonIntElementId(JSContext *cx, jsval idval, jsid *idp)
+{
+    JS_ASSERT(!JSVAL_IS_INT(idval));
+
+#if JS_HAS_XML_SUPPORT
+    if (JSVAL_IS_OBJECT(idval)) {
+        *idp = OBJECT_JSVAL_TO_JSID(idval);
+        return JS_TRUE;
+    }
+#endif
+
+    return InternStringElementId(cx, idval, idp);
+}
+
+#if JS_HAS_XML_SUPPORT
+#define CHECK_ELEMENT_ID(obj, id)                                             \
+    JS_BEGIN_MACRO                                                            \
+        if (JSID_IS_OBJECT(id) && !OBJECT_IS_XML(cx, obj)) {                  \
+            SAVE_SP(fp);                                                      \
+            ok = InternStringElementId(cx, OBJECT_JSID_TO_JSVAL(id), &id);    \
+            if (!ok)                                                          \
+                goto out;                                                     \
+        }                                                                     \
+    JS_END_MACRO
+
+#else
+#define CHECK_ELEMENT_ID(obj, id)       JS_ASSERT(!JSID_IS_OBJECT(id))
+#endif
+
+#ifndef MAX_INTERP_LEVEL
+#if defined(XP_OS2)
+#define MAX_INTERP_LEVEL 250
+#else
+#define MAX_INTERP_LEVEL 1000
+#endif
+#endif
+
+#define MAX_INLINE_CALL_COUNT 1000
+
+JSBool
+js_Interpret(JSContext *cx, jsbytecode *pc, jsval *result)
+{
+    JSRuntime *rt;
+    JSStackFrame *fp;
+    JSScript *script;
+    uintN inlineCallCount;
+    JSObject *obj, *obj2, *proto, *parent;
+    JSVersion currentVersion, originalVersion;
+    JSBranchCallback onbranch;
+    JSBool ok, cond;
+    JSTrapHandler interruptHandler;
+    jsint depth, len;
+    jsval *sp, *newsp;
+    void *mark;
+    jsbytecode *endpc, *pc2;
+    JSOp op, op2;
+#ifdef OSSP /* CLEANUP */
+    const JSCodeSpec *cs = NULL;
+#else
+    const JSCodeSpec *cs;
+#endif
+    jsatomid atomIndex;
+    JSAtom *atom;
+    uintN argc, slot, attrs;
+    jsval *vp, lval, rval, ltmp, rtmp;
+#ifdef OSSP /* CLEANUP */
+    jsid id = -1L;
+#else
+    jsid id;
+#endif
+    JSObject *withobj, *origobj, *propobj;
+    jsval iter_state;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+    JSString *str, *str2;
+    jsint i, j;
+    jsdouble d, d2;
+    JSClass *clasp, *funclasp;
+    JSFunction *fun;
+    JSType type;
+#ifdef DEBUG
+#ifdef OSSP /* CLEANUP */
+    FILE *tracefp = NULL;
+#else
+    FILE *tracefp;
+#endif
+#endif
+#if JS_HAS_EXPORT_IMPORT
+    JSIdArray *ida;
+#endif
+#if JS_HAS_SWITCH_STATEMENT
+    jsint low, high, off, npairs;
+    JSBool match;
+#endif
+#if JS_HAS_GETTER_SETTER
+    JSPropertyOp getter, setter;
+#endif
+#if JS_HAS_XML_SUPPORT
+    JSBool foreach = JS_FALSE;
+#endif
+    int stackDummy;
+
+    *result = JSVAL_VOID;
+    rt = cx->runtime;
+
+    /* Set registerized frame pointer and derived script pointer. */
+    fp = cx->fp;
+    script = fp->script;
+
+    /* Count of JS function calls that nest in this C js_Interpret frame. */
+    inlineCallCount = 0;
+
+    /*
+     * Optimized Get and SetVersion for proper script language versioning.
+     *
+     * If any native method or JSClass/JSObjectOps hook calls js_SetVersion
+     * and changes cx->version, the effect will "stick" and we will stop
+     * maintaining currentVersion.  This is relied upon by testsuites, for
+     * the most part -- web browsers select version before compiling and not
+     * at run-time.
+     */
+    currentVersion = script->version;
+    originalVersion = cx->version;
+    if (currentVersion != originalVersion)
+        js_SetVersion(cx, currentVersion);
+
+    /*
+     * Prepare to call a user-supplied branch handler, and abort the script
+     * if it returns false.  We reload onbranch after calling out to native
+     * functions (but not to getters, setters, or other native hooks).
+     */
+#define LOAD_BRANCH_CALLBACK(cx)    (onbranch = (cx)->branchCallback)
+
+    LOAD_BRANCH_CALLBACK(cx);
+    ok = JS_TRUE;
+#define CHECK_BRANCH(len)                                                     \
+    JS_BEGIN_MACRO                                                            \
+        if (len <= 0 && onbranch) {                                           \
+            SAVE_SP(fp);                                                      \
+            if (!(ok = (*onbranch)(cx, script)))                              \
+                goto out;                                                     \
+        }                                                                     \
+    JS_END_MACRO
+
+    /*
+     * Load the debugger's interrupt hook here and after calling out to native
+     * functions (but not to getters, setters, or other native hooks), so we do
+     * not have to reload it each time through the interpreter loop -- we hope
+     * the compiler can keep it in a register.
+     * XXX if it spills, we still lose
+     */
+#define LOAD_INTERRUPT_HANDLER(rt)  (interruptHandler = (rt)->interruptHandler)
+
+    LOAD_INTERRUPT_HANDLER(rt);
+
+    /* Check for too much js_Interpret nesting, or too deep a C stack. */
+    if (++cx->interpLevel == MAX_INTERP_LEVEL ||
+        !JS_CHECK_STACK_SIZE(cx, stackDummy)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
+        ok = JS_FALSE;
+        goto out2;
+    }
+
+    /*
+     * Allocate operand and pc stack slots for the script's worst-case depth,
+     * unless we're called to interpret a part of an already active script, a
+     * filtering predicate expression for example.
+     */
+    depth = (jsint) script->depth;
+    if (JS_LIKELY(!fp->spbase)) {
+        newsp = js_AllocRawStack(cx, (uintN)(2 * depth), &mark);
+        if (!newsp) {
+            ok = JS_FALSE;
+            goto out2;
+        }
+        sp = newsp + depth;
+        fp->spbase = sp;
+        SAVE_SP(fp);
+    } else {
+        sp = fp->sp;
+        JS_ASSERT(JS_UPTRDIFF(sp, fp->spbase) <= depth * sizeof(jsval));
+        newsp = fp->spbase - depth;
+        mark = NULL;
+    }
+
+    endpc = script->code + script->length;
+    while (pc < endpc) {
+        fp->pc = pc;
+        op = (JSOp) *pc;
+      do_op:
+        cs = &js_CodeSpec[op];
+        len = cs->length;
+
+#ifdef DEBUG
+        tracefp = (FILE *) cx->tracefp;
+        if (tracefp) {
+            intN nuses, n;
+
+            fprintf(tracefp, "%4u: ", js_PCToLineNumber(cx, script, pc));
+            js_Disassemble1(cx, script, pc,
+                            PTRDIFF(pc, script->code, jsbytecode), JS_FALSE,
+                            tracefp);
+            nuses = cs->nuses;
+            if (nuses) {
+                SAVE_SP(fp);
+                for (n = -nuses; n < 0; n++) {
+                    str = js_DecompileValueGenerator(cx, n, sp[n], NULL);
+                    if (str) {
+                        fprintf(tracefp, "%s %s",
+                                (n == -nuses) ? "  inputs:" : ",",
+                                JS_GetStringBytes(str));
+                    }
+                }
+                fprintf(tracefp, " @ %d\n", sp - fp->spbase);
+            }
+        }
+#endif
+
+        if (interruptHandler) {
+            SAVE_SP(fp);
+            switch (interruptHandler(cx, script, pc, &rval,
+                                     rt->interruptHandlerData)) {
+              case JSTRAP_ERROR:
+                ok = JS_FALSE;
+                goto out;
+              case JSTRAP_CONTINUE:
+                break;
+              case JSTRAP_RETURN:
+                fp->rval = rval;
+                goto out;
+#if JS_HAS_EXCEPTIONS
+              case JSTRAP_THROW:
+                cx->throwing = JS_TRUE;
+                cx->exception = rval;
+                ok = JS_FALSE;
+                goto out;
+#endif /* JS_HAS_EXCEPTIONS */
+              default:;
+            }
+            LOAD_INTERRUPT_HANDLER(rt);
+        }
+
+        switch (op) {
+          case JSOP_NOP:
+            break;
+
+          case JSOP_GROUP:
+            break;
+
+          case JSOP_PUSH:
+            PUSH_OPND(JSVAL_VOID);
+            break;
+
+          case JSOP_POP:
+            sp--;
+            break;
+
+          case JSOP_POP2:
+            sp -= 2;
+            break;
+
+          case JSOP_SWAP:
+            /*
+             * N.B. JSOP_SWAP doesn't swap the corresponding generating pcs
+             * for the operands it swaps.
+             */
+            ltmp = sp[-1];
+            sp[-1] = sp[-2];
+            sp[-2] = ltmp;
+            break;
+
+          case JSOP_POPV:
+            *result = POP_OPND();
+            break;
+
+          case JSOP_ENTERWITH:
+            FETCH_OBJECT(cx, -1, rval, obj);
+            SAVE_SP(fp);
+            withobj = js_NewObject(cx, &js_WithClass, obj, fp->scopeChain);
+            if (!withobj)
+                goto out;
+            rval = INT_TO_JSVAL(sp - fp->spbase);
+            OBJ_SET_SLOT(cx, withobj, JSSLOT_PRIVATE, rval);
+            fp->scopeChain = withobj;
+            STORE_OPND(-1, OBJECT_TO_JSVAL(withobj));
+            break;
+
+          case JSOP_LEAVEWITH:
+            rval = POP_OPND();
+            JS_ASSERT(JSVAL_IS_OBJECT(rval));
+            withobj = JSVAL_TO_OBJECT(rval);
+            JS_ASSERT(OBJ_GET_CLASS(cx, withobj) == &js_WithClass);
+
+            rval = OBJ_GET_SLOT(cx, withobj, JSSLOT_PARENT);
+            JS_ASSERT(JSVAL_IS_OBJECT(rval));
+            fp->scopeChain = JSVAL_TO_OBJECT(rval);
+            break;
+
+          case JSOP_SETRVAL:
+            fp->rval = POP_OPND();
+            break;
+
+          case JSOP_RETURN:
+            CHECK_BRANCH(-1);
+            fp->rval = POP_OPND();
+            /* FALL THROUGH */
+
+          case JSOP_RETRVAL:    /* fp->rval already set */
+            if (inlineCallCount)
+          inline_return:
+            {
+                JSInlineFrame *ifp = (JSInlineFrame *) fp;
+                void *hookData = ifp->hookData;
+
+                if (hookData) {
+                    JSInterpreterHook hook = cx->runtime->callHook;
+                    if (hook) {
+                        hook(cx, fp, JS_FALSE, &ok, hookData);
+                        LOAD_INTERRUPT_HANDLER(rt);
+                    }
+                }
+#if JS_HAS_ARGS_OBJECT
+                if (fp->argsobj)
+                    ok &= js_PutArgsObject(cx, fp);
+#endif
+
+                /* Restore context version only if callee hasn't set version. */
+                if (cx->version == currentVersion) {
+                    currentVersion = ifp->callerVersion;
+                    if (currentVersion != cx->version)
+                        js_SetVersion(cx, currentVersion);
+                }
+
+                /* Store the return value in the caller's operand frame. */
+                vp = fp->argv - 2;
+                *vp = fp->rval;
+
+                /* Restore cx->fp and release the inline frame's space. */
+                cx->fp = fp = fp->down;
+                JS_ARENA_RELEASE(&cx->stackPool, ifp->mark);
+
+                /* Restore sp to point just above the return value. */
+                fp->sp = vp + 1;
+                RESTORE_SP(fp);
+
+                /* Restore the calling script's interpreter registers. */
+                script = fp->script;
+                depth = (jsint) script->depth;
+                pc = fp->pc;
+                endpc = script->code + script->length;
+
+                /* Store the generating pc for the return value. */
+                vp[-depth] = (jsval)pc;
+
+                /* Set remaining variables for 'goto advance_pc'. */
+                op = (JSOp) *pc;
+                cs = &js_CodeSpec[op];
+                len = cs->length;
+
+                /* Resume execution in the calling frame. */
+                inlineCallCount--;
+                if (ok)
+                    goto advance_pc;
+            }
+            goto out;
+
+#if JS_HAS_SWITCH_STATEMENT
+          case JSOP_DEFAULT:
+            (void) POP();
+            /* FALL THROUGH */
+#endif
+          case JSOP_GOTO:
+            len = GET_JUMP_OFFSET(pc);
+            CHECK_BRANCH(len);
+            break;
+
+          case JSOP_IFEQ:
+            POP_BOOLEAN(cx, rval, cond);
+            if (cond == JS_FALSE) {
+                len = GET_JUMP_OFFSET(pc);
+                CHECK_BRANCH(len);
+            }
+            break;
+
+          case JSOP_IFNE:
+            POP_BOOLEAN(cx, rval, cond);
+            if (cond != JS_FALSE) {
+                len = GET_JUMP_OFFSET(pc);
+                CHECK_BRANCH(len);
+            }
+            break;
+
+          case JSOP_OR:
+            POP_BOOLEAN(cx, rval, cond);
+            if (cond == JS_TRUE) {
+                len = GET_JUMP_OFFSET(pc);
+                PUSH_OPND(rval);
+            }
+            break;
+
+          case JSOP_AND:
+            POP_BOOLEAN(cx, rval, cond);
+            if (cond == JS_FALSE) {
+                len = GET_JUMP_OFFSET(pc);
+                PUSH_OPND(rval);
+            }
+            break;
+
+
+#if JS_HAS_SWITCH_STATEMENT
+          case JSOP_DEFAULTX:
+            (void) POP();
+            /* FALL THROUGH */
+#endif
+          case JSOP_GOTOX:
+            len = GET_JUMPX_OFFSET(pc);
+            CHECK_BRANCH(len);
+            break;
+
+          case JSOP_IFEQX:
+            POP_BOOLEAN(cx, rval, cond);
+            if (cond == JS_FALSE) {
+                len = GET_JUMPX_OFFSET(pc);
+                CHECK_BRANCH(len);
+            }
+            break;
+
+          case JSOP_IFNEX:
+            POP_BOOLEAN(cx, rval, cond);
+            if (cond != JS_FALSE) {
+                len = GET_JUMPX_OFFSET(pc);
+                CHECK_BRANCH(len);
+            }
+            break;
+
+          case JSOP_ORX:
+            POP_BOOLEAN(cx, rval, cond);
+            if (cond == JS_TRUE) {
+                len = GET_JUMPX_OFFSET(pc);
+                PUSH_OPND(rval);
+            }
+            break;
+
+          case JSOP_ANDX:
+            POP_BOOLEAN(cx, rval, cond);
+            if (cond == JS_FALSE) {
+                len = GET_JUMPX_OFFSET(pc);
+                PUSH_OPND(rval);
+            }
+            break;
+
+          case JSOP_TOOBJECT:
+            rval = FETCH_OPND(-1);
+            if (!JSVAL_IS_PRIMITIVE(rval)) {
+                obj = JSVAL_TO_OBJECT(rval);
+            } else {
+                SAVE_SP(fp);
+                ok = js_ValueToObject(cx, rval, &obj);
+                if (!ok)
+                    goto out;
+            }
+            STORE_OPND(-1, OBJECT_TO_JSVAL(obj));
+            break;
+
+/*
+ * If the index value at sp[n] is not an int that fits in a jsval, it could
+ * be an object (an XML QName, AttributeName, or AnyName), but only if we are
+ * compiling with JS_HAS_XML_SUPPORT.  Otherwise convert the index value to a
+ * string atom id.
+ */
+#define FETCH_ELEMENT_ID(n, id)                                               \
+    JS_BEGIN_MACRO                                                            \
+        jsval idval_ = FETCH_OPND(n);                                         \
+        if (JSVAL_IS_INT(idval_)) {                                           \
+            id = INT_JSVAL_TO_JSID(idval_);                                   \
+        } else {                                                              \
+            SAVE_SP(fp);                                                      \
+            ok = InternNonIntElementId(cx, idval_, &id);                      \
+            if (!ok)                                                          \
+                goto out;                                                     \
+        }                                                                     \
+    JS_END_MACRO
+
+#if JS_HAS_IN_OPERATOR
+          case JSOP_IN:
+            SAVE_SP(fp);
+            rval = FETCH_OPND(-1);
+            if (JSVAL_IS_PRIMITIVE(rval)) {
+                str = js_DecompileValueGenerator(cx, -1, rval, NULL);
+                if (str) {
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                         JSMSG_IN_NOT_OBJECT,
+                                         JS_GetStringBytes(str));
+                }
+                ok = JS_FALSE;
+                goto out;
+            }
+            obj = JSVAL_TO_OBJECT(rval);
+            FETCH_ELEMENT_ID(-2, id);
+            CHECK_ELEMENT_ID(obj, id);
+            ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
+            if (!ok)
+                goto out;
+            sp--;
+            STORE_OPND(-1, BOOLEAN_TO_JSVAL(prop != NULL));
+            if (prop)
+                OBJ_DROP_PROPERTY(cx, obj2, prop);
+            break;
+#endif /* JS_HAS_IN_OPERATOR */
+
+          case JSOP_FORPROP:
+            /*
+             * Handle JSOP_FORPROP first, so the cost of the goto do_forinloop
+             * is not paid for the more common cases.
+             */
+            lval = FETCH_OPND(-1);
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+            i = -2;
+            goto do_forinloop;
+
+          case JSOP_FORNAME:
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+
+            /*
+             * ECMA 12.6.3 says to eval the LHS after looking for properties
+             * to enumerate, and bail without LHS eval if there are no props.
+             * We do Find here to share the most code at label do_forinloop.
+             * If looking for enumerable properties could have side effects,
+             * then we'd have to move this into the common code and condition
+             * it on op == JSOP_FORNAME.
+             */
+            SAVE_SP(fp);
+            ok = js_FindProperty(cx, id, &obj, &obj2, &prop);
+            if (!ok)
+                goto out;
+            if (prop)
+                OBJ_DROP_PROPERTY(cx, obj2, prop);
+            lval = OBJECT_TO_JSVAL(obj);
+            /* FALL THROUGH */
+
+          case JSOP_FORARG:
+          case JSOP_FORVAR:
+            /*
+             * JSOP_FORARG and JSOP_FORVAR don't require any lval computation
+             * here, because they address slots on the stack (in fp->args and
+             * fp->vars, respectively).
+             */
+            /* FALL THROUGH */
+
+          case JSOP_FORELEM:
+            /*
+             * JSOP_FORELEM simply initializes or updates the iteration state
+             * and leaves the index expression evaluation and assignment to the
+             * enumerator until after the next property has been acquired, via
+             * a JSOP_ENUMELEM bytecode.
+             */
+            i = -1;
+
+          do_forinloop:
+            /*
+             * ECMA-compatible for/in evals the object just once, before loop.
+             * Bad old bytecodes (since removed) did it on every iteration.
+             */
+            obj = JSVAL_TO_OBJECT(sp[i]);
+
+            /* If the thing to the right of 'in' has no properties, break. */
+            if (!obj) {
+                rval = JSVAL_FALSE;
+                goto end_forinloop;
+            }
+
+            /*
+             * Save the thing to the right of 'in' as origobj.  Later on, we
+             * use this variable to suppress enumeration of shadowed prototype
+             * properties.
+             */
+            origobj = obj;
+
+            /*
+             * Reach under the top of stack to find our property iterator, a
+             * JSObject that contains the iteration state.  (An object is used
+             * rather than a native struct so that the iteration state is
+             * cleaned up via GC if the for-in loop terminates abruptly.)
+             */
+            vp = &sp[i - 1];
+            rval = *vp;
+
+            /*
+             * Save sp in fp now, before any OBJ_* call-outs that might nest
+             * an interpreter or GC activation on this context.
+             */
+            SAVE_SP(fp);
+
+            /* Is this the first iteration ? */
+            if (JSVAL_IS_VOID(rval)) {
+                /* Yes, create a new JSObject to hold the iterator state */
+                propobj = js_NewObject(cx, &prop_iterator_class, NULL, obj);
+                if (!propobj) {
+                    ok = JS_FALSE;
+                    goto out;
+                }
+                propobj->slots[JSSLOT_ITER_STATE] = JSVAL_NULL;
+
+                /*
+                 * Root the parent slot so we can get it even in our finalizer
+                 * (otherwise, it would live as long as we do, but it might be
+                 * finalized first).
+                 */
+                ok = js_AddRoot(cx, &propobj->slots[JSSLOT_PARENT],
+                                "propobj->parent");
+                if (!ok)
+                    goto out;
+
+                /*
+                 * Rewrite the iterator so we know to do the next case.
+                 * Do this before calling the enumerator, which could
+                 * displace cx->newborn and cause GC.
+                 */
+                *vp = OBJECT_TO_JSVAL(propobj);
+
+                ok =
+#if JS_HAS_XML_SUPPORT
+                     (foreach && OBJECT_IS_XML(cx, obj))
+                     ? ((JSXMLObjectOps *) obj->map->ops)->enumerateValues
+                                    (cx, obj, JSENUMERATE_INIT, &iter_state,
+                                     NULL, NULL)
+                     :
+#endif
+                       OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state,
+                                     NULL);
+                if (!ok)
+                    goto out;
+
+                /*
+                 * Stash private iteration state into property iterator object.
+                 * NB: This code knows that the first slots are pre-allocated.
+                 */
+#if JS_INITIAL_NSLOTS < 5
+#error JS_INITIAL_NSLOTS must be greater than or equal to 5.
+#endif
+                propobj->slots[JSSLOT_ITER_STATE] = iter_state;
+            } else {
+                /* This is not the first iteration. Recover iterator state. */
+                propobj = JSVAL_TO_OBJECT(rval);
+                JS_ASSERT(OBJ_GET_CLASS(cx, propobj) == &prop_iterator_class);
+                obj = JSVAL_TO_OBJECT(propobj->slots[JSSLOT_PARENT]);
+                iter_state = propobj->slots[JSSLOT_ITER_STATE];
+            }
+
+          enum_next_property:
+          {
+            jsid fid;
+
+            /* Get the next jsid to be enumerated and store it in fid. */
+            ok =
+#if JS_HAS_XML_SUPPORT
+                 (foreach && OBJECT_IS_XML(cx, obj))
+                 ? ((JSXMLObjectOps *) obj->map->ops)->enumerateValues
+                                (cx, obj, JSENUMERATE_NEXT, &iter_state,
+                                 &fid, &rval)
+                 :
+#endif
+                   OBJ_ENUMERATE(cx, obj, JSENUMERATE_NEXT, &iter_state, &fid);
+            propobj->slots[JSSLOT_ITER_STATE] = iter_state;
+
+            /* No more jsids to iterate in obj? */
+            if (iter_state == JSVAL_NULL) {
+                /* Enumerate the properties on obj's prototype chain. */
+                obj = OBJ_GET_PROTO(cx, obj);
+                if (!obj) {
+                    /* End of property list -- terminate loop. */
+                    rval = JSVAL_FALSE;
+#if JS_HAS_XML_SUPPORT
+                    foreach = JS_FALSE;
+#endif
+                    goto end_forinloop;
+                }
+
+                ok =
+#if JS_HAS_XML_SUPPORT
+                     (foreach && OBJECT_IS_XML(cx, obj))
+                     ? ((JSXMLObjectOps *) obj->map->ops)->enumerateValues
+                                    (cx, obj, JSENUMERATE_INIT, &iter_state,
+                                     NULL, NULL)
+                     :
+#endif
+                       OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state,
+                                     NULL);
+
+                /*
+                 * Stash private iteration state into property iterator object.
+                 * We do this before checking 'ok' to ensure that propobj is
+                 * in a valid state even if OBJ_ENUMERATE returned JS_FALSE.
+                 * NB: This code knows that the first slots are pre-allocated.
+                 */
+                propobj->slots[JSSLOT_ITER_STATE] = iter_state;
+                if (!ok)
+                    goto out;
+
+                /*
+                 * Update the iterator JSObject's parent link to refer to the
+                 * current object. This is used in the iterator JSObject's
+                 * finalizer.
+                 */
+                propobj->slots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(obj);
+                goto enum_next_property;
+            }
+
+            /* Skip properties not owned by obj when looking from origobj. */
+            ok = OBJ_LOOKUP_PROPERTY(cx, origobj, fid, &obj2, &prop);
+            if (!ok)
+                goto out;
+            if (prop)
+                OBJ_DROP_PROPERTY(cx, obj2, prop);
+
+            /*
+             * If the id was deleted, or found in a prototype or an unrelated
+             * object (specifically, not in an inner object for obj), skip it.
+             * This means that OBJ_LOOKUP_PROPERTY implementations must return
+             * an object either further on the prototype chain, or related by
+             * the JSExtendedClass.outerObject optional hook.
+             */
+            if (!prop)
+                goto enum_next_property;
+            if (obj != obj2) {
+                cond = JS_FALSE;
+                clasp = OBJ_GET_CLASS(cx, obj2);
+                if (clasp->flags & JSCLASS_IS_EXTENDED) {
+                    JSExtendedClass *xclasp;
+
+                    xclasp = (JSExtendedClass *) clasp;
+                    cond = xclasp->outerObject &&
+                           xclasp->outerObject(cx, obj2) == obj;
+                }
+                if (!cond)
+                    goto enum_next_property;
+            }
+
+#if JS_HAS_XML_SUPPORT
+            if (foreach) {
+                /* Clear the local foreach flag set by our prefix bytecode. */
+                foreach = JS_FALSE;
+
+                /* If obj is not XML, we must get rval given its fid. */
+                if (!OBJECT_IS_XML(cx, obj)) {
+                    ok = OBJ_GET_PROPERTY(cx, origobj, fid, &rval);
+                    if (!ok)
+                        goto out;
+                }
+            } else
+#endif
+            {
+                /* Make rval a string for uniformity and compatibility. */
+                if (JSID_IS_ATOM(fid)) {
+                    rval = ATOM_KEY(JSID_TO_ATOM(fid));
+                }
+#if JS_HAS_XML_SUPPORT
+                else if (JSID_IS_OBJECT(fid)) {
+                    str = js_ValueToString(cx, OBJECT_JSID_TO_JSVAL(fid));
+                    if (!str) {
+                        ok = JS_FALSE;
+                        goto out;
+                    }
+
+                    rval = STRING_TO_JSVAL(str);
+                }
+#endif
+                else if (!JS_VERSION_IS_1_2(cx)) {
+                    str = js_NumberToString(cx, (jsdouble) JSID_TO_INT(fid));
+                    if (!str) {
+                        ok = JS_FALSE;
+                        goto out;
+                    }
+
+                    rval = STRING_TO_JSVAL(str);
+                } else {
+                    rval = INT_JSID_TO_JSVAL(fid);
+                }
+            }
+
+            switch (op) {
+              case JSOP_FORARG:
+                slot = GET_ARGNO(pc);
+                JS_ASSERT(slot < fp->fun->nargs);
+                fp->argv[slot] = rval;
+                break;
+
+              case JSOP_FORVAR:
+                slot = GET_VARNO(pc);
+                JS_ASSERT(slot < fp->fun->nvars);
+                fp->vars[slot] = rval;
+                break;
+
+              case JSOP_FORELEM:
+                /* FORELEM is not a SET operation, it's more like BINDNAME. */
+                PUSH_OPND(rval);
+                break;
+
+              default:
+                /* Convert lval to a non-null object containing id. */
+                VALUE_TO_OBJECT(cx, lval, obj);
+                if (i + 1 < 0)
+                    STORE_OPND(i + 1, OBJECT_TO_JSVAL(obj));
+
+                /* Set the variable obj[id] to refer to rval. */
+                fp->flags |= JSFRAME_ASSIGNING;
+                ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);
+                fp->flags &= ~JSFRAME_ASSIGNING;
+                if (!ok)
+                    goto out;
+                break;
+            }
+
+            /* Push true to keep looping through properties. */
+            rval = JSVAL_TRUE;
+
+          end_forinloop:
+            sp += i + 1;
+            PUSH_OPND(rval);
+            break;
+          }
+
+          case JSOP_DUP:
+            JS_ASSERT(sp > fp->spbase);
+            rval = sp[-1];
+            PUSH_OPND(rval);
+            break;
+
+          case JSOP_DUP2:
+            JS_ASSERT(sp - 1 > fp->spbase);
+            lval = FETCH_OPND(-2);
+            rval = FETCH_OPND(-1);
+            PUSH_OPND(lval);
+            PUSH_OPND(rval);
+            break;
+
+#define PROPERTY_OP(n, call)                                                  \
+    JS_BEGIN_MACRO                                                            \
+        /* Fetch the left part and resolve it to a non-null object. */        \
+        FETCH_OBJECT(cx, n, lval, obj);                                       \
+                                                                              \
+        /* Get or set the property, set ok false if error, true if success. */\
+        SAVE_SP(fp);                                                          \
+        call;                                                                 \
+        if (!ok)                                                              \
+            goto out;                                                         \
+    JS_END_MACRO
+
+#define ELEMENT_OP(n, call)                                                   \
+    JS_BEGIN_MACRO                                                            \
+        /* Fetch the right part and resolve it to an internal id. */          \
+        FETCH_ELEMENT_ID(n, id);                                              \
+                                                                              \
+        /* Fetch the left part and resolve it to a non-null object. */        \
+        FETCH_OBJECT(cx, n - 1, lval, obj);                                   \
+                                                                              \
+        /* Ensure that id has a type suitable for use with obj. */            \
+        CHECK_ELEMENT_ID(obj, id);                                            \
+                                                                              \
+        /* Get or set the element, set ok false if error, true if success. */ \
+        SAVE_SP(fp);                                                          \
+        call;                                                                 \
+        if (!ok)                                                              \
+            goto out;                                                         \
+    JS_END_MACRO
+
+/*
+ * Direct callers, i.e. those who do not wrap CACHED_GET and CACHED_SET calls
+ * in PROPERTY_OP or ELEMENT_OP macro calls must SAVE_SP(fp); beforehand, just
+ * in case a getter or setter function is invoked.  CACHED_GET and CACHED_SET
+ * use cx, obj, id, and rval from their caller's lexical environment.
+ */
+#define CACHED_GET(call)        CACHED_GET_VP(call, &rval)
+
+#define CACHED_GET_VP(call,vp)                                                \
+    JS_BEGIN_MACRO                                                            \
+        if (!OBJ_IS_NATIVE(obj)) {                                            \
+            ok = call;                                                        \
+        } else {                                                              \
+            JS_LOCK_OBJ(cx, obj);                                             \
+            PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop);          \
+            if (sprop) {                                                      \
+                JSScope *scope_ = OBJ_SCOPE(obj);                             \
+                slot = (uintN)sprop->slot;                                    \
+                *(vp) = (slot != SPROP_INVALID_SLOT)                          \
+                        ? LOCKED_OBJ_GET_SLOT(obj, slot)                      \
+                        : JSVAL_VOID;                                         \
+                JS_UNLOCK_SCOPE(cx, scope_);                                  \
+                ok = SPROP_GET(cx, sprop, obj, obj, vp);                      \
+                JS_LOCK_SCOPE(cx, scope_);                                    \
+                if (ok && SPROP_HAS_VALID_SLOT(sprop, scope_))                \
+                    LOCKED_OBJ_SET_SLOT(obj, slot, *(vp));                    \
+                JS_UNLOCK_SCOPE(cx, scope_);                                  \
+            } else {                                                          \
+                JS_UNLOCK_OBJ(cx, obj);                                       \
+                ok = call;                                                    \
+                /* No fill here: js_GetProperty fills the cache. */           \
+            }                                                                 \
+        }                                                                     \
+    JS_END_MACRO
+
+#define CACHED_SET(call)                                                      \
+    JS_BEGIN_MACRO                                                            \
+        if (!OBJ_IS_NATIVE(obj)) {                                            \
+            ok = call;                                                        \
+        } else {                                                              \
+            JSScope *scope_;                                                  \
+            JS_LOCK_OBJ(cx, obj);                                             \
+            PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop);          \
+            if (sprop &&                                                      \
+                !(sprop->attrs & JSPROP_READONLY) &&                          \
+                (scope_ = OBJ_SCOPE(obj), !SCOPE_IS_SEALED(scope_))) {        \
+                JS_UNLOCK_SCOPE(cx, scope_);                                  \
+                ok = SPROP_SET(cx, sprop, obj, obj, &rval);                   \
+                JS_LOCK_SCOPE(cx, scope_);                                    \
+                if (ok && SPROP_HAS_VALID_SLOT(sprop, scope_)) {              \
+                    LOCKED_OBJ_SET_SLOT(obj, sprop->slot, rval);              \
+                    GC_POKE(cx, JSVAL_NULL);  /* XXX second arg ignored */    \
+                }                                                             \
+                JS_UNLOCK_SCOPE(cx, scope_);                                  \
+            } else {                                                          \
+                JS_UNLOCK_OBJ(cx, obj);                                       \
+                ok = call;                                                    \
+                /* No fill here: js_SetProperty writes through the cache. */  \
+            }                                                                 \
+        }                                                                     \
+    JS_END_MACRO
+
+#define BEGIN_LITOPX_CASE(OP,PCOFF)                                           \
+          case OP:                                                            \
+            atomIndex = GET_ATOM_INDEX(pc + PCOFF);                           \
+          do_##OP:                                                            \
+            atom = js_GetAtom(cx, &script->atomMap, atomIndex);
+
+#define END_LITOPX_CASE                                                       \
+            break;                                                            \
+
+          BEGIN_LITOPX_CASE(JSOP_SETCONST, 0)
+            obj = fp->varobj;
+            rval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            ok = OBJ_DEFINE_PROPERTY(cx, obj, ATOM_TO_JSID(atom), rval,
+                                     NULL, NULL,
+                                     JSPROP_ENUMERATE | JSPROP_PERMANENT |
+                                     JSPROP_READONLY,
+                                     NULL);
+            if (!ok)
+                goto out;
+            STORE_OPND(-1, rval);
+          END_LITOPX_CASE
+
+          BEGIN_LITOPX_CASE(JSOP_BINDNAME, 0)
+            SAVE_SP(fp);
+            obj = js_FindIdentifierBase(cx, ATOM_TO_JSID(atom));
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            PUSH_OPND(OBJECT_TO_JSVAL(obj));
+          END_LITOPX_CASE
+
+          case JSOP_SETNAME:
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+            rval = FETCH_OPND(-1);
+            lval = FETCH_OPND(-2);
+            JS_ASSERT(!JSVAL_IS_PRIMITIVE(lval));
+            obj  = JSVAL_TO_OBJECT(lval);
+            SAVE_SP(fp);
+            CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));
+            if (!ok)
+                goto out;
+            sp--;
+            STORE_OPND(-1, rval);
+            obj = NULL;
+            break;
+
+#define INTEGER_OP(OP, EXTRA_CODE)                                            \
+    JS_BEGIN_MACRO                                                            \
+        FETCH_INT(cx, -1, j);                                                 \
+        FETCH_INT(cx, -2, i);                                                 \
+        if (!ok)                                                              \
+            goto out;                                                         \
+        EXTRA_CODE                                                            \
+        d = i OP j;                                                           \
+        sp--;                                                                 \
+        STORE_NUMBER(cx, -1, d);                                              \
+    JS_END_MACRO
+
+#define BITWISE_OP(OP)          INTEGER_OP(OP, (void) 0;)
+#define SIGNED_SHIFT_OP(OP)     INTEGER_OP(OP, j &= 31;)
+
+          case JSOP_BITOR:
+            BITWISE_OP(|);
+            break;
+
+          case JSOP_BITXOR:
+            BITWISE_OP(^);
+            break;
+
+          case JSOP_BITAND:
+            BITWISE_OP(&);
+            break;
+
+#define RELATIONAL_OP(OP)                                                     \
+    JS_BEGIN_MACRO                                                            \
+        rval = FETCH_OPND(-1);                                                \
+        lval = FETCH_OPND(-2);                                                \
+        /* Optimize for two int-tagged operands (typical loop control). */    \
+        if ((lval & rval) & JSVAL_INT) {                                      \
+            ltmp = lval ^ JSVAL_VOID;                                         \
+            rtmp = rval ^ JSVAL_VOID;                                         \
+            if (ltmp && rtmp) {                                               \
+                cond = JSVAL_TO_INT(lval) OP JSVAL_TO_INT(rval);              \
+            } else {                                                          \
+                d  = ltmp ? JSVAL_TO_INT(lval) : *rt->jsNaN;                  \
+                d2 = rtmp ? JSVAL_TO_INT(rval) : *rt->jsNaN;                  \
+                cond = JSDOUBLE_COMPARE(d, OP, d2, JS_FALSE);                 \
+            }                                                                 \
+        } else {                                                              \
+            VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_NUMBER, &lval);               \
+            sp[-2] = lval;                                                    \
+            VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_NUMBER, &rval);               \
+            if (JSVAL_IS_STRING(lval) && JSVAL_IS_STRING(rval)) {             \
+                str  = JSVAL_TO_STRING(lval);                                 \
+                str2 = JSVAL_TO_STRING(rval);                                 \
+                cond = js_CompareStrings(str, str2) OP 0;                     \
+            } else {                                                          \
+                VALUE_TO_NUMBER(cx, lval, d);                                 \
+                VALUE_TO_NUMBER(cx, rval, d2);                                \
+                cond = JSDOUBLE_COMPARE(d, OP, d2, JS_FALSE);                 \
+            }                                                                 \
+        }                                                                     \
+        sp--;                                                                 \
+        STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond));                               \
+    JS_END_MACRO
+
+/*
+ * NB: These macros can't use JS_BEGIN_MACRO/JS_END_MACRO around their bodies
+ * because they begin if/else chains, so callers must not put semicolons after
+ * the call expressions!
+ */
+#if JS_HAS_XML_SUPPORT
+#define XML_EQUALITY_OP(OP)                                                   \
+    if ((ltmp == JSVAL_OBJECT &&                                              \
+         (obj2 = JSVAL_TO_OBJECT(lval)) &&                                    \
+         OBJECT_IS_XML(cx, obj2)) ||                                          \
+        (rtmp == JSVAL_OBJECT &&                                              \
+         (obj2 = JSVAL_TO_OBJECT(rval)) &&                                    \
+         OBJECT_IS_XML(cx, obj2))) {                                          \
+        JSXMLObjectOps *ops;                                                  \
+                                                                              \
+        ops = (JSXMLObjectOps *) obj2->map->ops;                              \
+        if (obj2 == JSVAL_TO_OBJECT(rval))                                    \
+            rval = lval;                                                      \
+        SAVE_SP(fp);                                                          \
+        ok = ops->equality(cx, obj2, rval, &cond);                            \
+        if (!ok)                                                              \
+            goto out;                                                         \
+        cond = cond OP JS_TRUE;                                               \
+    } else
+
+#define XML_NAME_EQUALITY_OP(OP)                                              \
+    if (ltmp == JSVAL_OBJECT &&                                               \
+        (obj2 = JSVAL_TO_OBJECT(lval)) &&                                     \
+        ((clasp = OBJ_GET_CLASS(cx, obj2))->flags & JSCLASS_IS_EXTENDED)) {   \
+        JSExtendedClass *xclasp;                                              \
+                                                                              \
+        xclasp = (JSExtendedClass *) clasp;                                   \
+        SAVE_SP(fp);                                                          \
+        ok = xclasp->equality(cx, obj2, rval, &cond);                         \
+        if (!ok)                                                              \
+            goto out;                                                         \
+        cond = cond OP JS_TRUE;                                               \
+    } else
+#else
+#define XML_EQUALITY_OP(OP)             /* nothing */
+#define XML_NAME_EQUALITY_OP(OP)        /* nothing */
+#endif
+
+#define EQUALITY_OP(OP, IFNAN)                                                \
+    JS_BEGIN_MACRO                                                            \
+        rval = FETCH_OPND(-1);                                                \
+        lval = FETCH_OPND(-2);                                                \
+        ltmp = JSVAL_TAG(lval);                                               \
+        rtmp = JSVAL_TAG(rval);                                               \
+        XML_EQUALITY_OP(OP)                                                   \
+        if (ltmp == rtmp) {                                                   \
+            if (ltmp == JSVAL_STRING) {                                       \
+                str  = JSVAL_TO_STRING(lval);                                 \
+                str2 = JSVAL_TO_STRING(rval);                                 \
+                cond = js_CompareStrings(str, str2) OP 0;                     \
+            } else if (ltmp == JSVAL_DOUBLE) {                                \
+                d  = *JSVAL_TO_DOUBLE(lval);                                  \
+                d2 = *JSVAL_TO_DOUBLE(rval);                                  \
+                cond = JSDOUBLE_COMPARE(d, OP, d2, IFNAN);                    \
+            } else {                                                          \
+                XML_NAME_EQUALITY_OP(OP)                                      \
+                /* Handle all undefined (=>NaN) and int combinations. */      \
+                cond = lval OP rval;                                          \
+            }                                                                 \
+        } else {                                                              \
+            if (JSVAL_IS_NULL(lval) || JSVAL_IS_VOID(lval)) {                 \
+                cond = (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) OP 1;     \
+            } else if (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) {          \
+                cond = 1 OP 0;                                                \
+            } else {                                                          \
+                if (ltmp == JSVAL_OBJECT) {                                   \
+                    VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &sp[-2]);       \
+                    lval = sp[-2];                                            \
+                    ltmp = JSVAL_TAG(lval);                                   \
+                } else if (rtmp == JSVAL_OBJECT) {                            \
+                    VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &sp[-1]);       \
+                    rval = sp[-1];                                            \
+                    rtmp = JSVAL_TAG(rval);                                   \
+                }                                                             \
+                if (ltmp == JSVAL_STRING && rtmp == JSVAL_STRING) {           \
+                    str  = JSVAL_TO_STRING(lval);                             \
+                    str2 = JSVAL_TO_STRING(rval);                             \
+                    cond = js_CompareStrings(str, str2) OP 0;                 \
+                } else {                                                      \
+                    VALUE_TO_NUMBER(cx, lval, d);                             \
+                    VALUE_TO_NUMBER(cx, rval, d2);                            \
+                    cond = JSDOUBLE_COMPARE(d, OP, d2, IFNAN);                \
+                }                                                             \
+            }                                                                 \
+        }                                                                     \
+        sp--;                                                                 \
+        STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond));                               \
+    JS_END_MACRO
+
+          case JSOP_EQ:
+            EQUALITY_OP(==, JS_FALSE);
+            break;
+
+          case JSOP_NE:
+            EQUALITY_OP(!=, JS_TRUE);
+            break;
+
+#if !JS_BUG_FALLIBLE_EQOPS
+#define NEW_EQUALITY_OP(OP)                                                   \
+    JS_BEGIN_MACRO                                                            \
+        rval = FETCH_OPND(-1);                                                \
+        lval = FETCH_OPND(-2);                                                \
+        cond = js_StrictlyEqual(lval, rval) OP JS_TRUE;                       \
+        sp--;                                                                 \
+        STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond));                               \
+    JS_END_MACRO
+
+          case JSOP_NEW_EQ:
+            NEW_EQUALITY_OP(==);
+            break;
+
+          case JSOP_NEW_NE:
+            NEW_EQUALITY_OP(!=);
+            break;
+
+#if JS_HAS_SWITCH_STATEMENT
+          case JSOP_CASE:
+            NEW_EQUALITY_OP(==);
+            (void) POP();
+            if (cond) {
+                len = GET_JUMP_OFFSET(pc);
+                CHECK_BRANCH(len);
+            } else {
+                PUSH(lval);
+            }
+            break;
+
+          case JSOP_CASEX:
+            NEW_EQUALITY_OP(==);
+            (void) POP();
+            if (cond) {
+                len = GET_JUMPX_OFFSET(pc);
+                CHECK_BRANCH(len);
+            } else {
+                PUSH(lval);
+            }
+            break;
+#endif
+
+#endif /* !JS_BUG_FALLIBLE_EQOPS */
+
+          case JSOP_LT:
+            RELATIONAL_OP(<);
+            break;
+
+          case JSOP_LE:
+            RELATIONAL_OP(<=);
+            break;
+
+          case JSOP_GT:
+            RELATIONAL_OP(>);
+            break;
+
+          case JSOP_GE:
+            RELATIONAL_OP(>=);
+            break;
+
+#undef EQUALITY_OP
+#undef RELATIONAL_OP
+
+          case JSOP_LSH:
+            SIGNED_SHIFT_OP(<<);
+            break;
+
+          case JSOP_RSH:
+            SIGNED_SHIFT_OP(>>);
+            break;
+
+          case JSOP_URSH:
+          {
+            uint32 u;
+
+            FETCH_INT(cx, -1, j);
+            FETCH_UINT(cx, -2, u);
+            j &= 31;
+            d = u >> j;
+            sp--;
+            STORE_NUMBER(cx, -1, d);
+            break;
+          }
+
+#undef INTEGER_OP
+#undef BITWISE_OP
+#undef SIGNED_SHIFT_OP
+
+          case JSOP_ADD:
+            rval = FETCH_OPND(-1);
+            lval = FETCH_OPND(-2);
+#if JS_HAS_XML_SUPPORT
+            if (!JSVAL_IS_PRIMITIVE(lval) &&
+                (obj2 = JSVAL_TO_OBJECT(lval), OBJECT_IS_XML(cx, obj2)) &&
+                VALUE_IS_XML(cx, rval)) {
+                JSXMLObjectOps *ops;
+
+                ops = (JSXMLObjectOps *) obj2->map->ops;
+                SAVE_SP(fp);
+                ok = ops->concatenate(cx, obj2, rval, &rval);
+                if (!ok)
+                    goto out;
+                sp--;
+                STORE_OPND(-1, rval);
+                break;
+            }
+#endif
+            {
+                VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &sp[-2]);
+                lval = sp[-2];
+                VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &sp[-1]);
+                rval = sp[-1];
+                if ((cond = JSVAL_IS_STRING(lval)) || JSVAL_IS_STRING(rval)) {
+                    SAVE_SP(fp);
+                    if (cond) {
+                        str = JSVAL_TO_STRING(lval);
+                        ok = (str2 = js_ValueToString(cx, rval)) != NULL;
+                    } else {
+                        str2 = JSVAL_TO_STRING(rval);
+                        ok = (str = js_ValueToString(cx, lval)) != NULL;
+                    }
+                    if (!ok)
+                        goto out;
+                    str = js_ConcatStrings(cx, str, str2);
+                    if (!str) {
+                        ok = JS_FALSE;
+                        goto out;
+                    }
+                    sp--;
+                    STORE_OPND(-1, STRING_TO_JSVAL(str));
+                } else {
+                    VALUE_TO_NUMBER(cx, lval, d);
+                    VALUE_TO_NUMBER(cx, rval, d2);
+                    d += d2;
+                    sp--;
+                    STORE_NUMBER(cx, -1, d);
+                }
+            }
+            break;
+
+#define BINARY_OP(OP)                                                         \
+    JS_BEGIN_MACRO                                                            \
+        FETCH_NUMBER(cx, -1, d2);                                             \
+        FETCH_NUMBER(cx, -2, d);                                              \
+        d = d OP d2;                                                          \
+        sp--;                                                                 \
+        STORE_NUMBER(cx, -1, d);                                              \
+    JS_END_MACRO
+
+          case JSOP_SUB:
+            BINARY_OP(-);
+            break;
+
+          case JSOP_MUL:
+            BINARY_OP(*);
+            break;
+
+          case JSOP_DIV:
+            FETCH_NUMBER(cx, -1, d2);
+            FETCH_NUMBER(cx, -2, d);
+            sp--;
+            if (d2 == 0) {
+#if defined(XP_WIN)
+                /* XXX MSVC miscompiles such that (NaN == 0) */
+                if (JSDOUBLE_IS_NaN(d2))
+                    rval = DOUBLE_TO_JSVAL(rt->jsNaN);
+                else
+#endif
+                if (d == 0 || JSDOUBLE_IS_NaN(d))
+                    rval = DOUBLE_TO_JSVAL(rt->jsNaN);
+                else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31)
+                    rval = DOUBLE_TO_JSVAL(rt->jsNegativeInfinity);
+                else
+                    rval = DOUBLE_TO_JSVAL(rt->jsPositiveInfinity);
+                STORE_OPND(-1, rval);
+            } else {
+                d /= d2;
+                STORE_NUMBER(cx, -1, d);
+            }
+            break;
+
+          case JSOP_MOD:
+            FETCH_NUMBER(cx, -1, d2);
+            FETCH_NUMBER(cx, -2, d);
+            sp--;
+            if (d2 == 0) {
+                STORE_OPND(-1, DOUBLE_TO_JSVAL(rt->jsNaN));
+            } else {
+#if defined(XP_WIN)
+              /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
+              if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2)))
+#endif
+                d = fmod(d, d2);
+                STORE_NUMBER(cx, -1, d);
+            }
+            break;
+
+          case JSOP_NOT:
+            POP_BOOLEAN(cx, rval, cond);
+            PUSH_OPND(BOOLEAN_TO_JSVAL(!cond));
+            break;
+
+          case JSOP_BITNOT:
+            FETCH_INT(cx, -1, i);
+            d = (jsdouble) ~i;
+            STORE_NUMBER(cx, -1, d);
+            break;
+
+          case JSOP_NEG:
+            FETCH_NUMBER(cx, -1, d);
+#ifdef HPUX
+            /*
+             * Negation of a zero doesn't produce a negative
+             * zero on HPUX. Perform the operation by bit
+             * twiddling.
+             */
+            JSDOUBLE_HI32(d) ^= JSDOUBLE_HI32_SIGNBIT;
+#else
+            d = -d;
+#endif
+            STORE_NUMBER(cx, -1, d);
+            break;
+
+          case JSOP_POS:
+            FETCH_NUMBER(cx, -1, d);
+            STORE_NUMBER(cx, -1, d);
+            break;
+
+          case JSOP_NEW:
+            /* Get immediate argc and find the constructor function. */
+            argc = GET_ARGC(pc);
+
+#if JS_HAS_INITIALIZERS
+          do_new:
+#endif
+            SAVE_SP(fp);
+            vp = sp - (2 + argc);
+            JS_ASSERT(vp >= fp->spbase);
+
+            fun = NULL;
+            obj2 = NULL;
+            lval = *vp;
+            if (!JSVAL_IS_OBJECT(lval) ||
+                (obj2 = JSVAL_TO_OBJECT(lval)) == NULL ||
+                /* XXX clean up to avoid special cases above ObjectOps layer */
+                OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass ||
+                !obj2->map->ops->construct)
+            {
+                fun = js_ValueToFunction(cx, vp, JSV2F_CONSTRUCT);
+                if (!fun) {
+                    ok = JS_FALSE;
+                    goto out;
+                }
+            }
+
+            clasp = &js_ObjectClass;
+            if (!obj2) {
+                proto = parent = NULL;
+                fun = NULL;
+            } else {
+                /*
+                 * Get the constructor prototype object for this function.
+                 * Use the nominal |this| parameter slot, vp[1], as a local
+                 * root to protect this prototype, in case it has no other
+                 * strong refs.
+                 */
+                ok = OBJ_GET_PROPERTY(cx, obj2,
+                                      ATOM_TO_JSID(rt->atomState
+                                                   .classPrototypeAtom),
+                                      &vp[1]);
+                if (!ok)
+                    goto out;
+                rval = vp[1];
+                proto = JSVAL_IS_OBJECT(rval) ? JSVAL_TO_OBJECT(rval) : NULL;
+                parent = OBJ_GET_PARENT(cx, obj2);
+
+                if (OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass) {
+                    funclasp = ((JSFunction *)JS_GetPrivate(cx, obj2))->clasp;
+                    if (funclasp)
+                        clasp = funclasp;
+                }
+            }
+            obj = js_NewObject(cx, clasp, proto, parent);
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+
+            /* Now we have an object with a constructor method; call it. */
+            vp[1] = OBJECT_TO_JSVAL(obj);
+            ok = js_Invoke(cx, argc, JSINVOKE_CONSTRUCT);
+            RESTORE_SP(fp);
+            LOAD_BRANCH_CALLBACK(cx);
+            LOAD_INTERRUPT_HANDLER(rt);
+            if (!ok) {
+                cx->newborn[GCX_OBJECT] = NULL;
+                goto out;
+            }
+
+            /* Check the return value and update obj from it. */
+            rval = *vp;
+            if (JSVAL_IS_PRIMITIVE(rval)) {
+                if (fun || !JS_VERSION_IS_ECMA(cx)) {
+                    *vp = OBJECT_TO_JSVAL(obj);
+                    break;
+                }
+                /* native [[Construct]] returning primitive is error */
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_BAD_NEW_RESULT,
+                                     js_ValueToPrintableString(cx, rval));
+                ok = JS_FALSE;
+                goto out;
+            }
+            obj = JSVAL_TO_OBJECT(rval);
+            JS_RUNTIME_METER(rt, constructs);
+            break;
+
+          case JSOP_DELNAME:
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+
+            SAVE_SP(fp);
+            ok = js_FindProperty(cx, id, &obj, &obj2, &prop);
+            if (!ok)
+                goto out;
+
+            /* ECMA says to return true if name is undefined or inherited. */
+            rval = JSVAL_TRUE;
+            if (prop) {
+                OBJ_DROP_PROPERTY(cx, obj2, prop);
+                ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval);
+                if (!ok)
+                    goto out;
+            }
+            PUSH_OPND(rval);
+            break;
+
+          case JSOP_DELPROP:
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+            PROPERTY_OP(-1, ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval));
+            STORE_OPND(-1, rval);
+            break;
+
+          case JSOP_DELELEM:
+            ELEMENT_OP(-1, ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval));
+            sp--;
+            STORE_OPND(-1, rval);
+            break;
+
+          case JSOP_TYPEOF:
+            rval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            type = JS_TypeOfValue(cx, rval);
+            atom = rt->atomState.typeAtoms[type];
+            STORE_OPND(-1, ATOM_KEY(atom));
+            break;
+
+          case JSOP_VOID:
+            (void) POP_OPND();
+            PUSH_OPND(JSVAL_VOID);
+            break;
+
+          case JSOP_INCNAME:
+          case JSOP_DECNAME:
+          case JSOP_NAMEINC:
+          case JSOP_NAMEDEC:
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+
+            SAVE_SP(fp);
+            ok = js_FindProperty(cx, id, &obj, &obj2, &prop);
+            if (!ok)
+                goto out;
+            if (!prop)
+                goto atom_not_defined;
+
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+            lval = OBJECT_TO_JSVAL(obj);
+            i = 0;
+            goto do_incop;
+
+          case JSOP_INCPROP:
+          case JSOP_DECPROP:
+          case JSOP_PROPINC:
+          case JSOP_PROPDEC:
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+            lval = FETCH_OPND(-1);
+            i = -1;
+            goto do_incop;
+
+          case JSOP_INCELEM:
+          case JSOP_DECELEM:
+          case JSOP_ELEMINC:
+          case JSOP_ELEMDEC:
+            FETCH_ELEMENT_ID(-1, id);
+            lval = FETCH_OPND(-2);
+            i = -2;
+
+          do_incop:
+            VALUE_TO_OBJECT(cx, lval, obj);
+            if (i < 0)
+                STORE_OPND(i, OBJECT_TO_JSVAL(obj));
+            CHECK_ELEMENT_ID(obj, id);
+
+            /* The operand must contain a number. */
+            SAVE_SP(fp);
+            CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval));
+            if (!ok)
+                goto out;
+
+            /* The expression result goes in rtmp, the updated value in rval. */
+            if (JSVAL_IS_INT(rval) &&
+                rval != INT_TO_JSVAL(JSVAL_INT_MIN) &&
+                rval != INT_TO_JSVAL(JSVAL_INT_MAX)) {
+                if (cs->format & JOF_POST) {
+                    rtmp = rval;
+                    (cs->format & JOF_INC) ? (rval += 2) : (rval -= 2);
+                } else {
+                    (cs->format & JOF_INC) ? (rval += 2) : (rval -= 2);
+                    rtmp = rval;
+                }
+            } else {
+
+/*
+ * Initially, rval contains the value to increment or decrement, which is not
+ * yet converted.  As above, the expression result goes in rtmp, the updated
+ * value goes in rval.  Our caller must set vp to point at a GC-rooted jsval
+ * in which we home rtmp, to protect it from GC in case the unconverted rval
+ * is not a number.
+ */
+#define NONINT_INCREMENT_OP_MIDDLE()                                          \
+    JS_BEGIN_MACRO                                                            \
+        VALUE_TO_NUMBER(cx, rval, d);                                         \
+        if (cs->format & JOF_POST) {                                          \
+            rtmp = rval;                                                      \
+            if (!JSVAL_IS_NUMBER(rtmp)) {                                     \
+                ok = js_NewNumberValue(cx, d, &rtmp);                         \
+                if (!ok)                                                      \
+                    goto out;                                                 \
+                *vp = rtmp;                                                   \
+            }                                                                 \
+            (cs->format & JOF_INC) ? d++ : d--;                               \
+            ok = js_NewNumberValue(cx, d, &rval);                             \
+        } else {                                                              \
+            (cs->format & JOF_INC) ? ++d : --d;                               \
+            ok = js_NewNumberValue(cx, d, &rval);                             \
+            rtmp = rval;                                                      \
+        }                                                                     \
+        if (!ok)                                                              \
+            goto out;                                                         \
+    JS_END_MACRO
+
+                if (cs->format & JOF_POST) {
+                    /*
+                     * We must push early to protect the postfix increment
+                     * or decrement result, if converted to a jsdouble from
+                     * a non-number value, from GC nesting in the setter.
+                     */
+                    vp = sp++;
+                    SAVE_SP(fp);
+                    --i;
+                }
+#ifdef __GNUC__
+                else vp = NULL; /* suppress bogus gcc warnings */
+#endif
+
+                NONINT_INCREMENT_OP_MIDDLE();
+            }
+
+            fp->flags |= JSFRAME_ASSIGNING;
+            CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));
+            fp->flags &= ~JSFRAME_ASSIGNING;
+            if (!ok)
+                goto out;
+            sp += i;
+            PUSH_OPND(rtmp);
+            break;
+
+/*
+ * NB: This macro can't use JS_BEGIN_MACRO/JS_END_MACRO around its body because
+ * it must break from the switch case that calls it, not from the do...while(0)
+ * loop created by the JS_BEGIN/END_MACRO brackets.
+ */
+#define FAST_INCREMENT_OP(SLOT,COUNT,BASE,PRE,OP,MINMAX)                      \
+    slot = SLOT;                                                              \
+    JS_ASSERT(slot < fp->fun->COUNT);                                         \
+    vp = fp->BASE + slot;                                                     \
+    rval = *vp;                                                               \
+    if (JSVAL_IS_INT(rval) &&                                                 \
+        rval != INT_TO_JSVAL(JSVAL_INT_##MINMAX)) {                           \
+        PRE = rval;                                                           \
+        rval OP 2;                                                            \
+        *vp = rval;                                                           \
+        PUSH_OPND(PRE);                                                       \
+        break;                                                                \
+    }                                                                         \
+    goto do_nonint_fast_incop;
+
+          case JSOP_INCARG:
+            FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rval, +=, MAX);
+          case JSOP_DECARG:
+            FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rval, -=, MIN);
+          case JSOP_ARGINC:
+            FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rtmp, +=, MAX);
+          case JSOP_ARGDEC:
+            FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rtmp, -=, MIN);
+
+          case JSOP_INCVAR:
+            FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rval, +=, MAX);
+          case JSOP_DECVAR:
+            FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rval, -=, MIN);
+          case JSOP_VARINC:
+            FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rtmp, +=, MAX);
+          case JSOP_VARDEC:
+            FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rtmp, -=, MIN);
+
+#undef FAST_INCREMENT_OP
+
+          do_nonint_fast_incop:
+            NONINT_INCREMENT_OP_MIDDLE();
+            *vp = rval;
+            PUSH_OPND(rtmp);
+            break;
+
+#define FAST_GLOBAL_INCREMENT_OP(SLOWOP,PRE,OP,MINMAX)                        \
+    slot = GET_VARNO(pc);                                                     \
+    JS_ASSERT(slot < fp->nvars);                                              \
+    lval = fp->vars[slot];                                                    \
+    if (JSVAL_IS_NULL(lval)) {                                                \
+        op = SLOWOP;                                                          \
+        goto do_op;                                                           \
+    }                                                                         \
+    slot = JSVAL_TO_INT(lval);                                                \
+    obj = fp->varobj;                                                         \
+    rval = OBJ_GET_SLOT(cx, obj, slot);                                       \
+    if (JSVAL_IS_INT(rval) &&                                                 \
+        rval != INT_TO_JSVAL(JSVAL_INT_##MINMAX)) {                           \
+        PRE = rval;                                                           \
+        rval OP 2;                                                            \
+        OBJ_SET_SLOT(cx, obj, slot, rval);                                    \
+        PUSH_OPND(PRE);                                                       \
+        break;                                                                \
+    }                                                                         \
+    goto do_nonint_fast_global_incop;
+
+          case JSOP_INCGVAR:
+            FAST_GLOBAL_INCREMENT_OP(JSOP_INCNAME, rval, +=, MAX);
+          case JSOP_DECGVAR:
+            FAST_GLOBAL_INCREMENT_OP(JSOP_DECNAME, rval, -=, MIN);
+          case JSOP_GVARINC:
+            FAST_GLOBAL_INCREMENT_OP(JSOP_NAMEINC, rtmp, +=, MAX);
+          case JSOP_GVARDEC:
+            FAST_GLOBAL_INCREMENT_OP(JSOP_NAMEDEC, rtmp, -=, MIN);
+
+#undef FAST_GLOBAL_INCREMENT_OP
+
+          do_nonint_fast_global_incop:
+          {
+            const JSCodeSpec *cs = &js_CodeSpec[op];
+
+            vp = sp++;
+            SAVE_SP(fp);
+            NONINT_INCREMENT_OP_MIDDLE();
+            OBJ_SET_SLOT(cx, obj, slot, rval);
+            STORE_OPND(-1, rtmp);
+            len = cs->length;
+            break;
+          }
+
+          case JSOP_GETPROP:
+            /* Get an immediate atom naming the property. */
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+            PROPERTY_OP(-1, CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval)));
+            STORE_OPND(-1, rval);
+            break;
+
+          case JSOP_SETPROP:
+            /* Pop the right-hand side into rval for OBJ_SET_PROPERTY. */
+            rval = FETCH_OPND(-1);
+
+            /* Get an immediate atom naming the property. */
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+            PROPERTY_OP(-2, CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval)));
+            sp--;
+            STORE_OPND(-1, rval);
+            obj = NULL;
+            break;
+
+          case JSOP_GETELEM:
+            ELEMENT_OP(-1, CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval)));
+            sp--;
+            STORE_OPND(-1, rval);
+            break;
+
+          case JSOP_SETELEM:
+            rval = FETCH_OPND(-1);
+            ELEMENT_OP(-2, CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval)));
+            sp -= 2;
+            STORE_OPND(-1, rval);
+            obj = NULL;
+            break;
+
+          case JSOP_ENUMELEM:
+            /* Funky: the value to set is under the [obj, id] pair. */
+            FETCH_ELEMENT_ID(-1, id);
+            FETCH_OBJECT(cx, -2, lval, obj);
+            CHECK_ELEMENT_ID(obj, id);
+            rval = FETCH_OPND(-3);
+            SAVE_SP(fp);
+            ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);
+            if (!ok)
+                goto out;
+            sp -= 3;
+            break;
+
+/*
+ * LAZY_ARGS_THISP allows the JSOP_ARGSUB bytecode to defer creation of the
+ * arguments object until it is truly needed.  JSOP_ARGSUB optimizes away
+ * arguments objects when the only uses of the 'arguments' parameter are to
+ * fetch individual actual parameters.  But if such a use were then invoked,
+ * e.g., arguments[i](), the 'this' parameter would and must bind to the
+ * caller's arguments object.  So JSOP_ARGSUB sets obj to LAZY_ARGS_THISP.
+ */
+#define LAZY_ARGS_THISP ((JSObject *) 1)
+
+          case JSOP_PUSHOBJ:
+            if (obj == LAZY_ARGS_THISP && !(obj = js_GetArgsObject(cx, fp))) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            PUSH_OPND(OBJECT_TO_JSVAL(obj));
+            break;
+
+          case JSOP_CALL:
+          case JSOP_EVAL:
+            argc = GET_ARGC(pc);
+            vp = sp - (argc + 2);
+            lval = *vp;
+            SAVE_SP(fp);
+
+            if (JSVAL_IS_FUNCTION(cx, lval) &&
+                (obj = JSVAL_TO_OBJECT(lval),
+                 fun = (JSFunction *) JS_GetPrivate(cx, obj),
+                 fun->interpreted &&
+                 !(fun->flags & (JSFUN_HEAVYWEIGHT | JSFUN_BOUND_METHOD)) &&
+                 argc >= (uintN)(fun->nargs + fun->extra)))
+          /* inline_call: */
+            {
+                uintN nframeslots, nvars;
+                void *newmark;
+                JSInlineFrame *newifp;
+                JSInterpreterHook hook;
+
+                /* Restrict recursion of lightweight functions. */
+                if (inlineCallCount == MAX_INLINE_CALL_COUNT) {
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                         JSMSG_OVER_RECURSED);
+                    ok = JS_FALSE;
+                    goto out;
+                }
+
+#if JS_HAS_JIT
+                /* ZZZbe should do this only if interpreted often enough. */
+                ok = jsjit_Compile(cx, fun);
+                if (!ok)
+                    goto out;
+#endif
+
+                /* Compute the number of stack slots needed for fun. */
+                nframeslots = (sizeof(JSInlineFrame) + sizeof(jsval) - 1)
+                              / sizeof(jsval);
+                nvars = fun->nvars;
+                script = fun->u.script;
+                depth = (jsint) script->depth;
+
+                /* Allocate the frame and space for vars and operands. */
+                newsp = js_AllocRawStack(cx, nframeslots + nvars + 2 * depth,
+                                         &newmark);
+                if (!newsp) {
+                    ok = JS_FALSE;
+                    goto bad_inline_call;
+                }
+                newifp = (JSInlineFrame *) newsp;
+                newsp += nframeslots;
+
+                /* Initialize the stack frame. */
+                memset(newifp, 0, sizeof(JSInlineFrame));
+                newifp->frame.script = script;
+                newifp->frame.fun = fun;
+                newifp->frame.argc = argc;
+                newifp->frame.argv = vp + 2;
+                newifp->frame.rval = JSVAL_VOID;
+                newifp->frame.nvars = nvars;
+                newifp->frame.vars = newsp;
+                newifp->frame.down = fp;
+                newifp->frame.scopeChain = OBJ_GET_PARENT(cx, obj);
+                newifp->mark = newmark;
+
+                /* Compute the 'this' parameter now that argv is set. */
+                ok = js_ComputeThis(cx, JSVAL_TO_OBJECT(vp[1]), &newifp->frame);
+                if (!ok) {
+                    js_FreeRawStack(cx, newmark);
+                    goto bad_inline_call;
+                }
+#ifdef DUMP_CALL_TABLE
+                LogCall(cx, *vp, argc, vp + 2);
+#endif
+
+                /* Push void to initialize local variables. */
+                sp = newsp;
+                while (nvars--)
+                    PUSH(JSVAL_VOID);
+                sp += depth;
+                newifp->frame.spbase = sp;
+                SAVE_SP(&newifp->frame);
+
+                /* Call the debugger hook if present. */
+                hook = cx->runtime->callHook;
+                if (hook) {
+                    newifp->hookData = hook(cx, &newifp->frame, JS_TRUE, 0,
+                                            cx->runtime->callHookData);
+                    LOAD_INTERRUPT_HANDLER(rt);
+                }
+
+                /* Switch to new version if currentVersion wasn't overridden. */
+                newifp->callerVersion = cx->version;
+                if (cx->version == currentVersion) {
+                    currentVersion = script->version;
+                    if (currentVersion != cx->version)
+                        js_SetVersion(cx, currentVersion);
+                }
+
+                /* Push the frame and set interpreter registers. */
+                cx->fp = fp = &newifp->frame;
+                pc = script->code;
+                endpc = pc + script->length;
+                inlineCallCount++;
+                JS_RUNTIME_METER(rt, inlineCalls);
+                continue;
+
+              bad_inline_call:
+                script = fp->script;
+                depth = (jsint) script->depth;
+                goto out;
+            }
+
+            ok = js_Invoke(cx, argc, 0);
+            RESTORE_SP(fp);
+            LOAD_BRANCH_CALLBACK(cx);
+            LOAD_INTERRUPT_HANDLER(rt);
+            if (!ok)
+                goto out;
+            JS_RUNTIME_METER(rt, nonInlineCalls);
+#if JS_HAS_LVALUE_RETURN
+            if (cx->rval2set) {
+                /*
+                 * Sneaky: use the stack depth we didn't claim in our budget,
+                 * but that we know is there on account of [fun, this] already
+                 * having been pushed, at a minimum (if no args).  Those two
+                 * slots have been popped and [rval] has been pushed, which
+                 * leaves one more slot for rval2 before we might overflow.
+                 *
+                 * NB: rval2 must be the property identifier, and rval the
+                 * object from which to get the property.  The pair form an
+                 * ECMA "reference type", which can be used on the right- or
+                 * left-hand side of assignment ops.  Only native methods can
+                 * return reference types.  See JSOP_SETCALL just below for
+                 * the left-hand-side case.
+                 */
+                PUSH_OPND(cx->rval2);
+                cx->rval2set = JS_FALSE;
+                ELEMENT_OP(-1, ok = OBJ_GET_PROPERTY(cx, obj, id, &rval));
+                sp--;
+                STORE_OPND(-1, rval);
+            }
+#endif
+            obj = NULL;
+            break;
+
+#if JS_HAS_LVALUE_RETURN
+          case JSOP_SETCALL:
+            argc = GET_ARGC(pc);
+            SAVE_SP(fp);
+            ok = js_Invoke(cx, argc, 0);
+            RESTORE_SP(fp);
+            LOAD_BRANCH_CALLBACK(cx);
+            LOAD_INTERRUPT_HANDLER(rt);
+            if (!ok)
+                goto out;
+            if (!cx->rval2set) {
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_BAD_LEFTSIDE_OF_ASS);
+                ok = JS_FALSE;
+                goto out;
+            }
+            PUSH_OPND(cx->rval2);
+            cx->rval2set = JS_FALSE;
+            obj = NULL;
+            break;
+#endif
+
+          case JSOP_NAME:
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+
+            SAVE_SP(fp);
+            ok = js_FindProperty(cx, id, &obj, &obj2, &prop);
+            if (!ok)
+                goto out;
+            if (!prop) {
+                /* Kludge to allow (typeof foo == "undefined") tests. */
+                for (pc2 = pc + len; pc2 < endpc; pc2++) {
+                    op2 = (JSOp)*pc2;
+                    if (op2 == JSOP_TYPEOF) {
+                        PUSH_OPND(JSVAL_VOID);
+                        goto advance_pc;
+                    }
+                    if (op2 != JSOP_GROUP)
+                        break;
+                }
+                goto atom_not_defined;
+            }
+
+            /* Take the slow path if prop was not found in a native object. */
+            if (!OBJ_IS_NATIVE(obj) || !OBJ_IS_NATIVE(obj2)) {
+                OBJ_DROP_PROPERTY(cx, obj2, prop);
+                ok = OBJ_GET_PROPERTY(cx, obj, id, &rval);
+                if (!ok)
+                    goto out;
+                PUSH_OPND(rval);
+                break;
+            }
+
+            /* Get and push the obj[id] property's value. */
+            sprop = (JSScopeProperty *)prop;
+            slot = (uintN)sprop->slot;
+            rval = (slot != SPROP_INVALID_SLOT)
+                   ? LOCKED_OBJ_GET_SLOT(obj2, slot)
+                   : JSVAL_VOID;
+            JS_UNLOCK_OBJ(cx, obj2);
+            ok = SPROP_GET(cx, sprop, obj, obj2, &rval);
+            JS_LOCK_OBJ(cx, obj2);
+            if (!ok) {
+                OBJ_DROP_PROPERTY(cx, obj2, prop);
+                goto out;
+            }
+            if (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2)))
+                LOCKED_OBJ_SET_SLOT(obj2, slot, rval);
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+            PUSH_OPND(rval);
+            break;
+
+          case JSOP_UINT16:
+            i = (jsint) GET_ATOM_INDEX(pc);
+            rval = INT_TO_JSVAL(i);
+            PUSH_OPND(rval);
+            obj = NULL;
+            break;
+
+          case JSOP_UINT24:
+            i = (jsint) GET_LITERAL_INDEX(pc);
+            rval = INT_TO_JSVAL(i);
+            PUSH_OPND(rval);
+            break;
+
+          case JSOP_LITERAL:
+            atomIndex = GET_LITERAL_INDEX(pc);
+            atom = js_GetAtom(cx, &script->atomMap, atomIndex);
+            PUSH_OPND(ATOM_KEY(atom));
+            obj = NULL;
+            break;
+
+          case JSOP_FINDNAME:
+            atomIndex = GET_LITERAL_INDEX(pc);
+            atom = js_GetAtom(cx, &script->atomMap, atomIndex);
+            SAVE_SP(fp);
+            obj = js_FindIdentifierBase(cx, ATOM_TO_JSID(atom));
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            PUSH_OPND(OBJECT_TO_JSVAL(obj));
+            PUSH_OPND(ATOM_KEY(atom));
+            break;
+
+          case JSOP_LITOPX:
+            atomIndex = GET_LITERAL_INDEX(pc);
+            op = pc[1 + LITERAL_INDEX_LEN];
+            switch (op) {
+              case JSOP_ANONFUNOBJ:   goto do_JSOP_ANONFUNOBJ;
+              case JSOP_BINDNAME:     goto do_JSOP_BINDNAME;
+              case JSOP_CLOSURE:      goto do_JSOP_CLOSURE;
+              case JSOP_DEFCONST:     goto do_JSOP_DEFCONST;
+              case JSOP_DEFFUN:       goto do_JSOP_DEFFUN;
+              case JSOP_DEFLOCALFUN:  goto do_JSOP_DEFLOCALFUN;
+              case JSOP_DEFVAR:       goto do_JSOP_DEFVAR;
+#if JS_HAS_EXPORT_IMPORT
+              case JSOP_EXPORTNAME:   goto do_JSOP_EXPORTNAME;
+#endif
+#if JS_HAS_XML_SUPPORT
+              case JSOP_GETMETHOD:    goto do_JSOP_GETMETHOD;
+              case JSOP_SETMETHOD:    goto do_JSOP_SETMETHOD;
+#endif
+              case JSOP_INITCATCHVAR: goto do_JSOP_INITCATCHVAR;
+              case JSOP_NAMEDFUNOBJ:  goto do_JSOP_NAMEDFUNOBJ;
+              case JSOP_NUMBER:       goto do_JSOP_NUMBER;
+              case JSOP_OBJECT:       goto do_JSOP_OBJECT;
+#if JS_HAS_XML_SUPPORT
+              case JSOP_QNAMECONST:   goto do_JSOP_QNAMECONST;
+              case JSOP_QNAMEPART:    goto do_JSOP_QNAMEPART;
+#endif
+              case JSOP_REGEXP:       goto do_JSOP_REGEXP;
+              case JSOP_SETCONST:     goto do_JSOP_SETCONST;
+              case JSOP_STRING:       goto do_JSOP_STRING;
+#if JS_HAS_XML_SUPPORT
+              case JSOP_XMLCDATA:     goto do_JSOP_XMLCDATA;
+              case JSOP_XMLCOMMENT:   goto do_JSOP_XMLCOMMENT;
+              case JSOP_XMLOBJECT:    goto do_JSOP_XMLOBJECT;
+              case JSOP_XMLPI:        goto do_JSOP_XMLPI;
+#endif
+              default:                JS_ASSERT(0);
+            }
+            /* NOTREACHED */
+            break;
+
+          case JSOP_NUMBER:
+          case JSOP_STRING:
+          case JSOP_OBJECT:
+            atomIndex = GET_ATOM_INDEX(pc);
+
+          do_JSOP_NUMBER:
+          do_JSOP_STRING:
+          do_JSOP_OBJECT:
+            atom = js_GetAtom(cx, &script->atomMap, atomIndex);
+            PUSH_OPND(ATOM_KEY(atom));
+            obj = NULL;
+            break;
+
+          BEGIN_LITOPX_CASE(JSOP_REGEXP, 0)
+          {
+            JSRegExp *re;
+            JSObject *funobj;
+
+            /*
+             * Push a regexp object for the atom mapped by the bytecode at pc,
+             * cloning the literal's regexp object if necessary, to simulate in
+             * the pre-compile/execute-later case what ECMA specifies for the
+             * compile-and-go case: that scanning each regexp literal creates
+             * a single corresponding RegExp object.
+             *
+             * To support pre-compilation transparently, we must handle the
+             * case where a regexp object literal is used in a different global
+             * at execution time from the global with which it was scanned at
+             * compile time.  We do this by re-wrapping the JSRegExp private
+             * data struct with a cloned object having the right prototype and
+             * parent, and having its own lastIndex property value storage.
+             *
+             * Unlike JSOP_DEFFUN and other prolog bytecodes that may clone
+             * literal objects, we don't want to pay a script prolog execution
+             * price for all regexp literals in a script (many may not be used
+             * by a particular execution of that script, depending on control
+             * flow), so we initialize lazily here.
+             *
+             * XXX This code is specific to regular expression objects.  If we
+             * need a similar op for other kinds of object literals, we should
+             * push cloning down under JSObjectOps and reuse code here.
+             */
+            JS_ASSERT(ATOM_IS_OBJECT(atom));
+            obj = ATOM_TO_OBJECT(atom);
+            JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_RegExpClass);
+
+            re = (JSRegExp *) JS_GetPrivate(cx, obj);
+            slot = re->cloneIndex;
+            if (fp->fun) {
+                /*
+                 * We're in function code, not global or eval code (in eval
+                 * code, JSOP_REGEXP is never emitted).  The code generator
+                 * recorded in fp->fun->nregexps the number of re->cloneIndex
+                 * slots that it reserved in the cloned funobj.
+                 */
+                funobj = JSVAL_TO_OBJECT(fp->argv[-2]);
+                slot += JSCLASS_RESERVED_SLOTS(&js_FunctionClass);
+                if (!JS_GetReservedSlot(cx, funobj, slot, &rval))
+                    return JS_FALSE;
+                if (JSVAL_IS_VOID(rval))
+                    rval = JSVAL_NULL;
+            } else {
+                /*
+                 * We're in global code.  The code generator already arranged
+                 * via script->numGlobalVars to reserve a global variable slot
+                 * at cloneIndex.  All global variable slots are initialized
+                 * to null, not void, for faster testing in JSOP_*GVAR cases.
+                 */
+                rval = fp->vars[slot];
+#ifdef __GNUC__
+                funobj = NULL;  /* suppress bogus gcc warnings */
+#endif
+            }
+
+            if (JSVAL_IS_NULL(rval)) {
+                /* Compute the current global object in obj2. */
+                obj2 = fp->scopeChain;
+                while ((parent = OBJ_GET_PARENT(cx, obj2)) != NULL)
+                    obj2 = parent;
+
+                /*
+                 * We must home sp here, because either js_CloneRegExpObject
+                 * or JS_SetReservedSlot could nest a last-ditch GC.  We home
+                 * pc as well, in case js_CloneRegExpObject has to lookup the
+                 * "RegExp" class in the global object, which could entail a
+                 * JSNewResolveOp call.
+                 */
+                SAVE_SP(fp);
+
+                /*
+                 * If obj's parent is not obj2, we must clone obj so that it
+                 * has the right parent, and therefore, the right prototype.
+                 *
+                 * Yes, this means we assume that the correct RegExp.prototype
+                 * to which regexp instances (including literals) delegate can
+                 * be distinguished solely by the instance's parent, which was
+                 * set to the parent of the RegExp constructor function object
+                 * when the instance was created.  In other words,
+                 *
+                 *   (/x/.__parent__ == RegExp.__parent__) implies
+                 *   (/x/.__proto__ == RegExp.prototype)
+                 *
+                 * (unless you assign a different object to RegExp.prototype
+                 * at runtime, in which case, ECMA doesn't specify operation,
+                 * and you get what you deserve).
+                 *
+                 * This same coupling between instance parent and constructor
+                 * parent turns up everywhere (see jsobj.c's FindConstructor,
+                 * js_ConstructObject, and js_NewObject).  It's fundamental to
+                 * the design of the language when you consider multiple global
+                 * objects and separate compilation and execution, even though
+                 * it is not specified fully in ECMA.
+                 */
+                if (OBJ_GET_PARENT(cx, obj) != obj2) {
+                    obj = js_CloneRegExpObject(cx, obj, obj2);
+                    if (!obj) {
+                        ok = JS_FALSE;
+                        goto out;
+                    }
+                }
+                rval = OBJECT_TO_JSVAL(obj);
+
+                /* Store the regexp object value in its cloneIndex slot. */
+                if (fp->fun) {
+                    if (!JS_SetReservedSlot(cx, funobj, slot, rval))
+                        return JS_FALSE;
+                } else {
+                    fp->vars[slot] = rval;
+                }
+            }
+
+            PUSH_OPND(rval);
+            obj = NULL;
+          }
+          END_LITOPX_CASE
+
+          case JSOP_ZERO:
+            PUSH_OPND(JSVAL_ZERO);
+            obj = NULL;
+            break;
+
+          case JSOP_ONE:
+            PUSH_OPND(JSVAL_ONE);
+            obj = NULL;
+            break;
+
+          case JSOP_NULL:
+            PUSH_OPND(JSVAL_NULL);
+            obj = NULL;
+            break;
+
+          case JSOP_THIS:
+            obj = fp->thisp;
+            clasp = OBJ_GET_CLASS(cx, obj);
+            if (clasp->flags & JSCLASS_IS_EXTENDED) {
+                JSExtendedClass *xclasp;
+
+                xclasp = (JSExtendedClass *) clasp;
+                if (xclasp->outerObject) {
+                    obj = xclasp->outerObject(cx, obj);
+                    if (!obj) {
+                        ok = JS_FALSE;
+                        goto out;
+                    }
+                }
+            }
+
+            PUSH_OPND(OBJECT_TO_JSVAL(obj));
+            obj = NULL;
+            break;
+
+          case JSOP_FALSE:
+            PUSH_OPND(JSVAL_FALSE);
+            obj = NULL;
+            break;
+
+          case JSOP_TRUE:
+            PUSH_OPND(JSVAL_TRUE);
+            obj = NULL;
+            break;
+
+#if JS_HAS_SWITCH_STATEMENT
+          case JSOP_TABLESWITCH:
+            pc2 = pc;
+            len = GET_JUMP_OFFSET(pc2);
+
+            /*
+             * ECMAv2 forbids conversion of discriminant, so we will skip to
+             * the default case if the discriminant isn't already an int jsval.
+             * (This opcode is emitted only for dense jsint-domain switches.)
+             */
+            if ((cx->version & JSVERSION_MASK) == JSVERSION_DEFAULT ||
+                (cx->version & JSVERSION_MASK) >= JSVERSION_1_4) {
+                rval = POP_OPND();
+                if (!JSVAL_IS_INT(rval))
+                    break;
+                i = JSVAL_TO_INT(rval);
+            } else {
+                FETCH_INT(cx, -1, i);
+                sp--;
+            }
+
+            pc2 += JUMP_OFFSET_LEN;
+            low = GET_JUMP_OFFSET(pc2);
+            pc2 += JUMP_OFFSET_LEN;
+            high = GET_JUMP_OFFSET(pc2);
+
+            i -= low;
+            if ((jsuint)i < (jsuint)(high - low + 1)) {
+                pc2 += JUMP_OFFSET_LEN + JUMP_OFFSET_LEN * i;
+                off = (jsint) GET_JUMP_OFFSET(pc2);
+                if (off)
+                    len = off;
+            }
+            break;
+
+          case JSOP_LOOKUPSWITCH:
+            lval = POP_OPND();
+            pc2 = pc;
+            len = GET_JUMP_OFFSET(pc2);
+
+            if (!JSVAL_IS_NUMBER(lval) &&
+                !JSVAL_IS_STRING(lval) &&
+                !JSVAL_IS_BOOLEAN(lval)) {
+                goto advance_pc;
+            }
+
+            pc2 += JUMP_OFFSET_LEN;
+            npairs = (jsint) GET_ATOM_INDEX(pc2);
+            pc2 += ATOM_INDEX_LEN;
+
+#define SEARCH_PAIRS(MATCH_CODE)                                              \
+    while (npairs) {                                                          \
+        atom = GET_ATOM(cx, script, pc2);                                     \
+        rval = ATOM_KEY(atom);                                                \
+        MATCH_CODE                                                            \
+        if (match) {                                                          \
+            pc2 += ATOM_INDEX_LEN;                                            \
+            len = GET_JUMP_OFFSET(pc2);                                       \
+            goto advance_pc;                                                  \
+        }                                                                     \
+        pc2 += ATOM_INDEX_LEN + JUMP_OFFSET_LEN;                              \
+        npairs--;                                                             \
+    }
+            if (JSVAL_IS_STRING(lval)) {
+                str  = JSVAL_TO_STRING(lval);
+                SEARCH_PAIRS(
+                    match = (JSVAL_IS_STRING(rval) &&
+                             ((str2 = JSVAL_TO_STRING(rval)) == str ||
+                              !js_CompareStrings(str2, str)));
+                )
+            } else if (JSVAL_IS_DOUBLE(lval)) {
+                d = *JSVAL_TO_DOUBLE(lval);
+                SEARCH_PAIRS(
+                    match = (JSVAL_IS_DOUBLE(rval) &&
+                             *JSVAL_TO_DOUBLE(rval) == d);
+                )
+            } else {
+                SEARCH_PAIRS(
+                    match = (lval == rval);
+                )
+            }
+#undef SEARCH_PAIRS
+            break;
+
+          case JSOP_TABLESWITCHX:
+            pc2 = pc;
+            len = GET_JUMPX_OFFSET(pc2);
+
+            /*
+             * ECMAv2 forbids conversion of discriminant, so we will skip to
+             * the default case if the discriminant isn't already an int jsval.
+             * (This opcode is emitted only for dense jsint-domain switches.)
+             */
+            if ((cx->version & JSVERSION_MASK) == JSVERSION_DEFAULT ||
+                (cx->version & JSVERSION_MASK) >= JSVERSION_1_4) {
+                rval = POP_OPND();
+                if (!JSVAL_IS_INT(rval))
+                    break;
+                i = JSVAL_TO_INT(rval);
+            } else {
+                FETCH_INT(cx, -1, i);
+                sp--;
+            }
+
+            pc2 += JUMPX_OFFSET_LEN;
+            low = GET_JUMP_OFFSET(pc2);
+            pc2 += JUMP_OFFSET_LEN;
+            high = GET_JUMP_OFFSET(pc2);
+
+            i -= low;
+            if ((jsuint)i < (jsuint)(high - low + 1)) {
+                pc2 += JUMP_OFFSET_LEN + JUMPX_OFFSET_LEN * i;
+                off = (jsint) GET_JUMPX_OFFSET(pc2);
+                if (off)
+                    len = off;
+            }
+            break;
+
+          case JSOP_LOOKUPSWITCHX:
+            lval = POP_OPND();
+            pc2 = pc;
+            len = GET_JUMPX_OFFSET(pc2);
+
+            if (!JSVAL_IS_NUMBER(lval) &&
+                !JSVAL_IS_STRING(lval) &&
+                !JSVAL_IS_BOOLEAN(lval)) {
+                goto advance_pc;
+            }
+
+            pc2 += JUMPX_OFFSET_LEN;
+            npairs = (jsint) GET_ATOM_INDEX(pc2);
+            pc2 += ATOM_INDEX_LEN;
+
+#define SEARCH_EXTENDED_PAIRS(MATCH_CODE)                                     \
+    while (npairs) {                                                          \
+        atom = GET_ATOM(cx, script, pc2);                                     \
+        rval = ATOM_KEY(atom);                                                \
+        MATCH_CODE                                                            \
+        if (match) {                                                          \
+            pc2 += ATOM_INDEX_LEN;                                            \
+            len = GET_JUMPX_OFFSET(pc2);                                      \
+            goto advance_pc;                                                  \
+        }                                                                     \
+        pc2 += ATOM_INDEX_LEN + JUMPX_OFFSET_LEN;                             \
+        npairs--;                                                             \
+    }
+            if (JSVAL_IS_STRING(lval)) {
+                str  = JSVAL_TO_STRING(lval);
+                SEARCH_EXTENDED_PAIRS(
+                    match = (JSVAL_IS_STRING(rval) &&
+                             ((str2 = JSVAL_TO_STRING(rval)) == str ||
+                              !js_CompareStrings(str2, str)));
+                )
+            } else if (JSVAL_IS_DOUBLE(lval)) {
+                d = *JSVAL_TO_DOUBLE(lval);
+                SEARCH_EXTENDED_PAIRS(
+                    match = (JSVAL_IS_DOUBLE(rval) &&
+                             *JSVAL_TO_DOUBLE(rval) == d);
+                )
+            } else {
+                SEARCH_EXTENDED_PAIRS(
+                    match = (lval == rval);
+                )
+            }
+#undef SEARCH_EXTENDED_PAIRS
+            break;
+
+          case JSOP_CONDSWITCH:
+            break;
+
+#endif /* JS_HAS_SWITCH_STATEMENT */
+
+#if JS_HAS_EXPORT_IMPORT
+          case JSOP_EXPORTALL:
+            SAVE_SP(fp);
+            obj = fp->varobj;
+            ida = JS_Enumerate(cx, obj);
+            if (!ida) {
+                ok = JS_FALSE;
+            } else {
+                for (i = 0, j = ida->length; i < j; i++) {
+                    id = ida->vector[i];
+                    ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
+                    if (!ok)
+                        break;
+                    if (!prop)
+                        continue;
+                    ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs);
+                    if (ok) {
+                        attrs |= JSPROP_EXPORTED;
+                        ok = OBJ_SET_ATTRIBUTES(cx, obj, id, prop, &attrs);
+                    }
+                    OBJ_DROP_PROPERTY(cx, obj2, prop);
+                    if (!ok)
+                        break;
+                }
+                JS_DestroyIdArray(cx, ida);
+            }
+            break;
+
+          BEGIN_LITOPX_CASE(JSOP_EXPORTNAME, 0)
+            id   = ATOM_TO_JSID(atom);
+            obj  = fp->varobj;
+            SAVE_SP(fp);
+            ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
+            if (!ok)
+                goto out;
+            if (!prop) {
+                ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, NULL,
+                                         JSPROP_EXPORTED, NULL);
+            } else {
+                ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs);
+                if (ok) {
+                    attrs |= JSPROP_EXPORTED;
+                    ok = OBJ_SET_ATTRIBUTES(cx, obj, id, prop, &attrs);
+                }
+                OBJ_DROP_PROPERTY(cx, obj2, prop);
+            }
+            if (!ok)
+                goto out;
+          END_LITOPX_CASE
+
+          case JSOP_IMPORTALL:
+            id = (jsid) JSVAL_VOID;
+            PROPERTY_OP(-1, ok = ImportProperty(cx, obj, id));
+            sp--;
+            break;
+
+          case JSOP_IMPORTPROP:
+            /* Get an immediate atom naming the property. */
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+            PROPERTY_OP(-1, ok = ImportProperty(cx, obj, id));
+            sp--;
+            break;
+
+          case JSOP_IMPORTELEM:
+            ELEMENT_OP(-1, ok = ImportProperty(cx, obj, id));
+            sp -= 2;
+            break;
+#endif /* JS_HAS_EXPORT_IMPORT */
+
+          case JSOP_TRAP:
+            switch (JS_HandleTrap(cx, script, pc, &rval)) {
+              case JSTRAP_ERROR:
+                ok = JS_FALSE;
+                goto out;
+              case JSTRAP_CONTINUE:
+                JS_ASSERT(JSVAL_IS_INT(rval));
+                op = (JSOp) JSVAL_TO_INT(rval);
+                JS_ASSERT((uintN)op < (uintN)JSOP_LIMIT);
+                LOAD_INTERRUPT_HANDLER(rt);
+                goto do_op;
+              case JSTRAP_RETURN:
+                fp->rval = rval;
+                goto out;
+#if JS_HAS_EXCEPTIONS
+              case JSTRAP_THROW:
+                cx->throwing = JS_TRUE;
+                cx->exception = rval;
+                ok = JS_FALSE;
+                goto out;
+#endif /* JS_HAS_EXCEPTIONS */
+              default:;
+            }
+            LOAD_INTERRUPT_HANDLER(rt);
+            break;
+
+          case JSOP_ARGUMENTS:
+            SAVE_SP(fp);
+            ok = js_GetArgsValue(cx, fp, &rval);
+            if (!ok)
+                goto out;
+            PUSH_OPND(rval);
+            break;
+
+          case JSOP_ARGSUB:
+            id = INT_TO_JSID(GET_ARGNO(pc));
+            SAVE_SP(fp);
+            ok = js_GetArgsProperty(cx, fp, id, &obj, &rval);
+            if (!ok)
+                goto out;
+            if (!obj) {
+                /*
+                 * If arguments was not overridden by eval('arguments = ...'),
+                 * set obj to the magic cookie respected by JSOP_PUSHOBJ, just
+                 * in case this bytecode is part of an 'arguments[i](j, k)' or
+                 * similar such invocation sequence, where the function that
+                 * is invoked expects its 'this' parameter to be the caller's
+                 * arguments object.
+                 */
+                obj = LAZY_ARGS_THISP;
+            }
+            PUSH_OPND(rval);
+            break;
+
+#undef LAZY_ARGS_THISP
+
+          case JSOP_ARGCNT:
+            id = ATOM_TO_JSID(rt->atomState.lengthAtom);
+            SAVE_SP(fp);
+            ok = js_GetArgsProperty(cx, fp, id, &obj, &rval);
+            if (!ok)
+                goto out;
+            PUSH_OPND(rval);
+            break;
+
+          case JSOP_GETARG:
+            slot = GET_ARGNO(pc);
+            JS_ASSERT(slot < fp->fun->nargs);
+            PUSH_OPND(fp->argv[slot]);
+            obj = NULL;
+            break;
+
+          case JSOP_SETARG:
+            slot = GET_ARGNO(pc);
+            JS_ASSERT(slot < fp->fun->nargs);
+            vp = &fp->argv[slot];
+            GC_POKE(cx, *vp);
+            *vp = FETCH_OPND(-1);
+            obj = NULL;
+            break;
+
+          case JSOP_GETVAR:
+            slot = GET_VARNO(pc);
+            JS_ASSERT(slot < fp->fun->nvars);
+            PUSH_OPND(fp->vars[slot]);
+            obj = NULL;
+            break;
+
+          case JSOP_SETVAR:
+            slot = GET_VARNO(pc);
+            JS_ASSERT(slot < fp->fun->nvars);
+            vp = &fp->vars[slot];
+            GC_POKE(cx, *vp);
+            *vp = FETCH_OPND(-1);
+            obj = NULL;
+            break;
+
+          case JSOP_GETGVAR:
+            slot = GET_VARNO(pc);
+            JS_ASSERT(slot < fp->nvars);
+            lval = fp->vars[slot];
+            if (JSVAL_IS_NULL(lval)) {
+                op = JSOP_NAME;
+                goto do_op;
+            }
+            slot = JSVAL_TO_INT(lval);
+            obj = fp->varobj;
+            rval = OBJ_GET_SLOT(cx, obj, slot);
+            PUSH_OPND(rval);
+            break;
+
+          case JSOP_SETGVAR:
+            slot = GET_VARNO(pc);
+            JS_ASSERT(slot < fp->nvars);
+            rval = FETCH_OPND(-1);
+            lval = fp->vars[slot];
+            obj = fp->varobj;
+            if (JSVAL_IS_NULL(lval)) {
+                /*
+                 * Inline-clone and specialize JSOP_SETNAME code here because
+                 * JSOP_SETGVAR has arity 1: [rval], not arity 2: [obj, rval]
+                 * as JSOP_SETNAME does, where [obj] is due to JSOP_BINDNAME.
+                 */
+                atom = GET_ATOM(cx, script, pc);
+                id = ATOM_TO_JSID(atom);
+                SAVE_SP(fp);
+                CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));
+                if (!ok)
+                    goto out;
+                STORE_OPND(-1, rval);
+            } else {
+                slot = JSVAL_TO_INT(lval);
+                GC_POKE(cx, obj->slots[slot]);
+                OBJ_SET_SLOT(cx, obj, slot, rval);
+            }
+            obj = NULL;
+            break;
+
+          case JSOP_DEFCONST:
+          case JSOP_DEFVAR:
+            atomIndex = GET_ATOM_INDEX(pc);
+
+          do_JSOP_DEFCONST:
+          do_JSOP_DEFVAR:
+            atom = js_GetAtom(cx, &script->atomMap, atomIndex);
+            obj = fp->varobj;
+            attrs = JSPROP_ENUMERATE;
+            if (!(fp->flags & JSFRAME_EVAL))
+                attrs |= JSPROP_PERMANENT;
+            if (op == JSOP_DEFCONST)
+                attrs |= JSPROP_READONLY;
+
+            /* Lookup id in order to check for redeclaration problems. */
+            id = ATOM_TO_JSID(atom);
+            SAVE_SP(fp);
+            ok = js_CheckRedeclaration(cx, obj, id, attrs, &obj2, &prop);
+            if (!ok)
+                goto out;
+
+            /* Bind a variable only if it's not yet defined. */
+            if (!prop) {
+                ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, NULL,
+                                         attrs, &prop);
+                if (!ok)
+                    goto out;
+                JS_ASSERT(prop);
+                obj2 = obj;
+            }
+
+            /*
+             * Try to optimize a property we either just created, or found
+             * directly in the global object, that is permanent, has a slot,
+             * and has stub getter and setter, into a "fast global" accessed
+             * by the JSOP_*GVAR opcodes.
+             */
+            if (atomIndex < script->numGlobalVars &&
+                (attrs & JSPROP_PERMANENT) &&
+                obj2 == obj &&
+                OBJ_IS_NATIVE(obj)) {
+                sprop = (JSScopeProperty *) prop;
+                if (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj)) &&
+                    SPROP_HAS_STUB_GETTER(sprop) &&
+                    SPROP_HAS_STUB_SETTER(sprop)) {
+                    /*
+                     * Fast globals use fp->vars to map the global name's
+                     * atomIndex to the permanent fp->varobj slot number,
+                     * tagged as a jsval.  The atomIndex for the global's
+                     * name literal is identical to its fp->vars index.
+                     */
+                    fp->vars[atomIndex] = INT_TO_JSVAL(sprop->slot);
+                }
+            }
+
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+            break;
+
+          BEGIN_LITOPX_CASE(JSOP_DEFFUN, 0)
+          {
+            uintN flags;
+
+            atomIndex = GET_ATOM_INDEX(pc);
+            atom = js_GetAtom(cx, &script->atomMap, atomIndex);
+            obj = ATOM_TO_OBJECT(atom);
+            fun = (JSFunction *) JS_GetPrivate(cx, obj);
+            id = ATOM_TO_JSID(fun->atom);
+
+            /*
+             * We must be at top-level (either outermost block that forms a
+             * function's body, or a global) scope, not inside an expression
+             * (JSOP_{ANON,NAMED}FUNOBJ) or compound statement (JSOP_CLOSURE)
+             * in the same compilation unit (ECMA Program).
+             *
+             * However, we could be in a Program being eval'd from inside a
+             * with statement, so we need to distinguish scope chain head from
+             * variables object.  Hence the obj2 vs. parent distinction below.
+             * First we make sure the function object we're defining has the
+             * right scope chain.  Then we define its name in fp->varobj.
+             *
+             * If static link is not current scope, clone fun's object to link
+             * to the current scope via parent.  This clause exists to enable
+             * sharing of compiled functions among multiple equivalent scopes,
+             * splitting the cost of compilation evenly among the scopes and
+             * amortizing it over a number of executions.  Examples include XUL
+             * scripts and event handlers shared among Mozilla chrome windows,
+             * and server-side JS user-defined functions shared among requests.
+             *
+             * NB: The Script object exposes compile and exec in the language,
+             * such that this clause introduces an incompatible change from old
+             * JS versions that supported Script.  Such a JS version supported
+             * executing a script that defined and called functions scoped by
+             * the compile-time static link, not by the exec-time scope chain.
+             *
+             * We sacrifice compatibility, breaking such scripts, in order to
+             * promote compile-cost sharing and amortizing, and because Script
+             * is not and will not be standardized.
+             */
+            obj2 = fp->scopeChain;
+            if (OBJ_GET_PARENT(cx, obj) != obj2) {
+                obj = js_CloneFunctionObject(cx, obj, obj2);
+                if (!obj) {
+                    ok = JS_FALSE;
+                    goto out;
+                }
+            }
+
+            /*
+             * Protect obj from any GC hiding below OBJ_DEFINE_PROPERTY.  All
+             * paths from here must flow through the "Restore fp->scopeChain"
+             * code below the OBJ_DEFINE_PROPERTY call.
+             */
+            fp->scopeChain = obj;
+            rval = OBJECT_TO_JSVAL(obj);
+
+            /*
+             * ECMA requires functions defined when entering Global code to be
+             * permanent, and functions defined when entering Eval code to be
+             * impermanent.
+             */
+            attrs = JSPROP_ENUMERATE;
+            if (!(fp->flags & JSFRAME_EVAL))
+                attrs |= JSPROP_PERMANENT;
+
+            /*
+             * Load function flags that are also property attributes.  Getters
+             * and setters do not need a slot, their value is stored elsewhere
+             * in the property itself, not in obj->slots.
+             */
+            flags = fun->flags & (JSFUN_GETTER | JSFUN_SETTER);
+            if (flags) {
+                attrs |= flags | JSPROP_SHARED;
+                rval = JSVAL_VOID;
+            }
+
+            /*
+             * Check for a const property of the same name -- or any kind
+             * of property if executing with the strict option.  We check
+             * here at runtime as well as at compile-time, to handle eval
+             * as well as multiple HTML script tags.
+             */
+            parent = fp->varobj;
+            SAVE_SP(fp);
+            ok = js_CheckRedeclaration(cx, parent, id, attrs, NULL, NULL);
+            if (ok) {
+                ok = OBJ_DEFINE_PROPERTY(cx, parent, id, rval,
+                                         (flags & JSFUN_GETTER)
+                                         ? (JSPropertyOp) obj
+                                         : NULL,
+                                         (flags & JSFUN_SETTER)
+                                         ? (JSPropertyOp) obj
+                                         : NULL,
+                                         attrs,
+                                         &prop);
+            }
+
+            /* Restore fp->scopeChain now that obj is defined in fp->varobj. */
+            fp->scopeChain = obj2;
+            if (!ok)
+                goto out;
+
+#if 0
+            if (attrs == (JSPROP_ENUMERATE | JSPROP_PERMANENT) &&
+                script->numGlobalVars) {
+                /*
+                 * As with JSOP_DEFVAR and JSOP_DEFCONST (above), fast globals
+                 * use fp->vars to map the global function name's atomIndex to
+                 * its permanent fp->varobj slot number, tagged as a jsval.
+                 */
+                sprop = (JSScopeProperty *) prop;
+                fp->vars[atomIndex] = INT_TO_JSVAL(sprop->slot);
+            }
+#endif
+            OBJ_DROP_PROPERTY(cx, parent, prop);
+          }
+          END_LITOPX_CASE
+
+#if JS_HAS_LEXICAL_CLOSURE
+          BEGIN_LITOPX_CASE(JSOP_DEFLOCALFUN, VARNO_LEN)
+            /*
+             * Define a local function (i.e., one nested at the top level of
+             * another function), parented by the current scope chain, and
+             * stored in a local variable slot that the compiler allocated.
+             * This is an optimization over JSOP_DEFFUN that avoids requiring
+             * a call object for the outer function's activation.
+             */
+            slot = GET_VARNO(pc);
+            atom = js_GetAtom(cx, &script->atomMap, atomIndex);
+            obj = ATOM_TO_OBJECT(atom);
+            fun = (JSFunction *) JS_GetPrivate(cx, obj);
+
+            parent = fp->scopeChain;
+            if (OBJ_GET_PARENT(cx, obj) != parent) {
+                SAVE_SP(fp);
+                obj = js_CloneFunctionObject(cx, obj, parent);
+                if (!obj) {
+                    ok = JS_FALSE;
+                    goto out;
+                }
+            }
+            fp->vars[slot] = OBJECT_TO_JSVAL(obj);
+          END_LITOPX_CASE
+
+          BEGIN_LITOPX_CASE(JSOP_ANONFUNOBJ, 0)
+            /* Push the specified function object literal. */
+            obj = ATOM_TO_OBJECT(atom);
+
+            /* If re-parenting, push a clone of the function object. */
+            parent = fp->scopeChain;
+            if (OBJ_GET_PARENT(cx, obj) != parent) {
+                SAVE_SP(fp);
+                obj = js_CloneFunctionObject(cx, obj, parent);
+                if (!obj) {
+                    ok = JS_FALSE;
+                    goto out;
+                }
+            }
+            PUSH_OPND(OBJECT_TO_JSVAL(obj));
+            obj = NULL;
+          END_LITOPX_CASE
+
+          BEGIN_LITOPX_CASE(JSOP_NAMEDFUNOBJ, 0)
+            /* ECMA ed. 3 FunctionExpression: function Identifier [etc.]. */
+            rval = ATOM_KEY(atom);
+            JS_ASSERT(JSVAL_IS_FUNCTION(cx, rval));
+
+            /*
+             * 1. Create a new object as if by the expression new Object().
+             * 2. Add Result(1) to the front of the scope chain.
+             *
+             * Step 2 is achieved by making the new object's parent be the
+             * current scope chain, and then making the new object the parent
+             * of the Function object clone.
+             */
+            SAVE_SP(fp);
+            obj2 = fp->scopeChain;
+            parent = js_ConstructObject(cx, &js_ObjectClass, NULL, obj2,
+                                        0, NULL);
+            if (!parent) {
+                ok = JS_FALSE;
+                goto out;
+            }
+
+            /*
+             * 3. Create a new Function object as specified in section 13.2
+             * with [parameters and body specified by the function expression
+             * that was parsed by the compiler into a Function object, and
+             * saved in the script's atom map].
+             *
+             * Protect parent from GC after js_CloneFunctionObject calls into
+             * js_NewObject, which displaces the newborn object root in cx by
+             * allocating the clone, then runs a last-ditch GC while trying
+             * to allocate the clone's slots vector.  Another, multi-threaded
+             * path: js_CloneFunctionObject => js_NewObject => OBJ_GET_CLASS
+             * which may suspend the current request in ClaimScope, with the
+             * newborn displaced as in the first scenario.
+             */
+            fp->scopeChain = parent;
+            obj = js_CloneFunctionObject(cx, JSVAL_TO_OBJECT(rval), parent);
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+
+            /*
+             * Protect obj from any GC hiding below OBJ_DEFINE_PROPERTY.  All
+             * paths from here must flow through the "Restore fp->scopeChain"
+             * code below the OBJ_DEFINE_PROPERTY call.
+             */
+            fp->scopeChain = obj;
+            rval = OBJECT_TO_JSVAL(obj);
+
+            /*
+             * 4. Create a property in the object Result(1).  The property's
+             * name is [fun->atom, the identifier parsed by the compiler],
+             * value is Result(3), and attributes are { DontDelete, ReadOnly }.
+             */
+            fun = (JSFunction *) JS_GetPrivate(cx, obj);
+            attrs = fun->flags & (JSFUN_GETTER | JSFUN_SETTER);
+            if (attrs) {
+                attrs |= JSPROP_SHARED;
+                rval = JSVAL_VOID;
+            }
+            ok = OBJ_DEFINE_PROPERTY(cx, parent, ATOM_TO_JSID(fun->atom), rval,
+                                     (attrs & JSFUN_GETTER)
+                                     ? (JSPropertyOp) obj
+                                     : NULL,
+                                     (attrs & JSFUN_SETTER)
+                                     ? (JSPropertyOp) obj
+                                     : NULL,
+                                     attrs |
+                                     JSPROP_ENUMERATE | JSPROP_PERMANENT |
+                                     JSPROP_READONLY,
+                                     NULL);
+
+            /* Restore fp->scopeChain now that obj is defined in parent. */
+            fp->scopeChain = obj2;
+            if (!ok) {
+                cx->newborn[GCX_OBJECT] = NULL;
+                goto out;
+            }
+
+            /*
+             * 5. Remove Result(1) from the front of the scope chain [no-op].
+             * 6. Return Result(3).
+             */
+            PUSH_OPND(OBJECT_TO_JSVAL(obj));
+            obj = NULL;
+          END_LITOPX_CASE
+
+          BEGIN_LITOPX_CASE(JSOP_CLOSURE, 0)
+            /*
+             * ECMA ed. 3 extension: a named function expression in a compound
+             * statement (not at the top statement level of global code, or at
+             * the top level of a function body).
+             *
+             * Get immediate operand atom, which is a function object literal.
+             * From it, get the function to close.
+             */
+            JS_ASSERT(JSVAL_IS_FUNCTION(cx, ATOM_KEY(atom)));
+            obj = ATOM_TO_OBJECT(atom);
+
+            /*
+             * Clone the function object with the current scope chain as the
+             * clone's parent.  The original function object is the prototype
+             * of the clone.  Do this only if re-parenting; the compiler may
+             * have seen the right parent already and created a sufficiently
+             * well-scoped function object.
+             */
+            SAVE_SP(fp);
+            obj2 = fp->scopeChain;
+            if (OBJ_GET_PARENT(cx, obj) != obj2) {
+                obj = js_CloneFunctionObject(cx, obj, obj2);
+                if (!obj) {
+                    ok = JS_FALSE;
+                    goto out;
+                }
+            }
+
+            /*
+             * Protect obj from any GC hiding below OBJ_DEFINE_PROPERTY.  All
+             * paths from here must flow through the "Restore fp->scopeChain"
+             * code below the OBJ_DEFINE_PROPERTY call.
+             */
+            fp->scopeChain = obj;
+            rval = OBJECT_TO_JSVAL(obj);
+
+            /*
+             * Make a property in fp->varobj with id fun->atom and value obj,
+             * unless fun is a getter or setter (in which case, obj is cast to
+             * a JSPropertyOp and passed accordingly).
+             */
+            fun = (JSFunction *) JS_GetPrivate(cx, obj);
+            attrs = fun->flags & (JSFUN_GETTER | JSFUN_SETTER);
+            if (attrs) {
+                attrs |= JSPROP_SHARED;
+                rval = JSVAL_VOID;
+            }
+            parent = fp->varobj;
+            ok = OBJ_DEFINE_PROPERTY(cx, parent, ATOM_TO_JSID(fun->atom), rval,
+                                     (attrs & JSFUN_GETTER)
+                                     ? (JSPropertyOp) obj
+                                     : NULL,
+                                     (attrs & JSFUN_SETTER)
+                                     ? (JSPropertyOp) obj
+                                     : NULL,
+                                     attrs | JSPROP_ENUMERATE
+                                           | JSPROP_PERMANENT,
+                                     &prop);
+
+            /* Restore fp->scopeChain now that obj is defined in fp->varobj. */
+            fp->scopeChain = obj2;
+            if (!ok) {
+                cx->newborn[GCX_OBJECT] = NULL;
+                goto out;
+            }
+
+#if 0
+            if (attrs == 0 && script->numGlobalVars) {
+                /*
+                 * As with JSOP_DEFVAR and JSOP_DEFCONST (above), fast globals
+                 * use fp->vars to map the global function name's atomIndex to
+                 * its permanent fp->varobj slot number, tagged as a jsval.
+                 */
+                sprop = (JSScopeProperty *) prop;
+                fp->vars[atomIndex] = INT_TO_JSVAL(sprop->slot);
+            }
+#endif
+            OBJ_DROP_PROPERTY(cx, parent, prop);
+          END_LITOPX_CASE
+#endif /* JS_HAS_LEXICAL_CLOSURE */
+
+#if JS_HAS_GETTER_SETTER
+          case JSOP_GETTER:
+          case JSOP_SETTER:
+            JS_ASSERT(len == 1);
+            op2 = (JSOp) *++pc;
+            cs = &js_CodeSpec[op2];
+            len = cs->length;
+            switch (op2) {
+              case JSOP_SETNAME:
+              case JSOP_SETPROP:
+                atom = GET_ATOM(cx, script, pc);
+                id   = ATOM_TO_JSID(atom);
+                rval = FETCH_OPND(-1);
+                i = -1;
+                goto gs_pop_lval;
+
+              case JSOP_SETELEM:
+                rval = FETCH_OPND(-1);
+                FETCH_ELEMENT_ID(-2, id);
+                i = -2;
+              gs_pop_lval:
+                FETCH_OBJECT(cx, i - 1, lval, obj);
+                break;
+
+#if JS_HAS_INITIALIZERS
+              case JSOP_INITPROP:
+                JS_ASSERT(sp - fp->spbase >= 2);
+                rval = FETCH_OPND(-1);
+                i = -1;
+                atom = GET_ATOM(cx, script, pc);
+                id   = ATOM_TO_JSID(atom);
+                goto gs_get_lval;
+
+              case JSOP_INITELEM:
+                JS_ASSERT(sp - fp->spbase >= 3);
+                rval = FETCH_OPND(-1);
+                FETCH_ELEMENT_ID(-2, id);
+                i = -2;
+              gs_get_lval:
+                lval = FETCH_OPND(i-1);
+                JS_ASSERT(JSVAL_IS_OBJECT(lval));
+                obj = JSVAL_TO_OBJECT(lval);
+                break;
+#endif /* JS_HAS_INITIALIZERS */
+
+              default:
+                JS_ASSERT(0);
+            }
+
+            /* Ensure that id has a type suitable for use with obj. */
+            CHECK_ELEMENT_ID(obj, id);
+
+            if (JS_TypeOfValue(cx, rval) != JSTYPE_FUNCTION) {
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_BAD_GETTER_OR_SETTER,
+                                     (op == JSOP_GETTER)
+                                     ? js_getter_str
+                                     : js_setter_str);
+                ok = JS_FALSE;
+                goto out;
+            }
+
+            /*
+             * Getters and setters are just like watchpoints from an access
+             * control point of view.
+             */
+            SAVE_SP(fp);
+            ok = OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &rtmp, &attrs);
+            if (!ok)
+                goto out;
+
+            if (op == JSOP_GETTER) {
+                getter = (JSPropertyOp) JSVAL_TO_OBJECT(rval);
+                setter = NULL;
+                attrs = JSPROP_GETTER;
+            } else {
+                getter = NULL;
+                setter = (JSPropertyOp) JSVAL_TO_OBJECT(rval);
+                attrs = JSPROP_SETTER;
+            }
+            attrs |= JSPROP_ENUMERATE | JSPROP_SHARED;
+
+            /* Check for a readonly or permanent property of the same name. */
+            ok = js_CheckRedeclaration(cx, obj, id, attrs, NULL, NULL);
+            if (!ok)
+                goto out;
+
+            ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, getter, setter,
+                                     attrs, NULL);
+            if (!ok)
+                goto out;
+
+            obj = NULL;
+            sp += i;
+            if (cs->ndefs)
+                STORE_OPND(-1, rval);
+            break;
+#endif /* JS_HAS_GETTER_SETTER */
+
+#if JS_HAS_INITIALIZERS
+          case JSOP_NEWINIT:
+            argc = 0;
+            fp->sharpDepth++;
+            goto do_new;
+
+          case JSOP_ENDINIT:
+            if (--fp->sharpDepth == 0)
+                fp->sharpArray = NULL;
+
+            /* Re-set the newborn root to the top of this object tree. */
+            JS_ASSERT(sp - fp->spbase >= 1);
+            lval = FETCH_OPND(-1);
+            JS_ASSERT(JSVAL_IS_OBJECT(lval));
+            cx->newborn[GCX_OBJECT] = JSVAL_TO_GCTHING(lval);
+            break;
+
+          case JSOP_INITPROP:
+            /* Pop the property's value into rval. */
+            JS_ASSERT(sp - fp->spbase >= 2);
+            rval = FETCH_OPND(-1);
+
+            /* Get the immediate property name into id. */
+            atom = GET_ATOM(cx, script, pc);
+            id   = ATOM_TO_JSID(atom);
+            i = -1;
+            goto do_init;
+
+          case JSOP_INITELEM:
+            /* Pop the element's value into rval. */
+            JS_ASSERT(sp - fp->spbase >= 3);
+            rval = FETCH_OPND(-1);
+
+            /* Pop and conditionally atomize the element id. */
+            FETCH_ELEMENT_ID(-2, id);
+            i = -2;
+
+          do_init:
+            /* Find the object being initialized at top of stack. */
+            lval = FETCH_OPND(i-1);
+            JS_ASSERT(JSVAL_IS_OBJECT(lval));
+            obj = JSVAL_TO_OBJECT(lval);
+
+            /* Ensure that id has a type suitable for use with obj. */
+            CHECK_ELEMENT_ID(obj, id);
+
+            /* Set the property named by obj[id] to rval. */
+            SAVE_SP(fp);
+            ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);
+            if (!ok)
+                goto out;
+            sp += i;
+            break;
+
+#if JS_HAS_SHARP_VARS
+          case JSOP_DEFSHARP:
+            SAVE_SP(fp);
+            obj = fp->sharpArray;
+            if (!obj) {
+                obj = js_NewArrayObject(cx, 0, NULL);
+                if (!obj) {
+                    ok = JS_FALSE;
+                    goto out;
+                }
+                fp->sharpArray = obj;
+            }
+            i = (jsint) GET_ATOM_INDEX(pc);
+            id = INT_TO_JSID(i);
+            rval = FETCH_OPND(-1);
+            if (JSVAL_IS_PRIMITIVE(rval)) {
+                char numBuf[12];
+                JS_snprintf(numBuf, sizeof numBuf, "%u", (unsigned) i);
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_BAD_SHARP_DEF, numBuf);
+                ok = JS_FALSE;
+                goto out;
+            }
+            ok = OBJ_SET_PROPERTY(cx, obj, id, &rval);
+            if (!ok)
+                goto out;
+            break;
+
+          case JSOP_USESHARP:
+            i = (jsint) GET_ATOM_INDEX(pc);
+            id = INT_TO_JSID(i);
+            obj = fp->sharpArray;
+            if (!obj) {
+                rval = JSVAL_VOID;
+            } else {
+                SAVE_SP(fp);
+                ok = OBJ_GET_PROPERTY(cx, obj, id, &rval);
+                if (!ok)
+                    goto out;
+            }
+            if (!JSVAL_IS_OBJECT(rval)) {
+                char numBuf[12];
+                JS_snprintf(numBuf, sizeof numBuf, "%u", (unsigned) i);
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_BAD_SHARP_USE, numBuf);
+                ok = JS_FALSE;
+                goto out;
+            }
+            PUSH_OPND(rval);
+            break;
+#endif /* JS_HAS_SHARP_VARS */
+#endif /* JS_HAS_INITIALIZERS */
+
+#if JS_HAS_EXCEPTIONS
+          /* No-ops for ease of decompilation and jit'ing. */
+          case JSOP_TRY:
+          case JSOP_FINALLY:
+            break;
+
+          /* Reset the stack to the given depth. */
+          case JSOP_SETSP:
+            i = (jsint) GET_ATOM_INDEX(pc);
+            JS_ASSERT(i >= 0);
+            sp = fp->spbase + i;
+
+            obj = fp->scopeChain;
+            while (OBJ_GET_CLASS(cx, obj) == &js_WithClass &&
+                   JSVAL_TO_INT(OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE)) > i) {
+                obj = OBJ_GET_PARENT(cx, obj);
+            }
+            fp->scopeChain = obj;
+            break;
+
+          case JSOP_GOSUB:
+            i = PTRDIFF(pc, script->main, jsbytecode) + len;
+            len = GET_JUMP_OFFSET(pc);
+            PUSH(INT_TO_JSVAL(i));
+            break;
+
+          case JSOP_GOSUBX:
+            i = PTRDIFF(pc, script->main, jsbytecode) + len;
+            len = GET_JUMPX_OFFSET(pc);
+            PUSH(INT_TO_JSVAL(i));
+            break;
+
+          case JSOP_RETSUB:
+            rval = POP();
+            JS_ASSERT(JSVAL_IS_INT(rval));
+            i = JSVAL_TO_INT(rval);
+            pc = script->main + i;
+            len = 0;
+            break;
+
+          case JSOP_EXCEPTION:
+            PUSH(cx->exception);
+            cx->throwing = JS_FALSE;
+            break;
+
+          case JSOP_THROW:
+            cx->throwing = JS_TRUE;
+            cx->exception = POP_OPND();
+            ok = JS_FALSE;
+            /* let the code at out try to catch the exception. */
+            goto out;
+
+          BEGIN_LITOPX_CASE(JSOP_INITCATCHVAR, 0)
+            /* Load the value into rval, while keeping it live on stack. */
+            JS_ASSERT(sp - fp->spbase >= 2);
+            rval = FETCH_OPND(-1);
+
+            /* Get the immediate catch variable name into id. */
+            id   = ATOM_TO_JSID(atom);
+
+            /* Find the object being initialized at top of stack. */
+            lval = FETCH_OPND(-2);
+            JS_ASSERT(JSVAL_IS_OBJECT(lval));
+            obj = JSVAL_TO_OBJECT(lval);
+
+            /* Define obj[id] to contain rval and to be permanent. */
+            SAVE_SP(fp);
+            ok = OBJ_DEFINE_PROPERTY(cx, obj, id, rval, NULL, NULL,
+                                     JSPROP_PERMANENT, NULL);
+            if (!ok)
+                goto out;
+
+            /* Now that we're done with rval, pop it. */
+            sp--;
+          END_LITOPX_CASE
+#endif /* JS_HAS_EXCEPTIONS */
+
+#if JS_HAS_INSTANCEOF
+          case JSOP_INSTANCEOF:
+            rval = FETCH_OPND(-1);
+            if (JSVAL_IS_PRIMITIVE(rval) ||
+                !(obj = JSVAL_TO_OBJECT(rval))->map->ops->hasInstance) {
+                SAVE_SP(fp);
+                str = js_DecompileValueGenerator(cx, -1, rval, NULL);
+                if (str) {
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                         JSMSG_BAD_INSTANCEOF_RHS,
+                                         JS_GetStringBytes(str));
+                }
+                ok = JS_FALSE;
+                goto out;
+            }
+            lval = FETCH_OPND(-2);
+            cond = JS_FALSE;
+            SAVE_SP(fp);
+            ok = obj->map->ops->hasInstance(cx, obj, lval, &cond);
+            if (!ok)
+                goto out;
+            sp--;
+            STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond));
+            break;
+#endif /* JS_HAS_INSTANCEOF */
+
+#if JS_HAS_DEBUGGER_KEYWORD
+          case JSOP_DEBUGGER:
+          {
+            JSTrapHandler handler = rt->debuggerHandler;
+            if (handler) {
+                SAVE_SP(fp);
+                switch (handler(cx, script, pc, &rval,
+                                rt->debuggerHandlerData)) {
+                  case JSTRAP_ERROR:
+                    ok = JS_FALSE;
+                    goto out;
+                  case JSTRAP_CONTINUE:
+                    break;
+                  case JSTRAP_RETURN:
+                    fp->rval = rval;
+                    goto out;
+#if JS_HAS_EXCEPTIONS
+                  case JSTRAP_THROW:
+                    cx->throwing = JS_TRUE;
+                    cx->exception = rval;
+                    ok = JS_FALSE;
+                    goto out;
+#endif /* JS_HAS_EXCEPTIONS */
+                  default:;
+                }
+                LOAD_INTERRUPT_HANDLER(rt);
+            }
+            break;
+          }
+#endif /* JS_HAS_DEBUGGER_KEYWORD */
+
+#if JS_HAS_XML_SUPPORT
+          case JSOP_DEFXMLNS:
+            rval = POP();
+            SAVE_SP(fp);
+            ok = js_SetDefaultXMLNamespace(cx, rval);
+            if (!ok)
+                goto out;
+            break;
+
+          case JSOP_ANYNAME:
+            SAVE_SP(fp);
+            ok = js_GetAnyName(cx, &rval);
+            if (!ok)
+                goto out;
+            PUSH_OPND(rval);
+            break;
+
+          BEGIN_LITOPX_CASE(JSOP_QNAMEPART, 0)
+            PUSH_OPND(ATOM_KEY(atom));
+          END_LITOPX_CASE
+
+          BEGIN_LITOPX_CASE(JSOP_QNAMECONST, 0)
+            rval = ATOM_KEY(atom);
+            lval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            obj = js_ConstructXMLQNameObject(cx, lval, rval);
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            STORE_OPND(-1, OBJECT_TO_JSVAL(obj));
+          END_LITOPX_CASE
+
+          case JSOP_QNAME:
+            rval = FETCH_OPND(-1);
+            lval = FETCH_OPND(-2);
+            SAVE_SP(fp);
+            obj = js_ConstructXMLQNameObject(cx, lval, rval);
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            sp--;
+            STORE_OPND(-1, OBJECT_TO_JSVAL(obj));
+            break;
+
+          case JSOP_TOATTRNAME:
+            rval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            ok = js_ToAttributeName(cx, &rval);
+            if (!ok)
+                goto out;
+            STORE_OPND(-1, rval);
+            break;
+
+          case JSOP_TOATTRVAL:
+            rval = FETCH_OPND(-1);
+            JS_ASSERT(JSVAL_IS_STRING(rval));
+            SAVE_SP(fp);
+            str = js_EscapeAttributeValue(cx, JSVAL_TO_STRING(rval));
+            if (!str) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            STORE_OPND(-1, STRING_TO_JSVAL(str));
+            break;
+
+          case JSOP_ADDATTRNAME:
+          case JSOP_ADDATTRVAL:
+            rval = FETCH_OPND(-1);
+            lval = FETCH_OPND(-2);
+            str = JSVAL_TO_STRING(lval);
+            str2 = JSVAL_TO_STRING(rval);
+            SAVE_SP(fp);
+            str = js_AddAttributePart(cx, op == JSOP_ADDATTRNAME, str, str2);
+            if (!str) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            sp--;
+            STORE_OPND(-1, STRING_TO_JSVAL(str));
+            break;
+
+          case JSOP_BINDXMLNAME:
+            lval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            ok = js_FindXMLProperty(cx, lval, &obj, &rval);
+            if (!ok)
+                goto out;
+            STORE_OPND(-1, OBJECT_TO_JSVAL(obj));
+            PUSH_OPND(rval);
+            break;
+
+          case JSOP_SETXMLNAME:
+            obj = JSVAL_TO_OBJECT(FETCH_OPND(-3));
+            lval = FETCH_OPND(-2);
+            rval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            ok = js_SetXMLProperty(cx, obj, lval, &rval);
+            if (!ok)
+                goto out;
+            sp -= 2;
+            STORE_OPND(-1, rval);
+            obj = NULL;
+            break;
+
+          case JSOP_XMLNAME:
+            lval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            ok = js_FindXMLProperty(cx, lval, &obj, &rval);
+            if (!ok)
+                goto out;
+            ok = js_GetXMLProperty(cx, obj, rval, &rval);
+            if (!ok)
+                goto out;
+            STORE_OPND(-1, rval);
+            break;
+
+          case JSOP_DESCENDANTS:
+          case JSOP_DELDESC:
+            FETCH_OBJECT(cx, -2, lval, obj);
+            rval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            ok = js_GetXMLDescendants(cx, obj, rval, &rval);
+            if (!ok)
+                goto out;
+
+            if (op == JSOP_DELDESC) {
+                sp[-1] = rval;          /* set local root */
+                ok = js_DeleteXMLListElements(cx, JSVAL_TO_OBJECT(rval));
+                if (!ok)
+                    goto out;
+                rval = JSVAL_TRUE;      /* always succeed */
+            }
+
+            sp--;
+            STORE_OPND(-1, rval);
+            break;
+
+          case JSOP_FILTER:
+            FETCH_OBJECT(cx, -1, lval, obj);
+            len = GET_JUMP_OFFSET(pc);
+            SAVE_SP(fp);
+            ok = js_FilterXMLList(cx, obj, pc + cs->length, &rval);
+            if (!ok)
+                goto out;
+            JS_ASSERT(fp->sp == sp);
+            STORE_OPND(-1, rval);
+            break;
+
+          case JSOP_ENDFILTER:
+            *result = POP_OPND();
+            goto out;
+
+	  case JSOP_STARTXML:
+	  case JSOP_STARTXMLEXPR:
+	    break;
+
+          case JSOP_TOXML:
+            rval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            obj = js_ValueToXMLObject(cx, rval);
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            STORE_OPND(-1, OBJECT_TO_JSVAL(obj));
+            break;
+
+          case JSOP_TOXMLLIST:
+            rval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            obj = js_ValueToXMLListObject(cx, rval);
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            STORE_OPND(-1, OBJECT_TO_JSVAL(obj));
+            break;
+
+          case JSOP_XMLTAGEXPR:
+            rval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            str = js_ValueToString(cx, rval);
+            if (!str) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            STORE_OPND(-1, STRING_TO_JSVAL(str));
+            break;
+
+          case JSOP_XMLELTEXPR:
+            rval = FETCH_OPND(-1);
+            SAVE_SP(fp);
+            if (VALUE_IS_XML(cx, rval)) {
+                str = js_ValueToXMLString(cx, rval);
+            } else {
+                str = js_ValueToString(cx, rval);
+                if (str)
+                    str = js_EscapeElementValue(cx, str);
+            }
+            if (!str) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            STORE_OPND(-1, STRING_TO_JSVAL(str));
+            break;
+
+          BEGIN_LITOPX_CASE(JSOP_XMLOBJECT, 0)
+            SAVE_SP(fp);
+            obj = js_CloneXMLObject(cx, ATOM_TO_OBJECT(atom));
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            PUSH_OPND(OBJECT_TO_JSVAL(obj));
+            obj = NULL;
+          END_LITOPX_CASE
+
+          BEGIN_LITOPX_CASE(JSOP_XMLCDATA, 0)
+            str = ATOM_TO_STRING(atom);
+            obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_TEXT, NULL, str);
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            PUSH_OPND(OBJECT_TO_JSVAL(obj));
+          END_LITOPX_CASE
+
+          BEGIN_LITOPX_CASE(JSOP_XMLCOMMENT, 0)
+            str = ATOM_TO_STRING(atom);
+            obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_COMMENT, NULL, str);
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            PUSH_OPND(OBJECT_TO_JSVAL(obj));
+          END_LITOPX_CASE
+
+          BEGIN_LITOPX_CASE(JSOP_XMLPI, 0)
+            str = ATOM_TO_STRING(atom);
+            rval = FETCH_OPND(-1);
+            str2 = JSVAL_TO_STRING(rval);
+            SAVE_SP(fp);
+            obj = js_NewXMLSpecialObject(cx,
+                                         JSXML_CLASS_PROCESSING_INSTRUCTION,
+                                         str, str2);
+            if (!obj) {
+                ok = JS_FALSE;
+                goto out;
+            }
+            STORE_OPND(-1, OBJECT_TO_JSVAL(obj));
+          END_LITOPX_CASE
+
+          BEGIN_LITOPX_CASE(JSOP_GETMETHOD, 0)
+            /* Get an immediate atom naming the property. */
+            id   = ATOM_TO_JSID(atom);
+            FETCH_OBJECT(cx, -1, lval, obj);
+            SAVE_SP(fp);
+
+            /* Special-case XML object method lookup, per ECMA-357. */
+            if (OBJECT_IS_XML(cx, obj)) {
+                JSXMLObjectOps *ops;
+
+                ops = (JSXMLObjectOps *) obj->map->ops;
+                obj = ops->getMethod(cx, obj, id, &rval);
+                if (!obj)
+                    ok = JS_FALSE;
+            } else {
+                CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval));
+            }
+            if (!ok)
+                goto out;
+            STORE_OPND(-1, rval);
+          END_LITOPX_CASE
+
+          BEGIN_LITOPX_CASE(JSOP_SETMETHOD, 0)
+            /* Get an immediate atom naming the property. */
+            id   = ATOM_TO_JSID(atom);
+            rval = FETCH_OPND(-1);
+            FETCH_OBJECT(cx, -2, lval, obj);
+            SAVE_SP(fp);
+
+            /* Special-case XML object method lookup, per ECMA-357. */
+            if (OBJECT_IS_XML(cx, obj)) {
+                JSXMLObjectOps *ops;
+
+                ops = (JSXMLObjectOps *) obj->map->ops;
+                ok = ops->setMethod(cx, obj, id, &rval);
+            } else {
+                CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval));
+            }
+            if (!ok)
+                goto out;
+            --sp;
+            STORE_OPND(-1, rval);
+            obj = NULL;
+          END_LITOPX_CASE
+
+          case JSOP_GETFUNNS:
+            ok = js_GetFunctionNamespace(cx, &rval);
+            if (!ok)
+                goto out;
+            PUSH_OPND(rval);
+            break;
+
+          case JSOP_FOREACH:
+            foreach = JS_TRUE;
+            break;
+#endif /* JS_HAS_XML_SUPPORT */
+
+          default: {
+            char numBuf[12];
+            JS_snprintf(numBuf, sizeof numBuf, "%d", op);
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_BAD_BYTECODE, numBuf);
+            ok = JS_FALSE;
+            goto out;
+          }
+        }
+
+    advance_pc:
+        pc += len;
+
+#ifdef DEBUG
+        if (tracefp) {
+            intN ndefs, n;
+            jsval *siter;
+
+            ndefs = cs->ndefs;
+            if (ndefs) {
+                SAVE_SP(fp);
+                if (op == JSOP_FORELEM && sp[-1] == JSVAL_FALSE)
+                    --ndefs;
+                for (n = -ndefs; n < 0; n++) {
+                    str = js_DecompileValueGenerator(cx, n, sp[n], NULL);
+                    if (str) {
+                        fprintf(tracefp, "%s %s",
+                                (n == -ndefs) ? "  output:" : ",",
+                                JS_GetStringBytes(str));
+                    }
+                }
+                fprintf(tracefp, " @ %d\n", sp - fp->spbase);
+            }
+            fprintf(tracefp, "  stack: ");
+            for (siter = fp->spbase; siter < sp; siter++) {
+                str = js_ValueToSource(cx, *siter);
+                fprintf(tracefp, "%s ",
+                        str ? JS_GetStringBytes(str) : "<null>");
+            }
+            fputc('\n', tracefp);
+        }
+#endif
+    }
+out:
+
+#if JS_HAS_EXCEPTIONS
+    if (!ok) {
+        /*
+         * Has an exception been raised?  Also insist that we are in the
+         * interpreter activation that pushed fp's operand stack, to avoid
+         * catching exceptions within XML filtering predicate expressions,
+         * such as the one from tests/e4x/Regress/regress-301596.js:
+         *
+         *    try {
+         *        <xml/>.(@a == 1);
+         *        throw 5;
+         *    } catch (e) {
+         *    }
+         *
+         * The inner interpreter activation executing the predicate bytecode
+         * will throw "reference to undefined XML name @a" (or 5, in older
+         * versions that followed the first edition of ECMA-357 and evaluated
+         * unbound identifiers to undefined), and the exception must not be
+         * caught until control unwinds to the outer interpreter activation.
+         *
+         * Otherwise, the wrong stack depth will be restored by JSOP_SETSP,
+         * and the catch will move into the filtering predicate expression,
+         * leading to double catch execution if it rethrows.
+         *
+         * XXX This assumes the null mark case implies XML filtering predicate
+         * expression execution!
+         * FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=309894
+         */
+        if (cx->throwing && JS_LIKELY(mark != NULL)) {
+            /*
+             * Call debugger throw hook if set (XXX thread safety?).
+             */
+            JSTrapHandler handler = rt->throwHook;
+            if (handler) {
+                SAVE_SP(fp);
+                switch (handler(cx, script, pc, &rval, rt->throwHookData)) {
+                  case JSTRAP_ERROR:
+                    cx->throwing = JS_FALSE;
+                    goto no_catch;
+                  case JSTRAP_RETURN:
+                    ok = JS_TRUE;
+                    cx->throwing = JS_FALSE;
+                    fp->rval = rval;
+                    goto no_catch;
+                  case JSTRAP_THROW:
+                    cx->exception = rval;
+                  case JSTRAP_CONTINUE:
+                  default:;
+                }
+                LOAD_INTERRUPT_HANDLER(rt);
+            }
+
+            /*
+             * Look for a try block in script that can catch this exception.
+             */
+            SCRIPT_FIND_CATCH_START(script, pc, pc);
+            if (pc) {
+                /* Don't clear cx->throwing to save cx->exception from GC. */
+                len = 0;
+                ok = JS_TRUE;
+#if JS_HAS_XML_SUPPORT
+                foreach = JS_FALSE;
+#endif
+                goto advance_pc;
+            }
+        }
+no_catch:;
+    }
+#endif
+
+    /*
+     * Check whether control fell off the end of a lightweight function, or an
+     * exception thrown under such a function was not caught by it.  If so, go
+     * to the inline code under JSOP_RETURN.
+     */
+    if (inlineCallCount) {
+#if JS_HAS_XML_SUPPORT
+        foreach = JS_FALSE;
+#endif
+        goto inline_return;
+    }
+
+    /*
+     * Reset sp before freeing stack slots, because our caller may GC soon.
+     * Clear spbase to indicate that we've popped the 2 * depth operand slots.
+     * Restore the previous frame's execution state.
+     */
+    if (JS_LIKELY(mark != NULL)) {
+        fp->sp = fp->spbase;
+        fp->spbase = NULL;
+        js_FreeRawStack(cx, mark);
+    } else {
+        SAVE_SP(fp);
+    }
+
+out2:
+    if (cx->version == currentVersion && currentVersion != originalVersion)
+        js_SetVersion(cx, originalVersion);
+    cx->interpLevel--;
+    return ok;
+
+atom_not_defined:
+    {
+        const char *printable = js_AtomToPrintableString(cx, atom);
+        if (printable)
+            js_ReportIsNotDefined(cx, printable);
+        ok = JS_FALSE;
+#ifdef OSSP /* CLEANUP */
+        sp = NULL;
+#endif
+        goto out;
+    }
+}

Added: freeswitch/trunk/libs/js/src/jsinterp.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsinterp.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,322 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsinterp_h___
+#define jsinterp_h___
+/*
+ * JS interpreter interface.
+ */
+#include "jsprvtd.h"
+#include "jspubtd.h"
+
+JS_BEGIN_EXTERN_C
+
+/*
+ * JS stack frame, allocated on the C stack.
+ */
+struct JSStackFrame {
+    JSObject        *callobj;       /* lazily created Call object */
+    JSObject        *argsobj;       /* lazily created arguments object */
+    JSObject        *varobj;        /* variables object, where vars go */
+    JSScript        *script;        /* script being interpreted */
+    JSFunction      *fun;           /* function being called or null */
+    JSObject        *thisp;         /* "this" pointer if in method */
+    uintN           argc;           /* actual argument count */
+    jsval           *argv;          /* base of argument stack slots */
+    jsval           rval;           /* function return value */
+    uintN           nvars;          /* local variable count */
+    jsval           *vars;          /* base of variable stack slots */
+    JSStackFrame    *down;          /* previous frame */
+    void            *annotation;    /* used by Java security */
+    JSObject        *scopeChain;    /* scope chain */
+    jsbytecode      *pc;            /* program counter */
+    jsval           *sp;            /* stack pointer */
+    jsval           *spbase;        /* operand stack base */
+    uintN           sharpDepth;     /* array/object initializer depth */
+    JSObject        *sharpArray;    /* scope for #n= initializer vars */
+    uint32          flags;          /* frame flags -- see below */
+    JSStackFrame    *dormantNext;   /* next dormant frame chain */
+    JSObject        *xmlNamespace;  /* null or default xml namespace in E4X */
+};
+
+typedef struct JSInlineFrame {
+    JSStackFrame    frame;          /* base struct */
+    void            *mark;          /* mark before inline frame */
+    void            *hookData;      /* debugger call hook data */
+    JSVersion       callerVersion;  /* dynamic version of calling script */
+} JSInlineFrame;
+
+/* JS stack frame flags. */
+#define JSFRAME_CONSTRUCTING  0x01  /* frame is for a constructor invocation */
+#define JSFRAME_INTERNAL      0x02  /* internal call, not invoked by a script */
+#define JSFRAME_SKIP_CALLER   0x04  /* skip one link when evaluating f.caller
+                                       for this invocation of f */
+#define JSFRAME_ASSIGNING     0x08  /* a complex (not simplex JOF_ASSIGNING) op
+                                       is currently assigning to a property */
+#define JSFRAME_DEBUGGER      0x10  /* frame for JS_EvaluateInStackFrame */
+#define JSFRAME_EVAL          0x20  /* frame for obj_eval */
+#define JSFRAME_SPECIAL       0x30  /* special evaluation frame flags */
+#define JSFRAME_COMPILING     0x40  /* frame is being used by compiler */
+#define JSFRAME_COMPILE_N_GO  0x80  /* compiler-and-go mode, can optimize name
+                                       references based on scope chain */
+#define JSFRAME_SCRIPT_OBJECT 0x100 /* compiling source for a Script object */
+
+#define JSFRAME_OVERRIDE_SHIFT 24   /* override bit-set params; see jsfun.c */
+#define JSFRAME_OVERRIDE_BITS  8
+
+/*
+ * Property cache for quickened get/set property opcodes.
+ */
+#define PROPERTY_CACHE_LOG2     10
+#define PROPERTY_CACHE_SIZE     JS_BIT(PROPERTY_CACHE_LOG2)
+#define PROPERTY_CACHE_MASK     JS_BITMASK(PROPERTY_CACHE_LOG2)
+
+#define PROPERTY_CACHE_HASH(obj, id) \
+    ((((jsuword)(obj) >> JSVAL_TAGBITS) ^ (jsuword)(id)) & PROPERTY_CACHE_MASK)
+
+#ifdef JS_THREADSAFE
+
+#if HAVE_ATOMIC_DWORD_ACCESS
+
+#define PCE_LOAD(cache, pce, entry)     JS_ATOMIC_DWORD_LOAD(pce, entry)
+#define PCE_STORE(cache, pce, entry)    JS_ATOMIC_DWORD_STORE(pce, entry)
+
+#else  /* !HAVE_ATOMIC_DWORD_ACCESS */
+
+#define JS_PROPERTY_CACHE_METERING      1
+
+#define PCE_LOAD(cache, pce, entry)                                           \
+    JS_BEGIN_MACRO                                                            \
+        uint32 prefills_;                                                     \
+        uint32 fills_ = (cache)->fills;                                       \
+        do {                                                                  \
+            /* Load until cache->fills is stable (see FILL macro below). */   \
+            prefills_ = fills_;                                               \
+            (entry) = *(pce);                                                 \
+        } while ((fills_ = (cache)->fills) != prefills_);                     \
+    JS_END_MACRO
+
+#define PCE_STORE(cache, pce, entry)                                          \
+    JS_BEGIN_MACRO                                                            \
+        do {                                                                  \
+            /* Store until no racing collider stores half or all of pce. */   \
+            *(pce) = (entry);                                                 \
+        } while (PCE_OBJECT(*pce) != PCE_OBJECT(entry) ||                     \
+                 PCE_PROPERTY(*pce) != PCE_PROPERTY(entry));                  \
+    JS_END_MACRO
+
+#endif /* !HAVE_ATOMIC_DWORD_ACCESS */
+
+#else  /* !JS_THREADSAFE */
+
+#define PCE_LOAD(cache, pce, entry)     ((entry) = *(pce))
+#define PCE_STORE(cache, pce, entry)    (*(pce) = (entry))
+
+#endif /* !JS_THREADSAFE */
+
+typedef union JSPropertyCacheEntry {
+    struct {
+        JSObject        *object;        /* weak link to object */
+        JSScopeProperty *property;      /* weak link to property */
+    } s;
+#ifdef HAVE_ATOMIC_DWORD_ACCESS
+    prdword align;
+#endif
+} JSPropertyCacheEntry;
+
+/* These may be called in lvalue or rvalue position. */
+#define PCE_OBJECT(entry)       ((entry).s.object)
+#define PCE_PROPERTY(entry)     ((entry).s.property)
+
+typedef struct JSPropertyCache {
+    JSPropertyCacheEntry table[PROPERTY_CACHE_SIZE];
+    JSBool               empty;
+    JSBool               disabled;
+#ifdef JS_PROPERTY_CACHE_METERING
+    uint32               fills;
+    uint32               recycles;
+    uint32               tests;
+    uint32               misses;
+    uint32               flushes;
+# define PCMETER(x)      x
+#else
+# define PCMETER(x)      /* nothing */
+#endif
+} JSPropertyCache;
+
+#define PROPERTY_CACHE_FILL(cache, obj, id, sprop)                            \
+    JS_BEGIN_MACRO                                                            \
+        JSPropertyCache *cache_ = (cache);                                    \
+        if (!cache_->disabled) {                                              \
+            uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id);          \
+            JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_];          \
+            JSPropertyCacheEntry entry_;                                      \
+            JSScopeProperty *pce_sprop_;                                      \
+            PCE_LOAD(cache_, pce_, entry_);                                   \
+            pce_sprop_ = PCE_PROPERTY(entry_);                                \
+            PCMETER(if (pce_sprop_ && pce_sprop_ != sprop)                    \
+                        cache_->recycles++);                                  \
+            PCE_OBJECT(entry_) = obj;                                         \
+            PCE_PROPERTY(entry_) = sprop;                                     \
+            cache_->empty = JS_FALSE;                                         \
+            PCMETER(cache_->fills++);                                         \
+            PCE_STORE(cache_, pce_, entry_);                                  \
+        }                                                                     \
+    JS_END_MACRO
+
+#define PROPERTY_CACHE_TEST(cache, obj, id, sprop)                            \
+    JS_BEGIN_MACRO                                                            \
+        uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id);              \
+        JSPropertyCache *cache_ = (cache);                                    \
+        JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_];              \
+        JSPropertyCacheEntry entry_;                                          \
+        JSScopeProperty *pce_sprop_;                                          \
+        PCE_LOAD(cache_, pce_, entry_);                                       \
+        pce_sprop_ = PCE_PROPERTY(entry_);                                    \
+        PCMETER(cache_->tests++);                                             \
+        if (pce_sprop_ &&                                                     \
+            PCE_OBJECT(entry_) == obj &&                                      \
+            pce_sprop_->id == id) {                                           \
+            sprop = pce_sprop_;                                               \
+        } else {                                                              \
+            PCMETER(cache_->misses++);                                        \
+            sprop = NULL;                                                     \
+        }                                                                     \
+    JS_END_MACRO
+
+extern void
+js_FlushPropertyCache(JSContext *cx);
+
+extern void
+js_DisablePropertyCache(JSContext *cx);
+
+extern void
+js_EnablePropertyCache(JSContext *cx);
+
+extern JS_FRIEND_API(jsval *)
+js_AllocStack(JSContext *cx, uintN nslots, void **markp);
+
+extern JS_FRIEND_API(void)
+js_FreeStack(JSContext *cx, void *mark);
+
+extern JSBool
+js_GetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+extern JSBool
+js_SetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+extern JSBool
+js_GetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+extern JSBool
+js_SetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+#ifdef DUMP_CALL_TABLE
+# define JSOPTION_LOGCALL_TOSOURCE JS_BIT(15)
+
+extern JSHashTable  *js_CallTable;
+extern size_t       js_LogCallToSourceLimit;
+
+extern void         js_DumpCallTable(JSContext *cx);
+#endif
+
+/*
+ * Compute the 'this' parameter and store it in frame as frame.thisp.
+ * Activation objects ("Call" objects not created with "new Call()", i.e.,
+ * "Call" objects that have private data) may not be referred to by 'this',
+ * as dictated by ECMA.
+ *
+ * N.B.: fp->argv must be set, fp->argv[-1] the nominal 'this' paramter as
+ * a jsval, and fp->argv[-2] must be the callee object reference, usually a
+ * function object.  Also, fp->flags must contain JSFRAME_CONSTRUCTING if we
+ * are preparing for a constructor call.
+ */
+extern JSBool
+js_ComputeThis(JSContext *cx, JSObject *thisp, JSStackFrame *fp);
+
+/*
+ * NB: js_Invoke requires that cx is currently running JS (i.e., that cx->fp
+ * is non-null), and that the callee, |this| parameter, and actual arguments
+ * are already pushed on the stack under cx->fp->sp.
+ */
+extern JS_FRIEND_API(JSBool)
+js_Invoke(JSContext *cx, uintN argc, uintN flags);
+
+/*
+ * Consolidated js_Invoke flags simply rename the low JSFRAME_* flags.
+ */
+#define JSINVOKE_CONSTRUCT      JSFRAME_CONSTRUCTING
+#define JSINVOKE_INTERNAL       JSFRAME_INTERNAL
+#define JSINVOKE_SKIP_CALLER    JSFRAME_SKIP_CALLER
+
+/*
+ * "Internal" calls may come from C or C++ code using a JSContext on which no
+ * JS is running (!cx->fp), so they may need to push a dummy JSStackFrame.
+ */
+#define js_InternalCall(cx,obj,fval,argc,argv,rval)                           \
+    js_InternalInvoke(cx, obj, fval, 0, argc, argv, rval)
+
+#define js_InternalConstruct(cx,obj,fval,argc,argv,rval)                      \
+    js_InternalInvoke(cx, obj, fval, JSINVOKE_CONSTRUCT, argc, argv, rval)
+
+extern JSBool
+js_InternalInvoke(JSContext *cx, JSObject *obj, jsval fval, uintN flags,
+                  uintN argc, jsval *argv, jsval *rval);
+
+extern JSBool
+js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval,
+                    JSAccessMode mode, uintN argc, jsval *argv, jsval *rval);
+
+extern JSBool
+js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
+           JSStackFrame *down, uintN flags, jsval *result);
+
+extern JSBool
+js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs,
+                      JSObject **objp, JSProperty **propp);
+
+extern JSBool
+js_StrictlyEqual(jsval lval, jsval rval);
+
+extern JSBool
+js_Interpret(JSContext *cx, jsbytecode *pc, jsval *result);
+
+JS_END_EXTERN_C
+
+#endif /* jsinterp_h___ */

Added: freeswitch/trunk/libs/js/src/jslibmath.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jslibmath.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,318 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   IBM Corp.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * By default all math calls go to fdlibm.  The defines for each platform
+ * remap the math calls to native routines.
+ */
+
+#ifndef _LIBMATH_H
+#define _LIBMATH_H
+
+#include <math.h>
+#include "jsconfig.h"
+
+/*
+ * Define which platforms on which to use fdlibm.  Not used
+ * by default since there can be problems with endian-ness and such.
+ */
+
+#if defined(_WIN32) && !defined(__MWERKS__)
+#define JS_USE_FDLIBM_MATH 1
+
+#elif defined(SUNOS4)
+#define JS_USE_FDLIBM_MATH 1
+
+#elif defined(IRIX)
+#define JS_USE_FDLIBM_MATH 1
+
+#elif defined(SOLARIS)
+#define JS_USE_FDLIBM_MATH 1
+
+#elif defined(HPUX)
+#define JS_USE_FDLIBM_MATH 1
+
+#elif defined(linux)
+#define JS_USE_FDLIBM_MATH 1
+
+#elif defined(OSF1)
+/* Want to use some fdlibm functions but fdlibm broken on OSF1/alpha. */
+#define JS_USE_FDLIBM_MATH 0
+
+#elif defined(AIX)
+#define JS_USE_FDLIBM_MATH 1
+
+#else
+#define JS_USE_FDLIBM_MATH 0
+#endif
+
+#ifdef OSSP
+#undef JS_USE_FDLIBM_MATH
+#if defined(__FreeBSD__)
+#define JS_USE_FDLIBM_MATH 0
+#else
+#define JS_USE_FDLIBM_MATH 1
+#endif
+#endif
+
+#if !JS_USE_FDLIBM_MATH
+
+/*
+ * Use system provided math routines.
+ */
+
+#define fd_acos acos
+#define fd_asin asin
+#define fd_atan atan
+#define fd_atan2 atan2
+#define fd_ceil ceil
+#define fd_copysign copysign
+#define fd_cos cos
+#define fd_exp exp
+#define fd_fabs fabs
+#define fd_floor floor
+#define fd_fmod fmod
+#define fd_log log
+#define fd_pow pow
+#define fd_sin sin
+#define fd_sqrt sqrt
+#define fd_tan tan
+
+#else
+
+#ifdef OSSP
+#define fd_acos     js_fd_acos
+#define fd_asin     js_fd_asin
+#define fd_atan     js_fd_atan
+#define fd_atan2    js_fd_atan2
+#define fd_ceil     js_fd_ceil
+#define fd_copysign js_fd_copysign
+#define fd_cos      js_fd_cos
+#define fd_exp      js_fd_exp
+#define fd_fabs     js_fd_fabs
+#define fd_floor    js_fd_floor
+#define fd_fmod     js_fd_fmod
+#define fd_log      js_fd_log
+#define fd_pow      js_fd_pow
+#define fd_sin      js_fd_sin
+#define fd_sqrt     js_fd_sqrt
+#define fd_tan      js_fd_tan
+#endif
+
+/*
+ * Use math routines in fdlibm.
+ */
+
+#undef __P
+#ifdef __STDC__
+#define __P(p)  p
+#else
+#define __P(p)  ()
+#endif
+
+#if !defined(OSSP) && ((defined _WIN32 && !defined WINCE) || defined SUNOS4)
+
+#define fd_acos acos
+#define fd_asin asin
+#define fd_atan atan
+#define fd_cos cos
+#define fd_sin sin
+#define fd_tan tan
+#define fd_exp exp
+#define fd_log log
+#define fd_sqrt sqrt
+#define fd_ceil ceil
+#define fd_fabs fabs
+#define fd_floor floor
+#define fd_fmod fmod
+
+extern double fd_atan2 __P((double, double));
+extern double fd_copysign __P((double, double));
+extern double fd_pow __P((double, double));
+
+#elif !defined(OSSP) && defined IRIX
+
+#define fd_acos acos
+#define fd_asin asin
+#define fd_atan atan
+#define fd_exp exp
+#define fd_log log
+#define fd_log10 log10
+#define fd_sqrt sqrt
+#define fd_fabs fabs
+#define fd_floor floor
+#define fd_fmod fmod
+
+extern double fd_cos __P((double));
+extern double fd_sin __P((double));
+extern double fd_tan __P((double));
+extern double fd_atan2 __P((double, double));
+extern double fd_pow __P((double, double));
+extern double fd_ceil __P((double));
+extern double fd_copysign __P((double, double));
+
+#elif !defined(OSSP) && defined SOLARIS
+
+#define fd_atan atan
+#define fd_cos cos
+#define fd_sin sin
+#define fd_tan tan
+#define fd_exp exp
+#define fd_sqrt sqrt
+#define fd_ceil ceil
+#define fd_fabs fabs
+#define fd_floor floor
+#define fd_fmod fmod
+
+extern double fd_acos __P((double));
+extern double fd_asin __P((double));
+extern double fd_log __P((double));
+extern double fd_atan2 __P((double, double));
+extern double fd_pow __P((double, double));
+extern double fd_copysign __P((double, double));
+
+#elif !defined(OSSP) && defined HPUX
+
+#define fd_cos cos
+#define fd_sin sin
+#define fd_exp exp
+#define fd_sqrt sqrt
+#define fd_fabs fabs
+#define fd_floor floor
+#define fd_fmod fmod
+
+extern double fd_ceil __P((double));
+extern double fd_acos __P((double));
+extern double fd_log __P((double));
+extern double fd_atan2 __P((double, double));
+extern double fd_tan __P((double));
+extern double fd_pow __P((double, double));
+extern double fd_asin __P((double));
+extern double fd_atan __P((double));
+extern double fd_copysign __P((double, double));
+
+#elif !defined(OSSP) && defined(linux)
+
+#define fd_atan atan
+#define fd_atan2 atan2
+#define fd_ceil ceil
+#define fd_cos cos
+#define fd_fabs fabs
+#define fd_floor floor
+#define fd_fmod fmod
+#define fd_sin sin
+#define fd_sqrt sqrt
+#define fd_tan tan
+#define fd_copysign copysign
+
+extern double fd_asin __P((double));
+extern double fd_acos __P((double));
+extern double fd_exp __P((double));
+extern double fd_log __P((double));
+extern double fd_pow __P((double, double));
+
+#elif !defined(OSSP) && defined(OSF1)
+
+#define fd_acos acos
+#define fd_asin asin
+#define fd_atan atan
+#define fd_copysign copysign
+#define fd_cos cos
+#define fd_exp exp
+#define fd_fabs fabs
+#define fd_fmod fmod
+#define fd_sin sin
+#define fd_sqrt sqrt
+#define fd_tan tan
+
+extern double fd_atan2 __P((double, double));
+extern double fd_ceil __P((double));
+extern double fd_floor __P((double));
+extern double fd_log __P((double));
+extern double fd_pow __P((double, double));
+
+#elif !defined(OSSP) && defined(AIX)
+
+#define fd_acos acos
+#define fd_asin asin
+#define fd_atan2 atan2
+#define fd_copysign copysign
+#define fd_cos cos
+#define fd_exp exp
+#define fd_fabs fabs
+#define fd_floor floor
+#define fd_fmod fmod
+#define fd_log log
+#define fd_sin sin
+#define fd_sqrt sqrt
+
+extern double fd_atan __P((double));
+extern double fd_ceil __P((double));
+extern double fd_pow __P((double,double));
+extern double fd_tan __P((double));
+
+#else /* other platform.. generic paranoid slow fdlibm */
+
+extern double fd_acos __P((double));
+extern double fd_asin __P((double));
+extern double fd_atan __P((double));
+extern double fd_cos __P((double));
+extern double fd_sin __P((double));
+extern double fd_tan __P((double));
+
+extern double fd_exp __P((double));
+extern double fd_log __P((double));
+extern double fd_sqrt __P((double));
+
+extern double fd_ceil __P((double));
+extern double fd_fabs __P((double));
+extern double fd_floor __P((double));
+extern double fd_fmod __P((double, double));
+
+extern double fd_atan2 __P((double, double));
+extern double fd_pow __P((double, double));
+extern double fd_copysign __P((double, double));
+
+#endif
+
+#endif /* JS_USE_FDLIBM_MATH */
+
+#endif /* _LIBMATH_H */
+

Added: freeswitch/trunk/libs/js/src/jslock.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jslock.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1261 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef JS_THREADSAFE
+
+/*
+ * JS locking stubs.
+ */
+#include "jsstddef.h"
+#include <stdlib.h>
+#include "jspubtd.h"
+#include "prthread.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jstypes.h"
+#include "jsbit.h"
+#include "jscntxt.h"
+#include "jsdtoa.h"
+#include "jsgc.h"
+#include "jslock.h"
+#include "jsscope.h"
+#include "jsstr.h"
+
+#define ReadWord(W) (W)
+
+#ifndef NSPR_LOCK
+
+#include <memory.h>
+
+static PRLock **global_locks;
+static uint32 global_lock_count = 1;
+static uint32 global_locks_log2 = 0;
+static uint32 global_locks_mask = 0;
+
+#define GLOBAL_LOCK_INDEX(id)   (((uint32)(id) >> 2) & global_locks_mask)
+
+static void
+js_LockGlobal(void *id)
+{
+    uint32 i = GLOBAL_LOCK_INDEX(id);
+    PR_Lock(global_locks[i]);
+}
+
+static void
+js_UnlockGlobal(void *id)
+{
+    uint32 i = GLOBAL_LOCK_INDEX(id);
+    PR_Unlock(global_locks[i]);
+}
+
+/* Exclude Alpha NT. */
+#if defined(_WIN32) && defined(_M_IX86)
+#pragma warning( disable : 4035 )
+
+static JS_INLINE int
+js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
+{
+    __asm {
+        mov eax, ov
+        mov ecx, nv
+        mov ebx, w
+        lock cmpxchg [ebx], ecx
+        sete al
+        and eax, 1h
+    }
+}
+
+#elif defined(__GNUC__) && defined(__i386__)
+
+/* Note: This fails on 386 cpus, cmpxchgl is a >= 486 instruction */
+static JS_INLINE int
+js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
+{
+    unsigned int res;
+
+    __asm__ __volatile__ (
+                          "lock\n"
+                          "cmpxchgl %2, (%1)\n"
+                          "sete %%al\n"
+                          "andl $1, %%eax\n"
+                          : "=a" (res)
+                          : "r" (w), "r" (nv), "a" (ov)
+                          : "cc", "memory");
+    return (int)res;
+}
+
+#elif defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)
+
+static JS_INLINE int
+js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
+{
+#if defined(__GNUC__)
+    unsigned int res;
+    JS_ASSERT(ov != nv);
+    asm volatile ("\
+stbar\n\
+cas [%1],%2,%3\n\
+cmp %2,%3\n\
+be,a 1f\n\
+mov 1,%0\n\
+mov 0,%0\n\
+1:"
+                  : "=r" (res)
+                  : "r" (w), "r" (ov), "r" (nv));
+    return (int)res;
+#else /* !__GNUC__ */
+    extern int compare_and_swap(jsword*, jsword, jsword);
+    JS_ASSERT(ov != nv);
+    return compare_and_swap(w, ov, nv);
+#endif
+}
+
+#elif defined(AIX)
+
+#include <sys/atomic_op.h>
+
+static JS_INLINE int
+js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
+{
+    return !_check_lock((atomic_p)w, ov, nv);
+}
+
+#else
+
+#error "Define NSPR_LOCK if your platform lacks a compare-and-swap instruction."
+
+#endif /* arch-tests */
+
+#endif /* !NSPR_LOCK */
+
+jsword
+js_CurrentThreadId()
+{
+    return CurrentThreadId();
+}
+
+void
+js_InitLock(JSThinLock *tl)
+{
+#ifdef NSPR_LOCK
+    tl->owner = 0;
+    tl->fat = (JSFatLock*)JS_NEW_LOCK();
+#else
+    memset(tl, 0, sizeof(JSThinLock));
+#endif
+}
+
+void
+js_FinishLock(JSThinLock *tl)
+{
+#ifdef NSPR_LOCK
+    tl->owner = 0xdeadbeef;
+    if (tl->fat)
+        JS_DESTROY_LOCK(((JSLock*)tl->fat));
+#else
+    JS_ASSERT(tl->owner == 0);
+    JS_ASSERT(tl->fat == NULL);
+#endif
+}
+
+static void js_Dequeue(JSThinLock *);
+
+#ifdef DEBUG_SCOPE_COUNT
+
+#include <stdio.h>
+#include "jsdhash.h"
+
+static FILE *logfp;
+static JSDHashTable logtbl;
+
+typedef struct logentry {
+    JSDHashEntryStub stub;
+    char             op;
+    const char       *file;
+    int              line;
+} logentry;
+
+static void
+logit(JSScope *scope, char op, const char *file, int line)
+{
+    logentry *entry;
+
+    if (!logfp) {
+        logfp = fopen("/tmp/scope.log", "w");
+        if (!logfp)
+            return;
+        setvbuf(logfp, NULL, _IONBF, 0);
+    }
+    fprintf(logfp, "%p %c %s %d\n", scope, op, file, line);
+
+    if (!logtbl.entryStore &&
+        !JS_DHashTableInit(&logtbl, JS_DHashGetStubOps(), NULL,
+                           sizeof(logentry), 100)) {
+        return;
+    }
+    entry = (logentry *) JS_DHashTableOperate(&logtbl, scope, JS_DHASH_ADD);
+    if (!entry)
+        return;
+    entry->stub.key = scope;
+    entry->op = op;
+    entry->file = file;
+    entry->line = line;
+}
+
+void
+js_unlog_scope(JSScope *scope)
+{
+    if (!logtbl.entryStore)
+        return;
+    (void) JS_DHashTableOperate(&logtbl, scope, JS_DHASH_REMOVE);
+}
+
+# define LOGIT(scope,op) logit(scope, op, __FILE__, __LINE__)
+
+#else
+
+# define LOGIT(scope,op) /* nothing */
+
+#endif /* DEBUG_SCOPE_COUNT */
+
+/*
+ * Return true if scope's ownercx, or the ownercx of a single-threaded scope
+ * for which ownercx is waiting to become multi-threaded and shared, is cx.
+ * That condition implies deadlock in ClaimScope if cx's thread were to wait
+ * to share scope.
+ *
+ * (i) rt->gcLock held
+ */
+static JSBool
+WillDeadlock(JSScope *scope, JSContext *cx)
+{
+    JSContext *ownercx;
+
+    do {
+        ownercx = scope->ownercx;
+        if (ownercx == cx) {
+            JS_RUNTIME_METER(cx->runtime, deadlocksAvoided);
+            return JS_TRUE;
+        }
+    } while (ownercx && (scope = ownercx->scopeToShare) != NULL);
+    return JS_FALSE;
+}
+
+/*
+ * Make scope multi-threaded, i.e. share its ownership among contexts in rt
+ * using a "thin" or (if necessary due to contention) "fat" lock.  Called only
+ * from ClaimScope, immediately below, when we detect deadlock were we to wait
+ * for scope's lock, because its ownercx is waiting on a scope owned by the
+ * calling cx.
+ *
+ * (i) rt->gcLock held
+ */
+static void
+ShareScope(JSRuntime *rt, JSScope *scope)
+{
+    JSScope **todop;
+
+    if (scope->u.link) {
+        for (todop = &rt->scopeSharingTodo; *todop != scope;
+             todop = &(*todop)->u.link) {
+            JS_ASSERT(*todop != NO_SCOPE_SHARING_TODO);
+        }
+        *todop = scope->u.link;
+        scope->u.link = NULL;       /* null u.link for sanity ASAP */
+        JS_NOTIFY_ALL_CONDVAR(rt->scopeSharingDone);
+    }
+    js_InitLock(&scope->lock);
+    if (scope == rt->setSlotScope) {
+        /*
+         * Nesting locks on another thread that's using scope->ownercx: give
+         * the held lock a reentrancy count of 1 and set its lock.owner field
+         * directly (no compare-and-swap needed while scope->ownercx is still
+         * non-null).  See below in ClaimScope, before the ShareScope call,
+         * for more on why this is necessary.
+         *
+         * If NSPR_LOCK is defined, we cannot deadlock holding rt->gcLock and
+         * acquiring scope->lock.fat here, against another thread holding that
+         * fat lock and trying to grab rt->gcLock.  This is because no other
+         * thread can attempt to acquire scope->lock.fat until scope->ownercx
+         * is null *and* our thread has released rt->gcLock, which interlocks
+         * scope->ownercx's transition to null against tests of that member
+         * in ClaimScope.
+         */
+        scope->lock.owner = scope->ownercx->thread;
+#ifdef NSPR_LOCK
+        JS_ACQUIRE_LOCK((JSLock*)scope->lock.fat);
+#endif
+        scope->u.count = 1;
+    } else {
+        scope->u.count = 0;
+    }
+    js_FinishSharingScope(rt, scope);
+}
+
+/*
+ * js_FinishSharingScope is the tail part of ShareScope, split out to become a
+ * subroutine of JS_EndRequest too.  The bulk of the work here involves making
+ * mutable strings in the scope's object's slots be immutable.  We have to do
+ * this because such strings will soon be available to multiple threads, so
+ * their buffers can't be realloc'd any longer in js_ConcatStrings, and their
+ * members can't be modified by js_ConcatStrings, js_MinimizeDependentStrings,
+ * or js_UndependString.
+ *
+ * The last bit of work done by js_FinishSharingScope nulls scope->ownercx and
+ * updates rt->sharedScopes.
+ */
+#define MAKE_STRING_IMMUTABLE(rt, v, vp)                                      \
+    JS_BEGIN_MACRO                                                            \
+        JSString *str_ = JSVAL_TO_STRING(v);                                  \
+        uint8 *flagp_ = js_GetGCThingFlags(str_);                             \
+        if (*flagp_ & GCF_MUTABLE) {                                          \
+            if (JSSTRING_IS_DEPENDENT(str_) &&                                \
+                !js_UndependString(NULL, str_)) {                             \
+                JS_RUNTIME_METER(rt, badUndependStrings);                     \
+                *vp = JSVAL_VOID;                                             \
+            } else {                                                          \
+                *flagp_ &= ~GCF_MUTABLE;                                      \
+            }                                                                 \
+        }                                                                     \
+    JS_END_MACRO
+
+void
+js_FinishSharingScope(JSRuntime *rt, JSScope *scope)
+{
+    JSObject *obj;
+    uint32 nslots;
+    jsval v, *vp, *end;
+
+    obj = scope->object;
+    nslots = JS_MIN(obj->map->freeslot, obj->map->nslots);
+    for (vp = obj->slots, end = vp + nslots; vp < end; vp++) {
+        v = *vp;
+        if (JSVAL_IS_STRING(v))
+            MAKE_STRING_IMMUTABLE(rt, v, vp);
+    }
+
+    scope->ownercx = NULL;  /* NB: set last, after lock init */
+    JS_RUNTIME_METER(rt, sharedScopes);
+}
+
+/*
+ * Given a scope with apparently non-null ownercx different from cx, try to
+ * set ownercx to cx, claiming exclusive (single-threaded) ownership of scope.
+ * If we claim ownership, return true.  Otherwise, we wait for ownercx to be
+ * set to null (indicating that scope is multi-threaded); or if waiting would
+ * deadlock, we set ownercx to null ourselves via ShareScope.  In any case,
+ * once ownercx is null we return false.
+ */
+static JSBool
+ClaimScope(JSScope *scope, JSContext *cx)
+{
+    JSRuntime *rt;
+    JSContext *ownercx;
+    jsrefcount saveDepth;
+    PRStatus stat;
+
+    rt = cx->runtime;
+    JS_RUNTIME_METER(rt, claimAttempts);
+    JS_LOCK_GC(rt);
+
+    /* Reload in case ownercx went away while we blocked on the lock. */
+    while ((ownercx = scope->ownercx) != NULL) {
+        /*
+         * Avoid selflock if ownercx is dead, or is not running a request, or
+         * has the same thread as cx.  Set scope->ownercx to cx so that the
+         * matching JS_UNLOCK_SCOPE or JS_UNLOCK_OBJ macro call will take the
+         * fast path around the corresponding js_UnlockScope or js_UnlockObj
+         * function call.
+         *
+         * If scope->u.link is non-null, scope has already been inserted on
+         * the rt->scopeSharingTodo list, because another thread's context
+         * already wanted to lock scope while ownercx was running a request.
+         * We can't claim any scope whose u.link is non-null at this point,
+         * even if ownercx->requestDepth is 0 (see below where we suspend our
+         * request before waiting on rt->scopeSharingDone).
+         */
+        if (!scope->u.link &&
+            (!js_ValidContextPointer(rt, ownercx) ||
+             !ownercx->requestDepth ||
+             ownercx->thread == cx->thread)) {
+            JS_ASSERT(scope->u.count == 0);
+            scope->ownercx = cx;
+            JS_UNLOCK_GC(rt);
+            JS_RUNTIME_METER(rt, claimedScopes);
+            return JS_TRUE;
+        }
+
+        /*
+         * Avoid deadlock if scope's owner context is waiting on a scope that
+         * we own, by revoking scope's ownership.  This approach to deadlock
+         * avoidance works because the engine never nests scope locks, except
+         * for the notable case of js_SetProtoOrParent (see jsobj.c).
+         *
+         * If cx could hold locks on ownercx->scopeToShare, or if ownercx
+         * could hold locks on scope, we would need to keep reentrancy counts
+         * for all such "flyweight" (ownercx != NULL) locks, so that control
+         * would unwind properly once these locks became "thin" or "fat".
+         * Apart from the js_SetProtoOrParent exception, the engine promotes
+         * a scope from exclusive to shared access only when locking, never
+         * when holding or unlocking.
+         *
+         * If ownercx's thread is calling js_SetProtoOrParent, trying to lock
+         * the inner scope (the scope of the object being set as the prototype
+         * of the outer object), ShareScope will find the outer object's scope
+         * at rt->setSlotScope.  If it's the same as scope, we give it a lock
+         * held by ownercx's thread with reentrancy count of 1, then we return
+         * here and break.  After that we unwind to js_[GS]etSlotThreadSafe or
+         * js_LockScope (our caller), where we wait on the newly-fattened lock
+         * until ownercx's thread unwinds from js_SetProtoOrParent.
+         *
+         * Avoid deadlock before any of this scope/context cycle detection if
+         * cx is on the active GC's thread, because in that case, no requests
+         * will run until the GC completes.  Any scope wanted by the GC (from
+         * a finalizer) that can't be claimed must be slated for sharing.
+         */
+        if (rt->gcThread == cx->thread ||
+            (ownercx->scopeToShare &&
+             WillDeadlock(ownercx->scopeToShare, cx))) {
+            ShareScope(rt, scope);
+            break;
+        }
+
+        /*
+         * Thanks to the non-zero NO_SCOPE_SHARING_TODO link terminator, we
+         * can decide whether scope is on rt->scopeSharingTodo with a single
+         * non-null test, and avoid double-insertion bugs.
+         */
+        if (!scope->u.link) {
+            scope->u.link = rt->scopeSharingTodo;
+            rt->scopeSharingTodo = scope;
+            js_HoldObjectMap(cx, &scope->map);
+        }
+
+        /*
+         * Inline JS_SuspendRequest before we wait on rt->scopeSharingDone,
+         * saving and clearing cx->requestDepth so we don't deadlock if the
+         * GC needs to run on ownercx.
+         *
+         * Unlike JS_SuspendRequest and JS_EndRequest, we must take care not
+         * to decrement rt->requestCount if cx is active on the GC's thread,
+         * because the GC has already reduced rt->requestCount to exclude all
+         * such such contexts.
+         */
+        saveDepth = cx->requestDepth;
+        if (saveDepth) {
+            cx->requestDepth = 0;
+            if (rt->gcThread != cx->thread) {
+                JS_ASSERT(rt->requestCount > 0);
+                rt->requestCount--;
+                if (rt->requestCount == 0)
+                    JS_NOTIFY_REQUEST_DONE(rt);
+            }
+        }
+
+        /*
+         * We know that some other thread's context owns scope, which is now
+         * linked onto rt->scopeSharingTodo, awaiting the end of that other
+         * thread's request.  So it is safe to wait on rt->scopeSharingDone.
+         */
+        cx->scopeToShare = scope;
+        stat = PR_WaitCondVar(rt->scopeSharingDone, PR_INTERVAL_NO_TIMEOUT);
+        JS_ASSERT(stat != PR_FAILURE);
+
+        /*
+         * Inline JS_ResumeRequest after waiting on rt->scopeSharingDone,
+         * restoring cx->requestDepth.  Same note as above for the inlined,
+         * specialized JS_SuspendRequest code: beware rt->gcThread.
+         */
+        if (saveDepth) {
+            if (rt->gcThread != cx->thread) {
+                while (rt->gcLevel > 0)
+                    JS_AWAIT_GC_DONE(rt);
+                rt->requestCount++;
+            }
+            cx->requestDepth = saveDepth;
+        }
+
+        /*
+         * Don't clear cx->scopeToShare until after we're through waiting on
+         * all condition variables protected by rt->gcLock -- that includes
+         * rt->scopeSharingDone *and* rt->gcDone (hidden in JS_AWAIT_GC_DONE,
+         * in the inlined JS_ResumeRequest code immediately above).
+         *
+         * Otherwise, the GC could easily deadlock with another thread that
+         * owns a scope wanted by a finalizer.  By keeping cx->scopeToShare
+         * set till here, we ensure that such deadlocks are detected, which
+         * results in the finalized object's scope being shared (it must, of
+         * course, have other, live objects sharing it).
+         */
+        cx->scopeToShare = NULL;
+    }
+
+    JS_UNLOCK_GC(rt);
+    return JS_FALSE;
+}
+
+/* Exported to js.c, which calls it via OBJ_GET_* and JSVAL_IS_* macros. */
+JS_FRIEND_API(jsval)
+js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot)
+{
+    jsval v;
+    JSScope *scope;
+#ifndef NSPR_LOCK
+    JSThinLock *tl;
+    jsword me;
+#endif
+
+    /*
+     * We handle non-native objects via JSObjectOps.getRequiredSlot, treating
+     * all slots starting from 0 as required slots.  A property definition or
+     * some prior arrangement must have allocated slot.
+     *
+     * Note once again (see jspubtd.h, before JSGetRequiredSlotOp's typedef)
+     * the crucial distinction between a |required slot number| that's passed
+     * to the get/setRequiredSlot JSObjectOps, and a |reserved slot index|
+     * passed to the JS_Get/SetReservedSlot APIs.
+     */
+    if (!OBJ_IS_NATIVE(obj))
+        return OBJ_GET_REQUIRED_SLOT(cx, obj, slot);
+
+    /*
+     * Native object locking is inlined here to optimize the single-threaded
+     * and contention-free multi-threaded cases.
+     */
+    scope = OBJ_SCOPE(obj);
+    JS_ASSERT(scope->ownercx != cx);
+    JS_ASSERT(obj->slots && slot < obj->map->freeslot);
+
+    /*
+     * Avoid locking if called from the GC (see GC_AWARE_GET_SLOT in jsobj.h).
+     * Also avoid locking an object owning a sealed scope.  If neither of those
+     * special cases applies, try to claim scope's flyweight lock from whatever
+     * context may have had it in an earlier request.
+     */
+    if (CX_THREAD_IS_RUNNING_GC(cx) ||
+        (SCOPE_IS_SEALED(scope) && scope->object == obj) ||
+        (scope->ownercx && ClaimScope(scope, cx))) {
+        return obj->slots[slot];
+    }
+
+#ifndef NSPR_LOCK
+    tl = &scope->lock;
+    me = cx->thread;
+    JS_ASSERT(me == CurrentThreadId());
+    if (js_CompareAndSwap(&tl->owner, 0, me)) {
+        /*
+         * Got the lock with one compare-and-swap.  Even so, someone else may
+         * have mutated obj so it now has its own scope and lock, which would
+         * require either a restart from the top of this routine, or a thin
+         * lock release followed by fat lock acquisition.
+         */
+        if (scope == OBJ_SCOPE(obj)) {
+            v = obj->slots[slot];
+            if (!js_CompareAndSwap(&tl->owner, me, 0)) {
+                /* Assert that scope locks never revert to flyweight. */
+                JS_ASSERT(scope->ownercx != cx);
+                LOGIT(scope, '1');
+                scope->u.count = 1;
+                js_UnlockObj(cx, obj);
+            }
+            return v;
+        }
+        if (!js_CompareAndSwap(&tl->owner, me, 0))
+            js_Dequeue(tl);
+    }
+    else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) {
+        return obj->slots[slot];
+    }
+#endif
+
+    js_LockObj(cx, obj);
+    v = obj->slots[slot];
+
+    /*
+     * Test whether cx took ownership of obj's scope during js_LockObj.
+     *
+     * This does not mean that a given scope reverted to flyweight from "thin"
+     * or "fat" -- it does mean that obj's map pointer changed due to another
+     * thread setting a property, requiring obj to cease sharing a prototype
+     * object's scope (whose lock was not flyweight, else we wouldn't be here
+     * in the first place!).
+     */
+    scope = OBJ_SCOPE(obj);
+    if (scope->ownercx != cx)
+        js_UnlockScope(cx, scope);
+    return v;
+}
+
+void
+js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
+{
+    JSScope *scope;
+#ifndef NSPR_LOCK
+    JSThinLock *tl;
+    jsword me;
+#endif
+
+    /* Any string stored in a thread-safe object must be immutable. */
+    if (JSVAL_IS_STRING(v))
+        MAKE_STRING_IMMUTABLE(cx->runtime, v, &v);
+
+    /*
+     * We handle non-native objects via JSObjectOps.setRequiredSlot, as above
+     * for the Get case.
+     */
+    if (!OBJ_IS_NATIVE(obj)) {
+        OBJ_SET_REQUIRED_SLOT(cx, obj, slot, v);
+        return;
+    }
+
+    /*
+     * Native object locking is inlined here to optimize the single-threaded
+     * and contention-free multi-threaded cases.
+     */
+    scope = OBJ_SCOPE(obj);
+    JS_ASSERT(scope->ownercx != cx);
+    JS_ASSERT(obj->slots && slot < obj->map->freeslot);
+
+    /*
+     * Avoid locking if called from the GC (see GC_AWARE_GET_SLOT in jsobj.h).
+     * Also avoid locking an object owning a sealed scope.  If neither of those
+     * special cases applies, try to claim scope's flyweight lock from whatever
+     * context may have had it in an earlier request.
+     */
+    if (CX_THREAD_IS_RUNNING_GC(cx) ||
+        (SCOPE_IS_SEALED(scope) && scope->object == obj) ||
+        (scope->ownercx && ClaimScope(scope, cx))) {
+        obj->slots[slot] = v;
+        return;
+    }
+
+#ifndef NSPR_LOCK
+    tl = &scope->lock;
+    me = cx->thread;
+    JS_ASSERT(me == CurrentThreadId());
+    if (js_CompareAndSwap(&tl->owner, 0, me)) {
+        if (scope == OBJ_SCOPE(obj)) {
+            obj->slots[slot] = v;
+            if (!js_CompareAndSwap(&tl->owner, me, 0)) {
+                /* Assert that scope locks never revert to flyweight. */
+                JS_ASSERT(scope->ownercx != cx);
+                LOGIT(scope, '1');
+                scope->u.count = 1;
+                js_UnlockObj(cx, obj);
+            }
+            return;
+        }
+        if (!js_CompareAndSwap(&tl->owner, me, 0))
+            js_Dequeue(tl);
+    }
+    else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) {
+        obj->slots[slot] = v;
+        return;
+    }
+#endif
+
+    js_LockObj(cx, obj);
+    obj->slots[slot] = v;
+
+    /*
+     * Same drill as above, in js_GetSlotThreadSafe.  Note that we cannot
+     * assume obj has its own mutable scope (where scope->object == obj) yet,
+     * because OBJ_SET_SLOT is called for the "universal", common slots such
+     * as JSSLOT_PROTO and JSSLOT_PARENT, without a prior js_GetMutableScope.
+     * See also the JSPROP_SHARED attribute and its usage.
+     */
+    scope = OBJ_SCOPE(obj);
+    if (scope->ownercx != cx)
+        js_UnlockScope(cx, scope);
+}
+
+#ifndef NSPR_LOCK
+
+static JSFatLock *
+NewFatlock()
+{
+    JSFatLock *fl = (JSFatLock *)malloc(sizeof(JSFatLock)); /* for now */
+    if (!fl) return NULL;
+    fl->susp = 0;
+    fl->next = NULL;
+    fl->prevp = NULL;
+    fl->slock = PR_NewLock();
+    fl->svar = PR_NewCondVar(fl->slock);
+    return fl;
+}
+
+static void
+DestroyFatlock(JSFatLock *fl)
+{
+    PR_DestroyLock(fl->slock);
+    PR_DestroyCondVar(fl->svar);
+    free(fl);
+}
+
+static JSFatLock *
+ListOfFatlocks(int listc)
+{
+    JSFatLock *m;
+    JSFatLock *m0;
+    int i;
+
+    JS_ASSERT(listc>0);
+    m0 = m = NewFatlock();
+    for (i=1; i<listc; i++) {
+        m->next = NewFatlock();
+        m = m->next;
+    }
+    return m0;
+}
+
+static void
+DeleteListOfFatlocks(JSFatLock *m)
+{
+    JSFatLock *m0;
+    for (; m; m=m0) {
+        m0 = m->next;
+        DestroyFatlock(m);
+    }
+}
+
+static JSFatLockTable *fl_list_table = NULL;
+static uint32          fl_list_table_len = 0;
+static uint32          fl_list_chunk_len = 0;
+
+static JSFatLock *
+GetFatlock(void *id)
+{
+    JSFatLock *m;
+
+    uint32 i = GLOBAL_LOCK_INDEX(id);
+    if (fl_list_table[i].free == NULL) {
+#ifdef DEBUG
+        if (fl_list_table[i].taken)
+            printf("Ran out of fat locks!\n");
+#endif
+        fl_list_table[i].free = ListOfFatlocks(fl_list_chunk_len);
+    }
+    m = fl_list_table[i].free;
+    fl_list_table[i].free = m->next;
+    m->susp = 0;
+    m->next = fl_list_table[i].taken;
+    m->prevp = &fl_list_table[i].taken;
+    if (fl_list_table[i].taken)
+        fl_list_table[i].taken->prevp = &m->next;
+    fl_list_table[i].taken = m;
+    return m;
+}
+
+static void
+PutFatlock(JSFatLock *m, void *id)
+{
+    uint32 i;
+    if (m == NULL)
+        return;
+
+    /* Unlink m from fl_list_table[i].taken. */
+    *m->prevp = m->next;
+    if (m->next)
+        m->next->prevp = m->prevp;
+
+    /* Insert m in fl_list_table[i].free. */
+    i = GLOBAL_LOCK_INDEX(id);
+    m->next = fl_list_table[i].free;
+    fl_list_table[i].free = m;
+}
+
+#endif /* !NSPR_LOCK */
+
+JSBool
+js_SetupLocks(int listc, int globc)
+{
+#ifndef NSPR_LOCK
+    uint32 i;
+
+    if (global_locks)
+        return JS_TRUE;
+#ifdef DEBUG
+    if (listc > 10000 || listc < 0) /* listc == fat lock list chunk length */
+        printf("Bad number %d in js_SetupLocks()!\n", listc);
+    if (globc > 100 || globc < 0)   /* globc == number of global locks */
+        printf("Bad number %d in js_SetupLocks()!\n", listc);
+#endif
+    global_locks_log2 = JS_CeilingLog2(globc);
+    global_locks_mask = JS_BITMASK(global_locks_log2);
+    global_lock_count = JS_BIT(global_locks_log2);
+    global_locks = (PRLock **) malloc(global_lock_count * sizeof(PRLock*));
+    if (!global_locks)
+        return JS_FALSE;
+    for (i = 0; i < global_lock_count; i++) {
+        global_locks[i] = PR_NewLock();
+        if (!global_locks[i]) {
+            global_lock_count = i;
+            js_CleanupLocks();
+            return JS_FALSE;
+        }
+    }
+    fl_list_table = (JSFatLockTable *) malloc(i * sizeof(JSFatLockTable));
+    if (!fl_list_table) {
+        js_CleanupLocks();
+        return JS_FALSE;
+    }
+    fl_list_table_len = global_lock_count;
+    for (i = 0; i < global_lock_count; i++)
+        fl_list_table[i].free = fl_list_table[i].taken = NULL;
+    fl_list_chunk_len = listc;
+#endif /* !NSPR_LOCK */
+    return JS_TRUE;
+}
+
+void
+js_CleanupLocks()
+{
+#ifndef NSPR_LOCK
+    uint32 i;
+
+    if (global_locks) {
+        for (i = 0; i < global_lock_count; i++)
+            PR_DestroyLock(global_locks[i]);
+        free(global_locks);
+        global_locks = NULL;
+        global_lock_count = 1;
+        global_locks_log2 = 0;
+        global_locks_mask = 0;
+    }
+    if (fl_list_table) {
+        for (i = 0; i < fl_list_table_len; i++) {
+            DeleteListOfFatlocks(fl_list_table[i].free);
+            fl_list_table[i].free = NULL;
+            DeleteListOfFatlocks(fl_list_table[i].taken);
+            fl_list_table[i].taken = NULL;
+        }
+        free(fl_list_table);
+        fl_list_table = NULL;
+        fl_list_table_len = 0;
+    }
+#endif /* !NSPR_LOCK */
+}
+
+void
+js_InitContextForLocking(JSContext *cx)
+{
+    cx->thread = CurrentThreadId();
+    JS_ASSERT(Thin_GetWait(cx->thread) == 0);
+}
+
+#ifndef NSPR_LOCK
+
+/*
+ * Fast locking and unlocking is implemented by delaying the allocation of a
+ * system lock (fat lock) until contention.  As long as a locking thread A
+ * runs uncontended, the lock is represented solely by storing A's identity in
+ * the object being locked.
+ *
+ * If another thread B tries to lock the object currently locked by A, B is
+ * enqueued into a fat lock structure (which might have to be allocated and
+ * pointed to by the object), and suspended using NSPR conditional variables
+ * (wait).  A wait bit (Bacon bit) is set in the lock word of the object,
+ * signalling to A that when releasing the lock, B must be dequeued and
+ * notified.
+ *
+ * The basic operation of the locking primitives (js_Lock, js_Unlock,
+ * js_Enqueue, and js_Dequeue) is compare-and-swap.  Hence, when locking into
+ * the word pointed at by p, compare-and-swap(p, 0, A) success implies that p
+ * is unlocked.  Similarly, when unlocking p, if compare-and-swap(p, A, 0)
+ * succeeds this implies that p is uncontended (no one is waiting because the
+ * wait bit is not set).
+ *
+ * When dequeueing, the lock is released, and one of the threads suspended on
+ * the lock is notified.  If other threads still are waiting, the wait bit is
+ * kept (in js_Enqueue), and if not, the fat lock is deallocated.
+ *
+ * The functions js_Enqueue, js_Dequeue, js_SuspendThread, and js_ResumeThread
+ * are serialized using a global lock.  For scalability, a hashtable of global
+ * locks is used, which is indexed modulo the thin lock pointer.
+ */
+
+/*
+ * Invariants:
+ * (i)  global lock is held
+ * (ii) fl->susp >= 0
+ */
+static int
+js_SuspendThread(JSThinLock *tl)
+{
+    JSFatLock *fl;
+    PRStatus stat;
+
+    if (tl->fat == NULL)
+        fl = tl->fat = GetFatlock(tl);
+    else
+        fl = tl->fat;
+    JS_ASSERT(fl->susp >= 0);
+    fl->susp++;
+    PR_Lock(fl->slock);
+    js_UnlockGlobal(tl);
+    stat = PR_WaitCondVar(fl->svar, PR_INTERVAL_NO_TIMEOUT);
+    JS_ASSERT(stat != PR_FAILURE);
+    PR_Unlock(fl->slock);
+    js_LockGlobal(tl);
+    fl->susp--;
+    if (fl->susp == 0) {
+        PutFatlock(fl, tl);
+        tl->fat = NULL;
+    }
+    return tl->fat == NULL;
+}
+
+/*
+ * (i)  global lock is held
+ * (ii) fl->susp > 0
+ */
+static void
+js_ResumeThread(JSThinLock *tl)
+{
+    JSFatLock *fl = tl->fat;
+    PRStatus stat;
+
+    JS_ASSERT(fl != NULL);
+    JS_ASSERT(fl->susp > 0);
+    PR_Lock(fl->slock);
+    js_UnlockGlobal(tl);
+    stat = PR_NotifyCondVar(fl->svar);
+    JS_ASSERT(stat != PR_FAILURE);
+    PR_Unlock(fl->slock);
+}
+
+static void
+js_Enqueue(JSThinLock *tl, jsword me)
+{
+    jsword o, n;
+
+    js_LockGlobal(tl);
+    for (;;) {
+        o = ReadWord(tl->owner);
+        n = Thin_SetWait(o);
+        if (o != 0 && js_CompareAndSwap(&tl->owner, o, n)) {
+            if (js_SuspendThread(tl))
+                me = Thin_RemoveWait(me);
+            else
+                me = Thin_SetWait(me);
+        }
+        else if (js_CompareAndSwap(&tl->owner, 0, me)) {
+            js_UnlockGlobal(tl);
+            return;
+        }
+    }
+}
+
+static void
+js_Dequeue(JSThinLock *tl)
+{
+    jsword o;
+
+    js_LockGlobal(tl);
+    o = ReadWord(tl->owner);
+    JS_ASSERT(Thin_GetWait(o) != 0);
+    JS_ASSERT(tl->fat != NULL);
+    if (!js_CompareAndSwap(&tl->owner, o, 0)) /* release it */
+        JS_ASSERT(0);
+    js_ResumeThread(tl);
+}
+
+JS_INLINE void
+js_Lock(JSThinLock *tl, jsword me)
+{
+    JS_ASSERT(me == CurrentThreadId());
+    if (js_CompareAndSwap(&tl->owner, 0, me))
+        return;
+    if (Thin_RemoveWait(ReadWord(tl->owner)) != me)
+        js_Enqueue(tl, me);
+#ifdef DEBUG
+    else
+        JS_ASSERT(0);
+#endif
+}
+
+JS_INLINE void
+js_Unlock(JSThinLock *tl, jsword me)
+{
+    JS_ASSERT(me == CurrentThreadId());
+    if (js_CompareAndSwap(&tl->owner, me, 0))
+        return;
+    if (Thin_RemoveWait(ReadWord(tl->owner)) == me)
+        js_Dequeue(tl);
+#ifdef DEBUG
+    else
+        JS_ASSERT(0);
+#endif
+}
+
+#endif /* !NSPR_LOCK */
+
+void
+js_LockRuntime(JSRuntime *rt)
+{
+    PR_Lock(rt->rtLock);
+#ifdef DEBUG
+    rt->rtLockOwner = CurrentThreadId();
+#endif
+}
+
+void
+js_UnlockRuntime(JSRuntime *rt)
+{
+#ifdef DEBUG
+    rt->rtLockOwner = 0;
+#endif
+    PR_Unlock(rt->rtLock);
+}
+
+void
+js_LockScope(JSContext *cx, JSScope *scope)
+{
+    jsword me = cx->thread;
+
+    JS_ASSERT(me == CurrentThreadId());
+    JS_ASSERT(scope->ownercx != cx);
+    if (CX_THREAD_IS_RUNNING_GC(cx))
+        return;
+    if (scope->ownercx && ClaimScope(scope, cx))
+        return;
+
+    if (Thin_RemoveWait(ReadWord(scope->lock.owner)) == me) {
+        JS_ASSERT(scope->u.count > 0);
+        LOGIT(scope, '+');
+        scope->u.count++;
+    } else {
+        JSThinLock *tl = &scope->lock;
+        JS_LOCK0(tl, me);
+        JS_ASSERT(scope->u.count == 0);
+        LOGIT(scope, '1');
+        scope->u.count = 1;
+    }
+}
+
+void
+js_UnlockScope(JSContext *cx, JSScope *scope)
+{
+    jsword me = cx->thread;
+
+    /* We hope compilers use me instead of reloading cx->thread in the macro. */
+    if (CX_THREAD_IS_RUNNING_GC(cx))
+        return;
+    if (cx->lockedSealedScope == scope) {
+        cx->lockedSealedScope = NULL;
+        return;
+    }
+
+    /*
+     * If scope->ownercx is not null, it's likely that two contexts not using
+     * requests nested locks for scope.  The first context, cx here, claimed
+     * scope; the second, scope->ownercx here, re-claimed it because the first
+     * was not in a request, or was on the same thread.  We don't want to keep
+     * track of such nesting, because it penalizes the common non-nested case.
+     * Instead of asserting here and silently coping, we simply re-claim scope
+     * for cx and return.
+     *
+     * See http://bugzilla.mozilla.org/show_bug.cgi?id=229200 for a real world
+     * case where an asymmetric thread model (Mozilla's main thread is known
+     * to be the only thread that runs the GC) combined with multiple contexts
+     * per thread has led to such request-less nesting.
+     */
+    if (scope->ownercx) {
+        JS_ASSERT(scope->u.count == 0);
+        JS_ASSERT(scope->lock.owner == 0);
+        scope->ownercx = cx;
+        return;
+    }
+
+    JS_ASSERT(scope->u.count > 0);
+    if (Thin_RemoveWait(ReadWord(scope->lock.owner)) != me) {
+        JS_ASSERT(0);   /* unbalanced unlock */
+        return;
+    }
+    LOGIT(scope, '-');
+    if (--scope->u.count == 0) {
+        JSThinLock *tl = &scope->lock;
+        JS_UNLOCK0(tl, me);
+    }
+}
+
+/*
+ * NB: oldscope may be null if our caller is js_GetMutableScope and it just
+ * dropped the last reference to oldscope.
+ */
+void
+js_TransferScopeLock(JSContext *cx, JSScope *oldscope, JSScope *newscope)
+{
+    jsword me;
+    JSThinLock *tl;
+
+    JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, newscope));
+
+    /*
+     * If the last reference to oldscope went away, newscope needs no lock
+     * state update.
+     */
+    if (!oldscope)
+        return;
+    JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, oldscope));
+
+    /*
+     * Special case in js_LockScope and js_UnlockScope for the GC calling
+     * code that locks, unlocks, or mutates.  Nothing to do in these cases,
+     * because scope and newscope were "locked" by the GC thread, so neither
+     * was actually locked.
+     */
+    if (CX_THREAD_IS_RUNNING_GC(cx))
+        return;
+
+    /*
+     * Special case in js_LockObj and js_UnlockScope for locking the sealed
+     * scope of an object that owns that scope (the prototype or mutated obj
+     * for which OBJ_SCOPE(obj)->object == obj), and unlocking it.
+     */
+    JS_ASSERT(cx->lockedSealedScope != newscope);
+    if (cx->lockedSealedScope == oldscope) {
+        JS_ASSERT(newscope->ownercx == cx ||
+                  (!newscope->ownercx && newscope->u.count == 1));
+        cx->lockedSealedScope = NULL;
+        return;
+    }
+
+    /*
+     * If oldscope is single-threaded, there's nothing to do.
+     */
+    if (oldscope->ownercx) {
+        JS_ASSERT(oldscope->ownercx == cx);
+        JS_ASSERT(newscope->ownercx == cx ||
+                  (!newscope->ownercx && newscope->u.count == 1));
+        return;
+    }
+
+    /*
+     * We transfer oldscope->u.count only if newscope is not single-threaded.
+     * Flow unwinds from here through some number of JS_UNLOCK_SCOPE and/or
+     * JS_UNLOCK_OBJ macro calls, which will decrement newscope->u.count only
+     * if they find newscope->ownercx != cx.
+     */
+    if (newscope->ownercx != cx) {
+        JS_ASSERT(!newscope->ownercx);
+        newscope->u.count = oldscope->u.count;
+    }
+
+    /*
+     * Reset oldscope's lock state so that it is completely unlocked.
+     */
+    LOGIT(oldscope, '0');
+    oldscope->u.count = 0;
+    tl = &oldscope->lock;
+    me = cx->thread;
+    JS_UNLOCK0(tl, me);
+}
+
+void
+js_LockObj(JSContext *cx, JSObject *obj)
+{
+    JSScope *scope;
+
+    JS_ASSERT(OBJ_IS_NATIVE(obj));
+    for (;;) {
+        scope = OBJ_SCOPE(obj);
+        if (SCOPE_IS_SEALED(scope) && scope->object == obj &&
+            !cx->lockedSealedScope) {
+            cx->lockedSealedScope = scope;
+            return;
+        }
+
+        js_LockScope(cx, scope);
+
+        /* If obj still has this scope, we're done. */
+        if (scope == OBJ_SCOPE(obj))
+            return;
+
+        /* Lost a race with a mutator; retry with obj's new scope. */
+        js_UnlockScope(cx, scope);
+    }
+}
+
+void
+js_UnlockObj(JSContext *cx, JSObject *obj)
+{
+    JS_ASSERT(OBJ_IS_NATIVE(obj));
+    js_UnlockScope(cx, OBJ_SCOPE(obj));
+}
+
+#ifdef DEBUG
+
+JSBool
+js_IsRuntimeLocked(JSRuntime *rt)
+{
+    return CurrentThreadId() == rt->rtLockOwner;
+}
+
+JSBool
+js_IsObjLocked(JSContext *cx, JSObject *obj)
+{
+    JSScope *scope = OBJ_SCOPE(obj);
+
+    return MAP_IS_NATIVE(&scope->map) && js_IsScopeLocked(cx, scope);
+}
+
+JSBool
+js_IsScopeLocked(JSContext *cx, JSScope *scope)
+{
+    /* Special case: the GC locking any object's scope, see js_LockScope. */
+    if (CX_THREAD_IS_RUNNING_GC(cx))
+        return JS_TRUE;
+
+    /* Special case: locked object owning a sealed scope, see js_LockObj. */
+    if (cx->lockedSealedScope == scope)
+        return JS_TRUE;
+
+    /*
+     * General case: the scope is either exclusively owned (by cx), or it has
+     * a thin or fat lock to cope with shared (concurrent) ownership.
+     */
+    if (scope->ownercx) {
+        JS_ASSERT(scope->ownercx == cx);
+        return JS_TRUE;
+    }
+    return CurrentThreadId() == Thin_RemoveWait(ReadWord(scope->lock.owner));
+}
+
+#endif /* DEBUG */
+#endif /* JS_THREADSAFE */

Added: freeswitch/trunk/libs/js/src/jslock.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jslock.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,261 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef jslock_h__
+#define jslock_h__
+
+#ifdef JS_THREADSAFE
+
+#include "jstypes.h"
+#include "pratom.h"
+#include "prlock.h"
+#include "prcvar.h"
+
+#include "jsprvtd.h"    /* for JSScope, etc. */
+#include "jspubtd.h"    /* for JSRuntime, etc. */
+
+#define Thin_GetWait(W) ((jsword)(W) & 0x1)
+#define Thin_SetWait(W) ((jsword)(W) | 0x1)
+#define Thin_RemoveWait(W) ((jsword)(W) & ~0x1)
+
+typedef struct JSFatLock JSFatLock;
+
+struct JSFatLock {
+    int         susp;
+    PRLock      *slock;
+    PRCondVar   *svar;
+    JSFatLock   *next;
+    JSFatLock   **prevp;
+};
+
+typedef struct JSThinLock {
+    jsword      owner;
+    JSFatLock   *fat;
+} JSThinLock;
+
+typedef PRLock JSLock;
+
+typedef struct JSFatLockTable {
+    JSFatLock   *free;
+    JSFatLock   *taken;
+} JSFatLockTable;
+
+/*
+ * Atomic increment and decrement for a reference counter, given jsrefcount *p.
+ * NB: jsrefcount is int32, aka PRInt32, so that pratom.h functions work.
+ */
+#define JS_ATOMIC_INCREMENT(p)      PR_AtomicIncrement((PRInt32 *)(p))
+#define JS_ATOMIC_DECREMENT(p)      PR_AtomicDecrement((PRInt32 *)(p))
+#define JS_ATOMIC_ADD(p,v)          PR_AtomicAdd((PRInt32 *)(p), (PRInt32)(v))
+
+#define CurrentThreadId()           (jsword)PR_GetCurrentThread()
+#define JS_CurrentThreadId()        js_CurrentThreadId()
+#define JS_NEW_LOCK()               PR_NewLock()
+#define JS_DESTROY_LOCK(l)          PR_DestroyLock(l)
+#define JS_ACQUIRE_LOCK(l)          PR_Lock(l)
+#define JS_RELEASE_LOCK(l)          PR_Unlock(l)
+#define JS_LOCK0(P,M)               js_Lock(P,M)
+#define JS_UNLOCK0(P,M)             js_Unlock(P,M)
+
+#define JS_NEW_CONDVAR(l)           PR_NewCondVar(l)
+#define JS_DESTROY_CONDVAR(cv)      PR_DestroyCondVar(cv)
+#define JS_WAIT_CONDVAR(cv,to)      PR_WaitCondVar(cv,to)
+#define JS_NO_TIMEOUT               PR_INTERVAL_NO_TIMEOUT
+#define JS_NOTIFY_CONDVAR(cv)       PR_NotifyCondVar(cv)
+#define JS_NOTIFY_ALL_CONDVAR(cv)   PR_NotifyAllCondVar(cv)
+
+/*
+ * Include jsscope.h so JS_LOCK_OBJ macro callers don't have to include it.
+ * Since there is a JSThinLock member in JSScope, we can't nest this include
+ * much earlier (see JSThinLock's typedef, above).  Yes, that means there is
+ * an #include cycle between jslock.h and jsscope.h: moderate-sized XXX here,
+ * to be fixed by moving JS_LOCK_SCOPE to jsscope.h, JS_LOCK_OBJ to jsobj.h,
+ * and so on.
+ */
+#include "jsscope.h"
+
+#define JS_LOCK_RUNTIME(rt)         js_LockRuntime(rt)
+#define JS_UNLOCK_RUNTIME(rt)       js_UnlockRuntime(rt)
+
+/*
+ * NB: The JS_LOCK_OBJ and JS_UNLOCK_OBJ macros work *only* on native objects
+ * (objects for which OBJ_IS_NATIVE returns true).  All uses of these macros in
+ * the engine are predicated on OBJ_IS_NATIVE or equivalent checks.  These uses
+ * are for optimizations above the JSObjectOps layer, under which object locks
+ * normally hide.
+ */
+#define JS_LOCK_OBJ(cx,obj)         ((OBJ_SCOPE(obj)->ownercx == (cx))        \
+                                     ? (void)0                                \
+                                     : (js_LockObj(cx, obj)))
+#define JS_UNLOCK_OBJ(cx,obj)       ((OBJ_SCOPE(obj)->ownercx == (cx))        \
+                                     ? (void)0 : js_UnlockObj(cx, obj))
+
+#define JS_LOCK_SCOPE(cx,scope)     ((scope)->ownercx == (cx) ? (void)0       \
+                                     : js_LockScope(cx, scope))
+#define JS_UNLOCK_SCOPE(cx,scope)   ((scope)->ownercx == (cx) ? (void)0       \
+                                     : js_UnlockScope(cx, scope))
+#define JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope)                           \
+                                    js_TransferScopeLock(cx, scope, newscope)
+
+extern jsword js_CurrentThreadId();
+extern void js_LockRuntime(JSRuntime *rt);
+extern void js_UnlockRuntime(JSRuntime *rt);
+extern void js_LockObj(JSContext *cx, JSObject *obj);
+extern void js_UnlockObj(JSContext *cx, JSObject *obj);
+extern void js_LockScope(JSContext *cx, JSScope *scope);
+extern void js_UnlockScope(JSContext *cx, JSScope *scope);
+extern int js_SetupLocks(int,int);
+extern void js_CleanupLocks();
+extern void js_InitContextForLocking(JSContext *);
+extern void js_TransferScopeLock(JSContext *, JSScope *, JSScope *);
+extern JS_FRIEND_API(jsval)
+js_GetSlotThreadSafe(JSContext *, JSObject *, uint32);
+extern void js_SetSlotThreadSafe(JSContext *, JSObject *, uint32, jsval);
+extern void js_InitLock(JSThinLock *);
+extern void js_FinishLock(JSThinLock *);
+extern void js_FinishSharingScope(JSRuntime *rt, JSScope *scope);
+
+#ifdef DEBUG
+
+#define JS_IS_RUNTIME_LOCKED(rt)        js_IsRuntimeLocked(rt)
+#define JS_IS_OBJ_LOCKED(cx,obj)        js_IsObjLocked(cx,obj)
+#define JS_IS_SCOPE_LOCKED(cx,scope)    js_IsScopeLocked(cx,scope)
+
+extern JSBool js_IsRuntimeLocked(JSRuntime *rt);
+extern JSBool js_IsObjLocked(JSContext *cx, JSObject *obj);
+extern JSBool js_IsScopeLocked(JSContext *cx, JSScope *scope);
+
+#else
+
+#define JS_IS_RUNTIME_LOCKED(rt)        0
+#define JS_IS_OBJ_LOCKED(cx,obj)        1
+#define JS_IS_SCOPE_LOCKED(cx,scope)    1
+
+#endif /* DEBUG */
+
+#define JS_LOCK_OBJ_VOID(cx, obj, e)                                          \
+    JS_BEGIN_MACRO                                                            \
+        JS_LOCK_OBJ(cx, obj);                                                 \
+        e;                                                                    \
+        JS_UNLOCK_OBJ(cx, obj);                                               \
+    JS_END_MACRO
+
+#define JS_LOCK_VOID(cx, e)                                                   \
+    JS_BEGIN_MACRO                                                            \
+        JSRuntime *_rt = (cx)->runtime;                                       \
+        JS_LOCK_RUNTIME_VOID(_rt, e);                                         \
+    JS_END_MACRO
+
+#if defined(JS_USE_ONLY_NSPR_LOCKS) ||                                        \
+    !( (defined(_WIN32) && defined(_M_IX86)) ||                               \
+       (defined(__GNUC__) && defined(__i386__)) ||                            \
+       (defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)) ||        \
+       defined(AIX) )
+
+#define NSPR_LOCK 1
+
+#undef JS_LOCK0
+#undef JS_UNLOCK0
+#define JS_LOCK0(P,M)   (JS_ACQUIRE_LOCK(((JSLock*)(P)->fat)), (P)->owner = (M))
+#define JS_UNLOCK0(P,M) ((P)->owner = 0, JS_RELEASE_LOCK(((JSLock*)(P)->fat)))
+
+#else  /* arch-tests */
+
+#undef NSPR_LOCK
+
+extern JS_INLINE void js_Lock(JSThinLock *tl, jsword me);
+extern JS_INLINE void js_Unlock(JSThinLock *tl, jsword me);
+
+#endif /* arch-tests */
+
+#else  /* !JS_THREADSAFE */
+
+#define JS_ATOMIC_INCREMENT(p)      (++*(p))
+#define JS_ATOMIC_DECREMENT(p)      (--*(p))
+#define JS_ATOMIC_ADD(p,v)          (*(p) += (v))
+
+#define JS_CurrentThreadId() 0
+#define JS_NEW_LOCK()               NULL
+#define JS_DESTROY_LOCK(l)          ((void)0)
+#define JS_ACQUIRE_LOCK(l)          ((void)0)
+#define JS_RELEASE_LOCK(l)          ((void)0)
+#define JS_LOCK0(P,M)               ((void)0)
+#define JS_UNLOCK0(P,M)             ((void)0)
+
+#define JS_NEW_CONDVAR(l)           NULL
+#define JS_DESTROY_CONDVAR(cv)      ((void)0)
+#define JS_WAIT_CONDVAR(cv,to)      ((void)0)
+#define JS_NOTIFY_CONDVAR(cv)       ((void)0)
+#define JS_NOTIFY_ALL_CONDVAR(cv)   ((void)0)
+
+#define JS_LOCK_RUNTIME(rt)         ((void)0)
+#define JS_UNLOCK_RUNTIME(rt)       ((void)0)
+#define JS_LOCK_OBJ(cx,obj)         ((void)0)
+#define JS_UNLOCK_OBJ(cx,obj)       ((void)0)
+#define JS_LOCK_OBJ_VOID(cx,obj,e)  (e)
+#define JS_LOCK_SCOPE(cx,scope)     ((void)0)
+#define JS_UNLOCK_SCOPE(cx,scope)   ((void)0)
+#define JS_TRANSFER_SCOPE_LOCK(c,o,n) ((void)0)
+
+#define JS_IS_RUNTIME_LOCKED(rt)        1
+#define JS_IS_OBJ_LOCKED(cx,obj)        1
+#define JS_IS_SCOPE_LOCKED(cx,scope)    1
+#define JS_LOCK_VOID(cx, e)             JS_LOCK_RUNTIME_VOID((cx)->runtime, e)
+
+#endif /* !JS_THREADSAFE */
+
+#define JS_LOCK_RUNTIME_VOID(rt,e)                                            \
+    JS_BEGIN_MACRO                                                            \
+        JS_LOCK_RUNTIME(rt);                                                  \
+        e;                                                                    \
+        JS_UNLOCK_RUNTIME(rt);                                                \
+    JS_END_MACRO
+
+#define JS_LOCK_GC(rt)              JS_ACQUIRE_LOCK((rt)->gcLock)
+#define JS_UNLOCK_GC(rt)            JS_RELEASE_LOCK((rt)->gcLock)
+#define JS_LOCK_GC_VOID(rt,e)       (JS_LOCK_GC(rt), (e), JS_UNLOCK_GC(rt))
+#define JS_AWAIT_GC_DONE(rt)        JS_WAIT_CONDVAR((rt)->gcDone, JS_NO_TIMEOUT)
+#define JS_NOTIFY_GC_DONE(rt)       JS_NOTIFY_ALL_CONDVAR((rt)->gcDone)
+#define JS_AWAIT_REQUEST_DONE(rt)   JS_WAIT_CONDVAR((rt)->requestDone,        \
+                                                    JS_NO_TIMEOUT)
+#define JS_NOTIFY_REQUEST_DONE(rt)  JS_NOTIFY_CONDVAR((rt)->requestDone)
+
+#define JS_LOCK(P,CX)               JS_LOCK0(P,(CX)->thread)
+#define JS_UNLOCK(P,CX)             JS_UNLOCK0(P,(CX)->thread)
+
+#endif /* jslock_h___ */

Added: freeswitch/trunk/libs/js/src/jslog2.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jslog2.c	Mon Dec 18 10:53:47 2006
@@ -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 Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "jsstddef.h"
+#include "jsbit.h"
+
+/*
+** Compute the log of the least power of 2 greater than or equal to n
+*/
+JS_PUBLIC_API(JSIntn) JS_CeilingLog2(JSUint32 n)
+{
+    JSIntn log2 = 0;
+
+    if (n & (n-1))
+        log2++;
+    if (n >> 16)
+        log2 += 16, n >>= 16;
+    if (n >> 8)
+        log2 += 8, n >>= 8;
+    if (n >> 4)
+        log2 += 4, n >>= 4;
+    if (n >> 2)
+        log2 += 2, n >>= 2;
+    if (n >> 1)
+        log2++;
+    return log2;
+}
+
+/*
+** Compute the log of the greatest power of 2 less than or equal to n.
+** This really just finds the highest set bit in the word.
+*/
+JS_PUBLIC_API(JSIntn) JS_FloorLog2(JSUint32 n)
+{
+    JSIntn log2 = 0;
+
+    if (n >> 16)
+        log2 += 16, n >>= 16;
+    if (n >> 8)
+        log2 += 8, n >>= 8;
+    if (n >> 4)
+        log2 += 4, n >>= 4;
+    if (n >> 2)
+        log2 += 2, n >>= 2;
+    if (n >> 1)
+        log2++;
+    return log2;
+}

Added: freeswitch/trunk/libs/js/src/jslong.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jslong.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,281 @@
+/* -*- 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 Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "jsstddef.h"
+#include "jstypes.h"
+#include "jslong.h"
+
+static JSInt64 ll_zero = JSLL_INIT( 0x00000000,0x00000000 );
+static JSInt64 ll_maxint = JSLL_INIT( 0x7fffffff, 0xffffffff );
+static JSInt64 ll_minint = JSLL_INIT( 0x80000000, 0x00000000 );
+
+#ifdef HAVE_WATCOM_BUG_2
+JSInt64 __pascal __loadds __export
+    JSLL_Zero(void) { return ll_zero; }
+JSInt64 __pascal __loadds __export
+    JSLL_MaxInt(void) { return ll_maxint; }
+JSInt64 __pascal __loadds __export
+    JSLL_MinInt(void) { return ll_minint; }
+#else
+JS_PUBLIC_API(JSInt64) JSLL_Zero(void) { return ll_zero; }
+JS_PUBLIC_API(JSInt64) JSLL_MaxInt(void) { return ll_maxint; }
+JS_PUBLIC_API(JSInt64) JSLL_MinInt(void) { return ll_minint; }
+#endif
+
+#ifndef JS_HAVE_LONG_LONG
+/*
+** Divide 64-bit a by 32-bit b, which must be normalized so its high bit is 1.
+*/
+static void norm_udivmod32(JSUint32 *qp, JSUint32 *rp, JSUint64 a, JSUint32 b)
+{
+    JSUint32 d1, d0, q1, q0;
+    JSUint32 r1, r0, m;
+
+    d1 = jshi16(b);
+    d0 = jslo16(b);
+    r1 = a.hi % d1;
+    q1 = a.hi / d1;
+    m = q1 * d0;
+    r1 = (r1 << 16) | jshi16(a.lo);
+    if (r1 < m) {
+        q1--, r1 += b;
+        if (r1 >= b     /* i.e., we didn't get a carry when adding to r1 */
+            && r1 < m) {
+            q1--, r1 += b;
+        }
+    }
+    r1 -= m;
+    r0 = r1 % d1;
+    q0 = r1 / d1;
+    m = q0 * d0;
+    r0 = (r0 << 16) | jslo16(a.lo);
+    if (r0 < m) {
+        q0--, r0 += b;
+        if (r0 >= b
+            && r0 < m) {
+            q0--, r0 += b;
+        }
+    }
+    *qp = (q1 << 16) | q0;
+    *rp = r0 - m;
+}
+
+static JSUint32 CountLeadingZeros(JSUint32 a)
+{
+    JSUint32 t;
+    JSUint32 r = 32;
+
+    if ((t = a >> 16) != 0)
+        r -= 16, a = t;
+    if ((t = a >> 8) != 0)
+        r -= 8, a = t;
+    if ((t = a >> 4) != 0)
+        r -= 4, a = t;
+    if ((t = a >> 2) != 0)
+        r -= 2, a = t;
+    if ((t = a >> 1) != 0)
+        r -= 1, a = t;
+    if (a & 1)
+        r--;
+    return r;
+}
+
+JS_PUBLIC_API(void) jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b)
+{
+    JSUint32 n0, n1, n2;
+    JSUint32 q0, q1;
+    JSUint32 rsh, lsh;
+
+    n0 = a.lo;
+    n1 = a.hi;
+
+    if (b.hi == 0) {
+        if (b.lo > n1) {
+            /* (0 q0) = (n1 n0) / (0 D0) */
+
+            lsh = CountLeadingZeros(b.lo);
+
+            if (lsh) {
+                /*
+                 * Normalize, i.e. make the most significant bit of the
+                 * denominator be set.
+                 */
+                b.lo = b.lo << lsh;
+                n1 = (n1 << lsh) | (n0 >> (32 - lsh));
+                n0 = n0 << lsh;
+            }
+
+            a.lo = n0, a.hi = n1;
+            norm_udivmod32(&q0, &n0, a, b.lo);
+            q1 = 0;
+
+            /* remainder is in n0 >> lsh */
+        } else {
+            /* (q1 q0) = (n1 n0) / (0 d0) */
+
+            if (b.lo == 0)              /* user wants to divide by zero! */
+                b.lo = 1 / b.lo;        /* so go ahead and crash */
+
+            lsh = CountLeadingZeros(b.lo);
+
+            if (lsh == 0) {
+                /*
+                 * From (n1 >= b.lo)
+                 *   && (the most significant bit of b.lo is set),
+                 * conclude that
+                 *      (the most significant bit of n1 is set)
+                 *   && (the leading quotient digit q1 = 1).
+                 *
+                 * This special case is necessary, not an optimization
+                 * (Shifts counts of 32 are undefined).
+                 */
+                n1 -= b.lo;
+                q1 = 1;
+            } else {
+                /*
+                 * Normalize.
+                 */
+                rsh = 32 - lsh;
+
+                b.lo = b.lo << lsh;
+                n2 = n1 >> rsh;
+                n1 = (n1 << lsh) | (n0 >> rsh);
+                n0 = n0 << lsh;
+
+                a.lo = n1, a.hi = n2;
+                norm_udivmod32(&q1, &n1, a, b.lo);
+            }
+
+            /* n1 != b.lo... */
+
+            a.lo = n0, a.hi = n1;
+            norm_udivmod32(&q0, &n0, a, b.lo);
+
+            /* remainder in n0 >> lsh */
+        }
+
+        if (rp) {
+            rp->lo = n0 >> lsh;
+            rp->hi = 0;
+        }
+    } else {
+        if (b.hi > n1) {
+            /* (0 0) = (n1 n0) / (D1 d0) */
+
+            q0 = 0;
+            q1 = 0;
+
+            /* remainder in (n1 n0) */
+            if (rp) {
+                rp->lo = n0;
+                rp->hi = n1;
+            }
+        } else {
+            /* (0 q0) = (n1 n0) / (d1 d0) */
+
+            lsh = CountLeadingZeros(b.hi);
+            if (lsh == 0) {
+                /*
+                 * From (n1 >= b.hi)
+                 *   && (the most significant bit of b.hi is set),
+                 * conclude that
+                 *      (the most significant bit of n1 is set)
+                 *   && (the quotient digit q0 = 0 or 1).
+                 *
+                 * This special case is necessary, not an optimization.
+                 */
+
+                /*
+                 * The condition on the next line takes advantage of that
+                 * n1 >= b.hi (true due to control flow).
+                 */
+                if (n1 > b.hi || n0 >= b.lo) {
+                    q0 = 1;
+                    a.lo = n0, a.hi = n1;
+                    JSLL_SUB(a, a, b);
+                } else {
+                    q0 = 0;
+                }
+                q1 = 0;
+
+                if (rp) {
+                    rp->lo = n0;
+                    rp->hi = n1;
+                }
+            } else {
+                JSInt64 m;
+
+                /*
+                 * Normalize.
+                 */
+                rsh = 32 - lsh;
+
+                b.hi = (b.hi << lsh) | (b.lo >> rsh);
+                b.lo = b.lo << lsh;
+                n2 = n1 >> rsh;
+                n1 = (n1 << lsh) | (n0 >> rsh);
+                n0 = n0 << lsh;
+
+                a.lo = n1, a.hi = n2;
+                norm_udivmod32(&q0, &n1, a, b.hi);
+                JSLL_MUL32(m, q0, b.lo);
+
+                if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) {
+                    q0--;
+                    JSLL_SUB(m, m, b);
+                }
+
+                q1 = 0;
+
+                /* Remainder is ((n1 n0) - (m1 m0)) >> lsh */
+                if (rp) {
+                    a.lo = n0, a.hi = n1;
+                    JSLL_SUB(a, a, m);
+                    rp->lo = (a.hi << rsh) | (a.lo >> lsh);
+                    rp->hi = a.hi >> lsh;
+                }
+            }
+        }
+    }
+
+    if (qp) {
+        qp->lo = q0;
+        qp->hi = q1;
+    }
+}
+#endif /* !JS_HAVE_LONG_LONG */

Added: freeswitch/trunk/libs/js/src/jslong.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jslong.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,444 @@
+/* -*- 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 Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:                jslong.h
+** Description: Portable access to 64 bit numerics
+**
+** Long-long (64-bit signed integer type) support. Some C compilers
+** don't support 64 bit integers yet, so we use these macros to
+** support both machines that do and don't.
+**/
+#ifndef jslong_h___
+#define jslong_h___
+
+#include "jstypes.h"
+
+JS_BEGIN_EXTERN_C
+
+#ifdef OSSP
+#define JSLL_MaxInt   JS_LL_MaxInt
+#define JSLL_MinInt   JS_LL_MinInt
+#define JSLL_Zero     JS_LL_Zero
+#define jsll_udivmod  js_ll_udivmod
+#endif
+
+/***********************************************************************
+** DEFINES:     JSLL_MaxInt
+**              JSLL_MinInt
+**              JSLL_Zero
+** DESCRIPTION:
+**      Various interesting constants and static variable
+**      initializer
+***********************************************************************/
+#ifdef HAVE_WATCOM_BUG_2
+JSInt64 __pascal __loadds __export
+    JSLL_MaxInt(void);
+JSInt64 __pascal __loadds __export
+    JSLL_MinInt(void);
+JSInt64 __pascal __loadds __export
+    JSLL_Zero(void);
+#else
+extern JS_PUBLIC_API(JSInt64) JSLL_MaxInt(void);
+extern JS_PUBLIC_API(JSInt64) JSLL_MinInt(void);
+extern JS_PUBLIC_API(JSInt64) JSLL_Zero(void);
+#endif
+
+#define JSLL_MAXINT   JSLL_MaxInt()
+#define JSLL_MININT   JSLL_MinInt()
+#define JSLL_ZERO     JSLL_Zero()
+
+#ifdef JS_HAVE_LONG_LONG
+
+#if JS_BYTES_PER_LONG == 8
+#define JSLL_INIT(hi, lo)  ((hi ## L << 32) + lo ## L)
+#elif (defined(WIN32) || defined(WIN16)) && !defined(__GNUC__)
+#define JSLL_INIT(hi, lo)  ((hi ## i64 << 32) + lo ## i64)
+#else
+#define JSLL_INIT(hi, lo)  ((hi ## LL << 32) + lo ## LL)
+#endif
+
+/***********************************************************************
+** MACROS:      JSLL_*
+** DESCRIPTION:
+**      The following macros define portable access to the 64 bit
+**      math facilities.
+**
+***********************************************************************/
+
+/***********************************************************************
+** MACROS:      JSLL_<relational operators>
+**
+**  JSLL_IS_ZERO        Test for zero
+**  JSLL_EQ             Test for equality
+**  JSLL_NE             Test for inequality
+**  JSLL_GE_ZERO        Test for zero or positive
+**  JSLL_CMP            Compare two values
+***********************************************************************/
+#define JSLL_IS_ZERO(a)       ((a) == 0)
+#define JSLL_EQ(a, b)         ((a) == (b))
+#define JSLL_NE(a, b)         ((a) != (b))
+#define JSLL_GE_ZERO(a)       ((a) >= 0)
+#define JSLL_CMP(a, op, b)    ((JSInt64)(a) op (JSInt64)(b))
+#define JSLL_UCMP(a, op, b)   ((JSUint64)(a) op (JSUint64)(b))
+
+/***********************************************************************
+** MACROS:      JSLL_<logical operators>
+**
+**  JSLL_AND            Logical and
+**  JSLL_OR             Logical or
+**  JSLL_XOR            Logical exclusion
+**  JSLL_OR2            A disgusting deviation
+**  JSLL_NOT            Negation (one's compliment)
+***********************************************************************/
+#define JSLL_AND(r, a, b)        ((r) = (a) & (b))
+#define JSLL_OR(r, a, b)        ((r) = (a) | (b))
+#define JSLL_XOR(r, a, b)        ((r) = (a) ^ (b))
+#define JSLL_OR2(r, a)        ((r) = (r) | (a))
+#define JSLL_NOT(r, a)        ((r) = ~(a))
+
+/***********************************************************************
+** MACROS:      JSLL_<mathematical operators>
+**
+**  JSLL_NEG            Negation (two's compliment)
+**  JSLL_ADD            Summation (two's compliment)
+**  JSLL_SUB            Difference (two's compliment)
+***********************************************************************/
+#define JSLL_NEG(r, a)        ((r) = -(a))
+#define JSLL_ADD(r, a, b)     ((r) = (a) + (b))
+#define JSLL_SUB(r, a, b)     ((r) = (a) - (b))
+
+/***********************************************************************
+** MACROS:      JSLL_<mathematical operators>
+**
+**  JSLL_MUL            Product (two's compliment)
+**  JSLL_DIV            Quotient (two's compliment)
+**  JSLL_MOD            Modulus (two's compliment)
+***********************************************************************/
+#define JSLL_MUL(r, a, b)        ((r) = (a) * (b))
+#define JSLL_DIV(r, a, b)        ((r) = (a) / (b))
+#define JSLL_MOD(r, a, b)        ((r) = (a) % (b))
+
+/***********************************************************************
+** MACROS:      JSLL_<shifting operators>
+**
+**  JSLL_SHL            Shift left [0..64] bits
+**  JSLL_SHR            Shift right [0..64] bits with sign extension
+**  JSLL_USHR           Unsigned shift right [0..64] bits
+**  JSLL_ISHL           Signed shift left [0..64] bits
+***********************************************************************/
+#define JSLL_SHL(r, a, b)     ((r) = (JSInt64)(a) << (b))
+#define JSLL_SHR(r, a, b)     ((r) = (JSInt64)(a) >> (b))
+#define JSLL_USHR(r, a, b)    ((r) = (JSUint64)(a) >> (b))
+#define JSLL_ISHL(r, a, b)    ((r) = (JSInt64)(a) << (b))
+
+/***********************************************************************
+** MACROS:      JSLL_<conversion operators>
+**
+**  JSLL_L2I            Convert to signed 32 bit
+**  JSLL_L2UI           Convert to unsigned 32 bit
+**  JSLL_L2F            Convert to floating point
+**  JSLL_L2D            Convert to floating point
+**  JSLL_I2L            Convert signed to 64 bit
+**  JSLL_UI2L           Convert unsigned to 64 bit
+**  JSLL_F2L            Convert float to 64 bit
+**  JSLL_D2L            Convert float to 64 bit
+***********************************************************************/
+#define JSLL_L2I(i, l)        ((i) = (JSInt32)(l))
+#define JSLL_L2UI(ui, l)        ((ui) = (JSUint32)(l))
+#define JSLL_L2F(f, l)        ((f) = (JSFloat64)(l))
+#define JSLL_L2D(d, l)        ((d) = (JSFloat64)(l))
+
+#define JSLL_I2L(l, i)        ((l) = (JSInt64)(i))
+#define JSLL_UI2L(l, ui)        ((l) = (JSInt64)(ui))
+#define JSLL_F2L(l, f)        ((l) = (JSInt64)(f))
+#define JSLL_D2L(l, d)        ((l) = (JSInt64)(d))
+
+/***********************************************************************
+** MACROS:      JSLL_UDIVMOD
+** DESCRIPTION:
+**  Produce both a quotient and a remainder given an unsigned
+** INPUTS:      JSUint64 a: The dividend of the operation
+**              JSUint64 b: The quotient of the operation
+** OUTPUTS:     JSUint64 *qp: pointer to quotient
+**              JSUint64 *rp: pointer to remainder
+***********************************************************************/
+#define JSLL_UDIVMOD(qp, rp, a, b) \
+    (*(qp) = ((JSUint64)(a) / (b)), \
+     *(rp) = ((JSUint64)(a) % (b)))
+
+#else  /* !JS_HAVE_LONG_LONG */
+
+#ifdef IS_LITTLE_ENDIAN
+#define JSLL_INIT(hi, lo) {JS_INT32(lo), JS_INT32(hi)}
+#else
+#define JSLL_INIT(hi, lo) {JS_INT32(hi), JS_INT32(lo)}
+#endif
+
+#define JSLL_IS_ZERO(a)         (((a).hi == 0) && ((a).lo == 0))
+#define JSLL_EQ(a, b)           (((a).hi == (b).hi) && ((a).lo == (b).lo))
+#define JSLL_NE(a, b)           (((a).hi != (b).hi) || ((a).lo != (b).lo))
+#define JSLL_GE_ZERO(a)         (((a).hi >> 31) == 0)
+
+#ifdef DEBUG
+#define JSLL_CMP(a, op, b)      (JS_ASSERT((#op)[1] != '='), JSLL_REAL_CMP(a, op, b))
+#define JSLL_UCMP(a, op, b)     (JS_ASSERT((#op)[1] != '='), JSLL_REAL_UCMP(a, op, b))
+#else
+#define JSLL_CMP(a, op, b)      JSLL_REAL_CMP(a, op, b)
+#define JSLL_UCMP(a, op, b)     JSLL_REAL_UCMP(a, op, b)
+#endif
+
+#define JSLL_REAL_CMP(a,op,b)   (((JSInt32)(a).hi op (JSInt32)(b).hi) || \
+                                 (((a).hi == (b).hi) && ((a).lo op (b).lo)))
+#define JSLL_REAL_UCMP(a,op,b)  (((a).hi op (b).hi) || \
+                                 (((a).hi == (b).hi) && ((a).lo op (b).lo)))
+
+#define JSLL_AND(r, a, b)       ((r).lo = (a).lo & (b).lo, \
+                                 (r).hi = (a).hi & (b).hi)
+#define JSLL_OR(r, a, b)        ((r).lo = (a).lo | (b).lo, \
+                                 (r).hi = (a).hi | (b).hi)
+#define JSLL_XOR(r, a, b)       ((r).lo = (a).lo ^ (b).lo, \
+                                 (r).hi = (a).hi ^ (b).hi)
+#define JSLL_OR2(r, a)          ((r).lo = (r).lo | (a).lo, \
+                                 (r).hi = (r).hi | (a).hi)
+#define JSLL_NOT(r, a)          ((r).lo = ~(a).lo, \
+                                 (r).hi = ~(a).hi)
+
+#define JSLL_NEG(r, a)          ((r).lo = -(JSInt32)(a).lo, \
+                                 (r).hi = -(JSInt32)(a).hi - ((r).lo != 0))
+#define JSLL_ADD(r, a, b) { \
+    JSInt64 _a, _b; \
+    _a = a; _b = b; \
+    (r).lo = _a.lo + _b.lo; \
+    (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \
+}
+
+#define JSLL_SUB(r, a, b) { \
+    JSInt64 _a, _b; \
+    _a = a; _b = b; \
+    (r).lo = _a.lo - _b.lo; \
+    (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \
+}
+
+#define JSLL_MUL(r, a, b) { \
+    JSInt64 _a, _b; \
+    _a = a; _b = b; \
+    JSLL_MUL32(r, _a.lo, _b.lo); \
+    (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \
+}
+
+#define jslo16(a)        ((a) & JS_BITMASK(16))
+#define jshi16(a)        ((a) >> 16)
+
+#define JSLL_MUL32(r, a, b) { \
+     JSUint32 _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \
+     _a1 = jshi16(a), _a0 = jslo16(a); \
+     _b1 = jshi16(b), _b0 = jslo16(b); \
+     _y0 = _a0 * _b0; \
+     _y1 = _a0 * _b1; \
+     _y2 = _a1 * _b0; \
+     _y3 = _a1 * _b1; \
+     _y1 += jshi16(_y0);                         /* can't carry */ \
+     _y1 += _y2;                                /* might carry */ \
+     if (_y1 < _y2)    \
+        _y3 += (JSUint32)(JS_BIT(16));  /* propagate */ \
+     (r).lo = (jslo16(_y1) << 16) + jslo16(_y0); \
+     (r).hi = _y3 + jshi16(_y1); \
+}
+
+#define JSLL_UDIVMOD(qp, rp, a, b)    jsll_udivmod(qp, rp, a, b)
+
+extern JS_PUBLIC_API(void) jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b);
+
+#define JSLL_DIV(r, a, b) { \
+    JSInt64 _a, _b; \
+    JSUint32 _negative = (JSInt32)(a).hi < 0; \
+    if (_negative) { \
+    JSLL_NEG(_a, a); \
+    } else { \
+    _a = a; \
+    } \
+    if ((JSInt32)(b).hi < 0) { \
+    _negative ^= 1; \
+    JSLL_NEG(_b, b); \
+    } else { \
+    _b = b; \
+    } \
+    JSLL_UDIVMOD(&(r), 0, _a, _b); \
+    if (_negative) \
+    JSLL_NEG(r, r); \
+}
+
+#define JSLL_MOD(r, a, b) { \
+    JSInt64 _a, _b; \
+    JSUint32 _negative = (JSInt32)(a).hi < 0; \
+    if (_negative) { \
+    JSLL_NEG(_a, a); \
+    } else { \
+    _a = a; \
+    } \
+    if ((JSInt32)(b).hi < 0) { \
+    JSLL_NEG(_b, b); \
+    } else { \
+    _b = b; \
+    } \
+    JSLL_UDIVMOD(0, &(r), _a, _b); \
+    if (_negative) \
+    JSLL_NEG(r, r); \
+}
+
+#define JSLL_SHL(r, a, b) { \
+    if (b) { \
+    JSInt64 _a; \
+        _a = a; \
+        if ((b) < 32) { \
+        (r).lo = _a.lo << ((b) & 31); \
+        (r).hi = (_a.hi << ((b) & 31)) | (_a.lo >> (32 - (b))); \
+    } else { \
+        (r).lo = 0; \
+        (r).hi = _a.lo << ((b) & 31); \
+    } \
+    } else { \
+    (r) = (a); \
+    } \
+}
+
+/* a is an JSInt32, b is JSInt32, r is JSInt64 */
+#define JSLL_ISHL(r, a, b) { \
+    if (b) { \
+    JSInt64 _a; \
+    _a.lo = (a); \
+    _a.hi = 0; \
+        if ((b) < 32) { \
+        (r).lo = (a) << ((b) & 31); \
+        (r).hi = ((a) >> (32 - (b))); \
+    } else { \
+        (r).lo = 0; \
+        (r).hi = (a) << ((b) & 31); \
+    } \
+    } else { \
+    (r).lo = (a); \
+    (r).hi = 0; \
+    } \
+}
+
+#define JSLL_SHR(r, a, b) { \
+    if (b) { \
+    JSInt64 _a; \
+        _a = a; \
+    if ((b) < 32) { \
+        (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
+        (r).hi = (JSInt32)_a.hi >> ((b) & 31); \
+    } else { \
+        (r).lo = (JSInt32)_a.hi >> ((b) & 31); \
+        (r).hi = (JSInt32)_a.hi >> 31; \
+    } \
+    } else { \
+    (r) = (a); \
+    } \
+}
+
+#define JSLL_USHR(r, a, b) { \
+    if (b) { \
+    JSInt64 _a; \
+        _a = a; \
+    if ((b) < 32) { \
+        (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
+        (r).hi = _a.hi >> ((b) & 31); \
+    } else { \
+        (r).lo = _a.hi >> ((b) & 31); \
+        (r).hi = 0; \
+    } \
+    } else { \
+    (r) = (a); \
+    } \
+}
+
+#define JSLL_L2I(i, l)        ((i) = (l).lo)
+#define JSLL_L2UI(ui, l)        ((ui) = (l).lo)
+#define JSLL_L2F(f, l)        { double _d; JSLL_L2D(_d, l); (f) = (JSFloat64)_d; }
+
+#define JSLL_L2D(d, l) { \
+    int _negative; \
+    JSInt64 _absval; \
+ \
+    _negative = (l).hi >> 31; \
+    if (_negative) { \
+    JSLL_NEG(_absval, l); \
+    } else { \
+    _absval = l; \
+    } \
+    (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \
+    if (_negative) \
+    (d) = -(d); \
+}
+
+#define JSLL_I2L(l, i)        { JSInt32 _i = (i) >> 31; (l).lo = (i); (l).hi = _i; }
+#define JSLL_UI2L(l, ui)      ((l).lo = (ui), (l).hi = 0)
+#define JSLL_F2L(l, f)        { double _d = (double)f; JSLL_D2L(l, _d); }
+
+#define JSLL_D2L(l, d) { \
+    int _negative; \
+    double _absval, _d_hi; \
+    JSInt64 _lo_d; \
+ \
+    _negative = ((d) < 0); \
+    _absval = _negative ? -(d) : (d); \
+ \
+    (l).hi = _absval / 4.294967296e9; \
+    (l).lo = 0; \
+    JSLL_L2D(_d_hi, l); \
+    _absval -= _d_hi; \
+    _lo_d.hi = 0; \
+    if (_absval < 0) { \
+    _lo_d.lo = -_absval; \
+    JSLL_SUB(l, l, _lo_d); \
+    } else { \
+    _lo_d.lo = _absval; \
+    JSLL_ADD(l, l, _lo_d); \
+    } \
+ \
+    if (_negative) \
+    JSLL_NEG(l, l); \
+}
+
+#endif /* !JS_HAVE_LONG_LONG */
+
+JS_END_EXTERN_C
+
+#endif /* jslong_h___ */

Added: freeswitch/trunk/libs/js/src/jsmath.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsmath.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,469 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS math package.
+ */
+#include "jsstddef.h"
+#include "jslibmath.h"
+#include <stdlib.h>
+#include "jstypes.h"
+#include "jslong.h"
+#include "prmjtime.h"
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jslock.h"
+#include "jsmath.h"
+#include "jsnum.h"
+#include "jsobj.h"
+
+#ifndef M_E
+#define M_E             2.7182818284590452354
+#endif
+#ifndef M_LOG2E
+#define M_LOG2E         1.4426950408889634074
+#endif
+#ifndef M_LOG10E
+#define M_LOG10E        0.43429448190325182765
+#endif
+#ifndef M_LN2
+#define M_LN2           0.69314718055994530942
+#endif
+#ifndef M_LN10
+#define M_LN10          2.30258509299404568402
+#endif
+#ifndef M_PI
+#define M_PI            3.14159265358979323846
+#endif
+#ifndef M_SQRT2
+#define M_SQRT2         1.41421356237309504880
+#endif
+#ifndef M_SQRT1_2
+#define M_SQRT1_2       0.70710678118654752440
+#endif
+
+static JSConstDoubleSpec math_constants[] = {
+    {M_E,       "E",            0, {0,0,0}},
+    {M_LOG2E,   "LOG2E",        0, {0,0,0}},
+    {M_LOG10E,  "LOG10E",       0, {0,0,0}},
+    {M_LN2,     "LN2",          0, {0,0,0}},
+    {M_LN10,    "LN10",         0, {0,0,0}},
+    {M_PI,      "PI",           0, {0,0,0}},
+    {M_SQRT2,   "SQRT2",        0, {0,0,0}},
+    {M_SQRT1_2, "SQRT1_2",      0, {0,0,0}},
+    {0,0,0,{0,0,0}}
+};
+
+static JSClass math_class = {
+    "Math",
+    0,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+static JSBool
+math_abs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_fabs(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_acos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_acos(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_asin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_asin(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_atan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_atan(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_atan2(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, y, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    if (!js_ValueToNumber(cx, argv[1], &y))
+        return JS_FALSE;
+    z = fd_atan2(x, y);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_ceil(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_ceil(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_cos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_cos(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_exp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+#ifdef _WIN32
+    if (!JSDOUBLE_IS_NaN(x)) {
+        if (x == *cx->runtime->jsPositiveInfinity) {
+            *rval = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
+            return JS_TRUE;
+        }
+        if (x == *cx->runtime->jsNegativeInfinity) {
+            *rval = JSVAL_ZERO;
+            return JS_TRUE;
+        }
+    }
+#endif
+    z = fd_exp(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_floor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_floor(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_log(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_log(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_max(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z = *cx->runtime->jsNegativeInfinity;
+    uintN i;
+
+    if (argc == 0) {
+        *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
+        return JS_TRUE;
+    }
+    for (i = 0; i < argc; i++) {
+        if (!js_ValueToNumber(cx, argv[i], &x))
+            return JS_FALSE;
+        if (JSDOUBLE_IS_NaN(x)) {
+            *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
+            return JS_TRUE;
+        }
+        if ((x==0)&&(x==z)&&(fd_copysign(1.0,z)==-1))
+            z = x;
+        else
+            z = (x > z) ? x : z;
+    }
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_min(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z = *cx->runtime->jsPositiveInfinity;
+    uintN i;
+
+    if (argc == 0) {
+        *rval = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
+        return JS_TRUE;
+    }
+    for (i = 0; i < argc; i++) {
+        if (!js_ValueToNumber(cx, argv[i], &x))
+            return JS_FALSE;
+        if (JSDOUBLE_IS_NaN(x)) {
+            *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
+            return JS_TRUE;
+        }
+        if ((x==0)&&(x==z)&&(fd_copysign(1.0,x)==-1))
+            z = x;
+        else
+            z = (x < z) ? x : z;
+    }
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_pow(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, y, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    if (!js_ValueToNumber(cx, argv[1], &y))
+        return JS_FALSE;
+    z = fd_pow(x, y);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+/*
+ * Math.random() support, lifted from java.util.Random.java.
+ */
+static void
+random_setSeed(JSRuntime *rt, int64 seed)
+{
+    int64 tmp;
+
+    JSLL_I2L(tmp, 1000);
+    JSLL_DIV(seed, seed, tmp);
+    JSLL_XOR(tmp, seed, rt->rngMultiplier);
+    JSLL_AND(rt->rngSeed, tmp, rt->rngMask);
+}
+
+static void
+random_init(JSRuntime *rt)
+{
+    int64 tmp, tmp2;
+
+    /* Do at most once. */
+    if (rt->rngInitialized)
+        return;
+    rt->rngInitialized = JS_TRUE;
+
+    /* rt->rngMultiplier = 0x5DEECE66DL */
+    JSLL_ISHL(tmp, 0x5, 32);
+    JSLL_UI2L(tmp2, 0xDEECE66DL);
+    JSLL_OR(rt->rngMultiplier, tmp, tmp2);
+
+    /* rt->rngAddend = 0xBL */
+    JSLL_I2L(rt->rngAddend, 0xBL);
+
+    /* rt->rngMask = (1L << 48) - 1 */
+    JSLL_I2L(tmp, 1);
+    JSLL_SHL(tmp2, tmp, 48);
+    JSLL_SUB(rt->rngMask, tmp2, tmp);
+
+    /* rt->rngDscale = (jsdouble)(1L << 53) */
+    JSLL_SHL(tmp2, tmp, 53);
+    JSLL_L2D(rt->rngDscale, tmp2);
+
+    /* Finally, set the seed from current time. */
+    random_setSeed(rt, PRMJ_Now());
+}
+
+static uint32
+random_next(JSRuntime *rt, int bits)
+{
+    int64 nextseed, tmp;
+    uint32 retval;
+
+    JSLL_MUL(nextseed, rt->rngSeed, rt->rngMultiplier);
+    JSLL_ADD(nextseed, nextseed, rt->rngAddend);
+    JSLL_AND(nextseed, nextseed, rt->rngMask);
+    rt->rngSeed = nextseed;
+    JSLL_USHR(tmp, nextseed, 48 - bits);
+    JSLL_L2I(retval, tmp);
+    return retval;
+}
+
+static jsdouble
+random_nextDouble(JSRuntime *rt)
+{
+    int64 tmp, tmp2;
+    jsdouble d;
+
+    JSLL_ISHL(tmp, random_next(rt, 26), 27);
+    JSLL_UI2L(tmp2, random_next(rt, 27));
+    JSLL_ADD(tmp, tmp, tmp2);
+    JSLL_L2D(d, tmp);
+    return d / rt->rngDscale;
+}
+
+static JSBool
+math_random(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSRuntime *rt;
+    jsdouble z;
+
+    rt = cx->runtime;
+    JS_LOCK_RUNTIME(rt);
+    random_init(rt);
+    z = random_nextDouble(rt);
+    JS_UNLOCK_RUNTIME(rt);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_round(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_copysign(fd_floor(x + 0.5), x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_sin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_sin(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_sqrt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_sqrt(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+static JSBool
+math_tan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x, z;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    z = fd_tan(x);
+    return js_NewNumberValue(cx, z, rval);
+}
+
+#if JS_HAS_TOSOURCE
+static JSBool
+math_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    *rval = ATOM_KEY(cx->runtime->atomState.MathAtom);
+    return JS_TRUE;
+}
+#endif
+
+static JSFunctionSpec math_static_methods[] = {
+#if JS_HAS_TOSOURCE
+    {js_toSource_str,   math_toSource,          0, 0, 0},
+#endif
+    {"abs",             math_abs,               1, 0, 0},
+    {"acos",            math_acos,              1, 0, 0},
+    {"asin",            math_asin,              1, 0, 0},
+    {"atan",            math_atan,              1, 0, 0},
+    {"atan2",           math_atan2,             2, 0, 0},
+    {"ceil",            math_ceil,              1, 0, 0},
+    {"cos",             math_cos,               1, 0, 0},
+    {"exp",             math_exp,               1, 0, 0},
+    {"floor",           math_floor,             1, 0, 0},
+    {"log",             math_log,               1, 0, 0},
+    {"max",             math_max,               2, 0, 0},
+    {"min",             math_min,               2, 0, 0},
+    {"pow",             math_pow,               2, 0, 0},
+    {"random",          math_random,            0, 0, 0},
+    {"round",           math_round,             1, 0, 0},
+    {"sin",             math_sin,               1, 0, 0},
+    {"sqrt",            math_sqrt,              1, 0, 0},
+    {"tan",             math_tan,               1, 0, 0},
+    {0,0,0,0,0}
+};
+
+JSObject *
+js_InitMathClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *Math;
+
+    Math = JS_DefineObject(cx, obj, "Math", &math_class, NULL, 0);
+    if (!Math)
+        return NULL;
+    if (!JS_DefineFunctions(cx, Math, math_static_methods))
+        return NULL;
+    if (!JS_DefineConstDoubles(cx, Math, math_constants))
+        return NULL;
+    return Math;
+}

Added: freeswitch/trunk/libs/js/src/jsmath.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsmath.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,55 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* -*- Mode: C; tab-width: 8 -*-
+ * Copyright (C) 1998-1999 Netscape Communications Corporation, All Rights Reserved.
+ */
+
+#ifndef jsmath_h___
+#define jsmath_h___
+/*
+ * JS math functions.
+ */
+
+JS_BEGIN_EXTERN_C
+
+extern JSObject *
+js_InitMathClass(JSContext *cx, JSObject *obj);
+
+JS_END_EXTERN_C
+
+#endif /* jsmath_h___ */

Added: freeswitch/trunk/libs/js/src/jsnum.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsnum.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1145 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   IBM Corp.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS number type and wrapper class.
+ */
+#include "jsstddef.h"
+#if defined(XP_WIN) || defined(XP_OS2)
+#include <float.h>
+#endif
+#include <locale.h>
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsdtoa.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsopcode.h"
+#include "jsprf.h"
+#include "jsstr.h"
+
+static JSBool
+num_isNaN(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    *rval = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_NaN(x));
+    return JS_TRUE;
+}
+
+static JSBool
+num_isFinite(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble x;
+
+    if (!js_ValueToNumber(cx, argv[0], &x))
+        return JS_FALSE;
+    *rval = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_FINITE(x));
+    return JS_TRUE;
+}
+
+static JSBool
+num_parseFloat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+    jsdouble d;
+    const jschar *bp, *ep;
+
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    /* XXXbe js_strtod shouldn't require NUL termination */
+    bp = js_UndependString(cx, str);
+    if (!bp)
+        return JS_FALSE;
+    if (!js_strtod(cx, bp, &ep, &d))
+        return JS_FALSE;
+    if (ep == bp) {
+        *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
+        return JS_TRUE;
+    }
+    return js_NewNumberValue(cx, d, rval);
+}
+
+/* See ECMA 15.1.2.2. */
+static JSBool
+num_parseInt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsint radix;
+    JSString *str;
+    jsdouble d;
+    const jschar *bp, *ep;
+
+    if (argc > 1) {
+        if (!js_ValueToECMAInt32(cx, argv[1], &radix))
+            return JS_FALSE;
+    } else {
+        radix = 0;
+    }
+    if (radix != 0 && (radix < 2 || radix > 36)) {
+        *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
+        return JS_TRUE;
+    }
+
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    /* XXXbe js_strtointeger shouldn't require NUL termination */
+    bp = js_UndependString(cx, str);
+    if (!bp)
+        return JS_FALSE;
+    if (!js_strtointeger(cx, bp, &ep, radix, &d))
+        return JS_FALSE;
+    if (ep == bp) {
+        *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
+        return JS_TRUE;
+    }
+    return js_NewNumberValue(cx, d, rval);
+}
+
+const char js_Infinity_str[]   = "Infinity";
+const char js_NaN_str[]        = "NaN";
+const char js_isNaN_str[]      = "isNaN";
+const char js_isFinite_str[]   = "isFinite";
+const char js_parseFloat_str[] = "parseFloat";
+const char js_parseInt_str[]   = "parseInt";
+
+static JSFunctionSpec number_functions[] = {
+    {"isNaN",           num_isNaN,              1,0,0},
+    {"isFinite",        num_isFinite,           1,0,0},
+    {"parseFloat",      num_parseFloat,         1,0,0},
+    {"parseInt",        num_parseInt,           2,0,0},
+    {0,0,0,0,0}
+};
+
+JSClass js_NumberClass = {
+    "Number",
+    JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+static JSBool
+Number(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsdouble d;
+    jsval v;
+
+    if (argc != 0) {
+        if (!js_ValueToNumber(cx, argv[0], &d))
+            return JS_FALSE;
+    } else {
+        d = 0.0;
+    }
+    if (!js_NewNumberValue(cx, d, &v))
+        return JS_FALSE;
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        *rval = v;
+        return JS_TRUE;
+    }
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, v);
+    return JS_TRUE;
+}
+
+#if JS_HAS_TOSOURCE
+static JSBool
+num_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval v;
+    jsdouble d;
+    char numBuf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr;
+    char buf[64];
+    JSString *str;
+
+    if (!JS_InstanceOf(cx, obj, &js_NumberClass, argv))
+        return JS_FALSE;
+    v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    JS_ASSERT(JSVAL_IS_NUMBER(v));
+    d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v);
+    numStr = JS_dtostr(numBuf, sizeof numBuf, DTOSTR_STANDARD, 0, d);
+    if (!numStr) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+    JS_snprintf(buf, sizeof buf, "(new %s(%s))", js_NumberClass.name, numStr);
+    str = JS_NewStringCopyZ(cx, buf);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+#endif
+
+/* The buf must be big enough for MIN_INT to fit including '-' and '\0'. */
+static char *
+IntToString(jsint i, char *buf, size_t bufSize)
+{
+    char *cp;
+    jsuint u;
+
+    u = (i < 0) ? -i : i;
+
+    cp = buf + bufSize; /* one past last buffer cell */
+    *--cp = '\0';       /* null terminate the string to be */
+
+    /*
+     * Build the string from behind. We use multiply and subtraction
+     * instead of modulus because that's much faster.
+     */
+    do {
+        jsuint newu = u / 10;
+        *--cp = (char)(u - newu * 10) + '0';
+        u = newu;
+    } while (u != 0);
+
+    if (i < 0)
+        *--cp = '-';
+
+    return cp;
+}
+
+static JSBool
+num_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval v;
+    jsdouble d;
+    jsint base;
+    JSString *str;
+
+    if (!JS_InstanceOf(cx, obj, &js_NumberClass, argv))
+        return JS_FALSE;
+    v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    JS_ASSERT(JSVAL_IS_NUMBER(v));
+    d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v);
+    base = 10;
+    if (argc != 0) {
+        if (!js_ValueToECMAInt32(cx, argv[0], &base))
+            return JS_FALSE;
+        if (base < 2 || base > 36) {
+            char numBuf[12];
+            char *numStr = IntToString(base, numBuf, sizeof numBuf);
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_RADIX,
+                                 numStr);
+            return JS_FALSE;
+        }
+    }
+    if (base == 10)
+        str = js_NumberToString(cx, d);
+    else {
+        char *dStr = JS_dtobasestr(base, d);
+        if (!dStr) {
+            JS_ReportOutOfMemory(cx);
+            return JS_FALSE;
+        }
+        str = JS_NewStringCopyZ(cx, dStr);
+        free(dStr);
+    }
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+num_toLocaleString(JSContext *cx, JSObject *obj, uintN argc,
+                   jsval *argv, jsval *rval)
+{
+    char thousandsLength, decimalLength;
+    const char *numGrouping, *tmpGroup;
+    JSRuntime *rt;
+    JSString *numStr, *str;
+    char *num, *buf, *dec, *end, *tmpSrc, *tmpDest;
+    int digits, size, remainder, nrepeat;
+
+    /*
+     * Create the string, move back to bytes to make string twiddling
+     * a bit easier and so we can insert platform charset seperators.
+     */
+    if (!num_toString(cx, obj, 0, argv, rval))
+        return JS_FALSE;
+    JS_ASSERT(JSVAL_IS_STRING(*rval));
+    numStr = JSVAL_TO_STRING(*rval);
+    num = js_GetStringBytes(numStr);
+
+    /* Find bit before the decimal. */
+    dec = strchr(num, '.');
+    digits = dec ? dec - num : (int)strlen(num);
+    end = num + digits;
+
+    rt = cx->runtime;
+    thousandsLength = strlen(rt->thousandsSeparator);
+    decimalLength = strlen(rt->decimalSeparator);
+
+    /* Figure out how long resulting string will be. */
+    size = digits + (dec ? decimalLength + strlen(dec + 1) : 0);
+
+    numGrouping = tmpGroup = rt->numGrouping;
+    remainder = digits;
+    if (*num == '-')
+        remainder--;
+
+    while (*tmpGroup != CHAR_MAX && *tmpGroup != '\0') {
+        if (*tmpGroup >= remainder)
+            break;
+        size += thousandsLength;
+        remainder -= *tmpGroup;
+        tmpGroup++;
+    }
+    if (*tmpGroup == '\0' && *numGrouping != '\0') {
+        nrepeat = (remainder - 1) / tmpGroup[-1];
+        size += thousandsLength * nrepeat;
+        remainder -= nrepeat * tmpGroup[-1];
+    } else {
+        nrepeat = 0;
+    }
+    tmpGroup--;
+
+    buf = (char *)JS_malloc(cx, size + 1);
+    if (!buf)
+        return JS_FALSE;
+
+    tmpDest = buf;
+    tmpSrc = num;
+
+    while (*tmpSrc == '-' || remainder--)
+        *tmpDest++ = *tmpSrc++;
+    while (tmpSrc < end) {
+        strcpy(tmpDest, rt->thousandsSeparator);
+        tmpDest += thousandsLength;
+        memcpy(tmpDest, tmpSrc, *tmpGroup);
+        tmpDest += *tmpGroup;
+        tmpSrc += *tmpGroup;
+        if (--nrepeat < 0)
+            tmpGroup--;
+    }
+
+    if (dec) {
+        strcpy(tmpDest, rt->decimalSeparator);
+        tmpDest += decimalLength;
+        strcpy(tmpDest, dec + 1);
+    } else {
+        *tmpDest++ = '\0';
+    }
+
+    str = JS_NewString(cx, buf, size);
+    if (!str) {
+        JS_free(cx, buf);
+        return JS_FALSE;
+    }
+
+    *rval = STRING_TO_JSVAL(str);
+
+    return JS_TRUE;
+}
+
+static JSBool
+num_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    if (!JS_InstanceOf(cx, obj, &js_NumberClass, argv))
+        return JS_FALSE;
+    *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    return JS_TRUE;
+}
+
+
+#if JS_HAS_NUMBER_FORMATS
+#define MAX_PRECISION 100
+
+static JSBool
+num_to(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval, JSDToStrMode zeroArgMode,
+       JSDToStrMode oneArgMode, jsint precisionMin, jsint precisionMax, jsint precisionOffset)
+{
+    jsval v;
+    jsdouble d, precision;
+    JSString *str;
+    char buf[DTOSTR_VARIABLE_BUFFER_SIZE(MAX_PRECISION+1)], *numStr; /* Use MAX_PRECISION+1 because precisionOffset can be 1 */
+
+    if (!JS_InstanceOf(cx, obj, &js_NumberClass, argv))
+        return JS_FALSE;
+    v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    JS_ASSERT(JSVAL_IS_NUMBER(v));
+    d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v);
+
+    if (JSVAL_IS_VOID(argv[0])) {
+        precision = 0.0;
+        oneArgMode = zeroArgMode;
+    } else {
+        if (!js_ValueToNumber(cx, argv[0], &precision))
+            return JS_FALSE;
+        precision = js_DoubleToInteger(precision);
+        if (precision < precisionMin || precision > precisionMax) {
+            numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, precision);
+            if (!numStr)
+                JS_ReportOutOfMemory(cx);
+            else
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_PRECISION_RANGE, numStr);
+            return JS_FALSE;
+        }
+    }
+
+    numStr = JS_dtostr(buf, sizeof buf, oneArgMode, (jsint)precision + precisionOffset, d);
+    if (!numStr) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+    str = JS_NewStringCopyZ(cx, numStr);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+num_toFixed(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */
+    return num_to(cx, obj, argc, argv, rval, DTOSTR_FIXED, DTOSTR_FIXED, -20, MAX_PRECISION, 0);
+}
+
+static JSBool
+num_toExponential(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */
+    return num_to(cx, obj, argc, argv, rval, DTOSTR_STANDARD_EXPONENTIAL, DTOSTR_EXPONENTIAL, 0, MAX_PRECISION, 1);
+}
+
+static JSBool
+num_toPrecision(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */
+    return num_to(cx, obj, argc, argv, rval, DTOSTR_STANDARD, DTOSTR_PRECISION, 1, MAX_PRECISION, 0);
+}
+#endif /* JS_HAS_NUMBER_FORMATS */
+
+
+static JSFunctionSpec number_methods[] = {
+#if JS_HAS_TOSOURCE
+    {js_toSource_str,       num_toSource,       0,0,0},
+#endif
+    {js_toString_str,       num_toString,       0,0,0},
+    {js_toLocaleString_str, num_toLocaleString, 0,0,0},
+    {js_valueOf_str,        num_valueOf,        0,0,0},
+#if JS_HAS_NUMBER_FORMATS
+    {"toFixed",             num_toFixed,        1,0,0},
+    {"toExponential",       num_toExponential,  1,0,0},
+    {"toPrecision",         num_toPrecision,    1,0,0},
+#endif
+    {0,0,0,0,0}
+};
+
+/* NB: Keep this in synch with number_constants[]. */
+enum nc_slot {
+    NC_NaN,
+    NC_POSITIVE_INFINITY,
+    NC_NEGATIVE_INFINITY,
+    NC_MAX_VALUE,
+    NC_MIN_VALUE,
+    NC_LIMIT
+};
+
+/*
+ * Some to most C compilers forbid spelling these at compile time, or barf
+ * if you try, so all but MAX_VALUE are set up by js_InitRuntimeNumberState
+ * using union jsdpun.
+ */
+static JSConstDoubleSpec number_constants[] = {
+    {0,                         js_NaN_str,          0,{0,0,0}},
+    {0,                         "POSITIVE_INFINITY", 0,{0,0,0}},
+    {0,                         "NEGATIVE_INFINITY", 0,{0,0,0}},
+    {1.7976931348623157E+308,   "MAX_VALUE",         0,{0,0,0}},
+    {0,                         "MIN_VALUE",         0,{0,0,0}},
+    {0,0,0,{0,0,0}}
+};
+
+static jsdouble NaN;
+
+
+#if (defined XP_WIN || defined XP_OS2) &&                                     \
+    !defined WINCE &&                                                         \
+    !defined __MWERKS__ &&                                                    \
+    (defined _M_IX86 ||                                                       \
+     (defined __GNUC__ && !defined __MINGW32__))
+
+/*
+ * Set the exception mask to mask all exceptions and set the FPU precision
+ * to 53 bit mantissa.
+ * On Alpha platform this is handled via Compiler option.
+ */
+#define FIX_FPU() _control87(MCW_EM | PC_53, MCW_EM | MCW_PC)
+
+#else
+
+#define FIX_FPU() ((void)0)
+
+#endif
+
+JSBool
+js_InitRuntimeNumberState(JSContext *cx)
+{
+    JSRuntime *rt;
+    jsdpun u;
+    struct lconv *locale;
+
+    rt = cx->runtime;
+    JS_ASSERT(!rt->jsNaN);
+
+    FIX_FPU();
+
+    u.s.hi = JSDOUBLE_HI32_EXPMASK | JSDOUBLE_HI32_MANTMASK;
+    u.s.lo = 0xffffffff;
+    number_constants[NC_NaN].dval = NaN = u.d;
+    rt->jsNaN = js_NewDouble(cx, NaN, GCF_LOCK);
+    if (!rt->jsNaN)
+        return JS_FALSE;
+
+    u.s.hi = JSDOUBLE_HI32_EXPMASK;
+    u.s.lo = 0x00000000;
+    number_constants[NC_POSITIVE_INFINITY].dval = u.d;
+    rt->jsPositiveInfinity = js_NewDouble(cx, u.d, GCF_LOCK);
+    if (!rt->jsPositiveInfinity)
+        return JS_FALSE;
+
+    u.s.hi = JSDOUBLE_HI32_SIGNBIT | JSDOUBLE_HI32_EXPMASK;
+    u.s.lo = 0x00000000;
+    number_constants[NC_NEGATIVE_INFINITY].dval = u.d;
+    rt->jsNegativeInfinity = js_NewDouble(cx, u.d, GCF_LOCK);
+    if (!rt->jsNegativeInfinity)
+        return JS_FALSE;
+
+    u.s.hi = 0;
+    u.s.lo = 1;
+    number_constants[NC_MIN_VALUE].dval = u.d;
+
+    locale = localeconv();
+    rt->thousandsSeparator =
+        JS_strdup(cx, locale->thousands_sep ? locale->thousands_sep : "'");
+    rt->decimalSeparator =
+        JS_strdup(cx, locale->decimal_point ? locale->decimal_point : ".");
+    rt->numGrouping =
+        JS_strdup(cx, locale->grouping ? locale->grouping : "\3\0");
+
+    return rt->thousandsSeparator && rt->decimalSeparator && rt->numGrouping;
+}
+
+void
+js_FinishRuntimeNumberState(JSContext *cx)
+{
+    JSRuntime *rt = cx->runtime;
+
+    js_UnlockGCThingRT(rt, rt->jsNaN);
+    js_UnlockGCThingRT(rt, rt->jsNegativeInfinity);
+    js_UnlockGCThingRT(rt, rt->jsPositiveInfinity);
+
+    rt->jsNaN = NULL;
+    rt->jsNegativeInfinity = NULL;
+    rt->jsPositiveInfinity = NULL;
+
+    JS_free(cx, (void *)rt->thousandsSeparator);
+    JS_free(cx, (void *)rt->decimalSeparator);
+    JS_free(cx, (void *)rt->numGrouping);
+    rt->thousandsSeparator = rt->decimalSeparator = rt->numGrouping = NULL;
+}
+
+JSObject *
+js_InitNumberClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto, *ctor;
+    JSRuntime *rt;
+
+    /* XXX must do at least once per new thread, so do it per JSContext... */
+    FIX_FPU();
+
+    if (!JS_DefineFunctions(cx, obj, number_functions))
+        return NULL;
+
+    proto = JS_InitClass(cx, obj, NULL, &js_NumberClass, Number, 1,
+                         NULL, number_methods, NULL, NULL);
+    if (!proto || !(ctor = JS_GetConstructor(cx, proto)))
+        return NULL;
+    OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, JSVAL_ZERO);
+    if (!JS_DefineConstDoubles(cx, ctor, number_constants))
+        return NULL;
+
+    /* ECMA 15.1.1.1 */
+    rt = cx->runtime;
+    if (!JS_DefineProperty(cx, obj, js_NaN_str, DOUBLE_TO_JSVAL(rt->jsNaN),
+                           NULL, NULL, JSPROP_PERMANENT)) {
+        return NULL;
+    }
+
+    /* ECMA 15.1.1.2 */
+    if (!JS_DefineProperty(cx, obj, js_Infinity_str,
+                           DOUBLE_TO_JSVAL(rt->jsPositiveInfinity),
+                           NULL, NULL, JSPROP_PERMANENT)) {
+        return NULL;
+    }
+    return proto;
+}
+
+jsdouble *
+js_NewDouble(JSContext *cx, jsdouble d, uintN gcflag)
+{
+    jsdouble *dp;
+
+    dp = (jsdouble *) js_NewGCThing(cx, gcflag | GCX_DOUBLE, sizeof(jsdouble));
+    if (!dp)
+        return NULL;
+    *dp = d;
+    return dp;
+}
+
+void
+js_FinalizeDouble(JSContext *cx, jsdouble *dp)
+{
+    *dp = NaN;
+}
+
+JSBool
+js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval)
+{
+    jsdouble *dp;
+
+    dp = js_NewDouble(cx, d, 0);
+    if (!dp)
+        return JS_FALSE;
+    *rval = DOUBLE_TO_JSVAL(dp);
+    return JS_TRUE;
+}
+
+JSBool
+js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval)
+{
+    jsint i;
+
+    if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) {
+        *rval = INT_TO_JSVAL(i);
+    } else {
+        if (!js_NewDoubleValue(cx, d, rval))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+JSObject *
+js_NumberToObject(JSContext *cx, jsdouble d)
+{
+    JSObject *obj;
+    jsval v;
+
+    obj = js_NewObject(cx, &js_NumberClass, NULL, NULL);
+    if (!obj)
+        return NULL;
+    if (!js_NewNumberValue(cx, d, &v)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, v);
+    return obj;
+}
+
+JSString *
+js_NumberToString(JSContext *cx, jsdouble d)
+{
+    jsint i;
+    char buf[DTOSTR_STANDARD_BUFFER_SIZE];
+    char *numStr;
+
+    if (JSDOUBLE_IS_INT(d, i))
+        numStr = IntToString(i, buf, sizeof buf);
+    else {
+        numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, d);
+        if (!numStr) {
+            JS_ReportOutOfMemory(cx);
+            return NULL;
+        }
+    }
+    return JS_NewStringCopyZ(cx, numStr);
+}
+
+JSBool
+js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
+{
+    JSObject *obj;
+    JSString *str;
+    const jschar *bp, *ep;
+
+    if (JSVAL_IS_OBJECT(v)) {
+        obj = JSVAL_TO_OBJECT(v);
+        if (!obj) {
+            *dp = 0;
+            return JS_TRUE;
+        }
+        if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_NUMBER, &v))
+            return JS_FALSE;
+    }
+    if (JSVAL_IS_INT(v)) {
+        *dp = (jsdouble)JSVAL_TO_INT(v);
+    } else if (JSVAL_IS_DOUBLE(v)) {
+        *dp = *JSVAL_TO_DOUBLE(v);
+    } else if (JSVAL_IS_STRING(v)) {
+        str = JSVAL_TO_STRING(v);
+        /*
+         * Note that ECMA doesn't treat a string beginning with a '0' as an
+         * octal number here.  This works because all such numbers will be
+         * interpreted as decimal by js_strtod and will never get passed to
+         * js_strtointeger (which would interpret them as octal).
+         */
+        /* XXXbe js_strtod shouldn't require NUL termination */
+        bp = js_UndependString(cx, str);
+        if (!bp)
+            return JS_FALSE;
+        if ((!js_strtod(cx, bp, &ep, dp) ||
+             js_SkipWhiteSpace(ep) != bp + str->length) &&
+            (!js_strtointeger(cx, bp, &ep, 0, dp) ||
+             js_SkipWhiteSpace(ep) != bp + str->length)) {
+            goto badstr;
+        }
+    } else if (JSVAL_IS_BOOLEAN(v)) {
+        *dp = JSVAL_TO_BOOLEAN(v) ? 1 : 0;
+    } else {
+#if JS_BUG_FALLIBLE_TONUM
+        str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
+badstr:
+        if (str) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NAN,
+                                 JS_GetStringBytes(str));
+
+        }
+        return JS_FALSE;
+#else
+badstr:
+        *dp = *cx->runtime->jsNaN;
+#endif
+    }
+    return JS_TRUE;
+}
+
+JSBool
+js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
+{
+    jsdouble d;
+
+    if (!js_ValueToNumber(cx, v, &d))
+        return JS_FALSE;
+    return js_DoubleToECMAInt32(cx, d, ip);
+}
+
+JSBool
+js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip)
+{
+    jsdouble two32 = 4294967296.0;
+    jsdouble two31 = 2147483648.0;
+
+    if (!JSDOUBLE_IS_FINITE(d) || d == 0) {
+        *ip = 0;
+        return JS_TRUE;
+    }
+    d = fmod(d, two32);
+    d = (d >= 0) ? floor(d) : ceil(d) + two32;
+    if (d >= two31)
+        *ip = (int32)(d - two32);
+    else
+        *ip = (int32)d;
+    return JS_TRUE;
+}
+
+JSBool
+js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip)
+{
+    jsdouble d;
+
+    if (!js_ValueToNumber(cx, v, &d))
+        return JS_FALSE;
+    return js_DoubleToECMAUint32(cx, d, ip);
+}
+
+JSBool
+js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip)
+{
+    JSBool neg;
+    jsdouble two32 = 4294967296.0;
+
+    if (!JSDOUBLE_IS_FINITE(d) || d == 0) {
+        *ip = 0;
+        return JS_TRUE;
+    }
+
+    neg = (d < 0);
+    d = floor(neg ? -d : d);
+    d = neg ? -d : d;
+
+    d = fmod(d, two32);
+
+    d = (d >= 0) ? d : d + two32;
+    *ip = (uint32)d;
+    return JS_TRUE;
+}
+
+JSBool
+js_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
+{
+    jsdouble d;
+    JSString *str;
+
+    if (JSVAL_IS_INT(v)) {
+        *ip = JSVAL_TO_INT(v);
+        return JS_TRUE;
+    }
+    if (!js_ValueToNumber(cx, v, &d))
+        return JS_FALSE;
+    if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) {
+        str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
+        if (str) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_CANT_CONVERT, JS_GetStringBytes(str));
+
+        }
+        return JS_FALSE;
+    }
+    *ip = (int32)floor(d + 0.5);     /* Round to nearest */
+    return JS_TRUE;
+}
+
+JSBool
+js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip)
+{
+    jsdouble d;
+    jsuint i, m;
+    JSBool neg;
+
+    if (!js_ValueToNumber(cx, v, &d))
+        return JS_FALSE;
+    if (d == 0 || !JSDOUBLE_IS_FINITE(d)) {
+        *ip = 0;
+        return JS_TRUE;
+    }
+    i = (jsuint)d;
+    if ((jsdouble)i == d) {
+        *ip = (uint16)i;
+        return JS_TRUE;
+    }
+    neg = (d < 0);
+    d = floor(neg ? -d : d);
+    d = neg ? -d : d;
+    m = JS_BIT(16);
+    d = fmod(d, (double)m);
+    if (d < 0)
+        d += m;
+    *ip = (uint16) d;
+    return JS_TRUE;
+}
+
+jsdouble
+js_DoubleToInteger(jsdouble d)
+{
+    JSBool neg;
+
+    if (d == 0)
+        return d;
+    if (!JSDOUBLE_IS_FINITE(d)) {
+        if (JSDOUBLE_IS_NaN(d))
+            return 0;
+        return d;
+    }
+    neg = (d < 0);
+    d = floor(neg ? -d : d);
+    return neg ? -d : d;
+}
+
+
+JSBool
+js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp)
+{
+    char cbuf[32];
+    size_t i;
+    char *cstr, *istr, *estr;
+    JSBool negative;
+    jsdouble d;
+    const jschar *s1 = js_SkipWhiteSpace(s);
+    size_t length = js_strlen(s1);
+
+    /* Use cbuf to avoid malloc */
+    if (length >= sizeof cbuf) {
+        cstr = (char *) JS_malloc(cx, length + 1);
+        if (!cstr)
+           return JS_FALSE;
+    } else {
+        cstr = cbuf;
+    }
+
+    for (i = 0; i <= length; i++) {
+        if (s1[i] >> 8) {
+            cstr[i] = 0;
+            break;
+        }
+        cstr[i] = (char)s1[i];
+    }
+
+    istr = cstr;
+    if ((negative = (*istr == '-')) != 0 || *istr == '+')
+        istr++;
+    if (!strncmp(istr, js_Infinity_str, sizeof js_Infinity_str - 1)) {
+        d = *(negative ? cx->runtime->jsNegativeInfinity : cx->runtime->jsPositiveInfinity);
+        estr = istr + 8;
+    } else {
+        int err;
+        d = JS_strtod(cstr, &estr, &err);
+        if (err == JS_DTOA_ENOMEM) {
+            JS_ReportOutOfMemory(cx);
+            if (cstr != cbuf)
+                JS_free(cx, cstr);
+            return JS_FALSE;
+        }
+        if (err == JS_DTOA_ERANGE) {
+            if (d == HUGE_VAL)
+                d = *cx->runtime->jsPositiveInfinity;
+            else if (d == -HUGE_VAL)
+                d = *cx->runtime->jsNegativeInfinity;
+        }
+#ifdef HPUX
+        if (d == 0.0 && negative) {
+            /*
+             * "-0", "-1e-2000" come out as positive zero
+             * here on HPUX. Force a negative zero instead.
+             */
+            JSDOUBLE_HI32(d) = JSDOUBLE_HI32_SIGNBIT;
+            JSDOUBLE_LO32(d) = 0;
+        }
+#endif
+    }
+
+    i = estr - cstr;
+    if (cstr != cbuf)
+        JS_free(cx, cstr);
+    *ep = i ? s1 + i : s;
+    *dp = d;
+    return JS_TRUE;
+}
+
+struct BinaryDigitReader
+{
+    uintN base;                 /* Base of number; must be a power of 2 */
+    uintN digit;                /* Current digit value in radix given by base */
+    uintN digitMask;            /* Mask to extract the next bit from digit */
+    const jschar *digits;       /* Pointer to the remaining digits */
+    const jschar *end;          /* Pointer to first non-digit */
+};
+
+/* Return the next binary digit from the number or -1 if done */
+static intN GetNextBinaryDigit(struct BinaryDigitReader *bdr)
+{
+    intN bit;
+
+    if (bdr->digitMask == 0) {
+        uintN c;
+
+        if (bdr->digits == bdr->end)
+            return -1;
+
+        c = *bdr->digits++;
+        if ('0' <= c && c <= '9')
+            bdr->digit = c - '0';
+        else if ('a' <= c && c <= 'z')
+            bdr->digit = c - 'a' + 10;
+        else bdr->digit = c - 'A' + 10;
+        bdr->digitMask = bdr->base >> 1;
+    }
+    bit = (bdr->digit & bdr->digitMask) != 0;
+    bdr->digitMask >>= 1;
+    return bit;
+}
+
+JSBool
+js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint base, jsdouble *dp)
+{
+    JSBool negative;
+    jsdouble value;
+    const jschar *start;
+    const jschar *s1 = js_SkipWhiteSpace(s);
+
+    if ((negative = (*s1 == '-')) != 0 || *s1 == '+')
+        s1++;
+
+    if (base == 0) {
+        /* No base supplied, or some base that evaluated to 0. */
+        if (*s1 == '0') {
+            /* It's either hex or octal; only increment char if str isn't '0' */
+            if (s1[1] == 'X' || s1[1] == 'x') { /* Hex */
+                s1 += 2;
+                base = 16;
+            } else {    /* Octal */
+                base = 8;
+            }
+        } else {
+            base = 10; /* Default to decimal. */
+        }
+    } else if (base == 16 && *s1 == '0' && (s1[1] == 'X' || s1[1] == 'x')) {
+        /* If base is 16, ignore hex prefix. */
+        s1 += 2;
+    }
+
+    /*
+     * Done with the preliminaries; find some prefix of the string that's
+     * a number in the given base.
+     */
+    start = s1; /* Mark - if string is empty, we return NaN. */
+    value = 0.0;
+    for (;;) {
+        uintN digit;
+        jschar c = *s1;
+        if ('0' <= c && c <= '9')
+            digit = c - '0';
+        else if ('a' <= c && c <= 'z')
+            digit = c - 'a' + 10;
+        else if ('A' <= c && c <= 'Z')
+            digit = c - 'A' + 10;
+        else
+            break;
+        if (digit >= (uintN)base)
+            break;
+        value = value * base + digit;
+        s1++;
+    }
+
+    if (value >= 9007199254740992.0) {
+        if (base == 10) {
+            /*
+             * If we're accumulating a decimal number and the number is >=
+             * 2^53, then the result from the repeated multiply-add above may
+             * be inaccurate.  Call JS_strtod to get the correct answer.
+             */
+            size_t i;
+            size_t length = s1 - start;
+            char *cstr = (char *) JS_malloc(cx, length + 1);
+            char *estr;
+            int err=0;
+
+            if (!cstr)
+                return JS_FALSE;
+            for (i = 0; i != length; i++)
+                cstr[i] = (char)start[i];
+            cstr[length] = 0;
+
+            value = JS_strtod(cstr, &estr, &err);
+            if (err == JS_DTOA_ENOMEM) {
+                JS_ReportOutOfMemory(cx);
+                JS_free(cx, cstr);
+                return JS_FALSE;
+            }
+            if (err == JS_DTOA_ERANGE && value == HUGE_VAL)
+                value = *cx->runtime->jsPositiveInfinity;
+            JS_free(cx, cstr);
+        } else if ((base & (base - 1)) == 0) {
+            /*
+             * The number may also be inaccurate for power-of-two bases.  This
+             * happens if the addition in value * base + digit causes a round-
+             * down to an even least significant mantissa bit when the first
+             * dropped bit is a one.  If any of the following digits in the
+             * number (which haven't been added in yet) are nonzero, then the
+             * correct action would have been to round up instead of down.  An
+             * example occurs when reading the number 0x1000000000000081, which
+             * rounds to 0x1000000000000000 instead of 0x1000000000000100.
+             */
+            struct BinaryDigitReader bdr;
+            intN bit, bit2;
+            intN j;
+
+            bdr.base = base;
+            bdr.digitMask = 0;
+            bdr.digits = start;
+            bdr.end = s1;
+            value = 0.0;
+
+            /* Skip leading zeros. */
+            do {
+                bit = GetNextBinaryDigit(&bdr);
+            } while (bit == 0);
+
+            if (bit == 1) {
+                /* Gather the 53 significant bits (including the leading 1) */
+                value = 1.0;
+                for (j = 52; j; j--) {
+                    bit = GetNextBinaryDigit(&bdr);
+                    if (bit < 0)
+                        goto done;
+                    value = value*2 + bit;
+                }
+                /* bit2 is the 54th bit (the first dropped from the mantissa) */
+                bit2 = GetNextBinaryDigit(&bdr);
+                if (bit2 >= 0) {
+                    jsdouble factor = 2.0;
+                    intN sticky = 0;  /* sticky is 1 if any bit beyond the 54th is 1 */
+                    intN bit3;
+
+                    while ((bit3 = GetNextBinaryDigit(&bdr)) >= 0) {
+                        sticky |= bit3;
+                        factor *= 2;
+                    }
+                    value += bit2 & (bit | sticky);
+                    value *= factor;
+                }
+              done:;
+            }
+        }
+    }
+    /* We don't worry about inaccurate numbers for any other base. */
+
+    if (s1 == start) {
+        *dp = 0.0;
+        *ep = s;
+    } else {
+        *dp = negative ? -value : value;
+        *ep = s1;
+    }
+    return JS_TRUE;
+}

Added: freeswitch/trunk/libs/js/src/jsnum.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsnum.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,268 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsnum_h___
+#define jsnum_h___
+/*
+ * JS number (IEEE double) interface.
+ *
+ * JS numbers are optimistically stored in the top 31 bits of 32-bit integers,
+ * but floating point literals, results that overflow 31 bits, and division and
+ * modulus operands and results require a 64-bit IEEE double.  These are GC'ed
+ * and pointed to by 32-bit jsvals on the stack and in object properties.
+ *
+ * When a JS number is treated as an object (followed by . or []), the runtime
+ * wraps it with a JSObject whose valueOf method returns the unwrapped number.
+ */
+
+JS_BEGIN_EXTERN_C
+
+/*
+ * Stefan Hanske <sh990154 at mail.uni-greifswald.de> reports:
+ *  ARM is a little endian architecture but 64 bit double words are stored
+ * differently: the 32 bit words are in little endian byte order, the two words
+ * are stored in big endian`s way.
+ */
+
+#if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__)
+#define CPU_IS_ARM
+#endif
+
+typedef union jsdpun {
+    struct {
+#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
+        uint32 lo, hi;
+#else
+        uint32 hi, lo;
+#endif
+    } s;
+    jsdouble d;
+} jsdpun;
+
+#if (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || __GNUC__ > 2
+/*
+ * This version of the macros is safe for the alias optimizations that gcc
+ * does, but uses gcc-specific extensions.
+ */
+
+#define JSDOUBLE_HI32(x) (__extension__ ({ jsdpun u; u.d = (x); u.s.hi; }))
+#define JSDOUBLE_LO32(x) (__extension__ ({ jsdpun u; u.d = (x); u.s.lo; }))
+#define JSDOUBLE_SET_HI32(x, y) \
+    (__extension__ ({ jsdpun u; u.d = (x); u.s.hi = (y); (x) = u.d; }))
+#define JSDOUBLE_SET_LO32(x, y) \
+    (__extension__ ({ jsdpun u; u.d = (x); u.s.lo = (y); (x) = u.d; }))
+
+#else /* not or old GNUC */
+
+/*
+ * We don't know of any non-gcc compilers that perform alias optimization,
+ * so this code should work.
+ */
+
+#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
+#define JSDOUBLE_HI32(x)        (((uint32 *)&(x))[1])
+#define JSDOUBLE_LO32(x)        (((uint32 *)&(x))[0])
+#else
+#define JSDOUBLE_HI32(x)        (((uint32 *)&(x))[0])
+#define JSDOUBLE_LO32(x)        (((uint32 *)&(x))[1])
+#endif
+
+#define JSDOUBLE_SET_HI32(x, y) (JSDOUBLE_HI32(x)=(y))
+#define JSDOUBLE_SET_LO32(x, y) (JSDOUBLE_LO32(x)=(y))
+
+#endif /* not or old GNUC */
+
+#define JSDOUBLE_HI32_SIGNBIT   0x80000000
+#define JSDOUBLE_HI32_EXPMASK   0x7ff00000
+#define JSDOUBLE_HI32_MANTMASK  0x000fffff
+
+#define JSDOUBLE_IS_NaN(x)                                                    \
+    ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) == JSDOUBLE_HI32_EXPMASK &&   \
+     (JSDOUBLE_LO32(x) || (JSDOUBLE_HI32(x) & JSDOUBLE_HI32_MANTMASK)))
+
+#define JSDOUBLE_IS_INFINITE(x)                                               \
+    ((JSDOUBLE_HI32(x) & ~JSDOUBLE_HI32_SIGNBIT) == JSDOUBLE_HI32_EXPMASK &&  \
+     !JSDOUBLE_LO32(x))
+
+#define JSDOUBLE_IS_FINITE(x)                                                 \
+    ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) != JSDOUBLE_HI32_EXPMASK)
+
+#define JSDOUBLE_IS_NEGZERO(d)  (JSDOUBLE_HI32(d) == JSDOUBLE_HI32_SIGNBIT && \
+                                 JSDOUBLE_LO32(d) == 0)
+
+/*
+ * JSDOUBLE_IS_INT first checks that d is neither NaN nor infinite, to avoid
+ * raising SIGFPE on platforms such as Alpha Linux, then (only if the cast is
+ * safe) leaves i as (jsint)d.  This also avoid anomalous NaN floating point
+ * comparisons under MSVC.
+ */
+#define JSDOUBLE_IS_INT(d, i) (JSDOUBLE_IS_FINITE(d)                          \
+                               && !JSDOUBLE_IS_NEGZERO(d)                     \
+                               && ((d) == (i = (jsint)(d))))
+
+#if defined(XP_WIN)
+#define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN)                               \
+    ((JSDOUBLE_IS_NaN(LVAL) || JSDOUBLE_IS_NaN(RVAL))                         \
+     ? (IFNAN)                                                                \
+     : (LVAL) OP (RVAL))
+#else
+#define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL))
+#endif
+
+/* Initialize number constants and runtime state for the first context. */
+extern JSBool
+js_InitRuntimeNumberState(JSContext *cx);
+
+extern void
+js_FinishRuntimeNumberState(JSContext *cx);
+
+/* Initialize the Number class, returning its prototype object. */
+extern JSClass js_NumberClass;
+
+extern JSObject *
+js_InitNumberClass(JSContext *cx, JSObject *obj);
+
+/*
+ * String constants for global function names, used in jsapi.c and jsnum.c.
+ */
+extern const char js_Infinity_str[];
+extern const char js_NaN_str[];
+extern const char js_isNaN_str[];
+extern const char js_isFinite_str[];
+extern const char js_parseFloat_str[];
+extern const char js_parseInt_str[];
+
+/* GC-allocate a new JS number. */
+extern jsdouble *
+js_NewDouble(JSContext *cx, jsdouble d, uintN gcflag);
+
+extern void
+js_FinalizeDouble(JSContext *cx, jsdouble *dp);
+
+extern JSBool
+js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval);
+
+extern JSBool
+js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval);
+
+/* Construct a Number instance that wraps around d. */
+extern JSObject *
+js_NumberToObject(JSContext *cx, jsdouble d);
+
+/* Convert a number to a GC'ed string. */
+extern JSString *
+js_NumberToString(JSContext *cx, jsdouble d);
+
+/*
+ * Convert a value to a number, returning false after reporting any error,
+ * otherwise returning true with *dp set.
+ */
+extern JSBool
+js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp);
+
+/*
+ * Convert a value or a double to an int32, according to the ECMA rules
+ * for ToInt32.
+ */
+extern JSBool
+js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip);
+
+extern JSBool
+js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip);
+
+/*
+ * Convert a value or a double to a uint32, according to the ECMA rules
+ * for ToUint32.
+ */
+extern JSBool
+js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip);
+
+extern JSBool
+js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip);
+
+/*
+ * Convert a value to a number, then to an int32 if it fits by rounding to
+ * nearest; but failing with an error report if the double is out of range
+ * or unordered.
+ */
+extern JSBool
+js_ValueToInt32(JSContext *cx, jsval v, int32 *ip);
+
+/*
+ * Convert a value to a number, then to a uint16 according to the ECMA rules
+ * for ToUint16.
+ */
+extern JSBool
+js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip);
+
+/*
+ * Convert a jsdouble to an integral number, stored in a jsdouble.
+ * If d is NaN, return 0.  If d is an infinity, return it without conversion.
+ */
+extern jsdouble
+js_DoubleToInteger(jsdouble d);
+
+/*
+ * Similar to strtod except that it replaces overflows with infinities of the
+ * correct sign, and underflows with zeros of the correct sign.  Guaranteed to
+ * return the closest double number to the given input in dp.
+ *
+ * Also allows inputs of the form [+|-]Infinity, which produce an infinity of
+ * the appropriate sign.  The case of the "Infinity" string must match exactly.
+ * If the string does not contain a number, set *ep to s and return 0.0 in dp.
+ * Return false if out of memory.
+ */
+extern JSBool
+js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp);
+
+/*
+ * Similar to strtol except that it handles integers of arbitrary size.
+ * Guaranteed to return the closest double number to the given input when radix
+ * is 10 or a power of 2.  Callers may see round-off errors for very large
+ * numbers of a different radix than 10 or a power of 2.
+ *
+ * If the string does not contain a number, set *ep to s and return 0.0 in dp.
+ * Return false if out of memory.
+ */
+extern JSBool
+js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint radix, jsdouble *dp);
+
+JS_END_EXTERN_C
+
+#endif /* jsnum_h___ */

Added: freeswitch/trunk/libs/js/src/jsobj.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsobj.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4426 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS object implementation.
+ */
+#include "jsstddef.h"
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+#include "jshash.h" /* Added by JSIFY */
+#include "jsdhash.h"
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jsarray.h"
+#include "jsatom.h"
+#include "jsbool.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsfun.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsscope.h"
+#include "jsscript.h"
+#include "jsstr.h"
+#include "jsopcode.h"
+
+#include "jsdbgapi.h"   /* whether or not JS_HAS_OBJ_WATCHPOINT */
+
+#ifdef JS_THREADSAFE
+#define NATIVE_DROP_PROPERTY js_DropProperty
+
+extern void
+js_DropProperty(JSContext *cx, JSObject *obj, JSProperty *prop);
+#else
+#define NATIVE_DROP_PROPERTY NULL
+#endif
+
+JS_FRIEND_DATA(JSObjectOps) js_ObjectOps = {
+    js_NewObjectMap,        js_DestroyObjectMap,
+    js_LookupProperty,      js_DefineProperty,
+    js_GetProperty,         js_SetProperty,
+    js_GetAttributes,       js_SetAttributes,
+    js_DeleteProperty,      js_DefaultValue,
+    js_Enumerate,           js_CheckAccess,
+    NULL,                   NATIVE_DROP_PROPERTY,
+    js_Call,                js_Construct,
+    NULL,                   js_HasInstance,
+    js_SetProtoOrParent,    js_SetProtoOrParent,
+    js_Mark,                js_Clear,
+    js_GetRequiredSlot,     js_SetRequiredSlot
+};
+
+JSClass js_ObjectClass = {
+    js_Object_str,
+    0,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+#if JS_HAS_OBJ_PROTO_PROP
+
+static JSBool
+obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+static JSBool
+obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+static JSBool
+obj_getCount(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+static JSPropertySpec object_props[] = {
+    /* These two must come first; see object_props[slot].name usage below. */
+    {js_proto_str, JSSLOT_PROTO, JSPROP_PERMANENT|JSPROP_SHARED,
+                                                  obj_getSlot,  obj_setSlot},
+    {js_parent_str,JSSLOT_PARENT,JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED,
+                                                  obj_getSlot,  obj_setSlot},
+    {js_count_str, 0,            JSPROP_PERMANENT,obj_getCount, obj_getCount},
+    {0,0,0,0,0}
+};
+
+/* NB: JSSLOT_PROTO and JSSLOT_PARENT are already indexes into object_props. */
+#define JSSLOT_COUNT 2
+
+static JSBool
+ReportStrictSlot(JSContext *cx, uint32 slot)
+{
+    if (slot == JSSLOT_PROTO)
+        return JS_TRUE;
+    return JS_ReportErrorFlagsAndNumber(cx,
+                                        JSREPORT_WARNING | JSREPORT_STRICT,
+                                        js_GetErrorMessage, NULL,
+                                        JSMSG_DEPRECATED_USAGE,
+                                        object_props[slot].name);
+}
+
+static JSBool
+obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    uint32 slot;
+    jsid propid;
+    JSAccessMode mode;
+    uintN attrs;
+    JSObject *pobj;
+    JSClass *clasp;
+    JSExtendedClass *xclasp;
+
+    slot = (uint32) JSVAL_TO_INT(id);
+    if (id == INT_TO_JSVAL(JSSLOT_PROTO)) {
+        propid = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
+        mode = JSACC_PROTO;
+    } else {
+        propid = ATOM_TO_JSID(cx->runtime->atomState.parentAtom);
+        mode = JSACC_PARENT;
+    }
+
+    /* Let OBJ_CHECK_ACCESS get the slot's value, based on the access mode. */
+    if (!OBJ_CHECK_ACCESS(cx, obj, propid, mode, vp, &attrs))
+        return JS_FALSE;
+
+    pobj = JSVAL_TO_OBJECT(*vp);
+    if (pobj) {
+        clasp = OBJ_GET_CLASS(cx, pobj);
+        if (clasp->flags & JSCLASS_IS_EXTENDED) {
+            xclasp = (JSExtendedClass *) clasp;
+            if (xclasp->outerObject) {
+                pobj = xclasp->outerObject(cx, pobj);
+                if (!pobj)
+                    return JS_FALSE;
+                *vp = OBJECT_TO_JSVAL(pobj);
+            }
+        }
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSObject *pobj;
+    uint32 slot;
+    jsid propid;
+    uintN attrs;
+
+    if (!JSVAL_IS_OBJECT(*vp))
+        return JS_TRUE;
+    pobj = JSVAL_TO_OBJECT(*vp);
+    slot = (uint32) JSVAL_TO_INT(id);
+    if (JS_HAS_STRICT_OPTION(cx) && !ReportStrictSlot(cx, slot))
+        return JS_FALSE;
+
+    /* __parent__ is readonly and permanent, only __proto__ may be set. */
+    propid = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
+    if (!OBJ_CHECK_ACCESS(cx, obj, propid, JSACC_PROTO|JSACC_WRITE, vp, &attrs))
+        return JS_FALSE;
+
+    return js_SetProtoOrParent(cx, obj, slot, pobj);
+}
+
+static JSBool
+obj_getCount(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    jsval iter_state;
+    jsid num_properties;
+    JSBool ok;
+
+    if (JS_HAS_STRICT_OPTION(cx) && !ReportStrictSlot(cx, JSSLOT_COUNT))
+        return JS_FALSE;
+
+    /* Get the number of properties to enumerate. */
+    iter_state = JSVAL_NULL;
+    ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, &num_properties);
+    if (!ok)
+        goto out;
+
+    if (!JSVAL_IS_INT(num_properties)) {
+        JS_ASSERT(0);
+        *vp = JSVAL_ZERO;
+        goto out;
+    }
+    *vp = num_properties;
+
+out:
+    if (iter_state != JSVAL_NULL)
+        ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0);
+    return ok;
+}
+
+#else  /* !JS_HAS_OBJ_PROTO_PROP */
+
+#define object_props NULL
+
+#endif /* !JS_HAS_OBJ_PROTO_PROP */
+
+JSBool
+js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj)
+{
+    JSRuntime *rt;
+    JSObject *obj2, *oldproto;
+    JSScope *scope, *newscope;
+
+    /*
+     * Serialize all proto and parent setting in order to detect cycles.
+     * We nest locks in this function, and only here, in the following orders:
+     *
+     * (1)  rt->setSlotLock < pobj's scope lock;
+     *      rt->setSlotLock < pobj's proto-or-parent's scope lock;
+     *      rt->setSlotLock < pobj's grand-proto-or-parent's scope lock;
+     *      etc...
+     * (2)  rt->setSlotLock < obj's scope lock < pobj's scope lock.
+     *
+     * We avoid AB-BA deadlock by restricting obj from being on pobj's parent
+     * or proto chain (pobj may already be on obj's parent or proto chain; it
+     * could be moving up or down).  We finally order obj with respect to pobj
+     * at the bottom of this routine (just before releasing rt->setSlotLock),
+     * by making pobj be obj's prototype or parent.
+     *
+     * After we have set the slot and released rt->setSlotLock, another call
+     * to js_SetProtoOrParent could nest locks according to the first order
+     * list above, but it cannot deadlock with any other thread.  For there
+     * to be a deadlock, other parts of the engine would have to nest scope
+     * locks in the opposite order.  XXXbe ensure they don't!
+     */
+    rt = cx->runtime;
+#ifdef JS_THREADSAFE
+
+    JS_ACQUIRE_LOCK(rt->setSlotLock);
+    while (rt->setSlotBusy) {
+        jsrefcount saveDepth;
+
+        /* Take pains to avoid nesting rt->gcLock inside rt->setSlotLock! */
+        JS_RELEASE_LOCK(rt->setSlotLock);
+        saveDepth = JS_SuspendRequest(cx);
+        JS_ACQUIRE_LOCK(rt->setSlotLock);
+        if (rt->setSlotBusy)
+            JS_WAIT_CONDVAR(rt->setSlotDone, JS_NO_TIMEOUT);
+        JS_RELEASE_LOCK(rt->setSlotLock);
+        JS_ResumeRequest(cx, saveDepth);
+        JS_ACQUIRE_LOCK(rt->setSlotLock);
+    }
+    rt->setSlotBusy = JS_TRUE;
+    JS_RELEASE_LOCK(rt->setSlotLock);
+
+#define SET_SLOT_DONE(rt)                                                     \
+    JS_BEGIN_MACRO                                                            \
+        JS_ACQUIRE_LOCK((rt)->setSlotLock);                                   \
+        (rt)->setSlotBusy = JS_FALSE;                                         \
+        JS_NOTIFY_ALL_CONDVAR((rt)->setSlotDone);                             \
+        JS_RELEASE_LOCK((rt)->setSlotLock);                                   \
+    JS_END_MACRO
+
+#else
+
+#define SET_SLOT_DONE(rt)       /* nothing */
+
+#endif
+
+    obj2 = pobj;
+    while (obj2) {
+        if (obj2 == obj) {
+            SET_SLOT_DONE(rt);
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_CYCLIC_VALUE,
+#if JS_HAS_OBJ_PROTO_PROP
+                                 object_props[slot].name
+#else
+                                 (slot == JSSLOT_PROTO) ? js_proto_str
+                                                        : js_parent_str
+#endif
+                                 );
+            return JS_FALSE;
+        }
+        obj2 = JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj2, slot));
+    }
+
+    if (slot == JSSLOT_PROTO && OBJ_IS_NATIVE(obj)) {
+        /* Check to see whether obj shares its prototype's scope. */
+        JS_LOCK_OBJ(cx, obj);
+        scope = OBJ_SCOPE(obj);
+        oldproto = JSVAL_TO_OBJECT(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PROTO));
+        if (oldproto && OBJ_SCOPE(oldproto) == scope) {
+            /* Either obj needs a new empty scope, or it should share pobj's. */
+            if (!pobj ||
+                !OBJ_IS_NATIVE(pobj) ||
+                OBJ_GET_CLASS(cx, pobj) != LOCKED_OBJ_GET_CLASS(oldproto)) {
+                /*
+                 * With no proto and no scope of its own, obj is truly empty.
+                 *
+                 * If pobj is not native, obj needs its own empty scope -- it
+                 * should not continue to share oldproto's scope once oldproto
+                 * is not on obj's prototype chain.  That would put properties
+                 * from oldproto's scope ahead of properties defined by pobj,
+                 * in lookup order.
+                 *
+                 * If pobj's class differs from oldproto's, we may need a new
+                 * scope to handle differences in private and reserved slots,
+                 * so we suboptimally but safely make one.
+                 */
+                scope = js_GetMutableScope(cx, obj);
+                if (!scope) {
+                    JS_UNLOCK_OBJ(cx, obj);
+                    SET_SLOT_DONE(rt);
+                    return JS_FALSE;
+                }
+            } else if (OBJ_SCOPE(pobj) != scope) {
+#ifdef JS_THREADSAFE
+                /*
+                 * We are about to nest scope locks.  Help jslock.c:ShareScope
+                 * keep scope->u.count balanced for the JS_UNLOCK_SCOPE, while
+                 * avoiding deadlock, by recording scope in rt->setSlotScope.
+                 */
+                if (scope->ownercx) {
+                    JS_ASSERT(scope->ownercx == cx);
+                    rt->setSlotScope = scope;
+                }
+#endif
+
+                /* We can't deadlock because we checked for cycles above (2). */
+                JS_LOCK_OBJ(cx, pobj);
+                newscope = (JSScope *) js_HoldObjectMap(cx, pobj->map);
+                obj->map = &newscope->map;
+                js_DropObjectMap(cx, &scope->map, obj);
+                JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope);
+                scope = newscope;
+#ifdef JS_THREADSAFE
+                rt->setSlotScope = NULL;
+#endif
+            }
+        }
+        LOCKED_OBJ_SET_SLOT(obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(pobj));
+        JS_UNLOCK_SCOPE(cx, scope);
+    } else {
+        OBJ_SET_SLOT(cx, obj, slot, OBJECT_TO_JSVAL(pobj));
+    }
+
+    SET_SLOT_DONE(rt);
+    return JS_TRUE;
+
+#undef SET_SLOT_DONE
+}
+
+JS_STATIC_DLL_CALLBACK(JSHashNumber)
+js_hash_object(const void *key)
+{
+    return (JSHashNumber)JS_PTR_TO_UINT32(key) >> JSVAL_TAGBITS;
+}
+
+static JSHashEntry *
+MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap)
+{
+    JSSharpObjectMap *map;
+    JSHashTable *table;
+    JSHashNumber hash;
+    JSHashEntry **hep, *he;
+    jsatomid sharpid;
+    JSIdArray *ida;
+    JSBool ok;
+    jsint i, length;
+    jsid id;
+#if JS_HAS_GETTER_SETTER
+    JSObject *obj2;
+    JSProperty *prop;
+    uintN attrs;
+#endif
+    jsval val;
+    int stackDummy;
+
+    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
+        return NULL;
+    }
+
+    map = &cx->sharpObjectMap;
+    table = map->table;
+    hash = js_hash_object(obj);
+    hep = JS_HashTableRawLookup(table, hash, obj);
+    he = *hep;
+    if (!he) {
+        sharpid = 0;
+        he = JS_HashTableRawAdd(table, hep, hash, obj,
+                                JS_UINT32_TO_PTR(sharpid));
+        if (!he) {
+            JS_ReportOutOfMemory(cx);
+            return NULL;
+        }
+
+        /*
+         * Increment map->depth to protect js_EnterSharpObject from reentering
+         * itself badly.  Without this fix, if we reenter the basis case where
+         * map->depth == 0, when unwinding the inner call we will destroy the
+         * newly-created hash table and crash.
+         */
+        ++map->depth;
+        ida = JS_Enumerate(cx, obj);
+        --map->depth;
+        if (!ida)
+            return NULL;
+
+        ok = JS_TRUE;
+        for (i = 0, length = ida->length; i < length; i++) {
+            id = ida->vector[i];
+#if JS_HAS_GETTER_SETTER
+            ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
+            if (!ok)
+                break;
+            if (!prop)
+                continue;
+            ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);
+            if (ok) {
+                if (OBJ_IS_NATIVE(obj2) &&
+                    (attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
+                    val = JSVAL_NULL;
+                    if (attrs & JSPROP_GETTER)
+                        val = (jsval) ((JSScopeProperty*)prop)->getter;
+                    if (attrs & JSPROP_SETTER) {
+                        if (val != JSVAL_NULL) {
+                            /* Mark the getter, then set val to setter. */
+                            ok = (MarkSharpObjects(cx, JSVAL_TO_OBJECT(val),
+                                                   NULL)
+                                  != NULL);
+                        }
+                        val = (jsval) ((JSScopeProperty*)prop)->setter;
+                    }
+                } else {
+                    ok = OBJ_GET_PROPERTY(cx, obj, id, &val);
+                }
+            }
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+#else
+            ok = OBJ_GET_PROPERTY(cx, obj, id, &val);
+#endif
+            if (!ok)
+                break;
+            if (!JSVAL_IS_PRIMITIVE(val) &&
+                !MarkSharpObjects(cx, JSVAL_TO_OBJECT(val), NULL)) {
+                ok = JS_FALSE;
+                break;
+            }
+        }
+        if (!ok || !idap)
+            JS_DestroyIdArray(cx, ida);
+        if (!ok)
+            return NULL;
+    } else {
+        sharpid = JS_PTR_TO_UINT32(he->value);
+        if (sharpid == 0) {
+            sharpid = ++map->sharpgen << SHARP_ID_SHIFT;
+            he->value = JS_UINT32_TO_PTR(sharpid);
+        }
+        ida = NULL;
+    }
+    if (idap)
+        *idap = ida;
+    return he;
+}
+
+JSHashEntry *
+js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap,
+                    jschar **sp)
+{
+    JSSharpObjectMap *map;
+    JSHashTable *table;
+    JSIdArray *ida;
+    JSHashNumber hash;
+    JSHashEntry *he, **hep;
+    jsatomid sharpid;
+    char buf[20];
+    size_t len;
+
+    if (JS_HAS_NATIVE_BRANCH_CALLBACK_OPTION(cx) &&
+        cx->branchCallback &&
+        !cx->branchCallback(cx, NULL)) {
+        return NULL;
+    }
+
+    /* Set to null in case we return an early error. */
+    *sp = NULL;
+    map = &cx->sharpObjectMap;
+    table = map->table;
+    if (!table) {
+        table = JS_NewHashTable(8, js_hash_object, JS_CompareValues,
+                                JS_CompareValues, NULL, NULL);
+        if (!table) {
+            JS_ReportOutOfMemory(cx);
+            return NULL;
+        }
+        map->table = table;
+    }
+
+    ida = NULL;
+    if (map->depth == 0) {
+        he = MarkSharpObjects(cx, obj, &ida);
+        if (!he)
+            goto bad;
+        JS_ASSERT((JS_PTR_TO_UINT32(he->value) & SHARP_BIT) == 0);
+        if (!idap) {
+            JS_DestroyIdArray(cx, ida);
+            ida = NULL;
+        }
+    } else {
+        hash = js_hash_object(obj);
+        hep = JS_HashTableRawLookup(table, hash, obj);
+        he = *hep;
+
+        /*
+         * It's possible that the value of a property has changed from the
+         * first time the object's properties are traversed (when the property
+         * ids are entered into the hash table) to the second (when they are
+         * converted to strings), i.e., the OBJ_GET_PROPERTY() call is not
+         * idempotent.
+         */
+        if (!he) {
+            he = JS_HashTableRawAdd(table, hep, hash, obj, NULL);
+            if (!he) {
+                JS_ReportOutOfMemory(cx);
+                goto bad;
+            }
+            sharpid = 0;
+            goto out;
+        }
+    }
+
+    sharpid = JS_PTR_TO_UINT32(he->value);
+    if (sharpid != 0) {
+        len = JS_snprintf(buf, sizeof buf, "#%u%c",
+                          sharpid >> SHARP_ID_SHIFT,
+                          (sharpid & SHARP_BIT) ? '#' : '=');
+        *sp = js_InflateString(cx, buf, &len);
+        if (!*sp) {
+            if (ida)
+                JS_DestroyIdArray(cx, ida);
+            goto bad;
+        }
+    }
+
+out:
+    JS_ASSERT(he);
+    if ((sharpid & SHARP_BIT) == 0) {
+        if (idap && !ida) {
+            ida = JS_Enumerate(cx, obj);
+            if (!ida) {
+                if (*sp) {
+                    JS_free(cx, *sp);
+                    *sp = NULL;
+                }
+                goto bad;
+            }
+        }
+        map->depth++;
+    }
+
+    if (idap)
+        *idap = ida;
+    return he;
+
+bad:
+    /* Clean up the sharpObjectMap table on outermost error. */
+    if (map->depth == 0) {
+        map->sharpgen = 0;
+        JS_HashTableDestroy(map->table);
+        map->table = NULL;
+    }
+    return NULL;
+}
+
+void
+js_LeaveSharpObject(JSContext *cx, JSIdArray **idap)
+{
+    JSSharpObjectMap *map;
+    JSIdArray *ida;
+
+    map = &cx->sharpObjectMap;
+    JS_ASSERT(map->depth > 0);
+    if (--map->depth == 0) {
+        map->sharpgen = 0;
+        JS_HashTableDestroy(map->table);
+        map->table = NULL;
+    }
+    if (idap) {
+        ida = *idap;
+        if (ida) {
+            JS_DestroyIdArray(cx, ida);
+            *idap = NULL;
+        }
+    }
+}
+
+#define OBJ_TOSTRING_EXTRA      4       /* for 4 local GC roots */
+
+#if JS_HAS_INITIALIZERS || JS_HAS_TOSOURCE
+JSBool
+js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    JSBool ok, outermost;
+    JSHashEntry *he;
+    JSIdArray *ida;
+    jschar *chars, *ochars, *vsharp;
+    const jschar *idstrchars, *vchars;
+    size_t nchars, idstrlength, gsoplength, vlength, vsharplength;
+    char *comma;
+    jsint i, j, length, valcnt;
+    jsid id;
+#if JS_HAS_GETTER_SETTER
+    JSObject *obj2;
+    JSProperty *prop;
+    uintN attrs;
+#endif
+    jsval *val;
+    JSString *gsop[2];
+    JSAtom *atom;
+    JSString *idstr, *valstr, *str;
+    int stackDummy;
+
+    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
+        return JS_FALSE;
+    }
+
+    /*
+     * obj_toString for 1.2 calls toSource, and doesn't want the extra parens
+     * on the outside.
+     */
+    outermost = !JS_VERSION_IS_1_2(cx) && cx->sharpObjectMap.depth == 0;
+    he = js_EnterSharpObject(cx, obj, &ida, &chars);
+    if (!he)
+        return JS_FALSE;
+    if (IS_SHARP(he)) {
+        /*
+         * We didn't enter -- obj is already "sharp", meaning we've visited it
+         * already in our depth first search, and therefore chars contains a
+         * string of the form "#n#".
+         */
+        JS_ASSERT(!ida);
+#if JS_HAS_SHARP_VARS
+        nchars = js_strlen(chars);
+#else
+        chars[0] = '{';
+        chars[1] = '}';
+        chars[2] = 0;
+        nchars = 2;
+#endif
+        goto make_string;
+    }
+    JS_ASSERT(ida);
+    ok = JS_TRUE;
+
+    if (!chars) {
+        /* If outermost, allocate 4 + 1 for "({})" and the terminator. */
+        chars = (jschar *) malloc(((outermost ? 4 : 2) + 1) * sizeof(jschar));
+        nchars = 0;
+        if (!chars)
+            goto error;
+        if (outermost)
+            chars[nchars++] = '(';
+    } else {
+        /* js_EnterSharpObject returned a string of the form "#n=" in chars. */
+        MAKE_SHARP(he);
+        nchars = js_strlen(chars);
+        chars = (jschar *)
+            realloc((ochars = chars), (nchars + 2 + 1) * sizeof(jschar));
+        if (!chars) {
+            free(ochars);
+            goto error;
+        }
+        if (outermost) {
+            /*
+             * No need for parentheses around the whole shebang, because #n=
+             * unambiguously begins an object initializer, and never a block
+             * statement.
+             */
+            outermost = JS_FALSE;
+        }
+    }
+
+#ifdef DUMP_CALL_TABLE
+    if (cx->options & JSOPTION_LOGCALL_TOSOURCE) {
+        const char *classname = OBJ_GET_CLASS(cx, obj)->name;
+        size_t classnchars = strlen(classname);
+        static const char classpropid[] = "C";
+        const char *cp;
+        size_t onchars = nchars;
+
+        /* 2 for ': ', 2 quotes around classname, 2 for ', ' after. */
+        classnchars += sizeof classpropid - 1 + 2 + 2;
+        if (ida->length)
+            classnchars += 2;
+
+        /* 2 for the braces, 1 for the terminator */
+        chars = (jschar *)
+            realloc((ochars = chars),
+                    (nchars + classnchars + 2 + 1) * sizeof(jschar));
+        if (!chars) {
+            free(ochars);
+            goto error;
+        }
+
+        chars[nchars++] = '{';          /* 1 from the 2 braces */
+        for (cp = classpropid; *cp; cp++)
+            chars[nchars++] = (jschar) *cp;
+        chars[nchars++] = ':';
+        chars[nchars++] = ' ';          /* 2 for ': ' */
+        chars[nchars++] = '"';
+        for (cp = classname; *cp; cp++)
+            chars[nchars++] = (jschar) *cp;
+        chars[nchars++] = '"';          /* 2 quotes */
+        if (ida->length) {
+            chars[nchars++] = ',';
+            chars[nchars++] = ' ';      /* 2 for ', ' */
+        }
+
+        JS_ASSERT(nchars - onchars == 1 + classnchars);
+    } else
+#endif
+    chars[nchars++] = '{';
+
+    comma = NULL;
+
+    /*
+     * We have four local roots for cooked and raw value GC safety.  Hoist the
+     * "argv + 2" out of the loop using the val local, which refers to the raw
+     * (unconverted, "uncooked") values.
+     */
+    val = argv + 2;
+
+    for (i = 0, length = ida->length; i < length; i++) {
+        /* Get strings for id and value and GC-root them via argv. */
+        id = ida->vector[i];
+
+#if JS_HAS_GETTER_SETTER
+
+        ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop);
+        if (!ok)
+            goto error;
+        valcnt = 0;
+        if (prop) {
+            ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);
+            if (!ok) {
+                OBJ_DROP_PROPERTY(cx, obj2, prop);
+                goto error;
+            }
+            if (OBJ_IS_NATIVE(obj2) &&
+                (attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
+                if (attrs & JSPROP_GETTER) {
+                    val[valcnt] = (jsval) ((JSScopeProperty *)prop)->getter;
+#ifdef OLD_GETTER_SETTER
+                    gsop[valcnt] =
+                        ATOM_TO_STRING(cx->runtime->atomState.getterAtom);
+#else
+                    gsop[valcnt] =
+                        ATOM_TO_STRING(cx->runtime->atomState.getAtom);
+#endif
+                    valcnt++;
+                }
+                if (attrs & JSPROP_SETTER) {
+                    val[valcnt] = (jsval) ((JSScopeProperty *)prop)->setter;
+#ifdef OLD_GETTER_SETTER
+                    gsop[valcnt] =
+                        ATOM_TO_STRING(cx->runtime->atomState.setterAtom);
+#else
+                    gsop[valcnt] =
+                        ATOM_TO_STRING(cx->runtime->atomState.setAtom);
+#endif
+                    valcnt++;
+                }
+            } else {
+                valcnt = 1;
+                gsop[0] = NULL;
+                ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]);
+            }
+            OBJ_DROP_PROPERTY(cx, obj2, prop);
+        }
+
+#else  /* !JS_HAS_GETTER_SETTER */
+
+        valcnt = 1;
+        gsop[0] = NULL;
+        ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]);
+
+#endif /* !JS_HAS_GETTER_SETTER */
+
+        if (!ok)
+            goto error;
+
+        /* Convert id to a jsval and then to a string. */
+        atom = JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : NULL;
+        id = ID_TO_VALUE(id);
+        idstr = js_ValueToString(cx, id);
+        if (!idstr) {
+            ok = JS_FALSE;
+            goto error;
+        }
+        *rval = STRING_TO_JSVAL(idstr);         /* local root */
+
+        /*
+         * If id is a string that's a reserved identifier, or else id is not
+         * an identifier at all, then it needs to be quoted.  Also, negative
+         * integer ids must be quoted.
+         */
+        if (atom
+            ? (ATOM_KEYWORD(atom) || !js_IsIdentifier(idstr))
+            : (JSID_IS_OBJECT(id) || JSID_TO_INT(id) < 0)) {
+            idstr = js_QuoteString(cx, idstr, (jschar)'\'');
+            if (!idstr) {
+                ok = JS_FALSE;
+                goto error;
+            }
+            *rval = STRING_TO_JSVAL(idstr);     /* local root */
+        }
+        idstrchars = JSSTRING_CHARS(idstr);
+        idstrlength = JSSTRING_LENGTH(idstr);
+
+        for (j = 0; j < valcnt; j++) {
+            /* Convert val[j] to its canonical source form. */
+            valstr = js_ValueToSource(cx, val[j]);
+            if (!valstr) {
+                ok = JS_FALSE;
+                goto error;
+            }
+            argv[j] = STRING_TO_JSVAL(valstr);  /* local root */
+            vchars = JSSTRING_CHARS(valstr);
+            vlength = JSSTRING_LENGTH(valstr);
+
+#ifndef OLD_GETTER_SETTER
+            /*
+             * Remove '(function ' from the beginning of valstr and ')' from the
+             * end so that we can put "get" in front of the function definition.
+             */
+            if (gsop[j]) {
+                int n = strlen(js_function_str) + 2;
+                vchars += n;
+                vlength -= n + 1;
+            }
+#endif
+
+            /* If val[j] is a non-sharp object, consider sharpening it. */
+            vsharp = NULL;
+            vsharplength = 0;
+#if JS_HAS_SHARP_VARS
+            if (!JSVAL_IS_PRIMITIVE(val[j]) && vchars[0] != '#') {
+                he = js_EnterSharpObject(cx, JSVAL_TO_OBJECT(val[j]), NULL,
+                                         &vsharp);
+                if (!he) {
+                    ok = JS_FALSE;
+                    goto error;
+                }
+                if (IS_SHARP(he)) {
+                    vchars = vsharp;
+                    vlength = js_strlen(vchars);
+                } else {
+                    if (vsharp) {
+                        vsharplength = js_strlen(vsharp);
+                        MAKE_SHARP(he);
+                    }
+                    js_LeaveSharpObject(cx, NULL);
+                }
+            }
+#endif
+
+            /* Allocate 1 + 1 at end for closing brace and terminating 0. */
+            chars = (jschar *)
+                realloc((ochars = chars),
+                        (nchars + (comma ? 2 : 0) +
+                         idstrlength + 1 +
+                         (gsop[j] ? 1 + JSSTRING_LENGTH(gsop[j]) : 0) +
+                         vsharplength + vlength +
+                         (outermost ? 2 : 1) + 1) * sizeof(jschar));
+            if (!chars) {
+                /* Save code space on error: let JS_free ignore null vsharp. */
+                JS_free(cx, vsharp);
+                free(ochars);
+                goto error;
+            }
+
+            if (comma) {
+                chars[nchars++] = comma[0];
+                chars[nchars++] = comma[1];
+            }
+            comma = ", ";
+
+#ifdef OLD_GETTER_SETTER
+            js_strncpy(&chars[nchars], idstrchars, idstrlength);
+            nchars += idstrlength;
+            if (gsop[j]) {
+                chars[nchars++] = ' ';
+                gsoplength = JSSTRING_LENGTH(gsop[j]);
+                js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]), gsoplength);
+                nchars += gsoplength;
+            }
+            chars[nchars++] = ':';
+#else
+            if (gsop[j]) {
+                gsoplength = JSSTRING_LENGTH(gsop[j]);
+                js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]), gsoplength);
+                nchars += gsoplength;
+                chars[nchars++] = ' ';
+            }
+            js_strncpy(&chars[nchars], idstrchars, idstrlength);
+            nchars += idstrlength;
+            if (!gsop[j])
+                chars[nchars++] = ':';
+#endif
+            if (vsharplength) {
+                js_strncpy(&chars[nchars], vsharp, vsharplength);
+                nchars += vsharplength;
+            }
+            js_strncpy(&chars[nchars], vchars, vlength);
+            nchars += vlength;
+
+            if (vsharp)
+                JS_free(cx, vsharp);
+#ifdef DUMP_CALL_TABLE
+            if (outermost && nchars >= js_LogCallToSourceLimit)
+                break;
+#endif
+        }
+    }
+
+    chars[nchars++] = '}';
+    if (outermost)
+        chars[nchars++] = ')';
+    chars[nchars] = 0;
+
+  error:
+    js_LeaveSharpObject(cx, &ida);
+
+    if (!ok) {
+        if (chars)
+            free(chars);
+        return ok;
+    }
+
+    if (!chars) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+  make_string:
+    str = js_NewString(cx, chars, nchars, 0);
+    if (!str) {
+        free(chars);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+#endif /* JS_HAS_INITIALIZERS || JS_HAS_TOSOURCE */
+
+JSBool
+js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    jschar *chars;
+    size_t nchars;
+    const char *clazz, *prefix;
+    JSString *str;
+
+#if JS_HAS_INITIALIZERS
+    if (JS_VERSION_IS_1_2(cx))
+        return js_obj_toSource(cx, obj, argc, argv, rval);
+#endif
+
+    clazz = OBJ_GET_CLASS(cx, obj)->name;
+    nchars = 9 + strlen(clazz);         /* 9 for "[object ]" */
+    chars = (jschar *) JS_malloc(cx, (nchars + 1) * sizeof(jschar));
+    if (!chars)
+        return JS_FALSE;
+
+    prefix = "[object ";
+    nchars = 0;
+    while ((chars[nchars] = (jschar)*prefix) != 0)
+        nchars++, prefix++;
+    while ((chars[nchars] = (jschar)*clazz) != 0)
+        nchars++, clazz++;
+    chars[nchars++] = ']';
+    chars[nchars] = 0;
+
+    str = js_NewString(cx, chars, nchars, 0);
+    if (!str) {
+        JS_free(cx, chars);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+js_obj_toLocaleString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                      jsval *rval)
+{
+    JSString *str;
+
+    str = js_ValueToString(cx, argv[-1]);
+    if (!str)
+        return JS_FALSE;
+
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+obj_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+/*
+ * Check whether principals subsumes scopeobj's principals, and return true
+ * if so (or if scopeobj has no principals, for backward compatibility with
+ * the JS API, which does not require principals), and false otherwise.
+ */
+JSBool
+js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj,
+                         JSPrincipals *principals, const char *caller)
+{
+    JSRuntime *rt;
+    JSPrincipals *scopePrincipals;
+
+    rt = cx->runtime;
+    if (rt->findObjectPrincipals) {
+        scopePrincipals = rt->findObjectPrincipals(cx, scopeobj);
+        if (!principals || !scopePrincipals ||
+            !principals->subsume(principals, scopePrincipals)) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_BAD_INDIRECT_CALL, caller);
+            return JS_FALSE;
+        }
+    }
+    return JS_TRUE;
+}
+
+JSObject *
+js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller)
+{
+    JSClass *clasp;
+    JSExtendedClass *xclasp;
+    JSObject *inner;
+
+    if (!scopeobj)
+        goto bad;
+
+    OBJ_TO_INNER_OBJECT(cx, scopeobj);
+    if (!scopeobj)
+        return NULL;
+
+    inner = scopeobj;
+
+    /* XXX This is an awful gross hack. */
+    while (scopeobj) {
+        clasp = OBJ_GET_CLASS(cx, scopeobj);
+        if (clasp->flags & JSCLASS_IS_EXTENDED) {
+            xclasp = (JSExtendedClass*)clasp;
+            if (xclasp->innerObject &&
+                xclasp->innerObject(cx, scopeobj) != scopeobj) {
+                goto bad;
+            }
+        }
+
+        scopeobj = OBJ_GET_PARENT(cx, scopeobj);
+    }
+
+    return inner;
+
+bad:
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                         JSMSG_BAD_INDIRECT_CALL, caller);
+    return NULL;
+}
+
+static JSBool
+obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSStackFrame *fp, *caller;
+    JSBool indirectCall;
+    JSObject *scopeobj;
+    JSString *str;
+    const char *file;
+    uintN line;
+    JSPrincipals *principals;
+    JSScript *script;
+    JSBool ok;
+#if JS_HAS_EVAL_THIS_SCOPE
+    JSObject *callerScopeChain = NULL, *callerVarObj = NULL;
+    JSBool setCallerScopeChain = JS_FALSE, setCallerVarObj = JS_FALSE;
+#endif
+
+    fp = cx->fp;
+    caller = JS_GetScriptedCaller(cx, fp);
+    indirectCall = (caller && caller->pc && *caller->pc != JSOP_EVAL);
+
+    if (JS_VERSION_IS_ECMA(cx) &&
+        indirectCall &&
+        !JS_ReportErrorFlagsAndNumber(cx,
+                                      JSREPORT_WARNING | JSREPORT_STRICT,
+                                      js_GetErrorMessage, NULL,
+                                      JSMSG_BAD_INDIRECT_CALL,
+                                      js_eval_str)) {
+        return JS_FALSE;
+    }
+
+    if (!JSVAL_IS_STRING(argv[0])) {
+        *rval = argv[0];
+        return JS_TRUE;
+    }
+
+#if JS_HAS_SCRIPT_OBJECT
+    /*
+     * Script.prototype.compile/exec and Object.prototype.eval all take an
+     * optional trailing argument that overrides the scope object.
+     */
+    scopeobj = NULL;
+    if (argc >= 2) {
+        if (!js_ValueToObject(cx, argv[1], &scopeobj))
+            return JS_FALSE;
+        argv[1] = OBJECT_TO_JSVAL(scopeobj);
+    }
+    if (!scopeobj)
+#endif
+    {
+#if JS_HAS_EVAL_THIS_SCOPE
+        /* If obj.eval(str), emulate 'with (obj) eval(str)' in the caller. */
+        if (indirectCall) {
+            callerScopeChain = caller->scopeChain;
+            if (obj != callerScopeChain) {
+                if (!js_CheckPrincipalsAccess(cx, obj,
+                                              caller->script->principals,
+                                              js_eval_str)) {
+                    return JS_FALSE;
+                }
+
+                scopeobj = js_NewObject(cx, &js_WithClass, obj,
+                                        callerScopeChain);
+                if (!scopeobj)
+                    return JS_FALSE;
+
+                /* Set fp->scopeChain too, for the compiler. */
+                caller->scopeChain = fp->scopeChain = scopeobj;
+                setCallerScopeChain = JS_TRUE;
+            }
+
+            callerVarObj = caller->varobj;
+            if (obj != callerVarObj) {
+                /* Set fp->varobj too, for the compiler. */
+                caller->varobj = fp->varobj = obj;
+                setCallerVarObj = JS_TRUE;
+            }
+        }
+        /* From here on, control must exit through label out with ok set. */
+#endif
+
+#if JS_BUG_EVAL_THIS_SCOPE
+        /* An old version used the object in which eval was found for scope. */
+        scopeobj = obj;
+#else
+        /* Compile using caller's current scope object. */
+        if (caller)
+            scopeobj = caller->scopeChain;
+#endif
+    }
+
+    /* Ensure we compile this eval with the right object in the scope chain. */
+    scopeobj = js_CheckScopeChainValidity(cx, scopeobj, js_eval_str);
+    if (!scopeobj)
+        return JS_FALSE;
+
+    str = JSVAL_TO_STRING(argv[0]);
+    if (caller) {
+        file = caller->script->filename;
+        line = js_PCToLineNumber(cx, caller->script, caller->pc);
+        principals = JS_EvalFramePrincipals(cx, fp, caller);
+    } else {
+        file = NULL;
+        line = 0;
+        principals = NULL;
+    }
+
+    /*
+     * Set JSFRAME_EVAL on fp and any frames (e.g., fun_call if eval.call was
+     * invoked) between fp and its scripted caller, to help the compiler easily
+     * find the same caller whose scope and var obj we've set.
+     *
+     * XXX this nonsense could, and perhaps should, go away with a better way
+     * to pass params to the compiler than via the top-most frame.
+     */
+    do {
+        fp->flags |= JSFRAME_EVAL;
+    } while ((fp = fp->down) != caller);
+
+    script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals,
+                                             JSSTRING_CHARS(str),
+                                             JSSTRING_LENGTH(str),
+                                             file, line);
+    if (!script) {
+        ok = JS_FALSE;
+        goto out;
+    }
+
+#if !JS_BUG_EVAL_THIS_SCOPE
+#if JS_HAS_SCRIPT_OBJECT
+    if (argc < 2)
+#endif
+    {
+        /* Execute using caller's new scope object (might be a Call object). */
+        if (caller)
+            scopeobj = caller->scopeChain;
+    }
+#endif
+
+    /*
+     * Belt-and-braces: check that the lesser of eval's principals and the
+     * caller's principals has access to scopeobj.
+     */
+    ok = js_CheckPrincipalsAccess(cx, scopeobj, principals, js_eval_str);
+    if (!ok)
+        goto out;
+
+    ok = js_Execute(cx, scopeobj, script, caller, JSFRAME_EVAL, rval);
+    JS_DestroyScript(cx, script);
+
+out:
+#if JS_HAS_EVAL_THIS_SCOPE
+    /* Restore OBJ_GET_PARENT(scopeobj) not callerScopeChain in case of Call. */
+    if (setCallerScopeChain)
+        caller->scopeChain = callerScopeChain;
+    if (setCallerVarObj)
+        caller->varobj = callerVarObj;
+#endif
+    return ok;
+}
+
+#if JS_HAS_OBJ_WATCHPOINT
+
+static JSBool
+obj_watch_handler(JSContext *cx, JSObject *obj, jsval id, jsval old, jsval *nvp,
+                  void *closure)
+{
+    JSResolvingKey key;
+    JSResolvingEntry *entry;
+    uint32 generation;
+    JSObject *funobj;
+    jsval argv[3];
+    JSBool ok;
+
+    /* Avoid recursion on (obj, id) already being watched on cx. */
+    key.obj = obj;
+    key.id = id;
+    if (!js_StartResolving(cx, &key, JSRESFLAG_WATCH, &entry))
+        return JS_FALSE;
+    if (!entry)
+        return JS_TRUE;
+    generation = cx->resolvingTable->generation;
+
+    funobj = (JSObject *) closure;
+    argv[0] = id;
+    argv[1] = old;
+    argv[2] = *nvp;
+    ok = js_InternalCall(cx, obj, OBJECT_TO_JSVAL(funobj), 3, argv, nvp);
+    js_StopResolving(cx, &key, JSRESFLAG_WATCH, entry, generation);
+    return ok;
+}
+
+static JSBool
+obj_watch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSObject *callable;
+    jsval userid, value;
+    jsid propid;
+    uintN attrs;
+
+    callable = js_ValueToCallableObject(cx, &argv[1], 0);
+    if (!callable)
+        return JS_FALSE;
+
+    /* Compute the unique int/atom symbol id needed by js_LookupProperty. */
+    userid = argv[0];
+    if (!JS_ValueToId(cx, userid, &propid))
+        return JS_FALSE;
+
+    if (!OBJ_CHECK_ACCESS(cx, obj, propid, JSACC_WATCH, &value, &attrs))
+        return JS_FALSE;
+    if (attrs & JSPROP_READONLY)
+        return JS_TRUE;
+    return JS_SetWatchPoint(cx, obj, userid, obj_watch_handler, callable);
+}
+
+static JSBool
+obj_unwatch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return JS_ClearWatchPoint(cx, obj, argv[0], NULL, NULL);
+}
+
+#endif /* JS_HAS_OBJ_WATCHPOINT */
+
+#if JS_HAS_NEW_OBJ_METHODS
+/*
+ * Prototype and property query methods, to complement the 'in' and
+ * 'instanceof' operators.
+ */
+
+/* Proposed ECMA 15.2.4.5. */
+static JSBool
+obj_hasOwnProperty(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                   jsval *rval)
+{
+    return js_HasOwnPropertyHelper(cx, obj, obj->map->ops->lookupProperty,
+                                   argc, argv, rval);
+}
+
+JSBool
+js_HasOwnPropertyHelper(JSContext *cx, JSObject *obj, JSLookupPropOp lookup,
+                        uintN argc, jsval *argv, jsval *rval)
+{
+    jsid id;
+    JSObject *obj2;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+
+    if (!JS_ValueToId(cx, argv[0], &id))
+        return JS_FALSE;
+    if (!lookup(cx, obj, id, &obj2, &prop))
+        return JS_FALSE;
+    if (!prop) {
+        *rval = JSVAL_FALSE;
+    } else if (obj2 == obj) {
+        *rval = JSVAL_TRUE;
+    } else if (OBJ_IS_NATIVE(obj2)) {
+        sprop = (JSScopeProperty *)prop;
+        *rval = BOOLEAN_TO_JSVAL(SPROP_IS_SHARED_PERMANENT(sprop));
+    } else {
+        *rval = JSVAL_FALSE;
+    }
+    if (prop)
+        OBJ_DROP_PROPERTY(cx, obj2, prop);
+    return JS_TRUE;
+}
+
+/* Proposed ECMA 15.2.4.6. */
+static JSBool
+obj_isPrototypeOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                  jsval *rval)
+{
+    JSBool b;
+
+    if (!js_IsDelegate(cx, obj, *argv, &b))
+        return JS_FALSE;
+    *rval = BOOLEAN_TO_JSVAL(b);
+    return JS_TRUE;
+}
+
+/* Proposed ECMA 15.2.4.7. */
+static JSBool
+obj_propertyIsEnumerable(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                         jsval *rval)
+{
+    jsid id;
+    uintN attrs;
+    JSObject *obj2;
+    JSProperty *prop;
+    JSBool ok;
+
+    if (!JS_ValueToId(cx, argv[0], &id))
+        return JS_FALSE;
+
+    if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop))
+        return JS_FALSE;
+
+    if (!prop) {
+        *rval = JSVAL_FALSE;
+        return JS_TRUE;
+    }
+
+    /*
+     * XXX ECMA spec error compatible: return false unless hasOwnProperty.
+     * The ECMA spec really should be fixed so propertyIsEnumerable and the
+     * for..in loop agree on whether prototype properties are enumerable,
+     * obviously by fixing this method (not by breaking the for..in loop!).
+     *
+     * We check here for shared permanent prototype properties, which should
+     * be treated as if they are local to obj.  They are an implementation
+     * technique used to satisfy ECMA requirements; users should not be able
+     * to distinguish a shared permanent proto-property from a local one.
+     */
+    if (obj2 != obj &&
+        !(OBJ_IS_NATIVE(obj2) &&
+          SPROP_IS_SHARED_PERMANENT((JSScopeProperty *)prop))) {
+        OBJ_DROP_PROPERTY(cx, obj2, prop);
+        *rval = JSVAL_FALSE;
+        return JS_TRUE;
+    }
+
+    ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs);
+    OBJ_DROP_PROPERTY(cx, obj2, prop);
+    if (ok)
+        *rval = BOOLEAN_TO_JSVAL((attrs & JSPROP_ENUMERATE) != 0);
+    return ok;
+}
+#endif /* JS_HAS_NEW_OBJ_METHODS */
+
+#if JS_HAS_GETTER_SETTER
+static JSBool
+obj_defineGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    jsval fval, junk;
+    jsid id;
+    uintN attrs;
+
+    fval = argv[1];
+    if (JS_TypeOfValue(cx, fval) != JSTYPE_FUNCTION) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_GETTER_OR_SETTER,
+                             js_getter_str);
+        return JS_FALSE;
+    }
+
+    if (!JS_ValueToId(cx, argv[0], &id))
+        return JS_FALSE;
+    if (!js_CheckRedeclaration(cx, obj, id, JSPROP_GETTER, NULL, NULL))
+        return JS_FALSE;
+    /*
+     * Getters and setters are just like watchpoints from an access
+     * control point of view.
+     */
+    if (!OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &junk, &attrs))
+        return JS_FALSE;
+    return OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID,
+                               (JSPropertyOp) JSVAL_TO_OBJECT(fval), NULL,
+                               JSPROP_ENUMERATE | JSPROP_GETTER | JSPROP_SHARED,
+                               NULL);
+}
+
+static JSBool
+obj_defineSetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    jsval fval, junk;
+    jsid id;
+    uintN attrs;
+
+    fval = argv[1];
+    if (JS_TypeOfValue(cx, fval) != JSTYPE_FUNCTION) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_GETTER_OR_SETTER,
+                             js_setter_str);
+        return JS_FALSE;
+    }
+
+    if (!JS_ValueToId(cx, argv[0], &id))
+        return JS_FALSE;
+    if (!js_CheckRedeclaration(cx, obj, id, JSPROP_SETTER, NULL, NULL))
+        return JS_FALSE;
+    /*
+     * Getters and setters are just like watchpoints from an access
+     * control point of view.
+     */
+    if (!OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &junk, &attrs))
+        return JS_FALSE;
+    return OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID,
+                               NULL, (JSPropertyOp) JSVAL_TO_OBJECT(fval),
+                               JSPROP_ENUMERATE | JSPROP_SETTER | JSPROP_SHARED,
+                               NULL);
+}
+
+static JSBool
+obj_lookupGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    jsid id;
+    JSObject *pobj;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+
+    if (!JS_ValueToId(cx, argv[0], &id))
+        return JS_FALSE;
+    if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
+        return JS_FALSE;
+    if (prop) {
+        if (OBJ_IS_NATIVE(pobj)) {
+            sprop = (JSScopeProperty *) prop;
+            if (sprop->attrs & JSPROP_GETTER)
+                *rval = OBJECT_TO_JSVAL(sprop->getter);
+        }
+        OBJ_DROP_PROPERTY(cx, pobj, prop);
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+obj_lookupSetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    jsid id;
+    JSObject *pobj;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+
+    if (!JS_ValueToId(cx, argv[0], &id))
+        return JS_FALSE;
+    if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
+        return JS_FALSE;
+    if (prop) {
+        if (OBJ_IS_NATIVE(pobj)) {
+            sprop = (JSScopeProperty *) prop;
+            if (sprop->attrs & JSPROP_SETTER)
+                *rval = OBJECT_TO_JSVAL(sprop->setter);
+        }
+        OBJ_DROP_PROPERTY(cx, pobj, prop);
+    }
+    return JS_TRUE;
+}
+#endif /* JS_HAS_GETTER_SETTER */
+
+#if JS_HAS_OBJ_WATCHPOINT
+const char js_watch_str[] = "watch";
+const char js_unwatch_str[] = "unwatch";
+#endif
+#if JS_HAS_NEW_OBJ_METHODS
+const char js_hasOwnProperty_str[] = "hasOwnProperty";
+const char js_isPrototypeOf_str[] = "isPrototypeOf";
+const char js_propertyIsEnumerable_str[] = "propertyIsEnumerable";
+#endif
+#if JS_HAS_GETTER_SETTER
+const char js_defineGetter_str[] = "__defineGetter__";
+const char js_defineSetter_str[] = "__defineSetter__";
+const char js_lookupGetter_str[] = "__lookupGetter__";
+const char js_lookupSetter_str[] = "__lookupSetter__";
+#endif
+
+static JSFunctionSpec object_methods[] = {
+#if JS_HAS_TOSOURCE
+    {js_toSource_str,             js_obj_toSource,    0, 0, OBJ_TOSTRING_EXTRA},
+#endif
+    {js_toString_str,             js_obj_toString,    0, 0, OBJ_TOSTRING_EXTRA},
+    {js_toLocaleString_str,       js_obj_toLocaleString, 0, 0, OBJ_TOSTRING_EXTRA},
+    {js_valueOf_str,              obj_valueOf,        0,0,0},
+    {js_eval_str,                 obj_eval,           1,0,0},
+#if JS_HAS_OBJ_WATCHPOINT
+    {js_watch_str,                obj_watch,          2,0,0},
+    {js_unwatch_str,              obj_unwatch,        1,0,0},
+#endif
+#if JS_HAS_NEW_OBJ_METHODS
+    {js_hasOwnProperty_str,       obj_hasOwnProperty, 1,0,0},
+    {js_isPrototypeOf_str,        obj_isPrototypeOf,  1,0,0},
+    {js_propertyIsEnumerable_str, obj_propertyIsEnumerable, 1,0,0},
+#endif
+#if JS_HAS_GETTER_SETTER
+    {js_defineGetter_str,         obj_defineGetter,   2,0,0},
+    {js_defineSetter_str,         obj_defineSetter,   2,0,0},
+    {js_lookupGetter_str,         obj_lookupGetter,   1,0,0},
+    {js_lookupSetter_str,         obj_lookupSetter,   1,0,0},
+#endif
+    {0,0,0,0,0}
+};
+
+static JSBool
+Object(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    if (argc == 0) {
+        /* Trigger logic below to construct a blank object. */
+        obj = NULL;
+    } else {
+        /* If argv[0] is null or undefined, obj comes back null. */
+        if (!js_ValueToObject(cx, argv[0], &obj))
+            return JS_FALSE;
+    }
+    if (!obj) {
+        JS_ASSERT(!argc || JSVAL_IS_NULL(argv[0]) || JSVAL_IS_VOID(argv[0]));
+        if (cx->fp->flags & JSFRAME_CONSTRUCTING)
+            return JS_TRUE;
+        obj = js_NewObject(cx, &js_ObjectClass, NULL, NULL);
+        if (!obj)
+            return JS_FALSE;
+    }
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+/*
+ * ObjectOps and Class for with-statement stack objects.
+ */
+static JSBool
+with_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
+                    JSProperty **propp)
+{
+    JSObject *proto = OBJ_GET_PROTO(cx, obj);
+    if (!proto)
+        return js_LookupProperty(cx, obj, id, objp, propp);
+    return OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp);
+}
+
+static JSBool
+with_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+{
+    JSObject *proto = OBJ_GET_PROTO(cx, obj);
+    if (!proto)
+        return js_GetProperty(cx, obj, id, vp);
+    return OBJ_GET_PROPERTY(cx, proto, id, vp);
+}
+
+static JSBool
+with_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+{
+    JSObject *proto = OBJ_GET_PROTO(cx, obj);
+    if (!proto)
+        return js_SetProperty(cx, obj, id, vp);
+    return OBJ_SET_PROPERTY(cx, proto, id, vp);
+}
+
+static JSBool
+with_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
+                   uintN *attrsp)
+{
+    JSObject *proto = OBJ_GET_PROTO(cx, obj);
+    if (!proto)
+        return js_GetAttributes(cx, obj, id, prop, attrsp);
+    return OBJ_GET_ATTRIBUTES(cx, proto, id, prop, attrsp);
+}
+
+static JSBool
+with_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
+                   uintN *attrsp)
+{
+    JSObject *proto = OBJ_GET_PROTO(cx, obj);
+    if (!proto)
+        return js_SetAttributes(cx, obj, id, prop, attrsp);
+    return OBJ_SET_ATTRIBUTES(cx, proto, id, prop, attrsp);
+}
+
+static JSBool
+with_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
+{
+    JSObject *proto = OBJ_GET_PROTO(cx, obj);
+    if (!proto)
+        return js_DeleteProperty(cx, obj, id, rval);
+    return OBJ_DELETE_PROPERTY(cx, proto, id, rval);
+}
+
+static JSBool
+with_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
+{
+    JSObject *proto = OBJ_GET_PROTO(cx, obj);
+    if (!proto)
+        return js_DefaultValue(cx, obj, hint, vp);
+    return OBJ_DEFAULT_VALUE(cx, proto, hint, vp);
+}
+
+static JSBool
+with_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
+               jsval *statep, jsid *idp)
+{
+    JSObject *proto = OBJ_GET_PROTO(cx, obj);
+    if (!proto)
+        return js_Enumerate(cx, obj, enum_op, statep, idp);
+    return OBJ_ENUMERATE(cx, proto, enum_op, statep, idp);
+}
+
+static JSBool
+with_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
+                 jsval *vp, uintN *attrsp)
+{
+    JSObject *proto = OBJ_GET_PROTO(cx, obj);
+    if (!proto)
+        return js_CheckAccess(cx, obj, id, mode, vp, attrsp);
+    return OBJ_CHECK_ACCESS(cx, proto, id, mode, vp, attrsp);
+}
+
+static JSObject *
+with_ThisObject(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto = OBJ_GET_PROTO(cx, obj);
+    if (!proto)
+        return obj;
+    return OBJ_THIS_OBJECT(cx, proto);
+}
+
+JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps = {
+    js_NewObjectMap,        js_DestroyObjectMap,
+    with_LookupProperty,    js_DefineProperty,
+    with_GetProperty,       with_SetProperty,
+    with_GetAttributes,     with_SetAttributes,
+    with_DeleteProperty,    with_DefaultValue,
+    with_Enumerate,         with_CheckAccess,
+    with_ThisObject,        NATIVE_DROP_PROPERTY,
+    NULL,                   NULL,
+    NULL,                   NULL,
+    js_SetProtoOrParent,    js_SetProtoOrParent,
+    js_Mark,                js_Clear,
+    NULL,                   NULL
+};
+
+static JSObjectOps *
+with_getObjectOps(JSContext *cx, JSClass *clasp)
+{
+    return &js_WithObjectOps;
+}
+
+JSClass js_WithClass = {
+    "With",
+    JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   JS_FinalizeStub,
+    with_getObjectOps,
+    0,0,0,0,0,0,0
+};
+
+#if JS_HAS_OBJ_PROTO_PROP
+static JSBool
+With(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSObject *parent, *proto;
+    jsval v;
+
+    if (!JS_ReportErrorFlagsAndNumber(cx,
+                                      JSREPORT_WARNING | JSREPORT_STRICT,
+                                      js_GetErrorMessage, NULL,
+                                      JSMSG_DEPRECATED_USAGE,
+                                      js_WithClass.name)) {
+        return JS_FALSE;
+    }
+
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        obj = js_NewObject(cx, &js_WithClass, NULL, NULL);
+        if (!obj)
+            return JS_FALSE;
+        *rval = OBJECT_TO_JSVAL(obj);
+    }
+
+    parent = cx->fp->scopeChain;
+    if (argc > 0) {
+        if (!js_ValueToObject(cx, argv[0], &proto))
+            return JS_FALSE;
+        v = OBJECT_TO_JSVAL(proto);
+        if (!obj_setSlot(cx, obj, INT_TO_JSVAL(JSSLOT_PROTO), &v))
+            return JS_FALSE;
+        if (argc > 1) {
+            if (!js_ValueToObject(cx, argv[1], &parent))
+                return JS_FALSE;
+        }
+    }
+    v = OBJECT_TO_JSVAL(parent);
+    return obj_setSlot(cx, obj, INT_TO_JSVAL(JSSLOT_PARENT), &v);
+}
+#endif
+
+JSObject *
+js_InitObjectClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto;
+    jsval eval;
+
+#if JS_HAS_SHARP_VARS
+    JS_ASSERT(sizeof(jsatomid) * JS_BITS_PER_BYTE >= ATOM_INDEX_LIMIT_LOG2 + 1);
+#endif
+
+    proto = JS_InitClass(cx, obj, NULL, &js_ObjectClass, Object, 1,
+                         object_props, object_methods, NULL, NULL);
+    if (!proto)
+        return NULL;
+
+#if JS_HAS_OBJ_PROTO_PROP
+    if (!JS_InitClass(cx, obj, NULL, &js_WithClass, With, 0,
+                      NULL, NULL, NULL, NULL)) {
+        return NULL;
+    }
+#endif
+
+    /* ECMA (15.1.2.1) says 'eval' is also a property of the global object. */
+    if (!OBJ_GET_PROPERTY(cx, proto,
+                          ATOM_TO_JSID(cx->runtime->atomState.evalAtom),
+                          &eval)) {
+        return NULL;
+    }
+    if (!OBJ_DEFINE_PROPERTY(cx, obj,
+                             ATOM_TO_JSID(cx->runtime->atomState.evalAtom),
+                             eval, NULL, NULL, 0, NULL)) {
+        return NULL;
+    }
+
+    return proto;
+}
+
+void
+js_InitObjectMap(JSObjectMap *map, jsrefcount nrefs, JSObjectOps *ops,
+                 JSClass *clasp)
+{
+    map->nrefs = nrefs;
+    map->ops = ops;
+    map->nslots = JS_INITIAL_NSLOTS;
+    map->freeslot = JSSLOT_FREE(clasp);
+}
+
+JSObjectMap *
+js_NewObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops,
+                JSClass *clasp, JSObject *obj)
+{
+    return (JSObjectMap *) js_NewScope(cx, nrefs, ops, clasp, obj);
+}
+
+void
+js_DestroyObjectMap(JSContext *cx, JSObjectMap *map)
+{
+    js_DestroyScope(cx, (JSScope *)map);
+}
+
+JSObjectMap *
+js_HoldObjectMap(JSContext *cx, JSObjectMap *map)
+{
+    JS_ASSERT(map->nrefs >= 0);
+    JS_ATOMIC_INCREMENT(&map->nrefs);
+    return map;
+}
+
+JSObjectMap *
+js_DropObjectMap(JSContext *cx, JSObjectMap *map, JSObject *obj)
+{
+    JS_ASSERT(map->nrefs > 0);
+    JS_ATOMIC_DECREMENT(&map->nrefs);
+    if (map->nrefs == 0) {
+        map->ops->destroyObjectMap(cx, map);
+        return NULL;
+    }
+    if (MAP_IS_NATIVE(map) && ((JSScope *)map)->object == obj)
+        ((JSScope *)map)->object = NULL;
+    return map;
+}
+
+static JSBool
+GetClassPrototype(JSContext *cx, JSObject *scope, const char *name,
+                  JSObject **protop);
+
+static jsval *
+AllocSlots(JSContext *cx, jsval *slots, uint32 nslots)
+{
+    size_t nbytes, obytes, minbytes;
+    uint32 i, oslots;
+    jsval *newslots;
+
+    nbytes = (nslots + 1) * sizeof(jsval);
+    if (slots) {
+        oslots = slots[-1];
+        obytes = (oslots + 1) * sizeof(jsval);
+    } else {
+        oslots = 0;
+        obytes = 0;
+    }
+
+    if (nbytes <= GC_NBYTES_MAX) {
+        newslots = (jsval *) js_NewGCThing(cx, GCX_PRIVATE, nbytes);
+    } else {
+        newslots = (jsval *)
+                   JS_realloc(cx,
+                              (obytes <= GC_NBYTES_MAX) ? NULL : slots - 1,
+                              nbytes);
+    }
+    if (!newslots)
+        return NULL;
+
+    if (obytes != 0) {
+        /* If either nbytes or obytes fit in a GC-thing, we must copy. */
+        minbytes = JS_MIN(nbytes, obytes);
+        if (minbytes <= GC_NBYTES_MAX)
+            memcpy(newslots + 1, slots, minbytes - sizeof(jsval));
+
+        /* If nbytes are in a GC-thing but obytes aren't, free obytes. */
+        if (nbytes <= GC_NBYTES_MAX && obytes > GC_NBYTES_MAX)
+            JS_free(cx, slots - 1);
+
+        /* If we're extending an allocation, initialize free slots. */
+        if (nslots > oslots) {
+            for (i = 1 + oslots; i <= nslots; i++)
+                newslots[i] = JSVAL_VOID;
+        }
+    }
+
+    newslots[0] = nslots;
+    return ++newslots;
+}
+
+static void
+FreeSlots(JSContext *cx, jsval *slots)
+{
+    size_t nbytes;
+
+    /*
+     * NB: We count on smaller GC-things being finalized before larger things
+     * that become garbage during the same GC.  Without this assumption, we
+     * couldn't load slots[-1] here without possibly loading a gcFreeList link
+     * (see struct JSGCThing in jsgc.h).
+     */
+    nbytes = (slots[-1] + 1) * sizeof(jsval);
+    if (nbytes > GC_NBYTES_MAX)
+        JS_free(cx, slots - 1);
+}
+
+JSObject *
+js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
+{
+    JSObject *obj;
+    JSObjectOps *ops;
+    JSObjectMap *map;
+    JSClass *protoclasp;
+    uint32 nslots, i;
+    jsval *newslots;
+
+    /* Bootstrap the ur-object, and make it the default prototype object. */
+    if (!proto) {
+        if (!GetClassPrototype(cx, parent, clasp->name, &proto))
+            return NULL;
+        if (!proto && !GetClassPrototype(cx, parent, js_Object_str, &proto))
+            return NULL;
+    }
+
+    /* Always call the class's getObjectOps hook if it has one. */
+    ops = clasp->getObjectOps
+          ? clasp->getObjectOps(cx, clasp)
+          : &js_ObjectOps;
+
+    /*
+     * Allocate a zeroed object from the GC heap.  Do this *after* any other
+     * GC-thing allocations under GetClassPrototype or clasp->getObjectOps,
+     * to avoid displacing the newborn root for obj.
+     */
+    obj = (JSObject *) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject));
+    if (!obj)
+        return NULL;
+
+    /*
+     * Share proto's map only if it has the same JSObjectOps, and only if
+     * proto's class has the same private and reserved slots as obj's map
+     * and class have.  We assume that if prototype and object are of the
+     * same class, they always have the same number of computed reserved
+     * slots (returned via clasp->reserveSlots); otherwise, prototype and
+     * object classes must have the same (null or not) reserveSlots hook.
+     */
+    if (proto &&
+        (map = proto->map)->ops == ops &&
+        ((protoclasp = OBJ_GET_CLASS(cx, proto)) == clasp ||
+         (!((protoclasp->flags ^ clasp->flags) &
+            (JSCLASS_HAS_PRIVATE |
+             (JSCLASS_RESERVED_SLOTS_MASK << JSCLASS_RESERVED_SLOTS_SHIFT))) &&
+          protoclasp->reserveSlots == clasp->reserveSlots)))
+    {
+        /*
+         * Default parent to the parent of the prototype, which was set from
+         * the parent of the prototype's constructor.
+         */
+        if (!parent)
+            parent = OBJ_GET_PARENT(cx, proto);
+
+        /* Share the given prototype's map. */
+        obj->map = js_HoldObjectMap(cx, map);
+
+        /* Ensure that obj starts with the minimum slots for clasp. */
+        nslots = JS_INITIAL_NSLOTS;
+    } else {
+        /* Leave parent alone.  Allocate a new map for obj. */
+        map = ops->newObjectMap(cx, 1, ops, clasp, obj);
+        if (!map)
+            goto bad;
+        obj->map = map;
+
+        /* Let ops->newObjectMap set nslots so as to reserve slots. */
+        nslots = map->nslots;
+    }
+
+    /* Allocate a slots vector, with a -1'st element telling its length. */
+    newslots = AllocSlots(cx, NULL, nslots);
+    if (!newslots) {
+        js_DropObjectMap(cx, obj->map, obj);
+        obj->map = NULL;
+        goto bad;
+    }
+
+    /* Set the proto, parent, and class properties. */
+    newslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto);
+    newslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent);
+    newslots[JSSLOT_CLASS] = PRIVATE_TO_JSVAL(clasp);
+
+    /* Clear above JSSLOT_CLASS so the GC doesn't load uninitialized memory. */
+    for (i = JSSLOT_CLASS + 1; i < nslots; i++)
+        newslots[i] = JSVAL_VOID;
+
+    /* Store newslots after initializing all of 'em, just in case. */
+    obj->slots = newslots;
+
+    if (cx->runtime->objectHook) {
+        JS_KEEP_ATOMS(cx->runtime);
+        cx->runtime->objectHook(cx, obj, JS_TRUE, cx->runtime->objectHookData);
+        JS_UNKEEP_ATOMS(cx->runtime);
+    }
+
+    return obj;
+
+bad:
+    cx->newborn[GCX_OBJECT] = NULL;
+    return NULL;
+}
+
+JSBool
+js_FindConstructor(JSContext *cx, JSObject *start, const char *name, jsval *vp)
+{
+    JSAtom *atom;
+    JSObject *obj, *pobj;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+
+    atom = js_Atomize(cx, name, strlen(name), 0);
+    if (!atom)
+        return JS_FALSE;
+
+    if (start || (cx->fp && (start = cx->fp->scopeChain) != NULL)) {
+        /* Find the topmost object in the scope chain. */
+        do {
+            obj = start;
+            start = OBJ_GET_PARENT(cx, obj);
+        } while (start);
+    } else {
+        obj = cx->globalObject;
+        if (!obj) {
+            *vp = JSVAL_VOID;
+            return JS_TRUE;
+        }
+    }
+
+    JS_ASSERT(OBJ_IS_NATIVE(obj));
+    if (!js_LookupPropertyWithFlags(cx, obj, ATOM_TO_JSID(atom),
+                                    JSRESOLVE_CLASSNAME, &pobj, &prop)) {
+        return JS_FALSE;
+    }
+    if (!prop)  {
+        *vp = JSVAL_VOID;
+        return JS_TRUE;
+    }
+
+    JS_ASSERT(OBJ_IS_NATIVE(pobj));
+    sprop = (JSScopeProperty *) prop;
+    JS_ASSERT(SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)));
+    *vp = OBJ_GET_SLOT(cx, pobj, sprop->slot);
+    OBJ_DROP_PROPERTY(cx, pobj, prop);
+    return JS_TRUE;
+}
+
+JSObject *
+js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
+                   JSObject *parent, uintN argc, jsval *argv)
+{
+    jsval cval, rval;
+    JSTempValueRooter tvr;
+    JSObject *obj, *ctor;
+
+    if (!js_FindConstructor(cx, parent, clasp->name, &cval))
+        return NULL;
+    if (JSVAL_IS_PRIMITIVE(cval)) {
+        js_ReportIsNotFunction(cx, &cval, JSV2F_CONSTRUCT | JSV2F_SEARCH_STACK);
+        return NULL;
+    }
+
+    /*
+     * Protect cval in case a crazy getter for .prototype uproots it.  After
+     * this point, all control flow must exit through label out with obj set.
+     */
+    JS_PUSH_SINGLE_TEMP_ROOT(cx, cval, &tvr);
+    obj = NULL;
+
+    /*
+     * If proto or parent are NULL, set them to Constructor.prototype and/or
+     * Constructor.__parent__, just like JSOP_NEW does.
+     */
+    ctor = JSVAL_TO_OBJECT(cval);
+    if (!parent)
+        parent = OBJ_GET_PARENT(cx, ctor);
+    if (!proto) {
+        if (!OBJ_GET_PROPERTY(cx, ctor,
+                              ATOM_TO_JSID(cx->runtime->atomState
+                                           .classPrototypeAtom),
+                              &rval)) {
+            goto out;
+        }
+        if (JSVAL_IS_OBJECT(rval))
+            proto = JSVAL_TO_OBJECT(rval);
+    }
+
+    obj = js_NewObject(cx, clasp, proto, parent);
+    if (!obj)
+        goto out;
+
+    if (!js_InternalConstruct(cx, obj, cval, argc, argv, &rval)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        obj = NULL;
+        goto out;
+    }
+
+    if (!JSVAL_IS_PRIMITIVE(rval))
+        obj = JSVAL_TO_OBJECT(rval);
+out:
+    JS_POP_TEMP_ROOT(cx, &tvr);
+    return obj;
+}
+
+void
+js_FinalizeObject(JSContext *cx, JSObject *obj)
+{
+    JSObjectMap *map;
+
+    /* Cope with stillborn objects that have no map. */
+    map = obj->map;
+    if (!map)
+        return;
+    JS_ASSERT(obj->slots);
+
+    if (cx->runtime->objectHook)
+        cx->runtime->objectHook(cx, obj, JS_FALSE, cx->runtime->objectHookData);
+
+    /* Remove all watchpoints with weak links to obj. */
+    JS_ClearWatchPointsForObject(cx, obj);
+
+    /*
+     * Finalize obj first, in case it needs map and slots.  Optimized to use
+     * LOCKED_OBJ_GET_CLASS instead of OBJ_GET_CLASS, so we avoid "promoting"
+     * obj's scope from lock-free to lock-full (see jslock.c:ClaimScope) when
+     * we're called from the GC.  Only the GC should call js_FinalizeObject,
+     * and no other threads run JS (and possibly racing to update obj->slots)
+     * while the GC is running.
+     */
+    LOCKED_OBJ_GET_CLASS(obj)->finalize(cx, obj);
+
+    /* Drop map and free slots. */
+    js_DropObjectMap(cx, map, obj);
+    obj->map = NULL;
+    FreeSlots(cx, obj->slots);
+    obj->slots = NULL;
+}
+
+/* XXXbe if one adds props, deletes earlier props, adds more, the last added
+         won't recycle the deleted props' slots. */
+JSBool
+js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp)
+{
+    JSObjectMap *map;
+    JSClass *clasp;
+    uint32 nslots;
+    jsval *newslots;
+
+    map = obj->map;
+    JS_ASSERT(!MAP_IS_NATIVE(map) || ((JSScope *)map)->object == obj);
+    clasp = LOCKED_OBJ_GET_CLASS(obj);
+    if (map->freeslot == JSSLOT_FREE(clasp)) {
+        /* Adjust map->freeslot to include computed reserved slots, if any. */
+        if (clasp->reserveSlots)
+            map->freeslot += clasp->reserveSlots(cx, obj);
+    }
+    nslots = map->nslots;
+    if (map->freeslot >= nslots) {
+        nslots = map->freeslot;
+        JS_ASSERT(nslots >= JS_INITIAL_NSLOTS);
+        nslots += (nslots + 1) / 2;
+
+        newslots = AllocSlots(cx, obj->slots, nslots);
+        if (!newslots)
+            return JS_FALSE;
+        map->nslots = nslots;
+        obj->slots = newslots;
+    }
+
+#ifdef TOO_MUCH_GC
+    obj->slots[map->freeslot] = JSVAL_VOID;
+#endif
+    *slotp = map->freeslot++;
+    return JS_TRUE;
+}
+
+void
+js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot)
+{
+    JSObjectMap *map;
+    uint32 nslots;
+    jsval *newslots;
+
+    OBJ_CHECK_SLOT(obj, slot);
+    obj->slots[slot] = JSVAL_VOID;
+    map = obj->map;
+    JS_ASSERT(!MAP_IS_NATIVE(map) || ((JSScope *)map)->object == obj);
+    if (map->freeslot == slot + 1)
+        map->freeslot = slot;
+    nslots = map->nslots;
+    if (nslots > JS_INITIAL_NSLOTS && map->freeslot < nslots / 2) {
+        nslots = map->freeslot;
+        nslots += nslots / 2;
+        if (nslots < JS_INITIAL_NSLOTS)
+            nslots = JS_INITIAL_NSLOTS;
+
+        newslots = AllocSlots(cx, obj->slots, nslots);
+        if (!newslots)
+            return;
+        map->nslots = nslots;
+        obj->slots = newslots;
+    }
+}
+
+#if JS_BUG_EMPTY_INDEX_ZERO
+#define CHECK_FOR_EMPTY_INDEX(id)                                             \
+    JS_BEGIN_MACRO                                                            \
+        if (JSSTRING_LENGTH(_str) == 0)                                       \
+            id = JSVAL_ZERO;                                                  \
+    JS_END_MACRO
+#else
+#define CHECK_FOR_EMPTY_INDEX(id) /* nothing */
+#endif
+
+/* JSVAL_INT_MAX as a string */
+#define JSVAL_INT_MAX_STRING "1073741823"
+
+#define CHECK_FOR_STRING_INDEX(id)                                            \
+    JS_BEGIN_MACRO                                                            \
+        if (JSID_IS_ATOM(id)) {                                               \
+            JSAtom *atom_ = JSID_TO_ATOM(id);                                 \
+            JSString *str_ = ATOM_TO_STRING(atom_);                           \
+            const jschar *cp_ = str_->chars;                                  \
+            JSBool negative_ = (*cp_ == '-');                                 \
+            if (negative_) cp_++;                                             \
+            if (JS7_ISDEC(*cp_) &&                                            \
+                str_->length - negative_ <= sizeof(JSVAL_INT_MAX_STRING)-1) { \
+                id = CheckForStringIndex(id, cp_, negative_);                 \
+            } else {                                                          \
+                CHECK_FOR_EMPTY_INDEX(id);                                    \
+            }                                                                 \
+        }                                                                     \
+    JS_END_MACRO
+
+static jsid
+CheckForStringIndex(jsid id, const jschar *cp, JSBool negative)
+{
+    jsuint index = JS7_UNDEC(*cp++);
+    jsuint oldIndex = 0;
+    jsuint c = 0;
+
+    if (index != 0) {
+        while (JS7_ISDEC(*cp)) {
+            oldIndex = index;
+            c = JS7_UNDEC(*cp);
+            index = 10 * index + c;
+            cp++;
+        }
+    }
+    if (*cp == 0 &&
+        (oldIndex < (JSVAL_INT_MAX / 10) ||
+         (oldIndex == (JSVAL_INT_MAX / 10) &&
+          c <= (JSVAL_INT_MAX % 10)))) {
+        if (negative)
+            index = 0 - index;
+        id = INT_TO_JSID((jsint)index);
+    }
+    return id;
+}
+
+static JSBool
+HidePropertyName(JSContext *cx, jsid *idp)
+{
+    jsid id;
+    JSAtom *atom, *hidden;
+
+    id = *idp;
+    JS_ASSERT(JSID_IS_ATOM(id));
+
+    atom = JSID_TO_ATOM(id);
+    JS_ASSERT(!(atom->flags & ATOM_HIDDEN));
+    JS_ASSERT(ATOM_IS_STRING(atom));
+
+    hidden = js_AtomizeString(cx, ATOM_TO_STRING(atom), ATOM_HIDDEN);
+    if (!hidden)
+        return JS_FALSE;
+
+    /*
+     * Link hidden to unhidden atom to optimize call_enumerate -- this means
+     * the GC must mark a hidden atom's unhidden counterpart (see js_MarkAtom
+     * in jsgc.c).  It overloads the entry.value member, which for unhidden
+     * atoms may point to keyword information.
+     */
+    hidden->entry.value = atom;
+    *idp = ATOM_TO_JSID(hidden);
+    return JS_TRUE;
+}
+
+JSScopeProperty *
+js_AddHiddenProperty(JSContext *cx, JSObject *obj, jsid id,
+                     JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
+                     uintN attrs, uintN flags, intN shortid)
+{
+    if (!HidePropertyName(cx, &id))
+        return NULL;
+
+    flags |= SPROP_IS_HIDDEN;
+    return js_AddNativeProperty(cx, obj, id, getter, setter, slot, attrs,
+                                flags, shortid);
+}
+
+JSBool
+js_LookupHiddenProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
+                        JSProperty **propp)
+{
+    return HidePropertyName(cx, &id) &&
+           js_LookupProperty(cx, obj, id, objp, propp);
+}
+
+JSScopeProperty *
+js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
+                     JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
+                     uintN attrs, uintN flags, intN shortid)
+{
+    JSScope *scope;
+    JSScopeProperty *sprop;
+
+    JS_LOCK_OBJ(cx, obj);
+    scope = js_GetMutableScope(cx, obj);
+    if (!scope) {
+        sprop = NULL;
+    } else {
+        /*
+         * Handle old bug that took empty string as zero index.  Also convert
+         * string indices to integers if appropriate.
+         */
+        CHECK_FOR_STRING_INDEX(id);
+        sprop = js_AddScopeProperty(cx, scope, id, getter, setter, slot, attrs,
+                                    flags, shortid);
+    }
+    JS_UNLOCK_OBJ(cx, obj);
+    return sprop;
+}
+
+JSScopeProperty *
+js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj,
+                             JSScopeProperty *sprop, uintN attrs, uintN mask,
+                             JSPropertyOp getter, JSPropertyOp setter)
+{
+    JSScope *scope;
+
+    JS_LOCK_OBJ(cx, obj);
+    scope = js_GetMutableScope(cx, obj);
+    if (!scope) {
+        sprop = NULL;
+    } else {
+        sprop = js_ChangeScopePropertyAttrs(cx, scope, sprop, attrs, mask,
+                                            getter, setter);
+        if (sprop) {
+            PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, sprop->id,
+                                sprop);
+        }
+    }
+    JS_UNLOCK_OBJ(cx, obj);
+    return sprop;
+}
+
+JSBool
+js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
+                  JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
+                  JSProperty **propp)
+{
+    return js_DefineNativeProperty(cx, obj, id, value, getter, setter, attrs,
+                                   0, 0, propp);
+}
+
+/*
+ * Backward compatibility requires allowing addProperty hooks to mutate the
+ * nominal initial value of a slot-full property, while GC safety wants that
+ * value to be stored before the call-out through the hook.  Optimize to do
+ * both while saving cycles for classes that stub their addProperty hook.
+ */
+#define ADD_PROPERTY_HELPER(cx,clasp,obj,scope,sprop,vp,cleanup)              \
+    JS_BEGIN_MACRO                                                            \
+        if ((clasp)->addProperty != JS_PropertyStub) {                        \
+            jsval nominal_ = *(vp);                                           \
+            if (!(clasp)->addProperty(cx, obj, SPROP_USERID(sprop), vp)) {    \
+                cleanup;                                                      \
+            }                                                                 \
+            if (*(vp) != nominal_) {                                          \
+                if (SPROP_HAS_VALID_SLOT(sprop, scope))                       \
+                    LOCKED_OBJ_SET_SLOT(obj, (sprop)->slot, *(vp));           \
+            }                                                                 \
+        }                                                                     \
+    JS_END_MACRO
+
+JSBool
+js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
+                        JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
+                        uintN flags, intN shortid, JSProperty **propp)
+{
+    JSClass *clasp;
+    JSScope *scope;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+
+    /*
+     * Handle old bug that took empty string as zero index.  Also convert
+     * string indices to integers if appropriate.
+     */
+    CHECK_FOR_STRING_INDEX(id);
+
+#if JS_HAS_GETTER_SETTER
+    /*
+     * If defining a getter or setter, we must check for its counterpart and
+     * update the attributes and property ops.  A getter or setter is really
+     * only half of a property.
+     */
+    if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
+        JSObject *pobj;
+
+        /*
+         * If JS_THREADSAFE and id is found, js_LookupProperty returns with
+         * sprop non-null and pobj locked.  If pobj == obj, the property is
+         * already in obj and obj has its own (mutable) scope.  So if we are
+         * defining a getter whose setter was already defined, or vice versa,
+         * finish the job via js_ChangeScopePropertyAttributes, and refresh
+         * the property cache line for (obj, id) to map sprop.
+         */
+        if (!js_LookupProperty(cx, obj, id, &pobj, &prop))
+            return JS_FALSE;
+        sprop = (JSScopeProperty *) prop;
+        if (sprop &&
+            pobj == obj &&
+            (sprop->attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
+            sprop = js_ChangeScopePropertyAttrs(cx, OBJ_SCOPE(obj), sprop,
+                                                attrs, sprop->attrs,
+                                                (attrs & JSPROP_GETTER)
+                                                ? getter
+                                                : sprop->getter,
+                                                (attrs & JSPROP_SETTER)
+                                                ? setter
+                                                : sprop->setter);
+
+            /* NB: obj == pobj, so we can share unlock code at the bottom. */
+            if (!sprop)
+                goto bad;
+            goto out;
+        }
+
+        if (prop) {
+            /* NB: call OBJ_DROP_PROPERTY, as pobj might not be native. */
+            OBJ_DROP_PROPERTY(cx, pobj, prop);
+            prop = NULL;
+        }
+    }
+#endif /* JS_HAS_GETTER_SETTER */
+
+    /* Lock if object locking is required by this implementation. */
+    JS_LOCK_OBJ(cx, obj);
+
+    /* Use the object's class getter and setter by default. */
+    clasp = LOCKED_OBJ_GET_CLASS(obj);
+    if (!getter)
+        getter = clasp->getProperty;
+    if (!setter)
+        setter = clasp->setProperty;
+
+    /* Get obj's own scope if it has one, or create a new one for obj. */
+    scope = js_GetMutableScope(cx, obj);
+    if (!scope)
+        goto bad;
+
+    /* Add the property to scope, or replace an existing one of the same id. */
+    if (clasp->flags & JSCLASS_SHARE_ALL_PROPERTIES)
+        attrs |= JSPROP_SHARED;
+    sprop = js_AddScopeProperty(cx, scope, id, getter, setter,
+                                SPROP_INVALID_SLOT, attrs, flags, shortid);
+    if (!sprop)
+        goto bad;
+
+    /* Store value before calling addProperty, in case the latter GC's. */
+    if (SPROP_HAS_VALID_SLOT(sprop, scope))
+        LOCKED_OBJ_SET_SLOT(obj, sprop->slot, value);
+
+    /* XXXbe called with lock held */
+    ADD_PROPERTY_HELPER(cx, clasp, obj, scope, sprop, &value,
+                        js_RemoveScopeProperty(cx, scope, id);
+                        goto bad);
+
+#if JS_HAS_GETTER_SETTER
+out:
+#endif
+    PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, sprop);
+    if (propp)
+        *propp = (JSProperty *) sprop;
+    else
+        JS_UNLOCK_OBJ(cx, obj);
+    return JS_TRUE;
+
+bad:
+    JS_UNLOCK_OBJ(cx, obj);
+    return JS_FALSE;
+}
+
+/*
+ * Given pc pointing after a property accessing bytecode, return true if the
+ * access is a "object-detecting" in the sense used by web pages, e.g., when
+ * checking whether document.all is defined.
+ */
+static JSBool
+Detecting(JSContext *cx, jsbytecode *pc)
+{
+    JSScript *script;
+    jsbytecode *endpc;
+    JSOp op;
+    JSAtom *atom;
+
+    if (!cx->fp)
+        return JS_FALSE;
+    script = cx->fp->script;
+    for (endpc = script->code + script->length; pc < endpc; pc++) {
+        /* General case: a branch or equality op follows the access. */
+        op = (JSOp) *pc;
+        if (js_CodeSpec[op].format & JOF_DETECTING)
+            return JS_TRUE;
+
+        /*
+         * Special case #1: handle (document.all == null).  Don't sweat about
+         * JS1.2's revision of the equality operators here.
+         */
+        if (op == JSOP_NULL) {
+            if (++pc < endpc)
+                return *pc == JSOP_EQ || *pc == JSOP_NE;
+            break;
+        }
+
+        /*
+         * Special case #2: handle (document.all == undefined).  Don't worry
+         * about someone redefining undefined, which was added by Edition 3,
+         * so was read/write for backward compatibility.
+         */
+        if (op == JSOP_NAME) {
+            atom = GET_ATOM(cx, script, pc);
+            if (atom == cx->runtime->atomState.typeAtoms[JSTYPE_VOID] &&
+                (pc += js_CodeSpec[op].length) < endpc) {
+                op = (JSOp) *pc;
+                return op == JSOP_EQ || op == JSOP_NE ||
+                       op == JSOP_NEW_EQ || op == JSOP_NEW_NE;
+            }
+            break;
+        }
+
+        /* At this point, anything but grouping means we're not detecting. */
+        if (op != JSOP_GROUP)
+            break;
+    }
+    return JS_FALSE;
+}
+
+JS_FRIEND_API(JSBool)
+js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
+                  JSProperty **propp)
+{
+    return js_LookupPropertyWithFlags(cx, obj, id, 0, objp, propp);
+}
+
+JSBool
+js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
+                           JSObject **objp, JSProperty **propp)
+{
+    JSObject *start, *obj2, *proto;
+    JSScope *scope;
+    JSScopeProperty *sprop;
+    JSClass *clasp;
+    JSResolveOp resolve;
+    JSResolvingKey key;
+    JSResolvingEntry *entry;
+    uint32 generation;
+    JSNewResolveOp newresolve;
+    jsbytecode *pc;
+    const JSCodeSpec *cs;
+    uint32 format;
+    JSBool ok;
+
+    /*
+     * Handle old bug that took empty string as zero index.  Also convert
+     * string indices to integers if appropriate.
+     */
+    CHECK_FOR_STRING_INDEX(id);
+
+    /* Search scopes starting with obj and following the prototype link. */
+    start = obj;
+    for (;;) {
+        JS_LOCK_OBJ(cx, obj);
+        scope = OBJ_SCOPE(obj);
+        if (scope->object == obj) {
+            sprop = SCOPE_GET_PROPERTY(scope, id);
+        } else {
+            /* Shared prototype scope: try resolve before lookup. */
+            sprop = NULL;
+        }
+
+        /* Try obj's class resolve hook if id was not found in obj's scope. */
+        if (!sprop) {
+            clasp = LOCKED_OBJ_GET_CLASS(obj);
+            resolve = clasp->resolve;
+            if (resolve != JS_ResolveStub) {
+                /* Avoid recursion on (obj, id) already being resolved on cx. */
+                key.obj = obj;
+                key.id = id;
+
+                /*
+                 * Once we have successfully added an entry for (obj, key) to
+                 * cx->resolvingTable, control must go through cleanup: before
+                 * returning.  But note that JS_DHASH_ADD may find an existing
+                 * entry, in which case we bail to suppress runaway recursion.
+                 */
+                if (!js_StartResolving(cx, &key, JSRESFLAG_LOOKUP, &entry)) {
+                    JS_UNLOCK_OBJ(cx, obj);
+                    return JS_FALSE;
+                }
+                if (!entry) {
+                    /* Already resolving id in obj -- dampen recursion. */
+                    JS_UNLOCK_OBJ(cx, obj);
+                    goto out;
+                }
+                generation = cx->resolvingTable->generation;
+
+                /* Null *propp here so we can test it at cleanup: safely. */
+                *propp = NULL;
+
+                if (clasp->flags & JSCLASS_NEW_RESOLVE) {
+                    newresolve = (JSNewResolveOp)resolve;
+                    if (!(flags & JSRESOLVE_CLASSNAME) &&
+                        cx->fp &&
+                        (pc = cx->fp->pc)) {
+                        cs = &js_CodeSpec[*pc];
+                        format = cs->format;
+                        if ((format & JOF_MODEMASK) != JOF_NAME)
+                            flags |= JSRESOLVE_QUALIFIED;
+                        if ((format & JOF_ASSIGNING) ||
+                            (cx->fp->flags & JSFRAME_ASSIGNING)) {
+                            flags |= JSRESOLVE_ASSIGNING;
+                        } else {
+                            pc += cs->length;
+                            if (Detecting(cx, pc))
+                                flags |= JSRESOLVE_DETECTING;
+                        }
+                        if (format & JOF_DECLARING)
+                            flags |= JSRESOLVE_DECLARING;
+                    }
+                    obj2 = (clasp->flags & JSCLASS_NEW_RESOLVE_GETS_START)
+                           ? start
+                           : NULL;
+                    JS_UNLOCK_OBJ(cx, obj);
+
+                    /* Protect id and all atoms from a GC nested in resolve. */
+                    JS_KEEP_ATOMS(cx->runtime);
+                    ok = newresolve(cx, obj, ID_TO_VALUE(id), flags, &obj2);
+                    JS_UNKEEP_ATOMS(cx->runtime);
+                    if (!ok)
+                        goto cleanup;
+
+                    JS_LOCK_OBJ(cx, obj);
+                    if (obj2) {
+                        /* Resolved: juggle locks and lookup id again. */
+                        if (obj2 != obj) {
+                            JS_UNLOCK_OBJ(cx, obj);
+                            JS_LOCK_OBJ(cx, obj2);
+                        }
+                        scope = OBJ_SCOPE(obj2);
+                        if (!MAP_IS_NATIVE(&scope->map)) {
+                            /* Whoops, newresolve handed back a foreign obj2. */
+                            JS_ASSERT(obj2 != obj);
+                            JS_UNLOCK_OBJ(cx, obj2);
+                            ok = OBJ_LOOKUP_PROPERTY(cx, obj2, id, objp, propp);
+                            if (!ok || *propp)
+                                goto cleanup;
+                            JS_LOCK_OBJ(cx, obj2);
+                        } else {
+                            /*
+                             * Require that obj2 have its own scope now, as we
+                             * do for old-style resolve.  If it doesn't, then
+                             * id was not truly resolved, and we'll find it in
+                             * the proto chain, or miss it if obj2's proto is
+                             * not on obj's proto chain.  That last case is a
+                             * "too bad!" case.
+                             */
+                            if (scope->object == obj2)
+                                sprop = SCOPE_GET_PROPERTY(scope, id);
+                        }
+                        if (sprop) {
+                            JS_ASSERT(obj2 == scope->object);
+                            obj = obj2;
+                        } else if (obj2 != obj) {
+                            JS_UNLOCK_OBJ(cx, obj2);
+                            JS_LOCK_OBJ(cx, obj);
+                        }
+                    }
+                } else {
+                    /*
+                     * Old resolve always requires id re-lookup if obj owns
+                     * its scope after resolve returns.
+                     */
+                    JS_UNLOCK_OBJ(cx, obj);
+                    ok = resolve(cx, obj, ID_TO_VALUE(id));
+                    if (!ok)
+                        goto cleanup;
+                    JS_LOCK_OBJ(cx, obj);
+                    scope = OBJ_SCOPE(obj);
+                    JS_ASSERT(MAP_IS_NATIVE(&scope->map));
+                    if (scope->object == obj)
+                        sprop = SCOPE_GET_PROPERTY(scope, id);
+                }
+
+            cleanup:
+                js_StopResolving(cx, &key, JSRESFLAG_LOOKUP, entry, generation);
+                if (!ok || *propp)
+                    return ok;
+            }
+        }
+
+        if (sprop) {
+            JS_ASSERT(OBJ_SCOPE(obj) == scope);
+            *objp = scope->object;      /* XXXbe hide in jsscope.[ch] */
+
+            *propp = (JSProperty *) sprop;
+            return JS_TRUE;
+        }
+
+        proto = LOCKED_OBJ_GET_PROTO(obj);
+        JS_UNLOCK_OBJ(cx, obj);
+        if (!proto)
+            break;
+        if (!OBJ_IS_NATIVE(proto))
+            return OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp);
+        obj = proto;
+    }
+
+out:
+    *objp = NULL;
+    *propp = NULL;
+    return JS_TRUE;
+}
+
+JS_FRIEND_API(JSBool)
+js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
+                JSProperty **propp)
+{
+    JSRuntime *rt;
+    JSObject *obj, *pobj, *lastobj;
+    JSScopeProperty *sprop;
+    JSProperty *prop;
+
+    rt = cx->runtime;
+    obj = cx->fp->scopeChain;
+    do {
+        /* Try the property cache and return immediately on cache hit. */
+        if (OBJ_IS_NATIVE(obj)) {
+            JS_LOCK_OBJ(cx, obj);
+            PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop);
+            if (sprop) {
+                JS_ASSERT(OBJ_IS_NATIVE(obj));
+                *objp = obj;
+                *pobjp = obj;
+                *propp = (JSProperty *) sprop;
+                return JS_TRUE;
+            }
+            JS_UNLOCK_OBJ(cx, obj);
+        }
+
+        /* If cache miss, take the slow path. */
+        if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
+            return JS_FALSE;
+        if (prop) {
+            if (OBJ_IS_NATIVE(pobj)) {
+                sprop = (JSScopeProperty *) prop;
+                PROPERTY_CACHE_FILL(&rt->propertyCache, pobj, id, sprop);
+            }
+            *objp = obj;
+            *pobjp = pobj;
+            *propp = prop;
+            return JS_TRUE;
+        }
+        lastobj = obj;
+    } while ((obj = OBJ_GET_PARENT(cx, obj)) != NULL);
+
+    *objp = lastobj;
+    *pobjp = NULL;
+    *propp = NULL;
+    return JS_TRUE;
+}
+
+JSObject *
+js_FindIdentifierBase(JSContext *cx, jsid id)
+{
+    JSObject *obj, *pobj;
+    JSProperty *prop;
+
+    /*
+     * Look for id's property along the "with" statement chain and the
+     * statically-linked scope chain.
+     */
+    if (!js_FindProperty(cx, id, &obj, &pobj, &prop))
+        return NULL;
+    if (prop) {
+        OBJ_DROP_PROPERTY(cx, pobj, prop);
+        return obj;
+    }
+
+    /*
+     * Use the top-level scope from the scope chain, which won't end in the
+     * same scope as cx->globalObject for cross-context function calls.
+     */
+    JS_ASSERT(obj);
+
+    /*
+     * Property not found.  Give a strict warning if binding an undeclared
+     * top-level variable.
+     */
+    if (JS_HAS_STRICT_OPTION(cx)) {
+        JSString *str = JSVAL_TO_STRING(ID_TO_VALUE(id));
+        if (!JS_ReportErrorFlagsAndNumber(cx,
+                                          JSREPORT_WARNING | JSREPORT_STRICT,
+                                          js_GetErrorMessage, NULL,
+                                          JSMSG_UNDECLARED_VAR,
+                                          JS_GetStringBytes(str))) {
+            return NULL;
+        }
+    }
+    return obj;
+}
+
+JSBool
+js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+{
+    JSObject *obj2;
+    JSProperty *prop;
+    JSScope *scope;
+    JSScopeProperty *sprop;
+    uint32 slot;
+
+    /*
+     * Handle old bug that took empty string as zero index.  Also convert
+     * string indices to integers if appropriate.
+     */
+    CHECK_FOR_STRING_INDEX(id);
+
+    if (!js_LookupProperty(cx, obj, id, &obj2, &prop))
+        return JS_FALSE;
+    if (!prop) {
+        jsval default_val;
+
+#if JS_BUG_NULL_INDEX_PROPS
+        /* Indexed properties defaulted to null in old versions. */
+        default_val = (JSID_IS_INT(id) && JSID_TO_INT(id) >= 0)
+                      ? JSVAL_NULL
+                      : JSVAL_VOID;
+#else
+        default_val = JSVAL_VOID;
+#endif
+        *vp = default_val;
+
+        if (!OBJ_GET_CLASS(cx, obj)->getProperty(cx, obj, ID_TO_VALUE(id), vp))
+            return JS_FALSE;
+
+        /*
+         * Give a strict warning if foo.bar is evaluated by a script for an
+         * object foo with no property named 'bar'.
+         */
+        if (JS_HAS_STRICT_OPTION(cx) &&
+            *vp == default_val &&
+            cx->fp && cx->fp->pc &&
+            (*cx->fp->pc == JSOP_GETPROP || *cx->fp->pc == JSOP_GETELEM))
+        {
+            jsbytecode *pc;
+            JSString *str;
+
+            /* Kludge to allow (typeof foo == "undefined") tests. */
+            JS_ASSERT(cx->fp->script);
+            pc = cx->fp->pc;
+            pc += js_CodeSpec[*pc].length;
+            if (Detecting(cx, pc))
+                return JS_TRUE;
+
+            /* Ok, bad undefined property reference: whine about it. */
+            str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,
+                                             ID_TO_VALUE(id), NULL);
+            if (!str ||
+                !JS_ReportErrorFlagsAndNumber(cx,
+                                              JSREPORT_WARNING|JSREPORT_STRICT,
+                                              js_GetErrorMessage, NULL,
+                                              JSMSG_UNDEFINED_PROP,
+                                              JS_GetStringBytes(str))) {
+                return JS_FALSE;
+            }
+        }
+        return JS_TRUE;
+    }
+
+    if (!OBJ_IS_NATIVE(obj2)) {
+        OBJ_DROP_PROPERTY(cx, obj2, prop);
+        return OBJ_GET_PROPERTY(cx, obj2, id, vp);
+    }
+
+    /* Unlock obj2 before calling getter, relock after to avoid deadlock. */
+    scope = OBJ_SCOPE(obj2);
+    sprop = (JSScopeProperty *) prop;
+    slot = sprop->slot;
+    if (slot != SPROP_INVALID_SLOT) {
+        JS_ASSERT(slot < obj2->map->freeslot);
+        *vp = LOCKED_OBJ_GET_SLOT(obj2, slot);
+
+        /* If sprop has a stub getter, we're done. */
+        if (!sprop->getter)
+            goto out;
+    } else {
+        *vp = JSVAL_VOID;
+    }
+
+    JS_UNLOCK_SCOPE(cx, scope);
+    if (!SPROP_GET(cx, sprop, obj, obj2, vp))
+        return JS_FALSE;
+    JS_LOCK_SCOPE(cx, scope);
+
+    if (SPROP_HAS_VALID_SLOT(sprop, scope)) {
+        LOCKED_OBJ_SET_SLOT(obj2, slot, *vp);
+        PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj2, id, sprop);
+    }
+
+out:
+    JS_UNLOCK_SCOPE(cx, scope);
+    return JS_TRUE;
+}
+
+JSBool
+js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+{
+    JSObject *pobj;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+    JSScope *scope;
+    uintN attrs, flags;
+    intN shortid;
+    JSClass *clasp;
+    JSPropertyOp getter, setter;
+    jsval pval;
+    uint32 slot;
+
+    /*
+     * Handle old bug that took empty string as zero index.  Also convert
+     * string indices to integers if appropriate.
+     */
+    CHECK_FOR_STRING_INDEX(id);
+
+    if (!js_LookupProperty(cx, obj, id, &pobj, &prop))
+        return JS_FALSE;
+
+    if (prop && !OBJ_IS_NATIVE(pobj)) {
+        OBJ_DROP_PROPERTY(cx, pobj, prop);
+        prop = NULL;
+    }
+    sprop = (JSScopeProperty *) prop;
+
+    /*
+     * Now either sprop is null, meaning id was not found in obj or one of its
+     * prototypes; or sprop is non-null, meaning id was found in pobj's scope.
+     * If JS_THREADSAFE and sprop is non-null, then scope is locked, and sprop
+     * is held: we must OBJ_DROP_PROPERTY or JS_UNLOCK_SCOPE before we return
+     * (the two are equivalent for native objects, but we use JS_UNLOCK_SCOPE
+     * because it is cheaper).
+     */
+    attrs = JSPROP_ENUMERATE;
+    flags = 0;
+    shortid = 0;
+    clasp = OBJ_GET_CLASS(cx, obj);
+    getter = clasp->getProperty;
+    setter = clasp->setProperty;
+
+    if (sprop) {
+        /*
+         * Set scope for use below.  It was locked by js_LookupProperty, and
+         * we know pobj owns it (i.e., scope->object == pobj).  Therefore we
+         * optimize JS_UNLOCK_OBJ(cx, pobj) into JS_UNLOCK_SCOPE(cx, scope).
+         */
+        scope = OBJ_SCOPE(pobj);
+
+        attrs = sprop->attrs;
+        if ((attrs & JSPROP_READONLY) ||
+            (SCOPE_IS_SEALED(scope) && pobj == obj)) {
+            JS_UNLOCK_SCOPE(cx, scope);
+
+            /*
+             * Here, we'll either return true or goto read_only_error, which
+             * reports a strict warning or throws an error.  So we redefine
+             * the |flags| local variable to be JSREPORT_* flags to pass to
+             * JS_ReportErrorFlagsAndNumberUC at label read_only_error.  We
+             * must likewise re-task flags further below for the other 'goto
+             * read_only_error;' case.
+             */
+            flags = JSREPORT_ERROR;
+            if ((attrs & JSPROP_READONLY) && JS_VERSION_IS_ECMA(cx)) {
+                if (!JS_HAS_STRICT_OPTION(cx)) {
+                    /* Just return true per ECMA if not in strict mode. */
+                    return JS_TRUE;
+                }
+
+                /* Strict mode: report a read-only strict warning. */
+                flags = JSREPORT_STRICT | JSREPORT_WARNING;
+            }
+            goto read_only_error;
+        }
+
+        if (pobj != obj) {
+            /*
+             * We found id in a prototype object: prepare to share or shadow.
+             * NB: Thanks to the immutable, garbage-collected property tree
+             * maintained by jsscope.c in cx->runtime, we needn't worry about
+             * sprop going away behind our back after we've unlocked scope.
+             */
+            JS_UNLOCK_SCOPE(cx, scope);
+
+            /* Don't clone a shared prototype property. */
+            if (attrs & JSPROP_SHARED)
+                return SPROP_SET(cx, sprop, obj, pobj, vp);
+
+            /* Restore attrs to the ECMA default for new properties. */
+            attrs = JSPROP_ENUMERATE;
+
+            /*
+             * Preserve the shortid, getter, and setter when shadowing any
+             * property that has a shortid.  An old API convention requires
+             * that the property's getter and setter functions receive the
+             * shortid, not id, when they are called on the shadow we are
+             * about to create in obj's scope.
+             */
+            if (sprop->flags & SPROP_HAS_SHORTID) {
+                flags = SPROP_HAS_SHORTID;
+                shortid = sprop->shortid;
+                getter = sprop->getter;
+                setter = sprop->setter;
+            }
+
+            /*
+             * Forget we found the proto-property now that we've copied any
+             * needed member values.
+             */
+            sprop = NULL;
+        }
+#ifdef __GNUC__ /* suppress bogus gcc warnings */
+    } else {
+        scope = NULL;
+#endif
+    }
+
+    if (!sprop) {
+        if (SCOPE_IS_SEALED(OBJ_SCOPE(obj)) && OBJ_SCOPE(obj)->object == obj) {
+            flags = JSREPORT_ERROR;
+            goto read_only_error;
+        }
+
+        /* Find or make a property descriptor with the right heritage. */
+        JS_LOCK_OBJ(cx, obj);
+        scope = js_GetMutableScope(cx, obj);
+        if (!scope) {
+            JS_UNLOCK_OBJ(cx, obj);
+            return JS_FALSE;
+        }
+        if (clasp->flags & JSCLASS_SHARE_ALL_PROPERTIES)
+            attrs |= JSPROP_SHARED;
+        sprop = js_AddScopeProperty(cx, scope, id, getter, setter,
+                                    SPROP_INVALID_SLOT, attrs, flags, shortid);
+        if (!sprop) {
+            JS_UNLOCK_SCOPE(cx, scope);
+            return JS_FALSE;
+        }
+
+        /*
+         * Initialize the new property value (passed to setter) to undefined.
+         * Note that we store before calling addProperty, to match the order
+         * in js_DefineNativeProperty.
+         */
+        if (SPROP_HAS_VALID_SLOT(sprop, scope))
+            LOCKED_OBJ_SET_SLOT(obj, sprop->slot, JSVAL_VOID);
+
+        /* XXXbe called with obj locked */
+        ADD_PROPERTY_HELPER(cx, clasp, obj, scope, sprop, vp,
+                            js_RemoveScopeProperty(cx, scope, id);
+                            JS_UNLOCK_SCOPE(cx, scope);
+                            return JS_FALSE);
+
+        PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, sprop);
+    }
+
+    /* Get the current property value from its slot. */
+    slot = sprop->slot;
+    if (slot != SPROP_INVALID_SLOT) {
+        JS_ASSERT(slot < obj->map->freeslot);
+        pval = LOCKED_OBJ_GET_SLOT(obj, slot);
+
+        /* If sprop has a stub setter, keep scope locked and just store *vp. */
+        if (!sprop->setter)
+            goto set_slot;
+    }
+
+    /* Avoid deadlock by unlocking obj's scope while calling sprop's setter. */
+    JS_UNLOCK_SCOPE(cx, scope);
+
+    /* Let the setter modify vp before copying from it to obj->slots[slot]. */
+    if (!SPROP_SET(cx, sprop, obj, obj, vp))
+        return JS_FALSE;
+
+    /* Relock obj's scope until we are done with sprop. */
+    JS_LOCK_SCOPE(cx, scope);
+
+    /*
+     * Check whether sprop is still around (was not deleted), and whether it
+     * has a slot (it may never have had one, or we may have lost a race with
+     * someone who cleared scope).
+     */
+    if (SPROP_HAS_VALID_SLOT(sprop, scope)) {
+  set_slot:
+        GC_POKE(cx, pval);
+        LOCKED_OBJ_SET_SLOT(obj, slot, *vp);
+    }
+    JS_UNLOCK_SCOPE(cx, scope);
+    return JS_TRUE;
+
+  read_only_error: {
+    JSString *str = js_DecompileValueGenerator(cx,
+                                               JSDVG_IGNORE_STACK,
+                                               ID_TO_VALUE(id),
+                                               NULL);
+    if (!str)
+        return JS_FALSE;
+    return JS_ReportErrorFlagsAndNumberUC(cx, flags, js_GetErrorMessage,
+                                          NULL, JSMSG_READ_ONLY,
+                                          JS_GetStringChars(str));
+  }
+}
+
+JSBool
+js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
+                 uintN *attrsp)
+{
+    JSBool noprop, ok;
+    JSScopeProperty *sprop;
+
+    noprop = !prop;
+    if (noprop) {
+        if (!js_LookupProperty(cx, obj, id, &obj, &prop))
+            return JS_FALSE;
+        if (!prop) {
+            *attrsp = 0;
+            return JS_TRUE;
+        }
+        if (!OBJ_IS_NATIVE(obj)) {
+            ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, attrsp);
+            OBJ_DROP_PROPERTY(cx, obj, prop);
+            return ok;
+        }
+    }
+    sprop = (JSScopeProperty *)prop;
+    *attrsp = sprop->attrs;
+    if (noprop)
+        OBJ_DROP_PROPERTY(cx, obj, prop);
+    return JS_TRUE;
+}
+
+JSBool
+js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
+                 uintN *attrsp)
+{
+    JSBool noprop, ok;
+    JSScopeProperty *sprop;
+
+    noprop = !prop;
+    if (noprop) {
+        if (!js_LookupProperty(cx, obj, id, &obj, &prop))
+            return JS_FALSE;
+        if (!prop)
+            return JS_TRUE;
+        if (!OBJ_IS_NATIVE(obj)) {
+            ok = OBJ_SET_ATTRIBUTES(cx, obj, id, prop, attrsp);
+            OBJ_DROP_PROPERTY(cx, obj, prop);
+            return ok;
+        }
+    }
+    sprop = (JSScopeProperty *)prop;
+    sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop,
+                                         *attrsp &
+                                         ~(JSPROP_GETTER | JSPROP_SETTER), 0,
+                                         sprop->getter, sprop->setter);
+    if (noprop)
+        OBJ_DROP_PROPERTY(cx, obj, prop);
+    return (sprop != NULL);
+}
+
+JSBool
+js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
+{
+#if JS_HAS_PROP_DELETE
+
+    JSObject *proto;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+    JSString *str;
+    JSScope *scope;
+    JSBool ok;
+
+    *rval = JS_VERSION_IS_ECMA(cx) ? JSVAL_TRUE : JSVAL_VOID;
+
+    /*
+     * Handle old bug that took empty string as zero index.  Also convert
+     * string indices to integers if appropriate.
+     */
+    CHECK_FOR_STRING_INDEX(id);
+
+    if (!js_LookupProperty(cx, obj, id, &proto, &prop))
+        return JS_FALSE;
+    if (!prop || proto != obj) {
+        /*
+         * If the property was found in a native prototype, check whether it's
+         * shared and permanent.  Such a property stands for direct properties
+         * in all delegating objects, matching ECMA semantics without bloating
+         * each delegating object.
+         */
+        if (prop) {
+            if (OBJ_IS_NATIVE(proto)) {
+                sprop = (JSScopeProperty *)prop;
+                if (SPROP_IS_SHARED_PERMANENT(sprop))
+                    *rval = JSVAL_FALSE;
+            }
+            OBJ_DROP_PROPERTY(cx, proto, prop);
+            if (*rval == JSVAL_FALSE)
+                return JS_TRUE;
+        }
+
+        /*
+         * If no property, or the property comes unshared or impermanent from
+         * a prototype, call the class's delProperty hook, passing rval as the
+         * result parameter.
+         */
+        return OBJ_GET_CLASS(cx, obj)->delProperty(cx, obj, ID_TO_VALUE(id),
+                                                   rval);
+    }
+
+    sprop = (JSScopeProperty *)prop;
+    if (sprop->attrs & JSPROP_PERMANENT) {
+        OBJ_DROP_PROPERTY(cx, obj, prop);
+        if (JS_VERSION_IS_ECMA(cx)) {
+            *rval = JSVAL_FALSE;
+            return JS_TRUE;
+        }
+        str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK,
+                                         ID_TO_VALUE(id), NULL);
+        if (str) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_PERMANENT, JS_GetStringBytes(str));
+        }
+        return JS_FALSE;
+    }
+
+    /* XXXbe called with obj locked */
+    if (!LOCKED_OBJ_GET_CLASS(obj)->delProperty(cx, obj, SPROP_USERID(sprop),
+                                                rval)) {
+        OBJ_DROP_PROPERTY(cx, obj, prop);
+        return JS_FALSE;
+    }
+
+    scope = OBJ_SCOPE(obj);
+    if (SPROP_HAS_VALID_SLOT(sprop, scope))
+        GC_POKE(cx, LOCKED_OBJ_GET_SLOT(obj, sprop->slot));
+
+    PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, NULL);
+    ok = js_RemoveScopeProperty(cx, scope, id);
+    OBJ_DROP_PROPERTY(cx, obj, prop);
+    return ok;
+
+#else  /* !JS_HAS_PROP_DELETE */
+
+    jsval null = JSVAL_NULL;
+
+    *rval = JSVAL_VOID;
+    return js_SetProperty(cx, obj, id, &null);
+
+#endif /* !JS_HAS_PROP_DELETE */
+}
+
+JSBool
+js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
+{
+    jsval v;
+    JSString *str;
+
+    v = OBJECT_TO_JSVAL(obj);
+    switch (hint) {
+      case JSTYPE_STRING:
+        /*
+         * Propagate the exception if js_TryMethod finds an appropriate
+         * method, and calling that method returned failure.
+         */
+        if (!js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0, NULL,
+                          &v)) {
+            return JS_FALSE;
+        }
+
+        if (!JSVAL_IS_PRIMITIVE(v)) {
+            if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, hint, &v))
+                return JS_FALSE;
+
+            /*
+             * JS1.2 never failed (except for malloc failure) to convert an
+             * object to a string.  ECMA requires an error if both toString
+             * and valueOf fail to produce a primitive value.
+             */
+            if (!JSVAL_IS_PRIMITIVE(v) && JS_VERSION_IS_1_2(cx)) {
+                char *bytes = JS_smprintf("[object %s]",
+                                          OBJ_GET_CLASS(cx, obj)->name);
+                if (!bytes)
+                    return JS_FALSE;
+                str = JS_NewString(cx, bytes, strlen(bytes));
+                if (!str) {
+                    free(bytes);
+                    return JS_FALSE;
+                }
+                v = STRING_TO_JSVAL(str);
+                goto out;
+            }
+        }
+        break;
+
+      default:
+        if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, hint, &v))
+            return JS_FALSE;
+        if (!JSVAL_IS_PRIMITIVE(v)) {
+            JSType type = JS_TypeOfValue(cx, v);
+            if (type == hint ||
+                (type == JSTYPE_FUNCTION && hint == JSTYPE_OBJECT)) {
+                goto out;
+            }
+            /* Don't convert to string (source object literal) for JS1.2. */
+            if (JS_VERSION_IS_1_2(cx) && hint == JSTYPE_BOOLEAN)
+                goto out;
+            if (!js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0,
+                              NULL, &v))
+                return JS_FALSE;
+        }
+        break;
+    }
+    if (!JSVAL_IS_PRIMITIVE(v)) {
+        /* Avoid recursive death through js_DecompileValueGenerator. */
+        if (hint == JSTYPE_STRING) {
+            str = JS_InternString(cx, OBJ_GET_CLASS(cx, obj)->name);
+            if (!str)
+                return JS_FALSE;
+        } else {
+            str = NULL;
+        }
+        *vp = OBJECT_TO_JSVAL(obj);
+        str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, str);
+        if (str) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_CANT_CONVERT_TO,
+                                 JS_GetStringBytes(str),
+                                 (hint == JSTYPE_VOID)
+                                 ? "primitive type"
+                                 : js_type_str[hint]);
+        }
+        return JS_FALSE;
+    }
+out:
+    *vp = v;
+    return JS_TRUE;
+}
+
+JSIdArray *
+js_NewIdArray(JSContext *cx, jsint length)
+{
+    JSIdArray *ida;
+
+    ida = (JSIdArray *)
+          JS_malloc(cx, sizeof(JSIdArray) + (length-1) * sizeof(jsval));
+    if (ida)
+        ida->length = length;
+    return ida;
+}
+
+JSIdArray *
+js_SetIdArrayLength(JSContext *cx, JSIdArray *ida, jsint length)
+{
+    JSIdArray *rida;
+
+    rida = (JSIdArray *)
+           JS_realloc(cx, ida, sizeof(JSIdArray) + (length-1) * sizeof(jsval));
+    if (!rida)
+        JS_DestroyIdArray(cx, ida);
+    else
+        rida->length = length;
+    return rida;
+}
+
+/* Private type used to iterate over all properties of a native JS object */
+typedef struct JSNativeIteratorState {
+    jsint next_index;   /* index into jsid array */
+    JSIdArray *ida;     /* all property ids in enumeration */
+} JSNativeIteratorState;
+
+/*
+ * This function is used to enumerate the properties of native JSObjects
+ * and those host objects that do not define a JSNewEnumerateOp-style iterator
+ * function.
+ */
+JSBool
+js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
+             jsval *statep, jsid *idp)
+{
+    JSObject *proto;
+    JSClass *clasp;
+    JSEnumerateOp enumerate;
+    JSScopeProperty *sprop, *lastProp;
+    jsint i, length;
+    JSScope *scope;
+    JSIdArray *ida;
+    JSNativeIteratorState *state;
+
+    clasp = OBJ_GET_CLASS(cx, obj);
+    enumerate = clasp->enumerate;
+    if (clasp->flags & JSCLASS_NEW_ENUMERATE)
+        return ((JSNewEnumerateOp) enumerate)(cx, obj, enum_op, statep, idp);
+
+    switch (enum_op) {
+      case JSENUMERATE_INIT:
+        if (!enumerate(cx, obj))
+            return JS_FALSE;
+        length = 0;
+
+        /*
+         * The set of all property ids is pre-computed when the iterator
+         * is initialized so as to avoid problems with properties being
+         * deleted during the iteration.
+         */
+        JS_LOCK_OBJ(cx, obj);
+        scope = OBJ_SCOPE(obj);
+
+        /*
+         * If this object shares a scope with its prototype, don't enumerate
+         * its properties.  Otherwise they will be enumerated a second time
+         * when the prototype object is enumerated.
+         */
+        proto = OBJ_GET_PROTO(cx, obj);
+        if (proto && scope == OBJ_SCOPE(proto)) {
+            ida = js_NewIdArray(cx, 0);
+            if (!ida) {
+                JS_UNLOCK_OBJ(cx, obj);
+                return JS_FALSE;
+            }
+        } else {
+            /* Object has a private scope; Enumerate all props in scope. */
+            for (sprop = lastProp = SCOPE_LAST_PROP(scope); sprop;
+                 sprop = sprop->parent) {
+                if ((
+#ifdef DUMP_CALL_TABLE
+                     (cx->options & JSOPTION_LOGCALL_TOSOURCE) ||
+#endif
+                     (sprop->attrs & JSPROP_ENUMERATE)) &&
+                    !(sprop->flags & SPROP_IS_ALIAS) &&
+                    (!SCOPE_HAD_MIDDLE_DELETE(scope) ||
+                     SCOPE_HAS_PROPERTY(scope, sprop))) {
+                    length++;
+                }
+            }
+            ida = js_NewIdArray(cx, length);
+            if (!ida) {
+                JS_UNLOCK_OBJ(cx, obj);
+                return JS_FALSE;
+            }
+            i = length;
+            for (sprop = lastProp; sprop; sprop = sprop->parent) {
+                if ((
+#ifdef DUMP_CALL_TABLE
+                     (cx->options & JSOPTION_LOGCALL_TOSOURCE) ||
+#endif
+                     (sprop->attrs & JSPROP_ENUMERATE)) &&
+                    !(sprop->flags & SPROP_IS_ALIAS) &&
+                    (!SCOPE_HAD_MIDDLE_DELETE(scope) ||
+                     SCOPE_HAS_PROPERTY(scope, sprop))) {
+                    JS_ASSERT(i > 0);
+                    ida->vector[--i] = sprop->id;
+                }
+            }
+        }
+        JS_UNLOCK_OBJ(cx, obj);
+
+        state = (JSNativeIteratorState *)
+            JS_malloc(cx, sizeof(JSNativeIteratorState));
+        if (!state) {
+            JS_DestroyIdArray(cx, ida);
+            return JS_FALSE;
+        }
+        state->ida = ida;
+        state->next_index = 0;
+        *statep = PRIVATE_TO_JSVAL(state);
+        if (idp)
+            *idp = INT_TO_JSVAL(length);
+        break;
+
+      case JSENUMERATE_NEXT:
+        state = (JSNativeIteratorState *) JSVAL_TO_PRIVATE(*statep);
+        ida = state->ida;
+        length = ida->length;
+        if (state->next_index != length) {
+            *idp = ida->vector[state->next_index++];
+            break;
+        }
+        /* FALL THROUGH */
+
+      case JSENUMERATE_DESTROY:
+        state = (JSNativeIteratorState *) JSVAL_TO_PRIVATE(*statep);
+        JS_DestroyIdArray(cx, state->ida);
+        JS_free(cx, state);
+        *statep = JSVAL_NULL;
+        break;
+    }
+    return JS_TRUE;
+}
+
+JSBool
+js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
+               jsval *vp, uintN *attrsp)
+{
+    JSObject *pobj;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+    JSClass *clasp;
+    JSCheckAccessOp check;
+    JSBool ok;
+
+    if (!js_LookupProperty(cx, obj, id, &pobj, &prop))
+        return JS_FALSE;
+    if (!prop) {
+        *vp = JSVAL_VOID;
+        *attrsp = 0;
+        clasp = OBJ_GET_CLASS(cx, obj);
+        return !clasp->checkAccess ||
+               clasp->checkAccess(cx, obj, ID_TO_VALUE(id), mode, vp);
+    }
+    if (!OBJ_IS_NATIVE(pobj)) {
+        OBJ_DROP_PROPERTY(cx, pobj, prop);
+        return OBJ_CHECK_ACCESS(cx, pobj, id, mode, vp, attrsp);
+    }
+    sprop = (JSScopeProperty *)prop;
+    if (!(mode & JSACC_WRITE)) {
+        *vp = (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)))
+            ? LOCKED_OBJ_GET_SLOT(pobj, sprop->slot)
+            : ((mode & JSACC_WATCH) == JSACC_PROTO)
+            ? LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PROTO)
+            : (mode == JSACC_PARENT)
+            ? LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PARENT)
+            : JSVAL_VOID;
+    }
+    *attrsp = sprop->attrs;
+
+    /*
+     * If obj's class has a stub (null) checkAccess hook, use the per-runtime
+     * checkObjectAccess callback, if configured.
+     *
+     * We don't want to require all classes to supply a checkAccess hook; we
+     * need that hook only for certain classes used when precompiling scripts
+     * and functions ("brutal sharing").  But for general safety of built-in
+     * magic properties such as __proto__ and __parent__, we route all access
+     * checks, even for classes that stub out checkAccess, through the global
+     * checkObjectAccess hook.  This covers precompilation-based sharing and
+     * (possibly unintended) runtime sharing across trust boundaries.
+     */
+    clasp = LOCKED_OBJ_GET_CLASS(pobj);
+    check = clasp->checkAccess;
+    if (!check)
+        check = cx->runtime->checkObjectAccess;
+    if (check) {
+        JS_UNLOCK_OBJ(cx, pobj);
+        ok = check(cx, pobj, ID_TO_VALUE(id), mode, vp);
+        JS_LOCK_OBJ(cx, pobj);
+    } else {
+        ok = JS_TRUE;
+    }
+    OBJ_DROP_PROPERTY(cx, pobj, prop);
+    return ok;
+}
+
+#ifdef JS_THREADSAFE
+void
+js_DropProperty(JSContext *cx, JSObject *obj, JSProperty *prop)
+{
+    JS_UNLOCK_OBJ(cx, obj);
+}
+#endif
+
+static void
+ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags)
+{
+    /*
+     * The decompiler may need to access the args of the function in
+     * progress rather than the one we had hoped to call.
+     * So we switch the cx->fp to the frame below us. We stick the
+     * current frame in the dormantFrameChain to protect it from gc.
+     */
+
+    JSStackFrame *fp = cx->fp;
+    if (fp->down) {
+        JS_ASSERT(!fp->dormantNext);
+        fp->dormantNext = cx->dormantFrameChain;
+        cx->dormantFrameChain = fp;
+        cx->fp = fp->down;
+    }
+
+    js_ReportIsNotFunction(cx, vp, flags);
+
+    if (fp->down) {
+        JS_ASSERT(cx->dormantFrameChain == fp);
+        cx->dormantFrameChain = fp->dormantNext;
+        fp->dormantNext = NULL;
+        cx->fp = fp;
+    }
+}
+
+#ifdef NARCISSUS
+static JSBool
+GetCurrentExecutionContext(JSContext *cx, JSObject *obj, jsval *rval)
+{
+    JSObject *tmp;
+    jsval xcval;
+
+    while ((tmp = OBJ_GET_PARENT(cx, obj)) != NULL)
+        obj = tmp;
+    if (!OBJ_GET_PROPERTY(cx, obj,
+                          ATOM_TO_JSID(cx->runtime->atomState
+                                       .ExecutionContextAtom),
+                          &xcval)) {
+        return JS_FALSE;
+    }
+    if (JSVAL_IS_PRIMITIVE(xcval)) {
+        JS_ReportError(cx, "invalid ExecutionContext in global object");
+        return JS_FALSE;
+    }
+    if (!OBJ_GET_PROPERTY(cx, JSVAL_TO_OBJECT(xcval),
+                          ATOM_TO_JSID(cx->runtime->atomState.currentAtom),
+                          rval)) {
+        return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+#endif
+
+JSBool
+js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSClass *clasp;
+
+    clasp = OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[-2]));
+    if (!clasp->call) {
+#ifdef NARCISSUS
+        JSObject *callee, *args;
+        jsval fval, nargv[3];
+        JSBool ok;
+
+        callee = JSVAL_TO_OBJECT(argv[-2]);
+        if (!OBJ_GET_PROPERTY(cx, callee,
+                              ATOM_TO_JSID(cx->runtime->atomState.callAtom),
+                              &fval)) {
+            return JS_FALSE;
+        }
+        if (JSVAL_IS_FUNCTION(cx, fval)) {
+            if (!GetCurrentExecutionContext(cx, obj, &nargv[2]))
+                return JS_FALSE;
+            args = js_GetArgsObject(cx, cx->fp);
+            if (!args)
+                return JS_FALSE;
+            nargv[0] = OBJECT_TO_JSVAL(obj);
+            nargv[1] = OBJECT_TO_JSVAL(args);
+            return js_InternalCall(cx, callee, fval, 3, nargv, rval);
+        }
+        if (JSVAL_IS_OBJECT(fval) && JSVAL_TO_OBJECT(fval) != callee) {
+            argv[-2] = fval;
+            ok = js_Call(cx, obj, argc, argv, rval);
+            argv[-2] = OBJECT_TO_JSVAL(callee);
+            return ok;
+        }
+#endif
+        ReportIsNotFunction(cx, &argv[-2], 0);
+        return JS_FALSE;
+    }
+    return clasp->call(cx, obj, argc, argv, rval);
+}
+
+JSBool
+js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+             jsval *rval)
+{
+    JSClass *clasp;
+
+    clasp = OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[-2]));
+    if (!clasp->construct) {
+#ifdef NARCISSUS
+        JSObject *callee, *args;
+        jsval cval, nargv[2];
+        JSBool ok;
+
+        callee = JSVAL_TO_OBJECT(argv[-2]);
+        if (!OBJ_GET_PROPERTY(cx, callee,
+                              ATOM_TO_JSID(cx->runtime->atomState
+                                           .constructAtom),
+                              &cval)) {
+            return JS_FALSE;
+        }
+        if (JSVAL_IS_FUNCTION(cx, cval)) {
+            if (!GetCurrentExecutionContext(cx, obj, &nargv[1]))
+                return JS_FALSE;
+            args = js_GetArgsObject(cx, cx->fp);
+            if (!args)
+                return JS_FALSE;
+            nargv[0] = OBJECT_TO_JSVAL(args);
+            return js_InternalCall(cx, callee, cval, 2, nargv, rval);
+        }
+        if (JSVAL_IS_OBJECT(cval) && JSVAL_TO_OBJECT(cval) != callee) {
+            argv[-2] = cval;
+            ok = js_Call(cx, obj, argc, argv, rval);
+            argv[-2] = OBJECT_TO_JSVAL(callee);
+            return ok;
+        }
+#endif
+        ReportIsNotFunction(cx, &argv[-2], JSV2F_CONSTRUCT);
+        return JS_FALSE;
+    }
+    return clasp->construct(cx, obj, argc, argv, rval);
+}
+
+JSBool
+js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
+{
+    JSClass *clasp;
+    JSString *str;
+
+    clasp = OBJ_GET_CLASS(cx, obj);
+    if (clasp->hasInstance)
+        return clasp->hasInstance(cx, obj, v, bp);
+#ifdef NARCISSUS
+    {
+        jsval fval, rval;
+
+        if (!OBJ_GET_PROPERTY(cx, obj,
+                              ATOM_TO_JSID(cx->runtime->atomState
+                                           .hasInstanceAtom),
+                              &fval)) {
+            return JS_FALSE;
+        }
+        if (JSVAL_IS_FUNCTION(cx, fval)) {
+            return js_InternalCall(cx, obj, fval, 1, &v, &rval) &&
+                   js_ValueToBoolean(cx, rval, bp);
+        }
+    }
+#endif
+    str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK,
+                                     OBJECT_TO_JSVAL(obj), NULL);
+    if (str) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_INSTANCEOF_RHS,
+                             JS_GetStringBytes(str));
+    }
+    return JS_FALSE;
+}
+
+JSBool
+js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
+{
+    JSObject *obj2;
+
+    *bp = JS_FALSE;
+    if (JSVAL_IS_PRIMITIVE(v))
+        return JS_TRUE;
+    obj2 = JSVAL_TO_OBJECT(v);
+    while ((obj2 = OBJ_GET_PROTO(cx, obj2)) != NULL) {
+        if (obj2 == obj) {
+            *bp = JS_TRUE;
+            break;
+        }
+    }
+    return JS_TRUE;
+}
+
+JSBool
+js_GetClassPrototype(JSContext *cx, const char *name, JSObject **protop)
+{
+    return GetClassPrototype(cx, NULL, name, protop);
+}
+
+static JSBool
+GetClassPrototype(JSContext *cx, JSObject *scope, const char *name,
+                  JSObject **protop)
+{
+    jsval v;
+    JSObject *ctor;
+
+    if (!js_FindConstructor(cx, scope, name, &v))
+        return JS_FALSE;
+    if (JSVAL_IS_FUNCTION(cx, v)) {
+        ctor = JSVAL_TO_OBJECT(v);
+        if (!OBJ_GET_PROPERTY(cx, ctor,
+                              ATOM_TO_JSID(cx->runtime->atomState
+                                           .classPrototypeAtom),
+                              &v)) {
+            return JS_FALSE;
+        }
+        if (!JSVAL_IS_PRIMITIVE(v)) {
+            /*
+             * Set the newborn root in case v is otherwise unreferenced.
+             * It's ok to overwrite newborn roots here, since the getter
+             * called just above could have.  Unlike the common GC rooting
+             * model, our callers do not have to protect protop thanks to
+             * this newborn root, since they all immediately create a new
+             * instance that delegates to this object, or just query the
+             * prototype for its class.
+             */
+            cx->newborn[GCX_OBJECT] = JSVAL_TO_GCTHING(v);
+        }
+    }
+    *protop = JSVAL_IS_OBJECT(v) ? JSVAL_TO_OBJECT(v) : NULL;
+    return JS_TRUE;
+}
+
+/*
+ * For shared precompilation of function objects, we support cloning on entry
+ * to an execution context in which the function declaration or expression
+ * should be processed as if it were not precompiled, where the precompiled
+ * function's scope chain does not match the execution context's.  The cloned
+ * function object carries its execution-context scope in its parent slot; it
+ * links to the precompiled function (the "clone-parent") via its proto slot.
+ *
+ * Note that this prototype-based delegation leaves an unchecked access path
+ * from the clone to the clone-parent's 'constructor' property.  If the clone
+ * lives in a less privileged or shared scope than the clone-parent, this is
+ * a security hole, a sharing hazard, or both.  Therefore we check all such
+ * accesses with the following getter/setter pair, which we use when defining
+ * 'constructor' in f.prototype for all function objects f.
+ */
+static JSBool
+CheckCtorGetAccess(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSAtom *atom;
+    uintN attrs;
+
+    atom = cx->runtime->atomState.constructorAtom;
+    JS_ASSERT(id == ATOM_KEY(atom));
+    return OBJ_CHECK_ACCESS(cx, obj, ATOM_TO_JSID(atom), JSACC_READ,
+                            vp, &attrs);
+}
+
+static JSBool
+CheckCtorSetAccess(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSAtom *atom;
+    uintN attrs;
+
+    atom = cx->runtime->atomState.constructorAtom;
+    JS_ASSERT(id == ATOM_KEY(atom));
+    return OBJ_CHECK_ACCESS(cx, obj, ATOM_TO_JSID(atom), JSACC_WRITE,
+                            vp, &attrs);
+}
+
+JSBool
+js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto,
+                     uintN attrs)
+{
+    /*
+     * Use the given attributes for the prototype property of the constructor,
+     * as user-defined constructors have a DontDelete prototype (which may be
+     * reset), while native or "system" constructors have DontEnum | ReadOnly |
+     * DontDelete.
+     */
+    if (!OBJ_DEFINE_PROPERTY(cx, ctor,
+                             ATOM_TO_JSID(cx->runtime->atomState
+                                          .classPrototypeAtom),
+                             OBJECT_TO_JSVAL(proto),
+                             JS_PropertyStub, JS_PropertyStub,
+                             attrs, NULL)) {
+        return JS_FALSE;
+    }
+
+    /*
+     * ECMA says that Object.prototype.constructor, or f.prototype.constructor
+     * for a user-defined function f, is DontEnum.
+     */
+    return OBJ_DEFINE_PROPERTY(cx, proto,
+                               ATOM_TO_JSID(cx->runtime->atomState
+                                            .constructorAtom),
+                               OBJECT_TO_JSVAL(ctor),
+                               CheckCtorGetAccess, CheckCtorSetAccess,
+                               0, NULL);
+}
+
+JSBool
+js_ValueToObject(JSContext *cx, jsval v, JSObject **objp)
+{
+    JSObject *obj;
+
+    if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) {
+        obj = NULL;
+    } else if (JSVAL_IS_OBJECT(v)) {
+        obj = JSVAL_TO_OBJECT(v);
+        if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_OBJECT, &v))
+            return JS_FALSE;
+        if (JSVAL_IS_OBJECT(v))
+            obj = JSVAL_TO_OBJECT(v);
+    } else {
+        if (JSVAL_IS_STRING(v)) {
+            obj = js_StringToObject(cx, JSVAL_TO_STRING(v));
+        } else if (JSVAL_IS_INT(v)) {
+            obj = js_NumberToObject(cx, (jsdouble)JSVAL_TO_INT(v));
+        } else if (JSVAL_IS_DOUBLE(v)) {
+            obj = js_NumberToObject(cx, *JSVAL_TO_DOUBLE(v));
+        } else {
+            JS_ASSERT(JSVAL_IS_BOOLEAN(v));
+            obj = js_BooleanToObject(cx, JSVAL_TO_BOOLEAN(v));
+        }
+        if (!obj)
+            return JS_FALSE;
+    }
+    *objp = obj;
+    return JS_TRUE;
+}
+
+JSObject *
+js_ValueToNonNullObject(JSContext *cx, jsval v)
+{
+    JSObject *obj;
+    JSString *str;
+
+    if (!js_ValueToObject(cx, v, &obj))
+        return NULL;
+    if (!obj) {
+        str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL);
+        if (str) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_NO_PROPERTIES, JS_GetStringBytes(str));
+        }
+    }
+    return obj;
+}
+
+JSBool
+js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval)
+{
+#if JS_HAS_VALUEOF_HINT
+    jsval argv[1];
+
+    argv[0] = ATOM_KEY(cx->runtime->atomState.typeAtoms[type]);
+    return js_TryMethod(cx, obj, cx->runtime->atomState.valueOfAtom, 1, argv,
+                        rval);
+#else
+    return js_TryMethod(cx, obj, cx->runtime->atomState.valueOfAtom, 0, NULL,
+                        rval);
+#endif
+}
+
+JSBool
+js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
+             uintN argc, jsval *argv, jsval *rval)
+{
+    JSErrorReporter older;
+    jsval fval;
+    JSBool ok;
+    int stackDummy;
+
+    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
+        return JS_FALSE;
+    }
+
+    /*
+     * Report failure only if an appropriate method was found, and calling it
+     * returned failure.  We propagate failure in this case to make exceptions
+     * behave properly.
+     */
+    older = JS_SetErrorReporter(cx, NULL);
+    if (!OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &fval)) {
+        JS_ClearPendingException(cx);
+        ok = JS_TRUE;
+    } else if (!JSVAL_IS_PRIMITIVE(fval)) {
+        ok = js_InternalCall(cx, obj, fval, argc, argv, rval);
+    } else {
+        ok = JS_TRUE;
+    }
+    JS_SetErrorReporter(cx, older);
+    return ok;
+}
+
+#if JS_HAS_XDR
+
+#include "jsxdrapi.h"
+
+JSBool
+js_XDRObject(JSXDRState *xdr, JSObject **objp)
+{
+    JSContext *cx;
+    JSClass *clasp;
+    const char *className;
+    uint32 classId, classDef;
+    JSBool ok;
+    JSObject *proto;
+
+    cx = xdr->cx;
+    if (xdr->mode == JSXDR_ENCODE) {
+        clasp = OBJ_GET_CLASS(cx, *objp);
+        className = clasp->name;
+        classId = JS_XDRFindClassIdByName(xdr, className);
+        classDef = !classId;
+        if (classDef && !JS_XDRRegisterClass(xdr, clasp, &classId))
+            return JS_FALSE;
+    } else {
+        classDef = 0;
+        className = NULL;
+        clasp = NULL;           /* quell GCC overwarning */
+    }
+
+    /* XDR a flag word followed (if true) by the class name. */
+    if (!JS_XDRUint32(xdr, &classDef))
+        return JS_FALSE;
+    if (classDef && !JS_XDRCString(xdr, (char **) &className))
+        return JS_FALSE;
+
+    /* From here on, return through out: to free className if it was set. */
+    ok = JS_XDRUint32(xdr, &classId);
+    if (!ok)
+        goto out;
+
+    if (xdr->mode != JSXDR_ENCODE) {
+        if (classDef) {
+            ok = GetClassPrototype(cx, NULL, className, &proto);
+            if (!ok)
+                goto out;
+            clasp = OBJ_GET_CLASS(cx, proto);
+            ok = JS_XDRRegisterClass(xdr, clasp, &classId);
+            if (!ok)
+                goto out;
+        } else {
+            clasp = JS_XDRFindClassById(xdr, classId);
+            if (!clasp) {
+                char numBuf[12];
+                JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)classId);
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_CANT_FIND_CLASS, numBuf);
+                ok = JS_FALSE;
+                goto out;
+            }
+        }
+    }
+
+    if (!clasp->xdrObject) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_CANT_XDR_CLASS, clasp->name);
+        ok = JS_FALSE;
+    } else {
+        ok = clasp->xdrObject(xdr, objp);
+    }
+out:
+    if (xdr->mode != JSXDR_ENCODE && className)
+        JS_free(cx, (void *)className);
+    return ok;
+}
+
+#endif /* JS_HAS_XDR */
+
+#ifdef DEBUG_brendan
+
+#include <stdio.h>
+#include <math.h>
+
+uint32 js_entry_count_max;
+uint32 js_entry_count_sum;
+double js_entry_count_sqsum;
+uint32 js_entry_count_hist[11];
+
+static void
+MeterEntryCount(uintN count)
+{
+    if (count) {
+        js_entry_count_sum += count;
+        js_entry_count_sqsum += (double)count * count;
+        if (count > js_entry_count_max)
+            js_entry_count_max = count;
+    }
+    js_entry_count_hist[JS_MIN(count, 10)]++;
+}
+
+void
+js_DumpScopeMeters(JSRuntime *rt)
+{
+    static FILE *logfp;
+    if (!logfp)
+        logfp = fopen("/tmp/scope.stats", "a");
+
+    {
+        double mean = 0., var = 0., sigma = 0.;
+        double nscopes = rt->liveScopes;
+        double nentrys = js_entry_count_sum;
+        if (nscopes > 0 && nentrys >= 0) {
+            mean = nentrys / nscopes;
+            var = nscopes * js_entry_count_sqsum - nentrys * nentrys;
+            if (var < 0.0 || nscopes <= 1)
+                var = 0.0;
+            else
+                var /= nscopes * (nscopes - 1);
+
+            /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
+            sigma = (var != 0.) ? sqrt(var) : 0.;
+        }
+
+        fprintf(logfp,
+                "scopes %g entries %g mean %g sigma %g max %u",
+                nscopes, nentrys, mean, sigma, js_entry_count_max);
+    }
+
+    fprintf(logfp, " histogram %u %u %u %u %u %u %u %u %u %u %u\n",
+            js_entry_count_hist[0], js_entry_count_hist[1],
+            js_entry_count_hist[2], js_entry_count_hist[3],
+            js_entry_count_hist[4], js_entry_count_hist[5],
+            js_entry_count_hist[6], js_entry_count_hist[7],
+            js_entry_count_hist[8], js_entry_count_hist[9],
+            js_entry_count_hist[10]);
+    js_entry_count_sum = js_entry_count_max = 0;
+    js_entry_count_sqsum = 0;
+    memset(js_entry_count_hist, 0, sizeof js_entry_count_hist);
+    fflush(logfp);
+}
+
+#endif /* DEBUG_brendan */
+
+uint32
+js_Mark(JSContext *cx, JSObject *obj, void *arg)
+{
+    JSScope *scope;
+    JSScopeProperty *sprop;
+    JSClass *clasp;
+
+    JS_ASSERT(OBJ_IS_NATIVE(obj));
+    scope = OBJ_SCOPE(obj);
+#ifdef DEBUG_brendan
+    if (scope->object == obj)
+        MeterEntryCount(scope->entryCount);
+#endif
+
+    JS_ASSERT(!SCOPE_LAST_PROP(scope) ||
+              SCOPE_HAS_PROPERTY(scope, SCOPE_LAST_PROP(scope)));
+
+    for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
+        if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop))
+            continue;
+        MARK_SCOPE_PROPERTY(sprop);
+        if (JSID_IS_ATOM(sprop->id))
+            GC_MARK_ATOM(cx, JSID_TO_ATOM(sprop->id), arg);
+        else if (JSID_IS_OBJECT(sprop->id))
+            GC_MARK(cx, JSID_TO_OBJECT(sprop->id), "id", arg);
+
+#if JS_HAS_GETTER_SETTER
+        if (sprop->attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
+#ifdef GC_MARK_DEBUG
+            char buf[64];
+            JSAtom *atom = JSID_TO_ATOM(sprop->id);
+            const char *id = (atom && ATOM_IS_STRING(atom))
+                             ? JS_GetStringBytes(ATOM_TO_STRING(atom))
+                             : "unknown";
+#endif
+
+            if (sprop->attrs & JSPROP_GETTER) {
+#ifdef GC_MARK_DEBUG
+                JS_snprintf(buf, sizeof buf, "%s %s",
+                            id, js_getter_str);
+#endif
+                GC_MARK(cx,
+                        JSVAL_TO_GCTHING((jsval) sprop->getter),
+                        buf,
+                        arg);
+            }
+            if (sprop->attrs & JSPROP_SETTER) {
+#ifdef GC_MARK_DEBUG
+                JS_snprintf(buf, sizeof buf, "%s %s",
+                            id, js_setter_str);
+#endif
+                GC_MARK(cx,
+                        JSVAL_TO_GCTHING((jsval) sprop->setter),
+                        buf,
+                        arg);
+            }
+        }
+#endif /* JS_HAS_GETTER_SETTER */
+    }
+
+    /* No one runs while the GC is running, so we can use LOCKED_... here. */
+    clasp = LOCKED_OBJ_GET_CLASS(obj);
+    if (clasp->mark)
+        (void) clasp->mark(cx, obj, arg);
+
+    if (scope->object != obj) {
+        /*
+         * An unmutated object that shares a prototype's scope.  We can't tell
+         * how many slots are allocated and in use at obj->slots by looking at
+         * scope, so we get obj->slots' length from its -1'st element.
+         */
+        return (uint32) obj->slots[-1];
+    }
+    return JS_MIN(scope->map.freeslot, scope->map.nslots);
+}
+
+void
+js_Clear(JSContext *cx, JSObject *obj)
+{
+    JSScope *scope;
+    JSRuntime *rt;
+    JSScopeProperty *sprop;
+    uint32 i, n;
+
+    /*
+     * Clear our scope and the property cache of all obj's properties only if
+     * obj owns the scope (i.e., not if obj is unmutated and therefore sharing
+     * its prototype's scope).  NB: we do not clear any reserved slots lying
+     * below JSSLOT_FREE(clasp).
+     */
+    JS_LOCK_OBJ(cx, obj);
+    scope = OBJ_SCOPE(obj);
+    if (scope->object == obj) {
+        /* Clear the property cache before we clear the scope. */
+        rt = cx->runtime;
+        for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
+            if (!SCOPE_HAD_MIDDLE_DELETE(scope) ||
+                SCOPE_HAS_PROPERTY(scope, sprop)) {
+                PROPERTY_CACHE_FILL(&rt->propertyCache, obj, sprop->id, NULL);
+            }
+        }
+
+        /* Now that we're done using scope->lastProp/table, clear scope. */
+        js_ClearScope(cx, scope);
+
+        /* Clear slot values and reset freeslot so we're consistent. */
+        i = scope->map.nslots;
+        n = JSSLOT_FREE(LOCKED_OBJ_GET_CLASS(obj));
+        while (--i >= n)
+            obj->slots[i] = JSVAL_VOID;
+        scope->map.freeslot = n;
+    }
+    JS_UNLOCK_OBJ(cx, obj);
+}
+
+jsval
+js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot)
+{
+    jsval v;
+
+    JS_LOCK_OBJ(cx, obj);
+    v = (slot < (uint32) obj->slots[-1]) ? obj->slots[slot] : JSVAL_VOID;
+    JS_UNLOCK_OBJ(cx, obj);
+    return v;
+}
+
+JSBool
+js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v)
+{
+    JSScope *scope;
+    uint32 nslots;
+    JSClass *clasp;
+    jsval *newslots;
+
+    JS_LOCK_OBJ(cx, obj);
+    scope = OBJ_SCOPE(obj);
+    nslots = (uint32) obj->slots[-1];
+    if (slot >= nslots) {
+        /*
+         * At this point, obj may or may not own scope.  If some path calls
+         * js_GetMutableScope but does not add a slot-owning property, then
+         * scope->object == obj but nslots will be nominal.  If obj shares a
+         * prototype's scope, then we cannot update scope->map here, but we
+         * must update obj->slots[-1] when we grow obj->slots.
+         *
+         * See js_Mark, before the last return, where we make a special case
+         * for unmutated (scope->object != obj) objects.
+         */
+        JS_ASSERT(nslots == JS_INITIAL_NSLOTS);
+        clasp = LOCKED_OBJ_GET_CLASS(obj);
+        nslots = JSSLOT_FREE(clasp);
+        if (clasp->reserveSlots)
+            nslots += clasp->reserveSlots(cx, obj);
+        JS_ASSERT(slot < nslots);
+
+        newslots = AllocSlots(cx, obj->slots, nslots);
+        if (!newslots) {
+            JS_UNLOCK_SCOPE(cx, scope);
+            return JS_FALSE;
+        }
+        if (scope->object == obj)
+            scope->map.nslots = nslots;
+        obj->slots = newslots;
+    }
+
+    /* Whether or not we grew nslots, we may need to advance freeslot. */
+    if (scope->object == obj && slot >= scope->map.freeslot)
+        scope->map.freeslot = slot + 1;
+
+    obj->slots[slot] = v;
+    JS_UNLOCK_SCOPE(cx, scope);
+    return JS_TRUE;
+}
+
+#ifdef DEBUG
+
+/* Routines to print out values during debugging. */
+
+#ifdef OSSP
+void printChar(jschar *cp);
+void printString(JSString *str);
+void printVal(JSContext *cx, jsval val);
+void printObj(JSContext *cx, JSObject *jsobj);
+void printId(JSContext *cx, jsid id);
+void printAtom(JSAtom *atom);
+#endif
+
+void printChar(jschar *cp) {
+    fprintf(stderr, "jschar* (0x%p) \"", (void *)cp);
+    while (*cp)
+        fputc(*cp++, stderr);
+    fputc('"', stderr);
+    fputc('\n', stderr);
+}
+
+void printString(JSString *str) {
+    size_t i, n;
+    jschar *s;
+    fprintf(stderr, "string (0x%p) \"", (void *)str);
+    s = JSSTRING_CHARS(str);
+    for (i=0, n=JSSTRING_LENGTH(str); i < n; i++)
+        fputc(s[i], stderr);
+    fputc('"', stderr);
+    fputc('\n', stderr);
+}
+
+#ifndef OSSP
+void printVal(JSContext *cx, jsval val);
+#endif
+
+void printObj(JSContext *cx, JSObject *jsobj) {
+    jsuint i;
+    jsval val;
+    JSClass *clasp;
+
+    fprintf(stderr, "object 0x%p\n", (void *)jsobj);
+    clasp = OBJ_GET_CLASS(cx, jsobj);
+    fprintf(stderr, "class 0x%p %s\n", (void *)clasp, clasp->name);
+    for (i=0; i < jsobj->map->nslots; i++) {
+        fprintf(stderr, "slot %3d ", i);
+        val = jsobj->slots[i];
+        if (JSVAL_IS_OBJECT(val))
+            fprintf(stderr, "object 0x%p\n", (void *)JSVAL_TO_OBJECT(val));
+        else
+            printVal(cx, val);
+    }
+}
+
+void printVal(JSContext *cx, jsval val) {
+    fprintf(stderr, "val %d (0x%p) = ", (int)val, (void *)val);
+    if (JSVAL_IS_NULL(val)) {
+        fprintf(stderr, "null\n");
+    } else if (JSVAL_IS_VOID(val)) {
+        fprintf(stderr, "undefined\n");
+    } else if (JSVAL_IS_OBJECT(val)) {
+        printObj(cx, JSVAL_TO_OBJECT(val));
+    } else if (JSVAL_IS_INT(val)) {
+        fprintf(stderr, "(int) %d\n", JSVAL_TO_INT(val));
+    } else if (JSVAL_IS_STRING(val)) {
+        printString(JSVAL_TO_STRING(val));
+    } else if (JSVAL_IS_DOUBLE(val)) {
+        fprintf(stderr, "(double) %g\n", *JSVAL_TO_DOUBLE(val));
+    } else {
+        JS_ASSERT(JSVAL_IS_BOOLEAN(val));
+        fprintf(stderr, "(boolean) %s\n",
+                JSVAL_TO_BOOLEAN(val) ? "true" : "false");
+    }
+    fflush(stderr);
+}
+
+void printId(JSContext *cx, jsid id) {
+    fprintf(stderr, "id %d (0x%p) is ", (int)id, (void *)id);
+    printVal(cx, ID_TO_VALUE(id));
+}
+
+void printAtom(JSAtom *atom) {
+    printString(ATOM_TO_STRING(atom));
+}
+
+#endif

Added: freeswitch/trunk/libs/js/src/jsobj.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsobj.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,499 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsobj_h___
+#define jsobj_h___
+/*
+ * JS object definitions.
+ *
+ * A JS object consists of a possibly-shared object descriptor containing
+ * ordered property names, called the map; and a dense vector of property
+ * values, called slots.  The map/slot pointer pair is GC'ed, while the map
+ * is reference counted and the slot vector is malloc'ed.
+ */
+#include "jshash.h" /* Added by JSIFY */
+#include "jsprvtd.h"
+#include "jspubtd.h"
+
+JS_BEGIN_EXTERN_C
+
+struct JSObjectMap {
+    jsrefcount  nrefs;          /* count of all referencing objects */
+    JSObjectOps *ops;           /* high level object operation vtable */
+    uint32      nslots;         /* length of obj->slots vector */
+    uint32      freeslot;       /* index of next free obj->slots element */
+};
+
+/* Shorthand macros for frequently-made calls. */
+#define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp)                             \
+    (obj)->map->ops->lookupProperty(cx,obj,id,objp,propp)
+#define OBJ_DEFINE_PROPERTY(cx,obj,id,value,getter,setter,attrs,propp)        \
+    (obj)->map->ops->defineProperty(cx,obj,id,value,getter,setter,attrs,propp)
+#define OBJ_GET_PROPERTY(cx,obj,id,vp)                                        \
+    (obj)->map->ops->getProperty(cx,obj,id,vp)
+#define OBJ_SET_PROPERTY(cx,obj,id,vp)                                        \
+    (obj)->map->ops->setProperty(cx,obj,id,vp)
+#define OBJ_GET_ATTRIBUTES(cx,obj,id,prop,attrsp)                             \
+    (obj)->map->ops->getAttributes(cx,obj,id,prop,attrsp)
+#define OBJ_SET_ATTRIBUTES(cx,obj,id,prop,attrsp)                             \
+    (obj)->map->ops->setAttributes(cx,obj,id,prop,attrsp)
+#define OBJ_DELETE_PROPERTY(cx,obj,id,rval)                                   \
+    (obj)->map->ops->deleteProperty(cx,obj,id,rval)
+#define OBJ_DEFAULT_VALUE(cx,obj,hint,vp)                                     \
+    (obj)->map->ops->defaultValue(cx,obj,hint,vp)
+#define OBJ_ENUMERATE(cx,obj,enum_op,statep,idp)                              \
+    (obj)->map->ops->enumerate(cx,obj,enum_op,statep,idp)
+#define OBJ_CHECK_ACCESS(cx,obj,id,mode,vp,attrsp)                            \
+    (obj)->map->ops->checkAccess(cx,obj,id,mode,vp,attrsp)
+
+/* These four are time-optimized to avoid stub calls. */
+#define OBJ_THIS_OBJECT(cx,obj)                                               \
+    ((obj)->map->ops->thisObject                                              \
+     ? (obj)->map->ops->thisObject(cx,obj)                                    \
+     : (obj))
+#define OBJ_DROP_PROPERTY(cx,obj,prop)                                        \
+    ((obj)->map->ops->dropProperty                                            \
+     ? (obj)->map->ops->dropProperty(cx,obj,prop)                             \
+     : (void)0)
+#define OBJ_GET_REQUIRED_SLOT(cx,obj,slot)                                    \
+    ((obj)->map->ops->getRequiredSlot                                         \
+     ? (obj)->map->ops->getRequiredSlot(cx, obj, slot)                        \
+     : JSVAL_VOID)
+#define OBJ_SET_REQUIRED_SLOT(cx,obj,slot,v)                                  \
+    ((obj)->map->ops->setRequiredSlot                                         \
+     ? (obj)->map->ops->setRequiredSlot(cx, obj, slot, v)                     \
+     : JS_TRUE)
+
+#define OBJ_TO_INNER_OBJECT(cx,obj)                                           \
+    JS_BEGIN_MACRO                                                            \
+        JSClass *clasp_ = OBJ_GET_CLASS(cx, obj);                             \
+        if (clasp_->flags & JSCLASS_IS_EXTENDED) {                            \
+            JSExtendedClass *xclasp_ = (JSExtendedClass*)clasp_;              \
+            if (xclasp_->innerObject)                                         \
+                obj = xclasp_->innerObject(cx, obj);                          \
+        }                                                                     \
+    JS_END_MACRO
+
+/*
+ * In the original JS engine design, obj->slots pointed to a vector of length
+ * JS_INITIAL_NSLOTS words if obj->map was shared with a prototype object,
+ * else of length obj->map->nslots.  With the advent of JS_GetReservedSlot,
+ * JS_SetReservedSlot, and JSCLASS_HAS_RESERVED_SLOTS (see jsapi.h), the size
+ * of the minimum length slots vector in the case where map is shared cannot
+ * be constant.  This length starts at JS_INITIAL_NSLOTS, but may advance to
+ * include all the reserved slots.
+ *
+ * Therefore slots must be self-describing.  Rather than tag its low order bit
+ * (a bit is all we need) to distinguish initial length from reserved length,
+ * we do "the BSTR thing": over-allocate slots by one jsval, and store the
+ * *net* length (counting usable slots, which have non-negative obj->slots[]
+ * indices) in obj->slots[-1].  All code that sets obj->slots must be aware of
+ * this hack -- you have been warned, and jsobj.c has been updated!
+ */
+struct JSObject {
+    JSObjectMap *map;
+    jsval       *slots;
+};
+
+#define JSSLOT_PROTO        0
+#define JSSLOT_PARENT       1
+#define JSSLOT_CLASS        2
+#define JSSLOT_PRIVATE      3
+#define JSSLOT_START(clasp) (((clasp)->flags & JSCLASS_HAS_PRIVATE)           \
+                             ? JSSLOT_PRIVATE + 1                             \
+                             : JSSLOT_CLASS + 1)
+
+#define JSSLOT_FREE(clasp)  (JSSLOT_START(clasp)                              \
+                             + JSCLASS_RESERVED_SLOTS(clasp))
+
+#define JS_INITIAL_NSLOTS   5
+
+#ifdef DEBUG
+#define MAP_CHECK_SLOT(map,slot) \
+    JS_ASSERT((uint32)slot < JS_MIN((map)->freeslot, (map)->nslots))
+#define OBJ_CHECK_SLOT(obj,slot) \
+    MAP_CHECK_SLOT((obj)->map, slot)
+#else
+#define OBJ_CHECK_SLOT(obj,slot) ((void)0)
+#endif
+
+/* Fast macros for accessing obj->slots while obj is locked (if thread-safe). */
+#define LOCKED_OBJ_GET_SLOT(obj,slot) \
+    (OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot])
+#define LOCKED_OBJ_SET_SLOT(obj,slot,value) \
+    (OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot] = (value))
+#define LOCKED_OBJ_GET_PROTO(obj) \
+    JSVAL_TO_OBJECT(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PROTO))
+#define LOCKED_OBJ_GET_CLASS(obj) \
+    ((JSClass *)JSVAL_TO_PRIVATE(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_CLASS)))
+
+#ifdef JS_THREADSAFE
+
+/* Thread-safe functions and wrapper macros for accessing obj->slots. */
+#define OBJ_GET_SLOT(cx,obj,slot)                                             \
+    (OBJ_CHECK_SLOT(obj, slot),                                               \
+     (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->ownercx == cx)                    \
+     ? LOCKED_OBJ_GET_SLOT(obj, slot)                                         \
+     : js_GetSlotThreadSafe(cx, obj, slot))
+
+#define OBJ_SET_SLOT(cx,obj,slot,value)                                       \
+    (OBJ_CHECK_SLOT(obj, slot),                                               \
+     (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->ownercx == cx)                    \
+     ? (void) LOCKED_OBJ_SET_SLOT(obj, slot, value)                           \
+     : js_SetSlotThreadSafe(cx, obj, slot, value))
+
+/*
+ * If thread-safe, define an OBJ_GET_SLOT wrapper that bypasses, for a native
+ * object, the lock-free "fast path" test of (OBJ_SCOPE(obj)->ownercx == cx),
+ * to avoid needlessly switching from lock-free to lock-full scope when doing
+ * GC on a different context from the last one to own the scope.  The caller
+ * in this case is probably a JSClass.mark function, e.g., fun_mark, or maybe
+ * a finalizer.
+ *
+ * The GC runs only when all threads except the one on which the GC is active
+ * are suspended at GC-safe points, so there is no hazard in directly accessing
+ * obj->slots[slot] from the GC's thread, once rt->gcRunning has been set.  See
+ * jsgc.c for details.
+ */
+#define THREAD_IS_RUNNING_GC(rt, thread)                                      \
+    ((rt)->gcRunning && (rt)->gcThread == (thread))
+
+#define CX_THREAD_IS_RUNNING_GC(cx)                                           \
+    THREAD_IS_RUNNING_GC((cx)->runtime, (cx)->thread)
+
+#define GC_AWARE_GET_SLOT(cx, obj, slot)                                      \
+    ((OBJ_IS_NATIVE(obj) && CX_THREAD_IS_RUNNING_GC(cx))                      \
+     ? (obj)->slots[slot]                                                     \
+     : OBJ_GET_SLOT(cx, obj, slot))
+
+#else   /* !JS_THREADSAFE */
+
+#define OBJ_GET_SLOT(cx,obj,slot)       LOCKED_OBJ_GET_SLOT(obj,slot)
+#define OBJ_SET_SLOT(cx,obj,slot,value) LOCKED_OBJ_SET_SLOT(obj,slot,value)
+#define GC_AWARE_GET_SLOT(cx,obj,slot)  LOCKED_OBJ_GET_SLOT(obj,slot)
+
+#endif /* !JS_THREADSAFE */
+
+/* Thread-safe proto, parent, and class access macros. */
+#define OBJ_GET_PROTO(cx,obj) \
+    JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PROTO))
+#define OBJ_SET_PROTO(cx,obj,proto) \
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto))
+
+#define OBJ_GET_PARENT(cx,obj) \
+    JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PARENT))
+#define OBJ_SET_PARENT(cx,obj,parent) \
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent))
+
+#define OBJ_GET_CLASS(cx,obj) \
+    ((JSClass *)JSVAL_TO_PRIVATE(OBJ_GET_SLOT(cx, obj, JSSLOT_CLASS)))
+
+/* Test whether a map or object is native. */
+#define MAP_IS_NATIVE(map)                                                    \
+    ((map)->ops == &js_ObjectOps ||                                           \
+     ((map)->ops && (map)->ops->newObjectMap == js_ObjectOps.newObjectMap))
+
+#define OBJ_IS_NATIVE(obj)  MAP_IS_NATIVE((obj)->map)
+
+extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps;
+extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps;
+extern JSClass  js_ObjectClass;
+extern JSClass  js_WithClass;
+
+struct JSSharpObjectMap {
+    jsrefcount  depth;
+    jsatomid    sharpgen;
+    JSHashTable *table;
+};
+
+#define SHARP_BIT       ((jsatomid) 1)
+#define BUSY_BIT        ((jsatomid) 2)
+#define SHARP_ID_SHIFT  2
+#define IS_SHARP(he)    (JS_PTR_TO_UINT32((he)->value) & SHARP_BIT)
+#define MAKE_SHARP(he)  ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)|SHARP_BIT))
+#define IS_BUSY(he)     (JS_PTR_TO_UINT32((he)->value) & BUSY_BIT)
+#define MAKE_BUSY(he)   ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)|BUSY_BIT))
+#define CLEAR_BUSY(he)  ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)&~BUSY_BIT))
+
+extern JSHashEntry *
+js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap,
+                    jschar **sp);
+
+extern void
+js_LeaveSharpObject(JSContext *cx, JSIdArray **idap);
+
+extern JSBool
+js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval);
+
+extern JSBool
+js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval);
+
+extern JSBool
+js_HasOwnPropertyHelper(JSContext *cx, JSObject *obj, JSLookupPropOp lookup,
+                        uintN argc, jsval *argv, jsval *rval);
+
+extern JSObject *
+js_InitObjectClass(JSContext *cx, JSObject *obj);
+
+/* Select Object.prototype method names shared between jsapi.c and jsobj.c. */
+extern const char js_watch_str[];
+extern const char js_unwatch_str[];
+extern const char js_hasOwnProperty_str[];
+extern const char js_isPrototypeOf_str[];
+extern const char js_propertyIsEnumerable_str[];
+extern const char js_defineGetter_str[];
+extern const char js_defineSetter_str[];
+extern const char js_lookupGetter_str[];
+extern const char js_lookupSetter_str[];
+
+extern void
+js_InitObjectMap(JSObjectMap *map, jsrefcount nrefs, JSObjectOps *ops,
+                 JSClass *clasp);
+
+extern JSObjectMap *
+js_NewObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops,
+                JSClass *clasp, JSObject *obj);
+
+extern void
+js_DestroyObjectMap(JSContext *cx, JSObjectMap *map);
+
+extern JSObjectMap *
+js_HoldObjectMap(JSContext *cx, JSObjectMap *map);
+
+extern JSObjectMap *
+js_DropObjectMap(JSContext *cx, JSObjectMap *map, JSObject *obj);
+
+extern JSObject *
+js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
+
+extern JSBool
+js_FindConstructor(JSContext *cx, JSObject *start, const char *name, jsval *vp);
+
+extern JSObject *
+js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
+                   JSObject *parent, uintN argc, jsval *argv);
+
+extern void
+js_FinalizeObject(JSContext *cx, JSObject *obj);
+
+extern JSBool
+js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp);
+
+extern void
+js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot);
+
+/*
+ * Native property add and lookup variants that hide id in the hidden atom
+ * subspace, so as to avoid collisions between internal properties such as
+ * formal arguments and local variables in function objects, and externally
+ * set properties with the same ids.
+ */
+extern JSScopeProperty *
+js_AddHiddenProperty(JSContext *cx, JSObject *obj, jsid id,
+                     JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
+                     uintN attrs, uintN flags, intN shortid);
+
+extern JSBool
+js_LookupHiddenProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
+                        JSProperty **propp);
+
+/*
+ * Find or create a property named by id in obj's scope, with the given getter
+ * and setter, slot, attributes, and other members.
+ */
+extern JSScopeProperty *
+js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
+                     JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
+                     uintN attrs, uintN flags, intN shortid);
+
+/*
+ * Change sprop to have the given attrs, getter, and setter in scope, morphing
+ * it into a potentially new JSScopeProperty.  Return a pointer to the changed
+ * or identical property.
+ */
+extern JSScopeProperty *
+js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj,
+                             JSScopeProperty *sprop, uintN attrs, uintN mask,
+                             JSPropertyOp getter, JSPropertyOp setter);
+
+/*
+ * On error, return false.  On success, if propp is non-null, return true with
+ * obj locked and with a held property in *propp; if propp is null, return true
+ * but release obj's lock first.  Therefore all callers who pass non-null propp
+ * result parameters must later call OBJ_DROP_PROPERTY(cx, obj, *propp) both to
+ * drop the held property, and to release the lock on obj.
+ */
+extern JSBool
+js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
+                  JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
+                  JSProperty **propp);
+
+extern JSBool
+js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
+                        JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
+                        uintN flags, intN shortid, JSProperty **propp);
+
+/*
+ * Unlike js_DefineProperty, propp must be non-null.  On success, and if id was
+ * found, return true with *objp non-null and locked, and with a held property
+ * stored in *propp.  If successful but id was not found, return true with both
+ * *objp and *propp null.  Therefore all callers who receive a non-null *propp
+ * must later call OBJ_DROP_PROPERTY(cx, *objp, *propp).
+ */
+extern JS_FRIEND_API(JSBool)
+js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
+                  JSProperty **propp);
+
+/*
+ * Specialized subroutine that allows caller to preset JSRESOLVE_* flags.
+ */
+extern JSBool
+js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
+                           JSObject **objp, JSProperty **propp);
+
+extern JS_FRIEND_API(JSBool)
+js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
+                JSProperty **propp);
+
+extern JSObject *
+js_FindIdentifierBase(JSContext *cx, jsid id);
+
+extern JSObject *
+js_FindVariableScope(JSContext *cx, JSFunction **funp);
+
+extern JSBool
+js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
+
+extern JSBool
+js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
+
+extern JSBool
+js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
+                 uintN *attrsp);
+
+extern JSBool
+js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
+                 uintN *attrsp);
+
+extern JSBool
+js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval);
+
+extern JSBool
+js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp);
+
+extern JSIdArray *
+js_NewIdArray(JSContext *cx, jsint length);
+
+/*
+ * Unlike realloc(3), this function frees ida on failure.
+ */
+extern JSIdArray *
+js_SetIdArrayLength(JSContext *cx, JSIdArray *ida, jsint length);
+
+extern JSBool
+js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
+             jsval *statep, jsid *idp);
+
+extern JSBool
+js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
+               jsval *vp, uintN *attrsp);
+
+extern JSBool
+js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
+
+extern JSBool
+js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+             jsval *rval);
+
+extern JSBool
+js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
+
+extern JSBool
+js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj);
+
+extern JSBool
+js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
+
+extern JSBool
+js_GetClassPrototype(JSContext *cx, const char *name, JSObject **protop);
+
+extern JSBool
+js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto,
+                     uintN attrs);
+
+extern JSBool
+js_ValueToObject(JSContext *cx, jsval v, JSObject **objp);
+
+extern JSObject *
+js_ValueToNonNullObject(JSContext *cx, jsval v);
+
+extern JSBool
+js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval);
+
+extern JSBool
+js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
+             uintN argc, jsval *argv, jsval *rval);
+
+extern JSBool
+js_XDRObject(JSXDRState *xdr, JSObject **objp);
+
+extern uint32
+js_Mark(JSContext *cx, JSObject *obj, void *arg);
+
+extern void
+js_Clear(JSContext *cx, JSObject *obj);
+
+extern jsval
+js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot);
+
+extern JSBool
+js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v);
+
+extern JSObject *
+js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller);
+
+extern JSBool
+js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj,
+                         JSPrincipals *principals, const char *caller);
+JS_END_EXTERN_C
+
+#endif /* jsobj_h___ */

Added: freeswitch/trunk/libs/js/src/jsopcode.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsopcode.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,3142 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set sw=4 ts=8 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS bytecode descriptors, disassemblers, and decompilers.
+ */
+#include "jsstddef.h"
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsdtoa.h"
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jsarray.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsdbgapi.h"
+#include "jsemit.h"
+#include "jsfun.h"
+#include "jslock.h"
+#include "jsobj.h"
+#include "jsopcode.h"
+#include "jsregexp.h"
+#include "jsscope.h"
+#include "jsscript.h"
+#include "jsstr.h"
+
+const char js_const_str[]       = "const";
+const char js_var_str[]         = "var";
+const char js_function_str[]    = "function";
+const char js_in_str[]          = "in";
+const char js_instanceof_str[]  = "instanceof";
+const char js_new_str[]         = "new";
+const char js_delete_str[]      = "delete";
+const char js_typeof_str[]      = "typeof";
+const char js_void_str[]        = "void";
+const char js_null_str[]        = "null";
+const char js_this_str[]        = "this";
+const char js_false_str[]       = "false";
+const char js_true_str[]        = "true";
+const char js_default_str[]     = "default";
+
+const char *js_incop_str[]      = {"++", "--"};
+
+/* Pollute the namespace locally for MSVC Win16, but not for WatCom.  */
+#ifdef __WINDOWS_386__
+    #ifdef FAR
+        #undef FAR
+    #endif
+#else  /* !__WINDOWS_386__ */
+#ifndef FAR
+#define FAR
+#endif
+#endif /* !__WINDOWS_386__ */
+
+const JSCodeSpec FAR js_CodeSpec[] = {
+#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
+    {name,token,length,nuses,ndefs,prec,format},
+#include "jsopcode.tbl"
+#undef OPDEF
+};
+
+uintN js_NumCodeSpecs = sizeof (js_CodeSpec) / sizeof js_CodeSpec[0];
+
+/************************************************************************/
+
+static ptrdiff_t
+GetJumpOffset(jsbytecode *pc, jsbytecode *pc2)
+{
+    uint32 type;
+
+    type = (js_CodeSpec[*pc].format & JOF_TYPEMASK);
+    if (JOF_TYPE_IS_EXTENDED_JUMP(type))
+        return GET_JUMPX_OFFSET(pc2);
+    return GET_JUMP_OFFSET(pc2);
+}
+
+#ifdef DEBUG
+
+JS_FRIEND_API(JSBool)
+js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp)
+{
+    jsbytecode *pc, *end;
+    uintN len;
+
+    pc = script->code;
+    end = pc + script->length;
+    while (pc < end) {
+        if (pc == script->main)
+            fputs("main:\n", fp);
+        len = js_Disassemble1(cx, script, pc,
+                              PTRDIFF(pc, script->code, jsbytecode),
+                              lines, fp);
+        if (!len)
+            return JS_FALSE;
+        pc += len;
+    }
+    return JS_TRUE;
+}
+
+JS_FRIEND_API(uintN)
+js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
+                JSBool lines, FILE *fp)
+{
+    JSOp op;
+    const JSCodeSpec *cs;
+    ptrdiff_t len, off, jmplen;
+    uint32 type;
+    JSAtom *atom;
+    JSString *str;
+
+    op = (JSOp)*pc;
+    if (op >= JSOP_LIMIT) {
+        char numBuf1[12], numBuf2[12];
+        JS_snprintf(numBuf1, sizeof numBuf1, "%d", op);
+        JS_snprintf(numBuf2, sizeof numBuf2, "%d", JSOP_LIMIT);
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
+        return 0;
+    }
+    cs = &js_CodeSpec[op];
+    len = (ptrdiff_t) cs->length;
+    fprintf(fp, "%05u:", loc);
+    if (lines)
+        fprintf(fp, "%4u", JS_PCToLineNumber(cx, script, pc));
+    fprintf(fp, "  %s", cs->name);
+    type = cs->format & JOF_TYPEMASK;
+    switch (type) {
+      case JOF_BYTE:
+        if (op == JSOP_TRAP) {
+            op = JS_GetTrapOpcode(cx, script, pc);
+            if (op == JSOP_LIMIT)
+                return 0;
+            len = (ptrdiff_t) js_CodeSpec[op].length;
+        }
+        break;
+
+      case JOF_JUMP:
+      case JOF_JUMPX:
+        off = GetJumpOffset(pc, pc);
+        fprintf(fp, " %u (%d)", loc + off, off);
+        break;
+
+      case JOF_CONST:
+        atom = GET_ATOM(cx, script, pc);
+        str = js_ValueToSource(cx, ATOM_KEY(atom));
+        if (!str)
+            return 0;
+        fprintf(fp, " %s", JS_GetStringBytes(str));
+        break;
+
+      case JOF_UINT16:
+        fprintf(fp, " %u", GET_ARGC(pc));
+        break;
+
+#if JS_HAS_SWITCH_STATEMENT
+      case JOF_TABLESWITCH:
+      case JOF_TABLESWITCHX:
+      {
+        jsbytecode *pc2;
+        jsint i, low, high;
+
+        jmplen = (type == JOF_TABLESWITCH) ? JUMP_OFFSET_LEN
+                                           : JUMPX_OFFSET_LEN;
+        pc2 = pc;
+        off = GetJumpOffset(pc, pc2);
+        pc2 += jmplen;
+        low = GET_JUMP_OFFSET(pc2);
+        pc2 += JUMP_OFFSET_LEN;
+        high = GET_JUMP_OFFSET(pc2);
+        pc2 += JUMP_OFFSET_LEN;
+        fprintf(fp, " defaultOffset %d low %d high %d", off, low, high);
+        for (i = low; i <= high; i++) {
+            off = GetJumpOffset(pc, pc2);
+            fprintf(fp, "\n\t%d: %d", i, off);
+            pc2 += jmplen;
+        }
+        len = 1 + pc2 - pc;
+        break;
+      }
+
+      case JOF_LOOKUPSWITCH:
+      case JOF_LOOKUPSWITCHX:
+      {
+        jsbytecode *pc2;
+        jsatomid npairs;
+
+        jmplen = (type == JOF_LOOKUPSWITCH) ? JUMP_OFFSET_LEN
+                                            : JUMPX_OFFSET_LEN;
+        pc2 = pc;
+        off = GetJumpOffset(pc, pc2);
+        pc2 += jmplen;
+        npairs = GET_ATOM_INDEX(pc2);
+        pc2 += ATOM_INDEX_LEN;
+        fprintf(fp, " offset %d npairs %u", off, (uintN) npairs);
+        while (npairs) {
+            atom = GET_ATOM(cx, script, pc2);
+            pc2 += ATOM_INDEX_LEN;
+            off = GetJumpOffset(pc, pc2);
+            pc2 += jmplen;
+
+            str = js_ValueToSource(cx, ATOM_KEY(atom));
+            if (!str)
+                return 0;
+            fprintf(fp, "\n\t%s: %d", JS_GetStringBytes(str), off);
+            npairs--;
+        }
+        len = 1 + pc2 - pc;
+        break;
+      }
+#endif /* JS_HAS_SWITCH_STATEMENT */
+
+      case JOF_QARG:
+        fprintf(fp, " %u", GET_ARGNO(pc));
+        break;
+
+      case JOF_QVAR:
+        fprintf(fp, " %u", GET_VARNO(pc));
+        break;
+
+#if JS_HAS_LEXICAL_CLOSURE
+      case JOF_INDEXCONST:
+        fprintf(fp, " %u", GET_VARNO(pc));
+        pc += VARNO_LEN;
+        atom = GET_ATOM(cx, script, pc);
+        str = js_ValueToSource(cx, ATOM_KEY(atom));
+        if (!str)
+            return 0;
+        fprintf(fp, " %s", JS_GetStringBytes(str));
+        break;
+#endif
+
+      case JOF_UINT24:
+        if (op == JSOP_FINDNAME) {
+            /* Special case to avoid a JOF_FINDNAME just for this op. */
+            atom = js_GetAtom(cx, &script->atomMap, GET_LITERAL_INDEX(pc));
+            str = js_ValueToSource(cx, ATOM_KEY(atom));
+            if (!str)
+                return 0;
+            fprintf(fp, " %s", JS_GetStringBytes(str));
+            break;
+        }
+
+        JS_ASSERT(op == JSOP_UINT24 || op == JSOP_LITERAL);
+        fprintf(fp, " %u", GET_LITERAL_INDEX(pc));
+        break;
+
+      case JOF_LITOPX:
+        atom = js_GetAtom(cx, &script->atomMap, GET_LITERAL_INDEX(pc));
+        str = js_ValueToSource(cx, ATOM_KEY(atom));
+        if (!str)
+            return 0;
+
+        /*
+         * Bytecode: JSOP_LITOPX <uint24> op [<varno> if JSOP_DEFLOCALFUN].
+         * Advance pc to point at op.
+         */
+        pc += 1 + LITERAL_INDEX_LEN;
+        op = *pc;
+        cs = &js_CodeSpec[op];
+        fprintf(fp, " %s op %s", JS_GetStringBytes(str), cs->name);
+#if JS_HAS_LEXICAL_CLOSURE
+        if ((cs->format & JOF_TYPEMASK) == JOF_INDEXCONST)
+            fprintf(fp, " %u", GET_VARNO(pc));
+#endif
+
+        /*
+         * Set len to advance pc to skip op and any other immediates (namely,
+         * <varno> if JSOP_DEFLOCALFUN).
+         */
+        JS_ASSERT(cs->length > ATOM_INDEX_LEN);
+        len = cs->length - ATOM_INDEX_LEN;
+        break;
+
+      default: {
+        char numBuf[12];
+        JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format);
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_UNKNOWN_FORMAT, numBuf);
+        return 0;
+      }
+    }
+    fputs("\n", fp);
+    return len;
+}
+
+#endif /* DEBUG */
+
+/************************************************************************/
+
+/*
+ * Sprintf, but with unlimited and automatically allocated buffering.
+ */
+typedef struct Sprinter {
+    JSContext       *context;       /* context executing the decompiler */
+    JSArenaPool     *pool;          /* string allocation pool */
+    char            *base;          /* base address of buffer in pool */
+    size_t          size;           /* size of buffer allocated at base */
+    ptrdiff_t       offset;         /* offset of next free char in buffer */
+} Sprinter;
+
+#define INIT_SPRINTER(cx, sp, ap, off) \
+    ((sp)->context = cx, (sp)->pool = ap, (sp)->base = NULL, (sp)->size = 0,  \
+     (sp)->offset = off)
+
+#define OFF2STR(sp,off) ((sp)->base + (off))
+#define STR2OFF(sp,str) ((str) - (sp)->base)
+#define RETRACT(sp,str) ((sp)->offset = STR2OFF(sp, str))
+
+static JSBool
+SprintAlloc(Sprinter *sp, size_t nb)
+{
+    if (!sp->base) {
+        JS_ARENA_ALLOCATE_CAST(sp->base, char *, sp->pool, nb);
+    } else {
+        JS_ARENA_GROW_CAST(sp->base, char *, sp->pool, sp->size, nb);
+    }
+    if (!sp->base) {
+        JS_ReportOutOfMemory(sp->context);
+        return JS_FALSE;
+    }
+    sp->size += nb;
+    return JS_TRUE;
+}
+
+static ptrdiff_t
+SprintPut(Sprinter *sp, const char *s, size_t len)
+{
+    ptrdiff_t nb, offset;
+    char *bp;
+
+    /* Allocate space for s, including the '\0' at the end. */
+    nb = (sp->offset + len + 1) - sp->size;
+    if (nb > 0 && !SprintAlloc(sp, nb))
+        return -1;
+
+    /* Advance offset and copy s into sp's buffer. */
+    offset = sp->offset;
+    sp->offset += len;
+    bp = sp->base + offset;
+    memmove(bp, s, len);
+    bp[len] = 0;
+    return offset;
+}
+
+static ptrdiff_t
+Sprint(Sprinter *sp, const char *format, ...)
+{
+    va_list ap;
+    char *bp;
+    ptrdiff_t offset;
+
+    va_start(ap, format);
+    bp = JS_vsmprintf(format, ap);      /* XXX vsaprintf */
+    va_end(ap);
+    if (!bp) {
+        JS_ReportOutOfMemory(sp->context);
+        return -1;
+    }
+    offset = SprintPut(sp, bp, strlen(bp));
+    free(bp);
+    return offset;
+}
+
+const jschar js_EscapeMap[] = {
+    '\b', 'b',
+    '\f', 'f',
+    '\n', 'n',
+    '\r', 'r',
+    '\t', 't',
+    '\v', 'v',
+    '"',  '"',
+    '\'', '\'',
+    '\\', '\\',
+    0
+};
+
+static char *
+QuoteString(Sprinter *sp, JSString *str, jschar quote)
+{
+    ptrdiff_t off, len, nb;
+    const jschar *s, *t, *u, *z;
+    char *bp;
+    jschar c;
+    JSBool ok;
+
+    /* Sample off first for later return value pointer computation. */
+    off = sp->offset;
+    if (quote && Sprint(sp, "%c", (char)quote) < 0)
+        return NULL;
+
+    /* Loop control variables: z points at end of string sentinel. */
+    s = JSSTRING_CHARS(str);
+    z = s + JSSTRING_LENGTH(str);
+    for (t = s; t < z; s = ++t) {
+        /* Move t forward from s past un-quote-worthy characters. */
+        c = *t;
+        while (JS_ISPRINT(c) && c != quote && c != '\\' && !(c >> 8)) {
+            c = *++t;
+            if (t == z)
+                break;
+        }
+        len = PTRDIFF(t, s, jschar);
+
+        /* Allocate space for s, including the '\0' at the end. */
+        nb = (sp->offset + len + 1) - sp->size;
+        if (nb > 0 && !SprintAlloc(sp, nb))
+            return NULL;
+
+        /* Advance sp->offset and copy s into sp's buffer. */
+        bp = sp->base + sp->offset;
+        sp->offset += len;
+        while (--len >= 0)
+            *bp++ = (char) *s++;
+        *bp = '\0';
+
+        if (t == z)
+            break;
+
+        /* Use js_EscapeMap, \u, or \x only if necessary. */
+        if ((u = js_strchr(js_EscapeMap, c)) != NULL) {
+            ok = Sprint(sp, "\\%c", (char)u[1]) >= 0;
+        } else {
+#ifdef JS_C_STRINGS_ARE_UTF8
+            /* If this is a surrogate pair, make sure to print the pair. */
+            if (c >= 0xD800 && c <= 0xDBFF) {
+                jschar buffer[3];
+                buffer[0] = c;
+                buffer[1] = *++t;
+                buffer[2] = 0;
+                if (t == z) {
+                    ok = JS_FALSE;
+                    break;
+                }
+                ok = Sprint(sp, "%hs", buffer) >= 0;
+            } else {
+                /* Print as UTF-8 string. */
+                ok = Sprint(sp, "%hc", c) >= 0;
+            }
+#else
+            /* Use \uXXXX or \xXX  if the string cannot be displayed as UTF-8. */
+            ok = Sprint(sp, (c >> 8) ? "\\u%04X" : "\\x%02X", c) >= 0;
+#endif
+        }
+        if (!ok)
+            return NULL;
+    }
+
+    /* Sprint the closing quote and return the quoted string. */
+    if (quote && Sprint(sp, "%c", (char)quote) < 0)
+        return NULL;
+
+    /* 
+     * If we haven't Sprint'd anything yet, Sprint an empty string so that
+     * the OFF2STR below gives a valid result.
+     */
+    if (off == sp->offset && Sprint(sp, "") < 0)
+        return NULL;
+    return OFF2STR(sp, off);
+}
+
+JSString *
+js_QuoteString(JSContext *cx, JSString *str, jschar quote)
+{
+    void *mark;
+    Sprinter sprinter;
+    char *bytes;
+    JSString *escstr;
+
+    mark = JS_ARENA_MARK(&cx->tempPool);
+    INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0);
+    bytes = QuoteString(&sprinter, str, quote);
+    escstr = bytes ? JS_NewStringCopyZ(cx, bytes) : NULL;
+    JS_ARENA_RELEASE(&cx->tempPool, mark);
+    return escstr;
+}
+
+/************************************************************************/
+
+struct JSPrinter {
+    Sprinter        sprinter;       /* base class state */
+    JSArenaPool     pool;           /* string allocation pool */
+    uintN           indent;         /* indentation in spaces */
+    JSPackedBool    pretty;         /* pretty-print: indent, use newlines */
+    JSPackedBool    grouped;        /* in parenthesized expression context */
+    JSScript        *script;        /* script being printed */
+    JSScope         *scope;         /* script function scope */
+};
+
+/*
+ * Hack another flag, a la JS_DONT_PRETTY_PRINT, into uintN indent parameters
+ * to functions such as js_DecompileFunction and js_NewPrinter.  This time, as
+ * opposed to JS_DONT_PRETTY_PRINT back in the dark ages, we can assume that a
+ * uintN is at least 32 bits.
+ */
+#define JS_IN_GROUP_CONTEXT 0x10000
+
+JSPrinter *
+js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty)
+{
+    JSPrinter *jp;
+
+    jp = (JSPrinter *) JS_malloc(cx, sizeof(JSPrinter));
+    if (!jp)
+        return NULL;
+    INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);
+    JS_InitArenaPool(&jp->pool, name, 256, 1);
+    jp->indent = indent & ~JS_IN_GROUP_CONTEXT;
+    jp->pretty = pretty;
+    jp->grouped = (indent & JS_IN_GROUP_CONTEXT) != 0;
+    jp->script = NULL;
+    jp->scope = NULL;
+    return jp;
+}
+
+void
+js_DestroyPrinter(JSPrinter *jp)
+{
+    JS_FinishArenaPool(&jp->pool);
+    JS_free(jp->sprinter.context, jp);
+}
+
+JSString *
+js_GetPrinterOutput(JSPrinter *jp)
+{
+    JSContext *cx;
+    JSString *str;
+
+    cx = jp->sprinter.context;
+    if (!jp->sprinter.base)
+        return cx->runtime->emptyString;
+    str = JS_NewStringCopyZ(cx, jp->sprinter.base);
+    if (!str)
+        return NULL;
+    JS_FreeArenaPool(&jp->pool);
+    INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);
+    return str;
+}
+
+int
+js_printf(JSPrinter *jp, const char *format, ...)
+{
+    va_list ap;
+    char *bp, *fp;
+    int cc;
+
+    if (*format == '\0')
+        return 0;
+
+    va_start(ap, format);
+
+    /* If pretty-printing, expand magic tab into a run of jp->indent spaces. */
+    if (*format == '\t') {
+        if (jp->pretty && Sprint(&jp->sprinter, "%*s", jp->indent, "") < 0)
+            return -1;
+        format++;
+    }
+
+    /* Suppress newlines (must be once per format, at the end) if not pretty. */
+    fp = NULL;
+    if (!jp->pretty && format[cc = strlen(format) - 1] == '\n') {
+        fp = JS_strdup(jp->sprinter.context, format);
+        if (!fp)
+            return -1;
+        fp[cc] = '\0';
+        format = fp;
+    }
+
+    /* Allocate temp space, convert format, and put. */
+    bp = JS_vsmprintf(format, ap);      /* XXX vsaprintf */
+    if (fp) {
+        JS_free(jp->sprinter.context, fp);
+        format = NULL;
+    }
+    if (!bp) {
+        JS_ReportOutOfMemory(jp->sprinter.context);
+        return -1;
+    }
+
+    cc = strlen(bp);
+    if (SprintPut(&jp->sprinter, bp, (size_t)cc) < 0)
+        cc = -1;
+    free(bp);
+
+    va_end(ap);
+    return cc;
+}
+
+JSBool
+js_puts(JSPrinter *jp, const char *s)
+{
+    return SprintPut(&jp->sprinter, s, strlen(s)) >= 0;
+}
+
+/************************************************************************/
+
+typedef struct SprintStack {
+    Sprinter    sprinter;       /* sprinter for postfix to infix buffering */
+    ptrdiff_t   *offsets;       /* stack of postfix string offsets */
+    jsbytecode  *opcodes;       /* parallel stack of JS opcodes */
+    uintN       top;            /* top of stack index */
+    JSPrinter   *printer;       /* permanent output goes here */
+} SprintStack;
+
+/* Gap between stacked strings to allow for insertion of parens and commas. */
+#define PAREN_SLOP      (2 + 1)
+
+/*
+ * These pseudo-ops help js_DecompileValueGenerator decompile JSOP_SETNAME,
+ * JSOP_SETPROP, and JSOP_SETELEM, respectively.  See the first assertion in
+ * PushOff.
+ */
+#define JSOP_GETPROP2   254
+#define JSOP_GETELEM2   255
+
+static JSBool
+PushOff(SprintStack *ss, ptrdiff_t off, JSOp op)
+{
+    uintN top;
+
+#if JSOP_LIMIT > JSOP_GETPROP2
+#error JSOP_LIMIT must be <= JSOP_GETPROP2
+#endif
+    if (!SprintAlloc(&ss->sprinter, PAREN_SLOP))
+        return JS_FALSE;
+
+    /* ss->top points to the next free slot; be paranoid about overflow. */
+    top = ss->top;
+    JS_ASSERT(top < ss->printer->script->depth);
+    if (top >= ss->printer->script->depth) {
+        JS_ReportOutOfMemory(ss->sprinter.context);
+        return JS_FALSE;
+    }
+
+    /* The opcodes stack must contain real bytecodes that index js_CodeSpec. */
+    ss->offsets[top] = off;
+    ss->opcodes[top] = (op == JSOP_GETPROP2) ? JSOP_GETPROP
+                     : (op == JSOP_GETELEM2) ? JSOP_GETELEM
+                     : (jsbytecode) op;
+    ss->top = ++top;
+    ss->sprinter.offset += PAREN_SLOP;
+    return JS_TRUE;
+}
+
+static ptrdiff_t
+PopOff(SprintStack *ss, JSOp op)
+{
+    uintN top;
+    const JSCodeSpec *cs, *topcs;
+    ptrdiff_t off;
+
+    /* ss->top points to the next free slot; be paranoid about underflow. */
+    top = ss->top;
+    JS_ASSERT(top != 0);
+    if (top == 0)
+        return 0;
+
+    ss->top = --top;
+    topcs = &js_CodeSpec[ss->opcodes[top]];
+    cs = &js_CodeSpec[op];
+    if (topcs->prec != 0 && topcs->prec < cs->prec) {
+        ss->offsets[top] -= 2;
+        ss->sprinter.offset = ss->offsets[top];
+        off = Sprint(&ss->sprinter, "(%s)",
+                     OFF2STR(&ss->sprinter, ss->sprinter.offset + 2));
+    } else {
+        off = ss->sprinter.offset = ss->offsets[top];
+    }
+    return off;
+}
+
+#if JS_HAS_SWITCH_STATEMENT
+typedef struct TableEntry {
+    jsval       key;
+    ptrdiff_t   offset;
+    JSAtom      *label;
+    jsint       order;          /* source order for stable tableswitch sort */
+} TableEntry;
+
+static int
+CompareOffsets(const void *v1, const void *v2, void *arg)
+{
+    const TableEntry *te1 = (const TableEntry *) v1,
+                     *te2 = (const TableEntry *) v2;
+
+    if (te1->offset == te2->offset)
+        return (int) (te1->order - te2->order);
+    return (int) (te1->offset - te2->offset);
+}
+
+static JSBool
+Decompile(SprintStack *ss, jsbytecode *pc, intN nb);
+
+static JSBool
+DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
+                jsbytecode *pc, ptrdiff_t switchLength,
+                ptrdiff_t defaultOffset, JSBool isCondSwitch)
+{
+    JSContext *cx;
+    JSPrinter *jp;
+    char *lval, *rval;
+    uintN i;
+    ptrdiff_t diff, off, off2, caseExprOff;
+    jsval key;
+    JSString *str;
+
+    cx = ss->sprinter.context;
+    jp = ss->printer;
+
+    lval = OFF2STR(&ss->sprinter, PopOff(ss, JSOP_NOP));
+    js_printf(jp, "\tswitch (%s) {\n", lval);
+
+    if (tableLength) {
+        diff = table[0].offset - defaultOffset;
+        if (diff > 0) {
+            jp->indent += 2;
+            js_printf(jp, "\t%s:\n", js_default_str);
+            jp->indent += 2;
+            if (!Decompile(ss, pc + defaultOffset, diff))
+                return JS_FALSE;
+            jp->indent -= 4;
+        }
+
+        caseExprOff = isCondSwitch
+                      ? (ptrdiff_t) js_CodeSpec[JSOP_CONDSWITCH].length
+                      : 0;
+
+        for (i = 0; i < tableLength; i++) {
+            off = table[i].offset;
+            off2 = (i + 1 < tableLength) ? table[i + 1].offset : switchLength;
+
+            key = table[i].key;
+            if (isCondSwitch) {
+                ptrdiff_t nextCaseExprOff;
+
+                /*
+                 * key encodes the JSOP_CASE bytecode's offset from switchtop.
+                 * The next case expression follows immediately, unless we are
+                 * at the last case.
+                 */
+                nextCaseExprOff = (ptrdiff_t)JSVAL_TO_INT(key);
+                nextCaseExprOff += js_CodeSpec[pc[nextCaseExprOff]].length;
+                jp->indent += 2;
+                if (!Decompile(ss, pc + caseExprOff,
+                               nextCaseExprOff - caseExprOff)) {
+                    return JS_FALSE;
+                }
+                caseExprOff = nextCaseExprOff;
+            } else {
+                /*
+                 * key comes from an atom, not the decompiler, so we need to
+                 * quote it if it's a string literal.  But if table[i].label
+                 * is non-null, key was constant-propagated and label is the
+                 * name of the const we should show as the case label.  We set
+                 * key to undefined so this identifier is escaped, if required
+                 * by non-ASCII characters, but not quoted, by QuoteString.
+                 */
+                if (table[i].label) {
+                    str = ATOM_TO_STRING(table[i].label);
+                    key = JSVAL_VOID;
+                } else {
+                    str = js_ValueToString(cx, key);
+                    if (!str)
+                        return JS_FALSE;
+                }
+                rval = QuoteString(&ss->sprinter, str,
+                                   (jschar)(JSVAL_IS_STRING(key) ? '"' : 0));
+                if (!rval)
+                    return JS_FALSE;
+                RETRACT(&ss->sprinter, rval);
+                jp->indent += 2;
+                js_printf(jp, "\tcase %s:\n", rval);
+            }
+
+            jp->indent += 2;
+            if (off <= defaultOffset && defaultOffset < off2) {
+                diff = defaultOffset - off;
+                if (diff != 0) {
+                    if (!Decompile(ss, pc + off, diff))
+                        return JS_FALSE;
+                    off = defaultOffset;
+                }
+                jp->indent -= 2;
+                js_printf(jp, "\t%s:\n", js_default_str);
+                jp->indent += 2;
+            }
+            if (!Decompile(ss, pc + off, off2 - off))
+                return JS_FALSE;
+            jp->indent -= 4;
+        }
+    }
+
+    if (defaultOffset == switchLength) {
+        jp->indent += 2;
+        js_printf(jp, "\t%s:;\n", js_default_str);
+        jp->indent -= 2;
+    }
+    js_printf(jp, "\t}\n");
+    return JS_TRUE;
+}
+#endif
+
+static JSAtom *
+GetSlotAtom(JSPrinter *jp, JSPropertyOp getter, uintN slot)
+{
+    JSScope *scope;
+    JSScopeProperty *sprop;
+    JSObject *obj, *proto;
+
+    scope = jp->scope;
+    while (scope) {
+        for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
+            if (sprop->getter != getter)
+                continue;
+            JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
+            JS_ASSERT(JSID_IS_ATOM(sprop->id));
+            if ((uintN) sprop->shortid == slot)
+                return JSID_TO_ATOM(sprop->id);
+        }
+        obj = scope->object;
+        if (!obj)
+            break;
+        proto = OBJ_GET_PROTO(jp->sprinter.context, obj);
+        if (!proto)
+            break;
+        scope = OBJ_SCOPE(proto);
+    }
+    return NULL;
+}
+
+static const char *
+VarPrefix(jssrcnote *sn)
+{
+    if (sn) {
+        if (SN_TYPE(sn) == SRC_VAR)
+            return "var ";
+        if (SN_TYPE(sn) == SRC_CONST)
+            return "const ";
+    }
+    return "";
+}
+
+static JSBool
+Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
+{
+    JSContext *cx;
+    JSPrinter *jp, *jp2;
+    jsbytecode *endpc, *done, *forelem_tail, *forelem_done;
+    ptrdiff_t tail, todo, len, oplen, cond, next;
+    JSOp op, lastop, saveop;
+    const JSCodeSpec *cs, *topcs;
+    jssrcnote *sn, *sn2;
+    const char *lval, *rval, *xval, *fmt;
+    jsint i, argc;
+    char **argv;
+    jsatomid atomIndex;
+    JSAtom *atom;
+    JSObject *obj;
+    JSFunction *fun;
+    JSString *str;
+    JSBool ok;
+#if JS_HAS_XML_SUPPORT
+    JSBool foreach, inXML, quoteAttr;
+#else
+#define inXML JS_FALSE
+#endif
+    jsval val;
+    static const char catch_cookie[] = "/*CATCH*/";
+    static const char with_cookie[] = "/*WITH*/";
+
+/*
+ * Local macros
+ */
+#define DECOMPILE_CODE(pc,nb)   if (!Decompile(ss, pc, nb)) return JS_FALSE
+#define POP_STR()               OFF2STR(&ss->sprinter, PopOff(ss, op))
+#define LOCAL_ASSERT(expr)      JS_ASSERT(expr); if (!(expr)) return JS_FALSE
+
+/*
+ * Callers know that ATOM_IS_STRING(atom), and we leave it to the optimizer to
+ * common ATOM_TO_STRING(atom) here and near the call sites.
+ */
+#define ATOM_IS_IDENTIFIER(atom)                                              \
+    (!ATOM_KEYWORD(atom) && js_IsIdentifier(ATOM_TO_STRING(atom)))
+
+/*
+ * Given an atom already fetched from jp->script's atom map, quote/escape its
+ * string appropriately into rval, and select fmt from the quoted and unquoted
+ * alternatives.
+ */
+#define GET_QUOTE_AND_FMT(qfmt, ufmt, rval)                                   \
+    JS_BEGIN_MACRO                                                            \
+        jschar quote_;                                                        \
+        if (!ATOM_IS_IDENTIFIER(atom)) {                                      \
+            quote_ = '\'';                                                    \
+            fmt = qfmt;                                                       \
+        } else {                                                              \
+            quote_ = 0;                                                       \
+            fmt = ufmt;                                                       \
+        }                                                                     \
+        rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), quote_);      \
+        if (!rval)                                                            \
+            return JS_FALSE;                                                  \
+    JS_END_MACRO
+
+/*
+ * Get atom from jp->script's atom map, quote/escape its string appropriately
+ * into rval, and select fmt from the quoted and unquoted alternatives.
+ */
+#define GET_ATOM_QUOTE_AND_FMT(qfmt, ufmt, rval)                              \
+    JS_BEGIN_MACRO                                                            \
+        atom = GET_ATOM(cx, jp->script, pc);                                  \
+        GET_QUOTE_AND_FMT(qfmt, ufmt, rval);                                  \
+    JS_END_MACRO
+
+    cx = ss->sprinter.context;
+    jp = ss->printer;
+    endpc = pc + nb;
+    forelem_tail = forelem_done = NULL;
+    tail = -1;
+    todo = -2;                  /* NB: different from Sprint() error return. */
+    op = JSOP_NOP;
+    sn = NULL;
+    rval = NULL;
+#if JS_HAS_XML_SUPPORT
+    foreach = inXML = quoteAttr = JS_FALSE;
+#endif
+
+    while (pc < endpc) {
+        lastop = op;
+        op = saveop = (JSOp) *pc;
+        if (op >= JSOP_LIMIT) {
+            switch (op) {
+              case JSOP_GETPROP2:
+                saveop = JSOP_GETPROP;
+                break;
+              case JSOP_GETELEM2:
+                saveop = JSOP_GETELEM;
+                break;
+              default:;
+            }
+        }
+        cs = &js_CodeSpec[saveop];
+        len = oplen = cs->length;
+
+        if (cs->token) {
+            switch (cs->nuses) {
+              case 2:
+                rval = POP_STR();
+                lval = POP_STR();
+                sn = js_GetSrcNote(jp->script, pc);
+                if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
+                    /* Print only the right operand of the assignment-op. */
+                    todo = SprintPut(&ss->sprinter, rval, strlen(rval));
+                } else if (!inXML) {
+                    todo = Sprint(&ss->sprinter, "%s %s %s",
+                                  lval, cs->token, rval);
+                } else {
+                    /* In XML, just concatenate the two operands. */
+                    JS_ASSERT(op == JSOP_ADD);
+                    todo = Sprint(&ss->sprinter, "%s%s", lval, rval);
+                }
+                break;
+
+              case 1:
+                rval = POP_STR();
+                todo = Sprint(&ss->sprinter, "%s%s", cs->token, rval);
+                break;
+
+              case 0:
+                todo = SprintPut(&ss->sprinter, cs->token, strlen(cs->token));
+                break;
+
+              default:
+                todo = -2;
+                break;
+            }
+        } else {
+            switch (op) {
+#define BEGIN_LITOPX_CASE(OP)                                                 \
+              case OP:                                                        \
+                atomIndex = GET_ATOM_INDEX(pc);                               \
+              do_##OP:                                                        \
+                atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);
+
+#define END_LITOPX_CASE                                                       \
+                break;
+
+              case JSOP_NOP:
+                /*
+                 * Check for a do-while loop, a for-loop with an empty
+                 * initializer part, a labeled statement, a function
+                 * definition, or try/finally.
+                 */
+                sn = js_GetSrcNote(jp->script, pc);
+                todo = -2;
+                switch (sn ? SN_TYPE(sn) : SRC_NULL) {
+#if JS_HAS_DO_WHILE_LOOP
+                  case SRC_WHILE:
+                    js_printf(jp, "\tdo {\n");
+                    jp->indent += 4;
+                    break;
+#endif /* JS_HAS_DO_WHILE_LOOP */
+
+                  case SRC_FOR:
+                    rval = "";
+
+                  do_forloop:
+                    /* Skip the JSOP_NOP or JSOP_POP bytecode. */
+                    pc++;
+
+                    /* Get the cond, next, and loop-closing tail offsets. */
+                    cond = js_GetSrcNoteOffset(sn, 0);
+                    next = js_GetSrcNoteOffset(sn, 1);
+                    tail = js_GetSrcNoteOffset(sn, 2);
+                    LOCAL_ASSERT(tail + GetJumpOffset(pc+tail, pc+tail) == 0);
+
+                    /* Print the keyword and the possibly empty init-part. */
+                    js_printf(jp, "\tfor (%s;", rval);
+
+                    if (pc[cond] == JSOP_IFEQ || pc[cond] == JSOP_IFEQX) {
+                        /* Decompile the loop condition. */
+                        DECOMPILE_CODE(pc, cond);
+                        js_printf(jp, " %s", POP_STR());
+                    }
+
+                    /* Need a semicolon whether or not there was a cond. */
+                    js_puts(jp, ";");
+
+                    if (pc[next] != JSOP_GOTO && pc[next] != JSOP_GOTOX) {
+                        /* Decompile the loop updater. */
+                        DECOMPILE_CODE(pc + next, tail - next - 1);
+                        js_printf(jp, " %s", POP_STR());
+                    }
+
+                    /* Do the loop body. */
+                    js_printf(jp, ") {\n");
+                    jp->indent += 4;
+                    oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;
+                    DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);
+                    jp->indent -= 4;
+                    js_printf(jp, "\t}\n");
+
+                    /* Set len so pc skips over the entire loop. */
+                    len = tail + js_CodeSpec[pc[tail]].length;
+                    break;
+
+                  case SRC_LABEL:
+                    atom = js_GetAtom(cx, &jp->script->atomMap,
+                                      (jsatomid) js_GetSrcNoteOffset(sn, 0));
+                    jp->indent -= 4;
+                    rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                    if (!rval)
+                        return JS_FALSE;
+                    RETRACT(&ss->sprinter, rval);
+                    js_printf(jp, "\t%s:\n", rval);
+                    jp->indent += 4;
+                    break;
+
+                  case SRC_LABELBRACE:
+                    atom = js_GetAtom(cx, &jp->script->atomMap,
+                                      (jsatomid) js_GetSrcNoteOffset(sn, 0));
+                    rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                    if (!rval)
+                        return JS_FALSE;
+                    RETRACT(&ss->sprinter, rval);
+                    js_printf(jp, "\t%s: {\n", rval);
+                    jp->indent += 4;
+                    break;
+
+                  case SRC_ENDBRACE:
+                    jp->indent -= 4;
+                    js_printf(jp, "\t}\n");
+                    break;
+
+                  case SRC_CATCH:
+                    jp->indent -= 4;
+                    sn = js_GetSrcNote(jp->script, pc);
+                    pc += oplen;
+                    js_printf(jp, "\t} catch (");
+
+                    LOCAL_ASSERT(*pc == JSOP_NAME);
+                    pc += js_CodeSpec[JSOP_NAME].length;
+                    LOCAL_ASSERT(*pc == JSOP_PUSHOBJ);
+                    pc += js_CodeSpec[JSOP_PUSHOBJ].length;
+                    LOCAL_ASSERT(*pc == JSOP_NEWINIT);
+                    pc += js_CodeSpec[JSOP_NEWINIT].length;
+                    LOCAL_ASSERT(*pc == JSOP_EXCEPTION);
+                    pc += js_CodeSpec[JSOP_EXCEPTION].length;
+                    if (*pc == JSOP_LITOPX) {
+                        atomIndex = GET_LITERAL_INDEX(pc);
+                        pc += 1 + LITERAL_INDEX_LEN;
+                        LOCAL_ASSERT(*pc == JSOP_INITCATCHVAR);
+                        ++pc;
+                    } else {
+                        LOCAL_ASSERT(*pc == JSOP_INITCATCHVAR);
+                        atomIndex = GET_ATOM_INDEX(pc);
+                        pc += js_CodeSpec[JSOP_INITCATCHVAR].length;
+                    }
+                    atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);
+                    rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                    if (!rval)
+                        return JS_FALSE;
+                    RETRACT(&ss->sprinter, rval);
+                    js_printf(jp, "%s", rval);
+                    LOCAL_ASSERT(*pc == JSOP_ENTERWITH);
+                    pc += js_CodeSpec[JSOP_ENTERWITH].length;
+
+                    len = js_GetSrcNoteOffset(sn, 0);
+                    if (len) {
+                        js_printf(jp, " if ");
+                        DECOMPILE_CODE(pc, len);
+                        js_printf(jp, "%s", POP_STR());
+                        pc += len;
+                        LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
+                        pc += js_CodeSpec[*pc].length;
+                    }
+
+                    js_printf(jp, ") {\n");
+                    jp->indent += 4;
+                    todo = Sprint(&ss->sprinter, catch_cookie);
+                    len = 0;
+                    break;
+
+                  case SRC_FUNCDEF:
+                    atom = js_GetAtom(cx, &jp->script->atomMap,
+                                      (jsatomid) js_GetSrcNoteOffset(sn, 0));
+                    JS_ASSERT(ATOM_IS_OBJECT(atom));
+                  do_function:
+                    obj = ATOM_TO_OBJECT(atom);
+                    fun = (JSFunction *) JS_GetPrivate(cx, obj);
+                    jp2 = js_NewPrinter(cx, JS_GetFunctionName(fun),
+                                        jp->indent, jp->pretty);
+                    if (!jp2)
+                        return JS_FALSE;
+                    jp2->scope = jp->scope;
+                    js_puts(jp2, "\n");
+                    ok = js_DecompileFunction(jp2, fun);
+                    if (ok) {
+                        js_puts(jp2, "\n");
+                        str = js_GetPrinterOutput(jp2);
+                        if (str)
+                            js_printf(jp, "%s\n", JS_GetStringBytes(str));
+                        else
+                            ok = JS_FALSE;
+                    }
+                    js_DestroyPrinter(jp2);
+                    if (!ok)
+                        return JS_FALSE;
+
+                    break;
+
+                  default:;
+                }
+              case JSOP_RETRVAL:
+                break;
+
+              case JSOP_GROUP:
+                /* Use last real op so PopOff adds parens if needed. */
+                todo = PopOff(ss, lastop);
+
+                /* Now add user-supplied parens only if PopOff did not. */
+                cs    = &js_CodeSpec[lastop];
+                topcs = &js_CodeSpec[ss->opcodes[ss->top]];
+                if (topcs->prec >= cs->prec) {
+                    todo = Sprint(&ss->sprinter, "(%s)",
+                                  OFF2STR(&ss->sprinter, todo));
+                }
+                break;
+
+              case JSOP_PUSH:
+              case JSOP_PUSHOBJ:
+              case JSOP_BINDNAME:
+              do_JSOP_BINDNAME:
+                todo = Sprint(&ss->sprinter, "");
+                break;
+
+#if JS_HAS_EXCEPTIONS
+              case JSOP_TRY:
+                js_printf(jp, "\ttry {\n");
+                jp->indent += 4;
+                todo = -2;
+                break;
+
+            {
+              static const char finally_cookie[] = "/*FINALLY*/";
+
+              case JSOP_FINALLY:
+                jp->indent -= 4;
+                js_printf(jp, "\t} finally {\n");
+                jp->indent += 4;
+
+                /*
+                 * We must push an empty string placeholder for gosub's return
+                 * address, popped by JSOP_RETSUB and counted by script->depth
+                 * but not by ss->top (see JSOP_SETSP, below).
+                 */
+                todo = Sprint(&ss->sprinter, finally_cookie);
+                break;
+
+              case JSOP_RETSUB:
+                rval = POP_STR();
+                LOCAL_ASSERT(strcmp(rval, finally_cookie) == 0);
+                todo = -2;
+                break;
+            }
+
+              case JSOP_SWAP:
+                /*
+                 * We don't generate this opcode currently, and previously we
+                 * did not need to decompile it.  If old, serialized bytecode
+                 * uses it still, we should fall through and set todo = -2.
+                 */
+                /* FALL THROUGH */
+
+              case JSOP_GOSUB:
+              case JSOP_GOSUBX:
+                /*
+                 * JSOP_GOSUB and GOSUBX have no effect on the decompiler's
+                 * string stack because the next op in bytecode order finds
+                 * the stack balanced by a JSOP_RETSUB executed elsewhere.
+                 */
+                todo = -2;
+                break;
+
+              case JSOP_SETSP:
+                /*
+                 * The compiler models operand stack depth and fixes the stack
+                 * pointer on entry to a catch clause based on its depth model.
+                 * The decompiler must match the code generator's model, which
+                 * is why JSOP_FINALLY pushes a cookie that JSOP_RETSUB pops.
+                 */
+                LOCAL_ASSERT(ss->top >= (uintN) GET_ATOM_INDEX(pc));
+                ss->top = (uintN) GET_ATOM_INDEX(pc);
+                break;
+
+              case JSOP_EXCEPTION:
+                /*
+                 * The only other JSOP_EXCEPTION case occurs as part of a code
+                 * sequence that follows a SRC_CATCH-annotated JSOP_NOP.
+                 */
+                sn = js_GetSrcNote(jp->script, pc);
+                LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_HIDDEN);
+                todo = -2;
+                break;
+#endif /* JS_HAS_EXCEPTIONS */
+
+              case JSOP_POP:
+              case JSOP_POPV:
+                sn = js_GetSrcNote(jp->script, pc);
+                switch (sn ? SN_TYPE(sn) : SRC_NULL) {
+                  case SRC_FOR:
+                    rval = POP_STR();
+                    todo = -2;
+                    goto do_forloop;
+
+                  case SRC_PCDELTA:
+                    /* Pop and save to avoid blowing stack depth budget. */
+                    lval = JS_strdup(cx, POP_STR());
+                    if (!lval)
+                        return JS_FALSE;
+
+                    /*
+                     * The offset tells distance to the end of the right-hand
+                     * operand of the comma operator.
+                     */
+                    done = pc + len;
+                    pc += js_GetSrcNoteOffset(sn, 0);
+                    len = 0;
+
+                    if (!Decompile(ss, done, pc - done)) {
+                        JS_free(cx, (char *)lval);
+                        return JS_FALSE;
+                    }
+
+                    /* Pop Decompile result and print comma expression. */
+                    rval = POP_STR();
+                    todo = Sprint(&ss->sprinter, "%s, %s", lval, rval);
+                    JS_free(cx, (char *)lval);
+                    break;
+
+                  case SRC_HIDDEN:
+                    /* Hide this pop, it's from a goto in a with or for/in. */
+                    todo = -2;
+                    break;
+
+                  default:
+                    rval = POP_STR();
+                    if (*rval != '\0')
+                        js_printf(jp, "\t%s;\n", rval);
+                    todo = -2;
+                    break;
+                }
+                break;
+
+              case JSOP_POP2:
+                (void) PopOff(ss, op);
+                (void) PopOff(ss, op);
+                todo = -2;
+                break;
+
+              case JSOP_ENTERWITH:
+                JS_ASSERT(!js_GetSrcNote(jp->script, pc));
+                rval = POP_STR();
+                js_printf(jp, "\twith (%s) {\n", rval);
+                jp->indent += 4;
+                todo = Sprint(&ss->sprinter, with_cookie);
+                break;
+
+              case JSOP_LEAVEWITH:
+                sn = js_GetSrcNote(jp->script, pc);
+                todo = -2;
+                if (sn && SN_TYPE(sn) == SRC_HIDDEN)
+                    break;
+                rval = POP_STR();
+                if (sn && SN_TYPE(sn) == SRC_CATCH) {
+                    LOCAL_ASSERT(strcmp(rval, catch_cookie) == 0);
+                    LOCAL_ASSERT((uintN) js_GetSrcNoteOffset(sn, 0) == ss->top);
+                    break;
+                }
+                LOCAL_ASSERT(strcmp(rval, with_cookie) == 0);
+                jp->indent -= 4;
+                js_printf(jp, "\t}\n");
+                break;
+
+              case JSOP_SETRVAL:
+              case JSOP_RETURN:
+                lval = js_CodeSpec[JSOP_RETURN].name;
+                rval = POP_STR();
+                if (*rval != '\0')
+                    js_printf(jp, "\t%s %s;\n", lval, rval);
+                else
+                    js_printf(jp, "\t%s;\n", lval);
+                todo = -2;
+                break;
+
+#if JS_HAS_EXCEPTIONS
+              case JSOP_THROW:
+                sn = js_GetSrcNote(jp->script, pc);
+                todo = -2;
+                if (sn && SN_TYPE(sn) == SRC_HIDDEN)
+                    break;
+                rval = POP_STR();
+                js_printf(jp, "\t%s %s;\n", cs->name, rval);
+                break;
+#endif /* JS_HAS_EXCEPTIONS */
+
+              case JSOP_GOTO:
+              case JSOP_GOTOX:
+                sn = js_GetSrcNote(jp->script, pc);
+                switch (sn ? SN_TYPE(sn) : SRC_NULL) {
+                  case SRC_CONT2LABEL:
+                    atom = js_GetAtom(cx, &jp->script->atomMap,
+                                      (jsatomid) js_GetSrcNoteOffset(sn, 0));
+                    rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                    if (!rval)
+                        return JS_FALSE;
+                    RETRACT(&ss->sprinter, rval);
+                    js_printf(jp, "\tcontinue %s;\n", rval);
+                    break;
+                  case SRC_CONTINUE:
+                    js_printf(jp, "\tcontinue;\n");
+                    break;
+                  case SRC_BREAK2LABEL:
+                    atom = js_GetAtom(cx, &jp->script->atomMap,
+                                      (jsatomid) js_GetSrcNoteOffset(sn, 0));
+                    rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                    if (!rval)
+                        return JS_FALSE;
+                    RETRACT(&ss->sprinter, rval);
+                    js_printf(jp, "\tbreak %s;\n", rval);
+                    break;
+                  case SRC_HIDDEN:
+                    break;
+                  default:
+                    js_printf(jp, "\tbreak;\n");
+                    break;
+                }
+                todo = -2;
+                break;
+
+              case JSOP_IFEQ:
+              case JSOP_IFEQX:
+                len = GetJumpOffset(pc, pc);
+                sn = js_GetSrcNote(jp->script, pc);
+
+                switch (sn ? SN_TYPE(sn) : SRC_NULL) {
+                  case SRC_IF:
+                  case SRC_IF_ELSE:
+                    rval = POP_STR();
+                    js_printf(jp, "\tif (%s) {\n", rval);
+                    jp->indent += 4;
+                    if (SN_TYPE(sn) == SRC_IF) {
+                        DECOMPILE_CODE(pc + oplen, len - oplen);
+                    } else {
+                        len = js_GetSrcNoteOffset(sn, 0);
+                        DECOMPILE_CODE(pc + oplen, len - oplen);
+                        jp->indent -= 4;
+                        pc += len;
+                        LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
+                        oplen = js_CodeSpec[*pc].length;
+                        len = GetJumpOffset(pc, pc);
+                        js_printf(jp, "\t} else {\n");
+                        jp->indent += 4;
+                        DECOMPILE_CODE(pc + oplen, len - oplen);
+                    }
+                    jp->indent -= 4;
+                    js_printf(jp, "\t}\n");
+                    todo = -2;
+                    break;
+
+                  case SRC_WHILE:
+                    rval = POP_STR();
+                    js_printf(jp, "\twhile (%s) {\n", rval);
+                    jp->indent += 4;
+                    tail = js_GetSrcNoteOffset(sn, 0);
+                    DECOMPILE_CODE(pc + oplen, tail - oplen);
+                    jp->indent -= 4;
+                    js_printf(jp, "\t}\n");
+                    todo = -2;
+                    break;
+
+                  case SRC_COND:
+                    xval = JS_strdup(cx, POP_STR());
+                    if (!xval)
+                        return JS_FALSE;
+                    len = js_GetSrcNoteOffset(sn, 0);
+                    DECOMPILE_CODE(pc + oplen, len - oplen);
+                    lval = JS_strdup(cx, POP_STR());
+                    if (!lval) {
+                        JS_free(cx, (void *)xval);
+                        return JS_FALSE;
+                    }
+                    pc += len;
+                    LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
+                    oplen = js_CodeSpec[*pc].length;
+                    len = GetJumpOffset(pc, pc);
+                    DECOMPILE_CODE(pc + oplen, len - oplen);
+                    rval = POP_STR();
+                    todo = Sprint(&ss->sprinter, "%s ? %s : %s",
+                                  xval, lval, rval);
+                    JS_free(cx, (void *)xval);
+                    JS_free(cx, (void *)lval);
+                    break;
+
+                  default:
+                    break;
+                }
+                break;
+
+              case JSOP_IFNE:
+              case JSOP_IFNEX:
+#if JS_HAS_DO_WHILE_LOOP
+                /* Currently, this must be a do-while loop's upward branch. */
+                jp->indent -= 4;
+                js_printf(jp, "\t} while (%s);\n", POP_STR());
+                todo = -2;
+#else
+                JS_ASSERT(0);
+#endif /* JS_HAS_DO_WHILE_LOOP */
+                break;
+
+              case JSOP_OR:
+              case JSOP_ORX:
+                xval = "||";
+
+              do_logical_connective:
+                /* Top of stack is the first clause in a disjunction (||). */
+                lval = JS_strdup(cx, POP_STR());
+                if (!lval)
+                    return JS_FALSE;
+                done = pc + GetJumpOffset(pc, pc);
+                pc += len;
+                len = PTRDIFF(done, pc, jsbytecode);
+                DECOMPILE_CODE(pc, len);
+                rval = POP_STR();
+                if (jp->pretty &&
+                    jp->indent + 4 + strlen(lval) + 4 + strlen(rval) > 75) {
+                    rval = JS_strdup(cx, rval);
+                    if (!rval) {
+                        tail = -1;
+                    } else {
+                        todo = Sprint(&ss->sprinter, "%s %s\n", lval, xval);
+                        tail = Sprint(&ss->sprinter, "%*s%s",
+                                      jp->indent + 4, "", rval);
+                        JS_free(cx, (char *)rval);
+                    }
+                    if (tail < 0)
+                        todo = -1;
+                } else {
+                    todo = Sprint(&ss->sprinter, "%s %s %s", lval, xval, rval);
+                }
+                JS_free(cx, (char *)lval);
+                break;
+
+              case JSOP_AND:
+              case JSOP_ANDX:
+                xval = "&&";
+                goto do_logical_connective;
+
+              case JSOP_FORARG:
+                atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
+                LOCAL_ASSERT(atom);
+                goto do_fornameinloop;
+
+              case JSOP_FORVAR:
+                atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
+                LOCAL_ASSERT(atom);
+                goto do_fornameinloop;
+
+              case JSOP_FORNAME:
+                atom = GET_ATOM(cx, jp->script, pc);
+
+              do_fornameinloop:
+                sn = js_GetSrcNote(jp->script, pc);
+                xval = NULL;
+                lval = "";
+                goto do_forinloop;
+
+              case JSOP_FORPROP:
+                xval = NULL;
+                atom = GET_ATOM(cx, jp->script, pc);
+                if (!ATOM_IS_IDENTIFIER(atom)) {
+                    xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
+                                       (jschar)'\'');
+                    if (!xval)
+                        return JS_FALSE;
+                    atom = NULL;
+                }
+                lval = POP_STR();
+                sn = NULL;
+
+              do_forinloop:
+                pc += oplen;
+                LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
+                oplen = js_CodeSpec[*pc].length;
+                len = GetJumpOffset(pc, pc);
+                sn2 = js_GetSrcNote(jp->script, pc);
+                tail = js_GetSrcNoteOffset(sn2, 0);
+
+              do_forinbody:
+#if JS_HAS_XML_SUPPORT
+                if (foreach) {
+                    foreach = JS_FALSE;
+                    js_printf(jp, "\tfor %s (%s%s",
+                              js_each_str, VarPrefix(sn), lval);
+                } else
+#endif
+                    js_printf(jp, "\tfor (%s%s", VarPrefix(sn), lval);
+                if (atom) {
+                    xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                    if (!xval)
+                        return JS_FALSE;
+                    RETRACT(&ss->sprinter, xval);
+                    js_printf(jp, *lval ? ".%s" : "%s", xval);
+                } else if (xval && *xval) {
+                    js_printf(jp,
+                              (js_CodeSpec[lastop].format & JOF_XMLNAME)
+                              ? ".%s"
+                              : "[%s]",
+                              xval);
+                }
+                rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
+                js_printf(jp, " in %s) {\n", rval);
+                jp->indent += 4;
+                DECOMPILE_CODE(pc + oplen, tail - oplen);
+                jp->indent -= 4;
+                js_printf(jp, "\t}\n");
+                todo = -2;
+                break;
+
+              case JSOP_FORELEM:
+                pc++;
+                LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
+                len = js_CodeSpec[*pc].length;
+
+                /*
+                 * Arrange for the JSOP_ENUMELEM case to set tail for use by
+                 * do_forinbody: code that uses on it to find the loop-closing
+                 * jump (whatever its format, normal or extended), in order to
+                 * bound the recursively decompiled loop body.
+                 */
+                sn = js_GetSrcNote(jp->script, pc);
+                JS_ASSERT(!forelem_tail);
+                forelem_tail = pc + js_GetSrcNoteOffset(sn, 0);
+
+                /*
+                 * This gets a little wacky.  Only the length of the for loop
+                 * body PLUS the element-indexing expression is known here, so
+                 * we pass the after-loop pc to the JSOP_ENUMELEM case, which
+                 * is immediately below, to decompile that helper bytecode via
+                 * the 'forelem_done' local.
+                 *
+                 * Since a for..in loop can't nest in the head of another for
+                 * loop, we can use forelem_{tail,done} singletons to remember
+                 * state from JSOP_FORELEM to JSOP_ENUMELEM, thence (via goto)
+                 * to label do_forinbody.
+                 */
+                JS_ASSERT(!forelem_done);
+                forelem_done = pc + GetJumpOffset(pc, pc);
+                break;
+
+              case JSOP_ENUMELEM:
+                /*
+                 * The stack has the object under the (top) index expression.
+                 * The "rval" property id is underneath those two on the stack.
+                 * The for loop body net and gross lengths can now be adjusted
+                 * to account for the length of the indexing expression that
+                 * came after JSOP_FORELEM and before JSOP_ENUMELEM.
+                 */
+                atom = NULL;
+                xval = POP_STR();
+                lval = POP_STR();
+                rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
+                JS_ASSERT(forelem_tail > pc);
+                tail = forelem_tail - pc;
+                forelem_tail = NULL;
+                JS_ASSERT(forelem_done > pc);
+                len = forelem_done - pc;
+                forelem_done = NULL;
+                goto do_forinbody;
+
+#if JS_HAS_GETTER_SETTER
+              case JSOP_GETTER:
+              case JSOP_SETTER:
+                todo = -2;
+                break;
+#endif
+
+              case JSOP_DUP2:
+                rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-2]);
+                todo = SprintPut(&ss->sprinter, rval, strlen(rval));
+                if (todo < 0 || !PushOff(ss, todo, ss->opcodes[ss->top-2]))
+                    return JS_FALSE;
+                /* FALL THROUGH */
+
+              case JSOP_DUP:
+                rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
+                op = ss->opcodes[ss->top-1];
+                todo = SprintPut(&ss->sprinter, rval, strlen(rval));
+                break;
+
+              case JSOP_SETARG:
+                atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
+                LOCAL_ASSERT(atom);
+                goto do_setname;
+
+              case JSOP_SETVAR:
+                atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
+                LOCAL_ASSERT(atom);
+                goto do_setname;
+
+              case JSOP_SETCONST:
+              case JSOP_SETNAME:
+              case JSOP_SETGVAR:
+                atomIndex = GET_ATOM_INDEX(pc);
+
+              do_JSOP_SETCONST:
+                atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);
+
+              do_setname:
+                lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                if (!lval)
+                    return JS_FALSE;
+                rval = POP_STR();
+                if (op == JSOP_SETNAME)
+                    (void) PopOff(ss, op);
+
+              do_setlval:
+                sn = js_GetSrcNote(jp->script, pc - 1);
+                if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
+                    todo = Sprint(&ss->sprinter, "%s %s= %s",
+                                  lval, js_CodeSpec[lastop].token, rval);
+                } else {
+                    sn = js_GetSrcNote(jp->script, pc);
+                    todo = Sprint(&ss->sprinter, "%s%s = %s",
+                                  VarPrefix(sn), lval, rval);
+                }
+                break;
+
+              case JSOP_NEW:
+              case JSOP_CALL:
+              case JSOP_EVAL:
+#if JS_HAS_LVALUE_RETURN
+              case JSOP_SETCALL:
+#endif
+                saveop = op;
+                op = JSOP_NOP;           /* turn off parens */
+                argc = GET_ARGC(pc);
+                argv = (char **)
+                    JS_malloc(cx, (size_t)(argc + 1) * sizeof *argv);
+                if (!argv)
+                    return JS_FALSE;
+
+                ok = JS_TRUE;
+                for (i = argc; i > 0; i--) {
+                    argv[i] = JS_strdup(cx, POP_STR());
+                    if (!argv[i]) {
+                        ok = JS_FALSE;
+                        break;
+                    }
+                }
+
+                /* Skip the JSOP_PUSHOBJ-created empty string. */
+                LOCAL_ASSERT(ss->top >= 2);
+                (void) PopOff(ss, op);
+
+                /* Get the callee's decompiled image in argv[0]. */
+                argv[0] = JS_strdup(cx, POP_STR());
+                if (!argv[i])
+                    ok = JS_FALSE;
+
+                lval = "(", rval = ")";
+                if (saveop == JSOP_NEW) {
+                    todo = Sprint(&ss->sprinter, "%s %s%s",
+                                  js_new_str, argv[0], lval);
+                } else {
+                    todo = Sprint(&ss->sprinter, "%s%s",
+                                  argv[0], lval);
+                }
+                if (todo < 0)
+                    ok = JS_FALSE;
+
+                for (i = 1; i <= argc; i++) {
+                    if (!argv[i] ||
+                        Sprint(&ss->sprinter, "%s%s",
+                               argv[i], (i < argc) ? ", " : "") < 0) {
+                        ok = JS_FALSE;
+                        break;
+                    }
+                }
+                if (Sprint(&ss->sprinter, rval) < 0)
+                    ok = JS_FALSE;
+
+                for (i = 0; i <= argc; i++) {
+                    if (argv[i])
+                        JS_free(cx, argv[i]);
+                }
+                JS_free(cx, argv);
+                if (!ok)
+                    return JS_FALSE;
+                op = saveop;
+#if JS_HAS_LVALUE_RETURN
+                if (op == JSOP_SETCALL) {
+                    if (!PushOff(ss, todo, op))
+                        return JS_FALSE;
+                    todo = Sprint(&ss->sprinter, "");
+                }
+#endif
+                break;
+
+              case JSOP_DELNAME:
+                atom = GET_ATOM(cx, jp->script, pc);
+                lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                if (!lval)
+                    return JS_FALSE;
+                RETRACT(&ss->sprinter, lval);
+                todo = Sprint(&ss->sprinter, "%s %s", js_delete_str, lval);
+                break;
+
+              case JSOP_DELPROP:
+                GET_ATOM_QUOTE_AND_FMT("%s %s[%s]", "%s %s.%s", rval);
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter, fmt, js_delete_str, lval, rval);
+                break;
+
+              case JSOP_DELELEM:
+                xval = POP_STR();
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter,
+                              (js_CodeSpec[lastop].format & JOF_XMLNAME)
+                              ? "%s %s.%s"
+                              : "%s %s[%s]",
+                              js_delete_str, lval, xval);
+                break;
+
+#if JS_HAS_XML_SUPPORT
+              case JSOP_DELDESC:
+                xval = POP_STR();
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter, "%s %s..%s",
+                              js_delete_str, lval, xval);
+                break;
+#endif
+
+              case JSOP_TYPEOF:
+              case JSOP_VOID:
+                rval = POP_STR();
+                todo = Sprint(&ss->sprinter, "%s %s", cs->name, rval);
+                break;
+
+              case JSOP_INCARG:
+              case JSOP_DECARG:
+                atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
+                LOCAL_ASSERT(atom);
+                goto do_incatom;
+
+              case JSOP_INCVAR:
+              case JSOP_DECVAR:
+                atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
+                LOCAL_ASSERT(atom);
+                goto do_incatom;
+
+              case JSOP_INCNAME:
+              case JSOP_DECNAME:
+              case JSOP_INCGVAR:
+              case JSOP_DECGVAR:
+                atom = GET_ATOM(cx, jp->script, pc);
+              do_incatom:
+                lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                if (!lval)
+                    return JS_FALSE;
+                RETRACT(&ss->sprinter, lval);
+                todo = Sprint(&ss->sprinter, "%s%s",
+                              js_incop_str[!(cs->format & JOF_INC)], lval);
+                break;
+
+              case JSOP_INCPROP:
+              case JSOP_DECPROP:
+                GET_ATOM_QUOTE_AND_FMT("%s%s[%s]", "%s%s.%s", rval);
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter, fmt,
+                              js_incop_str[!(cs->format & JOF_INC)],
+                              lval, rval);
+                break;
+
+              case JSOP_INCELEM:
+              case JSOP_DECELEM:
+                xval = POP_STR();
+                lval = POP_STR();
+                if (*xval != '\0') {
+                    todo = Sprint(&ss->sprinter,
+                                  (js_CodeSpec[lastop].format & JOF_XMLNAME)
+                                  ? "%s%s.%s"
+                                  : "%s%s[%s]",
+                                  js_incop_str[!(cs->format & JOF_INC)],
+                                  lval, xval);
+                } else {
+                    todo = Sprint(&ss->sprinter, "%s%s",
+                                  js_incop_str[!(cs->format & JOF_INC)], lval);
+                }
+                break;
+
+              case JSOP_ARGINC:
+              case JSOP_ARGDEC:
+                atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
+                LOCAL_ASSERT(atom);
+                goto do_atominc;
+
+              case JSOP_VARINC:
+              case JSOP_VARDEC:
+                atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
+                LOCAL_ASSERT(atom);
+                goto do_atominc;
+
+              case JSOP_NAMEINC:
+              case JSOP_NAMEDEC:
+              case JSOP_GVARINC:
+              case JSOP_GVARDEC:
+                atom = GET_ATOM(cx, jp->script, pc);
+              do_atominc:
+                lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                if (!lval)
+                    return JS_FALSE;
+                todo = STR2OFF(&ss->sprinter, lval);
+                SprintPut(&ss->sprinter,
+                          js_incop_str[!(cs->format & JOF_INC)],
+                          2);
+                break;
+
+              case JSOP_PROPINC:
+              case JSOP_PROPDEC:
+                GET_ATOM_QUOTE_AND_FMT("%s[%s]%s", "%s.%s%s", rval);
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter, fmt, lval, rval,
+                              js_incop_str[!(cs->format & JOF_INC)]);
+                break;
+
+              case JSOP_ELEMINC:
+              case JSOP_ELEMDEC:
+                xval = POP_STR();
+                lval = POP_STR();
+                if (*xval != '\0') {
+                    todo = Sprint(&ss->sprinter,
+                                  (js_CodeSpec[lastop].format & JOF_XMLNAME)
+                                  ? "%s.%s%s"
+                                  : "%s[%s]%s",
+                                  lval, xval,
+                                  js_incop_str[!(cs->format & JOF_INC)]);
+                } else {
+                    todo = Sprint(&ss->sprinter, "%s%s",
+                                  lval, js_incop_str[!(cs->format & JOF_INC)]);
+                }
+                break;
+
+              case JSOP_GETPROP2:
+                op = JSOP_GETPROP;
+                (void) PopOff(ss, lastop);
+                /* FALL THROUGH */
+
+              case JSOP_GETPROP:
+                atom = GET_ATOM(cx, jp->script, pc);
+
+              do_getprop:
+                GET_QUOTE_AND_FMT("%s[%s]", "%s.%s", rval);
+
+              do_getprop_lval:
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter, fmt, lval, rval);
+                break;
+
+#if JS_HAS_XML_SUPPORT
+              BEGIN_LITOPX_CASE(JSOP_GETMETHOD)
+                sn = js_GetSrcNote(jp->script, pc);
+                if (sn && SN_TYPE(sn) == SRC_PCBASE)
+                    goto do_getprop;
+                GET_QUOTE_AND_FMT("%s.function::[%s]", "%s.function::%s", rval);
+                goto do_getprop_lval;
+
+              BEGIN_LITOPX_CASE(JSOP_SETMETHOD)
+                sn = js_GetSrcNote(jp->script, pc);
+                if (sn && SN_TYPE(sn) == SRC_PCBASE)
+                    goto do_setprop;
+                GET_QUOTE_AND_FMT("%s.function::[%s] %s= %s",
+                                  "%s.function::%s %s= %s",
+                                  xval);
+                goto do_setprop_rval;
+#endif
+
+              case JSOP_SETPROP:
+                atom = GET_ATOM(cx, jp->script, pc);
+
+              do_setprop:
+                GET_QUOTE_AND_FMT("%s[%s] %s= %s", "%s.%s %s= %s", xval);
+
+              do_setprop_rval:
+                rval = POP_STR();
+                lval = POP_STR();
+                sn = js_GetSrcNote(jp->script, pc - 1);
+                todo = Sprint(&ss->sprinter, fmt, lval, xval,
+                              (sn && SN_TYPE(sn) == SRC_ASSIGNOP)
+                              ? js_CodeSpec[lastop].token
+                              : "",
+                              rval);
+                break;
+
+              case JSOP_GETELEM2:
+                op = JSOP_GETELEM;
+                (void) PopOff(ss, lastop);
+                /* FALL THROUGH */
+
+              case JSOP_GETELEM:
+                op = JSOP_NOP;           /* turn off parens */
+                xval = POP_STR();
+                op = JSOP_GETELEM;
+                lval = POP_STR();
+                if (*xval == '\0') {
+                    todo = Sprint(&ss->sprinter, "%s", lval);
+                } else {
+                    todo = Sprint(&ss->sprinter,
+                                  (js_CodeSpec[lastop].format & JOF_XMLNAME)
+                                  ? "%s.%s"
+                                  : "%s[%s]",
+                                  lval, xval);
+                }
+                break;
+
+              case JSOP_SETELEM:
+                op = JSOP_NOP;           /* turn off parens */
+                rval = POP_STR();
+                xval = POP_STR();
+                op = JSOP_SETELEM;
+                lval = POP_STR();
+                if (*xval == '\0')
+                    goto do_setlval;
+                sn = js_GetSrcNote(jp->script, pc - 1);
+                todo = Sprint(&ss->sprinter,
+                              (js_CodeSpec[lastop].format & JOF_XMLNAME)
+                              ? "%s.%s %s= %s"
+                              : "%s[%s] %s= %s",
+                              lval, xval,
+                              (sn && SN_TYPE(sn) == SRC_ASSIGNOP)
+                              ? js_CodeSpec[lastop].token
+                              : "",
+                              rval);
+                break;
+
+              case JSOP_ARGSUB:
+                i = (jsint) GET_ATOM_INDEX(pc);
+                todo = Sprint(&ss->sprinter, "%s[%d]",
+                              js_arguments_str, (int) i);
+                break;
+
+              case JSOP_ARGCNT:
+                todo = Sprint(&ss->sprinter, "%s.%s",
+                              js_arguments_str, js_length_str);
+                break;
+
+              case JSOP_GETARG:
+                atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
+                LOCAL_ASSERT(atom);
+                goto do_name;
+
+              case JSOP_GETVAR:
+                atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
+                LOCAL_ASSERT(atom);
+                goto do_name;
+
+              case JSOP_NAME:
+              case JSOP_GETGVAR:
+                atom = GET_ATOM(cx, jp->script, pc);
+              do_name:
+                sn = js_GetSrcNote(jp->script, pc);
+                rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                if (!rval)
+                    return JS_FALSE;
+                RETRACT(&ss->sprinter, rval);
+                todo = Sprint(&ss->sprinter, "%s%s", VarPrefix(sn), rval);
+                break;
+
+              case JSOP_UINT16:
+                i = (jsint) GET_ATOM_INDEX(pc);
+                goto do_sprint_int;
+
+              case JSOP_UINT24:
+                i = (jsint) GET_LITERAL_INDEX(pc);
+              do_sprint_int:
+                todo = Sprint(&ss->sprinter, "%u", (unsigned) i);
+                break;
+
+              case JSOP_LITERAL:
+                atomIndex = GET_LITERAL_INDEX(pc);
+                goto do_JSOP_STRING;
+
+              case JSOP_FINDNAME:
+                atomIndex = GET_LITERAL_INDEX(pc);
+                todo = Sprint(&ss->sprinter, "");
+                if (todo < 0 || !PushOff(ss, todo, op))
+                    return JS_FALSE;
+                atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);
+                goto do_name;
+
+              case JSOP_LITOPX:
+                atomIndex = GET_LITERAL_INDEX(pc);
+                op = pc[1 + LITERAL_INDEX_LEN];
+                switch (op) {
+                  case JSOP_ANONFUNOBJ:   goto do_JSOP_ANONFUNOBJ;
+                  case JSOP_BINDNAME:     goto do_JSOP_BINDNAME;
+                  case JSOP_CLOSURE:      goto do_JSOP_CLOSURE;
+#if JS_HAS_EXPORT_IMPORT
+                  case JSOP_EXPORTNAME:   goto do_JSOP_EXPORTNAME;
+#endif
+#if JS_HAS_XML_SUPPORT
+                  case JSOP_GETMETHOD:    goto do_JSOP_GETMETHOD;
+                  case JSOP_SETMETHOD:    goto do_JSOP_SETMETHOD;
+#endif
+                  case JSOP_NAMEDFUNOBJ:  goto do_JSOP_NAMEDFUNOBJ;
+                  case JSOP_NUMBER:       goto do_JSOP_NUMBER;
+                  case JSOP_OBJECT:       goto do_JSOP_OBJECT;
+#if JS_HAS_XML_SUPPORT
+                  case JSOP_QNAMECONST:   goto do_JSOP_QNAMECONST;
+                  case JSOP_QNAMEPART:    goto do_JSOP_QNAMEPART;
+#endif
+                  case JSOP_REGEXP:       goto do_JSOP_REGEXP;
+                  case JSOP_SETCONST:     goto do_JSOP_SETCONST;
+                  case JSOP_STRING:       goto do_JSOP_STRING;
+#if JS_HAS_XML_SUPPORT
+                  case JSOP_XMLCDATA:     goto do_JSOP_XMLCDATA;
+                  case JSOP_XMLCOMMENT:   goto do_JSOP_XMLCOMMENT;
+                  case JSOP_XMLOBJECT:    goto do_JSOP_XMLOBJECT;
+                  case JSOP_XMLPI:        goto do_JSOP_XMLPI;
+#endif
+                  default:                JS_ASSERT(0);
+                }
+                /* NOTREACHED */
+                break;
+
+              BEGIN_LITOPX_CASE(JSOP_NUMBER)
+                val = ATOM_KEY(atom);
+                if (JSVAL_IS_INT(val)) {
+                    long ival = (long)JSVAL_TO_INT(val);
+                    todo = Sprint(&ss->sprinter, "%ld", ival);
+                } else {
+                    char buf[DTOSTR_STANDARD_BUFFER_SIZE];
+                    char *numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD,
+                                             0, *JSVAL_TO_DOUBLE(val));
+                    if (!numStr) {
+                        JS_ReportOutOfMemory(cx);
+                        return JS_FALSE;
+                    }
+                    todo = Sprint(&ss->sprinter, numStr);
+                }
+              END_LITOPX_CASE
+
+              BEGIN_LITOPX_CASE(JSOP_STRING)
+                rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
+                                   inXML ? 0 : (jschar)'"');
+                if (!rval)
+                    return JS_FALSE;
+                todo = STR2OFF(&ss->sprinter, rval);
+              END_LITOPX_CASE
+
+              case JSOP_OBJECT:
+              case JSOP_REGEXP:
+              case JSOP_ANONFUNOBJ:
+              case JSOP_NAMEDFUNOBJ:
+                atomIndex = GET_ATOM_INDEX(pc);
+
+              do_JSOP_OBJECT:
+              do_JSOP_REGEXP:
+              do_JSOP_ANONFUNOBJ:
+              do_JSOP_NAMEDFUNOBJ:
+                atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);
+                if (op == JSOP_OBJECT || op == JSOP_REGEXP) {
+                    if (!js_regexp_toString(cx, ATOM_TO_OBJECT(atom), 0, NULL,
+                                            &val)) {
+                        return JS_FALSE;
+                    }
+                } else {
+                    if (!js_fun_toString(cx, ATOM_TO_OBJECT(atom),
+                                         (pc + len < endpc &&
+                                          pc[len] == JSOP_GROUP)
+                                         ? JS_IN_GROUP_CONTEXT |
+                                           JS_DONT_PRETTY_PRINT
+                                         : JS_DONT_PRETTY_PRINT,
+                                         0, NULL, &val)) {
+                        return JS_FALSE;
+                    }
+                }
+                str = JSVAL_TO_STRING(val);
+                todo = SprintPut(&ss->sprinter, JS_GetStringBytes(str),
+                                 JSSTRING_LENGTH(str));
+                break;
+
+#if JS_HAS_SWITCH_STATEMENT
+              case JSOP_TABLESWITCH:
+              case JSOP_TABLESWITCHX:
+              {
+                jsbytecode *pc2;
+                ptrdiff_t jmplen, off, off2;
+                jsint j, n, low, high;
+                TableEntry *table, pivot;
+
+                sn = js_GetSrcNote(jp->script, pc);
+                JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
+                len = js_GetSrcNoteOffset(sn, 0);
+                jmplen = (op == JSOP_TABLESWITCH) ? JUMP_OFFSET_LEN
+                                                  : JUMPX_OFFSET_LEN;
+                pc2 = pc;
+                off = GetJumpOffset(pc, pc2);
+                pc2 += jmplen;
+                low = GET_JUMP_OFFSET(pc2);
+                pc2 += JUMP_OFFSET_LEN;
+                high = GET_JUMP_OFFSET(pc2);
+                pc2 += JUMP_OFFSET_LEN;
+
+                n = high - low + 1;
+                if (n == 0) {
+                    table = NULL;
+                    j = 0;
+                } else {
+                    table = (TableEntry *)
+                            JS_malloc(cx, (size_t)n * sizeof *table);
+                    if (!table)
+                        return JS_FALSE;
+                    for (i = j = 0; i < n; i++) {
+                        table[j].label = NULL;
+                        off2 = GetJumpOffset(pc, pc2);
+                        if (off2) {
+                            sn = js_GetSrcNote(jp->script, pc2);
+                            if (sn) {
+                                JS_ASSERT(SN_TYPE(sn) == SRC_LABEL);
+                                table[j].label =
+                                    js_GetAtom(cx, &jp->script->atomMap,
+                                               (jsatomid)
+                                               js_GetSrcNoteOffset(sn, 0));
+                            }
+                            table[j].key = INT_TO_JSVAL(low + i);
+                            table[j].offset = off2;
+                            table[j].order = j;
+                            j++;
+                        }
+                        pc2 += jmplen;
+                    }
+                    js_HeapSort(table, (size_t) j, &pivot, sizeof(TableEntry),
+                                CompareOffsets, NULL);
+                }
+
+                ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off,
+                                     JS_FALSE);
+                JS_free(cx, table);
+                if (!ok)
+                    return ok;
+                todo = -2;
+                break;
+              }
+
+              case JSOP_LOOKUPSWITCH:
+              case JSOP_LOOKUPSWITCHX:
+              {
+                jsbytecode *pc2;
+                ptrdiff_t jmplen, off, off2;
+                jsatomid npairs, k;
+                TableEntry *table;
+
+                sn = js_GetSrcNote(jp->script, pc);
+                JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
+                len = js_GetSrcNoteOffset(sn, 0);
+                jmplen = (op == JSOP_LOOKUPSWITCH) ? JUMP_OFFSET_LEN
+                                                   : JUMPX_OFFSET_LEN;
+                pc2 = pc;
+                off = GetJumpOffset(pc, pc2);
+                pc2 += jmplen;
+                npairs = GET_ATOM_INDEX(pc2);
+                pc2 += ATOM_INDEX_LEN;
+
+                table = (TableEntry *)
+                    JS_malloc(cx, (size_t)npairs * sizeof *table);
+                if (!table)
+                    return JS_FALSE;
+                for (k = 0; k < npairs; k++) {
+                    sn = js_GetSrcNote(jp->script, pc2);
+                    if (sn) {
+                        JS_ASSERT(SN_TYPE(sn) == SRC_LABEL);
+                        table[k].label =
+                            js_GetAtom(cx, &jp->script->atomMap, (jsatomid)
+                                       js_GetSrcNoteOffset(sn, 0));
+                    } else {
+                        table[k].label = NULL;
+                    }
+                    atom = GET_ATOM(cx, jp->script, pc2);
+                    pc2 += ATOM_INDEX_LEN;
+                    off2 = GetJumpOffset(pc, pc2);
+                    pc2 += jmplen;
+                    table[k].key = ATOM_KEY(atom);
+                    table[k].offset = off2;
+                }
+
+                ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off,
+                                     JS_FALSE);
+                JS_free(cx, table);
+                if (!ok)
+                    return ok;
+                todo = -2;
+                break;
+              }
+
+              case JSOP_CONDSWITCH:
+              {
+                jsbytecode *pc2;
+                ptrdiff_t off, off2, caseOff;
+                jsint ncases;
+                TableEntry *table;
+
+                sn = js_GetSrcNote(jp->script, pc);
+                JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
+                len = js_GetSrcNoteOffset(sn, 0);
+                off = js_GetSrcNoteOffset(sn, 1);
+
+                /*
+                 * Count the cases using offsets from switch to first case,
+                 * and case to case, stored in srcnote immediates.
+                 */
+                pc2 = pc;
+                off2 = off;
+                for (ncases = 0; off2 != 0; ncases++) {
+                    pc2 += off2;
+                    JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
+                              *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
+                    if (*pc2 == JSOP_DEFAULT || *pc2 == JSOP_DEFAULTX) {
+                        /* End of cases, but count default as a case. */
+                        off2 = 0;
+                    } else {
+                        sn = js_GetSrcNote(jp->script, pc2);
+                        JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
+                        off2 = js_GetSrcNoteOffset(sn, 0);
+                    }
+                }
+
+                /*
+                 * Allocate table and rescan the cases using their srcnotes,
+                 * stashing each case's delta from switch top in table[i].key,
+                 * and the distance to its statements in table[i].offset.
+                 */
+                table = (TableEntry *)
+                    JS_malloc(cx, (size_t)ncases * sizeof *table);
+                if (!table)
+                    return JS_FALSE;
+                pc2 = pc;
+                off2 = off;
+                for (i = 0; i < ncases; i++) {
+                    pc2 += off2;
+                    JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
+                              *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
+                    caseOff = pc2 - pc;
+                    table[i].key = INT_TO_JSVAL((jsint) caseOff);
+                    table[i].offset = caseOff + GetJumpOffset(pc2, pc2);
+                    if (*pc2 == JSOP_CASE || *pc2 == JSOP_CASEX) {
+                        sn = js_GetSrcNote(jp->script, pc2);
+                        JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
+                        off2 = js_GetSrcNoteOffset(sn, 0);
+                    }
+                }
+
+                /*
+                 * Find offset of default code by fetching the default offset
+                 * from the end of table.  JSOP_CONDSWITCH always has a default
+                 * case at the end.
+                 */
+                off = JSVAL_TO_INT(table[ncases-1].key);
+                pc2 = pc + off;
+                off += GetJumpOffset(pc2, pc2);
+
+                ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off,
+                                     JS_TRUE);
+                JS_free(cx, table);
+                if (!ok)
+                    return ok;
+                todo = -2;
+                break;
+              }
+
+              case JSOP_CASE:
+              case JSOP_CASEX:
+              {
+                lval = POP_STR();
+                if (!lval)
+                    return JS_FALSE;
+                js_printf(jp, "\tcase %s:\n", lval);
+                todo = -2;
+                break;
+              }
+
+#endif /* JS_HAS_SWITCH_STATEMENT */
+
+#if !JS_BUG_FALLIBLE_EQOPS
+              case JSOP_NEW_EQ:
+              case JSOP_NEW_NE:
+                rval = POP_STR();
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter, "%s %c%s %s",
+                              lval,
+                              (op == JSOP_NEW_EQ) ? '=' : '!',
+#if JS_HAS_TRIPLE_EQOPS
+                              JS_VERSION_IS_ECMA(cx) ? "==" :
+#endif
+                              "=",
+                              rval);
+                break;
+#endif
+
+#if JS_HAS_LEXICAL_CLOSURE
+              BEGIN_LITOPX_CASE(JSOP_CLOSURE)
+                JS_ASSERT(ATOM_IS_OBJECT(atom));
+                todo = -2;
+                goto do_function;
+              END_LITOPX_CASE
+#endif
+
+#if JS_HAS_EXPORT_IMPORT
+              case JSOP_EXPORTALL:
+                js_printf(jp, "\texport *\n");
+                todo = -2;
+                break;
+
+              BEGIN_LITOPX_CASE(JSOP_EXPORTNAME)
+                rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                if (!rval)
+                    return JS_FALSE;
+                RETRACT(&ss->sprinter, rval);
+                js_printf(jp, "\texport %s\n", rval);
+                todo = -2;
+              END_LITOPX_CASE
+
+              case JSOP_IMPORTALL:
+                lval = POP_STR();
+                js_printf(jp, "\timport %s.*\n", lval);
+                todo = -2;
+                break;
+
+              case JSOP_IMPORTPROP:
+              do_importprop:
+                GET_ATOM_QUOTE_AND_FMT("\timport %s[%s]\n", "\timport %s.%s\n",
+                                       rval);
+                lval = POP_STR();
+                js_printf(jp, fmt, lval, rval);
+                todo = -2;
+                break;
+
+              case JSOP_IMPORTELEM:
+                xval = POP_STR();
+                op = JSOP_GETELEM;
+                if (js_CodeSpec[lastop].format & JOF_XMLNAME)
+                    goto do_importprop;
+                lval = POP_STR();
+                js_printf(jp, "\timport %s[%s]\n", lval, xval);
+                todo = -2;
+                break;
+#endif /* JS_HAS_EXPORT_IMPORT */
+
+              case JSOP_TRAP:
+                op = JS_GetTrapOpcode(cx, jp->script, pc);
+                if (op == JSOP_LIMIT)
+                    return JS_FALSE;
+                *pc = op;
+                cs = &js_CodeSpec[op];
+                len = cs->length;
+                DECOMPILE_CODE(pc, len);
+                *pc = JSOP_TRAP;
+                todo = -2;
+                break;
+
+#if JS_HAS_INITIALIZERS
+              case JSOP_NEWINIT:
+                LOCAL_ASSERT(ss->top >= 2);
+                (void) PopOff(ss, op);
+                lval = POP_STR();
+#if JS_HAS_SHARP_VARS
+                op = (JSOp)pc[len];
+                if (op == JSOP_DEFSHARP) {
+                    pc += len;
+                    cs = &js_CodeSpec[op];
+                    len = cs->length;
+                    i = (jsint) GET_ATOM_INDEX(pc);
+                    todo = Sprint(&ss->sprinter, "#%u=%c",
+                                  (unsigned) i,
+                                  (*lval == 'O') ? '{' : '[');
+                } else
+#endif /* JS_HAS_SHARP_VARS */
+                {
+                    todo = Sprint(&ss->sprinter, (*lval == 'O') ? "{" : "[");
+                }
+                break;
+
+              case JSOP_ENDINIT:
+                rval = POP_STR();
+                sn = js_GetSrcNote(jp->script, pc);
+                todo = Sprint(&ss->sprinter, "%s%s%c",
+                              rval,
+                              (sn && SN_TYPE(sn) == SRC_CONTINUE) ? ", " : "",
+                              (*rval == '{') ? '}' : ']');
+                break;
+
+              case JSOP_INITPROP:
+                atom = GET_ATOM(cx, jp->script, pc);
+                xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
+                                   (jschar)
+                                   (ATOM_IS_IDENTIFIER(atom) ? 0 : '\''));
+                if (!xval)
+                    return JS_FALSE;
+                rval = POP_STR();
+                lval = POP_STR();
+              do_initprop:
+#ifdef OLD_GETTER_SETTER
+                todo = Sprint(&ss->sprinter, "%s%s%s%s%s:%s",
+                              lval,
+                              (lval[1] != '\0') ? ", " : "",
+                              xval,
+                              (lastop == JSOP_GETTER || lastop == JSOP_SETTER)
+                              ? " " : "",
+                              (lastop == JSOP_GETTER) ? js_getter_str :
+                              (lastop == JSOP_SETTER) ? js_setter_str :
+                              "",
+                              rval);
+#else
+                if (lastop == JSOP_GETTER || lastop == JSOP_SETTER) {
+                    rval += strlen(js_function_str) + 1;
+                    todo = Sprint(&ss->sprinter, "%s%s%s %s%.*s",
+                                  lval,
+                                  (lval[1] != '\0') ? ", " : "",
+                                  (lastop == JSOP_GETTER)
+                                  ? js_get_str : js_set_str,
+                                  xval,
+                                  strlen(rval) - 1,
+                                  rval);
+                } else {
+                    todo = Sprint(&ss->sprinter, "%s%s%s:%s",
+                                  lval,
+                                  (lval[1] != '\0') ? ", " : "",
+                                  xval,
+                                  rval);
+                }
+#endif
+                break;
+
+              case JSOP_INITELEM:
+                rval = POP_STR();
+                xval = POP_STR();
+                lval = POP_STR();
+                sn = js_GetSrcNote(jp->script, pc);
+                if (sn && SN_TYPE(sn) == SRC_LABEL)
+                    goto do_initprop;
+                todo = Sprint(&ss->sprinter, "%s%s%s",
+                              lval,
+                              (lval[1] != '\0' || *xval != '0') ? ", " : "",
+                              rval);
+                break;
+
+#if JS_HAS_SHARP_VARS
+              case JSOP_DEFSHARP:
+                i = (jsint) GET_ATOM_INDEX(pc);
+                rval = POP_STR();
+                todo = Sprint(&ss->sprinter, "#%u=%s", (unsigned) i, rval);
+                break;
+
+              case JSOP_USESHARP:
+                i = (jsint) GET_ATOM_INDEX(pc);
+                todo = Sprint(&ss->sprinter, "#%u#", (unsigned) i);
+                break;
+#endif /* JS_HAS_SHARP_VARS */
+#endif /* JS_HAS_INITIALIZERS */
+
+#if JS_HAS_DEBUGGER_KEYWORD
+              case JSOP_DEBUGGER:
+                js_printf(jp, "\tdebugger;\n");
+                todo = -2;
+                break;
+#endif /* JS_HAS_DEBUGGER_KEYWORD */
+
+#if JS_HAS_XML_SUPPORT
+              case JSOP_STARTXML:
+              case JSOP_STARTXMLEXPR:
+                inXML = op == JSOP_STARTXML; 
+                todo = -2;
+                break;
+
+              case JSOP_DEFXMLNS:
+                rval = POP_STR();
+                js_printf(jp, "\t%s %s %s %s;\n",
+                          js_default_str, js_xml_str, js_namespace_str, rval);
+                todo = -2;
+                break;
+
+              case JSOP_ANYNAME:
+                todo = SprintPut(&ss->sprinter, "*", 1);
+                break;
+
+              BEGIN_LITOPX_CASE(JSOP_QNAMEPART)
+                goto do_name;
+              END_LITOPX_CASE
+
+              BEGIN_LITOPX_CASE(JSOP_QNAMECONST)
+                rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
+                if (!rval)
+                    return JS_FALSE;
+                RETRACT(&ss->sprinter, rval);
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter, "%s::%s", lval, rval);
+              END_LITOPX_CASE
+
+              case JSOP_QNAME:
+                rval = POP_STR();
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter, "%s::[%s]", lval, rval);
+                break;
+
+              case JSOP_TOATTRNAME:
+                rval = POP_STR();
+                todo = Sprint(&ss->sprinter, "@%s", rval);
+                break;
+
+              case JSOP_TOATTRVAL:
+                todo = -2;
+                break;
+
+              case JSOP_ADDATTRNAME:
+                rval = POP_STR();
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter, "%s %s", lval, rval);
+                /* This gets reset by all XML tag expressions. */
+                quoteAttr = JS_TRUE;
+                break;
+
+              case JSOP_ADDATTRVAL:
+                rval = POP_STR();
+                lval = POP_STR();
+                if (quoteAttr)
+                    todo = Sprint(&ss->sprinter, "%s=\"%s\"", lval, rval);
+                else
+                    todo = Sprint(&ss->sprinter, "%s=%s", lval, rval);
+                break;
+
+              case JSOP_BINDXMLNAME:
+                /* Leave the name stacked and push a dummy string. */
+                todo = Sprint(&ss->sprinter, "");
+                break;
+
+              case JSOP_SETXMLNAME:
+                /* Pop the r.h.s., the dummy string, and the name. */
+                rval = POP_STR();
+                (void) PopOff(ss, op);
+                lval = POP_STR();
+                goto do_setlval;
+
+              case JSOP_XMLELTEXPR:
+              case JSOP_XMLTAGEXPR:
+                todo = Sprint(&ss->sprinter, "{%s}", POP_STR());
+                inXML = JS_TRUE; 
+                /* If we're an attribute value, we shouldn't quote this. */
+                quoteAttr = JS_FALSE;
+                break;
+
+              case JSOP_TOXMLLIST:
+                todo = Sprint(&ss->sprinter, "<>%s</>", POP_STR());
+                inXML = JS_FALSE;
+                break;
+
+              case JSOP_FOREACH:
+                foreach = JS_TRUE;
+                todo = -2;
+                break;
+
+              case JSOP_TOXML:
+                inXML = JS_FALSE;
+                /* FALL THROUGH */
+
+              case JSOP_XMLNAME:
+              case JSOP_FILTER:
+                /* Conversion and prefix ops do nothing in the decompiler. */
+                todo = -2;
+                break;
+
+              case JSOP_ENDFILTER:
+                rval = POP_STR();
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter, "%s.(%s)", lval, rval);
+                break;
+
+              case JSOP_DESCENDANTS:
+                rval = POP_STR();
+                lval = POP_STR();
+                todo = Sprint(&ss->sprinter, "%s..%s", lval, rval);
+                break;
+
+              BEGIN_LITOPX_CASE(JSOP_XMLOBJECT)
+                atom = GET_ATOM(cx, jp->script, pc);
+                todo = Sprint(&ss->sprinter, "<xml address='%p'>",
+                              ATOM_TO_OBJECT(atom));
+              END_LITOPX_CASE
+
+              BEGIN_LITOPX_CASE(JSOP_XMLCDATA)
+                todo = SprintPut(&ss->sprinter, "<![CDATA[", 9);
+                if (!QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0))
+                    return JS_FALSE;
+                SprintPut(&ss->sprinter, "]]>", 3);
+              END_LITOPX_CASE
+
+              BEGIN_LITOPX_CASE(JSOP_XMLCOMMENT)
+                todo = SprintPut(&ss->sprinter, "<!--", 4);
+                if (!QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0))
+                    return JS_FALSE;
+                SprintPut(&ss->sprinter, "-->", 3);
+              END_LITOPX_CASE
+
+              BEGIN_LITOPX_CASE(JSOP_XMLPI)
+                rval = JS_strdup(cx, POP_STR());
+                if (!rval)
+                    return JS_FALSE;
+                todo = SprintPut(&ss->sprinter, "<?", 2);
+                ok = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0) &&
+                     SprintPut(&ss->sprinter, " ", 1) >= 0 &&
+                     SprintPut(&ss->sprinter, rval, strlen(rval));
+                JS_free(cx, (char *)rval);
+                if (!ok)
+                    return JS_FALSE;
+                SprintPut(&ss->sprinter, "?>", 2);
+              END_LITOPX_CASE
+
+              case JSOP_GETFUNNS:
+                todo = SprintPut(&ss->sprinter, js_function_str, 8);
+                break;
+#endif /* JS_HAS_XML_SUPPORT */
+
+              default:
+                todo = -2;
+                break;
+
+#undef BEGIN_LITOPX_CASE
+#undef END_LITOPX_CASE
+            }
+        }
+
+        if (todo < 0) {
+            /* -2 means "don't push", -1 means reported error. */
+            if (todo == -1)
+                return JS_FALSE;
+        } else {
+            if (!PushOff(ss, todo, op))
+                return JS_FALSE;
+        }
+        pc += len;
+    }
+
+/*
+ * Undefine local macros.
+ */
+#undef inXML
+#undef DECOMPILE_CODE
+#undef POP_STR
+#undef LOCAL_ASSERT
+#undef ATOM_IS_IDENTIFIER
+#undef GET_QUOTE_AND_FMT
+#undef GET_ATOM_QUOTE_AND_FMT
+
+    return JS_TRUE;
+}
+
+
+JSBool
+js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len)
+{
+    SprintStack ss;
+    JSContext *cx;
+    void *mark, *space;
+    size_t offsetsz, opcodesz;
+    JSBool ok;
+    JSScript *oldscript;
+    char *last;
+
+    /* Initialize a sprinter for use with the offset stack. */
+    ss.printer = jp;
+    cx = jp->sprinter.context;
+    mark = JS_ARENA_MARK(&cx->tempPool);
+    INIT_SPRINTER(cx, &ss.sprinter, &cx->tempPool, PAREN_SLOP);
+
+    /* Allocate the parallel (to avoid padding) offset and opcode stacks. */
+    offsetsz = script->depth * sizeof(ptrdiff_t);
+    opcodesz = script->depth * sizeof(jsbytecode);
+    JS_ARENA_ALLOCATE(space, &cx->tempPool, offsetsz + opcodesz);
+    if (!space) {
+        ok = JS_FALSE;
+        goto out;
+    }
+    ss.offsets = (ptrdiff_t *) space;
+    ss.opcodes = (jsbytecode *) ((char *)space + offsetsz);
+    ss.top = 0;
+
+    /* Call recursive subroutine to do the hard work. */
+    oldscript = jp->script;
+    jp->script = script;
+    ok = Decompile(&ss, pc, len);
+    jp->script = oldscript;
+
+    /* If the given code didn't empty the stack, do it now. */
+    if (ss.top) {
+        do {
+            last = OFF2STR(&ss.sprinter, PopOff(&ss, JSOP_NOP));
+        } while (ss.top);
+        js_printf(jp, "%s", last);
+    }
+
+out:
+    /* Free all temporary stuff allocated under this call. */
+    JS_ARENA_RELEASE(&cx->tempPool, mark);
+    return ok;
+}
+
+JSBool
+js_DecompileScript(JSPrinter *jp, JSScript *script)
+{
+    return js_DecompileCode(jp, script, script->code, (uintN)script->length);
+}
+
+static const char native_code_str[] = "\t[native code]\n";
+
+JSBool
+js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun)
+{
+    JSScript *script;
+    JSScope *scope, *save;
+    JSBool ok;
+
+    if (!fun->interpreted) {
+        js_printf(jp, native_code_str);
+        return JS_TRUE;
+    }
+    script = fun->u.script;
+    scope = fun->object ? OBJ_SCOPE(fun->object) : NULL;
+    save = jp->scope;
+    jp->scope = scope;
+    ok = js_DecompileCode(jp, script, script->code, (uintN)script->length);
+    jp->scope = save;
+    return ok;
+}
+
+JSBool
+js_DecompileFunction(JSPrinter *jp, JSFunction *fun)
+{
+    JSContext *cx;
+    uintN i, nargs, indent;
+    void *mark;
+    JSAtom **params;
+    JSScope *scope, *oldscope;
+    JSScopeProperty *sprop;
+    JSBool ok;
+
+    /*
+     * If pretty, conform to ECMA-262 Edition 3, 15.3.4.2, by decompiling a
+     * FunctionDeclaration.  Otherwise, check the JSFUN_LAMBDA flag and force
+     * an expression by parenthesizing.
+     */
+    if (jp->pretty) {
+        js_printf(jp, "\t");
+    } else {
+        if (!jp->grouped && (fun->flags & JSFUN_LAMBDA))
+            js_puts(jp, "(");
+    }
+    if (fun->flags & JSFUN_GETTER)
+        js_printf(jp, "%s ", js_getter_str);
+    else if (fun->flags & JSFUN_SETTER)
+        js_printf(jp, "%s ", js_setter_str);
+
+    js_printf(jp, "%s ", js_function_str);
+    if (fun->atom && !QuoteString(&jp->sprinter, ATOM_TO_STRING(fun->atom), 0))
+        return JS_FALSE;
+    js_puts(jp, "(");
+
+    if (fun->interpreted && fun->object) {
+        /*
+         * Print the parameters.
+         *
+         * This code is complicated by the need to handle duplicate parameter
+         * names, as required by ECMA (bah!).  A duplicate parameter is stored
+         * as another node with the same id (the parameter name) but different
+         * shortid (the argument index) along the property tree ancestor line
+         * starting at SCOPE_LAST_PROP(scope).  Only the last duplicate param
+         * is mapped by the scope's hash table.
+         */
+        cx = jp->sprinter.context;
+        nargs = fun->nargs;
+        mark = JS_ARENA_MARK(&cx->tempPool);
+        JS_ARENA_ALLOCATE_CAST(params, JSAtom **, &cx->tempPool,
+                               nargs * sizeof(JSAtom *));
+        if (!params) {
+            JS_ReportOutOfMemory(cx);
+            return JS_FALSE;
+        }
+        scope = OBJ_SCOPE(fun->object);
+        for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {
+            if (sprop->getter != js_GetArgument)
+                continue;
+            JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);
+            JS_ASSERT((uint16) sprop->shortid < nargs);
+            JS_ASSERT(JSID_IS_ATOM(sprop->id));
+            params[(uint16) sprop->shortid] = JSID_TO_ATOM(sprop->id);
+        }
+        for (i = 0; i < nargs; i++) {
+            if (i > 0)
+                js_puts(jp, ", ");
+            if (!QuoteString(&jp->sprinter, ATOM_TO_STRING(params[i]), 0))
+                return JS_FALSE;
+        }
+        JS_ARENA_RELEASE(&cx->tempPool, mark);
+#ifdef __GNUC__
+    } else {
+        scope = NULL;
+#endif
+    }
+
+    js_printf(jp, ") {\n");
+    indent = jp->indent;
+    jp->indent += 4;
+    if (fun->interpreted && fun->object) {
+        oldscope = jp->scope;
+        jp->scope = scope;
+        ok = js_DecompileScript(jp, fun->u.script);
+        jp->scope = oldscope;
+        if (!ok) {
+            jp->indent = indent;
+            return JS_FALSE;
+        }
+    } else {
+        js_printf(jp, native_code_str);
+    }
+    jp->indent -= 4;
+    js_printf(jp, "\t}");
+
+    if (!jp->pretty) {
+        if (!jp->grouped && (fun->flags & JSFUN_LAMBDA))
+            js_puts(jp, ")");
+    }
+    return JS_TRUE;
+}
+
+JSString *
+js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
+                           JSString *fallback)
+{
+    JSStackFrame *fp, *down;
+    jsbytecode *pc, *begin, *end, *tmp;
+    jsval *sp, *base, *limit;
+    JSScript *script;
+    JSOp op;
+    const JSCodeSpec *cs;
+    uint32 format, mode, type;
+    intN depth;
+    jssrcnote *sn;
+    uintN len, off;
+    JSPrinter *jp;
+    JSString *name;
+
+    for (fp = cx->fp; fp && !fp->script; fp = fp->down)
+        continue;
+    if (!fp)
+        goto do_fallback;
+
+    /* Try to find sp's generating pc depth slots under it on the stack. */
+    pc = fp->pc;
+    if (spindex == JSDVG_SEARCH_STACK) {
+        if (!pc) {
+            /*
+             * Current frame is native: look under it for a scripted call
+             * in which a decompilable bytecode string that generated the
+             * value as an actual argument might exist.
+             */
+            JS_ASSERT(!fp->script && !(fp->fun && fp->fun->interpreted));
+            down = fp->down;
+            if (!down)
+                goto do_fallback;
+            script = down->script;
+            base = fp->argv;
+            limit = base + fp->argc;
+        } else {
+            /*
+             * This should be a script activation, either a top-level
+             * script or a scripted function.  But be paranoid about calls
+             * to js_DecompileValueGenerator from code that hasn't fully
+             * initialized a (default-all-zeroes) frame.
+             */
+            script = fp->script;
+            base = fp->spbase;
+            limit = fp->sp;
+        }
+
+        /*
+         * Pure paranoia about default-zeroed frames being active while
+         * js_DecompileValueGenerator is called.  It can't hurt much now;
+         * error reporting performance is not an issue.
+         */
+        if (!script || !base || !limit)
+            goto do_fallback;
+
+        /*
+         * Try to find operand-generating pc depth slots below sp.
+         *
+         * In the native case, we know the arguments have generating pc's
+         * under them, on account of fp->down->script being non-null: all
+         * compiled scripts get depth slots for generating pc's allocated
+         * upon activation, at the top of js_Interpret.
+         *
+         * In the script or scripted function case, the same reasoning
+         * applies to fp rather than to fp->down.
+         */
+        for (sp = base; sp < limit; sp++) {
+            if (*sp == v) {
+                depth = (intN)script->depth;
+                pc = (jsbytecode *) sp[-depth];
+                break;
+            }
+        }
+    } else {
+        /*
+         * At this point, pc may or may not be null, i.e., we could be in
+         * a script activation, or we could be in a native frame that was
+         * called by another native function.  Check pc and script.
+         */
+        if (!pc)
+            goto do_fallback;
+        script = fp->script;
+        if (!script)
+            goto do_fallback;
+
+        if (spindex != JSDVG_IGNORE_STACK) {
+            JS_ASSERT(spindex < 0);
+            depth = (intN)script->depth;
+#if !JS_HAS_NO_SUCH_METHOD
+            JS_ASSERT(-depth <= spindex);
+#endif
+            spindex -= depth;
+
+            base = (jsval *) cx->stackPool.current->base;
+            limit = (jsval *) cx->stackPool.current->avail;
+            sp = fp->sp + spindex;
+            if (JS_UPTRDIFF(sp, base) < JS_UPTRDIFF(limit, base))
+                pc = (jsbytecode *) *sp;
+        }
+    }
+
+    /*
+     * Again, be paranoid, this time about possibly loading an invalid pc
+     * from sp[-(1+depth)].
+     */
+    if (JS_UPTRDIFF(pc, script->code) >= (jsuword)script->length) {
+        pc = fp->pc;
+        if (!pc)
+            goto do_fallback;
+    }
+    op = (JSOp) *pc;
+    if (op == JSOP_TRAP)
+        op = JS_GetTrapOpcode(cx, script, pc);
+
+    /* XXX handle null as a special case, to avoid calling null "object" */
+    if (op == JSOP_NULL)
+        return ATOM_TO_STRING(cx->runtime->atomState.nullAtom);
+
+    cs = &js_CodeSpec[op];
+    format = cs->format;
+    mode = (format & JOF_MODEMASK);
+
+    /* NAME ops are self-contained, but others require left context. */
+    if (mode == JOF_NAME) {
+        begin = pc;
+    } else {
+        sn = js_GetSrcNote(script, pc);
+        if (!sn || (SN_TYPE(sn) != SRC_PCBASE && SN_TYPE(sn) != SRC_PCDELTA)) {
+            if (cs->token)
+                return JS_NewStringCopyZ(cx, cs->token);
+            goto do_fallback;
+        }
+        begin = pc - js_GetSrcNoteOffset(sn, 0);
+    }
+    end = pc + cs->length;
+    len = PTRDIFF(end, begin, jsbytecode);
+
+    if (format & (JOF_SET | JOF_DEL | JOF_INCDEC | JOF_IMPORT | JOF_FOR)) {
+        tmp = (jsbytecode *) JS_malloc(cx, len * sizeof(jsbytecode));
+        if (!tmp)
+            return NULL;
+        memcpy(tmp, begin, len * sizeof(jsbytecode));
+        if (mode == JOF_NAME) {
+            /*
+             * JOF_NAME does not imply JOF_CONST, so we must check for the
+             * QARG and QVAR format types and translate those to JSOP_GETARG
+             * or JSOP_GETVAR appropriately, instead of JSOP_NAME.
+             */
+            type = format & JOF_TYPEMASK;
+            tmp[0] = (type == JOF_QARG)
+                     ? JSOP_GETARG
+                     : (type == JOF_QVAR)
+                     ? JSOP_GETVAR
+                     : JSOP_NAME;
+        } else {
+            /*
+             * We must replace the faulting pc's bytecode with a corresponding
+             * JSOP_GET* code.  For JSOP_SET{PROP,ELEM}, we must use the "2nd"
+             * form of JSOP_GET{PROP,ELEM}, to throw away the assignment op's
+             * right-hand operand and decompile it as if it were a GET of its
+             * left-hand operand.
+             */
+            off = len - cs->length;
+            JS_ASSERT(off == (uintN) PTRDIFF(pc, begin, jsbytecode));
+            if (mode == JOF_PROP) {
+                tmp[off] = (format & JOF_SET) ? JSOP_GETPROP2 : JSOP_GETPROP;
+            } else if (mode == JOF_ELEM) {
+                tmp[off] = (format & JOF_SET) ? JSOP_GETELEM2 : JSOP_GETELEM;
+            } else {
+                /*
+                 * A zero mode means precisely that op is uncategorized for our
+                 * purposes, so we must write per-op special case code here.
+                 */
+                switch (op) {
+                  case JSOP_ENUMELEM:
+                    tmp[off] = JSOP_GETELEM;
+                    break;
+#if JS_HAS_LVALUE_RETURN
+                  case JSOP_SETCALL:
+                    tmp[off] = JSOP_CALL;
+                    break;
+#endif
+                  default:
+                    JS_ASSERT(0);
+                }
+            }
+        }
+        begin = tmp;
+    } else {
+        /* No need to revise script bytecode. */
+        tmp = NULL;
+    }
+
+    name = NULL;
+    jp = js_NewPrinter(cx, "js_DecompileValueGenerator", 0, JS_FALSE);
+    if (jp) {
+       if (fp->fun && fp->fun->object) {
+           JS_ASSERT(OBJ_IS_NATIVE(fp->fun->object));
+           jp->scope = OBJ_SCOPE(fp->fun->object);
+        }
+        if (js_DecompileCode(jp, script, begin, len))
+            name = js_GetPrinterOutput(jp);
+        js_DestroyPrinter(jp);
+    }
+    if (tmp)
+        JS_free(cx, tmp);
+    return name;
+
+  do_fallback:
+    return fallback ? fallback : js_ValueToString(cx, v);
+}

Added: freeswitch/trunk/libs/js/src/jsopcode.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsopcode.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,301 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsopcode_h___
+#define jsopcode_h___
+/*
+ * JS bytecode definitions.
+ */
+#include <stddef.h>
+#include "jsprvtd.h"
+#include "jspubtd.h"
+
+JS_BEGIN_EXTERN_C
+
+/*
+ * JS operation bytecodes.
+ */
+typedef enum JSOp {
+#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \
+    op = val,
+#include "jsopcode.tbl"
+#undef OPDEF
+    JSOP_LIMIT
+} JSOp;
+
+/*
+ * JS bytecode formats.
+ */
+#define JOF_BYTE          0       /* single bytecode, no immediates */
+#define JOF_JUMP          1       /* signed 16-bit jump offset immediate */
+#define JOF_CONST         2       /* unsigned 16-bit constant pool index */
+#define JOF_UINT16        3       /* unsigned 16-bit immediate operand */
+#define JOF_TABLESWITCH   4       /* table switch */
+#define JOF_LOOKUPSWITCH  5       /* lookup switch */
+#define JOF_QARG          6       /* quickened get/set function argument ops */
+#define JOF_QVAR          7       /* quickened get/set local variable ops */
+#define JOF_INDEXCONST    8       /* arg or var index + constant pool index */
+#define JOF_JUMPX         9       /* signed 32-bit jump offset immediate */
+#define JOF_TABLESWITCHX  10      /* extended (32-bit offset) table switch */
+#define JOF_LOOKUPSWITCHX 11      /* extended (32-bit offset) lookup switch */
+#define JOF_UINT24        12      /* extended unsigned 24-bit literal (index) */
+#define JOF_LITOPX        13      /* JOF_UINT24 followed by op being extended,
+                                     where op if JOF_CONST has no unsigned 16-
+                                     bit immediate operand */
+#define JOF_TYPEMASK      0x000f  /* mask for above immediate types */
+#define JOF_NAME          0x0010  /* name operation */
+#define JOF_PROP          0x0020  /* obj.prop operation */
+#define JOF_ELEM          0x0030  /* obj[index] operation */
+#define JOF_MODEMASK      0x0030  /* mask for above addressing modes */
+#define JOF_SET           0x0040  /* set (i.e., assignment) operation */
+#define JOF_DEL           0x0080  /* delete operation */
+#define JOF_DEC           0x0100  /* decrement (--, not ++) opcode */
+#define JOF_INC           0x0200  /* increment (++, not --) opcode */
+#define JOF_INCDEC        0x0300  /* increment or decrement opcode */
+#define JOF_POST          0x0400  /* postorder increment or decrement */
+#define JOF_IMPORT        0x0800  /* import property op */
+#define JOF_FOR           0x1000  /* for-in property op */
+#define JOF_ASSIGNING     JOF_SET /* hint for JSClass.resolve, used for ops
+                                     that do simplex assignment */
+#define JOF_DETECTING     0x2000  /* object detection flag for JSNewResolveOp */
+#define JOF_BACKPATCH     0x4000  /* backpatch placeholder during codegen */
+#define JOF_LEFTASSOC     0x8000  /* left-associative operator */
+#define JOF_DECLARING    0x10000  /* var, const, or function declaration op */
+#define JOF_XMLNAME      0x20000  /* XML name: *, a::b, @a, @a::b, etc. */
+
+#define JOF_TYPE_IS_EXTENDED_JUMP(t) \
+    ((unsigned)((t) - JOF_JUMPX) <= (unsigned)(JOF_LOOKUPSWITCHX - JOF_JUMPX))
+
+/*
+ * Immediate operand getters, setters, and bounds.
+ */
+
+/* Short (2-byte signed offset) relative jump macros. */
+#define JUMP_OFFSET_LEN         2
+#define JUMP_OFFSET_HI(off)     ((jsbytecode)((off) >> 8))
+#define JUMP_OFFSET_LO(off)     ((jsbytecode)(off))
+#define GET_JUMP_OFFSET(pc)     ((int16)(((pc)[1] << 8) | (pc)[2]))
+#define SET_JUMP_OFFSET(pc,off) ((pc)[1] = JUMP_OFFSET_HI(off),               \
+                                 (pc)[2] = JUMP_OFFSET_LO(off))
+#define JUMP_OFFSET_MIN         ((int16)0x8000)
+#define JUMP_OFFSET_MAX         ((int16)0x7fff)
+
+/*
+ * When a short jump won't hold a relative offset, its 2-byte immediate offset
+ * operand is an unsigned index of a span-dependency record, maintained until
+ * code generation finishes -- after which some (but we hope not nearly all)
+ * span-dependent jumps must be extended (see OptimizeSpanDeps in jsemit.c).
+ *
+ * If the span-dependency record index overflows SPANDEP_INDEX_MAX, the jump
+ * offset will contain SPANDEP_INDEX_HUGE, indicating that the record must be
+ * found (via binary search) by its "before span-dependency optimization" pc
+ * offset (from script main entry point).
+ */
+#define GET_SPANDEP_INDEX(pc)   ((uint16)(((pc)[1] << 8) | (pc)[2]))
+#define SET_SPANDEP_INDEX(pc,i) ((pc)[1] = JUMP_OFFSET_HI(i),                 \
+                                 (pc)[2] = JUMP_OFFSET_LO(i))
+#define SPANDEP_INDEX_MAX       ((uint16)0xfffe)
+#define SPANDEP_INDEX_HUGE      ((uint16)0xffff)
+
+/* Ultimately, if short jumps won't do, emit long (4-byte signed) offsets. */
+#define JUMPX_OFFSET_LEN        4
+#define JUMPX_OFFSET_B3(off)    ((jsbytecode)((off) >> 24))
+#define JUMPX_OFFSET_B2(off)    ((jsbytecode)((off) >> 16))
+#define JUMPX_OFFSET_B1(off)    ((jsbytecode)((off) >> 8))
+#define JUMPX_OFFSET_B0(off)    ((jsbytecode)(off))
+#define GET_JUMPX_OFFSET(pc)    ((int32)(((pc)[1] << 24) | ((pc)[2] << 16)    \
+                                         | ((pc)[3] << 8) | (pc)[4]))
+#define SET_JUMPX_OFFSET(pc,off)((pc)[1] = JUMPX_OFFSET_B3(off),              \
+                                 (pc)[2] = JUMPX_OFFSET_B2(off),              \
+                                 (pc)[3] = JUMPX_OFFSET_B1(off),              \
+                                 (pc)[4] = JUMPX_OFFSET_B0(off))
+#define JUMPX_OFFSET_MIN        ((int32)0x80000000)
+#define JUMPX_OFFSET_MAX        ((int32)0x7fffffff)
+
+/*
+ * A literal is indexed by a per-script atom map.  Most scripts have relatively
+ * few literals, so the standard JOF_CONST format specifies a fixed 16 bits of
+ * immediate operand index.  A script with more than 64K literals must push all
+ * high-indexed literals on the stack using JSOP_LITERAL, then use JOF_ELEM ops
+ * instead of JOF_PROP, etc.
+ */
+#define ATOM_INDEX_LEN          2
+#define ATOM_INDEX_HI(i)        ((jsbytecode)((i) >> 8))
+#define ATOM_INDEX_LO(i)        ((jsbytecode)(i))
+#define GET_ATOM_INDEX(pc)      ((jsatomid)(((pc)[1] << 8) | (pc)[2]))
+#define SET_ATOM_INDEX(pc,i)    ((pc)[1] = ATOM_INDEX_HI(i),                  \
+                                 (pc)[2] = ATOM_INDEX_LO(i))
+#define GET_ATOM(cx,script,pc)  js_GetAtom((cx), &(script)->atomMap,          \
+                                           GET_ATOM_INDEX(pc))
+
+/* A full atom index for JSOP_LITERAL uses 24 bits of immediate operand. */
+#define LITERAL_INDEX_LEN       3
+#define LITERAL_INDEX_HI(i)     ((jsbytecode)((i) >> 16))
+#define LITERAL_INDEX_MID(i)    ((jsbytecode)((i) >> 8))
+#define LITERAL_INDEX_LO(i)     ((jsbytecode)(i))
+#define GET_LITERAL_INDEX(pc)   ((jsatomid)(((pc)[1] << 16) |                 \
+                                            ((pc)[2] << 8) |                  \
+                                            (pc)[3]))
+#define SET_LITERAL_INDEX(pc,i) ((pc)[1] = LITERAL_INDEX_HI(i),               \
+                                 (pc)[2] = LITERAL_INDEX_MID(i),              \
+                                 (pc)[3] = LITERAL_INDEX_LO(i))
+
+/* Atom index limit is determined by SN_3BYTE_OFFSET_FLAG, see jsemit.h. */
+#define ATOM_INDEX_LIMIT_LOG2   23
+#define ATOM_INDEX_LIMIT        ((uint32)1 << ATOM_INDEX_LIMIT_LOG2)
+
+/* Actual argument count operand format helpers. */
+#define ARGC_HI(argc)           ((jsbytecode)((argc) >> 8))
+#define ARGC_LO(argc)           ((jsbytecode)(argc))
+#define GET_ARGC(pc)            ((uintN)(((pc)[1] << 8) | (pc)[2]))
+#define ARGC_LIMIT              ((uint32)1 << 16)
+
+/* Synonyms for quick JOF_QARG and JOF_QVAR bytecodes. */
+#define GET_ARGNO(pc)           GET_ARGC(pc)
+#define SET_ARGNO(pc,argno)     SET_JUMP_OFFSET(pc,argno)
+#define ARGNO_LEN               JUMP_OFFSET_LEN
+#define GET_VARNO(pc)           GET_ARGC(pc)
+#define SET_VARNO(pc,varno)     SET_JUMP_OFFSET(pc,varno)
+#define VARNO_LEN               JUMP_OFFSET_LEN
+
+struct JSCodeSpec {
+    const char          *name;          /* JS bytecode name */
+    const char          *token;         /* JS source literal or null */
+    int8                length;         /* length including opcode byte */
+    int8                nuses;          /* arity, -1 if variadic */
+    int8                ndefs;          /* number of stack results */
+    uint8               prec;           /* operator precedence */
+    uint32              format;         /* immediate operand format */
+};
+
+extern const char       js_const_str[];
+extern const char       js_var_str[];
+extern const char       js_function_str[];
+extern const char       js_in_str[];
+extern const char       js_instanceof_str[];
+extern const char       js_new_str[];
+extern const char       js_delete_str[];
+extern const char       js_typeof_str[];
+extern const char       js_void_str[];
+extern const char       js_null_str[];
+extern const char       js_this_str[];
+extern const char       js_false_str[];
+extern const char       js_true_str[];
+extern const char       js_default_str[];
+extern const JSCodeSpec js_CodeSpec[];
+extern uintN            js_NumCodeSpecs;
+extern const jschar     js_EscapeMap[];
+
+/*
+ * Return a GC'ed string containing the chars in str, with any non-printing
+ * chars or quotes (' or " as specified by the quote argument) escaped, and
+ * with the quote character at the beginning and end of the result string.
+ */
+extern JSString *
+js_QuoteString(JSContext *cx, JSString *str, jschar quote);
+
+/*
+ * JSPrinter operations, for printf style message formatting.  The return
+ * value from js_GetPrinterOutput() is the printer's cumulative output, in
+ * a GC'ed string.
+ */
+extern JSPrinter *
+js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty);
+
+extern void
+js_DestroyPrinter(JSPrinter *jp);
+
+extern JSString *
+js_GetPrinterOutput(JSPrinter *jp);
+
+extern int
+js_printf(JSPrinter *jp, const char *format, ...);
+
+extern JSBool
+js_puts(JSPrinter *jp, const char *s);
+
+#ifdef DEBUG
+/*
+ * Disassemblers, for debugging only.
+ */
+#include <stdio.h>
+
+extern JS_FRIEND_API(JSBool)
+js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp);
+
+extern JS_FRIEND_API(uintN)
+js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
+                JSBool lines, FILE *fp);
+#endif /* DEBUG */
+
+/*
+ * Decompilers, for script, function, and expression pretty-printing.
+ */
+extern JSBool
+js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len);
+
+extern JSBool
+js_DecompileScript(JSPrinter *jp, JSScript *script);
+
+extern JSBool
+js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun);
+
+extern JSBool
+js_DecompileFunction(JSPrinter *jp, JSFunction *fun);
+
+/*
+ * Find the source expression that resulted in v, and return a new string
+ * containing it.  Fall back on v's string conversion (fallback) if we can't
+ * find the bytecode that generated and pushed v on the operand stack.
+ *
+ * Search the current stack frame if spindex is JSDVG_SEARCH_STACK.  Don't
+ * look for v on the stack if spindex is JSDVG_IGNORE_STACK.  Otherwise,
+ * spindex is the negative index of v, measured from cx->fp->sp, or from a
+ * lower frame's sp if cx->fp is native.
+ */
+extern JSString *
+js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
+                           JSString *fallback);
+
+#define JSDVG_IGNORE_STACK      0
+#define JSDVG_SEARCH_STACK      1
+
+JS_END_EXTERN_C
+
+#endif /* jsopcode_h___ */

Added: freeswitch/trunk/libs/js/src/jsopcode.tbl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsopcode.tbl	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,394 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JavaScript operation bytecodes.  If you need to allocate a bytecode, look
+ * for a name of the form JSOP_UNUSED* and claim it.  Otherwise, always add at
+ * the end of the table.
+ *
+ * Includers must define an OPDEF macro of the following form:
+ *
+ * #define OPDEF(op,val,name,image,length,nuses,ndefs,prec,format) ...
+ *
+ * Selected arguments can be expanded in initializers.  The op argument is
+ * expanded followed by comma in the JSOp enum (jsopcode.h), e.g.  The value
+ * field must be dense for now, because jsopcode.c uses an OPDEF() expansion
+ * inside the js_CodeSpec[] initializer.
+ *
+ * Field        Description
+ * op           Bytecode name, which is the JSOp enumerator name
+ * value        Bytecode value, which is the JSOp enumerator value
+ * name         C string containing name for disassembler
+ * image        C string containing "image" for pretty-printer, null if ugly
+ * length       Number of bytes including any immediate operands
+ * nuses        Number of stack slots consumed by bytecode, -1 if variadic
+ * ndefs        Number of stack slots produced by bytecode
+ * prec         Operator precedence, zero if not an operator
+ * format       Bytecode plus immediate operand encoding format
+ *
+ * This file is best viewed with 128 columns:
+12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
+ */
+
+/* legend: op         val name          image       len use def prec  format */
+
+/* Longstanding JavaScript bytecodes. */
+OPDEF(JSOP_NOP,       0,  "nop",        NULL,         1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_PUSH,      1,  "push",       NULL,         1,  0,  1,  0,  JOF_BYTE)
+OPDEF(JSOP_POPV,      2,  "popv",       NULL,         1,  1,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_ENTERWITH, 3,  "enterwith",  NULL,         1,  1,  1,  0,  JOF_BYTE)
+OPDEF(JSOP_LEAVEWITH, 4,  "leavewith",  NULL,         1,  1,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_RETURN,    5,  "return",     NULL,         1,  1,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_GOTO,      6,  "goto",       NULL,         3,  0,  0,  0,  JOF_JUMP)
+OPDEF(JSOP_IFEQ,      7,  "ifeq",       NULL,         3,  1,  0,  0,  JOF_JUMP|JOF_DETECTING)
+OPDEF(JSOP_IFNE,      8,  "ifne",       NULL,         3,  1,  0,  0,  JOF_JUMP)
+
+/* Get the arguments object for the current, lightweight function activation. */
+OPDEF(JSOP_ARGUMENTS, 9, js_arguments_str, js_arguments_str, 1, 0, 1, 12, JOF_BYTE)
+
+/* ECMA-compliant for-in loop with argument or local variable loop control. */
+OPDEF(JSOP_FORARG,    10, "forarg",     NULL,         3,  0,  1,  0,  JOF_QARG|JOF_NAME|JOF_FOR)
+OPDEF(JSOP_FORVAR,    11, "forvar",     NULL,         3,  0,  1,  0,  JOF_QVAR|JOF_NAME|JOF_FOR)
+
+/* More longstanding bytecodes. */
+OPDEF(JSOP_DUP,       12, "dup",        NULL,         1,  1,  2,  0,  JOF_BYTE)
+OPDEF(JSOP_DUP2,      13, "dup2",       NULL,         1,  2,  4,  0,  JOF_BYTE)
+OPDEF(JSOP_SETCONST,  14, "setconst",   NULL,         3,  1,  1,  1,  JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING)
+OPDEF(JSOP_BITOR,     15, "bitor",      "|",          1,  2,  1,  2,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_BITXOR,    16, "bitxor",     "^",          1,  2,  1,  3,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_BITAND,    17, "bitand",     "&",          1,  2,  1,  4,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_EQ,        18, "eq",         "==",         1,  2,  1,  5,  JOF_BYTE|JOF_LEFTASSOC|JOF_DETECTING)
+OPDEF(JSOP_NE,        19, "ne",         "!=",         1,  2,  1,  5,  JOF_BYTE|JOF_LEFTASSOC|JOF_DETECTING)
+OPDEF(JSOP_LT,        20, "lt",         "<",          1,  2,  1,  6,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_LE,        21, "le",         "<=",         1,  2,  1,  6,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_GT,        22, "gt",         ">",          1,  2,  1,  6,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_GE,        23, "ge",         ">=",         1,  2,  1,  6,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_LSH,       24, "lsh",        "<<",         1,  2,  1,  7,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_RSH,       25, "rsh",        ">>",         1,  2,  1,  7,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_URSH,      26, "ursh",       ">>>",        1,  2,  1,  7,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_ADD,       27, "add",        "+",          1,  2,  1,  8,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_SUB,       28, "sub",        "-",          1,  2,  1,  8,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_MUL,       29, "mul",        "*",          1,  2,  1,  9,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_DIV,       30, "div",        "/",          1,  2,  1,  9,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_MOD,       31, "mod",        "%",          1,  2,  1,  9,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_NOT,       32, "not",        "!",          1,  1,  1, 10,  JOF_BYTE|JOF_DETECTING)
+OPDEF(JSOP_BITNOT,    33, "bitnot",     "~",          1,  1,  1, 10,  JOF_BYTE)
+OPDEF(JSOP_NEG,       34, "neg",        "-",          1,  1,  1, 10,  JOF_BYTE)
+OPDEF(JSOP_NEW,       35, js_new_str,   NULL,         3, -1,  1, 10,  JOF_UINT16)
+OPDEF(JSOP_DELNAME,   36, "delname",    NULL,         3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_DEL)
+OPDEF(JSOP_DELPROP,   37, "delprop",    NULL,         3,  1,  1, 10,  JOF_CONST|JOF_PROP|JOF_DEL)
+OPDEF(JSOP_DELELEM,   38, "delelem",    NULL,         1,  2,  1, 10,  JOF_BYTE |JOF_ELEM|JOF_DEL)
+OPDEF(JSOP_TYPEOF,    39, js_typeof_str,NULL,         1,  1,  1, 10,  JOF_BYTE|JOF_DETECTING)
+OPDEF(JSOP_VOID,      40, js_void_str,  NULL,         1,  1,  1, 10,  JOF_BYTE)
+OPDEF(JSOP_INCNAME,   41, "incname",    NULL,         3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_INC)
+OPDEF(JSOP_INCPROP,   42, "incprop",    NULL,         3,  1,  1, 10,  JOF_CONST|JOF_PROP|JOF_INC)
+OPDEF(JSOP_INCELEM,   43, "incelem",    NULL,         1,  2,  1, 10,  JOF_BYTE |JOF_ELEM|JOF_INC)
+OPDEF(JSOP_DECNAME,   44, "decname",    NULL,         3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_DEC)
+OPDEF(JSOP_DECPROP,   45, "decprop",    NULL,         3,  1,  1, 10,  JOF_CONST|JOF_PROP|JOF_DEC)
+OPDEF(JSOP_DECELEM,   46, "decelem",    NULL,         1,  2,  1, 10,  JOF_BYTE |JOF_ELEM|JOF_DEC)
+OPDEF(JSOP_NAMEINC,   47, "nameinc",    NULL,         3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_INC|JOF_POST)
+OPDEF(JSOP_PROPINC,   48, "propinc",    NULL,         3,  1,  1, 10,  JOF_CONST|JOF_PROP|JOF_INC|JOF_POST)
+OPDEF(JSOP_ELEMINC,   49, "eleminc",    NULL,         1,  2,  1, 10,  JOF_BYTE |JOF_ELEM|JOF_INC|JOF_POST)
+OPDEF(JSOP_NAMEDEC,   50, "namedec",    NULL,         3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_DEC|JOF_POST)
+OPDEF(JSOP_PROPDEC,   51, "propdec",    NULL,         3,  1,  1, 10,  JOF_CONST|JOF_PROP|JOF_DEC|JOF_POST)
+OPDEF(JSOP_ELEMDEC,   52, "elemdec",    NULL,         1,  2,  1, 10,  JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_POST)
+OPDEF(JSOP_GETPROP,   53, "getprop",    NULL,         3,  1,  1, 11,  JOF_CONST|JOF_PROP)
+OPDEF(JSOP_SETPROP,   54, "setprop",    NULL,         3,  2,  1,  1,  JOF_CONST|JOF_PROP|JOF_SET|JOF_ASSIGNING|JOF_DETECTING)
+OPDEF(JSOP_GETELEM,   55, "getelem",    NULL,         1,  2,  1, 11,  JOF_BYTE |JOF_ELEM|JOF_LEFTASSOC)
+OPDEF(JSOP_SETELEM,   56, "setelem",    NULL,         1,  3,  1,  1,  JOF_BYTE |JOF_ELEM|JOF_SET|JOF_ASSIGNING|JOF_DETECTING)
+OPDEF(JSOP_PUSHOBJ,   57, "pushobj",    NULL,         1,  0,  1,  0,  JOF_BYTE)
+OPDEF(JSOP_CALL,      58, "call",       NULL,         3, -1,  1, 11,  JOF_UINT16)
+OPDEF(JSOP_NAME,      59, "name",       NULL,         3,  0,  1, 12,  JOF_CONST|JOF_NAME)
+OPDEF(JSOP_NUMBER,    60, "number",     NULL,         3,  0,  1, 12,  JOF_CONST)
+OPDEF(JSOP_STRING,    61, "string",     NULL,         3,  0,  1, 12,  JOF_CONST)
+OPDEF(JSOP_ZERO,      62, "zero",       "0",          1,  0,  1, 12,  JOF_BYTE)
+OPDEF(JSOP_ONE,       63, "one",        "1",          1,  0,  1, 12,  JOF_BYTE)
+OPDEF(JSOP_NULL,      64, js_null_str,  js_null_str,  1,  0,  1, 12,  JOF_BYTE)
+OPDEF(JSOP_THIS,      65, js_this_str,  js_this_str,  1,  0,  1, 12,  JOF_BYTE)
+OPDEF(JSOP_FALSE,     66, js_false_str, js_false_str, 1,  0,  1, 12,  JOF_BYTE)
+OPDEF(JSOP_TRUE,      67, js_true_str,  js_true_str,  1,  0,  1, 12,  JOF_BYTE)
+OPDEF(JSOP_OR,        68, "or",         NULL,         3,  1,  0,  0,  JOF_JUMP|JOF_DETECTING)
+OPDEF(JSOP_AND,       69, "and",        NULL,         3,  1,  0,  0,  JOF_JUMP|JOF_DETECTING)
+
+/* The switch bytecodes have variable length. */
+OPDEF(JSOP_TABLESWITCH,  70, "tableswitch",  NULL,   -1,  1,  0,  0,  JOF_TABLESWITCH|JOF_DETECTING)
+OPDEF(JSOP_LOOKUPSWITCH, 71, "lookupswitch", NULL,   -1,  1,  0,  0,  JOF_LOOKUPSWITCH|JOF_DETECTING)
+
+/* New, infallible/transitive identity ops. */
+OPDEF(JSOP_NEW_EQ,    72, "eq",         NULL,         1,  2,  1,  5,  JOF_BYTE|JOF_DETECTING)
+OPDEF(JSOP_NEW_NE,    73, "ne",         NULL,         1,  2,  1,  5,  JOF_BYTE|JOF_DETECTING)
+
+/* Lexical closure constructor. */
+OPDEF(JSOP_CLOSURE,   74, "closure",    NULL,         3,  0,  0,  0,  JOF_CONST)
+
+/* Export and import ops. */
+OPDEF(JSOP_EXPORTALL, 75, "exportall",  NULL,         1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_EXPORTNAME,76, "exportname", NULL,         3,  0,  0,  0,  JOF_CONST|JOF_NAME)
+OPDEF(JSOP_IMPORTALL, 77, "importall",  NULL,         1,  1,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_IMPORTPROP,78, "importprop", NULL,         3,  1,  0,  0,  JOF_CONST|JOF_PROP|JOF_IMPORT)
+OPDEF(JSOP_IMPORTELEM,79, "importelem", NULL,         1,  2,  0,  0,  JOF_BYTE |JOF_ELEM|JOF_IMPORT)
+
+/* Push object literal. */
+OPDEF(JSOP_OBJECT,    80, "object",     NULL,         3,  0,  1, 12,  JOF_CONST)
+
+/* Pop value and discard it. */
+OPDEF(JSOP_POP,       81, "pop",        NULL,         1,  1,  0,  0,  JOF_BYTE)
+
+/* Convert value to number, for unary +. */
+OPDEF(JSOP_POS,       82, "pos",        "+",          1,  1,  1, 10,  JOF_BYTE)
+
+/* Trap into debugger for breakpoint, etc. */
+OPDEF(JSOP_TRAP,      83, "trap",       NULL,         1,  0,  0,  0,  JOF_BYTE)
+
+/* Fast get/set ops for function arguments and local variables. */
+OPDEF(JSOP_GETARG,    84, "getarg",     NULL,         3,  0,  1, 12,  JOF_QARG |JOF_NAME)
+OPDEF(JSOP_SETARG,    85, "setarg",     NULL,         3,  1,  1,  1,  JOF_QARG |JOF_NAME|JOF_SET|JOF_ASSIGNING)
+OPDEF(JSOP_GETVAR,    86, "getvar",     NULL,         3,  0,  1, 12,  JOF_QVAR |JOF_NAME)
+OPDEF(JSOP_SETVAR,    87, "setvar",     NULL,         3,  1,  1,  1,  JOF_QVAR |JOF_NAME|JOF_SET|JOF_ASSIGNING|JOF_DETECTING)
+
+/* Push unsigned 16-bit int constant. */
+OPDEF(JSOP_UINT16,    88, "uint16",     NULL,         3,  0,  1, 12,  JOF_UINT16)
+
+/* Object and array literal support. */
+OPDEF(JSOP_NEWINIT,   89, "newinit",    NULL,         1,  2,  1, 10,  JOF_BYTE)
+OPDEF(JSOP_ENDINIT,   90, "endinit",    NULL,         1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_INITPROP,  91, "initprop",   NULL,         3,  1,  0,  0,  JOF_CONST|JOF_PROP|JOF_DETECTING)
+OPDEF(JSOP_INITELEM,  92, "initelem",   NULL,         1,  2,  0,  0,  JOF_BYTE |JOF_ELEM|JOF_DETECTING)
+OPDEF(JSOP_DEFSHARP,  93, "defsharp",   NULL,         3,  0,  0,  0,  JOF_UINT16)
+OPDEF(JSOP_USESHARP,  94, "usesharp",   NULL,         3,  0,  1,  0,  JOF_UINT16)
+
+/* Fast inc/dec ops for args and local vars. */
+OPDEF(JSOP_INCARG,    95, "incarg",     NULL,         3,  0,  1, 10,  JOF_QARG |JOF_NAME|JOF_INC)
+OPDEF(JSOP_INCVAR,    96, "incvar",     NULL,         3,  0,  1, 10,  JOF_QVAR |JOF_NAME|JOF_INC)
+OPDEF(JSOP_DECARG,    97, "decarg",     NULL,         3,  0,  1, 10,  JOF_QARG |JOF_NAME|JOF_DEC)
+OPDEF(JSOP_DECVAR,    98, "decvar",     NULL,         3,  0,  1, 10,  JOF_QVAR |JOF_NAME|JOF_DEC)
+OPDEF(JSOP_ARGINC,    99, "arginc",     NULL,         3,  0,  1, 10,  JOF_QARG |JOF_NAME|JOF_INC|JOF_POST)
+OPDEF(JSOP_VARINC,    100,"varinc",     NULL,         3,  0,  1, 10,  JOF_QVAR |JOF_NAME|JOF_INC|JOF_POST)
+OPDEF(JSOP_ARGDEC,    101,"argdec",     NULL,         3,  0,  1, 10,  JOF_QARG |JOF_NAME|JOF_DEC|JOF_POST)
+OPDEF(JSOP_VARDEC,    102,"vardec",     NULL,         3,  0,  1, 10,  JOF_QVAR |JOF_NAME|JOF_DEC|JOF_POST)
+
+/* ECMA-compliant for/in ops. */
+OPDEF(JSOP_TOOBJECT,  103,"toobject",   NULL,         1,  1,  1,  0,  JOF_BYTE)
+OPDEF(JSOP_FORNAME,   104,"forname",    NULL,         3,  0,  1,  0,  JOF_CONST|JOF_NAME|JOF_FOR)
+OPDEF(JSOP_FORPROP,   105,"forprop",    NULL,         3,  1,  1,  0,  JOF_CONST|JOF_PROP|JOF_FOR)
+OPDEF(JSOP_FORELEM,   106,"forelem",    NULL,         1,  2,  4,  0,  JOF_BYTE |JOF_ELEM|JOF_FOR)
+OPDEF(JSOP_POP2,      107,"pop2",       NULL,         1,  2,  0,  0,  JOF_BYTE)
+
+/* ECMA-compliant assignment ops. */
+OPDEF(JSOP_BINDNAME,  108,"bindname",   NULL,         3,  0,  1,  0,  JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING)
+OPDEF(JSOP_SETNAME,   109,"setname",    NULL,         3,  2,  1,  1,  JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING|JOF_DETECTING)
+
+/* Exception handling ops. */
+OPDEF(JSOP_THROW,     110,"throw",      NULL,         1,  1,  0,  0,  JOF_BYTE)
+
+/* 'in' and 'instanceof' ops. */
+OPDEF(JSOP_IN,        111,js_in_str,    js_in_str,    1,  2,  1,  6,  JOF_BYTE|JOF_LEFTASSOC)
+OPDEF(JSOP_INSTANCEOF,112,js_instanceof_str,js_instanceof_str,1,2,1,6,JOF_BYTE|JOF_LEFTASSOC)
+
+/* debugger op */
+OPDEF(JSOP_DEBUGGER,  113,"debugger",   NULL,         1,  0,  0,  0,  JOF_BYTE)
+
+/* gosub/retsub for finally handling */
+OPDEF(JSOP_GOSUB,     114,"gosub",      NULL,         3,  0,  1,  0,  JOF_JUMP)
+OPDEF(JSOP_RETSUB,    115,"retsub",     NULL,         1,  1,  0,  0,  JOF_BYTE)
+
+/* More exception handling ops. */
+OPDEF(JSOP_EXCEPTION, 116,"exception",  NULL,         1,  0,  1,  0,  JOF_BYTE)
+OPDEF(JSOP_SETSP,     117,"setsp",      NULL,         3,  0,  0,  0,  JOF_UINT16)
+
+/*
+ * ECMA-compliant switch statement ops.
+ * CONDSWITCH is a decompilable NOP; CASE is ===, POP, jump if true, re-push
+ * lval if false; and DEFAULT is POP lval and GOTO.
+ */
+OPDEF(JSOP_CONDSWITCH,118,"condswitch", NULL,         1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_CASE,      119,"case",       NULL,         3,  1,  0,  0,  JOF_JUMP)
+OPDEF(JSOP_DEFAULT,   120,"default",    NULL,         3,  1,  0,  0,  JOF_JUMP)
+
+/*
+ * ECMA-compliant call to eval op
+ */
+OPDEF(JSOP_EVAL,      121,"eval",       NULL,         3, -1,  1, 11,  JOF_UINT16)
+
+/*
+ * ECMA-compliant helper for 'for (x[i] in o)' loops.
+ */
+OPDEF(JSOP_ENUMELEM,  122,"enumelem",   NULL,         1,  3,  0,  1,  JOF_BYTE |JOF_SET|JOF_ASSIGNING)
+
+/*
+ * Getter and setter prefix bytecodes.  These modify the next bytecode, either
+ * an assignment or a property initializer code, which then defines a property
+ * getter or setter.
+ */
+OPDEF(JSOP_GETTER,    123,js_getter_str,NULL,         1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_SETTER,    124,js_setter_str,NULL,         1,  0,  0,  0,  JOF_BYTE)
+
+/*
+ * Prolog bytecodes for defining function, var, and const names.
+ */
+OPDEF(JSOP_DEFFUN,    125,"deffun",     NULL,         3,  0,  0,  0,  JOF_CONST|JOF_DECLARING)
+OPDEF(JSOP_DEFCONST,  126,"defconst",   NULL,         3,  0,  0,  0,  JOF_CONST|JOF_NAME|JOF_DECLARING)
+OPDEF(JSOP_DEFVAR,    127,"defvar",     NULL,         3,  0,  0,  0,  JOF_CONST|JOF_NAME|JOF_DECLARING)
+
+/* Auto-clone (if needed due to re-parenting) and push an anonymous function. */
+OPDEF(JSOP_ANONFUNOBJ,  128, "anonfunobj",  NULL,     3,  0,  1, 12,  JOF_CONST)
+
+/* ECMA ed. 3 named function expression. */
+OPDEF(JSOP_NAMEDFUNOBJ, 129, "namedfunobj", NULL,     3,  0,  1, 12,  JOF_CONST)
+
+/*
+ * Like JSOP_INITPROP, but specialized to make a DontDelete property for ECMA
+ * Edition 3 catch variables.
+ */
+OPDEF(JSOP_INITCATCHVAR,130, "initcatchvar",NULL,     3,  1,  0,  0,  JOF_CONST)
+
+/* ECMA-mandated parenthesization opcode, which nulls the reference base register, obj; see jsinterp.c. */
+OPDEF(JSOP_GROUP,       131, "group",       NULL,     1,  0,  0,  0,  JOF_BYTE)
+
+/* Host object extension: given 'o.item(i) = j', the left-hand side compiles JSOP_SETCALL, rather than JSOP_CALL. */
+OPDEF(JSOP_SETCALL,     132, "setcall",     NULL,     3, -1,  2, 11,  JOF_UINT16|JOF_SET|JOF_ASSIGNING)
+
+/*
+ * Exception handling no-ops, for more economical byte-coding than SRC_TRYFIN
+ * srcnote-annotated JSOP_NOPs.
+ */
+OPDEF(JSOP_TRY,         133,"try",        NULL,       1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_FINALLY,     134,"finally",    NULL,       1,  0,  0,  0,  JOF_BYTE)
+
+/*
+ * Swap the top two stack elements.
+ * N.B. JSOP_SWAP doesn't swap the corresponding pc stack generating pcs, as
+ * they're not needed for the current use of preserving the top-of-stack return
+ * value when popping scopes while returning from catch blocks.
+ */
+OPDEF(JSOP_SWAP,        135,"swap",       NULL,       1,  2,  2,  0,  JOF_BYTE)
+
+/*
+ * Bytecodes that avoid making an arguments object in most cases:
+ * JSOP_ARGSUB gets arguments[i] from fp->argv, iff i is in [0, fp->argc-1].
+ * JSOP_ARGCNT returns fp->argc.
+ */
+OPDEF(JSOP_ARGSUB,      136,"argsub",     NULL,       3,  0,  1, 12,  JOF_QARG |JOF_NAME)
+OPDEF(JSOP_ARGCNT,      137,"argcnt",     NULL,       1,  0,  1, 12,  JOF_BYTE)
+
+/*
+ * Define a local function object as a local variable.
+ * The local variable's slot number is the first immediate two-byte operand.
+ * The function object's atom index is the second immediate operand.
+ */
+OPDEF(JSOP_DEFLOCALFUN, 138,"deflocalfun",NULL,       5,  0,  0,  0,  JOF_INDEXCONST|JOF_DECLARING)
+
+/* Extended jumps. */
+OPDEF(JSOP_GOTOX,         139,"gotox",    NULL,       5,  0,  0,  0,  JOF_JUMPX)
+OPDEF(JSOP_IFEQX,         140,"ifeqx",    NULL,       5,  1,  0,  0,  JOF_JUMPX|JOF_DETECTING)
+OPDEF(JSOP_IFNEX,         141,"ifnex",    NULL,       5,  1,  0,  0,  JOF_JUMPX)
+OPDEF(JSOP_ORX,           142,"orx",      NULL,       5,  1,  0,  0,  JOF_JUMPX|JOF_DETECTING)
+OPDEF(JSOP_ANDX,          143,"andx",     NULL,       5,  1,  0,  0,  JOF_JUMPX|JOF_DETECTING)
+OPDEF(JSOP_GOSUBX,        144,"gosubx",   NULL,       5,  0,  1,  0,  JOF_JUMPX)
+OPDEF(JSOP_CASEX,         145,"casex",    NULL,       5,  1,  0,  0,  JOF_JUMPX)
+OPDEF(JSOP_DEFAULTX,      146,"defaultx", NULL,       5,  1,  0,  0,  JOF_JUMPX)
+OPDEF(JSOP_TABLESWITCHX,  147,"tableswitchx",NULL,   -1,  1,  0,  0,  JOF_TABLESWITCHX|JOF_DETECTING)
+OPDEF(JSOP_LOOKUPSWITCHX, 148,"lookupswitchx",NULL,  -1,  1,  0,  0,  JOF_LOOKUPSWITCHX|JOF_DETECTING)
+
+/* Placeholders for a real jump opcode set during backpatch chain fixup. */
+OPDEF(JSOP_BACKPATCH,     149,"backpatch",NULL,       3,  0,  0,  0,  JOF_JUMP|JOF_BACKPATCH)
+OPDEF(JSOP_BACKPATCH_POP, 150,"backpatch_pop",NULL,   3,  1,  0,  0,  JOF_JUMP|JOF_BACKPATCH)
+OPDEF(JSOP_BACKPATCH_PUSH,151,"backpatch_push",NULL,  3,  0,  1,  0,  JOF_JUMP|JOF_BACKPATCH)
+
+/* Set and get return value pseudo-register in stack frame. */
+OPDEF(JSOP_SETRVAL,       152,"setrval",  NULL,       1,  1,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_RETRVAL,       153,"retrval",  NULL,       1,  0,  0,  0,  JOF_BYTE)
+
+/* Optimized global variable ops (we don't bother doing a JSOP_FORGVAR op). */
+OPDEF(JSOP_GETGVAR,       154,"getgvar",  NULL,       3,  0,  1, 12,  JOF_CONST|JOF_NAME)
+OPDEF(JSOP_SETGVAR,       155,"setgvar",  NULL,       3,  1,  1,  1,  JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING|JOF_DETECTING)
+OPDEF(JSOP_INCGVAR,       156,"incgvar",  NULL,       3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_INC)
+OPDEF(JSOP_DECGVAR,       157,"decgvar",  NULL,       3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_DEC)
+OPDEF(JSOP_GVARINC,       158,"gvarinc",  NULL,       3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_INC|JOF_POST)
+OPDEF(JSOP_GVARDEC,       159,"gvardec",  NULL,       3,  0,  1, 10,  JOF_CONST|JOF_NAME|JOF_DEC|JOF_POST)
+
+/* Regular expression literal requiring special "fork on exec" handling. */
+OPDEF(JSOP_REGEXP,        160,"regexp",   NULL,       3,  0,  1, 12,  JOF_CONST)
+
+/* XML (ECMA-357, a.k.a. "E4X") support. */
+OPDEF(JSOP_DEFXMLNS,      161,"defxmlns",   NULL,     1,  1,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_ANYNAME,       162,"anyname",    NULL,     1,  0,  1, 12,  JOF_BYTE|JOF_XMLNAME)
+OPDEF(JSOP_QNAMEPART,     163,"qnamepart",  NULL,     3,  0,  1, 12,  JOF_CONST|JOF_XMLNAME)
+OPDEF(JSOP_QNAMECONST,    164,"qnameconst", NULL,     3,  1,  1, 12,  JOF_CONST|JOF_XMLNAME)
+OPDEF(JSOP_QNAME,         165,"qname",      NULL,     1,  2,  1,  0,  JOF_BYTE|JOF_XMLNAME)
+OPDEF(JSOP_TOATTRNAME,    166,"toattrname", NULL,     1,  1,  1, 12,  JOF_BYTE|JOF_XMLNAME)
+OPDEF(JSOP_TOATTRVAL,     167,"toattrval",  NULL,     1,  1,  1, 12,  JOF_BYTE)
+OPDEF(JSOP_ADDATTRNAME,   168,"addattrname",NULL,     1,  2,  1,  8,  JOF_BYTE)
+OPDEF(JSOP_ADDATTRVAL,    169,"addattrval", NULL,     1,  2,  1,  8,  JOF_BYTE)
+OPDEF(JSOP_BINDXMLNAME,   170,"bindxmlname",NULL,     1,  1,  2,  0,  JOF_BYTE|JOF_XMLNAME|JOF_SET|JOF_ASSIGNING)
+OPDEF(JSOP_SETXMLNAME,    171,"setxmlname", NULL,     1,  3,  1,  1,  JOF_BYTE|JOF_XMLNAME|JOF_SET|JOF_ASSIGNING|JOF_DETECTING)
+OPDEF(JSOP_XMLNAME,       172,"xmlname",    NULL,     1,  1,  1, 12,  JOF_BYTE|JOF_XMLNAME)
+OPDEF(JSOP_DESCENDANTS,   173,"descendants",NULL,     1,  2,  1, 11,  JOF_BYTE)
+OPDEF(JSOP_FILTER,        174,"filter",     NULL,     3,  1,  1, 11,  JOF_JUMP)
+OPDEF(JSOP_ENDFILTER,     175,"endfilter",  NULL,     1,  1,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_TOXML,         176,"toxml",      NULL,     1,  1,  1, 12,  JOF_BYTE)
+OPDEF(JSOP_TOXMLLIST,     177,"toxmllist",  NULL,     1,  1,  1, 12,  JOF_BYTE)
+OPDEF(JSOP_XMLTAGEXPR,    178,"xmltagexpr", NULL,     1,  1,  1,  0,  JOF_BYTE)
+OPDEF(JSOP_XMLELTEXPR,    179,"xmleltexpr", NULL,     1,  1,  1,  0,  JOF_BYTE)
+OPDEF(JSOP_XMLOBJECT,     180,"xmlobject",  NULL,     3,  0,  1, 12,  JOF_CONST)
+OPDEF(JSOP_XMLCDATA,      181,"xmlcdata",   NULL,     3,  0,  1, 12,  JOF_CONST)
+OPDEF(JSOP_XMLCOMMENT,    182,"xmlcomment", NULL,     3,  0,  1, 12,  JOF_CONST)
+OPDEF(JSOP_XMLPI,         183,"xmlpi",      NULL,     3,  1,  1, 12,  JOF_CONST)
+OPDEF(JSOP_GETMETHOD,     184,"getmethod",  NULL,     3,  1,  1, 11,  JOF_CONST|JOF_PROP)
+OPDEF(JSOP_GETFUNNS,      185,"getfunns",   NULL,     1,  0,  1, 12,  JOF_BYTE)
+OPDEF(JSOP_FOREACH,       186,"foreach",    NULL,     1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_DELDESC,       187,"deldesc",    NULL,     1,  2,  1, 10,  JOF_BYTE |JOF_ELEM|JOF_DEL)
+
+/*
+ * Opcodes for extended literal addressing, using unsigned 24-bit immediate
+ * operands to hold integer operands (JSOP_UINT24), extended atom indexes in
+ * script->atomMap (JSOP_LITERAL, JSOP_FINDNAME), and ops prefixed by such
+ * atom index immediates (JSOP_LITOPX).  See jsemit.c, EmitAtomIndexOp.
+ */
+OPDEF(JSOP_UINT24,        188,"uint24",     NULL,     4,  0,  1, 12,  JOF_UINT24)
+OPDEF(JSOP_LITERAL,       189,"literal",    NULL,     4,  0,  1, 12,  JOF_UINT24)
+OPDEF(JSOP_FINDNAME,      190,"findname",   NULL,     4,  0,  2,  0,  JOF_UINT24)
+OPDEF(JSOP_LITOPX,        191,"litopx",     NULL,     5,  0,  0, 12,  JOF_LITOPX)
+
+/*
+ * Opcodes to help the decompiler deal with XML.
+ */
+OPDEF(JSOP_STARTXML,      192,"startxml",    NULL,    1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_STARTXMLEXPR,  193,"startxmlexpr",NULL,    1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_SETMETHOD,     194,"setmethod",   NULL,    3,  2,  1,  1,  JOF_CONST|JOF_PROP)

Added: freeswitch/trunk/libs/js/src/jsosdep.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsosdep.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,112 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsosdep_h___
+#define jsosdep_h___
+/*
+ * OS (and machine, and compiler XXX) dependent information.
+ */
+
+#if defined(XP_WIN) || defined(XP_OS2)
+
+#if defined(_WIN32) || defined (XP_OS2)
+#define JS_HAVE_LONG_LONG
+#else
+#undef JS_HAVE_LONG_LONG
+#endif
+#endif /* XP_WIN || XP_OS2 */
+
+#ifdef XP_BEOS
+#define JS_HAVE_LONG_LONG
+#endif
+
+
+#ifdef XP_UNIX
+
+/*
+ * Get OS specific header information.
+ */
+#if defined(AIXV3) || defined(AIX)
+#define JS_HAVE_LONG_LONG
+
+#elif defined(BSDI)
+#define JS_HAVE_LONG_LONG
+
+#elif defined(HPUX)
+#define JS_HAVE_LONG_LONG
+
+#elif defined(IRIX)
+#define JS_HAVE_LONG_LONG
+
+#elif defined(linux)
+#define JS_HAVE_LONG_LONG
+
+#elif defined(OSF1)
+#define JS_HAVE_LONG_LONG
+
+#elif defined(_SCO_DS)
+#undef JS_HAVE_LONG_LONG
+
+#elif defined(SOLARIS)
+#define JS_HAVE_LONG_LONG
+
+#elif defined(FREEBSD)
+#define JS_HAVE_LONG_LONG
+
+#elif defined(SUNOS4)
+#undef JS_HAVE_LONG_LONG
+
+/*
+** Missing function prototypes
+*/
+
+extern void *sbrk(int);
+
+#elif defined(UNIXWARE)
+#undef JS_HAVE_LONG_LONG
+
+#elif defined(VMS) && defined(__ALPHA)
+#define JS_HAVE_LONG_LONG
+
+#endif
+
+#endif /* XP_UNIX */
+
+#endif /* jsosdep_h___ */
+

Added: freeswitch/trunk/libs/js/src/jsotypes.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsotypes.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,202 @@
+/* -*- 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 Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This section typedefs the old 'native' types to the new PR<type>s.
+ * These definitions are scheduled to be eliminated at the earliest
+ * possible time. The NSPR API is implemented and documented using
+ * the new definitions.
+ */
+
+/*
+ * Note that we test for PROTYPES_H, not JSOTYPES_H.  This is to avoid
+ * double-definitions of scalar types such as uint32, if NSPR's
+ * protypes.h is also included.
+ */
+#ifndef PROTYPES_H
+#define PROTYPES_H
+
+#ifdef XP_BEOS
+/* BeOS defines most int types in SupportDefs.h (int8, uint8, int16,
+ * uint16, int32, uint32, int64, uint64), so in the interest of
+ * not conflicting with other definitions elsewhere we have to skip the
+ * #ifdef jungle below, duplicate some definitions, and do our stuff.
+ */
+#include <SupportDefs.h>
+
+typedef JSUintn uintn;
+#ifndef _XP_Core_
+typedef JSIntn intn;
+#endif
+
+#else
+
+/* SVR4 typedef of uint is commonly found on UNIX machines. */
+#ifdef XP_UNIX
+#include <sys/types.h>
+#else
+typedef JSUintn uint;
+#endif
+
+typedef JSUintn uintn;
+typedef JSUint64 uint64;
+#if !defined(_WIN32) && !defined(XP_OS2)
+typedef JSUint32 uint32;
+#else
+typedef unsigned long uint32;
+#endif
+typedef JSUint16 uint16;
+typedef JSUint8 uint8;
+
+#ifndef _XP_Core_
+typedef JSIntn intn;
+#endif
+
+/*
+ * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h, a very
+ * common header file) defines the types int8, int16, int32, and int64.
+ * So we don't define these four types here to avoid conflicts in case
+ * the code also includes sys/types.h.
+ */
+#if defined(AIX) && defined(HAVE_SYS_INTTYPES_H)
+#include <sys/inttypes.h>
+#else
+typedef JSInt64 int64;
+
+/* /usr/include/model.h on HP-UX defines int8, int16, and int32 */
+#ifdef HPUX
+#include <model.h>
+#else
+#if !defined(_WIN32) && !defined(XP_OS2)
+typedef JSInt32 int32;
+#else
+typedef long int32;
+#endif
+typedef JSInt16 int16;
+typedef JSInt8 int8;
+#endif /* HPUX */
+#endif /* AIX && HAVE_SYS_INTTYPES_H */
+
+#endif  /* XP_BEOS */
+
+typedef JSFloat64 float64;
+
+/* Re: jsbit.h */
+#define TEST_BIT        JS_TEST_BIT
+#define SET_BIT         JS_SET_BIT
+#define CLEAR_BIT       JS_CLEAR_BIT
+
+/* Re: prarena.h->plarena.h */
+#define PRArena PLArena
+#define PRArenaPool PLArenaPool
+#define PRArenaStats PLArenaStats
+#define PR_ARENA_ALIGN PL_ARENA_ALIGN
+#define PR_INIT_ARENA_POOL PL_INIT_ARENA_POOL
+#define PR_ARENA_ALLOCATE PL_ARENA_ALLOCATE
+#define PR_ARENA_GROW PL_ARENA_GROW
+#define PR_ARENA_MARK PL_ARENA_MARK
+#define PR_CLEAR_UNUSED PL_CLEAR_UNUSED
+#define PR_CLEAR_ARENA PL_CLEAR_ARENA
+#define PR_ARENA_RELEASE PL_ARENA_RELEASE
+#define PR_COUNT_ARENA PL_COUNT_ARENA
+#define PR_ARENA_DESTROY PL_ARENA_DESTROY
+#define PR_InitArenaPool PL_InitArenaPool
+#define PR_FreeArenaPool PL_FreeArenaPool
+#define PR_FinishArenaPool PL_FinishArenaPool
+#define PR_CompactArenaPool PL_CompactArenaPool
+#define PR_ArenaFinish PL_ArenaFinish
+#define PR_ArenaAllocate PL_ArenaAllocate
+#define PR_ArenaGrow PL_ArenaGrow
+#define PR_ArenaRelease PL_ArenaRelease
+#define PR_ArenaCountAllocation PL_ArenaCountAllocation
+#define PR_ArenaCountInplaceGrowth PL_ArenaCountInplaceGrowth
+#define PR_ArenaCountGrowth PL_ArenaCountGrowth
+#define PR_ArenaCountRelease PL_ArenaCountRelease
+#define PR_ArenaCountRetract PL_ArenaCountRetract
+
+/* Re: prevent.h->plevent.h */
+#define PREvent PLEvent
+#define PREventQueue PLEventQueue
+#define PR_CreateEventQueue PL_CreateEventQueue
+#define PR_DestroyEventQueue PL_DestroyEventQueue
+#define PR_GetEventQueueMonitor PL_GetEventQueueMonitor
+#define PR_ENTER_EVENT_QUEUE_MONITOR PL_ENTER_EVENT_QUEUE_MONITOR
+#define PR_EXIT_EVENT_QUEUE_MONITOR PL_EXIT_EVENT_QUEUE_MONITOR
+#define PR_PostEvent PL_PostEvent
+#define PR_PostSynchronousEvent PL_PostSynchronousEvent
+#define PR_GetEvent PL_GetEvent
+#define PR_EventAvailable PL_EventAvailable
+#define PREventFunProc PLEventFunProc
+#define PR_MapEvents PL_MapEvents
+#define PR_RevokeEvents PL_RevokeEvents
+#define PR_ProcessPendingEvents PL_ProcessPendingEvents
+#define PR_WaitForEvent PL_WaitForEvent
+#define PR_EventLoop PL_EventLoop
+#define PR_GetEventQueueSelectFD PL_GetEventQueueSelectFD
+#define PRHandleEventProc PLHandleEventProc
+#define PRDestroyEventProc PLDestroyEventProc
+#define PR_InitEvent PL_InitEvent
+#define PR_GetEventOwner PL_GetEventOwner
+#define PR_HandleEvent PL_HandleEvent
+#define PR_DestroyEvent PL_DestroyEvent
+#define PR_DequeueEvent PL_DequeueEvent
+#define PR_GetMainEventQueue PL_GetMainEventQueue
+
+/* Re: prhash.h->plhash.h */
+#define PRHashEntry PLHashEntry
+#define PRHashTable PLHashTable
+#define PRHashNumber PLHashNumber
+#define PRHashFunction PLHashFunction
+#define PRHashComparator PLHashComparator
+#define PRHashEnumerator PLHashEnumerator
+#define PRHashAllocOps PLHashAllocOps
+#define PR_NewHashTable PL_NewHashTable
+#define PR_HashTableDestroy PL_HashTableDestroy
+#define PR_HashTableRawLookup PL_HashTableRawLookup
+#define PR_HashTableRawAdd PL_HashTableRawAdd
+#define PR_HashTableRawRemove PL_HashTableRawRemove
+#define PR_HashTableAdd PL_HashTableAdd
+#define PR_HashTableRemove PL_HashTableRemove
+#define PR_HashTableEnumerateEntries PL_HashTableEnumerateEntries
+#define PR_HashTableLookup PL_HashTableLookup
+#define PR_HashTableDump PL_HashTableDump
+#define PR_HashString PL_HashString
+#define PR_CompareStrings PL_CompareStrings
+#define PR_CompareValues PL_CompareValues
+
+#endif /* !defined(PROTYPES_H) */

Added: freeswitch/trunk/libs/js/src/jsparse.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsparse.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4864 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS parser.
+ *
+ * This is a recursive-descent parser for the JavaScript language specified by
+ * "The JavaScript 1.5 Language Specification".  It uses lexical and semantic
+ * feedback to disambiguate non-LL(1) structures.  It generates trees of nodes
+ * induced by the recursive parsing (not precise syntax trees, see jsparse.h).
+ * After tree construction, it rewrites trees to fold constants and evaluate
+ * compile-time expressions.  Finally, it calls js_EmitTree (see jsemit.h) to
+ * generate bytecode.
+ *
+ * This parser attempts no error recovery.
+ */
+#include "jsstddef.h"
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "jstypes.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsemit.h"
+#include "jsfun.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsopcode.h"
+#include "jsparse.h"
+#include "jsscan.h"
+#include "jsscope.h"
+#include "jsscript.h"
+#include "jsstr.h"
+
+#if JS_HAS_XML_SUPPORT
+#include "jsxml.h"
+#endif
+
+/*
+ * JS parsers, from lowest to highest precedence.
+ *
+ * Each parser takes a context, a token stream, and a tree context struct.
+ * Each returns a parse node tree or null on error.
+ */
+
+typedef JSParseNode *
+JSParser(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc);
+
+typedef JSParseNode *
+JSMemberParser(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
+               JSBool allowCallSyntax);
+
+static JSParser FunctionStmt;
+#if JS_HAS_LEXICAL_CLOSURE
+static JSParser FunctionExpr;
+#endif
+static JSParser Statements;
+static JSParser Statement;
+static JSParser Variables;
+static JSParser Expr;
+static JSParser AssignExpr;
+static JSParser CondExpr;
+static JSParser OrExpr;
+static JSParser AndExpr;
+static JSParser BitOrExpr;
+static JSParser BitXorExpr;
+static JSParser BitAndExpr;
+static JSParser EqExpr;
+static JSParser RelExpr;
+static JSParser ShiftExpr;
+static JSParser AddExpr;
+static JSParser MulExpr;
+static JSParser UnaryExpr;
+static JSMemberParser MemberExpr;
+static JSParser PrimaryExpr;
+
+/*
+ * Insist that the next token be of type tt, or report errno and return null.
+ * NB: this macro uses cx and ts from its lexical environment.
+ */
+#define MUST_MATCH_TOKEN(tt, errno)                                           \
+    JS_BEGIN_MACRO                                                            \
+        if (js_GetToken(cx, ts) != tt) {                                      \
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, \
+                            errno);                                           \
+            return NULL;                                                      \
+        }                                                                     \
+    JS_END_MACRO
+
+#define CHECK_RECURSION()                                                     \
+    JS_BEGIN_MACRO                                                            \
+        int stackDummy;                                                       \
+        if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {                           \
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, \
+                                        JSMSG_OVER_RECURSED);                 \
+            return NULL;                                                      \
+        }                                                                     \
+    JS_END_MACRO
+
+#ifdef METER_PARSENODES
+static uint32 parsenodes = 0;
+static uint32 maxparsenodes = 0;
+static uint32 recyclednodes = 0;
+#endif
+
+static JSParseNode *
+RecycleTree(JSParseNode *pn, JSTreeContext *tc)
+{
+    JSParseNode *next;
+
+    if (!pn)
+        return NULL;
+    JS_ASSERT(pn != tc->nodeList);      /* catch back-to-back dup recycles */
+    next = pn->pn_next;
+    pn->pn_next = tc->nodeList;
+    tc->nodeList = pn;
+#ifdef METER_PARSENODES
+    recyclednodes++;
+#endif
+    return next;
+}
+
+static JSParseNode *
+NewOrRecycledNode(JSContext *cx, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+
+    pn = tc->nodeList;
+    if (!pn) {
+        JS_ARENA_ALLOCATE_TYPE(pn, JSParseNode, &cx->tempPool);
+        if (!pn)
+            JS_ReportOutOfMemory(cx);
+    } else {
+        tc->nodeList = pn->pn_next;
+
+        /* Recycle immediate descendents only, to save work and working set. */
+        switch (pn->pn_arity) {
+          case PN_FUNC:
+            RecycleTree(pn->pn_body, tc);
+            break;
+          case PN_LIST:
+            if (pn->pn_head) {
+                /* XXX check for dup recycles in the list */
+                *pn->pn_tail = tc->nodeList;
+                tc->nodeList = pn->pn_head;
+#ifdef METER_PARSENODES
+                recyclednodes += pn->pn_count;
+#endif
+            }
+            break;
+          case PN_TERNARY:
+            RecycleTree(pn->pn_kid1, tc);
+            RecycleTree(pn->pn_kid2, tc);
+            RecycleTree(pn->pn_kid3, tc);
+            break;
+          case PN_BINARY:
+            RecycleTree(pn->pn_left, tc);
+            RecycleTree(pn->pn_right, tc);
+            break;
+          case PN_UNARY:
+            RecycleTree(pn->pn_kid, tc);
+            break;
+          case PN_NAME:
+            RecycleTree(pn->pn_expr, tc);
+            break;
+          case PN_NULLARY:
+            break;
+        }
+    }
+#ifdef METER_PARSENODES
+    if (pn) {
+        parsenodes++;
+        if (parsenodes - recyclednodes > maxparsenodes)
+            maxparsenodes = parsenodes - recyclednodes;
+    }
+#endif
+    return pn;
+}
+
+/*
+ * Allocate a JSParseNode from cx's temporary arena.
+ */
+static JSParseNode *
+NewParseNode(JSContext *cx, JSTokenStream *ts, JSParseNodeArity arity,
+             JSTreeContext *tc)
+{
+    JSParseNode *pn;
+    JSToken *tp;
+
+    pn = NewOrRecycledNode(cx, tc);
+    if (!pn)
+        return NULL;
+    tp = &CURRENT_TOKEN(ts);
+    pn->pn_type = tp->type;
+    pn->pn_pos = tp->pos;
+    pn->pn_op = JSOP_NOP;
+    pn->pn_arity = arity;
+    pn->pn_next = NULL;
+#if JS_HAS_XML_SUPPORT
+    pn->pn_ts = ts;
+#endif
+    return pn;
+}
+
+static JSParseNode *
+NewBinary(JSContext *cx, JSTokenType tt,
+          JSOp op, JSParseNode *left, JSParseNode *right,
+          JSTreeContext *tc)
+{
+    JSParseNode *pn, *pn1, *pn2;
+
+    if (!left || !right)
+        return NULL;
+
+    /*
+     * Flatten a left-associative (left-heavy) tree of a given operator into
+     * a list, to reduce js_FoldConstants and js_EmitTree recursion.
+     */
+    if (left->pn_type == tt &&
+        left->pn_op == op &&
+        (js_CodeSpec[op].format & JOF_LEFTASSOC)) {
+        if (left->pn_arity != PN_LIST) {
+            pn1 = left->pn_left, pn2 = left->pn_right;
+            left->pn_arity = PN_LIST;
+            PN_INIT_LIST_1(left, pn1);
+            PN_APPEND(left, pn2);
+            if (tt == TOK_PLUS) {
+                if (pn1->pn_type == TOK_STRING)
+                    left->pn_extra |= PNX_STRCAT;
+                else if (pn1->pn_type != TOK_NUMBER)
+                    left->pn_extra |= PNX_CANTFOLD;
+                if (pn2->pn_type == TOK_STRING)
+                    left->pn_extra |= PNX_STRCAT;
+                else if (pn2->pn_type != TOK_NUMBER)
+                    left->pn_extra |= PNX_CANTFOLD;
+            }
+        }
+        PN_APPEND(left, right);
+        left->pn_pos.end = right->pn_pos.end;
+        if (tt == TOK_PLUS) {
+            if (right->pn_type == TOK_STRING)
+                left->pn_extra |= PNX_STRCAT;
+            else if (right->pn_type != TOK_NUMBER)
+                left->pn_extra |= PNX_CANTFOLD;
+        }
+        return left;
+    }
+
+    /*
+     * Fold constant addition immediately, to conserve node space and, what's
+     * more, so js_FoldConstants never sees mixed addition and concatenation
+     * operations with more than one leading non-string operand in a PN_LIST
+     * generated for expressions such as 1 + 2 + "pt" (which should evaluate
+     * to "3pt", not "12pt").
+     */
+    if (tt == TOK_PLUS &&
+        left->pn_type == TOK_NUMBER &&
+        right->pn_type == TOK_NUMBER) {
+        left->pn_dval += right->pn_dval;
+        left->pn_pos.end = right->pn_pos.end;
+        RecycleTree(right, tc);
+        return left;
+    }
+
+    pn = NewOrRecycledNode(cx, tc);
+    if (!pn)
+        return NULL;
+    pn->pn_type = tt;
+    pn->pn_pos.begin = left->pn_pos.begin;
+    pn->pn_pos.end = right->pn_pos.end;
+    pn->pn_op = op;
+    pn->pn_arity = PN_BINARY;
+    pn->pn_left = left;
+    pn->pn_right = right;
+    pn->pn_next = NULL;
+#if JS_HAS_XML_SUPPORT
+    pn->pn_ts = NULL;
+#endif
+    return pn;
+}
+
+#if JS_HAS_GETTER_SETTER
+static JSTokenType
+CheckGetterOrSetter(JSContext *cx, JSTokenStream *ts, JSTokenType tt)
+{
+    JSAtom *atom;
+    JSRuntime *rt;
+    JSOp op;
+    const char *name;
+
+    JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_NAME);
+    atom = CURRENT_TOKEN(ts).t_atom;
+    rt = cx->runtime;
+    if (atom == rt->atomState.getterAtom)
+        op = JSOP_GETTER;
+    else if (atom == rt->atomState.setterAtom)
+        op = JSOP_SETTER;
+    else
+        return TOK_NAME;
+    if (js_PeekTokenSameLine(cx, ts) != tt)
+        return TOK_NAME;
+    (void) js_GetToken(cx, ts);
+    if (CURRENT_TOKEN(ts).t_op != JSOP_NOP) {
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_BAD_GETTER_OR_SETTER,
+                                    (op == JSOP_GETTER)
+                                    ? js_getter_str
+                                    : js_setter_str);
+        return TOK_ERROR;
+    }
+    CURRENT_TOKEN(ts).t_op = op;
+    name = js_AtomToPrintableString(cx, atom);
+    if (!name ||
+        !js_ReportCompileErrorNumber(cx, ts,
+                                     JSREPORT_TS |
+                                     JSREPORT_WARNING |
+                                     JSREPORT_STRICT,
+                                     JSMSG_DEPRECATED_USAGE,
+                                     name)) {
+        return TOK_ERROR;
+    }
+    return tt;
+}
+#endif
+
+/*
+ * Parse a top-level JS script.
+ */
+JS_FRIEND_API(JSParseNode *)
+js_ParseTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts)
+{
+    JSStackFrame *fp, frame;
+    JSTreeContext tc;
+    JSParseNode *pn;
+
+    /*
+     * Push a compiler frame if we have no frames, or if the top frame is a
+     * lightweight function activation, or if its scope chain doesn't match
+     * the one passed to us.
+     */
+    fp = cx->fp;
+    if (!fp || !fp->varobj || fp->scopeChain != chain) {
+        memset(&frame, 0, sizeof frame);
+        frame.varobj = frame.scopeChain = chain;
+        if (cx->options & JSOPTION_VAROBJFIX) {
+            while ((chain = JS_GetParent(cx, chain)) != NULL)
+                frame.varobj = chain;
+        }
+        frame.down = fp;
+        if (fp)
+            frame.flags = fp->flags & (JSFRAME_SPECIAL | JSFRAME_COMPILE_N_GO);
+        cx->fp = &frame;
+    }
+
+    /*
+     * Protect atoms from being collected by a GC activation, which might
+     * - nest on this thread due to out of memory (the so-called "last ditch"
+     *   GC attempted within js_NewGCThing), or
+     * - run for any reason on another thread if this thread is suspended on
+     *   an object lock before it finishes generating bytecode into a script
+     *   protected from the GC by a root or a stack frame reference.
+     */
+    JS_KEEP_ATOMS(cx->runtime);
+    TREE_CONTEXT_INIT(&tc);
+    pn = Statements(cx, ts, &tc);
+    if (pn) {
+        if (!js_MatchToken(cx, ts, TOK_EOF)) {
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_SYNTAX_ERROR);
+            pn = NULL;
+        } else {
+            pn->pn_type = TOK_LC;
+            if (!js_FoldConstants(cx, pn, &tc))
+                pn = NULL;
+        }
+    }
+
+    TREE_CONTEXT_FINISH(&tc);
+    JS_UNKEEP_ATOMS(cx->runtime);
+    cx->fp = fp;
+    return pn;
+}
+
+/*
+ * Compile a top-level script.
+ */
+JS_FRIEND_API(JSBool)
+js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts,
+                      JSCodeGenerator *cg)
+{
+    JSStackFrame *fp, frame;
+    uint32 flags;
+    JSParseNode *pn;
+    JSBool ok;
+#ifdef METER_PARSENODES
+    void *sbrk(ptrdiff_t), *before = sbrk(0);
+#endif
+
+    /*
+     * Push a compiler frame if we have no frames, or if the top frame is a
+     * lightweight function activation, or if its scope chain doesn't match
+     * the one passed to us.
+     */
+    fp = cx->fp;
+    if (!fp || !fp->varobj || fp->scopeChain != chain) {
+        memset(&frame, 0, sizeof frame);
+        frame.varobj = frame.scopeChain = chain;
+        if (cx->options & JSOPTION_VAROBJFIX) {
+            while ((chain = JS_GetParent(cx, chain)) != NULL)
+                frame.varobj = chain;
+        }
+        frame.down = fp;
+        if (fp)
+            frame.flags = fp->flags & (JSFRAME_SPECIAL | JSFRAME_COMPILE_N_GO);
+        cx->fp = &frame;
+    }
+    flags = cx->fp->flags;
+    cx->fp->flags = flags |
+                    (JS_HAS_COMPILE_N_GO_OPTION(cx)
+                     ? JSFRAME_COMPILING | JSFRAME_COMPILE_N_GO
+                     : JSFRAME_COMPILING);
+
+    /* Prevent GC activation while compiling. */
+    JS_KEEP_ATOMS(cx->runtime);
+
+    pn = Statements(cx, ts, &cg->treeContext);
+    if (!pn) {
+        ok = JS_FALSE;
+    } else if (!js_MatchToken(cx, ts, TOK_EOF)) {
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_SYNTAX_ERROR);
+        ok = JS_FALSE;
+    } else {
+#ifdef METER_PARSENODES
+        printf("Parser growth: %d (%u nodes, %u max, %u unrecycled)\n",
+               (char *)sbrk(0) - (char *)before,
+               parsenodes,
+               maxparsenodes,
+               parsenodes - recyclednodes);
+        before = sbrk(0);
+#endif
+
+        /*
+         * No need to emit code here -- Statements already has, for each
+         * statement in turn.  Search for TCF_COMPILING in Statements, below.
+         * That flag is set for every tc == &cg->treeContext, and it implies
+         * that the tc can be downcast to a cg and used to emit code during
+         * parsing, rather than at the end of the parse phase.
+         */
+        JS_ASSERT(cg->treeContext.flags & TCF_COMPILING);
+        ok = JS_TRUE;
+    }
+
+#ifdef METER_PARSENODES
+    printf("Code-gen growth: %d (%u bytecodes, %u srcnotes)\n",
+           (char *)sbrk(0) - (char *)before, CG_OFFSET(cg), cg->noteCount);
+#endif
+#ifdef JS_ARENAMETER
+    JS_DumpArenaStats(stdout);
+#endif
+    JS_UNKEEP_ATOMS(cx->runtime);
+    cx->fp->flags = flags;
+    cx->fp = fp;
+    return ok;
+}
+
+/*
+ * Insist on a final return before control flows out of pn, but don't be too
+ * smart about loops (do {...; return e2;} while(0) at the end of a function
+ * that contains an early return e1 will get a strict-option-only warning).
+ */
+#define ENDS_IN_OTHER   0
+#define ENDS_IN_RETURN  1
+#define ENDS_IN_BREAK   2
+
+static int
+HasFinalReturn(JSParseNode *pn)
+{
+    uintN rv, rv2, hasDefault;
+    JSParseNode *pn2, *pn3;
+
+    switch (pn->pn_type) {
+      case TOK_LC:
+        if (!pn->pn_head)
+            return ENDS_IN_OTHER;
+        return HasFinalReturn(PN_LAST(pn));
+
+      case TOK_IF:
+        rv = HasFinalReturn(pn->pn_kid2);
+        if (pn->pn_kid3)
+            rv &= HasFinalReturn(pn->pn_kid3);
+        return rv;
+
+#if JS_HAS_SWITCH_STATEMENT
+      case TOK_SWITCH:
+        rv = ENDS_IN_RETURN;
+        hasDefault = ENDS_IN_OTHER;
+        for (pn2 = pn->pn_kid2->pn_head; rv && pn2; pn2 = pn2->pn_next) {
+            if (pn2->pn_type == TOK_DEFAULT)
+                hasDefault = ENDS_IN_RETURN;
+            pn3 = pn2->pn_right;
+            JS_ASSERT(pn3->pn_type == TOK_LC);
+            if (pn3->pn_head) {
+                rv2 = HasFinalReturn(PN_LAST(pn3));
+                if (rv2 == ENDS_IN_OTHER && pn2->pn_next)
+                    /* Falling through to next case or default. */;
+                else
+                    rv &= rv2;
+            }
+        }
+        /* If a final switch has no default case, we judge it harshly. */
+        rv &= hasDefault;
+        return rv;
+#endif /* JS_HAS_SWITCH_STATEMENT */
+
+      case TOK_BREAK:
+        return ENDS_IN_BREAK;
+
+      case TOK_WITH:
+        return HasFinalReturn(pn->pn_right);
+
+      case TOK_RETURN:
+        return ENDS_IN_RETURN;
+
+      case TOK_COLON:
+        return HasFinalReturn(pn->pn_expr);
+
+#if JS_HAS_EXCEPTIONS
+      case TOK_THROW:
+        return ENDS_IN_RETURN;
+
+      case TOK_TRY:
+        /* If we have a finally block that returns, we are done. */
+        if (pn->pn_kid3) {
+            rv = HasFinalReturn(pn->pn_kid3);
+            if (rv == ENDS_IN_RETURN)
+                return rv;
+        }
+
+        /* Else check the try block and any and all catch statements. */
+        rv = HasFinalReturn(pn->pn_kid1);
+        if (pn->pn_kid2)
+            rv &= HasFinalReturn(pn->pn_kid2);
+        return rv;
+
+      case TOK_CATCH:
+        /* Check this block's code and iterate over further catch blocks. */
+        rv = HasFinalReturn(pn->pn_kid3);
+        for (pn2 = pn->pn_kid2; pn2; pn2 = pn2->pn_kid2)
+            rv &= HasFinalReturn(pn2->pn_kid3);
+        return rv;
+#endif
+
+      default:
+        return ENDS_IN_OTHER;
+    }
+}
+
+static JSBool
+ReportNoReturnValue(JSContext *cx, JSTokenStream *ts)
+{
+    JSFunction *fun;
+    JSBool ok;
+
+    fun = cx->fp->fun;
+    if (fun->atom) {
+        char *name = js_GetStringBytes(ATOM_TO_STRING(fun->atom));
+        ok = js_ReportCompileErrorNumber(cx, ts,
+                                         JSREPORT_TS |
+                                         JSREPORT_WARNING |
+                                         JSREPORT_STRICT,
+                                         JSMSG_NO_RETURN_VALUE, name);
+    } else {
+        ok = js_ReportCompileErrorNumber(cx, ts,
+                                         JSREPORT_TS |
+                                         JSREPORT_WARNING |
+                                         JSREPORT_STRICT,
+                                         JSMSG_ANON_NO_RETURN_VALUE);
+    }
+    return ok;
+}
+
+static JSBool
+CheckFinalReturn(JSContext *cx, JSTokenStream *ts, JSParseNode *pn)
+{
+    return HasFinalReturn(pn) == ENDS_IN_RETURN || ReportNoReturnValue(cx, ts);
+}
+
+static JSParseNode *
+FunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun,
+             JSTreeContext *tc)
+{
+    JSStackFrame *fp, frame;
+    JSObject *funobj;
+    uintN oldflags;
+    JSParseNode *pn;
+
+    fp = cx->fp;
+    funobj = fun->object;
+    if (!fp || fp->fun != fun || fp->varobj != funobj ||
+        fp->scopeChain != funobj) {
+        memset(&frame, 0, sizeof frame);
+        frame.fun = fun;
+        frame.varobj = frame.scopeChain = funobj;
+        frame.down = fp;
+        if (fp)
+            frame.flags = fp->flags & JSFRAME_COMPILE_N_GO;
+        cx->fp = &frame;
+    }
+
+    oldflags = tc->flags;
+    tc->flags &= ~(TCF_RETURN_EXPR | TCF_RETURN_VOID);
+    tc->flags |= TCF_IN_FUNCTION;
+    pn = Statements(cx, ts, tc);
+
+    /* Check for falling off the end of a function that returns a value. */
+    if (pn && JS_HAS_STRICT_OPTION(cx) && (tc->flags & TCF_RETURN_EXPR)) {
+        if (!CheckFinalReturn(cx, ts, pn))
+            pn = NULL;
+    }
+
+    cx->fp = fp;
+    tc->flags = oldflags | (tc->flags & (TCF_FUN_FLAGS | TCF_HAS_DEFXMLNS));
+    return pn;
+}
+
+/*
+ * Compile a JS function body, which might appear as the value of an event
+ * handler attribute in an HTML <INPUT> tag.
+ */
+JSBool
+js_CompileFunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun)
+{
+    JSArenaPool codePool, notePool;
+    JSCodeGenerator funcg;
+    JSStackFrame *fp, frame;
+    JSObject *funobj;
+    JSParseNode *pn;
+    JSBool ok;
+
+    JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode));
+    JS_InitArenaPool(&notePool, "note", 1024, sizeof(jssrcnote));
+    if (!js_InitCodeGenerator(cx, &funcg, &codePool, &notePool,
+                              ts->filename, ts->lineno,
+                              ts->principals)) {
+        return JS_FALSE;
+    }
+
+    /* Prevent GC activation while compiling. */
+    JS_KEEP_ATOMS(cx->runtime);
+
+    /* Push a JSStackFrame for use by FunctionBody. */
+    fp = cx->fp;
+    funobj = fun->object;
+    JS_ASSERT(!fp || (fp->fun != fun && fp->varobj != funobj &&
+                      fp->scopeChain != funobj));
+    memset(&frame, 0, sizeof frame);
+    frame.fun = fun;
+    frame.varobj = frame.scopeChain = funobj;
+    frame.down = fp;
+    frame.flags = JS_HAS_COMPILE_N_GO_OPTION(cx)
+                  ? JSFRAME_COMPILING | JSFRAME_COMPILE_N_GO
+                  : JSFRAME_COMPILING;
+    cx->fp = &frame;
+
+    /* Ensure that the body looks like a block statement to js_EmitTree. */
+    CURRENT_TOKEN(ts).type = TOK_LC;
+    pn = FunctionBody(cx, ts, fun, &funcg.treeContext);
+    if (!pn) {
+        ok = JS_FALSE;
+    } else {
+        /*
+         * No need to emit code here -- Statements (via FunctionBody) already
+         * has.  See similar comment in js_CompileTokenStream, and bug 108257.
+         */
+        fun->u.script = js_NewScriptFromCG(cx, &funcg, fun);
+        if (!fun->u.script) {
+            ok = JS_FALSE;
+        } else {
+            fun->interpreted = JS_TRUE;
+            if (funcg.treeContext.flags & TCF_FUN_HEAVYWEIGHT)
+                fun->flags |= JSFUN_HEAVYWEIGHT;
+            ok = JS_TRUE;
+        }
+    }
+
+    /* Restore saved state and release code generation arenas. */
+    cx->fp = fp;
+    JS_UNKEEP_ATOMS(cx->runtime);
+    js_FinishCodeGenerator(cx, &funcg);
+    JS_FinishArenaPool(&codePool);
+    JS_FinishArenaPool(&notePool);
+    return ok;
+}
+
+static JSParseNode *
+FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
+            JSBool lambda)
+{
+    JSOp op, prevop;
+    JSParseNode *pn, *body, *result;
+    JSAtom *funAtom, *objAtom, *argAtom;
+    JSStackFrame *fp;
+    JSObject *varobj, *pobj;
+    JSAtomListElement *ale;
+    JSProperty *prop;
+    JSFunction *fun;
+    uintN dupflag;
+    JSBool ok;
+    JSTreeContext funtc;
+
+    /* Make a TOK_FUNCTION node. */
+#if JS_HAS_GETTER_SETTER
+    op = CURRENT_TOKEN(ts).t_op;
+#endif
+    pn = NewParseNode(cx, ts, PN_FUNC, tc);
+    if (!pn)
+        return NULL;
+
+    /* Scan the optional function name into funAtom. */
+    funAtom = js_MatchToken(cx, ts, TOK_NAME) ? CURRENT_TOKEN(ts).t_atom : NULL;
+#if !JS_HAS_LEXICAL_CLOSURE
+    if (!funAtom && !lambda) {
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_SYNTAX_ERROR);
+        return NULL;
+    }
+#endif
+
+    /* Find the nearest variable-declaring scope and use it as our parent. */
+    fp = cx->fp;
+    varobj = fp->varobj;
+
+    /*
+     * Record names for function statements in tc->decls so we know when to
+     * avoid optimizing variable references that might name a function.
+     */
+    if (!lambda && funAtom) {
+        ATOM_LIST_SEARCH(ale, &tc->decls, funAtom);
+        if (ale) {
+            prevop = ALE_JSOP(ale);
+            if (JS_HAS_STRICT_OPTION(cx) || prevop == JSOP_DEFCONST) {
+                const char *name = js_AtomToPrintableString(cx, funAtom);
+                if (!name ||
+                    !js_ReportCompileErrorNumber(cx, ts,
+                                                 (prevop != JSOP_DEFCONST)
+                                                 ? JSREPORT_TS |
+                                                   JSREPORT_WARNING |
+                                                   JSREPORT_STRICT
+                                                 : JSREPORT_TS | JSREPORT_ERROR,
+                                                 JSMSG_REDECLARED_VAR,
+                                                 (prevop == JSOP_DEFFUN ||
+                                                  prevop == JSOP_CLOSURE)
+                                                 ? js_function_str
+                                                 : (prevop == JSOP_DEFCONST)
+                                                 ? js_const_str
+                                                 : js_var_str,
+                                                 name)) {
+                    return NULL;
+                }
+            }
+            if (tc->topStmt && prevop == JSOP_DEFVAR)
+                tc->flags |= TCF_FUN_CLOSURE_VS_VAR;
+        } else {
+            ale = js_IndexAtom(cx, funAtom, &tc->decls);
+            if (!ale)
+                return NULL;
+        }
+        ALE_SET_JSOP(ale, tc->topStmt ? JSOP_CLOSURE : JSOP_DEFFUN);
+
+#if JS_HAS_LEXICAL_CLOSURE
+        /*
+         * A function nested at top level inside another's body needs only a
+         * local variable to bind its name to its value, and not an activation
+         * object property (it might also need the activation property, if the
+         * outer function contains with statements, e.g., but the stack slot
+         * wins when jsemit.c's LookupArgOrVar can optimize a JSOP_NAME into a
+         * JSOP_GETVAR bytecode).
+         */
+        if (!tc->topStmt && (tc->flags & TCF_IN_FUNCTION)) {
+            /*
+             * Define a property on the outer function so that LookupArgOrVar
+             * can properly optimize accesses.
+             */
+            JS_ASSERT(OBJ_GET_CLASS(cx, varobj) == &js_FunctionClass);
+            JS_ASSERT(fp->fun == (JSFunction *) JS_GetPrivate(cx, varobj));
+            if (!js_LookupHiddenProperty(cx, varobj, ATOM_TO_JSID(funAtom),
+                                         &pobj, &prop)) {
+                return NULL;
+            }
+            if (prop)
+                OBJ_DROP_PROPERTY(cx, pobj, prop);
+            if (!prop ||
+                pobj != varobj ||
+                ((JSScopeProperty *)prop)->getter != js_GetLocalVariable) {
+                if (!js_AddHiddenProperty(cx, varobj, ATOM_TO_JSID(funAtom),
+                                          js_GetLocalVariable,
+                                          js_SetLocalVariable,
+                                          SPROP_INVALID_SLOT,
+                                          JSPROP_PERMANENT | JSPROP_SHARED,
+                                          SPROP_HAS_SHORTID, fp->fun->nvars)) {
+                    return NULL;
+                }
+                if (fp->fun->nvars == JS_BITMASK(16)) {
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                         JSMSG_TOO_MANY_FUN_VARS);
+                    return NULL;
+                }
+                fp->fun->nvars++;
+            }
+        }
+#endif
+    }
+
+    fun = js_NewFunction(cx, NULL, NULL, 0, lambda ? JSFUN_LAMBDA : 0, varobj,
+                         funAtom);
+    if (!fun)
+        return NULL;
+#if JS_HAS_GETTER_SETTER
+    if (op != JSOP_NOP)
+        fun->flags |= (op == JSOP_GETTER) ? JSPROP_GETTER : JSPROP_SETTER;
+#endif
+
+
+    /*
+     * Set interpreted early so js_EmitTree can test it to decide whether to
+     * eliminate useless expressions.
+     */
+    fun->interpreted = JS_TRUE;
+
+    /*
+     * Atomize fun->object early to protect against a last-ditch GC under
+     * js_LookupHiddenProperty.
+     *
+     * Absent use of the new scoped local GC roots API around compiler calls,
+     * we need to atomize here to protect against a GC activation.  Atoms are
+     * protected from GC during compilation by the JS_FRIEND_API entry points
+     * in this file.  There doesn't seem to be any gain in switching from the
+     * atom-keeping method to the bulkier, slower scoped local roots method.
+     */
+    objAtom = js_AtomizeObject(cx, fun->object, 0);
+    if (!objAtom)
+        return NULL;
+
+    /* Now parse formal argument list and compute fun->nargs. */
+    MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_FORMAL);
+    if (!js_MatchToken(cx, ts, TOK_RP)) {
+        do {
+            MUST_MATCH_TOKEN(TOK_NAME, JSMSG_MISSING_FORMAL);
+            argAtom = CURRENT_TOKEN(ts).t_atom;
+            pobj = NULL;
+            if (!js_LookupHiddenProperty(cx, fun->object, ATOM_TO_JSID(argAtom),
+                                         &pobj, &prop)) {
+                return NULL;
+            }
+            dupflag = 0;
+            if (prop) {
+                ok = JS_TRUE;
+                if (pobj == fun->object &&
+                    ((JSScopeProperty *) prop)->getter == js_GetArgument) {
+                    const char *name = js_AtomToPrintableString(cx, argAtom);
+
+                    /*
+                     * A duplicate parameter name. We force a duplicate node
+                     * on the SCOPE_LAST_PROP(scope) list with the same id,
+                     * distinguished by the SPROP_IS_DUPLICATE flag, and not
+                     * mapped by an entry in scope.
+                     */
+                    ok = name &&
+                         js_ReportCompileErrorNumber(cx, ts,
+                                                     JSREPORT_TS |
+                                                     JSREPORT_WARNING |
+                                                     JSREPORT_STRICT,
+                                                     JSMSG_DUPLICATE_FORMAL,
+                                                     name);
+
+                    dupflag = SPROP_IS_DUPLICATE;
+                }
+                OBJ_DROP_PROPERTY(cx, pobj, prop);
+                if (!ok)
+                    return NULL;
+                prop = NULL;
+            }
+            if (!js_AddHiddenProperty(cx, fun->object, ATOM_TO_JSID(argAtom),
+                                      js_GetArgument, js_SetArgument,
+                                      SPROP_INVALID_SLOT,
+                                      JSPROP_PERMANENT | JSPROP_SHARED,
+                                      dupflag | SPROP_HAS_SHORTID,
+                                      fun->nargs)) {
+                return NULL;
+            }
+            if (fun->nargs == JS_BITMASK(16)) {
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_TOO_MANY_FUN_ARGS);
+                return NULL;
+            }
+            fun->nargs++;
+        } while (js_MatchToken(cx, ts, TOK_COMMA));
+
+        MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FORMAL);
+    }
+
+    MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_BODY);
+    pn->pn_pos.begin = CURRENT_TOKEN(ts).pos.begin;
+
+    TREE_CONTEXT_INIT(&funtc);
+    body = FunctionBody(cx, ts, fun, &funtc);
+    if (!body)
+        return NULL;
+
+    MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);
+    pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+
+#if JS_HAS_LEXICAL_CLOSURE
+    /*
+     * If we collected flags that indicate nested heavyweight functions, or
+     * this function contains heavyweight-making statements (references to
+     * __parent__ or __proto__; use of with, eval, import, or export; and
+     * assignment to arguments), flag the function as heavyweight (requiring
+     * a call object per invocation).
+     */
+    if (funtc.flags & TCF_FUN_HEAVYWEIGHT) {
+        fun->flags |= JSFUN_HEAVYWEIGHT;
+        tc->flags |= TCF_FUN_HEAVYWEIGHT;
+    } else {
+        /*
+         * If this function is a named statement function not at top-level
+         * (i.e. a JSOP_CLOSURE), or if it refers to unqualified names that
+         * are not local args or vars (TCF_FUN_USES_NONLOCALS), then our
+         * enclosing function, if any, must be heavyweight.
+         */
+        if ((!lambda && funAtom && tc->topStmt) ||
+            (funtc.flags & TCF_FUN_USES_NONLOCALS)) {
+            tc->flags |= TCF_FUN_HEAVYWEIGHT;
+        }
+    }
+#endif
+
+    result = pn;
+#if JS_HAS_LEXICAL_CLOSURE
+    if (lambda) {
+        /*
+         * ECMA ed. 3 standard: function expression, possibly anonymous.
+         */
+        op = funAtom ? JSOP_NAMEDFUNOBJ : JSOP_ANONFUNOBJ;
+    } else if (!funAtom) {
+        /*
+         * If this anonymous function definition is *not* embedded within a
+         * larger expression, we treat it as an expression statement, not as
+         * a function declaration -- and not as a syntax error (as ECMA-262
+         * Edition 3 would have it).  Backward compatibility trumps all.
+         */
+        result = NewParseNode(cx, ts, PN_UNARY, tc);
+        if (!result)
+            return NULL;
+        result->pn_type = TOK_SEMI;
+        result->pn_pos = pn->pn_pos;
+        result->pn_kid = pn;
+        op = JSOP_ANONFUNOBJ;
+    } else if (tc->topStmt) {
+        /*
+         * ECMA ed. 3 extension: a function expression statement not at the
+         * top level, e.g., in a compound statement such as the "then" part
+         * of an "if" statement, binds a closure only if control reaches that
+         * sub-statement.
+         */
+        op = JSOP_CLOSURE;
+    } else
+#endif
+        op = JSOP_NOP;
+
+    pn->pn_funAtom = objAtom;
+    pn->pn_op = op;
+    pn->pn_body = body;
+    pn->pn_flags = funtc.flags & (TCF_FUN_FLAGS | TCF_HAS_DEFXMLNS);
+    pn->pn_tryCount = funtc.tryCount;
+    TREE_CONTEXT_FINISH(&funtc);
+    return result;
+}
+
+static JSParseNode *
+FunctionStmt(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    return FunctionDef(cx, ts, tc, JS_FALSE);
+}
+
+#if JS_HAS_LEXICAL_CLOSURE
+static JSParseNode *
+FunctionExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    return FunctionDef(cx, ts, tc, JS_TRUE);
+}
+#endif
+
+/*
+ * Parse the statements in a block, creating a TOK_LC node that lists the
+ * statements' trees.  If called from block-parsing code, the caller must
+ * match { before and } after.
+ */
+static JSParseNode *
+Statements(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn, *pn2;
+    JSTokenType tt;
+
+    CHECK_RECURSION();
+
+    pn = NewParseNode(cx, ts, PN_LIST, tc);
+    if (!pn)
+        return NULL;
+    PN_INIT_LIST(pn);
+
+    ts->flags |= TSF_OPERAND;
+    while ((tt = js_PeekToken(cx, ts)) > TOK_EOF && tt != TOK_RC) {
+        ts->flags &= ~TSF_OPERAND;
+        pn2 = Statement(cx, ts, tc);
+        if (!pn2) {
+            if (ts->flags & TSF_EOF)
+                ts->flags |= TSF_UNEXPECTED_EOF;
+            return NULL;
+        }
+        ts->flags |= TSF_OPERAND;
+
+        /* If compiling top-level statements, emit as we go to save space. */
+        if (!tc->topStmt && (tc->flags & TCF_COMPILING)) {
+            if (cx->fp->fun &&
+                JS_HAS_STRICT_OPTION(cx) &&
+                (tc->flags & TCF_RETURN_EXPR)) {
+                /*
+                 * Check pn2 for lack of a final return statement if it is the
+                 * last statement in the block.
+                 */
+                tt = js_PeekToken(cx, ts);
+                if ((tt == TOK_EOF || tt == TOK_RC) &&
+                    !CheckFinalReturn(cx, ts, pn2)) {
+                    tt = TOK_ERROR;
+                    break;
+                }
+
+                /*
+                 * Clear TCF_RETURN_EXPR so FunctionBody doesn't try to
+                 * CheckFinalReturn again.
+                 */
+                tc->flags &= ~TCF_RETURN_EXPR;
+            }
+            if (!js_FoldConstants(cx, pn2, tc) ||
+                !js_AllocTryNotes(cx, (JSCodeGenerator *)tc) ||
+                !js_EmitTree(cx, (JSCodeGenerator *)tc, pn2)) {
+                tt = TOK_ERROR;
+                break;
+            }
+            RecycleTree(pn2, tc);
+        } else {
+            PN_APPEND(pn, pn2);
+        }
+    }
+    ts->flags &= ~TSF_OPERAND;
+    if (tt == TOK_ERROR)
+        return NULL;
+
+    pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+    return pn;
+}
+
+static JSParseNode *
+Condition(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn, *pn2;
+
+    MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_COND);
+    pn = Expr(cx, ts, tc);
+    if (!pn)
+        return NULL;
+    MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_COND);
+
+    /*
+     * Check for (a = b) and "correct" it to (a == b) iff b's operator has
+     * greater precedence than ==.
+     * XXX not ECMA, but documented in several books -- now a strict warning.
+     */
+    if (pn->pn_type == TOK_ASSIGN &&
+        pn->pn_op == JSOP_NOP &&
+        pn->pn_right->pn_type > TOK_EQOP)
+    {
+        JSBool rewrite = !JS_VERSION_IS_ECMA(cx);
+        if (!js_ReportCompileErrorNumber(cx, ts,
+                                         JSREPORT_TS |
+                                         JSREPORT_WARNING |
+                                         JSREPORT_STRICT,
+                                         JSMSG_EQUAL_AS_ASSIGN,
+                                         rewrite
+                                         ? "\nAssuming equality test"
+                                         : "")) {
+            return NULL;
+        }
+        if (rewrite) {
+            pn->pn_type = TOK_EQOP;
+            pn->pn_op = (JSOp)cx->jsop_eq;
+            pn2 = pn->pn_left;
+            switch (pn2->pn_op) {
+              case JSOP_SETNAME:
+                pn2->pn_op = JSOP_NAME;
+                break;
+              case JSOP_SETPROP:
+                pn2->pn_op = JSOP_GETPROP;
+                break;
+              case JSOP_SETELEM:
+                pn2->pn_op = JSOP_GETELEM;
+                break;
+              default:
+                JS_ASSERT(0);
+            }
+        }
+    }
+    return pn;
+}
+
+static JSBool
+MatchLabel(JSContext *cx, JSTokenStream *ts, JSParseNode *pn)
+{
+    JSAtom *label;
+#if JS_HAS_LABEL_STATEMENT
+    JSTokenType tt;
+
+    tt = js_PeekTokenSameLine(cx, ts);
+    if (tt == TOK_ERROR)
+        return JS_FALSE;
+    if (tt == TOK_NAME) {
+        (void) js_GetToken(cx, ts);
+        label = CURRENT_TOKEN(ts).t_atom;
+    } else {
+        label = NULL;
+    }
+#else
+    label = NULL;
+#endif
+    pn->pn_atom = label;
+    return JS_TRUE;
+}
+
+#if JS_HAS_EXPORT_IMPORT
+static JSParseNode *
+ImportExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn, *pn2;
+    JSTokenType tt;
+
+    MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_IMPORT_NAME);
+    pn = NewParseNode(cx, ts, PN_NAME, tc);
+    if (!pn)
+        return NULL;
+    pn->pn_op = JSOP_NAME;
+    pn->pn_atom = CURRENT_TOKEN(ts).t_atom;
+    pn->pn_expr = NULL;
+    pn->pn_slot = -1;
+    pn->pn_attrs = 0;
+
+    ts->flags |= TSF_OPERAND;
+    while ((tt = js_GetToken(cx, ts)) == TOK_DOT || tt == TOK_LB) {
+        ts->flags &= ~TSF_OPERAND;
+        if (pn->pn_op == JSOP_IMPORTALL)
+            goto bad_import;
+
+        if (tt == TOK_DOT) {
+            pn2 = NewParseNode(cx, ts, PN_NAME, tc);
+            if (!pn2)
+                return NULL;
+            if (js_MatchToken(cx, ts, TOK_STAR)) {
+                pn2->pn_op = JSOP_IMPORTALL;
+                pn2->pn_atom = NULL;
+            } else {
+                MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT);
+                pn2->pn_op = JSOP_GETPROP;
+                pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;
+                pn2->pn_slot = -1;
+                pn2->pn_attrs = 0;
+            }
+            pn2->pn_expr = pn;
+            pn2->pn_pos.begin = pn->pn_pos.begin;
+            pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+        } else {
+            /* Make a TOK_LB binary node. */
+            pn2 = NewBinary(cx, tt, JSOP_GETELEM, pn, Expr(cx, ts, tc), tc);
+            if (!pn2)
+                return NULL;
+
+            MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX);
+        }
+
+        pn = pn2;
+        ts->flags |= TSF_OPERAND;
+    }
+    ts->flags &= ~TSF_OPERAND;
+    if (tt == TOK_ERROR)
+        return NULL;
+    js_UngetToken(ts);
+
+    switch (pn->pn_op) {
+      case JSOP_GETPROP:
+        pn->pn_op = JSOP_IMPORTPROP;
+        break;
+      case JSOP_GETELEM:
+        pn->pn_op = JSOP_IMPORTELEM;
+        break;
+      case JSOP_IMPORTALL:
+        break;
+      default:
+        goto bad_import;
+    }
+    return pn;
+
+  bad_import:
+    js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                JSMSG_BAD_IMPORT);
+    return NULL;
+}
+#endif /* JS_HAS_EXPORT_IMPORT */
+
+extern const char js_with_statement_str[];
+
+static JSParseNode *
+Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSTokenType tt;
+    JSParseNode *pn, *pn1, *pn2, *pn3, *pn4;
+    JSStmtInfo stmtInfo, *stmt, *stmt2;
+    JSAtom *label;
+
+    CHECK_RECURSION();
+
+    ts->flags |= TSF_OPERAND;
+    tt = js_GetToken(cx, ts);
+    ts->flags &= ~TSF_OPERAND;
+
+#if JS_HAS_GETTER_SETTER
+    if (tt == TOK_NAME) {
+        tt = CheckGetterOrSetter(cx, ts, TOK_FUNCTION);
+        if (tt == TOK_ERROR)
+            return NULL;
+    }
+#endif
+
+    switch (tt) {
+#if JS_HAS_EXPORT_IMPORT
+      case TOK_EXPORT:
+        pn = NewParseNode(cx, ts, PN_LIST, tc);
+        if (!pn)
+            return NULL;
+        PN_INIT_LIST(pn);
+        if (js_MatchToken(cx, ts, TOK_STAR)) {
+            pn2 = NewParseNode(cx, ts, PN_NULLARY, tc);
+            if (!pn2)
+                return NULL;
+            PN_APPEND(pn, pn2);
+        } else {
+            do {
+                MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_EXPORT_NAME);
+                pn2 = NewParseNode(cx, ts, PN_NAME, tc);
+                if (!pn2)
+                    return NULL;
+                pn2->pn_op = JSOP_NAME;
+                pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;
+                pn2->pn_expr = NULL;
+                pn2->pn_slot = -1;
+                pn2->pn_attrs = 0;
+                PN_APPEND(pn, pn2);
+            } while (js_MatchToken(cx, ts, TOK_COMMA));
+        }
+        pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
+        tc->flags |= TCF_FUN_HEAVYWEIGHT;
+        break;
+
+      case TOK_IMPORT:
+        pn = NewParseNode(cx, ts, PN_LIST, tc);
+        if (!pn)
+            return NULL;
+        PN_INIT_LIST(pn);
+        do {
+            pn2 = ImportExpr(cx, ts, tc);
+            if (!pn2)
+                return NULL;
+            PN_APPEND(pn, pn2);
+        } while (js_MatchToken(cx, ts, TOK_COMMA));
+        pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
+        tc->flags |= TCF_FUN_HEAVYWEIGHT;
+        break;
+#endif /* JS_HAS_EXPORT_IMPORT */
+
+      case TOK_FUNCTION:
+#if JS_HAS_XML_SUPPORT
+        if (js_PeekToken(cx, ts) == TOK_DBLCOLON)
+            goto expression;
+#endif
+        return FunctionStmt(cx, ts, tc);
+
+      case TOK_IF:
+        /* An IF node has three kids: condition, then, and optional else. */
+        pn = NewParseNode(cx, ts, PN_TERNARY, tc);
+        if (!pn)
+            return NULL;
+        pn1 = Condition(cx, ts, tc);
+        if (!pn1)
+            return NULL;
+        js_PushStatement(tc, &stmtInfo, STMT_IF, -1);
+        pn2 = Statement(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        if (js_MatchToken(cx, ts, TOK_ELSE)) {
+            stmtInfo.type = STMT_ELSE;
+            pn3 = Statement(cx, ts, tc);
+            if (!pn3)
+                return NULL;
+            pn->pn_pos.end = pn3->pn_pos.end;
+        } else {
+            pn3 = NULL;
+            pn->pn_pos.end = pn2->pn_pos.end;
+        }
+        js_PopStatement(tc);
+        pn->pn_kid1 = pn1;
+        pn->pn_kid2 = pn2;
+        pn->pn_kid3 = pn3;
+        return pn;
+
+#if JS_HAS_SWITCH_STATEMENT
+      case TOK_SWITCH:
+      {
+        JSParseNode *pn5;
+        JSBool seenDefault = JS_FALSE;
+
+        pn = NewParseNode(cx, ts, PN_BINARY, tc);
+        if (!pn)
+            return NULL;
+        MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_SWITCH);
+
+        /* pn1 points to the switch's discriminant. */
+        pn1 = Expr(cx, ts, tc);
+        if (!pn1)
+            return NULL;
+
+        MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_SWITCH);
+        MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_SWITCH);
+
+        /* pn2 is a list of case nodes. The default case has pn_left == NULL */
+        pn2 = NewParseNode(cx, ts, PN_LIST, tc);
+        if (!pn2)
+            return NULL;
+        PN_INIT_LIST(pn2);
+
+        js_PushStatement(tc, &stmtInfo, STMT_SWITCH, -1);
+
+        while ((tt = js_GetToken(cx, ts)) != TOK_RC) {
+            switch (tt) {
+              case TOK_DEFAULT:
+                if (seenDefault) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_TOO_MANY_DEFAULTS);
+                    return NULL;
+                }
+                seenDefault = JS_TRUE;
+                /* fall through */
+
+              case TOK_CASE:
+                pn3 = NewParseNode(cx, ts, PN_BINARY, tc);
+                if (!pn3)
+                    return NULL;
+                if (tt == TOK_DEFAULT) {
+                    pn3->pn_left = NULL;
+                } else {
+                    pn3->pn_left = Expr(cx, ts, tc);
+                    if (!pn3->pn_left)
+                        return NULL;
+                }
+                PN_APPEND(pn2, pn3);
+                if (pn2->pn_count == JS_BIT(16)) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_TOO_MANY_CASES);
+                    return NULL;
+                }
+                break;
+
+              case TOK_ERROR:
+                return NULL;
+
+              default:
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_BAD_SWITCH);
+                return NULL;
+            }
+            MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_CASE);
+
+            pn4 = NewParseNode(cx, ts, PN_LIST, tc);
+            if (!pn4)
+                return NULL;
+            pn4->pn_type = TOK_LC;
+            PN_INIT_LIST(pn4);
+            ts->flags |= TSF_OPERAND;
+            while ((tt = js_PeekToken(cx, ts)) != TOK_RC &&
+                   tt != TOK_CASE && tt != TOK_DEFAULT) {
+                ts->flags &= ~TSF_OPERAND;
+                if (tt == TOK_ERROR)
+                    return NULL;
+                pn5 = Statement(cx, ts, tc);
+                if (!pn5)
+                    return NULL;
+                pn4->pn_pos.end = pn5->pn_pos.end;
+                PN_APPEND(pn4, pn5);
+                ts->flags |= TSF_OPERAND;
+            }
+            ts->flags &= ~TSF_OPERAND;
+
+            /* Fix the PN_LIST so it doesn't begin at the TOK_COLON. */
+            if (pn4->pn_head)
+                pn4->pn_pos.begin = pn4->pn_head->pn_pos.begin;
+            pn3->pn_pos.end = pn4->pn_pos.end;
+            pn3->pn_right = pn4;
+        }
+
+        js_PopStatement(tc);
+
+        pn->pn_pos.end = pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+        pn->pn_kid1 = pn1;
+        pn->pn_kid2 = pn2;
+        return pn;
+      }
+#endif /* JS_HAS_SWITCH_STATEMENT */
+
+      case TOK_WHILE:
+        pn = NewParseNode(cx, ts, PN_BINARY, tc);
+        if (!pn)
+            return NULL;
+        js_PushStatement(tc, &stmtInfo, STMT_WHILE_LOOP, -1);
+        pn2 = Condition(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        pn->pn_left = pn2;
+        pn2 = Statement(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        js_PopStatement(tc);
+        pn->pn_pos.end = pn2->pn_pos.end;
+        pn->pn_right = pn2;
+        return pn;
+
+#if JS_HAS_DO_WHILE_LOOP
+      case TOK_DO:
+        pn = NewParseNode(cx, ts, PN_BINARY, tc);
+        if (!pn)
+            return NULL;
+        js_PushStatement(tc, &stmtInfo, STMT_DO_LOOP, -1);
+        pn2 = Statement(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        pn->pn_left = pn2;
+        MUST_MATCH_TOKEN(TOK_WHILE, JSMSG_WHILE_AFTER_DO);
+        pn2 = Condition(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        js_PopStatement(tc);
+        pn->pn_pos.end = pn2->pn_pos.end;
+        pn->pn_right = pn2;
+        if ((cx->version & JSVERSION_MASK) != JSVERSION_ECMA_3) {
+            /*
+             * All legacy and extended versions must do automatic semicolon
+             * insertion after do-while.  See the testcase and discussion in
+             * http://bugzilla.mozilla.org/show_bug.cgi?id=238945.
+             */
+            (void) js_MatchToken(cx, ts, TOK_SEMI);
+            return pn;
+        }
+        break;
+#endif /* JS_HAS_DO_WHILE_LOOP */
+
+      case TOK_FOR:
+        /* A FOR node is binary, left is loop control and right is the body. */
+        pn = NewParseNode(cx, ts, PN_BINARY, tc);
+        if (!pn)
+            return NULL;
+        js_PushStatement(tc, &stmtInfo, STMT_FOR_LOOP, -1);
+
+#if JS_HAS_XML_SUPPORT
+        pn->pn_op = JSOP_NOP;
+        if (js_MatchToken(cx, ts, TOK_NAME)) {
+            if (CURRENT_TOKEN(ts).t_atom == cx->runtime->atomState.eachAtom)
+                pn->pn_op = JSOP_FOREACH;
+            else
+                js_UngetToken(ts);
+        }
+#endif
+
+        MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);
+        ts->flags |= TSF_OPERAND;
+        tt = js_PeekToken(cx, ts);
+        ts->flags &= ~TSF_OPERAND;
+        if (tt == TOK_SEMI) {
+#if JS_HAS_XML_SUPPORT
+            if (pn->pn_op == JSOP_FOREACH)
+                goto bad_for_each;
+#endif
+
+            /* No initializer -- set first kid of left sub-node to null. */
+            pn1 = NULL;
+        } else {
+            /* Set pn1 to a var list or an initializing expression. */
+#if JS_HAS_IN_OPERATOR
+            /*
+             * Set the TCF_IN_FOR_INIT flag during parsing of the first clause
+             * of the for statement.  This flag will be used by the RelExpr
+             * production; if it is set, then the 'in' keyword will not be
+             * recognized as an operator, leaving it available to be parsed as
+             * part of a for/in loop.  A side effect of this restriction is
+             * that (unparenthesized) expressions involving an 'in' operator
+             * are illegal in the init clause of an ordinary for loop.
+             */
+            tc->flags |= TCF_IN_FOR_INIT;
+#endif /* JS_HAS_IN_OPERATOR */
+            if (tt == TOK_VAR) {
+                (void) js_GetToken(cx, ts);
+                pn1 = Variables(cx, ts, tc);
+            } else {
+                pn1 = Expr(cx, ts, tc);
+            }
+#if JS_HAS_IN_OPERATOR
+            tc->flags &= ~TCF_IN_FOR_INIT;
+#endif /* JS_HAS_IN_OPERATOR */
+            if (!pn1)
+                return NULL;
+        }
+
+        /*
+         * We can be sure that it's a for/in loop if there's still an 'in'
+         * keyword here, even if JavaScript recognizes 'in' as an operator,
+         * as we've excluded 'in' from being parsed in RelExpr by setting
+         * the TCF_IN_FOR_INIT flag in our JSTreeContext.
+         */
+        if (pn1 && js_MatchToken(cx, ts, TOK_IN)) {
+            stmtInfo.type = STMT_FOR_IN_LOOP;
+
+            /* Check that the left side of the 'in' is valid. */
+            while (pn1->pn_type == TOK_RP)
+                pn1 = pn1->pn_kid;
+            if ((pn1->pn_type == TOK_VAR)
+                ? (pn1->pn_count > 1 || pn1->pn_op == JSOP_DEFCONST)
+                : (pn1->pn_type != TOK_NAME &&
+                   pn1->pn_type != TOK_DOT &&
+#if JS_HAS_LVALUE_RETURN
+                   pn1->pn_type != TOK_LP &&
+#endif
+#if JS_HAS_XML_SUPPORT
+                   (pn1->pn_type != TOK_UNARYOP ||
+                    pn1->pn_op != JSOP_XMLNAME) &&
+#endif
+                   pn1->pn_type != TOK_LB)) {
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_BAD_FOR_LEFTSIDE);
+                return NULL;
+            }
+
+            if (pn1->pn_type == TOK_VAR) {
+                /* Tell js_EmitTree(TOK_VAR) that pn1 is part of a for/in. */
+                pn1->pn_extra |= PNX_FORINVAR;
+
+                /* Generate a final POP only if the var has an initializer. */
+                pn2 = pn1->pn_head;
+                if (pn2->pn_expr)
+                    pn1->pn_extra |= PNX_POPVAR;
+            } else {
+                pn2 = pn1;
+#if JS_HAS_LVALUE_RETURN
+                if (pn2->pn_type == TOK_LP)
+                    pn2->pn_op = JSOP_SETCALL;
+#endif
+#if JS_HAS_XML_SUPPORT
+                if (pn2->pn_type == TOK_UNARYOP)
+                    pn2->pn_op = JSOP_BINDXMLNAME;
+#endif
+            }
+
+            /* Beware 'for (arguments in ...)' with or without a 'var'. */
+            if (pn2->pn_type == TOK_NAME &&
+                pn2->pn_atom == cx->runtime->atomState.argumentsAtom) {
+                tc->flags |= TCF_FUN_HEAVYWEIGHT;
+            }
+
+            /* Parse the object expression as the right operand of 'in'. */
+            pn2 = NewBinary(cx, TOK_IN, JSOP_NOP, pn1, Expr(cx, ts, tc), tc);
+            if (!pn2)
+                return NULL;
+            pn->pn_left = pn2;
+        } else {
+#if JS_HAS_XML_SUPPORT
+            if (pn->pn_op == JSOP_FOREACH)
+                goto bad_for_each;
+#endif
+
+            /* Parse the loop condition or null into pn2. */
+            MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_INIT);
+            ts->flags |= TSF_OPERAND;
+            tt = js_PeekToken(cx, ts);
+            ts->flags &= ~TSF_OPERAND;
+            if (tt == TOK_SEMI) {
+                pn2 = NULL;
+            } else {
+                pn2 = Expr(cx, ts, tc);
+                if (!pn2)
+                    return NULL;
+            }
+
+            /* Parse the update expression or null into pn3. */
+            MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_COND);
+            ts->flags |= TSF_OPERAND;
+            tt = js_PeekToken(cx, ts);
+            ts->flags &= ~TSF_OPERAND;
+            if (tt == TOK_RP) {
+                pn3 = NULL;
+            } else {
+                pn3 = Expr(cx, ts, tc);
+                if (!pn3)
+                    return NULL;
+            }
+
+            /* Build the RESERVED node to use as the left kid of pn. */
+            pn4 = NewParseNode(cx, ts, PN_TERNARY, tc);
+            if (!pn4)
+                return NULL;
+            pn4->pn_type = TOK_RESERVED;
+            pn4->pn_op = JSOP_NOP;
+            pn4->pn_kid1 = pn1;
+            pn4->pn_kid2 = pn2;
+            pn4->pn_kid3 = pn3;
+            pn->pn_left = pn4;
+        }
+
+        MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FOR_CTRL);
+
+        /* Parse the loop body into pn->pn_right. */
+        pn2 = Statement(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        pn->pn_right = pn2;
+        js_PopStatement(tc);
+
+        /* Record the absolute line number for source note emission. */
+        pn->pn_pos.end = pn2->pn_pos.end;
+        return pn;
+
+#if JS_HAS_XML_SUPPORT
+      bad_for_each:
+        js_ReportCompileErrorNumber(cx, pn,
+                                    JSREPORT_PN | JSREPORT_ERROR,
+                                    JSMSG_BAD_FOR_EACH_LOOP);
+        return NULL;
+#endif
+
+#if JS_HAS_EXCEPTIONS
+      case TOK_TRY: {
+        JSParseNode *catchtail = NULL;
+        /*
+         * try nodes are ternary.
+         * kid1 is the try Statement
+         * kid2 is the catch node
+         * kid3 is the finally Statement
+         *
+         * catch nodes are ternary.
+         * kid1 is the discriminant
+         * kid2 is the next catch node, or NULL
+         * kid3 is the catch block (on kid3 so that we can always append a
+         *                          new catch pn on catchtail->kid2)
+         *
+         * catch discriminant nodes are binary
+         * atom is the receptacle
+         * expr is the discriminant code
+         *
+         * finally nodes are unary (just the finally expression)
+         */
+        pn = NewParseNode(cx, ts, PN_TERNARY, tc);
+        pn->pn_op = JSOP_NOP;
+
+        MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_TRY);
+        js_PushStatement(tc, &stmtInfo, STMT_TRY, -1);
+        pn->pn_kid1 = Statements(cx, ts, tc);
+        if (!pn->pn_kid1)
+            return NULL;
+        MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_TRY);
+        js_PopStatement(tc);
+
+        catchtail = pn;
+        while (js_PeekToken(cx, ts) == TOK_CATCH) {
+            /* check for another catch after unconditional catch */
+            if (catchtail != pn && !catchtail->pn_kid1->pn_expr) {
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_CATCH_AFTER_GENERAL);
+                return NULL;
+            }
+
+            /*
+             * legal catch forms are:
+             * catch (v)
+             * catch (v if <boolean_expression>)
+             * (the latter is legal only #ifdef JS_HAS_CATCH_GUARD)
+             */
+            (void) js_GetToken(cx, ts); /* eat `catch' */
+            pn2 = NewParseNode(cx, ts, PN_TERNARY, tc);
+            if (!pn2)
+                return NULL;
+
+            /*
+             * We use a PN_NAME for the discriminant (catchguard) node
+             * with the actual discriminant code in the initializer spot
+             */
+            MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_CATCH);
+            MUST_MATCH_TOKEN(TOK_NAME, JSMSG_CATCH_IDENTIFIER);
+            pn3 = NewParseNode(cx, ts, PN_NAME, tc);
+            if (!pn3)
+                return NULL;
+
+            pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
+            pn3->pn_expr = NULL;
+#if JS_HAS_CATCH_GUARD
+            /*
+             * We use `catch (x if x === 5)' (not `catch (x : x === 5)') to
+             * avoid conflicting with the JS2/ECMA2 proposed catchguard syntax.
+             */
+            if (js_PeekToken(cx, ts) == TOK_IF) {
+                (void)js_GetToken(cx, ts); /* eat `if' */
+                pn3->pn_expr = Expr(cx, ts, tc);
+                if (!pn3->pn_expr)
+                    return NULL;
+            }
+#endif
+            pn2->pn_kid1 = pn3;
+
+            MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_CATCH);
+
+            MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_CATCH);
+            js_PushStatement(tc, &stmtInfo, STMT_CATCH, -1);
+            stmtInfo.label = pn3->pn_atom;
+            pn2->pn_kid3 = Statements(cx, ts, tc);
+            if (!pn2->pn_kid3)
+                return NULL;
+            MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_CATCH);
+            js_PopStatement(tc);
+
+            catchtail = catchtail->pn_kid2 = pn2;
+        }
+        catchtail->pn_kid2 = NULL;
+
+        if (js_MatchToken(cx, ts, TOK_FINALLY)) {
+            tc->tryCount++;
+            MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_FINALLY);
+            js_PushStatement(tc, &stmtInfo, STMT_FINALLY, -1);
+            pn->pn_kid3 = Statements(cx, ts, tc);
+            if (!pn->pn_kid3)
+                return NULL;
+            MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_FINALLY);
+            js_PopStatement(tc);
+        } else {
+            pn->pn_kid3 = NULL;
+        }
+        if (!pn->pn_kid2 && !pn->pn_kid3) {
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_CATCH_OR_FINALLY);
+            return NULL;
+        }
+        tc->tryCount++;
+        return pn;
+      }
+
+      case TOK_THROW:
+        pn = NewParseNode(cx, ts, PN_UNARY, tc);
+        if (!pn)
+            return NULL;
+
+        /* ECMA-262 Edition 3 says 'throw [no LineTerminator here] Expr'. */
+        ts->flags |= TSF_OPERAND;
+        tt = js_PeekTokenSameLine(cx, ts);
+        ts->flags &= ~TSF_OPERAND;
+        if (tt == TOK_ERROR)
+            return NULL;
+        if (tt == TOK_EOF || tt == TOK_EOL || tt == TOK_SEMI || tt == TOK_RC) {
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_SYNTAX_ERROR);
+            return NULL;
+        }
+
+        pn2 = Expr(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        pn->pn_pos.end = pn2->pn_pos.end;
+        pn->pn_op = JSOP_THROW;
+        pn->pn_kid = pn2;
+        break;
+
+      /* TOK_CATCH and TOK_FINALLY are both handled in the TOK_TRY case */
+      case TOK_CATCH:
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_CATCH_WITHOUT_TRY);
+        return NULL;
+
+      case TOK_FINALLY:
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_FINALLY_WITHOUT_TRY);
+        return NULL;
+
+#endif /* JS_HAS_EXCEPTIONS */
+
+      case TOK_BREAK:
+        pn = NewParseNode(cx, ts, PN_NULLARY, tc);
+        if (!pn)
+            return NULL;
+        if (!MatchLabel(cx, ts, pn))
+            return NULL;
+        stmt = tc->topStmt;
+        label = pn->pn_atom;
+        if (label) {
+            for (; ; stmt = stmt->down) {
+                if (!stmt) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_LABEL_NOT_FOUND);
+                    return NULL;
+                }
+                if (stmt->type == STMT_LABEL && stmt->label == label)
+                    break;
+            }
+        } else {
+            for (; ; stmt = stmt->down) {
+                if (!stmt) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_TOUGH_BREAK);
+                    return NULL;
+                }
+                if (STMT_IS_LOOP(stmt) || stmt->type == STMT_SWITCH)
+                    break;
+            }
+        }
+        if (label)
+            pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+        break;
+
+      case TOK_CONTINUE:
+        pn = NewParseNode(cx, ts, PN_NULLARY, tc);
+        if (!pn)
+            return NULL;
+        if (!MatchLabel(cx, ts, pn))
+            return NULL;
+        stmt = tc->topStmt;
+        label = pn->pn_atom;
+        if (label) {
+            for (stmt2 = NULL; ; stmt = stmt->down) {
+                if (!stmt) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_LABEL_NOT_FOUND);
+                    return NULL;
+                }
+                if (stmt->type == STMT_LABEL) {
+                    if (stmt->label == label) {
+                        if (!stmt2 || !STMT_IS_LOOP(stmt2)) {
+                            js_ReportCompileErrorNumber(cx, ts,
+                                                        JSREPORT_TS |
+                                                        JSREPORT_ERROR,
+                                                        JSMSG_BAD_CONTINUE);
+                            return NULL;
+                        }
+                        break;
+                    }
+                } else {
+                    stmt2 = stmt;
+                }
+            }
+        } else {
+            for (; ; stmt = stmt->down) {
+                if (!stmt) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_BAD_CONTINUE);
+                    return NULL;
+                }
+                if (STMT_IS_LOOP(stmt))
+                    break;
+            }
+        }
+        if (label)
+            pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+        break;
+
+      case TOK_WITH:
+        if (!js_ReportCompileErrorNumber(cx, ts,
+                                         JSREPORT_TS |
+                                         JSREPORT_WARNING |
+                                         JSREPORT_STRICT,
+                                         JSMSG_DEPRECATED_USAGE,
+                                         js_with_statement_str)) {
+            return NULL;
+        }
+
+        pn = NewParseNode(cx, ts, PN_BINARY, tc);
+        if (!pn)
+            return NULL;
+        MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_WITH);
+        pn2 = Expr(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_WITH);
+        pn->pn_left = pn2;
+
+        js_PushStatement(tc, &stmtInfo, STMT_WITH, -1);
+        pn2 = Statement(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        js_PopStatement(tc);
+
+        pn->pn_pos.end = pn2->pn_pos.end;
+        pn->pn_right = pn2;
+        tc->flags |= TCF_FUN_HEAVYWEIGHT;
+        return pn;
+
+      case TOK_VAR:
+        pn = Variables(cx, ts, tc);
+        if (!pn)
+            return NULL;
+
+        /* Tell js_EmitTree to generate a final POP. */
+        pn->pn_extra |= PNX_POPVAR;
+        break;
+
+      case TOK_RETURN:
+        if (!(tc->flags & TCF_IN_FUNCTION)) {
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_BAD_RETURN);
+            return NULL;
+        }
+        pn = NewParseNode(cx, ts, PN_UNARY, tc);
+        if (!pn)
+            return NULL;
+
+        /* This is ugly, but we don't want to require a semicolon. */
+        ts->flags |= TSF_OPERAND;
+        tt = js_PeekTokenSameLine(cx, ts);
+        ts->flags &= ~TSF_OPERAND;
+        if (tt == TOK_ERROR)
+            return NULL;
+
+        if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
+            pn2 = Expr(cx, ts, tc);
+            if (!pn2)
+                return NULL;
+            tc->flags |= TCF_RETURN_EXPR;
+            pn->pn_pos.end = pn2->pn_pos.end;
+            pn->pn_kid = pn2;
+        } else {
+            tc->flags |= TCF_RETURN_VOID;
+            pn->pn_kid = NULL;
+        }
+
+        if (JS_HAS_STRICT_OPTION(cx) &&
+            (~tc->flags & (TCF_RETURN_EXPR | TCF_RETURN_VOID)) == 0) {
+            /*
+             * We must be in a frame with a non-native function, because
+             * we're compiling one.
+             */
+            if (!ReportNoReturnValue(cx, ts))
+                return NULL;
+        }
+        break;
+
+      case TOK_LC:
+        js_PushStatement(tc, &stmtInfo, STMT_BLOCK, -1);
+        pn = Statements(cx, ts, tc);
+        if (!pn)
+            return NULL;
+
+        MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_IN_COMPOUND);
+        js_PopStatement(tc);
+        return pn;
+
+      case TOK_EOL:
+      case TOK_SEMI:
+        pn = NewParseNode(cx, ts, PN_UNARY, tc);
+        if (!pn)
+            return NULL;
+        pn->pn_type = TOK_SEMI;
+        pn->pn_kid = NULL;
+        return pn;
+
+#if JS_HAS_DEBUGGER_KEYWORD
+      case TOK_DEBUGGER:
+        pn = NewParseNode(cx, ts, PN_NULLARY, tc);
+        if (!pn)
+            return NULL;
+        pn->pn_type = TOK_DEBUGGER;
+        tc->flags |= TCF_FUN_HEAVYWEIGHT;
+        break;
+#endif /* JS_HAS_DEBUGGER_KEYWORD */
+
+#if JS_HAS_XML_SUPPORT
+      case TOK_DEFAULT:
+        pn = NewParseNode(cx, ts, PN_UNARY, tc);
+        if (!pn)
+            return NULL;
+        if (!js_MatchToken(cx, ts, TOK_NAME) ||
+            CURRENT_TOKEN(ts).t_atom != cx->runtime->atomState.xmlAtom ||
+            !js_MatchToken(cx, ts, TOK_NAME) ||
+            CURRENT_TOKEN(ts).t_atom != cx->runtime->atomState.namespaceAtom ||
+            !js_MatchToken(cx, ts, TOK_ASSIGN) ||
+            CURRENT_TOKEN(ts).t_op != JSOP_NOP) {
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_BAD_DEFAULT_XML_NAMESPACE);
+            return NULL;
+        }
+        pn2 = Expr(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        pn->pn_op = JSOP_DEFXMLNS;
+        pn->pn_pos.end = pn2->pn_pos.end;
+        pn->pn_kid = pn2;
+        tc->flags |= TCF_HAS_DEFXMLNS;
+        break;
+#endif
+
+      case TOK_ERROR:
+        return NULL;
+
+      default:
+#if JS_HAS_XML_SUPPORT
+      expression:
+#endif
+        js_UngetToken(ts);
+        pn2 = Expr(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+
+        if (js_PeekToken(cx, ts) == TOK_COLON) {
+            if (pn2->pn_type != TOK_NAME) {
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_BAD_LABEL);
+                return NULL;
+            }
+            label = pn2->pn_atom;
+            for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
+                if (stmt->type == STMT_LABEL && stmt->label == label) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_DUPLICATE_LABEL);
+                    return NULL;
+                }
+            }
+            (void) js_GetToken(cx, ts);
+
+            /* Push a label struct and parse the statement. */
+            js_PushStatement(tc, &stmtInfo, STMT_LABEL, -1);
+            stmtInfo.label = label;
+            pn = Statement(cx, ts, tc);
+            if (!pn)
+                return NULL;
+
+            /* Pop the label, set pn_expr, and return early. */
+            js_PopStatement(tc);
+            pn2->pn_type = TOK_COLON;
+            pn2->pn_pos.end = pn->pn_pos.end;
+            pn2->pn_expr = pn;
+            return pn2;
+        }
+
+        pn = NewParseNode(cx, ts, PN_UNARY, tc);
+        if (!pn)
+            return NULL;
+        pn->pn_type = TOK_SEMI;
+        pn->pn_pos = pn2->pn_pos;
+        pn->pn_kid = pn2;
+        break;
+    }
+
+    /* Check termination of this primitive statement. */
+    if (ON_CURRENT_LINE(ts, pn->pn_pos)) {
+        tt = js_PeekTokenSameLine(cx, ts);
+        if (tt == TOK_ERROR)
+            return NULL;
+        if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_SEMI_BEFORE_STMNT);
+            return NULL;
+        }
+    }
+
+    (void) js_MatchToken(cx, ts, TOK_SEMI);
+    return pn;
+}
+
+static JSParseNode *
+Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn, *pn2;
+    JSObject *obj, *pobj;
+    JSStackFrame *fp;
+    JSFunction *fun;
+    JSClass *clasp;
+    JSPropertyOp getter, setter, currentGetter, currentSetter;
+    JSAtom *atom;
+    JSAtomListElement *ale;
+    JSOp prevop;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+    JSBool ok;
+
+    /*
+     * The tricky part of this code is to create special parsenode opcodes for
+     * getting and setting variables (which will be stored as special slots in
+     * the frame).  The complex special case is an eval() inside a function.
+     * If the evaluated string references variables in the enclosing function,
+     * then we need to generate the special variable opcodes.  We determine
+     * this by looking up the variable id in the current variable scope.
+     */
+    JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_VAR);
+    pn = NewParseNode(cx, ts, PN_LIST, tc);
+    if (!pn)
+        return NULL;
+    pn->pn_op = CURRENT_TOKEN(ts).t_op;
+    PN_INIT_LIST(pn);
+
+    /*
+     * Skip eval and debugger frames when looking for the function whose code
+     * is being compiled.  If we are called from FunctionBody, TCF_IN_FUNCTION
+     * will be set in tc->flags, and we can be sure fp->fun is the function to
+     * use.  But if a function calls eval, the string argument is treated as a
+     * Program (per ECMA), so TCF_IN_FUNCTION won't be set.
+     *
+     * What's more, when the following code is reached from eval, cx->fp->fun
+     * is eval's JSFunction (a native function), so we need to skip its frame.
+     * We should find the scripted caller's function frame just below it, but
+     * we code a loop out of paranoia.
+     */
+    for (fp = cx->fp; (fp->flags & JSFRAME_SPECIAL) && fp->down; fp = fp->down)
+        continue;
+    obj = fp->varobj;
+    fun = fp->fun;
+    clasp = OBJ_GET_CLASS(cx, obj);
+    if (fun && clasp == &js_FunctionClass) {
+        /* We are compiling code inside a function */
+        getter = js_GetLocalVariable;
+        setter = js_SetLocalVariable;
+    } else if (fun && clasp == &js_CallClass) {
+        /* We are compiling code from an eval inside a function */
+        getter = js_GetCallVariable;
+        setter = js_SetCallVariable;
+    } else {
+        getter = clasp->getProperty;
+        setter = clasp->setProperty;
+    }
+
+    ok = JS_TRUE;
+    do {
+        currentGetter = getter;
+        currentSetter = setter;
+        MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_VARIABLE_NAME);
+        atom = CURRENT_TOKEN(ts).t_atom;
+
+        ATOM_LIST_SEARCH(ale, &tc->decls, atom);
+        if (ale) {
+            prevop = ALE_JSOP(ale);
+            if (JS_HAS_STRICT_OPTION(cx)
+                ? pn->pn_op != JSOP_DEFVAR || prevop != JSOP_DEFVAR
+                : pn->pn_op == JSOP_DEFCONST || prevop == JSOP_DEFCONST) {
+                const char *name = js_AtomToPrintableString(cx, atom);
+                if (!name ||
+                    !js_ReportCompileErrorNumber(cx, ts,
+                                                 (pn->pn_op != JSOP_DEFCONST &&
+                                                  prevop != JSOP_DEFCONST)
+                                                 ? JSREPORT_TS |
+                                                   JSREPORT_WARNING |
+                                                   JSREPORT_STRICT
+                                                 : JSREPORT_TS | JSREPORT_ERROR,
+                                                 JSMSG_REDECLARED_VAR,
+                                                 (prevop == JSOP_DEFFUN ||
+                                                  prevop == JSOP_CLOSURE)
+                                                 ? js_function_str
+                                                 : (prevop == JSOP_DEFCONST)
+                                                 ? js_const_str
+                                                 : js_var_str,
+                                                 name)) {
+                    return NULL;
+                }
+            }
+            if (pn->pn_op == JSOP_DEFVAR && prevop == JSOP_CLOSURE)
+                tc->flags |= TCF_FUN_CLOSURE_VS_VAR;
+        } else {
+            ale = js_IndexAtom(cx, atom, &tc->decls);
+            if (!ale)
+                return NULL;
+        }
+        ALE_SET_JSOP(ale, pn->pn_op);
+
+        pn2 = NewParseNode(cx, ts, PN_NAME, tc);
+        if (!pn2)
+            return NULL;
+        pn2->pn_op = JSOP_NAME;
+        pn2->pn_atom = atom;
+        pn2->pn_expr = NULL;
+        pn2->pn_slot = -1;
+        pn2->pn_attrs = (pn->pn_op == JSOP_DEFCONST)
+                        ? JSPROP_PERMANENT | JSPROP_READONLY
+                        : JSPROP_PERMANENT;
+        PN_APPEND(pn, pn2);
+
+        if (!fun) {
+            /* Don't lookup global variables at compile time. */
+            prop = NULL;
+        } else if (OBJ_IS_NATIVE(obj)) {
+            if (!js_LookupHiddenProperty(cx, obj, ATOM_TO_JSID(atom),
+                                         &pobj, &prop)) {
+                return NULL;
+            }
+        } else {
+            if (!OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &pobj, &prop))
+                return NULL;
+        }
+        if (prop && pobj == obj && OBJ_IS_NATIVE(pobj)) {
+            sprop = (JSScopeProperty *)prop;
+            if (sprop->getter == js_GetArgument) {
+                const char *name = js_AtomToPrintableString(cx, atom);
+                if (!name) {
+                    ok = JS_FALSE;
+                } else if (pn->pn_op == JSOP_DEFCONST) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_REDECLARED_PARAM,
+                                                name);
+                    ok = JS_FALSE;
+                } else {
+                    currentGetter = js_GetArgument;
+                    currentSetter = js_SetArgument;
+                    ok = js_ReportCompileErrorNumber(cx, ts,
+                                                     JSREPORT_TS |
+                                                     JSREPORT_WARNING |
+                                                     JSREPORT_STRICT,
+                                                     JSMSG_VAR_HIDES_ARG,
+                                                     name);
+                }
+            } else {
+                if (fun) {
+                    /* Not an argument, must be a redeclared local var. */
+                    if (clasp == &js_FunctionClass) {
+                        JS_ASSERT(sprop->getter == js_GetLocalVariable);
+                        JS_ASSERT((sprop->flags & SPROP_HAS_SHORTID) &&
+                                  (uint16) sprop->shortid < fun->nvars);
+                    } else if (clasp == &js_CallClass) {
+                        if (sprop->getter == js_GetCallVariable) {
+                            /*
+                             * Referencing a variable introduced by a var
+                             * statement in the enclosing function. Check
+                             * that the slot number we have is in range.
+                             */
+                            JS_ASSERT((sprop->flags & SPROP_HAS_SHORTID) &&
+                                      (uint16) sprop->shortid < fun->nvars);
+                        } else {
+                            /*
+                             * A variable introduced through another eval:
+                             * don't use the special getters and setters
+                             * since we can't allocate a slot in the frame.
+                             */
+                            currentGetter = sprop->getter;
+                            currentSetter = sprop->setter;
+                        }
+                    }
+
+                    /* Override the old getter and setter, to handle eval. */
+                    sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop,
+                                                         0, sprop->attrs,
+                                                         currentGetter,
+                                                         currentSetter);
+                    if (!sprop)
+                        ok = JS_FALSE;
+                }
+            }
+        } else {
+            /*
+             * Property not found in current variable scope: we have not seen
+             * this variable before.  Define a new local variable by adding a
+             * property to the function's scope, allocating one slot in the
+             * function's frame.  Global variables and any locals declared in
+             * with statement bodies are handled at runtime, by script prolog
+             * JSOP_DEFVAR bytecodes generated for slot-less vars.
+             */
+            sprop = NULL;
+            if (prop) {
+                OBJ_DROP_PROPERTY(cx, pobj, prop);
+                prop = NULL;
+            }
+            if (currentGetter == js_GetCallVariable) {
+                /* Can't increase fun->nvars in an active frame! */
+                currentGetter = clasp->getProperty;
+                currentSetter = clasp->setProperty;
+            }
+            if (currentGetter == js_GetLocalVariable &&
+                atom != cx->runtime->atomState.argumentsAtom &&
+                fp->scopeChain == obj &&
+                !js_InWithStatement(tc)) {
+                if (!js_AddHiddenProperty(cx, obj, ATOM_TO_JSID(atom),
+                                          currentGetter, currentSetter,
+                                          SPROP_INVALID_SLOT,
+                                          pn2->pn_attrs | JSPROP_SHARED,
+                                          SPROP_HAS_SHORTID, fun->nvars)) {
+                    return NULL;
+                }
+                if (fun->nvars == JS_BITMASK(16)) {
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                         JSMSG_TOO_MANY_FUN_VARS);
+                    return NULL;
+                }
+                fun->nvars++;
+            }
+        }
+
+        if (js_MatchToken(cx, ts, TOK_ASSIGN)) {
+            if (CURRENT_TOKEN(ts).t_op != JSOP_NOP) {
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_BAD_VAR_INIT);
+                ok = JS_FALSE;
+            } else {
+                pn2->pn_expr = AssignExpr(cx, ts, tc);
+                if (!pn2->pn_expr) {
+                    ok = JS_FALSE;
+                } else {
+                    pn2->pn_op = (pn->pn_op == JSOP_DEFCONST)
+                                 ? JSOP_SETCONST
+                                 : JSOP_SETNAME;
+                    if (atom == cx->runtime->atomState.argumentsAtom)
+                        tc->flags |= TCF_FUN_HEAVYWEIGHT;
+                }
+            }
+        }
+
+        if (prop)
+            OBJ_DROP_PROPERTY(cx, pobj, prop);
+        if (!ok)
+            return NULL;
+    } while (js_MatchToken(cx, ts, TOK_COMMA));
+
+    pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
+    return pn;
+}
+
+static JSParseNode *
+Expr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn, *pn2;
+
+    pn = AssignExpr(cx, ts, tc);
+    if (pn && js_MatchToken(cx, ts, TOK_COMMA)) {
+        pn2 = NewParseNode(cx, ts, PN_LIST, tc);
+        if (!pn2)
+            return NULL;
+        pn2->pn_pos.begin = pn->pn_pos.begin;
+        PN_INIT_LIST_1(pn2, pn);
+        pn = pn2;
+        do {
+            pn2 = AssignExpr(cx, ts, tc);
+            if (!pn2)
+                return NULL;
+            PN_APPEND(pn, pn2);
+        } while (js_MatchToken(cx, ts, TOK_COMMA));
+        pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
+    }
+    return pn;
+}
+
+static JSParseNode *
+AssignExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn, *pn2;
+    JSTokenType tt;
+    JSOp op;
+
+    CHECK_RECURSION();
+
+    pn = CondExpr(cx, ts, tc);
+    if (!pn)
+        return NULL;
+
+    tt = js_GetToken(cx, ts);
+#if JS_HAS_GETTER_SETTER
+    if (tt == TOK_NAME) {
+        tt = CheckGetterOrSetter(cx, ts, TOK_ASSIGN);
+        if (tt == TOK_ERROR)
+            return NULL;
+    }
+#endif
+    if (tt != TOK_ASSIGN) {
+        js_UngetToken(ts);
+        return pn;
+    }
+
+    op = CURRENT_TOKEN(ts).t_op;
+    for (pn2 = pn; pn2->pn_type == TOK_RP; pn2 = pn2->pn_kid)
+        continue;
+    switch (pn2->pn_type) {
+      case TOK_NAME:
+        pn2->pn_op = JSOP_SETNAME;
+        if (pn2->pn_atom == cx->runtime->atomState.argumentsAtom)
+            tc->flags |= TCF_FUN_HEAVYWEIGHT;
+        break;
+      case TOK_DOT:
+        pn2->pn_op = (pn2->pn_op == JSOP_GETMETHOD)
+                     ? JSOP_SETMETHOD
+                     : JSOP_SETPROP;
+        break;
+      case TOK_LB:
+        pn2->pn_op = JSOP_SETELEM;
+        break;
+#if JS_HAS_LVALUE_RETURN
+      case TOK_LP:
+        pn2->pn_op = JSOP_SETCALL;
+        break;
+#endif
+#if JS_HAS_XML_SUPPORT
+      case TOK_UNARYOP:
+        if (pn2->pn_op == JSOP_XMLNAME) {
+            pn2->pn_op = JSOP_SETXMLNAME;
+            break;
+        }
+        /* FALL THROUGH */
+#endif
+      default:
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_BAD_LEFTSIDE_OF_ASS);
+        return NULL;
+    }
+    pn = NewBinary(cx, TOK_ASSIGN, op, pn2, AssignExpr(cx, ts, tc), tc);
+    return pn;
+}
+
+static JSParseNode *
+CondExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn, *pn1, *pn2, *pn3;
+#if JS_HAS_IN_OPERATOR
+    uintN oldflags;
+#endif /* JS_HAS_IN_OPERATOR */
+
+    pn = OrExpr(cx, ts, tc);
+    if (pn && js_MatchToken(cx, ts, TOK_HOOK)) {
+        pn1 = pn;
+        pn = NewParseNode(cx, ts, PN_TERNARY, tc);
+        if (!pn)
+            return NULL;
+#if JS_HAS_IN_OPERATOR
+        /*
+         * Always accept the 'in' operator in the middle clause of a ternary,
+         * where it's unambiguous, even if we might be parsing the init of a
+         * for statement.
+         */
+        oldflags = tc->flags;
+        tc->flags &= ~TCF_IN_FOR_INIT;
+#endif /* JS_HAS_IN_OPERATOR */
+        pn2 = AssignExpr(cx, ts, tc);
+#if JS_HAS_IN_OPERATOR
+        tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS);
+#endif /* JS_HAS_IN_OPERATOR */
+
+        if (!pn2)
+            return NULL;
+        MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_IN_COND);
+        pn3 = AssignExpr(cx, ts, tc);
+        if (!pn3)
+            return NULL;
+        pn->pn_pos.begin = pn1->pn_pos.begin;
+        pn->pn_pos.end = pn3->pn_pos.end;
+        pn->pn_kid1 = pn1;
+        pn->pn_kid2 = pn2;
+        pn->pn_kid3 = pn3;
+    }
+    return pn;
+}
+
+static JSParseNode *
+OrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+
+    pn = AndExpr(cx, ts, tc);
+    if (pn && js_MatchToken(cx, ts, TOK_OR))
+        pn = NewBinary(cx, TOK_OR, JSOP_OR, pn, OrExpr(cx, ts, tc), tc);
+    return pn;
+}
+
+static JSParseNode *
+AndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+
+    pn = BitOrExpr(cx, ts, tc);
+    if (pn && js_MatchToken(cx, ts, TOK_AND))
+        pn = NewBinary(cx, TOK_AND, JSOP_AND, pn, AndExpr(cx, ts, tc), tc);
+    return pn;
+}
+
+static JSParseNode *
+BitOrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+
+    pn = BitXorExpr(cx, ts, tc);
+    while (pn && js_MatchToken(cx, ts, TOK_BITOR)) {
+        pn = NewBinary(cx, TOK_BITOR, JSOP_BITOR, pn, BitXorExpr(cx, ts, tc),
+                       tc);
+    }
+    return pn;
+}
+
+static JSParseNode *
+BitXorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+
+    pn = BitAndExpr(cx, ts, tc);
+    while (pn && js_MatchToken(cx, ts, TOK_BITXOR)) {
+        pn = NewBinary(cx, TOK_BITXOR, JSOP_BITXOR, pn, BitAndExpr(cx, ts, tc),
+                       tc);
+    }
+    return pn;
+}
+
+static JSParseNode *
+BitAndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+
+    pn = EqExpr(cx, ts, tc);
+    while (pn && js_MatchToken(cx, ts, TOK_BITAND))
+        pn = NewBinary(cx, TOK_BITAND, JSOP_BITAND, pn, EqExpr(cx, ts, tc), tc);
+    return pn;
+}
+
+static JSParseNode *
+EqExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+    JSOp op;
+
+    pn = RelExpr(cx, ts, tc);
+    while (pn && js_MatchToken(cx, ts, TOK_EQOP)) {
+        op = CURRENT_TOKEN(ts).t_op;
+        pn = NewBinary(cx, TOK_EQOP, op, pn, RelExpr(cx, ts, tc), tc);
+    }
+    return pn;
+}
+
+static JSParseNode *
+RelExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+    JSTokenType tt;
+    JSOp op;
+#if JS_HAS_IN_OPERATOR
+    uintN inForInitFlag = tc->flags & TCF_IN_FOR_INIT;
+
+    /*
+     * Uses of the in operator in ShiftExprs are always unambiguous,
+     * so unset the flag that prohibits recognizing it.
+     */
+    tc->flags &= ~TCF_IN_FOR_INIT;
+#endif /* JS_HAS_IN_OPERATOR */
+
+    pn = ShiftExpr(cx, ts, tc);
+    while (pn &&
+           (js_MatchToken(cx, ts, TOK_RELOP)
+#if JS_HAS_IN_OPERATOR
+            /*
+             * Recognize the 'in' token as an operator only if we're not
+             * currently in the init expr of a for loop.
+             */
+            || (inForInitFlag == 0 && js_MatchToken(cx, ts, TOK_IN))
+#endif /* JS_HAS_IN_OPERATOR */
+#if JS_HAS_INSTANCEOF
+            || js_MatchToken(cx, ts, TOK_INSTANCEOF)
+#endif /* JS_HAS_INSTANCEOF */
+            )) {
+        tt = CURRENT_TOKEN(ts).type;
+        op = CURRENT_TOKEN(ts).t_op;
+        pn = NewBinary(cx, tt, op, pn, ShiftExpr(cx, ts, tc), tc);
+    }
+#if JS_HAS_IN_OPERATOR
+    /* Restore previous state of inForInit flag. */
+    tc->flags |= inForInitFlag;
+#endif /* JS_HAS_IN_OPERATOR */
+
+    return pn;
+}
+
+static JSParseNode *
+ShiftExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+    JSOp op;
+
+    pn = AddExpr(cx, ts, tc);
+    while (pn && js_MatchToken(cx, ts, TOK_SHOP)) {
+        op = CURRENT_TOKEN(ts).t_op;
+        pn = NewBinary(cx, TOK_SHOP, op, pn, AddExpr(cx, ts, tc), tc);
+    }
+    return pn;
+}
+
+static JSParseNode *
+AddExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+    JSTokenType tt;
+    JSOp op;
+
+    pn = MulExpr(cx, ts, tc);
+    while (pn &&
+           (js_MatchToken(cx, ts, TOK_PLUS) ||
+            js_MatchToken(cx, ts, TOK_MINUS))) {
+        tt = CURRENT_TOKEN(ts).type;
+        op = (tt == TOK_PLUS) ? JSOP_ADD : JSOP_SUB;
+        pn = NewBinary(cx, tt, op, pn, MulExpr(cx, ts, tc), tc);
+    }
+    return pn;
+}
+
+static JSParseNode *
+MulExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+    JSTokenType tt;
+    JSOp op;
+
+    pn = UnaryExpr(cx, ts, tc);
+    while (pn &&
+           (js_MatchToken(cx, ts, TOK_STAR) ||
+            js_MatchToken(cx, ts, TOK_DIVOP))) {
+        tt = CURRENT_TOKEN(ts).type;
+        op = CURRENT_TOKEN(ts).t_op;
+        pn = NewBinary(cx, tt, op, pn, UnaryExpr(cx, ts, tc), tc);
+    }
+    return pn;
+}
+
+static JSParseNode *
+SetLvalKid(JSContext *cx, JSTokenStream *ts, JSParseNode *pn, JSParseNode *kid,
+           const char *name)
+{
+    while (kid->pn_type == TOK_RP)
+        kid = kid->pn_kid;
+    if (kid->pn_type != TOK_NAME &&
+        kid->pn_type != TOK_DOT &&
+#if JS_HAS_LVALUE_RETURN
+        (kid->pn_type != TOK_LP || kid->pn_op != JSOP_CALL) &&
+#endif
+#if JS_HAS_XML_SUPPORT
+        (kid->pn_type != TOK_UNARYOP || kid->pn_op != JSOP_XMLNAME) &&
+#endif
+        kid->pn_type != TOK_LB) {
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_BAD_OPERAND, name);
+        return NULL;
+    }
+    pn->pn_kid = kid;
+    return kid;
+}
+
+static const char *incop_name_str[] = {"increment", "decrement"};
+
+static JSBool
+SetIncOpKid(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
+            JSParseNode *pn, JSParseNode *kid,
+            JSTokenType tt, JSBool preorder)
+{
+    JSOp op;
+
+    kid = SetLvalKid(cx, ts, pn, kid, incop_name_str[tt == TOK_DEC]);
+    if (!kid)
+        return JS_FALSE;
+    switch (kid->pn_type) {
+      case TOK_NAME:
+        op = (tt == TOK_INC)
+             ? (preorder ? JSOP_INCNAME : JSOP_NAMEINC)
+             : (preorder ? JSOP_DECNAME : JSOP_NAMEDEC);
+        if (kid->pn_atom == cx->runtime->atomState.argumentsAtom)
+            tc->flags |= TCF_FUN_HEAVYWEIGHT;
+        break;
+
+      case TOK_DOT:
+        op = (tt == TOK_INC)
+             ? (preorder ? JSOP_INCPROP : JSOP_PROPINC)
+             : (preorder ? JSOP_DECPROP : JSOP_PROPDEC);
+        break;
+
+#if JS_HAS_LVALUE_RETURN
+      case TOK_LP:
+        JS_ASSERT(kid->pn_op == JSOP_CALL);
+        kid->pn_op = JSOP_SETCALL;
+        /* FALL THROUGH */
+#endif
+#if JS_HAS_XML_SUPPORT
+      case TOK_UNARYOP:
+        if (kid->pn_op == JSOP_XMLNAME)
+            kid->pn_op = JSOP_SETXMLNAME;
+        /* FALL THROUGH */
+#endif
+      case TOK_LB:
+        op = (tt == TOK_INC)
+             ? (preorder ? JSOP_INCELEM : JSOP_ELEMINC)
+             : (preorder ? JSOP_DECELEM : JSOP_ELEMDEC);
+        break;
+
+      default:
+        JS_ASSERT(0);
+        op = JSOP_NOP;
+    }
+    pn->pn_op = op;
+    return JS_TRUE;
+}
+
+static JSParseNode *
+UnaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSTokenType tt;
+    JSParseNode *pn, *pn2;
+
+    CHECK_RECURSION();
+
+    ts->flags |= TSF_OPERAND;
+    tt = js_GetToken(cx, ts);
+    ts->flags &= ~TSF_OPERAND;
+
+    switch (tt) {
+      case TOK_UNARYOP:
+      case TOK_PLUS:
+      case TOK_MINUS:
+        pn = NewParseNode(cx, ts, PN_UNARY, tc);
+        if (!pn)
+            return NULL;
+        pn->pn_type = TOK_UNARYOP;      /* PLUS and MINUS are binary */
+        pn->pn_op = CURRENT_TOKEN(ts).t_op;
+        pn2 = UnaryExpr(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        pn->pn_pos.end = pn2->pn_pos.end;
+        pn->pn_kid = pn2;
+        break;
+
+      case TOK_INC:
+      case TOK_DEC:
+        pn = NewParseNode(cx, ts, PN_UNARY, tc);
+        if (!pn)
+            return NULL;
+        pn2 = MemberExpr(cx, ts, tc, JS_TRUE);
+        if (!pn2)
+            return NULL;
+        if (!SetIncOpKid(cx, ts, tc, pn, pn2, tt, JS_TRUE))
+            return NULL;
+        pn->pn_pos.end = pn2->pn_pos.end;
+        break;
+
+      case TOK_DELETE:
+        pn = NewParseNode(cx, ts, PN_UNARY, tc);
+        if (!pn)
+            return NULL;
+        pn2 = UnaryExpr(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        pn->pn_pos.end = pn2->pn_pos.end;
+
+        /*
+         * Under ECMA3, deleting any unary expression is valid -- it simply
+         * returns true. Here we strip off any parentheses.
+         */
+        while (pn2->pn_type == TOK_RP)
+            pn2 = pn2->pn_kid;
+        pn->pn_kid = pn2;
+        break;
+
+      case TOK_ERROR:
+        return NULL;
+
+      default:
+        js_UngetToken(ts);
+        pn = MemberExpr(cx, ts, tc, JS_TRUE);
+        if (!pn)
+            return NULL;
+
+        /* Don't look across a newline boundary for a postfix incop. */
+        if (ON_CURRENT_LINE(ts, pn->pn_pos)) {
+            tt = js_PeekTokenSameLine(cx, ts);
+            if (tt == TOK_INC || tt == TOK_DEC) {
+                (void) js_GetToken(cx, ts);
+                pn2 = NewParseNode(cx, ts, PN_UNARY, tc);
+                if (!pn2)
+                    return NULL;
+                if (!SetIncOpKid(cx, ts, tc, pn2, pn, tt, JS_FALSE))
+                    return NULL;
+                pn2->pn_pos.begin = pn->pn_pos.begin;
+                pn = pn2;
+            }
+        }
+        break;
+    }
+    return pn;
+}
+
+static JSBool
+ArgumentList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
+             JSParseNode *listNode)
+{
+    JSBool matched;
+
+    ts->flags |= TSF_OPERAND;
+    matched = js_MatchToken(cx, ts, TOK_RP);
+    ts->flags &= ~TSF_OPERAND;
+    if (!matched) {
+        do {
+            JSParseNode *argNode = AssignExpr(cx, ts, tc);
+            if (!argNode)
+                return JS_FALSE;
+            PN_APPEND(listNode, argNode);
+        } while (js_MatchToken(cx, ts, TOK_COMMA));
+
+        if (js_GetToken(cx, ts) != TOK_RP) {
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_PAREN_AFTER_ARGS);
+            return JS_FALSE;
+        }
+    }
+    return JS_TRUE;
+}
+
+static JSParseNode *
+MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
+           JSBool allowCallSyntax)
+{
+    JSParseNode *pn, *pn2, *pn3;
+    JSTokenType tt;
+
+    CHECK_RECURSION();
+
+    /* Check for new expression first. */
+    ts->flags |= TSF_OPERAND;
+    tt = js_PeekToken(cx, ts);
+    ts->flags &= ~TSF_OPERAND;
+    if (tt == TOK_NEW) {
+        (void) js_GetToken(cx, ts);
+
+        pn = NewParseNode(cx, ts, PN_LIST, tc);
+        if (!pn)
+            return NULL;
+        pn2 = MemberExpr(cx, ts, tc, JS_FALSE);
+        if (!pn2)
+            return NULL;
+        pn->pn_op = JSOP_NEW;
+        PN_INIT_LIST_1(pn, pn2);
+        pn->pn_pos.begin = pn2->pn_pos.begin;
+
+        if (js_MatchToken(cx, ts, TOK_LP) && !ArgumentList(cx, ts, tc, pn))
+            return NULL;
+        if (pn->pn_count > ARGC_LIMIT) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_TOO_MANY_CON_ARGS);
+            return NULL;
+        }
+        pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
+    } else {
+        pn = PrimaryExpr(cx, ts, tc);
+        if (!pn)
+            return NULL;
+
+        if (pn->pn_type == TOK_ANYNAME ||
+            pn->pn_type == TOK_AT ||
+            pn->pn_type == TOK_DBLCOLON) {
+            pn2 = NewOrRecycledNode(cx, tc);
+            if (!pn2)
+                return NULL;
+            pn2->pn_type = TOK_UNARYOP;
+            pn2->pn_pos = pn->pn_pos;
+            pn2->pn_op = JSOP_XMLNAME;
+            pn2->pn_arity = PN_UNARY;
+            pn2->pn_kid = pn;
+            pn2->pn_next = NULL;
+            pn = pn2;
+        }
+    }
+
+    while ((tt = js_GetToken(cx, ts)) > TOK_EOF) {
+        if (tt == TOK_DOT) {
+            pn2 = NewParseNode(cx, ts, PN_NAME, tc);
+            if (!pn2)
+                return NULL;
+#if JS_HAS_XML_SUPPORT
+            pn3 = PrimaryExpr(cx, ts, tc);
+            if (!pn3)
+                return NULL;
+            tt = pn3->pn_type;
+            if (tt == TOK_NAME ||
+                (tt == TOK_DBLCOLON &&
+                 pn3->pn_arity == PN_NAME &&
+                 pn3->pn_expr->pn_type == TOK_FUNCTION)) {
+                pn2->pn_op = (tt == TOK_NAME) ? JSOP_GETPROP : JSOP_GETMETHOD;
+                pn2->pn_expr = pn;
+                pn2->pn_atom = pn3->pn_atom;
+                RecycleTree(pn3, tc);
+            } else {
+                if (TOKEN_TYPE_IS_XML(tt)) {
+                    pn2->pn_type = TOK_LB;
+                    pn2->pn_op = JSOP_GETELEM;
+                } else if (tt == TOK_RP) {
+                    JSParseNode *group = pn3;
+
+                    /* Recycle the useless TOK_RP/JSOP_GROUP node. */
+                    pn3 = group->pn_kid;
+                    group->pn_kid = NULL;
+                    RecycleTree(group, tc);
+                    pn2->pn_type = TOK_FILTER;
+                    pn2->pn_op = JSOP_FILTER;
+                } else {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_NAME_AFTER_DOT);
+                    return NULL;
+                }
+                pn2->pn_arity = PN_BINARY;
+                pn2->pn_left = pn;
+                pn2->pn_right = pn3;
+            }
+#else
+            MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT);
+            pn2->pn_op = JSOP_GETPROP;
+            pn2->pn_expr = pn;
+            pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;
+#endif
+            pn2->pn_pos.begin = pn->pn_pos.begin;
+            pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+#if JS_HAS_XML_SUPPORT
+        } else if (tt == TOK_DBLDOT) {
+            pn2 = NewParseNode(cx, ts, PN_BINARY, tc);
+            if (!pn2)
+                return NULL;
+            pn3 = PrimaryExpr(cx, ts, tc);
+            if (!pn3)
+                return NULL;
+            tt = pn3->pn_type;
+            if (tt == TOK_NAME) {
+                pn3->pn_type = TOK_STRING;
+                pn3->pn_arity = PN_NULLARY;
+                pn3->pn_op = JSOP_STRING;
+            } else if (!TOKEN_TYPE_IS_XML(tt)) {
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_NAME_AFTER_DOT);
+                return NULL;
+            }
+            pn2->pn_op = JSOP_DESCENDANTS;
+            pn2->pn_left = pn;
+            pn2->pn_right = pn3;
+            pn2->pn_pos.begin = pn->pn_pos.begin;
+            pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+#endif
+        } else if (tt == TOK_LB) {
+            pn2 = NewParseNode(cx, ts, PN_BINARY, tc);
+            if (!pn2)
+                return NULL;
+            pn3 = Expr(cx, ts, tc);
+            if (!pn3)
+                return NULL;
+
+            MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX);
+            pn2->pn_pos.begin = pn->pn_pos.begin;
+            pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+
+            /* Optimize o['p'] to o.p by rewriting pn2. */
+            if (pn3->pn_type == TOK_STRING) {
+                pn2->pn_type = TOK_DOT;
+                pn2->pn_op = JSOP_GETPROP;
+                pn2->pn_arity = PN_NAME;
+                pn2->pn_expr = pn;
+                pn2->pn_atom = pn3->pn_atom;
+            } else {
+                pn2->pn_op = JSOP_GETELEM;
+                pn2->pn_left = pn;
+                pn2->pn_right = pn3;
+            }
+        } else if (allowCallSyntax && tt == TOK_LP) {
+            pn2 = NewParseNode(cx, ts, PN_LIST, tc);
+            if (!pn2)
+                return NULL;
+
+            /* Pick JSOP_EVAL and flag tc as heavyweight if eval(...). */
+            pn2->pn_op = JSOP_CALL;
+            if (pn->pn_op == JSOP_NAME &&
+                pn->pn_atom == cx->runtime->atomState.evalAtom) {
+                pn2->pn_op = JSOP_EVAL;
+                tc->flags |= TCF_FUN_HEAVYWEIGHT;
+            }
+
+            PN_INIT_LIST_1(pn2, pn);
+            pn2->pn_pos.begin = pn->pn_pos.begin;
+
+            if (!ArgumentList(cx, ts, tc, pn2))
+                return NULL;
+            if (pn2->pn_count > ARGC_LIMIT) {
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_TOO_MANY_FUN_ARGS);
+                return NULL;
+            }
+            pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+        } else {
+            js_UngetToken(ts);
+            return pn;
+        }
+
+        pn = pn2;
+    }
+    if (tt == TOK_ERROR)
+        return NULL;
+    return pn;
+}
+
+static JSParseNode *
+BracketedExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    uintN oldflags;
+    JSParseNode *pn;
+
+#if JS_HAS_IN_OPERATOR
+    /*
+     * Always accept the 'in' operator in a parenthesized expression,
+     * where it's unambiguous, even if we might be parsing the init of a
+     * for statement.
+     */
+    oldflags = tc->flags;
+    tc->flags &= ~TCF_IN_FOR_INIT;
+#endif
+    pn = Expr(cx, ts, tc);
+#if JS_HAS_IN_OPERATOR
+    tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS);
+#endif
+    return pn;
+}
+
+#if JS_HAS_XML_SUPPORT
+
+static JSParseNode *
+EndBracketedExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+
+    pn = BracketedExpr(cx, ts, tc);
+    if (!pn)
+        return NULL;
+
+    MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_AFTER_ATTR_EXPR);
+    return pn;
+}
+
+/*
+ * From the ECMA-357 grammar in 11.1.1 and 11.1.2:
+ *
+ *      AttributeIdentifier:
+ *              @ PropertySelector
+ *              @ QualifiedIdentifier
+ *              @ [ Expression ]
+ *
+ *      PropertySelector:
+ *              Identifier
+ *              *
+ *
+ *      QualifiedIdentifier:
+ *              PropertySelector :: PropertySelector
+ *              PropertySelector :: [ Expression ]
+ *
+ * We adapt AttributeIdentifier and QualifiedIdentier to be LL(1), like so:
+ *
+ *      AttributeIdentifier:
+ *              @ QualifiedIdentifier
+ *              @ [ Expression ]
+ *
+ *      PropertySelector:
+ *              Identifier
+ *              *
+ *
+ *      QualifiedIdentifier:
+ *              PropertySelector :: PropertySelector
+ *              PropertySelector :: [ Expression ]
+ *              PropertySelector
+ *
+ * Since PrimaryExpression: Identifier in ECMA-262 and we want the semantics
+ * for that rule to result in a name node, but extend the grammar to include
+ * PrimaryExpression: QualifiedIdentifier, we factor further:
+ *
+ *      QualifiedIdentifier:
+ *              PropertySelector QualifiedSuffix
+ *
+ *      QualifiedSuffix:
+ *              :: PropertySelector
+ *              :: [ Expression ]
+ *              /nothing/
+ *
+ * And use this production instead of PrimaryExpression: QualifiedIdentifier:
+ *
+ *      PrimaryExpression:
+ *              Identifier QualifiedSuffix
+ *
+ * We hoists the :: match into callers of QualifiedSuffix, in order to tweak
+ * PropertySelector vs. Identifier pn_arity, pn_op, and other members.
+ */
+static JSParseNode *
+PropertySelector(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+
+    pn = NewParseNode(cx, ts, PN_NULLARY, tc);
+    if (!pn)
+        return NULL;
+    if (pn->pn_type == TOK_STAR) {
+        pn->pn_type = TOK_ANYNAME;
+        pn->pn_op = JSOP_ANYNAME;
+        pn->pn_atom = cx->runtime->atomState.starAtom;
+    } else {
+        JS_ASSERT(pn->pn_type == TOK_NAME);
+        pn->pn_op = JSOP_QNAMEPART;
+        pn->pn_arity = PN_NAME;
+        pn->pn_atom = CURRENT_TOKEN(ts).t_atom;
+        pn->pn_expr = NULL;
+        pn->pn_slot = -1;
+        pn->pn_attrs = 0;
+    }
+    return pn;
+}
+
+static JSParseNode *
+QualifiedSuffix(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
+                JSTreeContext *tc)
+{
+    JSParseNode *pn2, *pn3;
+    JSTokenType tt;
+
+    JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_DBLCOLON);
+    pn2 = NewParseNode(cx, ts, PN_NAME, tc);
+    if (!pn2)
+        return NULL;
+
+    /* Left operand of :: must be evaluated if it is an identifier. */
+    if (pn->pn_op == JSOP_QNAMEPART)
+        pn->pn_op = JSOP_NAME;
+
+    tt = js_GetToken(cx, ts);
+    if (tt == TOK_STAR || tt == TOK_NAME) {
+        /* Inline and specialize PropertySelector for JSOP_QNAMECONST. */
+        pn2->pn_op = JSOP_QNAMECONST;
+        pn2->pn_atom = (tt == TOK_STAR)
+                       ? cx->runtime->atomState.starAtom
+                       : CURRENT_TOKEN(ts).t_atom;
+        pn2->pn_expr = pn;
+        pn2->pn_slot = -1;
+        pn2->pn_attrs = 0;
+        return pn2;
+    }
+
+    if (tt != TOK_LB) {
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_SYNTAX_ERROR);
+        return NULL;
+    }
+    pn3 = EndBracketedExpr(cx, ts, tc);
+    if (!pn3)
+        return NULL;
+
+    pn2->pn_op = JSOP_QNAME;
+    pn2->pn_arity = PN_BINARY;
+    pn2->pn_left = pn;
+    pn2->pn_right = pn3;
+    return pn2;
+}
+
+static JSParseNode *
+QualifiedIdentifier(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+
+    pn = PropertySelector(cx, ts, tc);
+    if (!pn)
+        return NULL;
+    if (js_MatchToken(cx, ts, TOK_DBLCOLON))
+        pn = QualifiedSuffix(cx, ts, pn, tc);
+    return pn;
+}
+
+static JSParseNode *
+AttributeIdentifier(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn, *pn2;
+    JSTokenType tt;
+
+    JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_AT);
+    pn = NewParseNode(cx, ts, PN_UNARY, tc);
+    if (!pn)
+        return NULL;
+    pn->pn_op = JSOP_TOATTRNAME;
+    tt = js_GetToken(cx, ts);
+    if (tt == TOK_STAR || tt == TOK_NAME) {
+        pn2 = QualifiedIdentifier(cx, ts, tc);
+    } else if (tt == TOK_LB) {
+        pn2 = EndBracketedExpr(cx, ts, tc);
+    } else {
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_SYNTAX_ERROR);
+        return NULL;
+    }
+    if (!pn2)
+        return NULL;
+    pn->pn_kid = pn2;
+    return pn;
+}
+
+/*
+ * Make a TOK_LC unary node whose pn_kid is an expression.
+ */
+static JSParseNode *
+XMLExpr(JSContext *cx, JSTokenStream *ts, JSBool inTag, JSTreeContext *tc)
+{
+    JSParseNode *pn, *pn2;
+    uintN oldflags;
+
+    JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_LC);
+    pn = NewParseNode(cx, ts, PN_UNARY, tc);
+    if (!pn)
+        return NULL;
+
+    /*
+     * Turn off XML tag mode, but don't restore it after parsing this braced
+     * expression.  Instead, simply restore ts's old flags.  This is required
+     * because XMLExpr is called both from within a tag, and from within text
+     * contained in an element, but outside of any start, end, or point tag.
+     */
+    oldflags = ts->flags;
+    ts->flags = oldflags & ~TSF_XMLTAGMODE;
+    pn2 = Expr(cx, ts, tc);
+    if (!pn2)
+        return NULL;
+
+    MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_IN_XML_EXPR);
+    ts->flags = oldflags;
+    pn->pn_kid = pn2;
+    pn->pn_op = inTag ? JSOP_XMLTAGEXPR : JSOP_XMLELTEXPR;
+    return pn;
+}
+
+/*
+ * Make a terminal node for oneof TOK_XMLNAME, TOK_XMLATTR, TOK_XMLSPACE,
+ * TOK_XMLTEXT, TOK_XMLCDATA, TOK_XMLCOMMENT, or TOK_XMLPI.  When converting
+ * parse tree to XML, we preserve a TOK_XMLSPACE node only if it's the sole
+ * child of a container tag.
+ */
+static JSParseNode *
+XMLAtomNode(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn;
+    JSToken *tp;
+
+    pn = NewParseNode(cx, ts, PN_NULLARY, tc);
+    if (!pn)
+        return NULL;
+    tp = &CURRENT_TOKEN(ts);
+    pn->pn_op = tp->t_op;
+    pn->pn_atom = tp->t_atom;
+    if (tp->type == TOK_XMLPI)
+        pn->pn_atom2 = tp->t_atom2;
+    return pn;
+}
+
+/*
+ * Parse the productions:
+ *
+ *      XMLNameExpr:
+ *              XMLName XMLNameExpr?
+ *              { Expr } XMLNameExpr?
+ *
+ * Return a PN_LIST, PN_UNARY, or PN_NULLARY according as XMLNameExpr produces
+ * a list of names and/or expressions, a single expression, or a single name.
+ * If PN_LIST or PN_NULLARY, pn_type will be TOK_XMLNAME; if PN_UNARY, pn_type
+ * will be TOK_LC.
+ */
+static JSParseNode *
+XMLNameExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSParseNode *pn, *pn2, *list;
+    JSTokenType tt;
+
+    pn = list = NULL;
+    do {
+        tt = CURRENT_TOKEN(ts).type;
+        if (tt == TOK_LC) {
+            pn2 = XMLExpr(cx, ts, JS_TRUE, tc);
+            if (!pn2)
+                return NULL;
+        } else {
+            JS_ASSERT(tt == TOK_XMLNAME);
+            pn2 = XMLAtomNode(cx, ts, tc);
+            if (!pn2)
+                return NULL;
+        }
+
+        if (!pn) {
+            pn = pn2;
+        } else {
+            if (!list) {
+                list = NewParseNode(cx, ts, PN_LIST, tc);
+                if (!list)
+                    return NULL;
+                list->pn_type = TOK_XMLNAME;
+                list->pn_pos.begin = pn->pn_pos.begin;
+                PN_INIT_LIST_1(list, pn);
+                list->pn_extra = PNX_CANTFOLD;
+                pn = list;
+            }
+            pn->pn_pos.end = pn2->pn_pos.end;
+            PN_APPEND(pn, pn2);
+        }
+    } while ((tt = js_GetToken(cx, ts)) == TOK_XMLNAME || tt == TOK_LC);
+
+    js_UngetToken(ts);
+    return pn;
+}
+
+/*
+ * Macro to test whether an XMLNameExpr or XMLTagContent node can be folded
+ * at compile time into a JSXML tree.
+ */
+#define XML_FOLDABLE(pn)        ((pn)->pn_arity == PN_LIST                    \
+                                 ? ((pn)->pn_extra & PNX_CANTFOLD) == 0       \
+                                 : (pn)->pn_type != TOK_LC)
+
+/*
+ * Parse the productions:
+ *
+ *      XMLTagContent:
+ *              XMLNameExpr
+ *              XMLTagContent S XMLNameExpr S? = S? XMLAttr
+ *              XMLTagContent S XMLNameExpr S? = S? { Expr }
+ *
+ * Return a PN_LIST, PN_UNARY, or PN_NULLARY according to how XMLTagContent
+ * produces a list of name and attribute values and/or braced expressions, a
+ * single expression, or a single name.
+ *
+ * If PN_LIST or PN_NULLARY, pn_type will be TOK_XMLNAME for the case where
+ * XMLTagContent: XMLNameExpr.  If pn_type is not TOK_XMLNAME but pn_arity is
+ * PN_LIST, pn_type will be tagtype.  If PN_UNARY, pn_type will be TOK_LC and
+ * we parsed exactly one expression.
+ */
+static JSParseNode *
+XMLTagContent(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
+              JSTokenType tagtype, JSAtom **namep)
+{
+    JSParseNode *pn, *pn2, *list;
+    JSTokenType tt;
+
+    pn = XMLNameExpr(cx, ts, tc);
+    if (!pn)
+        return NULL;
+    *namep = (pn->pn_arity == PN_NULLARY) ? pn->pn_atom : NULL;
+    list = NULL;
+
+    while (js_MatchToken(cx, ts, TOK_XMLSPACE)) {
+        tt = js_GetToken(cx, ts);
+        if (tt != TOK_XMLNAME && tt != TOK_LC) {
+            js_UngetToken(ts);
+            break;
+        }
+
+        pn2 = XMLNameExpr(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+        if (!list) {
+            list = NewParseNode(cx, ts, PN_LIST, tc);
+            if (!list)
+                return NULL;
+            list->pn_type = tagtype;
+            list->pn_pos.begin = pn->pn_pos.begin;
+            PN_INIT_LIST_1(list, pn);
+            pn = list;
+        }
+        PN_APPEND(pn, pn2);
+        if (!XML_FOLDABLE(pn2))
+            pn->pn_extra |= PNX_CANTFOLD;
+
+        js_MatchToken(cx, ts, TOK_XMLSPACE);
+        MUST_MATCH_TOKEN(TOK_ASSIGN, JSMSG_NO_ASSIGN_IN_XML_ATTR);
+        js_MatchToken(cx, ts, TOK_XMLSPACE);
+
+        tt = js_GetToken(cx, ts);
+        if (tt == TOK_XMLATTR) {
+            pn2 = XMLAtomNode(cx, ts, tc);
+        } else if (tt == TOK_LC) {
+            pn2 = XMLExpr(cx, ts, JS_TRUE, tc);
+            pn->pn_extra |= PNX_CANTFOLD;
+        } else {
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_BAD_XML_ATTR_VALUE);
+            return NULL;
+        }
+        if (!pn2)
+            return NULL;
+        pn->pn_pos.end = pn2->pn_pos.end;
+        PN_APPEND(pn, pn2);
+    }
+
+    return pn;
+}
+
+#define XML_CHECK_FOR_ERROR_AND_EOF(tt,result)                                \
+    JS_BEGIN_MACRO                                                            \
+        if ((tt) <= TOK_EOF) {                                                \
+            if ((tt) == TOK_EOF) {                                            \
+                js_ReportCompileErrorNumber(cx, ts,                           \
+                                            JSREPORT_TS | JSREPORT_ERROR,     \
+                                            JSMSG_END_OF_XML_SOURCE);         \
+            }                                                                 \
+            return result;                                                    \
+        }                                                                     \
+    JS_END_MACRO
+
+static JSParseNode *
+XMLElementOrList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
+                 JSBool allowList);
+
+/*
+ * Consume XML element tag content, including the TOK_XMLETAGO (</) sequence
+ * that opens the end tag for the container.
+ */
+static JSBool
+XMLElementContent(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
+                  JSTreeContext *tc)
+{
+    JSTokenType tt;
+    JSParseNode *pn2;
+    JSAtom *textAtom;
+
+    ts->flags &= ~TSF_XMLTAGMODE;
+    for (;;) {
+        ts->flags |= TSF_XMLTEXTMODE;
+        tt = js_GetToken(cx, ts);
+        ts->flags &= ~TSF_XMLTEXTMODE;
+        XML_CHECK_FOR_ERROR_AND_EOF(tt, JS_FALSE);
+
+        JS_ASSERT(tt == TOK_XMLSPACE || tt == TOK_XMLTEXT);
+        textAtom = CURRENT_TOKEN(ts).t_atom;
+        if (textAtom) {
+            /* Non-zero-length XML text scanned. */
+            pn2 = XMLAtomNode(cx, ts, tc);
+            if (!pn2)
+                return JS_FALSE;
+            pn->pn_pos.end = pn2->pn_pos.end;
+            PN_APPEND(pn, pn2);
+        }
+
+        ts->flags |= TSF_OPERAND;
+        tt = js_GetToken(cx, ts);
+        ts->flags &= ~TSF_OPERAND;
+        XML_CHECK_FOR_ERROR_AND_EOF(tt, JS_FALSE);
+        if (tt == TOK_XMLETAGO)
+            break;
+
+        if (tt == TOK_LC) {
+            pn2 = XMLExpr(cx, ts, JS_FALSE, tc);
+            pn->pn_extra |= PNX_CANTFOLD;
+        } else if (tt == TOK_XMLSTAGO) {
+            pn2 = XMLElementOrList(cx, ts, tc, JS_FALSE);
+            if (pn2) {
+                pn2->pn_extra &= ~PNX_XMLROOT;
+                pn->pn_extra |= pn2->pn_extra;
+            }
+        } else {
+            JS_ASSERT(tt == TOK_XMLCDATA || tt == TOK_XMLCOMMENT ||
+                      tt == TOK_XMLPI);
+            pn2 = XMLAtomNode(cx, ts, tc);
+        }
+        if (!pn2)
+            return JS_FALSE;
+        pn->pn_pos.end = pn2->pn_pos.end;
+        PN_APPEND(pn, pn2);
+    }
+
+    JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_XMLETAGO);
+    ts->flags |= TSF_XMLTAGMODE;
+    return JS_TRUE;
+}
+
+/*
+ * Return a PN_LIST node containing an XML or XMLList Initialiser.
+ */
+static JSParseNode *
+XMLElementOrList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
+                 JSBool allowList)
+{
+    JSParseNode *pn, *pn2, *list;
+    JSBool hadSpace;
+    JSTokenType tt;
+    JSAtom *startAtom, *endAtom;
+
+    JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_XMLSTAGO);
+    pn = NewParseNode(cx, ts, PN_LIST, tc);
+    if (!pn)
+        return NULL;
+
+    ts->flags |= TSF_XMLTAGMODE;
+    hadSpace = js_MatchToken(cx, ts, TOK_XMLSPACE);
+    tt = js_GetToken(cx, ts);
+    if (tt == TOK_ERROR)
+        return NULL;
+
+    if (tt == TOK_XMLNAME || tt == TOK_LC) {
+        /*
+         * XMLElement.  Append the tag and its contents, if any, to pn.
+         */
+        pn2 = XMLTagContent(cx, ts, tc, TOK_XMLSTAGO, &startAtom);
+        if (!pn2)
+            return NULL;
+        js_MatchToken(cx, ts, TOK_XMLSPACE);
+
+        tt = js_GetToken(cx, ts);
+        if (tt == TOK_XMLPTAGC) {
+            /* Point tag (/>): recycle pn if pn2 is a list of tag contents. */
+            if (pn2->pn_type == TOK_XMLSTAGO) {
+                PN_INIT_LIST(pn);
+                RecycleTree(pn, tc);
+                pn = pn2;
+            } else {
+                JS_ASSERT(pn2->pn_type == TOK_XMLNAME ||
+                          pn2->pn_type == TOK_LC);
+                PN_INIT_LIST_1(pn, pn2);
+                if (!XML_FOLDABLE(pn2))
+                    pn->pn_extra |= PNX_CANTFOLD;
+            }
+            pn->pn_type = TOK_XMLPTAGC;
+            pn->pn_extra |= PNX_XMLROOT;
+        } else {
+            /* We had better have a tag-close (>) at this point. */
+            if (tt != TOK_XMLTAGC) {
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_BAD_XML_TAG_SYNTAX);
+                return NULL;
+            }
+            pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+
+            /* Make sure pn2 is a TOK_XMLSTAGO list containing tag contents. */
+            if (pn2->pn_type != TOK_XMLSTAGO) {
+                PN_INIT_LIST_1(pn, pn2);
+                if (!XML_FOLDABLE(pn2))
+                    pn->pn_extra |= PNX_CANTFOLD;
+                pn2 = pn;
+                pn = NewParseNode(cx, ts, PN_LIST, tc);
+                if (!pn)
+                    return NULL;
+            }
+
+            /* Now make pn a nominal-root TOK_XMLELEM list containing pn2. */
+            pn->pn_type = TOK_XMLELEM;
+            PN_INIT_LIST_1(pn, pn2);
+            if (!XML_FOLDABLE(pn2))
+                pn->pn_extra |= PNX_CANTFOLD;
+            pn->pn_extra |= PNX_XMLROOT;
+
+            /* Get element contents and delimiting end-tag-open sequence. */
+            if (!XMLElementContent(cx, ts, pn, tc))
+                return NULL;
+
+            js_MatchToken(cx, ts, TOK_XMLSPACE);
+            tt = js_GetToken(cx, ts);
+            XML_CHECK_FOR_ERROR_AND_EOF(tt, NULL);
+            if (tt != TOK_XMLNAME && tt != TOK_LC) {
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_BAD_XML_TAG_SYNTAX);
+                return NULL;
+            }
+
+            /* Parse end tag; check mismatch at compile-time if we can. */
+            pn2 = XMLTagContent(cx, ts, tc, TOK_XMLETAGO, &endAtom);
+            if (!pn2)
+                return NULL;
+            if (pn2->pn_type == TOK_XMLETAGO) {
+                /* Oops, end tag has attributes! */
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_BAD_XML_TAG_SYNTAX);
+                return NULL;
+            }
+            if (endAtom && startAtom && endAtom != startAtom) {
+                /* End vs. start tag name mismatch: point to the tag name. */
+                ++pn2->pn_pos.begin.index;
+                js_ReportCompileErrorNumber(cx, pn2,
+                                            JSREPORT_PN | JSREPORT_ERROR,
+                                            JSMSG_XML_TAG_NAME_MISMATCH);
+                return NULL;
+            }
+
+            /* Make a TOK_XMLETAGO list with pn2 as its single child. */
+            JS_ASSERT(pn2->pn_type == TOK_XMLNAME || pn2->pn_type == TOK_LC);
+            list = NewParseNode(cx, ts, PN_LIST, tc);
+            if (!list)
+                return NULL;
+            list->pn_type = TOK_XMLETAGO;
+            PN_INIT_LIST_1(list, pn2);
+            PN_APPEND(pn, list);
+            if (!XML_FOLDABLE(pn2)) {
+                list->pn_extra |= PNX_CANTFOLD;
+                pn->pn_extra |= PNX_CANTFOLD;
+            }
+
+            js_MatchToken(cx, ts, TOK_XMLSPACE);
+            MUST_MATCH_TOKEN(TOK_XMLTAGC, JSMSG_BAD_XML_TAG_SYNTAX);
+        }
+
+        /* Set pn_op now that pn has been updated to its final value. */
+        pn->pn_op = JSOP_TOXML;
+    } else if (!hadSpace && allowList && tt == TOK_XMLTAGC) {
+        /* XMLList Initialiser. */
+        pn->pn_type = TOK_XMLLIST;
+        pn->pn_op = JSOP_TOXMLLIST;
+        PN_INIT_LIST(pn);
+        pn->pn_extra |= PNX_XMLROOT;
+        if (!XMLElementContent(cx, ts, pn, tc))
+            return NULL;
+
+        MUST_MATCH_TOKEN(TOK_XMLTAGC, JSMSG_BAD_XML_LIST_SYNTAX);
+    } else {
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_BAD_XML_NAME_SYNTAX);
+        return NULL;
+    }
+
+    pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+    ts->flags &= ~TSF_XMLTAGMODE;
+    return pn;
+}
+
+static JSParseNode *
+XMLElementOrListRoot(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
+                     JSBool allowList)
+{
+    uint32 oldopts;
+    JSParseNode *pn;
+
+    /*
+     * Force XML support to be enabled so that comments and CDATA literals
+     * are recognized, instead of <! followed by -- starting an HTML comment
+     * to end of line (used in script tags to hide content from old browsers
+     * that don't recognize <script>).
+     */
+    oldopts = JS_SetOptions(cx, cx->options | JSOPTION_XML);
+    pn = XMLElementOrList(cx, ts, tc, allowList);
+    JS_SetOptions(cx, oldopts);
+    return pn;
+}
+
+JS_FRIEND_API(JSParseNode *)
+js_ParseXMLTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts,
+                       JSBool allowList)
+{
+    JSStackFrame *fp, frame;
+    JSParseNode *pn;
+    JSTreeContext tc;
+    JSTokenType tt;
+
+    /*
+     * Push a compiler frame if we have no frames, or if the top frame is a
+     * lightweight function activation, or if its scope chain doesn't match
+     * the one passed to us.
+     */
+    fp = cx->fp;
+    if (!fp || !fp->varobj || fp->scopeChain != chain) {
+        memset(&frame, 0, sizeof frame);
+        frame.varobj = frame.scopeChain = chain;
+        if (cx->options & JSOPTION_VAROBJFIX) {
+            while ((chain = JS_GetParent(cx, chain)) != NULL)
+                frame.varobj = chain;
+        }
+        frame.down = fp;
+        if (fp)
+            frame.flags = fp->flags & (JSFRAME_SPECIAL | JSFRAME_COMPILE_N_GO);
+        cx->fp = &frame;
+    }
+
+    JS_KEEP_ATOMS(cx->runtime);
+    TREE_CONTEXT_INIT(&tc);
+
+    /* Set XML-only mode to turn off special treatment of {expr} in XML. */
+    ts->flags |= TSF_OPERAND | TSF_XMLONLYMODE;
+    tt = js_GetToken(cx, ts);
+    ts->flags &= ~TSF_OPERAND;
+
+    if (tt != TOK_XMLSTAGO) {
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_BAD_XML_MARKUP);
+        pn = NULL;
+    } else {
+        pn = XMLElementOrListRoot(cx, ts, &tc, allowList);
+    }
+
+    ts->flags &= ~TSF_XMLONLYMODE;
+    TREE_CONTEXT_FINISH(&tc);
+    JS_UNKEEP_ATOMS(cx->runtime);
+    cx->fp = fp;
+    return pn;
+}
+
+#endif /* JS_HAS_XMLSUPPORT */
+
+static JSParseNode *
+PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
+{
+    JSTokenType tt;
+    JSParseNode *pn, *pn2, *pn3;
+#if JS_HAS_GETTER_SETTER
+    JSAtom *atom;
+    JSRuntime *rt;
+#endif
+
+#if JS_HAS_SHARP_VARS
+    JSParseNode *defsharp;
+    JSBool notsharp;
+
+    defsharp = NULL;
+    notsharp = JS_FALSE;
+  again:
+    /*
+     * Control flows here after #n= is scanned.  If the following primary is
+     * not valid after such a "sharp variable" definition, the tt switch case
+     * should set notsharp.
+     */
+#endif
+
+    CHECK_RECURSION();
+
+    ts->flags |= TSF_OPERAND;
+    tt = js_GetToken(cx, ts);
+    ts->flags &= ~TSF_OPERAND;
+
+#if JS_HAS_GETTER_SETTER
+    if (tt == TOK_NAME) {
+        tt = CheckGetterOrSetter(cx, ts, TOK_FUNCTION);
+        if (tt == TOK_ERROR)
+            return NULL;
+    }
+#endif
+
+    switch (tt) {
+#if JS_HAS_LEXICAL_CLOSURE || JS_HAS_XML_SUPPORT
+      case TOK_FUNCTION:
+#if JS_HAS_XML_SUPPORT
+        if (js_MatchToken(cx, ts, TOK_DBLCOLON)) {
+            pn2 = NewParseNode(cx, ts, PN_NULLARY, tc);
+            if (!pn2)
+                return NULL;
+            pn2->pn_type = TOK_FUNCTION;
+            pn = QualifiedSuffix(cx, ts, pn2, tc);
+            if (!pn)
+                return NULL;
+            break;
+        }
+#endif
+        pn = FunctionExpr(cx, ts, tc);
+        if (!pn)
+            return NULL;
+        break;
+#endif
+
+#if JS_HAS_INITIALIZERS
+      case TOK_LB:
+      {
+        JSBool matched;
+        jsuint atomIndex;
+
+        pn = NewParseNode(cx, ts, PN_LIST, tc);
+        if (!pn)
+            return NULL;
+        pn->pn_type = TOK_RB;
+
+#if JS_HAS_SHARP_VARS
+        if (defsharp) {
+            PN_INIT_LIST_1(pn, defsharp);
+            defsharp = NULL;
+        } else
+#endif
+            PN_INIT_LIST(pn);
+
+        ts->flags |= TSF_OPERAND;
+        matched = js_MatchToken(cx, ts, TOK_RB);
+        ts->flags &= ~TSF_OPERAND;
+        if (!matched) {
+            for (atomIndex = 0; ; atomIndex++) {
+                if (atomIndex == ATOM_INDEX_LIMIT) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_ARRAY_INIT_TOO_BIG);
+                    return NULL;
+                }
+
+                ts->flags |= TSF_OPERAND;
+                tt = js_PeekToken(cx, ts);
+                ts->flags &= ~TSF_OPERAND;
+                if (tt == TOK_RB) {
+                    pn->pn_extra |= PNX_ENDCOMMA;
+                    break;
+                }
+
+                if (tt == TOK_COMMA) {
+                    /* So CURRENT_TOKEN gets TOK_COMMA and not TOK_LB. */
+                    js_MatchToken(cx, ts, TOK_COMMA);
+                    pn2 = NewParseNode(cx, ts, PN_NULLARY, tc);
+                } else {
+                    pn2 = AssignExpr(cx, ts, tc);
+                }
+                if (!pn2)
+                    return NULL;
+                PN_APPEND(pn, pn2);
+
+                if (tt != TOK_COMMA) {
+                    /* If we didn't already match TOK_COMMA in above case. */
+                    if (!js_MatchToken(cx, ts, TOK_COMMA))
+                        break;
+                }
+            }
+
+            MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_AFTER_LIST);
+        }
+        pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+        return pn;
+      }
+
+      case TOK_LC:
+        pn = NewParseNode(cx, ts, PN_LIST, tc);
+        if (!pn)
+            return NULL;
+        pn->pn_type = TOK_RC;
+
+#if JS_HAS_SHARP_VARS
+        if (defsharp) {
+            PN_INIT_LIST_1(pn, defsharp);
+            defsharp = NULL;
+        } else
+#endif
+            PN_INIT_LIST(pn);
+
+        if (!js_MatchToken(cx, ts, TOK_RC)) {
+            do {
+                JSOp op;
+
+                tt = js_GetToken(cx, ts);
+                switch (tt) {
+                  case TOK_NUMBER:
+                    pn3 = NewParseNode(cx, ts, PN_NULLARY, tc);
+                    if (pn3)
+                        pn3->pn_dval = CURRENT_TOKEN(ts).t_dval;
+                    break;
+                  case TOK_NAME:
+#if JS_HAS_GETTER_SETTER
+                    atom = CURRENT_TOKEN(ts).t_atom;
+                    rt = cx->runtime;
+                    if (atom == rt->atomState.getAtom ||
+                        atom == rt->atomState.setAtom) {
+                        op = (atom == rt->atomState.getAtom)
+                             ? JSOP_GETTER
+                             : JSOP_SETTER;
+                        if (js_MatchToken(cx, ts, TOK_NAME)) {
+                            pn3 = NewParseNode(cx, ts, PN_NAME, tc);
+                            if (!pn3)
+                                return NULL;
+                            pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
+                            pn3->pn_expr = NULL;
+
+                            /* We have to fake a 'function' token here. */
+                            CURRENT_TOKEN(ts).t_op = JSOP_NOP;
+                            CURRENT_TOKEN(ts).type = TOK_FUNCTION;
+                            pn2 = FunctionExpr(cx, ts, tc);
+                            pn2 = NewBinary(cx, TOK_COLON, op, pn3, pn2, tc);
+                            goto skip;
+                        }
+                    }
+                    /* else fall thru ... */
+#endif
+                  case TOK_STRING:
+                    pn3 = NewParseNode(cx, ts, PN_NULLARY, tc);
+                    if (pn3)
+                        pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;
+                    break;
+                  case TOK_RC:
+                    if (!js_ReportCompileErrorNumber(cx, ts,
+                                                     JSREPORT_TS |
+                                                     JSREPORT_WARNING |
+                                                     JSREPORT_STRICT,
+                                                     JSMSG_TRAILING_COMMA)) {
+                        return NULL;
+                    }
+                    goto end_obj_init;
+                  default:
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_BAD_PROP_ID);
+                    return NULL;
+                }
+
+                tt = js_GetToken(cx, ts);
+#if JS_HAS_GETTER_SETTER
+                if (tt == TOK_NAME) {
+                    tt = CheckGetterOrSetter(cx, ts, TOK_COLON);
+                    if (tt == TOK_ERROR)
+                        return NULL;
+                }
+#endif
+                if (tt != TOK_COLON) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_COLON_AFTER_ID);
+                    return NULL;
+                }
+                op = CURRENT_TOKEN(ts).t_op;
+                pn2 = NewBinary(cx, TOK_COLON, op, pn3, AssignExpr(cx, ts, tc),
+                                tc);
+#if JS_HAS_GETTER_SETTER
+              skip:
+#endif
+                if (!pn2)
+                    return NULL;
+                PN_APPEND(pn, pn2);
+            } while (js_MatchToken(cx, ts, TOK_COMMA));
+
+            MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LIST);
+        }
+      end_obj_init:
+        pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+        return pn;
+
+#if JS_HAS_SHARP_VARS
+      case TOK_DEFSHARP:
+        if (defsharp)
+            goto badsharp;
+        defsharp = NewParseNode(cx, ts, PN_UNARY, tc);
+        if (!defsharp)
+            return NULL;
+        defsharp->pn_kid = NULL;
+        defsharp->pn_num = (jsint) CURRENT_TOKEN(ts).t_dval;
+        goto again;
+
+      case TOK_USESHARP:
+        /* Check for forward/dangling references at runtime, to allow eval. */
+        pn = NewParseNode(cx, ts, PN_NULLARY, tc);
+        if (!pn)
+            return NULL;
+        pn->pn_num = (jsint) CURRENT_TOKEN(ts).t_dval;
+        notsharp = JS_TRUE;
+        break;
+#endif /* JS_HAS_SHARP_VARS */
+#endif /* JS_HAS_INITIALIZERS */
+
+      case TOK_LP:
+        pn = NewParseNode(cx, ts, PN_UNARY, tc);
+        if (!pn)
+            return NULL;
+        pn2 = BracketedExpr(cx, ts, tc);
+        if (!pn2)
+            return NULL;
+
+        MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
+        pn->pn_type = TOK_RP;
+        pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
+        pn->pn_kid = pn2;
+        break;
+
+#if JS_HAS_XML_SUPPORT
+      case TOK_STAR:
+        pn = QualifiedIdentifier(cx, ts, tc);
+        if (!pn)
+            return NULL;
+        notsharp = JS_TRUE;
+        break;
+
+      case TOK_AT:
+        pn = AttributeIdentifier(cx, ts, tc);
+        if (!pn)
+            return NULL;
+        notsharp = JS_TRUE;
+        break;
+
+      case TOK_XMLSTAGO:
+        pn = XMLElementOrListRoot(cx, ts, tc, JS_TRUE);
+        if (!pn)
+            return NULL;
+        notsharp = JS_TRUE;     /* XXXbe could be sharp? */
+        break;
+#endif /* JS_HAS_XML_SUPPORT */
+
+      case TOK_STRING:
+#if JS_HAS_SHARP_VARS
+        notsharp = JS_TRUE;
+        /* FALL THROUGH */
+#endif
+
+#if JS_HAS_XML_SUPPORT
+      case TOK_XMLCDATA:
+      case TOK_XMLCOMMENT:
+      case TOK_XMLPI:
+#endif
+      case TOK_NAME:
+      case TOK_OBJECT:
+        pn = NewParseNode(cx, ts, PN_NULLARY, tc);
+        if (!pn)
+            return NULL;
+        pn->pn_atom = CURRENT_TOKEN(ts).t_atom;
+#if JS_HAS_XML_SUPPORT
+        if (tt == TOK_XMLPI)
+            pn->pn_atom2 = CURRENT_TOKEN(ts).t_atom2;
+        else
+#endif
+            pn->pn_op = CURRENT_TOKEN(ts).t_op;
+        if (tt == TOK_NAME) {
+            pn->pn_arity = PN_NAME;
+            pn->pn_expr = NULL;
+            pn->pn_slot = -1;
+            pn->pn_attrs = 0;
+
+#if JS_HAS_XML_SUPPORT
+            if (js_MatchToken(cx, ts, TOK_DBLCOLON)) {
+                pn = QualifiedSuffix(cx, ts, pn, tc);
+                if (!pn)
+                    return NULL;
+                break;
+            }
+#endif
+
+            /* Unqualified __parent__ and __proto__ uses require activations. */
+            if (pn->pn_atom == cx->runtime->atomState.parentAtom ||
+                pn->pn_atom == cx->runtime->atomState.protoAtom) {
+                tc->flags |= TCF_FUN_HEAVYWEIGHT;
+            } else {
+                JSAtomListElement *ale;
+                JSStackFrame *fp;
+                JSStmtInfo *stmt;
+
+                /* Measure optimizable global variable uses. */
+                ATOM_LIST_SEARCH(ale, &tc->decls, pn->pn_atom);
+                if (ale &&
+                    !(fp = cx->fp)->fun &&
+                    fp->scopeChain == fp->varobj &&
+                    !js_InWithStatement(tc) &&
+                    !js_InCatchBlock(tc, pn->pn_atom)) {
+                    tc->globalUses++;
+                    for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
+                        if (STMT_IS_LOOP(stmt)) {
+                            tc->loopyGlobalUses++;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        break;
+
+      case TOK_NUMBER:
+        pn = NewParseNode(cx, ts, PN_NULLARY, tc);
+        if (!pn)
+            return NULL;
+        pn->pn_dval = CURRENT_TOKEN(ts).t_dval;
+#if JS_HAS_SHARP_VARS
+        notsharp = JS_TRUE;
+#endif
+        break;
+
+      case TOK_PRIMARY:
+        pn = NewParseNode(cx, ts, PN_NULLARY, tc);
+        if (!pn)
+            return NULL;
+        pn->pn_op = CURRENT_TOKEN(ts).t_op;
+#if JS_HAS_SHARP_VARS
+        notsharp = JS_TRUE;
+#endif
+        break;
+
+#if !JS_HAS_EXPORT_IMPORT
+      case TOK_EXPORT:
+      case TOK_IMPORT:
+#endif
+      case TOK_ERROR:
+        /* The scanner or one of its subroutines reported the error. */
+        return NULL;
+
+      default:
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_SYNTAX_ERROR);
+        return NULL;
+    }
+
+#if JS_HAS_SHARP_VARS
+    if (defsharp) {
+        if (notsharp) {
+  badsharp:
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_BAD_SHARP_VAR_DEF);
+            return NULL;
+        }
+        defsharp->pn_kid = pn;
+        return defsharp;
+    }
+#endif
+    return pn;
+}
+
+static JSBool
+ContainsVarStmt(JSParseNode *pn)
+{
+    JSParseNode *pn2;
+
+    if (!pn)
+        return JS_FALSE;
+    switch (pn->pn_arity) {
+      case PN_LIST:
+        if (pn->pn_type == TOK_VAR)
+            return JS_TRUE;
+        for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
+            if (ContainsVarStmt(pn2))
+                return JS_TRUE;
+        }
+        break;
+      case PN_TERNARY:
+        return ContainsVarStmt(pn->pn_kid1) ||
+               ContainsVarStmt(pn->pn_kid2) ||
+               ContainsVarStmt(pn->pn_kid3);
+      case PN_BINARY:
+        /*
+         * Limit recursion if pn is a binary expression, which can't contain a
+         * var statement.
+         */
+        if (pn->pn_op != JSOP_NOP)
+            return JS_FALSE;
+        return ContainsVarStmt(pn->pn_left) || ContainsVarStmt(pn->pn_right);
+      case PN_UNARY:
+        if (pn->pn_op != JSOP_NOP)
+            return JS_FALSE;
+        return ContainsVarStmt(pn->pn_kid);
+      default:;
+    }
+    return JS_FALSE;
+}
+
+/*
+ * Fold from one constant type to another.
+ * XXX handles only strings and numbers for now
+ */
+static JSBool
+FoldType(JSContext *cx, JSParseNode *pn, JSTokenType type)
+{
+    if (pn->pn_type != type) {
+        switch (type) {
+          case TOK_NUMBER:
+            if (pn->pn_type == TOK_STRING) {
+                jsdouble d;
+                if (!js_ValueToNumber(cx, ATOM_KEY(pn->pn_atom), &d))
+                    return JS_FALSE;
+                pn->pn_dval = d;
+                pn->pn_type = TOK_NUMBER;
+                pn->pn_op = JSOP_NUMBER;
+            }
+            break;
+
+          case TOK_STRING:
+            if (pn->pn_type == TOK_NUMBER) {
+                JSString *str = js_NumberToString(cx, pn->pn_dval);
+                if (!str)
+                    return JS_FALSE;
+                pn->pn_atom = js_AtomizeString(cx, str, 0);
+                if (!pn->pn_atom)
+                    return JS_FALSE;
+                pn->pn_type = TOK_STRING;
+                pn->pn_op = JSOP_STRING;
+            }
+            break;
+
+          default:;
+        }
+    }
+    return JS_TRUE;
+}
+
+/*
+ * Fold two numeric constants.  Beware that pn1 and pn2 are recycled, unless
+ * one of them aliases pn, so you can't safely fetch pn2->pn_next, e.g., after
+ * a successful call to this function.
+ */
+static JSBool
+FoldBinaryNumeric(JSContext *cx, JSOp op, JSParseNode *pn1, JSParseNode *pn2,
+                  JSParseNode *pn, JSTreeContext *tc)
+{
+    jsdouble d, d2;
+    int32 i, j;
+    uint32 u;
+
+    JS_ASSERT(pn1->pn_type == TOK_NUMBER && pn2->pn_type == TOK_NUMBER);
+    d = pn1->pn_dval;
+    d2 = pn2->pn_dval;
+    switch (op) {
+      case JSOP_LSH:
+      case JSOP_RSH:
+        if (!js_DoubleToECMAInt32(cx, d, &i))
+            return JS_FALSE;
+        if (!js_DoubleToECMAInt32(cx, d2, &j))
+            return JS_FALSE;
+        j &= 31;
+        d = (op == JSOP_LSH) ? i << j : i >> j;
+        break;
+
+      case JSOP_URSH:
+        if (!js_DoubleToECMAUint32(cx, d, &u))
+            return JS_FALSE;
+        if (!js_DoubleToECMAInt32(cx, d2, &j))
+            return JS_FALSE;
+        j &= 31;
+        d = u >> j;
+        break;
+
+      case JSOP_ADD:
+        d += d2;
+        break;
+
+      case JSOP_SUB:
+        d -= d2;
+        break;
+
+      case JSOP_MUL:
+        d *= d2;
+        break;
+
+      case JSOP_DIV:
+        if (d2 == 0) {
+#if defined(XP_WIN)
+            /* XXX MSVC miscompiles such that (NaN == 0) */
+            if (JSDOUBLE_IS_NaN(d2))
+                d = *cx->runtime->jsNaN;
+            else
+#endif
+            if (d == 0 || JSDOUBLE_IS_NaN(d))
+                d = *cx->runtime->jsNaN;
+            else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31)
+                d = *cx->runtime->jsNegativeInfinity;
+            else
+                d = *cx->runtime->jsPositiveInfinity;
+        } else {
+            d /= d2;
+        }
+        break;
+
+      case JSOP_MOD:
+        if (d2 == 0) {
+            d = *cx->runtime->jsNaN;
+        } else {
+#if defined(XP_WIN)
+          /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
+          if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2)))
+#endif
+            d = fmod(d, d2);
+        }
+        break;
+
+      default:;
+    }
+
+    /* Take care to allow pn1 or pn2 to alias pn. */
+    if (pn1 != pn)
+        RecycleTree(pn1, tc);
+    if (pn2 != pn)
+        RecycleTree(pn2, tc);
+    pn->pn_type = TOK_NUMBER;
+    pn->pn_op = JSOP_NUMBER;
+    pn->pn_arity = PN_NULLARY;
+    pn->pn_dval = d;
+    return JS_TRUE;
+}
+
+#if JS_HAS_XML_SUPPORT
+
+static JSBool
+FoldXMLConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
+{
+    JSTokenType tt;
+    JSParseNode **pnp, *pn1, *pn2;
+    JSString *accum, *str;
+    uint32 i, j;
+
+    JS_ASSERT(pn->pn_arity == PN_LIST);
+    tt = pn->pn_type;
+    pnp = &pn->pn_head;
+    pn1 = *pnp;
+    accum = NULL;
+    if ((pn->pn_extra & PNX_CANTFOLD) == 0) {
+        if (tt == TOK_XMLETAGO)
+            accum = ATOM_TO_STRING(cx->runtime->atomState.etagoAtom);
+        else if (tt == TOK_XMLSTAGO || tt == TOK_XMLPTAGC)
+            accum = ATOM_TO_STRING(cx->runtime->atomState.stagoAtom);
+    }
+
+    for (pn2 = pn1, i = j = 0; pn2; pn2 = pn2->pn_next, i++) {
+        /* The parser already rejected end-tags with attributes. */
+        JS_ASSERT(tt != TOK_XMLETAGO || i == 0);
+        switch (pn2->pn_type) {
+          case TOK_XMLNAME:
+          case TOK_XMLATTR:
+          case TOK_XMLSPACE:
+          case TOK_XMLTEXT:
+          case TOK_STRING:
+            if (pn->pn_arity == PN_LIST)
+                goto cantfold;
+            str = ATOM_TO_STRING(pn2->pn_atom);
+            break;
+
+          case TOK_XMLCDATA:
+            str = js_MakeXMLCDATAString(cx, ATOM_TO_STRING(pn2->pn_atom));
+            if (!str)
+                return JS_FALSE;
+            break;
+
+          case TOK_XMLCOMMENT:
+            str = js_MakeXMLCommentString(cx, ATOM_TO_STRING(pn2->pn_atom));
+            if (!str)
+                return JS_FALSE;
+            break;
+
+          case TOK_XMLPI:
+            str = js_MakeXMLPIString(cx, ATOM_TO_STRING(pn2->pn_atom),
+                                         ATOM_TO_STRING(pn2->pn_atom2));
+            if (!str)
+                return JS_FALSE;
+            break;
+
+          cantfold:
+          default:
+            JS_ASSERT(*pnp == pn1);
+            if ((tt == TOK_XMLSTAGO || tt == TOK_XMLPTAGC) &&
+                (i & 1) ^ (j & 1)) {
+#ifdef DEBUG_brendanXXX
+                printf("1: %d, %d => %s\n",
+                       i, j, accum ? JS_GetStringBytes(accum) : "NULL");
+#endif
+            } else if (accum && pn1 != pn2) {
+                while (pn1->pn_next != pn2) {
+                    pn1 = RecycleTree(pn1, tc);
+                    --pn->pn_count;
+                }
+                pn1->pn_type = TOK_XMLTEXT;
+                pn1->pn_op = JSOP_STRING;
+                pn1->pn_arity = PN_NULLARY;
+                pn1->pn_atom = js_AtomizeString(cx, accum, 0);
+                if (!pn1->pn_atom)
+                    return JS_FALSE;
+                JS_ASSERT(pnp != &pn1->pn_next);
+                *pnp = pn1;
+            }
+            pnp = &pn2->pn_next;
+            pn1 = *pnp;
+            accum = NULL;
+            continue;
+        }
+
+        if (accum) {
+            str = ((tt == TOK_XMLSTAGO || tt == TOK_XMLPTAGC) && i != 0)
+                  ? js_AddAttributePart(cx, i & 1, accum, str)
+                  : js_ConcatStrings(cx, accum, str);
+            if (!str)
+                return JS_FALSE;
+#ifdef DEBUG_brendanXXX
+            printf("2: %d, %d => %s (%u)\n",
+                   i, j, JS_GetStringBytes(str), JSSTRING_LENGTH(str));
+#endif
+            ++j;
+        }
+        accum = str;
+    }
+
+    if (accum) {
+        str = NULL;
+        if ((pn->pn_extra & PNX_CANTFOLD) == 0) {
+            if (tt == TOK_XMLPTAGC)
+                str = ATOM_TO_STRING(cx->runtime->atomState.ptagcAtom);
+            else if (tt == TOK_XMLSTAGO || tt == TOK_XMLETAGO)
+                str = ATOM_TO_STRING(cx->runtime->atomState.tagcAtom);
+        }
+        if (str) {
+            accum = js_ConcatStrings(cx, accum, str);
+            if (!accum)
+                return JS_FALSE;
+        }
+
+        JS_ASSERT(*pnp == pn1);
+        while (pn1->pn_next) {
+            pn1 = RecycleTree(pn1, tc);
+            --pn->pn_count;
+        }
+        pn1->pn_type = TOK_XMLTEXT;
+        pn1->pn_op = JSOP_STRING;
+        pn1->pn_arity = PN_NULLARY;
+        pn1->pn_atom = js_AtomizeString(cx, accum, 0);
+        if (!pn1->pn_atom)
+            return JS_FALSE;
+        JS_ASSERT(pnp != &pn1->pn_next);
+        *pnp = pn1;
+    }
+
+    if (pn1 && pn->pn_count == 1) {
+        /*
+         * Only one node under pn, and it has been folded: move pn1 onto pn
+         * unless pn is an XML root (in which case we need it to tell the code
+         * generator to emit a JSOP_TOXML or JSOP_TOXMLLIST op).  If pn is an
+         * XML root *and* it's a point-tag, rewrite it to TOK_XMLELEM to avoid
+         * extra "<" and "/>" bracketing at runtime.
+         */
+        if (!(pn->pn_extra & PNX_XMLROOT)) {
+            PN_MOVE_NODE(pn, pn1);
+        } else if (tt == TOK_XMLPTAGC) {
+            pn->pn_type = TOK_XMLELEM;
+            pn->pn_op = JSOP_TOXML;
+        }
+    }
+    return JS_TRUE;
+}
+
+#endif /* JS_HAS_XML_SUPPORT */
+
+JSBool
+js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
+{
+    JSParseNode *pn1 = NULL, *pn2 = NULL, *pn3 = NULL;
+    int stackDummy;
+
+    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
+        return JS_FALSE;
+    }
+
+    switch (pn->pn_arity) {
+      case PN_FUNC:
+      {
+        uint16 oldflags = tc->flags;
+
+        tc->flags = (uint16) pn->pn_flags;
+        if (!js_FoldConstants(cx, pn->pn_body, tc))
+            return JS_FALSE;
+        tc->flags = oldflags;
+        break;
+      }
+
+      case PN_LIST:
+#if 0 /* JS_HAS_XML_SUPPORT */
+        switch (pn->pn_type) {
+          case TOK_XMLELEM:
+          case TOK_XMLLIST:
+          case TOK_XMLPTAGC:
+            /*
+             * Try to fold this XML parse tree once, from the top down, into
+             * a JSXML tree with just one object wrapping the tree root.
+             *
+             * Certain subtrees could be folded similarly, but we'd have to
+             * ensure that none used namespace prefixes declared elsewhere in
+             * its super-tree, and we would have to convert each XML object
+             * created at runtime for such sub-trees back into a string, and
+             * concatenate and re-parse anyway.
+             */
+            if ((pn->pn_extra & (PNX_XMLROOT | PNX_CANTFOLD)) == PNX_XMLROOT &&
+                !(tc->flags & TCF_HAS_DEFXMLNS)) {
+                JSObject *obj;
+                JSAtom *atom;
+
+                obj = js_ParseNodeToXMLObject(cx, pn);
+                if (!obj)
+                    return JS_FALSE;
+                atom = js_AtomizeObject(cx, obj, 0);
+                if (!atom)
+                    return JS_FALSE;
+                pn->pn_op = JSOP_XMLOBJECT;
+                pn->pn_arity = PN_NULLARY;
+                pn->pn_atom = atom;
+                return JS_TRUE;
+            }
+
+            /*
+             * Can't fold from parse node to XML tree -- try folding strings
+             * as much as possible, and folding XML sub-trees bottom up to
+             * minimize string concatenation and ToXML/ToXMLList operations
+             * at runtime.
+             */
+            break;
+
+          default:;
+        }
+#endif
+
+        /* Save the list head in pn1 for later use. */
+        for (pn1 = pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
+            if (!js_FoldConstants(cx, pn2, tc))
+                return JS_FALSE;
+        }
+        break;
+
+      case PN_TERNARY:
+        /* Any kid may be null (e.g. for (;;)). */
+        pn1 = pn->pn_kid1;
+        pn2 = pn->pn_kid2;
+        pn3 = pn->pn_kid3;
+        if (pn1 && !js_FoldConstants(cx, pn1, tc))
+            return JS_FALSE;
+        if (pn2 && !js_FoldConstants(cx, pn2, tc))
+            return JS_FALSE;
+        if (pn3 && !js_FoldConstants(cx, pn3, tc))
+            return JS_FALSE;
+        break;
+
+      case PN_BINARY:
+        /* First kid may be null (for default case in switch). */
+        pn1 = pn->pn_left;
+        pn2 = pn->pn_right;
+        if (pn1 && !js_FoldConstants(cx, pn1, tc))
+            return JS_FALSE;
+        if (!js_FoldConstants(cx, pn2, tc))
+            return JS_FALSE;
+        break;
+
+      case PN_UNARY:
+        /* Our kid may be null (e.g. return; vs. return e;). */
+        pn1 = pn->pn_kid;
+        if (pn1 && !js_FoldConstants(cx, pn1, tc))
+            return JS_FALSE;
+        break;
+
+      case PN_NAME:
+        /*
+         * Skip pn1 down along a chain of dotted member expressions to avoid
+         * excessive recursion.  Our only goal here is to fold constants (if
+         * any) in the primary expression operand to the left of the first
+         * dot in the chain.
+         */
+        pn1 = pn->pn_expr;
+        while (pn1 && pn1->pn_arity == PN_NAME)
+            pn1 = pn1->pn_expr;
+        if (pn1 && !js_FoldConstants(cx, pn1, tc))
+            return JS_FALSE;
+        break;
+
+      case PN_NULLARY:
+        break;
+    }
+
+    switch (pn->pn_type) {
+      case TOK_IF:
+        if (ContainsVarStmt(pn2) || ContainsVarStmt(pn3))
+            break;
+        /* FALL THROUGH */
+
+      case TOK_HOOK:
+        /* Reduce 'if (C) T; else E' into T for true C, E for false. */
+        switch (pn1->pn_type) {
+          case TOK_NUMBER:
+            if (pn1->pn_dval == 0)
+                pn2 = pn3;
+            break;
+          case TOK_STRING:
+            if (JSSTRING_LENGTH(ATOM_TO_STRING(pn1->pn_atom)) == 0)
+                pn2 = pn3;
+            break;
+          case TOK_PRIMARY:
+            if (pn1->pn_op == JSOP_TRUE)
+                break;
+            if (pn1->pn_op == JSOP_FALSE || pn1->pn_op == JSOP_NULL) {
+                pn2 = pn3;
+                break;
+            }
+            /* FALL THROUGH */
+          default:
+            /* Early return to dodge common code that copies pn2 to pn. */
+            return JS_TRUE;
+        }
+
+        if (pn2) {
+            /* pn2 is the then- or else-statement subtree to compile. */
+            PN_MOVE_NODE(pn, pn2);
+        } else {
+            /* False condition and no else: make pn an empty statement. */
+            pn->pn_type = TOK_SEMI;
+            pn->pn_arity = PN_UNARY;
+            pn->pn_kid = NULL;
+        }
+        RecycleTree(pn2, tc);
+        if (pn3 && pn3 != pn2)
+            RecycleTree(pn3, tc);
+        break;
+
+      case TOK_PLUS:
+        if (pn->pn_arity == PN_LIST) {
+            size_t length, length2;
+            jschar *chars;
+            JSString *str, *str2;
+
+            /*
+             * Any string literal term with all others number or string means
+             * this is a concatenation.  If any term is not a string or number
+             * literal, we can't fold.
+             */
+            JS_ASSERT(pn->pn_count > 2);
+            if (pn->pn_extra & PNX_CANTFOLD)
+                return JS_TRUE;
+            if (pn->pn_extra != PNX_STRCAT)
+                goto do_binary_op;
+
+            /* Ok, we're concatenating: convert non-string constant operands. */
+            length = 0;
+            for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
+                if (!FoldType(cx, pn2, TOK_STRING))
+                    return JS_FALSE;
+                /* XXX fold only if all operands convert to string */
+                if (pn2->pn_type != TOK_STRING)
+                    return JS_TRUE;
+                length += ATOM_TO_STRING(pn2->pn_atom)->length;
+            }
+
+            /* Allocate a new buffer and string descriptor for the result. */
+            chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
+            if (!chars)
+                return JS_FALSE;
+            str = js_NewString(cx, chars, length, 0);
+            if (!str) {
+                JS_free(cx, chars);
+                return JS_FALSE;
+            }
+
+            /* Fill the buffer, advancing chars and recycling kids as we go. */
+            for (pn2 = pn1; pn2; pn2 = RecycleTree(pn2, tc)) {
+                str2 = ATOM_TO_STRING(pn2->pn_atom);
+                length2 = str2->length;
+                js_strncpy(chars, str2->chars, length2);
+                chars += length2;
+            }
+            *chars = 0;
+
+            /* Atomize the result string and mutate pn to refer to it. */
+            pn->pn_atom = js_AtomizeString(cx, str, 0);
+            if (!pn->pn_atom)
+                return JS_FALSE;
+            pn->pn_type = TOK_STRING;
+            pn->pn_op = JSOP_STRING;
+            pn->pn_arity = PN_NULLARY;
+            break;
+        }
+
+        /* Handle a binary string concatenation. */
+        JS_ASSERT(pn->pn_arity == PN_BINARY);
+        if (pn1->pn_type == TOK_STRING || pn2->pn_type == TOK_STRING) {
+            JSString *left, *right, *str;
+
+            if (!FoldType(cx, (pn1->pn_type != TOK_STRING) ? pn1 : pn2,
+                          TOK_STRING)) {
+                return JS_FALSE;
+            }
+            if (pn1->pn_type != TOK_STRING || pn2->pn_type != TOK_STRING)
+                return JS_TRUE;
+            left = ATOM_TO_STRING(pn1->pn_atom);
+            right = ATOM_TO_STRING(pn2->pn_atom);
+            str = js_ConcatStrings(cx, left, right);
+            if (!str)
+                return JS_FALSE;
+            pn->pn_atom = js_AtomizeString(cx, str, 0);
+            if (!pn->pn_atom)
+                return JS_FALSE;
+            pn->pn_type = TOK_STRING;
+            pn->pn_op = JSOP_STRING;
+            pn->pn_arity = PN_NULLARY;
+            RecycleTree(pn1, tc);
+            RecycleTree(pn2, tc);
+            break;
+        }
+
+        /* Can't concatenate string literals, let's try numbers. */
+        goto do_binary_op;
+
+      case TOK_STAR:
+        /* The * in 'import *;' parses as a nullary star node. */
+        if (pn->pn_arity == PN_NULLARY)
+            break;
+        /* FALL THROUGH */
+
+      case TOK_SHOP:
+      case TOK_MINUS:
+      case TOK_DIVOP:
+      do_binary_op:
+        if (pn->pn_arity == PN_LIST) {
+            JS_ASSERT(pn->pn_count > 2);
+            for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
+                if (!FoldType(cx, pn2, TOK_NUMBER))
+                    return JS_FALSE;
+                /* XXX fold only if all operands convert to number */
+                if (pn2->pn_type != TOK_NUMBER)
+                    break;
+            }
+            if (!pn2) {
+                JSOp op = pn->pn_op;
+
+                pn2 = pn1->pn_next;
+                pn3 = pn2->pn_next;
+                if (!FoldBinaryNumeric(cx, op, pn1, pn2, pn, tc))
+                    return JS_FALSE;
+                while ((pn2 = pn3) != NULL) {
+                    pn3 = pn2->pn_next;
+                    if (!FoldBinaryNumeric(cx, op, pn, pn2, pn, tc))
+                        return JS_FALSE;
+                }
+            }
+        } else {
+            JS_ASSERT(pn->pn_arity == PN_BINARY);
+            if (!FoldType(cx, pn1, TOK_NUMBER) ||
+                !FoldType(cx, pn2, TOK_NUMBER)) {
+                return JS_FALSE;
+            }
+            if (pn1->pn_type == TOK_NUMBER && pn2->pn_type == TOK_NUMBER) {
+                if (!FoldBinaryNumeric(cx, pn->pn_op, pn1, pn2, pn, tc))
+                    return JS_FALSE;
+            }
+        }
+        break;
+
+      case TOK_UNARYOP:
+        if (pn1->pn_type == TOK_NUMBER) {
+            jsdouble d;
+            int32 i;
+
+            /* Operate on one numeric constant. */
+            d = pn1->pn_dval;
+            switch (pn->pn_op) {
+              case JSOP_BITNOT:
+                if (!js_DoubleToECMAInt32(cx, d, &i))
+                    return JS_FALSE;
+                d = ~i;
+                break;
+
+              case JSOP_NEG:
+#ifdef HPUX
+                /*
+                 * Negation of a zero doesn't produce a negative
+                 * zero on HPUX. Perform the operation by bit
+                 * twiddling.
+                 */
+                JSDOUBLE_HI32(d) ^= JSDOUBLE_HI32_SIGNBIT;
+#else
+                d = -d;
+#endif
+                break;
+
+              case JSOP_POS:
+                break;
+
+              case JSOP_NOT:
+                pn->pn_type = TOK_PRIMARY;
+                pn->pn_op = (d == 0) ? JSOP_TRUE : JSOP_FALSE;
+                pn->pn_arity = PN_NULLARY;
+                /* FALL THROUGH */
+
+              default:
+                /* Return early to dodge the common TOK_NUMBER code. */
+                return JS_TRUE;
+            }
+            pn->pn_type = TOK_NUMBER;
+            pn->pn_op = JSOP_NUMBER;
+            pn->pn_arity = PN_NULLARY;
+            pn->pn_dval = d;
+            RecycleTree(pn1, tc);
+        }
+        break;
+
+#if JS_HAS_XML_SUPPORT
+      case TOK_XMLELEM:
+      case TOK_XMLLIST:
+      case TOK_XMLPTAGC:
+      case TOK_XMLSTAGO:
+      case TOK_XMLETAGO:
+      case TOK_XMLNAME:
+        if (pn->pn_arity == PN_LIST) {
+            JS_ASSERT(pn->pn_type == TOK_XMLLIST || pn->pn_count != 0);
+            if (!FoldXMLConstants(cx, pn, tc))
+                return JS_FALSE;
+        }
+        break;
+
+      case TOK_AT:
+        if (pn1->pn_type == TOK_XMLNAME) {
+            jsval v;
+            JSAtom *atom;
+
+            v = ATOM_KEY(pn1->pn_atom);
+            if (!js_ToAttributeName(cx, &v))
+                return JS_FALSE;
+            JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
+            atom = js_AtomizeObject(cx, JSVAL_TO_OBJECT(v), 0);
+            if (!atom)
+                return JS_FALSE;
+
+            pn->pn_type = TOK_XMLNAME;
+            pn->pn_op = JSOP_OBJECT;
+            pn->pn_arity = PN_NULLARY;
+            pn->pn_atom = atom;
+            RecycleTree(pn1, tc);
+        }
+        break;
+#endif /* JS_HAS_XML_SUPPORT */
+
+      default:;
+    }
+
+    return JS_TRUE;
+}

Added: freeswitch/trunk/libs/js/src/jsparse.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsparse.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,414 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsparse_h___
+#define jsparse_h___
+/*
+ * JS parser definitions.
+ */
+#include "jsconfig.h"
+#include "jsprvtd.h"
+#include "jspubtd.h"
+#include "jsscan.h"
+
+JS_BEGIN_EXTERN_C
+
+/*
+ * Parsing builds a tree of nodes that directs code generation.  This tree is
+ * not a concrete syntax tree in all respects (for example, || and && are left
+ * associative, but (A && B && C) translates into the right-associated tree
+ * <A && <B && C>> so that code generation can emit a left-associative branch
+ * around <B && C> when A is false).  Nodes are labeled by token type, with a
+ * JSOp secondary label when needed:
+ *
+ * Label        Variant     Members
+ * -----        -------     -------
+ * <Definitions>
+ * TOK_FUNCTION func        pn_funAtom: atom holding function object containing
+ *                            arg and var properties.  We create the function
+ *                            object at parse (not emit) time to specialize arg
+ *                            and var bytecodes early.
+ *                          pn_body: TOK_LC node for function body statements
+ *                          pn_flags: TCF_FUN_* flags (see jsemit.h) collected
+ *                            while parsing the function's body
+ *                          pn_tryCount: of try statements in function
+ *
+ * <Statements>
+ * TOK_LC       list        pn_head: list of pn_count statements
+ * TOK_EXPORT   list        pn_head: list of pn_count TOK_NAMEs or one TOK_STAR
+ *                            (which is not a multiply node)
+ * TOK_IMPORT   list        pn_head: list of pn_count sub-trees of the form
+ *                            a.b.*, a[b].*, a.*, a.b, or a[b] -- but never a.
+ *                            Each member is expressed with TOK_DOT or TOK_LB.
+ *                            Each sub-tree's root node has a pn_op in the set
+ *                            JSOP_IMPORT{ALL,PROP,ELEM}
+ * TOK_IF       ternary     pn_kid1: cond, pn_kid2: then, pn_kid3: else or null
+ * TOK_SWITCH   binary      pn_left: discriminant
+ *                          pn_right: list of TOK_CASE nodes, with at most one
+ *                            TOK_DEFAULT node
+ * TOK_CASE,    binary      pn_left: case expr or null if TOK_DEFAULT
+ * TOK_DEFAULT              pn_right: TOK_LC node for this case's statements
+ *                          pn_val: constant value if lookup or table switch
+ * TOK_WHILE    binary      pn_left: cond, pn_right: body
+ * TOK_DO       binary      pn_left: body, pn_right: cond
+ * TOK_FOR      binary      pn_left: either
+ *                            for/in loop: a binary TOK_IN node with
+ *                              pn_left:  TOK_VAR or TOK_NAME to left of 'in'
+ *                                if TOK_VAR, its pn_extra may have PNX_POPVAR
+ *                                and PNX_FORINVAR bits set
+ *                              pn_right: object expr to right of 'in'
+ *                            for(;;) loop: a ternary TOK_RESERVED node with
+ *                              pn_kid1:  init expr before first ';'
+ *                              pn_kid2:  cond expr before second ';'
+ *                              pn_kid3:  update expr after second ';'
+ *                              any kid may be null
+ *                          pn_right: body
+ * TOK_THROW    unary       pn_op: JSOP_THROW, pn_kid: exception
+ * TOK_TRY      ternary     pn_kid1: try block
+ *                          pn_kid2: catch blocks or null
+ *                          pn_kid3: finally block or null
+ * TOK_CATCH    ternary     pn_kid1: PN_NAME node for catch var (with pn_expr
+ *                                   null or the catch guard expression)
+ *                          pn_kid2: more catch blocks or null
+ *                          pn_kid3: catch block statements
+ * TOK_BREAK    name        pn_atom: label or null
+ * TOK_CONTINUE name        pn_atom: label or null
+ * TOK_WITH     binary      pn_left: head expr, pn_right: body
+ * TOK_VAR      list        pn_head: list of pn_count TOK_NAME nodes
+ *                                   each name node has
+ *                                     pn_atom: variable name
+ *                                     pn_expr: initializer or null
+ * TOK_RETURN   unary       pn_kid: return expr or null
+ * TOK_SEMI     unary       pn_kid: expr or null statement
+ * TOK_COLON    name        pn_atom: label, pn_expr: labeled statement
+ *
+ * <Expressions>
+ * All left-associated binary trees of the same type are optimized into lists
+ * to avoid recursion when processing expression chains.
+ * TOK_COMMA    list        pn_head: list of pn_count comma-separated exprs
+ * TOK_ASSIGN   binary      pn_left: lvalue, pn_right: rvalue
+ *                          pn_op: JSOP_ADD for +=, etc.
+ * TOK_HOOK     ternary     pn_kid1: cond, pn_kid2: then, pn_kid3: else
+ * TOK_OR       binary      pn_left: first in || chain, pn_right: rest of chain
+ * TOK_AND      binary      pn_left: first in && chain, pn_right: rest of chain
+ * TOK_BITOR    binary      pn_left: left-assoc | expr, pn_right: ^ expr
+ * TOK_BITXOR   binary      pn_left: left-assoc ^ expr, pn_right: & expr
+ * TOK_BITAND   binary      pn_left: left-assoc & expr, pn_right: EQ expr
+ * TOK_EQOP     binary      pn_left: left-assoc EQ expr, pn_right: REL expr
+ *                          pn_op: JSOP_EQ, JSOP_NE, JSOP_NEW_EQ, JSOP_NEW_NE
+ * TOK_RELOP    binary      pn_left: left-assoc REL expr, pn_right: SH expr
+ *                          pn_op: JSOP_LT, JSOP_LE, JSOP_GT, JSOP_GE
+ * TOK_SHOP     binary      pn_left: left-assoc SH expr, pn_right: ADD expr
+ *                          pn_op: JSOP_LSH, JSOP_RSH, JSOP_URSH
+ * TOK_PLUS,    binary      pn_left: left-assoc ADD expr, pn_right: MUL expr
+ *                          pn_extra: if a left-associated binary TOK_PLUS
+ *                            tree has been flattened into a list (see above
+ *                            under <Expressions>), pn_extra will contain
+ *                            PNX_STRCAT if at least one list element is a
+ *                            string literal (TOK_STRING); if such a list has
+ *                            any non-string, non-number term, pn_extra will
+ *                            contain PNX_CANTFOLD.
+ *                          pn_
+ * TOK_MINUS                pn_op: JSOP_ADD, JSOP_SUB
+ * TOK_STAR,    binary      pn_left: left-assoc MUL expr, pn_right: UNARY expr
+ * TOK_DIVOP                pn_op: JSOP_MUL, JSOP_DIV, JSOP_MOD
+ * TOK_UNARYOP  unary       pn_kid: UNARY expr, pn_op: JSOP_NEG, JSOP_POS,
+ *                          JSOP_NOT, JSOP_BITNOT, JSOP_TYPEOF, JSOP_VOID
+ * TOK_INC,     unary       pn_kid: MEMBER expr
+ * TOK_DEC
+ * TOK_NEW      list        pn_head: list of ctor, arg1, arg2, ... argN
+ *                          pn_count: 1 + N (where N is number of args)
+ *                          ctor is a MEMBER expr
+ * TOK_DELETE   unary       pn_kid: MEMBER expr
+ * TOK_DOT,     name        pn_expr: MEMBER expr to left of .
+ * TOK_DBLDOT               pn_atom: name to right of .
+ * TOK_LB       binary      pn_left: MEMBER expr to left of [
+ *                          pn_right: expr between [ and ]
+ * TOK_LP       list        pn_head: list of call, arg1, arg2, ... argN
+ *                          pn_count: 1 + N (where N is number of args)
+ *                          call is a MEMBER expr naming a callable object
+ * TOK_RB       list        pn_head: list of pn_count array element exprs
+ *                          [,,] holes are represented by TOK_COMMA nodes
+ *                          #n=[...] produces TOK_DEFSHARP at head of list
+ *                          pn_extra: PN_ENDCOMMA if extra comma at end
+ * TOK_RC       list        pn_head: list of pn_count TOK_COLON nodes where
+ *                          each has pn_left: property id, pn_right: value
+ *                          #n={...} produces TOK_DEFSHARP at head of list
+ * TOK_DEFSHARP unary       pn_num: jsint value of n in #n=
+ *                          pn_kid: null for #n=[...] and #n={...}, primary
+ *                          if #n=primary for function, paren, name, object
+ *                          literal expressions
+ * TOK_USESHARP nullary     pn_num: jsint value of n in #n#
+ * TOK_RP       unary       pn_kid: parenthesized expression
+ * TOK_NAME,    name        pn_atom: name, string, or object atom
+ * TOK_STRING,              pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT, or
+ *                                 JSOP_REGEXP
+ * TOK_OBJECT               If JSOP_NAME, pn_op may be JSOP_*ARG or JSOP_*VAR
+ *                          with pn_slot >= 0 and pn_attrs telling const-ness
+ * TOK_NUMBER   dval        pn_dval: double value of numeric literal
+ * TOK_PRIMARY  nullary     pn_op: JSOp bytecode
+ * TOK_ANYNAME  nullary     pn_op: JSOP_ANYNAME
+ *                          pn_atom: cx->runtime->atomState.starAtom
+ * TOK_AT       unary       pn_op: JSOP_TOATTRNAME; pn_kid attribute id/expr
+ * TOK_DBLCOLON binary      pn_op: JSOP_QNAME
+ *                          pn_left: TOK_ANYNAME or TOK_NAME node
+ *                          pn_right: TOK_STRING "*" node, or expr within []
+ *              name        pn_op: JSOP_QNAMECONST
+ *                          pn_expr: TOK_ANYNAME or TOK_NAME left operand
+ *                          pn_atom: name on right of ::
+ * TOK_XMLELEM  list        XML element node
+ *                          pn_head: start tag, content1, ... contentN, end tag
+ *                          pn_count: 2 + N where N is number of content nodes
+ *                                    N may be > x.length() if {expr} embedded
+ * TOK_XMLLIST  list        XML list node
+ *                          pn_head: content1, ... contentN
+ * TOK_XMLSTAGO, list       XML start, end, and point tag contents
+ * TOK_XMLETAGC,            pn_head: tag name or {expr}, ... XML attrs ...
+ * TOK_XMLPTAGO
+ * TOK_XMLNAME  nullary     pn_atom: XML name, with no {expr} embedded
+ * TOK_XMLNAME  list        pn_head: tag name or {expr}, ... name or {expr}
+ * TOK_XMLATTR, nullary     pn_atom: attribute value string; pn_op: JSOP_STRING
+ * TOK_XMLCDATA,
+ * TOK_XMLCOMMENT
+ * TOK_XMLPI    nullary     pn_atom: XML processing instruction target
+ *                          pn_atom2: XML PI content, or null if no content
+ * TOK_XMLTEXT  nullary     pn_atom: marked-up text, or null if empty string
+ * TOK_LC       unary       {expr} in XML tag or content; pn_kid is expr
+ *
+ * So an XML tag with no {expr} and three attributes is a list with the form:
+ *
+ *    (tagname attrname1 attrvalue1 attrname2 attrvalue2 attrname2 attrvalue3)
+ *
+ * An XML tag with embedded expressions like so:
+ *
+ *    <name1{expr1} name2{expr2}name3={expr3}>
+ *
+ * would have the form:
+ *
+ *    ((name1 {expr1}) (name2 {expr2} name3) {expr3})
+ *
+ * where () bracket a list with elements separated by spaces, and {expr} is a
+ * TOK_LC unary node with expr as its kid.
+ *
+ * Thus, the attribute name/value pairs occupy successive odd and even list
+ * locations, where pn_head is the TOK_XMLNAME node at list location 0.  The
+ * parser builds the same sort of structures for elements:
+ *
+ *    <a x={x}>Hi there!<b y={y}>How are you?</b><answer>{x + y}</answer></a>
+ *
+ * translates to:
+ *
+ *    ((a x {x}) 'Hi there!' ((b y {y}) 'How are you?') ((answer) {x + y}))
+ */
+typedef enum JSParseNodeArity {
+    PN_FUNC     = -3,
+    PN_LIST     = -2,
+    PN_TERNARY  =  3,
+    PN_BINARY   =  2,
+    PN_UNARY    =  1,
+    PN_NAME     = -1,
+    PN_NULLARY  =  0
+} JSParseNodeArity;
+
+struct JSParseNode {
+    uint16              pn_type;
+    uint8               pn_op;
+    int8                pn_arity;
+    JSTokenPos          pn_pos;
+    ptrdiff_t           pn_offset;      /* first generated bytecode offset */
+    union {
+        struct {                        /* TOK_FUNCTION node */
+            JSAtom      *funAtom;       /* atomized function object */
+            JSParseNode *body;          /* TOK_LC list of statements */
+            uint32      flags;          /* accumulated tree context flags */
+            uint32      tryCount;       /* count of try statements in body */
+        } func;
+        struct {                        /* list of next-linked nodes */
+            JSParseNode *head;          /* first node in list */
+            JSParseNode **tail;         /* ptr to ptr to last node in list */
+            uint32      count;          /* number of nodes in list */
+            uint32      extra;          /* extra comma flag for [1,2,,] */
+        } list;
+        struct {                        /* ternary: if, for(;;), ?: */
+            JSParseNode *kid1;          /* condition, discriminant, etc. */
+            JSParseNode *kid2;          /* then-part, case list, etc. */
+            JSParseNode *kid3;          /* else-part, default case, etc. */
+        } ternary;
+        struct {                        /* two kids if binary */
+            JSParseNode *left;
+            JSParseNode *right;
+            jsval       val;            /* switch case value */
+        } binary;
+        struct {                        /* one kid if unary */
+            JSParseNode *kid;
+            jsint       num;            /* -1 or sharp variable number */
+        } unary;
+        struct {                        /* name, labeled statement, etc. */
+            JSAtom      *atom;          /* name or label atom, null if slot */
+            JSParseNode *expr;          /* object or initializer */
+            jsint       slot;           /* -1 or arg or local var slot */
+            uintN       attrs;          /* attributes if local var or const */
+        } name;
+        struct {
+            JSAtom      *atom;          /* first atom in pair */
+            JSAtom      *atom2;         /* second atom in pair or null */
+        } apair;
+        jsdouble        dval;           /* aligned numeric literal value */
+    } pn_u;
+    JSParseNode         *pn_next;       /* to align dval and pn_u on RISCs */
+#if JS_HAS_XML_SUPPORT
+    JSTokenStream       *pn_ts;         /* token stream for XML error reports */
+#endif
+};
+
+#define pn_funAtom      pn_u.func.funAtom
+#define pn_body         pn_u.func.body
+#define pn_flags        pn_u.func.flags
+#define pn_tryCount     pn_u.func.tryCount
+#define pn_head         pn_u.list.head
+#define pn_tail         pn_u.list.tail
+#define pn_count        pn_u.list.count
+#define pn_extra        pn_u.list.extra
+#define pn_kid1         pn_u.ternary.kid1
+#define pn_kid2         pn_u.ternary.kid2
+#define pn_kid3         pn_u.ternary.kid3
+#define pn_left         pn_u.binary.left
+#define pn_right        pn_u.binary.right
+#define pn_val          pn_u.binary.val
+#define pn_kid          pn_u.unary.kid
+#define pn_num          pn_u.unary.num
+#define pn_atom         pn_u.name.atom
+#define pn_expr         pn_u.name.expr
+#define pn_slot         pn_u.name.slot
+#define pn_attrs        pn_u.name.attrs
+#define pn_dval         pn_u.dval
+#define pn_atom2        pn_u.apair.atom2
+
+/* PN_LIST pn_extra flags. */
+#define PNX_STRCAT      0x01            /* TOK_PLUS list has string term */
+#define PNX_CANTFOLD    0x02            /* TOK_PLUS list has unfoldable term */
+#define PNX_POPVAR      0x04            /* TOK_VAR last result needs popping */
+#define PNX_FORINVAR    0x08            /* TOK_VAR is left kid of TOK_IN node,
+                                           which is left kid of TOK_FOR */
+#define PNX_ENDCOMMA    0x10            /* array literal has comma at end */
+#define PNX_XMLROOT     0x20            /* top-most node in XML literal tree */
+
+/*
+ * Move pn2 into pn, preserving pn->pn_pos and pn->pn_offset and handing off
+ * any kids in pn2->pn_u, by clearing pn2.
+ */
+#define PN_MOVE_NODE(pn, pn2)                                                 \
+    JS_BEGIN_MACRO                                                            \
+        (pn)->pn_type = (pn2)->pn_type;                                       \
+        (pn)->pn_op = (pn2)->pn_op;                                           \
+        (pn)->pn_arity = (pn2)->pn_arity;                                     \
+        (pn)->pn_u = (pn2)->pn_u;                                             \
+        PN_CLEAR_NODE(pn2);                                                   \
+    JS_END_MACRO
+
+#define PN_CLEAR_NODE(pn)                                                     \
+    JS_BEGIN_MACRO                                                            \
+        (pn)->pn_type = TOK_EOF;                                              \
+        (pn)->pn_op = JSOP_NOP;                                               \
+        (pn)->pn_arity = PN_NULLARY;                                          \
+    JS_END_MACRO
+
+/* True if pn is a parsenode representing a literal constant. */
+#define PN_IS_CONSTANT(pn)                                                    \
+    ((pn)->pn_type == TOK_NUMBER ||                                           \
+     (pn)->pn_type == TOK_STRING ||                                           \
+     ((pn)->pn_type == TOK_PRIMARY && (pn)->pn_op != JSOP_THIS))
+
+/*
+ * Compute a pointer to the last JSParseNode element in a singly-linked list.
+ * NB: list must be non-empty for correct PN_LAST usage!
+ */
+#define PN_LAST(list) \
+    ((JSParseNode *)((char *)(list)->pn_tail - offsetof(JSParseNode, pn_next)))
+
+#define PN_INIT_LIST(list)                                                    \
+    JS_BEGIN_MACRO                                                            \
+        (list)->pn_head = NULL;                                               \
+        (list)->pn_tail = &(list)->pn_head;                                   \
+        (list)->pn_count = (list)->pn_extra = 0;                              \
+    JS_END_MACRO
+
+#define PN_INIT_LIST_1(list, pn)                                              \
+    JS_BEGIN_MACRO                                                            \
+        (list)->pn_head = (pn);                                               \
+        (list)->pn_tail = &(pn)->pn_next;                                     \
+        (list)->pn_count = 1;                                                 \
+        (list)->pn_extra = 0;                                                 \
+    JS_END_MACRO
+
+#define PN_APPEND(list, pn)                                                   \
+    JS_BEGIN_MACRO                                                            \
+        *(list)->pn_tail = (pn);                                              \
+        (list)->pn_tail = &(pn)->pn_next;                                     \
+        (list)->pn_count++;                                                   \
+    JS_END_MACRO
+
+/*
+ * Parse a top-level JS script.
+ *
+ * The caller must prevent the GC from running while this function is active,
+ * because atoms and function newborns are not rooted yet.
+ */
+extern JS_FRIEND_API(JSParseNode *)
+js_ParseTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts);
+
+extern JS_FRIEND_API(JSBool)
+js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts,
+                      JSCodeGenerator *cg);
+
+extern JSBool
+js_CompileFunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun);
+
+extern JSBool
+js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc);
+
+#if JS_HAS_XML_SUPPORT
+JS_FRIEND_API(JSParseNode *)
+js_ParseXMLTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts,
+                       JSBool allowList);
+#endif
+
+JS_END_EXTERN_C
+
+#endif /* jsparse_h___ */

Added: freeswitch/trunk/libs/js/src/jsprf.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsprf.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1269 @@
+/* -*- 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 Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** Portable safe sprintf code.
+**
+** Author: Kipp E.B. Hickman
+*/
+#include "jsstddef.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "jsprf.h"
+#include "jslong.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jspubtd.h"
+#include "jsstr.h"
+
+/*
+** Note: on some platforms va_list is defined as an array,
+** and requires array notation.
+*/
+#ifdef OSSP
+#include "../config.h"
+#define VARARGS_ASSIGN(foo, bar)        va_copy(foo,bar)
+#else
+#ifdef HAVE_VA_COPY
+#define VARARGS_ASSIGN(foo, bar)        VA_COPY(foo,bar)
+#elif defined(HAVE_VA_LIST_AS_ARRAY)
+#define VARARGS_ASSIGN(foo, bar)        foo[0] = bar[0]
+#else
+#define VARARGS_ASSIGN(foo, bar)        (foo) = (bar)
+#endif
+#endif
+
+/*
+** WARNING: This code may *NOT* call JS_LOG (because JS_LOG calls it)
+*/
+
+/*
+** XXX This needs to be internationalized!
+*/
+
+typedef struct SprintfStateStr SprintfState;
+
+struct SprintfStateStr {
+    int (*stuff)(SprintfState *ss, const char *sp, JSUint32 len);
+
+    char *base;
+    char *cur;
+    JSUint32 maxlen;
+
+    int (*func)(void *arg, const char *sp, JSUint32 len);
+    void *arg;
+};
+
+/*
+** Numbered Arguement State
+*/
+struct NumArgState{
+    int     type;               /* type of the current ap                    */
+    va_list ap;                 /* point to the corresponding position on ap */
+};
+
+#define NAS_DEFAULT_NUM 20  /* default number of NumberedArgumentState array */
+
+
+#define TYPE_INT16      0
+#define TYPE_UINT16     1
+#define TYPE_INTN       2
+#define TYPE_UINTN      3
+#define TYPE_INT32      4
+#define TYPE_UINT32     5
+#define TYPE_INT64      6
+#define TYPE_UINT64     7
+#define TYPE_STRING     8
+#define TYPE_DOUBLE     9
+#define TYPE_INTSTR     10
+#define TYPE_WSTRING    11
+#define TYPE_UNKNOWN    20
+
+#define FLAG_LEFT       0x1
+#define FLAG_SIGNED     0x2
+#define FLAG_SPACED     0x4
+#define FLAG_ZEROS      0x8
+#define FLAG_NEG        0x10
+
+/*
+** Fill into the buffer using the data in src
+*/
+static int fill2(SprintfState *ss, const char *src, int srclen, int width,
+                int flags)
+{
+    char space = ' ';
+    int rv;
+
+    width -= srclen;
+    if ((width > 0) && ((flags & FLAG_LEFT) == 0)) {    /* Right adjusting */
+        if (flags & FLAG_ZEROS) {
+            space = '0';
+        }
+        while (--width >= 0) {
+            rv = (*ss->stuff)(ss, &space, 1);
+            if (rv < 0) {
+                return rv;
+            }
+        }
+    }
+
+    /* Copy out the source data */
+    rv = (*ss->stuff)(ss, src, (JSUint32)srclen);
+    if (rv < 0) {
+        return rv;
+    }
+
+    if ((width > 0) && ((flags & FLAG_LEFT) != 0)) {    /* Left adjusting */
+        while (--width >= 0) {
+            rv = (*ss->stuff)(ss, &space, 1);
+            if (rv < 0) {
+                return rv;
+            }
+        }
+    }
+    return 0;
+}
+
+/*
+** Fill a number. The order is: optional-sign zero-filling conversion-digits
+*/
+static int fill_n(SprintfState *ss, const char *src, int srclen, int width,
+                  int prec, int type, int flags)
+{
+    int zerowidth = 0;
+    int precwidth = 0;
+    int signwidth = 0;
+    int leftspaces = 0;
+    int rightspaces = 0;
+    int cvtwidth;
+    int rv;
+    char sign;
+
+    if ((type & 1) == 0) {
+        if (flags & FLAG_NEG) {
+            sign = '-';
+            signwidth = 1;
+        } else if (flags & FLAG_SIGNED) {
+            sign = '+';
+            signwidth = 1;
+        } else if (flags & FLAG_SPACED) {
+            sign = ' ';
+            signwidth = 1;
+        }
+    }
+    cvtwidth = signwidth + srclen;
+
+    if (prec > 0) {
+        if (prec > srclen) {
+            precwidth = prec - srclen;          /* Need zero filling */
+            cvtwidth += precwidth;
+        }
+    }
+
+    if ((flags & FLAG_ZEROS) && (prec < 0)) {
+        if (width > cvtwidth) {
+            zerowidth = width - cvtwidth;       /* Zero filling */
+            cvtwidth += zerowidth;
+        }
+    }
+
+    if (flags & FLAG_LEFT) {
+        if (width > cvtwidth) {
+            /* Space filling on the right (i.e. left adjusting) */
+            rightspaces = width - cvtwidth;
+        }
+    } else {
+        if (width > cvtwidth) {
+            /* Space filling on the left (i.e. right adjusting) */
+            leftspaces = width - cvtwidth;
+        }
+    }
+    while (--leftspaces >= 0) {
+        rv = (*ss->stuff)(ss, " ", 1);
+        if (rv < 0) {
+            return rv;
+        }
+    }
+    if (signwidth) {
+        rv = (*ss->stuff)(ss, &sign, 1);
+        if (rv < 0) {
+            return rv;
+        }
+    }
+    while (--precwidth >= 0) {
+        rv = (*ss->stuff)(ss, "0", 1);
+        if (rv < 0) {
+            return rv;
+        }
+    }
+    while (--zerowidth >= 0) {
+        rv = (*ss->stuff)(ss, "0", 1);
+        if (rv < 0) {
+            return rv;
+        }
+    }
+    rv = (*ss->stuff)(ss, src, (JSUint32)srclen);
+    if (rv < 0) {
+        return rv;
+    }
+    while (--rightspaces >= 0) {
+        rv = (*ss->stuff)(ss, " ", 1);
+        if (rv < 0) {
+            return rv;
+        }
+    }
+    return 0;
+}
+
+/*
+** Convert a long into its printable form
+*/
+static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix,
+                 int type, int flags, const char *hexp)
+{
+    char cvtbuf[100];
+    char *cvt;
+    int digits;
+
+    /* according to the man page this needs to happen */
+    if ((prec == 0) && (num == 0)) {
+        return 0;
+    }
+
+    /*
+    ** Converting decimal is a little tricky. In the unsigned case we
+    ** need to stop when we hit 10 digits. In the signed case, we can
+    ** stop when the number is zero.
+    */
+    cvt = cvtbuf + sizeof(cvtbuf);
+    digits = 0;
+    while (num) {
+        int digit = (((unsigned long)num) % radix) & 0xF;
+        *--cvt = hexp[digit];
+        digits++;
+        num = (long)(((unsigned long)num) / radix);
+    }
+    if (digits == 0) {
+        *--cvt = '0';
+        digits++;
+    }
+
+    /*
+    ** Now that we have the number converted without its sign, deal with
+    ** the sign and zero padding.
+    */
+    return fill_n(ss, cvt, digits, width, prec, type, flags);
+}
+
+/*
+** Convert a 64-bit integer into its printable form
+*/
+static int cvt_ll(SprintfState *ss, JSInt64 num, int width, int prec, int radix,
+                  int type, int flags, const char *hexp)
+{
+    char cvtbuf[100];
+    char *cvt;
+    int digits;
+    JSInt64 rad;
+
+    /* according to the man page this needs to happen */
+    if ((prec == 0) && (JSLL_IS_ZERO(num))) {
+        return 0;
+    }
+
+    /*
+    ** Converting decimal is a little tricky. In the unsigned case we
+    ** need to stop when we hit 10 digits. In the signed case, we can
+    ** stop when the number is zero.
+    */
+    JSLL_I2L(rad, radix);
+    cvt = cvtbuf + sizeof(cvtbuf);
+    digits = 0;
+    while (!JSLL_IS_ZERO(num)) {
+        JSInt32 digit;
+        JSInt64 quot, rem;
+        JSLL_UDIVMOD(&quot, &rem, num, rad);
+        JSLL_L2I(digit, rem);
+        *--cvt = hexp[digit & 0xf];
+        digits++;
+        num = quot;
+    }
+    if (digits == 0) {
+        *--cvt = '0';
+        digits++;
+    }
+
+    /*
+    ** Now that we have the number converted without its sign, deal with
+    ** the sign and zero padding.
+    */
+    return fill_n(ss, cvt, digits, width, prec, type, flags);
+}
+
+/*
+** Convert a double precision floating point number into its printable
+** form.
+**
+** XXX stop using sprintf to convert floating point
+*/
+static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1)
+{
+    char fin[20];
+    char fout[300];
+    int amount = fmt1 - fmt0;
+
+    JS_ASSERT((amount > 0) && (amount < (int)sizeof(fin)));
+    if (amount >= (int)sizeof(fin)) {
+        /* Totally bogus % command to sprintf. Just ignore it */
+        return 0;
+    }
+    memcpy(fin, fmt0, (size_t)amount);
+    fin[amount] = 0;
+
+    /* Convert floating point using the native sprintf code */
+#ifdef DEBUG
+    {
+        const char *p = fin;
+        while (*p) {
+            JS_ASSERT(*p != 'L');
+            p++;
+        }
+    }
+#endif
+    sprintf(fout, fin, d);
+
+    /*
+    ** This assert will catch overflow's of fout, when building with
+    ** debugging on. At least this way we can track down the evil piece
+    ** of calling code and fix it!
+    */
+    JS_ASSERT(strlen(fout) < sizeof(fout));
+
+    return (*ss->stuff)(ss, fout, strlen(fout));
+}
+
+/*
+** Convert a string into its printable form.  "width" is the output
+** width. "prec" is the maximum number of characters of "s" to output,
+** where -1 means until NUL.
+*/
+static int cvt_s(SprintfState *ss, const char *s, int width, int prec,
+                 int flags)
+{
+    int slen;
+
+    if (prec == 0)
+        return 0;
+
+    /* Limit string length by precision value */
+    slen = s ? strlen(s) : 6;
+    if (prec > 0) {
+        if (prec < slen) {
+            slen = prec;
+        }
+    }
+
+    /* and away we go */
+    return fill2(ss, s ? s : "(null)", slen, width, flags);
+}
+
+static int cvt_ws(SprintfState *ss, const jschar *ws, int width, int prec,
+                  int flags)
+{
+    int result;
+    /* 
+     * Supply NULL as the JSContext; errors are not reported, 
+     * and malloc() is used to allocate the buffer buffer. 
+     */
+    if (ws) {
+        int slen = js_strlen(ws);
+        char *s = js_DeflateString(NULL, ws, slen);
+        if (!s)
+            return -1; /* JSStuffFunc error indicator. */
+        result = cvt_s(ss, s, width, prec, flags);
+        free(s);
+    } else {
+        result = cvt_s(ss, NULL, width, prec, flags);
+    }
+    return result;
+}
+
+/*
+** BuildArgArray stands for Numbered Argument list Sprintf
+** for example,
+**      fmp = "%4$i, %2$d, %3s, %1d";
+** the number must start from 1, and no gap among them
+*/
+
+static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, struct NumArgState* nasArray )
+{
+    int number = 0, cn = 0, i;
+    const char *p;
+    char c;
+    struct NumArgState *nas;
+
+
+    /*
+    **  first pass:
+    **  detemine how many legal % I have got, then allocate space
+    */
+
+    p = fmt;
+    *rv = 0;
+    i = 0;
+    while( ( c = *p++ ) != 0 ){
+        if( c != '%' )
+            continue;
+        if( ( c = *p++ ) == '%' )       /* skip %% case */
+            continue;
+
+        while( c != 0 ){
+            if( c > '9' || c < '0' ){
+                if( c == '$' ){         /* numbered argument csae */
+                    if( i > 0 ){
+                        *rv = -1;
+                        return NULL;
+                    }
+                    number++;
+                } else {                /* non-numbered argument case */
+                    if( number > 0 ){
+                        *rv = -1;
+                        return NULL;
+                    }
+                    i = 1;
+                }
+                break;
+            }
+
+            c = *p++;
+        }
+    }
+
+    if( number == 0 ){
+        return NULL;
+    }
+
+
+    if( number > NAS_DEFAULT_NUM ){
+        nas = (struct NumArgState*)malloc( number * sizeof( struct NumArgState ) );
+        if( !nas ){
+            *rv = -1;
+            return NULL;
+        }
+    } else {
+        nas = nasArray;
+    }
+
+    for( i = 0; i < number; i++ ){
+        nas[i].type = TYPE_UNKNOWN;
+    }
+
+
+    /*
+    ** second pass:
+    ** set nas[].type
+    */
+
+    p = fmt;
+    while( ( c = *p++ ) != 0 ){
+        if( c != '%' )  continue;
+            c = *p++;
+        if( c == '%' )  continue;
+
+        cn = 0;
+        while( c && c != '$' ){     /* should improve error check later */
+            cn = cn*10 + c - '0';
+            c = *p++;
+        }
+
+        if( !c || cn < 1 || cn > number ){
+            *rv = -1;
+            break;
+        }
+
+        /* nas[cn] starts from 0, and make sure nas[cn].type is not assigned */
+        cn--;
+        if( nas[cn].type != TYPE_UNKNOWN )
+            continue;
+
+        c = *p++;
+
+        /* width */
+        if (c == '*') {
+            /* not supported feature, for the argument is not numbered */
+            *rv = -1;
+            break;
+        }
+
+        while ((c >= '0') && (c <= '9')) {
+            c = *p++;
+        }
+
+        /* precision */
+        if (c == '.') {
+            c = *p++;
+            if (c == '*') {
+                /* not supported feature, for the argument is not numbered */
+                *rv = -1;
+                break;
+            }
+
+            while ((c >= '0') && (c <= '9')) {
+                c = *p++;
+            }
+        }
+
+        /* size */
+        nas[cn].type = TYPE_INTN;
+        if (c == 'h') {
+            nas[cn].type = TYPE_INT16;
+            c = *p++;
+        } else if (c == 'L') {
+            /* XXX not quite sure here */
+            nas[cn].type = TYPE_INT64;
+            c = *p++;
+        } else if (c == 'l') {
+            nas[cn].type = TYPE_INT32;
+            c = *p++;
+            if (c == 'l') {
+                nas[cn].type = TYPE_INT64;
+                c = *p++;
+            }
+        }
+
+        /* format */
+        switch (c) {
+        case 'd':
+        case 'c':
+        case 'i':
+        case 'o':
+        case 'u':
+        case 'x':
+        case 'X':
+            break;
+
+        case 'e':
+        case 'f':
+        case 'g':
+            nas[ cn ].type = TYPE_DOUBLE;
+            break;
+
+        case 'p':
+            /* XXX should use cpp */
+            if (sizeof(void *) == sizeof(JSInt32)) {
+                nas[ cn ].type = TYPE_UINT32;
+            } else if (sizeof(void *) == sizeof(JSInt64)) {
+                nas[ cn ].type = TYPE_UINT64;
+            } else if (sizeof(void *) == sizeof(JSIntn)) {
+                nas[ cn ].type = TYPE_UINTN;
+            } else {
+                nas[ cn ].type = TYPE_UNKNOWN;
+            }
+            break;
+
+        case 'C':
+        case 'S':
+        case 'E':
+        case 'G':
+            /* XXX not supported I suppose */
+            JS_ASSERT(0);
+            nas[ cn ].type = TYPE_UNKNOWN;
+            break;
+
+        case 's':
+            nas[ cn ].type = (nas[ cn ].type == TYPE_UINT16) ? TYPE_WSTRING : TYPE_STRING;
+            break;
+
+        case 'n':
+            nas[ cn ].type = TYPE_INTSTR;
+            break;
+
+        default:
+            JS_ASSERT(0);
+            nas[ cn ].type = TYPE_UNKNOWN;
+            break;
+        }
+
+        /* get a legal para. */
+        if( nas[ cn ].type == TYPE_UNKNOWN ){
+            *rv = -1;
+            break;
+        }
+    }
+
+
+    /*
+    ** third pass
+    ** fill the nas[cn].ap
+    */
+
+    if( *rv < 0 ){
+        if( nas != nasArray )
+            free( nas );
+        return NULL;
+    }
+
+    cn = 0;
+    while( cn < number ){
+        if( nas[cn].type == TYPE_UNKNOWN ){
+            cn++;
+            continue;
+        }
+
+        VARARGS_ASSIGN(nas[cn].ap, ap);
+
+        switch( nas[cn].type ){
+        case TYPE_INT16:
+        case TYPE_UINT16:
+        case TYPE_INTN:
+        case TYPE_UINTN:                (void)va_arg( ap, JSIntn );             break;
+
+        case TYPE_INT32:                (void)va_arg( ap, JSInt32 );            break;
+
+        case TYPE_UINT32:       (void)va_arg( ap, JSUint32 );   break;
+
+        case TYPE_INT64:        (void)va_arg( ap, JSInt64 );            break;
+
+        case TYPE_UINT64:       (void)va_arg( ap, JSUint64 );           break;
+
+        case TYPE_STRING:       (void)va_arg( ap, char* );              break;
+
+        case TYPE_WSTRING:      (void)va_arg( ap, jschar* );            break;
+
+        case TYPE_INTSTR:       (void)va_arg( ap, JSIntn* );            break;
+
+        case TYPE_DOUBLE:       (void)va_arg( ap, double );             break;
+
+        default:
+            if( nas != nasArray )
+                free( nas );
+            *rv = -1;
+            return NULL;
+        }
+
+        cn++;
+    }
+
+
+    return nas;
+}
+
+/*
+** The workhorse sprintf code.
+*/
+static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
+{
+    char c;
+    int flags, width, prec, radix, type;
+    union {
+        char ch;
+        jschar wch;
+        int i;
+        long l;
+        JSInt64 ll;
+        double d;
+        const char *s;
+        const jschar* ws;
+        int *ip;
+    } u;
+    const char *fmt0;
+    static char *hex = "0123456789abcdef";
+    static char *HEX = "0123456789ABCDEF";
+    char *hexp;
+    int rv, i;
+    struct NumArgState *nas = NULL;
+    struct NumArgState nasArray[ NAS_DEFAULT_NUM ];
+    char pattern[20];
+    const char *dolPt = NULL;  /* in "%4$.2f", dolPt will poiont to . */
+#ifdef JS_C_STRINGS_ARE_UTF8
+    char utf8buf[6];
+    int utf8len;
+#endif
+
+    /*
+    ** build an argument array, IF the fmt is numbered argument
+    ** list style, to contain the Numbered Argument list pointers
+    */
+
+    nas = BuildArgArray( fmt, ap, &rv, nasArray );
+    if( rv < 0 ){
+        /* the fmt contains error Numbered Argument format, jliu at netscape.com */
+        JS_ASSERT(0);
+        return rv;
+    }
+
+    while ((c = *fmt++) != 0) {
+        if (c != '%') {
+            rv = (*ss->stuff)(ss, fmt - 1, 1);
+            if (rv < 0) {
+                return rv;
+            }
+            continue;
+        }
+        fmt0 = fmt - 1;
+
+        /*
+        ** Gobble up the % format string. Hopefully we have handled all
+        ** of the strange cases!
+        */
+        flags = 0;
+        c = *fmt++;
+        if (c == '%') {
+            /* quoting a % with %% */
+            rv = (*ss->stuff)(ss, fmt - 1, 1);
+            if (rv < 0) {
+                return rv;
+            }
+            continue;
+        }
+
+        if( nas != NULL ){
+            /* the fmt contains the Numbered Arguments feature */
+            i = 0;
+            while( c && c != '$' ){         /* should imporve error check later */
+                i = ( i * 10 ) + ( c - '0' );
+                c = *fmt++;
+            }
+
+            if( nas[i-1].type == TYPE_UNKNOWN ){
+                if( nas && ( nas != nasArray ) )
+                    free( nas );
+                return -1;
+            }
+
+            ap = nas[i-1].ap;
+            dolPt = fmt;
+            c = *fmt++;
+        }
+
+        /*
+         * Examine optional flags.  Note that we do not implement the
+         * '#' flag of sprintf().  The ANSI C spec. of the '#' flag is
+         * somewhat ambiguous and not ideal, which is perhaps why
+         * the various sprintf() implementations are inconsistent
+         * on this feature.
+         */
+        while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) {
+            if (c == '-') flags |= FLAG_LEFT;
+            if (c == '+') flags |= FLAG_SIGNED;
+            if (c == ' ') flags |= FLAG_SPACED;
+            if (c == '0') flags |= FLAG_ZEROS;
+            c = *fmt++;
+        }
+        if (flags & FLAG_SIGNED) flags &= ~FLAG_SPACED;
+        if (flags & FLAG_LEFT) flags &= ~FLAG_ZEROS;
+
+        /* width */
+        if (c == '*') {
+            c = *fmt++;
+            width = va_arg(ap, int);
+        } else {
+            width = 0;
+            while ((c >= '0') && (c <= '9')) {
+                width = (width * 10) + (c - '0');
+                c = *fmt++;
+            }
+        }
+
+        /* precision */
+        prec = -1;
+        if (c == '.') {
+            c = *fmt++;
+            if (c == '*') {
+                c = *fmt++;
+                prec = va_arg(ap, int);
+            } else {
+                prec = 0;
+                while ((c >= '0') && (c <= '9')) {
+                    prec = (prec * 10) + (c - '0');
+                    c = *fmt++;
+                }
+            }
+        }
+
+        /* size */
+        type = TYPE_INTN;
+        if (c == 'h') {
+            type = TYPE_INT16;
+            c = *fmt++;
+        } else if (c == 'L') {
+            /* XXX not quite sure here */
+            type = TYPE_INT64;
+            c = *fmt++;
+        } else if (c == 'l') {
+            type = TYPE_INT32;
+            c = *fmt++;
+            if (c == 'l') {
+                type = TYPE_INT64;
+                c = *fmt++;
+            }
+        }
+
+        /* format */
+        hexp = hex;
+        switch (c) {
+          case 'd': case 'i':                   /* decimal/integer */
+            radix = 10;
+            goto fetch_and_convert;
+
+          case 'o':                             /* octal */
+            radix = 8;
+            type |= 1;
+            goto fetch_and_convert;
+
+          case 'u':                             /* unsigned decimal */
+            radix = 10;
+            type |= 1;
+            goto fetch_and_convert;
+
+          case 'x':                             /* unsigned hex */
+            radix = 16;
+            type |= 1;
+            goto fetch_and_convert;
+
+          case 'X':                             /* unsigned HEX */
+            radix = 16;
+            hexp = HEX;
+            type |= 1;
+            goto fetch_and_convert;
+
+          fetch_and_convert:
+            switch (type) {
+              case TYPE_INT16:
+                u.l = va_arg(ap, int);
+                if (u.l < 0) {
+                    u.l = -u.l;
+                    flags |= FLAG_NEG;
+                }
+                goto do_long;
+              case TYPE_UINT16:
+                u.l = va_arg(ap, int) & 0xffff;
+                goto do_long;
+              case TYPE_INTN:
+                u.l = va_arg(ap, int);
+                if (u.l < 0) {
+                    u.l = -u.l;
+                    flags |= FLAG_NEG;
+                }
+                goto do_long;
+              case TYPE_UINTN:
+                u.l = (long)va_arg(ap, unsigned int);
+                goto do_long;
+
+              case TYPE_INT32:
+                u.l = va_arg(ap, JSInt32);
+                if (u.l < 0) {
+                    u.l = -u.l;
+                    flags |= FLAG_NEG;
+                }
+                goto do_long;
+              case TYPE_UINT32:
+                u.l = (long)va_arg(ap, JSUint32);
+              do_long:
+                rv = cvt_l(ss, u.l, width, prec, radix, type, flags, hexp);
+                if (rv < 0) {
+                    return rv;
+                }
+                break;
+
+              case TYPE_INT64:
+                u.ll = va_arg(ap, JSInt64);
+                if (!JSLL_GE_ZERO(u.ll)) {
+                    JSLL_NEG(u.ll, u.ll);
+                    flags |= FLAG_NEG;
+                }
+                goto do_longlong;
+              case TYPE_UINT64:
+                u.ll = va_arg(ap, JSUint64);
+              do_longlong:
+                rv = cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp);
+                if (rv < 0) {
+                    return rv;
+                }
+                break;
+            }
+            break;
+
+          case 'e':
+          case 'E':
+          case 'f':
+          case 'g':
+            u.d = va_arg(ap, double);
+            if( nas != NULL ){
+                i = fmt - dolPt;
+                if( i < (int)sizeof( pattern ) ){
+                    pattern[0] = '%';
+                    memcpy( &pattern[1], dolPt, (size_t)i );
+                    rv = cvt_f(ss, u.d, pattern, &pattern[i+1] );
+                }
+            } else
+                rv = cvt_f(ss, u.d, fmt0, fmt);
+
+            if (rv < 0) {
+                return rv;
+            }
+            break;
+
+          case 'c':
+            if ((flags & FLAG_LEFT) == 0) {
+                while (width-- > 1) {
+                    rv = (*ss->stuff)(ss, " ", 1);
+                    if (rv < 0) {
+                        return rv;
+                    }
+                }
+            }
+            switch (type) {
+              case TYPE_INT16:
+                /* Treat %hc as %c if JS_C_STRINGS_ARE_UTF8 is undefined. */
+#ifdef JS_C_STRINGS_ARE_UTF8
+                u.wch = va_arg(ap, int);
+                utf8len = js_OneUcs4ToUtf8Char (utf8buf, u.wch);
+                rv = (*ss->stuff)(ss, utf8buf, utf8len);
+                break;
+#endif
+              case TYPE_INTN:
+                u.ch = va_arg(ap, int);
+                rv = (*ss->stuff)(ss, &u.ch, 1);
+                break;
+            }
+            if (rv < 0) {
+                return rv;
+            }
+            if (flags & FLAG_LEFT) {
+                while (width-- > 1) {
+                    rv = (*ss->stuff)(ss, " ", 1);
+                    if (rv < 0) {
+                        return rv;
+                    }
+                }
+            }
+            break;
+
+          case 'p':
+            if (sizeof(void *) == sizeof(JSInt32)) {
+                type = TYPE_UINT32;
+            } else if (sizeof(void *) == sizeof(JSInt64)) {
+                type = TYPE_UINT64;
+            } else if (sizeof(void *) == sizeof(int)) {
+                type = TYPE_UINTN;
+            } else {
+                JS_ASSERT(0);
+                break;
+            }
+            radix = 16;
+            goto fetch_and_convert;
+
+#if 0
+          case 'C':
+          case 'S':
+          case 'E':
+          case 'G':
+            /* XXX not supported I suppose */
+            JS_ASSERT(0);
+            break;
+#endif
+
+          case 's':
+            if(type == TYPE_INT16) {
+                /* 
+                 * This would do a simple string/byte conversion 
+                 * if JS_C_STRINGS_ARE_UTF8 is not defined. 
+                 */
+                u.ws = va_arg(ap, const jschar*);
+                rv = cvt_ws(ss, u.ws, width, prec, flags);
+            } else {
+                u.s = va_arg(ap, const char*);
+                rv = cvt_s(ss, u.s, width, prec, flags);
+            }
+            if (rv < 0) {
+                return rv;
+            }
+            break;
+
+          case 'n':
+            u.ip = va_arg(ap, int*);
+            if (u.ip) {
+                *u.ip = ss->cur - ss->base;
+            }
+            break;
+
+          default:
+            /* Not a % token after all... skip it */
+#if 0
+            JS_ASSERT(0);
+#endif
+            rv = (*ss->stuff)(ss, "%", 1);
+            if (rv < 0) {
+                return rv;
+            }
+            rv = (*ss->stuff)(ss, fmt - 1, 1);
+            if (rv < 0) {
+                return rv;
+            }
+        }
+    }
+
+    /* Stuff trailing NUL */
+    rv = (*ss->stuff)(ss, "\0", 1);
+
+    if( nas && ( nas != nasArray ) ){
+        free( nas );
+    }
+
+    return rv;
+}
+
+/************************************************************************/
+
+static int FuncStuff(SprintfState *ss, const char *sp, JSUint32 len)
+{
+    int rv;
+
+    rv = (*ss->func)(ss->arg, sp, len);
+    if (rv < 0) {
+        return rv;
+    }
+    ss->maxlen += len;
+    return 0;
+}
+
+JS_PUBLIC_API(JSUint32) JS_sxprintf(JSStuffFunc func, void *arg,
+                                    const char *fmt, ...)
+{
+    va_list ap;
+    int rv;
+
+    va_start(ap, fmt);
+    rv = JS_vsxprintf(func, arg, fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+JS_PUBLIC_API(JSUint32) JS_vsxprintf(JSStuffFunc func, void *arg,
+                                     const char *fmt, va_list ap)
+{
+    SprintfState ss;
+    int rv;
+
+    ss.stuff = FuncStuff;
+    ss.func = func;
+    ss.arg = arg;
+    ss.maxlen = 0;
+    rv = dosprintf(&ss, fmt, ap);
+    return (rv < 0) ? (JSUint32)-1 : ss.maxlen;
+}
+
+/*
+** Stuff routine that automatically grows the malloc'd output buffer
+** before it overflows.
+*/
+static int GrowStuff(SprintfState *ss, const char *sp, JSUint32 len)
+{
+    ptrdiff_t off;
+    char *newbase;
+    JSUint32 newlen;
+
+    off = ss->cur - ss->base;
+    if (off + len >= ss->maxlen) {
+        /* Grow the buffer */
+        newlen = ss->maxlen + ((len > 32) ? len : 32);
+        if (ss->base) {
+            newbase = (char*) realloc(ss->base, newlen);
+        } else {
+            newbase = (char*) malloc(newlen);
+        }
+        if (!newbase) {
+            /* Ran out of memory */
+            return -1;
+        }
+        ss->base = newbase;
+        ss->maxlen = newlen;
+        ss->cur = ss->base + off;
+    }
+
+    /* Copy data */
+    while (len) {
+        --len;
+        *ss->cur++ = *sp++;
+    }
+    JS_ASSERT((JSUint32)(ss->cur - ss->base) <= ss->maxlen);
+    return 0;
+}
+
+/*
+** sprintf into a malloc'd buffer
+*/
+JS_PUBLIC_API(char *) JS_smprintf(const char *fmt, ...)
+{
+    va_list ap;
+    char *rv;
+
+    va_start(ap, fmt);
+    rv = JS_vsmprintf(fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+/*
+** Free memory allocated, for the caller, by JS_smprintf
+*/
+JS_PUBLIC_API(void) JS_smprintf_free(char *mem)
+{
+        free(mem);
+}
+
+JS_PUBLIC_API(char *) JS_vsmprintf(const char *fmt, va_list ap)
+{
+    SprintfState ss;
+    int rv;
+
+    ss.stuff = GrowStuff;
+    ss.base = 0;
+    ss.cur = 0;
+    ss.maxlen = 0;
+    rv = dosprintf(&ss, fmt, ap);
+    if (rv < 0) {
+        if (ss.base) {
+            free(ss.base);
+        }
+        return 0;
+    }
+    return ss.base;
+}
+
+/*
+** Stuff routine that discards overflow data
+*/
+static int LimitStuff(SprintfState *ss, const char *sp, JSUint32 len)
+{
+    JSUint32 limit = ss->maxlen - (ss->cur - ss->base);
+
+    if (len > limit) {
+        len = limit;
+    }
+    while (len) {
+        --len;
+        *ss->cur++ = *sp++;
+    }
+    return 0;
+}
+
+/*
+** sprintf into a fixed size buffer. Make sure there is a NUL at the end
+** when finished.
+*/
+JS_PUBLIC_API(JSUint32) JS_snprintf(char *out, JSUint32 outlen, const char *fmt, ...)
+{
+    va_list ap;
+    int rv;
+
+    JS_ASSERT((JSInt32)outlen > 0);
+    if ((JSInt32)outlen <= 0) {
+        return 0;
+    }
+
+    va_start(ap, fmt);
+    rv = JS_vsnprintf(out, outlen, fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+JS_PUBLIC_API(JSUint32) JS_vsnprintf(char *out, JSUint32 outlen,const char *fmt,
+                                  va_list ap)
+{
+    SprintfState ss;
+    JSUint32 n;
+
+    JS_ASSERT((JSInt32)outlen > 0);
+    if ((JSInt32)outlen <= 0) {
+        return 0;
+    }
+
+    ss.stuff = LimitStuff;
+    ss.base = out;
+    ss.cur = out;
+    ss.maxlen = outlen;
+    (void) dosprintf(&ss, fmt, ap);
+
+    /* If we added chars, and we didn't append a null, do it now. */
+    if( (ss.cur != ss.base) && (ss.cur[-1] != '\0') )
+        ss.cur[-1] = '\0';
+
+    n = ss.cur - ss.base;
+    return n ? n - 1 : n;
+}
+
+JS_PUBLIC_API(char *) JS_sprintf_append(char *last, const char *fmt, ...)
+{
+    va_list ap;
+    char *rv;
+
+    va_start(ap, fmt);
+    rv = JS_vsprintf_append(last, fmt, ap);
+    va_end(ap);
+    return rv;
+}
+
+JS_PUBLIC_API(char *) JS_vsprintf_append(char *last, const char *fmt, va_list ap)
+{
+    SprintfState ss;
+    int rv;
+
+    ss.stuff = GrowStuff;
+    if (last) {
+        int lastlen = strlen(last);
+        ss.base = last;
+        ss.cur = last + lastlen;
+        ss.maxlen = lastlen;
+    } else {
+        ss.base = 0;
+        ss.cur = 0;
+        ss.maxlen = 0;
+    }
+    rv = dosprintf(&ss, fmt, ap);
+    if (rv < 0) {
+        if (ss.base) {
+            free(ss.base);
+        }
+        return 0;
+    }
+    return ss.base;
+}
+

Added: freeswitch/trunk/libs/js/src/jsprf.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsprf.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,150 @@
+/* -*- 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 Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsprf_h___
+#define jsprf_h___
+
+/*
+** API for PR printf like routines. Supports the following formats
+**      %d - decimal
+**      %u - unsigned decimal
+**      %x - unsigned hex
+**      %X - unsigned uppercase hex
+**      %o - unsigned octal
+**      %hd, %hu, %hx, %hX, %ho - 16-bit versions of above
+**      %ld, %lu, %lx, %lX, %lo - 32-bit versions of above
+**      %lld, %llu, %llx, %llX, %llo - 64 bit versions of above
+**      %s - string
+**      %hs - 16-bit version of above (only available if compiled with JS_C_STRINGS_ARE_UTF8)
+**      %c - character
+**      %hc - 16-bit version of above (only available if compiled with JS_C_STRINGS_ARE_UTF8)
+**      %p - pointer (deals with machine dependent pointer size)
+**      %f - float
+**      %g - float
+*/
+#include "jstypes.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+JS_BEGIN_EXTERN_C
+
+/*
+** sprintf into a fixed size buffer. Guarantees that a NUL is at the end
+** of the buffer. Returns the length of the written output, NOT including
+** the NUL, or (JSUint32)-1 if an error occurs.
+*/
+extern JS_PUBLIC_API(JSUint32) JS_snprintf(char *out, JSUint32 outlen, const char *fmt, ...);
+
+/*
+** sprintf into a malloc'd buffer. Return a pointer to the malloc'd
+** buffer on success, NULL on failure. Call "JS_smprintf_free" to release
+** the memory returned.
+*/
+extern JS_PUBLIC_API(char*) JS_smprintf(const char *fmt, ...);
+
+/*
+** Free the memory allocated, for the caller, by JS_smprintf
+*/
+extern JS_PUBLIC_API(void) JS_smprintf_free(char *mem);
+
+/*
+** "append" sprintf into a malloc'd buffer. "last" is the last value of
+** the malloc'd buffer. sprintf will append data to the end of last,
+** growing it as necessary using realloc. If last is NULL, JS_sprintf_append
+** will allocate the initial string. The return value is the new value of
+** last for subsequent calls, or NULL if there is a malloc failure.
+*/
+extern JS_PUBLIC_API(char*) JS_sprintf_append(char *last, const char *fmt, ...);
+
+/*
+** sprintf into a function. The function "f" is called with a string to
+** place into the output. "arg" is an opaque pointer used by the stuff
+** function to hold any state needed to do the storage of the output
+** data. The return value is a count of the number of characters fed to
+** the stuff function, or (JSUint32)-1 if an error occurs.
+*/
+typedef JSIntn (*JSStuffFunc)(void *arg, const char *s, JSUint32 slen);
+
+extern JS_PUBLIC_API(JSUint32) JS_sxprintf(JSStuffFunc f, void *arg, const char *fmt, ...);
+
+/*
+** va_list forms of the above.
+*/
+extern JS_PUBLIC_API(JSUint32) JS_vsnprintf(char *out, JSUint32 outlen, const char *fmt, va_list ap);
+extern JS_PUBLIC_API(char*) JS_vsmprintf(const char *fmt, va_list ap);
+extern JS_PUBLIC_API(char*) JS_vsprintf_append(char *last, const char *fmt, va_list ap);
+extern JS_PUBLIC_API(JSUint32) JS_vsxprintf(JSStuffFunc f, void *arg, const char *fmt, va_list ap);
+
+/*
+***************************************************************************
+** FUNCTION: JS_sscanf
+** DESCRIPTION:
+**     JS_sscanf() scans the input character string, performs data
+**     conversions, and stores the converted values in the data objects
+**     pointed to by its arguments according to the format control
+**     string.
+**
+**     JS_sscanf() behaves the same way as the sscanf() function in the
+**     Standard C Library (stdio.h), with the following exceptions:
+**     - JS_sscanf() handles the NSPR integer and floating point types,
+**       such as JSInt16, JSInt32, JSInt64, and JSFloat64, whereas
+**       sscanf() handles the standard C types like short, int, long,
+**       and double.
+**     - JS_sscanf() has no multibyte character support, while sscanf()
+**       does.
+** INPUTS:
+**     const char *buf
+**         a character string holding the input to scan
+**     const char *fmt
+**         the format control string for the conversions
+**     ...
+**         variable number of arguments, each of them is a pointer to
+**         a data object in which the converted value will be stored
+** OUTPUTS: none
+** RETURNS: JSInt32
+**     The number of values converted and stored.
+** RESTRICTIONS:
+**    Multibyte characters in 'buf' or 'fmt' are not allowed.
+***************************************************************************
+*/
+
+extern JS_PUBLIC_API(JSInt32) JS_sscanf(const char *buf, const char *fmt, ...);
+
+JS_END_EXTERN_C
+
+#endif /* jsprf_h___ */

Added: freeswitch/trunk/libs/js/src/jsprvtd.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsprvtd.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,203 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsprvtd_h___
+#define jsprvtd_h___
+/*
+ * JS private typename definitions.
+ *
+ * This header is included only in other .h files, for convenience and for
+ * simplicity of type naming.  The alternative for structures is to use tags,
+ * which are named the same as their typedef names (legal in C/C++, and less
+ * noisy than suffixing the typedef name with "Struct" or "Str").  Instead,
+ * all .h files that include this file may use the same typedef name, whether
+ * declaring a pointer to struct type, or defining a member of struct type.
+ *
+ * A few fundamental scalar types are defined here too.  Neither the scalar
+ * nor the struct typedefs should change much, therefore the nearly-global
+ * make dependency induced by this file should not prove painful.
+ */
+
+#include "jspubtd.h"
+
+/* Internal identifier (jsid) macros. */
+#define JSID_ATOM                   0x0
+#define JSID_INT                    0x1
+#define JSID_OBJECT                 0x2
+#define JSID_TAGMASK                0x3
+#define JSID_TAG(id)                ((id) & JSID_TAGMASK)
+#define JSID_SETTAG(id,t)           ((id) | (t))
+#define JSID_CLRTAG(id)             ((id) & ~(jsid)JSID_TAGMASK)
+
+#define JSID_IS_ATOM(id)            (JSID_TAG(id) == JSID_ATOM)
+#define JSID_TO_ATOM(id)            ((JSAtom *)(id))
+#define ATOM_TO_JSID(atom)          ((jsid)(atom))
+#define ATOM_JSID_TO_JSVAL(id)      ATOM_KEY(JSID_TO_ATOM(id))
+
+#define JSID_IS_INT(id)             ((id) & JSID_INT)
+#define JSID_TO_INT(id)             ((jsint)(id) >> 1)
+#define INT_TO_JSID(i)              (((jsint)(i) << 1) | JSID_INT)
+#define INT_JSID_TO_JSVAL(id)       (id)
+#define INT_JSVAL_TO_JSID(v)        (v)
+
+#define JSID_IS_OBJECT(id)          (JSID_TAG(id) == JSID_OBJECT)
+#define JSID_TO_OBJECT(id)          ((JSObject *) JSID_CLRTAG(id))
+#define OBJECT_TO_JSID(obj)         ((jsid)(obj) | JSID_OBJECT)
+#define OBJECT_JSID_TO_JSVAL(id)    OBJECT_TO_JSVAL(JSID_CLRTAG(id))
+#define OBJECT_JSVAL_TO_JSID(v)     OBJECT_TO_JSID(JSVAL_TO_OBJECT(v))
+
+/* Scalar typedefs. */
+typedef uint8  jsbytecode;
+typedef uint8  jssrcnote;
+typedef uint32 jsatomid;
+
+/* Struct typedefs. */
+typedef struct JSArgumentFormatMap  JSArgumentFormatMap;
+typedef struct JSCodeGenerator      JSCodeGenerator;
+typedef struct JSDependentString    JSDependentString;
+typedef struct JSGCLockHashEntry    JSGCLockHashEntry;
+typedef struct JSGCRootHashEntry    JSGCRootHashEntry;
+typedef struct JSGCThing            JSGCThing;
+typedef struct JSParseNode          JSParseNode;
+typedef struct JSSharpObjectMap     JSSharpObjectMap;
+typedef struct JSToken              JSToken;
+typedef struct JSTokenPos           JSTokenPos;
+typedef struct JSTokenPtr           JSTokenPtr;
+typedef struct JSTokenStream        JSTokenStream;
+typedef struct JSTreeContext        JSTreeContext;
+typedef struct JSTryNote            JSTryNote;
+
+/* Friend "Advanced API" typedefs. */
+typedef struct JSAtom               JSAtom;
+typedef struct JSAtomList           JSAtomList;
+typedef struct JSAtomListElement    JSAtomListElement;
+typedef struct JSAtomMap            JSAtomMap;
+typedef struct JSAtomState          JSAtomState;
+typedef struct JSCodeSpec           JSCodeSpec;
+typedef struct JSPrinter            JSPrinter;
+typedef struct JSRegExp             JSRegExp;
+typedef struct JSRegExpStatics      JSRegExpStatics;
+typedef struct JSScope              JSScope;
+typedef struct JSScopeOps           JSScopeOps;
+typedef struct JSScopeProperty      JSScopeProperty;
+typedef struct JSStackFrame         JSStackFrame;
+typedef struct JSStackHeader        JSStackHeader;
+typedef struct JSStringBuffer       JSStringBuffer;
+typedef struct JSSubString          JSSubString;
+typedef struct JSXML                JSXML;
+typedef struct JSXMLNamespace       JSXMLNamespace;
+typedef struct JSXMLQName           JSXMLQName;
+typedef struct JSXMLArray           JSXMLArray;
+typedef struct JSXMLArrayCursor     JSXMLArrayCursor;
+
+/* "Friend" types used by jscntxt.h and jsdbgapi.h. */
+typedef enum JSTrapStatus {
+    JSTRAP_ERROR,
+    JSTRAP_CONTINUE,
+    JSTRAP_RETURN,
+    JSTRAP_THROW,
+    JSTRAP_LIMIT
+} JSTrapStatus;
+
+typedef JSTrapStatus
+(* JS_DLL_CALLBACK JSTrapHandler)(JSContext *cx, JSScript *script,
+                                  jsbytecode *pc, jsval *rval, void *closure);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsval id,
+                                        jsval old, jsval *newp, void *closure);
+
+/* called just after script creation */
+typedef void
+(* JS_DLL_CALLBACK JSNewScriptHook)(JSContext  *cx,
+                                    const char *filename,  /* URL of script */
+                                    uintN      lineno,     /* first line */
+                                    JSScript   *script,
+                                    JSFunction *fun,
+                                    void       *callerdata);
+
+/* called just before script destruction */
+typedef void
+(* JS_DLL_CALLBACK JSDestroyScriptHook)(JSContext *cx,
+                                        JSScript  *script,
+                                        void      *callerdata);
+
+typedef void
+(* JS_DLL_CALLBACK JSSourceHandler)(const char *filename, uintN lineno,
+                                    jschar *str, size_t length,
+                                    void **listenerTSData, void *closure);
+
+/*
+ * This hook captures high level script execution and function calls (JS or
+ * native).  It is used by JS_SetExecuteHook to hook top level scripts and by
+ * JS_SetCallHook to hook function calls.  It will get called twice per script
+ * or function call: just before execution begins and just after it finishes.
+ * In both cases the 'current' frame is that of the executing code.
+ *
+ * The 'before' param is JS_TRUE for the hook invocation before the execution
+ * and JS_FALSE for the invocation after the code has run.
+ *
+ * The 'ok' param is significant only on the post execution invocation to
+ * signify whether or not the code completed 'normally'.
+ *
+ * The 'closure' param is as passed to JS_SetExecuteHook or JS_SetCallHook
+ * for the 'before'invocation, but is whatever value is returned from that
+ * invocation for the 'after' invocation. Thus, the hook implementor *could*
+ * allocate a stucture in the 'before' invocation and return a pointer to that
+ * structure. The pointer would then be handed to the hook for the 'after'
+ * invocation. Alternately, the 'before' could just return the same value as
+ * in 'closure' to cause the 'after' invocation to be called with the same
+ * 'closure' value as the 'before'.
+ *
+ * Returning NULL in the 'before' hook will cause the 'after' hook *not* to
+ * be called.
+ */
+typedef void *
+(* JS_DLL_CALLBACK JSInterpreterHook)(JSContext *cx, JSStackFrame *fp, JSBool before,
+                                      JSBool *ok, void *closure);
+
+typedef void
+(* JS_DLL_CALLBACK JSObjectHook)(JSContext *cx, JSObject *obj, JSBool isNew,
+                                 void *closure);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSDebugErrorHook)(JSContext *cx, const char *message,
+                                     JSErrorReport *report, void *closure);
+
+#endif /* jsprvtd_h___ */

Added: freeswitch/trunk/libs/js/src/jspubtd.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jspubtd.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,635 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jspubtd_h___
+#define jspubtd_h___
+/*
+ * JS public API typedefs.
+ */
+#include "jstypes.h"
+#include "jscompat.h"
+
+JS_BEGIN_EXTERN_C
+
+/* Scalar typedefs. */
+typedef uint16    jschar;
+typedef int32     jsint;
+typedef uint32    jsuint;
+typedef float64   jsdouble;
+typedef jsword    jsval;
+typedef jsword    jsid;
+typedef int32     jsrefcount;   /* PRInt32 if JS_THREADSAFE, see jslock.h */
+
+/*
+ * Run-time version enumeration.  See jsconfig.h for compile-time counterparts
+ * to these values that may be selected by the JS_VERSION macro, and tested by
+ * #if expressions.
+ */
+typedef enum JSVersion {
+    JSVERSION_1_0     = 100,
+    JSVERSION_1_1     = 110,
+    JSVERSION_1_2     = 120,
+    JSVERSION_1_3     = 130,
+    JSVERSION_1_4     = 140,
+    JSVERSION_ECMA_3  = 148,
+    JSVERSION_1_5     = 150,
+    JSVERSION_1_6     = 160,
+    JSVERSION_DEFAULT = 0,
+    JSVERSION_UNKNOWN = -1
+} JSVersion;
+
+#define JSVERSION_IS_ECMA(version) \
+    ((version) == JSVERSION_DEFAULT || (version) >= JSVERSION_1_3)
+
+/* Result of typeof operator enumeration. */
+typedef enum JSType {
+    JSTYPE_VOID,                /* undefined */
+    JSTYPE_OBJECT,              /* object */
+    JSTYPE_FUNCTION,            /* function */
+    JSTYPE_STRING,              /* string */
+    JSTYPE_NUMBER,              /* number */
+    JSTYPE_BOOLEAN,             /* boolean */
+    JSTYPE_NULL,                /* null */
+    JSTYPE_XML,                 /* xml object */
+    JSTYPE_LIMIT
+} JSType;
+
+/* JSObjectOps.checkAccess mode enumeration. */
+typedef enum JSAccessMode {
+    JSACC_PROTO  = 0,           /* XXXbe redundant w.r.t. id */
+    JSACC_PARENT = 1,           /* XXXbe redundant w.r.t. id */
+    JSACC_IMPORT = 2,           /* import foo.bar */
+    JSACC_WATCH  = 3,           /* a watchpoint on object foo for id 'bar' */
+    JSACC_READ   = 4,           /* a "get" of foo.bar */
+    JSACC_WRITE  = 8,           /* a "set" of foo.bar = baz */
+    JSACC_LIMIT
+} JSAccessMode;
+
+#define JSACC_TYPEMASK          (JSACC_WRITE - 1)
+
+/*
+ * This enum type is used to control the behavior of a JSObject property
+ * iterator function that has type JSNewEnumerate.
+ */
+typedef enum JSIterateOp {
+    JSENUMERATE_INIT,       /* Create new iterator state */
+    JSENUMERATE_NEXT,       /* Iterate once */
+    JSENUMERATE_DESTROY     /* Destroy iterator state */
+} JSIterateOp;
+
+/* Struct typedefs. */
+typedef struct JSClass           JSClass;
+typedef struct JSExtendedClass   JSExtendedClass;
+typedef struct JSConstDoubleSpec JSConstDoubleSpec;
+typedef struct JSContext         JSContext;
+typedef struct JSErrorReport     JSErrorReport;
+typedef struct JSFunction        JSFunction;
+typedef struct JSFunctionSpec    JSFunctionSpec;
+typedef struct JSIdArray         JSIdArray;
+typedef struct JSProperty        JSProperty;
+typedef struct JSPropertySpec    JSPropertySpec;
+typedef struct JSObject          JSObject;
+typedef struct JSObjectMap       JSObjectMap;
+typedef struct JSObjectOps       JSObjectOps;
+typedef struct JSXMLObjectOps    JSXMLObjectOps;
+typedef struct JSRuntime         JSRuntime;
+typedef struct JSRuntime         JSTaskState;   /* XXX deprecated name */
+typedef struct JSScript          JSScript;
+typedef struct JSString          JSString;
+typedef struct JSXDRState        JSXDRState;
+typedef struct JSExceptionState  JSExceptionState;
+typedef struct JSLocaleCallbacks JSLocaleCallbacks;
+
+/* JSClass (and JSObjectOps where appropriate) function pointer typedefs. */
+
+/*
+ * Add, delete, get or set a property named by id in obj.  Note the jsval id
+ * type -- id may be a string (Unicode property identifier) or an int (element
+ * index).  The *vp out parameter, on success, is the new property value after
+ * an add, get, or set.  After a successful delete, *vp is JSVAL_FALSE iff
+ * obj[id] can't be deleted (because it's permanent).
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSPropertyOp)(JSContext *cx, JSObject *obj, jsval id,
+                                 jsval *vp);
+
+/*
+ * This function type is used for callbacks that enumerate the properties of
+ * a JSObject.  The behavior depends on the value of enum_op:
+ *
+ *  JSENUMERATE_INIT
+ *    A new, opaque iterator state should be allocated and stored in *statep.
+ *    (You can use PRIVATE_TO_JSVAL() to tag the pointer to be stored).
+ *
+ *    The number of properties that will be enumerated should be returned as
+ *    an integer jsval in *idp, if idp is non-null, and provided the number of
+ *    enumerable properties is known.  If idp is non-null and the number of
+ *    enumerable properties can't be computed in advance, *idp should be set
+ *    to JSVAL_ZERO.
+ *
+ *  JSENUMERATE_NEXT
+ *    A previously allocated opaque iterator state is passed in via statep.
+ *    Return the next jsid in the iteration using *idp.  The opaque iterator
+ *    state pointed at by statep is destroyed and *statep is set to JSVAL_NULL
+ *    if there are no properties left to enumerate.
+ *
+ *  JSENUMERATE_DESTROY
+ *    Destroy the opaque iterator state previously allocated in *statep by a
+ *    call to this function when enum_op was JSENUMERATE_INIT.
+ *
+ * The return value is used to indicate success, with a value of JS_FALSE
+ * indicating failure.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSNewEnumerateOp)(JSContext *cx, JSObject *obj,
+                                     JSIterateOp enum_op,
+                                     jsval *statep, jsid *idp);
+
+/*
+ * The old-style JSClass.enumerate op should define all lazy properties not
+ * yet reflected in obj.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSEnumerateOp)(JSContext *cx, JSObject *obj);
+
+/*
+ * Resolve a lazy property named by id in obj by defining it directly in obj.
+ * Lazy properties are those reflected from some peer native property space
+ * (e.g., the DOM attributes for a given node reflected as obj) on demand.
+ *
+ * JS looks for a property in an object, and if not found, tries to resolve
+ * the given id.  If resolve succeeds, the engine looks again in case resolve
+ * defined obj[id].  If no such property exists directly in obj, the process
+ * is repeated with obj's prototype, etc.
+ *
+ * NB: JSNewResolveOp provides a cheaper way to resolve lazy properties.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSResolveOp)(JSContext *cx, JSObject *obj, jsval id);
+
+/*
+ * Like JSResolveOp, but flags provide contextual information as follows:
+ *
+ *  JSRESOLVE_QUALIFIED   a qualified property id: obj.id or obj[id], not id
+ *  JSRESOLVE_ASSIGNING   obj[id] is on the left-hand side of an assignment
+ *  JSRESOLVE_DETECTING   'if (o.p)...' or similar detection opcode sequence
+ *  JSRESOLVE_DECLARING   var, const, or function prolog declaration opcode
+ *  JSRESOLVE_CLASSNAME   class name used when constructing
+ *
+ * The *objp out parameter, on success, should be null to indicate that id
+ * was not resolved; and non-null, referring to obj or one of its prototypes,
+ * if id was resolved.
+ *
+ * This hook instead of JSResolveOp is called via the JSClass.resolve member
+ * if JSCLASS_NEW_RESOLVE is set in JSClass.flags.
+ *
+ * Setting JSCLASS_NEW_RESOLVE and JSCLASS_NEW_RESOLVE_GETS_START further
+ * extends this hook by passing in the starting object on the prototype chain
+ * via *objp.  Thus a resolve hook implementation may define the property id
+ * being resolved in the object in which the id was first sought, rather than
+ * in a prototype object whose class led to the resolve hook being called.
+ *
+ * When using JSCLASS_NEW_RESOLVE_GETS_START, the resolve hook must therefore
+ * null *objp to signify "not resolved".  With only JSCLASS_NEW_RESOLVE and no
+ * JSCLASS_NEW_RESOLVE_GETS_START, the hook can assume *objp is null on entry.
+ * This is not good practice, but enough existing hook implementations count
+ * on it that we can't break compatibility by passing the starting object in
+ * *objp without a new JSClass flag.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSNewResolveOp)(JSContext *cx, JSObject *obj, jsval id,
+                                   uintN flags, JSObject **objp);
+
+/*
+ * Convert obj to the given type, returning true with the resulting value in
+ * *vp on success, and returning false on error or exception.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSConvertOp)(JSContext *cx, JSObject *obj, JSType type,
+                                jsval *vp);
+
+/*
+ * Finalize obj, which the garbage collector has determined to be unreachable
+ * from other live objects or from GC roots.  Obviously, finalizers must never
+ * store a reference to obj.
+ */
+typedef void
+(* JS_DLL_CALLBACK JSFinalizeOp)(JSContext *cx, JSObject *obj);
+
+/*
+ * Used by JS_AddExternalStringFinalizer and JS_RemoveExternalStringFinalizer
+ * to extend and reduce the set of string types finalized by the GC.
+ */
+typedef void
+(* JS_DLL_CALLBACK JSStringFinalizeOp)(JSContext *cx, JSString *str);
+
+/*
+ * The signature for JSClass.getObjectOps, used by JS_NewObject's internals
+ * to discover the set of high-level object operations to use for new objects
+ * of the given class.  All native objects have a JSClass, which is stored as
+ * a private (int-tagged) pointer in obj->slots[JSSLOT_CLASS].  In contrast,
+ * all native and host objects have a JSObjectMap at obj->map, which may be
+ * shared among a number of objects, and which contains the JSObjectOps *ops
+ * pointer used to dispatch object operations from API calls.
+ *
+ * Thus JSClass (which pre-dates JSObjectOps in the API) provides a low-level
+ * interface to class-specific code and data, while JSObjectOps allows for a
+ * higher level of operation, which does not use the object's class except to
+ * find the class's JSObjectOps struct, by calling clasp->getObjectOps, and to
+ * finalize the object.
+ *
+ * If this seems backwards, that's because it is!  API compatibility requires
+ * a JSClass *clasp parameter to JS_NewObject, etc.  Most host objects do not
+ * need to implement the larger JSObjectOps, and can share the common JSScope
+ * code and data used by the native (js_ObjectOps, see jsobj.c) ops.
+ *
+ * Further extension to preserve API compatibility: if this function returns
+ * a pointer to JSXMLObjectOps.base, not to JSObjectOps, then the engine calls
+ * extended hooks needed for E4X.
+ */
+typedef JSObjectOps *
+(* JS_DLL_CALLBACK JSGetObjectOps)(JSContext *cx, JSClass *clasp);
+
+/*
+ * JSClass.checkAccess type: check whether obj[id] may be accessed per mode,
+ * returning false on error/exception, true on success with obj[id]'s last-got
+ * value in *vp, and its attributes in *attrsp.  As for JSPropertyOp above, id
+ * is either a string or an int jsval.
+ *
+ * See JSCheckAccessIdOp, below, for the JSObjectOps counterpart, which takes
+ * a jsid (a tagged int or aligned, unique identifier pointer) rather than a
+ * jsval.  The native js_ObjectOps.checkAccess simply forwards to the object's
+ * clasp->checkAccess, so that both JSClass and JSObjectOps implementors may
+ * specialize access checks.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSCheckAccessOp)(JSContext *cx, JSObject *obj, jsval id,
+                                    JSAccessMode mode, jsval *vp);
+
+/*
+ * Encode or decode an object, given an XDR state record representing external
+ * data.  See jsxdrapi.h.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSXDRObjectOp)(JSXDRState *xdr, JSObject **objp);
+
+/*
+ * Check whether v is an instance of obj.  Return false on error or exception,
+ * true on success with JS_TRUE in *bp if v is an instance of obj, JS_FALSE in
+ * *bp otherwise.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSHasInstanceOp)(JSContext *cx, JSObject *obj, jsval v,
+                                    JSBool *bp);
+
+/*
+ * Function type for JSClass.mark and JSObjectOps.mark, called from the GC to
+ * scan live GC-things reachable from obj's private data structure.  For each
+ * such thing, a mark implementation must call
+ *
+ *    JS_MarkGCThing(cx, thing, name, arg);
+ *
+ * The trailing name and arg parameters are used for GC_MARK_DEBUG-mode heap
+ * dumping and ref-path tracing.  The mark function should pass a (typically
+ * literal) string naming the private data member for name, and it must pass
+ * the opaque arg parameter through from its caller.
+ *
+ * For the JSObjectOps.mark hook, the return value is the number of slots at
+ * obj->slots to scan.  For JSClass.mark, the return value is ignored.
+ *
+ * NB: JSMarkOp implementations cannot allocate new GC-things (JS_NewObject
+ * called from a mark function will fail silently, e.g.).
+ */
+typedef uint32
+(* JS_DLL_CALLBACK JSMarkOp)(JSContext *cx, JSObject *obj, void *arg);
+
+/*
+ * The optional JSClass.reserveSlots hook allows a class to make computed
+ * per-instance object slots reservations, in addition to or instead of using
+ * JSCLASS_HAS_RESERVED_SLOTS(n) in the JSClass.flags initializer to reserve
+ * a constant-per-class number of slots.  Implementations of this hook should
+ * return the number of slots to reserve, not including any reserved by using
+ * JSCLASS_HAS_RESERVED_SLOTS(n) in JSClass.flags.
+ *
+ * NB: called with obj locked by the JSObjectOps-specific mutual exclusion
+ * mechanism appropriate for obj, so don't nest other operations that might
+ * also lock obj.
+ */
+typedef uint32
+(* JS_DLL_CALLBACK JSReserveSlotsOp)(JSContext *cx, JSObject *obj);
+
+/* JSObjectOps function pointer typedefs. */
+
+/*
+ * Create a new subclass of JSObjectMap (see jsobj.h), with the nrefs and ops
+ * members initialized from the same-named parameters, and with the nslots and
+ * freeslot members initialized according to ops and clasp.  Return null on
+ * error, non-null on success.
+ *
+ * JSObjectMaps are reference-counted by generic code in the engine.  Usually,
+ * the nrefs parameter to JSObjectOps.newObjectMap will be 1, to count the ref
+ * returned to the caller on success.  After a successful construction, some
+ * number of js_HoldObjectMap and js_DropObjectMap calls ensue.  When nrefs
+ * reaches 0 due to a js_DropObjectMap call, JSObjectOps.destroyObjectMap will
+ * be called to dispose of the map.
+ */
+typedef JSObjectMap *
+(* JS_DLL_CALLBACK JSNewObjectMapOp)(JSContext *cx, jsrefcount nrefs,
+                                     JSObjectOps *ops, JSClass *clasp,
+                                     JSObject *obj);
+
+/*
+ * Generic type for an infallible JSObjectMap operation, used currently by
+ * JSObjectOps.destroyObjectMap.
+ */
+typedef void
+(* JS_DLL_CALLBACK JSObjectMapOp)(JSContext *cx, JSObjectMap *map);
+
+/*
+ * Look for id in obj and its prototype chain, returning false on error or
+ * exception, true on success.  On success, return null in *propp if id was
+ * not found.  If id was found, return the first object searching from obj
+ * along its prototype chain in which id names a direct property in *objp, and
+ * return a non-null, opaque property pointer in *propp.
+ *
+ * If JSLookupPropOp succeeds and returns with *propp non-null, that pointer
+ * may be passed as the prop parameter to a JSAttributesOp, as a short-cut
+ * that bypasses id re-lookup.  In any case, a non-null *propp result after a
+ * successful lookup must be dropped via JSObjectOps.dropProperty.
+ *
+ * NB: successful return with non-null *propp means the implementation may
+ * have locked *objp and added a reference count associated with *propp, so
+ * callers should not risk deadlock by nesting or interleaving other lookups
+ * or any obj-bearing ops before dropping *propp.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSLookupPropOp)(JSContext *cx, JSObject *obj, jsid id,
+                                   JSObject **objp, JSProperty **propp);
+
+/*
+ * Define obj[id], a direct property of obj named id, having the given initial
+ * value, with the specified getter, setter, and attributes.  If the propp out
+ * param is non-null, *propp on successful return contains an opaque property
+ * pointer usable as a speedup hint with JSAttributesOp.  But note that propp
+ * may be null, indicating that the caller is not interested in recovering an
+ * opaque pointer to the newly-defined property.
+ *
+ * If propp is non-null and JSDefinePropOp succeeds, its caller must be sure
+ * to drop *propp using JSObjectOps.dropProperty in short order, just as with
+ * JSLookupPropOp.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSDefinePropOp)(JSContext *cx, JSObject *obj,
+                                   jsid id, jsval value,
+                                   JSPropertyOp getter, JSPropertyOp setter,
+                                   uintN attrs, JSProperty **propp);
+
+/*
+ * Get, set, or delete obj[id], returning false on error or exception, true
+ * on success.  If getting or setting, the new value is returned in *vp on
+ * success.  If deleting without error, *vp will be JSVAL_FALSE if obj[id] is
+ * permanent, and JSVAL_TRUE if id named a direct property of obj that was in
+ * fact deleted, or if id names no direct property of obj (id could name a
+ * prototype property, or no property in obj or its prototype chain).
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSPropertyIdOp)(JSContext *cx, JSObject *obj, jsid id,
+                                   jsval *vp);
+
+/*
+ * Get or set attributes of the property obj[id].  Return false on error or
+ * exception, true with current attributes in *attrsp.  If prop is non-null,
+ * it must come from the *propp out parameter of a prior JSDefinePropOp or
+ * JSLookupPropOp call.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSAttributesOp)(JSContext *cx, JSObject *obj, jsid id,
+                                   JSProperty *prop, uintN *attrsp);
+
+/*
+ * JSObjectOps.checkAccess type: check whether obj[id] may be accessed per
+ * mode, returning false on error/exception, true on success with obj[id]'s
+ * last-got value in *vp, and its attributes in *attrsp.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSCheckAccessIdOp)(JSContext *cx, JSObject *obj, jsid id,
+                                      JSAccessMode mode, jsval *vp,
+                                      uintN *attrsp);
+
+/*
+ * A generic type for functions mapping an object to another object, or null
+ * if an error or exception was thrown on cx.  Used by JSObjectOps.thisObject
+ * at present.
+ */
+typedef JSObject *
+(* JS_DLL_CALLBACK JSObjectOp)(JSContext *cx, JSObject *obj);
+
+/*
+ * A generic type for functions taking a context, object, and property, with
+ * no return value.  Used by JSObjectOps.dropProperty currently (see above,
+ * JSDefinePropOp and JSLookupPropOp, for the object-locking protocol in which
+ * dropProperty participates).
+ */
+typedef void
+(* JS_DLL_CALLBACK JSPropertyRefOp)(JSContext *cx, JSObject *obj,
+                                    JSProperty *prop);
+
+/*
+ * Function type for JSObjectOps.setProto and JSObjectOps.setParent.  These
+ * hooks must check for cycles without deadlocking, and otherwise take special
+ * steps.  See jsobj.c, js_SetProtoOrParent, for an example.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSSetObjectSlotOp)(JSContext *cx, JSObject *obj,
+                                      uint32 slot, JSObject *pobj);
+
+/*
+ * Get and set a required slot, one that should already have been allocated.
+ * These operations are infallible, so required slots must be pre-allocated,
+ * or implementations must suppress out-of-memory errors.  The native ops
+ * (js_ObjectOps, see jsobj.c) access slots reserved by including a call to
+ * the JSCLASS_HAS_RESERVED_SLOTS(n) macro in the JSClass.flags initializer.
+ *
+ * NB: the slot parameter is a zero-based index into obj->slots[], unlike the
+ * index parameter to the JS_GetReservedSlot and JS_SetReservedSlot API entry
+ * points, which is a zero-based index into the JSCLASS_RESERVED_SLOTS(clasp)
+ * reserved slots that come after the initial well-known slots: proto, parent,
+ * class, and optionally, the private data slot.
+ */
+typedef jsval
+(* JS_DLL_CALLBACK JSGetRequiredSlotOp)(JSContext *cx, JSObject *obj,
+                                        uint32 slot);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSSetRequiredSlotOp)(JSContext *cx, JSObject *obj,
+                                        uint32 slot, jsval v);
+
+typedef JSObject *
+(* JS_DLL_CALLBACK JSGetMethodOp)(JSContext *cx, JSObject *obj, jsid id,
+                                  jsval *vp);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSSetMethodOp)(JSContext *cx, JSObject *obj, jsid id,
+                                  jsval *vp);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSEnumerateValuesOp)(JSContext *cx, JSObject *obj,
+                                        JSIterateOp enum_op,
+                                        jsval *statep, jsid *idp, jsval *vp);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSEqualityOp)(JSContext *cx, JSObject *obj, jsval v,
+                                 JSBool *bp);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSConcatenateOp)(JSContext *cx, JSObject *obj, jsval v,
+                                    jsval *vp);
+
+/* Typedef for native functions called by the JS VM. */
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSNative)(JSContext *cx, JSObject *obj, uintN argc,
+                             jsval *argv, jsval *rval);
+
+/* Callbacks and their arguments. */
+
+typedef enum JSGCStatus {
+    JSGC_BEGIN,
+    JSGC_END,
+    JSGC_MARK_END,
+    JSGC_FINALIZE_END
+} JSGCStatus;
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSGCCallback)(JSContext *cx, JSGCStatus status);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSBranchCallback)(JSContext *cx, JSScript *script);
+
+typedef void
+(* JS_DLL_CALLBACK JSErrorReporter)(JSContext *cx, const char *message,
+                                    JSErrorReport *report);
+
+/*
+ * Possible exception types. These types are part of a JSErrorFormatString 
+ * structure. They define which error to throw in case of a runtime error.
+ * JSEXN_NONE marks an unthrowable error.
+ */
+typedef enum JSExnType {
+    JSEXN_NONE = -1,
+      JSEXN_ERR,
+        JSEXN_INTERNALERR,
+        JSEXN_EVALERR,
+        JSEXN_RANGEERR,
+        JSEXN_REFERENCEERR,
+        JSEXN_SYNTAXERR,
+        JSEXN_TYPEERR,
+        JSEXN_URIERR,
+        JSEXN_LIMIT
+} JSExnType;
+
+typedef struct JSErrorFormatString {
+    const char *format;  /* the error message (may be UTF-8 if compiled with JS_C_STRINGS_ARE_UTF8) */
+    uint16 argCount;     /* the number of arguments to convert in the error message */
+    uint16 exnType;      /* One of the JSExnType constants above */
+} JSErrorFormatString;
+
+typedef const JSErrorFormatString *
+(* JS_DLL_CALLBACK JSErrorCallback)(void *userRef, const char *locale,
+                                    const uintN errorNumber);
+
+#ifdef va_start
+#define JS_ARGUMENT_FORMATTER_DEFINED 1
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSArgumentFormatter)(JSContext *cx, const char *format,
+                                        JSBool fromJS, jsval **vpp,
+#ifdef OSSP /* BUGFIX */
+                                        va_list app);
+#else
+                                        va_list *app);
+#endif
+#endif
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSLocaleToUpperCase)(JSContext *cx, JSString *src,
+                                        jsval *rval);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSLocaleToLowerCase)(JSContext *cx, JSString *src,
+                                        jsval *rval);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSLocaleCompare)(JSContext *cx,
+                                    JSString *src1, JSString *src2,
+                                    jsval *rval);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSLocaleToUnicode)(JSContext *cx, char *src, jsval *rval);
+
+/*
+ * Security protocol types.
+ */
+typedef struct JSPrincipals JSPrincipals;
+
+/*
+ * XDR-encode or -decode a principals instance, based on whether xdr->mode is
+ * JSXDR_ENCODE, in which case *principalsp should be encoded; or JSXDR_DECODE,
+ * in which case implementations must return a held (via JSPRINCIPALS_HOLD),
+ * non-null *principalsp out parameter.  Return true on success, false on any
+ * error, which the implementation must have reported.
+ */
+typedef JSBool
+(* JS_DLL_CALLBACK JSPrincipalsTranscoder)(JSXDRState *xdr,
+                                           JSPrincipals **principalsp);
+
+/*
+ * Return a weak reference to the principals associated with obj, possibly via
+ * the immutable parent chain leading from obj to a top-level container (e.g.,
+ * a window object in the DOM level 0).  If there are no principals associated
+ * with obj, return null.  Therefore null does not mean an error was reported;
+ * in no event should an error be reported or an exception be thrown by this
+ * callback's implementation.
+ */
+typedef JSPrincipals *
+(* JS_DLL_CALLBACK JSObjectPrincipalsFinder)(JSContext *cx, JSObject *obj);
+
+JS_END_EXTERN_C
+
+#endif /* jspubtd_h___ */

Added: freeswitch/trunk/libs/js/src/jsregexp.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsregexp.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4173 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set sw=4 ts=8 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS regular expressions, after Perl.
+ */
+#include "jsstddef.h"
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsapi.h"
+#include "jsarray.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsfun.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsopcode.h"
+#include "jsregexp.h"
+#include "jsscan.h"
+#include "jsstr.h"
+
+#if JS_HAS_REGEXPS
+
+/* Note : contiguity of 'simple opcodes' is important for SimpleMatch() */
+typedef enum REOp {
+    REOP_EMPTY         = 0,  /* match rest of input against rest of r.e. */
+    REOP_ALT           = 1,  /* alternative subexpressions in kid and next */
+    REOP_SIMPLE_START  = 2,  /* start of 'simple opcodes' */
+    REOP_BOL           = 2,  /* beginning of input (or line if multiline) */
+    REOP_EOL           = 3,  /* end of input (or line if multiline) */
+    REOP_WBDRY         = 4,  /* match "" at word boundary */
+    REOP_WNONBDRY      = 5,  /* match "" at word non-boundary */
+    REOP_DOT           = 6,  /* stands for any character */
+    REOP_DIGIT         = 7,  /* match a digit char: [0-9] */
+    REOP_NONDIGIT      = 8,  /* match a non-digit char: [^0-9] */
+    REOP_ALNUM         = 9,  /* match an alphanumeric char: [0-9a-z_A-Z] */
+    REOP_NONALNUM      = 10, /* match a non-alphanumeric char: [^0-9a-z_A-Z] */
+    REOP_SPACE         = 11, /* match a whitespace char */
+    REOP_NONSPACE      = 12, /* match a non-whitespace char */
+    REOP_BACKREF       = 13, /* back-reference (e.g., \1) to a parenthetical */
+    REOP_FLAT          = 14, /* match a flat string */
+    REOP_FLAT1         = 15, /* match a single char */
+    REOP_FLATi         = 16, /* case-independent REOP_FLAT */
+    REOP_FLAT1i        = 17, /* case-independent REOP_FLAT1 */
+    REOP_UCFLAT1       = 18, /* single Unicode char */
+    REOP_UCFLAT1i      = 19, /* case-independent REOP_UCFLAT1 */
+    REOP_UCFLAT        = 20, /* flat Unicode string; len immediate counts chars */
+    REOP_UCFLATi       = 21, /* case-independent REOP_UCFLAT */
+    REOP_CLASS         = 22, /* character class with index */
+    REOP_NCLASS        = 23, /* negated character class with index */
+    REOP_SIMPLE_END    = 23, /* end of 'simple opcodes' */
+    REOP_QUANT         = 25, /* quantified atom: atom{1,2} */
+    REOP_STAR          = 26, /* zero or more occurrences of kid */
+    REOP_PLUS          = 27, /* one or more occurrences of kid */
+    REOP_OPT           = 28, /* optional subexpression in kid */
+    REOP_LPAREN        = 29, /* left paren bytecode: kid is u.num'th sub-regexp */
+    REOP_RPAREN        = 30, /* right paren bytecode */
+    REOP_JUMP          = 31, /* for deoptimized closure loops */
+    REOP_DOTSTAR       = 32, /* optimize .* to use a single opcode */
+    REOP_ANCHOR        = 33, /* like .* but skips left context to unanchored r.e. */
+    REOP_EOLONLY       = 34, /* $ not preceded by any pattern */
+    REOP_BACKREFi      = 37, /* case-independent REOP_BACKREF */
+    REOP_LPARENNON     = 41, /* non-capturing version of REOP_LPAREN */
+    REOP_ASSERT        = 43, /* zero width positive lookahead assertion */
+    REOP_ASSERT_NOT    = 44, /* zero width negative lookahead assertion */
+    REOP_ASSERTTEST    = 45, /* sentinel at end of assertion child */
+    REOP_ASSERTNOTTEST = 46, /* sentinel at end of !assertion child */
+    REOP_MINIMALSTAR   = 47, /* non-greedy version of * */
+    REOP_MINIMALPLUS   = 48, /* non-greedy version of + */
+    REOP_MINIMALOPT    = 49, /* non-greedy version of ? */
+    REOP_MINIMALQUANT  = 50, /* non-greedy version of {} */
+    REOP_ENDCHILD      = 51, /* sentinel at end of quantifier child */
+    REOP_REPEAT        = 52, /* directs execution of greedy quantifier */
+    REOP_MINIMALREPEAT = 53, /* directs execution of non-greedy quantifier */
+    REOP_ALTPREREQ     = 54, /* prerequisite for ALT, either of two chars */
+    REOP_ALTPREREQ2    = 55, /* prerequisite for ALT, a char or a class */
+    REOP_ENDALT        = 56, /* end of final alternate */
+    REOP_CONCAT        = 57, /* concatenation of terms (parse time only) */
+
+    REOP_END
+} REOp;
+
+#define REOP_IS_SIMPLE(op)  ((unsigned)((op) - REOP_SIMPLE_START) <           \
+                             (unsigned)REOP_SIMPLE_END)
+
+struct RENode {
+    REOp            op;         /* r.e. op bytecode */
+    RENode          *next;      /* next in concatenation order */
+    void            *kid;       /* first operand */
+    union {
+        void        *kid2;      /* second operand */
+        jsint       num;        /* could be a number */
+        size_t      parenIndex; /* or a parenthesis index */
+        struct {                /* or a quantifier range */
+            uintN  min;
+            uintN  max;
+            JSPackedBool greedy;
+        } range;
+        struct {                /* or a character class */
+            size_t  startIndex;
+            size_t  kidlen;     /* length of string at kid, in jschars */
+            size_t  index;      /* index into class list */
+            uint16  bmsize;     /* bitmap size, based on max char code */
+            JSPackedBool sense;
+        } ucclass;
+        struct {                /* or a literal sequence */
+            jschar  chr;        /* of one character */
+            size_t  length;     /* or many (via the kid) */
+        } flat;
+        struct {
+            RENode  *kid2;      /* second operand from ALT */
+            jschar  ch1;        /* match char for ALTPREREQ */
+            jschar  ch2;        /* ditto, or class index for ALTPREREQ2 */
+        } altprereq;
+    } u;
+};
+
+#define RE_IS_LETTER(c)     (((c >= 'A') && (c <= 'Z')) ||                    \
+                             ((c >= 'a') && (c <= 'z')) )
+#define RE_IS_LINE_TERM(c)  ((c == '\n') || (c == '\r') ||                    \
+                             (c == LINE_SEPARATOR) || (c == PARA_SEPARATOR))
+
+#define CLASS_CACHE_SIZE    4
+
+typedef struct CompilerState {
+    JSContext       *context;
+    JSTokenStream   *tokenStream; /* For reporting errors */
+    const jschar    *cpbegin;
+    const jschar    *cpend;
+    const jschar    *cp;
+    size_t          parenCount;
+    size_t          classCount;   /* number of [] encountered */
+    size_t          treeDepth;    /* maximum depth of parse tree */
+    size_t          progLength;   /* estimated bytecode length */
+    RENode          *result;
+    size_t          classBitmapsMem; /* memory to hold all class bitmaps */
+    struct {
+        const jschar *start;        /* small cache of class strings */
+        size_t length;              /* since they're often the same */
+        size_t index;
+    } classCache[CLASS_CACHE_SIZE];
+    uint16          flags;
+} CompilerState;
+
+typedef struct EmitStateStackEntry {
+    jsbytecode      *altHead;       /* start of REOP_ALT* opcode */
+    jsbytecode      *nextAltFixup;  /* fixup pointer to next-alt offset */
+    jsbytecode      *nextTermFixup; /* fixup ptr. to REOP_JUMP offset */
+    jsbytecode      *endTermFixup;  /* fixup ptr. to REOPT_ALTPREREQ* offset */
+    RENode          *continueNode;  /* original REOP_ALT* node being stacked */
+    jsbytecode      continueOp;     /* REOP_JUMP or REOP_ENDALT continuation */
+    JSPackedBool    jumpToJumpFlag; /* true if we've patched jump-to-jump to
+                                       avoid 16-bit unsigned offset overflow */
+} EmitStateStackEntry;
+
+/*
+ * Immediate operand sizes and getter/setters.  Unlike the ones in jsopcode.h,
+ * the getters and setters take the pc of the offset, not of the opcode before
+ * the offset.
+ */
+#define ARG_LEN             2
+#define GET_ARG(pc)         ((uint16)(((pc)[0] << 8) | (pc)[1]))
+#define SET_ARG(pc, arg)    ((pc)[0] = (jsbytecode) ((arg) >> 8),       \
+                             (pc)[1] = (jsbytecode) (arg))
+
+#define OFFSET_LEN          ARG_LEN
+#define OFFSET_MAX          (JS_BIT(ARG_LEN * 8) - 1)
+#define GET_OFFSET(pc)      GET_ARG(pc)
+
+/*
+ * Maximum supported tree depth is maximum size of EmitStateStackEntry stack.
+ * For sanity, we limit it to 2^24 bytes.
+ */
+#define TREE_DEPTH_MAX  (JS_BIT(24) / sizeof(EmitStateStackEntry))
+
+/*
+ * The maximum memory that can be allocated for class bitmaps.
+ * For sanity, we limit it to 2^24 bytes.
+ */
+#define CLASS_BITMAPS_MEM_LIMIT JS_BIT(24)
+
+/*
+ * Functions to get size and write/read bytecode that represent small indexes
+ * compactly.
+ * Each byte in the code represent 7-bit chunk of the index. 8th bit when set
+ * indicates that the following byte brings more bits to the index. Otherwise
+ * this is the last byte in the index bytecode representing highest index bits.
+ */
+static size_t
+GetCompactIndexWidth(size_t index)
+{
+    size_t width;
+
+    for (width = 1; (index >>= 7) != 0; ++width) { }
+    return width;
+}
+
+static jsbytecode *
+WriteCompactIndex(jsbytecode *pc, size_t index)
+{
+    size_t next;
+
+    while ((next = index >> 7) != 0) {
+        *pc++ = (jsbytecode)(index | 0x80);
+        index = next;
+    }
+    *pc++ = (jsbytecode)index;
+    return pc;
+}
+
+static jsbytecode *
+ReadCompactIndex(jsbytecode *pc, size_t *result)
+{
+    size_t nextByte;
+
+    nextByte = *pc++;
+    if ((nextByte & 0x80) == 0) {
+        /*
+         * Short-circuit the most common case when compact index <= 127.
+         */
+        *result = nextByte;
+    } else {
+        size_t shift = 7;
+        *result = 0x7F & nextByte;
+        do {
+            nextByte = *pc++;
+            *result |= (nextByte & 0x7F) << shift;
+            shift += 7;
+        } while ((nextByte & 0x80) != 0);
+    }
+    return pc;
+}
+
+typedef struct RECapture {
+    ptrdiff_t index;           /* start of contents, -1 for empty  */
+    size_t length;             /* length of capture */
+} RECapture;
+
+typedef struct REMatchState {
+    const jschar *cp;
+    RECapture parens[1];      /* first of 're->parenCount' captures,
+                                 allocated at end of this struct */
+} REMatchState;
+
+struct REBackTrackData;
+
+typedef struct REProgState {
+    jsbytecode *continue_pc;        /* current continuation data */
+    jsbytecode continue_op;
+    ptrdiff_t index;                /* progress in text */
+    size_t parenSoFar;              /* highest indexed paren started */
+    union {
+        struct {
+            uintN min;             /* current quantifier limits */
+            uintN max;
+        } quantifier;
+        struct {
+            size_t top;             /* backtrack stack state */
+            size_t sz;
+        } assertion;
+    } u;
+} REProgState;
+
+typedef struct REBackTrackData {
+    size_t sz;                      /* size of previous stack entry */
+    jsbytecode *backtrack_pc;       /* where to backtrack to */
+    jsbytecode backtrack_op;
+    const jschar *cp;               /* index in text of match at backtrack */
+    size_t parenIndex;              /* start index of saved paren contents */
+    size_t parenCount;              /* # of saved paren contents */
+    size_t saveStateStackTop;       /* number of parent states */
+    /* saved parent states follow */
+    /* saved paren contents follow */
+} REBackTrackData;
+
+#define INITIAL_STATESTACK  100
+#define INITIAL_BACKTRACK   8000
+
+typedef struct REGlobalData {
+    JSContext *cx;
+    JSRegExp *regexp;               /* the RE in execution */
+    JSBool ok;                      /* runtime error (out_of_memory only?) */
+    size_t start;                   /* offset to start at */
+    ptrdiff_t skipped;              /* chars skipped anchoring this r.e. */
+    const jschar    *cpbegin;       /* text base address */
+    const jschar    *cpend;         /* text limit address */
+
+    REProgState *stateStack;        /* stack of state of current parents */
+    size_t stateStackTop;
+    size_t stateStackLimit;
+
+    REBackTrackData *backTrackStack;/* stack of matched-so-far positions */
+    REBackTrackData *backTrackSP;
+    size_t backTrackStackSize;
+    size_t cursz;                   /* size of current stack entry */
+
+    JSArenaPool     pool;           /* It's faster to use one malloc'd pool
+                                       than to malloc/free the three items
+                                       that are allocated from this pool */
+} REGlobalData;
+
+/*
+ * 1. If IgnoreCase is false, return ch.
+ * 2. Let u be ch converted to upper case as if by calling
+ *    String.prototype.toUpperCase on the one-character string ch.
+ * 3. If u does not consist of a single character, return ch.
+ * 4. Let cu be u's character.
+ * 5. If ch's code point value is greater than or equal to decimal 128 and cu's
+ *    code point value is less than decimal 128, then return ch.
+ * 6. Return cu.
+ */
+static jschar
+upcase(jschar ch)
+{
+    jschar cu = JS_TOUPPER(ch);
+    if (ch >= 128 && cu < 128)
+        return ch;
+    return cu;
+}
+
+static jschar
+downcase(jschar ch)
+{
+    jschar cl = JS_TOLOWER(ch);
+    if (cl >= 128 && ch < 128)
+        return ch;
+    return cl;
+}
+
+/* Construct and initialize an RENode, returning NULL for out-of-memory */
+static RENode *
+NewRENode(CompilerState *state, REOp op)
+{
+    JSContext *cx;
+    RENode *ren;
+
+    cx = state->context;
+    JS_ARENA_ALLOCATE_CAST(ren, RENode *, &cx->tempPool, sizeof *ren);
+    if (!ren) {
+        JS_ReportOutOfMemory(cx);
+        return NULL;
+    }
+    ren->op = op;
+    ren->next = NULL;
+    ren->kid = NULL;
+    return ren;
+}
+
+/*
+ * Validates and converts hex ascii value.
+ */
+static JSBool
+isASCIIHexDigit(jschar c, uintN *digit)
+{
+    uintN cv = c;
+
+    if (cv < '0')
+        return JS_FALSE;
+    if (cv <= '9') {
+        *digit = cv - '0';
+        return JS_TRUE;
+    }
+    cv |= 0x20;
+    if (cv >= 'a' && cv <= 'f') {
+        *digit = cv - 'a' + 10;
+        return JS_TRUE;
+    }
+    return JS_FALSE;
+}
+
+
+typedef struct {
+    REOp op;
+    const jschar *errPos;
+    size_t parenIndex;
+} REOpData;
+
+
+/*
+ * Process the op against the two top operands, reducing them to a single
+ * operand in the penultimate slot. Update progLength and treeDepth.
+ */
+static JSBool
+ProcessOp(CompilerState *state, REOpData *opData, RENode **operandStack,
+          intN operandSP)
+{
+    RENode *result;
+
+    switch (opData->op) {
+    case REOP_ALT:
+        result = NewRENode(state, REOP_ALT);
+        if (!result)
+            return JS_FALSE;
+        result->kid = operandStack[operandSP - 2];
+        result->u.kid2 = operandStack[operandSP - 1];
+        operandStack[operandSP - 2] = result;
+
+        if (state->treeDepth == TREE_DEPTH_MAX) {
+            js_ReportCompileErrorNumber(state->context, state->tokenStream,
+                                        JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_REGEXP_TOO_COMPLEX);
+            return JS_FALSE;
+        }
+        ++state->treeDepth;
+
+        /*
+         * Look at both alternates to see if there's a FLAT or a CLASS at
+         * the start of each. If so, use a prerequisite match.
+         */
+        if (((RENode *) result->kid)->op == REOP_FLAT &&
+            ((RENode *) result->u.kid2)->op == REOP_FLAT &&
+            (state->flags & JSREG_FOLD) == 0) {
+            result->op = REOP_ALTPREREQ;
+            result->u.altprereq.ch1 = ((RENode *) result->kid)->u.flat.chr;
+            result->u.altprereq.ch2 = ((RENode *) result->u.kid2)->u.flat.chr;
+            /* ALTPREREQ, <end>, uch1, uch2, <next>, ...,
+                                            JUMP, <end> ... ENDALT */
+            state->progLength += 13;
+        }
+        else
+        if (((RENode *) result->kid)->op == REOP_CLASS &&
+            ((RENode *) result->kid)->u.ucclass.index < 256 &&
+            ((RENode *) result->u.kid2)->op == REOP_FLAT &&
+            (state->flags & JSREG_FOLD) == 0) {
+            result->op = REOP_ALTPREREQ2;
+            result->u.altprereq.ch1 = ((RENode *) result->u.kid2)->u.flat.chr;
+            result->u.altprereq.ch2 = ((RENode *) result->kid)->u.ucclass.index;
+            /* ALTPREREQ2, <end>, uch1, uch2, <next>, ...,
+                                            JUMP, <end> ... ENDALT */
+            state->progLength += 13;
+        }
+        else
+        if (((RENode *) result->kid)->op == REOP_FLAT &&
+            ((RENode *) result->u.kid2)->op == REOP_CLASS &&
+            ((RENode *) result->u.kid2)->u.ucclass.index < 256 &&
+            (state->flags & JSREG_FOLD) == 0) {
+            result->op = REOP_ALTPREREQ2;
+            result->u.altprereq.ch1 = ((RENode *) result->kid)->u.flat.chr;
+            result->u.altprereq.ch2 =
+                ((RENode *) result->u.kid2)->u.ucclass.index;
+            /* ALTPREREQ2, <end>, uch1, uch2, <next>, ...,
+                                          JUMP, <end> ... ENDALT */
+            state->progLength += 13;
+        }
+        else {
+            /* ALT, <next>, ..., JUMP, <end> ... ENDALT */
+            state->progLength += 7;
+        }
+        break;
+
+    case REOP_CONCAT:
+        result = operandStack[operandSP - 2];
+        while (result->next)
+            result = result->next;
+        result->next = operandStack[operandSP - 1];
+        break;
+
+    case REOP_ASSERT:
+    case REOP_ASSERT_NOT:
+    case REOP_LPARENNON:
+    case REOP_LPAREN:
+        /* These should have been processed by a close paren. */
+        js_ReportCompileErrorNumberUC(state->context, state->tokenStream,
+                                      JSREPORT_TS | JSREPORT_ERROR,
+                                      JSMSG_MISSING_PAREN, opData->errPos);
+        return JS_FALSE;
+
+    default:;
+    }
+    return JS_TRUE;
+}
+
+/*
+ * Parser forward declarations.
+ */
+static JSBool ParseTerm(CompilerState *state);
+static JSBool ParseQuantifier(CompilerState *state);
+static intN ParseMinMaxQuantifier(CompilerState *state, JSBool ignoreValues);
+
+/*
+ * Top-down regular expression grammar, based closely on Perl4.
+ *
+ *  regexp:     altern                  A regular expression is one or more
+ *              altern '|' regexp       alternatives separated by vertical bar.
+ */
+#define INITIAL_STACK_SIZE  128
+
+static JSBool
+ParseRegExp(CompilerState *state)
+{
+    size_t parenIndex;
+    RENode *operand;
+    REOpData *operatorStack;
+    RENode **operandStack;
+    REOp op;
+    intN i;
+    JSBool result = JS_FALSE;
+
+    intN operatorSP = 0, operatorStackSize = INITIAL_STACK_SIZE;
+    intN operandSP = 0, operandStackSize = INITIAL_STACK_SIZE;
+
+    /* Watch out for empty regexp */
+    if (state->cp == state->cpend) {
+        state->result = NewRENode(state, REOP_EMPTY);
+        return (state->result != NULL);
+    }
+
+    operatorStack = (REOpData *)
+        JS_malloc(state->context, sizeof(REOpData) * operatorStackSize);
+    if (!operatorStack)
+        return JS_FALSE;
+
+    operandStack = (RENode **)
+        JS_malloc(state->context, sizeof(RENode *) * operandStackSize);
+    if (!operandStack)
+        goto out;
+
+    for (;;) {
+        parenIndex = state->parenCount;
+        if (state->cp == state->cpend) {
+            /*
+             * If we are at the end of the regexp and we're short one or more
+             * operands, the regexp must have the form /x|/ or some such, with
+             * left parentheses making us short more than one operand.
+             */
+            if (operatorSP >= operandSP) {
+                operand = NewRENode(state, REOP_EMPTY);
+                if (!operand)
+                    goto out;
+                goto pushOperand;
+            }
+        } else {
+            switch (*state->cp) {
+            case '(':
+                ++state->cp;
+                if (state->cp + 1 < state->cpend &&
+                    *state->cp == '?' &&
+                    (state->cp[1] == '=' ||
+                     state->cp[1] == '!' ||
+                     state->cp[1] == ':')) {
+                    switch (state->cp[1]) {
+                    case '=':
+                        op = REOP_ASSERT;
+                        /* ASSERT, <next>, ... ASSERTTEST */
+                        state->progLength += 4;
+                        break;
+                    case '!':
+                        op = REOP_ASSERT_NOT;
+                        /* ASSERTNOT, <next>, ... ASSERTNOTTEST */
+                        state->progLength += 4;
+                        break;
+                    default:
+                        op = REOP_LPARENNON;
+                        break;
+                    }
+                    state->cp += 2;
+                } else {
+                    op = REOP_LPAREN;
+                    /* LPAREN, <index>, ... RPAREN, <index> */
+                    state->progLength
+                        += 2 * (1 + GetCompactIndexWidth(parenIndex));
+                    state->parenCount++;
+                    if (state->parenCount == 65535) {
+                        js_ReportCompileErrorNumber(state->context,
+                                                    state->tokenStream,
+                                                    JSREPORT_TS |
+                                                    JSREPORT_ERROR,
+                                                    JSMSG_TOO_MANY_PARENS);
+                        goto out;
+                    }
+                }
+                goto pushOperator;
+
+            case ')':
+                /*
+                 * If there's no stacked open parenthesis, throw syntax error.
+                 */
+                for (i = operatorSP - 1; ; i--) {
+                    if (i < 0) {
+                        js_ReportCompileErrorNumber(state->context,
+                                                    state->tokenStream,
+                                                    JSREPORT_TS |
+                                                    JSREPORT_ERROR,
+                                                    JSMSG_UNMATCHED_RIGHT_PAREN);
+                        goto out;
+                    }
+                    if (operatorStack[i].op == REOP_ASSERT ||
+                        operatorStack[i].op == REOP_ASSERT_NOT ||
+                        operatorStack[i].op == REOP_LPARENNON ||
+                        operatorStack[i].op == REOP_LPAREN) {
+                        break;
+                    }
+                }
+                /* FALL THROUGH */
+
+            case '|':
+                /* Expected an operand before these, so make an empty one */
+                operand = NewRENode(state, REOP_EMPTY);
+                if (!operand)
+                    goto out;
+                goto pushOperand;
+
+            default:
+                if (!ParseTerm(state))
+                    goto out;
+                operand = state->result;
+pushOperand:
+                if (operandSP == operandStackSize) {
+                    operandStackSize += operandStackSize;
+                    operandStack = (RENode **)
+                        JS_realloc(state->context, operandStack,
+                                   sizeof(RENode *) * operandStackSize);
+                    if (!operandStack)
+                        goto out;
+                }
+                operandStack[operandSP++] = operand;
+                break;
+            }
+        }
+
+        /* At the end; process remaining operators. */
+restartOperator:
+        if (state->cp == state->cpend) {
+            while (operatorSP) {
+                --operatorSP;
+                if (!ProcessOp(state, &operatorStack[operatorSP],
+                               operandStack, operandSP))
+                    goto out;
+                --operandSP;
+            }
+            JS_ASSERT(operandSP == 1);
+            state->result = operandStack[0];
+            result = JS_TRUE;
+            goto out;
+        }
+
+        switch (*state->cp) {
+        case '|':
+            /* Process any stacked 'concat' operators */
+            ++state->cp;
+            while (operatorSP &&
+                   operatorStack[operatorSP - 1].op == REOP_CONCAT) {
+                --operatorSP;
+                if (!ProcessOp(state, &operatorStack[operatorSP],
+                               operandStack, operandSP)) {
+                    goto out;
+                }
+                --operandSP;
+            }
+            op = REOP_ALT;
+            goto pushOperator;
+
+        case ')':
+            /*
+             * If there's no stacked open parenthesis, throw syntax error.
+             */
+            for (i = operatorSP - 1; ; i--) {
+                if (i < 0) {
+                    js_ReportCompileErrorNumber(state->context,
+                                                state->tokenStream,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_UNMATCHED_RIGHT_PAREN);
+                    goto out;
+                }
+                if (operatorStack[i].op == REOP_ASSERT ||
+                    operatorStack[i].op == REOP_ASSERT_NOT ||
+                    operatorStack[i].op == REOP_LPARENNON ||
+                    operatorStack[i].op == REOP_LPAREN) {
+                    break;
+                }
+            }
+            ++state->cp;
+
+            /* Process everything on the stack until the open parenthesis. */
+            for (;;) {
+                JS_ASSERT(operatorSP);
+                --operatorSP;
+                switch (operatorStack[operatorSP].op) {
+                case REOP_ASSERT:
+                case REOP_ASSERT_NOT:
+                case REOP_LPAREN:
+                    operand = NewRENode(state, operatorStack[operatorSP].op);
+                    if (!operand)
+                        goto out;
+                    operand->u.parenIndex =
+                        operatorStack[operatorSP].parenIndex;
+                    JS_ASSERT(operandSP);
+                    operand->kid = operandStack[operandSP - 1];
+                    operandStack[operandSP - 1] = operand;
+                    if (state->treeDepth == TREE_DEPTH_MAX) {
+                        js_ReportCompileErrorNumber(state->context,
+                                                    state->tokenStream,
+                                                    JSREPORT_TS |
+                                                    JSREPORT_ERROR,
+                                                    JSMSG_REGEXP_TOO_COMPLEX);
+                        goto out;
+                    }
+                    ++state->treeDepth;
+                    /* FALL THROUGH */
+
+                case REOP_LPARENNON:
+                    state->result = operandStack[operandSP - 1];
+                    if (!ParseQuantifier(state))
+                        goto out;
+                    operandStack[operandSP - 1] = state->result;
+                    goto restartOperator;
+                default:
+                    if (!ProcessOp(state, &operatorStack[operatorSP],
+                                   operandStack, operandSP))
+                        goto out;
+                    --operandSP;
+                    break;
+                }
+            }
+            break;
+
+        case '{':
+        {
+            const jschar *errp = state->cp;
+
+            if (ParseMinMaxQuantifier(state, JS_TRUE) < 0) {
+                /*
+                 * This didn't even scan correctly as a quantifier, so we should
+                 * treat it as flat.
+                 */
+                op = REOP_CONCAT;
+                goto pushOperator;
+            }
+
+            state->cp = errp;
+            /* FALL THROUGH */
+        }
+
+        case '+':
+        case '*':
+        case '?':
+            js_ReportCompileErrorNumberUC(state->context, state->tokenStream,
+                                          JSREPORT_TS | JSREPORT_ERROR,
+                                          JSMSG_BAD_QUANTIFIER, state->cp);
+            result = JS_FALSE;
+            goto out;
+
+        default:
+            /* Anything else is the start of the next term. */
+            op = REOP_CONCAT;
+pushOperator:
+            if (operatorSP == operatorStackSize) {
+                operatorStackSize += operatorStackSize;
+                operatorStack = (REOpData *)
+                    JS_realloc(state->context, operatorStack,
+                               sizeof(REOpData) * operatorStackSize);
+                if (!operatorStack)
+                    goto out;
+            }
+            operatorStack[operatorSP].op = op;
+            operatorStack[operatorSP].errPos = state->cp;
+            operatorStack[operatorSP++].parenIndex = parenIndex;
+            break;
+        }
+    }
+out:
+    if (operatorStack)
+        JS_free(state->context, operatorStack);
+    if (operandStack)
+        JS_free(state->context, operandStack);
+    return result;
+}
+
+/*
+ * Hack two bits in CompilerState.flags, for use within FindParenCount to flag
+ * its being on the stack, and to propagate errors to its callers.
+ */
+#define JSREG_FIND_PAREN_COUNT  0x8000
+#define JSREG_FIND_PAREN_ERROR  0x4000
+
+/*
+ * Magic return value from FindParenCount and GetDecimalValue, to indicate
+ * overflow beyond GetDecimalValue's max parameter, or a computed maximum if
+ * its findMax parameter is non-null.
+ */
+#define OVERFLOW_VALUE          ((uintN)-1)
+
+static uintN
+FindParenCount(CompilerState *state)
+{
+    CompilerState temp;
+    int i;
+
+    if (state->flags & JSREG_FIND_PAREN_COUNT)
+        return OVERFLOW_VALUE;
+
+    /*
+     * Copy state into temp, flag it so we never report an invalid backref,
+     * and reset its members to parse the entire regexp.  This is obviously
+     * suboptimal, but GetDecimalValue calls us only if a backref appears to
+     * refer to a forward parenthetical, which is rare.
+     */
+    temp = *state;
+    temp.flags |= JSREG_FIND_PAREN_COUNT;
+    temp.cp = temp.cpbegin;
+    temp.parenCount = 0;
+    temp.classCount = 0;
+    temp.progLength = 0;
+    temp.treeDepth = 0;
+    temp.classBitmapsMem = 0;
+    for (i = 0; i < CLASS_CACHE_SIZE; i++)
+        temp.classCache[i].start = NULL;
+
+    if (!ParseRegExp(&temp)) {
+        state->flags |= JSREG_FIND_PAREN_ERROR;
+        return OVERFLOW_VALUE;
+    }
+    return temp.parenCount;
+}
+
+/*
+ * Extract and return a decimal value at state->cp.  The initial character c
+ * has already been read.  Return OVERFLOW_VALUE if the result exceeds max.
+ * Callers who pass a non-null findMax should test JSREG_FIND_PAREN_ERROR in
+ * state->flags to discover whether an error occurred under findMax.
+ */
+static uintN
+GetDecimalValue(jschar c, uintN max, uintN (*findMax)(CompilerState *state),
+                CompilerState *state)
+{
+    uintN value = JS7_UNDEC(c);
+    JSBool overflow = (value > max && (!findMax || value > findMax(state)));
+
+    /* The following restriction allows simpler overflow checks. */
+    JS_ASSERT(max <= ((uintN)-1 - 9) / 10);
+    while (state->cp < state->cpend) {
+        c = *state->cp;
+        if (!JS7_ISDEC(c))
+            break;
+        value = 10 * value + JS7_UNDEC(c);
+        if (!overflow && value > max && (!findMax || value > findMax(state)))
+            overflow = JS_TRUE;
+        ++state->cp;
+    }
+    return overflow ? OVERFLOW_VALUE : value;
+}
+
+/*
+ * Calculate the total size of the bitmap required for a class expression.
+ */
+static JSBool
+CalculateBitmapSize(CompilerState *state, RENode *target, const jschar *src,
+                    const jschar *end)
+{
+    uintN max = 0;
+    JSBool inRange = JS_FALSE;
+    jschar c, rangeStart = 0;
+    uintN n, digit, nDigits, i;
+
+    target->u.ucclass.bmsize = 0;
+    target->u.ucclass.sense = JS_TRUE;
+
+    if (src == end)
+        return JS_TRUE;
+
+    if (*src == '^') {
+        ++src;
+        target->u.ucclass.sense = JS_FALSE;
+    }
+
+    while (src != end) {
+        uintN localMax = 0;
+        switch (*src) {
+        case '\\':
+            ++src;
+            c = *src++;
+            switch (c) {
+            case 'b':
+                localMax = 0x8;
+                break;
+            case 'f':
+                localMax = 0xC;
+                break;
+            case 'n':
+                localMax = 0xA;
+                break;
+            case 'r':
+                localMax = 0xD;
+                break;
+            case 't':
+                localMax = 0x9;
+                break;
+            case 'v':
+                localMax = 0xB;
+                break;
+            case 'c':
+                if (src + 1 < end && RE_IS_LETTER(src[1]))
+                    localMax = (jschar) (*src++ & 0x1F);
+                else
+                    localMax = '\\';
+                break;
+            case 'x':
+                nDigits = 2;
+                goto lexHex;
+            case 'u':
+                nDigits = 4;
+lexHex:
+                n = 0;
+                for (i = 0; (i < nDigits) && (src < end); i++) {
+                    c = *src++;
+                    if (!isASCIIHexDigit(c, &digit)) {
+                        /*
+                         * Back off to accepting the original
+                         *'\' as a literal.
+                         */
+                        src -= i + 1;
+                        n = '\\';
+                        break;
+                    }
+                    n = (n << 4) | digit;
+                }
+                localMax = n;
+                break;
+            case 'd':
+                if (inRange) {
+                    JS_ReportErrorNumber(state->context,
+                                         js_GetErrorMessage, NULL,
+                                         JSMSG_BAD_CLASS_RANGE);
+                    return JS_FALSE;
+                }
+                localMax = '9';
+                break;
+            case 'D':
+            case 's':
+            case 'S':
+            case 'w':
+            case 'W':
+                if (inRange) {
+                    JS_ReportErrorNumber(state->context,
+                                         js_GetErrorMessage, NULL,
+                                         JSMSG_BAD_CLASS_RANGE);
+                    return JS_FALSE;
+                }
+                target->u.ucclass.bmsize = 65535;
+                return JS_TRUE;
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+                /*
+                 *  This is a non-ECMA extension - decimal escapes (in this
+                 *  case, octal!) are supposed to be an error inside class
+                 *  ranges, but supported here for backwards compatibility.
+                 *
+                 */
+                n = JS7_UNDEC(c);
+                c = *src;
+                if ('0' <= c && c <= '7') {
+                    src++;
+                    n = 8 * n + JS7_UNDEC(c);
+                    c = *src;
+                    if ('0' <= c && c <= '7') {
+                        src++;
+                        i = 8 * n + JS7_UNDEC(c);
+                        if (i <= 0377)
+                            n = i;
+                        else
+                            src--;
+                    }
+                }
+                localMax = n;
+                break;
+
+            default:
+                localMax = c;
+                break;
+            }
+            break;
+        default:
+            localMax = *src++;
+            break;
+        }
+        if (inRange) {
+            if (rangeStart > localMax) {
+                JS_ReportErrorNumber(state->context,
+                                     js_GetErrorMessage, NULL,
+                                     JSMSG_BAD_CLASS_RANGE);
+                return JS_FALSE;
+            }
+            inRange = JS_FALSE;
+        } else {
+            if (src < end - 1) {
+                if (*src == '-') {
+                    ++src;
+                    inRange = JS_TRUE;
+                    rangeStart = (jschar)localMax;
+                    continue;
+                }
+            }
+        }
+        if (state->flags & JSREG_FOLD) {
+            c = JS_MAX(upcase((jschar)localMax), downcase((jschar)localMax));
+            if (c > localMax)
+                localMax = c;
+        }
+        if (localMax > max)
+            max = localMax;
+    }
+    target->u.ucclass.bmsize = max;
+    return JS_TRUE;
+}
+
+/*
+ *  item:       assertion               An item is either an assertion or
+ *              quantatom               a quantified atom.
+ *
+ *  assertion:  '^'                     Assertions match beginning of string
+ *                                      (or line if the class static property
+ *                                      RegExp.multiline is true).
+ *              '$'                     End of string (or line if the class
+ *                                      static property RegExp.multiline is
+ *                                      true).
+ *              '\b'                    Word boundary (between \w and \W).
+ *              '\B'                    Word non-boundary.
+ *
+ *  quantatom:  atom                    An unquantified atom.
+ *              quantatom '{' n ',' m '}'
+ *                                      Atom must occur between n and m times.
+ *              quantatom '{' n ',' '}' Atom must occur at least n times.
+ *              quantatom '{' n '}'     Atom must occur exactly n times.
+ *              quantatom '*'           Zero or more times (same as {0,}).
+ *              quantatom '+'           One or more times (same as {1,}).
+ *              quantatom '?'           Zero or one time (same as {0,1}).
+ *
+ *              any of which can be optionally followed by '?' for ungreedy
+ *
+ *  atom:       '(' regexp ')'          A parenthesized regexp (what matched
+ *                                      can be addressed using a backreference,
+ *                                      see '\' n below).
+ *              '.'                     Matches any char except '\n'.
+ *              '[' classlist ']'       A character class.
+ *              '[' '^' classlist ']'   A negated character class.
+ *              '\f'                    Form Feed.
+ *              '\n'                    Newline (Line Feed).
+ *              '\r'                    Carriage Return.
+ *              '\t'                    Horizontal Tab.
+ *              '\v'                    Vertical Tab.
+ *              '\d'                    A digit (same as [0-9]).
+ *              '\D'                    A non-digit.
+ *              '\w'                    A word character, [0-9a-z_A-Z].
+ *              '\W'                    A non-word character.
+ *              '\s'                    A whitespace character, [ \b\f\n\r\t\v].
+ *              '\S'                    A non-whitespace character.
+ *              '\' n                   A backreference to the nth (n decimal
+ *                                      and positive) parenthesized expression.
+ *              '\' octal               An octal escape sequence (octal must be
+ *                                      two or three digits long, unless it is
+ *                                      0 for the null character).
+ *              '\x' hex                A hex escape (hex must be two digits).
+ *              '\u' unicode            A unicode escape (must be four digits).
+ *              '\c' ctrl               A control character, ctrl is a letter.
+ *              '\' literalatomchar     Any character except one of the above
+ *                                      that follow '\' in an atom.
+ *              otheratomchar           Any character not first among the other
+ *                                      atom right-hand sides.
+ */
+static JSBool
+ParseTerm(CompilerState *state)
+{
+    jschar c = *state->cp++;
+    uintN nDigits;
+    uintN num, tmp, n, i;
+    const jschar *termStart;
+
+    switch (c) {
+    /* assertions and atoms */
+    case '^':
+        state->result = NewRENode(state, REOP_BOL);
+        if (!state->result)
+            return JS_FALSE;
+        state->progLength++;
+        return JS_TRUE;
+    case '$':
+        state->result = NewRENode(state, REOP_EOL);
+        if (!state->result)
+            return JS_FALSE;
+        state->progLength++;
+        return JS_TRUE;
+    case '\\':
+        if (state->cp >= state->cpend) {
+            /* a trailing '\' is an error */
+            js_ReportCompileErrorNumber(state->context, state->tokenStream,
+                                        JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_TRAILING_SLASH);
+            return JS_FALSE;
+        }
+        c = *state->cp++;
+        switch (c) {
+        /* assertion escapes */
+        case 'b' :
+            state->result = NewRENode(state, REOP_WBDRY);
+            if (!state->result)
+                return JS_FALSE;
+            state->progLength++;
+            return JS_TRUE;
+        case 'B':
+            state->result = NewRENode(state, REOP_WNONBDRY);
+            if (!state->result)
+                return JS_FALSE;
+            state->progLength++;
+            return JS_TRUE;
+        /* Decimal escape */
+        case '0':
+            /* Give a strict warning. See also the note below. */
+            if (!js_ReportCompileErrorNumber(state->context,
+                                             state->tokenStream,
+                                             JSREPORT_TS |
+                                             JSREPORT_WARNING |
+                                             JSREPORT_STRICT,
+                                             JSMSG_INVALID_BACKREF)) {
+                return JS_FALSE;
+            }
+     doOctal:
+            num = 0;
+            while (state->cp < state->cpend) {
+                c = *state->cp;
+                if (c < '0' || '7' < c)
+                    break;
+                state->cp++;
+                tmp = 8 * num + (uintN)JS7_UNDEC(c);
+                if (tmp > 0377)
+                    break;
+                num = tmp;
+            }
+            c = (jschar)num;
+    doFlat:
+            state->result = NewRENode(state, REOP_FLAT);
+            if (!state->result)
+                return JS_FALSE;
+            state->result->u.flat.chr = c;
+            state->result->u.flat.length = 1;
+            state->progLength += 3;
+            break;
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+            termStart = state->cp - 1;
+            num = GetDecimalValue(c, state->parenCount, FindParenCount, state);
+            if (state->flags & JSREG_FIND_PAREN_ERROR)
+                return JS_FALSE;
+            if (num == OVERFLOW_VALUE) {
+                /* Give a strict mode warning. */
+                if (!js_ReportCompileErrorNumber(state->context,
+                                                 state->tokenStream,
+                                                 JSREPORT_TS |
+                                                 JSREPORT_WARNING |
+                                                 JSREPORT_STRICT,
+                                                 (c >= '8')
+                                                 ? JSMSG_INVALID_BACKREF
+                                                 : JSMSG_BAD_BACKREF)) {
+                    return JS_FALSE;
+                }
+
+                /*
+                 * Note: ECMA 262, 15.10.2.9 says that we should throw a syntax
+                 * error here. However, for compatibility with IE, we treat the
+                 * whole backref as flat if the first character in it is not a
+                 * valid octal character, and as an octal escape otherwise.
+                 */
+                state->cp = termStart;
+                if (c >= '8') {
+                    /* Treat this as flat. termStart - 1 is the \. */
+                    c = '\\';
+                    goto asFlat;
+                }
+
+                /* Treat this as an octal escape. */
+                goto doOctal;
+            }
+            JS_ASSERT(1 <= num && num <= 0x10000);
+            state->result = NewRENode(state, REOP_BACKREF);
+            if (!state->result)
+                return JS_FALSE;
+            state->result->u.parenIndex = num - 1;
+            state->progLength
+                += 1 + GetCompactIndexWidth(state->result->u.parenIndex);
+            break;
+        /* Control escape */
+        case 'f':
+            c = 0xC;
+            goto doFlat;
+        case 'n':
+            c = 0xA;
+            goto doFlat;
+        case 'r':
+            c = 0xD;
+            goto doFlat;
+        case 't':
+            c = 0x9;
+            goto doFlat;
+        case 'v':
+            c = 0xB;
+            goto doFlat;
+        /* Control letter */
+        case 'c':
+            if (state->cp + 1 < state->cpend && RE_IS_LETTER(state->cp[1])) {
+                c = (jschar) (*state->cp++ & 0x1F);
+            } else {
+                /* back off to accepting the original '\' as a literal */
+                --state->cp;
+                c = '\\';
+            }
+            goto doFlat;
+        /* HexEscapeSequence */
+        case 'x':
+            nDigits = 2;
+            goto lexHex;
+        /* UnicodeEscapeSequence */
+        case 'u':
+            nDigits = 4;
+lexHex:
+            n = 0;
+            for (i = 0; i < nDigits && state->cp < state->cpend; i++) {
+                uintN digit;
+                c = *state->cp++;
+                if (!isASCIIHexDigit(c, &digit)) {
+                    /*
+                     * Back off to accepting the original 'u' or 'x' as a
+                     * literal.
+                     */
+                    state->cp -= i + 2;
+                    n = *state->cp++;
+                    break;
+                }
+                n = (n << 4) | digit;
+            }
+            c = (jschar) n;
+            goto doFlat;
+        /* Character class escapes */
+        case 'd':
+            state->result = NewRENode(state, REOP_DIGIT);
+doSimple:
+            if (!state->result)
+                return JS_FALSE;
+            state->progLength++;
+            break;
+        case 'D':
+            state->result = NewRENode(state, REOP_NONDIGIT);
+            goto doSimple;
+        case 's':
+            state->result = NewRENode(state, REOP_SPACE);
+            goto doSimple;
+        case 'S':
+            state->result = NewRENode(state, REOP_NONSPACE);
+            goto doSimple;
+        case 'w':
+            state->result = NewRENode(state, REOP_ALNUM);
+            goto doSimple;
+        case 'W':
+            state->result = NewRENode(state, REOP_NONALNUM);
+            goto doSimple;
+        /* IdentityEscape */
+        default:
+            state->result = NewRENode(state, REOP_FLAT);
+            if (!state->result)
+                return JS_FALSE;
+            state->result->u.flat.chr = c;
+            state->result->u.flat.length = 1;
+            state->result->kid = (void *) (state->cp - 1);
+            state->progLength += 3;
+            break;
+        }
+        break;
+    case '[':
+        state->result = NewRENode(state, REOP_CLASS);
+        if (!state->result)
+            return JS_FALSE;
+        termStart = state->cp;
+        state->result->u.ucclass.startIndex = termStart - state->cpbegin;
+        for (;;) {
+            if (state->cp == state->cpend) {
+                js_ReportCompileErrorNumberUC(state->context, state->tokenStream,
+                                              JSREPORT_TS | JSREPORT_ERROR,
+                                              JSMSG_UNTERM_CLASS, termStart);
+
+                return JS_FALSE;
+            }
+            if (*state->cp == '\\') {
+                state->cp++;
+            } else {
+                if (*state->cp == ']') {
+                    state->result->u.ucclass.kidlen = state->cp - termStart;
+                    break;
+                }
+            }
+            state->cp++;
+        }
+        for (i = 0; i < CLASS_CACHE_SIZE; i++) {
+            if (!state->classCache[i].start) {
+                state->classCache[i].start = termStart;
+                state->classCache[i].length = state->result->u.ucclass.kidlen;
+                state->classCache[i].index = state->classCount;
+                break;
+            }
+            if (state->classCache[i].length ==
+                state->result->u.ucclass.kidlen) {
+                for (n = 0; ; n++) {
+                    if (n == state->classCache[i].length) {
+                        state->result->u.ucclass.index
+                            = state->classCache[i].index;
+                        goto claim;
+                    }
+                    if (state->classCache[i].start[n] != termStart[n])
+                        break;
+                }
+            }
+        }
+        state->result->u.ucclass.index = state->classCount++;
+
+    claim:
+        /*
+         * Call CalculateBitmapSize now as we want any errors it finds
+         * to be reported during the parse phase, not at execution.
+         */
+        if (!CalculateBitmapSize(state, state->result, termStart, state->cp++))
+            return JS_FALSE;
+        /*
+         * Update classBitmapsMem with number of bytes to hold bmsize bits,
+         * which is (bitsCount + 7) / 8 or (highest_bit + 1 + 7) / 8
+         * or highest_bit / 8 + 1 where highest_bit is u.ucclass.bmsize.
+         */
+        n = (state->result->u.ucclass.bmsize >> 3) + 1;
+        if (n > CLASS_BITMAPS_MEM_LIMIT - state->classBitmapsMem) {
+            js_ReportCompileErrorNumber(state->context, state->tokenStream,
+                                        JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_REGEXP_TOO_COMPLEX);
+            return JS_FALSE;
+        }
+        state->classBitmapsMem += n;
+        /* CLASS, <index> */
+        state->progLength
+            += 1 + GetCompactIndexWidth(state->result->u.ucclass.index);
+        break;
+
+    case '.':
+        state->result = NewRENode(state, REOP_DOT);
+        goto doSimple;
+
+    case '{':
+    {
+        const jschar *errp = state->cp--;
+        intN err;
+
+        err = ParseMinMaxQuantifier(state, JS_TRUE);
+        state->cp = errp;
+
+        if (err < 0)
+            goto asFlat;
+
+        /* FALL THROUGH */
+    }
+    case '*':
+    case '+':
+    case '?':
+        js_ReportCompileErrorNumberUC(state->context, state->tokenStream,
+                                      JSREPORT_TS | JSREPORT_ERROR,
+                                      JSMSG_BAD_QUANTIFIER, state->cp - 1);
+        return JS_FALSE;
+    default:
+asFlat:
+        state->result = NewRENode(state, REOP_FLAT);
+        if (!state->result)
+            return JS_FALSE;
+        state->result->u.flat.chr = c;
+        state->result->u.flat.length = 1;
+        state->result->kid = (void *) (state->cp - 1);
+        state->progLength += 3;
+        break;
+    }
+    return ParseQuantifier(state);
+}
+
+static JSBool
+ParseQuantifier(CompilerState *state)
+{
+    RENode *term;
+    term = state->result;
+    if (state->cp < state->cpend) {
+        switch (*state->cp) {
+        case '+':
+            state->result = NewRENode(state, REOP_QUANT);
+            if (!state->result)
+                return JS_FALSE;
+            state->result->u.range.min = 1;
+            state->result->u.range.max = (uintN)-1;
+            /* <PLUS>, <next> ... <ENDCHILD> */
+            state->progLength += 4;
+            goto quantifier;
+        case '*':
+            state->result = NewRENode(state, REOP_QUANT);
+            if (!state->result)
+                return JS_FALSE;
+            state->result->u.range.min = 0;
+            state->result->u.range.max = (uintN)-1;
+            /* <STAR>, <next> ... <ENDCHILD> */
+            state->progLength += 4;
+            goto quantifier;
+        case '?':
+            state->result = NewRENode(state, REOP_QUANT);
+            if (!state->result)
+                return JS_FALSE;
+            state->result->u.range.min = 0;
+            state->result->u.range.max = 1;
+            /* <OPT>, <next> ... <ENDCHILD> */
+            state->progLength += 4;
+            goto quantifier;
+        case '{':       /* balance '}' */
+        {
+            intN err;
+            const jschar *errp = state->cp;
+
+            err = ParseMinMaxQuantifier(state, JS_FALSE);
+            if (err == 0)
+                goto quantifier;
+            if (err == -1)
+                return JS_TRUE;
+
+            js_ReportCompileErrorNumberUC(state->context,
+                                          state->tokenStream,
+                                          JSREPORT_TS | JSREPORT_ERROR,
+                                          err, errp);
+            return JS_FALSE;
+        }
+        default:;
+        }
+    }
+    return JS_TRUE;
+
+quantifier:
+    if (state->treeDepth == TREE_DEPTH_MAX) {
+        js_ReportCompileErrorNumber(state->context, state->tokenStream,
+                                    JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_REGEXP_TOO_COMPLEX);
+        return JS_FALSE;
+    }
+
+    ++state->treeDepth;
+    ++state->cp;
+    state->result->kid = term;
+    if (state->cp < state->cpend && *state->cp == '?') {
+        ++state->cp;
+        state->result->u.range.greedy = JS_FALSE;
+    } else {
+        state->result->u.range.greedy = JS_TRUE;
+    }
+    return JS_TRUE;
+}
+
+static intN
+ParseMinMaxQuantifier(CompilerState *state, JSBool ignoreValues)
+{
+    uintN min, max;
+    jschar c;
+    const jschar *errp = state->cp++;
+
+    c = *state->cp;
+    if (JS7_ISDEC(c)) {
+        ++state->cp;
+        min = GetDecimalValue(c, 0xFFFF, NULL, state);
+        c = *state->cp;
+
+        if (!ignoreValues && min == OVERFLOW_VALUE)
+            return JSMSG_MIN_TOO_BIG;
+
+        if (c == ',') {
+            c = *++state->cp;
+            if (JS7_ISDEC(c)) {
+                ++state->cp;
+                max = GetDecimalValue(c, 0xFFFF, NULL, state);
+                c = *state->cp;
+                if (!ignoreValues && max == OVERFLOW_VALUE)
+                    return JSMSG_MAX_TOO_BIG;
+                if (!ignoreValues && min > max)
+                    return JSMSG_OUT_OF_ORDER;
+            } else {
+                max = (uintN)-1;
+            }
+        } else {
+            max = min;
+        }
+        if (c == '}') {
+            state->result = NewRENode(state, REOP_QUANT);
+            if (!state->result)
+                return JS_FALSE;
+            state->result->u.range.min = min;
+            state->result->u.range.max = max;
+            /*
+             * QUANT, <min>, <max>, <next> ... <ENDCHILD>
+             * where <max> is written as compact(max+1) to make
+             * (uintN)-1 sentinel to occupy 1 byte, not width_of(max)+1.
+             */
+            state->progLength += (1 + GetCompactIndexWidth(min)
+                                  + GetCompactIndexWidth(max + 1)
+                                  +3);
+            return 0;
+        }
+    }
+
+    state->cp = errp;
+    return -1;
+}
+
+static JSBool
+SetForwardJumpOffset(jsbytecode *jump, jsbytecode *target)
+{
+    ptrdiff_t offset = target - jump;
+
+    /* Check that target really points forward. */
+    JS_ASSERT(offset >= 2);
+    if ((size_t)offset > OFFSET_MAX)
+        return JS_FALSE;
+
+    jump[0] = JUMP_OFFSET_HI(offset);
+    jump[1] = JUMP_OFFSET_LO(offset);
+    return JS_TRUE;
+}
+
+/*
+ * Generate bytecode for the tree rooted at t using an explicit stack instead
+ * of recursion.
+ */
+static jsbytecode *
+EmitREBytecode(CompilerState *state, JSRegExp *re, size_t treeDepth,
+               jsbytecode *pc, RENode *t)
+{
+    EmitStateStackEntry *emitStateSP, *emitStateStack;
+    RECharSet *charSet;
+    REOp op;
+
+    if (treeDepth == 0) {
+        emitStateStack = NULL;
+    } else {
+        emitStateStack =
+            (EmitStateStackEntry *)JS_malloc(state->context,
+                                             sizeof(EmitStateStackEntry) *
+                                             treeDepth);
+        if (!emitStateStack)
+            return NULL;
+    }
+    emitStateSP = emitStateStack;
+    op = t->op;
+
+    for (;;) {
+        *pc++ = op;
+        switch (op) {
+        case REOP_EMPTY:
+            --pc;
+            break;
+
+        case REOP_ALTPREREQ2:
+        case REOP_ALTPREREQ:
+            JS_ASSERT(emitStateSP);
+            emitStateSP->altHead = pc - 1;
+            emitStateSP->endTermFixup = pc;
+            pc += OFFSET_LEN;
+            SET_ARG(pc, t->u.altprereq.ch1);
+            pc += ARG_LEN;
+            SET_ARG(pc, t->u.altprereq.ch2);
+            pc += ARG_LEN;
+
+            emitStateSP->nextAltFixup = pc;    /* offset to next alternate */
+            pc += OFFSET_LEN;
+
+            emitStateSP->continueNode = t;
+            emitStateSP->continueOp = REOP_JUMP;
+            emitStateSP->jumpToJumpFlag = JS_FALSE;
+            ++emitStateSP;
+            JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
+            t = (RENode *) t->kid;
+            op = t->op;
+            continue;
+
+        case REOP_JUMP:
+            emitStateSP->nextTermFixup = pc;    /* offset to following term */
+            pc += OFFSET_LEN;
+            if (!SetForwardJumpOffset(emitStateSP->nextAltFixup, pc))
+                goto jump_too_big;
+            emitStateSP->continueOp = REOP_ENDALT;
+            ++emitStateSP;
+            JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
+            t = t->u.kid2;
+            op = t->op;
+            continue;
+
+        case REOP_ENDALT:
+            /*
+             * If we already patched emitStateSP->nextTermFixup to jump to
+             * a nearer jump, to avoid 16-bit immediate offset overflow, we
+             * are done here.
+             */
+            if (emitStateSP->jumpToJumpFlag)
+                break;
+
+            /*
+             * Fix up the REOP_JUMP offset to go to the op after REOP_ENDALT.
+             * REOP_ENDALT is executed only on successful match of the last
+             * alternate in a group.
+             */
+            if (!SetForwardJumpOffset(emitStateSP->nextTermFixup, pc))
+                goto jump_too_big;
+            if (t->op != REOP_ALT) {
+                if (!SetForwardJumpOffset(emitStateSP->endTermFixup, pc))
+                    goto jump_too_big;
+            }
+
+            /*
+             * If the program is bigger than the REOP_JUMP offset range, then
+             * we must check for alternates before this one that are part of
+             * the same group, and fix up their jump offsets to target jumps
+             * close enough to fit in a 16-bit unsigned offset immediate.
+             */
+            if ((size_t)(pc - re->program) > OFFSET_MAX &&
+                emitStateSP > emitStateStack) {
+                EmitStateStackEntry *esp, *esp2;
+                jsbytecode *alt, *jump;
+                ptrdiff_t span, header;
+
+                esp2 = emitStateSP;
+                alt = esp2->altHead;
+                for (esp = esp2 - 1; esp >= emitStateStack; --esp) {
+                    if (esp->continueOp == REOP_ENDALT &&
+                        !esp->jumpToJumpFlag &&
+                        esp->nextTermFixup + OFFSET_LEN == alt &&
+                        (size_t)(pc - ((esp->continueNode->op != REOP_ALT)
+                                       ? esp->endTermFixup
+                                       : esp->nextTermFixup)) > OFFSET_MAX) {
+                        alt = esp->altHead;
+                        jump = esp->nextTermFixup;
+
+                        /*
+                         * The span must be 1 less than the distance from
+                         * jump offset to jump offset, so we actually jump
+                         * to a REOP_JUMP bytecode, not to its offset!
+                         */
+                        for (;;) {
+                            JS_ASSERT(jump < esp2->nextTermFixup);
+                            span = esp2->nextTermFixup - jump - 1;
+                            if ((size_t)span <= OFFSET_MAX)
+                                break;
+                            do {
+                                if (--esp2 == esp)
+                                    goto jump_too_big;
+                            } while (esp2->continueOp != REOP_ENDALT);
+                        }
+
+                        jump[0] = JUMP_OFFSET_HI(span);
+                        jump[1] = JUMP_OFFSET_LO(span);
+
+                        if (esp->continueNode->op != REOP_ALT) {
+                            /*
+                             * We must patch the offset at esp->endTermFixup
+                             * as well, for the REOP_ALTPREREQ{,2} opcodes.
+                             * If we're unlucky and endTermFixup is more than
+                             * OFFSET_MAX bytes from its target, we cheat by
+                             * jumping 6 bytes to the jump whose offset is at
+                             * esp->nextTermFixup, which has the same target.
+                             */
+                            jump = esp->endTermFixup;
+                            header = esp->nextTermFixup - jump;
+                            span += header;
+                            if ((size_t)span > OFFSET_MAX)
+                                span = header;
+
+                            jump[0] = JUMP_OFFSET_HI(span);
+                            jump[1] = JUMP_OFFSET_LO(span);
+                        }
+
+                        esp->jumpToJumpFlag = JS_TRUE;
+                    }
+                }
+            }
+            break;
+
+        case REOP_ALT:
+            JS_ASSERT(emitStateSP);
+            emitStateSP->altHead = pc - 1;
+            emitStateSP->nextAltFixup = pc;     /* offset to next alternate */
+            pc += OFFSET_LEN;
+            emitStateSP->continueNode = t;
+            emitStateSP->continueOp = REOP_JUMP;
+            emitStateSP->jumpToJumpFlag = JS_FALSE;
+            ++emitStateSP;
+            JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
+            t = t->kid;
+            op = t->op;
+            continue;
+
+        case REOP_FLAT:
+            /*
+             * Coalesce FLATs if possible and if it would not increase bytecode
+             * beyond preallocated limit. The latter happens only when bytecode
+             * size for coalesced string with offset p and length 2 exceeds 6
+             * bytes preallocated for 2 single char nodes, i.e. when
+             * 1 + GetCompactIndexWidth(p) + GetCompactIndexWidth(2) > 6 or
+             * GetCompactIndexWidth(p) > 4.
+             * Since when GetCompactIndexWidth(p) <= 4 coalescing of 3 or more
+             * nodes strictly decreases bytecode size, the check has to be
+             * done only for the first coalescing.
+             */
+            if (t->kid &&
+                GetCompactIndexWidth((jschar *)t->kid - state->cpbegin) <= 4)
+            {
+                while (t->next &&
+                       t->next->op == REOP_FLAT &&
+                       (jschar*)t->kid + t->u.flat.length ==
+                       (jschar*)t->next->kid) {
+                    t->u.flat.length += t->next->u.flat.length;
+                    t->next = t->next->next;
+                }
+            }
+            if (t->kid && t->u.flat.length > 1) {
+                pc[-1] = (state->flags & JSREG_FOLD) ? REOP_FLATi : REOP_FLAT;
+                pc = WriteCompactIndex(pc, (jschar *)t->kid - state->cpbegin);
+                pc = WriteCompactIndex(pc, t->u.flat.length);
+            } else if (t->u.flat.chr < 256) {
+                pc[-1] = (state->flags & JSREG_FOLD) ? REOP_FLAT1i : REOP_FLAT1;
+                *pc++ = (jsbytecode) t->u.flat.chr;
+            } else {
+                pc[-1] = (state->flags & JSREG_FOLD)
+                         ? REOP_UCFLAT1i
+                         : REOP_UCFLAT1;
+                SET_ARG(pc, t->u.flat.chr);
+                pc += ARG_LEN;
+            }
+            break;
+
+        case REOP_LPAREN:
+            JS_ASSERT(emitStateSP);
+            pc = WriteCompactIndex(pc, t->u.parenIndex);
+            emitStateSP->continueNode = t;
+            emitStateSP->continueOp = REOP_RPAREN;
+            ++emitStateSP;
+            JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
+            t = (RENode *) t->kid;
+            op = t->op;
+            continue;
+
+        case REOP_RPAREN:
+            pc = WriteCompactIndex(pc, t->u.parenIndex);
+            break;
+
+        case REOP_BACKREF:
+            pc = WriteCompactIndex(pc, t->u.parenIndex);
+            break;
+
+        case REOP_ASSERT:
+            JS_ASSERT(emitStateSP);
+            emitStateSP->nextTermFixup = pc;
+            pc += OFFSET_LEN;
+            emitStateSP->continueNode = t;
+            emitStateSP->continueOp = REOP_ASSERTTEST;
+            ++emitStateSP;
+            JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
+            t = (RENode *) t->kid;
+            op = t->op;
+            continue;
+
+        case REOP_ASSERTTEST:
+        case REOP_ASSERTNOTTEST:
+            if (!SetForwardJumpOffset(emitStateSP->nextTermFixup, pc))
+                goto jump_too_big;
+            break;
+
+        case REOP_ASSERT_NOT:
+            JS_ASSERT(emitStateSP);
+            emitStateSP->nextTermFixup = pc;
+            pc += OFFSET_LEN;
+            emitStateSP->continueNode = t;
+            emitStateSP->continueOp = REOP_ASSERTNOTTEST;
+            ++emitStateSP;
+            JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
+            t = (RENode *) t->kid;
+            op = t->op;
+            continue;
+
+        case REOP_QUANT:
+            JS_ASSERT(emitStateSP);
+            if (t->u.range.min == 0 && t->u.range.max == (uintN)-1) {
+                pc[-1] = (t->u.range.greedy) ? REOP_STAR : REOP_MINIMALSTAR;
+            } else if (t->u.range.min == 0 && t->u.range.max == 1) {
+                pc[-1] = (t->u.range.greedy) ? REOP_OPT : REOP_MINIMALOPT;
+            } else if (t->u.range.min == 1 && t->u.range.max == (uintN) -1) {
+                pc[-1] = (t->u.range.greedy) ? REOP_PLUS : REOP_MINIMALPLUS;
+            } else {
+                if (!t->u.range.greedy)
+                    pc[-1] = REOP_MINIMALQUANT;
+                pc = WriteCompactIndex(pc, t->u.range.min);
+                /*
+                 * Write max + 1 to avoid using size_t(max) + 1 bytes
+                 * for (uintN)-1 sentinel.
+                 */
+                pc = WriteCompactIndex(pc, t->u.range.max + 1);
+            }
+            emitStateSP->nextTermFixup = pc;
+            pc += OFFSET_LEN;
+            emitStateSP->continueNode = t;
+            emitStateSP->continueOp = REOP_ENDCHILD;
+            ++emitStateSP;
+            JS_ASSERT((size_t)(emitStateSP - emitStateStack) <= treeDepth);
+            t = (RENode *) t->kid;
+            op = t->op;
+            continue;
+
+        case REOP_ENDCHILD:
+            if (!SetForwardJumpOffset(emitStateSP->nextTermFixup, pc))
+                goto jump_too_big;
+            break;
+
+        case REOP_CLASS:
+            if (!t->u.ucclass.sense)
+                pc[-1] = REOP_NCLASS;
+            pc = WriteCompactIndex(pc, t->u.ucclass.index);
+            charSet = &re->classList[t->u.ucclass.index];
+            charSet->converted = JS_FALSE;
+            charSet->length = t->u.ucclass.bmsize;
+            charSet->u.src.startIndex = t->u.ucclass.startIndex;
+            charSet->u.src.length = t->u.ucclass.kidlen;
+            charSet->sense = t->u.ucclass.sense;
+            break;
+
+        default:
+            break;
+        }
+
+        t = t->next;
+        if (t) {
+            op = t->op;
+        } else {
+            if (emitStateSP == emitStateStack)
+                break;
+            --emitStateSP;
+            t = emitStateSP->continueNode;
+            op = emitStateSP->continueOp;
+        }
+    }
+
+  cleanup:
+    if (emitStateStack)
+        JS_free(state->context, emitStateStack);
+    return pc;
+
+  jump_too_big:
+    js_ReportCompileErrorNumber(state->context, state->tokenStream,
+                                JSREPORT_TS | JSREPORT_ERROR,
+                                JSMSG_REGEXP_TOO_COMPLEX);
+    pc = NULL;
+    goto cleanup;
+}
+
+
+JSRegExp *
+js_NewRegExp(JSContext *cx, JSTokenStream *ts,
+             JSString *str, uintN flags, JSBool flat)
+{
+    JSRegExp *re;
+    void *mark;
+    CompilerState state;
+    size_t resize;
+    jsbytecode *endPC;
+    uintN i;
+    size_t len;
+
+    re = NULL;
+    mark = JS_ARENA_MARK(&cx->tempPool);
+    len = JSSTRING_LENGTH(str);
+
+    state.context = cx;
+    state.tokenStream = ts;
+    state.cp = js_UndependString(cx, str);
+    if (!state.cp)
+        goto out;
+    state.cpbegin = state.cp;
+    state.cpend = state.cp + len;
+    state.flags = flags;
+    state.parenCount = 0;
+    state.classCount = 0;
+    state.progLength = 0;
+    state.treeDepth = 0;
+    state.classBitmapsMem = 0;
+    for (i = 0; i < CLASS_CACHE_SIZE; i++)
+        state.classCache[i].start = NULL;
+
+    if (len != 0 && flat) {
+        state.result = NewRENode(&state, REOP_FLAT);
+        state.result->u.flat.chr = *state.cpbegin;
+        state.result->u.flat.length = len;
+        state.result->kid = (void *) state.cpbegin;
+        /* Flat bytecode: REOP_FLAT compact(string_offset) compact(len). */
+        state.progLength += 1 + GetCompactIndexWidth(0)
+                          + GetCompactIndexWidth(len);
+    } else {
+        if (!ParseRegExp(&state))
+            goto out;
+    }
+    resize = offsetof(JSRegExp, program) + state.progLength + 1;
+    re = (JSRegExp *) JS_malloc(cx, resize);
+    if (!re)
+        goto out;
+
+    re->nrefs = 1;
+    JS_ASSERT(state.classBitmapsMem <= CLASS_BITMAPS_MEM_LIMIT);
+    re->classCount = state.classCount;
+    if (re->classCount) {
+        re->classList = (RECharSet *)
+            JS_malloc(cx, re->classCount * sizeof(RECharSet));
+        if (!re->classList) {
+            js_DestroyRegExp(cx, re);
+            re = NULL;
+            goto out;
+        }
+    } else {
+        re->classList = NULL;
+    }
+    endPC = EmitREBytecode(&state, re, state.treeDepth, re->program, state.result);
+    if (!endPC) {
+        js_DestroyRegExp(cx, re);
+        re = NULL;
+        goto out;
+    }
+    *endPC++ = REOP_END;
+    /*
+     * Check whether size was overestimated and shrink using realloc.
+     * This is safe since no pointers to newly parsed regexp or its parts
+     * besides re exist here.
+     */
+    if ((size_t)(endPC - re->program) != state.progLength + 1) {
+        JSRegExp *tmp;
+        JS_ASSERT((size_t)(endPC - re->program) < state.progLength + 1);
+        resize = offsetof(JSRegExp, program) + (endPC - re->program);
+        tmp = (JSRegExp *) JS_realloc(cx, re, resize);
+        if (tmp)
+            re = tmp;
+    }
+
+    re->flags = flags;
+    re->cloneIndex = 0;
+    re->parenCount = state.parenCount;
+    re->source = str;
+
+out:
+    JS_ARENA_RELEASE(&cx->tempPool, mark);
+    return re;
+}
+
+JSRegExp *
+js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts,
+                JSString *str, JSString *opt, JSBool flat)
+{
+    uintN flags;
+    jschar *s;
+    size_t i, n;
+    char charBuf[2];
+
+    flags = 0;
+    if (opt) {
+        s = JSSTRING_CHARS(opt);
+        for (i = 0, n = JSSTRING_LENGTH(opt); i < n; i++) {
+            switch (s[i]) {
+            case 'g':
+                flags |= JSREG_GLOB;
+                break;
+            case 'i':
+                flags |= JSREG_FOLD;
+                break;
+            case 'm':
+                flags |= JSREG_MULTILINE;
+                break;
+            default:
+                charBuf[0] = (char)s[i];
+                charBuf[1] = '\0';
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_BAD_FLAG, charBuf);
+                return NULL;
+            }
+        }
+    }
+    return js_NewRegExp(cx, ts, str, flags, flat);
+}
+
+
+#define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs)
+#define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re)
+
+/*
+ * Save the current state of the match - the position in the input
+ * text as well as the position in the bytecode. The state of any
+ * parent expressions is also saved (preceding state).
+ * Contents of parenCount parentheses from parenIndex are also saved.
+ */
+static REBackTrackData *
+PushBackTrackState(REGlobalData *gData, REOp op,
+                   jsbytecode *target, REMatchState *x, const jschar *cp,
+                   size_t parenIndex, size_t parenCount)
+{
+    size_t i;
+    REBackTrackData *result =
+        (REBackTrackData *) ((char *)gData->backTrackSP + gData->cursz);
+
+    size_t sz = sizeof(REBackTrackData) +
+                gData->stateStackTop * sizeof(REProgState) +
+                parenCount * sizeof(RECapture);
+
+    ptrdiff_t btsize = gData->backTrackStackSize;
+    ptrdiff_t btincr = ((char *)result + sz) -
+                       ((char *)gData->backTrackStack + btsize);
+
+    if (btincr > 0) {
+        ptrdiff_t offset = (char *)result - (char *)gData->backTrackStack;
+
+        btincr = JS_ROUNDUP(btincr, btsize);
+        JS_ARENA_GROW_CAST(gData->backTrackStack, REBackTrackData *,
+                           &gData->pool, btsize, btincr);
+        if (!gData->backTrackStack)
+            return NULL;
+        gData->backTrackStackSize = btsize + btincr;
+        result = (REBackTrackData *) ((char *)gData->backTrackStack + offset);
+    }
+    gData->backTrackSP = result;
+    result->sz = gData->cursz;
+    gData->cursz = sz;
+
+    result->backtrack_op = op;
+    result->backtrack_pc = target;
+    result->cp = cp;
+    result->parenCount = parenCount;
+
+    result->saveStateStackTop = gData->stateStackTop;
+    JS_ASSERT(gData->stateStackTop);
+    memcpy(result + 1, gData->stateStack,
+           sizeof(REProgState) * result->saveStateStackTop);
+
+    if (parenCount != 0) {
+        result->parenIndex = parenIndex;
+        memcpy((char *)(result + 1) +
+               sizeof(REProgState) * result->saveStateStackTop,
+               &x->parens[parenIndex],
+               sizeof(RECapture) * parenCount);
+        for (i = 0; i != parenCount; i++)
+            x->parens[parenIndex + i].index = -1;
+    }
+
+    return result;
+}
+
+
+/*
+ *   Consecutive literal characters.
+ */
+#if 0
+static REMatchState *
+FlatNMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars,
+             size_t length)
+{
+    size_t i;
+    if (length > gData->cpend - x->cp)
+        return NULL;
+    for (i = 0; i != length; i++) {
+        if (matchChars[i] != x->cp[i])
+            return NULL;
+    }
+    x->cp += length;
+    return x;
+}
+#endif
+
+static REMatchState *
+FlatNIMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars,
+              size_t length)
+{
+    size_t i;
+    JS_ASSERT(gData->cpend >= x->cp);
+    if (length > (size_t)(gData->cpend - x->cp))
+        return NULL;
+    for (i = 0; i != length; i++) {
+        if (upcase(matchChars[i]) != upcase(x->cp[i]))
+            return NULL;
+    }
+    x->cp += length;
+    return x;
+}
+
+/*
+ * 1. Evaluate DecimalEscape to obtain an EscapeValue E.
+ * 2. If E is not a character then go to step 6.
+ * 3. Let ch be E's character.
+ * 4. Let A be a one-element RECharSet containing the character ch.
+ * 5. Call CharacterSetMatcher(A, false) and return its Matcher result.
+ * 6. E must be an integer. Let n be that integer.
+ * 7. If n=0 or n>NCapturingParens then throw a SyntaxError exception.
+ * 8. Return an internal Matcher closure that takes two arguments, a State x
+ *    and a Continuation c, and performs the following:
+ *     1. Let cap be x's captures internal array.
+ *     2. Let s be cap[n].
+ *     3. If s is undefined, then call c(x) and return its result.
+ *     4. Let e be x's endIndex.
+ *     5. Let len be s's length.
+ *     6. Let f be e+len.
+ *     7. If f>InputLength, return failure.
+ *     8. If there exists an integer i between 0 (inclusive) and len (exclusive)
+ *        such that Canonicalize(s[i]) is not the same character as
+ *        Canonicalize(Input [e+i]), then return failure.
+ *     9. Let y be the State (f, cap).
+ *     10. Call c(y) and return its result.
+ */
+static REMatchState *
+BackrefMatcher(REGlobalData *gData, REMatchState *x, size_t parenIndex)
+{
+    size_t len, i;
+    const jschar *parenContent;
+    RECapture *cap = &x->parens[parenIndex];
+
+    if (cap->index == -1)
+        return x;
+
+    len = cap->length;
+    if (x->cp + len > gData->cpend)
+        return NULL;
+
+    parenContent = &gData->cpbegin[cap->index];
+    if (gData->regexp->flags & JSREG_FOLD) {
+        for (i = 0; i < len; i++) {
+            if (upcase(parenContent[i]) != upcase(x->cp[i]))
+                return NULL;
+        }
+    } else {
+        for (i = 0; i < len; i++) {
+            if (parenContent[i] != x->cp[i])
+                return NULL;
+        }
+    }
+    x->cp += len;
+    return x;
+}
+
+
+/* Add a single character to the RECharSet */
+static void
+AddCharacterToCharSet(RECharSet *cs, jschar c)
+{
+    uintN byteIndex = (uintN)(c >> 3);
+    JS_ASSERT(c <= cs->length);
+    cs->u.bits[byteIndex] |= 1 << (c & 0x7);
+}
+
+
+/* Add a character range, c1 to c2 (inclusive) to the RECharSet */
+static void
+AddCharacterRangeToCharSet(RECharSet *cs, jschar c1, jschar c2)
+{
+    uintN i;
+
+    uintN byteIndex1 = (uintN)(c1 >> 3);
+    uintN byteIndex2 = (uintN)(c2 >> 3);
+
+    JS_ASSERT((c2 <= cs->length) && (c1 <= c2));
+
+    c1 &= 0x7;
+    c2 &= 0x7;
+
+    if (byteIndex1 == byteIndex2) {
+        cs->u.bits[byteIndex1] |= ((uint8)0xFF >> (7 - (c2 - c1))) << c1;
+    } else {
+        cs->u.bits[byteIndex1] |= 0xFF << c1;
+        for (i = byteIndex1 + 1; i < byteIndex2; i++)
+            cs->u.bits[i] = 0xFF;
+        cs->u.bits[byteIndex2] |= (uint8)0xFF >> (7 - c2);
+    }
+}
+
+/* Compile the source of the class into a RECharSet */
+static JSBool
+ProcessCharSet(REGlobalData *gData, RECharSet *charSet)
+{
+    const jschar *src, *end;
+    JSBool inRange = JS_FALSE;
+    jschar rangeStart = 0;
+    uintN byteLength, n;
+    jschar c, thisCh;
+    intN nDigits, i;
+
+    JS_ASSERT(!charSet->converted);
+    /*
+     * Assert that startIndex and length points to chars inside [] inside
+     * source string.
+     */
+    JS_ASSERT(1 <= charSet->u.src.startIndex);
+    JS_ASSERT(charSet->u.src.startIndex
+              < JSSTRING_LENGTH(gData->regexp->source));
+    JS_ASSERT(charSet->u.src.length <= JSSTRING_LENGTH(gData->regexp->source)
+                                       - 1 - charSet->u.src.startIndex);
+
+    charSet->converted = JS_TRUE;
+    src = JSSTRING_CHARS(gData->regexp->source) + charSet->u.src.startIndex;
+    end = src + charSet->u.src.length;
+    JS_ASSERT(src[-1] == '[');
+    JS_ASSERT(end[0] == ']');
+
+    byteLength = (charSet->length >> 3) + 1;
+    charSet->u.bits = (uint8 *)JS_malloc(gData->cx, byteLength);
+    if (!charSet->u.bits)
+        return JS_FALSE;
+    memset(charSet->u.bits, 0, byteLength);
+
+    if (src == end)
+        return JS_TRUE;
+
+    if (*src == '^') {
+        JS_ASSERT(charSet->sense == JS_FALSE);
+        ++src;
+    } else {
+        JS_ASSERT(charSet->sense == JS_TRUE);
+    }
+
+    while (src != end) {
+        switch (*src) {
+        case '\\':
+            ++src;
+            c = *src++;
+            switch (c) {
+            case 'b':
+                thisCh = 0x8;
+                break;
+            case 'f':
+                thisCh = 0xC;
+                break;
+            case 'n':
+                thisCh = 0xA;
+                break;
+            case 'r':
+                thisCh = 0xD;
+                break;
+            case 't':
+                thisCh = 0x9;
+                break;
+            case 'v':
+                thisCh = 0xB;
+                break;
+            case 'c':
+                if (src + 1 < end && JS_ISWORD(src[1])) {
+                    thisCh = (jschar)(*src++ & 0x1F);
+                } else {
+                    --src;
+                    thisCh = '\\';
+                }
+                break;
+            case 'x':
+                nDigits = 2;
+                goto lexHex;
+            case 'u':
+                nDigits = 4;
+            lexHex:
+                n = 0;
+                for (i = 0; (i < nDigits) && (src < end); i++) {
+                    uintN digit;
+                    c = *src++;
+                    if (!isASCIIHexDigit(c, &digit)) {
+                        /*
+                         * Back off to accepting the original '\'
+                         * as a literal
+                         */
+                        src -= i + 1;
+                        n = '\\';
+                        break;
+                    }
+                    n = (n << 4) | digit;
+                }
+                thisCh = (jschar)n;
+                break;
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+                /*
+                 *  This is a non-ECMA extension - decimal escapes (in this
+                 *  case, octal!) are supposed to be an error inside class
+                 *  ranges, but supported here for backwards compatibility.
+                 */
+                n = JS7_UNDEC(c);
+                c = *src;
+                if ('0' <= c && c <= '7') {
+                    src++;
+                    n = 8 * n + JS7_UNDEC(c);
+                    c = *src;
+                    if ('0' <= c && c <= '7') {
+                        src++;
+                        i = 8 * n + JS7_UNDEC(c);
+                        if (i <= 0377)
+                            n = i;
+                        else
+                            src--;
+                    }
+                }
+                thisCh = (jschar)n;
+                break;
+
+            case 'd':
+                AddCharacterRangeToCharSet(charSet, '0', '9');
+                continue;   /* don't need range processing */
+            case 'D':
+                AddCharacterRangeToCharSet(charSet, 0, '0' - 1);
+                AddCharacterRangeToCharSet(charSet,
+                                           (jschar)('9' + 1),
+                                           (jschar)charSet->length);
+                continue;
+            case 's':
+                for (i = (intN)charSet->length; i >= 0; i--)
+                    if (JS_ISSPACE(i))
+                        AddCharacterToCharSet(charSet, (jschar)i);
+                continue;
+            case 'S':
+                for (i = (intN)charSet->length; i >= 0; i--)
+                    if (!JS_ISSPACE(i))
+                        AddCharacterToCharSet(charSet, (jschar)i);
+                continue;
+            case 'w':
+                for (i = (intN)charSet->length; i >= 0; i--)
+                    if (JS_ISWORD(i))
+                        AddCharacterToCharSet(charSet, (jschar)i);
+                continue;
+            case 'W':
+                for (i = (intN)charSet->length; i >= 0; i--)
+                    if (!JS_ISWORD(i))
+                        AddCharacterToCharSet(charSet, (jschar)i);
+                continue;
+            default:
+                thisCh = c;
+                break;
+
+            }
+            break;
+
+        default:
+            thisCh = *src++;
+            break;
+
+        }
+        if (inRange) {
+            if (gData->regexp->flags & JSREG_FOLD) {
+                AddCharacterRangeToCharSet(charSet, upcase(rangeStart),
+                                                    upcase(thisCh));
+                AddCharacterRangeToCharSet(charSet, downcase(rangeStart),
+                                                    downcase(thisCh));
+            } else {
+                AddCharacterRangeToCharSet(charSet, rangeStart, thisCh);
+            }
+            inRange = JS_FALSE;
+        } else {
+            if (gData->regexp->flags & JSREG_FOLD) {
+                AddCharacterToCharSet(charSet, upcase(thisCh));
+                AddCharacterToCharSet(charSet, downcase(thisCh));
+            } else {
+                AddCharacterToCharSet(charSet, thisCh);
+            }
+            if (src < end - 1) {
+                if (*src == '-') {
+                    ++src;
+                    inRange = JS_TRUE;
+                    rangeStart = thisCh;
+                }
+            }
+        }
+    }
+    return JS_TRUE;
+}
+
+void
+js_DestroyRegExp(JSContext *cx, JSRegExp *re)
+{
+    if (JS_ATOMIC_DECREMENT(&re->nrefs) == 0) {
+        if (re->classList) {
+            uintN i;
+            for (i = 0; i < re->classCount; i++) {
+                if (re->classList[i].converted)
+                    JS_free(cx, re->classList[i].u.bits);
+                re->classList[i].u.bits = NULL;
+            }
+            JS_free(cx, re->classList);
+        }
+        JS_free(cx, re);
+    }
+}
+
+static JSBool
+ReallocStateStack(REGlobalData *gData)
+{
+    size_t limit = gData->stateStackLimit;
+    size_t sz = sizeof(REProgState) * limit;
+
+    JS_ARENA_GROW_CAST(gData->stateStack, REProgState *, &gData->pool, sz, sz);
+    if (!gData->stateStack) {
+        gData->ok = JS_FALSE;
+        return JS_FALSE;
+    }
+    gData->stateStackLimit = limit + limit;
+    return JS_TRUE;
+}
+
+#define PUSH_STATE_STACK(data)                                                \
+    JS_BEGIN_MACRO                                                            \
+        ++(data)->stateStackTop;                                              \
+        if ((data)->stateStackTop == (data)->stateStackLimit &&               \
+            !ReallocStateStack((data))) {                                     \
+            return NULL;                                                      \
+        }                                                                     \
+    JS_END_MACRO
+
+/*
+ * Apply the current op against the given input to see if it's going to match
+ * or fail. Return false if we don't get a match, true if we do and update the
+ * state of the input and pc if the update flag is true.
+ */
+static REMatchState *
+SimpleMatch(REGlobalData *gData, REMatchState *x, REOp op,
+            jsbytecode **startpc, JSBool update)
+{
+    REMatchState *result = NULL;
+    jschar matchCh;
+    size_t parenIndex;
+    size_t offset, length, index;
+    jsbytecode *pc = *startpc;  /* pc has already been incremented past op */
+    jschar *source;
+    const jschar *startcp = x->cp;
+    jschar ch;
+    RECharSet *charSet;
+
+    switch (op) {
+    case REOP_BOL:
+        if (x->cp != gData->cpbegin) {
+            if (!gData->cx->regExpStatics.multiline &&
+                !(gData->regexp->flags & JSREG_MULTILINE)) {
+                break;
+            }
+            if (!RE_IS_LINE_TERM(x->cp[-1]))
+                break;
+        }
+        result = x;
+        break;
+    case REOP_EOL:
+        if (x->cp != gData->cpend) {
+            if (!gData->cx->regExpStatics.multiline &&
+                !(gData->regexp->flags & JSREG_MULTILINE)) {
+                break;
+            }
+            if (!RE_IS_LINE_TERM(*x->cp))
+                break;
+        }
+        result = x;
+        break;
+    case REOP_WBDRY:
+        if ((x->cp == gData->cpbegin || !JS_ISWORD(x->cp[-1])) ^
+            !(x->cp != gData->cpend && JS_ISWORD(*x->cp))) {
+            result = x;
+        }
+        break;
+    case REOP_WNONBDRY:
+        if ((x->cp == gData->cpbegin || !JS_ISWORD(x->cp[-1])) ^
+            (x->cp != gData->cpend && JS_ISWORD(*x->cp))) {
+            result = x;
+        }
+        break;
+    case REOP_DOT:
+        if (x->cp != gData->cpend && !RE_IS_LINE_TERM(*x->cp)) {
+            result = x;
+            result->cp++;
+        }
+        break;
+    case REOP_DIGIT:
+        if (x->cp != gData->cpend && JS_ISDIGIT(*x->cp)) {
+            result = x;
+            result->cp++;
+        }
+        break;
+    case REOP_NONDIGIT:
+        if (x->cp != gData->cpend && !JS_ISDIGIT(*x->cp)) {
+            result = x;
+            result->cp++;
+        }
+        break;
+    case REOP_ALNUM:
+        if (x->cp != gData->cpend && JS_ISWORD(*x->cp)) {
+            result = x;
+            result->cp++;
+        }
+        break;
+    case REOP_NONALNUM:
+        if (x->cp != gData->cpend && !JS_ISWORD(*x->cp)) {
+            result = x;
+            result->cp++;
+        }
+        break;
+    case REOP_SPACE:
+        if (x->cp != gData->cpend && JS_ISSPACE(*x->cp)) {
+            result = x;
+            result->cp++;
+        }
+        break;
+    case REOP_NONSPACE:
+        if (x->cp != gData->cpend && !JS_ISSPACE(*x->cp)) {
+            result = x;
+            result->cp++;
+        }
+        break;
+    case REOP_BACKREF:
+        pc = ReadCompactIndex(pc, &parenIndex);
+        JS_ASSERT(parenIndex < gData->regexp->parenCount);
+        result = BackrefMatcher(gData, x, parenIndex);
+        break;
+    case REOP_FLAT:
+        pc = ReadCompactIndex(pc, &offset);
+        JS_ASSERT(offset < JSSTRING_LENGTH(gData->regexp->source));
+        pc = ReadCompactIndex(pc, &length);
+        JS_ASSERT(1 <= length);
+        JS_ASSERT(length <= JSSTRING_LENGTH(gData->regexp->source) - offset);
+        if (length <= (size_t)(gData->cpend - x->cp)) {
+            source = JSSTRING_CHARS(gData->regexp->source) + offset;
+            for (index = 0; index != length; index++) {
+                if (source[index] != x->cp[index])
+                    return NULL;
+            }
+            x->cp += length;
+            result = x;
+        }
+        break;
+    case REOP_FLAT1:
+        matchCh = *pc++;
+        if (x->cp != gData->cpend && *x->cp == matchCh) {
+            result = x;
+            result->cp++;
+        }
+        break;
+    case REOP_FLATi:
+        pc = ReadCompactIndex(pc, &offset);
+        JS_ASSERT(offset < JSSTRING_LENGTH(gData->regexp->source));
+        pc = ReadCompactIndex(pc, &length);
+        JS_ASSERT(1 <= length);
+        JS_ASSERT(length <= JSSTRING_LENGTH(gData->regexp->source) - offset);
+        source = JSSTRING_CHARS(gData->regexp->source);
+        result = FlatNIMatcher(gData, x, source + offset, length);
+        break;
+    case REOP_FLAT1i:
+        matchCh = *pc++;
+        if (x->cp != gData->cpend && upcase(*x->cp) == upcase(matchCh)) {
+            result = x;
+            result->cp++;
+        }
+        break;
+    case REOP_UCFLAT1:
+        matchCh = GET_ARG(pc);
+        pc += ARG_LEN;
+        if (x->cp != gData->cpend && *x->cp == matchCh) {
+            result = x;
+            result->cp++;
+        }
+        break;
+    case REOP_UCFLAT1i:
+        matchCh = GET_ARG(pc);
+        pc += ARG_LEN;
+        if (x->cp != gData->cpend && upcase(*x->cp) == upcase(matchCh)) {
+            result = x;
+            result->cp++;
+        }
+        break;
+    case REOP_CLASS:
+        pc = ReadCompactIndex(pc, &index);
+        JS_ASSERT(index < gData->regexp->classCount);
+        if (x->cp != gData->cpend) {
+            charSet = &gData->regexp->classList[index];
+            JS_ASSERT(charSet->converted);
+            ch = *x->cp;
+            index = ch >> 3;
+            if (charSet->length != 0 &&
+                ch <= charSet->length &&
+                (charSet->u.bits[index] & (1 << (ch & 0x7)))) {
+                result = x;
+                result->cp++;
+            }
+        }
+        break;
+    case REOP_NCLASS:
+        pc = ReadCompactIndex(pc, &index);
+        JS_ASSERT(index < gData->regexp->classCount);
+        if (x->cp != gData->cpend) {
+            charSet = &gData->regexp->classList[index];
+            JS_ASSERT(charSet->converted);
+            ch = *x->cp;
+            index = ch >> 3;
+            if (charSet->length == 0 ||
+                ch > charSet->length ||
+                !(charSet->u.bits[index] & (1 << (ch & 0x7)))) {
+                result = x;
+                result->cp++;
+            }
+        }
+        break;
+    default:
+        JS_ASSERT(JS_FALSE);
+    }
+    if (result) {
+        if (update)
+            *startpc = pc;
+        else
+            x->cp = startcp;
+        return result;
+    }
+    x->cp = startcp;
+    return NULL;
+}
+
+static REMatchState *
+ExecuteREBytecode(REGlobalData *gData, REMatchState *x)
+{
+    REMatchState *result = NULL;
+    REBackTrackData *backTrackData;
+    jsbytecode *nextpc;
+    REOp nextop;
+    RECapture *cap;
+    REProgState *curState;
+    const jschar *startcp;
+    size_t parenIndex, k;
+    size_t parenSoFar = 0;
+
+    jschar matchCh1, matchCh2;
+    RECharSet *charSet;
+
+    JSBool anchor;
+    jsbytecode *pc = gData->regexp->program;
+    REOp op = (REOp) *pc++;
+
+    /*
+     * If the first node is a simple match, step the index into the string
+     * until that match is made, or fail if it can't be found at all.
+     */
+    if (REOP_IS_SIMPLE(op)) {
+        anchor = JS_FALSE;
+        while (x->cp <= gData->cpend) {
+            nextpc = pc;    /* reset back to start each time */
+            result = SimpleMatch(gData, x, op, &nextpc, JS_TRUE);
+            if (result) {
+                anchor = JS_TRUE;
+                x = result;
+                pc = nextpc;    /* accept skip to next opcode */
+                op = (REOp) *pc++;
+                break;
+            }
+            gData->skipped++;
+            x->cp++;
+        }
+        if (!anchor)
+            return NULL;
+    }
+
+    for (;;) {
+        if (REOP_IS_SIMPLE(op)) {
+            result = SimpleMatch(gData, x, op, &pc, JS_TRUE);
+        } else {
+            curState = &gData->stateStack[gData->stateStackTop];
+            switch (op) {
+            case REOP_EMPTY:
+                result = x;
+                break;
+
+            case REOP_ALTPREREQ2:
+                nextpc = pc + GET_OFFSET(pc);   /* start of next op */
+                pc += ARG_LEN;
+                matchCh2 = GET_ARG(pc);
+                pc += ARG_LEN;
+                k = GET_ARG(pc);
+                pc += ARG_LEN;
+
+                if (x->cp != gData->cpend) {
+                    if (*x->cp == matchCh2)
+                        goto doAlt;
+
+                    charSet = &gData->regexp->classList[k];
+                    if (!charSet->converted)
+                        if (!ProcessCharSet(gData, charSet))
+                            return NULL;
+                    matchCh1 = *x->cp;
+                    k = matchCh1 >> 3;
+                    if ((charSet->length == 0 ||
+                         matchCh1 > charSet->length ||
+                         !(charSet->u.bits[k] & (1 << (matchCh1 & 0x7)))) ^
+                        charSet->sense) {
+                        goto doAlt;
+                    }
+                }
+                result = NULL;
+                break;
+
+            case REOP_ALTPREREQ:
+                nextpc = pc + GET_OFFSET(pc);   /* start of next op */
+                pc += ARG_LEN;
+                matchCh1 = GET_ARG(pc);
+                pc += ARG_LEN;
+                matchCh2 = GET_ARG(pc);
+                pc += ARG_LEN;
+                if (x->cp == gData->cpend ||
+                    (*x->cp != matchCh1 && *x->cp != matchCh2)) {
+                    result = NULL;
+                    break;
+                }
+                /* else false thru... */
+
+            case REOP_ALT:
+            doAlt:
+                nextpc = pc + GET_OFFSET(pc);   /* start of next alternate */
+                pc += ARG_LEN;                  /* start of this alternate */
+                curState->parenSoFar = parenSoFar;
+                PUSH_STATE_STACK(gData);
+                op = (REOp) *pc++;
+                startcp = x->cp;
+                if (REOP_IS_SIMPLE(op)) {
+                    if (!SimpleMatch(gData, x, op, &pc, JS_TRUE)) {
+                        op = (REOp) *nextpc++;
+                        pc = nextpc;
+                        continue;
+                    }
+                    result = x;
+                    op = (REOp) *pc++;
+                }
+                nextop = (REOp) *nextpc++;
+                if (!PushBackTrackState(gData, nextop, nextpc, x, startcp, 0, 0))
+                    return NULL;
+                continue;
+
+            /*
+             * Occurs at (succesful) end of REOP_ALT,
+             */
+            case REOP_JUMP:
+                --gData->stateStackTop;
+                pc += GET_OFFSET(pc);
+                op = (REOp) *pc++;
+                continue;
+
+            /*
+             * Occurs at last (succesful) end of REOP_ALT,
+             */
+            case REOP_ENDALT:
+                --gData->stateStackTop;
+                op = (REOp) *pc++;
+                continue;
+
+            case REOP_LPAREN:
+                pc = ReadCompactIndex(pc, &parenIndex);
+                JS_ASSERT(parenIndex < gData->regexp->parenCount);
+                if (parenIndex + 1 > parenSoFar)
+                    parenSoFar = parenIndex + 1;
+                x->parens[parenIndex].index = x->cp - gData->cpbegin;
+                x->parens[parenIndex].length = 0;
+                op = (REOp) *pc++;
+                continue;
+
+            case REOP_RPAREN:
+                pc = ReadCompactIndex(pc, &parenIndex);
+                JS_ASSERT(parenIndex < gData->regexp->parenCount);
+                cap = &x->parens[parenIndex];
+                cap->length = x->cp - (gData->cpbegin + cap->index);
+                op = (REOp) *pc++;
+                continue;
+
+            case REOP_ASSERT:
+                nextpc = pc + GET_OFFSET(pc);  /* start of term after ASSERT */
+                pc += ARG_LEN;                 /* start of ASSERT child */
+                op = (REOp) *pc++;
+                if (REOP_IS_SIMPLE(op) &&
+                    !SimpleMatch(gData, x, op, &pc, JS_FALSE)) {
+                    result = NULL;
+                    break;
+                }
+                curState->u.assertion.top =
+                    (char *)gData->backTrackSP - (char *)gData->backTrackStack;
+                curState->u.assertion.sz = gData->cursz;
+                curState->index = x->cp - gData->cpbegin;
+                curState->parenSoFar = parenSoFar;
+                PUSH_STATE_STACK(gData);
+                if (!PushBackTrackState(gData, REOP_ASSERTTEST,
+                                        nextpc, x, x->cp, 0, 0)) {
+                    return NULL;
+                }
+                continue;
+
+            case REOP_ASSERT_NOT:
+                nextpc = pc + GET_OFFSET(pc);
+                pc += ARG_LEN;
+                op = (REOp) *pc++;
+                if (REOP_IS_SIMPLE(op) /* Note - fail to fail! */ &&
+                    SimpleMatch(gData, x, op, &pc, JS_FALSE) &&
+                    pc == nextpc) {
+                    result = NULL;
+                    break;
+                }
+                curState->u.assertion.top
+                    = (char *)gData->backTrackSP -
+                      (char *)gData->backTrackStack;
+                curState->u.assertion.sz = gData->cursz;
+                curState->index = x->cp - gData->cpbegin;
+                curState->parenSoFar = parenSoFar;
+                PUSH_STATE_STACK(gData);
+                if (!PushBackTrackState(gData, REOP_ASSERTNOTTEST,
+                                        nextpc, x, x->cp, 0, 0))
+                    return NULL;
+                continue;
+
+            case REOP_ASSERTTEST:
+                --gData->stateStackTop;
+                --curState;
+                x->cp = gData->cpbegin + curState->index;
+                gData->backTrackSP =
+                    (REBackTrackData *) ((char *)gData->backTrackStack +
+                                         curState->u.assertion.top);
+                gData->cursz = curState->u.assertion.sz;
+                if (result)
+                    result = x;
+                break;
+
+            case REOP_ASSERTNOTTEST:
+                --gData->stateStackTop;
+                --curState;
+                x->cp = gData->cpbegin + curState->index;
+                gData->backTrackSP =
+                    (REBackTrackData *) ((char *)gData->backTrackStack +
+                                         curState->u.assertion.top);
+                gData->cursz = curState->u.assertion.sz;
+                result = (!result) ? x : NULL;
+                break;
+
+            case REOP_END:
+                if (x)
+                    return x;
+                break;
+
+            case REOP_STAR:
+                curState->u.quantifier.min = 0;
+                curState->u.quantifier.max = (uintN)-1;
+                goto quantcommon;
+            case REOP_PLUS:
+                curState->u.quantifier.min = 1;
+                curState->u.quantifier.max = (uintN)-1;
+                goto quantcommon;
+            case REOP_OPT:
+                curState->u.quantifier.min = 0;
+                curState->u.quantifier.max = 1;
+                goto quantcommon;
+            case REOP_QUANT:
+                pc = ReadCompactIndex(pc, &k);
+                curState->u.quantifier.min = k;
+                pc = ReadCompactIndex(pc, &k);
+                /* max is k - 1 to use one byte for (uintN)-1 sentinel. */
+                curState->u.quantifier.max = k - 1;
+                JS_ASSERT(curState->u.quantifier.min
+                          <= curState->u.quantifier.max);
+            quantcommon:
+                if (curState->u.quantifier.max == 0) {
+                    pc = pc + GET_OFFSET(pc);
+                    op = (REOp) *pc++;
+                    result = x;
+                    continue;
+                }
+                /* Step over <next> */
+                nextpc = pc + ARG_LEN;
+                op = (REOp) *nextpc++;
+                startcp = x->cp;
+                if (REOP_IS_SIMPLE(op)) {
+                    if (!SimpleMatch(gData, x, op, &nextpc, JS_TRUE)) {
+                        if (curState->u.quantifier.min == 0)
+                            result = x;
+                        else
+                            result = NULL;
+                        pc = pc + GET_OFFSET(pc);
+                        break;
+                    }
+                    op = (REOp) *nextpc++;
+                    result = x;
+                }
+                curState->index = startcp - gData->cpbegin;
+                curState->continue_op = REOP_REPEAT;
+                curState->continue_pc = pc;
+                curState->parenSoFar = parenSoFar;
+                PUSH_STATE_STACK(gData);
+                if (curState->u.quantifier.min == 0 &&
+                    !PushBackTrackState(gData, REOP_REPEAT, pc, x, startcp,
+                                        0, 0)) {
+                    return NULL;
+                }
+                pc = nextpc;
+                continue;
+
+            case REOP_ENDCHILD: /* marks the end of a quantifier child */
+                pc = curState[-1].continue_pc;
+                op = curState[-1].continue_op;
+                continue;
+
+            case REOP_REPEAT:
+                --curState;
+                do {
+                    --gData->stateStackTop;
+                    if (!result) {
+                        /* Failed, see if we have enough children. */
+                        if (curState->u.quantifier.min == 0)
+                            goto repeatDone;
+                        goto break_switch;
+                    }
+                    if (curState->u.quantifier.min == 0 &&
+                        x->cp == gData->cpbegin + curState->index) {
+                        /* matched an empty string, that'll get us nowhere */
+                        result = NULL;
+                        goto break_switch;
+                    }
+                    if (curState->u.quantifier.min != 0)
+                        curState->u.quantifier.min--;
+                    if (curState->u.quantifier.max != (uintN) -1)
+                        curState->u.quantifier.max--;
+                    if (curState->u.quantifier.max == 0)
+                        goto repeatDone;
+                    nextpc = pc + ARG_LEN;
+                    nextop = (REOp) *nextpc;
+                    startcp = x->cp;
+                    if (REOP_IS_SIMPLE(nextop)) {
+                        nextpc++;
+                        if (!SimpleMatch(gData, x, nextop, &nextpc, JS_TRUE)) {
+                            if (curState->u.quantifier.min == 0)
+                                goto repeatDone;
+                            result = NULL;
+                            goto break_switch;
+                        }
+                        result = x;
+                    }
+                    curState->index = startcp - gData->cpbegin;
+                    PUSH_STATE_STACK(gData);
+                    if (curState->u.quantifier.min == 0 &&
+                        !PushBackTrackState(gData, REOP_REPEAT,
+                                            pc, x, startcp,
+                                            curState->parenSoFar,
+                                            parenSoFar -
+                                            curState->parenSoFar)) {
+                        return NULL;
+                    }
+                } while (*nextpc == REOP_ENDCHILD);
+                pc = nextpc;
+                op = (REOp) *pc++;
+                parenSoFar = curState->parenSoFar;
+                continue;
+
+            repeatDone:
+                result = x;
+                pc += GET_OFFSET(pc);
+                goto break_switch;
+
+            case REOP_MINIMALSTAR:
+                curState->u.quantifier.min = 0;
+                curState->u.quantifier.max = (uintN)-1;
+                goto minimalquantcommon;
+            case REOP_MINIMALPLUS:
+                curState->u.quantifier.min = 1;
+                curState->u.quantifier.max = (uintN)-1;
+                goto minimalquantcommon;
+            case REOP_MINIMALOPT:
+                curState->u.quantifier.min = 0;
+                curState->u.quantifier.max = 1;
+                goto minimalquantcommon;
+            case REOP_MINIMALQUANT:
+                pc = ReadCompactIndex(pc, &k);
+                curState->u.quantifier.min = k;
+                pc = ReadCompactIndex(pc, &k);
+                /* See REOP_QUANT comments about k - 1. */
+                curState->u.quantifier.max = k - 1;
+                JS_ASSERT(curState->u.quantifier.min
+                          <= curState->u.quantifier.max);
+            minimalquantcommon:
+                curState->index = x->cp - gData->cpbegin;
+                curState->parenSoFar = parenSoFar;
+                PUSH_STATE_STACK(gData);
+                if (curState->u.quantifier.min != 0) {
+                    curState->continue_op = REOP_MINIMALREPEAT;
+                    curState->continue_pc = pc;
+                    /* step over <next> */
+                    pc += OFFSET_LEN;
+                    op = (REOp) *pc++;
+                } else {
+                    if (!PushBackTrackState(gData, REOP_MINIMALREPEAT,
+                                            pc, x, x->cp, 0, 0)) {
+                        return NULL;
+                    }
+                    --gData->stateStackTop;
+                    pc = pc + GET_OFFSET(pc);
+                    op = (REOp) *pc++;
+                }
+                continue;
+
+            case REOP_MINIMALREPEAT:
+                --gData->stateStackTop;
+                --curState;
+
+                if (!result) {
+                    /*
+                     * Non-greedy failure - try to consume another child.
+                     */
+                    if (curState->u.quantifier.max == (uintN) -1 ||
+                        curState->u.quantifier.max > 0) {
+                        curState->index = x->cp - gData->cpbegin;
+                        curState->continue_op = REOP_MINIMALREPEAT;
+                        curState->continue_pc = pc;
+                        pc += ARG_LEN;
+                        for (k = curState->parenSoFar; k < parenSoFar; k++)
+                            x->parens[k].index = -1;
+                        PUSH_STATE_STACK(gData);
+                        op = (REOp) *pc++;
+                        continue;
+                    }
+                    /* Don't need to adjust pc since we're going to pop. */
+                    break;
+                }
+                if (curState->u.quantifier.min == 0 &&
+                    x->cp == gData->cpbegin + curState->index) {
+                    /* Matched an empty string, that'll get us nowhere. */
+                    result = NULL;
+                    break;
+                }
+                if (curState->u.quantifier.min != 0)
+                    curState->u.quantifier.min--;
+                if (curState->u.quantifier.max != (uintN) -1)
+                    curState->u.quantifier.max--;
+                if (curState->u.quantifier.min != 0) {
+                    curState->continue_op = REOP_MINIMALREPEAT;
+                    curState->continue_pc = pc;
+                    pc += ARG_LEN;
+                    for (k = curState->parenSoFar; k < parenSoFar; k++)
+                        x->parens[k].index = -1;
+                    curState->index = x->cp - gData->cpbegin;
+                    PUSH_STATE_STACK(gData);
+                    op = (REOp) *pc++;
+                    continue;
+                }
+                curState->index = x->cp - gData->cpbegin;
+                curState->parenSoFar = parenSoFar;
+                PUSH_STATE_STACK(gData);
+                if (!PushBackTrackState(gData, REOP_MINIMALREPEAT,
+                                        pc, x, x->cp,
+                                        curState->parenSoFar,
+                                        parenSoFar - curState->parenSoFar)) {
+                    return NULL;
+                }
+                --gData->stateStackTop;
+                pc = pc + GET_OFFSET(pc);
+                op = (REOp) *pc++;
+                continue;
+
+            default:
+                JS_ASSERT(JS_FALSE);
+                result = NULL;
+            }
+        break_switch:;
+        }
+
+        /*
+         *  If the match failed and there's a backtrack option, take it.
+         *  Otherwise this is a complete and utter failure.
+         */
+        if (!result) {
+            if (gData->cursz == 0)
+                return NULL;
+            backTrackData = gData->backTrackSP;
+            gData->cursz = backTrackData->sz;
+            gData->backTrackSP =
+                (REBackTrackData *) ((char *)backTrackData - backTrackData->sz);
+            x->cp = backTrackData->cp;
+            pc = backTrackData->backtrack_pc;
+            op = backTrackData->backtrack_op;
+            gData->stateStackTop = backTrackData->saveStateStackTop;
+            JS_ASSERT(gData->stateStackTop);
+
+            memcpy(gData->stateStack, backTrackData + 1,
+                   sizeof(REProgState) * backTrackData->saveStateStackTop);
+            curState = &gData->stateStack[gData->stateStackTop - 1];
+
+            if (backTrackData->parenCount) {
+                memcpy(&x->parens[backTrackData->parenIndex],
+                       (char *)(backTrackData + 1) +
+                       sizeof(REProgState) * backTrackData->saveStateStackTop,
+                       sizeof(RECapture) * backTrackData->parenCount);
+                parenSoFar = backTrackData->parenIndex + backTrackData->parenCount;
+            } else {
+                for (k = curState->parenSoFar; k < parenSoFar; k++)
+                    x->parens[k].index = -1;
+                parenSoFar = curState->parenSoFar;
+            }
+            continue;
+        }
+        x = result;
+
+        /*
+         *  Continue with the expression.
+         */
+        op = (REOp)*pc++;
+    }
+    return NULL;
+}
+
+static REMatchState *
+MatchRegExp(REGlobalData *gData, REMatchState *x)
+{
+    REMatchState *result;
+    const jschar *cp = x->cp;
+    const jschar *cp2;
+    uintN j;
+
+    /*
+     * Have to include the position beyond the last character
+     * in order to detect end-of-input/line condition.
+     */
+    for (cp2 = cp; cp2 <= gData->cpend; cp2++) {
+        gData->skipped = cp2 - cp;
+        x->cp = cp2;
+        for (j = 0; j < gData->regexp->parenCount; j++)
+            x->parens[j].index = -1;
+        result = ExecuteREBytecode(gData, x);
+        if (!gData->ok || result)
+            return result;
+        gData->backTrackSP = gData->backTrackStack;
+        gData->cursz = 0;
+        gData->stateStackTop = 0;
+        cp2 = cp + gData->skipped;
+    }
+    return NULL;
+}
+
+
+static REMatchState *
+InitMatch(JSContext *cx, REGlobalData *gData, JSRegExp *re)
+{
+    REMatchState *result;
+    uintN i;
+
+    gData->backTrackStackSize = INITIAL_BACKTRACK;
+    JS_ARENA_ALLOCATE_CAST(gData->backTrackStack, REBackTrackData *,
+                           &gData->pool,
+                           INITIAL_BACKTRACK);
+    if (!gData->backTrackStack)
+        return NULL;
+    gData->backTrackSP = gData->backTrackStack;
+    gData->cursz = 0;
+
+
+    gData->stateStackLimit = INITIAL_STATESTACK;
+    JS_ARENA_ALLOCATE_CAST(gData->stateStack, REProgState *,
+                           &gData->pool,
+                           sizeof(REProgState) * INITIAL_STATESTACK);
+    if (!gData->stateStack)
+        return NULL;
+    gData->stateStackTop = 0;
+
+    gData->cx = cx;
+    gData->regexp = re;
+    gData->ok = JS_TRUE;
+
+    JS_ARENA_ALLOCATE_CAST(result, REMatchState *,
+                           &gData->pool,
+                           offsetof(REMatchState, parens)
+                           + re->parenCount * sizeof(RECapture));
+    if (!result)
+        return NULL;
+
+    for (i = 0; i < re->classCount; i++)
+        if (!re->classList[i].converted)
+            if (!ProcessCharSet(gData, &re->classList[i]))
+                return NULL;
+
+    return result;
+}
+
+JSBool
+js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
+                 JSBool test, jsval *rval)
+{
+    REGlobalData gData;
+    REMatchState *x, *result;
+
+    const jschar *cp, *ep;
+    size_t i, length, start;
+    JSSubString *morepar;
+    JSBool ok;
+    JSRegExpStatics *res;
+    ptrdiff_t matchlen;
+    uintN num, morenum;
+    JSString *parstr, *matchstr;
+    JSObject *obj;
+
+    RECapture *parsub = NULL;
+
+    /*
+     * It's safe to load from cp because JSStrings have a zero at the end,
+     * and we never let cp get beyond cpend.
+     */
+    start = *indexp;
+    length = JSSTRING_LENGTH(str);
+    if (start > length)
+        start = length;
+    cp = JSSTRING_CHARS(str);
+    gData.cpbegin = cp;
+    gData.cpend = cp + length;
+    cp += start;
+    gData.start = start;
+    gData.skipped = 0;
+
+    JS_InitArenaPool(&gData.pool, "RegExpPool", 8096, 4);
+    x = InitMatch(cx, &gData, re);
+    if (!x)
+        return JS_FALSE;
+    x->cp = cp;
+
+    /*
+     * Call the recursive matcher to do the real work.  Return null on mismatch
+     * whether testing or not.  On match, return an extended Array object.
+     */
+    result = MatchRegExp(&gData, x);
+    ok = gData.ok;
+    if (!ok)
+        goto out;
+    if (!result) {
+        *rval = JSVAL_NULL;
+        goto out;
+    }
+    cp = result->cp;
+    i = cp - gData.cpbegin;
+    *indexp = i;
+    matchlen = i - (start + gData.skipped);
+    ep = cp;
+    cp -= matchlen;
+
+    if (test) {
+        /*
+         * Testing for a match and updating cx->regExpStatics: don't allocate
+         * an array object, do return true.
+         */
+        *rval = JSVAL_TRUE;
+
+        /* Avoid warning.  (gcc doesn't detect that obj is needed iff !test); */
+        obj = NULL;
+    } else {
+        /*
+         * The array returned on match has element 0 bound to the matched
+         * string, elements 1 through state.parenCount bound to the paren
+         * matches, an index property telling the length of the left context,
+         * and an input property referring to the input string.
+         */
+        obj = js_NewArrayObject(cx, 0, NULL);
+        if (!obj) {
+            ok = JS_FALSE;
+            goto out;
+        }
+        *rval = OBJECT_TO_JSVAL(obj);
+
+#define DEFVAL(val, id) {                                                     \
+    ok = js_DefineProperty(cx, obj, id, val,                                  \
+                           JS_PropertyStub, JS_PropertyStub,                  \
+                           JSPROP_ENUMERATE, NULL);                           \
+    if (!ok) {                                                                \
+        cx->newborn[GCX_OBJECT] = NULL;                                       \
+        cx->newborn[GCX_STRING] = NULL;                                       \
+        goto out;                                                             \
+    }                                                                         \
+}
+
+        matchstr = js_NewStringCopyN(cx, cp, matchlen, 0);
+        if (!matchstr) {
+            cx->newborn[GCX_OBJECT] = NULL;
+            ok = JS_FALSE;
+            goto out;
+        }
+        DEFVAL(STRING_TO_JSVAL(matchstr), INT_TO_JSID(0));
+    }
+
+    res = &cx->regExpStatics;
+    res->input = str;
+    res->parenCount = re->parenCount;
+    if (re->parenCount == 0) {
+        res->lastParen = js_EmptySubString;
+    } else {
+        for (num = 0; num < re->parenCount; num++) {
+            parsub = &result->parens[num];
+            if (num < 9) {
+                if (parsub->index == -1) {
+                    res->parens[num].chars = NULL;
+                    res->parens[num].length = 0;
+                } else {
+                    res->parens[num].chars = gData.cpbegin + parsub->index;
+                    res->parens[num].length = parsub->length;
+                }
+            } else {
+                morenum = num - 9;
+                morepar = res->moreParens;
+                if (!morepar) {
+                    res->moreLength = 10;
+                    morepar = (JSSubString*)
+                        JS_malloc(cx, 10 * sizeof(JSSubString));
+                } else if (morenum >= res->moreLength) {
+                    res->moreLength += 10;
+                    morepar = (JSSubString*)
+                        JS_realloc(cx, morepar,
+                                   res->moreLength * sizeof(JSSubString));
+                }
+                if (!morepar) {
+                    cx->newborn[GCX_OBJECT] = NULL;
+                    cx->newborn[GCX_STRING] = NULL;
+                    ok = JS_FALSE;
+                    goto out;
+                }
+                res->moreParens = morepar;
+                if (parsub->index == -1) {
+                    morepar[morenum].chars = NULL;
+                    morepar[morenum].length = 0;
+                } else {
+                    morepar[morenum].chars = gData.cpbegin + parsub->index;
+                    morepar[morenum].length = parsub->length;
+                }
+            }
+            if (test)
+                continue;
+            if (parsub->index == -1) {
+                ok = js_DefineProperty(cx, obj, INT_TO_JSID(num + 1),
+                                       JSVAL_VOID, NULL, NULL,
+                                       JSPROP_ENUMERATE, NULL);
+            } else {
+                parstr = js_NewStringCopyN(cx, gData.cpbegin + parsub->index,
+                                           parsub->length, 0);
+                if (!parstr) {
+                    cx->newborn[GCX_OBJECT] = NULL;
+                    cx->newborn[GCX_STRING] = NULL;
+                    ok = JS_FALSE;
+                    goto out;
+                }
+                ok = js_DefineProperty(cx, obj, INT_TO_JSID(num + 1),
+                                       STRING_TO_JSVAL(parstr), NULL, NULL,
+                                       JSPROP_ENUMERATE, NULL);
+            }
+            if (!ok) {
+                cx->newborn[GCX_OBJECT] = NULL;
+                cx->newborn[GCX_STRING] = NULL;
+                goto out;
+            }
+        }
+        if (parsub->index == -1) {
+            res->lastParen = js_EmptySubString;
+        } else {
+            res->lastParen.chars = gData.cpbegin + parsub->index;
+            res->lastParen.length = parsub->length;
+        }
+    }
+
+    if (!test) {
+        /*
+         * Define the index and input properties last for better for/in loop
+         * order (so they come after the elements).
+         */
+        DEFVAL(INT_TO_JSVAL(start + gData.skipped),
+               ATOM_TO_JSID(cx->runtime->atomState.indexAtom));
+        DEFVAL(STRING_TO_JSVAL(str),
+               ATOM_TO_JSID(cx->runtime->atomState.inputAtom));
+    }
+
+#undef DEFVAL
+
+    res->lastMatch.chars = cp;
+    res->lastMatch.length = matchlen;
+    if (JS_VERSION_IS_1_2(cx)) {
+        /*
+         * JS1.2 emulated Perl4.0.1.8 (patch level 36) for global regexps used
+         * in scalar contexts, and unintentionally for the string.match "list"
+         * pseudo-context.  On "hi there bye", the following would result:
+         *
+         * Language     while(/ /g){print("$`");}   s/ /$`/g
+         * perl4.036    "hi", "there"               "hihitherehi therebye"
+         * perl5        "hi", "hi there"            "hihitherehi therebye"
+         * js1.2        "hi", "there"               "hihitheretherebye"
+         */
+        res->leftContext.chars = JSSTRING_CHARS(str) + start;
+        res->leftContext.length = gData.skipped;
+    } else {
+        /*
+         * For JS1.3 and ECMAv2, emulate Perl5 exactly:
+         *
+         * js1.3        "hi", "hi there"            "hihitherehi therebye"
+         */
+        res->leftContext.chars = JSSTRING_CHARS(str);
+        res->leftContext.length = start + gData.skipped;
+    }
+    res->rightContext.chars = ep;
+    res->rightContext.length = gData.cpend - ep;
+
+out:
+    JS_FinishArenaPool(&gData.pool);
+    return ok;
+}
+
+/************************************************************************/
+
+enum regexp_tinyid {
+    REGEXP_SOURCE       = -1,
+    REGEXP_GLOBAL       = -2,
+    REGEXP_IGNORE_CASE  = -3,
+    REGEXP_LAST_INDEX   = -4,
+    REGEXP_MULTILINE    = -5
+};
+
+#define REGEXP_PROP_ATTRS (JSPROP_PERMANENT|JSPROP_SHARED)
+
+static JSPropertySpec regexp_props[] = {
+    {"source",     REGEXP_SOURCE,      REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
+    {"global",     REGEXP_GLOBAL,      REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
+    {"ignoreCase", REGEXP_IGNORE_CASE, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
+    {"lastIndex",  REGEXP_LAST_INDEX,  REGEXP_PROP_ATTRS,0,0},
+    {"multiline",  REGEXP_MULTILINE,   REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0},
+    {0,0,0,0,0}
+};
+
+static JSBool
+regexp_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    jsint slot;
+    JSRegExp *re;
+
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+    slot = JSVAL_TO_INT(id);
+    if (slot == REGEXP_LAST_INDEX)
+        return JS_GetReservedSlot(cx, obj, 0, vp);
+
+    JS_LOCK_OBJ(cx, obj);
+    re = (JSRegExp *) JS_GetInstancePrivate(cx, obj, &js_RegExpClass, NULL);
+    if (re) {
+        switch (slot) {
+          case REGEXP_SOURCE:
+            *vp = STRING_TO_JSVAL(re->source);
+            break;
+          case REGEXP_GLOBAL:
+            *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_GLOB) != 0);
+            break;
+          case REGEXP_IGNORE_CASE:
+            *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_FOLD) != 0);
+            break;
+          case REGEXP_MULTILINE:
+            *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_MULTILINE) != 0);
+            break;
+        }
+    }
+    JS_UNLOCK_OBJ(cx, obj);
+    return JS_TRUE;
+}
+
+static JSBool
+regexp_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSBool ok;
+    jsint slot;
+    jsdouble lastIndex;
+
+    ok = JS_TRUE;
+    if (!JSVAL_IS_INT(id))
+        return ok;
+    slot = JSVAL_TO_INT(id);
+    if (slot == REGEXP_LAST_INDEX) {
+        if (!js_ValueToNumber(cx, *vp, &lastIndex))
+            return JS_FALSE;
+        lastIndex = js_DoubleToInteger(lastIndex);
+        ok = js_NewNumberValue(cx, lastIndex, vp) &&
+             JS_SetReservedSlot(cx, obj, 0, *vp);
+    }
+    return ok;
+}
+
+/*
+ * RegExp class static properties and their Perl counterparts:
+ *
+ *  RegExp.input                $_
+ *  RegExp.multiline            $*
+ *  RegExp.lastMatch            $&
+ *  RegExp.lastParen            $+
+ *  RegExp.leftContext          $`
+ *  RegExp.rightContext         $'
+ */
+enum regexp_static_tinyid {
+    REGEXP_STATIC_INPUT         = -1,
+    REGEXP_STATIC_MULTILINE     = -2,
+    REGEXP_STATIC_LAST_MATCH    = -3,
+    REGEXP_STATIC_LAST_PAREN    = -4,
+    REGEXP_STATIC_LEFT_CONTEXT  = -5,
+    REGEXP_STATIC_RIGHT_CONTEXT = -6
+};
+
+JSBool
+js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res)
+{
+    JS_ClearRegExpStatics(cx);
+    return js_AddRoot(cx, &res->input, "res->input");
+}
+
+void
+js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res)
+{
+    if (res->moreParens) {
+        JS_free(cx, res->moreParens);
+        res->moreParens = NULL;
+    }
+    js_RemoveRoot(cx->runtime, &res->input);
+}
+
+static JSBool
+regexp_static_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    jsint slot;
+    JSRegExpStatics *res;
+    JSString *str;
+    JSSubString *sub;
+
+    res = &cx->regExpStatics;
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+    slot = JSVAL_TO_INT(id);
+    switch (slot) {
+      case REGEXP_STATIC_INPUT:
+        *vp = res->input ? STRING_TO_JSVAL(res->input)
+                         : JS_GetEmptyStringValue(cx);
+        return JS_TRUE;
+      case REGEXP_STATIC_MULTILINE:
+        *vp = BOOLEAN_TO_JSVAL(res->multiline);
+        return JS_TRUE;
+      case REGEXP_STATIC_LAST_MATCH:
+        sub = &res->lastMatch;
+        break;
+      case REGEXP_STATIC_LAST_PAREN:
+        sub = &res->lastParen;
+        break;
+      case REGEXP_STATIC_LEFT_CONTEXT:
+        sub = &res->leftContext;
+        break;
+      case REGEXP_STATIC_RIGHT_CONTEXT:
+        sub = &res->rightContext;
+        break;
+      default:
+        sub = REGEXP_PAREN_SUBSTRING(res, slot);
+        break;
+    }
+    str = js_NewStringCopyN(cx, sub->chars, sub->length, 0);
+    if (!str)
+        return JS_FALSE;
+    *vp = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+regexp_static_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSRegExpStatics *res;
+
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+    res = &cx->regExpStatics;
+    /* XXX use if-else rather than switch to keep MSVC1.52 from crashing */
+    if (JSVAL_TO_INT(id) == REGEXP_STATIC_INPUT) {
+        if (!JSVAL_IS_STRING(*vp) &&
+            !JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp)) {
+            return JS_FALSE;
+        }
+        res->input = JSVAL_TO_STRING(*vp);
+    } else if (JSVAL_TO_INT(id) == REGEXP_STATIC_MULTILINE) {
+        if (!JSVAL_IS_BOOLEAN(*vp) &&
+            !JS_ConvertValue(cx, *vp, JSTYPE_BOOLEAN, vp)) {
+            return JS_FALSE;
+        }
+        res->multiline = JSVAL_TO_BOOLEAN(*vp);
+    }
+    return JS_TRUE;
+}
+
+static JSPropertySpec regexp_static_props[] = {
+    {"input",
+     REGEXP_STATIC_INPUT,
+     JSPROP_ENUMERATE|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_setProperty},
+    {"multiline",
+     REGEXP_STATIC_MULTILINE,
+     JSPROP_ENUMERATE|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_setProperty},
+    {"lastMatch",
+     REGEXP_STATIC_LAST_MATCH,
+     JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+    {"lastParen",
+     REGEXP_STATIC_LAST_PAREN,
+     JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+    {"leftContext",
+     REGEXP_STATIC_LEFT_CONTEXT,
+     JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+    {"rightContext",
+     REGEXP_STATIC_RIGHT_CONTEXT,
+     JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+
+    /* XXX should have block scope and local $1, etc. */
+    {"$1", 0, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+    {"$2", 1, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+    {"$3", 2, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+    {"$4", 3, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+    {"$5", 4, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+    {"$6", 5, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+    {"$7", 6, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+    {"$8", 7, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+    {"$9", 8, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED,
+     regexp_static_getProperty,    regexp_static_getProperty},
+
+    {0,0,0,0,0}
+};
+
+static void
+regexp_finalize(JSContext *cx, JSObject *obj)
+{
+    JSRegExp *re;
+
+    re = (JSRegExp *) JS_GetPrivate(cx, obj);
+    if (!re)
+        return;
+    js_DestroyRegExp(cx, re);
+}
+
+/* Forward static prototype. */
+static JSBool
+regexp_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+            jsval *rval);
+
+static JSBool
+regexp_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return regexp_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);
+}
+
+#if JS_HAS_XDR
+
+#include "jsxdrapi.h"
+
+static JSBool
+regexp_xdrObject(JSXDRState *xdr, JSObject **objp)
+{
+    JSRegExp *re;
+    JSString *source;
+    uint32 flagsword;
+    JSObject *obj;
+
+    if (xdr->mode == JSXDR_ENCODE) {
+        re = (JSRegExp *) JS_GetPrivate(xdr->cx, *objp);
+        if (!re)
+            return JS_FALSE;
+        source = re->source;
+        flagsword = ((uint32)re->cloneIndex << 16) | re->flags;
+    }
+    if (!JS_XDRString(xdr, &source) ||
+        !JS_XDRUint32(xdr, &flagsword)) {
+        return JS_FALSE;
+    }
+    if (xdr->mode == JSXDR_DECODE) {
+        obj = js_NewObject(xdr->cx, &js_RegExpClass, NULL, NULL);
+        if (!obj)
+            return JS_FALSE;
+        re = js_NewRegExp(xdr->cx, NULL, source, (uint16)flagsword, JS_FALSE);
+        if (!re)
+            return JS_FALSE;
+        if (!JS_SetPrivate(xdr->cx, obj, re) ||
+            !js_SetLastIndex(xdr->cx, obj, 0)) {
+            js_DestroyRegExp(xdr->cx, re);
+            return JS_FALSE;
+        }
+        re->cloneIndex = (uint16)(flagsword >> 16);
+        *objp = obj;
+    }
+    return JS_TRUE;
+}
+
+#else  /* !JS_HAS_XDR */
+
+#define regexp_xdrObject NULL
+
+#endif /* !JS_HAS_XDR */
+
+static uint32
+regexp_mark(JSContext *cx, JSObject *obj, void *arg)
+{
+    JSRegExp *re = (JSRegExp *) JS_GetPrivate(cx, obj);
+    if (re)
+        JS_MarkGCThing(cx, re->source, "source", arg);
+    return 0;
+}
+
+JSClass js_RegExpClass = {
+    js_RegExp_str,
+    JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1),
+    JS_PropertyStub,    JS_PropertyStub,
+    regexp_getProperty, regexp_setProperty,
+    JS_EnumerateStub,   JS_ResolveStub,
+    JS_ConvertStub,     regexp_finalize,
+    NULL,               NULL,
+    regexp_call,        NULL,
+    regexp_xdrObject,   NULL,
+    regexp_mark,        0
+};
+
+static const jschar empty_regexp_ucstr[] = {'(', '?', ':', ')', 0};
+
+JSBool
+js_regexp_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                   jsval *rval)
+{
+    JSRegExp *re;
+    const jschar *source;
+    jschar *chars;
+    size_t length, nflags;
+    uintN flags;
+    JSString *str;
+
+    if (!JS_InstanceOf(cx, obj, &js_RegExpClass, argv))
+        return JS_FALSE;
+    JS_LOCK_OBJ(cx, obj);
+    re = (JSRegExp *) JS_GetPrivate(cx, obj);
+    if (!re) {
+        JS_UNLOCK_OBJ(cx, obj);
+        *rval = STRING_TO_JSVAL(cx->runtime->emptyString);
+        return JS_TRUE;
+    }
+
+    source = JSSTRING_CHARS(re->source);
+    length = JSSTRING_LENGTH(re->source);
+    if (length == 0) {
+        source = empty_regexp_ucstr;
+        length = sizeof(empty_regexp_ucstr) / sizeof(jschar) - 1;
+    }
+    length += 2;
+    nflags = 0;
+    for (flags = re->flags; flags != 0; flags &= flags - 1)
+        nflags++;
+    chars = (jschar*) JS_malloc(cx, (length + nflags + 1) * sizeof(jschar));
+    if (!chars) {
+        JS_UNLOCK_OBJ(cx, obj);
+        return JS_FALSE;
+    }
+
+    chars[0] = '/';
+    js_strncpy(&chars[1], source, length - 2);
+    chars[length-1] = '/';
+    if (nflags) {
+        if (re->flags & JSREG_GLOB)
+            chars[length++] = 'g';
+        if (re->flags & JSREG_FOLD)
+            chars[length++] = 'i';
+        if (re->flags & JSREG_MULTILINE)
+            chars[length++] = 'm';
+    }
+    JS_UNLOCK_OBJ(cx, obj);
+    chars[length] = 0;
+
+    str = js_NewString(cx, chars, length, 0);
+    if (!str) {
+        JS_free(cx, chars);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+regexp_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    JSString *opt, *str;
+    JSRegExp *oldre, *re;
+    JSBool ok, ok2;
+    JSObject *obj2;
+    size_t length, nbytes;
+    const jschar *cp, *start, *end;
+    jschar *nstart, *ncp, *tmp;
+
+    if (!JS_InstanceOf(cx, obj, &js_RegExpClass, argv))
+        return JS_FALSE;
+    opt = NULL;
+    if (argc == 0) {
+        str = cx->runtime->emptyString;
+    } else {
+        if (JSVAL_IS_OBJECT(argv[0])) {
+            /*
+             * If we get passed in a RegExp object we construct a new
+             * RegExp that is a duplicate of it by re-compiling the
+             * original source code. ECMA requires that it be an error
+             * here if the flags are specified. (We must use the flags
+             * from the original RegExp also).
+             */
+            obj2 = JSVAL_TO_OBJECT(argv[0]);
+            if (obj2 && OBJ_GET_CLASS(cx, obj2) == &js_RegExpClass) {
+                if (argc >= 2 && !JSVAL_IS_VOID(argv[1])) { /* 'flags' passed */
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                         JSMSG_NEWREGEXP_FLAGGED);
+                    return JS_FALSE;
+                }
+                JS_LOCK_OBJ(cx, obj2);
+                re = (JSRegExp *) JS_GetPrivate(cx, obj2);
+                if (!re) {
+                    JS_UNLOCK_OBJ(cx, obj2);
+                    return JS_FALSE;
+                }
+                re = js_NewRegExp(cx, NULL, re->source, re->flags, JS_FALSE);
+                JS_UNLOCK_OBJ(cx, obj2);
+                goto created;
+            }
+        }
+        str = js_ValueToString(cx, argv[0]);
+        if (!str)
+            return JS_FALSE;
+        argv[0] = STRING_TO_JSVAL(str);
+        if (argc > 1) {
+            if (JSVAL_IS_VOID(argv[1])) {
+                opt = NULL;
+            } else {
+                opt = js_ValueToString(cx, argv[1]);
+                if (!opt)
+                    return JS_FALSE;
+                argv[1] = STRING_TO_JSVAL(opt);
+            }
+        }
+
+        /* Escape any naked slashes in the regexp source. */
+        length = JSSTRING_LENGTH(str);
+        start = JSSTRING_CHARS(str);
+        end = start + length;
+        nstart = ncp = NULL;
+        for (cp = start; cp < end; cp++) {
+            if (*cp == '/' && (cp == start || cp[-1] != '\\')) {
+                nbytes = (++length + 1) * sizeof(jschar);
+                if (!nstart) {
+                    nstart = (jschar *) JS_malloc(cx, nbytes);
+                    if (!nstart)
+                        return JS_FALSE;
+                    ncp = nstart + (cp - start);
+                    js_strncpy(nstart, start, cp - start);
+                } else {
+                    tmp = (jschar *) JS_realloc(cx, nstart, nbytes);
+                    if (!tmp) {
+                        JS_free(cx, nstart);
+                        return JS_FALSE;
+                    }
+                    ncp = tmp + (ncp - nstart);
+                    nstart = tmp;
+                }
+                *ncp++ = '\\';
+            }
+            if (nstart)
+                *ncp++ = *cp;
+        }
+
+        if (nstart) {
+            /* Don't forget to store the backstop after the new string. */
+            JS_ASSERT((size_t)(ncp - nstart) == length);
+            *ncp = 0;
+            str = js_NewString(cx, nstart, length, 0);
+            if (!str) {
+                JS_free(cx, nstart);
+                return JS_FALSE;
+            }
+            argv[0] = STRING_TO_JSVAL(str);
+        }
+    }
+
+    re = js_NewRegExpOpt(cx, NULL, str, opt, JS_FALSE);
+created:
+    if (!re)
+        return JS_FALSE;
+    JS_LOCK_OBJ(cx, obj);
+    oldre = (JSRegExp *) JS_GetPrivate(cx, obj);
+    ok = JS_SetPrivate(cx, obj, re);
+    ok2 = js_SetLastIndex(cx, obj, 0);
+    JS_UNLOCK_OBJ(cx, obj);
+    if (!ok) {
+        js_DestroyRegExp(cx, re);
+        return JS_FALSE;
+    }
+    if (oldre)
+        js_DestroyRegExp(cx, oldre);
+    *rval = OBJECT_TO_JSVAL(obj);
+    return ok2;
+}
+
+static JSBool
+regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                JSBool test, jsval *rval)
+{
+    JSBool ok;
+    JSRegExp *re;
+    jsdouble lastIndex;
+    JSString *str;
+    size_t i;
+
+    ok = JS_InstanceOf(cx, obj, &js_RegExpClass, argv);
+    if (!ok)
+        return JS_FALSE;
+    JS_LOCK_OBJ(cx, obj);
+    re = (JSRegExp *) JS_GetPrivate(cx, obj);
+    if (!re) {
+        JS_UNLOCK_OBJ(cx, obj);
+        return JS_TRUE;
+    }
+
+    /* NB: we must reach out: after this paragraph, in order to drop re. */
+    HOLD_REGEXP(cx, re);
+    if (re->flags & JSREG_GLOB) {
+        ok = js_GetLastIndex(cx, obj, &lastIndex);
+    } else {
+        lastIndex = 0;
+    }
+    JS_UNLOCK_OBJ(cx, obj);
+    if (!ok)
+        goto out;
+
+    /* Now that obj is unlocked, it's safe to (potentially) grab the GC lock. */
+    if (argc == 0) {
+        str = cx->regExpStatics.input;
+        if (!str) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_NO_INPUT,
+                                 JS_GetStringBytes(re->source),
+                                 (re->flags & JSREG_GLOB) ? "g" : "",
+                                 (re->flags & JSREG_FOLD) ? "i" : "",
+                                 (re->flags & JSREG_MULTILINE) ? "m" : "");
+            ok = JS_FALSE;
+            goto out;
+        }
+    } else {
+        str = js_ValueToString(cx, argv[0]);
+        if (!str)
+            goto out;
+        argv[0] = STRING_TO_JSVAL(str);
+    }
+
+    if (lastIndex < 0 || JSSTRING_LENGTH(str) < lastIndex) {
+        ok = js_SetLastIndex(cx, obj, 0);
+        *rval = JSVAL_NULL;
+    } else {
+        i = (size_t) lastIndex;
+        ok = js_ExecuteRegExp(cx, re, str, &i, test, rval);
+        if (ok && (re->flags & JSREG_GLOB))
+            ok = js_SetLastIndex(cx, obj, (*rval == JSVAL_NULL) ? 0 : i);
+    }
+
+out:
+    DROP_REGEXP(cx, re);
+    return ok;
+}
+
+static JSBool
+regexp_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return regexp_exec_sub(cx, obj, argc, argv, JS_FALSE, rval);
+}
+
+static JSBool
+regexp_test(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    if (!regexp_exec_sub(cx, obj, argc, argv, JS_TRUE, rval))
+        return JS_FALSE;
+    if (*rval != JSVAL_TRUE)
+        *rval = JSVAL_FALSE;
+    return JS_TRUE;
+}
+
+static JSFunctionSpec regexp_methods[] = {
+#if JS_HAS_TOSOURCE
+    {js_toSource_str,   js_regexp_toString,     0,0,0},
+#endif
+    {js_toString_str,   js_regexp_toString,     0,0,0},
+    {"compile",         regexp_compile,         1,0,0},
+    {"exec",            regexp_exec,            0,0,0},
+    {"test",            regexp_test,            0,0,0},
+    {0,0,0,0,0}
+};
+
+static JSBool
+RegExp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        /*
+         * If first arg is regexp and no flags are given, just return the arg.
+         * (regexp_compile detects the regexp + flags case and throws a
+         * TypeError.)  See 10.15.3.1.
+         */
+        if ((argc < 2 || JSVAL_IS_VOID(argv[1])) &&
+            !JSVAL_IS_PRIMITIVE(argv[0]) &&
+            OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[0])) == &js_RegExpClass) {
+            *rval = argv[0];
+            return JS_TRUE;
+        }
+
+        /* Otherwise, replace obj with a new RegExp object. */
+        obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL);
+        if (!obj)
+            return JS_FALSE;
+    }
+    return regexp_compile(cx, obj, argc, argv, rval);
+}
+
+JSObject *
+js_InitRegExpClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto, *ctor;
+    jsval rval;
+
+    proto = JS_InitClass(cx, obj, NULL, &js_RegExpClass, RegExp, 1,
+                         regexp_props, regexp_methods,
+                         regexp_static_props, NULL);
+
+    if (!proto || !(ctor = JS_GetConstructor(cx, proto)))
+        return NULL;
+    if (!JS_AliasProperty(cx, ctor, "input",        "$_") ||
+        !JS_AliasProperty(cx, ctor, "multiline",    "$*") ||
+        !JS_AliasProperty(cx, ctor, "lastMatch",    "$&") ||
+        !JS_AliasProperty(cx, ctor, "lastParen",    "$+") ||
+        !JS_AliasProperty(cx, ctor, "leftContext",  "$`") ||
+        !JS_AliasProperty(cx, ctor, "rightContext", "$'")) {
+        goto bad;
+    }
+
+    /* Give RegExp.prototype private data so it matches the empty string. */
+    if (!regexp_compile(cx, proto, 0, NULL, &rval))
+        goto bad;
+    return proto;
+
+bad:
+    JS_DeleteProperty(cx, obj, js_RegExpClass.name);
+    return NULL;
+}
+
+JSObject *
+js_NewRegExpObject(JSContext *cx, JSTokenStream *ts,
+                   jschar *chars, size_t length, uintN flags)
+{
+    JSString *str;
+    JSObject *obj;
+    JSRegExp *re;
+    JSTempValueRooter tvr;
+
+    str = js_NewStringCopyN(cx, chars, length, 0);
+    if (!str)
+        return NULL;
+    re = js_NewRegExp(cx, ts,  str, flags, JS_FALSE);
+    if (!re)
+        return NULL;
+    JS_PUSH_SINGLE_TEMP_ROOT(cx, STRING_TO_JSVAL(str), &tvr);
+    obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL);
+    if (!obj || !JS_SetPrivate(cx, obj, re)) {
+        js_DestroyRegExp(cx, re);
+        obj = NULL;
+    }
+    if (obj && !js_SetLastIndex(cx, obj, 0))
+        obj = NULL;
+    JS_POP_TEMP_ROOT(cx, &tvr);
+    return obj;
+}
+
+JSObject *
+js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent)
+{
+    JSObject *clone;
+    JSRegExp *re;
+
+    JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_RegExpClass);
+    clone = js_NewObject(cx, &js_RegExpClass, NULL, parent);
+    if (!clone)
+        return NULL;
+    re = JS_GetPrivate(cx, obj);
+    if (!JS_SetPrivate(cx, clone, re) || !js_SetLastIndex(cx, clone, 0)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+    HOLD_REGEXP(cx, re);
+    return clone;
+}
+
+JSBool
+js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex)
+{
+    jsval v;
+
+    return JS_GetReservedSlot(cx, obj, 0, &v) &&
+           js_ValueToNumber(cx, v, lastIndex);
+}
+
+JSBool
+js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex)
+{
+    jsval v;
+
+    return js_NewNumberValue(cx, lastIndex, &v) &&
+           JS_SetReservedSlot(cx, obj, 0, v);
+}
+
+#endif /* JS_HAS_REGEXPS */

Added: freeswitch/trunk/libs/js/src/jsregexp.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsregexp.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,180 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsregexp_h___
+#define jsregexp_h___
+/*
+ * JS regular expression interface.
+ */
+#include <stddef.h>
+#include "jspubtd.h"
+#include "jsstr.h"
+
+#ifdef JS_THREADSAFE
+#include "jsdhash.h"
+#endif
+
+struct JSRegExpStatics {
+    JSString    *input;         /* input string to match (perl $_, GC root) */
+    JSBool      multiline;      /* whether input contains newlines (perl $*) */
+    uint16      parenCount;     /* number of valid elements in parens[] */
+    uint16      moreLength;     /* number of allocated elements in moreParens */
+    JSSubString parens[9];      /* last set of parens matched (perl $1, $2) */
+    JSSubString *moreParens;    /* null or realloc'd vector for $10, etc. */
+    JSSubString lastMatch;      /* last string matched (perl $&) */
+    JSSubString lastParen;      /* last paren matched (perl $+) */
+    JSSubString leftContext;    /* input to left of last match (perl $`) */
+    JSSubString rightContext;   /* input to right of last match (perl $') */
+};
+
+/*
+ * This struct holds a bitmap representation of a class from a regexp.
+ * There's a list of these referenced by the classList field in the JSRegExp
+ * struct below. The initial state has startIndex set to the offset in the
+ * original regexp source of the beginning of the class contents. The first
+ * use of the class converts the source representation into a bitmap.
+ *
+ */
+typedef struct RECharSet {
+    JSPackedBool    converted;
+    JSPackedBool    sense;
+    uint16          length;
+    union {
+        uint8       *bits;
+        struct {
+            size_t  startIndex;
+            size_t  length;
+        } src;
+    } u;
+} RECharSet;
+
+/*
+ * This macro is safe because moreParens is guaranteed to be allocated and big
+ * enough to hold parenCount, or else be null when parenCount is 0.
+ */
+#define REGEXP_PAREN_SUBSTRING(res, num)                                      \
+    (((jsuint)(num) < (jsuint)(res)->parenCount)                              \
+     ? ((jsuint)(num) < 9)                                                    \
+       ? &(res)->parens[num]                                                  \
+       : &(res)->moreParens[(num) - 9]                                        \
+     : &js_EmptySubString)
+
+typedef struct RENode RENode;
+
+struct JSRegExp {
+    jsrefcount   nrefs;         /* reference count */
+    uint16       flags;         /* flags, see jsapi.h's JSREG_* defines */
+    uint16       cloneIndex;    /* index in fp->vars or funobj->slots of
+                                   cloned regexp object */
+    size_t       parenCount;    /* number of parenthesized submatches */
+    size_t       classCount;    /* count [...] bitmaps */
+    RECharSet    *classList;    /* list of [...] bitmaps */
+    JSString     *source;       /* locked source string, sans // */
+    jsbytecode   program[1];    /* regular expression bytecode */
+};
+
+extern JSRegExp *
+js_NewRegExp(JSContext *cx, JSTokenStream *ts,
+             JSString *str, uintN flags, JSBool flat);
+
+extern JSRegExp *
+js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts,
+                JSString *str, JSString *opt, JSBool flat);
+
+extern void
+js_DestroyRegExp(JSContext *cx, JSRegExp *re);
+
+/*
+ * Execute re on input str at *indexp, returning null in *rval on mismatch.
+ * On match, return true if test is true, otherwise return an array object.
+ * Update *indexp and cx->regExpStatics always on match.
+ */
+extern JSBool
+js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
+                 JSBool test, jsval *rval);
+
+/*
+ * These two add and remove GC roots, respectively, so their calls must be
+ * well-ordered.
+ */
+extern JSBool
+js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res);
+
+extern void
+js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res);
+
+#define JSVAL_IS_REGEXP(cx, v)                                                \
+    (JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) &&                              \
+     OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_RegExpClass)
+
+extern JSClass js_RegExpClass;
+
+extern JSObject *
+js_InitRegExpClass(JSContext *cx, JSObject *obj);
+
+/*
+ * Export js_regexp_toString to the decompiler.
+ */
+extern JSBool
+js_regexp_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                   jsval *rval);
+
+/*
+ * Create, serialize/deserialize, or clone a RegExp object.
+ */
+extern JSObject *
+js_NewRegExpObject(JSContext *cx, JSTokenStream *ts,
+                   jschar *chars, size_t length, uintN flags);
+
+extern JSBool
+js_XDRRegExp(JSXDRState *xdr, JSObject **objp);
+
+extern JSObject *
+js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent);
+
+/*
+ * Get and set the per-object (clone or clone-parent) lastIndex slot.
+ */
+extern JSBool
+js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex);
+
+extern JSBool
+js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex);
+
+#endif /* jsregexp_h___ */

Added: freeswitch/trunk/libs/js/src/jsscan.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsscan.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,2132 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set sw=4 ts=8 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS lexical scanner.
+ */
+#include "jsstddef.h"
+#include <stdio.h>      /* first to avoid trouble on some systems */
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsarena.h" /* Added by JSIFY */
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsdtoa.h"
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsemit.h"
+#include "jsexn.h"
+#include "jsnum.h"
+#include "jsopcode.h"
+#include "jsregexp.h"
+#include "jsscan.h"
+#include "jsscript.h"
+
+#if JS_HAS_XML_SUPPORT
+#include "jsparse.h"
+#include "jsxml.h"
+#endif
+
+#define RESERVE_JAVA_KEYWORDS
+#define RESERVE_ECMA_KEYWORDS
+
+#define MAX_KEYWORD_LENGTH      12
+
+static struct keyword {
+    const char  *name;
+    JSTokenType tokentype;      /* JSTokenType */
+    JSOp        op;             /* JSOp */
+    JSVersion   version;        /* JSVersion */
+} keywords[] = {
+    {"break",           TOK_BREAK,              JSOP_NOP,   JSVERSION_DEFAULT},
+    {"case",            TOK_CASE,               JSOP_NOP,   JSVERSION_DEFAULT},
+    {"continue",        TOK_CONTINUE,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {js_default_str,    TOK_DEFAULT,            JSOP_NOP,   JSVERSION_DEFAULT},
+    {js_delete_str,     TOK_DELETE,             JSOP_NOP,   JSVERSION_DEFAULT},
+    {"do",              TOK_DO,                 JSOP_NOP,   JSVERSION_DEFAULT},
+    {"else",            TOK_ELSE,               JSOP_NOP,   JSVERSION_DEFAULT},
+    {"export",          TOK_EXPORT,             JSOP_NOP,   JSVERSION_1_2},
+    {js_false_str,      TOK_PRIMARY,            JSOP_FALSE, JSVERSION_DEFAULT},
+    {"for",             TOK_FOR,                JSOP_NOP,   JSVERSION_DEFAULT},
+    {js_function_str,   TOK_FUNCTION,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"if",              TOK_IF,                 JSOP_NOP,   JSVERSION_DEFAULT},
+    {js_in_str,         TOK_IN,                 JSOP_IN,    JSVERSION_DEFAULT},
+    {js_new_str,        TOK_NEW,                JSOP_NEW,   JSVERSION_DEFAULT},
+    {js_null_str,       TOK_PRIMARY,            JSOP_NULL,  JSVERSION_DEFAULT},
+    {"return",          TOK_RETURN,             JSOP_NOP,   JSVERSION_DEFAULT},
+    {"switch",          TOK_SWITCH,             JSOP_NOP,   JSVERSION_DEFAULT},
+    {js_this_str,       TOK_PRIMARY,            JSOP_THIS,  JSVERSION_DEFAULT},
+    {js_true_str,       TOK_PRIMARY,            JSOP_TRUE,  JSVERSION_DEFAULT},
+    {js_typeof_str,     TOK_UNARYOP,            JSOP_TYPEOF,JSVERSION_DEFAULT},
+    {js_var_str,        TOK_VAR,                JSOP_DEFVAR,JSVERSION_DEFAULT},
+    {js_void_str,       TOK_UNARYOP,            JSOP_VOID,  JSVERSION_DEFAULT},
+    {"while",           TOK_WHILE,              JSOP_NOP,   JSVERSION_DEFAULT},
+    {"with",            TOK_WITH,               JSOP_NOP,   JSVERSION_DEFAULT},
+
+#if JS_HAS_CONST
+    {js_const_str,      TOK_VAR,                JSOP_DEFCONST,JSVERSION_DEFAULT},
+#else
+    {js_const_str,      TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+#endif
+
+#if JS_HAS_EXCEPTIONS
+    {"try",             TOK_TRY,                JSOP_NOP,   JSVERSION_DEFAULT},
+    {"catch",           TOK_CATCH,              JSOP_NOP,   JSVERSION_DEFAULT},
+    {"finally",         TOK_FINALLY,            JSOP_NOP,   JSVERSION_DEFAULT},
+    {"throw",           TOK_THROW,              JSOP_NOP,   JSVERSION_DEFAULT},
+#else
+    {"try",             TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"catch",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"finally",         TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"throw",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+#endif
+
+#if JS_HAS_INSTANCEOF
+    {js_instanceof_str, TOK_INSTANCEOF,         JSOP_INSTANCEOF,JSVERSION_1_4},
+#else
+    {js_instanceof_str, TOK_RESERVED,           JSOP_NOP,   JSVERSION_1_4},
+#endif
+
+#ifdef RESERVE_JAVA_KEYWORDS
+    {"abstract",        TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"boolean",         TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"byte",            TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"char",            TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"class",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"double",          TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"extends",         TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"final",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"float",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"goto",            TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"implements",      TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"import",          TOK_IMPORT,             JSOP_NOP,   JSVERSION_DEFAULT},
+    {"int",             TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"interface",       TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"long",            TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"native",          TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"package",         TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"private",         TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"protected",       TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"public",          TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"short",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"static",          TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"super",           TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"synchronized",    TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"throws",          TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"transient",       TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+    {"volatile",        TOK_RESERVED,           JSOP_NOP,   JSVERSION_DEFAULT},
+#endif
+
+#ifdef RESERVE_ECMA_KEYWORDS
+    {"enum",           TOK_RESERVED,            JSOP_NOP,   JSVERSION_1_3},
+#endif
+
+#if JS_HAS_DEBUGGER_KEYWORD
+    {"debugger",       TOK_DEBUGGER,            JSOP_NOP,   JSVERSION_1_3},
+#elif defined(RESERVE_ECMA_KEYWORDS)
+    {"debugger",       TOK_RESERVED,            JSOP_NOP,   JSVERSION_1_3},
+#endif
+    {0,                TOK_EOF,                 JSOP_NOP,   JSVERSION_DEFAULT}
+};
+
+JSBool
+js_InitScanner(JSContext *cx)
+{
+    struct keyword *kw;
+    size_t length;
+    JSAtom *atom;
+
+    for (kw = keywords; kw->name; kw++) {
+        length = strlen(kw->name);
+        JS_ASSERT(length <= MAX_KEYWORD_LENGTH);
+        atom = js_Atomize(cx, kw->name, length, ATOM_PINNED);
+        if (!atom)
+            return JS_FALSE;
+        ATOM_SET_KEYWORD(atom, kw);
+    }
+    return JS_TRUE;
+}
+
+JS_FRIEND_API(void)
+js_MapKeywords(void (*mapfun)(const char *))
+{
+    struct keyword *kw;
+
+    for (kw = keywords; kw->name; kw++)
+        mapfun(kw->name);
+}
+
+JSTokenStream *
+js_NewTokenStream(JSContext *cx, const jschar *base, size_t length,
+                  const char *filename, uintN lineno,
+                  JSPrincipals *principals)
+{
+    JSTokenStream *ts;
+
+    ts = js_NewBufferTokenStream(cx, base, length);
+    if (!ts)
+        return NULL;
+    ts->filename = filename;
+    ts->lineno = lineno;
+    if (principals)
+        JSPRINCIPALS_HOLD(cx, principals);
+    ts->principals = principals;
+    return ts;
+}
+
+#define TBMIN   64
+
+static JSBool
+GrowTokenBuf(JSStringBuffer *sb, size_t newlength)
+{
+    JSContext *cx;
+    jschar *base;
+    ptrdiff_t offset, length;
+    size_t tbsize;
+    JSArenaPool *pool;
+
+    cx = sb->data;
+    base = sb->base;
+    offset = PTRDIFF(sb->ptr, base, jschar);
+    pool = &cx->tempPool;
+    if (!base) {
+        tbsize = TBMIN * sizeof(jschar);
+        length = TBMIN - 1;
+        JS_ARENA_ALLOCATE_CAST(base, jschar *, pool, tbsize);
+    } else {
+        length = PTRDIFF(sb->limit, base, jschar);
+        tbsize = (length + 1) * sizeof(jschar);
+        length += length + 1;
+        JS_ARENA_GROW_CAST(base, jschar *, pool, tbsize, tbsize);
+    }
+    if (!base) {
+        JS_ReportOutOfMemory(cx);
+        sb->base = STRING_BUFFER_ERROR_BASE;
+        return JS_FALSE;
+    }
+    sb->base = base;
+    sb->limit = base + length;
+    sb->ptr = base + offset;
+    return JS_TRUE;
+}
+
+JS_FRIEND_API(JSTokenStream *)
+js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length)
+{
+    size_t nb;
+    JSTokenStream *ts;
+
+    nb = sizeof(JSTokenStream) + JS_LINE_LIMIT * sizeof(jschar);
+    JS_ARENA_ALLOCATE_CAST(ts, JSTokenStream *, &cx->tempPool, nb);
+    if (!ts) {
+        JS_ReportOutOfMemory(cx);
+        return NULL;
+    }
+    memset(ts, 0, nb);
+    ts->lineno = 1;
+    ts->linebuf.base = ts->linebuf.limit = ts->linebuf.ptr = (jschar *)(ts + 1);
+    ts->userbuf.base = (jschar *)base;
+    ts->userbuf.limit = (jschar *)base + length;
+    ts->userbuf.ptr = (jschar *)base;
+    ts->tokenbuf.grow = GrowTokenBuf;
+    ts->tokenbuf.data = cx;
+    ts->listener = cx->runtime->sourceHandler;
+    ts->listenerData = cx->runtime->sourceHandlerData;
+    return ts;
+}
+
+JS_FRIEND_API(JSTokenStream *)
+js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp)
+{
+    jschar *base;
+    JSTokenStream *ts;
+    FILE *file;
+
+    JS_ARENA_ALLOCATE_CAST(base, jschar *, &cx->tempPool,
+                           JS_LINE_LIMIT * sizeof(jschar));
+    if (!base)
+        return NULL;
+    ts = js_NewBufferTokenStream(cx, base, JS_LINE_LIMIT);
+    if (!ts)
+        return NULL;
+    if (!filename || strcmp(filename, "-") == 0) {
+        file = defaultfp;
+    } else {
+        file = fopen(filename, "r");
+        if (!file) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN,
+                                 filename, "No such file or directory");
+            return NULL;
+        }
+    }
+    ts->userbuf.ptr = ts->userbuf.limit;
+    ts->file = file;
+    ts->filename = filename;
+    return ts;
+}
+
+JS_FRIEND_API(JSBool)
+js_CloseTokenStream(JSContext *cx, JSTokenStream *ts)
+{
+    if (ts->flags & TSF_OWNFILENAME)
+        JS_free(cx, (void *) ts->filename);
+    if (ts->principals)
+        JSPRINCIPALS_DROP(cx, ts->principals);
+    return !ts->file || fclose(ts->file) == 0;
+}
+
+JS_FRIEND_API(int)
+js_fgets(char *buf, int size, FILE *file)
+{
+    int n, i, c;
+    JSBool crflag;
+
+    n = size - 1;
+    if (n < 0)
+        return -1;
+
+    crflag = JS_FALSE;
+    for (i = 0; i < n && (c = getc(file)) != EOF; i++) {
+        buf[i] = c;
+        if (c == '\n') {        /* any \n ends a line */
+            i++;                /* keep the \n; we know there is room for \0 */
+            break;
+        }
+        if (crflag) {           /* \r not followed by \n ends line at the \r */
+            ungetc(c, file);
+            break;              /* and overwrite c in buf with \0 */
+        }
+        crflag = (c == '\r');
+    }
+
+    buf[i] = '\0';
+    return i;
+}
+
+static int32
+GetChar(JSTokenStream *ts)
+{
+    int32 c;
+    ptrdiff_t i, j, len, olen;
+    JSBool crflag;
+    char cbuf[JS_LINE_LIMIT];
+    jschar *ubuf, *nl;
+
+    if (ts->ungetpos != 0) {
+        c = ts->ungetbuf[--ts->ungetpos];
+    } else {
+        do {
+            if (ts->linebuf.ptr == ts->linebuf.limit) {
+                len = PTRDIFF(ts->userbuf.limit, ts->userbuf.ptr, jschar);
+                if (len <= 0) {
+                    if (!ts->file) {
+                        ts->flags |= TSF_EOF;
+                        return EOF;
+                    }
+
+                    /* Fill ts->userbuf so that \r and \r\n convert to \n. */
+                    crflag = (ts->flags & TSF_CRFLAG) != 0;
+                    len = js_fgets(cbuf, JS_LINE_LIMIT - crflag, ts->file);
+                    if (len <= 0) {
+                        ts->flags |= TSF_EOF;
+                        return EOF;
+                    }
+                    olen = len;
+                    ubuf = ts->userbuf.base;
+                    i = 0;
+                    if (crflag) {
+                        ts->flags &= ~TSF_CRFLAG;
+                        if (cbuf[0] != '\n') {
+                            ubuf[i++] = '\n';
+                            len++;
+                            ts->linepos--;
+                        }
+                    }
+                    for (j = 0; i < len; i++, j++)
+                        ubuf[i] = (jschar) (unsigned char) cbuf[j];
+                    ts->userbuf.limit = ubuf + len;
+                    ts->userbuf.ptr = ubuf;
+                }
+                if (ts->listener) {
+                    ts->listener(ts->filename, ts->lineno, ts->userbuf.ptr, len,
+                                 &ts->listenerTSData, ts->listenerData);
+                }
+
+                nl = ts->saveEOL;
+                if (!nl) {
+                    /*
+                     * Any one of \n, \r, or \r\n ends a line (the longest
+                     * match wins).  Also allow the Unicode line and paragraph
+                     * separators.
+                     */
+                    for (nl = ts->userbuf.ptr; nl < ts->userbuf.limit; nl++) {
+                        /*
+                         * Try to prevent value-testing on most characters by
+                         * filtering out characters that aren't 000x or 202x.
+                         */
+                        if ((*nl & 0xDFD0) == 0) {
+                            if (*nl == '\n')
+                                break;
+                            if (*nl == '\r') {
+                                if (nl + 1 < ts->userbuf.limit && nl[1] == '\n')
+                                    nl++;
+                                break;
+                            }
+                            if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR)
+                                break;
+                        }
+                    }
+                }
+
+                /*
+                 * If there was a line terminator, copy thru it into linebuf.
+                 * Else copy JS_LINE_LIMIT-1 bytes into linebuf.
+                 */
+                if (nl < ts->userbuf.limit)
+                    len = PTRDIFF(nl, ts->userbuf.ptr, jschar) + 1;
+                if (len >= JS_LINE_LIMIT) {
+                    len = JS_LINE_LIMIT - 1;
+                    ts->saveEOL = nl;
+                } else {
+                    ts->saveEOL = NULL;
+                }
+                js_strncpy(ts->linebuf.base, ts->userbuf.ptr, len);
+                ts->userbuf.ptr += len;
+                olen = len;
+
+                /*
+                 * Make sure linebuf contains \n for EOL (don't do this in
+                 * userbuf because the user's string might be readonly).
+                 */
+                if (nl < ts->userbuf.limit) {
+                    if (*nl == '\r') {
+                        if (ts->linebuf.base[len-1] == '\r') {
+                            /*
+                             * Does the line segment end in \r?  We must check
+                             * for a \n at the front of the next segment before
+                             * storing a \n into linebuf.  This case matters
+                             * only when we're reading from a file.
+                             */
+                            if (nl + 1 == ts->userbuf.limit && ts->file) {
+                                len--;
+                                ts->flags |= TSF_CRFLAG; /* clear NLFLAG? */
+                                if (len == 0) {
+                                    /*
+                                     * This can happen when a segment ends in
+                                     * \r\r.  Start over.  ptr == limit in this
+                                     * case, so we'll fall into buffer-filling
+                                     * code.
+                                     */
+                                    return GetChar(ts);
+                                }
+                            } else {
+                                ts->linebuf.base[len-1] = '\n';
+                            }
+                        }
+                    } else if (*nl == '\n') {
+                        if (nl > ts->userbuf.base &&
+                            nl[-1] == '\r' &&
+                            ts->linebuf.base[len-2] == '\r') {
+                            len--;
+                            JS_ASSERT(ts->linebuf.base[len] == '\n');
+                            ts->linebuf.base[len-1] = '\n';
+                        }
+                    } else if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) {
+                        ts->linebuf.base[len-1] = '\n';
+                    }
+                }
+
+                /* Reset linebuf based on adjusted segment length. */
+                ts->linebuf.limit = ts->linebuf.base + len;
+                ts->linebuf.ptr = ts->linebuf.base;
+
+                /* Update position of linebuf within physical userbuf line. */
+                if (!(ts->flags & TSF_NLFLAG))
+                    ts->linepos += ts->linelen;
+                else
+                    ts->linepos = 0;
+                if (ts->linebuf.limit[-1] == '\n')
+                    ts->flags |= TSF_NLFLAG;
+                else
+                    ts->flags &= ~TSF_NLFLAG;
+
+                /* Update linelen from original segment length. */
+                ts->linelen = olen;
+            }
+            c = *ts->linebuf.ptr++;
+        } while (JS_ISFORMAT(c));
+    }
+    if (c == '\n')
+        ts->lineno++;
+    return c;
+}
+
+static void
+UngetChar(JSTokenStream *ts, int32 c)
+{
+    if (c == EOF)
+        return;
+    JS_ASSERT(ts->ungetpos < sizeof ts->ungetbuf / sizeof ts->ungetbuf[0]);
+    if (c == '\n')
+        ts->lineno--;
+    ts->ungetbuf[ts->ungetpos++] = (jschar)c;
+}
+
+static int32
+PeekChar(JSTokenStream *ts)
+{
+    int32 c;
+
+    c = GetChar(ts);
+    UngetChar(ts, c);
+    return c;
+}
+
+static JSBool
+PeekChars(JSTokenStream *ts, intN n, jschar *cp)
+{
+    intN i, j;
+    int32 c;
+
+    for (i = 0; i < n; i++) {
+        c = GetChar(ts);
+        if (c == EOF)
+            break;
+        cp[i] = (jschar)c;
+    }
+    for (j = i - 1; j >= 0; j--)
+        UngetChar(ts, cp[j]);
+    return i == n;
+}
+
+static void
+SkipChars(JSTokenStream *ts, intN n)
+{
+    while (--n >= 0)
+        GetChar(ts);
+}
+
+static JSBool
+MatchChar(JSTokenStream *ts, int32 expect)
+{
+    int32 c;
+
+    c = GetChar(ts);
+    if (c == expect)
+        return JS_TRUE;
+    UngetChar(ts, c);
+    return JS_FALSE;
+}
+
+static JSBool
+ReportCompileErrorNumber(JSContext *cx, void *handle, uintN flags,
+                         uintN errorNumber, JSErrorReport *report,
+                         JSBool charArgs, va_list ap)
+{
+    JSString *linestr = NULL;
+    JSTokenStream *ts = NULL;
+    JSCodeGenerator *cg = NULL;
+#if JS_HAS_XML_SUPPORT
+    JSParseNode *pn = NULL;
+#endif
+    JSErrorReporter onError;
+    JSTokenPos *tp;
+    JSStackFrame *fp;
+    uintN index;
+    char *message;
+    JSBool warning;
+
+    memset(report, 0, sizeof (struct JSErrorReport));
+    report->flags = flags;
+    report->errorNumber = errorNumber;
+    message = NULL;
+
+    if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL,
+                                 errorNumber, &message, report, &warning,
+                                 charArgs, ap)) {
+        return JS_FALSE;
+    }
+
+    js_AddRoot(cx, &linestr, "error line buffer");
+
+    switch (flags & JSREPORT_HANDLE) {
+      case JSREPORT_TS:
+        ts = handle;
+        break;
+      case JSREPORT_CG:
+        cg = handle;
+        break;
+#if JS_HAS_XML_SUPPORT
+      case JSREPORT_PN:
+        pn = handle;
+        ts = pn->pn_ts;
+        break;
+#endif
+    }
+
+    JS_ASSERT(!ts || ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT);
+    onError = cx->errorReporter;
+    if (onError) {
+        /*
+         * We are typically called with non-null ts and null cg from jsparse.c.
+         * We can be called with null ts from the regexp compilation functions.
+         * The code generator (jsemit.c) may pass null ts and non-null cg.
+         */
+        do {
+            if (ts) {
+                report->filename = ts->filename;
+#if JS_HAS_XML_SUPPORT
+                if (pn) {
+                    report->lineno = pn->pn_pos.begin.lineno;
+                    if (report->lineno != ts->lineno)
+                        break;
+                }
+#endif
+                report->lineno = ts->lineno;
+                linestr = js_NewStringCopyN(cx, ts->linebuf.base,
+                                            PTRDIFF(ts->linebuf.limit,
+                                                    ts->linebuf.base,
+                                                    jschar),
+                                            0);
+                report->linebuf = linestr
+                                 ? JS_GetStringBytes(linestr)
+                                 : NULL;
+                tp = &ts->tokens[(ts->cursor+ts->lookahead) & NTOKENS_MASK].pos;
+#if JS_HAS_XML_SUPPORT
+                if (pn)
+                    tp = &pn->pn_pos;
+#endif
+                index = (tp->begin.lineno == tp->end.lineno)
+                        ? tp->begin.index - ts->linepos
+                        : 0;
+                report->tokenptr = linestr ? report->linebuf + index : NULL;
+                report->uclinebuf = linestr ? JS_GetStringChars(linestr) : NULL;
+                report->uctokenptr = linestr ? report->uclinebuf + index : NULL;
+                break;
+            }
+
+            if (cg) {
+                report->filename = cg->filename;
+                report->lineno = CG_CURRENT_LINE(cg);
+                break;
+            }
+
+            /*
+             * If we can't find out where the error was based on the current frame,
+             * see if the next frame has a script/pc combo we can use.
+             */
+            for (fp = cx->fp; fp; fp = fp->down) {
+                if (fp->script && fp->pc) {
+                    report->filename = fp->script->filename;
+                    report->lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
+                    break;
+                }
+            }
+        } while (0);
+
+#if JS_HAS_ERROR_EXCEPTIONS
+        /*
+         * If there's a runtime exception type associated with this error
+         * number, set that as the pending exception.  For errors occuring at
+         * compile time, this is very likely to be a JSEXN_SYNTAXERR.
+         *
+         * If an exception is thrown but not caught, the JSREPORT_EXCEPTION
+         * flag will be set in report.flags.  Proper behavior for an error
+         * reporter is to ignore a report with this flag for all but top-level
+         * compilation errors.  The exception will remain pending, and so long
+         * as the non-top-level "load", "eval", or "compile" native function
+         * returns false, the top-level reporter will eventually receive the
+         * uncaught exception report.
+         *
+         * XXX it'd probably be best if there was only one call to this
+         * function, but there seem to be two error reporter call points.
+         */
+
+        /*
+         * Try to raise an exception only if there isn't one already set --
+         * otherwise the exception will describe the last compile-time error,
+         * which is likely spurious.
+         */
+        if (!ts || !(ts->flags & TSF_ERROR)) {
+            if (js_ErrorToException(cx, message, report))
+                onError = NULL;
+        }
+
+        /*
+         * Suppress any compile-time errors that don't occur at the top level.
+         * This may still fail, as interplevel may be zero in contexts where we
+         * don't really want to call the error reporter, as when js is called
+         * by other code which could catch the error.
+         */
+        if (cx->interpLevel != 0 && !JSREPORT_IS_WARNING(flags))
+            onError = NULL;
+#endif
+        if (onError) {
+            JSDebugErrorHook hook = cx->runtime->debugErrorHook;
+
+            /*
+             * If debugErrorHook is present then we give it a chance to veto
+             * sending the error on to the regular error reporter.
+             */
+            if (hook && !hook(cx, message, report,
+                              cx->runtime->debugErrorHookData)) {
+                onError = NULL;
+            }
+        }
+        if (onError)
+            (*onError)(cx, message, report);
+    }
+
+    if (message)
+        JS_free(cx, message);
+    if (report->ucmessage)
+        JS_free(cx, (void *)report->ucmessage);
+
+    js_RemoveRoot(cx->runtime, &linestr);
+
+    if (ts && !JSREPORT_IS_WARNING(flags)) {
+        /* Set the error flag to suppress spurious reports. */
+        ts->flags |= TSF_ERROR;
+    }
+
+    return warning;
+}
+
+JSBool
+js_ReportCompileErrorNumber(JSContext *cx, void *handle, uintN flags,
+                            uintN errorNumber, ...)
+{
+    va_list ap;
+    JSErrorReport report;
+    JSBool warning;
+
+    if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))
+        return JS_TRUE;
+
+    va_start(ap, errorNumber);
+    warning = ReportCompileErrorNumber(cx, handle, flags, errorNumber,
+                                       &report, JS_TRUE, ap);
+    va_end(ap);
+
+    /* 
+     * We have to do this here because js_ReportCompileErrorNumberUC doesn't
+     * need to do this.
+     */
+    if (report.messageArgs) {
+        int i = 0;
+        while (report.messageArgs[i])
+            JS_free(cx, (void *)report.messageArgs[i++]);
+        JS_free(cx, (void *)report.messageArgs);
+    }
+
+    return warning;
+}
+
+JSBool
+js_ReportCompileErrorNumberUC(JSContext *cx, void *handle, uintN flags,
+                              uintN errorNumber, ...)
+{
+    va_list ap;
+    JSErrorReport report;
+    JSBool warning;
+
+    if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx))
+        return JS_TRUE;
+ 
+    va_start(ap, errorNumber);
+    warning = ReportCompileErrorNumber(cx, handle, flags, errorNumber,
+                                       &report, JS_FALSE, ap);
+    va_end(ap);
+
+    if (report.messageArgs)
+        JS_free(cx, (void *)report.messageArgs);
+
+    return warning;
+}
+
+static JSBool
+GrowStringBuffer(JSStringBuffer *sb, size_t newlength)
+{
+    ptrdiff_t offset;
+    jschar *bp;
+
+    offset = PTRDIFF(sb->ptr, sb->base, jschar);
+    newlength += offset;
+    bp = (jschar *) realloc(sb->base, (newlength + 1) * sizeof(jschar));
+    if (!bp) {
+        free(sb->base);
+        sb->base = STRING_BUFFER_ERROR_BASE;
+        return JS_FALSE;
+    }
+    sb->base = bp;
+    sb->ptr = bp + offset;
+    sb->limit = bp + newlength;
+    return JS_TRUE;
+}
+
+static void
+FreeStringBuffer(JSStringBuffer *sb)
+{
+    JS_ASSERT(STRING_BUFFER_OK(sb));
+    if (sb->base)
+        free(sb->base);
+}
+
+void
+js_InitStringBuffer(JSStringBuffer *sb)
+{
+    sb->base = sb->limit = sb->ptr = NULL;
+    sb->data = NULL;
+    sb->grow = GrowStringBuffer;
+    sb->free = FreeStringBuffer;
+}
+
+void
+js_FinishStringBuffer(JSStringBuffer *sb)
+{
+    sb->free(sb);
+}
+
+#define ENSURE_STRING_BUFFER(sb,n) \
+    ((sb)->ptr + (n) <= (sb)->limit || sb->grow(sb, n))
+
+static void
+FastAppendChar(JSStringBuffer *sb, jschar c)
+{
+    if (!STRING_BUFFER_OK(sb))
+        return;
+    if (!ENSURE_STRING_BUFFER(sb, 1))
+        return;
+    *sb->ptr++ = c;
+}
+
+void
+js_AppendChar(JSStringBuffer *sb, jschar c)
+{
+    jschar *bp;
+
+    if (!STRING_BUFFER_OK(sb))
+        return;
+    if (!ENSURE_STRING_BUFFER(sb, 1))
+        return;
+    bp = sb->ptr;
+    *bp++ = c;
+    *bp = 0;
+    sb->ptr = bp;
+}
+
+#if JS_HAS_XML_SUPPORT
+
+void
+js_RepeatChar(JSStringBuffer *sb, jschar c, uintN count)
+{
+    jschar *bp;
+
+    if (!STRING_BUFFER_OK(sb) || count == 0)
+        return;
+    if (!ENSURE_STRING_BUFFER(sb, count))
+        return;
+    for (bp = sb->ptr; count; --count)
+        *bp++ = c;
+    *bp = 0;
+    sb->ptr = bp;
+}
+
+void
+js_AppendCString(JSStringBuffer *sb, const char *asciiz)
+{
+    size_t length;
+    jschar *bp;
+
+    if (!STRING_BUFFER_OK(sb) || *asciiz == '\0')
+        return;
+    length = strlen(asciiz);
+    if (!ENSURE_STRING_BUFFER(sb, length))
+        return;
+    for (bp = sb->ptr; length; --length)
+        *bp++ = (jschar) *asciiz++;
+    *bp = 0;
+    sb->ptr = bp;
+}
+
+void
+js_AppendJSString(JSStringBuffer *sb, JSString *str)
+{
+    size_t length;
+    jschar *bp;
+
+    if (!STRING_BUFFER_OK(sb))
+        return;
+    length = JSSTRING_LENGTH(str);
+    if (length == 0 || !ENSURE_STRING_BUFFER(sb, length))
+        return;
+    bp = sb->ptr;
+    js_strncpy(bp, JSSTRING_CHARS(str), length);
+    bp += length;
+    *bp = 0;
+    sb->ptr = bp;
+}
+
+static JSBool
+GetXMLEntity(JSContext *cx, JSTokenStream *ts)
+{
+    ptrdiff_t offset, length, i;
+    int32 c, d;
+    JSBool ispair;
+    jschar *bp, digit;
+    char *bytes;
+    JSErrNum msg;
+
+    /* Put the entity, including the '&' already scanned, in ts->tokenbuf. */
+    offset = PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar);
+    FastAppendChar(&ts->tokenbuf, '&');
+    while ((c = GetChar(ts)) != ';') {
+        if (c == EOF || c == '\n') {
+            js_ReportCompileErrorNumber(cx, ts,
+                                        JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_END_OF_XML_ENTITY);
+            return JS_FALSE;
+        }
+        FastAppendChar(&ts->tokenbuf, (jschar) c);
+    }
+
+    /* Let length be the number of jschars after the '&', including the ';'. */
+    length = PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar) - offset;
+    bp = ts->tokenbuf.base + offset;
+    c = d = 0;
+    ispair = JS_FALSE;
+    if (length > 2 && bp[1] == '#') {
+        /* Match a well-formed XML Character Reference. */
+        i = 2;
+        if (length > 3 && JS_TOLOWER(bp[i]) == 'x') {
+            if (length > 9)     /* at most 6 hex digits allowed */
+                goto badncr;
+            while (++i < length) {
+                digit = bp[i];
+                if (!JS7_ISHEX(digit))
+                    goto badncr;
+                c = (c << 4) + JS7_UNHEX(digit);
+            }
+        } else {
+            while (i < length) {
+                digit = bp[i++];
+                if (!JS7_ISDEC(digit))
+                    goto badncr;
+                c = (c * 10) + JS7_UNDEC(digit);
+                if (c < 0)
+                    goto badncr;
+            }
+        }
+
+        if (0x10000 <= c && c <= 0x10FFFF) {
+            /* Form a surrogate pair (c, d) -- c is the high surrogate. */
+            d = 0xDC00 + (c & 0x3FF);
+            c = 0xD7C0 + (c >> 10);
+            ispair = JS_TRUE;
+        } else {
+            /* Enforce the http://www.w3.org/TR/REC-xml/#wf-Legalchar WFC. */
+            if (c != 0x9 && c != 0xA && c != 0xD &&
+                !(0x20 <= c && c <= 0xD7FF) &&
+                !(0xE000 <= c && c <= 0xFFFD)) {
+                goto badncr;
+            }
+        }
+    } else {
+        /* Try to match one of the five XML 1.0 predefined entities. */
+        switch (length) {
+          case 3:
+            if (bp[2] == 't') {
+                if (bp[1] == 'l')
+                    c = '<';
+                else if (bp[1] == 'g')
+                    c = '>';
+            }
+            break;
+          case 4:
+            if (bp[1] == 'a' && bp[2] == 'm' && bp[3] == 'p')
+                c = '&';
+            break;
+          case 5:
+            if (bp[3] == 'o') {
+                if (bp[1] == 'a' && bp[2] == 'p' && bp[4] == 's')
+                    c = '\'';
+                else if (bp[1] == 'q' && bp[2] == 'u' && bp[4] == 't')
+                    c = '"';
+            }
+            break;
+        }
+        if (c == 0) {
+            msg = JSMSG_UNKNOWN_XML_ENTITY;
+            goto bad;
+        }
+    }
+
+    /* If we matched, retract ts->tokenbuf and store the entity's value. */
+    *bp++ = (jschar) c;
+    if (ispair)
+        *bp++ = (jschar) d;
+    *bp = 0;
+    ts->tokenbuf.ptr = bp;
+    return JS_TRUE;
+
+badncr:
+    msg = JSMSG_BAD_XML_NCR;
+bad:
+    /* No match: throw a TypeError per ECMA-357 10.3.2.1 step 8(a). */
+    FastAppendChar(&ts->tokenbuf, ';');
+    bytes = js_DeflateString(cx, bp + 1,
+                             PTRDIFF(ts->tokenbuf.ptr, bp, jschar) - 2);
+    if (bytes) {
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    msg, bytes);
+        JS_free(cx, bytes);
+    }
+    return JS_FALSE;
+}
+
+#endif /* JS_HAS_XML_SUPPORT */
+
+JSTokenType
+js_PeekToken(JSContext *cx, JSTokenStream *ts)
+{
+    JSTokenType tt;
+
+    if (ts->lookahead != 0) {
+        tt = ts->tokens[(ts->cursor + ts->lookahead) & NTOKENS_MASK].type;
+    } else {
+        tt = js_GetToken(cx, ts);
+        js_UngetToken(ts);
+    }
+    return tt;
+}
+
+JSTokenType
+js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts)
+{
+    JSTokenType tt;
+
+    JS_ASSERT(ts->lookahead == 0 ||
+              ON_CURRENT_LINE(ts, CURRENT_TOKEN(ts).pos) ||
+              ts->tokens[(ts->cursor + ts->lookahead) & NTOKENS_MASK].type
+                  == TOK_EOL);
+    ts->flags |= TSF_NEWLINES;
+    tt = js_PeekToken(cx, ts);
+    ts->flags &= ~TSF_NEWLINES;
+    return tt;
+}
+
+/*
+ * We have encountered a '\': check for a Unicode escape sequence after it,
+ * returning the character code value if we found a Unicode escape sequence.
+ * Otherwise, non-destructively return the original '\'.
+ */
+static int32
+GetUnicodeEscape(JSTokenStream *ts)
+{
+    jschar cp[5];
+    int32 c;
+
+    if (PeekChars(ts, 5, cp) && cp[0] == 'u' &&
+        JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) &&
+        JS7_ISHEX(cp[3]) && JS7_ISHEX(cp[4]))
+    {
+        c = (((((JS7_UNHEX(cp[1]) << 4)
+                + JS7_UNHEX(cp[2])) << 4)
+              + JS7_UNHEX(cp[3])) << 4)
+            + JS7_UNHEX(cp[4]);
+        SkipChars(ts, 5);
+        return c;
+    }
+    return '\\';
+}
+
+static JSToken *
+NewToken(JSTokenStream *ts, ptrdiff_t adjust)
+{
+    JSToken *tp;
+
+    ts->cursor = (ts->cursor + 1) & NTOKENS_MASK;
+    tp = &CURRENT_TOKEN(ts);
+    tp->ptr = ts->linebuf.ptr + adjust;
+    tp->pos.begin.index = ts->linepos +
+                          PTRDIFF(tp->ptr, ts->linebuf.base, jschar) -
+                          ts->ungetpos;
+    tp->pos.begin.lineno = tp->pos.end.lineno = (uint16)ts->lineno;
+    return tp;
+}
+
+JSTokenType
+js_GetToken(JSContext *cx, JSTokenStream *ts)
+{
+    JSTokenType tt;
+    int32 c, qc;
+    JSToken *tp;
+    JSAtom *atom;
+    JSBool hadUnicodeEscape;
+
+#define INIT_TOKENBUF()     (ts->tokenbuf.ptr = ts->tokenbuf.base)
+#define NUL_TERM_TOKENBUF() (*ts->tokenbuf.ptr = 0)
+#define TRIM_TOKENBUF(i)    (ts->tokenbuf.ptr = ts->tokenbuf.base + i)
+#define TOKENBUF_LENGTH()   PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar)
+#define TOKENBUF_BASE()     (ts->tokenbuf.base)
+#define TOKENBUF_CHAR(i)    (ts->tokenbuf.base[i])
+#define TOKENBUF_TO_ATOM()  js_AtomizeChars(cx,                               \
+                                            TOKENBUF_BASE(),                  \
+                                            TOKENBUF_LENGTH(),                \
+                                            0)
+#define ADD_TO_TOKENBUF(c)  FastAppendChar(&ts->tokenbuf, (jschar) (c))
+
+    /* If there was a fatal error, keep returning TOK_ERROR. */
+    if (ts->flags & TSF_ERROR)
+        return TOK_ERROR;
+
+    /* Check for a pushed-back token resulting from mismatching lookahead. */
+    while (ts->lookahead != 0) {
+        JS_ASSERT(!(ts->flags & TSF_XMLTEXTMODE));
+        ts->lookahead--;
+        ts->cursor = (ts->cursor + 1) & NTOKENS_MASK;
+        tt = CURRENT_TOKEN(ts).type;
+        if (tt != TOK_EOL || (ts->flags & TSF_NEWLINES))
+            return tt;
+    }
+
+#if JS_HAS_XML_SUPPORT
+    if (ts->flags & TSF_XMLTEXTMODE) {
+        tt = TOK_XMLSPACE;      /* veto if non-space, return TOK_XMLTEXT */
+        tp = NewToken(ts, 0);
+        INIT_TOKENBUF();
+        qc = (ts->flags & TSF_XMLONLYMODE) ? '<' : '{';
+
+        while ((c = GetChar(ts)) != qc && c != '<' && c != EOF) {
+            if (c == '&' && qc == '<') {
+                if (!GetXMLEntity(cx, ts))
+                    goto error;
+                tt = TOK_XMLTEXT;
+                continue;
+            }
+
+            if (!JS_ISXMLSPACE(c))
+                tt = TOK_XMLTEXT;
+            ADD_TO_TOKENBUF(c);
+        }
+        UngetChar(ts, c);
+
+        if (TOKENBUF_LENGTH() == 0) {
+            atom = NULL;
+        } else {
+            atom = TOKENBUF_TO_ATOM();
+            if (!atom)
+                goto error;
+        }
+        tp->pos.end.lineno = (uint16)ts->lineno;
+        tp->t_op = JSOP_STRING;
+        tp->t_atom = atom;
+        goto out;
+    }
+
+    if (ts->flags & TSF_XMLTAGMODE) {
+        tp = NewToken(ts, 0);
+        c = GetChar(ts);
+        if (JS_ISXMLSPACE(c)) {
+            do {
+                c = GetChar(ts);
+            } while (JS_ISXMLSPACE(c));
+            UngetChar(ts, c);
+            tt = TOK_XMLSPACE;
+            goto out;
+        }
+
+        if (c == EOF) {
+            tt = TOK_EOF;
+            goto out;
+        }
+
+        INIT_TOKENBUF();
+        if (JS_ISXMLNSSTART(c)) {
+            JSBool sawColon = JS_FALSE;
+
+            ADD_TO_TOKENBUF(c);
+            while ((c = GetChar(ts)) != EOF && JS_ISXMLNAME(c)) {
+                if (c == ':') {
+                    int nextc;
+
+                    if (sawColon ||
+                        (nextc = PeekChar(ts),
+                         ((ts->flags & TSF_XMLONLYMODE) || nextc != '{') &&
+                         !JS_ISXMLNAME(nextc))) {
+                        js_ReportCompileErrorNumber(cx, ts,
+                                                    JSREPORT_TS |
+                                                    JSREPORT_ERROR,
+                                                    JSMSG_BAD_XML_QNAME);
+                        goto error;
+                    }
+                    sawColon = JS_TRUE;
+                }
+
+                ADD_TO_TOKENBUF(c);
+            }
+
+            UngetChar(ts, c);
+            atom = TOKENBUF_TO_ATOM();
+            if (!atom)
+                goto error;
+            tp->t_op = JSOP_STRING;
+            tp->t_atom = atom;
+            tt = TOK_XMLNAME;
+            goto out;
+        }
+
+        switch (c) {
+          case '{':
+            if (ts->flags & TSF_XMLONLYMODE)
+                goto bad_xml_char;
+            tt = TOK_LC;
+            goto out;
+
+          case '=':
+            tt = TOK_ASSIGN;
+            goto out;
+
+          case '"':
+          case '\'':
+            qc = c;
+            while ((c = GetChar(ts)) != qc) {
+                if (c == EOF) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_UNTERMINATED_STRING);
+                    goto error;
+                }
+
+                /*
+                 * XML attribute values are double-quoted when pretty-printed,
+                 * so escape " if it is expressed directly in a single-quoted
+                 * attribute value.
+                 */
+                if (c == '"') {
+                    JS_ASSERT(qc == '\'');
+                    js_AppendCString(&ts->tokenbuf, js_quot_entity_str);
+                    continue;
+                }
+
+                if (c == '&' && (ts->flags & TSF_XMLONLYMODE)) {
+                    if (!GetXMLEntity(cx, ts))
+                        goto error;
+                    continue;
+                }
+
+                ADD_TO_TOKENBUF(c);
+            }
+            atom = TOKENBUF_TO_ATOM();
+            if (!atom)
+                goto error;
+            tp->pos.end.lineno = (uint16)ts->lineno;
+            tp->t_op = JSOP_STRING;
+            tp->t_atom = atom;
+            tt = TOK_XMLATTR;
+            goto out;
+
+          case '>':
+            tt = TOK_XMLTAGC;
+            goto out;
+
+          case '/':
+            if (MatchChar(ts, '>')) {
+                tt = TOK_XMLPTAGC;
+                goto out;
+            }
+            /* FALL THROUGH */
+
+          bad_xml_char:
+          default:
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_BAD_XML_CHARACTER);
+            goto error;
+        }
+        /* NOTREACHED */
+    }
+#endif /* JS_HAS_XML_SUPPORT */
+
+retry:
+    do {
+        c = GetChar(ts);
+        if (c == '\n') {
+            ts->flags &= ~TSF_DIRTYLINE;
+            if (ts->flags & TSF_NEWLINES)
+                break;
+        }
+    } while (JS_ISSPACE(c));
+
+    tp = NewToken(ts, -1);
+    if (c == EOF) {
+        tt = TOK_EOF;
+        goto out;
+    }
+
+    hadUnicodeEscape = JS_FALSE;
+    if (JS_ISIDSTART(c) ||
+        (c == '\\' &&
+         (c = GetUnicodeEscape(ts),
+          hadUnicodeEscape = JS_ISIDSTART(c)))) {
+        INIT_TOKENBUF();
+        for (;;) {
+            ADD_TO_TOKENBUF(c);
+            c = GetChar(ts);
+            if (c == '\\') {
+                c = GetUnicodeEscape(ts);
+                if (!JS_ISIDENT(c))
+                    break;
+                hadUnicodeEscape = JS_TRUE;
+            } else {
+                if (!JS_ISIDENT(c))
+                    break;
+            }
+        }
+        UngetChar(ts, c);
+
+        atom = TOKENBUF_TO_ATOM();
+        if (!atom)
+            goto error;
+        if (!hadUnicodeEscape && ATOM_KEYWORD(atom)) {
+            struct keyword *kw;
+            
+            JS_ASSERT(!(atom->flags & ATOM_HIDDEN));
+            kw = ATOM_KEYWORD(atom);
+            if (kw->tokentype == TOK_RESERVED) {
+                char buf[MAX_KEYWORD_LENGTH + 1];
+                size_t buflen = sizeof(buf) - 1;
+                if (!js_DeflateStringToBuffer(cx, TOKENBUF_BASE(), TOKENBUF_LENGTH(),
+                                                  buf, &buflen))
+                    goto error;
+                buf [buflen] = 0;
+                if (!js_ReportCompileErrorNumber(cx, ts,
+                                                 JSREPORT_TS |
+                                                 JSREPORT_WARNING |
+                                                 JSREPORT_STRICT,
+                                                 JSMSG_RESERVED_ID, buf)) {
+                    goto error;
+                }
+            } else if (JS_VERSION_IS_ECMA(cx) ||
+                       kw->version <= (cx->version & JSVERSION_MASK)) {
+                tt = kw->tokentype;
+                tp->t_op = (JSOp) kw->op;
+                goto out;
+            }
+        }
+        tp->t_op = JSOP_NAME;
+        tp->t_atom = atom;
+        tt = TOK_NAME;
+        goto out;
+    }
+
+    if (JS7_ISDEC(c) || (c == '.' && JS7_ISDEC(PeekChar(ts)))) {
+        jsint radix;
+        const jschar *endptr;
+        jsdouble dval;
+
+        radix = 10;
+        INIT_TOKENBUF();
+
+        if (c == '0') {
+            ADD_TO_TOKENBUF(c);
+            c = GetChar(ts);
+            if (JS_TOLOWER(c) == 'x') {
+                ADD_TO_TOKENBUF(c);
+                c = GetChar(ts);
+                radix = 16;
+            } else if (JS7_ISDEC(c)) {
+                radix = 8;
+            }
+        }
+
+        while (JS7_ISHEX(c)) {
+            if (radix < 16) {
+                if (JS7_ISLET(c))
+                    break;
+
+                /*
+                 * We permit 08 and 09 as decimal numbers, which makes our
+                 * behaviour a superset of the ECMA numeric grammar.  We might
+                 * not always be so permissive, so we warn about it.
+                 */
+                if (radix == 8 && c >= '8') {
+                    if (!js_ReportCompileErrorNumber(cx, ts,
+                                                     JSREPORT_TS |
+                                                     JSREPORT_WARNING,
+                                                     JSMSG_BAD_OCTAL,
+                                                     c == '8' ? "08" : "09")) {
+                        goto error;
+                    }
+                    radix = 10;
+                }
+            }
+            ADD_TO_TOKENBUF(c);
+            c = GetChar(ts);
+        }
+
+        if (radix == 10 && (c == '.' || JS_TOLOWER(c) == 'e')) {
+            if (c == '.') {
+                do {
+                    ADD_TO_TOKENBUF(c);
+                    c = GetChar(ts);
+                } while (JS7_ISDEC(c));
+            }
+            if (JS_TOLOWER(c) == 'e') {
+                ADD_TO_TOKENBUF(c);
+                c = GetChar(ts);
+                if (c == '+' || c == '-') {
+                    ADD_TO_TOKENBUF(c);
+                    c = GetChar(ts);
+                }
+                if (!JS7_ISDEC(c)) {
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_MISSING_EXPONENT);
+                    goto error;
+                }
+                do {
+                    ADD_TO_TOKENBUF(c);
+                    c = GetChar(ts);
+                } while (JS7_ISDEC(c));
+            }
+        }
+
+        /* Put back the next char and NUL-terminate tokenbuf for js_strto*. */
+        UngetChar(ts, c);
+        ADD_TO_TOKENBUF(0);
+
+        if (radix == 10) {
+            if (!js_strtod(cx, TOKENBUF_BASE(), &endptr, &dval)) {
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_OUT_OF_MEMORY);
+                goto error;
+            }
+        } else {
+            if (!js_strtointeger(cx, TOKENBUF_BASE(), &endptr, radix, &dval)) {
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_OUT_OF_MEMORY);
+                goto error;
+            }
+        }
+        tp->t_dval = dval;
+        tt = TOK_NUMBER;
+        goto out;
+    }
+
+    if (c == '"' || c == '\'') {
+        qc = c;
+        INIT_TOKENBUF();
+        while ((c = GetChar(ts)) != qc) {
+            if (c == '\n' || c == EOF) {
+                UngetChar(ts, c);
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_UNTERMINATED_STRING);
+                goto error;
+            }
+            if (c == '\\') {
+                switch (c = GetChar(ts)) {
+                  case 'b': c = '\b'; break;
+                  case 'f': c = '\f'; break;
+                  case 'n': c = '\n'; break;
+                  case 'r': c = '\r'; break;
+                  case 't': c = '\t'; break;
+                  case 'v': c = '\v'; break;
+
+                  default:
+                    if ('0' <= c && c < '8') {
+                        int32 val = JS7_UNDEC(c);
+
+                        c = PeekChar(ts);
+                        if ('0' <= c && c < '8') {
+                            val = 8 * val + JS7_UNDEC(c);
+                            GetChar(ts);
+                            c = PeekChar(ts);
+                            if ('0' <= c && c < '8') {
+                                int32 save = val;
+                                val = 8 * val + JS7_UNDEC(c);
+                                if (val <= 0377)
+                                    GetChar(ts);
+                                else
+                                    val = save;
+                            }
+                        }
+
+                        c = (jschar)val;
+                    } else if (c == 'u') {
+                        jschar cp[4];
+                        if (PeekChars(ts, 4, cp) &&
+                            JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1]) &&
+                            JS7_ISHEX(cp[2]) && JS7_ISHEX(cp[3])) {
+                            c = (((((JS7_UNHEX(cp[0]) << 4)
+                                    + JS7_UNHEX(cp[1])) << 4)
+                                  + JS7_UNHEX(cp[2])) << 4)
+                                + JS7_UNHEX(cp[3]);
+                            SkipChars(ts, 4);
+                        }
+                    } else if (c == 'x') {
+                        jschar cp[2];
+                        if (PeekChars(ts, 2, cp) &&
+                            JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1])) {
+                            c = (JS7_UNHEX(cp[0]) << 4) + JS7_UNHEX(cp[1]);
+                            SkipChars(ts, 2);
+                        }
+                    } else if (c == '\n' && JS_VERSION_IS_ECMA(cx)) {
+                        /* ECMA follows C by removing escaped newlines. */
+                        continue;
+                    }
+                    break;
+                }
+            }
+            ADD_TO_TOKENBUF(c);
+        }
+        atom = TOKENBUF_TO_ATOM();
+        if (!atom)
+            goto error;
+        tp->pos.end.lineno = (uint16)ts->lineno;
+        tp->t_op = JSOP_STRING;
+        tp->t_atom = atom;
+        tt = TOK_STRING;
+        goto out;
+    }
+
+    switch (c) {
+      case '\n': tt = TOK_EOL; goto eol_out;
+      case ';':  tt = TOK_SEMI; break;
+      case '[':  tt = TOK_LB; break;
+      case ']':  tt = TOK_RB; break;
+      case '{':  tt = TOK_LC; break;
+      case '}':  tt = TOK_RC; break;
+      case '(':  tt = TOK_LP; break;
+      case ')':  tt = TOK_RP; break;
+      case ',':  tt = TOK_COMMA; break;
+      case '?':  tt = TOK_HOOK; break;
+
+      case '.':
+#if JS_HAS_XML_SUPPORT
+        if (MatchChar(ts, c))
+            tt = TOK_DBLDOT;
+        else
+#endif
+            tt = TOK_DOT;
+        break;
+
+      case ':':
+#if JS_HAS_XML_SUPPORT
+        if (MatchChar(ts, c)) {
+            tt = TOK_DBLCOLON;
+            break;
+        }
+#endif
+        /*
+         * Default so compiler can modify to JSOP_GETTER if 'p getter: v' in an
+         * object initializer, likewise for setter.
+         */
+        tp->t_op = JSOP_NOP;
+        tt = TOK_COLON;
+        break;
+
+      case '|':
+        if (MatchChar(ts, c)) {
+            tt = TOK_OR;
+        } else if (MatchChar(ts, '=')) {
+            tp->t_op = JSOP_BITOR;
+            tt = TOK_ASSIGN;
+        } else {
+            tt = TOK_BITOR;
+        }
+        break;
+
+      case '^':
+        if (MatchChar(ts, '=')) {
+            tp->t_op = JSOP_BITXOR;
+            tt = TOK_ASSIGN;
+        } else {
+            tt = TOK_BITXOR;
+        }
+        break;
+
+      case '&':
+        if (MatchChar(ts, c)) {
+            tt = TOK_AND;
+        } else if (MatchChar(ts, '=')) {
+            tp->t_op = JSOP_BITAND;
+            tt = TOK_ASSIGN;
+        } else {
+            tt = TOK_BITAND;
+        }
+        break;
+
+      case '=':
+        if (MatchChar(ts, c)) {
+#if JS_HAS_TRIPLE_EQOPS
+            tp->t_op = MatchChar(ts, c) ? JSOP_NEW_EQ : (JSOp)cx->jsop_eq;
+#else
+            tp->t_op = cx->jsop_eq;
+#endif
+            tt = TOK_EQOP;
+        } else {
+            tp->t_op = JSOP_NOP;
+            tt = TOK_ASSIGN;
+        }
+        break;
+
+      case '!':
+        if (MatchChar(ts, '=')) {
+#if JS_HAS_TRIPLE_EQOPS
+            tp->t_op = MatchChar(ts, '=') ? JSOP_NEW_NE : (JSOp)cx->jsop_ne;
+#else
+            tp->t_op = cx->jsop_ne;
+#endif
+            tt = TOK_EQOP;
+        } else {
+            tp->t_op = JSOP_NOT;
+            tt = TOK_UNARYOP;
+        }
+        break;
+
+#if JS_HAS_XML_SUPPORT
+      case '@':
+        tt = TOK_AT;
+        break;
+#endif
+
+      case '<':
+#if JS_HAS_XML_SUPPORT
+        /*
+         * After much testing, it's clear that Postel's advice to protocol
+         * designers ("be liberal in what you accept, and conservative in what
+         * you send") invites a natural-law repercussion for JS as "protocol":
+         *
+         * "If you are liberal in what you accept, others will utterly fail to
+         *  be conservative in what they send."
+         *
+         * Which means you will get <!-- comments to end of line in the middle
+         * of .js files, and after if conditions whose then statements are on
+         * the next line, and other wonders.  See at least the following bugs:
+         * https://bugzilla.mozilla.org/show_bug.cgi?id=309242
+         * https://bugzilla.mozilla.org/show_bug.cgi?id=309712
+         * https://bugzilla.mozilla.org/show_bug.cgi?id=310993
+         *
+         * So without JSOPTION_XML, we never scan an XML comment or CDATA
+         * literal.  We always scan <! as the start of an HTML comment hack
+         * to end of line, used since Netscape 2 to hide script tag content
+         * from script-unaware browsers.
+         */
+        if ((ts->flags & TSF_OPERAND) &&
+            (JS_HAS_XML_OPTION(cx) || PeekChar(ts) != '!')) {
+            /* Check for XML comment or CDATA section. */
+            if (MatchChar(ts, '!')) {
+                INIT_TOKENBUF();
+
+                /* Scan XML comment. */
+                if (MatchChar(ts, '-')) {
+                    if (!MatchChar(ts, '-'))
+                        goto bad_xml_markup;
+                    while ((c = GetChar(ts)) != '-' || !MatchChar(ts, '-')) {
+                        if (c == EOF)
+                            goto bad_xml_markup;
+                        ADD_TO_TOKENBUF(c);
+                    }
+                    tt = TOK_XMLCOMMENT;
+                    tp->t_op = JSOP_XMLCOMMENT;
+                    goto finish_xml_markup;
+                }
+
+                /* Scan CDATA section. */
+                if (MatchChar(ts, '[')) {
+                    jschar cp[6];
+                    if (PeekChars(ts, 6, cp) &&
+                        cp[0] == 'C' &&
+                        cp[1] == 'D' &&
+                        cp[2] == 'A' &&
+                        cp[3] == 'T' &&
+                        cp[4] == 'A' &&
+                        cp[5] == '[') {
+                        SkipChars(ts, 6);
+                        while ((c = GetChar(ts)) != ']' ||
+                               !PeekChars(ts, 2, cp) ||
+                               cp[0] != ']' ||
+                               cp[1] != '>') {
+                            if (c == EOF)
+                                goto bad_xml_markup;
+                            ADD_TO_TOKENBUF(c);
+                        }
+                        GetChar(ts);            /* discard ] but not > */
+                        tt = TOK_XMLCDATA;
+                        tp->t_op = JSOP_XMLCDATA;
+                        goto finish_xml_markup;
+                    }
+                    goto bad_xml_markup;
+                }
+            }
+
+            /* Check for processing instruction. */
+            if (MatchChar(ts, '?')) {
+                JSBool inTarget = JS_TRUE;
+                size_t targetLength = 0;
+                ptrdiff_t contentIndex = -1;
+
+                INIT_TOKENBUF();
+                while ((c = GetChar(ts)) != '?' || PeekChar(ts) != '>') {
+                    if (c == EOF)
+                        goto bad_xml_markup;
+                    if (inTarget) {
+                        if (JS_ISXMLSPACE(c)) {
+                            if (TOKENBUF_LENGTH() == 0)
+                                goto bad_xml_markup;
+                            inTarget = JS_FALSE;
+                        } else {
+                            if (!((TOKENBUF_LENGTH() == 0)
+                                  ? JS_ISXMLNSSTART(c)
+                                  : JS_ISXMLNS(c))) {
+                                goto bad_xml_markup;
+                            }
+                            ++targetLength;
+                        }
+                    } else {
+                        if (contentIndex < 0 && !JS_ISXMLSPACE(c))
+                            contentIndex = TOKENBUF_LENGTH();
+                    }
+                    ADD_TO_TOKENBUF(c);
+                }
+                if (contentIndex < 0) {
+                    atom = cx->runtime->atomState.emptyAtom;
+                } else {
+                    atom = js_AtomizeChars(cx,
+                                           &TOKENBUF_CHAR(contentIndex),
+                                           TOKENBUF_LENGTH() - contentIndex,
+                                           0);
+                    if (!atom)
+                        goto error;
+                    TRIM_TOKENBUF(targetLength);
+                }
+                tp->t_atom2 = atom;
+                tt = TOK_XMLPI;
+
+        finish_xml_markup:
+                if (!MatchChar(ts, '>'))
+                    goto bad_xml_markup;
+                atom = TOKENBUF_TO_ATOM();
+                if (!atom)
+                    goto error;
+                tp->t_atom = atom;
+                tp->pos.end.lineno = (uint16)ts->lineno;
+                goto out;
+            }
+
+            /* An XML start-of-tag character. */
+            tt = MatchChar(ts, '/') ? TOK_XMLETAGO : TOK_XMLSTAGO;
+            goto out;
+
+        bad_xml_markup:
+            js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                        JSMSG_BAD_XML_MARKUP);
+            goto error;
+        }
+#endif /* JS_HAS_XML_SUPPORT */
+
+        /* NB: treat HTML begin-comment as comment-till-end-of-line */
+        if (MatchChar(ts, '!')) {
+            if (MatchChar(ts, '-')) {
+                if (MatchChar(ts, '-')) {
+                    ts->flags |= TSF_IN_HTML_COMMENT;
+                    goto skipline;
+                }
+                UngetChar(ts, '-');
+            }
+            UngetChar(ts, '!');
+        }
+        if (MatchChar(ts, c)) {
+            tp->t_op = JSOP_LSH;
+            tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP;
+        } else {
+            tp->t_op = MatchChar(ts, '=') ? JSOP_LE : JSOP_LT;
+            tt = TOK_RELOP;
+        }
+        break;
+
+      case '>':
+        if (MatchChar(ts, c)) {
+            tp->t_op = MatchChar(ts, c) ? JSOP_URSH : JSOP_RSH;
+            tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP;
+        } else {
+            tp->t_op = MatchChar(ts, '=') ? JSOP_GE : JSOP_GT;
+            tt = TOK_RELOP;
+        }
+        break;
+
+      case '*':
+        tp->t_op = JSOP_MUL;
+        tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_STAR;
+        break;
+
+      case '/':
+        if (MatchChar(ts, '/')) {
+            /*
+             * Hack for source filters such as the Mozilla XUL preprocessor:
+             * "//@line 123\n" sets the number of the *next* line after the
+             * comment to 123.
+             */
+            if (JS_HAS_ATLINE_OPTION(cx)) {
+                jschar cp[5];
+                uintN i, line, temp;
+                char filename[1024];
+
+                if (PeekChars(ts, 5, cp) &&
+                    cp[0] == '@' &&
+                    cp[1] == 'l' &&
+                    cp[2] == 'i' &&
+                    cp[3] == 'n' &&
+                    cp[4] == 'e') {
+                    SkipChars(ts, 5);
+                    while ((c = GetChar(ts)) != '\n' && JS_ISSPACE(c))
+                        continue;
+                    if (JS7_ISDEC(c)) {
+                        line = JS7_UNDEC(c);
+                        while ((c = GetChar(ts)) != EOF && JS7_ISDEC(c)) {
+                            temp = 10 * line + JS7_UNDEC(c);
+                            if (temp < line) {
+                                /* Ignore overlarge line numbers. */
+                                goto skipline;
+                            }
+                            line = temp;
+                        }
+                        while (c != '\n' && JS_ISSPACE(c))
+                            c = GetChar(ts);
+                        i = 0;
+                        if (c == '"') {
+                            while ((c = GetChar(ts)) != EOF && c != '"') {
+                                if (c == '\n') {
+                                    UngetChar(ts, c);
+                                    goto skipline;
+                                }
+                                if ((c >> 8) != 0 || i >= sizeof filename - 1)
+                                    goto skipline;
+                                filename[i++] = (char) c;
+                            }
+                            if (c == '"') {
+                                while ((c = GetChar(ts)) != '\n' &&
+                                       JS_ISSPACE(c)) {
+                                    continue;
+                                }
+                            }
+                        }
+                        filename[i] = '\0';
+                        if (c == '\n') {
+                            if (i > 0) {
+                                if (ts->flags & TSF_OWNFILENAME)
+                                    JS_free(cx, (void *) ts->filename);
+                                ts->filename = JS_strdup(cx, filename);
+                                if (!ts->filename)
+                                    goto error;
+                                ts->flags |= TSF_OWNFILENAME;
+                            }
+                            ts->lineno = line;
+                        }
+                    }
+                    UngetChar(ts, c);
+                }
+            }
+
+skipline:
+            /* Optimize line skipping if we are not in an HTML comment. */
+            if (ts->flags & TSF_IN_HTML_COMMENT) {
+                while ((c = GetChar(ts)) != EOF && c != '\n') {
+                    if (c == '-' && MatchChar(ts, '-') && MatchChar(ts, '>'))
+                        ts->flags &= ~TSF_IN_HTML_COMMENT;
+                }
+            } else {
+                while ((c = GetChar(ts)) != EOF && c != '\n')
+                    continue;
+            }
+            UngetChar(ts, c);
+            ts->cursor = (ts->cursor - 1) & NTOKENS_MASK;
+            goto retry;
+        }
+
+        if (MatchChar(ts, '*')) {
+            while ((c = GetChar(ts)) != EOF &&
+                   !(c == '*' && MatchChar(ts, '/'))) {
+                /* Ignore all characters until comment close. */
+            }
+            if (c == EOF) {
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_UNTERMINATED_COMMENT);
+                goto error;
+            }
+            ts->cursor = (ts->cursor - 1) & NTOKENS_MASK;
+            goto retry;
+        }
+
+#if JS_HAS_REGEXPS
+        if (ts->flags & TSF_OPERAND) {
+            JSObject *obj;
+            uintN flags;
+            JSBool inCharClass = JS_FALSE;
+
+            INIT_TOKENBUF();
+            for (;;) {
+                c = GetChar(ts);
+                if (c == '\n' || c == EOF) {
+                    UngetChar(ts, c);
+                    js_ReportCompileErrorNumber(cx, ts,
+                                                JSREPORT_TS | JSREPORT_ERROR,
+                                                JSMSG_UNTERMINATED_REGEXP);
+                    goto error;
+                }
+                if (c == '\\') {
+                    ADD_TO_TOKENBUF(c);
+                    c = GetChar(ts);
+                } else if (c == '[') {
+                    inCharClass = JS_TRUE;
+                } else if (c == ']') {
+                    inCharClass = JS_FALSE;
+                } else if (c == '/' && !inCharClass) {
+                    /* For compat with IE, allow unescaped / in char classes. */
+                    break;
+                }
+                ADD_TO_TOKENBUF(c);
+            }
+            for (flags = 0; ; ) {
+                if (MatchChar(ts, 'g'))
+                    flags |= JSREG_GLOB;
+                else if (MatchChar(ts, 'i'))
+                    flags |= JSREG_FOLD;
+                else if (MatchChar(ts, 'm'))
+                    flags |= JSREG_MULTILINE;
+                else
+                    break;
+            }
+            c = PeekChar(ts);
+            if (JS7_ISLET(c)) {
+                tp->ptr = ts->linebuf.ptr - 1;
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_BAD_REGEXP_FLAG);
+                (void) GetChar(ts);
+                goto error;
+            }
+            /* XXXbe fix jsregexp.c so it doesn't depend on NUL termination */
+            NUL_TERM_TOKENBUF();
+            obj = js_NewRegExpObject(cx, ts,
+                                     TOKENBUF_BASE(),
+                                     TOKENBUF_LENGTH(),
+                                     flags);
+            if (!obj)
+                goto error;
+            atom = js_AtomizeObject(cx, obj, 0);
+            if (!atom)
+                goto error;
+
+            /*
+             * If the regexp's script is one-shot, we can avoid the extra
+             * fork-on-exec costs of JSOP_REGEXP by selecting JSOP_OBJECT.
+             * Otherwise, to avoid incorrect proto, parent, and lastIndex
+             * sharing among threads and sequentially across re-execution,
+             * select JSOP_REGEXP.
+             */
+            tp->t_op = (cx->fp->flags & (JSFRAME_EVAL | JSFRAME_COMPILE_N_GO))
+                       ? JSOP_OBJECT
+                       : JSOP_REGEXP;
+            tp->t_atom = atom;
+            tt = TOK_OBJECT;
+            break;
+        }
+#endif /* JS_HAS_REGEXPS */
+
+        tp->t_op = JSOP_DIV;
+        tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP;
+        break;
+
+      case '%':
+        tp->t_op = JSOP_MOD;
+        tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP;
+        break;
+
+      case '~':
+        tp->t_op = JSOP_BITNOT;
+        tt = TOK_UNARYOP;
+        break;
+
+      case '+':
+        if (MatchChar(ts, '=')) {
+            tp->t_op = JSOP_ADD;
+            tt = TOK_ASSIGN;
+        } else if (MatchChar(ts, c)) {
+            tt = TOK_INC;
+        } else {
+            tp->t_op = JSOP_POS;
+            tt = TOK_PLUS;
+        }
+        break;
+
+      case '-':
+        if (MatchChar(ts, '=')) {
+            tp->t_op = JSOP_SUB;
+            tt = TOK_ASSIGN;
+        } else if (MatchChar(ts, c)) {
+            if (PeekChar(ts) == '>' && !(ts->flags & TSF_DIRTYLINE)) {
+                ts->flags &= ~TSF_IN_HTML_COMMENT;
+                goto skipline;
+            }
+            tt = TOK_DEC;
+        } else {
+            tp->t_op = JSOP_NEG;
+            tt = TOK_MINUS;
+        }
+        break;
+
+#if JS_HAS_SHARP_VARS
+      case '#':
+      {
+        uint32 n;
+
+        c = GetChar(ts);
+        if (!JS7_ISDEC(c)) {
+            UngetChar(ts, c);
+            goto badchar;
+        }
+        n = (uint32)JS7_UNDEC(c);
+        for (;;) {
+            c = GetChar(ts);
+            if (!JS7_ISDEC(c))
+                break;
+            n = 10 * n + JS7_UNDEC(c);
+            if (n >= ATOM_INDEX_LIMIT) {
+                js_ReportCompileErrorNumber(cx, ts,
+                                            JSREPORT_TS | JSREPORT_ERROR,
+                                            JSMSG_SHARPVAR_TOO_BIG);
+                goto error;
+            }
+        }
+        tp->t_dval = (jsdouble) n;
+        if (JS_HAS_STRICT_OPTION(cx) &&
+            (c == '=' || c == '#')) {
+            char buf[20];
+            JS_snprintf(buf, sizeof buf, "#%u%c", n, c);
+            if (!js_ReportCompileErrorNumber(cx, ts,
+                                             JSREPORT_TS |
+                                             JSREPORT_WARNING |
+                                             JSREPORT_STRICT,
+                                             JSMSG_DEPRECATED_USAGE,
+                                             buf)) {
+                goto error;
+            }
+        }
+        if (c == '=')
+            tt = TOK_DEFSHARP;
+        else if (c == '#')
+            tt = TOK_USESHARP;
+        else
+            goto badchar;
+        break;
+      }
+#endif /* JS_HAS_SHARP_VARS */
+
+#if JS_HAS_SHARP_VARS || JS_HAS_XML_SUPPORT
+      badchar:
+#endif
+
+      default:
+        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
+                                    JSMSG_ILLEGAL_CHARACTER);
+        goto error;
+    }
+
+out:
+    JS_ASSERT(tt != TOK_EOL);
+    ts->flags |= TSF_DIRTYLINE;
+
+eol_out:
+    if (!STRING_BUFFER_OK(&ts->tokenbuf))
+        tt = TOK_ERROR;
+    JS_ASSERT(tt < TOK_LIMIT);
+    tp->pos.end.index = ts->linepos +
+                        PTRDIFF(ts->linebuf.ptr, ts->linebuf.base, jschar) -
+                        ts->ungetpos;
+    tp->type = tt;
+    return tt;
+
+error:
+    tt = TOK_ERROR;
+    ts->flags |= TSF_ERROR;
+    goto out;
+
+#undef INIT_TOKENBUF
+#undef TRIM_TOKENBUF
+#undef TOKENBUF_LENGTH
+#undef TOKENBUF_BASE
+#undef TOKENBUF_CHAR
+#undef TOKENBUF_TO_ATOM
+#undef ADD_TO_TOKENBUF
+}
+
+void
+js_UngetToken(JSTokenStream *ts)
+{
+    JS_ASSERT(ts->lookahead < NTOKENS_MASK);
+    if (ts->flags & TSF_ERROR)
+        return;
+    ts->lookahead++;
+    ts->cursor = (ts->cursor - 1) & NTOKENS_MASK;
+}
+
+JSBool
+js_MatchToken(JSContext *cx, JSTokenStream *ts, JSTokenType tt)
+{
+    if (js_GetToken(cx, ts) == tt)
+        return JS_TRUE;
+    js_UngetToken(ts);
+    return JS_FALSE;
+}

Added: freeswitch/trunk/libs/js/src/jsscan.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsscan.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,363 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsscan_h___
+#define jsscan_h___
+/*
+ * JS lexical scanner interface.
+ */
+#include <stddef.h>
+#include <stdio.h>
+#include "jsopcode.h"
+#include "jsprvtd.h"
+#include "jspubtd.h"
+
+JS_BEGIN_EXTERN_C
+
+typedef enum JSTokenType {
+    TOK_ERROR = -1,                     /* well-known as the only code < EOF */
+    TOK_EOF = 0,                        /* end of file */
+    TOK_EOL = 1,                        /* end of line */
+    TOK_SEMI = 2,                       /* semicolon */
+    TOK_COMMA = 3,                      /* comma operator */
+    TOK_ASSIGN = 4,                     /* assignment ops (= += -= etc.) */
+    TOK_HOOK = 5, TOK_COLON = 6,        /* conditional (?:) */
+    TOK_OR = 7,                         /* logical or (||) */
+    TOK_AND = 8,                        /* logical and (&&) */
+    TOK_BITOR = 9,                      /* bitwise-or (|) */
+    TOK_BITXOR = 10,                    /* bitwise-xor (^) */
+    TOK_BITAND = 11,                    /* bitwise-and (&) */
+    TOK_EQOP = 12,                      /* equality ops (== !=) */
+    TOK_RELOP = 13,                     /* relational ops (< <= > >=) */
+    TOK_SHOP = 14,                      /* shift ops (<< >> >>>) */
+    TOK_PLUS = 15,                      /* plus */
+    TOK_MINUS = 16,                     /* minus */
+    TOK_STAR = 17, TOK_DIVOP = 18,      /* multiply/divide ops (* / %) */
+    TOK_UNARYOP = 19,                   /* unary prefix operator */
+    TOK_INC = 20, TOK_DEC = 21,         /* increment/decrement (++ --) */
+    TOK_DOT = 22,                       /* member operator (.) */
+    TOK_LB = 23, TOK_RB = 24,           /* left and right brackets */
+    TOK_LC = 25, TOK_RC = 26,           /* left and right curlies (braces) */
+    TOK_LP = 27, TOK_RP = 28,           /* left and right parentheses */
+    TOK_NAME = 29,                      /* identifier */
+    TOK_NUMBER = 30,                    /* numeric constant */
+    TOK_STRING = 31,                    /* string constant */
+    TOK_OBJECT = 32,                    /* RegExp or other object constant */
+    TOK_PRIMARY = 33,                   /* true, false, null, this, super */
+    TOK_FUNCTION = 34,                  /* function keyword */
+    TOK_EXPORT = 35,                    /* export keyword */
+    TOK_IMPORT = 36,                    /* import keyword */
+    TOK_IF = 37,                        /* if keyword */
+    TOK_ELSE = 38,                      /* else keyword */
+    TOK_SWITCH = 39,                    /* switch keyword */
+    TOK_CASE = 40,                      /* case keyword */
+    TOK_DEFAULT = 41,                   /* default keyword */
+    TOK_WHILE = 42,                     /* while keyword */
+    TOK_DO = 43,                        /* do keyword */
+    TOK_FOR = 44,                       /* for keyword */
+    TOK_BREAK = 45,                     /* break keyword */
+    TOK_CONTINUE = 46,                  /* continue keyword */
+    TOK_IN = 47,                        /* in keyword */
+    TOK_VAR = 48,                       /* var keyword */
+    TOK_WITH = 49,                      /* with keyword */
+    TOK_RETURN = 50,                    /* return keyword */
+    TOK_NEW = 51,                       /* new keyword */
+    TOK_DELETE = 52,                    /* delete keyword */
+    TOK_DEFSHARP = 53,                  /* #n= for object/array initializers */
+    TOK_USESHARP = 54,                  /* #n# for object/array initializers */
+    TOK_TRY = 55,                       /* try keyword */
+    TOK_CATCH = 56,                     /* catch keyword */
+    TOK_FINALLY = 57,                   /* finally keyword */
+    TOK_THROW = 58,                     /* throw keyword */
+    TOK_INSTANCEOF = 59,                /* instanceof keyword */
+    TOK_DEBUGGER = 60,                  /* debugger keyword */
+    TOK_XMLSTAGO = 61,                  /* XML start tag open (<) */
+    TOK_XMLETAGO = 62,                  /* XML end tag open (</) */
+    TOK_XMLPTAGC = 63,                  /* XML point tag close (/>) */
+    TOK_XMLTAGC = 64,                   /* XML start or end tag close (>) */
+    TOK_XMLNAME = 65,                   /* XML start-tag non-final fragment */
+    TOK_XMLATTR = 66,                   /* XML quoted attribute value */
+    TOK_XMLSPACE = 67,                  /* XML whitespace */
+    TOK_XMLTEXT = 68,                   /* XML text */
+    TOK_XMLCOMMENT = 69,                /* XML comment */
+    TOK_XMLCDATA = 70,                  /* XML CDATA section */
+    TOK_XMLPI = 71,                     /* XML processing instruction */
+    TOK_AT = 72,                        /* XML attribute op (@) */
+    TOK_DBLCOLON = 73,                  /* namespace qualified name op (::) */
+    TOK_ANYNAME = 74,                   /* XML AnyName singleton (*) */
+    TOK_DBLDOT = 75,                    /* XML descendant op (..) */
+    TOK_FILTER = 76,                    /* XML filtering predicate op (.()) */
+    TOK_XMLELEM = 77,                   /* XML element node type (no token) */
+    TOK_XMLLIST = 78,                   /* XML list node type (no token) */
+    TOK_RESERVED,                       /* reserved keywords */
+    TOK_LIMIT                           /* domain size */
+} JSTokenType;
+
+#define IS_PRIMARY_TOKEN(tt) \
+    ((uintN)((tt) - TOK_NAME) <= (uintN)(TOK_PRIMARY - TOK_NAME))
+
+#define TOKEN_TYPE_IS_XML(tt) \
+    (tt == TOK_AT || tt == TOK_DBLCOLON || tt == TOK_ANYNAME)
+
+struct JSStringBuffer {
+    jschar      *base;
+    jschar      *limit;         /* length limit for quick bounds check */
+    jschar      *ptr;           /* slot for next non-NUL char to store */
+    void        *data;
+    JSBool      (*grow)(JSStringBuffer *sb, size_t newlength);
+    void        (*free)(JSStringBuffer *sb);
+};
+
+#define STRING_BUFFER_ERROR_BASE        ((jschar *) 1)
+#define STRING_BUFFER_OK(sb)            ((sb)->base != STRING_BUFFER_ERROR_BASE)
+#define STRING_BUFFER_OFFSET(sb)        ((sb)->ptr -(sb)->base)
+
+extern void
+js_InitStringBuffer(JSStringBuffer *sb);
+
+extern void
+js_FinishStringBuffer(JSStringBuffer *sb);
+
+extern void
+js_AppendChar(JSStringBuffer *sb, jschar c);
+
+extern void
+js_RepeatChar(JSStringBuffer *sb, jschar c, uintN count);
+
+extern void
+js_AppendCString(JSStringBuffer *sb, const char *asciiz);
+
+extern void
+js_AppendJSString(JSStringBuffer *sb, JSString *str);
+
+struct JSTokenPtr {
+    uint16              index;          /* index of char in physical line */
+    uint16              lineno;         /* physical line number */
+};
+
+struct JSTokenPos {
+    JSTokenPtr          begin;          /* first character and line of token */
+    JSTokenPtr          end;            /* index 1 past last char, last line */
+};
+
+struct JSToken {
+    JSTokenType         type;           /* char value or above enumerator */
+    JSTokenPos          pos;            /* token position in file */
+    jschar              *ptr;           /* beginning of token in line buffer */
+    union {
+        struct {                        /* non-numeric literal */
+            JSOp        op;             /* operator, for minimal parser */
+            JSAtom      *atom;          /* atom table entry */
+        } s;
+        struct {                        /* atom pair, for XML PIs */
+            JSAtom      *atom2;         /* auxiliary atom table entry */
+            JSAtom      *atom;          /* main atom table entry */
+        } p;
+        jsdouble        dval;           /* floating point number */
+    } u;
+};
+
+#define t_op            u.s.op
+#define t_atom          u.s.atom
+#define t_atom2         u.p.atom2
+#define t_dval          u.dval
+
+typedef struct JSTokenBuf {
+    jschar              *base;          /* base of line or stream buffer */
+    jschar              *limit;         /* limit for quick bounds check */
+    jschar              *ptr;           /* next char to get, or slot to use */
+} JSTokenBuf;
+
+#define JS_LINE_LIMIT   256             /* logical line buffer size limit --
+                                           physical line length is unlimited */
+#define NTOKENS         4               /* 1 current + 2 lookahead, rounded */
+#define NTOKENS_MASK    (NTOKENS-1)     /* to power of 2 to avoid divmod by 3 */
+
+struct JSTokenStream {
+    JSToken             tokens[NTOKENS];/* circular token buffer */
+    uintN               cursor;         /* index of last parsed token */
+    uintN               lookahead;      /* count of lookahead tokens */
+    uintN               lineno;         /* current line number */
+    uintN               ungetpos;       /* next free char slot in ungetbuf */
+    jschar              ungetbuf[6];    /* at most 6, for \uXXXX lookahead */
+    uintN               flags;          /* flags -- see below */
+    ptrdiff_t           linelen;        /* physical linebuf segment length */
+    ptrdiff_t           linepos;        /* linebuf offset in physical line */
+    JSTokenBuf          linebuf;        /* line buffer for diagnostics */
+    JSTokenBuf          userbuf;        /* user input buffer if !file */
+    JSStringBuffer      tokenbuf;       /* current token string buffer */
+    const char          *filename;      /* input filename or null */
+    FILE                *file;          /* stdio stream if reading from file */
+    JSPrincipals        *principals;    /* principals associated with source */
+    JSSourceHandler     listener;       /* callback for source; eg debugger */
+    void                *listenerData;  /* listener 'this' data */
+    void                *listenerTSData;/* listener data for this TokenStream */
+    jschar              *saveEOL;       /* save next end of line in userbuf, to
+                                           optimize for very long lines */
+};
+
+#define CURRENT_TOKEN(ts)       ((ts)->tokens[(ts)->cursor])
+#define ON_CURRENT_LINE(ts,pos) ((uint16)(ts)->lineno == (pos).end.lineno)
+
+/* JSTokenStream flags */
+#define TSF_ERROR       0x01            /* fatal error while compiling */
+#define TSF_EOF         0x02            /* hit end of file */
+#define TSF_NEWLINES    0x04            /* tokenize newlines */
+#define TSF_OPERAND     0x08            /* looking for operand, not operator */
+#define TSF_NLFLAG      0x20            /* last linebuf ended with \n */
+#define TSF_CRFLAG      0x40            /* linebuf would have ended with \r */
+#define TSF_DIRTYLINE   0x80            /* non-whitespace since start of line */
+#define TSF_OWNFILENAME 0x100           /* ts->filename is malloc'd */
+#define TSF_XMLTAGMODE  0x200           /* scanning within an XML tag in E4X */
+#define TSF_XMLTEXTMODE 0x400           /* scanning XMLText terminal from E4X */
+#define TSF_XMLONLYMODE 0x800           /* don't scan {expr} within text/tag */
+
+/* Flag indicating unexpected end of input, i.e. TOK_EOF not at top-level. */
+#define TSF_UNEXPECTED_EOF 0x1000
+
+/*
+ * To handle the hard case of contiguous HTML comments, we want to clear the
+ * TSF_DIRTYINPUT flag at the end of each such comment.  But we'd rather not
+ * scan for --> within every //-style comment unless we have to.  So we set
+ * TSF_IN_HTML_COMMENT when a <!-- is scanned as an HTML begin-comment, and
+ * clear it (and TSF_DIRTYINPUT) when we scan --> either on a clean line, or
+ * only if (ts->flags & TSF_IN_HTML_COMMENT), in a //-style comment.
+ *
+ * This still works as before given a malformed comment hiding hack such as:
+ *
+ *    <script>
+ *      <!-- comment hiding hack #1
+ *      code goes here
+ *      // --> oops, markup for script-unaware browsers goes here!
+ *    </script>
+ *
+ * It does not cope with malformed comment hiding hacks where --> is hidden
+ * by C-style comments, or on a dirty line.  Such cases are already broken.
+ */
+#define TSF_IN_HTML_COMMENT 0x2000
+
+/* Unicode separators that are treated as line terminators, in addition to \n, \r */
+#define LINE_SEPARATOR  0x2028
+#define PARA_SEPARATOR  0x2029
+
+/*
+ * Create a new token stream, either from an input buffer or from a file.
+ * Return null on file-open or memory-allocation failure.
+ *
+ * NB: All of js_New{,Buffer,File}TokenStream() return a pointer to transient
+ * memory in the current context's temp pool.  This memory is deallocated via
+ * JS_ARENA_RELEASE() after parsing is finished.
+ */
+extern JSTokenStream *
+js_NewTokenStream(JSContext *cx, const jschar *base, size_t length,
+                  const char *filename, uintN lineno, JSPrincipals *principals);
+
+extern JS_FRIEND_API(JSTokenStream *)
+js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length);
+
+extern JS_FRIEND_API(JSTokenStream *)
+js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp);
+
+extern JS_FRIEND_API(JSBool)
+js_CloseTokenStream(JSContext *cx, JSTokenStream *ts);
+
+extern JS_FRIEND_API(int)
+js_fgets(char *buf, int size, FILE *file);
+
+/*
+ * Initialize the scanner, installing JS keywords into cx's global scope.
+ */
+extern JSBool
+js_InitScanner(JSContext *cx);
+
+/*
+ * Friend-exported API entry point to call a mapping function on each reserved
+ * identifier in the scanner's keyword table.
+ */
+extern JS_FRIEND_API(void)
+js_MapKeywords(void (*mapfun)(const char *));
+
+/*
+ * Report a compile-time error by its number, using ts or cg to show context.
+ * Return true for a warning, false for an error.
+ */
+extern JSBool
+js_ReportCompileErrorNumber(JSContext *cx, void *handle, uintN flags,
+                            uintN errorNumber, ...);
+
+extern JSBool
+js_ReportCompileErrorNumberUC(JSContext *cx, void *handle, uintN flags,
+                              uintN errorNumber, ...);
+
+/* Steal some JSREPORT_* bits (see jsapi.h) to tell handle's type. */
+#define JSREPORT_HANDLE 0x300
+#define JSREPORT_TS     0x000
+#define JSREPORT_CG     0x100
+#define JSREPORT_PN     0x200
+
+/*
+ * Look ahead one token and return its type.
+ */
+extern JSTokenType
+js_PeekToken(JSContext *cx, JSTokenStream *ts);
+
+extern JSTokenType
+js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts);
+
+/*
+ * Get the next token from ts.
+ */
+extern JSTokenType
+js_GetToken(JSContext *cx, JSTokenStream *ts);
+
+/*
+ * Push back the last scanned token onto ts.
+ */
+extern void
+js_UngetToken(JSTokenStream *ts);
+
+/*
+ * Get the next token from ts if its type is tt.
+ */
+extern JSBool
+js_MatchToken(JSContext *cx, JSTokenStream *ts, JSTokenType tt);
+
+JS_END_EXTERN_C
+
+#endif /* jsscan_h___ */

Added: freeswitch/trunk/libs/js/src/jsscope.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsscope.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1642 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS symbol tables.
+ */
+#include "jsstddef.h"
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsarena.h"
+#include "jsbit.h"
+#include "jsclist.h"
+#include "jsdhash.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsdbgapi.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsscope.h"
+#include "jsstr.h"
+
+JSScope *
+js_GetMutableScope(JSContext *cx, JSObject *obj)
+{
+    JSScope *scope, *newscope;
+
+    scope = OBJ_SCOPE(obj);
+    JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope));
+    if (scope->object == obj)
+        return scope;
+    newscope = js_NewScope(cx, 0, scope->map.ops, LOCKED_OBJ_GET_CLASS(obj),
+                           obj);
+    if (!newscope)
+        return NULL;
+    JS_LOCK_SCOPE(cx, newscope);
+    obj->map = js_HoldObjectMap(cx, &newscope->map);
+    scope = (JSScope *) js_DropObjectMap(cx, &scope->map, obj);
+    JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope);
+    return newscope;
+}
+
+/*
+ * JSScope uses multiplicative hashing, _a la_ jsdhash.[ch], but specialized
+ * to minimize footprint.  But if a scope has fewer than SCOPE_HASH_THRESHOLD
+ * entries, we use linear search and avoid allocating scope->table.
+ */
+#define SCOPE_HASH_THRESHOLD    6
+#define MIN_SCOPE_SIZE_LOG2     4
+#define MIN_SCOPE_SIZE          JS_BIT(MIN_SCOPE_SIZE_LOG2)
+#define SCOPE_TABLE_NBYTES(n)   ((n) * sizeof(JSScopeProperty *))
+
+static void
+InitMinimalScope(JSScope *scope)
+{
+    scope->hashShift = JS_DHASH_BITS - MIN_SCOPE_SIZE_LOG2;
+    scope->entryCount = scope->removedCount = 0;
+    scope->table = NULL;
+    scope->lastProp = NULL;
+}
+
+static JSBool
+CreateScopeTable(JSScope *scope)
+{
+    int sizeLog2;
+    JSScopeProperty *sprop, **spp;
+
+    JS_ASSERT(!scope->table);
+    JS_ASSERT(scope->lastProp);
+
+    if (scope->entryCount > SCOPE_HASH_THRESHOLD) {
+        /*
+         * Ouch: calloc failed at least once already -- let's try again,
+         * overallocating to hold at least twice the current population.
+         */
+        sizeLog2 = JS_CeilingLog2(2 * scope->entryCount);
+        scope->hashShift = JS_DHASH_BITS - sizeLog2;
+    } else {
+        JS_ASSERT(scope->hashShift == JS_DHASH_BITS - MIN_SCOPE_SIZE_LOG2);
+        sizeLog2 = MIN_SCOPE_SIZE_LOG2;
+    }
+
+    scope->table = (JSScopeProperty **)
+        calloc(JS_BIT(sizeLog2), sizeof(JSScopeProperty *));
+    if (!scope->table)
+        return JS_FALSE;
+
+    scope->hashShift = JS_DHASH_BITS - sizeLog2;
+    for (sprop = scope->lastProp; sprop; sprop = sprop->parent) {
+        spp = js_SearchScope(scope, sprop->id, JS_TRUE);
+        SPROP_STORE_PRESERVING_COLLISION(spp, sprop);
+    }
+    return JS_TRUE;
+}
+
+JSScope *
+js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp,
+            JSObject *obj)
+{
+    JSScope *scope;
+
+    scope = (JSScope *) JS_malloc(cx, sizeof(JSScope));
+    if (!scope)
+        return NULL;
+
+    js_InitObjectMap(&scope->map, nrefs, ops, clasp);
+    scope->object = obj;
+    scope->flags = 0;
+    scope->dswIndex = 0;
+    InitMinimalScope(scope);
+
+#ifdef JS_THREADSAFE
+    scope->ownercx = cx;
+    memset(&scope->lock, 0, sizeof scope->lock);
+
+    /*
+     * Set u.link = NULL, not u.count = 0, in case the target architecture's
+     * null pointer has a non-zero integer representation.
+     */
+    scope->u.link = NULL;
+
+#ifdef DEBUG
+    scope->file[0] = scope->file[1] = scope->file[2] = scope->file[3] = NULL;
+    scope->line[0] = scope->line[1] = scope->line[2] = scope->line[3] = 0;
+#endif
+#endif
+
+    JS_RUNTIME_METER(cx->runtime, liveScopes);
+    JS_RUNTIME_METER(cx->runtime, totalScopes);
+    return scope;
+}
+
+#ifdef DEBUG_SCOPE_COUNT
+extern void
+js_unlog_scope(JSScope *scope);
+#endif
+
+void
+js_DestroyScope(JSContext *cx, JSScope *scope)
+{
+#ifdef DEBUG_SCOPE_COUNT
+    js_unlog_scope(scope);
+#endif
+
+#ifdef JS_THREADSAFE
+    /* Scope must be single-threaded at this point, so set scope->ownercx. */
+    JS_ASSERT(scope->u.count == 0);
+    scope->ownercx = cx;
+    js_FinishLock(&scope->lock);
+#endif
+    if (scope->table)
+        JS_free(cx, scope->table);
+
+#ifdef DEBUG
+    JS_LOCK_RUNTIME_VOID(cx->runtime,
+                         cx->runtime->liveScopeProps -= scope->entryCount);
+#endif
+    JS_RUNTIME_UNMETER(cx->runtime, liveScopes);
+    JS_free(cx, scope);
+}
+
+#ifdef DUMP_SCOPE_STATS
+typedef struct JSScopeStats {
+    jsrefcount          searches;
+    jsrefcount          steps;
+    jsrefcount          hits;
+    jsrefcount          misses;
+    jsrefcount          stepHits;
+    jsrefcount          stepMisses;
+    jsrefcount          adds;
+    jsrefcount          redundantAdds;
+    jsrefcount          addFailures;
+    jsrefcount          changeFailures;
+    jsrefcount          compresses;
+    jsrefcount          grows;
+    jsrefcount          removes;
+    jsrefcount          removeFrees;
+    jsrefcount          uselessRemoves;
+    jsrefcount          shrinks;
+} JSScopeStats;
+
+JS_FRIEND_DATA(JSScopeStats) js_scope_stats;
+
+# define METER(x)       JS_ATOMIC_INCREMENT(&js_scope_stats.x)
+#else
+# define METER(x)       /* nothing */
+#endif
+
+/*
+ * Double hashing needs the second hash code to be relatively prime to table
+ * size, so we simply make hash2 odd.  The inputs to multiplicative hash are
+ * the golden ratio, expressed as a fixed-point 32 bit fraction, and the int
+ * property index or named property's atom number (observe that most objects
+ * have either no indexed properties, or almost all indexed and a few names,
+ * so collisions between index and atom number are unlikely).
+ */
+#define SCOPE_HASH0(id)                 (HASH_ID(id) * JS_GOLDEN_RATIO)
+#define SCOPE_HASH1(hash0,shift)        ((hash0) >> (shift))
+#define SCOPE_HASH2(hash0,log2,shift)   ((((hash0) << (log2)) >> (shift)) | 1)
+
+JS_FRIEND_API(JSScopeProperty **)
+js_SearchScope(JSScope *scope, jsid id, JSBool adding)
+{
+    JSHashNumber hash0, hash1, hash2;
+    int hashShift, sizeLog2;
+    JSScopeProperty *stored, *sprop, **spp, **firstRemoved;
+    uint32 sizeMask;
+
+    METER(searches);
+    if (!scope->table) {
+        /* Not enough properties to justify hashing: search from lastProp. */
+        JS_ASSERT(!SCOPE_HAD_MIDDLE_DELETE(scope));
+        for (spp = &scope->lastProp; (sprop = *spp); spp = &sprop->parent) {
+            if (sprop->id == id) {
+                METER(hits);
+                return spp;
+            }
+        }
+        METER(misses);
+        return spp;
+    }
+
+    /* Compute the primary hash address. */
+    hash0 = SCOPE_HASH0(id);
+    hashShift = scope->hashShift;
+    hash1 = SCOPE_HASH1(hash0, hashShift);
+    spp = scope->table + hash1;
+
+    /* Miss: return space for a new entry. */
+    stored = *spp;
+    if (SPROP_IS_FREE(stored)) {
+        METER(misses);
+        return spp;
+    }
+
+    /* Hit: return entry. */
+    sprop = SPROP_CLEAR_COLLISION(stored);
+    if (sprop && sprop->id == id) {
+        METER(hits);
+        return spp;
+    }
+
+    /* Collision: double hash. */
+    sizeLog2 = JS_DHASH_BITS - hashShift;
+    hash2 = SCOPE_HASH2(hash0, sizeLog2, hashShift);
+    sizeMask = JS_BITMASK(sizeLog2);
+
+    /* Save the first removed entry pointer so we can recycle it if adding. */
+    if (SPROP_IS_REMOVED(stored)) {
+        firstRemoved = spp;
+    } else {
+        firstRemoved = NULL;
+        if (adding && !SPROP_HAD_COLLISION(stored))
+            SPROP_FLAG_COLLISION(spp, sprop);
+    }
+
+    for (;;) {
+        METER(steps);
+        hash1 -= hash2;
+        hash1 &= sizeMask;
+        spp = scope->table + hash1;
+
+        stored = *spp;
+        if (SPROP_IS_FREE(stored)) {
+            METER(stepMisses);
+            return (adding && firstRemoved) ? firstRemoved : spp;
+        }
+
+        sprop = SPROP_CLEAR_COLLISION(stored);
+        if (sprop && sprop->id == id) {
+            METER(stepHits);
+            return spp;
+        }
+
+        if (SPROP_IS_REMOVED(stored)) {
+            if (!firstRemoved)
+                firstRemoved = spp;
+        } else {
+            if (adding && !SPROP_HAD_COLLISION(stored))
+                SPROP_FLAG_COLLISION(spp, sprop);
+        }
+    }
+
+    /* NOTREACHED */
+    return NULL;
+}
+
+static JSBool
+ChangeScope(JSContext *cx, JSScope *scope, int change)
+{
+    int oldlog2, newlog2;
+    uint32 oldsize, newsize, nbytes;
+    JSScopeProperty **table, **oldtable, **spp, **oldspp, *sprop;
+
+    /* Grow, shrink, or compress by changing scope->table. */
+    oldlog2 = JS_DHASH_BITS - scope->hashShift;
+    newlog2 = oldlog2 + change;
+    oldsize = JS_BIT(oldlog2);
+    newsize = JS_BIT(newlog2);
+    nbytes = SCOPE_TABLE_NBYTES(newsize);
+    table = (JSScopeProperty **) calloc(nbytes, 1);
+    if (!table) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+
+    /* Now that we have a new table allocated, update scope members. */
+    scope->hashShift = JS_DHASH_BITS - newlog2;
+    scope->removedCount = 0;
+    oldtable = scope->table;
+    scope->table = table;
+
+    /* Copy only live entries, leaving removed and free ones behind. */
+    for (oldspp = oldtable; oldsize != 0; oldspp++) {
+        sprop = SPROP_FETCH(oldspp);
+        if (sprop) {
+            spp = js_SearchScope(scope, sprop->id, JS_TRUE);
+            JS_ASSERT(SPROP_IS_FREE(*spp));
+            *spp = sprop;
+        }
+        oldsize--;
+    }
+
+    /* Finally, free the old table storage. */
+    JS_free(cx, oldtable);
+    return JS_TRUE;
+}
+
+/*
+ * Take care to exclude the mark and duplicate bits, in case we're called from
+ * the GC, or we are searching for a property that has not yet been flagged as
+ * a duplicate when making a duplicate formal parameter.
+ */
+#define SPROP_FLAGS_NOT_MATCHED (SPROP_MARK | SPROP_IS_DUPLICATE)
+
+JS_STATIC_DLL_CALLBACK(JSDHashNumber)
+js_HashScopeProperty(JSDHashTable *table, const void *key)
+{
+    const JSScopeProperty *sprop = (const JSScopeProperty *)key;
+    JSDHashNumber hash;
+    JSPropertyOp gsop;
+
+    /* Accumulate from least to most random so the low bits are most random. */
+    hash = 0;
+    gsop = sprop->getter;
+    if (gsop)
+        hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ (jsword)gsop;
+    gsop = sprop->setter;
+    if (gsop)
+        hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ (jsword)gsop;
+
+    hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4)
+           ^ (sprop->flags & ~SPROP_FLAGS_NOT_MATCHED);
+
+    hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->attrs;
+    hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->shortid;
+    hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->slot;
+    hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->id;
+    return hash;
+}
+
+#define SPROP_MATCH(sprop, child)                                             \
+    SPROP_MATCH_PARAMS(sprop, (child)->id, (child)->getter, (child)->setter,  \
+                       (child)->slot, (child)->attrs, (child)->flags,         \
+                       (child)->shortid)
+
+#define SPROP_MATCH_PARAMS(sprop, aid, agetter, asetter, aslot, aattrs,       \
+                           aflags, ashortid)                                  \
+    ((sprop)->id == (aid) &&                                                  \
+     SPROP_MATCH_PARAMS_AFTER_ID(sprop, agetter, asetter, aslot, aattrs,      \
+                                 aflags, ashortid))
+
+#define SPROP_MATCH_PARAMS_AFTER_ID(sprop, agetter, asetter, aslot, aattrs,   \
+                                    aflags, ashortid)                         \
+    ((sprop)->getter == (agetter) &&                                          \
+     (sprop)->setter == (asetter) &&                                          \
+     (sprop)->slot == (aslot) &&                                              \
+     (sprop)->attrs == (aattrs) &&                                            \
+     (((sprop)->flags ^ (aflags)) & ~SPROP_FLAGS_NOT_MATCHED) == 0 &&         \
+     (sprop)->shortid == (ashortid))
+
+JS_STATIC_DLL_CALLBACK(JSBool)
+js_MatchScopeProperty(JSDHashTable *table,
+                      const JSDHashEntryHdr *hdr,
+                      const void *key)
+{
+    const JSPropertyTreeEntry *entry = (const JSPropertyTreeEntry *)hdr;
+    const JSScopeProperty *sprop = entry->child;
+    const JSScopeProperty *kprop = (const JSScopeProperty *)key;
+
+    return SPROP_MATCH(sprop, kprop);
+}
+
+static const JSDHashTableOps PropertyTreeHashOps = {
+    JS_DHashAllocTable,
+    JS_DHashFreeTable,
+    JS_DHashGetKeyStub,
+    js_HashScopeProperty,
+    js_MatchScopeProperty,
+    JS_DHashMoveEntryStub,
+    JS_DHashClearEntryStub,
+    JS_DHashFinalizeStub,
+    NULL
+};
+
+/*
+ * A property tree node on rt->propertyFreeList overlays the following prefix
+ * struct on JSScopeProperty.
+ */
+typedef struct FreeNode {
+    jsid                id;
+    JSScopeProperty     *next;
+    JSScopeProperty     **prevp;
+} FreeNode;
+
+#define FREENODE(sprop) ((FreeNode *) (sprop))
+
+#define FREENODE_INSERT(list, sprop)                                          \
+    JS_BEGIN_MACRO                                                            \
+        FREENODE(sprop)->next = (list);                                       \
+        FREENODE(sprop)->prevp = &(list);                                     \
+        if (list)                                                             \
+            FREENODE(list)->prevp = &FREENODE(sprop)->next;                   \
+        (list) = (sprop);                                                     \
+    JS_END_MACRO
+
+#define FREENODE_REMOVE(sprop)                                                \
+    JS_BEGIN_MACRO                                                            \
+        *FREENODE(sprop)->prevp = FREENODE(sprop)->next;                      \
+        if (FREENODE(sprop)->next)                                            \
+            FREENODE(FREENODE(sprop)->next)->prevp = FREENODE(sprop)->prevp;  \
+    JS_END_MACRO
+
+/* NB: Called with the runtime lock held. */
+static JSScopeProperty *
+NewScopeProperty(JSRuntime *rt)
+{
+    JSScopeProperty *sprop;
+
+    sprop = rt->propertyFreeList;
+    if (sprop) {
+        FREENODE_REMOVE(sprop);
+    } else {
+        JS_ARENA_ALLOCATE_CAST(sprop, JSScopeProperty *,
+                               &rt->propertyArenaPool,
+                               sizeof(JSScopeProperty));
+        if (!sprop)
+            return NULL;
+    }
+
+    JS_RUNTIME_METER(rt, livePropTreeNodes);
+    JS_RUNTIME_METER(rt, totalPropTreeNodes);
+    return sprop;
+}
+
+#define CHUNKY_KIDS_TAG         ((jsuword)1)
+#define KIDS_IS_CHUNKY(kids)    ((jsuword)(kids) & CHUNKY_KIDS_TAG)
+#define KIDS_TO_CHUNK(kids)     ((PropTreeKidsChunk *)                        \
+                                 ((jsuword)(kids) & ~CHUNKY_KIDS_TAG))
+#define CHUNK_TO_KIDS(chunk)    ((JSScopeProperty *)                          \
+                                 ((jsuword)(chunk) | CHUNKY_KIDS_TAG))
+#define MAX_KIDS_PER_CHUNK      10
+
+typedef struct PropTreeKidsChunk PropTreeKidsChunk;
+
+struct PropTreeKidsChunk {
+    JSScopeProperty     *kids[MAX_KIDS_PER_CHUNK];
+    PropTreeKidsChunk   *next;
+};
+
+static PropTreeKidsChunk *
+NewPropTreeKidsChunk(JSRuntime *rt)
+{
+    PropTreeKidsChunk *chunk;
+
+    chunk = calloc(1, sizeof *chunk);
+    if (!chunk)
+        return NULL;
+    JS_ASSERT(((jsuword)chunk & CHUNKY_KIDS_TAG) == 0);
+    JS_RUNTIME_METER(rt, propTreeKidsChunks);
+    return chunk;
+}
+
+static void
+DestroyPropTreeKidsChunk(JSRuntime *rt, PropTreeKidsChunk *chunk)
+{
+    JS_RUNTIME_UNMETER(rt, propTreeKidsChunks);
+    free(chunk);
+}
+
+/* NB: Called with the runtime lock held. */
+static JSBool
+InsertPropertyTreeChild(JSRuntime *rt, JSScopeProperty *parent,
+                        JSScopeProperty *child)
+{
+    JSPropertyTreeEntry *entry;
+    JSScopeProperty **childp, *kids, *sprop;
+    PropTreeKidsChunk *chunk, **chunkp;
+    uintN i;
+
+    JS_ASSERT(!parent || child->parent != parent);
+
+    if (!parent) {
+        entry = (JSPropertyTreeEntry *)
+            JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_ADD);
+        if (!entry)
+            return JS_FALSE;
+        childp = &entry->child;
+        sprop = *childp;
+        if (!sprop) {
+            *childp = child;
+        } else {
+            /*
+             * A "Duplicate child" case.
+             *
+             * We can't do away with child, as at least one live scope entry
+             * still points at it.  What's more, that scope's lastProp chains
+             * through an ancestor line to reach child, and js_Enumerate and
+             * others count on this linkage.  We must leave child out of the
+             * hash table, and not require it to be there when we eventually
+             * GC it (see RemovePropertyTreeChild, below).
+             *
+             * It is necessary to leave the duplicate child out of the hash
+             * table to preserve entry uniqueness.  It is safe to leave the
+             * child out of the hash table (unlike the duplicate child cases
+             * below), because the child's parent link will be null, which
+             * can't dangle.
+             */
+            JS_ASSERT(sprop != child && SPROP_MATCH(sprop, child));
+            JS_RUNTIME_METER(rt, duplicatePropTreeNodes);
+        }
+    } else {
+        childp = &parent->kids;
+        kids = *childp;
+        if (kids) {
+            if (KIDS_IS_CHUNKY(kids)) {
+                chunk = KIDS_TO_CHUNK(kids);
+                do {
+                    for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {
+                        childp = &chunk->kids[i];
+                        sprop = *childp;
+                        if (!sprop)
+                            goto insert;
+
+                        JS_ASSERT(sprop != child);
+                        if (SPROP_MATCH(sprop, child)) {
+                            /*
+                             * Duplicate child, see comment above.  In this
+                             * case, we must let the duplicate be inserted at
+                             * this level in the tree, so we keep iterating,
+                             * looking for an empty slot in which to insert.
+                             */
+                            JS_ASSERT(sprop != child);
+                            JS_RUNTIME_METER(rt, duplicatePropTreeNodes);
+                        }
+                    }
+                    chunkp = &chunk->next;
+                } while ((chunk = *chunkp) != NULL);
+
+                chunk = NewPropTreeKidsChunk(rt);
+                if (!chunk)
+                    return JS_FALSE;
+                *chunkp = chunk;
+                childp = &chunk->kids[0];
+            } else {
+                sprop = kids;
+                JS_ASSERT(sprop != child);
+                if (SPROP_MATCH(sprop, child)) {
+                    /*
+                     * Duplicate child, see comment above.  Once again, we
+                     * must let duplicates created by deletion pile up in a
+                     * kids-chunk-list, in order to find them when sweeping
+                     * and thereby avoid dangling parent pointers.
+                     */
+                    JS_RUNTIME_METER(rt, duplicatePropTreeNodes);
+                }
+
+                chunk = NewPropTreeKidsChunk(rt);
+                if (!chunk)
+                    return JS_FALSE;
+                parent->kids = CHUNK_TO_KIDS(chunk);
+                chunk->kids[0] = sprop;
+                childp = &chunk->kids[1];
+            }
+        }
+    insert:
+        *childp = child;
+    }
+
+    child->parent = parent;
+    return JS_TRUE;
+}
+
+/* NB: Called with the runtime lock held. */
+static void
+RemovePropertyTreeChild(JSRuntime *rt, JSScopeProperty *child)
+{
+    JSPropertyTreeEntry *entry;
+    JSScopeProperty *parent, *kids, *kid;
+    PropTreeKidsChunk *list, *chunk, **chunkp, *lastChunk;
+    uintN i, j;
+
+    parent = child->parent;
+    if (!parent) {
+        /*
+         * Don't remove child if it is not in rt->propertyTreeHash, but only
+         * matches a root child in the table that has compatible members. See
+         * the "Duplicate child" comments in InsertPropertyTreeChild, above.
+         */
+        entry = (JSPropertyTreeEntry *)
+            JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_LOOKUP);
+
+        if (entry->child == child)
+            JS_DHashTableRawRemove(&rt->propertyTreeHash, &entry->hdr);
+    } else {
+        kids = parent->kids;
+        if (KIDS_IS_CHUNKY(kids)) {
+            list = chunk = KIDS_TO_CHUNK(kids);
+            chunkp = &list;
+
+            do {
+                for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {
+                    if (chunk->kids[i] == child) {
+                        lastChunk = chunk;
+                        if (!lastChunk->next) {
+                            j = i + 1;
+                        } else {
+                            j = 0;
+                            do {
+                                chunkp = &lastChunk->next;
+                                lastChunk = *chunkp;
+                            } while (lastChunk->next);
+                        }
+                        for (; j < MAX_KIDS_PER_CHUNK; j++) {
+                            if (!lastChunk->kids[j])
+                                break;
+                        }
+                        --j;
+                        if (chunk != lastChunk || j > i)
+                            chunk->kids[i] = lastChunk->kids[j];
+                        lastChunk->kids[j] = NULL;
+                        if (j == 0) {
+                            *chunkp = NULL;
+                            if (!list)
+                                parent->kids = NULL;
+                            DestroyPropTreeKidsChunk(rt, lastChunk);
+                        }
+                        return;
+                    }
+                }
+
+                chunkp = &chunk->next;
+            } while ((chunk = *chunkp) != NULL);
+        } else {
+            kid = kids;
+            if (kid == child)
+                parent->kids = NULL;
+        }
+    }
+}
+
+/*
+ * Called *without* the runtime lock held, this function acquires that lock
+ * only when inserting a new child.  Thus there may be races to find or add
+ * a node that result in duplicates.  We expect such races to be rare!
+ */
+static JSScopeProperty *
+GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent,
+                     JSScopeProperty *child)
+{
+    JSRuntime *rt;
+    JSPropertyTreeEntry *entry;
+    JSScopeProperty *sprop;
+    PropTreeKidsChunk *chunk;
+    uintN i;
+
+    rt = cx->runtime;
+    if (!parent) {
+        JS_LOCK_RUNTIME(rt);
+
+        entry = (JSPropertyTreeEntry *)
+            JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_ADD);
+        if (!entry)
+            goto out_of_memory;
+
+        sprop = entry->child;
+        if (sprop)
+            goto out;
+    } else {
+        /*
+         * Because chunks are appended at the end and never deleted except by
+         * the GC, we can search without taking the runtime lock.  We may miss
+         * a matching sprop added by another thread, and make a duplicate one,
+         * but that is an unlikely, therefore small, cost.  The property tree
+         * has extremely low fan-out below its root in popular embeddings with
+         * real-world workloads.
+         *
+         * If workload changes so as to increase fan-out significantly below
+         * the property tree root, we'll want to add another tag bit stored in
+         * parent->kids that indicates a JSDHashTable pointer.
+         */
+        entry = NULL;
+        sprop = parent->kids;
+        if (sprop) {
+            if (KIDS_IS_CHUNKY(sprop)) {
+                chunk = KIDS_TO_CHUNK(sprop);
+                do {
+                    for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {
+                        sprop = chunk->kids[i];
+                        if (!sprop)
+                            goto not_found;
+
+                        if (SPROP_MATCH(sprop, child))
+                            return sprop;
+                    }
+                } while ((chunk = chunk->next) != NULL);
+            } else {
+                if (SPROP_MATCH(sprop, child))
+                    return sprop;
+            }
+        }
+
+    not_found:
+        JS_LOCK_RUNTIME(rt);
+    }
+
+    sprop = NewScopeProperty(rt);
+    if (!sprop)
+        goto out_of_memory;
+
+    sprop->id = child->id;
+    sprop->getter = child->getter;
+    sprop->setter = child->setter;
+    sprop->slot = child->slot;
+    sprop->attrs = child->attrs;
+    sprop->flags = child->flags;
+    sprop->shortid = child->shortid;
+    sprop->parent = sprop->kids = NULL;
+    if (!parent) {
+        entry->child = sprop;
+    } else {
+        if (!InsertPropertyTreeChild(rt, parent, sprop))
+            goto out_of_memory;
+    }
+
+out:
+    JS_UNLOCK_RUNTIME(rt);
+    return sprop;
+
+out_of_memory:
+    JS_UNLOCK_RUNTIME(rt);
+    JS_ReportOutOfMemory(cx);
+    return NULL;
+}
+
+#ifdef DEBUG_notbrendan
+#define CHECK_ANCESTOR_LINE(scope, sparse)                                    \
+    JS_BEGIN_MACRO                                                            \
+        if ((scope)->table) CheckAncestorLine(scope, sparse);                 \
+    JS_END_MACRO
+
+static void
+CheckAncestorLine(JSScope *scope, JSBool sparse)
+{
+    uint32 size;
+    JSScopeProperty **spp, **start, **end, *ancestorLine, *sprop, *aprop;
+    uint32 entryCount, ancestorCount;
+
+    ancestorLine = SCOPE_LAST_PROP(scope);
+    if (ancestorLine)
+        JS_ASSERT(SCOPE_HAS_PROPERTY(scope, ancestorLine));
+
+    entryCount = 0;
+    size = SCOPE_CAPACITY(scope);
+    start = scope->table;
+    for (spp = start, end = start + size; spp < end; spp++) {
+        sprop = SPROP_FETCH(spp);
+        if (sprop) {
+            entryCount++;
+            for (aprop = ancestorLine; aprop; aprop = aprop->parent) {
+                if (aprop == sprop)
+                    break;
+            }
+            JS_ASSERT(aprop);
+        }
+    }
+    JS_ASSERT(entryCount == scope->entryCount);
+
+    ancestorCount = 0;
+    for (sprop = ancestorLine; sprop; sprop = sprop->parent) {
+        if (SCOPE_HAD_MIDDLE_DELETE(scope) &&
+            !SCOPE_HAS_PROPERTY(scope, sprop)) {
+            JS_ASSERT(sparse || (sprop->flags & SPROP_IS_DUPLICATE));
+            continue;
+        }
+        ancestorCount++;
+    }
+    JS_ASSERT(ancestorCount == scope->entryCount);
+}
+#else
+#define CHECK_ANCESTOR_LINE(scope, sparse) /* nothing */
+#endif
+
+static void
+ReportReadOnlyScope(JSContext *cx, JSScope *scope)
+{
+    JSString *str;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(scope->object));
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_READ_ONLY,
+                         str
+                         ? JS_GetStringBytes(str)
+                         : LOCKED_OBJ_GET_CLASS(scope->object)->name);
+}
+
+JSScopeProperty *
+js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id,
+                    JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
+                    uintN attrs, uintN flags, intN shortid)
+{
+    JSScopeProperty **spp, *sprop, *overwriting, **spvec, **spp2, child;
+    uint32 size, splen, i;
+    int change;
+
+    JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope));
+    CHECK_ANCESTOR_LINE(scope, JS_TRUE);
+
+    /*
+     * You can't add properties to a sealed scope.  But note well that you can
+     * change property attributes in a sealed scope, even though that replaces
+     * a JSScopeProperty * in the scope's hash table -- but no id is added, so
+     * the scope remains sealed.
+     */
+    if (SCOPE_IS_SEALED(scope)) {
+        ReportReadOnlyScope(cx, scope);
+        return NULL;
+    }
+
+    /*
+     * Normalize stub getter and setter values for faster is-stub testing in
+     * the SPROP_CALL_[GS]ETTER macros.
+     */
+    if (getter == JS_PropertyStub)
+        getter = NULL;
+    if (setter == JS_PropertyStub)
+        setter = NULL;
+
+    /*
+     * Search for id in order to claim its entry, allocating a property tree
+     * node if one doesn't already exist for our parameters.
+     */
+    spp = js_SearchScope(scope, id, JS_TRUE);
+    sprop = overwriting = SPROP_FETCH(spp);
+    if (!sprop) {
+        /* Check whether we need to grow, if the load factor is >= .75. */
+        size = SCOPE_CAPACITY(scope);
+        if (scope->entryCount + scope->removedCount >= size - (size >> 2)) {
+            if (scope->removedCount >= size >> 2) {
+                METER(compresses);
+                change = 0;
+            } else {
+                METER(grows);
+                change = 1;
+            }
+            if (!ChangeScope(cx, scope, change) &&
+                scope->entryCount + scope->removedCount == size - 1) {
+                METER(addFailures);
+                return NULL;
+            }
+            spp = js_SearchScope(scope, id, JS_TRUE);
+            JS_ASSERT(!SPROP_FETCH(spp));
+        }
+    } else {
+        /* Property exists: js_SearchScope must have returned a valid entry. */
+        JS_ASSERT(!SPROP_IS_REMOVED(*spp));
+
+        /*
+         * If all property members match, this is a redundant add and we can
+         * return early.  If the caller wants to allocate a slot, but doesn't
+         * care which slot, copy sprop->slot into slot so we can match sprop,
+         * if all other members match.
+         */
+        if (!(attrs & JSPROP_SHARED) &&
+            slot == SPROP_INVALID_SLOT &&
+            SPROP_HAS_VALID_SLOT(sprop, scope)) {
+            slot = sprop->slot;
+        }
+        if (SPROP_MATCH_PARAMS_AFTER_ID(sprop, getter, setter, slot, attrs,
+                                        flags, shortid)) {
+            METER(redundantAdds);
+            return sprop;
+        }
+
+        /*
+         * Duplicate formal parameters require us to leave the old property
+         * on the ancestor line, so the decompiler can find it, even though
+         * its entry in scope->table is overwritten to point at a new property
+         * descending from the old one.  The SPROP_IS_DUPLICATE flag helps us
+         * cope with the consequent disparity between ancestor line height and
+         * scope->entryCount.
+         */
+        if (flags & SPROP_IS_DUPLICATE) {
+            sprop->flags |= SPROP_IS_DUPLICATE;
+        } else {
+            /*
+             * If we are clearing sprop to force an existing property to be
+             * overwritten (apart from a duplicate formal parameter), we must
+             * unlink it from the ancestor line at scope->lastProp, lazily if
+             * sprop is not lastProp.  And we must remove the entry at *spp,
+             * precisely so the lazy "middle delete" fixup code further below
+             * won't find sprop in scope->table, in spite of sprop being on
+             * the ancestor line.
+             *
+             * When we finally succeed in finding or creating a new sprop
+             * and storing its pointer at *spp, we'll use the |overwriting|
+             * local saved when we first looked up id to decide whether we're
+             * indeed creating a new entry, or merely overwriting an existing
+             * property.
+             */
+            if (sprop == SCOPE_LAST_PROP(scope)) {
+                do {
+                    SCOPE_REMOVE_LAST_PROP(scope);
+                    if (!SCOPE_HAD_MIDDLE_DELETE(scope))
+                        break;
+                    sprop = SCOPE_LAST_PROP(scope);
+                } while (sprop && !SCOPE_HAS_PROPERTY(scope, sprop));
+            } else if (!SCOPE_HAD_MIDDLE_DELETE(scope)) {
+                /*
+                 * If we have no hash table yet, we need one now.  The middle
+                 * delete code is simple-minded that way!
+                 */
+                if (!scope->table) {
+                    if (!CreateScopeTable(scope)) {
+                        JS_ReportOutOfMemory(cx);
+                        return NULL;
+                    }
+                    spp = js_SearchScope(scope, id, JS_TRUE);
+                    sprop = overwriting = SPROP_FETCH(spp);
+                }
+                SCOPE_SET_MIDDLE_DELETE(scope);
+            }
+        }
+
+        /*
+         * If we fail later on trying to find or create a new sprop, we will
+         * goto fail_overwrite and restore *spp from |overwriting|.  Note that
+         * we don't bother to keep scope->removedCount in sync, because we'll
+         * fix up *spp and scope->entryCount shortly, no matter how control
+         * flow returns from this function.
+         */
+        if (scope->table)
+            SPROP_STORE_PRESERVING_COLLISION(spp, NULL);
+        scope->entryCount--;
+        CHECK_ANCESTOR_LINE(scope, JS_TRUE);
+        sprop = NULL;
+    }
+
+    if (!sprop) {
+        /*
+         * If properties were deleted from the middle of the list starting at
+         * scope->lastProp, we may need to fork the property tree and squeeze
+         * all deleted properties out of scope's ancestor line.  Otherwise we
+         * risk adding a node with the same id as a "middle" node, violating
+         * the rule that properties along an ancestor line have distinct ids
+         * (unless flagged SPROP_IS_DUPLICATE).
+         */
+        if (SCOPE_HAD_MIDDLE_DELETE(scope)) {
+            JS_ASSERT(scope->table);
+            CHECK_ANCESTOR_LINE(scope, JS_TRUE);
+
+            splen = scope->entryCount;
+            if (splen == 0) {
+                JS_ASSERT(scope->lastProp == NULL);
+            } else {
+                /*
+                 * Enumerate live entries in scope->table using a temporary
+                 * vector, by walking the (possibly sparse, due to deletions)
+                 * ancestor line from scope->lastProp.
+                 */
+                spvec = (JSScopeProperty **)
+                        JS_malloc(cx, SCOPE_TABLE_NBYTES(splen));
+                if (!spvec)
+                    goto fail_overwrite;
+                i = splen;
+                sprop = SCOPE_LAST_PROP(scope);
+                JS_ASSERT(sprop);
+                do {
+                    /*
+                     * NB: test SCOPE_GET_PROPERTY, not SCOPE_HAS_PROPERTY --
+                     * the latter insists that sprop->id maps to sprop, while
+                     * the former simply tests whether sprop->id is bound in
+                     * scope.  We must allow for duplicate formal parameters
+                     * along the ancestor line, and fork them as needed.
+                     */
+                    if (!SCOPE_GET_PROPERTY(scope, sprop->id))
+                        continue;
+
+                    JS_ASSERT(sprop != overwriting);
+                    if (i == 0) {
+                        /*
+                         * If our original splen estimate, scope->entryCount,
+                         * is less than the ancestor line height, there must
+                         * be duplicate formal parameters in this (function
+                         * object) scope.  Count remaining ancestors in order
+                         * to realloc spvec.
+                         */
+                        JSScopeProperty *tmp = sprop;
+                        do {
+                            if (SCOPE_GET_PROPERTY(scope, tmp->id))
+                                i++;
+                        } while ((tmp = tmp->parent) != NULL);
+                        spp2 = (JSScopeProperty **)
+                             JS_realloc(cx, spvec, SCOPE_TABLE_NBYTES(splen+i));
+                        if (!spp2) {
+                            JS_free(cx, spvec);
+                            goto fail_overwrite;
+                        }
+
+                        spvec = spp2;
+                        memmove(spvec + i, spvec, SCOPE_TABLE_NBYTES(splen));
+                        splen += i;
+                    }
+
+                    spvec[--i] = sprop;
+                } while ((sprop = sprop->parent) != NULL);
+                JS_ASSERT(i == 0);
+
+                /*
+                 * Now loop forward through spvec, forking the property tree
+                 * whenever we see a "parent gap" due to deletions from scope.
+                 * NB: sprop is null on first entry to the loop body.
+                 */
+                do {
+                    if (spvec[i]->parent == sprop) {
+                        sprop = spvec[i];
+                    } else {
+                        sprop = GetPropertyTreeChild(cx, sprop, spvec[i]);
+                        if (!sprop) {
+                            JS_free(cx, spvec);
+                            goto fail_overwrite;
+                        }
+
+                        spp2 = js_SearchScope(scope, sprop->id, JS_FALSE);
+                        JS_ASSERT(SPROP_FETCH(spp2) == spvec[i]);
+                        SPROP_STORE_PRESERVING_COLLISION(spp2, sprop);
+                    }
+                } while (++i < splen);
+                JS_free(cx, spvec);
+
+                /*
+                 * Now sprop points to the last property in scope, where the
+                 * ancestor line from sprop to the root is dense w.r.t. scope:
+                 * it contains no nodes not mapped by scope->table, apart from
+                 * any stinking ECMA-mandated duplicate formal parameters.
+                 */
+                scope->lastProp = sprop;
+                CHECK_ANCESTOR_LINE(scope, JS_FALSE);
+                JS_RUNTIME_METER(cx->runtime, middleDeleteFixups);
+            }
+
+            SCOPE_CLR_MIDDLE_DELETE(scope);
+        }
+
+        /*
+         * Aliases share another property's slot, passed in the |slot| param.
+         * Shared properties have no slot.  Unshared properties that do not
+         * alias another property's slot get one here, but may lose it due to
+         * a JS_ClearScope call.
+         */
+        if (!(flags & SPROP_IS_ALIAS)) {
+            if (attrs & JSPROP_SHARED) {
+                slot = SPROP_INVALID_SLOT;
+            } else {
+                /*
+                 * We may have set slot from a nearly-matching sprop, above.
+                 * If so, we're overwriting that nearly-matching sprop, so we
+                 * can reuse its slot -- we don't need to allocate a new one.
+                 * Callers should therefore pass SPROP_INVALID_SLOT for all
+                 * non-alias, unshared property adds.
+                 */
+                if (slot != SPROP_INVALID_SLOT)
+                    JS_ASSERT(overwriting);
+                else if (!js_AllocSlot(cx, scope->object, &slot))
+                    goto fail_overwrite;
+            }
+        }
+
+        /*
+         * Check for a watchpoint on a deleted property; if one exists, change
+         * setter to js_watch_set.
+         * XXXbe this could get expensive with lots of watchpoints...
+         */
+        if (!JS_CLIST_IS_EMPTY(&cx->runtime->watchPointList) &&
+            js_FindWatchPoint(cx->runtime, scope, id)) {
+            setter = js_WrapWatchedSetter(cx, id, attrs, setter);
+            if (!setter)
+                goto fail_overwrite;
+        }
+
+        /* Find or create a property tree node labeled by our arguments. */
+        child.id = id;
+        child.getter = getter;
+        child.setter = setter;
+        child.slot = slot;
+        child.attrs = attrs;
+        child.flags = flags;
+        child.shortid = shortid;
+        sprop = GetPropertyTreeChild(cx, scope->lastProp, &child);
+        if (!sprop)
+            goto fail_overwrite;
+
+        /* Store the tree node pointer in the table entry for id. */
+        if (scope->table)
+            SPROP_STORE_PRESERVING_COLLISION(spp, sprop);
+        scope->entryCount++;
+        scope->lastProp = sprop;
+        CHECK_ANCESTOR_LINE(scope, JS_FALSE);
+        if (!overwriting) {
+            JS_RUNTIME_METER(cx->runtime, liveScopeProps);
+            JS_RUNTIME_METER(cx->runtime, totalScopeProps);
+        }
+
+        /*
+         * If we reach the hashing threshold, try to allocate scope->table.
+         * If we can't (a rare event, preceded by swapping to death on most
+         * modern OSes), stick with linear search rather than whining about
+         * this little set-back.  Therefore we must test !scope->table and
+         * scope->entryCount >= SCOPE_HASH_THRESHOLD, not merely whether the
+         * entry count just reached the threshold.
+         */
+        if (!scope->table && scope->entryCount >= SCOPE_HASH_THRESHOLD)
+            (void) CreateScopeTable(scope);
+    }
+
+    METER(adds);
+    return sprop;
+
+fail_overwrite:
+    if (overwriting) {
+        /*
+         * We may or may not have forked overwriting out of scope's ancestor
+         * line, so we must check (the alternative is to set a flag above, but
+         * that hurts the common, non-error case).  If we did fork overwriting
+         * out, we'll add it back at scope->lastProp.  This means enumeration
+         * order can change due to a failure to overwrite an id.
+         * XXXbe very minor incompatibility
+         */
+        for (sprop = SCOPE_LAST_PROP(scope); ; sprop = sprop->parent) {
+            if (!sprop) {
+                sprop = SCOPE_LAST_PROP(scope);
+                if (overwriting->parent == sprop) {
+                    scope->lastProp = overwriting;
+                } else {
+                    sprop = GetPropertyTreeChild(cx, sprop, overwriting);
+                    if (sprop) {
+                        JS_ASSERT(sprop != overwriting);
+                        scope->lastProp = sprop;
+                    }
+                    overwriting = sprop;
+                }
+                break;
+            }
+            if (sprop == overwriting)
+                break;
+        }
+        if (overwriting) {
+            if (scope->table)
+                SPROP_STORE_PRESERVING_COLLISION(spp, overwriting);
+            scope->entryCount++;
+        }
+        CHECK_ANCESTOR_LINE(scope, JS_TRUE);
+    }
+    METER(addFailures);
+    return NULL;
+}
+
+JSScopeProperty *
+js_ChangeScopePropertyAttrs(JSContext *cx, JSScope *scope,
+                            JSScopeProperty *sprop, uintN attrs, uintN mask,
+                            JSPropertyOp getter, JSPropertyOp setter)
+{
+    JSScopeProperty child, *newsprop, **spp;
+
+    CHECK_ANCESTOR_LINE(scope, JS_TRUE);
+
+    /* Allow only shared (slot-less) => unshared (slot-full) transition. */
+    attrs |= sprop->attrs & mask;
+    JS_ASSERT(!((attrs ^ sprop->attrs) & JSPROP_SHARED) ||
+              !(attrs & JSPROP_SHARED));
+    if (getter == JS_PropertyStub)
+        getter = NULL;
+    if (setter == JS_PropertyStub)
+        setter = NULL;
+    if (sprop->attrs == attrs &&
+        sprop->getter == getter &&
+        sprop->setter == setter) {
+        return sprop;
+    }
+
+    child.id = sprop->id;
+    child.getter = getter;
+    child.setter = setter;
+    child.slot = sprop->slot;
+    child.attrs = attrs;
+    child.flags = sprop->flags;
+    child.shortid = sprop->shortid;
+
+    if (SCOPE_LAST_PROP(scope) == sprop) {
+        /*
+         * Optimize the case where the last property added to scope is changed
+         * to have a different attrs, getter, or setter.  In the last property
+         * case, we need not fork the property tree.  But since we do not call
+         * js_AddScopeProperty, we may need to allocate a new slot directly.
+         */
+        if ((sprop->attrs & JSPROP_SHARED) && !(attrs & JSPROP_SHARED)) {
+            JS_ASSERT(child.slot == SPROP_INVALID_SLOT);
+            if (!js_AllocSlot(cx, scope->object, &child.slot))
+                return NULL;
+        }
+
+        newsprop = GetPropertyTreeChild(cx, sprop->parent, &child);
+        if (newsprop) {
+            spp = js_SearchScope(scope, sprop->id, JS_FALSE);
+            JS_ASSERT(SPROP_FETCH(spp) == sprop);
+
+            if (scope->table)
+                SPROP_STORE_PRESERVING_COLLISION(spp, newsprop);
+            scope->lastProp = newsprop;
+            CHECK_ANCESTOR_LINE(scope, JS_TRUE);
+        }
+    } else {
+        /*
+         * Let js_AddScopeProperty handle this |overwriting| case, including
+         * the conservation of sprop->slot (if it's valid).  We must not call
+         * js_RemoveScopeProperty here, it will free a valid sprop->slot and
+         * js_AddScopeProperty won't re-allocate it.
+         */
+        newsprop = js_AddScopeProperty(cx, scope, child.id,
+                                       child.getter, child.setter, child.slot,
+                                       child.attrs, child.flags, child.shortid);
+    }
+
+#ifdef DUMP_SCOPE_STATS
+    if (!newsprop)
+        METER(changeFailures);
+#endif
+    return newsprop;
+}
+
+JSBool
+js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id)
+{
+    JSScopeProperty **spp, *stored, *sprop;
+    uint32 size;
+
+    JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope));
+    CHECK_ANCESTOR_LINE(scope, JS_TRUE);
+    if (SCOPE_IS_SEALED(scope)) {
+        ReportReadOnlyScope(cx, scope);
+        return JS_FALSE;
+    }
+    METER(removes);
+
+    spp = js_SearchScope(scope, id, JS_FALSE);
+    stored = *spp;
+    sprop = SPROP_CLEAR_COLLISION(stored);
+    if (!sprop) {
+        METER(uselessRemoves);
+        return JS_TRUE;
+    }
+
+    /* Convert from a list to a hash so we can handle "middle deletes". */
+    if (!scope->table && sprop != scope->lastProp) {
+        if (!CreateScopeTable(scope)) {
+            JS_ReportOutOfMemory(cx);
+            return JS_FALSE;
+        }
+        spp = js_SearchScope(scope, id, JS_FALSE);
+        stored = *spp;
+        sprop = SPROP_CLEAR_COLLISION(stored);
+    }
+
+    /* First, if sprop is unshared and not cleared, free its slot number. */
+    if (SPROP_HAS_VALID_SLOT(sprop, scope))
+        js_FreeSlot(cx, scope->object, sprop->slot);
+
+    /* Next, remove id by setting its entry to a removed or free sentinel. */
+    if (SPROP_HAD_COLLISION(stored)) {
+        JS_ASSERT(scope->table);
+        *spp = SPROP_REMOVED;
+        scope->removedCount++;
+    } else {
+        METER(removeFrees);
+        if (scope->table)
+            *spp = NULL;
+    }
+    scope->entryCount--;
+    JS_RUNTIME_UNMETER(cx->runtime, liveScopeProps);
+
+    /* Update scope->lastProp directly, or set its deferred update flag. */
+    if (sprop == SCOPE_LAST_PROP(scope)) {
+        do {
+            SCOPE_REMOVE_LAST_PROP(scope);
+            if (!SCOPE_HAD_MIDDLE_DELETE(scope))
+                break;
+            sprop = SCOPE_LAST_PROP(scope);
+        } while (sprop && !SCOPE_HAS_PROPERTY(scope, sprop));
+    } else if (!SCOPE_HAD_MIDDLE_DELETE(scope)) {
+        SCOPE_SET_MIDDLE_DELETE(scope);
+    }
+    CHECK_ANCESTOR_LINE(scope, JS_TRUE);
+
+    /* Last, consider shrinking scope's table if its load factor is <= .25. */
+    size = SCOPE_CAPACITY(scope);
+    if (size > MIN_SCOPE_SIZE && scope->entryCount <= size >> 2) {
+        METER(shrinks);
+        (void) ChangeScope(cx, scope, -1);
+    }
+
+    return JS_TRUE;
+}
+
+void
+js_ClearScope(JSContext *cx, JSScope *scope)
+{
+    CHECK_ANCESTOR_LINE(scope, JS_TRUE);
+#ifdef DEBUG
+    JS_LOCK_RUNTIME_VOID(cx->runtime,
+                         cx->runtime->liveScopeProps -= scope->entryCount);
+#endif
+
+    if (scope->table)
+        free(scope->table);
+    SCOPE_CLR_MIDDLE_DELETE(scope);
+    InitMinimalScope(scope);
+}
+
+#ifdef DUMP_SCOPE_STATS
+
+#include <stdio.h>
+#include <math.h>
+
+uint32 js_nkids_max;
+uint32 js_nkids_sum;
+double js_nkids_sqsum;
+uint32 js_nkids_hist[11];
+
+static void
+MeterKidCount(uintN nkids)
+{
+    if (nkids) {
+        js_nkids_sum += nkids;
+        js_nkids_sqsum += (double)nkids * nkids;
+        if (nkids > js_nkids_max)
+            js_nkids_max = nkids;
+    }
+    js_nkids_hist[JS_MIN(nkids, 10)]++;
+}
+
+static void
+MeterPropertyTree(JSScopeProperty *node)
+{
+    uintN i, nkids;
+    JSScopeProperty *kids, *kid;
+    PropTreeKidsChunk *chunk;
+
+    nkids = 0;
+    kids = node->kids;
+    if (kids) {
+        if (KIDS_IS_CHUNKY(kids)) {
+            for (chunk = KIDS_TO_CHUNK(kids); chunk; chunk = chunk->next) {
+                for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {
+                    kid = chunk->kids[i];
+                    if (!kid)
+                        break;
+                    MeterPropertyTree(kid);
+                    nkids++;
+                }
+            }
+        } else {
+            MeterPropertyTree(kids);
+            nkids = 1;
+        }
+    }
+
+    MeterKidCount(nkids);
+}
+
+JS_STATIC_DLL_CALLBACK(JSDHashOperator)
+js_MeterPropertyTree(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number,
+                     void *arg)
+{
+    JSPropertyTreeEntry *entry = (JSPropertyTreeEntry *)hdr;
+
+    MeterPropertyTree(entry->child);
+    return JS_DHASH_NEXT;
+}
+
+#include "jsprf.h"
+
+static void
+DumpSubtree(JSScopeProperty *sprop, int level, FILE *fp)
+{
+    char buf[10];
+    JSScopeProperty *kids, *kid;
+    PropTreeKidsChunk *chunk;
+    uintN i;
+
+    fprintf(fp, "%*sid %s g/s %p/%p slot %lu attrs %x flags %x shortid %d\n",
+            level, "",
+            JSID_IS_ATOM(sprop->id)
+            ? JS_GetStringBytes(ATOM_TO_STRING(JSID_TO_ATOM(sprop->id)))
+            : JSID_IS_OBJECT(sprop->id)
+            ? js_ValueToPrintableString(cx, OBJECT_JSID_TO_JSVAL(sprop->id))
+            : (JS_snprintf(buf, sizeof buf, "%ld", JSVAL_TO_INT(sprop->id)),
+               buf)
+            (void *) sprop->getter, (void *) sprop->setter,
+            (unsigned long) sprop->slot, sprop->attrs, sprop->flags,
+            sprop->shortid);
+    kids = sprop->kids;
+    if (kids) {
+        ++level;
+        if (KIDS_IS_CHUNKY(kids)) {
+            chunk = KIDS_TO_CHUNK(kids);
+            do {
+                for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {
+                    kid = chunk->kids[i];
+                    if (!kid)
+                        break;
+                    JS_ASSERT(kid->parent == sprop);
+                    DumpSubtree(kid, level, fp);
+                }
+            } while ((chunk = chunk->next) != NULL);
+        } else {
+            kid = kids;
+            DumpSubtree(kid, level, fp);
+        }
+    }
+}
+
+#endif /* DUMP_SCOPE_STATS */
+
+void
+js_SweepScopeProperties(JSRuntime *rt)
+{
+    JSArena **ap, *a;
+    JSScopeProperty *limit, *sprop, *parent, *kids, *kid;
+    uintN liveCount;
+    PropTreeKidsChunk *chunk, *nextChunk;
+    uintN i;
+
+#ifdef DUMP_SCOPE_STATS
+    uint32 livePropCapacity = 0, totalLiveCount = 0;
+    static FILE *logfp;
+    if (!logfp)
+        logfp = fopen("/tmp/proptree.stats", "a");
+
+    MeterKidCount(rt->propertyTreeHash.entryCount);
+    JS_DHashTableEnumerate(&rt->propertyTreeHash, js_MeterPropertyTree, NULL);
+
+    {
+        double mean = 0.0, var = 0.0, sigma = 0.0;
+        double nodesum = rt->livePropTreeNodes;
+        double kidsum = js_nkids_sum;
+        if (nodesum > 0 && kidsum >= 0) {
+            mean = kidsum / nodesum;
+            var = nodesum * js_nkids_sqsum - kidsum * kidsum;
+            if (var < 0.0 || nodesum <= 1)
+                var = 0.0;
+            else
+                var /= nodesum * (nodesum - 1);
+
+            /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
+            sigma = (var != 0.0) ? sqrt(var) : 0.0;
+        }
+
+        fprintf(logfp,
+                "props %u nodes %g beta %g meankids %g sigma %g max %u",
+                rt->liveScopeProps, nodesum, nodesum / rt->liveScopeProps,
+                mean, sigma, js_nkids_max);
+    }
+
+    fprintf(logfp, " histogram %u %u %u %u %u %u %u %u %u %u %u",
+            js_nkids_hist[0], js_nkids_hist[1],
+            js_nkids_hist[2], js_nkids_hist[3],
+            js_nkids_hist[4], js_nkids_hist[5],
+            js_nkids_hist[6], js_nkids_hist[7],
+            js_nkids_hist[8], js_nkids_hist[9],
+            js_nkids_hist[10]);
+    js_nkids_sum = js_nkids_max = 0;
+    js_nkids_sqsum = 0;
+    memset(js_nkids_hist, 0, sizeof js_nkids_hist);
+#endif
+
+    ap = &rt->propertyArenaPool.first.next;
+    while ((a = *ap) != NULL) {
+        limit = (JSScopeProperty *) a->avail;
+        liveCount = 0;
+        for (sprop = (JSScopeProperty *) a->base; sprop < limit; sprop++) {
+            /* If the id is null, sprop is already on the freelist. */
+            if (sprop->id == JSVAL_NULL)
+                continue;
+
+            /* If the mark bit is set, sprop is alive, so we skip it. */
+            if (sprop->flags & SPROP_MARK) {
+                sprop->flags &= ~SPROP_MARK;
+                liveCount++;
+                continue;
+            }
+
+            /* Ok, sprop is garbage to collect: unlink it from its parent. */
+            RemovePropertyTreeChild(rt, sprop);
+
+            /* Take care to reparent all sprop's kids to their grandparent. */
+            kids = sprop->kids;
+            if (kids) {
+                sprop->kids = NULL;
+                parent = sprop->parent;
+                if (KIDS_IS_CHUNKY(kids)) {
+                    chunk = KIDS_TO_CHUNK(kids);
+                    do {
+                        for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) {
+                            kid = chunk->kids[i];
+                            if (!kid)
+                                break;
+                            JS_ASSERT(kid->parent == sprop);
+                            InsertPropertyTreeChild(rt, parent, kid);
+                        }
+                        nextChunk = chunk->next;
+                        DestroyPropTreeKidsChunk(rt, chunk);
+                    } while ((chunk = nextChunk) != NULL);
+                } else {
+                    kid = kids;
+                    InsertPropertyTreeChild(rt, parent, kid);
+                }
+            }
+
+            /* Clear id so we know (above) that sprop is on the freelist. */
+            sprop->id = JSVAL_NULL;
+            FREENODE_INSERT(rt->propertyFreeList, sprop);
+            JS_RUNTIME_UNMETER(rt, livePropTreeNodes);
+        }
+
+        /* If a contains no live properties, return it to the malloc heap. */
+        if (liveCount == 0) {
+            for (sprop = (JSScopeProperty *) a->base; sprop < limit; sprop++)
+                FREENODE_REMOVE(sprop);
+            JS_ARENA_DESTROY(&rt->propertyArenaPool, a, ap);
+        } else {
+#ifdef DUMP_SCOPE_STATS
+            livePropCapacity += limit - (JSScopeProperty *) a->base;
+            totalLiveCount += liveCount;
+#endif
+            ap = &a->next;
+        }
+    }
+
+#ifdef DUMP_SCOPE_STATS
+    fprintf(logfp, " arenautil %g%%\n",
+            (totalLiveCount * 100.0) / livePropCapacity);
+    fflush(logfp);
+#endif
+
+#ifdef DUMP_PROPERTY_TREE
+    {
+        FILE *dumpfp = fopen("/tmp/proptree.dump", "w");
+        if (dumpfp) {
+            JSPropertyTreeEntry *pte, *end;
+
+            pte = (JSPropertyTreeEntry *) rt->propertyTreeHash.entryStore;
+            end = pte + JS_DHASH_TABLE_SIZE(&rt->propertyTreeHash);
+            while (pte < end) {
+                if (pte->child)
+                    DumpSubtree(pte->child, 0, dumpfp);
+                pte++;
+            }
+            fclose(dumpfp);
+        }
+    }
+#endif
+}
+
+JSBool
+js_InitPropertyTree(JSRuntime *rt)
+{
+    if (!JS_DHashTableInit(&rt->propertyTreeHash, &PropertyTreeHashOps, NULL,
+                           sizeof(JSPropertyTreeEntry), JS_DHASH_MIN_SIZE)) {
+        rt->propertyTreeHash.ops = NULL;
+        return JS_FALSE;
+    }
+    JS_InitArenaPool(&rt->propertyArenaPool, "properties",
+                     256 * sizeof(JSScopeProperty), sizeof(void *));
+    return JS_TRUE;
+}
+
+void
+js_FinishPropertyTree(JSRuntime *rt)
+{
+    if (rt->propertyTreeHash.ops) {
+        JS_DHashTableFinish(&rt->propertyTreeHash);
+        rt->propertyTreeHash.ops = NULL;
+    }
+    JS_FinishArenaPool(&rt->propertyArenaPool);
+}

Added: freeswitch/trunk/libs/js/src/jsscope.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsscope.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,394 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsscope_h___
+#define jsscope_h___
+/*
+ * JS symbol tables.
+ */
+#include "jstypes.h"
+#include "jsobj.h"
+#include "jsprvtd.h"
+#include "jspubtd.h"
+
+#ifdef JS_THREADSAFE
+# include "jslock.h"
+#endif
+
+/*
+ * Given P independent, non-unique properties each of size S words mapped by
+ * all scopes in a runtime, construct a property tree of N nodes each of size
+ * S+L words (L for tree linkage).  A nominal L value is 2 for leftmost-child
+ * and right-sibling links.  We hope that the N < P by enough that the space
+ * overhead of L, and the overhead of scope entries pointing at property tree
+ * nodes, is worth it.
+ *
+ * The tree construction goes as follows.  If any empty scope in the runtime
+ * has a property X added to it, find or create a node under the tree root
+ * labeled X, and set scope->lastProp to point at that node.  If any non-empty
+ * scope whose most recently added property is labeled Y has another property
+ * labeled Z added, find or create a node for Z under the node that was added
+ * for Y, and set scope->lastProp to point at that node.
+ *
+ * A property is labeled by its members' values: id, getter, setter, slot,
+ * attributes, tiny or short id, and a field telling for..in order.  Note that
+ * labels are not unique in the tree, but they are unique among a node's kids
+ * (barring rare and benign multi-threaded race condition outcomes, see below)
+ * and along any ancestor line from the tree root to a given leaf node (except
+ * for the hard case of duplicate formal parameters to a function).
+ *
+ * Thus the root of the tree represents all empty scopes, and the first ply
+ * of the tree represents all scopes containing one property, etc.  Each node
+ * in the tree can stand for any number of scopes having the same ordered set
+ * of properties, where that node was the last added to the scope.  (We need
+ * not store the root of the tree as a node, and do not -- all we need are
+ * links to its kids.)
+ *
+ * Sidebar on for..in loop order: ECMA requires no particular order, but this
+ * implementation has promised and delivered property definition order, and
+ * compatibility is king.  We could use an order number per property, which
+ * would require a sort in js_Enumerate, and an entry order generation number
+ * per scope.  An order number beats a list, which should be doubly-linked for
+ * O(1) delete.  An even better scheme is to use a parent link in the property
+ * tree, so that the ancestor line can be iterated from scope->lastProp when
+ * filling in a JSIdArray from back to front.  This parent link also helps the
+ * GC to sweep properties iteratively.
+ *
+ * What if a property Y is deleted from a scope?  If Y is the last property in
+ * the scope, we simply adjust the scope's lastProp member after we remove the
+ * scope's hash-table entry pointing at that property node.  The parent link
+ * mentioned in the for..in sidebar above makes this adjustment O(1).  But if
+ * Y comes between X and Z in the scope, then we might have to "fork" the tree
+ * at X, leaving X->Y->Z in case other scopes have those properties added in
+ * that order; and to finish the fork, we'd add a node labeled Z with the path
+ * X->Z, if it doesn't exist.  This could lead to lots of extra nodes, and to
+ * O(n^2) growth when deleting lots of properties.
+ *
+ * Rather, for O(1) growth all around, we should share the path X->Y->Z among
+ * scopes having those three properties added in that order, and among scopes
+ * having only X->Z where Y was deleted.  All such scopes have a lastProp that
+ * points to the Z child of Y.  But a scope in which Y was deleted does not
+ * have a table entry for Y, and when iterating that scope by traversing the
+ * ancestor line from Z, we will have to test for a table entry for each node,
+ * skipping nodes that lack entries.
+ *
+ * What if we add Y again?  X->Y->Z->Y is wrong and we'll enumerate Y twice.
+ * Therefore we must fork in such a case, if not earlier.  Because delete is
+ * "bursty", we should not fork eagerly.  Delaying a fork till we are at risk
+ * of adding Y after it was deleted already requires a flag in the JSScope, to
+ * wit, SCOPE_MIDDLE_DELETE.
+ *
+ * What about thread safety?  If the property tree operations done by requests
+ * are find-node and insert-node, then the only hazard is duplicate insertion.
+ * This is harmless except for minor bloat.  When all requests have ended or
+ * been suspended, the GC is free to sweep the tree after marking all nodes
+ * reachable from scopes, performing remove-node operations as needed.  Note
+ * also that the stable storage of the property nodes during active requests
+ * permits the property cache (see jsinterp.h) to dereference JSScopeProperty
+ * weak references safely.
+ *
+ * Is the property tree worth it compared to property storage in each table's
+ * entries?  To decide, we must find the relation <> between the words used
+ * with a property tree and the words required without a tree.
+ *
+ * Model all scopes as one super-scope of capacity T entries (T a power of 2).
+ * Let alpha be the load factor of this double hash-table.  With the property
+ * tree, each entry in the table is a word-sized pointer to a node that can be
+ * shared by many scopes.  But all such pointers are overhead compared to the
+ * situation without the property tree, where the table stores property nodes
+ * directly, as entries each of size S words.  With the property tree, we need
+ * L=2 extra words per node for siblings and kids pointers.  Without the tree,
+ * (1-alpha)*S*T words are wasted on free or removed sentinel-entries required
+ * by double hashing.
+ *
+ * Therefore,
+ *
+ *      (property tree)                 <> (no property tree)
+ *      N*(S+L) + T                     <> S*T
+ *      N*(S+L) + T                     <> P*S + (1-alpha)*S*T
+ *      N*(S+L) + alpha*T + (1-alpha)*T <> P*S + (1-alpha)*S*T
+ *
+ * Note that P is alpha*T by definition, so
+ *
+ *      N*(S+L) + P + (1-alpha)*T <> P*S + (1-alpha)*S*T
+ *      N*(S+L)                   <> P*S - P + (1-alpha)*S*T - (1-alpha)*T
+ *      N*(S+L)                   <> (P + (1-alpha)*T) * (S-1)
+ *      N*(S+L)                   <> (P + (1-alpha)*P/alpha) * (S-1)
+ *      N*(S+L)                   <> P * (1/alpha) * (S-1)
+ *
+ * Let N = P*beta for a compression ratio beta, beta <= 1:
+ *
+ *      P*beta*(S+L) <> P * (1/alpha) * (S-1)
+ *      beta*(S+L)   <> (S-1)/alpha
+ *      beta         <> (S-1)/((S+L)*alpha)
+ *
+ * For S = 6 (32-bit architectures) and L = 2, the property tree wins iff
+ *
+ *      beta < 5/(8*alpha)
+ *
+ * We ensure that alpha <= .75, so the property tree wins if beta < .83_.  An
+ * average beta from recent Mozilla browser startups was around .6.
+ *
+ * Can we reduce L?  Observe that the property tree degenerates into a list of
+ * lists if at most one property Y follows X in all scopes.  In or near such a
+ * case, we waste a word on the right-sibling link outside of the root ply of
+ * the tree.  Note also that the root ply tends to be large, so O(n^2) growth
+ * searching it is likely, indicating the need for hashing (but with increased
+ * thread safety costs).
+ *
+ * If only K out of N nodes in the property tree have more than one child, we
+ * could eliminate the sibling link and overlay a children list or hash-table
+ * pointer on the leftmost-child link (which would then be either null or an
+ * only-child link; the overlay could be tagged in the low bit of the pointer,
+ * or flagged elsewhere in the property tree node, although such a flag must
+ * not be considered when comparing node labels during tree search).
+ *
+ * For such a system, L = 1 + (K * averageChildrenTableSize) / N instead of 2.
+ * If K << N, L approaches 1 and the property tree wins if beta < .95.
+ *
+ * We observe that fan-out below the root ply of the property tree appears to
+ * have extremely low degree (see the MeterPropertyTree code that histograms
+ * child-counts in jsscope.c), so instead of a hash-table we use a linked list
+ * of child node pointer arrays ("kid chunks").  The details are isolated in
+ * jsscope.c; others must treat JSScopeProperty.kids as opaque.  We leave it
+ * strongly typed for debug-ability of the common (null or one-kid) cases.
+ *
+ * One final twist (can you stand it?): the mean number of entries per scope
+ * in Mozilla is < 5, with a large standard deviation (~8).  Instead of always
+ * allocating scope->table, we leave it null while initializing all the other
+ * scope members as if it were non-null and minimal-length.  Until a property
+ * is added that crosses the threshold of 6 or more entries for hashing, or
+ * until a "middle delete" occurs, we use linear search from scope->lastProp
+ * to find a given id, and save on the space overhead of a hash table.
+ */
+
+struct JSScope {
+    JSObjectMap     map;                /* base class state */
+    JSObject        *object;            /* object that owns this scope */
+    uint8           flags;              /* flags, see below */
+    int8            hashShift;          /* multiplicative hash shift */
+    uint16          dswIndex;           /* Deutsch-Schorr-Waite scaled index */
+    uint32          entryCount;         /* number of entries in table */
+    uint32          removedCount;       /* removed entry sentinels in table */
+    JSScopeProperty **table;            /* table of ptrs to shared tree nodes */
+    JSScopeProperty *lastProp;          /* pointer to last property added */
+#ifdef JS_THREADSAFE
+    JSContext       *ownercx;           /* creating context, NULL if shared */
+    JSThinLock      lock;               /* binary semaphore protecting scope */
+    union {                             /* union lockful and lock-free state: */
+        jsrefcount  count;              /* lock entry count for reentrancy */
+        JSScope     *link;              /* next link in rt->scopeSharingTodo */
+    } u;
+#ifdef DEBUG
+    const char      *file[4];           /* file where lock was (re-)taken */
+    unsigned int    line[4];            /* line where lock was (re-)taken */
+#endif
+#endif
+};
+
+#define OBJ_SCOPE(obj)                  ((JSScope *)(obj)->map)
+
+/* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */
+#define SCOPE_CAPACITY(scope)           JS_BIT(JS_DHASH_BITS-(scope)->hashShift)
+
+/* Scope flags and some macros to hide them from other files than jsscope.c. */
+#define SCOPE_MIDDLE_DELETE             0x0001
+#define SCOPE_SEALED                    0x0002
+
+#define SCOPE_HAD_MIDDLE_DELETE(scope)  ((scope)->flags & SCOPE_MIDDLE_DELETE)
+#define SCOPE_SET_MIDDLE_DELETE(scope)  ((scope)->flags |= SCOPE_MIDDLE_DELETE)
+#define SCOPE_CLR_MIDDLE_DELETE(scope)  ((scope)->flags &= ~SCOPE_MIDDLE_DELETE)
+
+#define SCOPE_IS_SEALED(scope)          ((scope)->flags & SCOPE_SEALED)
+#define SCOPE_SET_SEALED(scope)         ((scope)->flags |= SCOPE_SEALED)
+#if 0
+/*
+ * Don't define this, it can't be done safely because JS_LOCK_OBJ will avoid
+ * taking the lock if the object owns its scope and the scope is sealed.
+ */
+#define SCOPE_CLR_SEALED(scope)         ((scope)->flags &= ~SCOPE_SEALED)
+#endif
+
+/*
+ * A little information hiding for scope->lastProp, in case it ever becomes
+ * a tagged pointer again.
+ */
+#define SCOPE_LAST_PROP(scope)          ((scope)->lastProp)
+#define SCOPE_REMOVE_LAST_PROP(scope)   ((scope)->lastProp =                  \
+                                         (scope)->lastProp->parent)
+
+struct JSScopeProperty {
+    jsid            id;                 /* int-tagged jsval/untagged JSAtom* */
+    JSPropertyOp    getter;             /* getter and setter hooks or objects */
+    JSPropertyOp    setter;
+    uint32          slot;               /* index in obj->slots vector */
+    uint8           attrs;              /* attributes, see jsapi.h JSPROP_* */
+    uint8           flags;              /* flags, see below for defines */
+    int16           shortid;            /* tinyid, or local arg/var index */
+    JSScopeProperty *parent;            /* parent node, reverse for..in order */
+    JSScopeProperty *kids;              /* null, single child, or a tagged ptr
+                                           to many-kids data structure */
+};
+
+/* JSScopeProperty pointer tag bit indicating a collision. */
+#define SPROP_COLLISION                 ((jsuword)1)
+#define SPROP_REMOVED                   ((JSScopeProperty *) SPROP_COLLISION)
+
+/* Macros to get and set sprop pointer values and collision flags. */
+#define SPROP_IS_FREE(sprop)            ((sprop) == NULL)
+#define SPROP_IS_REMOVED(sprop)         ((sprop) == SPROP_REMOVED)
+#define SPROP_IS_LIVE(sprop)            ((sprop) > SPROP_REMOVED)
+#define SPROP_FLAG_COLLISION(spp,sprop) (*(spp) = (JSScopeProperty *)         \
+                                         ((jsuword)(sprop) | SPROP_COLLISION))
+#define SPROP_HAD_COLLISION(sprop)      ((jsuword)(sprop) & SPROP_COLLISION)
+#define SPROP_FETCH(spp)                SPROP_CLEAR_COLLISION(*(spp))
+
+#define SPROP_CLEAR_COLLISION(sprop)                                          \
+    ((JSScopeProperty *) ((jsuword)(sprop) & ~SPROP_COLLISION))
+
+#define SPROP_STORE_PRESERVING_COLLISION(spp, sprop)                          \
+    (*(spp) = (JSScopeProperty *) ((jsuword)(sprop)                           \
+                                   | SPROP_HAD_COLLISION(*(spp))))
+
+/* Bits stored in sprop->flags. */
+#define SPROP_MARK                      0x01
+#define SPROP_IS_DUPLICATE              0x02
+#define SPROP_IS_ALIAS                  0x04
+#define SPROP_HAS_SHORTID               0x08
+#define SPROP_IS_HIDDEN                 0x10    /* a normally-hidden property,
+                                                   e.g., function arg or var */
+
+/*
+ * If SPROP_HAS_SHORTID is set in sprop->flags, we use sprop->shortid rather
+ * than id when calling sprop's getter or setter.
+ */
+#define SPROP_USERID(sprop)                                                   \
+    (((sprop)->flags & SPROP_HAS_SHORTID) ? INT_TO_JSVAL((sprop)->shortid)    \
+                                          : ID_TO_VALUE((sprop)->id))
+
+#define SPROP_INVALID_SLOT              0xffffffff
+
+#define SPROP_HAS_VALID_SLOT(sprop, scope)                                    \
+    ((sprop)->slot < (scope)->map.freeslot)
+
+#define SPROP_HAS_STUB_GETTER(sprop)    (!(sprop)->getter)
+#define SPROP_HAS_STUB_SETTER(sprop)    (!(sprop)->setter)
+
+#define SPROP_CALL_GETTER(cx,sprop,getter,obj,obj2,vp)                        \
+    (!(getter) ||                                                             \
+     (getter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
+#define SPROP_CALL_SETTER(cx,sprop,setter,obj,obj2,vp)                        \
+    (!(setter) ||                                                             \
+     (setter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp))
+
+#define SPROP_GET(cx,sprop,obj,obj2,vp)                                       \
+    (((sprop)->attrs & JSPROP_GETTER)                                         \
+     ? js_InternalGetOrSet(cx, obj, (sprop)->id,                              \
+                           OBJECT_TO_JSVAL((sprop)->getter), JSACC_READ,      \
+                           0, 0, vp)                                          \
+     : SPROP_CALL_GETTER(cx, sprop, (sprop)->getter, obj, obj2, vp))
+
+#define SPROP_SET(cx,sprop,obj,obj2,vp)                                       \
+    (((sprop)->attrs & JSPROP_SETTER)                                         \
+     ? js_InternalGetOrSet(cx, obj, (sprop)->id,                              \
+                           OBJECT_TO_JSVAL((sprop)->setter), JSACC_WRITE,     \
+                           1, vp, vp)                                         \
+     : ((sprop)->attrs & JSPROP_GETTER)                                       \
+     ? (JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,                    \
+                             JSMSG_GETTER_ONLY, NULL), JS_FALSE)              \
+     : SPROP_CALL_SETTER(cx, sprop, (sprop)->setter, obj, obj2, vp))
+
+/* Macro for common expression to test for shared permanent attributes. */
+#define SPROP_IS_SHARED_PERMANENT(sprop)                                      \
+    ((~(sprop)->attrs & (JSPROP_SHARED | JSPROP_PERMANENT)) == 0)
+
+extern JSScope *
+js_GetMutableScope(JSContext *cx, JSObject *obj);
+
+extern JSScope *
+js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp,
+            JSObject *obj);
+
+extern void
+js_DestroyScope(JSContext *cx, JSScope *scope);
+
+#define ID_TO_VALUE(id) (JSID_IS_ATOM(id) ? ATOM_JSID_TO_JSVAL(id) :          \
+                         JSID_IS_OBJECT(id) ? OBJECT_JSID_TO_JSVAL(id) :      \
+                         (jsval)(id))
+#define HASH_ID(id)     (JSID_IS_ATOM(id) ? JSID_TO_ATOM(id)->number :        \
+                         JSID_IS_OBJECT(id) ? (jsatomid) JSID_CLRTAG(id) :    \
+                         (jsatomid) JSID_TO_INT(id))
+
+extern JS_FRIEND_API(JSScopeProperty **)
+js_SearchScope(JSScope *scope, jsid id, JSBool adding);
+
+#define SCOPE_GET_PROPERTY(scope, id)                                         \
+    SPROP_FETCH(js_SearchScope(scope, id, JS_FALSE))
+
+#define SCOPE_HAS_PROPERTY(scope, sprop)                                      \
+    (SCOPE_GET_PROPERTY(scope, (sprop)->id) == (sprop))
+
+extern JSScopeProperty *
+js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id,
+                    JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
+                    uintN attrs, uintN flags, intN shortid);
+
+extern JSScopeProperty *
+js_ChangeScopePropertyAttrs(JSContext *cx, JSScope *scope,
+                            JSScopeProperty *sprop, uintN attrs, uintN mask,
+                            JSPropertyOp getter, JSPropertyOp setter);
+
+extern JSBool
+js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id);
+
+extern void
+js_ClearScope(JSContext *cx, JSScope *scope);
+
+#define MARK_SCOPE_PROPERTY(sprop)      ((sprop)->flags |= SPROP_MARK)
+
+extern void
+js_SweepScopeProperties(JSRuntime *rt);
+
+extern JSBool
+js_InitPropertyTree(JSRuntime *rt);
+
+extern void
+js_FinishPropertyTree(JSRuntime *rt);
+
+#endif /* jsscope_h___ */

Added: freeswitch/trunk/libs/js/src/jsscript.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsscript.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1473 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS script operations.
+ */
+#include "jsstddef.h"
+#include <string.h>
+#include "jstypes.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jsatom.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsdbgapi.h"
+#include "jsemit.h"
+#include "jsfun.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsopcode.h"
+#include "jsscript.h"
+#if JS_HAS_XDR
+#include "jsxdrapi.h"
+#endif
+
+#if JS_HAS_SCRIPT_OBJECT
+
+static const char js_script_exec[] = "Script.prototype.exec";
+static const char js_script_compile[] = "Script.prototype.compile";
+
+#if JS_HAS_TOSOURCE
+static JSBool
+script_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    JSScript *script;
+    size_t i, j, k, n;
+    char buf[16];
+    jschar *s, *t;
+    uint32 indent;
+    JSString *str;
+
+    if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
+        return JS_FALSE;
+    script = (JSScript *) JS_GetPrivate(cx, obj);
+
+    /* Let n count the source string length, j the "front porch" length. */
+    j = JS_snprintf(buf, sizeof buf, "(new %s(", js_ScriptClass.name);
+    n = j + 2;
+    if (!script) {
+        /* Let k count the constructor argument string length. */
+        k = 0;
+        s = NULL;               /* quell GCC overwarning */
+    } else {
+        indent = 0;
+        if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
+            return JS_FALSE;
+        str = JS_DecompileScript(cx, script, "Script.prototype.toSource",
+                                 (uintN)indent);
+        if (!str)
+            return JS_FALSE;
+        str = js_QuoteString(cx, str, '\'');
+        if (!str)
+            return JS_FALSE;
+        s = JSSTRING_CHARS(str);
+        k = JSSTRING_LENGTH(str);
+        n += k;
+    }
+
+    /* Allocate the source string and copy into it. */
+    t = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar));
+    if (!t)
+        return JS_FALSE;
+    for (i = 0; i < j; i++)
+        t[i] = buf[i];
+    for (j = 0; j < k; i++, j++)
+        t[i] = s[j];
+    t[i++] = ')';
+    t[i++] = ')';
+    t[i] = 0;
+
+    /* Create and return a JS string for t. */
+    str = JS_NewUCString(cx, t, n);
+    if (!str) {
+        JS_free(cx, t);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+#endif /* JS_HAS_TOSOURCE */
+
+static JSBool
+script_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    JSScript *script;
+    uint32 indent;
+    JSString *str;
+
+    if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
+        return JS_FALSE;
+    script = (JSScript *) JS_GetPrivate(cx, obj);
+    if (!script) {
+        *rval = STRING_TO_JSVAL(cx->runtime->emptyString);
+        return JS_TRUE;
+    }
+
+    indent = 0;
+    if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
+        return JS_FALSE;
+    str = JS_DecompileScript(cx, script, "Script.prototype.toString",
+                             (uintN)indent);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+script_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    JSScript *oldscript, *script;
+    JSString *str;
+    JSStackFrame *fp, *caller;
+    JSObject *scopeobj;
+    const char *file;
+    uintN line;
+    JSPrincipals *principals;
+
+    /* Make sure obj is a Script object. */
+    if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
+        return JS_FALSE;
+
+    /* If no args, leave private undefined and return early. */
+    if (argc == 0)
+        goto out;
+
+    /* Otherwise, the first arg is the script source to compile. */
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(str);
+
+    /* Compile using the caller's scope chain, which js_Invoke passes to fp. */
+    fp = cx->fp;
+    caller = JS_GetScriptedCaller(cx, fp);
+    JS_ASSERT(!caller || fp->scopeChain == caller->scopeChain);
+
+    scopeobj = NULL;
+    if (argc >= 2) {
+        if (!js_ValueToObject(cx, argv[1], &scopeobj))
+            return JS_FALSE;
+        argv[1] = OBJECT_TO_JSVAL(scopeobj);
+    }
+    if (caller) {
+        if (!scopeobj)
+            scopeobj = caller->scopeChain;
+
+        file = caller->script->filename;
+        line = js_PCToLineNumber(cx, caller->script, caller->pc);
+        principals = JS_EvalFramePrincipals(cx, fp, caller);
+    } else {
+        file = NULL;
+        line = 0;
+        principals = NULL;
+    }
+
+    /* Ensure we compile this script with the right (inner) principals. */
+    scopeobj = js_CheckScopeChainValidity(cx, scopeobj, js_script_compile);
+    if (!scopeobj)
+        return JS_FALSE;
+
+    /*
+     * Compile the new script using the caller's scope chain, a la eval().
+     * Unlike jsobj.c:obj_eval, however, we do not set JSFRAME_EVAL in fp's
+     * flags, because compilation is here separated from execution, and the
+     * run-time scope chain may not match the compile-time.  JSFRAME_EVAL is
+     * tested in jsemit.c and jsscan.c to optimize based on identity of run-
+     * and compile-time scope.
+     */
+    fp->flags |= JSFRAME_SCRIPT_OBJECT;
+    script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals,
+                                             JSSTRING_CHARS(str),
+                                             JSSTRING_LENGTH(str),
+                                             file, line);
+    if (!script)
+        return JS_FALSE;
+
+    /* Swap script for obj's old script, if any. */
+    oldscript = (JSScript *) JS_GetPrivate(cx, obj);
+    if (!JS_SetPrivate(cx, obj, script)) {
+        js_DestroyScript(cx, script);
+        return JS_FALSE;
+    }
+    if (oldscript)
+        js_DestroyScript(cx, oldscript);
+
+    script->object = obj;
+out:
+    /* Return the object. */
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+static JSBool
+script_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSScript *script;
+    JSObject *scopeobj, *parent;
+    JSStackFrame *fp, *caller;
+    JSPrincipals *principals;
+
+    if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
+        return JS_FALSE;
+    script = (JSScript *) JS_GetPrivate(cx, obj);
+    if (!script)
+        return JS_TRUE;
+
+    scopeobj = NULL;
+    if (argc) {
+        if (!js_ValueToObject(cx, argv[0], &scopeobj))
+            return JS_FALSE;
+        argv[0] = OBJECT_TO_JSVAL(scopeobj);
+    }
+
+    /*
+     * Emulate eval() by using caller's this, var object, sharp array, etc.,
+     * all propagated by js_Execute via a non-null fourth (down) argument to
+     * js_Execute.  If there is no scripted caller, js_Execute uses its second
+     * (chain) argument to set the exec frame's varobj, thisp, and scopeChain.
+     *
+     * Unlike eval, which the compiler detects, Script.prototype.exec may be
+     * called from a lightweight function, or even from native code (in which
+     * case fp->varobj and fp->scopeChain are null).  If exec is called from
+     * a lightweight function, we will need to get a Call object representing
+     * its frame, to act as the var object and scope chain head.
+     */
+    fp = cx->fp;
+    caller = JS_GetScriptedCaller(cx, fp);
+    if (caller && !caller->varobj) {
+        /* Called from a lightweight function. */
+        JS_ASSERT(caller->fun && !(caller->fun->flags & JSFUN_HEAVYWEIGHT));
+
+        /* Scope chain links from Call object to callee's parent. */
+        parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(caller->argv[-2]));
+        if (!js_GetCallObject(cx, caller, parent))
+            return JS_FALSE;
+    }
+
+    if (!scopeobj) {
+        /* No scope object passed in: try to use the caller's scope chain. */
+        if (caller) {
+            /*
+             * Load caller->scopeChain after the conditional js_GetCallObject
+             * call above, which resets scopeChain as well as varobj.
+             */
+            scopeobj = caller->scopeChain;
+        } else {
+            /*
+             * Called from native code, so we don't know what scope object to
+             * use.  We could use parent (see above), but Script.prototype.exec
+             * might be a shared/sealed "superglobal" method.  A more general
+             * approach would use cx->globalObject, which will be the same as
+             * exec.__parent__ in the non-superglobal case.  In the superglobal
+             * case it's the right object: the global, not the superglobal.
+             */
+            scopeobj = cx->globalObject;
+        }
+    }
+
+    scopeobj = js_CheckScopeChainValidity(cx, scopeobj, js_script_exec);
+    if (!scopeobj)
+        return JS_FALSE;
+
+    /* Belt-and-braces: check that this script object has access to scopeobj. */
+    principals = script->principals;
+    if (!js_CheckPrincipalsAccess(cx, scopeobj, principals, js_script_exec))
+        return JS_FALSE;
+
+    return js_Execute(cx, scopeobj, script, caller, JSFRAME_EVAL, rval);
+}
+
+#if JS_HAS_XDR
+
+static JSBool
+XDRAtomListElement(JSXDRState *xdr, JSAtomListElement *ale)
+{
+    jsval value;
+    jsatomid index;
+
+    if (xdr->mode == JSXDR_ENCODE)
+        value = ATOM_KEY(ALE_ATOM(ale));
+
+    index = ALE_INDEX(ale);
+    if (!JS_XDRUint32(xdr, &index))
+        return JS_FALSE;
+    ALE_SET_INDEX(ale, index);
+
+    if (!JS_XDRValue(xdr, &value))
+        return JS_FALSE;
+
+    if (xdr->mode == JSXDR_DECODE) {
+        if (!ALE_SET_ATOM(ale, js_AtomizeValue(xdr->cx, value, 0)))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+XDRAtomMap(JSXDRState *xdr, JSAtomMap *map)
+{
+    uint32 length;
+    uintN i;
+    JSBool ok;
+
+    if (xdr->mode == JSXDR_ENCODE)
+        length = map->length;
+
+    if (!JS_XDRUint32(xdr, &length))
+        return JS_FALSE;
+
+    if (xdr->mode == JSXDR_DECODE) {
+        JSContext *cx;
+        void *mark;
+        JSAtomList al;
+        JSAtomListElement *ale;
+
+        cx = xdr->cx;
+        mark = JS_ARENA_MARK(&cx->tempPool);
+        ATOM_LIST_INIT(&al);
+        for (i = 0; i < length; i++) {
+            JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool);
+            if (!ale ||
+                !XDRAtomListElement(xdr, ale)) {
+                if (!ale)
+                    JS_ReportOutOfMemory(cx);
+                JS_ARENA_RELEASE(&cx->tempPool, mark);
+                return JS_FALSE;
+            }
+            ALE_SET_NEXT(ale, al.list);
+            al.count++;
+            al.list = ale;
+        }
+        ok = js_InitAtomMap(cx, map, &al);
+        JS_ARENA_RELEASE(&cx->tempPool, mark);
+        return ok;
+    }
+
+    if (xdr->mode == JSXDR_ENCODE) {
+        JSAtomListElement ale;
+
+        for (i = 0; i < map->length; i++) {
+            ALE_SET_ATOM(&ale, map->vector[i]);
+            ALE_SET_INDEX(&ale, i);
+            if (!XDRAtomListElement(xdr, &ale))
+                return JS_FALSE;
+        }
+    }
+    return JS_TRUE;
+}
+
+JSBool
+js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic)
+{
+    JSContext *cx;
+    JSScript *script, *newscript;
+    uint32 length, lineno, depth, magic, nsrcnotes, ntrynotes;
+    uint32 prologLength, version;
+    JSBool filenameWasSaved;
+    jssrcnote *notes, *sn;
+
+    cx = xdr->cx;
+    script = *scriptp;
+    nsrcnotes = ntrynotes = 0;
+    filenameWasSaved = JS_FALSE;
+    notes = NULL;
+
+    /*
+     * Encode prologLength and version after script->length (_2 or greater),
+     * but decode both new (>= _2) and old, prolog&version-free (_1) scripts.
+     * Version _3 supports principals serialization.  Version _4 reorders the
+     * nsrcnotes and ntrynotes fields to come before everything except magic,
+     * length, prologLength, and version, so that srcnote and trynote storage
+     * can be allocated as part of the JSScript (along with bytecode storage).
+     */
+    if (xdr->mode == JSXDR_ENCODE)
+        magic = JSXDR_MAGIC_SCRIPT_CURRENT;
+    if (!JS_XDRUint32(xdr, &magic))
+        return JS_FALSE;
+    if (magic != JSXDR_MAGIC_SCRIPT_4 &&
+        magic != JSXDR_MAGIC_SCRIPT_3 &&
+        magic != JSXDR_MAGIC_SCRIPT_2 &&
+        magic != JSXDR_MAGIC_SCRIPT_1) {
+        if (!hasMagic) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_BAD_SCRIPT_MAGIC);
+            return JS_FALSE;
+        }
+        *hasMagic = JS_FALSE;
+        return JS_TRUE;
+    }
+    if (hasMagic)
+        *hasMagic = JS_TRUE;
+
+    if (xdr->mode == JSXDR_ENCODE) {
+        length = script->length;
+        prologLength = PTRDIFF(script->main, script->code, jsbytecode);
+        JS_ASSERT((int16)script->version != JSVERSION_UNKNOWN);
+        version = (uint32)script->version | (script->numGlobalVars << 16);
+        lineno = (uint32)script->lineno;
+        depth = (uint32)script->depth;
+
+        /* Count the srcnotes, keeping notes pointing at the first one. */
+        notes = SCRIPT_NOTES(script);
+        for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
+            continue;
+        nsrcnotes = PTRDIFF(sn, notes, jssrcnote);
+        nsrcnotes++;            /* room for the terminator */
+
+        /* Count the trynotes. */
+        if (script->trynotes) {
+            while (script->trynotes[ntrynotes].catchStart)
+                ntrynotes++;
+            ntrynotes++;        /* room for the end marker */
+        }
+    }
+
+    if (!JS_XDRUint32(xdr, &length))
+        return JS_FALSE;
+    if (magic >= JSXDR_MAGIC_SCRIPT_2) {
+        if (!JS_XDRUint32(xdr, &prologLength))
+            return JS_FALSE;
+        if (!JS_XDRUint32(xdr, &version))
+            return JS_FALSE;
+
+        /* To fuse allocations, we need srcnote and trynote counts early. */
+        if (magic >= JSXDR_MAGIC_SCRIPT_4) {
+            if (!JS_XDRUint32(xdr, &nsrcnotes))
+                return JS_FALSE;
+            if (!JS_XDRUint32(xdr, &ntrynotes))
+                return JS_FALSE;
+        }
+    }
+
+    if (xdr->mode == JSXDR_DECODE) {
+        script = js_NewScript(cx, length, nsrcnotes, ntrynotes);
+        if (!script)
+            return JS_FALSE;
+        if (magic >= JSXDR_MAGIC_SCRIPT_2) {
+            script->main += prologLength;
+            script->version = (JSVersion) (version & 0xffff);
+            script->numGlobalVars = (uint16) (version >> 16);
+
+            /* If we know nsrcnotes, we allocated space for notes in script. */
+            if (magic >= JSXDR_MAGIC_SCRIPT_4)
+                notes = SCRIPT_NOTES(script);
+        }
+        *scriptp = script;
+    }
+
+    /*
+     * Control hereafter must goto error on failure, in order for the DECODE
+     * case to destroy script and conditionally free notes, which if non-null
+     * in the (DECODE and magic < _4) case must point at a temporary vector
+     * allocated just below.
+     */
+    if (!JS_XDRBytes(xdr, (char *)script->code, length * sizeof(jsbytecode)) ||
+        !XDRAtomMap(xdr, &script->atomMap)) {
+        goto error;
+    }
+
+    if (magic < JSXDR_MAGIC_SCRIPT_4) {
+        if (!JS_XDRUint32(xdr, &nsrcnotes))
+            goto error;
+        if (xdr->mode == JSXDR_DECODE) {
+            notes = (jssrcnote *) JS_malloc(cx, nsrcnotes * sizeof(jssrcnote));
+            if (!notes)
+                goto error;
+        }
+    }
+
+    if (!JS_XDRBytes(xdr, (char *)notes, nsrcnotes * sizeof(jssrcnote)) ||
+        !JS_XDRCStringOrNull(xdr, (char **)&script->filename) ||
+        !JS_XDRUint32(xdr, &lineno) ||
+        !JS_XDRUint32(xdr, &depth) ||
+        (magic < JSXDR_MAGIC_SCRIPT_4 && !JS_XDRUint32(xdr, &ntrynotes))) {
+        goto error;
+    }
+
+    /* Script principals transcoding support comes with versions >= _3. */
+    if (magic >= JSXDR_MAGIC_SCRIPT_3) {
+        JSPrincipals *principals;
+        uint32 encodeable;
+
+        if (xdr->mode == JSXDR_ENCODE) {
+            principals = script->principals;
+            encodeable = (cx->runtime->principalsTranscoder != NULL);
+            if (!JS_XDRUint32(xdr, &encodeable))
+                goto error;
+            if (encodeable &&
+                !cx->runtime->principalsTranscoder(xdr, &principals)) {
+                goto error;
+            }
+        } else {
+            if (!JS_XDRUint32(xdr, &encodeable))
+                goto error;
+            if (encodeable) {
+                if (!cx->runtime->principalsTranscoder) {
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                         JSMSG_CANT_DECODE_PRINCIPALS);
+                    goto error;
+                }
+                if (!cx->runtime->principalsTranscoder(xdr, &principals))
+                    goto error;
+                script->principals = principals;
+            }
+        }
+    }
+
+    if (xdr->mode == JSXDR_DECODE) {
+        const char *filename = script->filename;
+        if (filename) {
+            filename = js_SaveScriptFilename(cx, filename);
+            if (!filename)
+                goto error;
+            JS_free(cx, (void *) script->filename);
+            script->filename = filename;
+            filenameWasSaved = JS_TRUE;
+        }
+        script->lineno = (uintN)lineno;
+        script->depth = (uintN)depth;
+
+        if (magic < JSXDR_MAGIC_SCRIPT_4) {
+            /*
+             * Argh, we have to reallocate script, copy notes into the extra
+             * space after the bytecodes, and free the temporary notes vector.
+             * First, add enough slop to nsrcnotes so we can align the address
+             * after the srcnotes of the first trynote.
+             */
+            uint32 osrcnotes = nsrcnotes;
+
+            if (ntrynotes)
+                nsrcnotes += JSTRYNOTE_ALIGNMASK;
+            newscript = (JSScript *) JS_realloc(cx, script,
+                                                sizeof(JSScript) +
+                                                length * sizeof(jsbytecode) +
+                                                nsrcnotes * sizeof(jssrcnote) +
+                                                ntrynotes * sizeof(JSTryNote));
+            if (!newscript)
+                goto error;
+
+            *scriptp = script = newscript;
+            script->code = (jsbytecode *)(script + 1);
+            script->main = script->code + prologLength;
+            memcpy(script->code + length, notes, osrcnotes * sizeof(jssrcnote));
+            JS_free(cx, (void *) notes);
+            notes = NULL;
+            if (ntrynotes) {
+                script->trynotes = (JSTryNote *)
+                                   ((jsword)(SCRIPT_NOTES(script) + nsrcnotes) &
+                                    ~(jsword)JSTRYNOTE_ALIGNMASK);
+                memset(script->trynotes, 0, ntrynotes * sizeof(JSTryNote));
+            }
+        }
+    }
+
+    while (ntrynotes) {
+        JSTryNote *tn = &script->trynotes[--ntrynotes];
+        uint32 start = (uint32) tn->start,
+               catchLength = (uint32) tn->length,
+               catchStart = (uint32) tn->catchStart;
+
+        if (!JS_XDRUint32(xdr, &start) ||
+            !JS_XDRUint32(xdr, &catchLength) ||
+            !JS_XDRUint32(xdr, &catchStart)) {
+            goto error;
+        }
+        tn->start = (ptrdiff_t) start;
+        tn->length = (ptrdiff_t) catchLength;
+        tn->catchStart = (ptrdiff_t) catchStart;
+    }
+    return JS_TRUE;
+
+  error:
+    if (xdr->mode == JSXDR_DECODE) {
+        if (script->filename && !filenameWasSaved) {
+            JS_free(cx, (void *) script->filename);
+            script->filename = NULL;
+        }
+        if (notes && magic < JSXDR_MAGIC_SCRIPT_4)
+            JS_free(cx, (void *) notes);
+        js_DestroyScript(cx, script);
+        *scriptp = NULL;
+    }
+    return JS_FALSE;
+}
+
+#if JS_HAS_XDR_FREEZE_THAW
+/*
+ * These cannot be exposed to web content, and chrome does not need them, so
+ * we take them out of the Mozilla client altogether.  Fortunately, there is
+ * no way to serialize a native function (see fun_xdrObject in jsfun.c).
+ */
+
+static JSBool
+script_freeze(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    JSXDRState *xdr;
+    JSScript *script;
+    JSBool ok, hasMagic;
+    uint32 len;
+    void *buf;
+    JSString *str;
+
+    if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
+        return JS_FALSE;
+    script = (JSScript *) JS_GetPrivate(cx, obj);
+    if (!script)
+        return JS_TRUE;
+
+    /* create new XDR */
+    xdr = JS_XDRNewMem(cx, JSXDR_ENCODE);
+    if (!xdr)
+        return JS_FALSE;
+
+    /* write  */
+    ok = js_XDRScript(xdr, &script, &hasMagic);
+    if (!ok)
+        goto out;
+    if (!hasMagic) {
+        *rval = JSVAL_VOID;
+        goto out;
+    }
+
+    buf = JS_XDRMemGetData(xdr, &len);
+    if (!buf) {
+        ok = JS_FALSE;
+        goto out;
+    }
+
+    JS_ASSERT((jsword)buf % sizeof(jschar) == 0);
+    len /= sizeof(jschar);
+    str = JS_NewUCStringCopyN(cx, (jschar *)buf, len);
+    if (!str) {
+        ok = JS_FALSE;
+        goto out;
+    }
+
+#if IS_BIG_ENDIAN
+  {
+    jschar *chars;
+    uint32 i;
+
+    /* Swap bytes in Unichars to keep frozen strings machine-independent. */
+    chars = JS_GetStringChars(str);
+    for (i = 0; i < len; i++)
+        chars[i] = JSXDR_SWAB16(chars[i]);
+  }
+#endif
+    *rval = STRING_TO_JSVAL(str);
+
+out:
+    JS_XDRDestroy(xdr);
+    return ok;
+}
+
+static JSBool
+script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+            jsval *rval)
+{
+    JSXDRState *xdr;
+    JSString *str;
+    void *buf;
+    uint32 len;
+    JSScript *script, *oldscript;
+    JSBool ok, hasMagic;
+
+    if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
+        return JS_FALSE;
+
+    if (argc == 0)
+        return JS_TRUE;
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(str);
+
+    /* create new XDR */
+    xdr = JS_XDRNewMem(cx, JSXDR_DECODE);
+    if (!xdr)
+        return JS_FALSE;
+
+    buf = JS_GetStringChars(str);
+    len = JS_GetStringLength(str);
+#if IS_BIG_ENDIAN
+  {
+    jschar *from, *to;
+    uint32 i;
+
+    /* Swap bytes in Unichars to keep frozen strings machine-independent. */
+    from = (jschar *)buf;
+    to = (jschar *) JS_malloc(cx, len * sizeof(jschar));
+    if (!to) {
+        JS_XDRDestroy(xdr);
+        return JS_FALSE;
+    }
+    for (i = 0; i < len; i++)
+        to[i] = JSXDR_SWAB16(from[i]);
+    buf = (char *)to;
+  }
+#endif
+    len *= sizeof(jschar);
+    JS_XDRMemSetData(xdr, buf, len);
+
+    /* XXXbe should magic mismatch be error, or false return value? */
+    ok = js_XDRScript(xdr, &script, &hasMagic);
+    if (!ok)
+        goto out;
+    if (!hasMagic) {
+        *rval = JSVAL_FALSE;
+        goto out;
+    }
+
+    /* Swap script for obj's old script, if any. */
+    oldscript = (JSScript *) JS_GetPrivate(cx, obj);
+    ok = JS_SetPrivate(cx, obj, script);
+    if (!ok) {
+        JS_free(cx, script);
+        goto out;
+    }
+    if (oldscript)
+        js_DestroyScript(cx, oldscript);
+
+    script->object = obj;
+    js_CallNewScriptHook(cx, script, NULL);
+
+out:
+    /*
+     * We reset the buffer to be NULL so that it doesn't free the chars
+     * memory owned by str (argv[0]).
+     */
+    JS_XDRMemSetData(xdr, NULL, 0);
+    JS_XDRDestroy(xdr);
+#if IS_BIG_ENDIAN
+    JS_free(cx, buf);
+#endif
+    *rval = JSVAL_TRUE;
+    return ok;
+}
+
+static const char js_thaw_str[] = "thaw";
+
+#endif /* JS_HAS_XDR_FREEZE_THAW */
+#endif /* JS_HAS_XDR */
+
+static JSFunctionSpec script_methods[] = {
+#if JS_HAS_TOSOURCE
+    {js_toSource_str,   script_toSource,        0,0,0},
+#endif
+    {js_toString_str,   script_toString,        0,0,0},
+    {"compile",         script_compile,         2,0,0},
+    {"exec",            script_exec,            1,0,0},
+#if JS_HAS_XDR_FREEZE_THAW
+    {"freeze",          script_freeze,          0,0,0},
+    {js_thaw_str,       script_thaw,            1,0,0},
+#endif /* JS_HAS_XDR_FREEZE_THAW */
+    {0,0,0,0,0}
+};
+
+#endif /* JS_HAS_SCRIPT_OBJECT */
+
+static void
+script_finalize(JSContext *cx, JSObject *obj)
+{
+    JSScript *script;
+
+    script = (JSScript *) JS_GetPrivate(cx, obj);
+    if (script)
+        js_DestroyScript(cx, script);
+}
+
+static JSBool
+script_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+#if JS_HAS_SCRIPT_OBJECT
+    return script_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);
+#else
+    return JS_FALSE;
+#endif
+}
+
+static uint32
+script_mark(JSContext *cx, JSObject *obj, void *arg)
+{
+    JSScript *script;
+
+    script = (JSScript *) JS_GetPrivate(cx, obj);
+    if (script)
+        js_MarkScript(cx, script, arg);
+    return 0;
+}
+
+JS_FRIEND_DATA(JSClass) js_ScriptClass = {
+    js_Script_str,
+    JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   script_finalize,
+    NULL,             NULL,             script_call,      NULL,/*XXXbe xdr*/
+    NULL,             NULL,             script_mark,      0
+};
+
+#if JS_HAS_SCRIPT_OBJECT
+
+static JSBool
+Script(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    /* If not constructing, replace obj with a new Script object. */
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
+        if (!obj)
+            return JS_FALSE;
+    }
+    return script_compile(cx, obj, argc, argv, rval);
+}
+
+#if JS_HAS_XDR_FREEZE_THAW
+
+static JSBool
+script_static_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                   jsval *rval)
+{
+    obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
+    if (!obj)
+        return JS_FALSE;
+    if (!script_thaw(cx, obj, argc, argv, rval))
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+static JSFunctionSpec script_static_methods[] = {
+    {js_thaw_str,       script_static_thaw,     1,0,0},
+    {0,0,0,0,0}
+};
+
+#else  /* !JS_HAS_XDR_FREEZE_THAW */
+
+#define script_static_methods   NULL
+
+#endif /* !JS_HAS_XDR_FREEZE_THAW */
+
+JSObject *
+js_InitScriptClass(JSContext *cx, JSObject *obj)
+{
+    return JS_InitClass(cx, obj, NULL, &js_ScriptClass, Script, 1,
+                        NULL, script_methods, NULL, script_static_methods);
+}
+
+#endif /* JS_HAS_SCRIPT_OBJECT */
+
+/*
+ * Shared script filename management.
+ */
+JS_STATIC_DLL_CALLBACK(int)
+js_compare_strings(const void *k1, const void *k2)
+{
+    return strcmp(k1, k2) == 0;
+}
+
+/* Shared with jsatom.c to save code space. */
+extern void * JS_DLL_CALLBACK
+js_alloc_table_space(void *priv, size_t size);
+
+extern void JS_DLL_CALLBACK
+js_free_table_space(void *priv, void *item);
+
+/* NB: This struct overlays JSHashEntry -- see jshash.h, do not reorganize. */
+typedef struct ScriptFilenameEntry {
+    JSHashEntry         *next;          /* hash chain linkage */
+    JSHashNumber        keyHash;        /* key hash function result */
+    const void          *key;           /* ptr to filename, below */
+    uint32              flags;          /* user-defined filename prefix flags */
+    JSPackedBool        mark;           /* GC mark flag */
+    char                filename[3];    /* two or more bytes, NUL-terminated */
+} ScriptFilenameEntry;
+
+JS_STATIC_DLL_CALLBACK(JSHashEntry *)
+js_alloc_sftbl_entry(void *priv, const void *key)
+{
+    size_t nbytes = offsetof(ScriptFilenameEntry, filename) + strlen(key) + 1;
+
+    return (JSHashEntry *) malloc(JS_MAX(nbytes, sizeof(JSHashEntry)));
+}
+
+JS_STATIC_DLL_CALLBACK(void)
+js_free_sftbl_entry(void *priv, JSHashEntry *he, uintN flag)
+{
+    if (flag != HT_FREE_ENTRY)
+        return;
+    free(he);
+}
+
+static JSHashAllocOps sftbl_alloc_ops = {
+    js_alloc_table_space,   js_free_table_space,
+    js_alloc_sftbl_entry,   js_free_sftbl_entry
+};
+
+JSBool
+js_InitRuntimeScriptState(JSRuntime *rt)
+{
+#ifdef JS_THREADSAFE
+    JS_ASSERT(!rt->scriptFilenameTableLock);
+    rt->scriptFilenameTableLock = JS_NEW_LOCK();
+    if (!rt->scriptFilenameTableLock)
+        return JS_FALSE;
+#endif
+    JS_ASSERT(!rt->scriptFilenameTable);
+    rt->scriptFilenameTable =
+        JS_NewHashTable(16, JS_HashString, js_compare_strings, NULL,
+                        &sftbl_alloc_ops, NULL);
+    if (!rt->scriptFilenameTable) {
+        js_FinishRuntimeScriptState(rt);    /* free lock if threadsafe */
+        return JS_FALSE;
+    }
+    JS_INIT_CLIST(&rt->scriptFilenamePrefixes);
+    return JS_TRUE;
+}
+
+typedef struct ScriptFilenamePrefix {
+    JSCList     links;      /* circular list linkage for easy deletion */
+    const char  *name;      /* pointer to pinned ScriptFilenameEntry string */
+    size_t      length;     /* prefix string length, precomputed */
+    uint32      flags;      /* user-defined flags to inherit from this prefix */
+} ScriptFilenamePrefix;
+
+void
+js_FinishRuntimeScriptState(JSRuntime *rt)
+{
+    if (rt->scriptFilenameTable) {
+        JS_HashTableDestroy(rt->scriptFilenameTable);
+        rt->scriptFilenameTable = NULL;
+    }
+#ifdef JS_THREADSAFE
+    if (rt->scriptFilenameTableLock) {
+        JS_DESTROY_LOCK(rt->scriptFilenameTableLock);
+        rt->scriptFilenameTableLock = NULL;
+    }
+#endif
+}
+
+void
+js_FreeRuntimeScriptState(JSRuntime *rt)
+{
+    ScriptFilenamePrefix *sfp;
+
+    while (!JS_CLIST_IS_EMPTY(&rt->scriptFilenamePrefixes)) {
+        sfp = (ScriptFilenamePrefix *) rt->scriptFilenamePrefixes.next;
+        JS_REMOVE_LINK(&sfp->links);
+        free(sfp);
+    }
+    js_FinishRuntimeScriptState(rt);
+}
+
+#ifdef DEBUG_brendan
+size_t sftbl_savings = 0;
+#endif
+
+static ScriptFilenameEntry *
+SaveScriptFilename(JSRuntime *rt, const char *filename, uint32 flags)
+{
+    JSHashTable *table;
+    JSHashNumber hash;
+    JSHashEntry **hep;
+    ScriptFilenameEntry *sfe;
+    size_t length;
+    JSCList *head, *link;
+    ScriptFilenamePrefix *sfp;
+
+    table = rt->scriptFilenameTable;
+    hash = JS_HashString(filename);
+    hep = JS_HashTableRawLookup(table, hash, filename);
+    sfe = (ScriptFilenameEntry *) *hep;
+#ifdef DEBUG_brendan
+    if (sfe)
+        sftbl_savings += strlen(sfe->filename);
+#endif
+
+    if (!sfe) {
+        sfe = (ScriptFilenameEntry *)
+              JS_HashTableRawAdd(table, hep, hash, filename, NULL);
+        if (!sfe)
+            return NULL;
+        sfe->key = strcpy(sfe->filename, filename);
+        sfe->flags = 0;
+        sfe->mark = JS_FALSE;
+    }
+
+    /* If saving a prefix, add it to the set in rt->scriptFilenamePrefixes. */
+    if (flags != 0) {
+        /* Search in case filename was saved already; we must be idempotent. */
+        sfp = NULL;
+        length = strlen(filename);
+        for (head = link = &rt->scriptFilenamePrefixes;
+             link->next != head;
+             link = link->next) {
+            /* Lag link behind sfp to insert in non-increasing length order. */
+            sfp = (ScriptFilenamePrefix *) link->next;
+            if (!strcmp(sfp->name, filename))
+                break;
+            if (sfp->length <= length) {
+                sfp = NULL;
+                break;
+            }
+            sfp = NULL;
+        }
+
+        if (!sfp) {
+            /* No such prefix: add one now. */
+            sfp = (ScriptFilenamePrefix *) malloc(sizeof(ScriptFilenamePrefix));
+            if (!sfp)
+                return NULL;
+            JS_INSERT_AFTER(&sfp->links, link);
+            sfp->name = sfe->filename;
+            sfp->length = length;
+            sfp->flags = 0;
+        }
+
+        /*
+         * Accumulate flags in both sfe and sfp: sfe for later access from the
+         * JS_GetScriptedCallerFilenameFlags debug-API, and sfp so that longer
+         * filename entries can inherit by prefix.
+         */
+        sfe->flags |= flags;
+        sfp->flags |= flags;
+    }
+
+    return sfe;
+}
+
+const char *
+js_SaveScriptFilename(JSContext *cx, const char *filename)
+{
+    JSRuntime *rt;
+    ScriptFilenameEntry *sfe;
+    JSCList *head, *link;
+    ScriptFilenamePrefix *sfp;
+
+    rt = cx->runtime;
+    JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock);
+    sfe = SaveScriptFilename(rt, filename, 0);
+    if (!sfe) {
+        JS_RELEASE_LOCK(rt->scriptFilenameTableLock);
+        JS_ReportOutOfMemory(cx);
+        return NULL;
+    }
+
+    /*
+     * Try to inherit flags by prefix.  We assume there won't be more than a
+     * few (dozen! ;-) prefixes, so linear search is tolerable.
+     * XXXbe every time I've assumed that in the JS engine, I've been wrong!
+     */
+    for (head = &rt->scriptFilenamePrefixes, link = head->next;
+         link != head;
+         link = link->next) {
+        sfp = (ScriptFilenamePrefix *) link;
+        if (!strncmp(sfp->name, filename, sfp->length)) {
+            sfe->flags |= sfp->flags;
+            break;
+        }
+    }
+    JS_RELEASE_LOCK(rt->scriptFilenameTableLock);
+    return sfe->filename;
+}
+
+const char *
+js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags)
+{
+    ScriptFilenameEntry *sfe;
+
+    /* This may be called very early, via the jsdbgapi.h entry point. */
+    if (!rt->scriptFilenameTable && !js_InitRuntimeScriptState(rt))
+        return NULL;
+
+    JS_ACQUIRE_LOCK(rt->scriptFilenameTableLock);
+    sfe = SaveScriptFilename(rt, filename, flags);
+    JS_RELEASE_LOCK(rt->scriptFilenameTableLock);
+    if (!sfe)
+        return NULL;
+
+    return sfe->filename;
+}
+
+/*
+ * Back up from a saved filename by its offset within its hash table entry.
+ */
+#define FILENAME_TO_SFE(fn) \
+    ((ScriptFilenameEntry *) ((fn) - offsetof(ScriptFilenameEntry, filename)))
+
+/*
+ * The sfe->key member, redundant given sfe->filename but required by the old
+ * jshash.c code, here gives us a useful sanity check.  This assertion will
+ * very likely botch if someone tries to mark a string that wasn't allocated
+ * as an sfe->filename.
+ */
+#define ASSERT_VALID_SFE(sfe)   JS_ASSERT((sfe)->key == (sfe)->filename)
+
+uint32
+js_GetScriptFilenameFlags(const char *filename)
+{
+    ScriptFilenameEntry *sfe;
+
+    sfe = FILENAME_TO_SFE(filename);
+    ASSERT_VALID_SFE(sfe);
+    return sfe->flags;
+}
+
+void
+js_MarkScriptFilename(const char *filename)
+{
+    ScriptFilenameEntry *sfe;
+
+    sfe = FILENAME_TO_SFE(filename);
+    ASSERT_VALID_SFE(sfe);
+    sfe->mark = JS_TRUE;
+}
+
+JS_STATIC_DLL_CALLBACK(intN)
+js_script_filename_marker(JSHashEntry *he, intN i, void *arg)
+{
+    ScriptFilenameEntry *sfe = (ScriptFilenameEntry *) he;
+
+    sfe->mark = JS_TRUE;
+    return HT_ENUMERATE_NEXT;
+}
+
+void
+js_MarkScriptFilenames(JSRuntime *rt, uintN gcflags)
+{
+    JSCList *head, *link;
+    ScriptFilenamePrefix *sfp;
+
+    if (gcflags & GC_KEEP_ATOMS) {
+        JS_HashTableEnumerateEntries(rt->scriptFilenameTable,
+                                     js_script_filename_marker,
+                                     rt);
+    }
+    for (head = &rt->scriptFilenamePrefixes, link = head->next;
+         link != head;
+         link = link->next) {
+        sfp = (ScriptFilenamePrefix *) link;
+        js_MarkScriptFilename(sfp->name);
+    }
+}
+
+JS_STATIC_DLL_CALLBACK(intN)
+js_script_filename_sweeper(JSHashEntry *he, intN i, void *arg)
+{
+    ScriptFilenameEntry *sfe = (ScriptFilenameEntry *) he;
+
+    if (!sfe->mark)
+        return HT_ENUMERATE_REMOVE;
+    sfe->mark = JS_FALSE;
+    return HT_ENUMERATE_NEXT;
+}
+
+void
+js_SweepScriptFilenames(JSRuntime *rt)
+{
+    JS_HashTableEnumerateEntries(rt->scriptFilenameTable,
+                                 js_script_filename_sweeper,
+                                 rt);
+#ifdef DEBUG_notme
+    printf("script filename table savings so far: %u\n", sftbl_savings);
+#endif
+}
+
+JSScript *
+js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 ntrynotes)
+{
+    JSScript *script;
+
+    /* Round up source note count to align script->trynotes for its type. */
+    if (ntrynotes)
+        nsrcnotes += JSTRYNOTE_ALIGNMASK;
+    script = (JSScript *) JS_malloc(cx,
+                                    sizeof(JSScript) +
+                                    length * sizeof(jsbytecode) +
+                                    nsrcnotes * sizeof(jssrcnote) +
+                                    ntrynotes * sizeof(JSTryNote));
+    if (!script)
+        return NULL;
+    memset(script, 0, sizeof(JSScript));
+    script->code = script->main = (jsbytecode *)(script + 1);
+    script->length = length;
+    script->version = cx->version;
+    if (ntrynotes) {
+        script->trynotes = (JSTryNote *)
+                           ((jsword)(SCRIPT_NOTES(script) + nsrcnotes) &
+                            ~(jsword)JSTRYNOTE_ALIGNMASK);
+        memset(script->trynotes, 0, ntrynotes * sizeof(JSTryNote));
+    }
+    return script;
+}
+
+JS_FRIEND_API(JSScript *)
+js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun)
+{
+    uint32 mainLength, prologLength, nsrcnotes, ntrynotes;
+    JSScript *script;
+    const char *filename;
+
+    mainLength = CG_OFFSET(cg);
+    prologLength = CG_PROLOG_OFFSET(cg);
+    CG_COUNT_FINAL_SRCNOTES(cg, nsrcnotes);
+    CG_COUNT_FINAL_TRYNOTES(cg, ntrynotes);
+    script = js_NewScript(cx, prologLength + mainLength, nsrcnotes, ntrynotes);
+    if (!script)
+        return NULL;
+
+    /* Now that we have script, error control flow must go to label bad. */
+    script->main += prologLength;
+    memcpy(script->code, CG_PROLOG_BASE(cg), prologLength * sizeof(jsbytecode));
+    memcpy(script->main, CG_BASE(cg), mainLength * sizeof(jsbytecode));
+    script->numGlobalVars = cg->treeContext.numGlobalVars;
+    if (!js_InitAtomMap(cx, &script->atomMap, &cg->atomList))
+        goto bad;
+
+    filename = cg->filename;
+    if (filename) {
+        script->filename = js_SaveScriptFilename(cx, filename);
+        if (!script->filename)
+            goto bad;
+    }
+    script->lineno = cg->firstLine;
+    script->depth = cg->maxStackDepth;
+    if (cg->principals) {
+        script->principals = cg->principals;
+        JSPRINCIPALS_HOLD(cx, script->principals);
+    }
+
+    if (!js_FinishTakingSrcNotes(cx, cg, SCRIPT_NOTES(script)))
+        goto bad;
+    if (script->trynotes)
+        js_FinishTakingTryNotes(cx, cg, script->trynotes);
+
+    /* Tell the debugger about this compiled script. */
+    js_CallNewScriptHook(cx, script, fun);
+    return script;
+
+bad:
+    js_DestroyScript(cx, script);
+    return NULL;
+}
+
+JS_FRIEND_API(void)
+js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun)
+{
+    JSRuntime *rt;
+    JSNewScriptHook hook;
+
+    rt = cx->runtime;
+    hook = rt->newScriptHook;
+    if (hook) {
+        JS_KEEP_ATOMS(rt);
+        hook(cx, script->filename, script->lineno, script, fun,
+             rt->newScriptHookData);
+        JS_UNKEEP_ATOMS(rt);
+    }
+}
+
+JS_FRIEND_API(void)
+js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
+{
+    JSRuntime *rt;
+    JSDestroyScriptHook hook;
+
+    rt = cx->runtime;
+    hook = rt->destroyScriptHook;
+    if (hook)
+        hook(cx, script, rt->destroyScriptHookData);
+}
+
+void
+js_DestroyScript(JSContext *cx, JSScript *script)
+{
+    js_CallDestroyScriptHook(cx, script);
+
+    JS_ClearScriptTraps(cx, script);
+    js_FreeAtomMap(cx, &script->atomMap);
+    if (script->principals)
+        JSPRINCIPALS_DROP(cx, script->principals);
+    JS_free(cx, script);
+}
+
+void
+js_MarkScript(JSContext *cx, JSScript *script, void *arg)
+{
+    JSAtomMap *map;
+    uintN i, length;
+    JSAtom **vector;
+
+    map = &script->atomMap;
+    length = map->length;
+    vector = map->vector;
+    for (i = 0; i < length; i++)
+        GC_MARK_ATOM(cx, vector[i], arg);
+
+    if (script->filename)
+        js_MarkScriptFilename(script->filename);
+}
+
+jssrcnote *
+js_GetSrcNote(JSScript *script, jsbytecode *pc)
+{
+    jssrcnote *sn;
+    ptrdiff_t offset, target;
+
+    target = PTRDIFF(pc, script->code, jsbytecode);
+    if ((uint32)target >= script->length)
+        return NULL;
+    offset = 0;
+    for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
+        offset += SN_DELTA(sn);
+        if (offset == target && SN_IS_GETTABLE(sn))
+            return sn;
+    }
+    return NULL;
+}
+
+uintN
+js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
+{
+    JSAtom *atom;
+    JSFunction *fun;
+    uintN lineno;
+    ptrdiff_t offset, target;
+    jssrcnote *sn;
+    JSSrcNoteType type;
+
+    /*
+     * Special case: function definition needs no line number note because
+     * the function's script contains its starting line number.
+     */
+    if (*pc == JSOP_DEFFUN) {
+        atom = GET_ATOM(cx, script, pc);
+        fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(atom));
+        JS_ASSERT(fun->interpreted);
+        return fun->u.script->lineno;
+    }
+
+    /*
+     * General case: walk through source notes accumulating their deltas,
+     * keeping track of line-number notes, until we pass the note for pc's
+     * offset within script->code.
+     */
+    lineno = script->lineno;
+    offset = 0;
+    target = PTRDIFF(pc, script->code, jsbytecode);
+    for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
+        offset += SN_DELTA(sn);
+        type = (JSSrcNoteType) SN_TYPE(sn);
+        if (type == SRC_SETLINE) {
+            if (offset <= target)
+                lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
+        } else if (type == SRC_NEWLINE) {
+            if (offset <= target)
+                lineno++;
+        }
+        if (offset > target)
+            break;
+    }
+    return lineno;
+}
+
+/* The line number limit is the same as the jssrcnote offset limit. */
+#define SN_LINE_LIMIT   (SN_3BYTE_OFFSET_FLAG << 16)
+
+jsbytecode *
+js_LineNumberToPC(JSScript *script, uintN target)
+{
+    ptrdiff_t offset, best;
+    uintN lineno, bestdiff, diff;
+    jssrcnote *sn;
+    JSSrcNoteType type;
+
+    offset = 0;
+    best = -1;
+    lineno = script->lineno;
+    bestdiff = SN_LINE_LIMIT;
+    for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
+        if (lineno == target)
+            goto out;
+        if (lineno > target) {
+            diff = lineno - target;
+            if (diff < bestdiff) {
+                bestdiff = diff;
+                best = offset;
+            }
+        }
+        offset += SN_DELTA(sn);
+        type = (JSSrcNoteType) SN_TYPE(sn);
+        if (type == SRC_SETLINE) {
+            lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
+        } else if (type == SRC_NEWLINE) {
+            lineno++;
+        }
+    }
+    if (best >= 0)
+        offset = best;
+out:
+    return script->code + offset;
+}
+
+JS_FRIEND_API(uintN)
+js_GetScriptLineExtent(JSScript *script)
+{
+    uintN lineno;
+    jssrcnote *sn;
+    JSSrcNoteType type;
+
+    lineno = script->lineno;
+    for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
+        type = (JSSrcNoteType) SN_TYPE(sn);
+        if (type == SRC_SETLINE) {
+            lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
+        } else if (type == SRC_NEWLINE) {
+            lineno++;
+        }
+    }
+    return 1 + lineno - script->lineno;
+}

Added: freeswitch/trunk/libs/js/src/jsscript.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsscript.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,209 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsscript_h___
+#define jsscript_h___
+/*
+ * JS script descriptor.
+ */
+#include "jsatom.h"
+#include "jsprvtd.h"
+
+JS_BEGIN_EXTERN_C
+
+/*
+ * Exception handling runtime information.
+ *
+ * All fields except length are code offsets relative to the main entry point
+ * of the script.  If script->trynotes is not null, it points to a vector of
+ * these structs terminated by one with catchStart == 0.
+ */
+struct JSTryNote {
+    ptrdiff_t    start;         /* start of try statement */
+    ptrdiff_t    length;        /* count of try statement bytecodes */
+    ptrdiff_t    catchStart;    /* start of catch block (0 if end) */
+};
+
+#define JSTRYNOTE_GRAIN         sizeof(ptrdiff_t)
+#define JSTRYNOTE_ALIGNMASK     (JSTRYNOTE_GRAIN - 1)
+
+struct JSScript {
+    jsbytecode   *code;         /* bytecodes and their immediate operands */
+    uint32       length;        /* length of code vector */
+    jsbytecode   *main;         /* main entry point, after predef'ing prolog */
+    uint16       version;       /* JS version under which script was compiled */
+    uint16       numGlobalVars; /* declared global var/const/function count */
+    JSAtomMap    atomMap;       /* maps immediate index to literal struct */
+    const char   *filename;     /* source filename or null */
+    uintN        lineno;        /* base line number of script */
+    uintN        depth;         /* maximum stack depth in slots */
+    JSTryNote    *trynotes;     /* exception table for this script */
+    JSPrincipals *principals;   /* principals for this script */
+    JSObject     *object;       /* optional Script-class object wrapper */
+};
+
+/* No need to store script->notes now that it is allocated right after code. */
+#define SCRIPT_NOTES(script)    ((jssrcnote*)((script)->code+(script)->length))
+
+#define SCRIPT_FIND_CATCH_START(script, pc, catchpc)                          \
+    JS_BEGIN_MACRO                                                            \
+        JSTryNote *tn_ = (script)->trynotes;                                  \
+        jsbytecode *catchpc_ = NULL;                                          \
+        if (tn_) {                                                            \
+            ptrdiff_t off_ = PTRDIFF(pc, (script)->main, jsbytecode);         \
+            if (off_ >= 0) {                                                  \
+                while ((jsuword)(off_ - tn_->start) >= (jsuword)tn_->length)  \
+                    ++tn_;                                                    \
+                if (tn_->catchStart)                                          \
+                    catchpc_ = (script)->main + tn_->catchStart;              \
+            }                                                                 \
+        }                                                                     \
+        catchpc = catchpc_;                                                   \
+    JS_END_MACRO
+
+extern JS_FRIEND_DATA(JSClass) js_ScriptClass;
+
+extern JSObject *
+js_InitScriptClass(JSContext *cx, JSObject *obj);
+
+/*
+ * On first new context in rt, initialize script runtime state, specifically
+ * the script filename table and its lock.
+ */
+extern JSBool
+js_InitRuntimeScriptState(JSRuntime *rt);
+
+/*
+ * On last context destroy for rt, if script filenames are all GC'd, free the
+ * script filename table and its lock.
+ */
+extern void
+js_FinishRuntimeScriptState(JSRuntime *rt);
+
+/*
+ * On JS_DestroyRuntime(rt), forcibly free script filename prefixes and any
+ * script filename table entries that have not been GC'd, the latter using
+ * js_FinishRuntimeScriptState.
+ *
+ * This allows script filename prefixes to outlive any context in rt.
+ */
+extern void
+js_FreeRuntimeScriptState(JSRuntime *rt);
+
+extern const char *
+js_SaveScriptFilename(JSContext *cx, const char *filename);
+
+extern const char *
+js_SaveScriptFilenameRT(JSRuntime *rt, const char *filename, uint32 flags);
+
+extern uint32
+js_GetScriptFilenameFlags(const char *filename);
+
+extern void
+js_MarkScriptFilename(const char *filename);
+
+extern void
+js_MarkScriptFilenames(JSRuntime *rt, uintN gcflags);
+
+extern void
+js_SweepScriptFilenames(JSRuntime *rt);
+
+/*
+ * Two successively less primitive ways to make a new JSScript.  The first
+ * does *not* call a non-null cx->runtime->newScriptHook -- only the second,
+ * js_NewScriptFromCG, calls this optional debugger hook.
+ *
+ * The js_NewScript function can't know whether the script it creates belongs
+ * to a function, or is top-level or eval code, but the debugger wants access
+ * to the newly made script's function, if any -- so callers of js_NewScript
+ * are responsible for notifying the debugger after successfully creating any
+ * kind (function or other) of new JSScript.
+ */
+extern JSScript *
+js_NewScript(JSContext *cx, uint32 length, uint32 snlength, uint32 tnlength);
+
+extern JS_FRIEND_API(JSScript *)
+js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun);
+
+/*
+ * New-script-hook calling is factored from js_NewScriptFromCG so that it
+ * and callers of js_XDRScript can share this code.  In the case of callers
+ * of js_XDRScript, the hook should be invoked only after successful decode
+ * of any owning function (the fun parameter) or script object (null fun).
+ */
+extern JS_FRIEND_API(void)
+js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun);
+
+extern JS_FRIEND_API(void)
+js_CallDestroyScriptHook(JSContext *cx, JSScript *script);
+
+extern void
+js_DestroyScript(JSContext *cx, JSScript *script);
+
+extern void
+js_MarkScript(JSContext *cx, JSScript *script, void *arg);
+
+extern jssrcnote *
+js_GetSrcNote(JSScript *script, jsbytecode *pc);
+
+/* XXX need cx to lock function objects declared by prolog bytecodes. */
+extern uintN
+js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
+
+extern jsbytecode *
+js_LineNumberToPC(JSScript *script, uintN lineno);
+
+extern JS_FRIEND_API(uintN)
+js_GetScriptLineExtent(JSScript *script);
+
+/*
+ * If magic is non-null, js_XDRScript succeeds on magic number mismatch but
+ * returns false in *magic; it reflects a match via a true *magic out param.
+ * If magic is null, js_XDRScript returns false on bad magic number errors,
+ * which it reports.
+ *
+ * NB: callers must call js_CallNewScriptHook after successful JSXDR_DECODE
+ * and subsequent set-up of owning function or script object, if any.
+ */
+extern JSBool
+js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *magic);
+
+JS_END_EXTERN_C
+
+#endif /* jsscript_h___ */

Added: freeswitch/trunk/libs/js/src/jsshell.msg
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsshell.msg	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+	Error messages for JSShell. See js.msg for format.
+*/
+
+MSG_DEF(JSSMSG_NOT_AN_ERROR,             0, 0, JSEXN_NONE, "<Error #0 is reserved>")
+MSG_DEF(JSSMSG_CANT_OPEN,                1, 2, JSEXN_NONE, "can't open {0}: {1}") 
+MSG_DEF(JSSMSG_TRAP_USAGE,               2, 0, JSEXN_NONE, "usage: trap [fun] [pc] expr") 
+MSG_DEF(JSSMSG_LINE2PC_USAGE,            3, 0, JSEXN_NONE, "usage: line2pc [fun] line") 
+MSG_DEF(JSSMSG_FILE_SCRIPTS_ONLY,        4, 0, JSEXN_NONE, "only works on JS scripts read from files") 
+MSG_DEF(JSSMSG_UNEXPECTED_EOF,           5, 1, JSEXN_NONE, "unexpected EOF in {0}") 
+MSG_DEF(JSSMSG_DOEXP_USAGE,              6, 0, JSEXN_NONE, "usage: doexp obj id") 

Added: freeswitch/trunk/libs/js/src/jsstddef.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsstddef.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,83 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * stddef inclusion here to first declare ptrdif as a signed long instead of a
+ * signed int.
+ */
+
+#ifdef _WINDOWS
+# ifndef XP_WIN
+# define XP_WIN
+# endif
+#if defined(_WIN32) || defined(WIN32)
+# ifndef XP_WIN32
+# define XP_WIN32
+# endif
+#else
+# ifndef XP_WIN16
+# define XP_WIN16
+# endif
+#endif
+#endif
+
+#ifdef XP_WIN16
+#ifndef _PTRDIFF_T_DEFINED
+typedef long ptrdiff_t;
+
+/*
+ * The Win16 compiler treats pointer differences as 16-bit signed values.
+ * This macro allows us to treat them as 17-bit signed values, stored in
+ * a 32-bit type.
+ */
+#define PTRDIFF(p1, p2, type)                                 \
+    ((((unsigned long)(p1)) - ((unsigned long)(p2))) / sizeof(type))
+
+#define _PTRDIFF_T_DEFINED
+#endif /*_PTRDIFF_T_DEFINED*/
+#else /*WIN16*/
+
+#define PTRDIFF(p1, p2, type)                                 \
+        ((p1) - (p2))
+
+#endif
+
+#include <stddef.h>
+
+

Added: freeswitch/trunk/libs/js/src/jsstr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsstr.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,4849 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sw=4 et tw=80:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * JS string type implementation.
+ *
+ * In order to avoid unnecessary js_LockGCThing/js_UnlockGCThing calls, these
+ * native methods store strings (possibly newborn) converted from their 'this'
+ * parameter and arguments on the stack: 'this' conversions at argv[-1], arg
+ * conversions at their index (argv[0], argv[1]).  This is a legitimate method
+ * of rooting things that might lose their newborn root due to subsequent GC
+ * allocations in the same native method.
+ */
+#include "jsstddef.h"
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jshash.h" /* Added by JSIFY */
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jsarray.h"
+#include "jsatom.h"
+#include "jsbool.h"
+#include "jscntxt.h"
+#include "jsconfig.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsopcode.h"
+#include "jsregexp.h"
+#include "jsstr.h"
+
+#if JS_HAS_REPLACE_LAMBDA
+#include "jsinterp.h"
+#endif
+
+#define JSSTRDEP_RECURSION_LIMIT        100
+
+size_t
+js_MinimizeDependentStrings(JSString *str, int level, JSString **basep)
+{
+    JSString *base;
+    size_t start, length;
+
+    JS_ASSERT(JSSTRING_IS_DEPENDENT(str));
+    base = JSSTRDEP_BASE(str);
+    start = JSSTRDEP_START(str);
+    if (JSSTRING_IS_DEPENDENT(base)) {
+        if (level < JSSTRDEP_RECURSION_LIMIT) {
+            start += js_MinimizeDependentStrings(base, level + 1, &base);
+        } else {
+            do {
+                start += JSSTRDEP_START(base);
+                base = JSSTRDEP_BASE(base);
+            } while (JSSTRING_IS_DEPENDENT(base));
+        }
+        if (start == 0) {
+            JS_ASSERT(JSSTRING_IS_PREFIX(str));
+            JSPREFIX_SET_BASE(str, base);
+        } else if (start <= JSSTRDEP_START_MASK) {
+            length = JSSTRDEP_LENGTH(str);
+            JSSTRDEP_SET_START_AND_LENGTH(str, start, length);
+            JSSTRDEP_SET_BASE(str, base);
+        }
+    }
+    *basep = base;
+    return start;
+}
+
+jschar *
+js_GetDependentStringChars(JSString *str)
+{
+    size_t start;
+    JSString *base;
+
+    start = js_MinimizeDependentStrings(str, 0, &base);
+    JS_ASSERT(!JSSTRING_IS_DEPENDENT(base));
+    JS_ASSERT(start < base->length);
+    return base->chars + start;
+}
+
+jschar *
+js_GetStringChars(JSString *str)
+{
+    if (JSSTRING_IS_DEPENDENT(str) && !js_UndependString(NULL, str))
+        return NULL;
+
+    *js_GetGCThingFlags(str) &= ~GCF_MUTABLE;
+    return str->chars;
+}
+
+JSString *
+js_ConcatStrings(JSContext *cx, JSString *left, JSString *right)
+{
+    size_t rn, ln, lrdist, n;
+    jschar *rs, *ls, *s;
+    JSDependentString *ldep;    /* non-null if left should become dependent */
+    JSString *str;
+
+    if (JSSTRING_IS_DEPENDENT(right)) {
+        rn = JSSTRDEP_LENGTH(right);
+        rs = JSSTRDEP_CHARS(right);
+    } else {
+        rn = right->length;
+        rs = right->chars;
+    }
+    if (rn == 0)
+        return left;
+
+    if (JSSTRING_IS_DEPENDENT(left) ||
+        !(*js_GetGCThingFlags(left) & GCF_MUTABLE)) {
+        /* We must copy if left does not own a buffer to realloc. */
+        ln = JSSTRING_LENGTH(left);
+        if (ln == 0)
+            return right;
+        ls = JSSTRING_CHARS(left);
+        s = (jschar *) JS_malloc(cx, (ln + rn + 1) * sizeof(jschar));
+        if (!s)
+            return NULL;
+        js_strncpy(s, ls, ln);
+        ldep = NULL;
+    } else {
+        /* We can realloc left's space and make it depend on our result. */
+        ln = left->length;
+        if (ln == 0)
+            return right;
+        ls = left->chars;
+        s = (jschar *) JS_realloc(cx, ls, (ln + rn + 1) * sizeof(jschar));
+        if (!s)
+            return NULL;
+
+        /* Take care: right could depend on left! */
+        lrdist = (size_t)(rs - ls);
+        if (lrdist < ln)
+            rs = s + lrdist;
+        left->chars = ls = s;
+        ldep = JSSTRDEP(left);
+    }
+
+    js_strncpy(s + ln, rs, rn);
+    n = ln + rn;
+    s[n] = 0;
+    str = js_NewString(cx, s, n, GCF_MUTABLE);
+    if (!str) {
+        /* Out of memory: clean up any space we (re-)allocated. */
+        if (!ldep) {
+            JS_free(cx, s);
+        } else {
+            s = JS_realloc(cx, ls, (ln + 1) * sizeof(jschar));
+            if (s)
+                left->chars = s;
+        }
+    } else {
+        /* Morph left into a dependent prefix if we realloc'd its buffer. */
+        if (ldep) {
+            JSPREFIX_SET_LENGTH(ldep, ln);
+            JSPREFIX_SET_BASE(ldep, str);
+#ifdef DEBUG
+          {
+            JSRuntime *rt = cx->runtime;
+            JS_RUNTIME_METER(rt, liveDependentStrings);
+            JS_RUNTIME_METER(rt, totalDependentStrings);
+            JS_LOCK_RUNTIME_VOID(rt,
+                (rt->strdepLengthSum += (double)ln,
+                 rt->strdepLengthSquaredSum += (double)ln * (double)ln));
+          }
+#endif
+        }
+    }
+
+    return str;
+}
+
+/*
+ * May be called with null cx by js_GetStringChars, above; and by the jslock.c
+ * MAKE_STRING_IMMUTABLE file-local macro.
+ */
+const jschar *
+js_UndependString(JSContext *cx, JSString *str)
+{
+    size_t n, size;
+    jschar *s;
+
+    if (JSSTRING_IS_DEPENDENT(str)) {
+        n = JSSTRDEP_LENGTH(str);
+        size = (n + 1) * sizeof(jschar);
+        s = (jschar *) (cx ? JS_malloc(cx, size) : malloc(size));
+        if (!s)
+            return NULL;
+
+        js_strncpy(s, JSSTRDEP_CHARS(str), n);
+        s[n] = 0;
+        str->length = n;
+        str->chars = s;
+
+#ifdef DEBUG
+        if (cx) {
+            JSRuntime *rt = cx->runtime;
+            JS_RUNTIME_UNMETER(rt, liveDependentStrings);
+            JS_RUNTIME_UNMETER(rt, totalDependentStrings);
+            JS_LOCK_RUNTIME_VOID(rt,
+                (rt->strdepLengthSum -= (double)n,
+                 rt->strdepLengthSquaredSum -= (double)n * (double)n));
+        }
+#endif
+    }
+
+    return str->chars;
+}
+
+/*
+ * Forward declarations for URI encode/decode and helper routines
+ */
+static JSBool
+str_decodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval);
+
+static JSBool
+str_decodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                        jsval *rval);
+
+static JSBool
+str_encodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval);
+
+static JSBool
+str_encodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                        jsval *rval);
+
+static uint32
+Utf8ToOneUcs4Char(const uint8 *utf8Buffer, int utf8Length);
+
+/*
+ * Contributions from the String class to the set of methods defined for the
+ * global object.  escape and unescape used to be defined in the Mocha library,
+ * but as ECMA decided to spec them, they've been moved to the core engine
+ * and made ECMA-compliant.  (Incomplete escapes are interpreted as literal
+ * characters by unescape.)
+ */
+
+/*
+ * Stuff to emulate the old libmocha escape, which took a second argument
+ * giving the type of escape to perform.  Retained for compatibility, and
+ * copied here to avoid reliance on net.h, mkparse.c/NET_EscapeBytes.
+ */
+
+#define URL_XALPHAS     ((uint8) 1)
+#define URL_XPALPHAS    ((uint8) 2)
+#define URL_PATH        ((uint8) 4)
+
+static const uint8 urlCharType[256] =
+/*      Bit 0           xalpha          -- the alphas
+ *      Bit 1           xpalpha         -- as xalpha but
+ *                             converts spaces to plus and plus to %20
+ *      Bit 2 ...       path            -- as xalphas but doesn't escape '/'
+ */
+    /*   0 1 2 3 4 5 6 7 8 9 A B C D E F */
+    {    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,       /* 0x */
+         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,       /* 1x */
+         0,0,0,0,0,0,0,0,0,0,7,4,0,7,7,4,       /* 2x   !"#$%&'()*+,-./  */
+         7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0,       /* 3x  0123456789:;<=>?  */
+         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,       /* 4x  @ABCDEFGHIJKLMNO  */
+         7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7,       /* 5X  PQRSTUVWXYZ[\]^_  */
+         0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,       /* 6x  `abcdefghijklmno  */
+         7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,       /* 7X  pqrstuvwxyz{\}~  DEL */
+         0, };
+
+/* This matches the ECMA escape set when mask is 7 (default.) */
+
+#define IS_OK(C, mask) (urlCharType[((uint8) (C))] & (mask))
+
+/* See ECMA-262 15.1.2.4. */
+JSBool
+js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+    size_t i, ni, length, newlength;
+    const jschar *chars;
+    jschar *newchars;
+    jschar ch;
+    jsint mask;
+    jsdouble d;
+    const char digits[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+                           '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+    mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH;
+    if (argc > 1) {
+        if (!js_ValueToNumber(cx, argv[1], &d))
+            return JS_FALSE;
+        if (!JSDOUBLE_IS_FINITE(d) ||
+            (mask = (jsint)d) != d ||
+            mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH))
+        {
+            char numBuf[12];
+            JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) mask);
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_BAD_STRING_MASK, numBuf);
+            return JS_FALSE;
+        }
+    }
+
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(str);
+
+    chars = JSSTRING_CHARS(str);
+    length = newlength = JSSTRING_LENGTH(str);
+
+    /* Take a first pass and see how big the result string will need to be. */
+    for (i = 0; i < length; i++) {
+        if ((ch = chars[i]) < 128 && IS_OK(ch, mask))
+            continue;
+        if (ch < 256) {
+            if (mask == URL_XPALPHAS && ch == ' ')
+                continue;   /* The character will be encoded as '+' */
+            newlength += 2; /* The character will be encoded as %XX */
+        } else {
+            newlength += 5; /* The character will be encoded as %uXXXX */
+        }
+
+        /*
+         * This overflow test works because newlength is incremented by at
+         * most 5 on each iteration.
+         */
+        if (newlength < length) {
+            JS_ReportOutOfMemory(cx);
+            return JS_FALSE;
+        }
+    }
+
+    if (newlength >= ~(size_t)0 / sizeof(jschar)) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+
+    newchars = (jschar *) JS_malloc(cx, (newlength + 1) * sizeof(jschar));
+    if (!newchars)
+        return JS_FALSE;
+    for (i = 0, ni = 0; i < length; i++) {
+        if ((ch = chars[i]) < 128 && IS_OK(ch, mask)) {
+            newchars[ni++] = ch;
+        } else if (ch < 256) {
+            if (mask == URL_XPALPHAS && ch == ' ') {
+                newchars[ni++] = '+'; /* convert spaces to pluses */
+            } else {
+                newchars[ni++] = '%';
+                newchars[ni++] = digits[ch >> 4];
+                newchars[ni++] = digits[ch & 0xF];
+            }
+        } else {
+            newchars[ni++] = '%';
+            newchars[ni++] = 'u';
+            newchars[ni++] = digits[ch >> 12];
+            newchars[ni++] = digits[(ch & 0xF00) >> 8];
+            newchars[ni++] = digits[(ch & 0xF0) >> 4];
+            newchars[ni++] = digits[ch & 0xF];
+        }
+    }
+    JS_ASSERT(ni == newlength);
+    newchars[newlength] = 0;
+
+    str = js_NewString(cx, newchars, newlength, 0);
+    if (!str) {
+        JS_free(cx, newchars);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+#undef IS_OK
+
+/* See ECMA-262 15.1.2.5 */
+static JSBool
+str_unescape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+    size_t i, ni, length;
+    const jschar *chars;
+    jschar *newchars;
+    jschar ch;
+
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(str);
+
+    chars = JSSTRING_CHARS(str);
+    length = JSSTRING_LENGTH(str);
+
+    /* Don't bother allocating less space for the new string. */
+    newchars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
+    if (!newchars)
+        return JS_FALSE;
+    ni = i = 0;
+    while (i < length) {
+        ch = chars[i++];
+        if (ch == '%') {
+            if (i + 1 < length &&
+                JS7_ISHEX(chars[i]) && JS7_ISHEX(chars[i + 1]))
+            {
+                ch = JS7_UNHEX(chars[i]) * 16 + JS7_UNHEX(chars[i + 1]);
+                i += 2;
+            } else if (i + 4 < length && chars[i] == 'u' &&
+                       JS7_ISHEX(chars[i + 1]) && JS7_ISHEX(chars[i + 2]) &&
+                       JS7_ISHEX(chars[i + 3]) && JS7_ISHEX(chars[i + 4]))
+            {
+                ch = (((((JS7_UNHEX(chars[i + 1]) << 4)
+                        + JS7_UNHEX(chars[i + 2])) << 4)
+                      + JS7_UNHEX(chars[i + 3])) << 4)
+                    + JS7_UNHEX(chars[i + 4]);
+                i += 5;
+            }
+        }
+        newchars[ni++] = ch;
+    }
+    newchars[ni] = 0;
+
+    str = js_NewString(cx, newchars, ni, 0);
+    if (!str) {
+        JS_free(cx, newchars);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+#if JS_HAS_UNEVAL
+static JSBool
+str_uneval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+
+    str = js_ValueToSource(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+#endif
+
+const char js_escape_str[] = "escape";
+const char js_unescape_str[] = "unescape";
+#if JS_HAS_UNEVAL
+const char js_uneval_str[] = "uneval";
+#endif
+const char js_decodeURI_str[] = "decodeURI";
+const char js_encodeURI_str[] = "encodeURI";
+const char js_decodeURIComponent_str[] = "decodeURIComponent";
+const char js_encodeURIComponent_str[] = "encodeURIComponent";
+
+static JSFunctionSpec string_functions[] = {
+    {js_escape_str,             js_str_escape,              1,0,0},
+    {js_unescape_str,           str_unescape,               1,0,0},
+#if JS_HAS_UNEVAL
+    {js_uneval_str,             str_uneval,                 1,0,0},
+#endif
+    {js_decodeURI_str,          str_decodeURI,              1,0,0},
+    {js_encodeURI_str,          str_encodeURI,              1,0,0},
+    {js_decodeURIComponent_str, str_decodeURI_Component,    1,0,0},
+    {js_encodeURIComponent_str, str_encodeURI_Component,    1,0,0},
+
+    {0,0,0,0,0}
+};
+
+jschar      js_empty_ucstr[]  = {0};
+JSSubString js_EmptySubString = {0, js_empty_ucstr};
+
+enum string_tinyid {
+    STRING_LENGTH = -1
+};
+
+static JSPropertySpec string_props[] = {
+    {js_length_str,     STRING_LENGTH,
+                        JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED, 0,0},
+    {0,0,0,0,0}
+};
+
+static JSBool
+str_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSString *str;
+    jsint slot;
+
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+
+    /*
+     * Call js_ValueToString because getters and setters can be invoked on
+     * objects of different class, unlike enumerate, resolve, and the other
+     * class hooks.
+     */
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+
+    slot = JSVAL_TO_INT(id);
+    if (slot == STRING_LENGTH)
+        *vp = INT_TO_JSVAL((jsint) JSSTRING_LENGTH(str));
+    return JS_TRUE;
+}
+
+#define STRING_ELEMENT_ATTRS (JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT)
+
+static JSBool
+str_enumerate(JSContext *cx, JSObject *obj)
+{
+    JSString *str, *str1;
+    size_t i, length;
+
+    /* Avoid infinite recursion via js_obj_toSource (see bug 271477). */
+    if (JS_VERSION_IS_1_2(cx))
+        return JS_TRUE;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_TRUE;
+    cx->newborn[GCX_STRING] = (JSGCThing *) str;
+
+    length = JSSTRING_LENGTH(str);
+    for (i = 0; i < length; i++) {
+        str1 = js_NewDependentString(cx, str, i, 1, 0);
+        if (!str1)
+            return JS_FALSE;
+        if (!OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSID(i),
+                                 STRING_TO_JSVAL(str1), NULL, NULL,
+                                 STRING_ELEMENT_ATTRS, NULL)) {
+            return JS_FALSE;
+        }
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+str_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
+            JSObject **objp)
+{
+    JSString *str, *str1;
+    jsint slot;
+
+    if (!JSVAL_IS_INT(id) || (flags & JSRESOLVE_ASSIGNING))
+        return JS_TRUE;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_TRUE;
+    cx->newborn[GCX_STRING] = (JSGCThing *) str;
+
+    slot = JSVAL_TO_INT(id);
+    if ((size_t)slot < JSSTRING_LENGTH(str)) {
+        str1 = js_NewDependentString(cx, str, (size_t)slot, 1, 0);
+        if (!str1)
+            return JS_FALSE;
+        if (!OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSID(slot),
+                                 STRING_TO_JSVAL(str1), NULL, NULL,
+                                 STRING_ELEMENT_ATTRS, NULL)) {
+            return JS_FALSE;
+        }
+        *objp = obj;
+    }
+    return JS_TRUE;
+}
+
+JSClass js_StringClass = {
+    js_String_str,
+    JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
+    JS_PropertyStub,   JS_PropertyStub,   str_getProperty,   JS_PropertyStub,
+    str_enumerate, (JSResolveOp)str_resolve, JS_ConvertStub, JS_FinalizeStub,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+#if JS_HAS_TOSOURCE
+
+/*
+ * String.prototype.quote is generic (as are most string methods), unlike
+ * toSource, toString, and valueOf.
+ */
+static JSBool
+str_quote(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    str = js_QuoteString(cx, str, '"');
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+str_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval v;
+    JSString *str;
+    size_t i, j, k, n;
+    char buf[16];
+    jschar *s, *t;
+
+    if (!JS_InstanceOf(cx, obj, &js_StringClass, argv))
+        return JS_FALSE;
+    v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    if (!JSVAL_IS_STRING(v))
+        return js_obj_toSource(cx, obj, argc, argv, rval);
+    str = js_QuoteString(cx, JSVAL_TO_STRING(v), '"');
+    if (!str)
+        return JS_FALSE;
+    j = JS_snprintf(buf, sizeof buf, "(new %s(", js_StringClass.name);
+    s = JSSTRING_CHARS(str);
+    k = JSSTRING_LENGTH(str);
+    n = j + k + 2;
+    t = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar));
+    if (!t)
+        return JS_FALSE;
+    for (i = 0; i < j; i++)
+        t[i] = buf[i];
+    for (j = 0; j < k; i++, j++)
+        t[i] = s[j];
+    t[i++] = ')';
+    t[i++] = ')';
+    t[i] = 0;
+    str = js_NewString(cx, t, n, 0);
+    if (!str) {
+        JS_free(cx, t);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+#endif /* JS_HAS_TOSOURCE */
+
+static JSBool
+str_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval v;
+
+    if (!JS_InstanceOf(cx, obj, &js_StringClass, argv))
+        return JS_FALSE;
+    v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    if (!JSVAL_IS_STRING(v))
+        return js_obj_toString(cx, obj, argc, argv, rval);
+    *rval = v;
+    return JS_TRUE;
+}
+
+static JSBool
+str_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    if (!JS_InstanceOf(cx, obj, &js_StringClass, argv))
+        return JS_FALSE;
+    *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
+    return JS_TRUE;
+}
+
+/*
+ * Java-like string native methods.
+ */
+static JSBool
+str_substring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    JSString *str;
+    jsdouble d;
+    jsdouble length, begin, end;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    if (argc != 0) {
+        if (!js_ValueToNumber(cx, argv[0], &d))
+            return JS_FALSE;
+        length = JSSTRING_LENGTH(str);
+        begin = js_DoubleToInteger(d);
+        if (begin < 0)
+            begin = 0;
+        else if (begin > length)
+            begin = length;
+
+        if (argc == 1) {
+            end = length;
+        } else {
+            if (!js_ValueToNumber(cx, argv[1], &d))
+                return JS_FALSE;
+            end = js_DoubleToInteger(d);
+            if (end < 0)
+                end = 0;
+            else if (end > length)
+                end = length;
+            if (end < begin) {
+                if (!JS_VERSION_IS_1_2(cx)) {
+                    /* XXX emulate old JDK1.0 java.lang.String.substring. */
+                    jsdouble tmp = begin;
+                    begin = end;
+                    end = tmp;
+                } else {
+                    end = begin;
+                }
+            }
+        }
+
+        str = js_NewDependentString(cx, str, (size_t)begin,
+                                    (size_t)(end - begin), 0);
+        if (!str)
+            return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+str_toLowerCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    JSString *str;
+    size_t i, n;
+    jschar *s, *news;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    n = JSSTRING_LENGTH(str);
+    news = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar));
+    if (!news)
+        return JS_FALSE;
+    s = JSSTRING_CHARS(str);
+    for (i = 0; i < n; i++)
+        news[i] = JS_TOLOWER(s[i]);
+    news[n] = 0;
+    str = js_NewString(cx, news, n, 0);
+    if (!str) {
+        JS_free(cx, news);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+str_toLocaleLowerCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    JSString *str;
+
+    /*
+     * Forcefully ignore the first (or any) argument and return toLowerCase(),
+     * ECMA has reserved that argument, presumably for defining the locale.
+     */
+    if (cx->localeCallbacks && cx->localeCallbacks->localeToLowerCase) {
+        str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+        if (!str)
+            return JS_FALSE;
+        argv[-1] = STRING_TO_JSVAL(str);
+        return cx->localeCallbacks->localeToLowerCase(cx, str, rval);
+    }
+    return str_toLowerCase(cx, obj, 0, argv, rval);
+}
+
+static JSBool
+str_toUpperCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    JSString *str;
+    size_t i, n;
+    jschar *s, *news;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    n = JSSTRING_LENGTH(str);
+    news = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar));
+    if (!news)
+        return JS_FALSE;
+    s = JSSTRING_CHARS(str);
+    for (i = 0; i < n; i++)
+        news[i] = JS_TOUPPER(s[i]);
+    news[n] = 0;
+    str = js_NewString(cx, news, n, 0);
+    if (!str) {
+        JS_free(cx, news);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+str_toLocaleUpperCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    JSString *str;
+
+    /*
+     * Forcefully ignore the first (or any) argument and return toUpperCase(),
+     * ECMA has reserved that argument, presumbaly for defining the locale.
+     */
+    if (cx->localeCallbacks && cx->localeCallbacks->localeToUpperCase) {
+        str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+        if (!str)
+            return JS_FALSE;
+        argv[-1] = STRING_TO_JSVAL(str);
+        return cx->localeCallbacks->localeToUpperCase(cx, str, rval);
+    }
+    return str_toUpperCase(cx, obj, 0, argv, rval);
+}
+
+static JSBool
+str_localeCompare(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                  jsval *rval)
+{
+    JSString *str, *thatStr;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    if (argc == 0) {
+        *rval = JSVAL_ZERO;
+    } else {
+        thatStr = js_ValueToString(cx, argv[0]);
+        if (!thatStr)
+            return JS_FALSE;
+        if (cx->localeCallbacks && cx->localeCallbacks->localeCompare) {
+            argv[0] = STRING_TO_JSVAL(thatStr);
+            return cx->localeCallbacks->localeCompare(cx, str, thatStr, rval);
+        }
+        *rval = INT_TO_JSVAL(js_CompareStrings(str, thatStr));
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+str_charAt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+    jsdouble d;
+    size_t index;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    if (argc == 0) {
+        d = 0.0;
+    } else {
+        if (!js_ValueToNumber(cx, argv[0], &d))
+            return JS_FALSE;
+        d = js_DoubleToInteger(d);
+    }
+
+    if (d < 0 || JSSTRING_LENGTH(str) <= d) {
+        *rval = JS_GetEmptyStringValue(cx);
+    } else {
+        index = (size_t)d;
+        str = js_NewDependentString(cx, str, index, 1, 0);
+        if (!str)
+            return JS_FALSE;
+        *rval = STRING_TO_JSVAL(str);
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+str_charCodeAt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    JSString *str;
+    jsdouble d;
+    size_t index;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    if (argc == 0) {
+        d = 0.0;
+    } else {
+        if (!js_ValueToNumber(cx, argv[0], &d))
+            return JS_FALSE;
+        d = js_DoubleToInteger(d);
+    }
+
+    if (d < 0 || JSSTRING_LENGTH(str) <= d) {
+        *rval = JS_GetNaNValue(cx);
+    } else {
+        index = (size_t)d;
+        *rval = INT_TO_JSVAL((jsint) JSSTRING_CHARS(str)[index]);
+    }
+    return JS_TRUE;
+}
+
+jsint
+js_BoyerMooreHorspool(const jschar *text, jsint textlen,
+                      const jschar *pat, jsint patlen,
+                      jsint start)
+{
+    jsint i, j, k, m;
+    uint8 skip[BMH_CHARSET_SIZE];
+    jschar c;
+
+    JS_ASSERT(0 < patlen && patlen <= BMH_PATLEN_MAX);
+    for (i = 0; i < BMH_CHARSET_SIZE; i++)
+        skip[i] = (uint8)patlen;
+    m = patlen - 1;
+    for (i = 0; i < m; i++) {
+        c = pat[i];
+        if (c >= BMH_CHARSET_SIZE)
+            return BMH_BAD_PATTERN;
+        skip[c] = (uint8)(m - i);
+    }
+    for (k = start + m;
+         k < textlen;
+         k += ((c = text[k]) >= BMH_CHARSET_SIZE) ? patlen : skip[c]) {
+        for (i = k, j = m; ; i--, j--) {
+            if (j < 0)
+                return i + 1;
+            if (text[i] != pat[j])
+                break;
+        }
+    }
+    return -1;
+}
+
+static JSBool
+str_indexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str, *str2;
+    jsint i, j, index, textlen, patlen;
+    const jschar *text, *pat;
+    jsdouble d;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+    text = JSSTRING_CHARS(str);
+    textlen = (jsint) JSSTRING_LENGTH(str);
+
+    str2 = js_ValueToString(cx, argv[0]);
+    if (!str2)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(str2);
+    pat = JSSTRING_CHARS(str2);
+    patlen = (jsint) JSSTRING_LENGTH(str2);
+
+    if (argc > 1) {
+        if (!js_ValueToNumber(cx, argv[1], &d))
+            return JS_FALSE;
+        d = js_DoubleToInteger(d);
+        if (d < 0)
+            i = 0;
+        else if (d > textlen)
+            i = textlen;
+        else
+            i = (jsint)d;
+    } else {
+        i = 0;
+    }
+    if (patlen == 0) {
+        *rval = INT_TO_JSVAL(i);
+        return JS_TRUE;
+    }
+
+    /* XXX tune the BMH threshold (512) */
+    if ((jsuint)(patlen - 2) <= BMH_PATLEN_MAX - 2 && textlen >= 512) {
+        index = js_BoyerMooreHorspool(text, textlen, pat, patlen, i);
+        if (index != BMH_BAD_PATTERN)
+            goto out;
+    }
+
+    index = -1;
+    j = 0;
+    while (i + j < textlen) {
+        if (text[i + j] == pat[j]) {
+            if (++j == patlen) {
+                index = i;
+                break;
+            }
+        } else {
+            i++;
+            j = 0;
+        }
+    }
+
+out:
+    *rval = INT_TO_JSVAL(index);
+    return JS_TRUE;
+}
+
+static JSBool
+str_lastIndexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                  jsval *rval)
+{
+    JSString *str, *str2;
+    const jschar *text, *pat;
+    jsint i, j, textlen, patlen;
+    jsdouble d;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+    text = JSSTRING_CHARS(str);
+    textlen = (jsint) JSSTRING_LENGTH(str);
+
+    str2 = js_ValueToString(cx, argv[0]);
+    if (!str2)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(str2);
+    pat = JSSTRING_CHARS(str2);
+    patlen = (jsint) JSSTRING_LENGTH(str2);
+
+    if (argc > 1) {
+        if (!js_ValueToNumber(cx, argv[1], &d))
+            return JS_FALSE;
+        if (JSDOUBLE_IS_NaN(d)) {
+            i = textlen;
+        } else {
+            d = js_DoubleToInteger(d);
+            if (d < 0)
+                i = 0;
+            else if (d > textlen)
+                i = textlen;
+            else
+                i = (jsint)d;
+        }
+    } else {
+        i = textlen;
+    }
+
+    if (patlen == 0) {
+        *rval = INT_TO_JSVAL(i);
+        return JS_TRUE;
+    }
+
+    j = 0;
+    while (i >= 0) {
+        /* Don't assume that text is NUL-terminated: it could be dependent. */
+        if (i + j < textlen && text[i + j] == pat[j]) {
+            if (++j == patlen)
+                break;
+        } else {
+            i--;
+            j = 0;
+        }
+    }
+    *rval = INT_TO_JSVAL(i);
+    return JS_TRUE;
+}
+
+/*
+ * Perl-inspired string functions.
+ */
+#if JS_HAS_REGEXPS
+typedef struct GlobData {
+    uintN       flags;          /* inout: mode and flag bits, see below */
+    uintN       optarg;         /* in: index of optional flags argument */
+    JSString    *str;           /* out: 'this' parameter object as string */
+    JSRegExp    *regexp;        /* out: regexp parameter object private data */
+} GlobData;
+
+/*
+ * Mode and flag bit definitions for match_or_replace's GlobData.flags field.
+ */
+#define MODE_MATCH      0x00    /* in: return match array on success */
+#define MODE_REPLACE    0x01    /* in: match and replace */
+#define MODE_SEARCH     0x02    /* in: search only, return match index or -1 */
+#define GET_MODE(f)     ((f) & 0x03)
+#define FORCE_FLAT      0x04    /* in: force flat (non-regexp) string match */
+#define KEEP_REGEXP     0x08    /* inout: keep GlobData.regexp alive for caller
+                                          of match_or_replace; if set on input
+                                          but clear on output, regexp ownership
+                                          does not pass to caller */
+#define GLOBAL_REGEXP   0x10    /* out: regexp had the 'g' flag */
+
+static JSBool
+match_or_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 JSBool (*glob)(JSContext *cx, jsint count, GlobData *data),
+                 GlobData *data, jsval *rval)
+{
+    JSString *str, *src, *opt;
+    JSObject *reobj;
+    JSRegExp *re;
+    size_t index, length;
+    JSBool ok, test;
+    jsint count;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+    data->str = str;
+
+    if (JSVAL_IS_REGEXP(cx, argv[0])) {
+        reobj = JSVAL_TO_OBJECT(argv[0]);
+        re = (JSRegExp *) JS_GetPrivate(cx, reobj);
+    } else {
+        src = js_ValueToString(cx, argv[0]);
+        if (!src)
+            return JS_FALSE;
+        if (data->optarg < argc) {
+            argv[0] = STRING_TO_JSVAL(src);
+            opt = js_ValueToString(cx, argv[data->optarg]);
+            if (!opt)
+                return JS_FALSE;
+        } else {
+            opt = NULL;
+        }
+        re = js_NewRegExpOpt(cx, NULL, src, opt,
+                             (data->flags & FORCE_FLAT) != 0);
+        if (!re)
+            return JS_FALSE;
+        reobj = NULL;
+    }
+    data->regexp = re;
+
+    if (re->flags & JSREG_GLOB)
+        data->flags |= GLOBAL_REGEXP;
+    index = 0;
+    if (GET_MODE(data->flags) == MODE_SEARCH) {
+        ok = js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, rval);
+        if (ok) {
+            *rval = (*rval == JSVAL_TRUE)
+                    ? INT_TO_JSVAL(cx->regExpStatics.leftContext.length)
+                    : INT_TO_JSVAL(-1);
+        }
+    } else if (data->flags & GLOBAL_REGEXP) {
+        if (reobj) {
+            /* Set the lastIndex property's reserved slot to 0. */
+            ok = js_SetLastIndex(cx, reobj, 0);
+            if (!ok)
+                return JS_FALSE;
+        } else {
+            ok = JS_TRUE;
+        }
+        length = JSSTRING_LENGTH(str);
+        for (count = 0; index <= length; count++) {
+            ok = js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, rval);
+            if (!ok || *rval != JSVAL_TRUE)
+                break;
+            ok = glob(cx, count, data);
+            if (!ok)
+                break;
+            if (cx->regExpStatics.lastMatch.length == 0) {
+                if (index == length)
+                    break;
+                index++;
+            }
+        }
+    } else {
+        if (GET_MODE(data->flags) == MODE_REPLACE) {
+            test = JS_TRUE;
+        } else {
+            /*
+             * MODE_MATCH implies str_match is being called from a script or a
+             * scripted function.  If the caller cares only about testing null
+             * vs. non-null return value, optimize away the array object that
+             * would normally be returned in *rval.
+             */
+            JSStackFrame *fp = cx->fp->down;
+
+            /* Skip Function.prototype.call and .apply frames. */
+            while (fp && !fp->pc) {
+                JS_ASSERT(!fp->script);
+                fp = fp->down;
+            }
+
+            /* Assume a full array result is required, then prove otherwise. */
+            test = JS_FALSE;
+            if (fp) {
+                JS_ASSERT(*fp->pc == JSOP_CALL || *fp->pc == JSOP_NEW);
+                JS_ASSERT(js_CodeSpec[*fp->pc].length == 3);
+                switch (fp->pc[3]) {
+                  case JSOP_POP:
+                  case JSOP_IFEQ:
+                  case JSOP_IFNE:
+                  case JSOP_IFEQX:
+                  case JSOP_IFNEX:
+                    test = JS_TRUE;
+                    break;
+                  default:;
+                }
+            }
+        }
+        ok = js_ExecuteRegExp(cx, re, str, &index, test, rval);
+    }
+
+    if (reobj) {
+        /* Tell our caller that it doesn't need to destroy data->regexp. */
+        data->flags &= ~KEEP_REGEXP;
+    } else if (!(data->flags & KEEP_REGEXP)) {
+        /* Caller didn't want to keep data->regexp, so null and destroy it.  */
+        data->regexp = NULL;
+        js_DestroyRegExp(cx, re);
+    }
+    return ok;
+}
+
+typedef struct MatchData {
+    GlobData    base;
+    jsval       *arrayval;      /* NB: local root pointer */
+} MatchData;
+
+static JSBool
+match_glob(JSContext *cx, jsint count, GlobData *data)
+{
+    MatchData *mdata;
+    JSObject *arrayobj;
+    JSSubString *matchsub;
+    JSString *matchstr;
+    jsval v;
+
+    mdata = (MatchData *)data;
+    arrayobj = JSVAL_TO_OBJECT(*mdata->arrayval);
+    if (!arrayobj) {
+        arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL);
+        if (!arrayobj)
+            return JS_FALSE;
+        *mdata->arrayval = OBJECT_TO_JSVAL(arrayobj);
+    }
+    matchsub = &cx->regExpStatics.lastMatch;
+    matchstr = js_NewStringCopyN(cx, matchsub->chars, matchsub->length, 0);
+    if (!matchstr)
+        return JS_FALSE;
+    v = STRING_TO_JSVAL(matchstr);
+    return js_SetProperty(cx, arrayobj, INT_TO_JSID(count), &v);
+}
+
+static JSBool
+str_match(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    MatchData mdata;
+    JSBool ok;
+
+    mdata.base.flags = MODE_MATCH;
+    mdata.base.optarg = 1;
+    mdata.arrayval = &argv[2];
+    *mdata.arrayval = JSVAL_NULL;
+    ok = match_or_replace(cx, obj, argc, argv, match_glob, &mdata.base, rval);
+    if (ok && !JSVAL_IS_NULL(*mdata.arrayval))
+        *rval = *mdata.arrayval;
+    return ok;
+}
+
+static JSBool
+str_search(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    GlobData data;
+
+    data.flags = MODE_SEARCH;
+    data.optarg = 1;
+    return match_or_replace(cx, obj, argc, argv, NULL, &data, rval);
+}
+
+typedef struct ReplaceData {
+    GlobData    base;           /* base struct state */
+    JSObject    *lambda;        /* replacement function object or null */
+    JSString    *repstr;        /* replacement string */
+    jschar      *dollar;        /* null or pointer to first $ in repstr */
+    jschar      *dollarEnd;     /* limit pointer for js_strchr_limit */
+    jschar      *chars;         /* result chars, null initially */
+    size_t      length;         /* result length, 0 initially */
+    jsint       index;          /* index in result of next replacement */
+    jsint       leftIndex;      /* left context index in base.str->chars */
+    JSSubString dollarStr;      /* for "$$" interpret_dollar result */
+} ReplaceData;
+
+static JSSubString *
+interpret_dollar(JSContext *cx, jschar *dp, jschar *ep, ReplaceData *rdata,
+                 size_t *skip)
+{
+    JSVersion version;
+    JSRegExpStatics *res;
+    jschar dc, *cp;
+    uintN num, tmp;
+    JSString *str;
+
+    JS_ASSERT(*dp == '$');
+
+    /*
+     * Allow a real backslash (literal "\\" before "$1") to escape "$1", e.g.
+     * Do this only for versions strictly less than ECMAv3.
+     */
+    version = cx->version & JSVERSION_MASK;
+    if (version != JSVERSION_DEFAULT && version <= JSVERSION_1_4) {
+        if (dp > JSSTRING_CHARS(rdata->repstr) && dp[-1] == '\\')
+            return NULL;
+    }
+
+    /* If there is only a dollar, bail now */
+    if (dp + 1 >= ep)
+        return NULL;
+
+    /* Interpret all Perl match-induced dollar variables. */
+    res = &cx->regExpStatics;
+    dc = dp[1];
+    if (JS7_ISDEC(dc)) {
+        if (version != JSVERSION_DEFAULT && version <= JSVERSION_1_4) {
+            if (dc == '0')
+                return NULL;
+
+            /* Check for overflow to avoid gobbling arbitrary decimal digits. */
+            num = 0;
+            cp = dp;
+            while (++cp < ep && (dc = *cp, JS7_ISDEC(dc))) {
+                tmp = 10 * num + JS7_UNDEC(dc);
+                if (tmp < num)
+                    break;
+                num = tmp;
+            }
+        } else { /* ECMA 3, 1-9 or 01-99 */
+            num = JS7_UNDEC(dc);
+            if (num > res->parenCount)
+                return NULL;
+
+            cp = dp + 2;
+            if (cp < ep && (dc = *cp, JS7_ISDEC(dc))) {
+                tmp = 10 * num + JS7_UNDEC(dc);
+                if (tmp <= res->parenCount) {
+                    cp++;
+                    num = tmp;
+                }
+            }
+            if (num == 0)
+                return NULL;
+        }
+        /* Adjust num from 1 $n-origin to 0 array-index-origin. */
+        num--;
+        *skip = cp - dp;
+        return REGEXP_PAREN_SUBSTRING(res, num);
+    }
+
+    *skip = 2;
+    switch (dc) {
+      case '$':
+        rdata->dollarStr.chars = dp;
+        rdata->dollarStr.length = 1;
+        return &rdata->dollarStr;
+      case '&':
+        return &res->lastMatch;
+      case '+':
+        return &res->lastParen;
+      case '`':
+        if (version == JSVERSION_1_2) {
+            /*
+             * JS1.2 imitated the Perl4 bug where left context at each step
+             * in an iterative use of a global regexp started from last match,
+             * not from the start of the target string.  But Perl4 does start
+             * $` at the beginning of the target string when it is used in a
+             * substitution, so we emulate that special case here.
+             */
+            str = rdata->base.str;
+            res->leftContext.chars = JSSTRING_CHARS(str);
+            res->leftContext.length = res->lastMatch.chars
+                                    - JSSTRING_CHARS(str);
+        }
+        return &res->leftContext;
+      case '\'':
+        return &res->rightContext;
+    }
+    return NULL;
+}
+
+static JSBool
+find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep)
+{
+    JSString *repstr;
+    size_t replen, skip;
+    jschar *dp, *ep;
+    JSSubString *sub;
+#if JS_HAS_REPLACE_LAMBDA
+    JSObject *lambda;
+
+    lambda = rdata->lambda;
+    if (lambda) {
+        uintN argc, i, j, m, n, p;
+        jsval *sp, *oldsp, rval;
+        void *mark;
+        JSStackFrame *fp;
+        JSBool ok;
+
+        /*
+         * Save the regExpStatics from the current regexp, since they may be
+         * clobbered by a RegExp usage in the lambda function.  Note that all
+         * members of JSRegExpStatics are JSSubStrings, so not GC roots, save
+         * input, which is rooted otherwise via argv[-1] in str_replace.
+         */
+        JSRegExpStatics save = cx->regExpStatics;
+        JSBool freeMoreParens = JS_FALSE;
+
+        /*
+         * In the lambda case, not only do we find the replacement string's
+         * length, we compute repstr and return it via rdata for use within
+         * do_replace.  The lambda is called with arguments ($&, $1, $2, ...,
+         * index, input), i.e., all the properties of a regexp match array.
+         * For $&, etc., we must create string jsvals from cx->regExpStatics.
+         * We grab up stack space to keep the newborn strings GC-rooted.
+         */
+        p = rdata->base.regexp->parenCount;
+        argc = 1 + p + 2;
+        sp = js_AllocStack(cx, 2 + argc, &mark);
+        if (!sp)
+            return JS_FALSE;
+
+        /* Push lambda and its 'this' parameter. */
+        *sp++ = OBJECT_TO_JSVAL(lambda);
+        *sp++ = OBJECT_TO_JSVAL(OBJ_GET_PARENT(cx, lambda));
+
+#define PUSH_REGEXP_STATIC(sub)                                               \
+    JS_BEGIN_MACRO                                                            \
+        JSString *str = js_NewStringCopyN(cx,                                 \
+                                          cx->regExpStatics.sub.chars,        \
+                                          cx->regExpStatics.sub.length,       \
+                                          0);                                 \
+        if (!str) {                                                           \
+            ok = JS_FALSE;                                                    \
+            goto lambda_out;                                                  \
+        }                                                                     \
+        *sp++ = STRING_TO_JSVAL(str);                                         \
+    JS_END_MACRO
+
+        /* Push $&, $1, $2, ... */
+        PUSH_REGEXP_STATIC(lastMatch);
+        i = 0;
+        m = cx->regExpStatics.parenCount;
+        n = JS_MIN(m, 9);
+        for (j = 0; i < n; i++, j++)
+            PUSH_REGEXP_STATIC(parens[j]);
+        for (j = 0; i < m; i++, j++)
+            PUSH_REGEXP_STATIC(moreParens[j]);
+
+        /*
+         * We need to clear moreParens in the top-of-stack cx->regExpStatics
+         * to it won't be possibly realloc'ed, leaving the bottom-of-stack
+         * moreParens pointing to freed memory.
+         */
+        cx->regExpStatics.moreParens = NULL;
+        freeMoreParens = JS_TRUE;
+
+#undef PUSH_REGEXP_STATIC
+
+        /* Make sure to push undefined for any unmatched parens. */
+        for (; i < p; i++)
+            *sp++ = JSVAL_VOID;
+
+        /* Push match index and input string. */
+        *sp++ = INT_TO_JSVAL((jsint)cx->regExpStatics.leftContext.length);
+        *sp++ = STRING_TO_JSVAL(rdata->base.str);
+
+        /* Lift current frame to include the args and do the call. */
+        fp = cx->fp;
+        oldsp = fp->sp;
+        fp->sp = sp;
+        ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL);
+        rval = fp->sp[-1];
+        fp->sp = oldsp;
+
+        if (ok) {
+            /*
+             * NB: we count on the newborn string root to hold any string
+             * created by this js_ValueToString that would otherwise be GC-
+             * able, until we use rdata->repstr in do_replace.
+             */
+            repstr = js_ValueToString(cx, rval);
+            if (!repstr) {
+                ok = JS_FALSE;
+            } else {
+                rdata->repstr = repstr;
+                *sizep = JSSTRING_LENGTH(repstr);
+            }
+        }
+
+      lambda_out:
+        js_FreeStack(cx, mark);
+        if (freeMoreParens)
+            JS_free(cx, cx->regExpStatics.moreParens);
+        cx->regExpStatics = save;
+        return ok;
+    }
+#endif /* JS_HAS_REPLACE_LAMBDA */
+
+    repstr = rdata->repstr;
+    replen = JSSTRING_LENGTH(repstr);
+    for (dp = rdata->dollar, ep = rdata->dollarEnd; dp;
+         dp = js_strchr_limit(dp, '$', ep)) {
+        sub = interpret_dollar(cx, dp, ep, rdata, &skip);
+        if (sub) {
+            replen += sub->length - skip;
+            dp += skip;
+        }
+        else
+            dp++;
+    }
+    *sizep = replen;
+    return JS_TRUE;
+}
+
+static void
+do_replace(JSContext *cx, ReplaceData *rdata, jschar *chars)
+{
+    JSString *repstr;
+    jschar *bp, *cp, *dp, *ep;
+    size_t len, skip;
+    JSSubString *sub;
+
+    repstr = rdata->repstr;
+    bp = cp = JSSTRING_CHARS(repstr);
+    for (dp = rdata->dollar, ep = rdata->dollarEnd; dp;
+         dp = js_strchr_limit(dp, '$', ep)) {
+        len = dp - cp;
+        js_strncpy(chars, cp, len);
+        chars += len;
+        cp = dp;
+        sub = interpret_dollar(cx, dp, ep, rdata, &skip);
+        if (sub) {
+            len = sub->length;
+            js_strncpy(chars, sub->chars, len);
+            chars += len;
+            cp += skip;
+            dp += skip;
+        } else {
+            dp++;
+        }
+    }
+    js_strncpy(chars, cp, JSSTRING_LENGTH(repstr) - (cp - bp));
+}
+
+static JSBool
+replace_glob(JSContext *cx, jsint count, GlobData *data)
+{
+    ReplaceData *rdata;
+    JSString *str;
+    size_t leftoff, leftlen, replen, growth;
+    const jschar *left;
+    jschar *chars;
+
+    rdata = (ReplaceData *)data;
+    str = data->str;
+    leftoff = rdata->leftIndex;
+    left = JSSTRING_CHARS(str) + leftoff;
+    leftlen = cx->regExpStatics.lastMatch.chars - left;
+    rdata->leftIndex = cx->regExpStatics.lastMatch.chars - JSSTRING_CHARS(str);
+    rdata->leftIndex += cx->regExpStatics.lastMatch.length;
+    if (!find_replen(cx, rdata, &replen))
+        return JS_FALSE;
+    growth = leftlen + replen;
+    chars = (jschar *)
+        (rdata->chars
+         ? JS_realloc(cx, rdata->chars, (rdata->length + growth + 1)
+                                        * sizeof(jschar))
+         : JS_malloc(cx, (growth + 1) * sizeof(jschar)));
+    if (!chars) {
+        JS_free(cx, rdata->chars);
+        rdata->chars = NULL;
+        return JS_FALSE;
+    }
+    rdata->chars = chars;
+    rdata->length += growth;
+    chars += rdata->index;
+    rdata->index += growth;
+    js_strncpy(chars, left, leftlen);
+    chars += leftlen;
+    do_replace(cx, rdata, chars);
+    return JS_TRUE;
+}
+
+static JSBool
+str_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSObject *lambda;
+    JSString *repstr, *str;
+    ReplaceData rdata;
+    JSVersion version;
+    JSBool ok;
+    jschar *chars;
+    size_t leftlen, rightlen, length;
+
+#if JS_HAS_REPLACE_LAMBDA
+    if (JS_TypeOfValue(cx, argv[1]) == JSTYPE_FUNCTION) {
+        lambda = JSVAL_TO_OBJECT(argv[1]);
+        repstr = NULL;
+    } else
+#endif
+    {
+        if (!JS_ConvertValue(cx, argv[1], JSTYPE_STRING, &argv[1]))
+            return JS_FALSE;
+        repstr = JSVAL_TO_STRING(argv[1]);
+        lambda = NULL;
+    }
+
+    /*
+     * For ECMA Edition 3, the first argument is to be converted to a string
+     * to match in a "flat" sense (without regular expression metachars having
+     * special meanings) UNLESS the first arg is a RegExp object.
+     */
+    rdata.base.flags = MODE_REPLACE | KEEP_REGEXP;
+    version = cx->version & JSVERSION_MASK;
+    if (version == JSVERSION_DEFAULT || version > JSVERSION_1_4)
+        rdata.base.flags |= FORCE_FLAT;
+    rdata.base.optarg = 2;
+
+    rdata.lambda = lambda;
+    rdata.repstr = repstr;
+    if (repstr) {
+        rdata.dollarEnd = JSSTRING_CHARS(repstr) + JSSTRING_LENGTH(repstr);
+        rdata.dollar = js_strchr_limit(JSSTRING_CHARS(repstr), '$',
+                                       rdata.dollarEnd);
+    } else {
+        rdata.dollar = rdata.dollarEnd = NULL;
+    }
+    rdata.chars = NULL;
+    rdata.length = 0;
+    rdata.index = 0;
+    rdata.leftIndex = 0;
+
+    ok = match_or_replace(cx, obj, argc, argv, replace_glob, &rdata.base, rval);
+    if (!ok)
+        return JS_FALSE;
+
+    if (!rdata.chars) {
+        if ((rdata.base.flags & GLOBAL_REGEXP) || *rval != JSVAL_TRUE) {
+            /* Didn't match even once. */
+            *rval = STRING_TO_JSVAL(rdata.base.str);
+            goto out;
+        }
+        leftlen = cx->regExpStatics.leftContext.length;
+        ok = find_replen(cx, &rdata, &length);
+        if (!ok)
+            goto out;
+        length += leftlen;
+        chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
+        if (!chars) {
+            ok = JS_FALSE;
+            goto out;
+        }
+        js_strncpy(chars, cx->regExpStatics.leftContext.chars, leftlen);
+        do_replace(cx, &rdata, chars + leftlen);
+        rdata.chars = chars;
+        rdata.length = length;
+    }
+
+    rightlen = cx->regExpStatics.rightContext.length;
+    length = rdata.length + rightlen;
+    chars = (jschar *)
+        JS_realloc(cx, rdata.chars, (length + 1) * sizeof(jschar));
+    if (!chars) {
+        JS_free(cx, rdata.chars);
+        ok = JS_FALSE;
+        goto out;
+    }
+    js_strncpy(chars + rdata.length, cx->regExpStatics.rightContext.chars,
+               rightlen);
+    chars[length] = 0;
+
+    str = js_NewString(cx, chars, length, 0);
+    if (!str) {
+        JS_free(cx, chars);
+        ok = JS_FALSE;
+        goto out;
+    }
+    *rval = STRING_TO_JSVAL(str);
+
+out:
+    /* If KEEP_REGEXP is still set, it's our job to destroy regexp now. */
+    if (rdata.base.flags & KEEP_REGEXP)
+        js_DestroyRegExp(cx, rdata.base.regexp);
+    return ok;
+}
+#endif /* JS_HAS_REGEXPS */
+
+/*
+ * Subroutine used by str_split to find the next split point in str, starting
+ * at offset *ip and looking either for the separator substring given by sep,
+ * or for the next re match.  In the re case, return the matched separator in
+ * *sep, and the possibly updated offset in *ip.
+ *
+ * Return -2 on error, -1 on end of string, >= 0 for a valid index of the next
+ * separator occurrence if found, or str->length if no separator is found.
+ */
+static jsint
+find_split(JSContext *cx, JSString *str, JSRegExp *re, jsint *ip,
+           JSSubString *sep)
+{
+    jsint i, j, k;
+    jschar *chars;
+    size_t length;
+
+    /*
+     * Stop if past end of string.  If at end of string, we will compare the
+     * null char stored there (by js_NewString*) to sep->chars[j] in the while
+     * loop at the end of this function, so that
+     *
+     *  "ab,".split(',') => ["ab", ""]
+     *
+     * and the resulting array converts back to the string "ab," for symmetry.
+     * However, we ape Perl and do this only if there is a sufficiently large
+     * limit argument (see str_split).
+     */
+    i = *ip;
+    if ((size_t)i > JSSTRING_LENGTH(str))
+        return -1;
+
+    /*
+     * Perl4 special case for str.split(' '), only if the user has selected
+     * JavaScript1.2 explicitly.  Split on whitespace, and skip leading w/s.
+     * Strange but true, apparently modeled after awk.
+     *
+     * NB: we set sep->length to the length of the w/s run, so we must test
+     * sep->chars[1] == 0 to make sure sep is just one space.
+     */
+    chars = JSSTRING_CHARS(str);
+    length = JSSTRING_LENGTH(str);
+    if (JS_VERSION_IS_1_2(cx) &&
+        !re && *sep->chars == ' ' && sep->chars[1] == 0) {
+
+        /* Skip leading whitespace if at front of str. */
+        if (i == 0) {
+            while (JS_ISSPACE(chars[i]))
+                i++;
+            *ip = i;
+        }
+
+        /* Don't delimit whitespace at end of string. */
+        if ((size_t)i == length)
+            return -1;
+
+        /* Skip over the non-whitespace chars. */
+        while ((size_t)i < length && !JS_ISSPACE(chars[i]))
+            i++;
+
+        /* Now skip the next run of whitespace. */
+        j = i;
+        while ((size_t)j < length && JS_ISSPACE(chars[j]))
+            j++;
+
+        /* Update sep->length to count delimiter chars. */
+        sep->length = (size_t)(j - i);
+        return i;
+    }
+
+#if JS_HAS_REGEXPS
+    /*
+     * Match a regular expression against the separator at or above index i.
+     * Call js_ExecuteRegExp with true for the test argument.  On successful
+     * match, get the separator from cx->regExpStatics.lastMatch.
+     */
+    if (re) {
+        size_t index;
+        jsval rval;
+
+      again:
+        /* JS1.2 deviated from Perl by never matching at end of string. */
+        index = (size_t)i;
+        if (!js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, &rval))
+            return -2;
+        if (rval != JSVAL_TRUE) {
+            /* Mismatch: ensure our caller advances i past end of string. */
+            sep->length = 1;
+            return length;
+        }
+        i = (jsint)index;
+        *sep = cx->regExpStatics.lastMatch;
+        if (sep->length == 0) {
+            /*
+             * Empty string match: never split on an empty match at the start
+             * of a find_split cycle.  Same rule as for an empty global match
+             * in match_or_replace.
+             */
+            if (i == *ip) {
+                /*
+                 * "Bump-along" to avoid sticking at an empty match, but don't
+                 * bump past end of string -- our caller must do that by adding
+                 * sep->length to our return value.
+                 */
+                if ((size_t)i == length) {
+                    if (JS_VERSION_IS_1_2(cx)) {
+                        sep->length = 1;
+                        return i;
+                    }
+                    return -1;
+                }
+                i++;
+                goto again;
+            }
+            if ((size_t)i == length) {
+                /*
+                 * If there was a trivial zero-length match at the end of the
+                 * split, then we shouldn't output the matched string at the end
+                 * of the split array. See ECMA-262 Ed. 3, 15.5.4.14, Step 15.
+                 */
+                sep->chars = NULL;
+            }
+        }
+        JS_ASSERT((size_t)i >= sep->length);
+        return i - sep->length;
+    }
+#endif /* JS_HAS_REGEXPS */
+
+    /*
+     * Deviate from ECMA by never splitting an empty string by any separator
+     * string into a non-empty array (an array of length 1 that contains the
+     * empty string).
+     */
+    if (!JS_VERSION_IS_ECMA(cx) && length == 0)
+        return -1;
+
+    /*
+     * Special case: if sep is the empty string, split str into one character
+     * substrings.  Let our caller worry about whether to split once at end of
+     * string into an empty substring.
+     *
+     * For 1.2 compatibility, at the end of the string, we return the length as
+     * the result, and set the separator length to 1 -- this allows the caller
+     * to include an additional null string at the end of the substring list.
+     */
+    if (sep->length == 0) {
+        if (JS_VERSION_IS_1_2(cx)) {
+            if ((size_t)i == length) {
+                sep->length = 1;
+                return i;
+            }
+            return i + 1;
+        }
+        return ((size_t)i == length) ? -1 : i + 1;
+    }
+
+    /*
+     * Now that we know sep is non-empty, search starting at i in str for an
+     * occurrence of all of sep's chars.  If we find them, return the index of
+     * the first separator char.  Otherwise, return length.
+     */
+    j = 0;
+    while ((size_t)(k = i + j) < length) {
+        if (chars[k] == sep->chars[j]) {
+            if ((size_t)++j == sep->length)
+                return i;
+        } else {
+            i++;
+            j = 0;
+        }
+    }
+    return k;
+}
+
+static JSBool
+str_split(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str, *sub;
+    JSObject *arrayobj;
+    jsval v;
+    JSBool ok, limited;
+    JSRegExp *re;
+    JSSubString *sep, tmp;
+    jsdouble d;
+    jsint i, j;
+    uint32 len, limit;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL);
+    if (!arrayobj)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(arrayobj);
+
+    if (argc == 0) {
+        v = STRING_TO_JSVAL(str);
+        ok = JS_SetElement(cx, arrayobj, 0, &v);
+    } else {
+#if JS_HAS_REGEXPS
+        if (JSVAL_IS_REGEXP(cx, argv[0])) {
+            re = (JSRegExp *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0]));
+            sep = &tmp;
+
+            /* Set a magic value so we can detect a successful re match. */
+            sep->chars = NULL;
+        } else
+#endif
+        {
+            JSString *str2 = js_ValueToString(cx, argv[0]);
+            if (!str2)
+                return JS_FALSE;
+            argv[0] = STRING_TO_JSVAL(str2);
+
+            /*
+             * Point sep at a local copy of str2's header because find_split
+             * will modify sep->length.
+             */
+            tmp.length = JSSTRING_LENGTH(str2);
+            tmp.chars = JSSTRING_CHARS(str2);
+            sep = &tmp;
+            re = NULL;
+        }
+
+        /* Use the second argument as the split limit, if given. */
+        limited = (argc > 1) && !JSVAL_IS_VOID(argv[1]);
+        limit = 0; /* Avoid warning. */
+        if (limited) {
+            if (!js_ValueToNumber(cx, argv[1], &d))
+                return JS_FALSE;
+
+            /* Clamp limit between 0 and 1 + string length. */
+            if (!js_DoubleToECMAUint32(cx, d, &limit))
+                return JS_FALSE;
+            if (limit > JSSTRING_LENGTH(str))
+                limit = 1 + JSSTRING_LENGTH(str);
+        }
+
+        len = i = 0;
+        while ((j = find_split(cx, str, re, &i, sep)) >= 0) {
+            if (limited && len >= limit)
+                break;
+            sub = js_NewDependentString(cx, str, i, (size_t)(j - i), 0);
+            if (!sub)
+                return JS_FALSE;
+            v = STRING_TO_JSVAL(sub);
+            if (!JS_SetElement(cx, arrayobj, len, &v))
+                return JS_FALSE;
+            len++;
+#if JS_HAS_REGEXPS
+            /*
+             * Imitate perl's feature of including parenthesized substrings
+             * that matched part of the delimiter in the new array, after the
+             * split substring that was delimited.
+             */
+            if (re && sep->chars) {
+                uintN num;
+                JSSubString *parsub;
+
+                for (num = 0; num < cx->regExpStatics.parenCount; num++) {
+                    if (limited && len >= limit)
+                        break;
+                    parsub = REGEXP_PAREN_SUBSTRING(&cx->regExpStatics, num);
+                    sub = js_NewStringCopyN(cx, parsub->chars, parsub->length,
+                                            0);
+                    if (!sub)
+                        return JS_FALSE;
+                    v = STRING_TO_JSVAL(sub);
+                    if (!JS_SetElement(cx, arrayobj, len, &v))
+                        return JS_FALSE;
+                    len++;
+                }
+                sep->chars = NULL;
+            }
+#endif
+            i = j + sep->length;
+            if (!JS_VERSION_IS_ECMA(cx)) {
+                /*
+                 * Deviate from ECMA to imitate Perl, which omits a final
+                 * split unless a limit argument is given and big enough.
+                 */
+                if (!limited && (size_t)i == JSSTRING_LENGTH(str))
+                    break;
+            }
+        }
+        ok = (j != -2);
+    }
+    return ok;
+}
+
+#if JS_HAS_PERL_SUBSTR
+static JSBool
+str_substr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+    jsdouble d;
+    jsdouble length, begin, end;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    if (argc != 0) {
+        if (!js_ValueToNumber(cx, argv[0], &d))
+            return JS_FALSE;
+        length = JSSTRING_LENGTH(str);
+        begin = js_DoubleToInteger(d);
+        if (begin < 0) {
+            begin += length;
+            if (begin < 0)
+                begin = 0;
+        } else if (begin > length) {
+            begin = length;
+        }
+
+        if (argc == 1) {
+            end = length;
+        } else {
+            if (!js_ValueToNumber(cx, argv[1], &d))
+                return JS_FALSE;
+            end = js_DoubleToInteger(d);
+            if (end < 0)
+                end = 0;
+            end += begin;
+            if (end > length)
+                end = length;
+        }
+
+        str = js_NewDependentString(cx, str, (size_t)begin,
+                                    (size_t)(end - begin), 0);
+        if (!str)
+            return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+#endif /* JS_HAS_PERL_SUBSTR */
+
+#if JS_HAS_SEQUENCE_OPS
+/*
+ * Python-esque sequence operations.
+ */
+static JSBool
+str_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str, *str2;
+    uintN i;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    for (i = 0; i < argc; i++) {
+        str2 = js_ValueToString(cx, argv[i]);
+        if (!str2)
+            return JS_FALSE;
+        argv[i] = STRING_TO_JSVAL(str2);
+
+        str = js_ConcatStrings(cx, str, str2);
+        if (!str)
+            return JS_FALSE;
+    }
+
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+str_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+    jsdouble d;
+    jsdouble length, begin, end;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    if (argc != 0) {
+        if (!js_ValueToNumber(cx, argv[0], &d))
+            return JS_FALSE;
+        length = JSSTRING_LENGTH(str);
+        begin = js_DoubleToInteger(d);
+        if (begin < 0) {
+            begin += length;
+            if (begin < 0)
+                begin = 0;
+        } else if (begin > length) {
+            begin = length;
+        }
+
+        if (argc == 1) {
+            end = length;
+        } else {
+            if (!js_ValueToNumber(cx, argv[1], &d))
+                return JS_FALSE;
+            end = js_DoubleToInteger(d);
+            if (end < 0) {
+                end += length;
+                if (end < 0)
+                    end = 0;
+            } else if (end > length) {
+                end = length;
+            }
+            if (end < begin)
+                end = begin;
+        }
+
+        str = js_NewDependentString(cx, str, (size_t)begin,
+                                    (size_t)(end - begin), 0);
+        if (!str)
+            return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+#endif /* JS_HAS_SEQUENCE_OPS */
+
+#if JS_HAS_STR_HTML_HELPERS
+/*
+ * HTML composition aids.
+ */
+static JSBool
+tagify(JSContext *cx, JSObject *obj, jsval *argv,
+       const char *begin, JSString *param, const char *end,
+       jsval *rval)
+{
+    JSString *str;
+    jschar *tagbuf;
+    size_t beglen, endlen, parlen, taglen;
+    size_t i, j;
+
+    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    argv[-1] = STRING_TO_JSVAL(str);
+
+    if (!end)
+        end = begin;
+
+    beglen = strlen(begin);
+    taglen = 1 + beglen + 1;                            /* '<begin' + '>' */
+    parlen = 0; /* Avoid warning. */
+    if (param) {
+        parlen = JSSTRING_LENGTH(param);
+        taglen += 2 + parlen + 1;                       /* '="param"' */
+    }
+    endlen = strlen(end);
+    taglen += JSSTRING_LENGTH(str) + 2 + endlen + 1;    /* 'str</end>' */
+
+    tagbuf = (jschar *) JS_malloc(cx, (taglen + 1) * sizeof(jschar));
+    if (!tagbuf)
+        return JS_FALSE;
+
+    j = 0;
+    tagbuf[j++] = '<';
+    for (i = 0; i < beglen; i++)
+        tagbuf[j++] = (jschar)begin[i];
+    if (param) {
+        tagbuf[j++] = '=';
+        tagbuf[j++] = '"';
+        js_strncpy(&tagbuf[j], JSSTRING_CHARS(param), parlen);
+        j += parlen;
+        tagbuf[j++] = '"';
+    }
+    tagbuf[j++] = '>';
+    js_strncpy(&tagbuf[j], JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
+    j += JSSTRING_LENGTH(str);
+    tagbuf[j++] = '<';
+    tagbuf[j++] = '/';
+    for (i = 0; i < endlen; i++)
+        tagbuf[j++] = (jschar)end[i];
+    tagbuf[j++] = '>';
+    JS_ASSERT(j == taglen);
+    tagbuf[j] = 0;
+
+    str = js_NewString(cx, tagbuf, taglen, 0);
+    if (!str) {
+        free((char *)tagbuf);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+tagify_value(JSContext *cx, JSObject *obj, jsval *argv,
+             const char *begin, const char *end,
+             jsval *rval)
+{
+    JSString *param;
+
+    param = js_ValueToString(cx, argv[0]);
+    if (!param)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(param);
+    return tagify(cx, obj, argv, begin, param, end, rval);
+}
+
+static JSBool
+str_bold(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify(cx, obj, argv, "b", NULL, NULL, rval);
+}
+
+static JSBool
+str_italics(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify(cx, obj, argv, "i", NULL, NULL, rval);
+}
+
+static JSBool
+str_fixed(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify(cx, obj, argv, "tt", NULL, NULL, rval);
+}
+
+static JSBool
+str_fontsize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify_value(cx, obj, argv, "font size", "font", rval);
+}
+
+static JSBool
+str_fontcolor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    return tagify_value(cx, obj, argv, "font color", "font", rval);
+}
+
+static JSBool
+str_link(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify_value(cx, obj, argv, "a href", "a", rval);
+}
+
+static JSBool
+str_anchor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify_value(cx, obj, argv, "a name", "a", rval);
+}
+
+static JSBool
+str_strike(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify(cx, obj, argv, "strike", NULL, NULL, rval);
+}
+
+static JSBool
+str_small(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify(cx, obj, argv, "small", NULL, NULL, rval);
+}
+
+static JSBool
+str_big(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify(cx, obj, argv, "big", NULL, NULL, rval);
+}
+
+static JSBool
+str_blink(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify(cx, obj, argv, "blink", NULL, NULL, rval);
+}
+
+static JSBool
+str_sup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify(cx, obj, argv, "sup", NULL, NULL, rval);
+}
+
+static JSBool
+str_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    return tagify(cx, obj, argv, "sub", NULL, NULL, rval);
+}
+#endif /* JS_HAS_STR_HTML_HELPERS */
+
+static JSFunctionSpec string_methods[] = {
+#if JS_HAS_TOSOURCE
+    {"quote",               str_quote,              0,JSFUN_GENERIC_NATIVE,0},
+    {js_toSource_str,       str_toSource,           0,0,0},
+#endif
+
+    /* Java-like methods. */
+    {js_toString_str,       str_toString,           0,0,0},
+    {js_valueOf_str,        str_valueOf,            0,0,0},
+    {"substring",           str_substring,          2,JSFUN_GENERIC_NATIVE,0},
+    {"toLowerCase",         str_toLowerCase,        0,JSFUN_GENERIC_NATIVE,0},
+    {"toUpperCase",         str_toUpperCase,        0,JSFUN_GENERIC_NATIVE,0},
+    {"charAt",              str_charAt,             1,JSFUN_GENERIC_NATIVE,0},
+    {"charCodeAt",          str_charCodeAt,         1,JSFUN_GENERIC_NATIVE,0},
+    {"indexOf",             str_indexOf,            1,JSFUN_GENERIC_NATIVE,0},
+    {"lastIndexOf",         str_lastIndexOf,        1,JSFUN_GENERIC_NATIVE,0},
+    {"toLocaleLowerCase",   str_toLocaleLowerCase,  0,JSFUN_GENERIC_NATIVE,0},
+    {"toLocaleUpperCase",   str_toLocaleUpperCase,  0,JSFUN_GENERIC_NATIVE,0},
+    {"localeCompare",       str_localeCompare,      1,JSFUN_GENERIC_NATIVE,0},
+
+    /* Perl-ish methods (search is actually Python-esque). */
+#if JS_HAS_REGEXPS
+    {"match",               str_match,              1,JSFUN_GENERIC_NATIVE,2},
+    {"search",              str_search,             1,JSFUN_GENERIC_NATIVE,0},
+    {"replace",             str_replace,            2,JSFUN_GENERIC_NATIVE,0},
+    {"split",               str_split,              2,JSFUN_GENERIC_NATIVE,0},
+#endif
+#if JS_HAS_PERL_SUBSTR
+    {"substr",              str_substr,             2,JSFUN_GENERIC_NATIVE,0},
+#endif
+
+    /* Python-esque sequence methods. */
+#if JS_HAS_SEQUENCE_OPS
+    {"concat",              str_concat,             0,JSFUN_GENERIC_NATIVE,0},
+    {"slice",               str_slice,              0,JSFUN_GENERIC_NATIVE,0},
+#endif
+
+    /* HTML string methods. */
+#if JS_HAS_STR_HTML_HELPERS
+    {"bold",                str_bold,               0,0,0},
+    {"italics",             str_italics,            0,0,0},
+    {"fixed",               str_fixed,              0,0,0},
+    {"fontsize",            str_fontsize,           1,0,0},
+    {"fontcolor",           str_fontcolor,          1,0,0},
+    {"link",                str_link,               1,0,0},
+    {"anchor",              str_anchor,             1,0,0},
+    {"strike",              str_strike,             0,0,0},
+    {"small",               str_small,              0,0,0},
+    {"big",                 str_big,                0,0,0},
+    {"blink",               str_blink,              0,0,0},
+    {"sup",                 str_sup,                0,0,0},
+    {"sub",                 str_sub,                0,0,0},
+#endif
+
+    {0,0,0,0,0}
+};
+
+static JSBool
+String(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSString *str;
+
+    if (argc > 0) {
+        str = js_ValueToString(cx, argv[0]);
+        if (!str)
+            return JS_FALSE;
+        argv[0] = STRING_TO_JSVAL(str);
+    } else {
+        str = cx->runtime->emptyString;
+    }
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        *rval = STRING_TO_JSVAL(str);
+        return JS_TRUE;
+    }
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, STRING_TO_JSVAL(str));
+    return JS_TRUE;
+}
+
+static JSBool
+str_fromCharCode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    jschar *chars;
+    uintN i;
+    uint16 code;
+    JSString *str;
+
+    chars = (jschar *) JS_malloc(cx, (argc + 1) * sizeof(jschar));
+    if (!chars)
+        return JS_FALSE;
+    for (i = 0; i < argc; i++) {
+        if (!js_ValueToUint16(cx, argv[i], &code)) {
+            JS_free(cx, chars);
+            return JS_FALSE;
+        }
+        chars[i] = (jschar)code;
+    }
+    chars[i] = 0;
+    str = js_NewString(cx, chars, argc, 0);
+    if (!str) {
+        JS_free(cx, chars);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSFunctionSpec string_static_methods[] = {
+    {"fromCharCode",    str_fromCharCode,       1,0,0},
+    {0,0,0,0,0}
+};
+
+static JSHashTable *deflated_string_cache;
+#ifdef DEBUG
+static uint32 deflated_string_cache_bytes;
+#endif
+#ifdef JS_THREADSAFE
+static JSLock *deflated_string_cache_lock;
+#endif
+
+JSBool
+js_InitStringGlobals(void)
+{
+#ifdef JS_THREADSAFE
+    /* Must come through here once in primordial thread to init safely! */
+    if (!deflated_string_cache_lock) {
+        deflated_string_cache_lock = JS_NEW_LOCK();
+        if (!deflated_string_cache_lock)
+            return JS_FALSE;
+    }
+#endif
+    return JS_TRUE;
+}
+
+void
+js_FreeStringGlobals()
+{
+    if (deflated_string_cache) {
+        JS_HashTableDestroy(deflated_string_cache);
+        deflated_string_cache = NULL;
+    }
+#ifdef JS_THREADSAFE
+    if (deflated_string_cache_lock) {
+        JS_DESTROY_LOCK(deflated_string_cache_lock);
+        deflated_string_cache_lock = NULL;
+    }
+#endif
+}
+
+JSBool
+js_InitRuntimeStringState(JSContext *cx)
+{
+    JSRuntime *rt;
+    JSString *empty;
+    JSAtom *atom;
+
+    rt = cx->runtime;
+    JS_ASSERT(!rt->emptyString);
+
+    /* Make a permanently locked empty string. */
+    empty = js_NewStringCopyN(cx, js_empty_ucstr, 0, GCF_LOCK);
+    if (!empty)
+        return JS_FALSE;
+
+    /* Atomize it for scripts that use '' + x to convert x to string. */
+    atom = js_AtomizeString(cx, empty, ATOM_PINNED);
+    if (!atom)
+        return JS_FALSE;
+
+    rt->emptyString = empty;
+    rt->atomState.emptyAtom = atom;
+    return JS_TRUE;
+}
+
+void
+js_FinishRuntimeStringState(JSContext *cx)
+{
+    JSRuntime *rt = cx->runtime;
+
+    js_UnlockGCThingRT(rt, rt->emptyString);
+    rt->emptyString = NULL;
+}
+
+JSObject *
+js_InitStringClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto;
+
+    /* Define the escape, unescape functions in the global object. */
+    if (!JS_DefineFunctions(cx, obj, string_functions))
+        return NULL;
+
+    proto = JS_InitClass(cx, obj, NULL, &js_StringClass, String, 1,
+                         string_props, string_methods,
+                         NULL, string_static_methods);
+    if (!proto)
+        return NULL;
+    OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE,
+                 STRING_TO_JSVAL(cx->runtime->emptyString));
+    return proto;
+}
+
+JSString *
+js_NewString(JSContext *cx, jschar *chars, size_t length, uintN gcflag)
+{
+    JSString *str;
+
+    if (length > JSSTRING_LENGTH_MASK) {
+        JS_ReportOutOfMemory(cx);
+        return NULL;
+    }
+
+    str = (JSString *) js_NewGCThing(cx, gcflag | GCX_STRING, sizeof(JSString));
+    if (!str)
+        return NULL;
+    str->length = length;
+    str->chars = chars;
+#ifdef DEBUG
+  {
+    JSRuntime *rt = cx->runtime;
+    JS_RUNTIME_METER(rt, liveStrings);
+    JS_RUNTIME_METER(rt, totalStrings);
+    JS_LOCK_RUNTIME_VOID(rt,
+        (rt->lengthSum += (double)length,
+         rt->lengthSquaredSum += (double)length * (double)length));
+  }
+#endif
+    return str;
+}
+
+JSString *
+js_NewDependentString(JSContext *cx, JSString *base, size_t start,
+                      size_t length, uintN gcflag)
+{
+    JSDependentString *ds;
+
+    if (length == 0)
+        return cx->runtime->emptyString;
+
+    if (start == 0 && length == JSSTRING_LENGTH(base))
+        return base;
+
+    if (start > JSSTRDEP_START_MASK ||
+        (start != 0 && length > JSSTRDEP_LENGTH_MASK)) {
+        return js_NewStringCopyN(cx, JSSTRING_CHARS(base) + start, length,
+                                 gcflag);
+    }
+
+    ds = (JSDependentString *)
+         js_NewGCThing(cx, gcflag | GCX_MUTABLE_STRING, sizeof(JSString));
+    if (!ds)
+        return NULL;
+    if (start == 0) {
+        JSPREFIX_SET_LENGTH(ds, length);
+        JSPREFIX_SET_BASE(ds, base);
+    } else {
+        JSSTRDEP_SET_START_AND_LENGTH(ds, start, length);
+        JSSTRDEP_SET_BASE(ds, base);
+    }
+#ifdef DEBUG
+  {
+    JSRuntime *rt = cx->runtime;
+    JS_RUNTIME_METER(rt, liveDependentStrings);
+    JS_RUNTIME_METER(rt, totalDependentStrings);
+    JS_RUNTIME_METER(rt, liveStrings);
+    JS_RUNTIME_METER(rt, totalStrings);
+    JS_LOCK_RUNTIME_VOID(rt,
+        (rt->strdepLengthSum += (double)length,
+         rt->strdepLengthSquaredSum += (double)length * (double)length));
+    JS_LOCK_RUNTIME_VOID(rt,
+        (rt->lengthSum += (double)length,
+         rt->lengthSquaredSum += (double)length * (double)length));
+  }
+#endif
+    return (JSString *)ds;
+}
+
+#ifdef DEBUG
+#include <math.h>
+
+#ifdef OSSP
+void printJSStringStats(JSRuntime *rt);
+#endif
+
+void printJSStringStats(JSRuntime *rt) {
+    double mean = 0., var = 0., sigma = 0.;
+    jsrefcount count = rt->totalStrings;
+    if (count > 0 && rt->lengthSum >= 0) {
+        mean = rt->lengthSum / count;
+        var = count * rt->lengthSquaredSum - rt->lengthSum * rt->lengthSum;
+        if (var < 0.0 || count <= 1)
+            var = 0.0;
+        else
+            var /= count * (count - 1);
+
+        /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
+        sigma = (var != 0.) ? sqrt(var) : 0.;
+    }
+    fprintf(stderr, "%lu total strings, mean length %g (sigma %g)\n",
+            (unsigned long)count, mean, sigma);
+
+    mean = var = sigma = 0.;
+    count = rt->totalDependentStrings;
+    if (count > 0 && rt->strdepLengthSum >= 0) {
+        mean = rt->strdepLengthSum / count;
+        var = count * rt->strdepLengthSquaredSum
+            - rt->strdepLengthSum * rt->strdepLengthSum;
+        if (var < 0.0 || count <= 1)
+            var = 0.0;
+        else
+            var /= count * (count - 1);
+
+        /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */
+        sigma = (var != 0.) ? sqrt(var) : 0.;
+    }
+    fprintf(stderr, "%lu total dependent strings, mean length %g (sigma %g)\n",
+            (unsigned long)count, mean, sigma);
+}
+#endif
+
+JSString *
+js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n, uintN gcflag)
+{
+    jschar *news;
+    JSString *str;
+
+    news = (jschar *)JS_malloc(cx, (n + 1) * sizeof(jschar));
+    if (!news)
+        return NULL;
+    js_strncpy(news, s, n);
+    news[n] = 0;
+    str = js_NewString(cx, news, n, gcflag);
+    if (!str)
+        JS_free(cx, news);
+    return str;
+}
+
+JSString *
+js_NewStringCopyZ(JSContext *cx, const jschar *s, uintN gcflag)
+{
+    size_t n, m;
+    jschar *news;
+    JSString *str;
+
+    n = js_strlen(s);
+    m = (n + 1) * sizeof(jschar);
+    news = (jschar *) JS_malloc(cx, m);
+    if (!news)
+        return NULL;
+    memcpy(news, s, m);
+    str = js_NewString(cx, news, n, gcflag);
+    if (!str)
+        JS_free(cx, news);
+    return str;
+}
+
+JS_STATIC_DLL_CALLBACK(JSHashNumber)
+js_hash_string_pointer(const void *key)
+{
+    return (JSHashNumber)JS_PTR_TO_UINT32(key) >> JSVAL_TAGBITS;
+}
+
+void
+js_PurgeDeflatedStringCache(JSString *str)
+{
+    JSHashNumber hash;
+    JSHashEntry *he, **hep;
+
+    if (!deflated_string_cache)
+        return;
+
+    hash = js_hash_string_pointer(str);
+    JS_ACQUIRE_LOCK(deflated_string_cache_lock);
+    hep = JS_HashTableRawLookup(deflated_string_cache, hash, str);
+    he = *hep;
+    if (he) {
+#ifdef DEBUG
+        deflated_string_cache_bytes -= JSSTRING_LENGTH(str);
+#endif
+        free(he->value);
+        JS_HashTableRawRemove(deflated_string_cache, hep, he);
+    }
+    JS_RELEASE_LOCK(deflated_string_cache_lock);
+}
+
+void
+js_FinalizeString(JSContext *cx, JSString *str)
+{
+    js_FinalizeStringRT(cx->runtime, str);
+}
+
+void
+js_FinalizeStringRT(JSRuntime *rt, JSString *str)
+{
+    JSBool valid;
+
+    JS_RUNTIME_UNMETER(rt, liveStrings);
+    if (JSSTRING_IS_DEPENDENT(str)) {
+        /* If JSSTRFLAG_DEPENDENT is set, this string must be valid. */
+        JS_ASSERT(JSSTRDEP_BASE(str));
+        JS_RUNTIME_UNMETER(rt, liveDependentStrings);
+        valid = JS_TRUE;
+    } else {
+        /* A stillborn string has null chars, so is not valid. */
+        valid = (str->chars != NULL);
+        if (valid)
+            free(str->chars);
+    }
+    if (valid) {
+        js_PurgeDeflatedStringCache(str);
+        str->chars = NULL;
+    }
+    str->length = 0;
+}
+
+JSObject *
+js_StringToObject(JSContext *cx, JSString *str)
+{
+    JSObject *obj;
+
+    obj = js_NewObject(cx, &js_StringClass, NULL, NULL);
+    if (!obj)
+        return NULL;
+    OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, STRING_TO_JSVAL(str));
+    return obj;
+}
+
+JS_FRIEND_API(const char *)
+js_ValueToPrintableString(JSContext *cx, jsval v)
+{
+    JSString *str;
+    const char *bytes;
+
+    str = js_ValueToString(cx, v);
+    if (!str)
+        return NULL;
+    str = js_QuoteString(cx, str, 0);
+    if (!str)
+        return NULL;
+    bytes = js_GetStringBytes(str);
+    if (!bytes)
+        JS_ReportOutOfMemory(cx);
+    return bytes;
+}
+
+JSString *
+js_ValueToString(JSContext *cx, jsval v)
+{
+    JSObject *obj;
+    JSString *str;
+
+    if (JSVAL_IS_OBJECT(v)) {
+        obj = JSVAL_TO_OBJECT(v);
+        if (!obj)
+            return ATOM_TO_STRING(cx->runtime->atomState.nullAtom);
+        if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_STRING, &v))
+            return NULL;
+    }
+    if (JSVAL_IS_STRING(v)) {
+        str = JSVAL_TO_STRING(v);
+    } else if (JSVAL_IS_INT(v)) {
+        str = js_NumberToString(cx, JSVAL_TO_INT(v));
+    } else if (JSVAL_IS_DOUBLE(v)) {
+        str = js_NumberToString(cx, *JSVAL_TO_DOUBLE(v));
+    } else if (JSVAL_IS_BOOLEAN(v)) {
+        str = js_BooleanToString(cx, JSVAL_TO_BOOLEAN(v));
+    } else {
+        str = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
+    }
+    return str;
+}
+
+JSString *
+js_ValueToSource(JSContext *cx, jsval v)
+{
+    if (JSVAL_IS_STRING(v))
+        return js_QuoteString(cx, JSVAL_TO_STRING(v), '"');
+    if (JSVAL_IS_PRIMITIVE(v)) {
+        /* Special case to preserve negative zero, _contra_ toString. */
+        if (JSVAL_IS_DOUBLE(v) && JSDOUBLE_IS_NEGZERO(*JSVAL_TO_DOUBLE(v))) {
+            /* NB: _ucNstr rather than _ucstr to indicate non-terminated. */
+            static const jschar js_negzero_ucNstr[] = {'-', '0'};
+
+            return js_NewStringCopyN(cx, js_negzero_ucNstr, 2, 0);
+        }
+    } else {
+        if (!js_TryMethod(cx, JSVAL_TO_OBJECT(v),
+                          cx->runtime->atomState.toSourceAtom,
+                          0, NULL, &v)) {
+            return NULL;
+        }
+    }
+    return js_ValueToString(cx, v);
+}
+
+JSHashNumber
+js_HashString(JSString *str)
+{
+    JSHashNumber h;
+    const jschar *s;
+    size_t n;
+
+    h = 0;
+    for (s = JSSTRING_CHARS(str), n = JSSTRING_LENGTH(str); n; s++, n--)
+        h = (h >> (JS_HASH_BITS - 4)) ^ (h << 4) ^ *s;
+    return h;
+}
+
+intN
+js_CompareStrings(JSString *str1, JSString *str2)
+{
+    size_t l1, l2, n, i;
+    const jschar *s1, *s2;
+    intN cmp;
+
+    l1 = JSSTRING_LENGTH(str1), l2 = JSSTRING_LENGTH(str2);
+    s1 = JSSTRING_CHARS(str1),  s2 = JSSTRING_CHARS(str2);
+    n = JS_MIN(l1, l2);
+    for (i = 0; i < n; i++) {
+        cmp = s1[i] - s2[i];
+        if (cmp != 0)
+            return cmp;
+    }
+    return (intN)(l1 - l2);
+}
+
+size_t
+js_strlen(const jschar *s)
+{
+    const jschar *t;
+
+    for (t = s; *t != 0; t++)
+        continue;
+    return (size_t)(t - s);
+}
+
+jschar *
+js_strchr(const jschar *s, jschar c)
+{
+    while (*s != 0) {
+        if (*s == c)
+            return (jschar *)s;
+        s++;
+    }
+    return NULL;
+}
+
+jschar *
+js_strchr_limit(const jschar *s, jschar c, const jschar *limit)
+{
+    while (s < limit) {
+        if (*s == c)
+            return (jschar *)s;
+        s++;
+    }
+    return NULL;
+}
+
+const jschar *
+js_SkipWhiteSpace(const jschar *s)
+{
+    /* JS_ISSPACE is false on a null. */
+    while (JS_ISSPACE(*s))
+        s++;
+    return s;
+}
+
+#ifdef JS_C_STRINGS_ARE_UTF8
+
+jschar *
+js_InflateString(JSContext *cx, const char *bytes, size_t *length)
+{
+    jschar *chars = NULL;
+    size_t dstlen = 0;
+
+    if (!js_InflateStringToBuffer(cx, bytes, *length, NULL, &dstlen))
+        return NULL;
+    chars = (jschar *) JS_malloc(cx, (dstlen + 1) * sizeof (jschar));
+    if (!chars)
+        return NULL;
+    js_InflateStringToBuffer(cx, bytes, *length, chars, &dstlen);
+    chars [dstlen] = 0;
+    *length = dstlen;
+    return chars;
+}
+
+/*
+ * May be called with null cx by js_GetStringBytes, see below.
+ */
+char *
+js_DeflateString(JSContext *cx, const jschar *chars, size_t length)
+{
+    size_t size = 0;
+    char *bytes = NULL;
+    if (!js_DeflateStringToBuffer (cx, chars, length, NULL, &size))
+        return NULL;
+    bytes = (char *) (cx ? JS_malloc(cx, size+1) : malloc(size+1));
+    if (!bytes)
+        return NULL;
+    js_DeflateStringToBuffer (cx, chars, length, bytes, &size);
+    bytes [size] = 0;
+    return bytes;
+}
+
+JSBool
+js_DeflateStringToBuffer(JSContext *cx, const jschar* src, size_t srclen, char* dst, size_t* dstlenp)
+{
+    size_t i, utf8Len, dstlen = *dstlenp, origDstlen = dstlen;
+    jschar c, c2;
+    uint32 v;
+    uint8 utf8buf[6];
+
+    if (!dst)
+        dstlen = origDstlen = (size_t) -1;
+
+    while (srclen) {
+        c = *src++;
+        srclen--;
+        if ((c >= 0xDC00) && (c <= 0xDFFF))
+            goto badSurrogate;
+        if (c < 0xD800 || c > 0xDBFF) {
+            v = c;
+        } else {
+            if (srclen < 1)
+                goto bufferTooSmall;
+            c2 = *src++;
+            srclen--;
+            if ((c2 < 0xDC00) || (c2 > 0xDFFF)) {
+                c = c2;
+                goto badSurrogate;
+            }
+            v = ((c - 0xD800) << 10) + (c2 - 0xDC00) + 0x10000;
+        }
+        if (v < 0x0080) {
+            /* OSSP BUGFIX */ /* no encoding necessary - performance hack */
+            if (!dstlen)
+                goto bufferTooSmall;
+            if (dst)
+                *dst++ = (char) v;
+            utf8Len = 1;
+        } else {
+            utf8Len = js_OneUcs4ToUtf8Char(utf8buf, v);
+            if (utf8Len > dstlen)
+                goto bufferTooSmall;
+            if (dst) {
+                for (i = 0; i < utf8Len; i++)
+                    *dst++ = (char) utf8buf [i];
+            }
+        }
+        dstlen -= utf8Len;
+    }
+    *dstlenp = (origDstlen - dstlen);
+    return JS_TRUE;
+
+badSurrogate:
+    *dstlenp = (origDstlen - dstlen);
+    if (cx) {
+        char buffer [10];
+        JS_snprintf (buffer, 10, "0x%x", c);
+        JS_ReportErrorFlagsAndNumber(cx,
+                                JSREPORT_ERROR,
+                                js_GetErrorMessage, NULL,
+                                JSMSG_BAD_SURROGATE_CHAR,
+                                buffer);
+    }
+    return JS_FALSE;
+
+bufferTooSmall:
+    *dstlenp = (origDstlen - dstlen);
+    if (cx)
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BUFFER_TOO_SMALL);
+    return JS_FALSE;
+}
+
+JSBool
+js_InflateStringToBuffer(JSContext *cx, const char *src, size_t srclen, jschar* dst, size_t* dstlenp)
+{
+    uint32 v;
+    size_t offset = 0, j, n, dstlen = *dstlenp, origDstlen = dstlen;
+
+    if (!dst)
+        dstlen = origDstlen = (size_t) -1;
+
+    while (srclen) {
+        v = (uint8) *src;
+        n = 1;
+        if (v & 0x80) {
+            while (v & (0x80 >> n))
+                n++;
+            if (n > srclen)
+                goto bufferTooSmall;
+            if (n == 1 || n > 6)
+                goto badCharacter;
+            for (j = 1; j < n; j++) {
+                if ((src [j] & 0xC0) != 0x80)
+                    goto badCharacter;
+            }
+            v = Utf8ToOneUcs4Char(src, n);
+            if (v >= 0x10000) {
+                v -= 0x10000;
+                if (v > 0xFFFFF || dstlen < 2) {
+                    *dstlenp = (origDstlen - dstlen);
+                    if (cx) {
+                        char buffer [10];
+                        JS_snprintf (buffer, 10, "0x%x", v + 0x10000);
+                        JS_ReportErrorFlagsAndNumber(cx,
+                                                JSREPORT_ERROR,
+                                                js_GetErrorMessage, NULL,
+                                                JSMSG_UTF8_CHAR_TOO_LARGE,
+                                                buffer);
+                    }
+                    return JS_FALSE;
+                }
+                if (dstlen < 2)
+                    goto bufferTooSmall;
+                if (dst) {
+                    *dst++ = (jschar)((v >> 10) + 0xD800);
+                    v = (jschar)((v & 0x3FF) + 0xDC00);
+                }
+                dstlen--;
+            }
+        }
+        if (!dstlen)
+            goto bufferTooSmall;
+        if (dst)
+            *dst++ = (jschar) v;
+        dstlen--;
+        offset += n;
+        src += n;
+        srclen -= n;
+    }
+    *dstlenp = (origDstlen - dstlen);
+    return JS_TRUE;
+
+badCharacter:
+    *dstlenp = (origDstlen - dstlen);
+    if (cx) {
+        char buffer [10];
+        JS_snprintf (buffer, 10, "%d", offset);
+        JS_ReportErrorFlagsAndNumber(cx,
+                                JSREPORT_ERROR,
+                                js_GetErrorMessage, NULL,
+                                JSMSG_MALFORMED_UTF8_CHAR,
+                                buffer);
+    }
+    return JS_FALSE;
+
+bufferTooSmall:
+    *dstlenp = (origDstlen - dstlen);
+    if (cx)
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BUFFER_TOO_SMALL);
+    return JS_FALSE;
+}
+
+#else
+
+JSBool
+js_InflateStringToBuffer(JSContext* cx, const char *bytes, size_t length, jschar *chars, size_t* charsLength)
+{
+    size_t i;
+
+    if (length > *charsLength) {
+        for (i = 0; i < *charsLength; i++)
+            chars[i] = (unsigned char) bytes[i];
+        if (cx)
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BUFFER_TOO_SMALL);
+        return JS_FALSE;
+    }
+    else {
+        for (i = 0; i < length; i++)
+            chars[i] = (unsigned char) bytes[i];
+        *charsLength = length;
+        return JS_TRUE;
+    }
+}
+
+jschar *
+js_InflateString(JSContext *cx, const char *bytes, size_t *bytesLength)
+{
+    jschar *chars;
+    size_t i, length = *bytesLength;
+
+    chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
+    if (!chars) {
+        *bytesLength = 0;
+        return NULL;
+    }
+    for (i = 0; i < length; i++)
+        chars[i] = (unsigned char) bytes[i];
+    chars [length] = 0;
+    *bytesLength = length;
+    return chars;
+}
+
+JSBool
+js_DeflateStringToBuffer(JSContext* cx, const jschar *chars, size_t length, char *bytes, size_t* bytesLength)
+{
+    size_t i;
+
+    if (length > *bytesLength) {
+        for (i = 0; i < *bytesLength; i++)
+            bytes[i] = (char) chars[i];
+        if (cx)
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BUFFER_TOO_SMALL);
+        return JS_FALSE;
+    }
+    else {
+        for (i = 0; i < length; i++)
+            bytes[i] = (char) chars[i];
+        *bytesLength = length;
+        return JS_TRUE;
+    }
+}
+
+/*
+ * May be called with null cx by js_GetStringBytes, see below.
+ */
+char *
+js_DeflateString(JSContext *cx, const jschar *chars, size_t length)
+{
+    size_t i, size;
+    char *bytes;
+
+    size = (length + 1) * sizeof(char);
+    bytes = (char *) (cx ? JS_malloc(cx, size) : malloc(size));
+    if (!bytes)
+        return NULL;
+
+    for (i = 0; i < length; i++)
+        bytes[i] = (char) chars[i];
+
+    bytes [length] = 0;
+    return bytes;
+}
+
+#endif
+
+static JSHashTable *
+GetDeflatedStringCache(void)
+{
+    JSHashTable *cache;
+
+    cache = deflated_string_cache;
+    if (!cache) {
+        cache = JS_NewHashTable(8, js_hash_string_pointer,
+                                JS_CompareValues, JS_CompareValues,
+                                NULL, NULL);
+        deflated_string_cache = cache;
+    }
+    return cache;
+}
+
+JSBool
+js_SetStringBytes(JSString *str, char *bytes, size_t length)
+{
+    JSHashTable *cache;
+    JSBool ok;
+    JSHashNumber hash;
+    JSHashEntry **hep;
+
+    JS_ACQUIRE_LOCK(deflated_string_cache_lock);
+
+    cache = GetDeflatedStringCache();
+    if (!cache) {
+        ok = JS_FALSE;
+    } else {
+        hash = js_hash_string_pointer(str);
+        hep = JS_HashTableRawLookup(cache, hash, str);
+        JS_ASSERT(*hep == NULL);
+        ok = JS_HashTableRawAdd(cache, hep, hash, str, bytes) != NULL;
+#ifdef DEBUG
+        if (ok)
+            deflated_string_cache_bytes += length;
+#endif
+    }
+
+    JS_RELEASE_LOCK(deflated_string_cache_lock);
+    return ok;
+}
+
+char *
+js_GetStringBytes(JSString *str)
+{
+    JSHashTable *cache;
+    char *bytes;
+    JSHashNumber hash;
+    JSHashEntry *he, **hep;
+
+    JS_ACQUIRE_LOCK(deflated_string_cache_lock);
+
+    cache = GetDeflatedStringCache();
+    if (!cache) {
+        bytes = NULL;
+    } else {
+        hash = js_hash_string_pointer(str);
+        hep = JS_HashTableRawLookup(cache, hash, str);
+        he = *hep;
+        if (he) {
+            bytes = (char *) he->value;
+
+            /* Try to catch failure to JS_ShutDown between runtime epochs. */
+            JS_ASSERT((*bytes == '\0' && JSSTRING_LENGTH(str) == 0) ||
+                      *bytes == (char) JSSTRING_CHARS(str)[0]);
+        } else {
+            bytes = js_DeflateString(NULL, JSSTRING_CHARS(str),
+                                           JSSTRING_LENGTH(str));
+            if (bytes) {
+                if (JS_HashTableRawAdd(cache, hep, hash, str, bytes)) {
+#ifdef DEBUG
+                    deflated_string_cache_bytes += JSSTRING_LENGTH(str);
+#endif
+                } else {
+                    free(bytes);
+                    bytes = NULL;
+                }
+            }
+        }
+    }
+
+    JS_RELEASE_LOCK(deflated_string_cache_lock);
+    return bytes;
+}
+
+/*
+ * From java.lang.Character.java:
+ *
+ * The character properties are currently encoded into 32 bits in the
+ * following manner:
+ *
+ * 10 bits      signed offset used for converting case
+ *  1 bit       if 1, adding the signed offset converts the character to
+ *              lowercase
+ *  1 bit       if 1, subtracting the signed offset converts the character to
+ *              uppercase
+ *  1 bit       if 1, character has a titlecase equivalent (possibly itself)
+ *  3 bits      0  may not be part of an identifier
+ *              1  ignorable control; may continue a Unicode identifier or JS
+ *                 identifier
+ *              2  may continue a JS identifier but not a Unicode identifier
+ *                 (unused)
+ *              3  may continue a Unicode identifier or JS identifier
+ *              4  is a JS whitespace character
+ *              5  may start or continue a JS identifier;
+ *                 may continue but not start a Unicode identifier (_)
+ *              6  may start or continue a JS identifier but not a Unicode
+ *                 identifier ($)
+ *              7  may start or continue a Unicode identifier or JS identifier
+ *              Thus:
+ *                 5, 6, 7 may start a JS identifier
+ *                 1, 2, 3, 5, 6, 7 may continue a JS identifier
+ *                 7 may start a Unicode identifier
+ *                 1, 3, 5, 7 may continue a Unicode identifier
+ *                 1 is ignorable within an identifier
+ *                 4 is JS whitespace
+ *  2 bits      0  this character has no numeric property
+ *              1  adding the digit offset to the character code and then
+ *                 masking with 0x1F will produce the desired numeric value
+ *              2  this character has a "strange" numeric value
+ *              3  a JS supradecimal digit: adding the digit offset to the
+ *                 character code, then masking with 0x1F, then adding 10
+ *                 will produce the desired numeric value
+ *  5 bits      digit offset
+ *  1 bit       XML 1.0 name start character
+ *  1 bit       XML 1.0 name character
+ *  2 bits      reserved for future use
+ *  5 bits      character type
+ */
+
+/* The X table has 1024 entries for a total of 1024 bytes. */
+
+const uint8 js_X[] = {
+  0,   1,   2,   3,   4,   5,   6,   7,  /*  0x0000 */
+  8,   9,  10,  11,  12,  13,  14,  15,  /*  0x0200 */
+ 16,  17,  18,  19,  20,  21,  22,  23,  /*  0x0400 */
+ 24,  25,  26,  27,  28,  28,  28,  28,  /*  0x0600 */
+ 28,  28,  28,  28,  29,  30,  31,  32,  /*  0x0800 */
+ 33,  34,  35,  36,  37,  38,  39,  40,  /*  0x0A00 */
+ 41,  42,  43,  44,  45,  46,  28,  28,  /*  0x0C00 */
+ 47,  48,  49,  50,  51,  52,  53,  28,  /*  0x0E00 */
+ 28,  28,  54,  55,  56,  57,  58,  59,  /*  0x1000 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x1200 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x1400 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x1600 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x1800 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x1A00 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x1C00 */
+ 60,  60,  61,  62,  63,  64,  65,  66,  /*  0x1E00 */
+ 67,  68,  69,  70,  71,  72,  73,  74,  /*  0x2000 */
+ 75,  75,  75,  76,  77,  78,  28,  28,  /*  0x2200 */
+ 79,  80,  81,  82,  83,  83,  84,  85,  /*  0x2400 */
+ 86,  85,  28,  28,  87,  88,  89,  28,  /*  0x2600 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x2800 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x2A00 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x2C00 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x2E00 */
+ 90,  91,  92,  93,  94,  56,  95,  28,  /*  0x3000 */
+ 96,  97,  98,  99,  83, 100,  83, 101,  /*  0x3200 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x3400 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x3600 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x3800 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x3A00 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x3C00 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x3E00 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x4000 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x4200 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x4400 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x4600 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x4800 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x4A00 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0x4C00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x4E00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x5000 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x5200 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x5400 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x5600 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x5800 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x5A00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x5C00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x5E00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x6000 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x6200 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x6400 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x6600 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x6800 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x6A00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x6C00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x6E00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x7000 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x7200 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x7400 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x7600 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x7800 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x7A00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x7C00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x7E00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x8000 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x8200 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x8400 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x8600 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x8800 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x8A00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x8C00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x8E00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x9000 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x9200 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x9400 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x9600 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x9800 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x9A00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0x9C00 */
+ 56,  56,  56,  56,  56,  56, 102,  28,  /*  0x9E00 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0xA000 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0xA200 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0xA400 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0xA600 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0xA800 */
+ 28,  28,  28,  28,  28,  28,  28,  28,  /*  0xAA00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xAC00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xAE00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xB000 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xB200 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xB400 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xB600 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xB800 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xBA00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xBC00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xBE00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xC000 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xC200 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xC400 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xC600 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xC800 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xCA00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xCC00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xCE00 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xD000 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xD200 */
+ 56,  56,  56,  56,  56,  56,  56,  56,  /*  0xD400 */
+ 56,  56,  56,  56,  56,  56, 103,  28,  /*  0xD600 */
+104, 104, 104, 104, 104, 104, 104, 104,  /*  0xD800 */
+104, 104, 104, 104, 104, 104, 104, 104,  /*  0xDA00 */
+104, 104, 104, 104, 104, 104, 104, 104,  /*  0xDC00 */
+104, 104, 104, 104, 104, 104, 104, 104,  /*  0xDE00 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xE000 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xE200 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xE400 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xE600 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xE800 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xEA00 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xEC00 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xEE00 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xF000 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xF200 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xF400 */
+105, 105, 105, 105, 105, 105, 105, 105,  /*  0xF600 */
+105, 105, 105, 105,  56,  56,  56,  56,  /*  0xF800 */
+106,  28,  28,  28, 107, 108, 109, 110,  /*  0xFA00 */
+ 56,  56,  56,  56, 111, 112, 113, 114,  /*  0xFC00 */
+115, 116,  56, 117, 118, 119, 120, 121   /*  0xFE00 */
+};
+
+/* The Y table has 7808 entries for a total of 7808 bytes. */
+
+const uint8 js_Y[] = {
+  0,   0,   0,   0,   0,   0,   0,   0,  /*    0 */
+  0,   1,   1,   1,   1,   1,   0,   0,  /*    0 */
+  0,   0,   0,   0,   0,   0,   0,   0,  /*    0 */
+  0,   0,   0,   0,   0,   0,   0,   0,  /*    0 */
+  2,   3,   3,   3,   4,   3,   3,   3,  /*    0 */
+  5,   6,   3,   7,   3,   8,   3,   3,  /*    0 */
+  9,   9,   9,   9,   9,   9,   9,   9,  /*    0 */
+  9,   9,   3,   3,   7,   7,   7,   3,  /*    0 */
+  3,  10,  10,  10,  10,  10,  10,  10,  /*    1 */
+ 10,  10,  10,  10,  10,  10,  10,  10,  /*    1 */
+ 10,  10,  10,  10,  10,  10,  10,  10,  /*    1 */
+ 10,  10,  10,   5,   3,   6,  11,  12,  /*    1 */
+ 11,  13,  13,  13,  13,  13,  13,  13,  /*    1 */
+ 13,  13,  13,  13,  13,  13,  13,  13,  /*    1 */
+ 13,  13,  13,  13,  13,  13,  13,  13,  /*    1 */
+ 13,  13,  13,   5,   7,   6,   7,   0,  /*    1 */
+  0,   0,   0,   0,   0,   0,   0,   0,  /*    2 */
+  0,   0,   0,   0,   0,   0,   0,   0,  /*    2 */
+  0,   0,   0,   0,   0,   0,   0,   0,  /*    2 */
+  0,   0,   0,   0,   0,   0,   0,   0,  /*    2 */
+  2,   3,   4,   4,   4,   4,  15,  15,  /*    2 */
+ 11,  15,  16,   5,   7,   8,  15,  11,  /*    2 */
+ 15,   7,  17,  17,  11,  16,  15,   3,  /*    2 */
+ 11,  18,  16,   6,  19,  19,  19,   3,  /*    2 */
+ 20,  20,  20,  20,  20,  20,  20,  20,  /*    3 */
+ 20,  20,  20,  20,  20,  20,  20,  20,  /*    3 */
+ 20,  20,  20,  20,  20,  20,  20,   7,  /*    3 */
+ 20,  20,  20,  20,  20,  20,  20,  16,  /*    3 */
+ 21,  21,  21,  21,  21,  21,  21,  21,  /*    3 */
+ 21,  21,  21,  21,  21,  21,  21,  21,  /*    3 */
+ 21,  21,  21,  21,  21,  21,  21,   7,  /*    3 */
+ 21,  21,  21,  21,  21,  21,  21,  22,  /*    3 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    4 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    4 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    4 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    4 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    4 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    4 */
+ 25,  26,  23,  24,  23,  24,  23,  24,  /*    4 */
+ 16,  23,  24,  23,  24,  23,  24,  23,  /*    4 */
+ 24,  23,  24,  23,  24,  23,  24,  23,  /*    5 */
+ 24,  16,  23,  24,  23,  24,  23,  24,  /*    5 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    5 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    5 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    5 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    5 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    5 */
+ 27,  23,  24,  23,  24,  23,  24,  28,  /*    5 */
+ 16,  29,  23,  24,  23,  24,  30,  23,  /*    6 */
+ 24,  31,  31,  23,  24,  16,  32,  32,  /*    6 */
+ 33,  23,  24,  31,  34,  16,  35,  36,  /*    6 */
+ 23,  24,  16,  16,  35,  37,  16,  38,  /*    6 */
+ 23,  24,  23,  24,  23,  24,  38,  23,  /*    6 */
+ 24,  39,  40,  16,  23,  24,  39,  23,  /*    6 */
+ 24,  41,  41,  23,  24,  23,  24,  42,  /*    6 */
+ 23,  24,  16,  40,  23,  24,  40,  40,  /*    6 */
+ 40,  40,  40,  40,  43,  44,  45,  43,  /*    7 */
+ 44,  45,  43,  44,  45,  23,  24,  23,  /*    7 */
+ 24,  23,  24,  23,  24,  23,  24,  23,  /*    7 */
+ 24,  23,  24,  23,  24,  16,  23,  24,  /*    7 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    7 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    7 */
+ 16,  43,  44,  45,  23,  24,  46,  46,  /*    7 */
+ 46,  46,  23,  24,  23,  24,  23,  24,  /*    7 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    8 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    8 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*    8 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*    8 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*    8 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*    8 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*    8 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*    8 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*    9 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*    9 */
+ 16,  16,  16,  47,  48,  16,  49,  49,  /*    9 */
+ 50,  50,  16,  51,  16,  16,  16,  16,  /*    9 */
+ 49,  16,  16,  52,  16,  16,  16,  16,  /*    9 */
+ 53,  54,  16,  16,  16,  16,  16,  54,  /*    9 */
+ 16,  16,  55,  16,  16,  16,  16,  16,  /*    9 */
+ 16,  16,  16,  16,  16,  16,  16,  16,  /*    9 */
+ 16,  16,  16,  56,  16,  16,  16,  16,  /*   10 */
+ 56,  16,  57,  57,  16,  16,  16,  16,  /*   10 */
+ 16,  16,  58,  16,  16,  16,  16,  16,  /*   10 */
+ 16,  16,  16,  16,  16,  16,  16,  16,  /*   10 */
+ 16,  16,  16,  16,  16,  16,  16,  16,  /*   10 */
+ 16,  46,  46,  46,  46,  46,  46,  46,  /*   10 */
+ 59,  59,  59,  59,  59,  59,  59,  59,  /*   10 */
+ 59,  11,  11,  59,  59,  59,  59,  59,  /*   10 */
+ 59,  59,  11,  11,  11,  11,  11,  11,  /*   11 */
+ 11,  11,  11,  11,  11,  11,  11,  11,  /*   11 */
+ 59,  59,  11,  11,  11,  11,  11,  11,  /*   11 */
+ 11,  11,  11,  11,  11,  11,  11,  46,  /*   11 */
+ 59,  59,  59,  59,  59,  11,  11,  11,  /*   11 */
+ 11,  11,  46,  46,  46,  46,  46,  46,  /*   11 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   11 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   11 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   12 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   12 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   12 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   12 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   12 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   12 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   12 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   12 */
+ 60,  60,  60,  60,  60,  60,  46,  46,  /*   13 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   13 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   13 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   13 */
+ 60,  60,  46,  46,  46,  46,  46,  46,  /*   13 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   13 */
+ 46,  46,  46,  46,   3,   3,  46,  46,  /*   13 */
+ 46,  46,  59,  46,  46,  46,   3,  46,  /*   13 */
+ 46,  46,  46,  46,  11,  11,  61,   3,  /*   14 */
+ 62,  62,  62,  46,  63,  46,  64,  64,  /*   14 */
+ 16,  20,  20,  20,  20,  20,  20,  20,  /*   14 */
+ 20,  20,  20,  20,  20,  20,  20,  20,  /*   14 */
+ 20,  20,  46,  20,  20,  20,  20,  20,  /*   14 */
+ 20,  20,  20,  20,  65,  66,  66,  66,  /*   14 */
+ 16,  21,  21,  21,  21,  21,  21,  21,  /*   14 */
+ 21,  21,  21,  21,  21,  21,  21,  21,  /*   14 */
+ 21,  21,  16,  21,  21,  21,  21,  21,  /*   15 */
+ 21,  21,  21,  21,  67,  68,  68,  46,  /*   15 */
+ 69,  70,  38,  38,  38,  71,  72,  46,  /*   15 */
+ 46,  46,  38,  46,  38,  46,  38,  46,  /*   15 */
+ 38,  46,  23,  24,  23,  24,  23,  24,  /*   15 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   15 */
+ 73,  74,  16,  40,  46,  46,  46,  46,  /*   15 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   15 */
+ 46,  75,  75,  75,  75,  75,  75,  75,  /*   16 */
+ 75,  75,  75,  75,  75,  46,  75,  75,  /*   16 */
+ 20,  20,  20,  20,  20,  20,  20,  20,  /*   16 */
+ 20,  20,  20,  20,  20,  20,  20,  20,  /*   16 */
+ 20,  20,  20,  20,  20,  20,  20,  20,  /*   16 */
+ 20,  20,  20,  20,  20,  20,  20,  20,  /*   16 */
+ 21,  21,  21,  21,  21,  21,  21,  21,  /*   16 */
+ 21,  21,  21,  21,  21,  21,  21,  21,  /*   16 */
+ 21,  21,  21,  21,  21,  21,  21,  21,  /*   17 */
+ 21,  21,  21,  21,  21,  21,  21,  21,  /*   17 */
+ 46,  74,  74,  74,  74,  74,  74,  74,  /*   17 */
+ 74,  74,  74,  74,  74,  46,  74,  74,  /*   17 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   17 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   17 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   17 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   17 */
+ 23,  24,  15,  60,  60,  60,  60,  46,  /*   18 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   18 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   18 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   18 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   18 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   18 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   18 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   18 */
+ 40,  23,  24,  23,  24,  46,  46,  23,  /*   19 */
+ 24,  46,  46,  23,  24,  46,  46,  46,  /*   19 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   19 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   19 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   19 */
+ 23,  24,  23,  24,  46,  46,  23,  24,  /*   19 */
+ 23,  24,  23,  24,  23,  24,  46,  46,  /*   19 */
+ 23,  24,  46,  46,  46,  46,  46,  46,  /*   19 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   20 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   20 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   20 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   20 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   20 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   20 */
+ 46,  76,  76,  76,  76,  76,  76,  76,  /*   20 */
+ 76,  76,  76,  76,  76,  76,  76,  76,  /*   20 */
+ 76,  76,  76,  76,  76,  76,  76,  76,  /*   21 */
+ 76,  76,  76,  76,  76,  76,  76,  76,  /*   21 */
+ 76,  76,  76,  76,  76,  76,  76,  46,  /*   21 */
+ 46,  59,   3,   3,   3,   3,   3,   3,  /*   21 */
+ 46,  77,  77,  77,  77,  77,  77,  77,  /*   21 */
+ 77,  77,  77,  77,  77,  77,  77,  77,  /*   21 */
+ 77,  77,  77,  77,  77,  77,  77,  77,  /*   21 */
+ 77,  77,  77,  77,  77,  77,  77,  77,  /*   21 */
+ 77,  77,  77,  77,  77,  77,  77,  16,  /*   22 */
+ 46,   3,  46,  46,  46,  46,  46,  46,  /*   22 */
+ 46,  60,  60,  60,  60,  60,  60,  60,  /*   22 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   22 */
+ 60,  60,  46,  60,  60,  60,  60,  60,  /*   22 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   22 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   22 */
+ 60,  60,  46,  60,  60,  60,   3,  60,  /*   22 */
+  3,  60,  60,   3,  60,  46,  46,  46,  /*   23 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   23 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   23 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   23 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   23 */
+ 40,  40,  40,  46,  46,  46,  46,  46,  /*   23 */
+ 40,  40,  40,   3,   3,  46,  46,  46,  /*   23 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   23 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   24 */
+ 46,  46,  46,  46,   3,  46,  46,  46,  /*   24 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   24 */
+ 46,  46,  46,   3,  46,  46,  46,   3,  /*   24 */
+ 46,  40,  40,  40,  40,  40,  40,  40,  /*   24 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   24 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   24 */
+ 40,  40,  40,  46,  46,  46,  46,  46,  /*   24 */
+ 59,  40,  40,  40,  40,  40,  40,  40,  /*   25 */
+ 40,  40,  40,  60,  60,  60,  60,  60,  /*   25 */
+ 60,  60,  60,  46,  46,  46,  46,  46,  /*   25 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   25 */
+ 78,  78,  78,  78,  78,  78,  78,  78,  /*   25 */
+ 78,  78,   3,   3,   3,   3,  46,  46,  /*   25 */
+ 60,  40,  40,  40,  40,  40,  40,  40,  /*   25 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   25 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   26 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   26 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   26 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   26 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   26 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   26 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   26 */
+ 46,  46,  40,  40,  40,  40,  40,  46,  /*   26 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   27 */
+ 40,  40,  40,  40,  40,  40,  40,  46,  /*   27 */
+ 40,  40,  40,  40,   3,  40,  60,  60,  /*   27 */
+ 60,  60,  60,  60,  60,  79,  79,  60,  /*   27 */
+ 60,  60,  60,  60,  60,  59,  59,  60,  /*   27 */
+ 60,  15,  60,  60,  60,  60,  46,  46,  /*   27 */
+  9,   9,   9,   9,   9,   9,   9,   9,  /*   27 */
+  9,   9,  46,  46,  46,  46,  46,  46,  /*   27 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   28 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   28 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   28 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   28 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   28 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   28 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   28 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   28 */
+ 46,  60,  60,  80,  46,  40,  40,  40,  /*   29 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   29 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   29 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   29 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   29 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   29 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   29 */
+ 40,  40,  46,  46,  60,  40,  80,  80,  /*   29 */
+ 80,  60,  60,  60,  60,  60,  60,  60,  /*   30 */
+ 60,  80,  80,  80,  80,  60,  46,  46,  /*   30 */
+ 15,  60,  60,  60,  60,  46,  46,  46,  /*   30 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   30 */
+ 40,  40,  60,  60,   3,   3,  81,  81,  /*   30 */
+ 81,  81,  81,  81,  81,  81,  81,  81,  /*   30 */
+  3,  46,  46,  46,  46,  46,  46,  46,  /*   30 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   30 */
+ 46,  60,  80,  80,  46,  40,  40,  40,  /*   31 */
+ 40,  40,  40,  40,  40,  46,  46,  40,  /*   31 */
+ 40,  46,  46,  40,  40,  40,  40,  40,  /*   31 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   31 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   31 */
+ 40,  46,  40,  40,  40,  40,  40,  40,  /*   31 */
+ 40,  46,  40,  46,  46,  46,  40,  40,  /*   31 */
+ 40,  40,  46,  46,  60,  46,  80,  80,  /*   31 */
+ 80,  60,  60,  60,  60,  46,  46,  80,  /*   32 */
+ 80,  46,  46,  80,  80,  60,  46,  46,  /*   32 */
+ 46,  46,  46,  46,  46,  46,  46,  80,  /*   32 */
+ 46,  46,  46,  46,  40,  40,  46,  40,  /*   32 */
+ 40,  40,  60,  60,  46,  46,  81,  81,  /*   32 */
+ 81,  81,  81,  81,  81,  81,  81,  81,  /*   32 */
+ 40,  40,   4,   4,  82,  82,  82,  82,  /*   32 */
+ 19,  83,  15,  46,  46,  46,  46,  46,  /*   32 */
+ 46,  46,  60,  46,  46,  40,  40,  40,  /*   33 */
+ 40,  40,  40,  46,  46,  46,  46,  40,  /*   33 */
+ 40,  46,  46,  40,  40,  40,  40,  40,  /*   33 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   33 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   33 */
+ 40,  46,  40,  40,  40,  40,  40,  40,  /*   33 */
+ 40,  46,  40,  40,  46,  40,  40,  46,  /*   33 */
+ 40,  40,  46,  46,  60,  46,  80,  80,  /*   33 */
+ 80,  60,  60,  46,  46,  46,  46,  60,  /*   34 */
+ 60,  46,  46,  60,  60,  60,  46,  46,  /*   34 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   34 */
+ 46,  40,  40,  40,  40,  46,  40,  46,  /*   34 */
+ 46,  46,  46,  46,  46,  46,  81,  81,  /*   34 */
+ 81,  81,  81,  81,  81,  81,  81,  81,  /*   34 */
+ 60,  60,  40,  40,  40,  46,  46,  46,  /*   34 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   34 */
+ 46,  60,  60,  80,  46,  40,  40,  40,  /*   35 */
+ 40,  40,  40,  40,  46,  40,  46,  40,  /*   35 */
+ 40,  40,  46,  40,  40,  40,  40,  40,  /*   35 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   35 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   35 */
+ 40,  46,  40,  40,  40,  40,  40,  40,  /*   35 */
+ 40,  46,  40,  40,  46,  40,  40,  40,  /*   35 */
+ 40,  40,  46,  46,  60,  40,  80,  80,  /*   35 */
+ 80,  60,  60,  60,  60,  60,  46,  60,  /*   36 */
+ 60,  80,  46,  80,  80,  60,  46,  46,  /*   36 */
+ 15,  46,  46,  46,  46,  46,  46,  46,  /*   36 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   36 */
+ 40,  46,  46,  46,  46,  46,  81,  81,  /*   36 */
+ 81,  81,  81,  81,  81,  81,  81,  81,  /*   36 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   36 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   36 */
+ 46,  60,  80,  80,  46,  40,  40,  40,  /*   37 */
+ 40,  40,  40,  40,  40,  46,  46,  40,  /*   37 */
+ 40,  46,  46,  40,  40,  40,  40,  40,  /*   37 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   37 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   37 */
+ 40,  46,  40,  40,  40,  40,  40,  40,  /*   37 */
+ 40,  46,  40,  40,  46,  46,  40,  40,  /*   37 */
+ 40,  40,  46,  46,  60,  40,  80,  60,  /*   37 */
+ 80,  60,  60,  60,  46,  46,  46,  80,  /*   38 */
+ 80,  46,  46,  80,  80,  60,  46,  46,  /*   38 */
+ 46,  46,  46,  46,  46,  46,  60,  80,  /*   38 */
+ 46,  46,  46,  46,  40,  40,  46,  40,  /*   38 */
+ 40,  40,  46,  46,  46,  46,  81,  81,  /*   38 */
+ 81,  81,  81,  81,  81,  81,  81,  81,  /*   38 */
+ 15,  46,  46,  46,  46,  46,  46,  46,  /*   38 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   38 */
+ 46,  46,  60,  80,  46,  40,  40,  40,  /*   39 */
+ 40,  40,  40,  46,  46,  46,  40,  40,  /*   39 */
+ 40,  46,  40,  40,  40,  40,  46,  46,  /*   39 */
+ 46,  40,  40,  46,  40,  46,  40,  40,  /*   39 */
+ 46,  46,  46,  40,  40,  46,  46,  46,  /*   39 */
+ 40,  40,  40,  46,  46,  46,  40,  40,  /*   39 */
+ 40,  40,  40,  40,  40,  40,  46,  40,  /*   39 */
+ 40,  40,  46,  46,  46,  46,  80,  80,  /*   39 */
+ 60,  80,  80,  46,  46,  46,  80,  80,  /*   40 */
+ 80,  46,  80,  80,  80,  60,  46,  46,  /*   40 */
+ 46,  46,  46,  46,  46,  46,  46,  80,  /*   40 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   40 */
+ 46,  46,  46,  46,  46,  46,  46,  81,  /*   40 */
+ 81,  81,  81,  81,  81,  81,  81,  81,  /*   40 */
+ 84,  19,  19,  46,  46,  46,  46,  46,  /*   40 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   40 */
+ 46,  80,  80,  80,  46,  40,  40,  40,  /*   41 */
+ 40,  40,  40,  40,  40,  46,  40,  40,  /*   41 */
+ 40,  46,  40,  40,  40,  40,  40,  40,  /*   41 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   41 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   41 */
+ 40,  46,  40,  40,  40,  40,  40,  40,  /*   41 */
+ 40,  40,  40,  40,  46,  40,  40,  40,  /*   41 */
+ 40,  40,  46,  46,  46,  46,  60,  60,  /*   41 */
+ 60,  80,  80,  80,  80,  46,  60,  60,  /*   42 */
+ 60,  46,  60,  60,  60,  60,  46,  46,  /*   42 */
+ 46,  46,  46,  46,  46,  60,  60,  46,  /*   42 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   42 */
+ 40,  40,  46,  46,  46,  46,  81,  81,  /*   42 */
+ 81,  81,  81,  81,  81,  81,  81,  81,  /*   42 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   42 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   42 */
+ 46,  46,  80,  80,  46,  40,  40,  40,  /*   43 */
+ 40,  40,  40,  40,  40,  46,  40,  40,  /*   43 */
+ 40,  46,  40,  40,  40,  40,  40,  40,  /*   43 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   43 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   43 */
+ 40,  46,  40,  40,  40,  40,  40,  40,  /*   43 */
+ 40,  40,  40,  40,  46,  40,  40,  40,  /*   43 */
+ 40,  40,  46,  46,  46,  46,  80,  60,  /*   43 */
+ 80,  80,  80,  80,  80,  46,  60,  80,  /*   44 */
+ 80,  46,  80,  80,  60,  60,  46,  46,  /*   44 */
+ 46,  46,  46,  46,  46,  80,  80,  46,  /*   44 */
+ 46,  46,  46,  46,  46,  46,  40,  46,  /*   44 */
+ 40,  40,  46,  46,  46,  46,  81,  81,  /*   44 */
+ 81,  81,  81,  81,  81,  81,  81,  81,  /*   44 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   44 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   44 */
+ 46,  46,  80,  80,  46,  40,  40,  40,  /*   45 */
+ 40,  40,  40,  40,  40,  46,  40,  40,  /*   45 */
+ 40,  46,  40,  40,  40,  40,  40,  40,  /*   45 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   45 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   45 */
+ 40,  46,  40,  40,  40,  40,  40,  40,  /*   45 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   45 */
+ 40,  40,  46,  46,  46,  46,  80,  80,  /*   45 */
+ 80,  60,  60,  60,  46,  46,  80,  80,  /*   46 */
+ 80,  46,  80,  80,  80,  60,  46,  46,  /*   46 */
+ 46,  46,  46,  46,  46,  46,  46,  80,  /*   46 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   46 */
+ 40,  40,  46,  46,  46,  46,  81,  81,  /*   46 */
+ 81,  81,  81,  81,  81,  81,  81,  81,  /*   46 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   46 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   46 */
+ 46,  40,  40,  40,  40,  40,  40,  40,  /*   47 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   47 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   47 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   47 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   47 */
+ 40,  40,  40,  40,  40,  40,  40,   3,  /*   47 */
+ 40,  60,  40,  40,  60,  60,  60,  60,  /*   47 */
+ 60,  60,  60,  46,  46,  46,  46,   4,  /*   47 */
+ 40,  40,  40,  40,  40,  40,  59,  60,  /*   48 */
+ 60,  60,  60,  60,  60,  60,  60,  15,  /*   48 */
+  9,   9,   9,   9,   9,   9,   9,   9,  /*   48 */
+  9,   9,   3,   3,  46,  46,  46,  46,  /*   48 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   48 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   48 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   48 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   48 */
+ 46,  40,  40,  46,  40,  46,  46,  40,  /*   49 */
+ 40,  46,  40,  46,  46,  40,  46,  46,  /*   49 */
+ 46,  46,  46,  46,  40,  40,  40,  40,  /*   49 */
+ 46,  40,  40,  40,  40,  40,  40,  40,  /*   49 */
+ 46,  40,  40,  40,  46,  40,  46,  40,  /*   49 */
+ 46,  46,  40,  40,  46,  40,  40,   3,  /*   49 */
+ 40,  60,  40,  40,  60,  60,  60,  60,  /*   49 */
+ 60,  60,  46,  60,  60,  40,  46,  46,  /*   49 */
+ 40,  40,  40,  40,  40,  46,  59,  46,  /*   50 */
+ 60,  60,  60,  60,  60,  60,  46,  46,  /*   50 */
+  9,   9,   9,   9,   9,   9,   9,   9,  /*   50 */
+  9,   9,  46,  46,  40,  40,  46,  46,  /*   50 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   50 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   50 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   50 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   50 */
+ 15,  15,  15,  15,   3,   3,   3,   3,  /*   51 */
+  3,   3,   3,   3,   3,   3,   3,   3,  /*   51 */
+  3,   3,   3,  15,  15,  15,  15,  15,  /*   51 */
+ 60,  60,  15,  15,  15,  15,  15,  15,  /*   51 */
+ 78,  78,  78,  78,  78,  78,  78,  78,  /*   51 */
+ 78,  78,  85,  85,  85,  85,  85,  85,  /*   51 */
+ 85,  85,  85,  85,  15,  60,  15,  60,  /*   51 */
+ 15,  60,   5,   6,   5,   6,  80,  80,  /*   51 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   52 */
+ 46,  40,  40,  40,  40,  40,  40,  40,  /*   52 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   52 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   52 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   52 */
+ 40,  40,  46,  46,  46,  46,  46,  46,  /*   52 */
+ 46,  60,  60,  60,  60,  60,  60,  60,  /*   52 */
+ 60,  60,  60,  60,  60,  60,  60,  80,  /*   52 */
+ 60,  60,  60,  60,  60,   3,  60,  60,  /*   53 */
+ 60,  60,  60,  60,  46,  46,  46,  46,  /*   53 */
+ 60,  60,  60,  60,  60,  60,  46,  60,  /*   53 */
+ 46,  60,  60,  60,  60,  60,  60,  60,  /*   53 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   53 */
+ 60,  60,  60,  60,  60,  60,  46,  46,  /*   53 */
+ 46,  60,  60,  60,  60,  60,  60,  60,  /*   53 */
+ 46,  60,  46,  46,  46,  46,  46,  46,  /*   53 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   54 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   54 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   54 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   54 */
+ 76,  76,  76,  76,  76,  76,  76,  76,  /*   54 */
+ 76,  76,  76,  76,  76,  76,  76,  76,  /*   54 */
+ 76,  76,  76,  76,  76,  76,  76,  76,  /*   54 */
+ 76,  76,  76,  76,  76,  76,  76,  76,  /*   54 */
+ 76,  76,  76,  76,  76,  76,  46,  46,  /*   55 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   55 */
+ 16,  16,  16,  16,  16,  16,  16,  16,  /*   55 */
+ 16,  16,  16,  16,  16,  16,  16,  16,  /*   55 */
+ 16,  16,  16,  16,  16,  16,  16,  16,  /*   55 */
+ 16,  16,  16,  16,  16,  16,  16,  16,  /*   55 */
+ 16,  16,  16,  16,  16,  16,  16,  46,  /*   55 */
+ 46,  46,  46,   3,  46,  46,  46,  46,  /*   55 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   56 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   56 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   56 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   56 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   56 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   56 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   56 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   56 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   57 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   57 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   57 */
+ 40,  40,  46,  46,  46,  46,  46,  40,  /*   57 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   57 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   57 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   57 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   57 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   58 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   58 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   58 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   58 */
+ 40,  40,  40,  46,  46,  46,  46,  46,  /*   58 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   58 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   58 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   58 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   59 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   59 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   59 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   59 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   59 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   59 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   59 */
+ 40,  40,  46,  46,  46,  46,  46,  46,  /*   59 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   60 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   60 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   60 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   60 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   60 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   60 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   60 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   60 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   61 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   61 */
+ 23,  24,  23,  24,  23,  24,  16,  16,  /*   61 */
+ 16,  16,  16,  16,  46,  46,  46,  46,  /*   61 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   61 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   61 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   61 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   61 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   62 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   62 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   62 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   62 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   62 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   62 */
+ 23,  24,  23,  24,  23,  24,  23,  24,  /*   62 */
+ 23,  24,  46,  46,  46,  46,  46,  46,  /*   62 */
+ 86,  86,  86,  86,  86,  86,  86,  86,  /*   63 */
+ 87,  87,  87,  87,  87,  87,  87,  87,  /*   63 */
+ 86,  86,  86,  86,  86,  86,  46,  46,  /*   63 */
+ 87,  87,  87,  87,  87,  87,  46,  46,  /*   63 */
+ 86,  86,  86,  86,  86,  86,  86,  86,  /*   63 */
+ 87,  87,  87,  87,  87,  87,  87,  87,  /*   63 */
+ 86,  86,  86,  86,  86,  86,  86,  86,  /*   63 */
+ 87,  87,  87,  87,  87,  87,  87,  87,  /*   63 */
+ 86,  86,  86,  86,  86,  86,  46,  46,  /*   64 */
+ 87,  87,  87,  87,  87,  87,  46,  46,  /*   64 */
+ 16,  86,  16,  86,  16,  86,  16,  86,  /*   64 */
+ 46,  87,  46,  87,  46,  87,  46,  87,  /*   64 */
+ 86,  86,  86,  86,  86,  86,  86,  86,  /*   64 */
+ 87,  87,  87,  87,  87,  87,  87,  87,  /*   64 */
+ 88,  88,  89,  89,  89,  89,  90,  90,  /*   64 */
+ 91,  91,  92,  92,  93,  93,  46,  46,  /*   64 */
+ 86,  86,  86,  86,  86,  86,  86,  86,  /*   65 */
+ 87,  87,  87,  87,  87,  87,  87,  87,  /*   65 */
+ 86,  86,  86,  86,  86,  86,  86,  86,  /*   65 */
+ 87,  87,  87,  87,  87,  87,  87,  87,  /*   65 */
+ 86,  86,  86,  86,  86,  86,  86,  86,  /*   65 */
+ 87,  87,  87,  87,  87,  87,  87,  87,  /*   65 */
+ 86,  86,  16,  94,  16,  46,  16,  16,  /*   65 */
+ 87,  87,  95,  95,  96,  11,  38,  11,  /*   65 */
+ 11,  11,  16,  94,  16,  46,  16,  16,  /*   66 */
+ 97,  97,  97,  97,  96,  11,  11,  11,  /*   66 */
+ 86,  86,  16,  16,  46,  46,  16,  16,  /*   66 */
+ 87,  87,  98,  98,  46,  11,  11,  11,  /*   66 */
+ 86,  86,  16,  16,  16,  99,  16,  16,  /*   66 */
+ 87,  87, 100, 100, 101,  11,  11,  11,  /*   66 */
+ 46,  46,  16,  94,  16,  46,  16,  16,  /*   66 */
+102, 102, 103, 103,  96,  11,  11,  46,  /*   66 */
+  2,   2,   2,   2,   2,   2,   2,   2,  /*   67 */
+  2,   2,   2,   2, 104, 104, 104, 104,  /*   67 */
+  8,   8,   8,   8,   8,   8,   3,   3,  /*   67 */
+  5,   6,   5,   5,   5,   6,   5,   5,  /*   67 */
+  3,   3,   3,   3,   3,   3,   3,   3,  /*   67 */
+105, 106, 104, 104, 104, 104, 104,  46,  /*   67 */
+  3,   3,   3,   3,   3,   3,   3,   3,  /*   67 */
+  3,   5,   6,   3,   3,   3,   3,  12,  /*   67 */
+ 12,   3,   3,   3,   7,   5,   6,  46,  /*   68 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   68 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   68 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   68 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   68 */
+ 46,  46, 104, 104, 104, 104, 104, 104,  /*   68 */
+ 17,  46,  46,  46,  17,  17,  17,  17,  /*   68 */
+ 17,  17,   7,   7,   7,   5,   6,  16,  /*   68 */
+107, 107, 107, 107, 107, 107, 107, 107,  /*   69 */
+107, 107,   7,   7,   7,   5,   6,  46,  /*   69 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   69 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   69 */
+  4,   4,   4,   4,   4,   4,   4,   4,  /*   69 */
+  4,   4,   4,   4,  46,  46,  46,  46,  /*   69 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   69 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   69 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   70 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   70 */
+ 60,  60,  60,  60,  60,  60,  60,  60,  /*   70 */
+ 60,  60,  60,  60,  60,  79,  79,  79,  /*   70 */
+ 79,  60,  46,  46,  46,  46,  46,  46,  /*   70 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   70 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   70 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   70 */
+ 15,  15,  38,  15,  15,  15,  15,  38,  /*   71 */
+ 15,  15,  16,  38,  38,  38,  16,  16,  /*   71 */
+ 38,  38,  38,  16,  15,  38,  15,  15,  /*   71 */
+ 38,  38,  38,  38,  38,  38,  15,  15,  /*   71 */
+ 15,  15,  15,  15,  38,  15,  38,  15,  /*   71 */
+ 38,  15,  38,  38,  38,  38,  16,  16,  /*   71 */
+ 38,  38,  15,  38,  16,  40,  40,  40,  /*   71 */
+ 40,  46,  46,  46,  46,  46,  46,  46,  /*   71 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   72 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   72 */
+ 46,  46,  46,  19,  19,  19,  19,  19,  /*   72 */
+ 19,  19,  19,  19,  19,  19,  19, 108,  /*   72 */
+109, 109, 109, 109, 109, 109, 109, 109,  /*   72 */
+109, 109, 109, 109, 110, 110, 110, 110,  /*   72 */
+111, 111, 111, 111, 111, 111, 111, 111,  /*   72 */
+111, 111, 111, 111, 112, 112, 112, 112,  /*   72 */
+113, 113, 113,  46,  46,  46,  46,  46,  /*   73 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   73 */
+  7,   7,   7,   7,   7,  15,  15,  15,  /*   73 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   73 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   73 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   73 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   73 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   73 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   74 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   74 */
+ 15,  15,   7,  15,   7,  15,  15,  15,  /*   74 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   74 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   74 */
+ 15,  15,  15,  46,  46,  46,  46,  46,  /*   74 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   74 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   74 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   75 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   75 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   75 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   75 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   75 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   75 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   75 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   75 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   76 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   76 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   76 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   76 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   76 */
+  7,   7,   7,   7,   7,   7,   7,   7,  /*   76 */
+  7,   7,  46,  46,  46,  46,  46,  46,  /*   76 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   76 */
+ 15,  46,  15,  15,  15,  15,  15,  15,  /*   77 */
+  7,   7,   7,   7,  15,  15,  15,  15,  /*   77 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   77 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   77 */
+  7,   7,  15,  15,  15,  15,  15,  15,  /*   77 */
+ 15,   5,   6,  15,  15,  15,  15,  15,  /*   77 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   77 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   77 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   78 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   78 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   78 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   78 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   78 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   78 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   78 */
+ 15,  15,  15,  46,  46,  46,  46,  46,  /*   78 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   79 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   79 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   79 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   79 */
+ 15,  15,  15,  15,  15,  46,  46,  46,  /*   79 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   79 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   79 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   79 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   80 */
+ 15,  15,  15,  46,  46,  46,  46,  46,  /*   80 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   80 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   80 */
+114, 114, 114, 114, 114, 114, 114, 114,  /*   80 */
+114, 114, 114, 114, 114, 114, 114, 114,  /*   80 */
+114, 114, 114, 114,  82,  82,  82,  82,  /*   80 */
+ 82,  82,  82,  82,  82,  82,  82,  82,  /*   80 */
+ 82,  82,  82,  82,  82,  82,  82,  82,  /*   81 */
+115, 115, 115, 115, 115, 115, 115, 115,  /*   81 */
+115, 115, 115, 115, 115, 115, 115, 115,  /*   81 */
+115, 115, 115, 115,  15,  15,  15,  15,  /*   81 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   81 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   81 */
+ 15,  15,  15,  15,  15,  15, 116, 116,  /*   81 */
+116, 116, 116, 116, 116, 116, 116, 116,  /*   81 */
+116, 116, 116, 116, 116, 116, 116, 116,  /*   82 */
+116, 116, 116, 116, 116, 116, 116, 116,  /*   82 */
+117, 117, 117, 117, 117, 117, 117, 117,  /*   82 */
+117, 117, 117, 117, 117, 117, 117, 117,  /*   82 */
+117, 117, 117, 117, 117, 117, 117, 117,  /*   82 */
+117, 117, 118,  46,  46,  46,  46,  46,  /*   82 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   82 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   82 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   83 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   83 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   83 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   83 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   83 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   83 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   83 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   83 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   84 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   84 */
+ 15,  15,  15,  15,  15,  15,  46,  46,  /*   84 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   84 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   84 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   84 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   84 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   84 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   85 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   85 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   85 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   85 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   85 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   85 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   85 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   85 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   86 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   86 */
+ 15,  15,  15,  15,  46,  46,  46,  46,  /*   86 */
+ 46,  46,  15,  15,  15,  15,  15,  15,  /*   86 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   86 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   86 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   86 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   86 */
+ 46,  15,  15,  15,  15,  46,  15,  15,  /*   87 */
+ 15,  15,  46,  46,  15,  15,  15,  15,  /*   87 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   87 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   87 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   87 */
+ 46,  15,  15,  15,  15,  15,  15,  15,  /*   87 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   87 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   87 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   88 */
+ 15,  15,  15,  15,  46,  15,  46,  15,  /*   88 */
+ 15,  15,  15,  46,  46,  46,  15,  46,  /*   88 */
+ 15,  15,  15,  15,  15,  15,  15,  46,  /*   88 */
+ 46,  15,  15,  15,  15,  15,  15,  15,  /*   88 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   88 */
+ 46,  46,  46,  46,  46,  46, 119, 119,  /*   88 */
+119, 119, 119, 119, 119, 119, 119, 119,  /*   88 */
+114, 114, 114, 114, 114, 114, 114, 114,  /*   89 */
+114, 114,  83,  83,  83,  83,  83,  83,  /*   89 */
+ 83,  83,  83,  83,  15,  46,  46,  46,  /*   89 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   89 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   89 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   89 */
+ 46,  15,  15,  15,  15,  15,  15,  15,  /*   89 */
+ 15,  15,  15,  15,  15,  15,  15,  46,  /*   89 */
+  2,   3,   3,   3,  15,  59,   3, 120,  /*   90 */
+  5,   6,   5,   6,   5,   6,   5,   6,  /*   90 */
+  5,   6,  15,  15,   5,   6,   5,   6,  /*   90 */
+  5,   6,   5,   6,   8,   5,   6,   5,  /*   90 */
+ 15, 121, 121, 121, 121, 121, 121, 121,  /*   90 */
+121, 121,  60,  60,  60,  60,  60,  60,  /*   90 */
+  8,  59,  59,  59,  59,  59,  15,  15,  /*   90 */
+ 46,  46,  46,  46,  46,  46,  46,  15,  /*   90 */
+ 46,  40,  40,  40,  40,  40,  40,  40,  /*   91 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   91 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   91 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   91 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   91 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   91 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   91 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   91 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   92 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   92 */
+ 40,  40,  40,  40,  40,  46,  46,  46,  /*   92 */
+ 46,  60,  60,  59,  59,  59,  59,  46,  /*   92 */
+ 46,  40,  40,  40,  40,  40,  40,  40,  /*   92 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   92 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   92 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   92 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   93 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   93 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   93 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   93 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   93 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   93 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   93 */
+ 40,  40,  40,   3,  59,  59,  59,  46,  /*   93 */
+ 46,  46,  46,  46,  46,  40,  40,  40,  /*   94 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   94 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   94 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   94 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   94 */
+ 40,  40,  40,  40,  40,  46,  46,  46,  /*   94 */
+ 46,  40,  40,  40,  40,  40,  40,  40,  /*   94 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   94 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*   95 */
+ 40,  40,  40,  40,  40,  40,  40,  46,  /*   95 */
+ 15,  15,  85,  85,  85,  85,  15,  15,  /*   95 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   95 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   95 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   95 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   95 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   95 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   96 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   96 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   96 */
+ 15,  15,  15,  15,  15,  46,  46,  46,  /*   96 */
+ 85,  85,  85,  85,  85,  85,  85,  85,  /*   96 */
+ 85,  85,  15,  15,  15,  15,  15,  15,  /*   96 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   96 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   96 */
+ 15,  15,  15,  15,  46,  46,  46,  46,  /*   97 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   97 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   97 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   97 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   97 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   97 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   97 */
+ 15,  15,  15,  15,  46,  46,  46,  15,  /*   97 */
+114, 114, 114, 114, 114, 114, 114, 114,  /*   98 */
+114, 114,  15,  15,  15,  15,  15,  15,  /*   98 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   98 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   98 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   98 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   98 */
+ 15,  46,  46,  46,  46,  46,  46,  46,  /*   98 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*   98 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   99 */
+ 15,  15,  15,  15,  46,  46,  46,  46,  /*   99 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   99 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   99 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   99 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   99 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*   99 */
+ 15,  15,  15,  15,  15,  15,  15,  46,  /*   99 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  100 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  100 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  100 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  100 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  100 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  100 */
+ 15,  15,  15,  15,  15,  15,  15,  46,  /*  100 */
+ 46,  46,  46,  15,  15,  15,  15,  15,  /*  100 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  101 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  101 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  101 */
+ 15,  15,  15,  15,  15,  15,  46,  46,  /*  101 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  101 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  101 */
+ 15,  15,  15,  15,  15,  15,  15,  15,  /*  101 */
+ 15,  15,  15,  15,  15,  15,  15,  46,  /*  101 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  102 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  102 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  102 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  102 */
+ 40,  40,  40,  40,  40,  40,  46,  46,  /*  102 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  102 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  102 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  102 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  103 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  103 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  103 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  103 */
+ 40,  40,  40,  40,  46,  46,  46,  46,  /*  103 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  103 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  103 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  103 */
+122, 122, 122, 122, 122, 122, 122, 122,  /*  104 */
+122, 122, 122, 122, 122, 122, 122, 122,  /*  104 */
+122, 122, 122, 122, 122, 122, 122, 122,  /*  104 */
+122, 122, 122, 122, 122, 122, 122, 122,  /*  104 */
+122, 122, 122, 122, 122, 122, 122, 122,  /*  104 */
+122, 122, 122, 122, 122, 122, 122, 122,  /*  104 */
+122, 122, 122, 122, 122, 122, 122, 122,  /*  104 */
+122, 122, 122, 122, 122, 122, 122, 122,  /*  104 */
+123, 123, 123, 123, 123, 123, 123, 123,  /*  105 */
+123, 123, 123, 123, 123, 123, 123, 123,  /*  105 */
+123, 123, 123, 123, 123, 123, 123, 123,  /*  105 */
+123, 123, 123, 123, 123, 123, 123, 123,  /*  105 */
+123, 123, 123, 123, 123, 123, 123, 123,  /*  105 */
+123, 123, 123, 123, 123, 123, 123, 123,  /*  105 */
+123, 123, 123, 123, 123, 123, 123, 123,  /*  105 */
+123, 123, 123, 123, 123, 123, 123, 123,  /*  105 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  106 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  106 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  106 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  106 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  106 */
+ 40,  40,  40,  40,  40,  40,  46,  46,  /*  106 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  106 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  106 */
+ 16,  16,  16,  16,  16,  16,  16,  46,  /*  107 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  107 */
+ 46,  46,  46,  16,  16,  16,  16,  16,  /*  107 */
+ 46,  46,  46,  46,  46,  46,  60,  40,  /*  107 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  107 */
+ 40,   7,  40,  40,  40,  40,  40,  40,  /*  107 */
+ 40,  40,  40,  40,  40,  40,  40,  46,  /*  107 */
+ 40,  40,  40,  40,  40,  46,  40,  46,  /*  107 */
+ 40,  40,  46,  40,  40,  46,  40,  40,  /*  108 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  108 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  108 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  108 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  108 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  108 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  108 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  108 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  109 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  109 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  109 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  109 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  109 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  109 */
+ 40,  40,  46,  46,  46,  46,  46,  46,  /*  109 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  109 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  110 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  110 */
+ 46,  46,  46,  40,  40,  40,  40,  40,  /*  110 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  110 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  110 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  110 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  110 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  110 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  111 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  111 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  111 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  111 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  111 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  111 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  111 */
+ 40,  40,  40,  40,  40,  40,   5,   6,  /*  111 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  112 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  112 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  112 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  112 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  112 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  112 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  112 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  112 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  113 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  113 */
+ 46,  46,  40,  40,  40,  40,  40,  40,  /*  113 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  113 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  113 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  113 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  113 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  113 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  114 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  114 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  114 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  114 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  114 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  114 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  114 */
+ 40,  40,  40,  40,  46,  46,  46,  46,  /*  114 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  115 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  115 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  115 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  115 */
+ 60,  60,  60,  60,  46,  46,  46,  46,  /*  115 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  115 */
+  3,   8,   8,  12,  12,   5,   6,   5,  /*  115 */
+  6,   5,   6,   5,   6,   5,   6,   5,  /*  115 */
+  6,   5,   6,   5,   6,  46,  46,  46,  /*  116 */
+ 46,   3,   3,   3,   3,  12,  12,  12,  /*  116 */
+  3,   3,   3,  46,   3,   3,   3,   3,  /*  116 */
+  8,   5,   6,   5,   6,   5,   6,   3,  /*  116 */
+  3,   3,   7,   8,   7,   7,   7,  46,  /*  116 */
+  3,   4,   3,   3,  46,  46,  46,  46,  /*  116 */
+ 40,  40,  40,  46,  40,  46,  40,  40,  /*  116 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  116 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  117 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  117 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  117 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  117 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  117 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  117 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  117 */
+ 40,  40,  40,  40,  40,  46,  46, 104,  /*  117 */
+ 46,   3,   3,   3,   4,   3,   3,   3,  /*  118 */
+  5,   6,   3,   7,   3,   8,   3,   3,  /*  118 */
+  9,   9,   9,   9,   9,   9,   9,   9,  /*  118 */
+  9,   9,   3,   3,   7,   7,   7,   3,  /*  118 */
+  3,  10,  10,  10,  10,  10,  10,  10,  /*  118 */
+ 10,  10,  10,  10,  10,  10,  10,  10,  /*  118 */
+ 10,  10,  10,  10,  10,  10,  10,  10,  /*  118 */
+ 10,  10,  10,   5,   3,   6,  11,  12,  /*  118 */
+ 11,  13,  13,  13,  13,  13,  13,  13,  /*  119 */
+ 13,  13,  13,  13,  13,  13,  13,  13,  /*  119 */
+ 13,  13,  13,  13,  13,  13,  13,  13,  /*  119 */
+ 13,  13,  13,   5,   7,   6,   7,  46,  /*  119 */
+ 46,   3,   5,   6,   3,   3,  40,  40,  /*  119 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  119 */
+ 59,  40,  40,  40,  40,  40,  40,  40,  /*  119 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  119 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  120 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  120 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  120 */
+ 40,  40,  40,  40,  40,  40,  59,  59,  /*  120 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  120 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  120 */
+ 40,  40,  40,  40,  40,  40,  40,  40,  /*  120 */
+ 40,  40,  40,  40,  40,  40,  40,  46,  /*  120 */
+ 46,  46,  40,  40,  40,  40,  40,  40,  /*  121 */
+ 46,  46,  40,  40,  40,  40,  40,  40,  /*  121 */
+ 46,  46,  40,  40,  40,  40,  40,  40,  /*  121 */
+ 46,  46,  40,  40,  40,  46,  46,  46,  /*  121 */
+  4,   4,   7,  11,  15,   4,   4,  46,  /*  121 */
+  7,   7,   7,   7,   7,  15,  15,  46,  /*  121 */
+ 46,  46,  46,  46,  46,  46,  46,  46,  /*  121 */
+ 46,  46,  46,  46,  46,  15,  46,  46   /*  121 */
+};
+
+/* The A table has 124 entries for a total of 496 bytes. */
+
+const uint32 js_A[] = {
+0x0001000F,  /*    0   Cc, ignorable */
+0x0004000F,  /*    1   Cc, whitespace */
+0x0004000C,  /*    2   Zs, whitespace */
+0x00000018,  /*    3   Po */
+0x0006001A,  /*    4   Sc, currency */
+0x00000015,  /*    5   Ps */
+0x00000016,  /*    6   Pe */
+0x00000019,  /*    7   Sm */
+0x00000014,  /*    8   Pd */
+0x00036089,  /*    9   Nd, identifier part, decimal 16 */
+0x0827FF81,  /*   10   Lu, hasLower (add 32), identifier start, supradecimal 31 */
+0x0000001B,  /*   11   Sk */
+0x00050017,  /*   12   Pc, underscore */
+0x0817FF82,  /*   13   Ll, hasUpper (subtract 32), identifier start, supradecimal 31 */
+0x0000000C,  /*   14   Zs */
+0x0000001C,  /*   15   So */
+0x00070182,  /*   16   Ll, identifier start */
+0x0000600B,  /*   17   No, decimal 16 */
+0x0000500B,  /*   18   No, decimal 8 */
+0x0000800B,  /*   19   No, strange */
+0x08270181,  /*   20   Lu, hasLower (add 32), identifier start */
+0x08170182,  /*   21   Ll, hasUpper (subtract 32), identifier start */
+0xE1D70182,  /*   22   Ll, hasUpper (subtract -121), identifier start */
+0x00670181,  /*   23   Lu, hasLower (add 1), identifier start */
+0x00570182,  /*   24   Ll, hasUpper (subtract 1), identifier start */
+0xCE670181,  /*   25   Lu, hasLower (add -199), identifier start */
+0x3A170182,  /*   26   Ll, hasUpper (subtract 232), identifier start */
+0xE1E70181,  /*   27   Lu, hasLower (add -121), identifier start */
+0x4B170182,  /*   28   Ll, hasUpper (subtract 300), identifier start */
+0x34A70181,  /*   29   Lu, hasLower (add 210), identifier start */
+0x33A70181,  /*   30   Lu, hasLower (add 206), identifier start */
+0x33670181,  /*   31   Lu, hasLower (add 205), identifier start */
+0x32A70181,  /*   32   Lu, hasLower (add 202), identifier start */
+0x32E70181,  /*   33   Lu, hasLower (add 203), identifier start */
+0x33E70181,  /*   34   Lu, hasLower (add 207), identifier start */
+0x34E70181,  /*   35   Lu, hasLower (add 211), identifier start */
+0x34670181,  /*   36   Lu, hasLower (add 209), identifier start */
+0x35670181,  /*   37   Lu, hasLower (add 213), identifier start */
+0x00070181,  /*   38   Lu, identifier start */
+0x36A70181,  /*   39   Lu, hasLower (add 218), identifier start */
+0x00070185,  /*   40   Lo, identifier start */
+0x36670181,  /*   41   Lu, hasLower (add 217), identifier start */
+0x36E70181,  /*   42   Lu, hasLower (add 219), identifier start */
+0x00AF0181,  /*   43   Lu, hasLower (add 2), hasTitle, identifier start */
+0x007F0183,  /*   44   Lt, hasUpper (subtract 1), hasLower (add 1), hasTitle, identifier start */
+0x009F0182,  /*   45   Ll, hasUpper (subtract 2), hasTitle, identifier start */
+0x00000000,  /*   46   unassigned */
+0x34970182,  /*   47   Ll, hasUpper (subtract 210), identifier start */
+0x33970182,  /*   48   Ll, hasUpper (subtract 206), identifier start */
+0x33570182,  /*   49   Ll, hasUpper (subtract 205), identifier start */
+0x32970182,  /*   50   Ll, hasUpper (subtract 202), identifier start */
+0x32D70182,  /*   51   Ll, hasUpper (subtract 203), identifier start */
+0x33D70182,  /*   52   Ll, hasUpper (subtract 207), identifier start */
+0x34570182,  /*   53   Ll, hasUpper (subtract 209), identifier start */
+0x34D70182,  /*   54   Ll, hasUpper (subtract 211), identifier start */
+0x35570182,  /*   55   Ll, hasUpper (subtract 213), identifier start */
+0x36970182,  /*   56   Ll, hasUpper (subtract 218), identifier start */
+0x36570182,  /*   57   Ll, hasUpper (subtract 217), identifier start */
+0x36D70182,  /*   58   Ll, hasUpper (subtract 219), identifier start */
+0x00070084,  /*   59   Lm, identifier start */
+0x00030086,  /*   60   Mn, identifier part */
+0x09A70181,  /*   61   Lu, hasLower (add 38), identifier start */
+0x09670181,  /*   62   Lu, hasLower (add 37), identifier start */
+0x10270181,  /*   63   Lu, hasLower (add 64), identifier start */
+0x0FE70181,  /*   64   Lu, hasLower (add 63), identifier start */
+0x09970182,  /*   65   Ll, hasUpper (subtract 38), identifier start */
+0x09570182,  /*   66   Ll, hasUpper (subtract 37), identifier start */
+0x10170182,  /*   67   Ll, hasUpper (subtract 64), identifier start */
+0x0FD70182,  /*   68   Ll, hasUpper (subtract 63), identifier start */
+0x0F970182,  /*   69   Ll, hasUpper (subtract 62), identifier start */
+0x0E570182,  /*   70   Ll, hasUpper (subtract 57), identifier start */
+0x0BD70182,  /*   71   Ll, hasUpper (subtract 47), identifier start */
+0x0D970182,  /*   72   Ll, hasUpper (subtract 54), identifier start */
+0x15970182,  /*   73   Ll, hasUpper (subtract 86), identifier start */
+0x14170182,  /*   74   Ll, hasUpper (subtract 80), identifier start */
+0x14270181,  /*   75   Lu, hasLower (add 80), identifier start */
+0x0C270181,  /*   76   Lu, hasLower (add 48), identifier start */
+0x0C170182,  /*   77   Ll, hasUpper (subtract 48), identifier start */
+0x00034089,  /*   78   Nd, identifier part, decimal 0 */
+0x00000087,  /*   79   Me */
+0x00030088,  /*   80   Mc, identifier part */
+0x00037489,  /*   81   Nd, identifier part, decimal 26 */
+0x00005A0B,  /*   82   No, decimal 13 */
+0x00006E0B,  /*   83   No, decimal 23 */
+0x0000740B,  /*   84   No, decimal 26 */
+0x0000000B,  /*   85   No */
+0xFE170182,  /*   86   Ll, hasUpper (subtract -8), identifier start */
+0xFE270181,  /*   87   Lu, hasLower (add -8), identifier start */
+0xED970182,  /*   88   Ll, hasUpper (subtract -74), identifier start */
+0xEA970182,  /*   89   Ll, hasUpper (subtract -86), identifier start */
+0xE7170182,  /*   90   Ll, hasUpper (subtract -100), identifier start */
+0xE0170182,  /*   91   Ll, hasUpper (subtract -128), identifier start */
+0xE4170182,  /*   92   Ll, hasUpper (subtract -112), identifier start */
+0xE0970182,  /*   93   Ll, hasUpper (subtract -126), identifier start */
+0xFDD70182,  /*   94   Ll, hasUpper (subtract -9), identifier start */
+0xEDA70181,  /*   95   Lu, hasLower (add -74), identifier start */
+0xFDE70181,  /*   96   Lu, hasLower (add -9), identifier start */
+0xEAA70181,  /*   97   Lu, hasLower (add -86), identifier start */
+0xE7270181,  /*   98   Lu, hasLower (add -100), identifier start */
+0xFE570182,  /*   99   Ll, hasUpper (subtract -7), identifier start */
+0xE4270181,  /*  100   Lu, hasLower (add -112), identifier start */
+0xFE670181,  /*  101   Lu, hasLower (add -7), identifier start */
+0xE0270181,  /*  102   Lu, hasLower (add -128), identifier start */
+0xE0A70181,  /*  103   Lu, hasLower (add -126), identifier start */
+0x00010010,  /*  104   Cf, ignorable */
+0x0004000D,  /*  105   Zl, whitespace */
+0x0004000E,  /*  106   Zp, whitespace */
+0x0000400B,  /*  107   No, decimal 0 */
+0x0000440B,  /*  108   No, decimal 2 */
+0x0427438A,  /*  109   Nl, hasLower (add 16), identifier start, decimal 1 */
+0x0427818A,  /*  110   Nl, hasLower (add 16), identifier start, strange */
+0x0417638A,  /*  111   Nl, hasUpper (subtract 16), identifier start, decimal 17 */
+0x0417818A,  /*  112   Nl, hasUpper (subtract 16), identifier start, strange */
+0x0007818A,  /*  113   Nl, identifier start, strange */
+0x0000420B,  /*  114   No, decimal 1 */
+0x0000720B,  /*  115   No, decimal 25 */
+0x06A0001C,  /*  116   So, hasLower (add 26) */
+0x0690001C,  /*  117   So, hasUpper (subtract 26) */
+0x00006C0B,  /*  118   No, decimal 22 */
+0x0000560B,  /*  119   No, decimal 11 */
+0x0007738A,  /*  120   Nl, identifier start, decimal 25 */
+0x0007418A,  /*  121   Nl, identifier start, decimal 0 */
+0x00000013,  /*  122   Cs */
+0x00000012   /*  123   Co */
+};
+
+const jschar js_uriReservedPlusPound_ucstr[] =
+    {';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#', 0};
+const jschar js_uriUnescaped_ucstr[] =
+    {'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',
+     '-', '_', '.', '!', '~', '*', '\'', '(', ')', 0};
+
+#define URI_CHUNK 64U
+
+/* Concatenate jschars onto an unshared/newborn JSString. */
+static JSBool
+AddCharsToURI(JSContext *cx, JSString *str, const jschar *chars, size_t length)
+{
+    size_t total;
+
+    JS_ASSERT(!JSSTRING_IS_DEPENDENT(str));
+    total = str->length + length + 1;
+    if (!str->chars ||
+        JS_HOWMANY(total, URI_CHUNK) > JS_HOWMANY(str->length + 1, URI_CHUNK)) {
+        total = JS_ROUNDUP(total, URI_CHUNK);
+        str->chars = JS_realloc(cx, str->chars, total * sizeof(jschar));
+        if (!str->chars)
+            return JS_FALSE;
+    }
+    js_strncpy(str->chars + str->length, chars, length);
+    str->length += length;
+    str->chars[str->length] = 0;
+    return JS_TRUE;
+}
+
+/*
+ * ECMA 3, 15.1.3 URI Handling Function Properties
+ *
+ * The following are implementations of the algorithms
+ * given in the ECMA specification for the hidden functions
+ * 'Encode' and 'Decode'.
+ */
+static JSBool
+Encode(JSContext *cx, JSString *str, const jschar *unescapedSet,
+       const jschar *unescapedSet2, jsval *rval)
+{
+    size_t length, j, k, L;
+    jschar *chars, c, c2;
+    uint32 v;
+    uint8 utf8buf[6];
+    jschar hexBuf[4];
+    static const char HexDigits[] = "0123456789ABCDEF"; /* NB: uppercase */
+    JSString *R;
+
+    length = JSSTRING_LENGTH(str);
+    if (length == 0) {
+        *rval = STRING_TO_JSVAL(cx->runtime->emptyString);
+        return JS_TRUE;
+    }
+
+    R = js_NewString(cx, NULL, 0, 0);
+    if (!R)
+        return JS_FALSE;
+
+    hexBuf[0] = '%';
+    hexBuf[3] = 0;
+    chars = JSSTRING_CHARS(str);
+    for (k = 0; k < length; k++) {
+        c = chars[k];
+        if (js_strchr(unescapedSet, c) ||
+            (unescapedSet2 && js_strchr(unescapedSet2, c))) {
+            if (!AddCharsToURI(cx, R, &c, 1))
+                return JS_FALSE;
+        } else {
+            if ((c >= 0xDC00) && (c <= 0xDFFF)) {
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_BAD_URI, NULL);
+                return JS_FALSE;
+            }
+            if (c < 0xD800 || c > 0xDBFF) {
+                v = c;
+            } else {
+                k++;
+                if (k == length) {
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_BAD_URI, NULL);
+                    return JS_FALSE;
+                }
+                c2 = chars[k];
+                if ((c2 < 0xDC00) || (c2 > 0xDFFF)) {
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_BAD_URI, NULL);
+                    return JS_FALSE;
+                }
+                v = ((c - 0xD800) << 10) + (c2 - 0xDC00) + 0x10000;
+            }
+            L = js_OneUcs4ToUtf8Char(utf8buf, v);
+            for (j = 0; j < L; j++) {
+                hexBuf[1] = HexDigits[utf8buf[j] >> 4];
+                hexBuf[2] = HexDigits[utf8buf[j] & 0xf];
+                if (!AddCharsToURI(cx, R, hexBuf, 3))
+                    return JS_FALSE;
+            }
+        }
+    }
+
+    /*
+     * Shrinking realloc can fail (e.g., with a BSD-style allocator), but we
+     * don't worry about that case here.  Worst case, R hangs onto URI_CHUNK-1
+     * more jschars than it needs.
+     */
+    chars = (jschar *) JS_realloc(cx, R->chars, (R->length+1) * sizeof(jschar));
+    if (chars)
+        R->chars = chars;
+    *rval = STRING_TO_JSVAL(R);
+    return JS_TRUE;
+}
+
+static JSBool
+Decode(JSContext *cx, JSString *str, const jschar *reservedSet, jsval *rval)
+{
+    size_t length, start, k;
+    jschar *chars, c, H;
+    uint32 v;
+    jsuint B;
+    uint8 octets[6];
+    JSString *R;
+    intN j, n;
+
+    length = JSSTRING_LENGTH(str);
+    if (length == 0) {
+        *rval = STRING_TO_JSVAL(cx->runtime->emptyString);
+        return JS_TRUE;
+    }
+
+    R = js_NewString(cx, NULL, 0, 0);
+    if (!R)
+        return JS_FALSE;
+
+    chars = JSSTRING_CHARS(str);
+    for (k = 0; k < length; k++) {
+        c = chars[k];
+        if (c == '%') {
+            start = k;
+            if ((k + 2) >= length)
+                goto bad;
+            if (!JS7_ISHEX(chars[k+1]) || !JS7_ISHEX(chars[k+2]))
+                goto bad;
+            B = JS7_UNHEX(chars[k+1]) * 16 + JS7_UNHEX(chars[k+2]);
+            k += 2;
+            if (!(B & 0x80)) {
+                c = (jschar)B;
+            } else {
+                n = 1;
+                while (B & (0x80 >> n))
+                    n++;
+                if (n == 1 || n > 6)
+                    goto bad;
+                octets[0] = (uint8)B;
+                if (k + 3 * (n - 1) >= length)
+                    goto bad;
+                for (j = 1; j < n; j++) {
+                    k++;
+                    if (chars[k] != '%')
+                        goto bad;
+                    if (!JS7_ISHEX(chars[k+1]) || !JS7_ISHEX(chars[k+2]))
+                        goto bad;
+                    B = JS7_UNHEX(chars[k+1]) * 16 + JS7_UNHEX(chars[k+2]);
+                    if ((B & 0xC0) != 0x80)
+                        goto bad;
+                    k += 2;
+                    octets[j] = (char)B;
+                }
+                v = Utf8ToOneUcs4Char(octets, n);
+                if (v >= 0x10000) {
+                    v -= 0x10000;
+                    if (v > 0xFFFFF)
+                        goto bad;
+                    c = (jschar)((v & 0x3FF) + 0xDC00);
+                    H = (jschar)((v >> 10) + 0xD800);
+                    if (!AddCharsToURI(cx, R, &H, 1))
+                        return JS_FALSE;
+                } else {
+                    c = (jschar)v;
+                }
+            }
+            if (js_strchr(reservedSet, c)) {
+                if (!AddCharsToURI(cx, R, &chars[start], (k - start + 1)))
+                    return JS_FALSE;
+            } else {
+                if (!AddCharsToURI(cx, R, &c, 1))
+                    return JS_FALSE;
+            }
+        } else {
+            if (!AddCharsToURI(cx, R, &c, 1))
+                return JS_FALSE;
+        }
+    }
+
+    /*
+     * Shrinking realloc can fail (e.g., with a BSD-style allocator), but we
+     * don't worry about that case here.  Worst case, R hangs onto URI_CHUNK-1
+     * more jschars than it needs.
+     */
+    chars = (jschar *) JS_realloc(cx, R->chars, (R->length+1) * sizeof(jschar));
+    if (chars)
+        R->chars = chars;
+    *rval = STRING_TO_JSVAL(R);
+    return JS_TRUE;
+
+bad:
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_URI);
+    return JS_FALSE;
+}
+
+static JSBool
+str_decodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    JSString *str;
+
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(str);
+    return Decode(cx, str, js_uriReservedPlusPound_ucstr, rval);
+}
+
+static JSBool
+str_decodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                        jsval *rval)
+{
+    JSString *str;
+
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(str);
+    return Decode(cx, str, js_empty_ucstr, rval);
+}
+
+static JSBool
+str_encodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    JSString *str;
+
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(str);
+    return Encode(cx, str, js_uriReservedPlusPound_ucstr, js_uriUnescaped_ucstr,
+                  rval);
+}
+
+static JSBool
+str_encodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                        jsval *rval)
+{
+    JSString *str;
+
+    str = js_ValueToString(cx, argv[0]);
+    if (!str)
+        return JS_FALSE;
+    argv[0] = STRING_TO_JSVAL(str);
+    return Encode(cx, str, js_uriUnescaped_ucstr, NULL, rval);
+}
+
+/*
+ * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at
+ * least 6 bytes long.  Return the number of UTF-8 bytes of data written.
+ */
+int
+js_OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char)
+{
+    int utf8Length = 1;
+
+    JS_ASSERT(ucs4Char <= 0x7FFFFFFF);
+    if (ucs4Char < 0x80) {
+        *utf8Buffer = (uint8)ucs4Char;
+    } else {
+        int i;
+        uint32 a = ucs4Char >> 11;
+        utf8Length = 2;
+        while (a) {
+            a >>= 5;
+            utf8Length++;
+        }
+        i = utf8Length;
+        while (--i) {
+            utf8Buffer[i] = (uint8)((ucs4Char & 0x3F) | 0x80);
+            ucs4Char >>= 6;
+        }
+        *utf8Buffer = (uint8)(0x100 - (1 << (8-utf8Length)) + ucs4Char);
+    }
+    return utf8Length;
+}
+
+/*
+ * Convert a utf8 character sequence into a UCS-4 character and return that
+ * character.  It is assumed that the caller already checked that the sequence
+ * is valid.
+ */
+static uint32
+Utf8ToOneUcs4Char(const uint8 *utf8Buffer, int utf8Length)
+{
+    uint32 ucs4Char;
+    uint32 minucs4Char;
+    /* from Unicode 3.1, non-shortest form is illegal */
+    static const uint32 minucs4Table[] = {
+        0x00000080, 0x00000800, 0x0001000, 0x0020000, 0x0400000
+    };
+
+    JS_ASSERT(utf8Length >= 1 && utf8Length <= 6);
+    if (utf8Length == 1) {
+        ucs4Char = *utf8Buffer;
+        JS_ASSERT(!(ucs4Char & 0x80));
+    } else {
+        JS_ASSERT((*utf8Buffer & (0x100 - (1 << (7-utf8Length)))) ==
+                  (0x100 - (1 << (8-utf8Length))));
+        ucs4Char = *utf8Buffer++ & ((1<<(7-utf8Length))-1);
+        minucs4Char = minucs4Table[utf8Length-2];
+        while (--utf8Length) {
+            JS_ASSERT((*utf8Buffer & 0xC0) == 0x80);
+            ucs4Char = ucs4Char<<6 | (*utf8Buffer++ & 0x3F);
+        }
+        if (ucs4Char < minucs4Char ||
+            ucs4Char == 0xFFFE || ucs4Char == 0xFFFF) {
+            ucs4Char = 0xFFFD;
+        }
+    }
+    return ucs4Char;
+}

Added: freeswitch/trunk/libs/js/src/jsstr.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsstr.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,482 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsstr_h___
+#define jsstr_h___
+/*
+ * JS string type implementation.
+ *
+ * A JS string is a counted array of unicode characters.  To support handoff
+ * of API client memory, the chars are allocated separately from the length,
+ * necessitating a pointer after the count, to form a separately allocated
+ * string descriptor.  String descriptors are GC'ed, while their chars are
+ * allocated from the malloc heap.
+ *
+ * When a string is treated as an object (by following it with . or []), the
+ * runtime wraps it with a JSObject whose valueOf method returns the unwrapped
+ * string descriptor.
+ */
+#include <ctype.h>
+#include "jspubtd.h"
+#include "jsprvtd.h"
+#include "jshash.h"
+
+JS_BEGIN_EXTERN_C
+
+/*
+ * The original GC-thing "string" type, a flat character string owned by its
+ * GC-thing descriptor.  The chars member points to a vector having byte size
+ * (length + 1) * sizeof(jschar), terminated at index length by a zero jschar.
+ * The terminator is purely a backstop, in case the chars pointer flows out to
+ * native code that requires \u0000 termination.
+ *
+ * NB: Always use the JSSTRING_LENGTH and JSSTRING_CHARS accessor macros,
+ * unless you guard str->member uses with !JSSTRING_IS_DEPENDENT(str).
+ */
+struct JSString {
+    size_t          length;
+    jschar          *chars;
+};
+
+/*
+ * Overlay structure for a string that depends on another string's characters.
+ * Distinguished by the JSSTRFLAG_DEPENDENT bit being set in length.  The base
+ * member may point to another dependent string if JSSTRING_CHARS has not been
+ * called yet.  The length chars in a dependent string are stored starting at
+ * base->chars + start, and are not necessarily zero-terminated.  If start is
+ * 0, it is not stored, length is a full size_t (minus the JSSTRFLAG_* bits in
+ * the high two positions), and the JSSTRFLAG_PREFIX flag is set.
+ */
+struct JSDependentString {
+    size_t          length;
+    JSString        *base;
+};
+
+/* Definitions for flags stored in the high order bits of JSString.length. */
+#define JSSTRFLAG_BITS              2
+#define JSSTRFLAG_SHIFT(flg)        ((size_t)(flg) << JSSTRING_LENGTH_BITS)
+#define JSSTRFLAG_MASK              JSSTRFLAG_SHIFT(JS_BITMASK(JSSTRFLAG_BITS))
+#define JSSTRFLAG_DEPENDENT         JSSTRFLAG_SHIFT(1)
+#define JSSTRFLAG_PREFIX            JSSTRFLAG_SHIFT(2)
+
+/* Universal JSString type inquiry and accessor macros. */
+#define JSSTRING_BIT(n)             ((size_t)1 << (n))
+#define JSSTRING_BITMASK(n)         (JSSTRING_BIT(n) - 1)
+#define JSSTRING_HAS_FLAG(str,flg)  ((str)->length & (flg))
+#define JSSTRING_IS_DEPENDENT(str)  JSSTRING_HAS_FLAG(str, JSSTRFLAG_DEPENDENT)
+#define JSSTRING_IS_PREFIX(str)     JSSTRING_HAS_FLAG(str, JSSTRFLAG_PREFIX)
+#define JSSTRING_CHARS(str)         (JSSTRING_IS_DEPENDENT(str)               \
+                                     ? JSSTRDEP_CHARS(str)                    \
+                                     : (str)->chars)
+#define JSSTRING_LENGTH(str)        (JSSTRING_IS_DEPENDENT(str)               \
+                                     ? JSSTRDEP_LENGTH(str)                   \
+                                     : (str)->length)
+#define JSSTRING_LENGTH_BITS        (sizeof(size_t) * JS_BITS_PER_BYTE        \
+                                     - JSSTRFLAG_BITS)
+#define JSSTRING_LENGTH_MASK        JSSTRING_BITMASK(JSSTRING_LENGTH_BITS)
+
+/* Specific JSDependentString shift/mask accessor and mutator macros. */
+#define JSSTRDEP_START_BITS         (JSSTRING_LENGTH_BITS-JSSTRDEP_LENGTH_BITS)
+#define JSSTRDEP_START_SHIFT        JSSTRDEP_LENGTH_BITS
+#define JSSTRDEP_START_MASK         JSSTRING_BITMASK(JSSTRDEP_START_BITS)
+#define JSSTRDEP_LENGTH_BITS        (JSSTRING_LENGTH_BITS / 2)
+#define JSSTRDEP_LENGTH_MASK        JSSTRING_BITMASK(JSSTRDEP_LENGTH_BITS)
+
+#define JSSTRDEP(str)               ((JSDependentString *)(str))
+#define JSSTRDEP_START(str)         (JSSTRING_IS_PREFIX(str) ? 0              \
+                                     : ((JSSTRDEP(str)->length                \
+                                         >> JSSTRDEP_START_SHIFT)             \
+                                        & JSSTRDEP_START_MASK))
+#define JSSTRDEP_LENGTH(str)        (JSSTRDEP(str)->length                    \
+                                     & (JSSTRING_IS_PREFIX(str)               \
+                                        ? JSSTRING_LENGTH_MASK                \
+                                        : JSSTRDEP_LENGTH_MASK))
+
+#define JSSTRDEP_SET_START_AND_LENGTH(str,off,len)                            \
+    (JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT                              \
+                           | ((off) << JSSTRDEP_START_SHIFT)                  \
+                           | (len))
+#define JSPREFIX_SET_LENGTH(str,len)                                          \
+    (JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT | JSSTRFLAG_PREFIX | (len))
+
+#define JSSTRDEP_BASE(str)          (JSSTRDEP(str)->base)
+#define JSSTRDEP_SET_BASE(str,bstr) (JSSTRDEP(str)->base = (bstr))
+#define JSPREFIX_BASE(str)          JSSTRDEP_BASE(str)
+#define JSPREFIX_SET_BASE(str,bstr) JSSTRDEP_SET_BASE(str,bstr)
+
+#define JSSTRDEP_CHARS(str)                                                   \
+    (JSSTRING_IS_DEPENDENT(JSSTRDEP_BASE(str))                                \
+     ? js_GetDependentStringChars(str)                                        \
+     : JSSTRDEP_BASE(str)->chars + JSSTRDEP_START(str))
+
+extern size_t
+js_MinimizeDependentStrings(JSString *str, int level, JSString **basep);
+
+extern jschar *
+js_GetDependentStringChars(JSString *str);
+
+extern jschar *
+js_GetStringChars(JSString *str);
+
+extern JSString *
+js_ConcatStrings(JSContext *cx, JSString *left, JSString *right);
+
+extern const jschar *
+js_UndependString(JSContext *cx, JSString *str);
+
+struct JSSubString {
+    size_t          length;
+    const jschar    *chars;
+};
+
+extern jschar      js_empty_ucstr[];
+extern JSSubString js_EmptySubString;
+
+/* Unicode character attribute lookup tables. */
+extern const uint8 js_X[];
+extern const uint8 js_Y[];
+extern const uint32 js_A[];
+
+/* Enumerated Unicode general category types. */
+typedef enum JSCharType {
+    JSCT_UNASSIGNED             = 0,
+    JSCT_UPPERCASE_LETTER       = 1,
+    JSCT_LOWERCASE_LETTER       = 2,
+    JSCT_TITLECASE_LETTER       = 3,
+    JSCT_MODIFIER_LETTER        = 4,
+    JSCT_OTHER_LETTER           = 5,
+    JSCT_NON_SPACING_MARK       = 6,
+    JSCT_ENCLOSING_MARK         = 7,
+    JSCT_COMBINING_SPACING_MARK = 8,
+    JSCT_DECIMAL_DIGIT_NUMBER   = 9,
+    JSCT_LETTER_NUMBER          = 10,
+    JSCT_OTHER_NUMBER           = 11,
+    JSCT_SPACE_SEPARATOR        = 12,
+    JSCT_LINE_SEPARATOR         = 13,
+    JSCT_PARAGRAPH_SEPARATOR    = 14,
+    JSCT_CONTROL                = 15,
+    JSCT_FORMAT                 = 16,
+    JSCT_PRIVATE_USE            = 18,
+    JSCT_SURROGATE              = 19,
+    JSCT_DASH_PUNCTUATION       = 20,
+    JSCT_START_PUNCTUATION      = 21,
+    JSCT_END_PUNCTUATION        = 22,
+    JSCT_CONNECTOR_PUNCTUATION  = 23,
+    JSCT_OTHER_PUNCTUATION      = 24,
+    JSCT_MATH_SYMBOL            = 25,
+    JSCT_CURRENCY_SYMBOL        = 26,
+    JSCT_MODIFIER_SYMBOL        = 27,
+    JSCT_OTHER_SYMBOL           = 28
+} JSCharType;
+
+/* Character classifying and mapping macros, based on java.lang.Character. */
+#define JS_CCODE(c)     (js_A[js_Y[(js_X[(uint16)(c)>>6]<<6)|((c)&0x3F)]])
+#define JS_CTYPE(c)     (JS_CCODE(c) & 0x1F)
+
+#define JS_ISALPHA(c)   ((((1 << JSCT_UPPERCASE_LETTER) |                     \
+                           (1 << JSCT_LOWERCASE_LETTER) |                     \
+                           (1 << JSCT_TITLECASE_LETTER) |                     \
+                           (1 << JSCT_MODIFIER_LETTER) |                      \
+                           (1 << JSCT_OTHER_LETTER))                          \
+                          >> JS_CTYPE(c)) & 1)
+
+#define JS_ISALNUM(c)   ((((1 << JSCT_UPPERCASE_LETTER) |                     \
+                           (1 << JSCT_LOWERCASE_LETTER) |                     \
+                           (1 << JSCT_TITLECASE_LETTER) |                     \
+                           (1 << JSCT_MODIFIER_LETTER) |                      \
+                           (1 << JSCT_OTHER_LETTER) |                         \
+                           (1 << JSCT_DECIMAL_DIGIT_NUMBER))                  \
+                          >> JS_CTYPE(c)) & 1)
+
+/* A unicode letter, suitable for use in an identifier. */
+#define JS_ISLETTER(c)   ((((1 << JSCT_UPPERCASE_LETTER) |                    \
+                            (1 << JSCT_LOWERCASE_LETTER) |                    \
+                            (1 << JSCT_TITLECASE_LETTER) |                    \
+                            (1 << JSCT_MODIFIER_LETTER) |                     \
+                            (1 << JSCT_OTHER_LETTER) |                        \
+                            (1 << JSCT_LETTER_NUMBER))                        \
+                           >> JS_CTYPE(c)) & 1)
+
+/*
+ * 'IdentifierPart' from ECMA grammar, is Unicode letter or combining mark or
+ * digit or connector punctuation.
+ */
+#define JS_ISIDPART(c)  ((((1 << JSCT_UPPERCASE_LETTER) |                     \
+                           (1 << JSCT_LOWERCASE_LETTER) |                     \
+                           (1 << JSCT_TITLECASE_LETTER) |                     \
+                           (1 << JSCT_MODIFIER_LETTER) |                      \
+                           (1 << JSCT_OTHER_LETTER) |                         \
+                           (1 << JSCT_LETTER_NUMBER) |                        \
+                           (1 << JSCT_NON_SPACING_MARK) |                     \
+                           (1 << JSCT_COMBINING_SPACING_MARK) |               \
+                           (1 << JSCT_DECIMAL_DIGIT_NUMBER) |                 \
+                           (1 << JSCT_CONNECTOR_PUNCTUATION))                 \
+                          >> JS_CTYPE(c)) & 1)
+
+/* Unicode control-format characters, ignored in input */
+#define JS_ISFORMAT(c) (((1 << JSCT_FORMAT) >> JS_CTYPE(c)) & 1)
+
+/*
+ * Per ECMA-262 15.10.2.6, these characters are the only ones that make up a
+ * "word", as far as a RegExp is concerned.  If we want a Unicode-friendlier
+ * definition of "word", we should rename this macro to something regexp-y.
+ */
+#define JS_ISWORD(c)    ((c) < 128 && (isalnum(c) || (c) == '_'))
+
+#define JS_ISIDSTART(c) (JS_ISLETTER(c) || (c) == '_' || (c) == '$')
+#define JS_ISIDENT(c)   (JS_ISIDPART(c) || (c) == '_' || (c) == '$')
+
+#define JS_ISXMLSPACE(c)        ((c) == ' ' || (c) == '\t' || (c) == '\r' ||  \
+                                 (c) == '\n')
+#define JS_ISXMLNSSTART(c)      ((JS_CCODE(c) & 0x00000100) || (c) == '_')
+#define JS_ISXMLNS(c)           ((JS_CCODE(c) & 0x00000080) || (c) == '.' ||  \
+                                 (c) == '-' || (c) == '_')
+#define JS_ISXMLNAMESTART(c)    (JS_ISXMLNSSTART(c) || (c) == ':')
+#define JS_ISXMLNAME(c)         (JS_ISXMLNS(c) || (c) == ':')
+
+#define JS_ISDIGIT(c)   (JS_CTYPE(c) == JSCT_DECIMAL_DIGIT_NUMBER)
+
+/* XXXbe unify on A/X/Y tbls, avoid ctype.h? */
+/* XXXbe fs, etc. ? */
+#define JS_ISSPACE(c)   ((JS_CCODE(c) & 0x00070000) == 0x00040000)
+#define JS_ISPRINT(c)   ((c) < 128 && isprint(c))
+
+#define JS_ISUPPER(c)   (JS_CTYPE(c) == JSCT_UPPERCASE_LETTER)
+#define JS_ISLOWER(c)   (JS_CTYPE(c) == JSCT_LOWERCASE_LETTER)
+
+#define JS_TOUPPER(c)   ((jschar) ((JS_CCODE(c) & 0x00100000)                 \
+                                   ? (c) - ((int32)JS_CCODE(c) >> 22)         \
+                                   : (c)))
+#define JS_TOLOWER(c)   ((jschar) ((JS_CCODE(c) & 0x00200000)                 \
+                                   ? (c) + ((int32)JS_CCODE(c) >> 22)         \
+                                   : (c)))
+
+/* Shorthands for ASCII (7-bit) decimal and hex conversion. */
+#define JS7_ISDEC(c)    ((c) < 128 && isdigit(c))
+#define JS7_UNDEC(c)    ((c) - '0')
+#define JS7_ISHEX(c)    ((c) < 128 && isxdigit(c))
+#define JS7_UNHEX(c)    (uintN)(isdigit(c) ? (c) - '0' : 10 + tolower(c) - 'a')
+#define JS7_ISLET(c)    ((c) < 128 && isalpha(c))
+
+/* Initialize truly global state associated with JS strings. */
+extern JSBool
+js_InitStringGlobals(void);
+
+extern void
+js_FreeStringGlobals(void);
+
+extern void
+js_PurgeDeflatedStringCache(JSString *str);
+
+/* Initialize per-runtime string state for the first context in the runtime. */
+extern JSBool
+js_InitRuntimeStringState(JSContext *cx);
+
+extern void
+js_FinishRuntimeStringState(JSContext *cx);
+
+/* Initialize the String class, returning its prototype object. */
+extern JSClass js_StringClass;
+
+extern JSObject *
+js_InitStringClass(JSContext *cx, JSObject *obj);
+
+extern const char js_escape_str[];
+extern const char js_unescape_str[];
+extern const char js_uneval_str[];
+extern const char js_decodeURI_str[];
+extern const char js_encodeURI_str[];
+extern const char js_decodeURIComponent_str[];
+extern const char js_encodeURIComponent_str[];
+
+/* GC-allocate a string descriptor for the given malloc-allocated chars. */
+extern JSString *
+js_NewString(JSContext *cx, jschar *chars, size_t length, uintN gcflag);
+
+extern JSString *
+js_NewDependentString(JSContext *cx, JSString *base, size_t start,
+                      size_t length, uintN gcflag);
+
+/* Copy a counted string and GC-allocate a descriptor for it. */
+extern JSString *
+js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n, uintN gcflag);
+
+/* Copy a C string and GC-allocate a descriptor for it. */
+extern JSString *
+js_NewStringCopyZ(JSContext *cx, const jschar *s, uintN gcflag);
+
+/* Free the chars held by str when it is finalized by the GC. */
+extern void
+js_FinalizeString(JSContext *cx, JSString *str);
+
+extern void
+js_FinalizeStringRT(JSRuntime *rt, JSString *str);
+
+/* Wrap a string value in a String object. */
+extern JSObject *
+js_StringToObject(JSContext *cx, JSString *str);
+
+/*
+ * Convert a value to a printable C string.
+ */
+extern JS_FRIEND_API(const char *)
+js_ValueToPrintableString(JSContext *cx, jsval v);
+
+/*
+ * Convert a value to a string, returning null after reporting an error,
+ * otherwise returning a new string reference.
+ */
+extern JSString *
+js_ValueToString(JSContext *cx, jsval v);
+
+/*
+ * Convert a value to its source expression, returning null after reporting
+ * an error, otherwise returning a new string reference.
+ */
+extern JSString *
+js_ValueToSource(JSContext *cx, jsval v);
+
+#ifdef HT_ENUMERATE_NEXT        /* XXX don't require jshash.h */
+/*
+ * Compute a hash function from str.
+ */
+extern JSHashNumber
+js_HashString(JSString *str);
+#endif
+
+/*
+ * Return less than, equal to, or greater than zero depending on whether
+ * str1 is less than, equal to, or greater than str2.
+ */
+extern intN
+js_CompareStrings(JSString *str1, JSString *str2);
+
+/*
+ * Boyer-Moore-Horspool superlinear search for pat:patlen in text:textlen.
+ * The patlen argument must be positive and no greater than BMH_PATLEN_MAX.
+ * The start argument tells where in text to begin the search.
+ *
+ * Return the index of pat in text, or -1 if not found.
+ */
+#define BMH_CHARSET_SIZE 256    /* ISO-Latin-1 */
+#define BMH_PATLEN_MAX   255    /* skip table element is uint8 */
+
+#define BMH_BAD_PATTERN  (-2)   /* return value if pat is not ISO-Latin-1 */
+
+extern jsint
+js_BoyerMooreHorspool(const jschar *text, jsint textlen,
+                      const jschar *pat, jsint patlen,
+                      jsint start);
+
+extern size_t
+js_strlen(const jschar *s);
+
+extern jschar *
+js_strchr(const jschar *s, jschar c);
+
+extern jschar *
+js_strchr_limit(const jschar *s, jschar c, const jschar *limit);
+
+#define js_strncpy(t, s, n)     memcpy((t), (s), (n) * sizeof(jschar))
+
+/*
+ * Return s advanced past any Unicode white space characters.
+ */
+extern const jschar *
+js_SkipWhiteSpace(const jschar *s);
+
+/*
+ * Inflate bytes to JS chars and vice versa.  Report out of memory via cx
+ * and return null on error, otherwise return the jschar or byte vector that
+ * was JS_malloc'ed. length is updated with the length of the new string in jschars.
+ */
+extern jschar *
+js_InflateString(JSContext *cx, const char *bytes, size_t *length);
+
+extern char *
+js_DeflateString(JSContext *cx, const jschar *chars, size_t length);
+
+/*
+ * Inflate bytes to JS chars into a buffer.
+ * 'chars' must be large enough for 'length' jschars.
+ * The buffer is NOT null-terminated.
+ * cx may be NULL, which means no errors are thrown.
+ * The destination length needs to be initialized with the buffer size, takes the number of chars moved.
+ */
+extern JSBool
+js_InflateStringToBuffer(JSContext* cx, const char *bytes, size_t length, jschar *chars, size_t* charsLength);
+
+/*
+ * Deflate JS chars to bytes into a buffer.
+ * 'bytes' must be large enough for 'length chars.
+ * The buffer is NOT null-terminated.
+ * cx may be NULL, which means no errors are thrown.
+ * The destination length needs to be initialized with the buffer size, takes the number of bytes moved.
+ */
+extern JSBool
+js_DeflateStringToBuffer(JSContext* cx, const jschar *chars, size_t charsLength, char *bytes, size_t* length);
+
+/*
+ * Associate bytes with str in the deflated string cache, returning true on
+ * successful association, false on out of memory.
+ */
+extern JSBool
+js_SetStringBytes(JSString *str, char *bytes, size_t length);
+
+/*
+ * Find or create a deflated string cache entry for str that contains its
+ * characters chopped from Unicode code points into bytes.
+ */
+extern char *
+js_GetStringBytes(JSString *str);
+
+JSBool
+js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval);
+
+/*
+ * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at
+ * least 6 bytes long.  Return the number of UTF-8 bytes of data written.
+ */
+extern int
+js_OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char);
+
+JS_END_EXTERN_C
+
+#endif /* jsstr_h___ */

Added: freeswitch/trunk/libs/js/src/jstypes.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jstypes.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,421 @@
+/* -*- 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 Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   IBM Corp.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+** File:                jstypes.h
+** Description: Definitions of NSPR's basic types
+**
+** Prototypes and macros used to make up for deficiencies in ANSI environments
+** that we have found.
+**
+** Since we do not wrap <stdlib.h> and all the other standard headers, authors
+** of portable code will not know in general that they need these definitions.
+** Instead of requiring these authors to find the dependent uses in their code
+** and take the following steps only in those C files, we take steps once here
+** for all C files.
+**/
+
+#ifndef jstypes_h___
+#define jstypes_h___
+
+#include <stddef.h>
+
+/***********************************************************************
+** MACROS:      JS_EXTERN_API
+**              JS_EXPORT_API
+** DESCRIPTION:
+**      These are only for externally visible routines and globals.  For
+**      internal routines, just use "extern" for type checking and that
+**      will not export internal cross-file or forward-declared symbols.
+**      Define a macro for declaring procedures return types. We use this to
+**      deal with windoze specific type hackery for DLL definitions. Use
+**      JS_EXTERN_API when the prototype for the method is declared. Use
+**      JS_EXPORT_API for the implementation of the method.
+**
+** Example:
+**   in dowhim.h
+**     JS_EXTERN_API( void ) DoWhatIMean( void );
+**   in dowhim.c
+**     JS_EXPORT_API( void ) DoWhatIMean( void ) { return; }
+**
+**
+***********************************************************************/
+#ifdef WIN32
+/* These also work for __MWERKS__ */
+#define JS_EXTERN_API(__type) extern __declspec(dllexport) __type
+#define JS_EXPORT_API(__type) __declspec(dllexport) __type
+#define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define JS_EXPORT_DATA(__type) __declspec(dllexport) __type
+
+#define JS_DLL_CALLBACK
+#define JS_STATIC_DLL_CALLBACK(__x) static __x
+
+#elif defined(WIN16)
+
+#ifdef _WINDLL
+#define JS_EXTERN_API(__type) extern __type _cdecl _export _loadds
+#define JS_EXPORT_API(__type) __type _cdecl _export _loadds
+#define JS_EXTERN_DATA(__type) extern __type _export
+#define JS_EXPORT_DATA(__type) __type _export
+
+#define JS_DLL_CALLBACK             __cdecl __loadds
+#define JS_STATIC_DLL_CALLBACK(__x) static __x CALLBACK
+
+#else /* this must be .EXE */
+#define JS_EXTERN_API(__type) extern __type _cdecl _export
+#define JS_EXPORT_API(__type) __type _cdecl _export
+#define JS_EXTERN_DATA(__type) extern __type _export
+#define JS_EXPORT_DATA(__type) __type _export
+
+#define JS_DLL_CALLBACK             __cdecl __loadds
+#define JS_STATIC_DLL_CALLBACK(__x) __x JS_DLL_CALLBACK
+#endif /* _WINDLL */
+
+#else /* Unix */
+
+#ifdef HAVE_VISIBILITY_PRAGMA
+#define JS_EXTERNAL_VIS __attribute__((visibility ("default")))
+#else
+#define JS_EXTERNAL_VIS
+#endif
+
+#define JS_EXTERN_API(__type) extern JS_EXTERNAL_VIS __type
+#define JS_EXPORT_API(__type) JS_EXTERNAL_VIS __type
+#define JS_EXTERN_DATA(__type) extern JS_EXTERNAL_VIS __type
+#define JS_EXPORT_DATA(__type) JS_EXTERNAL_VIS __type
+
+#define JS_DLL_CALLBACK
+#define JS_STATIC_DLL_CALLBACK(__x) static __x
+
+#endif
+
+#ifdef _WIN32
+#  if defined(__MWERKS__) || defined(__GNUC__)
+#    define JS_IMPORT_API(__x)      __x
+#  else
+#    define JS_IMPORT_API(__x)      __declspec(dllimport) __x
+#  endif
+#else
+#    define JS_IMPORT_API(__x)      JS_EXPORT_API (__x)
+#endif
+
+#if defined(_WIN32) && !defined(__MWERKS__)
+#    define JS_IMPORT_DATA(__x)      __declspec(dllimport) __x
+#else
+#    define JS_IMPORT_DATA(__x)     JS_EXPORT_DATA (__x)
+#endif
+
+/*
+ * The linkage of JS API functions differs depending on whether the file is
+ * used within the JS library or not.  Any source file within the JS
+ * interpreter should define EXPORT_JS_API whereas any client of the library
+ * should not.
+ */
+#ifdef EXPORT_JS_API
+#define JS_PUBLIC_API(t)    JS_EXPORT_API(t)
+#define JS_PUBLIC_DATA(t)   JS_EXPORT_DATA(t)
+#else
+#define JS_PUBLIC_API(t)    JS_IMPORT_API(t)
+#define JS_PUBLIC_DATA(t)   JS_IMPORT_DATA(t)
+#endif
+
+#define JS_FRIEND_API(t)    JS_PUBLIC_API(t)
+#define JS_FRIEND_DATA(t)   JS_PUBLIC_DATA(t)
+
+#ifdef _WIN32
+#   define JS_INLINE __inline
+#elif defined(__GNUC__)
+#   define JS_INLINE
+#else
+#   define JS_INLINE
+#endif
+
+/***********************************************************************
+** MACROS:      JS_BEGIN_MACRO
+**              JS_END_MACRO
+** DESCRIPTION:
+**      Macro body brackets so that macros with compound statement definitions
+**      behave syntactically more like functions when called.
+***********************************************************************/
+#define JS_BEGIN_MACRO  do {
+#define JS_END_MACRO    } while (0)
+
+/***********************************************************************
+** MACROS:      JS_BEGIN_EXTERN_C
+**              JS_END_EXTERN_C
+** DESCRIPTION:
+**      Macro shorthands for conditional C++ extern block delimiters.
+***********************************************************************/
+#ifdef __cplusplus
+#define JS_BEGIN_EXTERN_C       extern "C" {
+#define JS_END_EXTERN_C         }
+#else
+#define JS_BEGIN_EXTERN_C
+#define JS_END_EXTERN_C
+#endif
+
+/***********************************************************************
+** MACROS:      JS_BIT
+**              JS_BITMASK
+** DESCRIPTION:
+** Bit masking macros.  XXX n must be <= 31 to be portable
+***********************************************************************/
+#define JS_BIT(n)       ((JSUint32)1 << (n))
+#define JS_BITMASK(n)   (JS_BIT(n) - 1)
+
+/***********************************************************************
+** MACROS:      JS_PTR_TO_INT32
+**              JS_PTR_TO_UINT32
+**              JS_INT32_TO_PTR
+**              JS_UINT32_TO_PTR
+** DESCRIPTION:
+** Integer to pointer and pointer to integer conversion macros.
+***********************************************************************/
+#define JS_PTR_TO_INT32(x)  ((jsint)((char *)(x) - (char *)0))
+#define JS_PTR_TO_UINT32(x) ((jsuint)((char *)(x) - (char *)0))
+#define JS_INT32_TO_PTR(x)  ((void *)((char *)0 + (jsint)(x)))
+#define JS_UINT32_TO_PTR(x) ((void *)((char *)0 + (jsuint)(x)))
+
+/***********************************************************************
+** MACROS:      JS_HOWMANY
+**              JS_ROUNDUP
+**              JS_MIN
+**              JS_MAX
+** DESCRIPTION:
+**      Commonly used macros for operations on compatible types.
+***********************************************************************/
+#define JS_HOWMANY(x,y) (((x)+(y)-1)/(y))
+#define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y))
+#define JS_MIN(x,y)     ((x)<(y)?(x):(y))
+#define JS_MAX(x,y)     ((x)>(y)?(x):(y))
+
+#if (defined(XP_WIN) && !defined(CROSS_COMPILE)) || defined (WINCE)
+#    include "jscpucfg.h"        /* Use standard Mac or Windows configuration */
+#elif defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_OS2) || defined(CROSS_COMPILE)
+#    include "jsautocfg.h"       /* Use auto-detected configuration */
+#    include "jsosdep.h"         /* ...and platform-specific flags */
+#else
+#    error "Must define one of XP_BEOS, XP_OS2, XP_WIN or XP_UNIX"
+#endif
+
+JS_BEGIN_EXTERN_C
+
+/************************************************************************
+** TYPES:       JSUint8
+**              JSInt8
+** DESCRIPTION:
+**  The int8 types are known to be 8 bits each. There is no type that
+**      is equivalent to a plain "char".
+************************************************************************/
+#if JS_BYTES_PER_BYTE == 1
+typedef unsigned char JSUint8;
+typedef signed char JSInt8;
+#else
+#error No suitable type for JSInt8/JSUint8
+#endif
+
+/************************************************************************
+** TYPES:       JSUint16
+**              JSInt16
+** DESCRIPTION:
+**  The int16 types are known to be 16 bits each.
+************************************************************************/
+#if JS_BYTES_PER_SHORT == 2
+typedef unsigned short JSUint16;
+typedef short JSInt16;
+#else
+#error No suitable type for JSInt16/JSUint16
+#endif
+
+/************************************************************************
+** TYPES:       JSUint32
+**              JSInt32
+** DESCRIPTION:
+**  The int32 types are known to be 32 bits each.
+************************************************************************/
+#if JS_BYTES_PER_INT == 4
+typedef unsigned int JSUint32;
+typedef int JSInt32;
+#define JS_INT32(x)  x
+#define JS_UINT32(x) x ## U
+#elif JS_BYTES_PER_LONG == 4
+typedef unsigned long JSUint32;
+typedef long JSInt32;
+#define JS_INT32(x)  x ## L
+#define JS_UINT32(x) x ## UL
+#else
+#error No suitable type for JSInt32/JSUint32
+#endif
+
+/************************************************************************
+** TYPES:       JSUint64
+**              JSInt64
+** DESCRIPTION:
+**  The int64 types are known to be 64 bits each. Care must be used when
+**      declaring variables of type JSUint64 or JSInt64. Different hardware
+**      architectures and even different compilers have varying support for
+**      64 bit values. The only guaranteed portability requires the use of
+**      the JSLL_ macros (see jslong.h).
+************************************************************************/
+#ifdef JS_HAVE_LONG_LONG
+#if JS_BYTES_PER_LONG == 8
+typedef long JSInt64;
+typedef unsigned long JSUint64;
+#elif defined(WIN16)
+typedef __int64 JSInt64;
+typedef unsigned __int64 JSUint64;
+#elif defined(WIN32) && !defined(__GNUC__)
+typedef __int64  JSInt64;
+typedef unsigned __int64 JSUint64;
+#else
+typedef long long JSInt64;
+typedef unsigned long long JSUint64;
+#endif /* JS_BYTES_PER_LONG == 8 */
+#else  /* !JS_HAVE_LONG_LONG */
+typedef struct {
+#ifdef IS_LITTLE_ENDIAN
+    JSUint32 lo, hi;
+#else
+    JSUint32 hi, lo;
+#endif
+} JSInt64;
+typedef JSInt64 JSUint64;
+#endif /* !JS_HAVE_LONG_LONG */
+
+/************************************************************************
+** TYPES:       JSUintn
+**              JSIntn
+** DESCRIPTION:
+**  The JSIntn types are most appropriate for automatic variables. They are
+**      guaranteed to be at least 16 bits, though various architectures may
+**      define them to be wider (e.g., 32 or even 64 bits). These types are
+**      never valid for fields of a structure.
+************************************************************************/
+#if JS_BYTES_PER_INT >= 2
+typedef int JSIntn;
+typedef unsigned int JSUintn;
+#else
+#error 'sizeof(int)' not sufficient for platform use
+#endif
+
+/************************************************************************
+** TYPES:       JSFloat64
+** DESCRIPTION:
+**  NSPR's floating point type is always 64 bits.
+************************************************************************/
+typedef double          JSFloat64;
+
+/************************************************************************
+** TYPES:       JSSize
+** DESCRIPTION:
+**  A type for representing the size of objects.
+************************************************************************/
+typedef size_t JSSize;
+
+/************************************************************************
+** TYPES:       JSPtrDiff
+** DESCRIPTION:
+**  A type for pointer difference. Variables of this type are suitable
+**      for storing a pointer or pointer sutraction.
+************************************************************************/
+typedef ptrdiff_t JSPtrdiff;
+
+/************************************************************************
+** TYPES:       JSUptrdiff
+** DESCRIPTION:
+**  A type for pointer difference. Variables of this type are suitable
+**      for storing a pointer or pointer sutraction.
+************************************************************************/
+typedef unsigned long JSUptrdiff;
+
+/************************************************************************
+** TYPES:       JSBool
+** DESCRIPTION:
+**  Use JSBool for variables and parameter types. Use JS_FALSE and JS_TRUE
+**      for clarity of target type in assignments and actual arguments. Use
+**      'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans
+**      just as you would C int-valued conditions.
+************************************************************************/
+typedef JSIntn JSBool;
+#define JS_TRUE (JSIntn)1
+#define JS_FALSE (JSIntn)0
+
+/************************************************************************
+** TYPES:       JSPackedBool
+** DESCRIPTION:
+**  Use JSPackedBool within structs where bitfields are not desireable
+**      but minimum and consistant overhead matters.
+************************************************************************/
+typedef JSUint8 JSPackedBool;
+
+/*
+** A JSWord is an integer that is the same size as a void*
+*/
+typedef long JSWord;
+typedef unsigned long JSUword;
+
+#include "jsotypes.h"
+
+/***********************************************************************
+** MACROS:      JS_LIKELY
+**              JS_UNLIKELY
+** DESCRIPTION:
+**      These macros allow you to give a hint to the compiler about branch
+**      probability so that it can better optimize.  Use them like this:
+**
+**      if (JS_LIKELY(v == 1)) {
+**          ... expected code path ...
+**      }
+**
+**      if (JS_UNLIKELY(v == 0)) {
+**          ... non-expected code path ...
+**      }
+**
+***********************************************************************/
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#define JS_LIKELY(x)    (__builtin_expect((x), 1))
+#define JS_UNLIKELY(x)  (__builtin_expect((x), 0))
+#else
+#define JS_LIKELY(x)    (x)
+#define JS_UNLIKELY(x)  (x)
+#endif
+
+JS_END_EXTERN_C
+
+#endif /* jstypes_h___ */

Added: freeswitch/trunk/libs/js/src/jsutil.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsutil.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,191 @@
+/* -*- 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 Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   IBM Corp.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * PR assertion checker.
+ */
+#include "jsstddef.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "jstypes.h"
+#include "jsutil.h"
+
+#ifdef WIN32
+#    include <windows.h>
+#endif
+
+JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln)
+{
+    fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
+#if defined(WIN32)
+    DebugBreak();
+#endif
+#if defined(XP_OS2)
+    asm("int $3");
+#endif
+    abort();
+}
+
+#if defined DEBUG_notme && defined XP_UNIX
+
+#define __USE_GNU 1
+#include <dlfcn.h>
+#include <setjmp.h>
+#include <string.h>
+#include "jshash.h"
+#include "jsprf.h"
+
+JSCallsite js_calltree_root = {0, NULL, NULL, 0, NULL, NULL, NULL, NULL};
+
+static JSCallsite *
+CallTree(uint32 *bp)
+{
+    uint32 *bpup, *bpdown, pc;
+    JSCallsite *parent, *site, **csp;
+    Dl_info info;
+    int ok, offset;
+    const char *symbol;
+    char *method;
+
+    /* Reverse the stack frame list to avoid recursion. */
+    bpup = NULL;
+    for (;;) {
+        bpdown = (uint32*) bp[0];
+        bp[0] = (uint32) bpup;
+        if ((uint32*) bpdown[0] < bpdown)
+            break;
+        bpup = bp;
+        bp = bpdown;
+    }
+
+    /* Reverse the stack again, finding and building a path in the tree. */
+    parent = &js_calltree_root;
+    do {
+        bpup = (uint32*) bp[0];
+        bp[0] = (uint32) bpdown;
+        pc = bp[1];
+
+        csp = &parent->kids;
+        while ((site = *csp) != NULL) {
+            if (site->pc == pc) {
+                /* Put the most recently used site at the front of siblings. */
+                *csp = site->siblings;
+                site->siblings = parent->kids;
+                parent->kids = site;
+
+                /* Site already built -- go up the stack. */
+                goto upward;
+            }
+            csp = &site->siblings;
+        }
+
+        /* Check for recursion: see if pc is on our ancestor line. */
+        for (site = parent; site; site = site->parent) {
+            if (site->pc == pc)
+                goto upward;
+        }
+
+        /*
+         * Not in tree at all: let's find our symbolic callsite info.
+         * XXX static syms are masked by nearest lower global
+         */
+        info.dli_fname = info.dli_sname = NULL;
+        ok = dladdr((void*) pc, &info);
+        if (ok < 0) {
+            fprintf(stderr, "dladdr failed!\n");
+            return NULL;
+        }
+
+/* XXXbe sub 0x08040000? or something, see dbaron bug with tenthumbs comment */
+        symbol = info.dli_sname;
+        offset = (char*)pc - (char*)info.dli_fbase;
+        method = symbol
+                 ? strdup(symbol)
+                 : JS_smprintf("%s+%X",
+                               info.dli_fname ? info.dli_fname : "main",
+                               offset);
+        if (!method)
+            return NULL;
+
+        /* Create a new callsite record. */
+        site = (JSCallsite *) malloc(sizeof(JSCallsite));
+        if (!site)
+            return NULL;
+
+        /* Insert the new site into the tree. */
+        site->pc = pc;
+        site->name = method;
+        site->library = info.dli_fname;
+        site->offset = offset;
+        site->parent = parent;
+        site->siblings = parent->kids;
+        parent->kids = site;
+        site->kids = NULL;
+
+      upward:
+        parent = site;
+        bpdown = bp;
+        bp = bpup;
+    } while (bp);
+
+    return site;
+}
+
+JSCallsite *
+JS_Backtrace(int skip)
+{
+    jmp_buf jb;
+    uint32 *bp, *bpdown;
+
+    setjmp(jb);
+
+    /* Stack walking code adapted from Kipp's "leaky". */
+    bp = (uint32*) jb[0].__jmpbuf[JB_BP];
+    while (--skip >= 0) {
+        bpdown = (uint32*) *bp++;
+        if (bpdown < bp)
+            break;
+        bp = bpdown;
+    }
+
+    return CallTree(bp);
+}
+
+#endif /* DEBUG_notme && XP_UNIX */

Added: freeswitch/trunk/libs/js/src/jsutil.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsutil.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,94 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * PR assertion checker.
+ */
+
+#ifndef jsutil_h___
+#define jsutil_h___
+
+JS_BEGIN_EXTERN_C
+
+#ifdef DEBUG
+
+extern JS_PUBLIC_API(void)
+JS_Assert(const char *s, const char *file, JSIntn ln);
+#define JS_ASSERT(_expr) \
+    ((_expr)?((void)0):JS_Assert(# _expr,__FILE__,__LINE__))
+
+#define JS_NOT_REACHED(_reasonStr) \
+    JS_Assert(_reasonStr,__FILE__,__LINE__)
+
+#else
+
+#define JS_ASSERT(expr) ((void) 0)
+#define JS_NOT_REACHED(reasonStr)
+
+#endif /* defined(DEBUG) */
+
+/*
+** Abort the process in a non-graceful manner. This will cause a core file,
+** call to the debugger or other moral equivalent as well as causing the
+** entire process to stop.
+*/
+extern JS_PUBLIC_API(void) JS_Abort(void);
+
+#ifdef XP_UNIX
+
+typedef struct JSCallsite JSCallsite;
+
+struct JSCallsite {
+    uint32      pc;
+    char        *name;
+    const char  *library;
+    int         offset;
+    JSCallsite  *parent;
+    JSCallsite  *siblings;
+    JSCallsite  *kids;
+    void        *handy;
+};
+
+extern JSCallsite *JS_Backtrace(int skip);
+
+#endif
+
+JS_END_EXTERN_C
+
+#endif /* jsutil_h___ */

Added: freeswitch/trunk/libs/js/src/jsxdrapi.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsxdrapi.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,686 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "jsstddef.h"
+#include "jsconfig.h"
+
+#if JS_HAS_XDR
+
+#include <string.h>
+#include "jstypes.h"
+#include "jsutil.h" /* Added by JSIFY */
+#include "jsdhash.h"
+#include "jsprf.h"
+#include "jsapi.h"
+#include "jscntxt.h"
+#include "jsnum.h"
+#include "jsobj.h"              /* js_XDRObject */
+#include "jsscript.h"           /* js_XDRScript */
+#include "jsstr.h"
+#include "jsxdrapi.h"
+
+#ifdef DEBUG
+#define DBG(x) x
+#else
+#define DBG(x) ((void)0)
+#endif
+
+typedef struct JSXDRMemState {
+    JSXDRState  state;
+    char        *base;
+    uint32      count;
+    uint32      limit;
+} JSXDRMemState;
+
+#define MEM_BLOCK       8192
+#define MEM_PRIV(xdr)   ((JSXDRMemState *)(xdr))
+
+#define MEM_BASE(xdr)   (MEM_PRIV(xdr)->base)
+#define MEM_COUNT(xdr)  (MEM_PRIV(xdr)->count)
+#define MEM_LIMIT(xdr)  (MEM_PRIV(xdr)->limit)
+
+#define MEM_LEFT(xdr, bytes)                                                  \
+    JS_BEGIN_MACRO                                                            \
+        if ((xdr)->mode == JSXDR_DECODE &&                                    \
+            MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) {                        \
+            JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL,         \
+                                 JSMSG_END_OF_DATA);                          \
+            return 0;                                                         \
+        }                                                                     \
+    JS_END_MACRO
+
+#define MEM_NEED(xdr, bytes)                                                  \
+    JS_BEGIN_MACRO                                                            \
+        if ((xdr)->mode == JSXDR_ENCODE) {                                    \
+            if (MEM_LIMIT(xdr) &&                                             \
+                MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) {                    \
+                uint32 limit_ = JS_ROUNDUP(MEM_COUNT(xdr) + bytes, MEM_BLOCK);\
+                void *data_ = JS_realloc((xdr)->cx, MEM_BASE(xdr), limit_);   \
+                if (!data_)                                                   \
+                    return 0;                                                 \
+                MEM_BASE(xdr) = data_;                                        \
+                MEM_LIMIT(xdr) = limit_;                                      \
+            }                                                                 \
+        } else {                                                              \
+            MEM_LEFT(xdr, bytes);                                             \
+        }                                                                     \
+    JS_END_MACRO
+
+#define MEM_DATA(xdr)        ((void *)(MEM_BASE(xdr) + MEM_COUNT(xdr)))
+#define MEM_INCR(xdr,bytes)  (MEM_COUNT(xdr) += (bytes))
+
+static JSBool
+mem_get32(JSXDRState *xdr, uint32 *lp)
+{
+    MEM_LEFT(xdr, 4);
+    *lp = *(uint32 *)MEM_DATA(xdr);
+    MEM_INCR(xdr, 4);
+    return JS_TRUE;
+}
+
+static JSBool
+mem_set32(JSXDRState *xdr, uint32 *lp)
+{
+    MEM_NEED(xdr, 4);
+    *(uint32 *)MEM_DATA(xdr) = *lp;
+    MEM_INCR(xdr, 4);
+    return JS_TRUE;
+}
+
+static JSBool
+mem_getbytes(JSXDRState *xdr, char *bytes, uint32 len)
+{
+    MEM_LEFT(xdr, len);
+    memcpy(bytes, MEM_DATA(xdr), len);
+    MEM_INCR(xdr, len);
+    return JS_TRUE;
+}
+
+static JSBool
+mem_setbytes(JSXDRState *xdr, char *bytes, uint32 len)
+{
+    MEM_NEED(xdr, len);
+    memcpy(MEM_DATA(xdr), bytes, len);
+    MEM_INCR(xdr, len);
+    return JS_TRUE;
+}
+
+static void *
+mem_raw(JSXDRState *xdr, uint32 len)
+{
+    void *data;
+    if (xdr->mode == JSXDR_ENCODE) {
+        MEM_NEED(xdr, len);
+    } else if (xdr->mode == JSXDR_DECODE) {
+        MEM_LEFT(xdr, len);
+    }
+    data = MEM_DATA(xdr);
+    MEM_INCR(xdr, len);
+    return data;
+}
+
+static JSBool
+mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence)
+{
+    switch (whence) {
+      case JSXDR_SEEK_CUR:
+        if ((int32)MEM_COUNT(xdr) + offset < 0) {
+            JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
+                                 JSMSG_SEEK_BEYOND_START);
+            return JS_FALSE;
+        }
+        if (offset > 0)
+            MEM_NEED(xdr, offset);
+        MEM_COUNT(xdr) += offset;
+        return JS_TRUE;
+      case JSXDR_SEEK_SET:
+        if (offset < 0) {
+            JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
+                                 JSMSG_SEEK_BEYOND_START);
+            return JS_FALSE;
+        }
+        if (xdr->mode == JSXDR_ENCODE) {
+            if ((uint32)offset > MEM_COUNT(xdr))
+                MEM_NEED(xdr, offset - MEM_COUNT(xdr));
+            MEM_COUNT(xdr) = offset;
+        } else {
+            if ((uint32)offset > MEM_LIMIT(xdr)) {
+                JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
+                                     JSMSG_SEEK_BEYOND_END);
+                return JS_FALSE;
+            }
+            MEM_COUNT(xdr) = offset;
+        }
+        return JS_TRUE;
+      case JSXDR_SEEK_END:
+        if (offset >= 0 ||
+            xdr->mode == JSXDR_ENCODE ||
+            (int32)MEM_LIMIT(xdr) + offset < 0) {
+            JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
+                                 JSMSG_END_SEEK);
+            return JS_FALSE;
+        }
+        MEM_COUNT(xdr) = MEM_LIMIT(xdr) + offset;
+        return JS_TRUE;
+      default: {
+        char numBuf[12];
+        JS_snprintf(numBuf, sizeof numBuf, "%d", whence);
+        JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
+                             JSMSG_WHITHER_WHENCE, numBuf);
+        return JS_FALSE;
+      }
+    }
+}
+
+static uint32
+mem_tell(JSXDRState *xdr)
+{
+    return MEM_COUNT(xdr);
+}
+
+static void
+mem_finalize(JSXDRState *xdr)
+{
+    JS_free(xdr->cx, MEM_BASE(xdr));
+}
+
+static JSXDROps xdrmem_ops = {
+    mem_get32,      mem_set32,      mem_getbytes,   mem_setbytes,
+    mem_raw,        mem_seek,       mem_tell,       mem_finalize
+};
+
+JS_PUBLIC_API(void)
+JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx)
+{
+    xdr->mode = mode;
+    xdr->cx = cx;
+    xdr->registry = NULL;
+    xdr->numclasses = xdr->maxclasses = 0;
+    xdr->reghash = NULL;
+    xdr->userdata = NULL;
+}
+
+JS_PUBLIC_API(JSXDRState *)
+JS_XDRNewMem(JSContext *cx, JSXDRMode mode)
+{
+    JSXDRState *xdr = (JSXDRState *) JS_malloc(cx, sizeof(JSXDRMemState));
+    if (!xdr)
+        return NULL;
+    JS_XDRInitBase(xdr, mode, cx);
+    if (mode == JSXDR_ENCODE) {
+        if (!(MEM_BASE(xdr) = JS_malloc(cx, MEM_BLOCK))) {
+            JS_free(cx, xdr);
+            return NULL;
+        }
+    } else {
+        /* XXXbe ok, so better not deref MEM_BASE(xdr) if not ENCODE */
+        MEM_BASE(xdr) = NULL;
+    }
+    xdr->ops = &xdrmem_ops;
+    MEM_COUNT(xdr) = 0;
+    MEM_LIMIT(xdr) = MEM_BLOCK;
+    return xdr;
+}
+
+JS_PUBLIC_API(void *)
+JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp)
+{
+    if (xdr->ops != &xdrmem_ops)
+        return NULL;
+    *lp = MEM_COUNT(xdr);
+    return MEM_BASE(xdr);
+}
+
+JS_PUBLIC_API(void)
+JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len)
+{
+    if (xdr->ops != &xdrmem_ops)
+        return;
+    MEM_LIMIT(xdr) = len;
+    MEM_BASE(xdr) = data;
+    MEM_COUNT(xdr) = 0;
+}
+
+JS_PUBLIC_API(uint32)
+JS_XDRMemDataLeft(JSXDRState *xdr)
+{
+    if (xdr->ops != &xdrmem_ops)
+        return 0;
+    return MEM_LIMIT(xdr) - MEM_COUNT(xdr);
+}
+
+JS_PUBLIC_API(void)
+JS_XDRMemResetData(JSXDRState *xdr)
+{
+    if (xdr->ops != &xdrmem_ops)
+        return;
+    MEM_COUNT(xdr) = 0;
+}
+
+JS_PUBLIC_API(void)
+JS_XDRDestroy(JSXDRState *xdr)
+{
+    JSContext *cx = xdr->cx;
+    xdr->ops->finalize(xdr);
+    if (xdr->registry) {
+        JS_free(cx, xdr->registry);
+        if (xdr->reghash)
+            JS_DHashTableDestroy(xdr->reghash);
+    }
+    JS_free(cx, xdr);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_XDRUint8(JSXDRState *xdr, uint8 *b)
+{
+    uint32 l = *b;
+    if (!JS_XDRUint32(xdr, &l))
+        return JS_FALSE;
+    *b = (uint8) l;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_XDRUint16(JSXDRState *xdr, uint16 *s)
+{
+    uint32 l = *s;
+    if (!JS_XDRUint32(xdr, &l))
+        return JS_FALSE;
+    *s = (uint16) l;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_XDRUint32(JSXDRState *xdr, uint32 *lp)
+{
+    JSBool ok = JS_TRUE;
+    if (xdr->mode == JSXDR_ENCODE) {
+        uint32 xl = JSXDR_SWAB32(*lp);
+        ok = xdr->ops->set32(xdr, &xl);
+    } else if (xdr->mode == JSXDR_DECODE) {
+        ok = xdr->ops->get32(xdr, lp);
+        *lp = JSXDR_SWAB32(*lp);
+    }
+    return ok;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_XDRBytes(JSXDRState *xdr, char *bytes, uint32 len)
+{
+    uint32 padlen;
+    static char padbuf[JSXDR_ALIGN-1];
+
+    if (xdr->mode == JSXDR_ENCODE) {
+        if (!xdr->ops->setbytes(xdr, bytes, len))
+            return JS_FALSE;
+    } else {
+        if (!xdr->ops->getbytes(xdr, bytes, len))
+            return JS_FALSE;
+    }
+    len = xdr->ops->tell(xdr);
+    if (len % JSXDR_ALIGN) {
+        padlen = JSXDR_ALIGN - (len % JSXDR_ALIGN);
+        if (xdr->mode == JSXDR_ENCODE) {
+            if (!xdr->ops->setbytes(xdr, padbuf, padlen))
+                return JS_FALSE;
+        } else {
+            if (!xdr->ops->seek(xdr, padlen, JSXDR_SEEK_CUR))
+                return JS_FALSE;
+        }
+    }
+    return JS_TRUE;
+}
+
+/**
+ * Convert between a C string and the XDR representation:
+ * leading 32-bit count, then counted vector of chars,
+ * then possibly \0 padding to multiple of 4.
+ */
+JS_PUBLIC_API(JSBool)
+JS_XDRCString(JSXDRState *xdr, char **sp)
+{
+    uint32 len;
+
+    if (xdr->mode == JSXDR_ENCODE)
+        len = strlen(*sp);
+    JS_XDRUint32(xdr, &len);
+    if (xdr->mode == JSXDR_DECODE) {
+        if (!(*sp = (char *) JS_malloc(xdr->cx, len + 1)))
+            return JS_FALSE;
+    }
+    if (!JS_XDRBytes(xdr, *sp, len)) {
+        if (xdr->mode == JSXDR_DECODE)
+            JS_free(xdr->cx, *sp);
+        return JS_FALSE;
+    }
+    if (xdr->mode == JSXDR_DECODE) {
+        (*sp)[len] = '\0';
+    } else if (xdr->mode == JSXDR_FREE) {
+        JS_free(xdr->cx, *sp);
+        *sp = NULL;
+    }
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_XDRCStringOrNull(JSXDRState *xdr, char **sp)
+{
+    uint32 null = (*sp == NULL);
+    if (!JS_XDRUint32(xdr, &null))
+        return JS_FALSE;
+    if (null) {
+        *sp = NULL;
+        return JS_TRUE;
+    }
+    return JS_XDRCString(xdr, sp);
+}
+
+/*
+ * Convert between a JS (Unicode) string and the XDR representation.
+ */
+JS_PUBLIC_API(JSBool)
+JS_XDRString(JSXDRState *xdr, JSString **strp)
+{
+    uint32 i, len, padlen, nbytes;
+    jschar *chars = NULL, *raw;
+
+    if (xdr->mode == JSXDR_ENCODE)
+        len = JSSTRING_LENGTH(*strp);
+    if (!JS_XDRUint32(xdr, &len))
+        return JS_FALSE;
+    nbytes = len * sizeof(jschar);
+
+    if (xdr->mode == JSXDR_DECODE) {
+        if (!(chars = (jschar *) JS_malloc(xdr->cx, nbytes + sizeof(jschar))))
+            return JS_FALSE;
+    } else {
+        chars = JSSTRING_CHARS(*strp);
+    }
+
+    padlen = nbytes % JSXDR_ALIGN;
+    if (padlen) {
+        padlen = JSXDR_ALIGN - padlen;
+        nbytes += padlen;
+    }
+    if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes)))
+        goto bad;
+    if (xdr->mode == JSXDR_ENCODE) {
+        for (i = 0; i < len; i++)
+            raw[i] = JSXDR_SWAB16(chars[i]);
+        if (padlen)
+            memset((char *)raw + nbytes - padlen, 0, padlen);
+    } else if (xdr->mode == JSXDR_DECODE) {
+        for (i = 0; i < len; i++)
+            chars[i] = JSXDR_SWAB16(raw[i]);
+        chars[len] = 0;
+
+        if (!(*strp = JS_NewUCString(xdr->cx, chars, len)))
+            goto bad;
+    }
+    return JS_TRUE;
+
+bad:
+    if (xdr->mode == JSXDR_DECODE)
+        JS_free(xdr->cx, chars);
+    return JS_FALSE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp)
+{
+    uint32 null = (*strp == NULL);
+    if (!JS_XDRUint32(xdr, &null))
+        return JS_FALSE;
+    if (null) {
+        *strp = NULL;
+        return JS_TRUE;
+    }
+    return JS_XDRString(xdr, strp);
+}
+
+JS_PUBLIC_API(JSBool)
+JS_XDRDouble(JSXDRState *xdr, jsdouble **dp)
+{
+    jsdpun u;
+
+    if (xdr->mode == JSXDR_ENCODE)
+        u.d = **dp;
+    if (!JS_XDRUint32(xdr, &u.s.lo) || !JS_XDRUint32(xdr, &u.s.hi))
+        return JS_FALSE;
+    if (xdr->mode == JSXDR_DECODE) {
+        *dp = JS_NewDouble(xdr->cx, u.d);
+        if (!*dp)
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+/* These are magic pseudo-tags: see jsapi.h, near the top, for real tags. */
+#define JSVAL_XDRNULL   0x8
+#define JSVAL_XDRVOID   0xA
+
+JS_PUBLIC_API(JSBool)
+JS_XDRValue(JSXDRState *xdr, jsval *vp)
+{
+    uint32 type;
+
+    if (xdr->mode == JSXDR_ENCODE) {
+        if (JSVAL_IS_NULL(*vp))
+            type = JSVAL_XDRNULL;
+        else if (JSVAL_IS_VOID(*vp))
+            type = JSVAL_XDRVOID;
+        else
+            type = JSVAL_TAG(*vp);
+    }
+    if (!JS_XDRUint32(xdr, &type))
+        return JS_FALSE;
+
+    switch (type) {
+      case JSVAL_XDRNULL:
+        *vp = JSVAL_NULL;
+        break;
+      case JSVAL_XDRVOID:
+        *vp = JSVAL_VOID;
+        break;
+      case JSVAL_STRING: {
+        JSString *str;
+        if (xdr->mode == JSXDR_ENCODE)
+            str = JSVAL_TO_STRING(*vp);
+        if (!JS_XDRString(xdr, &str))
+            return JS_FALSE;
+        if (xdr->mode == JSXDR_DECODE)
+            *vp = STRING_TO_JSVAL(str);
+        break;
+      }
+      case JSVAL_DOUBLE: {
+        jsdouble *dp;
+        if (xdr->mode == JSXDR_ENCODE)
+            dp = JSVAL_TO_DOUBLE(*vp);
+        if (!JS_XDRDouble(xdr, &dp))
+            return JS_FALSE;
+        if (xdr->mode == JSXDR_DECODE)
+            *vp = DOUBLE_TO_JSVAL(dp);
+        break;
+      }
+      case JSVAL_OBJECT: {
+        JSObject *obj;
+        if (xdr->mode == JSXDR_ENCODE)
+            obj = JSVAL_TO_OBJECT(*vp);
+        if (!js_XDRObject(xdr, &obj))
+            return JS_FALSE;
+        if (xdr->mode == JSXDR_DECODE)
+            *vp = OBJECT_TO_JSVAL(obj);
+        break;
+      }
+      case JSVAL_BOOLEAN: {
+        uint32 b;
+        if (xdr->mode == JSXDR_ENCODE)
+            b = (uint32) JSVAL_TO_BOOLEAN(*vp);
+        if (!JS_XDRUint32(xdr, &b))
+            return JS_FALSE;
+        if (xdr->mode == JSXDR_DECODE)
+            *vp = BOOLEAN_TO_JSVAL((JSBool) b);
+        break;
+      }
+      default: {
+        uint32 i;
+
+        JS_ASSERT(type & JSVAL_INT);
+        if (xdr->mode == JSXDR_ENCODE)
+            i = (uint32) JSVAL_TO_INT(*vp);
+        if (!JS_XDRUint32(xdr, &i))
+            return JS_FALSE;
+        if (xdr->mode == JSXDR_DECODE)
+            *vp = INT_TO_JSVAL((int32) i);
+        break;
+      }
+    }
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(JSBool)
+JS_XDRScript(JSXDRState *xdr, JSScript **scriptp)
+{
+    if (!js_XDRScript(xdr, scriptp, NULL))
+        return JS_FALSE;
+    if (xdr->mode == JSXDR_DECODE)
+        js_CallNewScriptHook(xdr->cx, *scriptp, NULL);
+    return JS_TRUE;
+}
+
+#define CLASS_REGISTRY_MIN      8
+#define CLASS_INDEX_TO_ID(i)    ((i)+1)
+#define CLASS_ID_TO_INDEX(id)   ((id)-1)
+
+typedef struct JSRegHashEntry {
+    JSDHashEntryHdr hdr;
+    const char      *name;
+    uint32          index;
+} JSRegHashEntry;
+
+JS_PUBLIC_API(JSBool)
+JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp)
+{
+    uintN numclasses, maxclasses;
+    JSClass **registry;
+
+    numclasses = xdr->numclasses;
+    maxclasses = xdr->maxclasses;
+    if (numclasses == maxclasses) {
+        maxclasses = (maxclasses == 0) ? CLASS_REGISTRY_MIN : maxclasses << 1;
+        registry = (JSClass **)
+            JS_realloc(xdr->cx, xdr->registry, maxclasses * sizeof(JSClass *));
+        if (!registry)
+            return JS_FALSE;
+        xdr->registry = registry;
+        xdr->maxclasses = maxclasses;
+    } else {
+        JS_ASSERT(numclasses && numclasses < maxclasses);
+        registry = xdr->registry;
+    }
+
+    registry[numclasses] = clasp;
+    if (xdr->reghash) {
+        JSRegHashEntry *entry = (JSRegHashEntry *)
+            JS_DHashTableOperate(xdr->reghash, clasp->name, JS_DHASH_ADD);
+        if (!entry) {
+            JS_ReportOutOfMemory(xdr->cx);
+            return JS_FALSE;
+        }
+        entry->name = clasp->name;
+        entry->index = numclasses;
+    }
+    *idp = CLASS_INDEX_TO_ID(numclasses);
+    xdr->numclasses = ++numclasses;
+    return JS_TRUE;
+}
+
+JS_PUBLIC_API(uint32)
+JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name)
+{
+    uintN i, numclasses;
+
+    numclasses = xdr->numclasses;
+    if (numclasses >= 10) {
+        JSRegHashEntry *entry;
+
+        /* Bootstrap reghash from registry on first overpopulated Find. */
+        if (!xdr->reghash) {
+            xdr->reghash = JS_NewDHashTable(JS_DHashGetStubOps(), NULL,
+                                            sizeof(JSRegHashEntry),
+                                            numclasses);
+            if (xdr->reghash) {
+                for (i = 0; i < numclasses; i++) {
+                    JSClass *clasp = xdr->registry[i];
+                    entry = (JSRegHashEntry *)
+                        JS_DHashTableOperate(xdr->reghash, clasp->name,
+                                             JS_DHASH_ADD);
+                    entry->name = clasp->name;
+                    entry->index = i;
+                }
+            }
+        }
+
+        /* If we managed to create reghash, use it for O(1) Find. */
+        if (xdr->reghash) {
+            entry = (JSRegHashEntry *)
+                JS_DHashTableOperate(xdr->reghash, name, JS_DHASH_LOOKUP);
+            if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr))
+                return CLASS_INDEX_TO_ID(entry->index);
+        }
+    }
+
+    /* Only a few classes, or we couldn't malloc reghash: use linear search. */
+    for (i = 0; i < numclasses; i++) {
+        if (!strcmp(name, xdr->registry[i]->name))
+            return CLASS_INDEX_TO_ID(i);
+    }
+    return 0;
+}
+
+JS_PUBLIC_API(JSClass *)
+JS_XDRFindClassById(JSXDRState *xdr, uint32 id)
+{
+    uintN i = CLASS_ID_TO_INDEX(id);
+
+    if (i >= xdr->numclasses)
+        return NULL;
+    return xdr->registry[i];
+}
+
+#endif /* JS_HAS_XDR */

Added: freeswitch/trunk/libs/js/src/jsxdrapi.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsxdrapi.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,193 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsxdrapi_h___
+#define jsxdrapi_h___
+
+/*
+ * JS external data representation interface API.
+ *
+ * The XDR system is comprised of three major parts:
+ *
+ * - the state serialization/deserialization APIs, which allow consumers
+ *   of the API to serialize JS runtime state (script bytecodes, atom maps,
+ *   object graphs, etc.) for later restoration.  These portions
+ *   are implemented in various appropriate files, such as jsscript.c
+ *   for the script portions and jsobj.c for object state.
+ * - the callback APIs through which the runtime requests an opaque
+ *   representation of a native object, and through which the runtime
+ *   constructs a live native object from an opaque representation. These
+ *   portions are the responsibility of the native object implementor.
+ * - utility functions for en/decoding of primitive types, such as
+ *   JSStrings.  This portion is implemented in jsxdrapi.c.
+ *
+ * Spiritually guided by Sun's XDR, where appropriate.
+ */
+
+#include "jspubtd.h"
+#include "jsprvtd.h"
+
+JS_BEGIN_EXTERN_C
+
+/* We use little-endian byteorder for all encoded data */
+
+#if defined IS_LITTLE_ENDIAN
+#define JSXDR_SWAB32(x) x
+#define JSXDR_SWAB16(x) x
+#elif defined IS_BIG_ENDIAN
+#define JSXDR_SWAB32(x) (((uint32)(x) >> 24) |                                \
+                         (((uint32)(x) >> 8) & 0xff00) |                      \
+                         (((uint32)(x) << 8) & 0xff0000) |                    \
+                         ((uint32)(x) << 24))
+#define JSXDR_SWAB16(x) (((uint16)(x) >> 8) | ((uint16)(x) << 8))
+#else
+#error "unknown byte order"
+#endif
+
+#define JSXDR_ALIGN     4
+
+typedef enum JSXDRMode {
+    JSXDR_ENCODE,
+    JSXDR_DECODE,
+    JSXDR_FREE
+} JSXDRMode;
+
+typedef enum JSXDRWhence {
+    JSXDR_SEEK_SET,
+    JSXDR_SEEK_CUR,
+    JSXDR_SEEK_END
+} JSXDRWhence;
+
+typedef struct JSXDROps {
+    JSBool      (*get32)(JSXDRState *, uint32 *);
+    JSBool      (*set32)(JSXDRState *, uint32 *);
+    JSBool      (*getbytes)(JSXDRState *, char *, uint32);
+    JSBool      (*setbytes)(JSXDRState *, char *, uint32);
+    void *      (*raw)(JSXDRState *, uint32);
+    JSBool      (*seek)(JSXDRState *, int32, JSXDRWhence);
+    uint32      (*tell)(JSXDRState *);
+    void        (*finalize)(JSXDRState *);
+} JSXDROps;
+
+struct JSXDRState {
+    JSXDRMode   mode;
+    JSXDROps    *ops;
+    JSContext   *cx;
+    JSClass     **registry;
+    uintN       numclasses;
+    uintN       maxclasses;
+    void        *reghash;
+    void        *userdata;
+};
+
+extern JS_PUBLIC_API(void)
+JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx);
+
+extern JS_PUBLIC_API(JSXDRState *)
+JS_XDRNewMem(JSContext *cx, JSXDRMode mode);
+
+extern JS_PUBLIC_API(void *)
+JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp);
+
+extern JS_PUBLIC_API(void)
+JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len);
+
+extern JS_PUBLIC_API(uint32)
+JS_XDRMemDataLeft(JSXDRState *xdr);
+
+extern JS_PUBLIC_API(void)
+JS_XDRMemResetData(JSXDRState *xdr);
+
+extern JS_PUBLIC_API(void)
+JS_XDRDestroy(JSXDRState *xdr);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRUint8(JSXDRState *xdr, uint8 *b);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRUint16(JSXDRState *xdr, uint16 *s);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRUint32(JSXDRState *xdr, uint32 *lp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRBytes(JSXDRState *xdr, char *bytes, uint32 len);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRCString(JSXDRState *xdr, char **sp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRCStringOrNull(JSXDRState *xdr, char **sp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRString(JSXDRState *xdr, JSString **strp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRDouble(JSXDRState *xdr, jsdouble **dp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRValue(JSXDRState *xdr, jsval *vp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRScript(JSXDRState *xdr, JSScript **scriptp);
+
+extern JS_PUBLIC_API(JSBool)
+JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp);
+
+extern JS_PUBLIC_API(uint32)
+JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name);
+
+extern JS_PUBLIC_API(JSClass *)
+JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
+
+/*
+ * Magic numbers.
+ */
+#define JSXDR_MAGIC_SCRIPT_1        0xdead0001
+#define JSXDR_MAGIC_SCRIPT_2        0xdead0002
+#define JSXDR_MAGIC_SCRIPT_3        0xdead0003
+#define JSXDR_MAGIC_SCRIPT_4        0xdead0004
+#define JSXDR_MAGIC_SCRIPT_CURRENT  JSXDR_MAGIC_SCRIPT_4
+
+JS_END_EXTERN_C
+
+#endif /* ! jsxdrapi_h___ */

Added: freeswitch/trunk/libs/js/src/jsxml.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsxml.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,8062 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=4 sw=4 et tw=80:
+ *
+ * ***** 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 SpiderMonkey E4X code, released August, 2004.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "jsstddef.h"
+#include "jsconfig.h"
+
+#if JS_HAS_XML_SUPPORT
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "jstypes.h"
+#include "jsbit.h"
+#include "jsprf.h"
+#include "jsutil.h"
+#include "jsapi.h"
+#include "jsarray.h"
+#include "jsatom.h"
+#include "jsbool.h"
+#include "jscntxt.h"
+#include "jsfun.h"
+#include "jsgc.h"
+#include "jsinterp.h"
+#include "jslock.h"
+#include "jsnum.h"
+#include "jsobj.h"
+#include "jsopcode.h"
+#include "jsparse.h"
+#include "jsscan.h"
+#include "jsscope.h"
+#include "jsscript.h"
+#include "jsstr.h"
+#include "jsxml.h"
+
+#ifdef DEBUG
+#include <string.h>     /* for #ifdef DEBUG memset calls */
+#endif
+
+/*
+ * NOTES
+ * - in the js shell, you must use the -x command line option, or call
+ *   options('xml') before compiling anything that uses XML literals
+ *
+ * TODO
+ * - XXXbe patrol
+ * - Fuse objects and their JSXML* private data into single GC-things
+ * - fix function::foo vs. x.(foo == 42) collision using proper namespacing
+ * - fix the !TCF_HAS_DEFXMLNS optimization in js_FoldConstants
+ * - JSCLASS_DOCUMENT_OBSERVER support -- live two-way binding to Gecko's DOM!
+ * - JS_TypeOfValue sure could use a cleaner interface to "types"
+ */
+
+#ifdef DEBUG_brendan
+#define METERING        1
+#endif
+
+#ifdef METERING
+static struct {
+    jsrefcount  qname;
+    jsrefcount  qnameobj;
+    jsrefcount  liveqname;
+    jsrefcount  liveqnameobj;
+    jsrefcount  namespace;
+    jsrefcount  namespaceobj;
+    jsrefcount  livenamespace;
+    jsrefcount  livenamespaceobj;
+    jsrefcount  xml;
+    jsrefcount  xmlobj;
+    jsrefcount  livexml;
+    jsrefcount  livexmlobj;
+} xml_stats;
+
+#define METER(x)        JS_ATOMIC_INCREMENT(&(x))
+#define UNMETER(x)      JS_ATOMIC_DECREMENT(&(x))
+#else
+#define METER(x)        /* nothing */
+#define UNMETER(x)      /* nothing */
+#endif
+
+/*
+ * Random utilities and global functions.
+ */
+const char js_AnyName_str[]       = "AnyName";
+const char js_AttributeName_str[] = "AttributeName";
+const char js_isXMLName_str[]     = "isXMLName";
+const char js_XMLList_str[]       = "XMLList";
+const char js_localName_str[]     = "localName";
+const char js_xml_parent_str[]    = "parent";
+const char js_prefix_str[]        = "prefix";
+const char js_toXMLString_str[]   = "toXMLString";
+const char js_uri_str[]           = "uri";
+
+const char js_amp_entity_str[]    = "&amp;";
+const char js_gt_entity_str[]     = "&gt;";
+const char js_lt_entity_str[]     = "&lt;";
+const char js_quot_entity_str[]   = "&quot;";
+
+#define IS_EMPTY(str) (JSSTRING_LENGTH(str) == 0)
+#define IS_STAR(str)  (JSSTRING_LENGTH(str) == 1 && *JSSTRING_CHARS(str) == '*')
+
+static JSBool
+xml_isXMLName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    *rval = BOOLEAN_TO_JSVAL(js_IsXMLName(cx, argv[0]));
+    return JS_TRUE;
+}
+
+/*
+ * Namespace class and library functions.
+ */
+enum namespace_tinyid {
+    NAMESPACE_PREFIX = -1,
+    NAMESPACE_URI = -2
+};
+
+static JSBool
+namespace_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSXMLNamespace *ns;
+
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+
+    ns = (JSXMLNamespace *)
+         JS_GetInstancePrivate(cx, obj, &js_NamespaceClass.base, NULL);
+    if (!ns)
+        return JS_TRUE;
+
+    switch (JSVAL_TO_INT(id)) {
+      case NAMESPACE_PREFIX:
+        *vp = ns->prefix ? STRING_TO_JSVAL(ns->prefix) : JSVAL_VOID;
+        break;
+      case NAMESPACE_URI:
+        *vp = STRING_TO_JSVAL(ns->uri);
+        break;
+    }
+    return JS_TRUE;
+}
+
+static void
+namespace_finalize(JSContext *cx, JSObject *obj)
+{
+    JSXMLNamespace *ns;
+    JSRuntime *rt;
+
+    ns = (JSXMLNamespace *) JS_GetPrivate(cx, obj);
+    if (!ns)
+        return;
+    JS_ASSERT(ns->object == obj);
+    ns->object = NULL;
+    UNMETER(xml_stats.livenamespaceobj);
+
+    rt = cx->runtime;
+    if (rt->functionNamespaceObject == obj)
+        rt->functionNamespaceObject = NULL;
+}
+
+static void
+namespace_mark_vector(JSContext *cx, JSXMLNamespace **vec, uint32 len,
+                      void *arg)
+{
+    uint32 i;
+    JSXMLNamespace *ns;
+
+    for (i = 0; i < len; i++) {
+        ns = vec[i];
+        {
+#ifdef GC_MARK_DEBUG
+            char buf[100];
+
+            JS_snprintf(buf, sizeof buf, "%s=%s",
+                        ns->prefix ? JS_GetStringBytes(ns->prefix) : "",
+                        JS_GetStringBytes(ns->uri));
+#else
+            const char *buf = NULL;
+#endif
+            JS_MarkGCThing(cx, ns, buf, arg);
+        }
+    }
+}
+
+static uint32
+namespace_mark(JSContext *cx, JSObject *obj, void *arg)
+{
+    JSXMLNamespace *ns;
+
+    ns = (JSXMLNamespace *) JS_GetPrivate(cx, obj);
+    JS_MarkGCThing(cx, ns, js_private_str, arg);
+    return 0;
+}
+
+static JSBool
+namespace_equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
+{
+    JSXMLNamespace *ns, *ns2;
+    JSObject *obj2;
+
+    ns = (JSXMLNamespace *) JS_GetPrivate(cx, obj);
+    JS_ASSERT(JSVAL_IS_OBJECT(v));
+    obj2 = JSVAL_TO_OBJECT(v);
+    if (!obj2 || OBJ_GET_CLASS(cx, obj2) != &js_NamespaceClass.base) {
+        *bp = JS_FALSE;
+    } else {
+        ns2 = (JSXMLNamespace *) JS_GetPrivate(cx, obj2);
+        *bp = !js_CompareStrings(ns->uri, ns2->uri);
+    }
+    return JS_TRUE;
+}
+
+JS_FRIEND_DATA(JSExtendedClass) js_NamespaceClass = {
+  { "Namespace",
+    JSCLASS_HAS_PRIVATE | JSCLASS_CONSTRUCT_PROTOTYPE | JSCLASS_IS_EXTENDED,
+    JS_PropertyStub,   JS_PropertyStub,   namespace_getProperty, NULL,
+    JS_EnumerateStub,  JS_ResolveStub,    JS_ConvertStub,    namespace_finalize,
+    NULL,              NULL,              NULL,              NULL,
+    NULL,              NULL,              namespace_mark,    NULL },
+    namespace_equality,
+    NULL, NULL,
+    JSCLASS_NO_RESERVED_MEMBERS
+};
+
+#define NAMESPACE_ATTRS                                                       \
+    (JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED)
+
+static JSPropertySpec namespace_props[] = {
+    {js_prefix_str,    NAMESPACE_PREFIX,  NAMESPACE_ATTRS,   0, 0},
+    {js_uri_str,       NAMESPACE_URI,     NAMESPACE_ATTRS,   0, 0},
+    {0,0,0,0,0}
+};
+
+static JSBool
+namespace_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                   jsval *rval)
+{
+    JSXMLNamespace *ns;
+
+    ns = (JSXMLNamespace *)
+         JS_GetInstancePrivate(cx, obj, &js_NamespaceClass.base, argv);
+    if (!ns)
+        return JS_FALSE;
+
+    *rval = STRING_TO_JSVAL(ns->uri);
+    return JS_TRUE;
+}
+
+static JSFunctionSpec namespace_methods[] = {
+    {js_toString_str,  namespace_toString,        0,0,0},
+    {0,0,0,0,0}
+};
+
+JSXMLNamespace *
+js_NewXMLNamespace(JSContext *cx, JSString *prefix, JSString *uri,
+                   JSBool declared)
+{
+    JSXMLNamespace *ns;
+
+    ns = (JSXMLNamespace *)
+         js_NewGCThing(cx, GCX_NAMESPACE, sizeof(JSXMLNamespace));
+    if (!ns)
+        return NULL;
+    ns->object = NULL;
+    ns->prefix = prefix;
+    ns->uri = uri;
+    ns->declared = declared;
+    METER(xml_stats.namespace);
+    METER(xml_stats.livenamespace);
+    return ns;
+}
+
+void
+js_MarkXMLNamespace(JSContext *cx, JSXMLNamespace *ns, void *arg)
+{
+    JS_MarkGCThing(cx, ns->object, js_object_str, arg);
+    JS_MarkGCThing(cx, ns->prefix, js_prefix_str, arg);
+    JS_MarkGCThing(cx, ns->uri, js_uri_str, arg);
+}
+
+void
+js_FinalizeXMLNamespace(JSContext *cx, JSXMLNamespace *ns)
+{
+    UNMETER(xml_stats.livenamespace);
+}
+
+JSObject *
+js_NewXMLNamespaceObject(JSContext *cx, JSString *prefix, JSString *uri,
+                         JSBool declared)
+{
+    JSXMLNamespace *ns;
+
+    ns = js_NewXMLNamespace(cx, prefix, uri, declared);
+    if (!ns)
+        return NULL;
+    return js_GetXMLNamespaceObject(cx, ns);
+}
+
+JSObject *
+js_GetXMLNamespaceObject(JSContext *cx, JSXMLNamespace *ns)
+{
+    JSObject *obj;
+
+    obj = ns->object;
+    if (obj) {
+        JS_ASSERT(JS_GetPrivate(cx, obj) == ns);
+        return obj;
+    }
+    obj = js_NewObject(cx, &js_NamespaceClass.base, NULL, NULL);
+    if (!obj || !JS_SetPrivate(cx, obj, ns)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+    ns->object = obj;
+    METER(xml_stats.namespaceobj);
+    METER(xml_stats.livenamespaceobj);
+    return obj;
+}
+
+/*
+ * QName class and library functions.
+ */
+enum qname_tinyid {
+    QNAME_URI = -1,
+    QNAME_LOCALNAME = -2
+};
+
+static JSBool
+qname_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSXMLQName *qn;
+
+    if (!JSVAL_IS_INT(id))
+        return JS_TRUE;
+
+    qn = (JSXMLQName *)
+         JS_GetInstancePrivate(cx, obj, &js_QNameClass.base, NULL);
+    if (!qn)
+        return JS_TRUE;
+
+    switch (JSVAL_TO_INT(id)) {
+      case QNAME_URI:
+        *vp = qn->uri ? STRING_TO_JSVAL(qn->uri) : JSVAL_NULL;
+        break;
+      case QNAME_LOCALNAME:
+        *vp = STRING_TO_JSVAL(qn->localName);
+        break;
+    }
+    return JS_TRUE;
+}
+
+static void
+qname_finalize(JSContext *cx, JSObject *obj)
+{
+    JSXMLQName *qn;
+
+    qn = (JSXMLQName *) JS_GetPrivate(cx, obj);
+    if (!qn)
+        return;
+    JS_ASSERT(qn->object == obj);
+    qn->object = NULL;
+    UNMETER(xml_stats.liveqnameobj);
+}
+
+static void
+anyname_finalize(JSContext* cx, JSObject* obj)
+{
+    JSRuntime *rt;
+
+    /* Make sure the next call to js_GetAnyName doesn't try to use obj. */
+    rt = cx->runtime;
+    if (rt->anynameObject == obj)
+        rt->anynameObject = NULL;
+
+    qname_finalize(cx, obj);
+}
+
+static uint32
+qname_mark(JSContext *cx, JSObject *obj, void *arg)
+{
+    JSXMLQName *qn;
+
+    qn = (JSXMLQName *) JS_GetPrivate(cx, obj);
+    JS_MarkGCThing(cx, qn, js_private_str, arg);
+    return 0;
+}
+
+static JSBool
+qname_identity(JSXMLQName *qna, JSXMLQName *qnb)
+{
+    if (!qna->uri ^ !qnb->uri)
+        return JS_FALSE;
+    if (qna->uri && js_CompareStrings(qna->uri, qnb->uri))
+        return JS_FALSE;
+    return !js_CompareStrings(qna->localName, qnb->localName);
+}
+
+static JSBool
+qname_equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
+{
+    JSXMLQName *qn, *qn2;
+    JSObject *obj2;
+
+    qn = (JSXMLQName *) JS_GetPrivate(cx, obj);
+    JS_ASSERT(JSVAL_IS_OBJECT(v));
+    obj2 = JSVAL_TO_OBJECT(v);
+    if (!obj2 || OBJ_GET_CLASS(cx, obj2) != &js_QNameClass.base) {
+        *bp = JS_FALSE;
+    } else {
+        qn2 = (JSXMLQName *) JS_GetPrivate(cx, obj2);
+        *bp = qname_identity(qn, qn2);
+    }
+    return JS_TRUE;
+}
+
+JS_FRIEND_DATA(JSExtendedClass) js_QNameClass = {
+  { "QName",
+    JSCLASS_HAS_PRIVATE | JSCLASS_CONSTRUCT_PROTOTYPE | JSCLASS_IS_EXTENDED,
+    JS_PropertyStub,   JS_PropertyStub,   qname_getProperty, NULL,
+    JS_EnumerateStub,  JS_ResolveStub,    JS_ConvertStub,    qname_finalize,
+    NULL,              NULL,              NULL,              NULL,
+    NULL,              NULL,              qname_mark,        NULL },
+    qname_equality,
+    NULL, NULL,
+    JSCLASS_NO_RESERVED_MEMBERS
+};
+
+/*
+ * Classes for the ECMA-357-internal types AttributeName and AnyName, which
+ * are like QName, except that they have no property getters.  They share the
+ * qname_toString method, and therefore are exposed as constructable objects
+ * in this implementation.
+ */
+JS_FRIEND_DATA(JSClass) js_AttributeNameClass = {
+    js_AttributeName_str, JSCLASS_HAS_PRIVATE | JSCLASS_CONSTRUCT_PROTOTYPE,
+    JS_PropertyStub,   JS_PropertyStub,   JS_PropertyStub,   JS_PropertyStub,
+    JS_EnumerateStub,  JS_ResolveStub,    JS_ConvertStub,    qname_finalize,
+    NULL,              NULL,              NULL,              NULL,
+    NULL,              NULL,              qname_mark,        NULL
+};
+
+JS_FRIEND_DATA(JSClass) js_AnyNameClass = {
+    js_AnyName_str,    JSCLASS_HAS_PRIVATE | JSCLASS_CONSTRUCT_PROTOTYPE,
+    JS_PropertyStub,   JS_PropertyStub,   JS_PropertyStub,   JS_PropertyStub,
+    JS_EnumerateStub,  JS_ResolveStub,    JS_ConvertStub,    anyname_finalize,
+    NULL,              NULL,              NULL,              NULL,
+    NULL,              NULL,              qname_mark,        NULL
+};
+
+#define QNAME_ATTRS                                                           \
+    (JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED)
+
+static JSPropertySpec qname_props[] = {
+    {js_uri_str,       QNAME_URI,         QNAME_ATTRS,       0, 0},
+    {js_localName_str, QNAME_LOCALNAME,   QNAME_ATTRS,       0, 0},
+    {0,0,0,0,0}
+};
+
+static JSBool
+qname_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    JSClass *clasp;
+    JSXMLQName *qn;
+    JSString *str, *qualstr;
+    size_t length;
+    jschar *chars;
+
+    clasp = OBJ_GET_CLASS(cx, obj);
+    if (clasp == &js_AttributeNameClass || clasp == &js_AnyNameClass) {
+        qn = (JSXMLQName *) JS_GetPrivate(cx, obj);
+    } else {
+        qn = (JSXMLQName *)
+             JS_GetInstancePrivate(cx, obj, &js_QNameClass.base, argv);
+        if (!qn)
+            return JS_FALSE;
+    }
+
+    if (!qn->uri) {
+        /* No uri means wildcard qualifier. */
+        str = ATOM_TO_STRING(cx->runtime->atomState.starQualifierAtom);
+    } else if (IS_EMPTY(qn->uri)) {
+        /* Empty string for uri means localName is in no namespace. */
+        str = cx->runtime->emptyString;
+    } else {
+        qualstr = ATOM_TO_STRING(cx->runtime->atomState.qualifierAtom);
+        str = js_ConcatStrings(cx, qn->uri, qualstr);
+        if (!str)
+            return JS_FALSE;
+    }
+    str = js_ConcatStrings(cx, str, qn->localName);
+    if (!str)
+        return JS_FALSE;
+
+    if (str && clasp == &js_AttributeNameClass) {
+        length = JSSTRING_LENGTH(str);
+        chars = (jschar *) JS_malloc(cx, (length + 2) * sizeof(jschar));
+        if (!chars)
+            return JS_FALSE;
+        *chars = '@';
+        js_strncpy(chars + 1, JSSTRING_CHARS(str), length);
+        chars[++length] = 0;
+        str = js_NewString(cx, chars, length, 0);
+        if (!str) {
+            JS_free(cx, chars);
+            return JS_FALSE;
+        }
+    }
+
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSFunctionSpec qname_methods[] = {
+    {js_toString_str,  qname_toString,    0,0,0},
+    {0,0,0,0,0}
+};
+
+JSXMLQName *
+js_NewXMLQName(JSContext *cx, JSString *uri, JSString *prefix,
+               JSString *localName)
+{
+    JSXMLQName *qn;
+
+    qn = (JSXMLQName *) js_NewGCThing(cx, GCX_QNAME, sizeof(JSXMLQName));
+    if (!qn)
+        return NULL;
+    qn->object = NULL;
+    qn->uri = uri;
+    qn->prefix = prefix;
+    qn->localName = localName;
+    METER(xml_stats.qname);
+    METER(xml_stats.liveqname);
+    return qn;
+}
+
+void
+js_MarkXMLQName(JSContext *cx, JSXMLQName *qn, void *arg)
+{
+    JS_MarkGCThing(cx, qn->object, js_object_str, arg);
+    JS_MarkGCThing(cx, qn->uri, js_uri_str, arg);
+    JS_MarkGCThing(cx, qn->prefix, js_prefix_str, arg);
+    JS_MarkGCThing(cx, qn->localName, js_localName_str, arg);
+}
+
+void
+js_FinalizeXMLQName(JSContext *cx, JSXMLQName *qn)
+{
+    UNMETER(xml_stats.liveqname);
+}
+
+JSObject *
+js_NewXMLQNameObject(JSContext *cx, JSString *uri, JSString *prefix,
+                     JSString *localName)
+{
+    JSXMLQName *qn;
+
+    qn = js_NewXMLQName(cx, uri, prefix, localName);
+    if (!qn)
+        return NULL;
+    return js_GetXMLQNameObject(cx, qn);
+}
+
+JSObject *
+js_GetXMLQNameObject(JSContext *cx, JSXMLQName *qn)
+{
+    JSObject *obj;
+
+    obj = qn->object;
+    if (obj) {
+        JS_ASSERT(JS_GetPrivate(cx, obj) == qn);
+        return obj;
+    }
+    obj = js_NewObject(cx, &js_QNameClass.base, NULL, NULL);
+    if (!obj || !JS_SetPrivate(cx, obj, qn)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+    qn->object = obj;
+    METER(xml_stats.qnameobj);
+    METER(xml_stats.liveqnameobj);
+    return obj;
+}
+
+JSObject *
+js_GetAttributeNameObject(JSContext *cx, JSXMLQName *qn)
+{
+    JSObject *obj;
+
+    obj = qn->object;
+    if (obj) {
+        if (OBJ_GET_CLASS(cx, obj) == &js_AttributeNameClass)
+            return obj;
+        qn = js_NewXMLQName(cx, qn->uri, qn->prefix, qn->localName);
+        if (!qn)
+            return NULL;
+    }
+
+    obj = js_NewObject(cx, &js_AttributeNameClass, NULL, NULL);
+    if (!obj || !JS_SetPrivate(cx, obj, qn)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+
+    qn->object = obj;
+    METER(xml_stats.qnameobj);
+    METER(xml_stats.liveqnameobj);
+    return obj;
+}
+
+JSObject *
+js_ConstructXMLQNameObject(JSContext *cx, jsval nsval, jsval lnval)
+{
+    jsval argv[2];
+
+    /*
+     * ECMA-357 11.1.2,
+     * The _QualifiedIdentifier : PropertySelector :: PropertySelector_
+     * production, step 2.
+     */
+    if (!JSVAL_IS_PRIMITIVE(nsval) &&
+        OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(nsval)) == &js_AnyNameClass) {
+        nsval = JSVAL_NULL;
+    }
+
+    argv[0] = nsval;
+    argv[1] = lnval;
+    return js_ConstructObject(cx, &js_QNameClass.base, NULL, NULL, 2, argv);
+}
+
+static JSBool
+IsXMLName(const jschar *cp, size_t n)
+{
+    JSBool rv;
+    jschar c;
+
+    rv = JS_FALSE;
+    if (n != 0 && JS_ISXMLNSSTART(*cp)) {
+        while (--n != 0) {
+            c = *++cp;
+            if (!JS_ISXMLNS(c))
+                return rv;
+        }
+        rv = JS_TRUE;
+    }
+    return rv;
+}
+
+JSBool
+js_IsXMLName(JSContext *cx, jsval v)
+{
+    JSClass *clasp;
+    JSXMLQName *qn;
+    JSString *name;
+    JSErrorReporter older;
+
+    /*
+     * Inline specialization of the QName constructor called with v passed as
+     * the only argument, to compute the localName for the constructed qname,
+     * without actually allocating the object or computing its uri and prefix.
+     * See ECMA-357 13.1.2.1 step 1 and 13.3.2.
+     */
+    if (!JSVAL_IS_PRIMITIVE(v) &&
+        (clasp = OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)),
+         clasp == &js_QNameClass.base ||
+         clasp == &js_AttributeNameClass ||
+         clasp == &js_AnyNameClass)) {
+        qn = (JSXMLQName *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v));
+        name = qn->localName;
+    } else {
+        older = JS_SetErrorReporter(cx, NULL);
+        name = js_ValueToString(cx, v);
+        JS_SetErrorReporter(cx, older);
+        if (!name) {
+            JS_ClearPendingException(cx);
+            return JS_FALSE;
+        }
+    }
+
+    return IsXMLName(JSSTRING_CHARS(name), JSSTRING_LENGTH(name));
+}
+
+static JSBool
+Namespace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval urival, prefixval;
+    JSObject *uriobj;
+    JSBool isNamespace, isQName;
+    JSClass *clasp;
+    JSString *empty, *prefix;
+    JSXMLNamespace *ns, *ns2;
+    JSXMLQName *qn;
+
+    urival = argv[argc > 1];
+    isNamespace = isQName = JS_FALSE;
+    if (!JSVAL_IS_PRIMITIVE(urival)) {
+        uriobj = JSVAL_TO_OBJECT(urival);
+        clasp = OBJ_GET_CLASS(cx, uriobj);
+        isNamespace = (clasp == &js_NamespaceClass.base);
+        isQName = (clasp == &js_QNameClass.base);
+    }
+#ifdef __GNUC__         /* suppress bogus gcc warnings */
+    else uriobj = NULL;
+#endif
+
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        /* Namespace called as function. */
+        if (argc == 1 && isNamespace) {
+            /* Namespace called with one Namespace argument is identity. */
+            *rval = urival;
+            return JS_TRUE;
+        }
+
+        /* Create and return a new QName object exactly as if constructed. */
+        obj = js_NewObject(cx, &js_NamespaceClass.base, NULL, NULL);
+        if (!obj)
+            return JS_FALSE;
+        *rval = OBJECT_TO_JSVAL(obj);
+    }
+    METER(xml_stats.namespaceobj);
+    METER(xml_stats.livenamespaceobj);
+
+    /*
+     * Create and connect private data to rooted obj early, so we don't have
+     * to worry about rooting string newborns hanging off of the private data
+     * further below.
+     */
+    empty = cx->runtime->emptyString;
+    ns = js_NewXMLNamespace(cx, empty, empty, JS_FALSE);
+    if (!ns)
+        return JS_FALSE;
+    if (!JS_SetPrivate(cx, obj, ns))
+        return JS_FALSE;
+    ns->object = obj;
+
+    if (argc == 1) {
+        if (isNamespace) {
+            ns2 = (JSXMLNamespace *) JS_GetPrivate(cx, uriobj);
+            ns->uri = ns2->uri;
+            ns->prefix = ns2->prefix;
+        } else if (isQName &&
+                   (qn = (JSXMLQName *) JS_GetPrivate(cx, uriobj))->uri) {
+            ns->uri = qn->uri;
+            ns->prefix = qn->prefix;
+        } else {
+            ns->uri = js_ValueToString(cx, urival);
+            if (!ns->uri)
+                return JS_FALSE;
+
+            /* NULL here represents *undefined* in ECMA-357 13.2.2 3(c)iii. */
+            if (!IS_EMPTY(ns->uri))
+                ns->prefix = NULL;
+        }
+    } else if (argc == 2) {
+        if (isQName &&
+            (qn = (JSXMLQName *) JS_GetPrivate(cx, uriobj))->uri) {
+            ns->uri = qn->uri;
+        } else {
+            ns->uri = js_ValueToString(cx, urival);
+            if (!ns->uri)
+                return JS_FALSE;
+        }
+
+        prefixval = argv[0];
+        if (IS_EMPTY(ns->uri)) {
+            if (!JSVAL_IS_VOID(prefixval)) {
+                prefix = js_ValueToString(cx, prefixval);
+                if (!prefix)
+                    return JS_FALSE;
+                if (!IS_EMPTY(prefix)) {
+                    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                         JSMSG_BAD_XML_NAMESPACE,
+                                         js_ValueToPrintableString(cx,
+                                             STRING_TO_JSVAL(prefix)));
+                    return JS_FALSE;
+                }
+            }
+        } else if (JSVAL_IS_VOID(prefixval) || !js_IsXMLName(cx, prefixval)) {
+            /* NULL here represents *undefined* in ECMA-357 13.2.2 4(d) etc. */
+            ns->prefix = NULL;
+        } else {
+            prefix = js_ValueToString(cx, prefixval);
+            if (!prefix)
+                return JS_FALSE;
+            ns->prefix = prefix;
+        }
+    }
+
+    return JS_TRUE;
+}
+
+static JSBool
+QName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval nameval, nsval;
+    JSBool isQName, isNamespace;
+    JSXMLQName *qn;
+    JSString *uri, *prefix, *name;
+    JSObject *nsobj;
+    JSClass *clasp;
+    JSXMLNamespace *ns;
+
+    nameval = argv[argc > 1];
+    isQName =
+        !JSVAL_IS_PRIMITIVE(nameval) &&
+        OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(nameval)) == &js_QNameClass.base;
+
+    if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
+        /* QName called as function. */
+        if (argc == 1 && isQName) {
+            /* QName called with one QName argument is identity. */
+            *rval = nameval;
+            return JS_TRUE;
+        }
+
+        /*
+         * Create and return a new QName object exactly as if constructed.
+         * Use the constructor's clasp so we can be shared by AttributeName
+         * (see below after this function).
+         */
+        obj = js_NewObject(cx,
+                           argv
+                           ? JS_ValueToFunction(cx, argv[-2])->clasp
+                           : &js_QNameClass.base,
+                           NULL, NULL);
+        if (!obj)
+            return JS_FALSE;
+        *rval = OBJECT_TO_JSVAL(obj);
+    }
+    METER(xml_stats.qnameobj);
+    METER(xml_stats.liveqnameobj);
+
+    if (isQName) {
+        /* If namespace is not specified and name is a QName, clone it. */
+        qn = (JSXMLQName *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(nameval));
+        if (argc == 1) {
+            uri = qn->uri;
+            prefix = qn->prefix;
+            name = qn->localName;
+            goto out;
+        }
+
+        /* Namespace and qname were passed -- use the qname's localName. */
+        nameval = STRING_TO_JSVAL(qn->localName);
+    }
+
+    if (argc == 0) {
+        name = cx->runtime->emptyString;
+    } else {
+        name = js_ValueToString(cx, nameval);
+        if (!name)
+            return JS_FALSE;
+
+        /* Use argv[1] as a local root for name, even if it was not passed. */
+        argv[1] = STRING_TO_JSVAL(name);
+    }
+
+    nsval = argv[0];
+    if (argc == 1 || JSVAL_IS_VOID(nsval)) {
+        if (IS_STAR(name)) {
+            nsval = JSVAL_NULL;
+        } else {
+            if (!js_GetDefaultXMLNamespace(cx, &nsval))
+                return JS_FALSE;
+        }
+    }
+
+    if (JSVAL_IS_NULL(nsval)) {
+        /* NULL prefix represents *undefined* in ECMA-357 13.3.2 5(a). */
+        uri = prefix = NULL;
+    } else {
+        /*
+         * Inline specialization of the Namespace constructor called with
+         * nsval passed as the only argument, to compute the uri and prefix
+         * for the constructed namespace, without actually allocating the
+         * object or computing other members.  See ECMA-357 13.3.2 6(a) and
+         * 13.2.2.
+         */
+        isNamespace = isQName = JS_FALSE;
+        if (!JSVAL_IS_PRIMITIVE(nsval)) {
+            nsobj = JSVAL_TO_OBJECT(nsval);
+            clasp = OBJ_GET_CLASS(cx, nsobj);
+            isNamespace = (clasp == &js_NamespaceClass.base);
+            isQName = (clasp == &js_QNameClass.base);
+        }
+#ifdef __GNUC__         /* suppress bogus gcc warnings */
+        else nsobj = NULL;
+#endif
+
+        if (isNamespace) {
+            ns = (JSXMLNamespace *) JS_GetPrivate(cx, nsobj);
+            uri = ns->uri;
+            prefix = ns->prefix;
+        } else if (isQName &&
+                   (qn = (JSXMLQName *) JS_GetPrivate(cx, nsobj))->uri) {
+            uri = qn->uri;
+            prefix = qn->prefix;
+        } else {
+            uri = js_ValueToString(cx, nsval);
+            if (!uri)
+                return JS_FALSE;
+            argv[0] = STRING_TO_JSVAL(uri);     /* local root */
+
+            /* NULL here represents *undefined* in ECMA-357 13.2.2 3(c)iii. */
+            prefix = IS_EMPTY(uri) ? cx->runtime->emptyString : NULL;
+        }
+    }
+
+out:
+    qn = js_NewXMLQName(cx, uri, prefix, name);
+    if (!qn)
+        return JS_FALSE;
+    if (!JS_SetPrivate(cx, obj, qn))
+        return JS_FALSE;
+    qn->object = obj;
+    return JS_TRUE;
+}
+
+static JSBool
+AttributeName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    /*
+     * Since js_AttributeNameClass was initialized, obj will have that as its
+     * class, not js_QNameClass.
+     */
+    return QName(cx, obj, argc, argv, rval);
+}
+
+/*
+ * XMLArray library functions.
+ */
+static JSBool
+namespace_identity(const void *a, const void *b)
+{
+    const JSXMLNamespace *nsa = (const JSXMLNamespace *) a;
+    const JSXMLNamespace *nsb = (const JSXMLNamespace *) b;
+
+    if (nsa->prefix && nsb->prefix) {
+        if (js_CompareStrings(nsa->prefix, nsb->prefix))
+            return JS_FALSE;
+    } else {
+        if (nsa->prefix || nsb->prefix)
+            return JS_FALSE;
+    }
+    return !js_CompareStrings(nsa->uri, nsb->uri);
+}
+
+static JSBool
+attr_identity(const void *a, const void *b)
+{
+    const JSXML *xmla = (const JSXML *) a;
+    const JSXML *xmlb = (const JSXML *) b;
+
+    return qname_identity(xmla->name, xmlb->name);
+}
+
+static void
+XMLArrayCursorInit(JSXMLArrayCursor *cursor, JSXMLArray *array)
+{
+    JSXMLArrayCursor *next;
+
+    cursor->array = array;
+    cursor->index = 0;
+    next = cursor->next = array->cursors;
+    if (next)
+        next->prevp = &cursor->next;
+    cursor->prevp = &array->cursors;
+    array->cursors = cursor;
+}
+
+static void
+XMLArrayCursorFinish(JSXMLArrayCursor *cursor)
+{
+    JSXMLArrayCursor *next;
+
+    if (!cursor->array)
+        return;
+    next = cursor->next;
+    if (next)
+        next->prevp = cursor->prevp;
+    *cursor->prevp = next;
+    cursor->array = NULL;
+}
+
+/* NB: called with null cx from the GC, via xml_mark => XMLArrayTrim. */
+static JSBool
+XMLArraySetCapacity(JSContext *cx, JSXMLArray *array, uint32 capacity)
+{
+    void **vector;
+
+    if (capacity == 0) {
+        /* We could let realloc(p, 0) free this, but purify gets confused. */
+        if (array->vector)
+            free(array->vector);
+        vector = NULL;
+    } else {
+        if ((size_t)capacity > ~(size_t)0 / sizeof(void *) ||
+            !(vector = (void **)
+                       realloc(array->vector, capacity * sizeof(void *)))) {
+            if (cx)
+                JS_ReportOutOfMemory(cx);
+            return JS_FALSE;
+        }
+    }
+    array->capacity = JSXML_PRESET_CAPACITY | capacity;
+    array->vector = vector;
+    return JS_TRUE;
+}
+
+static void
+XMLArrayTrim(JSXMLArray *array)
+{
+    if (array->capacity & JSXML_PRESET_CAPACITY)
+        return;
+    if (array->length < array->capacity)
+        XMLArraySetCapacity(NULL, array, array->length);
+}
+
+static JSBool
+XMLArrayInit(JSContext *cx, JSXMLArray *array, uint32 capacity)
+{
+    array->length = array->capacity = 0;
+    array->vector = NULL;
+    array->cursors = NULL;
+    return capacity == 0 || XMLArraySetCapacity(cx, array, capacity);
+}
+
+static void
+XMLArrayFinish(JSContext *cx, JSXMLArray *array)
+{
+    JSXMLArrayCursor *cursor;
+
+    JS_free(cx, array->vector);
+
+    while ((cursor = array->cursors) != NULL)
+        XMLArrayCursorFinish(cursor);
+
+#ifdef DEBUG
+    memset(array, 0xd5, sizeof *array);
+#endif
+}
+
+#define XML_NOT_FOUND   ((uint32) -1)
+
+static uint32
+XMLArrayFindMember(const JSXMLArray *array, void *elt, JSIdentityOp identity)
+{
+    void **vector;
+    uint32 i, n;
+
+    /* The identity op must not reallocate array->vector. */
+    vector = array->vector;
+    if (identity) {
+        for (i = 0, n = array->length; i < n; i++) {
+            if (identity(vector[i], elt))
+                return i;
+        }
+    } else {
+        for (i = 0, n = array->length; i < n; i++) {
+            if (vector[i] == elt)
+                return i;
+        }
+    }
+    return XML_NOT_FOUND;
+}
+
+/*
+ * Grow array vector capacity by powers of two to LINEAR_THRESHOLD, and after
+ * that, grow by LINEAR_INCREMENT.  Both must be powers of two, and threshold
+ * should be greater than increment.
+ */
+#define LINEAR_THRESHOLD        256
+#define LINEAR_INCREMENT        32
+
+static JSBool
+XMLArrayAddMember(JSContext *cx, JSXMLArray *array, uint32 index, void *elt)
+{
+    uint32 capacity, i;
+    int log2;
+    void **vector;
+
+    if (index >= array->length) {
+        if (index >= JSXML_CAPACITY(array)) {
+            /* Arrange to clear JSXML_PRESET_CAPACITY from array->capacity. */
+            capacity = index + 1;
+            if (index >= LINEAR_THRESHOLD) {
+                capacity = JS_ROUNDUP(capacity, LINEAR_INCREMENT);
+            } else {
+                JS_CEILING_LOG2(log2, capacity);
+                capacity = JS_BIT(log2);
+            }
+            if ((size_t)capacity > ~(size_t)0 / sizeof(void *) ||
+                !(vector = (void **)
+                           realloc(array->vector, capacity * sizeof(void *)))) {
+                JS_ReportOutOfMemory(cx);
+                return JS_FALSE;
+            }
+            array->capacity = capacity;
+            array->vector = vector;
+            for (i = array->length; i < index; i++)
+                vector[i] = NULL;
+        }
+        array->length = index + 1;
+    }
+
+    array->vector[index] = elt;
+    return JS_TRUE;
+}
+
+static JSBool
+XMLArrayInsert(JSContext *cx, JSXMLArray *array, uint32 i, uint32 n)
+{
+    uint32 j;
+    JSXMLArrayCursor *cursor;
+
+    j = array->length;
+    JS_ASSERT(i <= j);
+    if (!XMLArraySetCapacity(cx, array, j + n))
+        return JS_FALSE;
+
+    array->length = j + n;
+    JS_ASSERT(n != (uint32)-1);
+    while (j != i) {
+        --j;
+        array->vector[j + n] = array->vector[j];
+    }
+
+    for (cursor = array->cursors; cursor; cursor = cursor->next) {
+        if (cursor->index > i)
+            cursor->index += n;
+    }
+    return JS_TRUE;
+}
+
+static void *
+XMLArrayDelete(JSContext *cx, JSXMLArray *array, uint32 index, JSBool compress)
+{
+    uint32 length;
+    void **vector, *elt;
+    JSXMLArrayCursor *cursor;
+
+    length = array->length;
+    if (index >= length)
+        return NULL;
+
+    vector = array->vector;
+    elt = vector[index];
+    if (compress) {
+        while (++index < length)
+            vector[index-1] = vector[index];
+        array->length = length - 1;
+        array->capacity = JSXML_CAPACITY(array);
+    } else {
+        vector[index] = NULL;
+    }
+
+    for (cursor = array->cursors; cursor; cursor = cursor->next) {
+        if (cursor->index > index)
+            --cursor->index;
+    }
+    return elt;
+}
+
+static void
+XMLArrayTruncate(JSContext *cx, JSXMLArray *array, uint32 length)
+{
+    void **vector;
+
+    JS_ASSERT(!array->cursors);
+    if (length >= array->length)
+        return;
+
+    if (length == 0) {
+        if (array->vector)
+            free(array->vector);
+        vector = NULL;
+    } else {
+        vector = realloc(array->vector, length * sizeof(void *));
+        if (!vector)
+            return;
+    }
+
+    if (array->length > length)
+        array->length = length;
+    array->capacity = length;
+    array->vector = vector;
+}
+
+#define XMLARRAY_FIND_MEMBER(a,e,f) XMLArrayFindMember(a, (void *)(e), f)
+#define XMLARRAY_HAS_MEMBER(a,e,f)  (XMLArrayFindMember(a, (void *)(e), f) != \
+                                     XML_NOT_FOUND)
+#define XMLARRAY_MEMBER(a,i,t)      ((t *) (a)->vector[i])
+#define XMLARRAY_SET_MEMBER(a,i,e)  ((a)->vector[i] = (void *)(e))
+#define XMLARRAY_ADD_MEMBER(x,a,i,e)XMLArrayAddMember(x, a, i, (void *)(e))
+#define XMLARRAY_INSERT(x,a,i,n)    XMLArrayInsert(x, a, i, n)
+#define XMLARRAY_APPEND(x,a,e)      XMLARRAY_ADD_MEMBER(x, a, (a)->length, (e))
+#define XMLARRAY_DELETE(x,a,i,c,t)  ((t *) XMLArrayDelete(x, a, i, c))
+#define XMLARRAY_TRUNCATE(x,a,n)    XMLArrayTruncate(x, a, n)
+
+/*
+ * Define XML setting property strings and constants early, so everyone can
+ * use the same names and their magic numbers (tinyids, flags).
+ */
+static const char js_ignoreComments_str[]   = "ignoreComments";
+static const char js_ignoreProcessingInstructions_str[]
+                                            = "ignoreProcessingInstructions";
+static const char js_ignoreWhitespace_str[] = "ignoreWhitespace";
+static const char js_prettyPrinting_str[]   = "prettyPrinting";
+static const char js_prettyIndent_str[]     = "prettyIndent";
+
+/*
+ * NB: These XML static property tinyids must
+ * (a) not collide with the generic negative tinyids at the top of jsfun.c;
+ * (b) index their corresponding xml_static_props array elements.
+ * Don't change 'em!
+ */
+enum xml_static_tinyid {
+    XML_IGNORE_COMMENTS,
+    XML_IGNORE_PROCESSING_INSTRUCTIONS,
+    XML_IGNORE_WHITESPACE,
+    XML_PRETTY_PRINTING,
+    XML_PRETTY_INDENT
+};
+
+static JSBool
+xml_setting_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSBool b;
+    uint8 flag;
+
+    JS_ASSERT(JSVAL_IS_INT(id));
+    if (!js_ValueToBoolean(cx, *vp, &b))
+        return JS_FALSE;
+
+    flag = JS_BIT(JSVAL_TO_INT(id));
+    if (b)
+        cx->xmlSettingFlags |= flag;
+    else
+        cx->xmlSettingFlags &= ~flag;
+    return JS_TRUE;
+}
+
+static JSPropertySpec xml_static_props[] = {
+    {js_ignoreComments_str,     XML_IGNORE_COMMENTS,   JSPROP_PERMANENT,
+                                NULL, xml_setting_setter},
+    {js_ignoreProcessingInstructions_str,
+                   XML_IGNORE_PROCESSING_INSTRUCTIONS, JSPROP_PERMANENT,
+                                NULL, xml_setting_setter},
+    {js_ignoreWhitespace_str,   XML_IGNORE_WHITESPACE, JSPROP_PERMANENT,
+                                NULL, xml_setting_setter},
+    {js_prettyPrinting_str,     XML_PRETTY_PRINTING,   JSPROP_PERMANENT,
+                                NULL, xml_setting_setter},
+    {js_prettyIndent_str,       XML_PRETTY_INDENT,     JSPROP_PERMANENT,
+                                NULL, NULL},
+    {0,0,0,0,0}
+};
+
+/* Derive cx->xmlSettingFlags bits from xml_static_props tinyids. */
+#define XSF_IGNORE_COMMENTS     JS_BIT(XML_IGNORE_COMMENTS)
+#define XSF_IGNORE_PROCESSING_INSTRUCTIONS                                    \
+                                JS_BIT(XML_IGNORE_PROCESSING_INSTRUCTIONS)
+#define XSF_IGNORE_WHITESPACE   JS_BIT(XML_IGNORE_WHITESPACE)
+#define XSF_PRETTY_PRINTING     JS_BIT(XML_PRETTY_PRINTING)
+#define XSF_CACHE_VALID         JS_BIT(XML_PRETTY_INDENT)
+
+/*
+ * Extra, unrelated but necessarily disjoint flag used by ParseNodeToXML.
+ * This flag means a couple of things:
+ *
+ * - The top JSXML created for a parse tree must have an object owning it.
+ *
+ * - That the default namespace normally inherited from the temporary
+ *   <parent xmlns='...'> tag that wraps a runtime-concatenated XML source
+ *   string must, in the case of a precompiled XML object tree, inherit via
+ *   ad-hoc code in ParseNodeToXML.
+ *
+ * Because of the second purpose, we name this flag XSF_PRECOMPILED_ROOT.
+ */
+#define XSF_PRECOMPILED_ROOT    (XSF_CACHE_VALID << 1)
+
+/* Macros for special-casing xml:, xmlns= and xmlns:foo= in ParseNodeToQName. */
+#define IS_XML(str)                                                           \
+    (JSSTRING_LENGTH(str) == 3 && IS_XML_CHARS(JSSTRING_CHARS(str)))
+
+#define IS_XMLNS(str)                                                         \
+    (JSSTRING_LENGTH(str) == 5 && IS_XMLNS_CHARS(JSSTRING_CHARS(str)))
+
+#define IS_XML_CHARS(chars)                                                   \
+    (JS_TOLOWER((chars)[0]) == 'x' &&                                         \
+     JS_TOLOWER((chars)[1]) == 'm' &&                                         \
+     JS_TOLOWER((chars)[2]) == 'l')
+
+#define HAS_NS_AFTER_XML(chars)                                               \
+    (JS_TOLOWER((chars)[3]) == 'n' &&                                         \
+     JS_TOLOWER((chars)[4]) == 's')
+
+#define IS_XMLNS_CHARS(chars)                                                 \
+    (IS_XML_CHARS(chars) && HAS_NS_AFTER_XML(chars))
+
+#define STARTS_WITH_XML(chars,length)                                         \
+    (length >= 3 && IS_XML_CHARS(chars))
+
+static const char xml_namespace_str[] = "http://www.w3.org/XML/1998/namespace";
+static const char xmlns_namespace_str[] = "http://www.w3.org/2000/xmlns/";
+
+static JSXMLQName *
+ParseNodeToQName(JSContext *cx, JSParseNode *pn, JSXMLArray *inScopeNSes,
+                 JSBool isAttributeName)
+{
+    JSString *str, *uri, *prefix, *localName;
+    size_t length, offset;
+    const jschar *start, *limit, *colon;
+    uint32 n;
+    JSXMLNamespace *ns;
+
+    JS_ASSERT(pn->pn_arity == PN_NULLARY);
+    str = ATOM_TO_STRING(pn->pn_atom);
+    length = JSSTRING_LENGTH(str);
+    start = JSSTRING_CHARS(str);
+    JS_ASSERT(length != 0 && *start != '@');
+    JS_ASSERT(length != 1 || *start != '*');
+
+    uri = cx->runtime->emptyString;
+    limit = start + length;
+    colon = js_strchr_limit(start, ':', limit);
+    if (colon) {
+        offset = PTRDIFF(colon, start, jschar);
+        prefix = js_NewDependentString(cx, str, 0, offset, 0);
+        if (!prefix)
+            return NULL;
+
+        if (STARTS_WITH_XML(start, offset)) {
+            if (offset == 3) {
+                uri = JS_InternString(cx, xml_namespace_str);
+                if (!uri)
+                    return NULL;
+            } else if (offset == 5 && HAS_NS_AFTER_XML(start)) {
+                uri = JS_InternString(cx, xmlns_namespace_str);
+                if (!uri)
+                    return NULL;
+            } else {
+                uri = NULL;
+            }
+        } else {
+            uri = NULL;
+            n = inScopeNSes->length;
+            while (n != 0) {
+                ns = XMLARRAY_MEMBER(inScopeNSes, --n, JSXMLNamespace);
+                if (ns->prefix && !js_CompareStrings(ns->prefix, prefix)) {
+                    uri = ns->uri;
+                    break;
+                }
+            }
+        }
+
+        if (!uri) {
+            js_ReportCompileErrorNumber(cx, pn,
+                                        JSREPORT_PN | JSREPORT_ERROR,
+                                        JSMSG_BAD_XML_NAMESPACE,
+                                        js_ValueToPrintableString(cx,
+                                            STRING_TO_JSVAL(prefix)));
+            return NULL;
+        }
+
+        localName = js_NewStringCopyN(cx, colon + 1, length - (offset + 1), 0);
+        if (!localName)
+            return NULL;
+    } else {
+        if (isAttributeName) {
+            /*
+             * An unprefixed attribute is not in any namespace, so set prefix
+             * as well as uri to the empty string.
+             */
+            prefix = uri;
+        } else {
+            /*
+             * Loop from back to front looking for the closest declared default
+             * namespace.
+             */
+            n = inScopeNSes->length;
+            while (n != 0) {
+                ns = XMLARRAY_MEMBER(inScopeNSes, --n, JSXMLNamespace);
+                if (!ns->prefix || IS_EMPTY(ns->prefix)) {
+                    uri = ns->uri;
+                    break;
+                }
+            }
+            prefix = NULL;
+        }
+        localName = str;
+    }
+
+    return js_NewXMLQName(cx, uri, prefix, localName);
+}
+
+static JSString *
+ChompXMLWhitespace(JSContext *cx, JSString *str)
+{
+    size_t length, newlength, offset;
+    const jschar *cp, *start, *end;
+    jschar c;
+
+    length = JSSTRING_LENGTH(str);
+    for (cp = start = JSSTRING_CHARS(str), end = cp + length; cp < end; cp++) {
+        c = *cp;
+        if (!JS_ISXMLSPACE(c))
+            break;
+    }
+    while (end > cp) {
+        c = end[-1];
+        if (!JS_ISXMLSPACE(c))
+            break;
+        --end;
+    }
+    newlength = PTRDIFF(end, cp, jschar);
+    if (newlength == length)
+        return str;
+    offset = PTRDIFF(cp, start, jschar);
+    return js_NewDependentString(cx, str, offset, newlength, 0);
+}
+
+static JSXML *
+ParseNodeToXML(JSContext *cx, JSParseNode *pn, JSXMLArray *inScopeNSes,
+               uintN flags)
+{
+    JSXML *xml, *kid, *attr, *attrj;
+    JSString *str;
+    uint32 length, n, i, j;
+    JSParseNode *pn2, *pn3, *head, **pnp;
+    JSXMLNamespace *ns;
+    JSXMLQName *qn, *attrjqn;
+    JSXMLClass xml_class;
+
+#define PN2X_SKIP_CHILD ((JSXML *) 1)
+
+    /*
+     * Cases return early to avoid common code that gets an outermost xml's
+     * object, which protects GC-things owned by xml and its descendants from
+     * garbage collection.
+     */
+    xml = NULL;
+    if (!JS_EnterLocalRootScope(cx))
+        return NULL;
+    switch (pn->pn_type) {
+      case TOK_XMLELEM:
+        length = inScopeNSes->length;
+        pn2 = pn->pn_head;
+        xml = ParseNodeToXML(cx, pn2, inScopeNSes, flags);
+        if (!xml)
+            goto fail;
+        flags &= ~XSF_PRECOMPILED_ROOT;
+
+        n = pn->pn_count;
+        JS_ASSERT(n >= 2);
+        n -= 2;
+        if (!XMLArraySetCapacity(cx, &xml->xml_kids, n))
+            goto fail;
+
+        i = 0;
+        while ((pn2 = pn2->pn_next) != NULL) {
+            if (!pn2->pn_next) {
+                /* Don't append the end tag! */
+                JS_ASSERT(pn2->pn_type == TOK_XMLETAGO);
+                break;
+            }
+
+            if ((flags & XSF_IGNORE_WHITESPACE) &&
+                n > 1 && pn2->pn_type == TOK_XMLSPACE) {
+                --n;
+                continue;
+            }
+
+            kid = ParseNodeToXML(cx, pn2, inScopeNSes, flags);
+            if (kid == PN2X_SKIP_CHILD) {
+                --n;
+                continue;
+            }
+
+            if (!kid) {
+                xml->xml_kids.length = i;
+                goto fail;
+            }
+
+            /* Store kid in xml right away, to protect it from GC. */
+            XMLARRAY_SET_MEMBER(&xml->xml_kids, i, kid);
+            kid->parent = xml;
+            ++i;
+
+            /* XXX where is this documented in an XML spec, or in E4X? */
+            if ((flags & XSF_IGNORE_WHITESPACE) &&
+                n > 1 && kid->xml_class == JSXML_CLASS_TEXT) {
+                str = ChompXMLWhitespace(cx, kid->xml_value);
+                if (!str)
+                    goto fail;
+                kid->xml_value = str;
+            }
+        }
+
+        JS_ASSERT(i == n);
+        xml->xml_kids.length = n;
+        if (n < pn->pn_count - 2)
+            XMLArrayTrim(&xml->xml_kids);
+        XMLARRAY_TRUNCATE(cx, inScopeNSes, length);
+        break;
+
+      case TOK_XMLLIST:
+        xml = js_NewXML(cx, JSXML_CLASS_LIST);
+        if (!xml)
+            goto fail;
+
+        n = pn->pn_count;
+        if (!XMLArraySetCapacity(cx, &xml->xml_kids, n))
+            goto fail;
+
+        i = 0;
+        for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
+            /*
+             * Always ignore insignificant whitespace in lists -- we shouldn't
+             * condition this on an XML.ignoreWhitespace setting when the list
+             * constructor is XMLList (note XML/XMLList unification hazard).
+             */
+            if (pn2->pn_type == TOK_XMLSPACE) {
+                --n;
+                continue;
+            }
+
+            kid = ParseNodeToXML(cx, pn2, inScopeNSes, flags);
+            if (kid == PN2X_SKIP_CHILD) {
+                --n;
+                continue;
+            }
+
+            if (!kid) {
+                xml->xml_kids.length = i;
+                goto fail;
+            }
+
+            XMLARRAY_SET_MEMBER(&xml->xml_kids, i, kid);
+            ++i;
+        }
+
+        xml->xml_kids.length = n;
+        if (n < pn->pn_count)
+            XMLArrayTrim(&xml->xml_kids);
+        break;
+
+      case TOK_XMLSTAGO:
+      case TOK_XMLPTAGC:
+        length = inScopeNSes->length;
+        pn2 = pn->pn_head;
+        JS_ASSERT(pn2->pn_type = TOK_XMLNAME);
+        if (pn2->pn_arity == PN_LIST)
+            goto syntax;
+
+        xml = js_NewXML(cx, JSXML_CLASS_ELEMENT);
+        if (!xml)
+            goto fail;
+
+        /* First pass: check syntax and process namespace declarations. */
+        JS_ASSERT(pn->pn_count >= 1);
+        n = pn->pn_count - 1;
+        pnp = &pn2->pn_next;
+        head = *pnp;
+        while ((pn2 = *pnp) != NULL) {
+            size_t length;
+            const jschar *chars;
+
+            if (pn2->pn_type != TOK_XMLNAME || pn2->pn_arity != PN_NULLARY)
+                goto syntax;
+
+            /* Enforce "Well-formedness constraint: Unique Att Spec". */
+            for (pn3 = head; pn3 != pn2; pn3 = pn3->pn_next->pn_next) {
+                if (pn3->pn_atom == pn2->pn_atom) {
+                    js_ReportCompileErrorNumber(cx, pn2,
+                                                JSREPORT_PN | JSREPORT_ERROR,
+                                                JSMSG_DUPLICATE_XML_ATTR,
+                                                js_ValueToPrintableString(cx,
+                                                    ATOM_KEY(pn2->pn_atom)));
+                    goto fail;
+                }
+            }
+
+            str = ATOM_TO_STRING(pn2->pn_atom);
+            pn2 = pn2->pn_next;
+            JS_ASSERT(pn2);
+            if (pn2->pn_type != TOK_XMLATTR)
+                goto syntax;
+
+            length = JSSTRING_LENGTH(str);
+            chars = JSSTRING_CHARS(str);
+            if (length >= 5 &&
+                IS_XMLNS_CHARS(chars) &&
+                (length == 5 || chars[5] == ':')) {
+                JSString *uri, *prefix;
+
+                uri = ATOM_TO_STRING(pn2->pn_atom);
+                if (length == 5) {
+                    /* 10.3.2.1. Step 6(h)(i)(1)(a). */
+                    prefix = cx->runtime->emptyString;
+                } else {
+                    prefix = js_NewStringCopyN(cx, chars + 6, length - 6, 0);
+                    if (!prefix)
+                        goto fail;
+                }
+
+                /*
+                 * Once the new ns is appended to xml->xml_namespaces, it is
+                 * protected from GC by the object that owns xml -- which is
+                 * either xml->object if outermost, or the object owning xml's
+                 * oldest ancestor if !outermost.
+                 */
+                ns = js_NewXMLNamespace(cx, prefix, uri, JS_TRUE);
+                if (!ns)
+                    goto fail;
+
+                /*
+                 * Don't add a namespace that's already in scope.  If someone
+                 * extracts a child property from its parent via [[Get]], then
+                 * we enforce the invariant, noted many times in ECMA-357, that
+                 * the child's namespaces form a possibly-improper superset of
+                 * its ancestors' namespaces.
+                 */
+                if (!XMLARRAY_HAS_MEMBER(inScopeNSes, ns, namespace_identity)) {
+                    if (!XMLARRAY_APPEND(cx, inScopeNSes, ns) ||
+                        !XMLARRAY_APPEND(cx, &xml->xml_namespaces, ns)) {
+                        goto fail;
+                    }
+                }
+
+                JS_ASSERT(n >= 2);
+                n -= 2;
+                *pnp = pn2->pn_next;
+                /* XXXbe recycle pn2 */
+                continue;
+            }
+
+            pnp = &pn2->pn_next;
+        }
+
+        /*
+         * If called from js_ParseNodeToXMLObject, emulate the effect of the
+         * <parent xmlns='%s'>...</parent> wrapping done by "ToXML Applied to
+         * the String Type" (ECMA-357 10.3.1).
+         */
+        if (flags & XSF_PRECOMPILED_ROOT) {
+            JS_ASSERT(length >= 1);
+            ns = XMLARRAY_MEMBER(inScopeNSes, 0, JSXMLNamespace);
+            JS_ASSERT(!XMLARRAY_HAS_MEMBER(&xml->xml_namespaces, ns,
+                                           namespace_identity));
+            ns = js_NewXMLNamespace(cx, ns->prefix, ns->uri, JS_FALSE);
+            if (!ns)
+                goto fail;
+            if (!XMLARRAY_APPEND(cx, &xml->xml_namespaces, ns))
+                goto fail;
+        }
+        XMLArrayTrim(&xml->xml_namespaces);
+
+        /* Second pass: process tag name and attributes, using namespaces. */
+        pn2 = pn->pn_head;
+        qn = ParseNodeToQName(cx, pn2, inScopeNSes, JS_FALSE);
+        if (!qn)
+            goto fail;
+        xml->name = qn;
+
+        JS_ASSERT((n & 1) == 0);
+        n >>= 1;
+        if (!XMLArraySetCapacity(cx, &xml->xml_attrs, n))
+            goto fail;
+
+        for (i = 0; (pn2 = pn2->pn_next) != NULL; i++) {
+            qn = ParseNodeToQName(cx, pn2, inScopeNSes, JS_TRUE);
+            if (!qn) {
+                xml->xml_attrs.length = i;
+                goto fail;
+            }
+
+            /*
+             * Enforce "Well-formedness constraint: Unique Att Spec", part 2:
+             * this time checking local name and namespace URI.
+             */
+            for (j = 0; j < i; j++) {
+                attrj = XMLARRAY_MEMBER(&xml->xml_attrs, j, JSXML);
+                attrjqn = attrj->name;
+                if (!js_CompareStrings(attrjqn->uri, qn->uri) &&
+                    !js_CompareStrings(attrjqn->localName, qn->localName)) {
+                    js_ReportCompileErrorNumber(cx, pn2,
+                                                JSREPORT_PN | JSREPORT_ERROR,
+                                                JSMSG_DUPLICATE_XML_ATTR,
+                                                js_ValueToPrintableString(cx,
+                                                    ATOM_KEY(pn2->pn_atom)));
+                    goto fail;
+                }
+            }
+
+            pn2 = pn2->pn_next;
+            JS_ASSERT(pn2);
+            JS_ASSERT(pn2->pn_type == TOK_XMLATTR);
+
+            attr = js_NewXML(cx, JSXML_CLASS_ATTRIBUTE);
+            if (!attr) {
+                xml->xml_attrs.length = i;
+                goto fail;
+            }
+
+            XMLARRAY_SET_MEMBER(&xml->xml_attrs, i, attr);
+            attr->parent = xml;
+            attr->name = qn;
+            attr->xml_value = ATOM_TO_STRING(pn2->pn_atom);
+        }
+
+        xml->xml_attrs.length = n;
+
+        /* Point tag closes its own namespace scope. */
+        if (pn->pn_type == TOK_XMLPTAGC)
+            XMLARRAY_TRUNCATE(cx, inScopeNSes, length);
+        break;
+
+      case TOK_XMLSPACE:
+      case TOK_XMLTEXT:
+      case TOK_XMLCDATA:
+      case TOK_XMLCOMMENT:
+      case TOK_XMLPI:
+        str = ATOM_TO_STRING(pn->pn_atom);
+        qn = NULL;
+        if (pn->pn_type == TOK_XMLCOMMENT) {
+            if (flags & XSF_IGNORE_COMMENTS)
+                goto skip_child;
+            xml_class = JSXML_CLASS_COMMENT;
+        } else if (pn->pn_type == TOK_XMLPI) {
+            if (IS_XML(str)) {
+                js_ReportCompileErrorNumber(cx, pn,
+                                            JSREPORT_PN | JSREPORT_ERROR,
+                                            JSMSG_RESERVED_ID,
+                                            js_ValueToPrintableString(cx,
+                                                STRING_TO_JSVAL(str)));
+                goto fail;
+            }
+
+            if (flags & XSF_IGNORE_PROCESSING_INSTRUCTIONS)
+                goto skip_child;
+
+            qn = ParseNodeToQName(cx, pn, inScopeNSes, JS_FALSE);
+            if (!qn)
+                goto fail;
+
+            str = pn->pn_atom2
+                  ? ATOM_TO_STRING(pn->pn_atom2)
+                  : cx->runtime->emptyString;
+            xml_class = JSXML_CLASS_PROCESSING_INSTRUCTION;
+        } else {
+            /* CDATA section content, or element text. */
+            xml_class = JSXML_CLASS_TEXT;
+        }
+
+        xml = js_NewXML(cx, xml_class);
+        if (!xml)
+            goto fail;
+        xml->name = qn;
+        if (pn->pn_type == TOK_XMLSPACE)
+            xml->xml_flags |= XMLF_WHITESPACE_TEXT;
+        xml->xml_value = str;
+        break;
+
+      default:
+        goto syntax;
+    }
+
+    JS_LeaveLocalRootScope(cx);
+    if ((flags & XSF_PRECOMPILED_ROOT) && !js_GetXMLObject(cx, xml))
+        return NULL;
+    return xml;
+
+skip_child:
+    js_LeaveLocalRootScope(cx);
+    return PN2X_SKIP_CHILD;
+
+#undef PN2X_SKIP_CHILD
+
+syntax:
+    js_ReportCompileErrorNumber(cx, pn, JSREPORT_PN | JSREPORT_ERROR,
+                                JSMSG_BAD_XML_MARKUP);
+fail:
+    JS_LeaveLocalRootScope(cx);
+    return NULL;
+}
+
+/*
+ * XML helper, object-ops, and library functions.  We start with the helpers,
+ * in ECMA-357 order, but merging XML (9.1) and XMLList (9.2) helpers.
+ */
+static JSBool
+GetXMLSetting(JSContext *cx, const char *name, jsval *vp)
+{
+    jsval v;
+
+    if (!js_FindConstructor(cx, NULL, js_XML_str, &v))
+        return JS_FALSE;
+    if (!JSVAL_IS_FUNCTION(cx, v)) {
+        *vp = JSVAL_VOID;
+        return JS_TRUE;
+    }
+    return JS_GetProperty(cx, JSVAL_TO_OBJECT(v), name, vp);
+}
+
+static JSBool
+GetBooleanXMLSetting(JSContext *cx, const char *name, JSBool *bp)
+{
+    int i;
+    jsval v;
+
+    if (cx->xmlSettingFlags & XSF_CACHE_VALID) {
+        for (i = 0; xml_static_props[i].name; i++) {
+            if (!strcmp(xml_static_props[i].name, name)) {
+                *bp = (cx->xmlSettingFlags & JS_BIT(i)) != 0;
+                return JS_TRUE;
+            }
+        }
+        *bp = JS_FALSE;
+        return JS_TRUE;
+    }
+
+    return GetXMLSetting(cx, name, &v) && js_ValueToBoolean(cx, v, bp);
+}
+
+static JSBool
+GetUint32XMLSetting(JSContext *cx, const char *name, uint32 *uip)
+{
+    jsval v;
+
+    return GetXMLSetting(cx, name, &v) && js_ValueToECMAUint32(cx, v, uip);
+}
+
+static JSBool
+GetXMLSettingFlags(JSContext *cx, uintN *flagsp)
+{
+    JSBool flag;
+
+    /* Just get the first flag to validate the setting flags cache. */
+    if (!GetBooleanXMLSetting(cx, js_ignoreComments_str, &flag))
+        return JS_FALSE;
+    *flagsp = cx->xmlSettingFlags;
+    return JS_TRUE;
+}
+
+static JSXML *
+ParseXMLSource(JSContext *cx, JSString *src)
+{
+    jsval nsval;
+    JSXMLNamespace *ns;
+    size_t urilen, srclen, length, offset, dstlen;
+    jschar *chars;
+    const jschar *srcp, *endp;
+    void *mark;
+    JSTokenStream *ts;
+    uintN lineno;
+    JSStackFrame *fp;
+    JSOp op;
+    JSParseNode *pn;
+    JSXML *xml;
+    JSXMLArray nsarray;
+    uintN flags;
+
+    static const char prefix[] = "<parent xmlns='";
+    static const char middle[] = "'>";
+    static const char suffix[] = "</parent>";
+
+#define constrlen(constr)   (sizeof(constr) - 1)
+
+    if (!js_GetDefaultXMLNamespace(cx, &nsval))
+        return NULL;
+    ns = (JSXMLNamespace *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(nsval));
+
+    urilen = JSSTRING_LENGTH(ns->uri);
+    srclen = JSSTRING_LENGTH(src);
+    length = constrlen(prefix) + urilen + constrlen(middle) + srclen +
+             constrlen(suffix);
+
+    chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
+    if (!chars)
+        return NULL;
+
+    dstlen = length;
+    js_InflateStringToBuffer(cx, prefix, constrlen(prefix), chars, &dstlen);
+    offset = dstlen;
+    js_strncpy(chars + offset, JSSTRING_CHARS(ns->uri), urilen);
+    offset += urilen;
+    dstlen = length - offset + 1;
+    js_InflateStringToBuffer(cx, middle, constrlen(middle), chars + offset, &dstlen);
+    offset += dstlen;
+    srcp = JSSTRING_CHARS(src);
+    js_strncpy(chars + offset, srcp, srclen);
+    offset += srclen;
+    dstlen = length - offset + 1;
+    js_InflateStringToBuffer(cx, suffix, constrlen(suffix), chars + offset, &dstlen);
+    chars [offset + dstlen] = 0;
+
+    mark = JS_ARENA_MARK(&cx->tempPool);
+    ts = js_NewBufferTokenStream(cx, chars, length);
+    if (!ts)
+        return NULL;
+    for (fp = cx->fp; fp && !fp->pc; fp = fp->down)
+        continue;
+    if (fp) {
+        op = (JSOp) *fp->pc;
+        if (op == JSOP_TOXML || op == JSOP_TOXMLLIST) {
+            ts->filename = fp->script->filename;
+            lineno = js_PCToLineNumber(cx, fp->script, fp->pc);
+            for (endp = srcp + srclen; srcp < endp; srcp++)
+                if (*srcp == '\n')
+                    --lineno;
+            ts->lineno = lineno;
+        }
+    }
+
+    JS_KEEP_ATOMS(cx->runtime);
+    pn = js_ParseXMLTokenStream(cx, cx->fp->scopeChain, ts, JS_FALSE);
+    xml = NULL;
+    if (pn && XMLArrayInit(cx, &nsarray, 1)) {
+        if (GetXMLSettingFlags(cx, &flags))
+            xml = ParseNodeToXML(cx, pn, &nsarray, flags);
+
+        XMLArrayFinish(cx, &nsarray);
+    }
+    JS_UNKEEP_ATOMS(cx->runtime);
+
+    JS_ARENA_RELEASE(&cx->tempPool, mark);
+    JS_free(cx, chars);
+    return xml;
+
+#undef constrlen
+}
+
+/*
+ * Errata in 10.3.1, 10.4.1, and 13.4.4.24 (at least).
+ *
+ * 10.3.1 Step 6(a) fails to NOTE that implementations that do not enforce
+ * the constraint:
+ *
+ *     for all x belonging to XML:
+ *         x.[[InScopeNamespaces]] >= x.[[Parent]].[[InScopeNamespaces]]
+ *
+ * must union x.[[InScopeNamespaces]] into x[0].[[InScopeNamespaces]] here
+ * (in new sub-step 6(a), renumbering the others to (b) and (c)).
+ *
+ * Same goes for 10.4.1 Step 7(a).
+ *
+ * In order for XML.prototype.namespaceDeclarations() to work correctly, the
+ * default namespace thereby unioned into x[0].[[InScopeNamespaces]] must be
+ * flagged as not declared, so that 13.4.4.24 Step 8(a) can exclude all such
+ * undeclared namespaces associated with x not belonging to ancestorNS.
+ */
+static JSXML *
+OrphanXMLChild(JSContext *cx, JSXML *xml, uint32 i)
+{
+    JSXMLNamespace *ns;
+
+    ns = XMLARRAY_MEMBER(&xml->xml_namespaces, 0, JSXMLNamespace);
+    xml = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+    if (xml->xml_class == JSXML_CLASS_ELEMENT) {
+        if (!XMLARRAY_APPEND(cx, &xml->xml_namespaces, ns))
+            return NULL;
+        ns->declared = JS_FALSE;
+    }
+    xml->parent = NULL;
+    return xml;
+}
+
+static JSObject *
+ToXML(JSContext *cx, jsval v)
+{
+    JSObject *obj;
+    JSXML *xml;
+    JSClass *clasp;
+    JSString *str;
+    uint32 length;
+
+    if (JSVAL_IS_PRIMITIVE(v)) {
+        if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v))
+            goto bad;
+    } else {
+        obj = JSVAL_TO_OBJECT(v);
+        if (OBJECT_IS_XML(cx, obj)) {
+            xml = (JSXML *) JS_GetPrivate(cx, obj);
+            if (xml->xml_class == JSXML_CLASS_LIST) {
+                if (xml->xml_kids.length != 1)
+                    goto bad;
+                xml = XMLARRAY_MEMBER(&xml->xml_kids, 0, JSXML);
+                JS_ASSERT(xml->xml_class != JSXML_CLASS_LIST);
+                return js_GetXMLObject(cx, xml);
+            }
+            return obj;
+        }
+
+        clasp = OBJ_GET_CLASS(cx, obj);
+        if (clasp->flags & JSCLASS_DOCUMENT_OBSERVER) {
+            JS_ASSERT(0);
+        }
+
+        if (clasp != &js_StringClass &&
+            clasp != &js_NumberClass &&
+            clasp != &js_BooleanClass) {
+            goto bad;
+        }
+    }
+
+    str = js_ValueToString(cx, v);
+    if (!str)
+        return NULL;
+    if (IS_EMPTY(str)) {
+        length = 0;
+#ifdef __GNUC__         /* suppress bogus gcc warnings */
+        xml = NULL;
+#endif
+    } else {
+        xml = ParseXMLSource(cx, str);
+        if (!xml)
+            return NULL;
+        length = JSXML_LENGTH(xml);
+    }
+
+    if (length == 0) {
+        obj = js_NewXMLObject(cx, JSXML_CLASS_TEXT);
+        if (!obj)
+            return NULL;
+    } else if (length == 1) {
+        xml = OrphanXMLChild(cx, xml, 0);
+        if (!xml)
+            return NULL;
+        obj = js_GetXMLObject(cx, xml);
+        if (!obj)
+            return NULL;
+    } else {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_SYNTAX_ERROR);
+        return NULL;
+    }
+    return obj;
+
+bad:
+    str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK, v, NULL);
+    if (str) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_XML_CONVERSION,
+                             JS_GetStringBytes(str));
+    }
+    return NULL;
+}
+
+static JSBool
+Append(JSContext *cx, JSXML *list, JSXML *kid);
+
+static JSObject *
+ToXMLList(JSContext *cx, jsval v)
+{
+    JSObject *obj, *listobj;
+    JSXML *xml, *list, *kid;
+    JSClass *clasp;
+    JSString *str;
+    uint32 i, length;
+
+    if (JSVAL_IS_PRIMITIVE(v)) {
+        if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v))
+            goto bad;
+    } else {
+        obj = JSVAL_TO_OBJECT(v);
+        if (OBJECT_IS_XML(cx, obj)) {
+            xml = (JSXML *) JS_GetPrivate(cx, obj);
+            if (xml->xml_class != JSXML_CLASS_LIST) {
+                listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+                if (!listobj)
+                    return NULL;
+                list = (JSXML *) JS_GetPrivate(cx, listobj);
+                if (!Append(cx, list, xml))
+                    return NULL;
+                return listobj;
+            }
+            return obj;
+        }
+
+        clasp = OBJ_GET_CLASS(cx, obj);
+        if (clasp->flags & JSCLASS_DOCUMENT_OBSERVER) {
+            JS_ASSERT(0);
+        }
+
+        if (clasp != &js_StringClass &&
+            clasp != &js_NumberClass &&
+            clasp != &js_BooleanClass) {
+            goto bad;
+        }
+    }
+
+    str = js_ValueToString(cx, v);
+    if (!str)
+        return NULL;
+    if (IS_EMPTY(str)) {
+        xml = NULL;
+        length = 0;
+    } else {
+        if (!JS_EnterLocalRootScope(cx))
+            return NULL;
+        xml = ParseXMLSource(cx, str);
+        if (!xml) {
+            JS_LeaveLocalRootScope(cx);
+            return NULL;
+        }
+        length = JSXML_LENGTH(xml);
+    }
+
+    listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+    if (listobj) {
+        list = (JSXML *) JS_GetPrivate(cx, listobj);
+        for (i = 0; i < length; i++) {
+            kid = OrphanXMLChild(cx, xml, i);
+            if (!kid)
+                return NULL;
+            if (!Append(cx, list, kid)) {
+                listobj = NULL;
+                break;
+            }
+        }
+    }
+
+    if (xml)
+        JS_LeaveLocalRootScope(cx);
+    return listobj;
+
+bad:
+    str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK, v, NULL);
+    if (str) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_XMLLIST_CONVERSION,
+                             JS_GetStringBytes(str));
+    }
+    return NULL;
+}
+
+/*
+ * ECMA-357 10.2.1 Steps 5-7 pulled out as common subroutines of XMLToXMLString
+ * and their library-public js_* counterparts.  The guts of MakeXMLCDataString,
+ * MakeXMLCommentString, and MakeXMLPIString are further factored into a common
+ * MakeXMLSpecialString subroutine.
+ *
+ * These functions take ownership of sb->base, if sb is non-null, in all cases
+ * of success or failure.
+ */
+static JSString *
+MakeXMLSpecialString(JSContext *cx, JSStringBuffer *sb,
+                     JSString *str, JSString *str2,
+                     const jschar *prefix, size_t prefixlength,
+                     const jschar *suffix, size_t suffixlength)
+{
+    JSStringBuffer localSB;
+    size_t length, length2, newlength;
+    jschar *bp, *base;
+
+    if (!sb) {
+        sb = &localSB;
+        js_InitStringBuffer(sb);
+    }
+
+    length = JSSTRING_LENGTH(str);
+    length2 = str2 ? JSSTRING_LENGTH(str2) : 0;
+    newlength = STRING_BUFFER_OFFSET(sb) +
+                prefixlength + length + ((length2 != 0) ? 1 + length2 : 0) +
+                suffixlength;
+    bp = base = (jschar *)
+                JS_realloc(cx, sb->base, (newlength + 1) * sizeof(jschar));
+    if (!bp) {
+        js_FinishStringBuffer(sb);
+        return NULL;
+    }
+
+    bp += STRING_BUFFER_OFFSET(sb);
+    js_strncpy(bp, prefix, prefixlength);
+    bp += prefixlength;
+    js_strncpy(bp, JSSTRING_CHARS(str), length);
+    bp += length;
+    if (length2 != 0) {
+        *bp++ = (jschar) ' ';
+        js_strncpy(bp, JSSTRING_CHARS(str2), length2);
+        bp += length2;
+    }
+    js_strncpy(bp, suffix, suffixlength);
+    bp[suffixlength] = 0;
+
+    str = js_NewString(cx, base, newlength, 0);
+    if (!str)
+        free(base);
+    return str;
+}
+
+static JSString *
+MakeXMLCDATAString(JSContext *cx, JSStringBuffer *sb, JSString *str)
+{
+    static const jschar cdata_prefix_ucNstr[] = {'<', '!', '[',
+                                                 'C', 'D', 'A', 'T', 'A',
+                                                 '['};
+    static const jschar cdata_suffix_ucNstr[] = {']', ']', '>'};
+
+    return MakeXMLSpecialString(cx, sb, str, NULL,
+                                cdata_prefix_ucNstr, 9,
+                                cdata_suffix_ucNstr, 3);
+}
+
+static JSString *
+MakeXMLCommentString(JSContext *cx, JSStringBuffer *sb, JSString *str)
+{
+    static const jschar comment_prefix_ucNstr[] = {'<', '!', '-', '-'};
+    static const jschar comment_suffix_ucNstr[] = {'-', '-', '>'};
+
+    return MakeXMLSpecialString(cx, sb, str, NULL,
+                                comment_prefix_ucNstr, 4,
+                                comment_suffix_ucNstr, 3);
+}
+
+static JSString *
+MakeXMLPIString(JSContext *cx, JSStringBuffer *sb, JSString *name,
+                JSString *value)
+{
+    static const jschar pi_prefix_ucNstr[] = {'<', '?'};
+    static const jschar pi_suffix_ucNstr[] = {'?', '>'};
+
+    return MakeXMLSpecialString(cx, sb, name, value,
+                                pi_prefix_ucNstr, 2,
+                                pi_suffix_ucNstr, 2);
+}
+
+/*
+ * ECMA-357 10.2.1 17(d-g) pulled out into a common subroutine that appends
+ * equals, a double quote, an attribute value, and a closing double quote.
+ */
+static void
+AppendAttributeValue(JSContext *cx, JSStringBuffer *sb, JSString *valstr)
+{
+    js_AppendCString(sb, "=\"");
+    valstr = js_EscapeAttributeValue(cx, valstr);
+    if (!valstr) {
+        free(sb->base);
+        sb->base = STRING_BUFFER_ERROR_BASE;
+        return;
+    }
+    js_AppendJSString(sb, valstr);
+    js_AppendChar(sb, '"');
+}
+
+/*
+ * ECMA-357 10.2.1.1 EscapeElementValue helper method.
+ *
+ * This function takes ownership of sb->base, if sb is non-null, in all cases
+ * of success or failure.
+ */
+static JSString *
+EscapeElementValue(JSContext *cx, JSStringBuffer *sb, JSString *str)
+{
+    size_t length, newlength;
+    const jschar *cp, *start, *end;
+    jschar c;
+
+    length = newlength = JSSTRING_LENGTH(str);
+    for (cp = start = JSSTRING_CHARS(str), end = cp + length; cp < end; cp++) {
+        c = *cp;
+        if (c == '<' || c == '>')
+            newlength += 3;
+        else if (c == '&')
+            newlength += 4;
+    }
+    if ((sb && STRING_BUFFER_OFFSET(sb) != 0) || newlength > length) {
+        JSStringBuffer localSB;
+        if (!sb) {
+            sb = &localSB;
+            js_InitStringBuffer(sb);
+        }
+        if (!sb->grow(sb, STRING_BUFFER_OFFSET(sb) + newlength)) {
+            JS_ReportOutOfMemory(cx);
+            return NULL;
+        }
+        for (cp = start; cp < end; cp++) {
+            c = *cp;
+            if (c == '<')
+                js_AppendCString(sb, js_lt_entity_str);
+            else if (c == '>')
+                js_AppendCString(sb, js_gt_entity_str);
+            else if (c == '&')
+                js_AppendCString(sb, js_amp_entity_str);
+            else
+                js_AppendChar(sb, c);
+        }
+        JS_ASSERT(STRING_BUFFER_OK(sb));
+        str = js_NewString(cx, sb->base, STRING_BUFFER_OFFSET(sb), 0);
+        if (!str)
+            js_FinishStringBuffer(sb);
+    }
+    return str;
+}
+
+/*
+ * ECMA-357 10.2.1.2 EscapeAttributeValue helper method.
+ * This function takes ownership of sb->base, if sb is non-null, in all cases.
+ */
+static JSString *
+EscapeAttributeValue(JSContext *cx, JSStringBuffer *sb, JSString *str)
+{
+    size_t length, newlength;
+    const jschar *cp, *start, *end;
+    jschar c;
+
+    length = newlength = JSSTRING_LENGTH(str);
+    for (cp = start = JSSTRING_CHARS(str), end = cp + length; cp < end; cp++) {
+        c = *cp;
+        if (c == '"')
+            newlength += 5;
+        else if (c == '<')
+            newlength += 3;
+        else if (c == '&' || c == '\n' || c == '\r' || c == '\t')
+            newlength += 4;
+    }
+    if ((sb && STRING_BUFFER_OFFSET(sb) != 0) || newlength > length) {
+        JSStringBuffer localSB;
+        if (!sb) {
+            sb = &localSB;
+            js_InitStringBuffer(sb);
+        }
+        if (!sb->grow(sb, STRING_BUFFER_OFFSET(sb) + newlength)) {
+            JS_ReportOutOfMemory(cx);
+            return NULL;
+        }
+        for (cp = start; cp < end; cp++) {
+            c = *cp;
+            if (c == '"')
+                js_AppendCString(sb, js_quot_entity_str);
+            else if (c == '<')
+                js_AppendCString(sb, js_lt_entity_str);
+            else if (c == '&')
+                js_AppendCString(sb, js_amp_entity_str);
+            else if (c == '\n')
+                js_AppendCString(sb, "&#xA;");
+            else if (c == '\r')
+                js_AppendCString(sb, "&#xD;");
+            else if (c == '\t')
+                js_AppendCString(sb, "&#x9;");
+            else
+                js_AppendChar(sb, c);
+        }
+        JS_ASSERT(STRING_BUFFER_OK(sb));
+        str = js_NewString(cx, sb->base, STRING_BUFFER_OFFSET(sb), 0);
+        if (!str)
+            js_FinishStringBuffer(sb);
+    }
+    return str;
+}
+
+/* 13.3.5.4 [[GetNamespace]]([InScopeNamespaces]) */
+static JSXMLNamespace *
+GetNamespace(JSContext *cx, JSXMLQName *qn, const JSXMLArray *inScopeNSes)
+{
+    JSXMLNamespace *match, *ns;
+    uint32 i, n;
+    jsval argv[2];
+    JSObject *nsobj;
+
+    JS_ASSERT(qn->uri);
+    if (!qn->uri) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_XML_NAMESPACE,
+                             qn->prefix
+                             ? js_ValueToPrintableString(cx,
+                                   STRING_TO_JSVAL(qn->prefix))
+                             : js_type_str[JSTYPE_VOID]);
+        return NULL;
+    }
+
+    /* Look for a matching namespace in inScopeNSes, if provided. */
+    match = NULL;
+    if (inScopeNSes) {
+        for (i = 0, n = inScopeNSes->length; i < n; i++) {
+            ns = XMLARRAY_MEMBER(inScopeNSes, i, JSXMLNamespace);
+
+            /*
+             * Erratum, very tricky, and not specified in ECMA-357 13.3.5.4:
+             * If we preserve prefixes, we must match null qn->prefix against
+             * an empty ns->prefix, in order to avoid generating redundant
+             * prefixed and default namespaces for cases such as:
+             *
+             *   x = <t xmlns="http://foo.com"/>
+             *   print(x.toXMLString());
+             *
+             * Per 10.3.2.1, the namespace attribute in t has an empty string
+             * prefix (*not* a null prefix), per 10.3.2.1 Step 6(h)(i)(1):
+             *
+             *   1. If the [local name] property of a is "xmlns"
+             *      a. Map ns.prefix to the empty string
+             *
+             * But t's name has a null prefix in this implementation, meaning
+             * *undefined*, per 10.3.2.1 Step 6(c)'s NOTE (which refers to
+             * the http://www.w3.org/TR/xml-infoset/ spec, item 2.2.3, without
+             * saying how "no value" maps to an ECMA-357 value -- but it must
+             * map to the *undefined* prefix value).
+             *
+             * Since "" != undefined (or null, in the current implementation)
+             * the ECMA-357 spec will fail to match in [[GetNamespace]] called
+             * on t with argument {} U {(prefix="", uri="http://foo.com")}.
+             * This spec bug leads to ToXMLString results that duplicate the
+             * declared namespace.
+             */
+            if (!js_CompareStrings(ns->uri, qn->uri) &&
+                (ns->prefix == qn->prefix ||
+                 ((ns->prefix && qn->prefix)
+                  ? !js_CompareStrings(ns->prefix, qn->prefix)
+                  : IS_EMPTY(ns->prefix ? ns->prefix : qn->prefix)))) {
+                match = ns;
+                break;
+            }
+        }
+    }
+
+    /* If we didn't match, make a new namespace from qn. */
+    if (!match) {
+        argv[0] = qn->prefix ? STRING_TO_JSVAL(qn->prefix) : JSVAL_VOID;
+        argv[1] = STRING_TO_JSVAL(qn->uri);
+        nsobj = js_ConstructObject(cx, &js_NamespaceClass.base, NULL, NULL,
+                                   2, argv);
+        if (!nsobj)
+            return NULL;
+        match = (JSXMLNamespace *) JS_GetPrivate(cx, nsobj);
+    }
+    return match;
+}
+
+static JSString *
+GeneratePrefix(JSContext *cx, JSString *uri, JSXMLArray *decls)
+{
+    const jschar *cp, *start, *end;
+    size_t length, newlength, offset;
+    uint32 i, n, m, serial;
+    jschar *bp, *dp;
+    JSBool done;
+    JSXMLNamespace *ns;
+    JSString *prefix;
+
+    JS_ASSERT(!IS_EMPTY(uri));
+
+    /*
+     * Try peeling off the last filename suffix or pathname component till
+     * we have a valid XML name.  This heuristic will prefer "xul" given
+     * ".../there.is.only.xul", "xbl" given ".../xbl", and "xbl2" given any
+     * likely URI of the form ".../xbl2/2005".
+     */
+    start = JSSTRING_CHARS(uri);
+    cp = end = start + JSSTRING_LENGTH(uri);
+    while (--cp > start) {
+        if (*cp == '.' || *cp == '/' || *cp == ':') {
+            ++cp;
+            if (IsXMLName(cp, PTRDIFF(end, cp, jschar)))
+                break;
+            end = --cp;
+        }
+    }
+    length = PTRDIFF(end, cp, jschar);
+
+    /*
+     * Now search through decls looking for a collision.  If we collide with
+     * an existing prefix, start tacking on a hyphen and a serial number.
+     */
+    serial = 0;
+    bp = NULL;
+#ifdef __GNUC__         /* suppress bogus gcc warnings */
+    newlength = 0;
+#endif
+    do {
+        done = JS_TRUE;
+        for (i = 0, n = decls->length; i < n; i++) {
+            ns = XMLARRAY_MEMBER(decls, i, JSXMLNamespace);
+            if (ns->prefix &&
+                JSSTRING_LENGTH(ns->prefix) == length &&
+                !memcmp(JSSTRING_CHARS(ns->prefix), cp,
+                        length * sizeof(jschar))) {
+                if (!bp) {
+                    newlength = length + 2 + (size_t) log10(n);
+                    bp = (jschar *)
+                         JS_malloc(cx, (newlength + 1) * sizeof(jschar));
+                    if (!bp)
+                        return NULL;
+                    js_strncpy(bp, cp, length);
+                }
+
+                ++serial;
+                JS_ASSERT(serial <= n);
+                dp = bp + length + 2 + (size_t) log10(serial);
+                *dp = 0;
+                for (m = serial; m != 0; m /= 10)
+                    *--dp = (jschar)('0' + m % 10);
+                *--dp = '-';
+                JS_ASSERT(dp == bp + length);
+
+                done = JS_FALSE;
+                break;
+            }
+        }
+    } while (!done);
+
+    if (!bp) {
+        offset = PTRDIFF(cp, start, jschar);
+        prefix = js_NewDependentString(cx, uri, offset, length, 0);
+    } else {
+        prefix = js_NewString(cx, bp, newlength, 0);
+        if (!prefix)
+            JS_free(cx, bp);
+    }
+    return prefix;
+}
+
+static JSBool
+namespace_match(const void *a, const void *b)
+{
+    const JSXMLNamespace *nsa = (const JSXMLNamespace *) a;
+    const JSXMLNamespace *nsb = (const JSXMLNamespace *) b;
+
+    if (nsb->prefix)
+        return nsa->prefix && !js_CompareStrings(nsa->prefix, nsb->prefix);
+    return !js_CompareStrings(nsa->uri, nsb->uri);
+}
+
+/* ECMA-357 10.2.1 and 10.2.2 */
+static JSString *
+XMLToXMLString(JSContext *cx, JSXML *xml, const JSXMLArray *ancestorNSes,
+               uintN indentLevel)
+{
+    JSBool pretty, indentKids;
+    JSStringBuffer sb;
+    JSString *str, *prefix, *kidstr;
+    uint32 i, n;
+    JSXMLArray empty, decls, ancdecls;
+    JSXMLNamespace *ns, *ns2;
+    uintN nextIndentLevel;
+    JSXML *attr, *kid;
+
+    if (!GetBooleanXMLSetting(cx, js_prettyPrinting_str, &pretty))
+        return NULL;
+
+    js_InitStringBuffer(&sb);
+    if (pretty)
+        js_RepeatChar(&sb, ' ', indentLevel);
+    str = NULL;
+
+    switch (xml->xml_class) {
+      case JSXML_CLASS_TEXT:
+        /* Step 4. */
+        if (pretty) {
+            str = ChompXMLWhitespace(cx, xml->xml_value);
+            if (!str)
+                return NULL;
+        } else {
+            str = xml->xml_value;
+        }
+        return EscapeElementValue(cx, &sb, str);
+
+      case JSXML_CLASS_ATTRIBUTE:
+        /* Step 5. */
+        return EscapeAttributeValue(cx, &sb, xml->xml_value);
+
+      case JSXML_CLASS_COMMENT:
+        /* Step 6. */
+        return MakeXMLCommentString(cx, &sb, xml->xml_value);
+
+      case JSXML_CLASS_PROCESSING_INSTRUCTION:
+        /* Step 7. */
+        return MakeXMLPIString(cx, &sb, xml->name->localName, xml->xml_value);
+
+      case JSXML_CLASS_LIST:
+        /* ECMA-357 10.2.2. */
+        for (i = 0, n = xml->xml_kids.length; i < n; i++) {
+            if (pretty && i != 0)
+                js_AppendChar(&sb, '\n');
+
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            kidstr = XMLToXMLString(cx, kid, ancestorNSes, indentLevel);
+            if (!kidstr)
+                goto list_out;
+
+            js_AppendJSString(&sb, kidstr);
+        }
+
+        if (!sb.base) {
+            if (!STRING_BUFFER_OK(&sb)) {
+                JS_ReportOutOfMemory(cx);
+                return NULL;
+            }
+            return cx->runtime->emptyString;
+        }
+
+        str = js_NewString(cx, sb.base, STRING_BUFFER_OFFSET(&sb), 0);
+      list_out:
+        if (!str)
+            js_FinishStringBuffer(&sb);
+        return str;
+
+      default:;
+    }
+
+    /* After this point, control must flow through label out: to exit. */
+    if (!JS_EnterLocalRootScope(cx))
+        return NULL;
+
+    /* ECMA-357 10.2.1 step 8 onward: handle ToXMLString on an XML element. */
+    if (!ancestorNSes) {
+        XMLArrayInit(cx, &empty, 0);
+        ancestorNSes = &empty;
+    }
+    XMLArrayInit(cx, &decls, 0);
+    ancdecls.capacity = 0;
+
+    /* Clone in-scope namespaces not in ancestorNSes into decls. */
+    for (i = 0, n = xml->xml_namespaces.length; i < n; i++) {
+        ns = XMLARRAY_MEMBER(&xml->xml_namespaces, i, JSXMLNamespace);
+        if (!ns->declared)
+            continue;
+        if (!XMLARRAY_HAS_MEMBER(ancestorNSes, ns, namespace_identity)) {
+            /* NOTE: may want to exclude unused namespaces here. */
+            ns2 = js_NewXMLNamespace(cx, ns->prefix, ns->uri, JS_TRUE);
+            if (!ns2)
+                goto out;
+            if (!XMLARRAY_APPEND(cx, &decls, ns2))
+                goto out;
+        }
+    }
+
+    /*
+     * Union ancestorNSes and decls into ancdecls.  Note that ancdecls does
+     * not own its member references.  In the spec, ancdecls has no name, but
+     * is always written out as (AncestorNamespaces U namespaceDeclarations).
+     */
+    if (!XMLArrayInit(cx, &ancdecls, ancestorNSes->length + decls.length))
+        goto out;
+    for (i = 0, n = ancestorNSes->length; i < n; i++) {
+        ns2 = XMLARRAY_MEMBER(ancestorNSes, i, JSXMLNamespace);
+        JS_ASSERT(!XMLARRAY_HAS_MEMBER(&decls, ns2, namespace_identity));
+        if (!XMLARRAY_APPEND(cx, &ancdecls, ns2))
+            goto out;
+    }
+    for (i = 0, n = decls.length; i < n; i++) {
+        ns2 = XMLARRAY_MEMBER(&decls, i, JSXMLNamespace);
+        JS_ASSERT(!XMLARRAY_HAS_MEMBER(&ancdecls, ns2, namespace_identity));
+        if (!XMLARRAY_APPEND(cx, &ancdecls, ns2))
+            goto out;
+    }
+
+    /* Step 11, except we don't clone ns unless its prefix is undefined. */
+    ns = GetNamespace(cx, xml->name, &ancdecls);
+    if (!ns)
+        goto out;
+
+    /* Step 12 (NULL means *undefined* here), plus the deferred ns cloning. */
+    if (!ns->prefix) {
+        /*
+         * Create a namespace prefix that isn't used by any member of decls.
+         * Assign the new prefix to a copy of ns.  Flag this namespace as if
+         * it were declared, for assertion-testing's sake later below.
+         *
+         * Erratum: if ns->prefix and xml->name are both null (*undefined* in
+         * ECMA-357), we know that xml was named using the default namespace
+         * (proof: see GetNamespace and the Namespace constructor called with
+         * two arguments).  So we ought not generate a new prefix here, when
+         * we can declare ns as the default namespace for xml.
+         *
+         * This helps descendants inherit the namespace instead of redundantly
+         * redeclaring it with generated prefixes in each descendant.
+         */
+        if (!xml->name->prefix) {
+            prefix = cx->runtime->emptyString;
+        } else {
+            prefix = GeneratePrefix(cx, ns->uri, &ancdecls);
+            if (!prefix)
+                goto out;
+        }
+        ns = js_NewXMLNamespace(cx, prefix, ns->uri, JS_TRUE);
+        if (!ns)
+            goto out;
+
+        /*
+         * If the xml->name was unprefixed, we must remove any declared default
+         * namespace from decls before appending ns.  How can you get a default
+         * namespace in decls that doesn't match the one from name?  Apparently
+         * by calling x.setNamespace(ns) where ns has no prefix.  The other way
+         * to fix this is to update x's in-scope namespaces when setNamespace
+         * is called, but that's not specified by ECMA-357.
+         *
+         * Likely Erratum here, depending on whether the lack of update to x's
+         * in-scope namespace in XML.prototype.setNamespace (13.4.4.36) is an
+         * erratum or not.  Note that changing setNamespace to update the list
+         * of in-scope namespaces will change x.namespaceDeclarations().
+         */
+        if (IS_EMPTY(prefix)) {
+            i = XMLArrayFindMember(&decls, ns, namespace_match);
+            if (i != XML_NOT_FOUND)
+                XMLArrayDelete(cx, &decls, i, JS_TRUE);
+        }
+
+        /*
+         * In the spec, ancdecls has no name, but is always written out as
+         * (AncestorNamespaces U namespaceDeclarations).  Since we compute
+         * that union in ancdecls, any time we append a namespace strong
+         * ref to decls, we must also append a weak ref to ancdecls.  Order
+         * matters here: code at label out: releases strong refs in decls.
+         */
+        if (!XMLARRAY_APPEND(cx, &ancdecls, ns) ||
+            !XMLARRAY_APPEND(cx, &decls, ns)) {
+            goto out;
+        }
+    }
+
+    /* Format the element or point-tag into sb. */
+    js_AppendChar(&sb, '<');
+
+    if (ns->prefix && !IS_EMPTY(ns->prefix)) {
+        js_AppendJSString(&sb, ns->prefix);
+        js_AppendChar(&sb, ':');
+    }
+    js_AppendJSString(&sb, xml->name->localName);
+
+    /*
+     * Step 16 makes a union to avoid writing two loops in step 17, to share
+     * common attribute value appending spec-code.  We prefer two loops for
+     * faster code and less data overhead.
+     */
+
+    /* Step 17(c): append XML namespace declarations. */
+    for (i = 0, n = decls.length; i < n; i++) {
+        ns2 = XMLARRAY_MEMBER(&decls, i, JSXMLNamespace);
+        JS_ASSERT(ns2->declared);
+
+        js_AppendCString(&sb, " xmlns");
+
+        /* 17(c)(ii): NULL means *undefined* here. */
+        if (!ns2->prefix) {
+            prefix = GeneratePrefix(cx, ns2->uri, &ancdecls);
+            if (!prefix)
+                goto out;
+            ns2->prefix = prefix;
+        }
+
+        /* 17(c)(iii). */
+        if (!IS_EMPTY(ns2->prefix)) {
+            js_AppendChar(&sb, ':');
+            js_AppendJSString(&sb, ns2->prefix);
+        }
+
+        /* 17(d-g). */
+        AppendAttributeValue(cx, &sb, ns2->uri);
+    }
+
+    /* Step 17(b): append attributes. */
+    for (i = 0, n = xml->xml_attrs.length; i < n; i++) {
+        attr = XMLARRAY_MEMBER(&xml->xml_attrs, i, JSXML);
+        js_AppendChar(&sb, ' ');
+        ns2 = GetNamespace(cx, attr->name, &ancdecls);
+        if (!ns2)
+            goto out;
+
+        /* 17(b)(ii): NULL means *undefined* here. */
+        if (!ns2->prefix) {
+            prefix = GeneratePrefix(cx, ns2->uri, &ancdecls);
+            if (!prefix)
+                goto out;
+
+            /* Again, we avoid copying ns2 until we know it's prefix-less. */
+            ns2 = js_NewXMLNamespace(cx, prefix, ns2->uri, JS_TRUE);
+            if (!ns2)
+                goto out;
+
+            /*
+             * In the spec, ancdecls has no name, but is always written out as
+             * (AncestorNamespaces U namespaceDeclarations).  Since we compute
+             * that union in ancdecls, any time we append a namespace strong
+             * ref to decls, we must also append a weak ref to ancdecls.  Order
+             * matters here: code at label out: releases strong refs in decls.
+             */
+            if (!XMLARRAY_APPEND(cx, &ancdecls, ns2) ||
+                !XMLARRAY_APPEND(cx, &decls, ns2)) {
+                goto out;
+            }
+        }
+
+        /* 17(b)(iii). */
+        if (!IS_EMPTY(ns2->prefix)) {
+            js_AppendJSString(&sb, ns2->prefix);
+            js_AppendChar(&sb, ':');
+        }
+
+        /* 17(b)(iv). */
+        js_AppendJSString(&sb, attr->name->localName);
+
+        /* 17(d-g). */
+        AppendAttributeValue(cx, &sb, attr->xml_value);
+    }
+
+    /* Step 18: handle point tags. */
+    n = xml->xml_kids.length;
+    if (n == 0) {
+        js_AppendCString(&sb, "/>");
+    } else {
+        /* Steps 19 through 25: handle element content, and open the end-tag. */
+        js_AppendChar(&sb, '>');
+        indentKids = n > 1 ||
+                     (n == 1 &&
+                      XMLARRAY_MEMBER(&xml->xml_kids, 0, JSXML)->xml_class
+                      != JSXML_CLASS_TEXT);
+
+        if (pretty && indentKids) {
+            if (!GetUint32XMLSetting(cx, js_prettyIndent_str, &i))
+                goto out;
+            nextIndentLevel = indentLevel + i;
+        } else {
+            nextIndentLevel = 0;
+        }
+
+        for (i = 0; i < n; i++) {
+            if (pretty && indentKids)
+                js_AppendChar(&sb, '\n');
+
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            kidstr = XMLToXMLString(cx, kid, &ancdecls, nextIndentLevel);
+            if (!kidstr)
+                goto out;
+
+            js_AppendJSString(&sb, kidstr);
+        }
+
+        if (pretty && indentKids) {
+            js_AppendChar(&sb, '\n');
+            js_RepeatChar(&sb, ' ', indentLevel);
+        }
+        js_AppendCString(&sb, "</");
+
+        /* Step 26. */
+        if (ns->prefix && !IS_EMPTY(ns->prefix)) {
+            js_AppendJSString(&sb, ns->prefix);
+            js_AppendChar(&sb, ':');
+        }
+
+        /* Step 27. */
+        js_AppendJSString(&sb, xml->name->localName);
+        js_AppendChar(&sb, '>');
+    }
+
+    if (!STRING_BUFFER_OK(&sb)) {
+        JS_ReportOutOfMemory(cx);
+        goto out;
+    }
+
+    str = js_NewString(cx, sb.base, STRING_BUFFER_OFFSET(&sb), 0);
+out:
+    JS_LeaveLocalRootScope(cx);
+    if (!str)
+        js_FinishStringBuffer(&sb);
+    XMLArrayFinish(cx, &decls);
+    if (ancdecls.capacity != 0)
+        XMLArrayFinish(cx, &ancdecls);
+    return str;
+}
+
+/* ECMA-357 10.2 */
+static JSString *
+ToXMLString(JSContext *cx, jsval v)
+{
+    JSObject *obj;
+    JSString *str;
+    JSXML *xml;
+
+    if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_XML_CONVERSION,
+                             js_type_str[JSVAL_IS_NULL(v)
+                                         ? JSTYPE_NULL
+                                         : JSTYPE_VOID]);
+        return NULL;
+    }
+
+    if (JSVAL_IS_BOOLEAN(v) || JSVAL_IS_NUMBER(v))
+        return js_ValueToString(cx, v);
+
+    if (JSVAL_IS_STRING(v))
+        return EscapeElementValue(cx, NULL, JSVAL_TO_STRING(v));
+
+    obj = JSVAL_TO_OBJECT(v);
+    if (!OBJECT_IS_XML(cx, obj)) {
+        if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_STRING, &v))
+            return NULL;
+        str = js_ValueToString(cx, v);
+        if (!str)
+            return NULL;
+        return EscapeElementValue(cx, NULL, str);
+    }
+
+    /* Handle non-element cases in this switch, returning from each case. */
+    xml = (JSXML *) JS_GetPrivate(cx, obj);
+    return XMLToXMLString(cx, xml, NULL, 0);
+}
+
+static JSXMLQName *
+ToAttributeName(JSContext *cx, jsval v)
+{
+    JSString *name, *uri, *prefix;
+    JSObject *obj;
+    JSClass *clasp;
+    JSXMLQName *qn;
+    JSTempValueRooter tvr;
+
+    if (JSVAL_IS_STRING(v)) {
+        name = JSVAL_TO_STRING(v);
+        uri = prefix = cx->runtime->emptyString;
+    } else {
+        if (JSVAL_IS_PRIMITIVE(v)) {
+            name = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK, v, NULL);
+            if (name) {
+                JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                     JSMSG_BAD_XML_ATTR_NAME,
+                                     JS_GetStringBytes(name));
+            }
+            return NULL;
+        }
+
+        obj = JSVAL_TO_OBJECT(v);
+        clasp = OBJ_GET_CLASS(cx, obj);
+        if (clasp == &js_AttributeNameClass)
+            return (JSXMLQName *) JS_GetPrivate(cx, obj);
+
+        if (clasp == &js_QNameClass.base) {
+            qn = (JSXMLQName *) JS_GetPrivate(cx, obj);
+            uri = qn->uri;
+            prefix = qn->prefix;
+            name = qn->localName;
+        } else {
+            if (clasp == &js_AnyNameClass) {
+                name = ATOM_TO_STRING(cx->runtime->atomState.starAtom);
+            } else {
+                name = js_ValueToString(cx, v);
+                if (!name)
+                    return NULL;
+            }
+            uri = prefix = cx->runtime->emptyString;
+        }
+    }
+
+    qn = js_NewXMLQName(cx, uri, prefix, name);
+    if (!qn)
+        return NULL;
+
+    /*
+     * Temp and local root scope APIs take GC-thing pointers tagged as jsvals
+     * and blindly untag.  Since qn is a GC-thing pointer, we can treat it as
+     * an object pointer.
+     */
+    JS_PUSH_SINGLE_TEMP_ROOT(cx, OBJECT_TO_JSVAL(qn), &tvr);
+    obj = js_GetAttributeNameObject(cx, qn);
+    JS_POP_TEMP_ROOT(cx, &tvr);
+    if (!obj)
+        return NULL;
+    return qn;
+}
+
+static JSXMLQName *
+ToXMLName(JSContext *cx, jsval v, jsid *funidp)
+{
+    JSString *name;
+    JSObject *obj;
+    JSClass *clasp;
+    uint32 index;
+    JSXMLQName *qn;
+    JSAtom *atom;
+
+    if (JSVAL_IS_STRING(v)) {
+        name = JSVAL_TO_STRING(v);
+    } else {
+        if (JSVAL_IS_PRIMITIVE(v)) {
+            name = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK, v, NULL);
+            if (name)
+                goto bad;
+            return NULL;
+        }
+
+        obj = JSVAL_TO_OBJECT(v);
+        clasp = OBJ_GET_CLASS(cx, obj);
+        if (clasp == &js_AttributeNameClass || clasp == &js_QNameClass.base)
+            goto out;
+        if (clasp == &js_AnyNameClass) {
+            name = ATOM_TO_STRING(cx->runtime->atomState.starAtom);
+            goto construct;
+        }
+        name = js_ValueToString(cx, v);
+        if (!name)
+            return NULL;
+    }
+
+    /*
+     * ECMA-357 10.6.1 step 1 seems to be incorrect.  The spec says:
+     *
+     * 1. If ToString(ToNumber(P)) == ToString(P), throw a TypeError exception
+     *
+     * First, _P_ should be _s_, to refer to the given string.
+     *
+     * Second, why does ToXMLName applied to the string type throw TypeError
+     * only for numeric literals without any leading or trailing whitespace?
+     *
+     * If the idea is to reject uint32 property names, then the check needs to
+     * be stricter, to exclude hexadecimal and floating point literals.
+     */
+    if (js_IdIsIndex(STRING_TO_JSVAL(name), &index))
+        goto bad;
+
+    if (*JSSTRING_CHARS(name) == '@') {
+        name = js_NewDependentString(cx, name, 1, JSSTRING_LENGTH(name) - 1, 0);
+        if (!name)
+            return NULL;
+        *funidp = 0;
+        return ToAttributeName(cx, STRING_TO_JSVAL(name));
+    }
+
+construct:
+    v = STRING_TO_JSVAL(name);
+    obj = js_ConstructObject(cx, &js_QNameClass.base, NULL, NULL, 1, &v);
+    if (!obj)
+        return NULL;
+
+out:
+    qn = (JSXMLQName *) JS_GetPrivate(cx, obj);
+    atom = cx->runtime->atomState.lazy.functionNamespaceURIAtom;
+    if (atom &&
+        (qn->uri == ATOM_TO_STRING(atom) ||
+         !js_CompareStrings(qn->uri, ATOM_TO_STRING(atom)))) {
+        if (!JS_ValueToId(cx, STRING_TO_JSVAL(qn->localName), funidp))
+            return NULL;
+    } else {
+        *funidp = 0;
+    }
+    return qn;
+
+bad:
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                         JSMSG_BAD_XML_NAME,
+                         js_ValueToPrintableString(cx, STRING_TO_JSVAL(name)));
+    return NULL;
+}
+
+/* ECMA-357 9.1.1.13 XML [[AddInScopeNamespace]]. */
+static JSBool
+AddInScopeNamespace(JSContext *cx, JSXML *xml, JSXMLNamespace *ns)
+{
+    JSXMLNamespace *match, *ns2;
+    uint32 i, n, m;
+
+    if (xml->xml_class != JSXML_CLASS_ELEMENT)
+        return JS_TRUE;
+
+    /* NULL means *undefined* here -- see ECMA-357 9.1.1.13 step 2. */
+    if (!ns->prefix) {
+        match = NULL;
+        for (i = 0, n = xml->xml_namespaces.length; i < n; i++) {
+            ns2 = XMLARRAY_MEMBER(&xml->xml_namespaces, i, JSXMLNamespace);
+            if (!js_CompareStrings(ns2->uri, ns->uri)) {
+                match = ns2;
+                break;
+            }
+        }
+        if (!match && !XMLARRAY_ADD_MEMBER(cx, &xml->xml_namespaces, n, ns))
+            return JS_FALSE;
+    } else {
+        if (IS_EMPTY(ns->prefix) && IS_EMPTY(xml->name->uri))
+            return JS_TRUE;
+        match = NULL;
+#ifdef __GNUC__         /* suppress bogus gcc warnings */
+        m = XML_NOT_FOUND;
+#endif
+        for (i = 0, n = xml->xml_namespaces.length; i < n; i++) {
+            ns2 = XMLARRAY_MEMBER(&xml->xml_namespaces, i, JSXMLNamespace);
+            if (ns2->prefix && !js_CompareStrings(ns2->prefix, ns->prefix)) {
+                match = ns2;
+                m = i;
+                break;
+            }
+        }
+        if (match && js_CompareStrings(match->uri, ns->uri)) {
+            ns2 = XMLARRAY_DELETE(cx, &xml->xml_namespaces, m, JS_TRUE,
+                                  JSXMLNamespace);
+            JS_ASSERT(ns2 == match);
+            match->prefix = NULL;
+            if (!AddInScopeNamespace(cx, xml, match))
+                return JS_FALSE;
+        }
+        if (!XMLARRAY_APPEND(cx, &xml->xml_namespaces, ns))
+            return JS_FALSE;
+    }
+
+    /* OPTION: enforce that descendants have superset namespaces. */
+    return JS_TRUE;
+}
+
+/* ECMA-357 9.2.1.6 XMLList [[Append]]. */
+static JSBool
+Append(JSContext *cx, JSXML *list, JSXML *xml)
+{
+    uint32 i, j, k, n;
+    JSXML *kid;
+
+    JS_ASSERT(list->xml_class == JSXML_CLASS_LIST);
+    i = list->xml_kids.length;
+    n = 1;
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        list->xml_target = xml->xml_target;
+        list->xml_targetprop = xml->xml_targetprop;
+        n = JSXML_LENGTH(xml);
+        k = i + n;
+        if (!XMLArraySetCapacity(cx, &list->xml_kids, k))
+            return JS_FALSE;
+        for (j = 0; j < n; j++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, j, JSXML);
+            XMLARRAY_SET_MEMBER(&list->xml_kids, i + j, kid);
+        }
+        list->xml_kids.length = k;
+        return JS_TRUE;
+    }
+
+    list->xml_target = xml->parent;
+    if (xml->xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION)
+        list->xml_targetprop = NULL;
+    else
+        list->xml_targetprop = xml->name;
+    if (!XMLARRAY_ADD_MEMBER(cx, &list->xml_kids, i, xml))
+        return JS_FALSE;
+    return JS_TRUE;
+}
+
+/* ECMA-357 9.1.1.7 XML [[DeepCopy]] and 9.2.1.7 XMLList [[DeepCopy]]. */
+static JSXML *
+DeepCopyInLRS(JSContext *cx, JSXML *xml, uintN flags);
+
+static JSXML *
+DeepCopy(JSContext *cx, JSXML *xml, JSObject *obj, uintN flags)
+{
+    JSXML *copy;
+    JSBool ok;
+
+    /* Our caller may not be protecting newborns with a local root scope. */
+    if (!JS_EnterLocalRootScope(cx))
+        return NULL;
+    copy = DeepCopyInLRS(cx, xml, flags);
+    if (copy) {
+        if (obj) {
+            /* Caller provided the object for this copy, hook 'em up. */
+            ok = JS_SetPrivate(cx, obj, copy);
+            if (ok)
+                copy->object = obj;
+        } else {
+            ok = js_GetXMLObject(cx, copy) != NULL;
+        }
+        if (!ok)
+            copy = NULL;
+    }
+    JS_LeaveLocalRootScope(cx);
+    return copy;
+}
+
+/*
+ * (i) We must be in a local root scope (InLRS).
+ * (ii) parent must have a rooted object.
+ * (iii) from's owning object must be locked if not thread-local.
+ */
+static JSBool
+DeepCopySetInLRS(JSContext *cx, JSXMLArray *from, JSXMLArray *to, JSXML *parent,
+                 uintN flags)
+{
+    uint32 i, j, n;
+    JSXML *kid, *kid2;
+    JSString *str;
+
+    JS_ASSERT(cx->localRootStack);
+
+    n = from->length;
+    if (!XMLArraySetCapacity(cx, to, n))
+        return JS_FALSE;
+
+    for (i = j = 0; i < n; i++) {
+        kid = XMLARRAY_MEMBER(from, i, JSXML);
+        if ((flags & XSF_IGNORE_COMMENTS) &&
+            kid->xml_class == JSXML_CLASS_COMMENT) {
+            continue;
+        }
+        if ((flags & XSF_IGNORE_PROCESSING_INSTRUCTIONS) &&
+            kid->xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION) {
+            continue;
+        }
+        if ((flags & XSF_IGNORE_WHITESPACE) &&
+            (kid->xml_flags & XMLF_WHITESPACE_TEXT)) {
+            continue;
+        }
+        kid2 = DeepCopyInLRS(cx, kid, flags);
+        if (!kid2) {
+            to->length = j;
+            return JS_FALSE;
+        }
+
+        if ((flags & XSF_IGNORE_WHITESPACE) &&
+            n > 1 && kid2->xml_class == JSXML_CLASS_TEXT) {
+            str = ChompXMLWhitespace(cx, kid2->xml_value);
+            if (!str) {
+                to->length = j;
+                return JS_FALSE;
+            }
+            kid2->xml_value = str;
+        }
+
+        XMLARRAY_SET_MEMBER(to, j++, kid2);
+        if (parent->xml_class != JSXML_CLASS_LIST)
+            kid2->parent = parent;
+    }
+
+    to->length = j;
+    if (j < n)
+        XMLArrayTrim(to);
+    return JS_TRUE;
+}
+
+static JSXML *
+DeepCopyInLRS(JSContext *cx, JSXML *xml, uintN flags)
+{
+    JSXML *copy;
+    JSXMLQName *qn;
+    JSBool ok;
+    uint32 i, n;
+    JSXMLNamespace *ns, *ns2;
+
+    /* Our caller must be protecting newborn objects. */
+    JS_ASSERT(cx->localRootStack);
+
+    copy = js_NewXML(cx, xml->xml_class);
+    if (!copy)
+        return NULL;
+    qn = xml->name;
+    if (qn) {
+        qn = js_NewXMLQName(cx, qn->uri, qn->prefix, qn->localName);
+        if (!qn) {
+            ok = JS_FALSE;
+            goto out;
+        }
+    }
+    copy->name = qn;
+    copy->xml_flags = xml->xml_flags;
+
+    if (JSXML_HAS_VALUE(xml)) {
+        copy->xml_value = xml->xml_value;
+        ok = JS_TRUE;
+    } else {
+        ok = DeepCopySetInLRS(cx, &xml->xml_kids, &copy->xml_kids, copy, flags);
+        if (!ok)
+            goto out;
+
+        if (xml->xml_class == JSXML_CLASS_LIST) {
+            copy->xml_target = xml->xml_target;
+            copy->xml_targetprop = xml->xml_targetprop;
+        } else {
+            n = xml->xml_namespaces.length;
+            ok = XMLArraySetCapacity(cx, &copy->xml_namespaces, n);
+            if (!ok)
+                goto out;
+            for (i = 0; i < n; i++) {
+                ns = XMLARRAY_MEMBER(&xml->xml_namespaces, i, JSXMLNamespace);
+                ns2 = js_NewXMLNamespace(cx, ns->prefix, ns->uri, ns->declared);
+                if (!ns2) {
+                    copy->xml_namespaces.length = i;
+                    ok = JS_FALSE;
+                    goto out;
+                }
+                XMLARRAY_SET_MEMBER(&copy->xml_namespaces, i, ns2);
+            }
+            copy->xml_namespaces.length = n;
+
+            ok = DeepCopySetInLRS(cx, &xml->xml_attrs, &copy->xml_attrs, copy,
+                                  0);
+            if (!ok)
+                goto out;
+        }
+    }
+
+out:
+    if (!ok)
+        return NULL;
+    return copy;
+}
+
+static void
+ReportBadXMLName(JSContext *cx, jsval id)
+{
+    JSString *name;
+
+    name = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK, id, NULL);
+    if (name) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_BAD_XML_NAME,
+                             JS_GetStringBytes(name));
+    }
+}
+
+/* ECMA-357 9.1.1.4 XML [[DeleteByIndex]]. */
+static JSBool
+DeleteByIndex(JSContext *cx, JSXML *xml, jsval id, jsval *vp)
+{
+    uint32 index;
+    JSXML *kid;
+
+    if (!js_IdIsIndex(id, &index)) {
+        ReportBadXMLName(cx, id);
+        return JS_FALSE;
+    }
+
+    if (JSXML_HAS_KIDS(xml) && index < xml->xml_kids.length) {
+        kid = XMLARRAY_MEMBER(&xml->xml_kids, index, JSXML);
+        kid->parent = NULL;
+        XMLArrayDelete(cx, &xml->xml_kids, index, JS_TRUE);
+    }
+
+    *vp = JSVAL_TRUE;
+    return JS_TRUE;
+}
+
+typedef JSBool (*JSXMLNameMatcher)(JSXMLQName *nameqn, JSXML *xml);
+
+static JSBool
+MatchAttrName(JSXMLQName *nameqn, JSXML *attr)
+{
+    JSXMLQName *attrqn = attr->name;
+
+    return (IS_STAR(nameqn->localName) ||
+            !js_CompareStrings(attrqn->localName, nameqn->localName)) &&
+           (!nameqn->uri ||
+            !js_CompareStrings(attrqn->uri, nameqn->uri));
+}
+
+static JSBool
+MatchElemName(JSXMLQName *nameqn, JSXML *elem)
+{
+    return (IS_STAR(nameqn->localName) ||
+            (elem->xml_class == JSXML_CLASS_ELEMENT &&
+             !js_CompareStrings(elem->name->localName, nameqn->localName))) &&
+           (!nameqn->uri ||
+            (elem->xml_class == JSXML_CLASS_ELEMENT &&
+             !js_CompareStrings(elem->name->uri, nameqn->uri)));
+}
+
+/* ECMA-357 9.1.1.8 XML [[Descendants]] and 9.2.1.8 XMLList [[Descendants]]. */
+static JSBool
+DescendantsHelper(JSContext *cx, JSXML *xml, JSXMLQName *nameqn, JSXML *list)
+{
+    uint32 i, n;
+    JSXML *attr, *kid;
+
+    if (xml->xml_class == JSXML_CLASS_ELEMENT &&
+        OBJ_GET_CLASS(cx, nameqn->object) == &js_AttributeNameClass) {
+        for (i = 0, n = xml->xml_attrs.length; i < n; i++) {
+            attr = XMLARRAY_MEMBER(&xml->xml_attrs, i, JSXML);
+            if (MatchAttrName(nameqn, attr)) {
+                if (!Append(cx, list, attr))
+                    return JS_FALSE;
+            }
+        }
+    }
+
+    for (i = 0, n = JSXML_LENGTH(xml); i < n; i++) {
+        kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+        if (OBJ_GET_CLASS(cx, nameqn->object) != &js_AttributeNameClass &&
+            MatchElemName(nameqn, kid)) {
+            if (!Append(cx, list, kid))
+                return JS_FALSE;
+        }
+        if (!DescendantsHelper(cx, kid, nameqn, list))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+static JSXML *
+Descendants(JSContext *cx, JSXML *xml, jsval id)
+{
+    jsid funid;
+    JSXMLQName *nameqn;
+    JSObject *listobj;
+    JSXML *list, *kid;
+    uint32 i, n;
+    JSBool ok;
+
+    nameqn = ToXMLName(cx, id, &funid);
+    if (!nameqn)
+        return NULL;
+
+    listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+    if (!listobj)
+        return NULL;
+    list = (JSXML *) JS_GetPrivate(cx, listobj);
+    if (funid)
+        return list;
+
+    /*
+     * Protect nameqn's object and strings from GC by linking list to it
+     * temporarily.  The cx->newborn[GCX_OBJECT] GC root protects listobj,
+     * which protects list.  Any other object allocations occuring beneath
+     * DescendantsHelper use local roots.
+     */
+    list->name = nameqn;
+    if (!JS_EnterLocalRootScope(cx))
+        return NULL;
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        ok = JS_TRUE;
+        for (i = 0, n = xml->xml_kids.length; i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+                ok = DescendantsHelper(cx, kid, nameqn, list);
+                if (!ok)
+                    break;
+            }
+        }
+    } else {
+        ok = DescendantsHelper(cx, xml, nameqn, list);
+    }
+    JS_LeaveLocalRootScope(cx);
+    if (!ok)
+        return NULL;
+    list->name = NULL;
+    return list;
+}
+
+/* Recursive (JSXML *) parameterized version of Equals. */
+static JSBool
+XMLEquals(JSContext *cx, JSXML *xml, JSXML *vxml, JSBool *bp)
+{
+    JSXMLQName *qn, *vqn;
+    uint32 i, j, n;
+    JSXML **xvec, **vvec, *attr, *vattr;
+    JSObject *xobj, *vobj;
+
+retry:
+    if (xml->xml_class != vxml->xml_class) {
+        if (xml->xml_class == JSXML_CLASS_LIST && xml->xml_kids.length == 1) {
+            xml = XMLARRAY_MEMBER(&xml->xml_kids, 0, JSXML);
+            goto retry;
+        }
+        if (vxml->xml_class == JSXML_CLASS_LIST && vxml->xml_kids.length == 1) {
+            vxml = XMLARRAY_MEMBER(&vxml->xml_kids, 0, JSXML);
+            goto retry;
+        }
+        *bp = JS_FALSE;
+        return JS_TRUE;
+    }
+
+    qn = xml->name;
+    vqn = vxml->name;
+    if (qn) {
+        *bp = vqn &&
+              !js_CompareStrings(qn->localName, vqn->localName) &&
+              !js_CompareStrings(qn->uri, vqn->uri);
+    } else {
+        *bp = vqn == NULL;
+    }
+    if (!*bp)
+        return JS_TRUE;
+
+    if (JSXML_HAS_VALUE(xml)) {
+        *bp = !js_CompareStrings(xml->xml_value, vxml->xml_value);
+    } else if ((n = xml->xml_kids.length) != vxml->xml_kids.length) {
+        *bp = JS_FALSE;
+    } else {
+        xvec = (JSXML **) xml->xml_kids.vector;
+        vvec = (JSXML **) vxml->xml_kids.vector;
+        for (i = 0; i < n; i++) {
+            xobj = js_GetXMLObject(cx, xvec[i]);
+            vobj = js_GetXMLObject(cx, vvec[i]);
+            if (!xobj || !vobj)
+                return JS_FALSE;
+            if (!js_XMLObjectOps.equality(cx, xobj, OBJECT_TO_JSVAL(vobj), bp))
+                return JS_FALSE;
+            if (!*bp)
+                break;
+        }
+
+        if (*bp && xml->xml_class == JSXML_CLASS_ELEMENT) {
+            n = xml->xml_attrs.length;
+            if (n != vxml->xml_attrs.length)
+                *bp = JS_FALSE;
+            for (i = 0; i < n; i++) {
+                attr = XMLARRAY_MEMBER(&xml->xml_attrs, i, JSXML);
+                j = XMLARRAY_FIND_MEMBER(&vxml->xml_attrs, attr, attr_identity);
+                if (j == XML_NOT_FOUND) {
+                    *bp = JS_FALSE;
+                    break;
+                }
+                vattr = XMLARRAY_MEMBER(&vxml->xml_attrs, j, JSXML);
+                *bp = !js_CompareStrings(attr->xml_value, vattr->xml_value);
+                if (!*bp)
+                    break;
+            }
+        }
+    }
+
+    return JS_TRUE;
+}
+
+/* ECMA-357 9.1.1.9 XML [[Equals]] and 9.2.1.9 XMLList [[Equals]]. */
+static JSBool
+Equals(JSContext *cx, JSXML *xml, jsval v, JSBool *bp)
+{
+    JSObject *vobj;
+    JSXML *vxml;
+
+    if (JSVAL_IS_PRIMITIVE(v)) {
+        *bp = JS_FALSE;
+        if (xml->xml_class == JSXML_CLASS_LIST) {
+            if (xml->xml_kids.length == 1) {
+                vxml = XMLARRAY_MEMBER(&xml->xml_kids, 0, JSXML);
+                vobj = js_GetXMLObject(cx, vxml);
+                if (!vobj)
+                    return JS_FALSE;
+                return js_XMLObjectOps.equality(cx, vobj, v, bp);
+            }
+            if (JSVAL_IS_VOID(v) && xml->xml_kids.length == 0)
+                *bp = JS_TRUE;
+        }
+    } else {
+        vobj = JSVAL_TO_OBJECT(v);
+        if (!OBJECT_IS_XML(cx, vobj)) {
+            *bp = JS_FALSE;
+        } else {
+            vxml = (JSXML *) JS_GetPrivate(cx, vobj);
+            if (!XMLEquals(cx, xml, vxml, bp))
+                return JS_FALSE;
+        }
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+Replace(JSContext *cx, JSXML *xml, jsval id, jsval v);
+
+static JSBool
+CheckCycle(JSContext *cx, JSXML *xml, JSXML *kid)
+{
+    do {
+        if (xml == kid) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                                 JSMSG_CYCLIC_VALUE, js_XML_str);
+            return JS_FALSE;
+        }
+    } while ((xml = xml->parent) != NULL);
+
+    return JS_TRUE;
+}
+
+/* ECMA-357 9.1.1.11 XML [[Insert]]. */
+static JSBool
+Insert(JSContext *cx, JSXML *xml, jsval id, jsval v)
+{
+    uint32 i, j, n;
+    JSXML *vxml, *kid;
+    JSObject *vobj;
+
+    if (!JSXML_HAS_KIDS(xml))
+        return JS_TRUE;
+
+    if (!js_IdIsIndex(id, &i)) {
+        ReportBadXMLName(cx, id);
+        return JS_FALSE;
+    }
+
+    n = 1;
+    vxml = NULL;
+    if (!JSVAL_IS_PRIMITIVE(v)) {
+        vobj = JSVAL_TO_OBJECT(v);
+        if (OBJECT_IS_XML(cx, vobj)) {
+            vxml = (JSXML *) JS_GetPrivate(cx, vobj);
+            if (!CheckCycle(cx, xml, vxml))
+                return JS_FALSE;
+            if (vxml->xml_class == JSXML_CLASS_LIST)
+                n = vxml->xml_kids.length;
+        }
+    }
+
+    if (n == 0)
+        return JS_TRUE;
+
+    if (!XMLArrayInsert(cx, &xml->xml_kids, i, n))
+        return JS_FALSE;
+
+    if (vxml && vxml->xml_class == JSXML_CLASS_LIST) {
+        for (j = 0; j < n; j++) {
+            kid = XMLARRAY_MEMBER(&vxml->xml_kids, j, JSXML);
+            kid->parent = xml;
+            XMLARRAY_SET_MEMBER(&xml->xml_kids, i + j, kid);
+
+            /* OPTION: enforce that descendants have superset namespaces. */
+        }
+    } else {
+        /*
+         * Tricky: ECMA-357 9.1.1.11 step 7 specifies:
+         *
+         *      For j = x.[[Length]]-1 downto i,
+         *              rename property ToString(j) of x to ToString(j + n)
+         *
+         * That loop, coded above, simply copies pointers up in xml->xml_kids.
+         * We don't need to change property "names", nor do we need to null
+         * pointers in the vxml->xml_class == JSXML_CLASS_LIST case, above.
+         *
+         * But here, before calling Replace, we must help Replace discern that
+         * the "properties" have been "renamed" by nulling the n xml->xml_kids
+         * slots that have been evacuated to make way for vxml.
+         */
+        for (j = 0; j < n; j++)
+            xml->xml_kids.vector[i + j] = NULL;
+        if (!Replace(cx, xml, id, v))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+IndexToIdVal(JSContext *cx, uint32 index, jsval *idvp)
+{
+    JSString *str;
+
+    if (index <= JSVAL_INT_MAX) {
+        *idvp = INT_TO_JSVAL(index);
+    } else {
+        str = js_NumberToString(cx, (jsdouble) index);
+        if (!str)
+            return JS_FALSE;
+        *idvp = STRING_TO_JSVAL(str);
+    }
+    return JS_TRUE;
+}
+
+/* ECMA-357 9.1.1.12 XML [[Replace]]. */
+static JSBool
+Replace(JSContext *cx, JSXML *xml, jsval id, jsval v)
+{
+    uint32 i, n;
+    JSXML *vxml, *kid;
+    JSObject *vobj;
+    jsval junk;
+    JSString *str;
+
+    if (!JSXML_HAS_KIDS(xml))
+        return JS_TRUE;
+
+    if (!js_IdIsIndex(id, &i)) {
+        ReportBadXMLName(cx, id);
+        return JS_FALSE;
+    }
+
+    /*
+     * 9.1.1.12
+     * [[Replace]] handles _i >= x.[[Length]]_ by incrementing _x.[[Length]_.
+     * It should therefore constrain callers to pass in _i <= x.[[Length]]_.
+     */
+    n = xml->xml_kids.length;
+    JS_ASSERT(i <= n);
+    if (i >= n) {
+        if (!IndexToIdVal(cx, n, &id))
+            return JS_FALSE;
+        i = n;
+    }
+
+    vxml = NULL;
+    if (!JSVAL_IS_PRIMITIVE(v)) {
+        vobj = JSVAL_TO_OBJECT(v);
+        if (OBJECT_IS_XML(cx, vobj))
+            vxml = (JSXML *) JS_GetPrivate(cx, vobj);
+    }
+
+    switch (vxml ? vxml->xml_class : JSXML_CLASS_LIMIT) {
+      case JSXML_CLASS_ELEMENT:
+        /* OPTION: enforce that descendants have superset namespaces. */
+        if (!CheckCycle(cx, xml, vxml))
+            return JS_FALSE;
+      case JSXML_CLASS_COMMENT:
+      case JSXML_CLASS_PROCESSING_INSTRUCTION:
+      case JSXML_CLASS_TEXT:
+        goto do_replace;
+
+      case JSXML_CLASS_LIST:
+        if (i < n && !DeleteByIndex(cx, xml, id, &junk))
+            return JS_FALSE;
+        if (!Insert(cx, xml, id, v))
+            return JS_FALSE;
+        break;
+
+      default:
+        str = js_ValueToString(cx, v);
+        if (!str)
+            return JS_FALSE;
+
+        vxml = js_NewXML(cx, JSXML_CLASS_TEXT);
+        if (!vxml)
+            return JS_FALSE;
+        vxml->xml_value = str;
+
+      do_replace:
+        vxml->parent = xml;
+        if (i < n) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid)
+                kid->parent = NULL;
+        }
+        if (!XMLARRAY_ADD_MEMBER(cx, &xml->xml_kids, i, vxml))
+            return JS_FALSE;
+        break;
+    }
+
+    return JS_TRUE;
+}
+
+/* Forward declared -- its implementation uses other statics that call it. */
+static JSBool
+ResolveValue(JSContext *cx, JSXML *list, JSXML **result);
+
+/* ECMA-357 9.1.1.3 XML [[Delete]], 9.2.1.3 XML [[Delete]]. */
+static JSBool
+DeleteProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSXML *xml, *kid, *parent;
+    JSBool isIndex;
+    JSXMLArray *array;
+    uint32 length, index, deleteCount;
+    JSXMLQName *nameqn;
+    jsid funid;
+    JSObject *nameobj, *kidobj;
+    JSXMLNameMatcher matcher;
+
+    xml = (JSXML *) JS_GetPrivate(cx, obj);
+    isIndex = js_IdIsIndex(id, &index);
+    if (JSXML_HAS_KIDS(xml)) {
+        array = &xml->xml_kids;
+        length = array->length;
+    } else {
+        array = NULL;
+        length = 0;
+    }
+
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        /* ECMA-357 9.2.1.3. */
+        if (isIndex && index < length) {
+            kid = XMLARRAY_MEMBER(array, index, JSXML);
+            parent = kid->parent;
+            if (parent) {
+                JS_ASSERT(parent != xml);
+                JS_ASSERT(JSXML_HAS_KIDS(parent));
+
+                if (kid->xml_class == JSXML_CLASS_ATTRIBUTE) {
+                    nameqn = kid->name;
+                    nameobj = js_GetAttributeNameObject(cx, nameqn);
+                    if (!nameobj || !js_GetXMLObject(cx, parent))
+                        return JS_FALSE;
+
+                    id = OBJECT_TO_JSVAL(nameobj);
+                    if (!DeleteProperty(cx, parent->object, id, vp))
+                        return JS_FALSE;
+                } else {
+                    index = XMLARRAY_FIND_MEMBER(&parent->xml_kids, kid, NULL);
+                    JS_ASSERT(index != XML_NOT_FOUND);
+                    if (!IndexToIdVal(cx, index, &id))
+                        return JS_FALSE;
+                    if (!DeleteByIndex(cx, parent, id, vp))
+                        return JS_FALSE;
+                }
+            }
+
+            XMLArrayDelete(cx, array, index, JS_TRUE);
+        } else {
+            for (index = 0; index < length; index++) {
+                kid = XMLARRAY_MEMBER(array, index, JSXML);
+                if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+                    kidobj = js_GetXMLObject(cx, kid);
+                    if (!kidobj || !DeleteProperty(cx, kidobj, id, vp))
+                        return JS_FALSE;
+                }
+            }
+        }
+    } else {
+        /* ECMA-357 9.1.1.3. */
+        if (isIndex) {
+            /* See NOTE in spec: this variation is reserved for future use. */
+            ReportBadXMLName(cx, id);
+            return JS_FALSE;
+        }
+
+        nameqn = ToXMLName(cx, id, &funid);
+        if (!nameqn)
+            return JS_FALSE;
+        if (funid)
+            goto out;
+        nameobj = nameqn->object;
+
+        if (OBJ_GET_CLASS(cx, nameobj) == &js_AttributeNameClass) {
+            if (xml->xml_class != JSXML_CLASS_ELEMENT)
+                goto out;
+            array = &xml->xml_attrs;
+            length = array->length;
+            matcher = MatchAttrName;
+        } else {
+            matcher = MatchElemName;
+        }
+        if (length != 0) {
+            deleteCount = 0;
+            for (index = 0; index < length; index++) {
+                kid = XMLARRAY_MEMBER(array, index, JSXML);
+                if (matcher(nameqn, kid)) {
+                    kid->parent = NULL;
+                    XMLArrayDelete(cx, array, index, JS_FALSE);
+                    ++deleteCount;
+                } else if (deleteCount != 0) {
+                    XMLARRAY_SET_MEMBER(array,
+                                        index - deleteCount,
+                                        array->vector[index]);
+                }
+            }
+            array->length -= deleteCount;
+        }
+    }
+
+out:
+    *vp = JSVAL_TRUE;
+    return JS_TRUE;
+}
+
+/*
+ * Class compatibility mask flag bits stored in xml_methods[i].extra.  If XML
+ * and XMLList are unified (an incompatible change to ECMA-357), then we don't
+ * need any of this.
+ */
+#define XML_MASK                0x1
+#define XMLLIST_MASK            0x2
+#define GENERIC_MASK            (XML_MASK | XMLLIST_MASK)
+#define CLASS_TO_MASK(c)        (1 + ((c) == JSXML_CLASS_LIST))
+
+static JSBool
+GetFunction(JSContext *cx, JSObject *obj, JSXML *xml, jsid id, jsval *vp)
+{
+    jsval fval;
+    JSFunction *fun;
+
+    do {
+        /* XXXbe really want a separate scope for function::*. */
+        if (!js_GetProperty(cx, obj, id, &fval))
+            return JS_FALSE;
+        if (JSVAL_IS_FUNCTION(cx, fval)) {
+            if (xml && OBJECT_IS_XML(cx, obj)) {
+                fun = (JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(fval));
+                if (fun->spare &&
+                    (fun->spare & CLASS_TO_MASK(xml->xml_class)) == 0) {
+                    /* XML method called on XMLList or vice versa. */
+                    fval = JSVAL_VOID;
+                }
+            }
+            break;
+        }
+    } while ((obj = OBJ_GET_PROTO(cx, obj)) != NULL);
+    *vp = fval;
+    return JS_TRUE;
+}
+
+static JSBool
+SyncInScopeNamespaces(JSContext *cx, JSXML *xml)
+{
+    JSXMLArray *nsarray;
+    uint32 i, n;
+    JSXMLNamespace *ns;
+
+    nsarray = &xml->xml_namespaces;
+    while ((xml = xml->parent) != NULL) {
+        for (i = 0, n = xml->xml_namespaces.length; i < n; i++) {
+            ns = XMLARRAY_MEMBER(&xml->xml_namespaces, i, JSXMLNamespace);
+            if (!XMLARRAY_HAS_MEMBER(nsarray, ns, namespace_identity)) {
+                if (!XMLARRAY_APPEND(cx, nsarray, ns))
+                    return JS_FALSE;
+            }
+        }
+    }
+    return JS_TRUE;
+}
+
+/* ECMA-357 9.1.1.1 XML [[Get]] and 9.2.1.1 XMLList [[Get]]. */
+static JSBool
+GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSXML *xml, *list, *kid;
+    uint32 index, i, n;
+    JSObject *kidobj, *listobj, *nameobj;
+    JSXMLQName *nameqn;
+    jsid funid;
+    JSBool ok;
+    jsval kidval;
+    JSXMLArray *array;
+    JSXMLNameMatcher matcher;
+
+    xml = (JSXML *) JS_GetInstancePrivate(cx, obj, &js_XMLClass, NULL);
+    if (!xml)
+        return JS_TRUE;
+
+retry:
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        /* ECMA-357 9.2.1.1 starts here. */
+        if (js_IdIsIndex(id, &index)) {
+            /*
+             * Erratum: 9.2 is not completely clear that indexed properties
+             * correspond to kids, but that's what it seems to say, and it's
+             * what any sane user would want.
+             */
+            if (index < xml->xml_kids.length) {
+                kid = XMLARRAY_MEMBER(&xml->xml_kids, index, JSXML);
+                kidobj = js_GetXMLObject(cx, kid);
+                if (!kidobj)
+                    return JS_FALSE;
+
+                *vp = OBJECT_TO_JSVAL(kidobj);
+            } else {
+                *vp = JSVAL_VOID;
+            }
+            return JS_TRUE;
+        }
+
+        nameqn = ToXMLName(cx, id, &funid);
+        if (!nameqn)
+            return JS_FALSE;
+        if (funid)
+            return GetFunction(cx, obj, xml, funid, vp);
+
+        /*
+         * Recursion through GetProperty may allocate more list objects, so
+         * we make use of local root scopes here.  Each new allocation will
+         * push the newborn onto the local root stack.
+         */
+        ok = JS_EnterLocalRootScope(cx);
+        if (!ok)
+            return JS_FALSE;
+
+        /*
+         * NB: nameqn is already protected from GC by cx->newborn[GCX_OBJECT]
+         * until listobj is created.  After that, a local root keeps listobj
+         * alive, and listobj's private keeps nameqn alive via targetprop.
+         */
+        listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+        if (!listobj) {
+            ok = JS_FALSE;
+        } else {
+            list = (JSXML *) JS_GetPrivate(cx, listobj);
+            list->xml_target = xml;
+            list->xml_targetprop = nameqn;
+
+            for (i = 0, n = JSXML_LENGTH(xml); i < n; i++) {
+                kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+                if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+                    kidobj = js_GetXMLObject(cx, kid);
+                    if (!kidobj) {
+                        ok = JS_FALSE;
+                        break;
+                    }
+                    ok = GetProperty(cx, kidobj, id, &kidval);
+                    if (!ok)
+                        break;
+                    kidobj = JSVAL_TO_OBJECT(kidval);
+                    kid = (JSXML *) JS_GetPrivate(cx, kidobj);
+                    if (JSXML_LENGTH(kid) > 0) {
+                        ok = Append(cx, list, kid);
+                        if (!ok)
+                            break;
+                    }
+                }
+            }
+        }
+    } else {
+        /* ECMA-357 9.1.1.1 starts here. */
+        if (js_IdIsIndex(id, &index)) {
+            obj = ToXMLList(cx, OBJECT_TO_JSVAL(obj));
+            if (!obj)
+                return JS_FALSE;
+            xml = (JSXML *) JS_GetPrivate(cx, obj);
+            goto retry;
+        }
+
+        nameqn = ToXMLName(cx, id, &funid);
+        if (!nameqn)
+            return JS_FALSE;
+        if (funid)
+            return GetFunction(cx, obj, xml, funid, vp);
+        nameobj = nameqn->object;
+
+        /*
+         * Recursion through GetProperty may allocate more list objects, so
+         * we make use of local root scopes here.  Each new allocation will
+         * push the newborn onto the local root stack.
+         */
+        ok = JS_EnterLocalRootScope(cx);
+        if (!ok)
+            return JS_FALSE;
+
+        listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+        if (!listobj) {
+            ok = JS_FALSE;
+        } else {
+            list = (JSXML *) JS_GetPrivate(cx, listobj);
+            list->xml_target = xml;
+            list->xml_targetprop = nameqn;
+
+            if (JSXML_HAS_KIDS(xml)) {
+                if (OBJ_GET_CLASS(cx, nameobj) == &js_AttributeNameClass) {
+                    array = &xml->xml_attrs;
+                    matcher = MatchAttrName;
+                } else {
+                    array = &xml->xml_kids;
+                    matcher = MatchElemName;
+                }
+                for (i = 0, n = array->length; i < n; i++) {
+                    kid = XMLARRAY_MEMBER(array, i, JSXML);
+                    if (matcher(nameqn, kid)) {
+                        if (array == &xml->xml_kids &&
+                            kid->xml_class == JSXML_CLASS_ELEMENT) {
+                            ok = SyncInScopeNamespaces(cx, kid);
+                            if (!ok)
+                                break;
+                        }
+                        ok = Append(cx, list, kid);
+                        if (!ok)
+                            break;
+                    }
+                }
+            }
+        }
+    }
+
+    /* Common tail code for list and non-list cases. */
+    JS_LeaveLocalRootScope(cx);
+    if (!ok)
+        return JS_FALSE;
+
+    *vp = OBJECT_TO_JSVAL(listobj);
+    return JS_TRUE;
+}
+
+static JSXML *
+CopyOnWrite(JSContext *cx, JSXML *xml, JSObject *obj)
+{
+    JS_ASSERT(xml->object != obj);
+
+    xml = DeepCopy(cx, xml, obj, 0);
+    if (!xml)
+        return NULL;
+
+    JS_ASSERT(xml->object == obj);
+    return xml;
+}
+
+#define CHECK_COPY_ON_WRITE(cx,xml,obj)                                       \
+    (xml->object == obj ? xml : CopyOnWrite(cx, xml, obj))
+
+static JSString *
+KidToString(JSContext *cx, JSXML *xml, uint32 index)
+{
+    JSXML *kid;
+    JSObject *kidobj;
+
+    kid = XMLARRAY_MEMBER(&xml->xml_kids, index, JSXML);
+    kidobj = js_GetXMLObject(cx, kid);
+    if (!kidobj)
+        return NULL;
+    return js_ValueToString(cx, OBJECT_TO_JSVAL(kidobj));
+}
+
+/* ECMA-357 9.1.1.2 XML [[Put]] and 9.2.1.2 XMLList [[Put]]. */
+static JSBool
+PutProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSBool ok, primitiveAssign;
+    JSXML *xml, *vxml, *rxml, *kid, *attr, *parent, *copy, *kid2, *match;
+    JSObject *vobj, *nameobj, *attrobj, *parentobj, *kidobj, *copyobj;
+    JSXMLQName *targetprop, *nameqn, *attrqn;
+    uint32 index, i, j, k, n, q;
+    jsval attrval, nsval, junk;
+    jsid funid;
+    JSString *left, *right, *space;
+    JSXMLNamespace *ns;
+
+    xml = (JSXML *) JS_GetInstancePrivate(cx, obj, &js_XMLClass, NULL);
+    if (!xml)
+        return JS_TRUE;
+
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml)
+        return JS_FALSE;
+
+    /* Precompute vxml for 9.2.1.2 2(c)(vii)(2-3) and 2(d) and 9.1.1.2 1. */
+    vxml = NULL;
+    if (!JSVAL_IS_PRIMITIVE(*vp)) {
+        vobj = JSVAL_TO_OBJECT(*vp);
+        if (OBJECT_IS_XML(cx, vobj))
+            vxml = (JSXML *) JS_GetPrivate(cx, vobj);
+    }
+
+    /* Control flow after here must exit via label out. */
+    ok = JS_EnterLocalRootScope(cx);
+    if (!ok)
+        return JS_FALSE;
+
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        /* ECMA-357 9.2.1.2. */
+        if (js_IdIsIndex(id, &index)) {
+            /* Step 1 sets i to the property index. */
+            i = index;
+
+            /* 2(a-b). */
+            if (xml->xml_target) {
+                ok = ResolveValue(cx, xml->xml_target, &rxml);
+                if (!ok)
+                    goto out;
+                if (!rxml)
+                    goto out;
+                JS_ASSERT(rxml->object);
+            } else {
+                rxml = NULL;
+            }
+
+            /* 2(c). */
+            if (index >= xml->xml_kids.length) {
+                /* 2(c)(i). */
+                if (rxml) {
+                    if (rxml->xml_class == JSXML_CLASS_LIST) {
+                        if (rxml->xml_kids.length != 1)
+                            goto out;
+                        rxml = XMLARRAY_MEMBER(&rxml->xml_kids, 0, JSXML);
+                        ok = js_GetXMLObject(cx, rxml) != NULL;
+                        if (!ok)
+                            goto out;
+                    }
+
+                    /*
+                     * Erratum: ECMA-357 9.2.1.2 step 2(c)(ii) sets
+                     * _y.[[Parent]] = r_ where _r_ is the result of
+                     * [[ResolveValue]] called on _x.[[TargetObject]] in
+                     * 2(a)(i).  This can result in text parenting text:
+                     *
+                     *    var MYXML = new XML();
+                     *    MYXML.appendChild(new XML("<TEAM>Giants</TEAM>"));
+                     *
+                     * (testcase from Werner Sharp <wsharp at macromedia.com>).
+                     *
+                     * To match insertChildAfter, insertChildBefore,
+                     * prependChild, and setChildren, we should silently
+                     * do nothing in this case.
+                     */
+                    if (!JSXML_HAS_KIDS(rxml))
+                        goto out;
+                }
+
+                /* 2(c)(ii) is distributed below as several js_NewXML calls. */
+                targetprop = xml->xml_targetprop;
+                if (!targetprop || IS_STAR(targetprop->localName)) {
+                    /* 2(c)(iv)(1-2), out of order w.r.t. 2(c)(iii). */
+                    kid = js_NewXML(cx, JSXML_CLASS_TEXT);
+                    if (!kid)
+                        goto bad;
+                } else {
+                    nameobj = js_GetXMLQNameObject(cx, targetprop);
+                    if (!nameobj)
+                        goto bad;
+                    if (OBJ_GET_CLASS(cx, nameobj) == &js_AttributeNameClass) {
+                        /*
+                         * 2(c)(iii)(1-3).
+                         * Note that rxml can't be null here, because target
+                         * and targetprop are non-null.
+                         */
+                        ok = GetProperty(cx, rxml->object, id, &attrval);
+                        if (!ok)
+                            goto out;
+                        attrobj = JSVAL_TO_OBJECT(attrval);
+                        attr = (JSXML *) JS_GetPrivate(cx, attrobj);
+                        if (JSXML_LENGTH(attr) != 0)
+                            goto out;
+
+                        kid = js_NewXML(cx, JSXML_CLASS_ATTRIBUTE);
+                    } else {
+                        /* 2(c)(v). */
+                        kid = js_NewXML(cx, JSXML_CLASS_ELEMENT);
+                    }
+                    if (!kid)
+                        goto bad;
+
+                    /* An important bit of 2(c)(ii). */
+                    kid->name = targetprop;
+                }
+
+                /* Final important bit of 2(c)(ii). */
+                kid->parent = rxml;
+
+                /* 2(c)(vi-vii). */
+                i = xml->xml_kids.length;
+                if (kid->xml_class != JSXML_CLASS_ATTRIBUTE) {
+                    /*
+                     * 2(c)(vii)(1) tests whether _y.[[Parent]]_ is not null.
+                     * y.[[Parent]] is here called kid->parent, which we know
+                     * from 2(c)(ii) is _r_, here called rxml.  So let's just
+                     * test that!  Erratum, the spec should be simpler here.
+                     */
+                    if (rxml) {
+                        JS_ASSERT(JSXML_HAS_KIDS(rxml));
+                        n = rxml->xml_kids.length;
+                        j = n - 1;
+                        if (n != 0 && i != 0) {
+                            for (n = j, j = 0; j < n; j++) {
+                                if (rxml->xml_kids.vector[j] ==
+                                    xml->xml_kids.vector[i-1]) {
+                                    break;
+                                }
+                            }
+                        }
+
+                        kidobj = js_GetXMLObject(cx, kid);
+                        if (!kidobj)
+                            goto bad;
+                        ok = Insert(cx, rxml, INT_TO_JSVAL(j + 1),
+                                    OBJECT_TO_JSVAL(kidobj));
+                        if (!ok)
+                            goto out;
+                    }
+
+                    /*
+                     * 2(c)(vii)(2-3).
+                     * Erratum: [[PropertyName]] in 2(c)(vii)(3) must be a
+                     * typo for [[TargetProperty]].
+                     */
+                    if (vxml) {
+                        kid->name = (vxml->xml_class == JSXML_CLASS_LIST)
+                                    ? vxml->xml_targetprop
+                                    : vxml->name;
+                    }
+                }
+
+                /* 2(c)(viii). */
+                ok = Append(cx, xml, kid);
+                if (!ok)
+                    goto out;
+            }
+
+            /* 2(d). */
+            if (!vxml ||
+                vxml->xml_class == JSXML_CLASS_TEXT ||
+                vxml->xml_class == JSXML_CLASS_ATTRIBUTE) {
+                ok = JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp);
+                if (!ok)
+                    goto out;
+            }
+
+            /* 2(e). */
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            parent = kid->parent;
+            if (kid->xml_class == JSXML_CLASS_ATTRIBUTE) {
+                nameobj = js_GetAttributeNameObject(cx, kid->name);
+                if (!nameobj)
+                    goto bad;
+                id = OBJECT_TO_JSVAL(nameobj);
+
+                /* 2(e)(i). */
+                parentobj = parent->object;
+                ok = PutProperty(cx, parentobj, id, vp);
+                if (!ok)
+                    goto out;
+
+                /* 2(e)(ii). */
+                ok = GetProperty(cx, parentobj, id, vp);
+                if (!ok)
+                    goto out;
+                attr = (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(*vp));
+
+                /* 2(e)(iii). */
+                xml->xml_kids.vector[i] = attr->xml_kids.vector[0];
+            }
+
+            /* 2(f). */
+            else if (vxml && vxml->xml_class == JSXML_CLASS_LIST) {
+                /* 2(f)(i) Create a shallow copy _c_ of _V_. */
+                copyobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+                if (!copyobj)
+                    goto bad;
+                copy = (JSXML *) JS_GetPrivate(cx, copyobj);
+                n = vxml->xml_kids.length;
+                ok = XMLArraySetCapacity(cx, &copy->xml_kids, n);
+                if (!ok)
+                    goto out;
+                for (k = 0; k < n; k++) {
+                    kid2 = XMLARRAY_MEMBER(&vxml->xml_kids, k, JSXML);
+                    XMLARRAY_SET_MEMBER(&copy->xml_kids, k, kid2);
+                }
+                copy->xml_kids.length = n;
+
+                JS_ASSERT(parent != xml);
+                if (parent) {
+                    q = XMLARRAY_FIND_MEMBER(&parent->xml_kids, kid, NULL);
+                    JS_ASSERT(q != XML_NOT_FOUND);
+
+                    ok = IndexToIdVal(cx, q, &id);
+                    if (!ok)
+                        goto out;
+                    ok = Replace(cx, parent, id, OBJECT_TO_JSVAL(copyobj));
+                    if (!ok)
+                        goto out;
+
+#ifdef DEBUG
+                    /* Erratum: this loop in the spec is useless. */
+                    for (j = 0, n = copy->xml_kids.length; j < n; j++) {
+                        kid2 = XMLARRAY_MEMBER(&parent->xml_kids, q + j, JSXML);
+                        JS_ASSERT(XMLARRAY_MEMBER(&copy->xml_kids, j, JSXML)
+                                  == kid2);
+                    }
+#endif
+                }
+
+                /*
+                 * 2(f)(iv-vi).
+                 * Erratum: notice the unhandled zero-length V basis case and
+                 * the off-by-one errors for the n != 0 cases in the spec.
+                 */
+                if (n == 0) {
+                    XMLArrayDelete(cx, &xml->xml_kids, i, JS_TRUE);
+                } else {
+                    ok = XMLArrayInsert(cx, &xml->xml_kids, i + 1, n - 1);
+                    if (!ok)
+                        goto out;
+
+                    for (j = 0; j < n; j++)
+                        xml->xml_kids.vector[i + j] = copy->xml_kids.vector[j];
+                }
+            }
+
+            /* 2(g). */
+            else if (vxml || JSXML_HAS_VALUE(kid)) {
+                if (parent) {
+                    q = XMLARRAY_FIND_MEMBER(&parent->xml_kids, kid, NULL);
+                    JS_ASSERT(q != XML_NOT_FOUND);
+
+                    ok = IndexToIdVal(cx, q, &id);
+                    if (!ok)
+                        goto out;
+                    ok = Replace(cx, parent, id, *vp);
+                    if (!ok)
+                        goto out;
+
+                    vxml = XMLARRAY_MEMBER(&parent->xml_kids, q, JSXML);
+                    *vp = OBJECT_TO_JSVAL(vxml->object);
+                }
+
+                /*
+                 * 2(g)(iii).
+                 * Erratum: _V_ may not be of type XML, but all index-named
+                 * properties _x[i]_ in an XMLList _x_ must be of type XML,
+                 * according to 9.2.1.1 Overview and other places in the spec.
+                 *
+                 * Thanks to 2(d), we know _V_ (*vp here) is either a string
+                 * or an XML/XMLList object.  If *vp is a string, call ToXML
+                 * on it to satisfy the constraint.
+                 */
+                if (!vxml) {
+                    JS_ASSERT(JSVAL_IS_STRING(*vp));
+                    vobj = ToXML(cx, *vp);
+                    if (!vobj)
+                        goto bad;
+                    *vp = OBJECT_TO_JSVAL(vobj);
+                    vxml = (JSXML *) JS_GetPrivate(cx, vobj);
+                }
+                XMLARRAY_SET_MEMBER(&xml->xml_kids, i, vxml);
+            }
+
+            /* 2(h). */
+            else {
+                kidobj = js_GetXMLObject(cx, kid);
+                if (!kidobj)
+                    goto bad;
+                id = ATOM_KEY(cx->runtime->atomState.starAtom);
+                ok = PutProperty(cx, kidobj, id, vp);
+                if (!ok)
+                    goto out;
+            }
+        } else {
+            /*
+             * 3.
+             * Erratum: if x.[[Length]] > 1 or [[ResolveValue]] returns null
+             * or an r with r.[[Length]] != 1, throw TypeError.
+             */
+            n = JSXML_LENGTH(xml);
+            if (n > 1)
+                goto type_error;
+            if (n == 0) {
+                ok = ResolveValue(cx, xml, &rxml);
+                if (!ok)
+                    goto out;
+                if (!rxml || JSXML_LENGTH(rxml) != 1)
+                    goto type_error;
+                ok = Append(cx, xml, rxml);
+                if (!ok)
+                    goto out;
+            }
+            JS_ASSERT(JSXML_LENGTH(xml) == 1);
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, 0, JSXML);
+            kidobj = js_GetXMLObject(cx, kid);
+            if (!kidobj)
+                goto bad;
+            ok = PutProperty(cx, kidobj, id, vp);
+            if (!ok)
+                goto out;
+        }
+    } else {
+        /*
+         * ECMA-357 9.1.1.2.
+         * Erratum: move steps 3 and 4 to before 1 and 2, to avoid wasted
+         * effort in ToString or [[DeepCopy]].
+         */
+        if (js_IdIsIndex(id, &index)) {
+            /* See NOTE in spec: this variation is reserved for future use. */
+            ReportBadXMLName(cx, id);
+            goto bad;
+        }
+
+        nameqn = ToXMLName(cx, id, &funid);
+        if (!nameqn)
+            goto bad;
+        if (funid) {
+            ok = js_SetProperty(cx, obj, funid, vp);
+            goto out;
+        }
+        nameobj = nameqn->object;
+
+        if (JSXML_HAS_VALUE(xml))
+            goto out;
+
+        if (!vxml ||
+            vxml->xml_class == JSXML_CLASS_TEXT ||
+            vxml->xml_class == JSXML_CLASS_ATTRIBUTE) {
+            ok = JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp);
+            if (!ok)
+                goto out;
+        } else {
+            rxml = DeepCopyInLRS(cx, vxml, 0);
+            if (!rxml || !js_GetXMLObject(cx, rxml))
+                goto bad;
+            vxml = rxml;
+            *vp = OBJECT_TO_JSVAL(vxml->object);
+        }
+
+        /*
+         * 6.
+         * Erratum: why is this done here, so early? use is way later....
+         */
+        ok = js_GetDefaultXMLNamespace(cx, &nsval);
+        if (!ok)
+            goto out;
+
+        if (OBJ_GET_CLASS(cx, nameobj) == &js_AttributeNameClass) {
+            /* 7(a). */
+            if (!js_IsXMLName(cx, OBJECT_TO_JSVAL(nameobj)))
+                goto out;
+
+            /* 7(b-c). */
+            if (vxml && vxml->xml_class == JSXML_CLASS_LIST) {
+                n = vxml->xml_kids.length;
+                if (n == 0) {
+                    *vp = STRING_TO_JSVAL(cx->runtime->emptyString);
+                } else {
+                    left = KidToString(cx, vxml, 0);
+                    if (!left)
+                        goto bad;
+
+                    space = ATOM_TO_STRING(cx->runtime->atomState.spaceAtom);
+                    for (i = 1; i < n; i++) {
+                        left = js_ConcatStrings(cx, left, space);
+                        if (!left)
+                            goto bad;
+                        right = KidToString(cx, vxml, i);
+                        if (!right)
+                            goto bad;
+                        left = js_ConcatStrings(cx, left, right);
+                        if (!left)
+                            goto bad;
+                    }
+
+                    *vp = STRING_TO_JSVAL(left);
+                }
+            } else {
+                ok = JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp);
+                if (!ok)
+                    goto out;
+            }
+
+            /* 7(d-e). */
+            match = NULL;
+            for (i = 0, n = xml->xml_attrs.length; i < n; i++) {
+                attr = XMLARRAY_MEMBER(&xml->xml_attrs, i, JSXML);
+                attrqn = attr->name;
+                if (!js_CompareStrings(attrqn->localName, nameqn->localName) &&
+                    (!nameqn->uri ||
+                     !js_CompareStrings(attrqn->uri, nameqn->uri))) {
+                    if (!match) {
+                        match = attr;
+                    } else {
+                        nameobj = js_GetAttributeNameObject(cx, attrqn);
+                        if (!nameobj)
+                            goto bad;
+
+                        id = OBJECT_TO_JSVAL(nameobj);
+                        ok = DeleteProperty(cx, obj, id, &junk);
+                        if (!ok)
+                            goto out;
+                        --i;
+                    }
+                }
+            }
+
+            /* 7(f). */
+            attr = match;
+            if (!attr) {
+                /* 7(f)(i-ii). */
+                if (!nameqn->uri) {
+                    left = right = cx->runtime->emptyString;
+                } else {
+                    left = nameqn->uri;
+                    right = nameqn->prefix;
+                }
+                nameqn = js_NewXMLQName(cx, left, right, nameqn->localName);
+                if (!nameqn)
+                    goto bad;
+
+                /* 7(f)(iii). */
+                attr = js_NewXML(cx, JSXML_CLASS_ATTRIBUTE);
+                if (!attr)
+                    goto bad;
+                attr->parent = xml;
+                attr->name = nameqn;
+
+                /* 7(f)(iv). */
+                ok = XMLARRAY_ADD_MEMBER(cx, &xml->xml_attrs, n, attr);
+                if (!ok)
+                    goto out;
+
+                /* 7(f)(v-vi). */
+                ns = GetNamespace(cx, nameqn, NULL);
+                if (!ns)
+                    goto bad;
+                ok = AddInScopeNamespace(cx, xml, ns);
+                if (!ok)
+                    goto out;
+            }
+
+            /* 7(g). */
+            attr->xml_value = JSVAL_TO_STRING(*vp);
+            goto out;
+        }
+
+        /* 8-9. */
+        if (!js_IsXMLName(cx, OBJECT_TO_JSVAL(nameobj)) &&
+            !IS_STAR(nameqn->localName)) {
+            goto out;
+        }
+
+        /* 10-11. */
+        id = JSVAL_VOID;
+        primitiveAssign = !vxml && !IS_STAR(nameqn->localName);
+
+        /* 12. */
+        k = n = xml->xml_kids.length;
+        kid2 = NULL;
+        while (k != 0) {
+            --k;
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, k, JSXML);
+            if (MatchElemName(nameqn, kid)) {
+                if (!JSVAL_IS_VOID(id)) {
+                    ok = DeleteByIndex(cx, xml, id, &junk);
+                    if (!ok)
+                        goto out;
+                }
+                ok = IndexToIdVal(cx, k, &id);
+                if (!ok)
+                    goto out;
+                kid2 = kid;
+            }
+        }
+
+        /*
+         * Erratum: ECMA-357 specified child insertion inconsistently:
+         * insertChildBefore and insertChildAfter insert an arbitrary XML
+         * instance, and therefore can create cycles, but appendChild as
+         * specified by the "Overview" of 13.4.4.3 calls [[DeepCopy]] on
+         * its argument.  But the "Semantics" in 13.4.4.3 do not include
+         * any [[DeepCopy]] call.
+         *
+         * Fixing this (https://bugzilla.mozilla.org/show_bug.cgi?id=312692)
+         * required adding cycle detection, and allowing duplicate kids to
+         * be created (see comment 6 in the bug).  Allowing duplicate kid
+         * references means the loop above will delete all but the lowest
+         * indexed reference, and each [[DeleteByIndex]] nulls the kid's
+         * parent.  Thus the need to restore parent here.  This is covered
+         * by https://bugzilla.mozilla.org/show_bug.cgi?id=327564.
+         */
+        if (kid2) {
+            JS_ASSERT(kid2->parent == xml || !kid2->parent);
+            if (!kid2->parent)
+                kid2->parent = xml;
+        }
+
+        /* 13. */
+        if (JSVAL_IS_VOID(id)) {
+            /* 13(a). */
+            ok = IndexToIdVal(cx, n, &id);
+            if (!ok)
+                goto out;
+
+            /* 13(b). */
+            if (primitiveAssign) {
+                if (!nameqn->uri) {
+                    ns = (JSXMLNamespace *)
+                         JS_GetPrivate(cx, JSVAL_TO_OBJECT(nsval));
+                    left = ns->uri;
+                    right = ns->prefix;
+                } else {
+                    left = nameqn->uri;
+                    right = nameqn->prefix;
+                }
+                nameqn = js_NewXMLQName(cx, left, right, nameqn->localName);
+                if (!nameqn)
+                    goto bad;
+
+                /* 13(b)(iii). */
+                vobj = js_NewXMLObject(cx, JSXML_CLASS_ELEMENT);
+                if (!vobj)
+                    goto bad;
+                vxml = (JSXML *) JS_GetPrivate(cx, vobj);
+                vxml->parent = xml;
+                vxml->name = nameqn;
+
+                /* 13(b)(iv-vi). */
+                ns = GetNamespace(cx, nameqn, NULL);
+                if (!ns)
+                    goto bad;
+                ok = Replace(cx, xml, id, OBJECT_TO_JSVAL(vobj));
+                if (!ok)
+                    goto out;
+                ok = AddInScopeNamespace(cx, vxml, ns);
+                if (!ok)
+                    goto out;
+            }
+        }
+
+        /* 14. */
+        if (primitiveAssign) {
+            js_IdIsIndex(id, &index);
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, index, JSXML);
+            if (JSXML_HAS_KIDS(kid)) {
+                XMLArrayFinish(cx, &kid->xml_kids);
+                ok = XMLArrayInit(cx, &kid->xml_kids, 1);
+                if (!ok)
+                    goto out;
+            }
+
+            /* 14(b-c). */
+            /* XXXbe Erratum? redundant w.r.t. 7(b-c) else clause above */
+            ok = JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp);
+            if (!ok)
+                goto out;
+            if (!IS_EMPTY(JSVAL_TO_STRING(*vp)))
+                ok = Replace(cx, kid, JSVAL_ZERO, *vp);
+        } else {
+            /* 15(a). */
+            ok = Replace(cx, xml, id, *vp);
+        }
+    }
+
+out:
+    JS_LeaveLocalRootScope(cx);
+    return ok;
+
+type_error:
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                         JSMSG_BAD_XMLLIST_PUT,
+                         js_ValueToPrintableString(cx, id));
+bad:
+    ok = JS_FALSE;
+    goto out;
+}
+
+/* ECMA-357 9.1.1.10 XML [[ResolveValue]], 9.2.1.10 XMLList [[ResolveValue]]. */
+static JSBool
+ResolveValue(JSContext *cx, JSXML *list, JSXML **result)
+{
+    JSXML *target, *base;
+    JSXMLQName *targetprop;
+    jsval id, tv;
+
+    /* Our caller must be protecting newborn objects. */
+    JS_ASSERT(cx->localRootStack);
+
+    if (list->xml_class != JSXML_CLASS_LIST || list->xml_kids.length != 0) {
+        if (!js_GetXMLObject(cx, list))
+            return JS_FALSE;
+        *result = list;
+        return JS_TRUE;
+    }
+
+    target = list->xml_target;
+    targetprop = list->xml_targetprop;
+    if (!target ||
+        !targetprop ||
+        OBJ_GET_CLASS(cx, targetprop->object) == &js_AttributeNameClass ||
+        IS_STAR(targetprop->localName)) {
+        *result = NULL;
+        return JS_TRUE;
+    }
+
+    if (!ResolveValue(cx, target, &base))
+        return JS_FALSE;
+    if (!base) {
+        *result = NULL;
+        return JS_TRUE;
+    }
+    if (!js_GetXMLObject(cx, base))
+        return JS_FALSE;
+
+    id = OBJECT_TO_JSVAL(targetprop->object);
+    if (!GetProperty(cx, base->object, id, &tv))
+        return JS_FALSE;
+    target = (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(tv));
+
+    if (JSXML_LENGTH(target) == 0) {
+        if (base->xml_class == JSXML_CLASS_LIST && JSXML_LENGTH(base) > 1) {
+            *result = NULL;
+            return JS_TRUE;
+        }
+        tv = STRING_TO_JSVAL(cx->runtime->emptyString);
+        if (!PutProperty(cx, base->object, id, &tv))
+            return JS_FALSE;
+        if (!GetProperty(cx, base->object, id, &tv))
+            return JS_FALSE;
+        target = (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(tv));
+    }
+
+    *result = target;
+    return JS_TRUE;
+}
+
+/*
+ * HasProperty must be able to return a found JSProperty and the object in
+ * which it was found, if id is of the form function::name.  For other ids,
+ * if they index or name an XML child, we return FOUND_XML_PROPERTY in *propp
+ * and null in *objp.
+ *
+ * DROP_PROPERTY helps HasProperty callers drop function properties without
+ * trying to drop the magic FOUND_XML_PROPERTY cookie.
+ */
+#define FOUND_XML_PROPERTY              ((JSProperty *) 1)
+#define DROP_PROPERTY(cx,pobj,prop)     (((prop) != FOUND_XML_PROPERTY)       \
+                                         ? OBJ_DROP_PROPERTY(cx, pobj, prop)  \
+                                         : (void) 0)
+
+/* ECMA-357 9.1.1.6 XML [[HasProperty]] and 9.2.1.5 XMLList [[HasProperty]]. */
+static JSBool
+HasProperty(JSContext *cx, JSObject *obj, jsval id, JSObject **objp,
+            JSProperty **propp)
+{
+    JSXML *xml, *kid;
+    uint32 i, n;
+    JSObject *kidobj;
+    JSXMLQName *qn;
+    jsid funid;
+    JSXMLArray *array;
+    JSXMLNameMatcher matcher;
+
+    *objp = NULL;
+    *propp = NULL;
+
+    xml = (JSXML *) JS_GetPrivate(cx, obj);
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        n = JSXML_LENGTH(xml);
+        if (js_IdIsIndex(id, &i)) {
+            if (i < n)
+                *propp = FOUND_XML_PROPERTY;
+            return JS_TRUE;
+        }
+
+        for (i = 0; i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+                kidobj = js_GetXMLObject(cx, kid);
+                if (!kidobj || !HasProperty(cx, kidobj, id, objp, propp))
+                    return JS_FALSE;
+                if (*propp)
+                    return JS_TRUE;
+            }
+        }
+    } else {
+        if (xml->xml_class == JSXML_CLASS_ELEMENT && js_IdIsIndex(id, &i)) {
+            if (i == 0)
+                *propp = FOUND_XML_PROPERTY;
+            return JS_TRUE;
+        }
+
+        qn = ToXMLName(cx, id, &funid);
+        if (!qn)
+            return JS_FALSE;
+        if (funid)
+            return js_LookupProperty(cx, obj, funid, objp, propp);
+
+        if (xml->xml_class != JSXML_CLASS_ELEMENT)
+            return JS_TRUE;
+
+        if (OBJ_GET_CLASS(cx, qn->object) == &js_AttributeNameClass) {
+            array = &xml->xml_attrs;
+            matcher = MatchAttrName;
+        } else {
+            array = &xml->xml_kids;
+            matcher = MatchElemName;
+        }
+        for (i = 0, n = array->length; i < n; i++) {
+            kid = XMLARRAY_MEMBER(array, i, JSXML);
+            if (matcher(qn, kid)) {
+                *propp = FOUND_XML_PROPERTY;
+                return JS_TRUE;
+            }
+        }
+    }
+
+    return JS_TRUE;
+}
+
+static void
+xml_finalize(JSContext *cx, JSObject *obj)
+{
+    JSXML *xml;
+
+    xml = (JSXML *) JS_GetPrivate(cx, obj);
+    if (!xml)
+        return;
+    if (xml->object == obj)
+        xml->object = NULL;
+    UNMETER(xml_stats.livexmlobj);
+}
+
+static void
+xml_mark_vector(JSContext *cx, JSXML **vec, uint32 len, void *arg)
+{
+    uint32 i;
+    JSXML *elt;
+
+    for (i = 0; i < len; i++) {
+        elt = vec[i];
+        {
+#ifdef GC_MARK_DEBUG
+            char buf[100];
+            JSXMLQName *qn = elt->name;
+
+            JS_snprintf(buf, sizeof buf, "%s::%s",
+                        qn->uri ? JS_GetStringBytes(qn->uri) : "*",
+                        JS_GetStringBytes(qn->localName));
+#else
+            const char *buf = NULL;
+#endif
+            JS_MarkGCThing(cx, elt, buf, arg);
+        }
+    }
+}
+
+/*
+ * js_XMLObjectOps.newObjectMap == js_NewObjectMap, so XML objects appear to
+ * be native.  Therefore, xml_lookupProperty must return a valid JSProperty
+ * pointer parameter via *propp to signify "property found".  Since the only
+ * call to xml_lookupProperty is via OBJ_LOOKUP_PROPERTY, and then only from
+ * js_FindXMLProperty (in this file) and js_FindProperty (in jsobj.c, called
+ * from jsinterp.c), the only time we add a JSScopeProperty here is when an
+ * unqualified name or XML name is being accessed.
+ *
+ * This scope property both speeds up subsequent js_Find*Property calls, and
+ * keeps the JSOP_NAME code in js_Interpret happy by giving it an sprop with
+ * (getter, setter) == (GetProperty, PutProperty).  We can't use that getter
+ * and setter as js_XMLClass's getProperty and setProperty, because doing so
+ * would break the XML methods, which are function-valued properties of the
+ * XML.prototype object.
+ *
+ * NB: xml_deleteProperty must take care to remove any property added here.
+ */
+static JSBool
+xml_lookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
+                   JSProperty **propp)
+{
+    JSScopeProperty *sprop;
+
+    if (!HasProperty(cx, obj, ID_TO_VALUE(id), objp, propp))
+        return JS_FALSE;
+
+    if (*propp == FOUND_XML_PROPERTY) {
+        sprop = js_AddNativeProperty(cx, obj, id, GetProperty, PutProperty,
+                                     SPROP_INVALID_SLOT, JSPROP_ENUMERATE,
+                                     0, 0);
+        if (!sprop)
+            return JS_FALSE;
+
+        JS_LOCK_OBJ(cx, obj);
+        *objp = obj;
+        *propp = (JSProperty *) sprop;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+xml_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
+                   JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
+                   JSProperty **propp)
+{
+    if (JSVAL_IS_FUNCTION(cx, value) || getter || setter ||
+        (attrs & JSPROP_ENUMERATE) == 0 ||
+        (attrs & (JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED))) {
+        return js_DefineProperty(cx, obj, id, value, getter, setter, attrs,
+                                 propp);
+    }
+
+    if (!PutProperty(cx, obj, ID_TO_VALUE(id), &value))
+        return JS_FALSE;
+    if (propp)
+        *propp = NULL;
+    return JS_TRUE;
+}
+
+static JSBool
+xml_getProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+{
+    if (id == JS_DEFAULT_XML_NAMESPACE_ID) {
+        *vp = JSVAL_VOID;
+        return JS_TRUE;
+    }
+
+    return GetProperty(cx, obj, ID_TO_VALUE(id), vp);
+}
+
+static JSBool
+xml_setProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+{
+    return PutProperty(cx, obj, ID_TO_VALUE(id), vp);
+}
+
+static JSBool
+FoundProperty(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
+              JSBool *foundp)
+{
+    JSObject *pobj;
+
+    if (prop) {
+        *foundp = JS_TRUE;
+    } else {
+        if (!HasProperty(cx, obj, ID_TO_VALUE(id), &pobj, &prop))
+            return JS_FALSE;
+        if (prop)
+            DROP_PROPERTY(cx, pobj, prop);
+        *foundp = (prop != NULL);
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+xml_getAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
+                  uintN *attrsp)
+{
+    JSBool found;
+
+    if (!FoundProperty(cx, obj, id, prop, &found))
+        return JS_FALSE;
+    *attrsp = found ? JSPROP_ENUMERATE : 0;
+    return JS_TRUE;
+}
+
+static JSBool
+xml_setAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
+                  uintN *attrsp)
+{
+    JSBool found;
+
+    if (!FoundProperty(cx, obj, id, prop, &found))
+        return JS_FALSE;
+    if (found) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_CANT_SET_XML_ATTRS);
+    }
+    return !found;
+}
+
+static JSBool
+xml_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
+{
+    /*
+     * If this object has its own (mutable) scope, and if id isn't an index,
+     * then we may have added a property to the scope in xml_lookupProperty
+     * for it to return to mean "found" and to provide a handle for access
+     * operations to call the property's getter or setter.  The property also
+     * helps speed up unqualified accesses via the property cache, avoiding
+     * what amount to two HasProperty searches.
+     *
+     * But now it's time to remove any such property, to purge the property
+     * cache and remove the scope entry.
+     */
+    if (OBJ_SCOPE(obj)->object == obj && !JSID_IS_INT(id)) {
+        if (!js_DeleteProperty(cx, obj, id, rval))
+            return JS_FALSE;
+    }
+
+    return DeleteProperty(cx, obj, ID_TO_VALUE(id), rval);
+}
+
+static JSBool
+xml_defaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
+{
+    JSXML *xml;
+
+    if (hint == JSTYPE_OBJECT) {
+        /* Called from for..in code in js_Interpret: return an XMLList. */
+        xml = (JSXML *) JS_GetPrivate(cx, obj);
+        if (xml->xml_class != JSXML_CLASS_LIST) {
+            obj = ToXMLList(cx, OBJECT_TO_JSVAL(obj));
+            if (!obj)
+                return JS_FALSE;
+        }
+        *vp = OBJECT_TO_JSVAL(obj);
+        return JS_TRUE;
+    }
+
+    return JS_CallFunctionName(cx, obj, js_toString_str, 0, NULL, vp);
+}
+
+static JSBool
+xml_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
+              jsval *statep, jsid *idp)
+{
+    JSXML *xml;
+    uint32 length, index;
+    JSXMLArrayCursor *cursor;
+
+    xml = (JSXML *) JS_GetPrivate(cx, obj);
+    length = JSXML_LENGTH(xml);
+
+    switch (enum_op) {
+      case JSENUMERATE_INIT:
+        if (length == 0) {
+            cursor = NULL;
+        } else {
+            cursor = (JSXMLArrayCursor *) JS_malloc(cx, sizeof *cursor);
+            if (!cursor)
+                return JS_FALSE;
+            XMLArrayCursorInit(cursor, &xml->xml_kids);
+        }
+        *statep = PRIVATE_TO_JSVAL(cursor);
+        if (idp)
+            *idp = INT_TO_JSID(length);
+        break;
+
+      case JSENUMERATE_NEXT:
+        cursor = JSVAL_TO_PRIVATE(*statep);
+        if (cursor && cursor->array && (index = cursor->index) < length) {
+            *idp = INT_TO_JSID(index);
+            cursor->index = index + 1;
+            break;
+        }
+        /* FALL THROUGH */
+
+      case JSENUMERATE_DESTROY:
+        cursor = JSVAL_TO_PRIVATE(*statep);
+        if (cursor) {
+            XMLArrayCursorFinish(cursor);
+            JS_free(cx, cursor);
+        }
+        *statep = JSVAL_NULL;
+        break;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+xml_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
+{
+    return JS_TRUE;
+}
+
+static uint32
+xml_mark(JSContext *cx, JSObject *obj, void *arg)
+{
+    JSXML *xml;
+
+    xml = (JSXML *) JS_GetPrivate(cx, obj);
+    JS_MarkGCThing(cx, xml, js_private_str, arg);
+    return js_Mark(cx, obj, arg);
+}
+
+static void
+xml_clear(JSContext *cx, JSObject *obj)
+{
+}
+
+static JSBool
+HasSimpleContent(JSXML *xml)
+{
+    JSXML *kid;
+    JSBool simple;
+    uint32 i, n;
+
+again:
+    switch (xml->xml_class) {
+      case JSXML_CLASS_COMMENT:
+      case JSXML_CLASS_PROCESSING_INSTRUCTION:
+        return JS_FALSE;
+      case JSXML_CLASS_LIST:
+        if (xml->xml_kids.length == 0)
+            return JS_TRUE;
+        if (xml->xml_kids.length == 1) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, 0, JSXML);
+            xml = kid;
+            goto again;
+        }
+        /* FALL THROUGH */
+      default:
+        simple = JS_TRUE;
+        for (i = 0, n = JSXML_LENGTH(xml); i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+                simple = JS_FALSE;
+                break;
+            }
+        }
+        return simple;
+    }
+}
+
+static JSObject *
+xml_getMethod(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+{
+    JSXML *xml;
+    jsval fval;
+
+    JS_ASSERT(JS_InstanceOf(cx, obj, &js_XMLClass, NULL));
+    xml = (JSXML *) JS_GetPrivate(cx, obj);
+
+retry:
+    /* 11.2.2.1 Step 3(d) onward. */
+    if (!GetFunction(cx, obj, xml, id, &fval))
+        return NULL;
+
+    if (JSVAL_IS_VOID(fval) && OBJECT_IS_XML(cx, obj)) {
+        if (xml->xml_class == JSXML_CLASS_LIST) {
+            if (xml->xml_kids.length == 1) {
+                xml = XMLARRAY_MEMBER(&xml->xml_kids, 0, JSXML);
+                obj = js_GetXMLObject(cx, xml);
+                if (!obj)
+                    return NULL;
+                goto retry;
+            }
+        } else if (HasSimpleContent(xml)) {
+            JSString *str;
+            JSObject *tmp;
+
+            str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+            if (!str || !js_ValueToObject(cx, STRING_TO_JSVAL(str), &tmp))
+                return NULL;
+            if (!js_GetProperty(cx, tmp, id, &fval))
+                return NULL;
+            if (!JSVAL_IS_VOID(fval))
+                obj = tmp;
+        }
+    }
+
+    *vp = fval;
+    return obj;
+}
+
+static JSBool
+xml_setMethod(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+{
+    return js_SetProperty(cx, obj, id, vp);
+}
+
+static JSBool
+xml_enumerateValues(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
+                    jsval *statep, jsid *idp, jsval *vp)
+{
+    JSXML *xml, *kid;
+    uint32 length, index;
+    JSXMLArrayCursor *cursor;
+    JSObject *kidobj;
+
+    xml = (JSXML *) JS_GetPrivate(cx, obj);
+    length = JSXML_LENGTH(xml);
+    JS_ASSERT(INT_FITS_IN_JSVAL(length));
+
+    switch (enum_op) {
+      case JSENUMERATE_INIT:
+        if (length == 0) {
+            cursor = NULL;
+        } else {
+            cursor = (JSXMLArrayCursor *) JS_malloc(cx, sizeof *cursor);
+            if (!cursor)
+                return JS_FALSE;
+            XMLArrayCursorInit(cursor, &xml->xml_kids);
+        }
+        *statep = PRIVATE_TO_JSVAL(cursor);
+        if (idp)
+            *idp = INT_TO_JSID(length);
+        if (vp)
+            *vp = JSVAL_VOID;
+        break;
+
+      case JSENUMERATE_NEXT:
+        cursor = JSVAL_TO_PRIVATE(*statep);
+        if (cursor && cursor->array && (index = cursor->index) < length) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, index, JSXML);
+            kidobj = js_GetXMLObject(cx, kid);
+            if (!kidobj)
+                return JS_FALSE;
+            JS_ASSERT(INT_FITS_IN_JSVAL(index));
+            *idp = INT_TO_JSID(index);
+            *vp = OBJECT_TO_JSVAL(kidobj);
+            cursor->index = index + 1;
+            break;
+        }
+        /* FALL THROUGH */
+
+      case JSENUMERATE_DESTROY:
+        cursor = JSVAL_TO_PRIVATE(*statep);
+        if (cursor) {
+            XMLArrayCursorFinish(cursor);
+            JS_free(cx, cursor);
+        }
+        *statep = JSVAL_NULL;
+        break;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+xml_equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
+{
+    JSXML *xml, *vxml;
+    JSObject *vobj;
+    JSBool ok;
+    JSString *str, *vstr;
+    jsdouble d, d2;
+
+    xml = (JSXML *) JS_GetPrivate(cx, obj);
+    vxml = NULL;
+    if (!JSVAL_IS_PRIMITIVE(v)) {
+        vobj = JSVAL_TO_OBJECT(v);
+        if (OBJECT_IS_XML(cx, vobj))
+            vxml = (JSXML *) JS_GetPrivate(cx, vobj);
+    }
+
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        ok = Equals(cx, xml, v, bp);
+    } else if (vxml) {
+        if (vxml->xml_class == JSXML_CLASS_LIST) {
+            ok = Equals(cx, vxml, OBJECT_TO_JSVAL(obj), bp);
+        } else {
+            if (((xml->xml_class == JSXML_CLASS_TEXT ||
+                  xml->xml_class == JSXML_CLASS_ATTRIBUTE) &&
+                 HasSimpleContent(vxml)) ||
+                ((vxml->xml_class == JSXML_CLASS_TEXT ||
+                  vxml->xml_class == JSXML_CLASS_ATTRIBUTE) &&
+                 HasSimpleContent(xml))) {
+                ok = JS_EnterLocalRootScope(cx);
+                if (ok) {
+                    str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+                    vstr = js_ValueToString(cx, v);
+                    ok = str && vstr;
+                    if (ok)
+                        *bp = !js_CompareStrings(str, vstr);
+                    JS_LeaveLocalRootScope(cx);
+                }
+            } else {
+                ok = XMLEquals(cx, xml, vxml, bp);
+            }
+        }
+    } else {
+        ok = JS_EnterLocalRootScope(cx);
+        if (ok) {
+            if (HasSimpleContent(xml)) {
+                str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+                vstr = js_ValueToString(cx, v);
+                ok = str && vstr;
+                if (ok)
+                    *bp = !js_CompareStrings(str, vstr);
+            } else if (JSVAL_IS_STRING(v) || JSVAL_IS_NUMBER(v)) {
+                str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj));
+                if (!str) {
+                    ok = JS_FALSE;
+                } else if (JSVAL_IS_STRING(v)) {
+                    *bp = !js_CompareStrings(str, JSVAL_TO_STRING(v));
+                } else {
+                    ok = js_ValueToNumber(cx, STRING_TO_JSVAL(str), &d);
+                    if (ok) {
+                        d2 = JSVAL_IS_INT(v) ? JSVAL_TO_INT(v)
+                                             : *JSVAL_TO_DOUBLE(v);
+                        *bp = JSDOUBLE_COMPARE(d, ==, d2, JS_FALSE);
+                    }
+                }
+            } else {
+                *bp = JS_FALSE;
+            }
+            JS_LeaveLocalRootScope(cx);
+        }
+    }
+    return ok;
+}
+
+static JSBool
+xml_concatenate(JSContext *cx, JSObject *obj, jsval v, jsval *vp)
+{
+    JSBool ok;
+    JSObject *listobj, *robj;
+    JSXML *list, *lxml, *rxml;
+
+    ok = JS_EnterLocalRootScope(cx);
+    if (!ok)
+        return JS_FALSE;
+
+    listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+    if (!listobj) {
+        ok = JS_FALSE;
+        goto out;
+    }
+
+    list = (JSXML *) JS_GetPrivate(cx, listobj);
+    lxml = (JSXML *) JS_GetPrivate(cx, obj);
+    ok = Append(cx, list, lxml);
+    if (!ok)
+        goto out;
+
+    if (VALUE_IS_XML(cx, v)) {
+        rxml = (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v));
+    } else {
+        robj = ToXML(cx, v);
+        if (!robj) {
+            ok = JS_FALSE;
+            goto out;
+        }
+        rxml = (JSXML *) JS_GetPrivate(cx, robj);
+    }
+    ok = Append(cx, list, rxml);
+    if (!ok)
+        goto out;
+
+    *vp = OBJECT_TO_JSVAL(listobj);
+out:
+    JS_LeaveLocalRootScope(cx);
+    return ok;
+}
+
+/* Use js_NewObjectMap so XML objects satisfy OBJ_IS_NATIVE tests. */
+JS_FRIEND_DATA(JSXMLObjectOps) js_XMLObjectOps = {
+  { js_NewObjectMap,            js_DestroyObjectMap,
+    xml_lookupProperty,         xml_defineProperty,
+    xml_getProperty,            xml_setProperty,
+    xml_getAttributes,          xml_setAttributes,
+    xml_deleteProperty,         xml_defaultValue,
+    xml_enumerate,              js_CheckAccess,
+    NULL,                       NULL,
+    NULL,                       NULL,
+    NULL,                       xml_hasInstance,
+    js_SetProtoOrParent,        js_SetProtoOrParent,
+    xml_mark,                   xml_clear,
+    NULL,                       NULL },
+    xml_getMethod,              xml_setMethod,
+    xml_enumerateValues,        xml_equality,
+    xml_concatenate
+};
+
+static JSObjectOps *
+xml_getObjectOps(JSContext *cx, JSClass *clasp)
+{
+    return &js_XMLObjectOps.base;
+}
+
+JS_FRIEND_DATA(JSClass) js_XMLClass = {
+    js_XML_str,        JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub,   JS_PropertyStub,   JS_PropertyStub,   JS_PropertyStub,
+    JS_EnumerateStub,  JS_ResolveStub,    JS_ConvertStub,    xml_finalize,
+    xml_getObjectOps,  NULL,              NULL,              NULL,
+    NULL,              NULL,              NULL,              NULL
+};
+
+static JSObject *
+CallConstructorFunction(JSContext *cx, JSObject *obj, JSClass *clasp,
+                        uintN argc, jsval *argv)
+{
+    JSObject *tmp;
+    jsval rval;
+
+    while ((tmp = OBJ_GET_PARENT(cx, obj)) != NULL)
+        obj = tmp;
+    if (!JS_CallFunctionName(cx, obj, clasp->name, argc, argv, &rval))
+        return NULL;
+    JS_ASSERT(!JSVAL_IS_PRIMITIVE(rval));
+    return JSVAL_TO_OBJECT(rval);
+}
+
+#define XML_METHOD_PROLOG                                                     \
+    JS_BEGIN_MACRO                                                            \
+        xml = (JSXML *) JS_GetInstancePrivate(cx, obj, &js_XMLClass, argv);   \
+        if (!xml)                                                             \
+            return JS_FALSE;                                                  \
+    JS_END_MACRO
+
+static JSBool
+xml_addNamespace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    JSXML *xml;
+    JSObject *nsobj;
+    JSXMLNamespace *ns;
+
+    XML_METHOD_PROLOG;
+    if (xml->xml_class != JSXML_CLASS_ELEMENT)
+        return JS_TRUE;
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml)
+        return JS_FALSE;
+
+    nsobj = CallConstructorFunction(cx, obj, &js_NamespaceClass.base, 1, argv);
+    if (!nsobj)
+        return JS_FALSE;
+    argv[0] = OBJECT_TO_JSVAL(nsobj);
+
+    ns = (JSXMLNamespace *) JS_GetPrivate(cx, nsobj);
+    if (!AddInScopeNamespace(cx, xml, ns))
+        return JS_FALSE;
+    ns->declared = JS_TRUE;
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+static JSBool
+xml_appendChild(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    JSXML *xml, *vxml;
+    jsval name, v;
+    JSObject *vobj;
+
+    XML_METHOD_PROLOG;
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml)
+        return JS_FALSE;
+
+    if (!js_GetAnyName(cx, &name))
+        return JS_FALSE;
+
+    if (!GetProperty(cx, obj, name, &v))
+        return JS_FALSE;
+
+    JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
+    vobj = JSVAL_TO_OBJECT(v);
+    JS_ASSERT(OBJECT_IS_XML(cx, vobj));
+    vxml = (JSXML *) JS_GetPrivate(cx, vobj);
+    JS_ASSERT(vxml->xml_class == JSXML_CLASS_LIST);
+
+    if (!IndexToIdVal(cx, vxml->xml_kids.length, &name))
+        return JS_FALSE;
+    if (!PutProperty(cx, JSVAL_TO_OBJECT(v), name, &argv[0]))
+        return JS_FALSE;
+
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_attribute(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    JSXMLQName *qn;
+
+    qn = ToAttributeName(cx, argv[0]);
+    if (!qn)
+        return JS_FALSE;
+    argv[0] = OBJECT_TO_JSVAL(qn->object);      /* local root */
+    return GetProperty(cx, obj, argv[0], rval);
+}
+
+/* XML and XMLList */
+static JSBool
+xml_attributes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    jsval name;
+    JSXMLQName *qn;
+    JSTempValueRooter tvr;
+    JSBool ok;
+
+    name = ATOM_KEY(cx->runtime->atomState.starAtom);
+    qn = ToAttributeName(cx, name);
+    if (!qn)
+        return JS_FALSE;
+    name = OBJECT_TO_JSVAL(qn->object);
+    JS_PUSH_SINGLE_TEMP_ROOT(cx, name, &tvr);
+    ok = GetProperty(cx, obj, name, rval);
+    JS_POP_TEMP_ROOT(cx, &tvr);
+    return ok;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_child_helper(JSContext *cx, JSObject *obj, JSXML *xml, jsval name,
+                 jsval *rval)
+{
+    uint32 index;
+    JSXML *kid;
+    JSObject *kidobj;
+
+    /* ECMA-357 13.4.4.6 */
+    JS_ASSERT(xml->xml_class != JSXML_CLASS_LIST);
+
+    if (js_IdIsIndex(name, &index)) {
+        if (index >= JSXML_LENGTH(xml)) {
+            *rval = JSVAL_VOID;
+        } else {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, index, JSXML);
+            kidobj = js_GetXMLObject(cx, kid);
+            if (!kidobj)
+                return JS_FALSE;
+            *rval = OBJECT_TO_JSVAL(kidobj);
+        }
+        return JS_TRUE;
+    }
+
+    return GetProperty(cx, obj, name, rval);
+}
+
+static JSBool
+xml_child(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSXML *xml, *list, *kid, *vxml;
+    jsval name, v;
+    uint32 i, n;
+    JSObject *listobj, *kidobj;
+
+    XML_METHOD_PROLOG;
+    name = argv[0];
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        /* ECMA-357 13.5.4.4 */
+        listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+        if (!listobj)
+            return JS_FALSE;
+
+        *rval = OBJECT_TO_JSVAL(listobj);
+        list = (JSXML *) JS_GetPrivate(cx, listobj);
+        list->xml_target = xml;
+
+        for (i = 0, n = xml->xml_kids.length; i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            kidobj = js_GetXMLObject(cx, kid);
+            if (!kidobj)
+                return JS_FALSE;
+            if (!xml_child_helper(cx, kidobj, kid, name, &v))
+                return JS_FALSE;
+            if (JSVAL_IS_VOID(v)) {
+                /* The property didn't exist in this kid. */
+                continue;
+            }
+
+            JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
+            vxml = (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v));
+            if ((!JSXML_HAS_KIDS(vxml) || vxml->xml_kids.length != 0) &&
+                !Append(cx, list, vxml)) {
+                return JS_FALSE;
+            }
+        }
+        return JS_TRUE;
+    }
+
+    return xml_child_helper(cx, obj, xml, name, rval);
+}
+
+static JSBool
+xml_childIndex(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+               jsval *rval)
+{
+    JSXML *xml, *parent;
+    uint32 i, n;
+
+    XML_METHOD_PROLOG;
+    parent = xml->parent;
+    if (!parent || xml->xml_class == JSXML_CLASS_ATTRIBUTE) {
+        *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
+        return JS_TRUE;
+    }
+    for (i = 0, n = JSXML_LENGTH(parent); i < n; i++) {
+        if (XMLARRAY_MEMBER(&parent->xml_kids, i, JSXML) == xml)
+            break;
+    }
+    JS_ASSERT(i < n);
+    return js_NewNumberValue(cx, i, rval);
+}
+
+/* XML and XMLList */
+static JSBool
+xml_children(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+             jsval *rval)
+{
+    jsval name;
+
+    name = ATOM_KEY(cx->runtime->atomState.starAtom);
+    return GetProperty(cx, obj, name, rval);
+}
+
+/* XML and XMLList */
+static JSBool
+xml_comments(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+             jsval *rval)
+{
+    JSXML *xml, *list, *kid, *vxml;
+    JSObject *listobj, *kidobj;
+    JSBool ok;
+    uint32 i, n;
+    jsval v;
+
+    XML_METHOD_PROLOG;
+    listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+    if (!listobj)
+        return JS_FALSE;
+
+    *rval = OBJECT_TO_JSVAL(listobj);
+    list = (JSXML *) JS_GetPrivate(cx, listobj);
+    list->xml_target = xml;
+
+    ok = JS_TRUE;
+
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        /* 13.5.4.6 Step 2. */
+        for (i = 0, n = JSXML_LENGTH(xml); i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+                ok = JS_EnterLocalRootScope(cx);
+                if (!ok)
+                    break;
+                kidobj = js_GetXMLObject(cx, kid);
+                ok = kidobj
+                     ? xml_comments(cx, kidobj, argc, argv, &v)
+                     : JS_FALSE;
+                JS_LeaveLocalRootScope(cx);
+                if (!ok)
+                    break;
+                vxml = (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v));
+                if (JSXML_LENGTH(vxml) != 0) {
+                    ok = Append(cx, list, vxml);
+                    if (!ok)
+                        break;
+                }
+            }
+        }
+    } else {
+        /* 13.4.4.9 Step 2. */
+        for (i = 0, n = JSXML_LENGTH(xml); i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_COMMENT) {
+                ok = Append(cx, list, kid);
+                if (!ok)
+                    break;
+            }
+        }
+    }
+
+    return ok;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_contains(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+             jsval *rval)
+{
+    JSXML *xml, *kid;
+    jsval value;
+    JSBool eq;
+    JSObject *kidobj;
+    uint32 i, n;
+
+    XML_METHOD_PROLOG;
+    value = argv[0];
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        eq = JS_FALSE;
+        for (i = 0, n = xml->xml_kids.length; i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            kidobj = js_GetXMLObject(cx, kid);
+            if (!kidobj || !xml_equality(cx, kidobj, value, &eq))
+                return JS_FALSE;
+            if (eq)
+                break;
+        }
+    } else {
+        if (!xml_equality(cx, obj, value, &eq))
+            return JS_FALSE;
+    }
+    *rval = BOOLEAN_TO_JSVAL(eq);
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_copy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSXML *xml, *copy;
+
+    XML_METHOD_PROLOG;
+    copy = DeepCopy(cx, xml, NULL, 0);
+    if (!copy)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(copy->object);
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_descendants(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    JSXML *xml, *list;
+    jsval name;
+
+    XML_METHOD_PROLOG;
+    name = (argc == 0) ? ATOM_KEY(cx->runtime->atomState.starAtom) : argv[0];
+    list = Descendants(cx, xml, name);
+    if (!list)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(list->object);
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_elements(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+             jsval *rval)
+{
+    JSXML *xml, *list, *kid, *vxml;
+    jsval name, v;
+    JSXMLQName *nameqn;
+    jsid funid;
+    JSObject *listobj, *kidobj;
+    JSBool ok;
+    uint32 i, n;
+
+    XML_METHOD_PROLOG;
+    name = (argc == 0) ? ATOM_KEY(cx->runtime->atomState.starAtom) : argv[0];
+    nameqn = ToXMLName(cx, name, &funid);
+    if (!nameqn)
+        return JS_FALSE;
+    argv[0] = OBJECT_TO_JSVAL(nameqn->object);
+
+    listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+    if (!listobj)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(listobj);
+    if (funid)
+        return JS_TRUE;
+
+    list = (JSXML *) JS_GetPrivate(cx, listobj);
+    list->xml_target = xml;
+    list->xml_targetprop = nameqn;
+    ok = JS_TRUE;
+
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        /* 13.5.4.6 */
+        for (i = 0, n = JSXML_LENGTH(xml); i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+                ok = JS_EnterLocalRootScope(cx);
+                if (!ok)
+                    break;
+                kidobj = js_GetXMLObject(cx, kid);
+                ok = kidobj
+                     ? xml_elements(cx, kidobj, argc, argv, &v)
+                     : JS_FALSE;
+                JS_LeaveLocalRootScope(cx);
+                if (!ok)
+                    break;
+                vxml = (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v));
+                if (JSXML_LENGTH(vxml) != 0) {
+                    ok = Append(cx, list, vxml);
+                    if (!ok)
+                        break;
+                }
+            }
+        }
+    } else {
+        for (i = 0, n = JSXML_LENGTH(xml); i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_ELEMENT &&
+                MatchElemName(nameqn, kid)) {
+                ok = Append(cx, list, kid);
+                if (!ok)
+                    break;
+            }
+        }
+    }
+
+    return ok;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_hasOwnProperty(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                   jsval *rval)
+{
+    jsval name;
+    JSObject *pobj;
+    JSProperty *prop;
+
+    name = argv[0];
+    if (!HasProperty(cx, obj, name, &pobj, &prop))
+        return JS_FALSE;
+    if (!prop) {
+        return js_HasOwnPropertyHelper(cx, obj, js_LookupProperty, argc, argv,
+                                       rval);
+    }
+    DROP_PROPERTY(cx, pobj, prop);
+    *rval = JSVAL_TRUE;
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_hasComplexContent(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                      jsval *rval)
+{
+    JSXML *xml, *kid;
+    JSObject *kidobj;
+    uint32 i, n;
+
+    XML_METHOD_PROLOG;
+again:
+    switch (xml->xml_class) {
+      case JSXML_CLASS_ATTRIBUTE:
+      case JSXML_CLASS_COMMENT:
+      case JSXML_CLASS_PROCESSING_INSTRUCTION:
+      case JSXML_CLASS_TEXT:
+        *rval = JSVAL_FALSE;
+        break;
+      case JSXML_CLASS_LIST:
+        if (xml->xml_kids.length == 0) {
+            *rval = JSVAL_TRUE;
+        } else if (xml->xml_kids.length == 1) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, 0, JSXML);
+            kidobj = js_GetXMLObject(cx, kid);
+            if (!kidobj)
+                return JS_FALSE;
+            obj = kidobj;
+            xml = (JSXML *) JS_GetPrivate(cx, obj);
+            goto again;
+        }
+        /* FALL THROUGH */
+      default:
+        *rval = JSVAL_FALSE;
+        for (i = 0, n = xml->xml_kids.length; i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+                *rval = JSVAL_TRUE;
+                break;
+            }
+        }
+        break;
+    }
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_hasSimpleContent(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                     jsval *rval)
+{
+    JSXML *xml;
+
+    XML_METHOD_PROLOG;
+    *rval = BOOLEAN_TO_JSVAL(HasSimpleContent(xml));
+    return JS_TRUE;
+}
+
+static JSBool
+xml_inScopeNamespaces(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                      jsval *rval)
+{
+    JSObject *arrayobj, *nsobj;
+    JSXML *xml;
+    uint32 length, i, j, n;
+    JSXMLNamespace *ns, *ns2;
+    jsval v;
+
+    arrayobj = js_NewArrayObject(cx, 0, NULL);
+    if (!arrayobj)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(arrayobj);
+    length = 0;
+
+    XML_METHOD_PROLOG;
+    do {
+        if (xml->xml_class != JSXML_CLASS_ELEMENT)
+            continue;
+        for (i = 0, n = xml->xml_namespaces.length; i < n; i++) {
+            ns = XMLARRAY_MEMBER(&xml->xml_namespaces, i, JSXMLNamespace);
+
+            for (j = 0; j < length; j++) {
+                if (!JS_GetElement(cx, arrayobj, j, &v))
+                    return JS_FALSE;
+                nsobj = JSVAL_TO_OBJECT(v);
+                ns2 = (JSXMLNamespace *) JS_GetPrivate(cx, nsobj);
+                if ((ns2->prefix && ns->prefix)
+                    ? !js_CompareStrings(ns2->prefix, ns->prefix)
+                    : !js_CompareStrings(ns2->uri, ns->uri)) {
+                    break;
+                }
+            }
+
+            if (j == length) {
+                nsobj = js_GetXMLNamespaceObject(cx, ns);
+                if (!nsobj)
+                    return JS_FALSE;
+                v = OBJECT_TO_JSVAL(nsobj);
+                if (!JS_SetElement(cx, arrayobj, length, &v))
+                    return JS_FALSE;
+                ++length;
+            }
+        }
+    } while ((xml = xml->parent) != NULL);
+    return JS_TRUE;
+}
+
+static JSBool
+xml_insertChildAfter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                     jsval *rval)
+{
+    JSXML *xml, *kid;
+    jsval arg;
+    uint32 i;
+
+    XML_METHOD_PROLOG;
+    if (!JSXML_HAS_KIDS(xml))
+        return JS_TRUE;
+
+    arg = argv[0];
+    if (JSVAL_IS_NULL(arg)) {
+        kid = NULL;
+        i = 0;
+    } else {
+        if (!VALUE_IS_XML(cx, arg))
+            return JS_TRUE;
+        kid = (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(arg));
+        i = XMLARRAY_FIND_MEMBER(&xml->xml_kids, kid, NULL);
+        if (i == XML_NOT_FOUND)
+            return JS_TRUE;
+        ++i;
+    }
+
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml)
+        return JS_FALSE;
+    if (!Insert(cx, xml, INT_TO_JSID(i), argv[1]))
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+static JSBool
+xml_insertChildBefore(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                      jsval *rval)
+{
+    JSXML *xml, *kid;
+    jsval arg;
+    uint32 i;
+
+    XML_METHOD_PROLOG;
+    if (!JSXML_HAS_KIDS(xml))
+        return JS_TRUE;
+
+    arg = argv[0];
+    if (JSVAL_IS_NULL(arg)) {
+        kid = NULL;
+        i = xml->xml_kids.length;
+    } else {
+        if (!VALUE_IS_XML(cx, arg))
+            return JS_TRUE;
+        kid = (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(arg));
+        i = XMLARRAY_FIND_MEMBER(&xml->xml_kids, kid, NULL);
+        if (i == XML_NOT_FOUND)
+            return JS_TRUE;
+    }
+
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml)
+        return JS_FALSE;
+    if (!Insert(cx, xml, INT_TO_JSID(i), argv[1]))
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_length(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSXML *xml;
+
+    XML_METHOD_PROLOG;
+    if (xml->xml_class != JSXML_CLASS_LIST) {
+        *rval = JSVAL_ONE;
+    } else {
+        if (!js_NewNumberValue(cx, xml->xml_kids.length, rval))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+xml_localName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    JSXML *xml;
+
+    XML_METHOD_PROLOG;
+    *rval = xml->name ? STRING_TO_JSVAL(xml->name->localName) : JSVAL_NULL;
+    return JS_TRUE;
+}
+
+static JSBool
+xml_name(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSXML *xml;
+    JSObject *nameobj;
+
+    XML_METHOD_PROLOG;
+    if (!xml->name) {
+        *rval = JSVAL_NULL;
+    } else {
+        nameobj = js_GetXMLQNameObject(cx, xml->name);
+        if (!nameobj)
+            return JS_FALSE;
+        *rval = OBJECT_TO_JSVAL(nameobj);
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+xml_namespace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    JSXML *xml;
+    JSObject *arrayobj;
+    JSBool ok;
+    jsuint i, length;
+    jsval v;
+    JSXMLArray inScopeNSes;
+    JSXMLNamespace *ns;
+    JSString *prefix;
+
+    XML_METHOD_PROLOG;
+    if (argc == 0 &&
+        (xml->xml_class == JSXML_CLASS_TEXT ||
+         xml->xml_class == JSXML_CLASS_COMMENT ||
+         xml->xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION)) {
+        *rval = JSVAL_NULL;
+        return JS_TRUE;
+    }
+
+    if (!xml_inScopeNamespaces(cx, obj, 0, NULL, rval))
+        return JS_FALSE;
+    arrayobj = JSVAL_TO_OBJECT(*rval);
+    ok = js_GetLengthProperty(cx, arrayobj, &length);
+    if (!ok)
+        return JS_FALSE;
+
+    if (argc == 0) {
+        if (!XMLArrayInit(cx, &inScopeNSes, length))
+            return JS_FALSE;
+
+        for (i = 0; i < length; i++) {
+            ok = OBJ_GET_PROPERTY(cx, arrayobj, INT_TO_JSID(i), &v);
+            if (!ok)
+                break;
+            JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
+            ns = (JSXMLNamespace *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v));
+            XMLARRAY_SET_MEMBER(&inScopeNSes, i, ns);
+        }
+
+        inScopeNSes.length = i;
+        ns = ok ? GetNamespace(cx, xml->name, &inScopeNSes) : NULL;
+        XMLArrayFinish(cx, &inScopeNSes);
+        if (!ns)
+            return JS_FALSE;
+
+        *rval = OBJECT_TO_JSVAL(ns->object);
+    } else {
+        prefix = js_ValueToString(cx, argv[0]);
+        if (!prefix)
+            return JS_FALSE;
+        argv[0] = STRING_TO_JSVAL(prefix);      /* local root */
+
+        for (i = 0; i < length; i++) {
+            if (!OBJ_GET_PROPERTY(cx, arrayobj, INT_TO_JSID(i), &v))
+                return JS_FALSE;
+            JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
+            ns = (JSXMLNamespace *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v));
+            if (ns->prefix && !js_CompareStrings(ns->prefix, prefix))
+                break;
+        }
+
+        *rval = (i < length) ? OBJECT_TO_JSVAL(ns->object) : JSVAL_VOID;
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+xml_namespaceDeclarations(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                          jsval *rval)
+{
+    JSObject *arrayobj, *nsobj;
+    JSXML *xml, *yml;
+    JSBool ok;
+    JSXMLArray ancestors, declared;
+    uint32 i, n;
+    JSXMLNamespace *ns;
+    jsval v;
+
+    arrayobj = js_NewArrayObject(cx, 0, NULL);
+    if (!arrayobj)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(arrayobj);
+
+    XML_METHOD_PROLOG;
+    if (JSXML_HAS_VALUE(xml) || xml->xml_class == JSXML_CLASS_LIST)
+        return JS_TRUE;
+
+    /* From here, control flow must goto out to finish these arrays. */
+    ok = JS_TRUE;
+    XMLArrayInit(cx, &ancestors, 0);
+    XMLArrayInit(cx, &declared, 0);
+    yml = xml;
+
+    while ((yml = yml->parent) != NULL) {
+        JS_ASSERT(yml->xml_class == JSXML_CLASS_ELEMENT);
+        for (i = 0, n = yml->xml_namespaces.length; i < n; i++) {
+            ns = XMLARRAY_MEMBER(&yml->xml_namespaces, i, JSXMLNamespace);
+            if (!XMLARRAY_HAS_MEMBER(&ancestors, ns, namespace_match)) {
+                ok = XMLARRAY_APPEND(cx, &ancestors, ns);
+                if (!ok)
+                    goto out;
+            }
+        }
+    }
+
+    for (i = 0, n = xml->xml_namespaces.length; i < n; i++) {
+        ns = XMLARRAY_MEMBER(&xml->xml_namespaces, i, JSXMLNamespace);
+        if (!ns->declared)
+            continue;
+        if (!XMLARRAY_HAS_MEMBER(&ancestors, ns, namespace_match)) {
+            ok = XMLARRAY_APPEND(cx, &declared, ns);
+            if (!ok)
+                goto out;
+        }
+    }
+
+    for (i = 0, n = declared.length; i < n; i++) {
+        ns = XMLARRAY_MEMBER(&declared, i, JSXMLNamespace);
+        nsobj = js_GetXMLNamespaceObject(cx, ns);
+        if (!nsobj) {
+            ok = JS_FALSE;
+            goto out;
+        }
+        v = OBJECT_TO_JSVAL(nsobj);
+        ok = OBJ_SET_PROPERTY(cx, arrayobj, INT_TO_JSID(i), &v);
+        if (!ok)
+            goto out;
+    }
+
+out:
+    XMLArrayFinish(cx, &ancestors);
+    XMLArrayFinish(cx, &declared);
+    return ok;
+}
+
+static const char js_attribute_str[] = "attribute";
+static const char js_text_str[]      = "text";
+
+/* Exported to jsgc.c #ifdef GC_MARK_DEBUG. */
+const char *js_xml_class_str[] = {
+    "list",
+    "element",
+    js_attribute_str,
+    "processing-instruction",
+    js_text_str,
+    "comment"
+};
+
+static JSBool
+xml_nodeKind(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+             jsval *rval)
+{
+    JSXML *xml;
+    JSString *str;
+
+    XML_METHOD_PROLOG;
+    str = JS_InternString(cx, js_xml_class_str[xml->xml_class]);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+static JSBool
+NormalizingDelete(JSContext *cx, JSObject *obj, JSXML *xml, jsval id)
+{
+    jsval junk;
+
+    if (xml->xml_class == JSXML_CLASS_LIST)
+        return DeleteProperty(cx, obj, id, &junk);
+    return DeleteByIndex(cx, xml, id, &junk);
+}
+
+/*
+ * Erratum? the testcase js/tests/e4x/XML/13.4.4.26.js wants all-whitespace
+ * text between tags to be removed by normalize.
+ */
+static JSBool
+IsXMLSpace(JSString *str)
+{
+    const jschar *cp, *end;
+
+    cp = JSSTRING_CHARS(str);
+    end = cp + JSSTRING_LENGTH(str);
+    while (cp < end) {
+        if (!JS_ISXMLSPACE(*cp))
+            return JS_FALSE;
+        ++cp;
+    }
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_normalize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+              jsval *rval)
+{
+    JSXML *xml, *kid, *kid2;
+    uint32 i, n;
+    JSObject *kidobj;
+    JSString *str;
+    jsval junk;
+
+    XML_METHOD_PROLOG;
+    *rval = OBJECT_TO_JSVAL(obj);
+    if (!JSXML_HAS_KIDS(xml))
+        return JS_TRUE;
+
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml)
+        return JS_FALSE;
+
+    for (i = 0, n = xml->xml_kids.length; i < n; i++) {
+        kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+        if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+            kidobj = js_GetXMLObject(cx, kid);
+            if (!kidobj || !xml_normalize(cx, kidobj, argc, argv, &junk))
+                return JS_FALSE;
+        } else if (kid->xml_class == JSXML_CLASS_TEXT) {
+            while (i + 1 < n &&
+                   (kid2 = XMLARRAY_MEMBER(&xml->xml_kids, i + 1, JSXML))
+                   ->xml_class == JSXML_CLASS_TEXT) {
+                str = js_ConcatStrings(cx, kid->xml_value, kid2->xml_value);
+                if (!str)
+                    return JS_FALSE;
+                if (!NormalizingDelete(cx, obj, xml, INT_TO_JSVAL(i + 1)))
+                    return JS_FALSE;
+                n = xml->xml_kids.length;
+                kid->xml_value = str;
+            }
+            if (IS_EMPTY(kid->xml_value) || IsXMLSpace(kid->xml_value)) {
+                if (!NormalizingDelete(cx, obj, xml, INT_TO_JSVAL(i)))
+                    return JS_FALSE;
+                n = xml->xml_kids.length;
+                --i;
+            }
+        }
+    }
+
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_parent(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSXML *xml, *parent, *kid;
+    uint32 i, n;
+    JSObject *parentobj;
+
+    XML_METHOD_PROLOG;
+    parent = xml->parent;
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        *rval = JSVAL_VOID;
+        n = xml->xml_kids.length;
+        if (n == 0)
+            return JS_TRUE;
+
+        kid = XMLARRAY_MEMBER(&xml->xml_kids, 0, JSXML);
+        parent = kid->parent;
+        for (i = 1; i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->parent != parent)
+                return JS_TRUE;
+        }
+    }
+
+    if (!parent) {
+        *rval = JSVAL_NULL;
+        return JS_TRUE;
+    }
+
+    parentobj = js_GetXMLObject(cx, parent);
+    if (!parentobj)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(parentobj);
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_processingInstructions(JSContext *cx, JSObject *obj, uintN argc,
+                           jsval *argv, jsval *rval)
+{
+    JSXML *xml, *list, *kid, *vxml;
+    jsval name, v;
+    JSXMLQName *nameqn;
+    jsid funid;
+    JSObject *listobj, *kidobj;
+    JSBool ok;
+    uint32 i, n;
+
+    XML_METHOD_PROLOG;
+    name = (argc == 0) ? ATOM_KEY(cx->runtime->atomState.starAtom) : argv[0];
+    nameqn = ToXMLName(cx, name, &funid);
+    if (!nameqn)
+        return JS_FALSE;
+    argv[0] = OBJECT_TO_JSVAL(nameqn->object);
+
+    listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+    if (!listobj)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(listobj);
+    if (funid)
+        return JS_TRUE;
+
+    list = (JSXML *) JS_GetPrivate(cx, listobj);
+    list->xml_target = xml;
+    list->xml_targetprop = nameqn;
+    ok = JS_TRUE;
+
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        /* 13.5.4.17 Step 4 (misnumbered 9 -- Erratum?). */
+        for (i = 0, n = JSXML_LENGTH(xml); i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+                ok = JS_EnterLocalRootScope(cx);
+                if (!ok)
+                    break;
+                kidobj = js_GetXMLObject(cx, kid);
+                ok = kidobj
+                     ? xml_processingInstructions(cx, kidobj, argc, argv, &v)
+                     : JS_FALSE;
+                JS_LeaveLocalRootScope(cx);
+                if (!ok)
+                    break;
+                vxml = (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v));
+                if (JSXML_LENGTH(vxml) != 0) {
+                    ok = Append(cx, list, vxml);
+                    if (!ok)
+                        break;
+                }
+            }
+        }
+    } else {
+        /* 13.4.4.28 Step 4. */
+        for (i = 0, n = JSXML_LENGTH(xml); i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION &&
+                (IS_STAR(nameqn->localName) ||
+                 !js_CompareStrings(nameqn->localName, kid->name->localName))) {
+                ok = Append(cx, list, kid);
+                if (!ok)
+                    break;
+            }
+        }
+    }
+
+    return ok;
+}
+
+static JSBool
+xml_prependChild(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    JSXML *xml;
+
+    XML_METHOD_PROLOG;
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(obj);
+    return Insert(cx, xml, JSVAL_ZERO, argv[0]);
+}
+
+/* XML and XMLList */
+static JSBool
+xml_propertyIsEnumerable(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                         jsval *rval)
+{
+    JSXML *xml;
+    jsval name;
+    uint32 index;
+
+    XML_METHOD_PROLOG;
+    name = argv[0];
+    *rval = JSVAL_FALSE;
+    if (js_IdIsIndex(name, &index)) {
+        if (xml->xml_class == JSXML_CLASS_LIST) {
+            /* 13.5.4.18. */
+            *rval = BOOLEAN_TO_JSVAL(index < xml->xml_kids.length);
+        } else {
+            /* 13.4.4.30. */
+            *rval = BOOLEAN_TO_JSVAL(index == 0);
+        }
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+namespace_full_match(const void *a, const void *b)
+{
+    const JSXMLNamespace *nsa = (const JSXMLNamespace *) a;
+    const JSXMLNamespace *nsb = (const JSXMLNamespace *) b;
+
+    if (nsa->prefix && nsb->prefix &&
+        js_CompareStrings(nsa->prefix, nsb->prefix)) {
+        return JS_FALSE;
+    }
+    return !js_CompareStrings(nsa->uri, nsb->uri);
+}
+
+static JSBool
+xml_removeNamespace_helper(JSContext *cx, JSXML *xml, JSXMLNamespace *ns)
+{
+    JSXMLNamespace *thisns, *attrns;
+    uint32 i, n;
+    JSXML *attr, *kid;
+
+    thisns = GetNamespace(cx, xml->name, &xml->xml_namespaces);
+    JS_ASSERT(thisns);
+    if (thisns == ns)
+        return JS_TRUE;
+
+    for (i = 0, n = xml->xml_attrs.length; i < n; i++) {
+        attr = XMLARRAY_MEMBER(&xml->xml_attrs, i, JSXML);
+        attrns = GetNamespace(cx, attr->name, &xml->xml_namespaces);
+        JS_ASSERT(attrns);
+        if (attrns == ns)
+            return JS_TRUE;
+    }
+
+    i = XMLARRAY_FIND_MEMBER(&xml->xml_namespaces, ns, namespace_full_match);
+    if (i != XML_NOT_FOUND)
+        XMLArrayDelete(cx, &xml->xml_namespaces, i, JS_TRUE);
+
+    for (i = 0, n = xml->xml_kids.length; i < n; i++) {
+        kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+        if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+            if (!xml_removeNamespace_helper(cx, kid, ns))
+                return JS_FALSE;
+        }
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+xml_removeNamespace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                    jsval *rval)
+{
+    JSXML *xml;
+    JSObject *nsobj;
+    JSXMLNamespace *ns;
+
+    XML_METHOD_PROLOG;
+    *rval = OBJECT_TO_JSVAL(obj);
+    if (xml->xml_class != JSXML_CLASS_ELEMENT)
+        return JS_TRUE;
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml)
+        return JS_FALSE;
+
+    nsobj = CallConstructorFunction(cx, obj, &js_NamespaceClass.base, 1, argv);
+    if (!nsobj)
+        return JS_FALSE;
+    argv[0] = OBJECT_TO_JSVAL(nsobj);
+    ns = (JSXMLNamespace *) JS_GetPrivate(cx, nsobj);
+
+    /* NOTE: remove ns from each ancestor if not used by that ancestor. */
+    return xml_removeNamespace_helper(cx, xml, ns);
+}
+
+static JSBool
+xml_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSXML *xml, *vxml, *kid;
+    jsval name, value, id, junk;
+    uint32 index;
+    JSObject *nameobj;
+    JSXMLQName *nameqn;
+
+    XML_METHOD_PROLOG;
+    *rval = OBJECT_TO_JSVAL(obj);
+    if (xml->xml_class != JSXML_CLASS_ELEMENT)
+        return JS_TRUE;
+
+    value = argv[1];
+    vxml = VALUE_IS_XML(cx, value)
+           ? (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(value))
+           : NULL;
+    if (!vxml) {
+        if (!JS_ConvertValue(cx, value, JSTYPE_STRING, &argv[1]))
+            return JS_FALSE;
+        value = argv[1];
+    } else {
+        vxml = DeepCopy(cx, vxml, NULL, 0);
+        if (!vxml)
+            return JS_FALSE;
+        value = argv[1] = OBJECT_TO_JSVAL(vxml->object);
+    }
+
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml)
+        return JS_FALSE;
+
+    name = argv[0];
+    if (js_IdIsIndex(name, &index))
+        return Replace(cx, xml, name, value);
+
+    /* Call function QName per spec, not ToXMLName, to avoid attribute names. */
+    nameobj = CallConstructorFunction(cx, obj, &js_QNameClass.base, 1, &name);
+    if (!nameobj)
+        return JS_FALSE;
+    argv[0] = OBJECT_TO_JSVAL(nameobj);
+    nameqn = (JSXMLQName *) JS_GetPrivate(cx, nameobj);
+
+    id = JSVAL_VOID;
+    index = xml->xml_kids.length;
+    while (index != 0) {
+        --index;
+        kid = XMLARRAY_MEMBER(&xml->xml_kids, index, JSXML);
+        if (MatchElemName(nameqn, kid)) {
+            if (!JSVAL_IS_VOID(id) && !DeleteByIndex(cx, xml, id, &junk))
+                return JS_FALSE;
+            if (!IndexToIdVal(cx, index, &id))
+                return JS_FALSE;
+        }
+    }
+    if (JSVAL_IS_VOID(id))
+        return JS_TRUE;
+    return Replace(cx, xml, id, value);
+}
+
+static JSBool
+xml_setChildren(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    if (!PutProperty(cx, obj, ATOM_KEY(cx->runtime->atomState.starAtom),
+                     &argv[0])) {
+        return JS_FALSE;
+    }
+
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+static JSBool
+xml_setLocalName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    JSXML *xml;
+    jsval name;
+    JSXMLQName *nameqn;
+    JSString *namestr;
+
+    XML_METHOD_PROLOG;
+    if (!JSXML_HAS_NAME(xml))
+        return JS_TRUE;
+
+    name = argv[0];
+    if (!JSVAL_IS_PRIMITIVE(name) &&
+        OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(name)) == &js_QNameClass.base) {
+        nameqn = (JSXMLQName *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(name));
+        namestr = nameqn->localName;
+    } else {
+        if (!JS_ConvertValue(cx, name, JSTYPE_STRING, &argv[0]))
+            return JS_FALSE;
+        name = argv[0];
+        namestr = JSVAL_TO_STRING(name);
+    }
+
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml)
+        return JS_FALSE;
+    xml->name->localName = namestr;
+    return JS_TRUE;
+}
+
+static JSBool
+xml_setName(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSXML *xml, *nsowner;
+    jsval name;
+    JSXMLQName *nameqn;
+    JSObject *nameobj;
+    JSXMLArray *nsarray;
+    uint32 i, n;
+    JSXMLNamespace *ns;
+
+    XML_METHOD_PROLOG;
+    if (!JSXML_HAS_NAME(xml))
+        return JS_TRUE;
+
+    name = argv[0];
+    if (!JSVAL_IS_PRIMITIVE(name) &&
+        OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(name)) == &js_QNameClass.base &&
+        !(nameqn = (JSXMLQName *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(name)))
+         ->uri) {
+        name = argv[0] = STRING_TO_JSVAL(nameqn->localName);
+    }
+
+    nameobj = js_ConstructObject(cx, &js_QNameClass.base, NULL, NULL, 1, &name);
+    if (!nameobj)
+        return JS_FALSE;
+    nameqn = (JSXMLQName *) JS_GetPrivate(cx, nameobj);
+
+    /* ECMA-357 13.4.4.35 Step 4. */
+    if (xml->xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION)
+        nameqn->uri = cx->runtime->emptyString;
+
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml)
+        return JS_FALSE;
+    xml->name = nameqn;
+
+    /*
+     * Erratum: nothing in 13.4.4.35 talks about making the name match the
+     * in-scope namespaces, either by finding an in-scope namespace with a
+     * matching uri and setting the new name's prefix to that namespace's
+     * prefix, or by extending the in-scope namespaces for xml (which are in
+     * xml->parent if xml is an attribute or a PI).
+     */
+    if (xml->xml_class == JSXML_CLASS_ELEMENT) {
+        nsowner = xml;
+    } else {
+        if (!xml->parent || xml->parent->xml_class != JSXML_CLASS_ELEMENT)
+            return JS_TRUE;
+        nsowner = xml->parent;
+    }
+
+    if (nameqn->prefix) {
+        /*
+         * The name being set has a prefix, which originally came from some
+         * namespace object (which may be the null namespace, where both the
+         * prefix and uri are the empty string).  We must go through a full
+         * GetNamespace in case that namespace is in-scope in nsowner.
+         *
+         * If we find such an in-scope namespace, we return true right away,
+         * in this block.  Otherwise, we fall through to the final return of
+         * AddInScopeNamespace(cx, nsowner, ns).
+         */
+        ns = GetNamespace(cx, nameqn, &nsowner->xml_namespaces);
+        if (!ns)
+            return JS_FALSE;
+
+        /* XXXbe have to test membership to see whether GetNamespace added */
+        if (XMLARRAY_HAS_MEMBER(&nsowner->xml_namespaces, ns, NULL))
+            return JS_TRUE;
+    } else {
+        /*
+         * At this point, we know nameqn->prefix is null, so nameqn->uri can't
+         * be the empty string (the null namespace always uses the empty string
+         * for both prefix and uri).
+         *
+         * This means we must inline GetNamespace and specialize it to match
+         * uri only, never prefix.  If we find a namespace with nameqn's uri
+         * already in nsowner->xml_namespaces, then all that we need do is set
+         * nameqn->prefix to that namespace's prefix.
+         *
+         * If no such namespace exists, we can create one without going through
+         * the constructor, because we know nameqn->uri is non-empty (so prefix
+         * does not need to be converted from null to empty by QName).
+         */
+        JS_ASSERT(!IS_EMPTY(nameqn->uri));
+
+        nsarray = &nsowner->xml_namespaces;
+        for (i = 0, n = nsarray->length; i < n; i++) {
+            ns = XMLARRAY_MEMBER(nsarray, i, JSXMLNamespace);
+            if (!js_CompareStrings(ns->uri, nameqn->uri)) {
+                nameqn->prefix = ns->prefix;
+                return JS_TRUE;
+            }
+        }
+
+        ns = js_NewXMLNamespace(cx, NULL, nameqn->uri, JS_TRUE);
+        if (!ns)
+            return JS_FALSE;
+    }
+
+    return AddInScopeNamespace(cx, nsowner, ns);
+}
+
+static JSBool
+xml_setNamespace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    JSXML *xml, *nsowner;
+    JSObject *nsobj, *qnobj;
+    JSXMLNamespace *ns;
+    jsval qnargv[2];
+
+    XML_METHOD_PROLOG;
+    if (xml->xml_class != JSXML_CLASS_ELEMENT &&
+        xml->xml_class != JSXML_CLASS_ATTRIBUTE) {
+        return JS_TRUE;
+    }
+
+    xml = CHECK_COPY_ON_WRITE(cx, xml, obj);
+    if (!xml || !js_GetXMLQNameObject(cx, xml->name))
+        return JS_FALSE;
+
+    nsobj = js_ConstructObject(cx, &js_NamespaceClass.base, NULL, obj, 1, argv);
+    if (!nsobj)
+        return JS_FALSE;
+    ns = (JSXMLNamespace *) JS_GetPrivate(cx, nsobj);
+    ns->declared = JS_TRUE;
+
+    qnargv[0] = argv[0] = OBJECT_TO_JSVAL(nsobj);
+    qnargv[1] = OBJECT_TO_JSVAL(xml->name->object);
+    qnobj = js_ConstructObject(cx, &js_QNameClass.base, NULL, NULL, 2, qnargv);
+    if (!qnobj)
+        return JS_FALSE;
+
+    xml->name = (JSXMLQName *) JS_GetPrivate(cx, qnobj);
+
+    /*
+     * Erratum: the spec fails to update the governing in-scope namespaces.
+     * See the erratum noted in xml_setName, above.
+     */
+    if (xml->xml_class == JSXML_CLASS_ELEMENT) {
+        nsowner = xml;
+    } else {
+        if (!xml->parent || xml->parent->xml_class != JSXML_CLASS_ELEMENT)
+            return JS_TRUE;
+        nsowner = xml->parent;
+    }
+    return AddInScopeNamespace(cx, nsowner, ns);
+}
+
+/* XML and XMLList */
+static JSBool
+xml_text(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSXML *xml, *list, *kid, *vxml;
+    JSObject *listobj, *kidobj;
+    uint32 i, n;
+    JSBool ok;
+    jsval v;
+
+    XML_METHOD_PROLOG;
+    listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+    if (!listobj)
+        return JS_FALSE;
+
+    *rval = OBJECT_TO_JSVAL(listobj);
+    list = (JSXML *) JS_GetPrivate(cx, listobj);
+    list->xml_target = xml;
+
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        ok = JS_TRUE;
+        for (i = 0, n = xml->xml_kids.length; i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_ELEMENT) {
+                ok = JS_EnterLocalRootScope(cx);
+                if (!ok)
+                    break;
+                kidobj = js_GetXMLObject(cx, kid);
+                ok = kidobj
+                     ? xml_text(cx, kidobj, argc, argv, &v)
+                     : JS_FALSE;
+                JS_LeaveLocalRootScope(cx);
+                if (!ok)
+                    return JS_FALSE;
+                vxml = (JSXML *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v));
+                if (JSXML_LENGTH(vxml) != 0 && !Append(cx, list, vxml))
+                    return JS_FALSE;
+            }
+        }
+    } else {
+        for (i = 0, n = JSXML_LENGTH(xml); i < n; i++) {
+            kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            if (kid->xml_class == JSXML_CLASS_TEXT && !Append(cx, list, kid))
+                return JS_FALSE;
+        }
+    }
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_toXMLString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    JSString *str;
+
+    str = ToXMLString(cx, OBJECT_TO_JSVAL(obj));
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSString *
+xml_toString_helper(JSContext *cx, JSXML *xml)
+{
+    JSString *str, *kidstr;
+    JSXML *kid;
+    uint32 i, n;
+
+    if (xml->xml_class == JSXML_CLASS_ATTRIBUTE ||
+        xml->xml_class == JSXML_CLASS_TEXT) {
+        return xml->xml_value;
+    }
+
+    if (!HasSimpleContent(xml))
+        return ToXMLString(cx, OBJECT_TO_JSVAL(xml->object));
+
+    str = cx->runtime->emptyString;
+    JS_EnterLocalRootScope(cx);
+    for (i = 0, n = xml->xml_kids.length; i < n; i++) {
+        kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+        if (kid->xml_class != JSXML_CLASS_COMMENT &&
+            kid->xml_class != JSXML_CLASS_PROCESSING_INSTRUCTION) {
+            kidstr = xml_toString_helper(cx, kid);
+            if (!kidstr) {
+                str = NULL;
+                break;
+            }
+            str = js_ConcatStrings(cx, str, kidstr);
+            if (!str)
+                break;
+        }
+    }
+    JS_LeaveLocalRootScope(cx);
+    return str;
+}
+
+static JSBool
+xml_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+             jsval *rval)
+{
+    JSXML *xml;
+    JSString *str;
+
+    XML_METHOD_PROLOG;
+    str = xml_toString_helper(cx, xml);
+    if (!str)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
+/* XML and XMLList */
+static JSBool
+xml_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+static JSFunctionSpec xml_methods[] = {
+    {"addNamespace",          xml_addNamespace,          1,0,XML_MASK},
+    {"appendChild",           xml_appendChild,           1,0,XML_MASK},
+    {js_attribute_str,        xml_attribute,             1,0,GENERIC_MASK},
+    {"attributes",            xml_attributes,            0,0,GENERIC_MASK},
+    {"child",                 xml_child,                 1,0,GENERIC_MASK},
+    {"childIndex",            xml_childIndex,            0,0,XML_MASK},
+    {"children",              xml_children,              0,0,GENERIC_MASK},
+    {"comments",              xml_comments,              0,0,GENERIC_MASK},
+    {"contains",              xml_contains,              1,0,GENERIC_MASK},
+    {"copy",                  xml_copy,                  0,0,GENERIC_MASK},
+    {"descendants",           xml_descendants,           1,0,GENERIC_MASK},
+    {"elements",              xml_elements,              1,0,GENERIC_MASK},
+    {"hasOwnProperty",        xml_hasOwnProperty,        1,0,GENERIC_MASK},
+    {"hasComplexContent",     xml_hasComplexContent,     1,0,GENERIC_MASK},
+    {"hasSimpleContent",      xml_hasSimpleContent,      1,0,GENERIC_MASK},
+    {"inScopeNamespaces",     xml_inScopeNamespaces,     0,0,XML_MASK},
+    {"insertChildAfter",      xml_insertChildAfter,      2,0,XML_MASK},
+    {"insertChildBefore",     xml_insertChildBefore,     2,0,XML_MASK},
+    {js_length_str,           xml_length,                0,0,GENERIC_MASK},
+    {js_localName_str,        xml_localName,             0,0,XML_MASK},
+    {js_name_str,             xml_name,                  0,0,XML_MASK},
+    {js_namespace_str,        xml_namespace,             1,0,XML_MASK},
+    {"namespaceDeclarations", xml_namespaceDeclarations, 0,0,XML_MASK},
+    {"nodeKind",              xml_nodeKind,              0,0,XML_MASK},
+    {"normalize",             xml_normalize,             0,0,GENERIC_MASK},
+    {js_xml_parent_str,       xml_parent,                0,0,GENERIC_MASK},
+    {"processingInstructions",xml_processingInstructions,1,0,GENERIC_MASK},
+    {"prependChild",          xml_prependChild,          1,0,XML_MASK},
+    {"propertyIsEnumerable",  xml_propertyIsEnumerable,  1,0,GENERIC_MASK},
+    {"removeNamespace",       xml_removeNamespace,       1,0,XML_MASK},
+    {"replace",               xml_replace,               2,0,XML_MASK},
+    {"setChildren",           xml_setChildren,           1,0,XML_MASK},
+    {"setLocalName",          xml_setLocalName,          1,0,XML_MASK},
+    {"setName",               xml_setName,               1,0,XML_MASK},
+    {"setNamespace",          xml_setNamespace,          1,0,XML_MASK},
+    {js_text_str,             xml_text,                  0,0,GENERIC_MASK},
+    {js_toString_str,         xml_toString,              0,0,GENERIC_MASK},
+    {js_toXMLString_str,      xml_toXMLString,           0,0,GENERIC_MASK},
+    {js_valueOf_str,          xml_valueOf,               0,0,GENERIC_MASK},
+    {0,0,0,0,0}
+};
+
+static JSBool
+CopyXMLSettings(JSContext *cx, JSObject *from, JSObject *to)
+{
+    int i;
+    const char *name;
+    jsval v;
+
+    for (i = XML_IGNORE_COMMENTS; i < XML_PRETTY_INDENT; i++) {
+        name = xml_static_props[i].name;
+        if (!JS_GetProperty(cx, from, name, &v))
+            return JS_FALSE;
+        if (JSVAL_IS_BOOLEAN(v) && !JS_SetProperty(cx, to, name, &v))
+            return JS_FALSE;
+    }
+
+    name = xml_static_props[i].name;
+    if (!JS_GetProperty(cx, from, name, &v))
+        return JS_FALSE;
+    if (JSVAL_IS_NUMBER(v) && !JS_SetProperty(cx, to, name, &v))
+        return JS_FALSE;
+    return JS_TRUE;
+}
+
+static JSBool
+SetDefaultXMLSettings(JSContext *cx, JSObject *obj)
+{
+    int i;
+    jsval v;
+
+    for (i = XML_IGNORE_COMMENTS; i < XML_PRETTY_INDENT; i++) {
+        v = JSVAL_TRUE;
+        if (!JS_SetProperty(cx, obj, xml_static_props[i].name, &v))
+            return JS_FALSE;
+    }
+    v = INT_TO_JSVAL(2);
+    return JS_SetProperty(cx, obj, xml_static_props[i].name, &v);
+}
+
+static JSBool
+xml_settings(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    JSObject *settings;
+
+    settings = JS_NewObject(cx, NULL, NULL, NULL);
+    if (!settings)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(settings);
+    return CopyXMLSettings(cx, obj, settings);
+}
+
+static JSBool
+xml_setSettings(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                jsval *rval)
+{
+    jsval v;
+    JSBool ok;
+    JSObject *settings;
+
+    v = argv[0];
+    if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) {
+        cx->xmlSettingFlags = 0;
+        ok = SetDefaultXMLSettings(cx, obj);
+    } else {
+        if (JSVAL_IS_PRIMITIVE(v))
+            return JS_TRUE;
+        settings = JSVAL_TO_OBJECT(v);
+        cx->xmlSettingFlags = 0;
+        ok = CopyXMLSettings(cx, settings, obj);
+    }
+    if (ok)
+        cx->xmlSettingFlags |= XSF_CACHE_VALID;
+    return ok;
+}
+
+static JSBool
+xml_defaultSettings(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                    jsval *rval)
+{
+    JSObject *settings;
+
+    settings = JS_NewObject(cx, NULL, NULL, NULL);
+    if (!settings)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(settings);
+    return SetDefaultXMLSettings(cx, settings);
+}
+
+static JSFunctionSpec xml_static_methods[] = {
+    {"settings",         xml_settings,          0,0,0},
+    {"setSettings",      xml_setSettings,       1,0,0},
+    {"defaultSettings",  xml_defaultSettings,   0,0,0},
+    {0,0,0,0,0}
+};
+
+static JSBool
+XML(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval v;
+    JSXML *xml, *copy;
+    JSObject *xobj, *vobj;
+    JSClass *clasp;
+
+    v = argv[0];
+    if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v))
+        v = STRING_TO_JSVAL(cx->runtime->emptyString);
+
+    xobj = ToXML(cx, v);
+    if (!xobj)
+        return JS_FALSE;
+    *rval = OBJECT_TO_JSVAL(xobj);
+    xml = (JSXML *) JS_GetPrivate(cx, xobj);
+
+    if ((cx->fp->flags & JSFRAME_CONSTRUCTING) && !JSVAL_IS_PRIMITIVE(v)) {
+        vobj = JSVAL_TO_OBJECT(v);
+        clasp = OBJ_GET_CLASS(cx, vobj);
+        if (clasp == &js_XMLClass ||
+            (clasp->flags & JSCLASS_DOCUMENT_OBSERVER)) {
+            /* No need to lock obj, it's newly constructed and thread local. */
+            copy = DeepCopy(cx, xml, obj, 0);
+            if (!copy)
+                return JS_FALSE;
+            JS_ASSERT(copy->object == obj);
+            *rval = OBJECT_TO_JSVAL(obj);
+            return JS_TRUE;
+        }
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+XMLList(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    jsval v;
+    JSObject *vobj, *listobj;
+    JSXML *xml, *list;
+
+    v = argv[0];
+    if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v))
+        v = STRING_TO_JSVAL(cx->runtime->emptyString);
+
+    if ((cx->fp->flags & JSFRAME_CONSTRUCTING) && !JSVAL_IS_PRIMITIVE(v)) {
+        vobj = JSVAL_TO_OBJECT(v);
+        if (OBJECT_IS_XML(cx, vobj)) {
+            xml = (JSXML *) JS_GetPrivate(cx, vobj);
+            if (xml->xml_class == JSXML_CLASS_LIST) {
+                listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+                if (!listobj)
+                    return JS_FALSE;
+                *rval = OBJECT_TO_JSVAL(listobj);
+
+                list = (JSXML *) JS_GetPrivate(cx, listobj);
+                if (!Append(cx, list, xml))
+                    return JS_FALSE;
+                return JS_TRUE;
+            }
+        }
+    }
+
+    /* Toggle on XML support since the script has explicitly requested it. */
+    listobj = ToXMLList(cx, v);
+    if (!listobj)
+        return JS_FALSE;
+
+    *rval = OBJECT_TO_JSVAL(listobj);
+    return JS_TRUE;
+}
+
+#define JSXML_LIST_SIZE     (offsetof(JSXML, u) + sizeof(struct JSXMLListVar))
+#define JSXML_ELEMENT_SIZE  (offsetof(JSXML, u) + sizeof(struct JSXMLVar))
+#define JSXML_LEAF_SIZE     (offsetof(JSXML, u) + sizeof(JSString *))
+
+static size_t sizeof_JSXML[JSXML_CLASS_LIMIT] = {
+    JSXML_LIST_SIZE,        /* JSXML_CLASS_LIST */
+    JSXML_ELEMENT_SIZE,     /* JSXML_CLASS_ELEMENT */
+    JSXML_LEAF_SIZE,        /* JSXML_CLASS_ATTRIBUTE */
+    JSXML_LEAF_SIZE,        /* JSXML_CLASS_PROCESSING_INSTRUCTION */
+    JSXML_LEAF_SIZE,        /* JSXML_CLASS_TEXT */
+    JSXML_LEAF_SIZE         /* JSXML_CLASS_COMMENT */
+};
+
+#ifdef DEBUG_notme
+JSCList xml_leaks = JS_INIT_STATIC_CLIST(&xml_leaks);
+uint32  xml_serial;
+#endif
+
+JSXML *
+js_NewXML(JSContext *cx, JSXMLClass xml_class)
+{
+    JSXML *xml;
+
+    xml = (JSXML *) js_NewGCThing(cx, GCX_XML, sizeof_JSXML[xml_class]);
+    if (!xml)
+        return NULL;
+
+    xml->object = NULL;
+    xml->domnode = NULL;
+    xml->parent = NULL;
+    xml->name = NULL;
+    xml->xml_class = xml_class;
+    xml->xml_flags = 0;
+    if (JSXML_CLASS_HAS_VALUE(xml_class)) {
+        xml->xml_value = cx->runtime->emptyString;
+    } else {
+        XMLArrayInit(cx, &xml->xml_kids, 0);
+        if (xml_class == JSXML_CLASS_LIST) {
+            xml->xml_target = NULL;
+            xml->xml_targetprop = NULL;
+        } else {
+            XMLArrayInit(cx, &xml->xml_namespaces, 0);
+            XMLArrayInit(cx, &xml->xml_attrs, 0);
+        }
+    }
+
+#ifdef DEBUG_notme
+    JS_APPEND_LINK(&xml->links, &xml_leaks);
+    xml->serial = xml_serial++;
+#endif
+    METER(xml_stats.xml);
+    METER(xml_stats.livexml);
+    return xml;
+}
+
+/*
+ * Code factored from js_MarkXML for use by xml_DeutschScorrWaite, see below.
+ * All things marked here cannot lead to overlong lists (mark stack overflow).
+ */
+static void
+xml_mark_tail(JSContext *cx, JSXML *xml, void *arg)
+{
+    XMLArrayTrim(&xml->xml_kids);
+
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        if (xml->xml_target)
+            js_MarkXML(cx, xml->xml_target, arg);
+        if (xml->xml_targetprop)
+            js_MarkXMLQName(cx, xml->xml_targetprop, arg);
+    } else {
+        namespace_mark_vector(cx,
+                              (JSXMLNamespace **) xml->xml_namespaces.vector,
+                              xml->xml_namespaces.length,
+                              arg);
+        XMLArrayTrim(&xml->xml_namespaces);
+
+        xml_mark_vector(cx,
+                        (JSXML **) xml->xml_attrs.vector,
+                        xml->xml_attrs.length,
+                        arg);
+        XMLArrayTrim(&xml->xml_attrs);
+    }
+}
+
+static void
+xml_DeutschSchorrWaite(JSContext *cx, JSXML *xml, void *arg)
+{
+    JSXML *top, *kid;
+    uint8 *flagp;
+    uint32 i, n;
+#ifdef JS_GCMETER
+    JSRuntime *rt = cx->runtime;
+# define GCMETER(x)     x
+#else
+# define GCMETER(x)     /* nothing */
+#endif
+
+    top = NULL;
+    flagp = js_GetGCThingFlags(xml);
+
+down:
+    GCMETER(if (++rt->gcStats.dswdepth > rt->gcStats.maxdswdepth)
+                rt->gcStats.maxdswdepth = rt->gcStats.dswdepth);
+
+    *flagp |= GCF_MARK;
+
+    i = 0;
+    for (;;) {
+        /*
+         * Let (i == n) index xml->parent, not any child in xml->xml_kids.
+         * Use JSXML_LENGTH here and below in case xml is a leaf node whose
+         * parent we are marking non-recursively.  In the case where parent
+         * is being marked, the "kid/down" sense is backwards -- humor me.
+         */
+        for (n = JSXML_LENGTH(xml); i <= n; i++) {
+            if (i < n) {
+                kid = XMLARRAY_MEMBER(&xml->xml_kids, i, JSXML);
+            } else {
+                kid = xml->parent;
+                if (!kid)
+                    continue;
+            }
+
+            flagp = js_GetGCThingFlags(kid);
+            if (*flagp & GCF_MARK)
+                continue;
+
+            /*
+             * Don't descend if a for..in loop is enumerating xml's kids, i.e.
+             * if xml has kids and its xml_kids.cursors member is non-null.
+             */
+            if (JSXML_HAS_KIDS(kid) &&
+                (JSXML_HAS_VALUE(xml) || !xml->xml_kids.cursors)) {
+                if (i < n)
+                    XMLARRAY_SET_MEMBER(&xml->xml_kids, i, top);
+                else
+                    xml->parent = top;
+                if (JSXML_HAS_KIDS(xml))
+                    xml->xml_kids.cursors = JS_UINT32_TO_PTR(i);
+                top = xml;
+                xml = kid;
+                goto down;
+            }
+
+            js_MarkXML(cx, kid, arg);
+        }
+
+        /* If we are back at the root (or we never left it), we're done. */
+        GCMETER(rt->gcStats.dswdepth--);
+        xml->xml_kids.cursors = NULL;
+        if (!top)
+            return;
+
+        /* Time to go back up the spanning tree. */
+        GCMETER(rt->gcStats.dswup++);
+        i = JSXML_HAS_KIDS(top) ? JS_PTR_TO_UINT32(top->xml_kids.cursors) : 0;
+        if (i < JSXML_LENGTH(top)) {
+            kid = XMLARRAY_MEMBER(&top->xml_kids, i, JSXML);
+            XMLARRAY_SET_MEMBER(&top->xml_kids, i, xml);
+        } else {
+            JS_ASSERT(i == JSXML_LENGTH(top));
+            kid = top->parent;
+            top->parent = xml;
+        }
+        xml = top;
+        top = kid;
+        i++;
+    }
+#undef GCMETER
+}
+
+void
+js_MarkXML(JSContext *cx, JSXML *xml, void *arg)
+{
+    int stackDummy;
+
+    JS_MarkGCThing(cx, xml->object, js_object_str, arg);
+    JS_MarkGCThing(cx, xml->name, js_name_str, arg);
+    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
+        xml_DeutschSchorrWaite(cx, xml, arg);
+    } else {
+        JS_MarkGCThing(cx, xml->parent, js_xml_parent_str, arg);
+
+        if (JSXML_HAS_VALUE(xml)) {
+            JS_MarkGCThing(cx, xml->xml_value, "value", arg);
+        } else {
+            xml_mark_vector(cx,
+                            (JSXML **) xml->xml_kids.vector,
+                            xml->xml_kids.length,
+                            arg);
+
+            xml_mark_tail(cx, xml, arg);
+        }
+    }
+}
+
+void
+js_FinalizeXML(JSContext *cx, JSXML *xml)
+{
+    if (JSXML_HAS_KIDS(xml)) {
+        XMLArrayFinish(cx, &xml->xml_kids);
+        if (xml->xml_class == JSXML_CLASS_ELEMENT) {
+            XMLArrayFinish(cx, &xml->xml_namespaces);
+            XMLArrayFinish(cx, &xml->xml_attrs);
+        }
+    }
+
+#ifdef DEBUG_notme
+    JS_REMOVE_LINK(&xml->links);
+#endif
+
+    UNMETER(xml_stats.livexml);
+}
+
+JSObject *
+js_ParseNodeToXMLObject(JSContext *cx, JSParseNode *pn)
+{
+    jsval nsval;
+    JSXMLNamespace *ns;
+    JSXMLArray nsarray;
+    JSXML *xml;
+
+    if (!js_GetDefaultXMLNamespace(cx, &nsval))
+        return NULL;
+    JS_ASSERT(!JSVAL_IS_PRIMITIVE(nsval));
+    ns = (JSXMLNamespace *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(nsval));
+
+    if (!XMLArrayInit(cx, &nsarray, 1))
+        return NULL;
+
+    XMLARRAY_APPEND(cx, &nsarray, ns);
+    xml = ParseNodeToXML(cx, pn, &nsarray, XSF_PRECOMPILED_ROOT);
+    XMLArrayFinish(cx, &nsarray);
+    if (!xml)
+        return NULL;
+
+    return xml->object;
+}
+
+JSObject *
+js_NewXMLObject(JSContext *cx, JSXMLClass xml_class)
+{
+    JSXML *xml;
+
+    xml = js_NewXML(cx, xml_class);
+    if (!xml)
+        return NULL;
+    return js_GetXMLObject(cx, xml);
+}
+
+static JSObject *
+NewXMLObject(JSContext *cx, JSXML *xml)
+{
+    JSObject *obj;
+
+    obj = js_NewObject(cx, &js_XMLClass, NULL, NULL);
+    if (!obj || !JS_SetPrivate(cx, obj, xml)) {
+        cx->newborn[GCX_OBJECT] = NULL;
+        return NULL;
+    }
+    METER(xml_stats.xmlobj);
+    METER(xml_stats.livexmlobj);
+    return obj;
+}
+
+JSObject *
+js_GetXMLObject(JSContext *cx, JSXML *xml)
+{
+    JSObject *obj;
+
+    obj = xml->object;
+    if (obj) {
+        JS_ASSERT(JS_GetPrivate(cx, obj) == xml);
+        return obj;
+    }
+
+    /*
+     * A JSXML cannot be shared among threads unless it has an object.
+     * A JSXML cannot be given an object unless:
+     * (a) it has no parent; or
+     * (b) its parent has no object (therefore is thread-private); or
+     * (c) its parent's object is locked.
+     *
+     * Once given an object, a JSXML is immutable.
+     */
+    JS_ASSERT(!xml->parent ||
+              !xml->parent->object ||
+              JS_IS_OBJ_LOCKED(cx, xml->parent->object));
+
+    obj = NewXMLObject(cx, xml);
+    if (!obj)
+        return NULL;
+    xml->object = obj;
+    return obj;
+}
+
+JSObject *
+js_InitNamespaceClass(JSContext *cx, JSObject *obj)
+{
+    return JS_InitClass(cx, obj, NULL, &js_NamespaceClass.base, Namespace, 2,
+                        namespace_props, namespace_methods, NULL, NULL);
+}
+
+JSObject *
+js_InitQNameClass(JSContext *cx, JSObject *obj)
+{
+    return JS_InitClass(cx, obj, NULL, &js_QNameClass.base, QName, 2,
+                        qname_props, qname_methods, NULL, NULL);
+}
+
+JSObject *
+js_InitAttributeNameClass(JSContext *cx, JSObject *obj)
+{
+    return JS_InitClass(cx, obj, NULL, &js_AttributeNameClass, AttributeName, 2,
+                        qname_props, qname_methods, NULL, NULL);
+}
+
+JSObject *
+js_InitAnyNameClass(JSContext *cx, JSObject *obj)
+{
+    jsval v;
+
+    if (!js_GetAnyName(cx, &v))
+        return NULL;
+    return JSVAL_TO_OBJECT(v);
+}
+
+JSObject *
+js_InitXMLClass(JSContext *cx, JSObject *obj)
+{
+    JSObject *proto, *pobj, *ctor;
+    JSFunctionSpec *fs;
+    JSFunction *fun;
+    JSXML *xml;
+    JSProperty *prop;
+    JSScopeProperty *sprop;
+    jsval cval, argv[1], junk;
+
+    /* Define the isXMLName function. */
+    if (!JS_DefineFunction(cx, obj, js_isXMLName_str, xml_isXMLName, 1, 0))
+        return NULL;
+
+    /* Define the XML class constructor and prototype. */
+    proto = JS_InitClass(cx, obj, NULL, &js_XMLClass, XML, 1,
+                         NULL, NULL,
+                         xml_static_props, xml_static_methods);
+    if (!proto)
+        return NULL;
+
+    /*
+     * XXX Hack alert: expand JS_DefineFunctions here to copy fs->extra into
+     * fun->spare, clearing fun->extra.  No xml_methods require extra local GC
+     * roots allocated after actual arguments on the VM stack, but we need a
+     * way to tell which methods work only on XML objects, which work only on
+     * XMLList objects, and which work on either.
+     */
+    for (fs = xml_methods; fs->name; fs++) {
+        fun = JS_DefineFunction(cx, proto, fs->name, fs->call, fs->nargs,
+                                fs->flags);
+        if (!fun)
+            return NULL;
+        fun->extra = 0;
+        fun->spare = fs->extra;
+    }
+
+    xml = js_NewXML(cx, JSXML_CLASS_TEXT);
+    if (!xml || !JS_SetPrivate(cx, proto, xml))
+        return NULL;
+    xml->object = proto;
+    METER(xml_stats.xmlobj);
+    METER(xml_stats.livexmlobj);
+
+    /*
+     * Prepare to set default settings on the XML constructor we just made.
+     * NB: We can't use JS_GetConstructor, because it calls OBJ_GET_PROPERTY,
+     * which is xml_getProperty, which creates a new XMLList every time!  We
+     * must instead call js_LookupProperty directly.
+     */
+    if (!js_LookupProperty(cx, proto,
+                           ATOM_TO_JSID(cx->runtime->atomState.constructorAtom),
+                           &pobj, &prop)) {
+        return NULL;
+    }
+    JS_ASSERT(prop);
+    sprop = (JSScopeProperty *) prop;
+    JS_ASSERT(SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)));
+    cval = OBJ_GET_SLOT(cx, pobj, sprop->slot);
+    OBJ_DROP_PROPERTY(cx, pobj, prop);
+    JS_ASSERT(JSVAL_IS_FUNCTION(cx, cval));
+
+    /* Set default settings. */
+    ctor = JSVAL_TO_OBJECT(cval);
+    argv[0] = JSVAL_VOID;
+    if (!xml_setSettings(cx, ctor, 1, argv, &junk))
+        return NULL;
+
+    /* Define the XMLList function and give it the same prototype as XML. */
+    fun = JS_DefineFunction(cx, obj, js_XMLList_str, XMLList, 1, 0);
+    if (!fun)
+        return NULL;
+    if (!js_SetClassPrototype(cx, fun->object, proto,
+                              JSPROP_READONLY | JSPROP_PERMANENT)) {
+        return NULL;
+    }
+    return proto;
+}
+
+JSObject *
+js_InitXMLClasses(JSContext *cx, JSObject *obj)
+{
+    if (!js_InitNamespaceClass(cx, obj))
+        return NULL;
+    if (!js_InitQNameClass(cx, obj))
+        return NULL;
+    if (!js_InitAttributeNameClass(cx, obj))
+        return NULL;
+    if (!js_InitAnyNameClass(cx, obj))
+        return NULL;
+    return js_InitXMLClass(cx, obj);
+}
+
+JSBool
+js_GetFunctionNamespace(JSContext *cx, jsval *vp)
+{
+    JSRuntime *rt;
+    JSObject *obj;
+    JSAtom *atom;
+    JSString *prefix, *uri;
+
+    /* An invalid URI, for internal use only, guaranteed not to collide. */
+    static const char anti_uri[] = "@mozilla.org/js/function";
+
+    rt = cx->runtime;
+    obj = rt->functionNamespaceObject;
+    if (!obj) {
+        atom = js_Atomize(cx, js_function_str, 8, 0);
+        JS_ASSERT(atom);
+        prefix = ATOM_TO_STRING(atom);
+
+        atom = js_Atomize(cx, anti_uri, sizeof anti_uri - 1, ATOM_PINNED);
+        if (!atom)
+            return JS_FALSE;
+        rt->atomState.lazy.functionNamespaceURIAtom = atom;
+
+        uri = ATOM_TO_STRING(atom);
+        obj = js_NewXMLNamespaceObject(cx, prefix, uri, JS_FALSE);
+        if (!obj)
+            return JS_FALSE;
+
+        /*
+         * Avoid entraining any in-scope Object.prototype.  The loss of
+         * Namespace.prototype is not detectable, as there is no way to
+         * refer to this instance in scripts.  When used to qualify method
+         * names, its prefix and uri references are copied to the QName.
+         */
+        OBJ_SET_PROTO(cx, obj, NULL);
+        OBJ_SET_PARENT(cx, obj, NULL);
+        rt->functionNamespaceObject = obj;
+    }
+    *vp = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+/*
+ * Note the asymmetry between js_GetDefaultXMLNamespace and js_SetDefaultXML-
+ * Namespace.  Get searches fp->scopeChain for JS_DEFAULT_XML_NAMESPACE_ID,
+ * while Set sets JS_DEFAULT_XML_NAMESPACE_ID in fp->varobj (unless fp is a
+ * lightweight function activation).  There's no requirement that fp->varobj
+ * lie directly on fp->scopeChain, although it should be reachable using the
+ * prototype chain from a scope object (cf. JSOPTION_VAROBJFIX in jsapi.h).
+ *
+ * If Get can't find JS_DEFAULT_XML_NAMESPACE_ID along the scope chain, it
+ * creates a default namespace via 'new Namespace()'.  In contrast, Set uses
+ * its v argument as the uri of a new Namespace, with "" as the prefix.  See
+ * ECMA-357 12.1 and 12.1.1.  Note that if Set is called with a Namespace n,
+ * the default XML namespace will be set to ("", n.uri).  So the uri string
+ * is really the only usefully stored value of the default namespace.
+ */
+JSBool
+js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp)
+{
+    JSStackFrame *fp;
+    JSObject *nsobj, *obj, *tmp;
+    jsval v;
+
+    fp = cx->fp;
+    nsobj = fp->xmlNamespace;
+    if (nsobj) {
+        *vp = OBJECT_TO_JSVAL(nsobj);
+        return JS_TRUE;
+    }
+
+    obj = NULL;
+    for (tmp = fp->scopeChain; tmp; tmp = OBJ_GET_PARENT(cx, obj)) {
+        obj = tmp;
+        if (!OBJ_GET_PROPERTY(cx, obj, JS_DEFAULT_XML_NAMESPACE_ID, &v))
+            return JS_FALSE;
+        if (!JSVAL_IS_PRIMITIVE(v)) {
+            fp->xmlNamespace = JSVAL_TO_OBJECT(v);
+            *vp = v;
+            return JS_TRUE;
+        }
+    }
+
+    nsobj = js_ConstructObject(cx, &js_NamespaceClass.base, NULL, obj, 0, NULL);
+    if (!nsobj)
+        return JS_FALSE;
+    v = OBJECT_TO_JSVAL(nsobj);
+    if (obj &&
+        !OBJ_DEFINE_PROPERTY(cx, obj, JS_DEFAULT_XML_NAMESPACE_ID, v,
+                             JS_PropertyStub, JS_PropertyStub,
+                             JSPROP_PERMANENT, NULL)) {
+        return JS_FALSE;
+    }
+    fp->xmlNamespace = nsobj;
+    *vp = v;
+    return JS_TRUE;
+}
+
+JSBool
+js_SetDefaultXMLNamespace(JSContext *cx, jsval v)
+{
+    jsval argv[2];
+    JSObject *nsobj, *varobj;
+    JSStackFrame *fp;
+
+    argv[0] = STRING_TO_JSVAL(cx->runtime->emptyString);
+    argv[1] = v;
+    nsobj = js_ConstructObject(cx, &js_NamespaceClass.base, NULL, NULL,
+                               2, argv);
+    if (!nsobj)
+        return JS_FALSE;
+    v = OBJECT_TO_JSVAL(nsobj);
+
+    fp = cx->fp;
+    varobj = fp->varobj;
+    if (varobj) {
+        if (!OBJ_DEFINE_PROPERTY(cx, varobj, JS_DEFAULT_XML_NAMESPACE_ID, v,
+                                 JS_PropertyStub, JS_PropertyStub,
+                                 JSPROP_PERMANENT, NULL)) {
+            return JS_FALSE;
+        }
+    } else {
+        JS_ASSERT(fp->fun && !(fp->fun->flags & JSFUN_HEAVYWEIGHT));
+    }
+    fp->xmlNamespace = JSVAL_TO_OBJECT(v);
+    return JS_TRUE;
+}
+
+JSBool
+js_ToAttributeName(JSContext *cx, jsval *vp)
+{
+    JSXMLQName *qn;
+
+    qn = ToAttributeName(cx, *vp);
+    if (!qn)
+        return JS_FALSE;
+    *vp = OBJECT_TO_JSVAL(qn->object);
+    return JS_TRUE;
+}
+
+JSString *
+js_EscapeAttributeValue(JSContext *cx, JSString *str)
+{
+    return EscapeAttributeValue(cx, NULL, str);
+}
+
+JSString *
+js_AddAttributePart(JSContext *cx, JSBool isName, JSString *str, JSString *str2)
+{
+    size_t len, len2, newlen;
+    jschar *chars;
+
+    if (JSSTRING_IS_DEPENDENT(str) ||
+        !(*js_GetGCThingFlags(str) & GCF_MUTABLE)) {
+        str = js_NewStringCopyN(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
+                                0);
+        if (!str)
+            return NULL;
+    }
+
+    len = str->length;
+    len2 = JSSTRING_LENGTH(str2);
+    newlen = (isName) ? len + 1 + len2 : len + 2 + len2 + 1;
+    chars = (jschar *) JS_realloc(cx, str->chars, (newlen+1) * sizeof(jschar));
+    if (!chars)
+        return NULL;
+
+    /*
+     * Reallocating str (because we know it has no other references) requires
+     * purging any deflated string cached for it.
+     */
+    js_PurgeDeflatedStringCache(str);
+
+    str->chars = chars;
+    str->length = newlen;
+    chars += len;
+    if (isName) {
+        *chars++ = ' ';
+        js_strncpy(chars, JSSTRING_CHARS(str2), len2);
+        chars += len2;
+    } else {
+        *chars++ = '=';
+        *chars++ = '"';
+        js_strncpy(chars, JSSTRING_CHARS(str2), len2);
+        chars += len2;
+        *chars++ = '"';
+    }
+    *chars = 0;
+    return str;
+}
+
+JSString *
+js_EscapeElementValue(JSContext *cx, JSString *str)
+{
+    return EscapeElementValue(cx, NULL, str);
+}
+
+JSString *
+js_ValueToXMLString(JSContext *cx, jsval v)
+{
+    return ToXMLString(cx, v);
+}
+
+static JSBool
+anyname_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+                 jsval *rval)
+{
+    *rval = ATOM_KEY(cx->runtime->atomState.starAtom);
+    return JS_TRUE;
+}
+
+JSBool
+js_GetAnyName(JSContext *cx, jsval *vp)
+{
+    JSRuntime *rt;
+    JSObject *obj;
+    JSXMLQName *qn;
+
+    rt = cx->runtime;
+    obj = rt->anynameObject;
+    if (!obj) {
+        qn = js_NewXMLQName(cx, rt->emptyString, rt->emptyString,
+                            ATOM_TO_STRING(rt->atomState.starAtom));
+        if (!qn)
+            return JS_FALSE;
+
+        obj = js_NewObject(cx, &js_AnyNameClass, NULL, NULL);
+        if (!obj || !JS_SetPrivate(cx, obj, qn)) {
+            cx->newborn[GCX_OBJECT] = NULL;
+            return JS_FALSE;
+        }
+        qn->object = obj;
+        METER(xml_stats.qnameobj);
+        METER(xml_stats.liveqnameobj);
+
+        /*
+         * Avoid entraining any in-scope Object.prototype.  This loses the
+         * default toString inheritance, but no big deal: we want a better
+         * custom one for clearer diagnostics.
+         */
+        if (!JS_DefineFunction(cx, obj, js_toString_str, anyname_toString,
+                               0, 0)) {
+            return JS_FALSE;
+        }
+        OBJ_SET_PROTO(cx, obj, NULL);
+        JS_ASSERT(!OBJ_GET_PARENT(cx, obj));
+        rt->anynameObject = obj;
+    }
+    *vp = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+JSBool
+js_FindXMLProperty(JSContext *cx, jsval name, JSObject **objp, jsval *namep)
+{
+    JSXMLQName *qn;
+    jsid funid, id;
+    JSObject *obj, *pobj, *lastobj;
+    JSProperty *prop;
+    const char *printable;
+
+    qn = ToXMLName(cx, name, &funid);
+    if (!qn)
+        return JS_FALSE;
+    id = OBJECT_TO_JSID(qn->object);
+
+    obj = cx->fp->scopeChain;
+    do {
+        if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
+            return JS_FALSE;
+        if (prop) {
+            OBJ_DROP_PROPERTY(cx, pobj, prop);
+
+            /*
+             * Call OBJ_THIS_OBJECT to skip any With object that wraps an XML
+             * object to carry scope chain linkage in js_FilterXMLList.
+             */
+            pobj = OBJ_THIS_OBJECT(cx, obj);
+            if (OBJECT_IS_XML(cx, pobj)) {
+                *objp = pobj;
+                *namep = ID_TO_VALUE(id);
+                return JS_TRUE;
+            }
+        }
+
+        lastobj = obj;
+    } while ((obj = OBJ_GET_PARENT(cx, obj)) != NULL);
+
+    printable = js_ValueToPrintableString(cx, name);
+    if (printable) {
+        JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR,
+                                     js_GetErrorMessage, NULL,
+                                     JSMSG_UNDEFINED_XML_NAME, printable);
+    }
+    return JS_FALSE;
+}
+
+JSBool
+js_GetXMLProperty(JSContext *cx, JSObject *obj, jsval name, jsval *vp)
+{
+    return GetProperty(cx, obj, name, vp);
+}
+
+JSBool
+js_SetXMLProperty(JSContext *cx, JSObject *obj, jsval name, jsval *vp)
+{
+    return PutProperty(cx, obj, name, vp);
+}
+
+static JSXML *
+GetPrivate(JSContext *cx, JSObject *obj, const char *method)
+{
+    JSXML *xml;
+
+    xml = (JSXML *) JS_GetInstancePrivate(cx, obj, &js_XMLClass, NULL);
+    if (!xml) {
+        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                             JSMSG_INCOMPATIBLE_METHOD,
+                             js_XML_str, method, OBJ_GET_CLASS(cx, obj)->name);
+    }
+    return xml;
+}
+
+JSBool
+js_GetXMLDescendants(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    JSXML *xml, *list;
+
+    xml = GetPrivate(cx, obj, "descendants internal method");
+    if (!xml)
+        return JS_FALSE;
+
+    list = Descendants(cx, xml, id);
+    if (!list)
+        return JS_FALSE;
+    *vp = OBJECT_TO_JSVAL(list->object);
+    return JS_TRUE;
+}
+
+JSBool
+js_DeleteXMLListElements(JSContext *cx, JSObject *listobj)
+{
+    JSXML *list;
+    uint32 n;
+    jsval junk;
+
+    list = (JSXML *) JS_GetPrivate(cx, listobj);
+    for (n = list->xml_kids.length; n != 0; --n) {
+        if (!DeleteProperty(cx, listobj, INT_TO_JSID(0), &junk))
+            return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+JSBool
+js_FilterXMLList(JSContext *cx, JSObject *obj, jsbytecode *pc, jsval *vp)
+{
+    JSBool ok, match;
+    JSStackFrame *fp;
+    JSObject *scobj, *listobj, *resobj, *withobj, *kidobj;
+    JSXML *xml, *list, *result, *kid;
+    uint32 i, n;
+
+    ok = JS_EnterLocalRootScope(cx);
+    if (!ok)
+        return JS_FALSE;
+
+    /* All control flow after this point must exit via label out or bad. */
+    fp = cx->fp;
+    scobj = fp->scopeChain;
+    xml = GetPrivate(cx, obj, "filtering predicate operator");
+    if (!xml)
+        goto bad;
+
+    if (xml->xml_class == JSXML_CLASS_LIST) {
+        list = xml;
+    } else {
+        listobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+        if (!listobj)
+            goto bad;
+        list = (JSXML *) JS_GetPrivate(cx, listobj);
+        ok = Append(cx, list, xml);
+        if (!ok)
+            goto out;
+    }
+
+    resobj = js_NewXMLObject(cx, JSXML_CLASS_LIST);
+    if (!resobj)
+        goto bad;
+    result = (JSXML *) JS_GetPrivate(cx, resobj);
+
+    /* Hoist the scope chain update out of the loop over kids. */
+    withobj = js_NewObject(cx, &js_WithClass, NULL, scobj);
+    if (!withobj)
+        goto bad;
+    fp->scopeChain = withobj;
+
+    for (i = 0, n = list->xml_kids.length; i < n; i++) {
+        kid = XMLARRAY_MEMBER(&list->xml_kids, i, JSXML);
+        kidobj = js_GetXMLObject(cx, kid);
+        if (!kidobj)
+            goto bad;
+        OBJ_SET_PROTO(cx, withobj, kidobj);
+        ok = js_Interpret(cx, pc, vp) && js_ValueToBoolean(cx, *vp, &match);
+        if (!ok)
+            goto out;
+        if (match) {
+            ok = Append(cx, result, kid);
+            if (!ok)
+                goto out;
+        }
+    }
+
+    *vp = OBJECT_TO_JSVAL(resobj);
+
+out:
+    fp->scopeChain = scobj;
+    JS_LeaveLocalRootScope(cx);
+    return ok;
+bad:
+    ok = JS_FALSE;
+    goto out;
+}
+
+JSObject *
+js_ValueToXMLObject(JSContext *cx, jsval v)
+{
+    return ToXML(cx, v);
+}
+
+JSObject *
+js_ValueToXMLListObject(JSContext *cx, jsval v)
+{
+    return ToXMLList(cx, v);
+}
+
+JSObject *
+js_CloneXMLObject(JSContext *cx, JSObject *obj)
+{
+    uintN flags;
+    JSXML *xml;
+
+    if (!GetXMLSettingFlags(cx, &flags))
+        return NULL;
+    xml = (JSXML *) JS_GetPrivate(cx, obj);
+    if (flags & (XSF_IGNORE_COMMENTS |
+                 XSF_IGNORE_PROCESSING_INSTRUCTIONS |
+                 XSF_IGNORE_WHITESPACE)) {
+        xml = DeepCopy(cx, xml, NULL, flags);
+        if (!xml)
+            return NULL;
+        return xml->object;
+    }
+    return NewXMLObject(cx, xml);
+}
+
+JSObject *
+js_NewXMLSpecialObject(JSContext *cx, JSXMLClass xml_class, JSString *name,
+                       JSString *value)
+{
+    uintN flags;
+    JSObject *obj;
+    JSXML *xml;
+    JSXMLQName *qn;
+
+    if (!GetXMLSettingFlags(cx, &flags))
+        return NULL;
+
+    if ((xml_class == JSXML_CLASS_COMMENT &&
+         (flags & XSF_IGNORE_COMMENTS)) ||
+        (xml_class == JSXML_CLASS_PROCESSING_INSTRUCTION &&
+         (flags & XSF_IGNORE_PROCESSING_INSTRUCTIONS))) {
+        return js_NewXMLObject(cx, JSXML_CLASS_TEXT);
+    }
+
+    obj = js_NewXMLObject(cx, xml_class);
+    if (!obj)
+        return NULL;
+    xml = (JSXML *) JS_GetPrivate(cx, obj);
+    if (name) {
+        qn = js_NewXMLQName(cx, cx->runtime->emptyString, NULL, name);
+        if (!qn)
+            return NULL;
+        xml->name = qn;
+    }
+    xml->xml_value = value;
+    return obj;
+}
+
+JSString *
+js_MakeXMLCDATAString(JSContext *cx, JSString *str)
+{
+    return MakeXMLCDATAString(cx, NULL, str);
+}
+
+JSString *
+js_MakeXMLCommentString(JSContext *cx, JSString *str)
+{
+    return MakeXMLCommentString(cx, NULL, str);
+}
+
+JSString *
+js_MakeXMLPIString(JSContext *cx, JSString *name, JSString *str)
+{
+    return MakeXMLPIString(cx, NULL, name, str);
+}
+
+#endif /* JS_HAS_XML_SUPPORT */

Added: freeswitch/trunk/libs/js/src/jsxml.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/jsxml.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,328 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is SpiderMonkey E4X code, released August, 2004.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jsxml_h___
+#define jsxml_h___
+
+#include "jsstddef.h"
+#include "jspubtd.h"
+
+extern const char js_AnyName_str[];
+extern const char js_AttributeName_str[];
+extern const char js_isXMLName_str[];
+extern const char js_XMLList_str[];
+
+extern const char js_amp_entity_str[];
+extern const char js_gt_entity_str[];
+extern const char js_lt_entity_str[];
+extern const char js_quot_entity_str[];
+
+struct JSXMLNamespace {
+    JSObject            *object;
+    JSString            *prefix;
+    JSString            *uri;
+    JSBool              declared;       /* true if declared in its XML tag */
+};
+
+extern JSXMLNamespace *
+js_NewXMLNamespace(JSContext *cx, JSString *prefix, JSString *uri,
+                   JSBool declared);
+
+extern void
+js_MarkXMLNamespace(JSContext *cx, JSXMLNamespace *ns, void *arg);
+
+extern void
+js_FinalizeXMLNamespace(JSContext *cx, JSXMLNamespace *ns);
+
+extern JSObject *
+js_NewXMLNamespaceObject(JSContext *cx, JSString *prefix, JSString *uri,
+                         JSBool declared);
+
+extern JSObject *
+js_GetXMLNamespaceObject(JSContext *cx, JSXMLNamespace *ns);
+
+struct JSXMLQName {
+    JSObject            *object;
+    JSString            *uri;
+    JSString            *prefix;
+    JSString            *localName;
+};
+
+extern JSXMLQName *
+js_NewXMLQName(JSContext *cx, JSString *uri, JSString *prefix,
+               JSString *localName);
+
+extern void
+js_MarkXMLQName(JSContext *cx, JSXMLQName *qn, void *arg);
+
+extern void
+js_FinalizeXMLQName(JSContext *cx, JSXMLQName *qn);
+
+extern JSObject *
+js_NewXMLQNameObject(JSContext *cx, JSString *uri, JSString *prefix,
+                     JSString *localName);
+
+extern JSObject *
+js_GetXMLQNameObject(JSContext *cx, JSXMLQName *qn);
+
+extern JSObject *
+js_GetAttributeNameObject(JSContext *cx, JSXMLQName *qn);
+
+extern JSObject *
+js_ConstructXMLQNameObject(JSContext *cx, jsval nsval, jsval lnval);
+
+typedef JSBool
+(* JS_DLL_CALLBACK JSIdentityOp)(const void *a, const void *b);
+
+struct JSXMLArray {
+    uint32              length;
+    uint32              capacity;
+    void                **vector;
+    JSXMLArrayCursor    *cursors;
+};
+
+#define JSXML_PRESET_CAPACITY   JS_BIT(31)
+#define JSXML_CAPACITY_MASK     JS_BITMASK(31)
+#define JSXML_CAPACITY(array)   ((array)->capacity & JSXML_CAPACITY_MASK)
+
+struct JSXMLArrayCursor {
+    JSXMLArray          *array;
+    uint32              index;
+    JSXMLArrayCursor    *next;
+    JSXMLArrayCursor    **prevp;
+};
+
+/*
+ * NB: don't reorder this enum without changing all array initializers that
+ * depend on it in jsxml.c.
+ */ 
+typedef enum JSXMLClass {
+    JSXML_CLASS_LIST,
+    JSXML_CLASS_ELEMENT,
+    JSXML_CLASS_ATTRIBUTE,
+    JSXML_CLASS_PROCESSING_INSTRUCTION,
+    JSXML_CLASS_TEXT,
+    JSXML_CLASS_COMMENT,
+    JSXML_CLASS_LIMIT
+} JSXMLClass;
+
+#define JSXML_CLASS_HAS_KIDS(class_)    ((class_) < JSXML_CLASS_ATTRIBUTE)
+#define JSXML_CLASS_HAS_VALUE(class_)   ((class_) >= JSXML_CLASS_ATTRIBUTE)
+#define JSXML_CLASS_HAS_NAME(class_)                                          \
+    ((uintN)((class_) - JSXML_CLASS_ELEMENT) <=                               \
+     (uintN)(JSXML_CLASS_PROCESSING_INSTRUCTION - JSXML_CLASS_ELEMENT))
+
+#ifdef DEBUG_notme
+#include "jsclist.h"
+#endif
+
+struct JSXML {
+#ifdef DEBUG_notme
+    JSCList             links;
+    uint32              serial;
+#endif
+    JSObject            *object;
+    void                *domnode;       /* DOM node if mapped info item */
+    JSXML               *parent;
+    JSXMLQName          *name;
+    uint16              xml_class;      /* discriminates u, below */
+    uint16              xml_flags;      /* flags, see below */
+    union {
+        struct JSXMLListVar {
+            JSXMLArray  kids;           /* NB: must come first */
+            JSXML       *target;
+            JSXMLQName  *targetprop;
+        } list;
+        struct JSXMLVar {
+            JSXMLArray  kids;           /* NB: must come first */
+            JSXMLArray  namespaces;
+            JSXMLArray  attrs;
+        } elem;
+        JSString        *value;
+    } u;
+
+    /* Don't add anything after u -- see js_NewXML for why. */
+};
+
+/* union member shorthands */
+#define xml_kids        u.list.kids
+#define xml_target      u.list.target
+#define xml_targetprop  u.list.targetprop
+#define xml_namespaces  u.elem.namespaces
+#define xml_attrs       u.elem.attrs
+#define xml_value       u.value
+
+/* xml_flags values */
+#define XMLF_WHITESPACE_TEXT    0x1
+
+/* xml_class-testing macros */
+#define JSXML_HAS_KIDS(xml)     JSXML_CLASS_HAS_KIDS((xml)->xml_class)
+#define JSXML_HAS_VALUE(xml)    JSXML_CLASS_HAS_VALUE((xml)->xml_class)
+#define JSXML_HAS_NAME(xml)     JSXML_CLASS_HAS_NAME((xml)->xml_class)
+#define JSXML_LENGTH(xml)       (JSXML_CLASS_HAS_KIDS((xml)->xml_class)       \
+                                 ? (xml)->xml_kids.length                     \
+                                 : 0)
+
+extern JSXML *
+js_NewXML(JSContext *cx, JSXMLClass xml_class);
+
+extern void
+js_MarkXML(JSContext *cx, JSXML *xml, void *arg);
+
+extern void
+js_FinalizeXML(JSContext *cx, JSXML *xml);
+
+extern JSObject *
+js_ParseNodeToXMLObject(JSContext *cx, JSParseNode *pn);
+
+extern JSObject *
+js_NewXMLObject(JSContext *cx, JSXMLClass xml_class);
+
+extern JSObject *
+js_GetXMLObject(JSContext *cx, JSXML *xml);
+
+extern JS_FRIEND_DATA(JSXMLObjectOps)   js_XMLObjectOps;
+extern JS_FRIEND_DATA(JSClass)          js_XMLClass;
+extern JS_FRIEND_DATA(JSExtendedClass)  js_NamespaceClass;
+extern JS_FRIEND_DATA(JSExtendedClass)  js_QNameClass;
+extern JS_FRIEND_DATA(JSClass)          js_AttributeNameClass;
+extern JS_FRIEND_DATA(JSClass)          js_AnyNameClass;
+
+/*
+ * Macros to test whether an object or a value is of type "xml" (per typeof).
+ * NB: jsapi.h must be included before any call to VALUE_IS_XML.
+ */
+#define OBJECT_IS_XML(cx,obj)   ((obj)->map->ops == &js_XMLObjectOps.base)
+#define VALUE_IS_XML(cx,v)      (!JSVAL_IS_PRIMITIVE(v) &&                    \
+                                 OBJECT_IS_XML(cx, JSVAL_TO_OBJECT(v)))
+
+extern JSObject *
+js_InitNamespaceClass(JSContext *cx, JSObject *obj);
+
+extern JSObject *
+js_InitQNameClass(JSContext *cx, JSObject *obj);
+
+extern JSObject *
+js_InitAttributeNameClass(JSContext *cx, JSObject *obj);
+
+extern JSObject *
+js_InitAnyNameClass(JSContext *cx, JSObject *obj);
+
+extern JSObject *
+js_InitXMLClass(JSContext *cx, JSObject *obj);
+
+extern JSObject *
+js_InitXMLClasses(JSContext *cx, JSObject *obj);
+
+extern JSBool
+js_GetFunctionNamespace(JSContext *cx, jsval *vp);
+
+extern JSBool
+js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp);
+
+extern JSBool
+js_SetDefaultXMLNamespace(JSContext *cx, jsval v);
+
+/*
+ * Return true if v is a XML QName object, or if it converts to a string that
+ * contains a valid XML qualified name (one containing no :), false otherwise.
+ * NB: This function is an infallible predicate, it hides exceptions.
+ */
+extern JSBool
+js_IsXMLName(JSContext *cx, jsval v);
+
+extern JSBool
+js_ToAttributeName(JSContext *cx, jsval *vp);
+
+extern JSString *
+js_EscapeAttributeValue(JSContext *cx, JSString *str);
+
+extern JSString *
+js_AddAttributePart(JSContext *cx, JSBool isName, JSString *str,
+                    JSString *str2);
+
+extern JSString *
+js_EscapeElementValue(JSContext *cx, JSString *str);
+
+extern JSString *
+js_ValueToXMLString(JSContext *cx, jsval v);
+
+extern JSBool
+js_GetAnyName(JSContext *cx, jsval *vp);
+
+extern JSBool
+js_FindXMLProperty(JSContext *cx, jsval name, JSObject **objp, jsval *namep);
+
+extern JSBool
+js_GetXMLProperty(JSContext *cx, JSObject *obj, jsval name, jsval *vp);
+
+extern JSBool
+js_SetXMLProperty(JSContext *cx, JSObject *obj, jsval name, jsval *vp);
+
+extern JSBool
+js_GetXMLDescendants(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
+extern JSBool
+js_DeleteXMLListElements(JSContext *cx, JSObject *listobj);
+
+extern JSBool
+js_FilterXMLList(JSContext *cx, JSObject *obj, jsbytecode *pc, jsval *vp);
+
+extern JSObject *
+js_ValueToXMLObject(JSContext *cx, jsval v);
+
+extern JSObject *
+js_ValueToXMLListObject(JSContext *cx, jsval v);
+
+extern JSObject *
+js_CloneXMLObject(JSContext *cx, JSObject *obj);
+
+extern JSObject *
+js_NewXMLSpecialObject(JSContext *cx, JSXMLClass xml_class, JSString *name,
+                       JSString *value);
+
+extern JSString *
+js_MakeXMLCDATAString(JSContext *cx, JSString *str);
+
+extern JSString *
+js_MakeXMLCommentString(JSContext *cx, JSString *str);
+
+extern JSString *
+js_MakeXMLPIString(JSContext *cx, JSString *name, JSString *str);
+
+#endif /* jsxml_h___ */

Added: freeswitch/trunk/libs/js/src/perlconnect/JS.pm
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/perlconnect/JS.pm	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,318 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Communicator client code, released
+# March 31, 1998.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the 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 *****
+
+############################################################################
+# JS.pm is a Perl interface to JavaScript 3/2/99 5:23PM
+# The packages implemented here include
+#           JS, JS::Runtime, JS::Contents, JS::Object
+# See README.html for more information about this module.
+############################################################################
+
+package JS;
+$VERSION='0.03';
+require Exporter;
+use DynaLoader;
+ at ISA = qw(Exporter DynaLoader);
+use strict;
+use vars qw($VERSION);
+
+sub boot        #7/31/98 5:28PM
+{
+    # this is to load the JS DLL at run-time
+    bootstrap JS $VERSION;
+    push @DynaLoader::dl_library_path, $ENV{'LD_LIBRARY_PATH'};
+}   ##boot
+
+sub new {
+    my ($class, $maxbytes) = @_;
+    my $self = new JS::Runtime($maxbytes);
+    return $self;
+}
+
+############################################################
+# JS::Runtime
+############################################################
+package JS::Runtime;
+use strict;
+use vars qw ($AUTOLOAD $DEBUG %CONTEXTS);
+
+# we use %CONTEXT hash to remember all created contex. 
+# reason of this is increase reference to context objects
+# and ensure corret order of destructor calls
+
+sub AUTOLOAD        #7/28/98 8:24PM
+{
+    print "\nJS::Runtime::AUTOLOAD: $AUTOLOAD, not implemented yet\n" if $DEBUG;
+}   ##AUTOLOAD
+
+
+# Constructor. Calls NewRuntime
+
+sub new     #7/31/98 3:39PM
+{
+    warn "JS::Runtime::new\n" if $DEBUG;
+    my($class, $maxbytes) = @_;
+    my $self = JS::NewRuntime(scalar($maxbytes));
+    return  $self;
+}   ##new
+
+sub createContext {
+    my ($self, $stacksize) = @_;
+    #my $cx = $self->NewContext($stacksize);
+    my $cx = JS::Context->new($self, $stacksize);
+#    $CONTEXTS{$self} = [] unless exists $CONTEXTS{$self};
+#    push @{$CONTEXTS{$self}}, $cx;
+    return $cx;
+}
+
+# Destructor for Runtimes
+sub DESTROY     #7/31/98 4:54PM
+{
+    my $self = shift;
+    warn "JS::Runtime::DESTROY\n" if $DEBUG;
+    JS::DestroyRuntime($self);
+}   ##DESTROY
+
+############################################################
+# JS::Context
+############################################################
+package JS::Context;
+use vars qw($AUTOLOAD $DEBUG);
+
+# sub AUTOLOAD        #7/28/98 8:24PM
+# {
+#     print "\nJS::Context::AUTOLOAD: $AUTOLOAD, not implemented yet\n" if $DEBUG;
+# }   ##AUTOLOAD
+
+sub new     #7/31/98 3:39PM
+{
+    warn "JS::Context::new\n" if $DEBUG;
+    my($class, $rt, $stacksize) = @_;
+    $class = ref $class || $class;
+    my $cx = JS::Runtime::NewContext($rt, $stacksize);
+    my $self = {
+		_handle => $cx,
+		_name => ("name_" . int (rand 1000)),
+	       };
+      $self->{_handle};
+    bless $self, $class;
+    return  $self;
+}   ##new
+
+use Data::Dumper;
+
+sub exec {
+    my ($self, $script) = @_;
+    $self->exec_($script);
+}
+
+sub DESTROY     #7/31/98 4:54PM
+{
+    my $self = shift;
+    warn "JS::Context::DESTROY\n" if $DEBUG;
+    JS::Runtime::DestroyContext($self);
+}   ##DESTROY
+
+
+############################################################
+# JS::Script
+############################################################
+package JS::Script;
+
+sub new {
+    my ($class, $cx, $code, $name) = @_;
+    $class = ref $class || $class;
+    my $self = {};
+    bless $self, $class;
+    $self->{_script} = $self->compileScript($cx, $code, $name);
+    $self->{_root} = $self->rootScript($cx, $name);
+    $self->{_cx} = $cx; #!!! dangerous
+    $self->{_name} = $name;
+    return $self;
+}
+
+sub DESTROY {
+    my $self = shift;
+    print "---> script destroy\n";
+    my $cx = $self->{_cx};
+    $self->destroyScript($cx);
+}
+
+############################################################
+# JS::Object
+############################################################
+package JS::Object;
+use vars qw($AUTOLOAD $DEBUG);
+
+sub AUTOLOAD        #7/28/98 8:24PM
+{
+    $_ = $AUTOLOAD;
+    $_ =~ s/.*://;
+    print "\nJS::Object::AUTOLOAD: $_, not implemented yet\n" if $DEBUG;
+}   ##AUTOLOAD
+
+
+
+############################################################
+# executable part
+############################################################
+#$JS::Runtime::DEBUG = 1;
+#$JS::Context::DEBUG = 1;
+#$JS::Object::DEBUG = 1;
+
+&JS::boot();
+
+1;
+
+############################################################
+# the end
+############################################################
+
+
+
+
+__END__
+
+package JS;
+$VERSION = '0.03';
+require Exporter;
+require DynaLoader;
+ at ISA = qw(Exporter DynaLoader);
+
+#@ISA = qw(JS);
+
+############################################################################
+# Duplicates JS::Context::new is a way
+############################################################################
+sub new         #7/31/98 5:32PM
+{
+    print "JS::new" if $DEBUG;
+    my $rt = new JS::Runtime(10_000);
+    $this = new JS::Context($rt, 1_024);
+    return $this
+}   ##new
+
+############################################################################
+# Uses DynaLoader to load JS support DLL, performs the initialization
+############################################################################
+sub boot        #7/31/98 5:28PM
+{
+    # this is to load the JS DLL at run-time
+    bootstrap JS $VERSION;
+    push @dl_library_path, $ENV{'LD_LIBRARY_PATH'};
+}   ##boot
+
+############################################################################
+package JS::Runtime;
+ at EXPORT = qw($this);
+
+sub AUTOLOAD        #7/28/98 8:24PM
+{
+    print "\nJS::Runtime::AUTOLOAD: $AUTOLOAD, not implemented yet\n" if $DEBUG;
+}   ##AUTOLOAD
+
+############################################################################
+# Constructor. Calls NewRuntime and saves the returned value in this
+############################################################################
+sub new     #7/31/98 3:39PM
+{
+    print "JS::Runtime::new\n" if $DEBUG;
+    my($class, $maxbytes) = @_;
+    $this = JS::NewRuntime(scalar($maxbytes));
+    return  $this;
+}   ##new
+
+############################################################################
+# Destructor for Runtimes
+############################################################################
+sub DESTROY     #7/31/98 4:54PM
+{
+    my $self = shift;
+    print "JS::Runtime::DESTROY\n" if $DEBUG;
+warn("JS::Runtime::DESTROY\n");
+    JS::DestroyRuntime($self);
+    undef $this;
+}   ##DESTROY
+
+############################################################################
+package JS::Context;
+ at EXPORT = qw($this);
+
+sub AUTOLOAD        #7/28/98 8:24PM
+{
+    print "\nJS::Context::AUTOLOAD: $AUTOLOAD, not implemented yet\n" if $DEBUG;
+}   ##AUTOLOAD
+
+############################################################################
+# Constructor. Calls NewContext and saves the returned value in this
+############################################################################
+sub new     #7/31/98 3:39PM
+{
+    print "JS::Context::new\n" if $DEBUG;
+warn("JS::Context::new\n");
+    my($class, $rt, $stacksize) = @_;
+    $this = JS::Runtime::NewContext($rt, $stacksize);
+    return  $this;
+}   ##new
+
+############################################################################
+# Destructor for Contexts
+############################################################################
+sub DESTROY     #7/31/98 4:54PM
+{
+    my $self = shift;
+    print "JS::Context::DESTROY\n" if $DEBUG;
+warn("JS::Context::DESTROY\n");
+    JS::Runtime::DestroyContext($self);
+    undef $this;
+}   ##DESTROY
+
+############################################################################
+
+package JS::Object;
+
+sub AUTOLOAD        #7/28/98 8:24PM
+{
+    $_ = $AUTOLOAD;
+    $_ =~ s/.*://;
+    print "\nJS::Object::AUTOLOAD: $_, not implemented yet\n" if $DEBUG;
+}   ##AUTOLOAD
+
+&JS::boot();
+
+1;

Added: freeswitch/trunk/libs/js/src/perlconnect/JS.xs
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/perlconnect/JS.xs	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1055 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the 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 ***** */
+
+/*
+ * PerlConnect. Provides means for OO Perl <==> JS communications
+ */
+
+/* This is an program written in XSUB. You need to compile it using xsubpp   */
+/* usually found in your perl\bin directory. On my machine I do it like this:*/
+/*      perl c:\perl\lib\ExtUtils\xsubpp  -typemap  \                        */
+/*           c:\perl\lib\extutils\typemap -typemap typemap JS.xs > JS.c      */
+/* See perlxs man page for details.                                          */
+/* Don't edit the resulting C file directly. See README.html for more info   */
+/* on PerlConnect in general                                                 */
+
+#ifdef __cplusplus
+    extern "C"; {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#ifdef __cplusplus
+    }
+#endif
+
+#include <jsapi.h>
+#include "jsperlpvt.h"
+#ifdef OSSP
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+
+/* __REMOVE__ */
+/* #include <stdio.h>  */
+
+/************************************************************/
+/* utils */
+
+static JSBool
+checkError(JSContext *cx)
+{
+    if(SvTRUE(GvSV(PL_errgv))){ 
+        JS_ReportError(cx, "perl eval failed: %s",
+            SvPV(GvSV(PL_errgv), PL_na));
+        /* clear error status. there should be a way to do this faster */
+        perl_eval_sv(newSVpv("undef $@;", 0), G_KEEPERR);
+        return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+static void
+clearException(JSContext *cx) 
+{
+    if (JS_IsExceptionPending(cx)) {
+        JS_ClearPendingException(cx);
+    }
+}
+
+/************************************************************/
+/* calback stub */
+
+/* this is internal js structure needed in errorFromPrivate */
+typedef struct JSExnPrivate {
+    JSErrorReport *errorReport;
+} JSExnPrivate;
+
+static
+JSClass global_class = {
+    "Global", 0,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub, JS_FinalizeStub
+};
+
+/* __PH__BEGIN  */
+/* perl callback structure */
+/* prefix PCB means Perl CallBack */
+
+struct PerlCallbackItem{
+    char*  name;
+    SV*    perl_proc;
+    int    param_num;
+    struct PerlCallbackItem *next;
+};
+
+typedef struct PerlCallbackItem PerlCallbackItem;
+
+
+struct PerlObjectItem {
+    char * name;
+    SV* pObject;
+    /* OSSP BUGFIX *//*JSObject *jsStub;*/
+    JSObject *jsObject;
+    JSClass *jsClass;
+    struct PerlCallbackItem* vector;
+    struct PerlObjectItem *next;
+};
+
+typedef struct PerlObjectItem PerlObjectItem;
+
+/* error reporter */
+/* OSSP BUGFIX *//*struct JSContextItem;*/
+/* OSSP BUGFIX *//*struct JSContextItem;*/
+struct  JSContextItem {
+    JSContext *cx;
+    SV *errorReporter;
+    PerlObjectItem *objects;
+    int dieFromErrors;
+    struct JSContextItem* next;
+};
+
+typedef struct JSContextItem JSContextItem;
+
+static JSContextItem *context_list = NULL;
+
+static JSContextItem*
+PCB_NewContextItem() {
+    JSContextItem *ret;
+    ret = (JSContextItem*)calloc(1, sizeof(JSContextItem));
+    return ret;
+}
+
+static JSContextItem*
+PCB_FindContextItem (JSContext *cx) {
+    JSContextItem *cxitem =  context_list;
+    while ( cxitem ) {
+        if (cxitem->cx == cx ) return cxitem;
+        cxitem = cxitem->next;
+    }
+    return NULL;
+}
+
+static  SV*
+PCB_FindErrorReporter (JSContext *cx) {
+    JSContextItem *cxitem;
+    if (cxitem = PCB_FindContextItem(cx)) {
+        return cxitem->errorReporter;
+    } else {
+        return NULL;
+    }
+}
+
+static void
+PCB_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
+{
+    SV *report_proc;
+    if ( report_proc = PCB_FindErrorReporter(cx) ) {
+        dSP;
+        PUSHMARK(SP);
+        XPUSHs(sv_2mortal(newSVpv((char*)message, 0)));
+        if ( report ) {
+            if ( report->filename ) {
+                XPUSHs(sv_2mortal(newSVpv((char*)report->filename, 0)));
+            }
+            XPUSHs(sv_2mortal(newSViv(report->lineno)));
+            if (report->linebuf) {
+                XPUSHs(sv_2mortal(newSVpv((char*)report->linebuf, 0)));
+                XPUSHs(sv_2mortal(newSVpv((char*)report->tokenptr, 0)));
+            }
+        }
+        PUTBACK;
+        perl_call_sv(report_proc, G_VOID | G_DISCARD);
+    } else {
+        warn(message);
+    }
+}
+
+/* perl object stuff */
+
+
+/* functions for callback list handling */
+static PerlCallbackItem*
+PCB_AddCallback(PerlObjectItem* object, char *name, 
+                SV* perl_proc, int param_num) {
+    PerlCallbackItem *cbk;
+
+    cbk = (PerlCallbackItem*)calloc(1, sizeof(PerlCallbackItem));
+    cbk->name = (char*) malloc(strlen(name) + 1);
+    strcpy(cbk->name, name);
+    SvREFCNT_inc(perl_proc);
+    cbk->perl_proc = perl_proc;
+    cbk->param_num = param_num;
+
+    cbk->next = object->vector;
+    object->vector = cbk;
+
+    return cbk;
+}
+
+/* functions for perl object list handling */
+
+static PerlObjectItem*
+PCB_AddObject(char *name, SV *pobj, JSContext *cx, JSObject *jso, JSClass *class) {
+    JSContextItem *cxitem;
+    PerlObjectItem *object;
+
+    /* we should always find the item */
+    cxitem = PCB_FindContextItem(cx);
+    object = (PerlObjectItem*) calloc(1, sizeof(PerlObjectItem));
+    object->name = (char*) malloc(strlen(name) + 1);
+    strcpy(object->name, name);
+    SvREFCNT_inc(pobj);
+    object->pObject = pobj;
+    object->jsObject = jso;
+    object->jsClass = class;
+    object->next = cxitem->objects;
+    cxitem->objects = object;
+
+    return object;
+}
+
+static PerlObjectItem*
+PCB_FindObject(JSContext *cx, JSObject *jso) {
+    JSContextItem *cxitem;
+    PerlObjectItem *objitem;
+
+    cxitem = PCB_FindContextItem(cx);
+    objitem = cxitem->objects;
+
+    while ( objitem ) {
+        if ( objitem->jsObject == jso ) return objitem;
+        objitem = objitem->next;
+    }
+    return NULL;
+}
+
+static PerlCallbackItem*
+PCB_FindCallback(PerlObjectItem *obj, const char *name) {
+    PerlCallbackItem *cbkitem;
+
+    cbkitem = obj->vector;
+    while ( cbkitem ) {
+        if ( strcmp(name, cbkitem->name) == 0 ) return cbkitem;
+        cbkitem = cbkitem->next;
+    }
+    return NULL;
+}
+
+/* deletion functions */
+
+static void 
+PCB_FreeCallbackItem(PerlCallbackItem *callback) {
+    free(callback->name);
+    /* we have to decrease ref. count to proc */
+    SvREFCNT_dec(callback->perl_proc);
+    free(callback);
+}
+
+static void 
+PCB_FreeObjectItem(PerlObjectItem *object) {
+    PerlCallbackItem *cbkitem, *next;
+    JSClass *class;
+
+    free(object->name);
+    free(object->jsClass);
+
+    SvREFCNT_dec(object->pObject);
+    cbkitem = object->vector;
+    while ( cbkitem ) {
+        next = cbkitem->next;
+        PCB_FreeCallbackItem(cbkitem);
+        cbkitem = next;
+    }
+    free(object);
+}
+
+static void 
+PCB_FreeContextItem(JSContext *cx) {
+    JSContextItem *cxitem, *aux;
+    PerlObjectItem *objitem, *next;
+
+    cxitem = PCB_FindContextItem(cx);
+    objitem = cxitem->objects;
+
+    while ( objitem ) {
+        next = objitem->next;
+        PCB_FreeObjectItem(objitem);
+        objitem = next;
+    }
+
+    if (cxitem->errorReporter) {
+        SvREFCNT_dec(cxitem->errorReporter);
+    }
+    
+    if ( context_list == cxitem ) {
+        context_list = cxitem->next;
+    } else {
+        aux = context_list;
+        while ( aux->next != cxitem ) aux = aux->next;
+        aux->next = cxitem->next;
+    }
+    free(cxitem);
+}
+
+/* later the object list should be bind to JS Context
+   in this case is needed to update destructor PerlFreeObjectList
+ */
+
+/* property getter and setter - cooperate with AUTOLOAD */
+
+static JSBool
+PCB_GetProperty(JSContext *cx, JSObject *obj, jsval name, jsval *rval) {
+    PerlObjectItem *po;
+    int i, cnt, len;
+    I32 ax;
+    SV *proc_sv;
+    HV *stash;
+    char prop_name[256];
+    char full_name[256];
+    char *foo;
+    GV *gv;
+    dSP;
+
+    /* property name */
+    strcpy(prop_name, JS_GetStringBytes(JSVAL_TO_STRING(name)));
+
+    if (! (po = PCB_FindObject(cx, obj)))
+        croak("Couldn't find stub for object");
+    if ( (PCB_FindCallback(po, prop_name)))
+        return(JS_TRUE);
+
+    stash = SvSTASH(SvRV(po->pObject));
+    /* strcpy(full_name, HvNAME(stash));
+    strcat(full_name, "::");
+    strcat(full_name, prop_name);
+
+    proc_sv = sv_newmortal();
+    sv_setpv(proc_sv, full_name); */
+    /* start of perl call stuff */
+
+    gv = gv_fetchmeth(stash, prop_name, strlen(prop_name), -1);
+    /* better check and error report should be done here */
+    if (!gv) return JS_FALSE;
+
+    ENTER;
+    SAVETMPS;
+    PUSHMARK(SP);
+    XPUSHs(po->pObject); /* self for perl AUTOLOAD */
+    PUTBACK;
+
+    /* cnt = perl_call_sv(proc_sv, 0); */
+    cnt = perl_call_sv((SV*)GvCV(gv), G_ARRAY);    
+
+    SPAGAIN;
+    /* adjust stack for use of ST macro (see perlcall) */
+    SP -= cnt;
+    ax = (SP - PL_stack_base) + 1;
+
+    /* read value(s) */
+    if (cnt == 1) {
+        SVToJSVAL(cx, obj, ST(0), rval);
+    } else {
+        JSObject *jsarr;
+        jsval val;
+        int i;
+        jsarr = JS_NewArrayObject(cx, 0, NULL);
+        for (i = 0; i < cnt; i++) {
+            SVToJSVAL(cx, JS_GetGlobalObject(cx), ST(i), &val);
+            JS_DefineElement(cx, jsarr, i, val, NULL, NULL, 0);
+        }
+        *rval = OBJECT_TO_JSVAL(jsarr);
+    }
+    PUTBACK;
+
+    FREETMPS;
+    LEAVE;
+
+    return(JS_TRUE);
+}
+
+static JSBool
+PCB_SetProperty(JSContext *cx, JSObject *obj, jsval name, jsval *rval) {
+    PerlObjectItem *po;
+    int i, cnt, len;
+    I32 ax;
+    SV *proc_sv, *value_sv;
+    HV *stash;
+    char prop_name[256];
+    char full_name[256];
+    char *foo;
+    dSP;
+
+    /* property name */
+    strcpy(prop_name, JS_GetStringBytes(JSVAL_TO_STRING(name)));
+
+    if (! (po = PCB_FindObject(cx, obj)))
+        croak("Couldn't find stub for object");
+    if ( (PCB_FindCallback(po, prop_name)))
+        return(JS_TRUE);
+
+    stash = SvSTASH(SvRV(po->pObject));
+    strcpy(full_name, HvNAME(stash));
+    strcat(full_name, "::");
+    strcat(full_name, prop_name);
+
+    proc_sv = sv_newmortal();
+    sv_setpv(proc_sv, full_name);
+    JSVALToSV(cx, obj, *rval, &value_sv);
+    /* start of perl call stuff */
+    ENTER;
+    SAVETMPS;
+    PUSHMARK(SP);
+    XPUSHs(po->pObject); /* self for perl AUTOLOAD */
+    XPUSHs(value_sv);
+    PUTBACK;
+
+    cnt = perl_call_sv(proc_sv, G_ARRAY);
+    
+    SPAGAIN;
+    /* adjust stack for use of ST macro (see perlcall) */
+    SP -= cnt;
+    ax = (SP - PL_stack_base) + 1;
+
+    /* read value(s) */
+    if (cnt == 1) {
+        SVToJSVAL(cx, obj, ST(0), rval);
+    } else {
+        JSObject *jsarr;
+        jsval val;
+        int i;
+        jsarr = JS_NewArrayObject(cx, 0, NULL);
+        for (i = 0; i < cnt; i++) {
+            SVToJSVAL(cx, JS_GetGlobalObject(cx), ST(i), &val);
+            JS_DefineElement(cx, jsarr, i, val, NULL, NULL, 0);
+        }
+        *rval = OBJECT_TO_JSVAL(jsarr);
+    }
+    PUTBACK;
+
+    FREETMPS;
+    LEAVE;
+
+    return(JS_TRUE);
+}
+
+/* helper functions */ 
+/* JSClass pointer is disposed by 
+   JS engine during context cleanup _PH_ 
+ */
+void
+PCB_FinalizeStub(JSContext *cx, JSObject *obj) {
+}
+
+static JSClass* 
+PCB_NewStdJSClass(char *name) {	
+    JSClass *class;
+
+    class = (JSClass*)calloc(1, sizeof(JSClass));
+    class->name = name;
+    class->flags = JSCLASS_HAS_PRIVATE;
+    class->addProperty = JS_PropertyStub;
+    class->delProperty = JS_PropertyStub;  
+    class->getProperty = PCB_GetProperty;  
+    class->setProperty = PCB_SetProperty;
+    class->enumerate = JS_EnumerateStub;
+    class->resolve = JS_ResolveStub;
+    class->convert = JS_ConvertStub;
+    /* OSSP BUGFIX */
+    /*class->finalize = JS_FinalizeStub;*/
+    class->finalize = PCB_FinalizeStub;
+    return(class);
+}
+
+static JSBool
+PCB_UniversalStub (JSContext *cx, JSObject *obj, uintN argc, 
+                   jsval *argv, jsval *rval) {
+    JSFunction *fun;
+    PerlObjectItem *po;
+    PerlCallbackItem *cbk;
+    int i, cnt;
+    I32 ax;
+    SV* sv;
+    dSP;
+
+    fun = JS_ValueToFunction(cx, argv[-2]);
+    if (! (po = PCB_FindObject(cx, obj)))
+        croak("Couldn't find stub for object");
+    if (! (cbk = PCB_FindCallback(po, JS_GetFunctionName(fun))))
+        croak("Couldn't find perl callback");
+    /* start of perl call stuff */
+    ENTER;
+    SAVETMPS;
+    PUSHMARK(SP);
+    XPUSHs(po->pObject); /* self for perl object method */
+    for (i = 0; i < argc; i++) {
+        JSVALToSV(cx, obj, argv[i], &sv);
+        XPUSHs(sv);
+    }
+    PUTBACK;
+    cnt = perl_call_sv(SvRV(cbk->perl_proc), G_ARRAY | G_KEEPERR | G_EVAL);
+
+    SPAGAIN;
+    /* adjust stack for use of ST macro (see perlcall) */
+    SP -= cnt;
+    ax = (SP - PL_stack_base) + 1;
+
+    /* read value(s) */
+    if (cnt == 1) {
+        SVToJSVAL(cx, obj, ST(0), rval);
+    } else {
+        JSObject *jsarr;
+        jsval val;
+        int i;
+        jsarr = JS_NewArrayObject(cx, 0, NULL);
+        for (i = 0; i < cnt; i++) {
+            SVToJSVAL(cx, JS_GetGlobalObject(cx), ST(i), &val);
+            JS_DefineElement(cx, jsarr, i, val, NULL, NULL, 0);
+        }
+        *rval = OBJECT_TO_JSVAL(jsarr);
+    }
+
+    PUTBACK;
+    FREETMPS;
+    LEAVE;
+
+    /* this solution is not perfect, but usefull when nested call happens */
+    return(checkError(cx) && !JS_IsExceptionPending(cx));
+};
+
+/* __PH__END */
+
+
+/* Helper functions needed for most JS API routines */
+/*
+static JSRuntime *
+getRuntime()
+{
+    return (JSRuntime *)SvIV((SV*)SvRV(perl_get_sv("JS::Runtime::rt", FALSE)));
+}
+
+static JSContext *
+getContext()
+{
+    return (JSContext *)SvIV((SV*)SvRV(perl_get_sv("JS::Context::this", FALSE)));
+}
+ */ /* commented as obsolete by __PH__ */
+
+/*
+    The following packages are defined below:
+    JS -- main container for all JS functionality
+        JS::Runtime -- wrapper around JSRuntime *
+        JS::Context -- wrapper around JSContext *
+        JS::Object  -- wrapper around JSObject *
+ */
+
+MODULE = JS  PACKAGE = JS   PREFIX = JS_
+PROTOTYPES:  DISABLE
+ # package JS
+
+ #   Most of the functions below have names coinsiding with those of the
+ #   corresponding JS API functions. Thus, they are not commented.
+JSRuntime *
+JS_NewRuntime(maxbytes)
+    int maxbytes
+    OUTPUT:
+    RETVAL
+
+void
+JS_DestroyRuntime(rt)
+    JSRuntime *rt
+    CODE:
+    /*
+        Make sure that the reference count to the runtime is zero.
+        O.w. this sequence of commands will cause double-deallocation:
+            $rt = new JS::Runtime(10_000);
+            $rt1 = $rt;
+            [exit here]
+        So both $rt->DESTROY and $rt1->DESTROY will cause runtime destruction.
+
+        _PH_ That's not true, I guess. At least for Perl 5.
+     */
+     /* warn("===> before runtime check\n"); */
+    if(SvREFCNT(ST(0)) == 1){
+        /* warn("===> really runtime destroing"); */
+        /* __PH__ */
+        /*__PH__END */
+        JS_DestroyRuntime(rt);
+    }
+
+
+ # package JS::Runtime
+MODULE = JS    PACKAGE = JS::Runtime   PREFIX = JS_
+
+int
+JS_NewContext(rt, stacksize)
+    JSRuntime *rt
+    int        stacksize
+    PREINIT:
+    JSContextItem *cxitem;
+    CODE:
+    {
+        JSObject *obj;
+        /* jsval v; comment out unused var __PH__*/
+        JSContext *cx;
+        cx = JS_NewContext(rt, stacksize);
+        cxitem = PCB_NewContextItem();
+        cxitem->cx = cx;
+        cxitem->next = context_list;
+        context_list = cxitem;
+        /* __PH__ set the error reporter */
+        JS_SetErrorReporter(cx, PCB_ErrorReporter); 
+        obj = JS_NewObject(cx, &global_class, NULL, NULL);
+        JS_SetGlobalObject(cx, obj);
+        JS_InitStandardClasses(cx, obj);
+        RETVAL = (int)cx;
+    }
+    OUTPUT:
+    RETVAL
+
+void
+JS_DestroyContext(cx)
+    JSContext *cx
+    CODE:
+    /* See the comment about ref. count above */
+    /* warn("===> before context check\n"); */
+    if(SvREFCNT(ST(0)) == 1){
+        /* warn("===> really destroing context"); */
+        if (JS_IsExceptionPending(cx)) {
+            JS_ClearPendingException(cx);
+        }
+        JS_SetErrorReporter(cx, NULL);
+        JS_GC(cx); /* OSSP BUGFIX */ /*important*/
+        JS_DestroyContext(cx);
+        PCB_FreeContextItem(cx);
+    }
+
+
+ # package JS::Context
+MODULE = JS    PACKAGE = JS::Context   PREFIX = JS_
+
+jsval
+JS_eval(cx, bytes, ...)
+    JSContext *cx
+    char *bytes
+    PREINIT:
+    JSContextItem *cxitem;
+    char *filename = NULL;
+    CODE:
+    {
+        jsval rval;
+        if (items > 2) { filename = SvPV(ST(2), PL_na); };
+        /* Call on the global object */
+        if(!JS_EvaluateScript(cx, JS_GetGlobalObject(cx), 
+                              bytes, strlen(bytes), 
+                              filename ? filename : "Perl", 
+                              0, &rval)){
+            cxitem = PCB_FindContextItem(cx);
+            if (!cxitem || cxitem->dieFromErrors)
+                croak("JS script evaluation failed");
+       
+            clearException(cx);
+            XSRETURN_UNDEF;
+        } 
+        RETVAL = rval; 
+    }
+    clearException(cx);
+    OUTPUT:
+    RETVAL
+
+
+jsval
+JS_exec_(cx, script)
+    JSContext *cx
+    SV    *script
+    PREINIT:
+    JSContextItem *cxitem;
+    JSScript *handle;
+    CODE:
+    {
+        jsval rval;
+        handle = (JSScript*)SvIV(*hv_fetch((HV*)SvRV(script), "_script", 7, 0));
+        /* Call on the global object */
+        if(!JS_ExecuteScript(cx, JS_GetGlobalObject(cx), 
+                             handle, &rval)) {
+            cxitem = PCB_FindContextItem(cx);
+            if (!cxitem || cxitem->dieFromErrors)
+                croak("JS script evaluation failed");
+
+            clearException(cx);
+            XSRETURN_UNDEF;
+        }
+        clearException(cx);
+        RETVAL = rval;
+    }
+    OUTPUT:
+    RETVAL
+
+#void
+#JS_destroyScript(cx, script)
+#     JSContext *cx
+#     JSScript *script
+#    CODE:
+#    JS_DestroyScript(cx, script);
+
+# __PH__
+void
+JS_setErrorReporter(cx, reporter)
+    JSContext *cx
+    SV* reporter
+    PREINIT:
+    JSContextItem *cxitem;
+    CODE:
+    cxitem = PCB_FindContextItem(cx);
+    SvREFCNT_inc(reporter);
+    if ( cxitem ) cxitem->errorReporter = reporter;
+
+void
+JS_unsetErrorReporter(cx)
+    JSContext *cx
+    PREINIT:
+    JSContextItem *cxitem;
+    CODE:
+    cxitem = PCB_FindContextItem(cx);
+    if ( cxitem ) {
+        if ( cxitem->errorReporter ) 
+            SvREFCNT_dec(cxitem->errorReporter);
+        cxitem->errorReporter = NULL;
+    }
+
+int
+JS_hasException(cx)
+    JSContext *cx
+    CODE:
+    RETVAL = ! JS_IsExceptionPending(cx);
+    OUTPUT:
+    RETVAL
+
+void 
+JS_reportError(cx, msg)
+    JSContext *cx
+    char *msg
+    CODE:
+    JS_ReportError(cx, msg);
+
+void 
+JS_errorFromPrivate(cx, msg, ex)
+     JSContext *cx
+     char *msg
+     JSObject *ex
+     PREINIT:
+     JSErrorReport *rep;
+     CODE:
+     rep = (JSErrorReport*) JS_GetPrivate(cx, ex);
+     if (rep)
+       PCB_ErrorReporter(cx, msg, ((JSExnPrivate*)rep)->errorReport);
+
+void
+JS_setDieFromErrors(cx, value)
+     JSContext *cx
+     int value
+     PREINIT:
+     JSContextItem *cxitem;
+     CODE:
+     cxitem = PCB_FindContextItem(cx);
+     if ( cxitem ) cxitem->dieFromErrors = value;
+
+void
+JS_createObject(cx, object, name,  methods)
+    JSContext *cx 
+    SV *object
+    char *name
+    SV *methods
+    PREINIT:
+    JSObject *jso;
+    HV *m_hash;
+    I32 len;	
+    HE *he;
+    int i;
+    PerlObjectItem *po;
+    JSClass *object_class;
+    PerlCallbackItem *pcbitem;
+    CODE:
+    if (SvTYPE(SvRV(methods)) != SVt_PVHV) {
+        croak("Second parameter has to be HASHREF");
+    }
+    /* create js object in given context */
+    object_class = PCB_NewStdJSClass(name);
+    /* OSSP BUGFIX */ /* jso = JS_NewObject(cx, object_class, NULL, 0); */
+
+    jso = JS_DefineObject(cx, JS_GetGlobalObject(cx), name, 
+                          object_class, NULL, 
+                          JSPROP_ENUMERATE | JSPROP_READONLY | 
+                          JSPROP_PERMANENT);
+
+
+    if (!jso) croak("Unable create JS object");
+    /* create callback info */
+    po = PCB_AddObject(name, object, cx, jso, object_class);
+    m_hash = (HV*)SvRV(methods);
+    hv_iterinit(m_hash);
+    while ((he = hv_iternext(m_hash))) {
+	PCB_AddCallback(po, hv_iterkey(he, &len), hv_iterval(m_hash, he), 0);
+    }
+    /* set js object methods */
+    /* HERE _PH_ */
+    pcbitem = po->vector;
+    while ( pcbitem ) {
+        if (! JS_DefineFunction(cx, jso, pcbitem->name, 
+                                PCB_UniversalStub, 0, 0)) 
+            croak("Unable create JS function");
+        pcbitem = pcbitem->next;
+    }
+
+# __PH__END
+
+
+ # package JS::Object
+MODULE = JS    PACKAGE = JS::Object   PREFIX = JS_
+
+ #
+ #   The methods below get used when hash is tied.
+ #
+SV *
+JS_TIEHASH(class, obj)
+    char *class
+    SV *obj
+    PREINIT:
+    JSContext* cx;
+    CODE:
+        RETVAL = SvREFCNT_inc(obj);
+    OUTPUT:
+    RETVAL
+
+SV *
+JS_TIEARRAY(class, obj)
+    char *class
+    SV *obj
+    PREINIT:
+    JSContext* cx;
+    CODE:
+        RETVAL = SvREFCNT_inc(obj);
+    OUTPUT:
+    RETVAL
+
+jsval
+JS_FETCH(obj, key)
+    JSObject *obj
+    char *key
+    PREINIT:
+    JSContext* cx;
+    jsval rval;
+    MAGIC *magic;
+    CODE:
+    {
+        /* printf("+++++++++> FETCH\n"); */
+        magic = mg_find(SvRV(ST(0)), '~');
+        if (magic) {
+            cx = (JSContext *)SvIV(magic->mg_obj);
+        } else {
+            warn("Tied object has no magic\n");
+        }
+        JS_GetProperty(cx, obj, key, &rval);
+        RETVAL = rval;
+    }
+    OUTPUT:
+    RETVAL
+
+int
+JS_FETCHSIZE(obj)
+    JSObject *obj
+    PREINIT:
+    JSContext* cx;
+    MAGIC *magic;
+    CODE:
+    {
+        /* printf("+++++++++> FETCHSIZE: %d\n", ST(0)); */
+        magic = mg_find(SvRV(ST(0)), '~');
+        if (magic) {
+            cx = (JSContext *)SvIV(magic->mg_obj);
+        } else {
+            warn("Tied object has no magic\n");
+        }
+        JS_IsArrayObject(cx, obj);
+        JS_GetArrayLength(cx, obj, &RETVAL);
+    }
+    OUTPUT:
+    RETVAL
+
+void
+JS_STORE(obj, key, value)
+    JSObject *obj
+    char *key
+    jsval value
+    PREINIT:
+    JSContext* cx;
+    MAGIC *magic;
+    {
+        /* printf("+++++++++> STORE\n"); */
+        magic = mg_find(SvRV(ST(0)), '~');
+        if (magic) {
+            cx = (JSContext *)SvIV(magic->mg_obj);
+        } else {
+            warn("Tied object has no magic\n");
+        }
+    }
+    CODE:
+    {
+        JS_SetProperty(cx, obj, key, &value);
+    }
+
+void
+JS_DELETE(obj, key)
+    JSObject *obj
+    char *key
+    PREINIT:
+    JSContext* cx;
+    MAGIC *magic;
+    CODE:
+    {
+        /* printf("+++++++++> DELETE\n"); */
+        magic = mg_find(SvRV(ST(0)), '~');
+        if (magic) {
+            cx = (JSContext *)SvIV(magic->mg_obj);
+        } else {
+            warn("Tied object has no magic\n");
+        }      
+        JS_DeleteProperty(cx, obj, key);
+    }
+
+void
+JS_CLEAR(obj)
+    JSObject *obj
+    PREINIT:
+    JSContext* cx;
+    MAGIC *magic;
+    CODE:
+    {
+        /* printf("+++++++++> CLEAR\n"); */
+        magic = mg_find(SvRV(ST(0)), '~');
+        if (magic) {
+            cx = (JSContext *)SvIV(magic->mg_obj);
+        } else {
+            warn("Tied object has no magic\n");
+        }
+        JS_ClearScope(cx, obj);
+    }
+
+int
+JS_EXISTS(obj, key)
+    JSObject *obj
+    char *key
+    PREINIT:
+    JSContext* cx;
+    MAGIC *magic;
+    CODE:
+    {
+        jsval v;
+        /* printf("+++++++++> EXISTS\n"); */
+        magic = mg_find(SvRV(ST(0)), '~');
+        if (magic) {
+            cx = (JSContext *)SvIV(magic->mg_obj);
+        } else {
+            warn("Tied object has no magic\n");
+        }
+        JS_LookupProperty(cx, obj, key, &v);
+        RETVAL = !JSVAL_IS_VOID(v);
+    }
+    OUTPUT:
+    RETVAL
+
+#script
+MODULE = JS    PACKAGE = JS::Script   PREFIX = JS_
+
+int
+JS_compileScript(object, cx, bytes, ...)
+    SV *object
+    JSContext *cx
+    char *bytes
+    PREINIT:
+    JSContextItem *cxitem;
+    char *filename = NULL;
+    CODE:
+    {
+        if (items > 2) { filename = SvPV(ST(2), PL_na); };
+        /* Call on the global object */
+        if(!(RETVAL = (int)JS_CompileScript(cx, JS_GetGlobalObject(cx), 
+                                       bytes, strlen(bytes), 
+                                       filename ? filename : "Perl", 
+                                       0)))
+            {
+                cxitem = PCB_FindContextItem(cx);
+                if (!cxitem || cxitem->dieFromErrors)
+                    croak("JS script compilation failed");
+                XSRETURN_UNDEF;
+            }
+    }
+    OUTPUT:
+    RETVAL
+
+int 
+JS_rootScript(object, cx, name)
+    SV *object
+    JSContext *cx
+    char *name
+    PREINIT:
+    JSObject **scrobj;
+    JSScript *handle;
+    CODE:
+    handle = (JSScript*)SvIV(*hv_fetch((HV*)SvRV(object), "_script", 7, 0));
+    scrobj = malloc(sizeof(JSObject*));
+    *scrobj = JS_NewScriptObject(cx, handle);
+    JS_AddNamedRoot(cx, scrobj, name);
+    RETVAL = (int)scrobj;
+    OUTPUT:
+    RETVAL
+
+void 
+JS_destroyScript(object, cx)
+    SV *object
+    JSContext *cx
+    PREINIT:
+    JSObject **scrobj;
+    JSScript *handle;
+    CODE:
+    handle = (JSScript*)SvIV(*hv_fetch((HV*)SvRV(object), "_script", 7, 0));
+    scrobj = (JSObject**)SvIV(*hv_fetch((HV*)SvRV(object), "_root", 5, 0));
+    JS_RemoveRoot(cx, scrobj);
+

Added: freeswitch/trunk/libs/js/src/perlconnect/MANIFEST
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/perlconnect/MANIFEST	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,11 @@
+MANIFEST
+.cvsignore
+JS.pm
+JS.xs
+jsperl.c
+jsperl.h
+jsperlpvt.h
+Makefile.PL
+Makefile.PL.in
+PerlConnect.pm
+typemap

Added: freeswitch/trunk/libs/js/src/perlconnect/Makefile.PL.in
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/perlconnect/Makefile.PL.in	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,11 @@
+
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+    NAME         => 'JS',
+	DEFINE       => '-DOSSP -DXP_UNIX',
+	INC          => "-I..",
+	LIBS         => "-L../../.libs -ljs @LIBS@",
+	VERSION_FROM => 'JS.pm',
+);
+

Added: freeswitch/trunk/libs/js/src/perlconnect/PerlConnect.pm
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/perlconnect/PerlConnect.pm	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,126 @@
+############################################################################
+# PerlConnect support package. 8/3/98 2:50PM
+# This packages implements private methods called from jsperl.c
+# Please don't try to include in from Perl
+# See README.html and JS.xs for information about this module.
+############################################################################
+
+package JS;
+require Exporter;
+require DynaLoader;
+ at ISA = qw(Exporter DynaLoader);
+ at EXPORT_OK = qw(perl_eval perl_resolve perl_call $js $ver);
+
+# version string for the interpreter
+$ver = "[Perl Interpreter: Version $] compiled under $^O]\n";
+$DEBUG = undef;
+
+############################################################################
+# TODO: This will be added
+############################################################################
+sub AUTOLOAD        #7/28/98 8:24PM
+{
+    print "\nJS::AUTOLOAD: $AUTOLOAD, not implemented yet\n" if $DEBUG;
+}   ##AUTOLOAD
+
+############################################################################
+# Evaluates the parameter and returns the return result of eval() as a
+# reference
+############################################################################
+sub perl_eval       #7/15/98 5:13PM
+{
+    my($stmt) = shift;
+    package main;
+    my(@_js) = eval($stmt);
+    package JS;
+    my($_js) = (scalar(@_js)==1)?$_js[0]:\@_js;
+    undef $js;
+    $js = (ref $_js) ? $_js: \$_js;
+    print "Failure in perl_call!" unless ref $js;
+}   ##perl_eval
+
+############################################################################
+# Calls the procesure passed as the first parameter and passes the rest of
+# the arguments to it. The return result is converted to a reference as
+# before
+############################################################################
+sub perl_call       #7/21/98 2:16PM
+{
+    my($proc) = shift;
+    my($_js);
+
+    $proc =~ s/main:://g;
+    #print "Calling $proc\n";
+    package main;
+    my(@_js) = &$proc(@_);
+    package JS;
+    #print "here: ", @_js, "\n";
+    $_js = (scalar(@_js)==1)?$_js[0]:\@_js;
+    undef $js;
+    $js = (ref $_js) ? $_js: \$_js;
+    #print ref $js;
+    print "Failure in perl_call!" unless ref $js;
+}   ##perl_call
+
+############################################################################
+# Takes the first parameter and tries to retrieve this variable
+############################################################################
+sub perl_resolve        #7/22/98 10:08AM
+{
+    my($name)  = shift;
+    my(@parts) = split('::', $name);
+    my($last_part)  = pop(@parts);
+
+    # variable lookup -- variables must start with $, @, or %
+    if($last_part =~ /^([\$\@\%])(.+)/){
+        my($resolved_name) = "$1".join('::', @parts)."::$2";
+        package main;
+        my(@_js) = eval($resolved_name);
+        package JS;
+        my($_js) = (scalar(@_js)==1)?$_js[0]:\@_js;
+        undef $js;
+        $js = (ref $_js) ? $_js: \$_js;
+    }else{
+        $name =~ s/main:://g;
+        # if this function exists
+        # function -- set $js to 1 to indicate this
+        if(eval "return defined(&main::$name)"){
+            print "function $name\n" if $DEBUG;
+            $js = 1;
+        # module
+        }else{
+            print "must be a module\n" if $DEBUG;
+            $js=2;
+            return;
+            # defined module -- try to do an eval and check $@ to trap errors
+            # as a result, the module is automatically pre-use'd if it exists
+            $name =~ s/main:://g;
+            if(eval "use $name; return !(defined($@));"){
+                $js = 2;
+            # o.w. this module is undefined
+            }else{
+                $js = 3;
+            }
+        }
+    }
+}   ##perl_resolve
+
+############################################################################
+# Validates package name
+############################################################################
+sub perl_validate_package       #7/22/98 10:15AM
+{
+    print "perl_validate_package\n" if $DEBUG;
+    my($name) = shift;
+    print $name if $DEBUG;
+    $js = $name?1:undef;
+}   ##perl_validate_package
+
+# test procedure
+sub c{
+    print "da!\n" if wantarray;
+    print "Called!\n";
+    return @_;
+}
+
+1;
\ No newline at end of file

Added: freeswitch/trunk/libs/js/src/perlconnect/jsperl.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/perlconnect/jsperl.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,1100 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the 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 ***** */
+
+/*
+ * PerlConnect module.
+ */
+
+/*
+    The first two headers are from the Perl distribution.
+    Play with "perl -MExtUtils::Embed -e ccopts -e ldopts"
+    to find out which directories should be included. Refer
+    to perlembed man page for more info.
+*/
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include <jsapi.h>
+#include <string.h>
+
+/*---------------------------------------------------------------------------*/
+/* PerlConnect. Provides means for OO JS <==> Perl communications            */
+/* See README.html for more info on PerlConnect. Look for TODO in this file  */
+/* for things that are bogus or not completely implemented. Has been tested  */
+/* with 5.004 only                                                           */
+/*---------------------------------------------------------------------------*/
+
+/* Forward declarations */
+static JSBool PerlConstruct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *v);
+static void PerlFinalize(JSContext *cx, JSObject *obj);
+static JSBool perl_eval(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval);
+static JSBool perl_call(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval);
+static JSBool perl_use(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval);
+static JSBool use(JSContext *cx, JSObject *obj, int argc, jsval *argv, const char* t);
+static JSBool PMGetProperty(JSContext *cx, JSObject *obj, jsval name, jsval* rval);
+static JSBool PMSetProperty(JSContext *cx, JSObject *obj, jsval name, jsval *rval);
+static JSBool PerlToString(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval);
+static JSBool processReturn(JSContext *cx, JSObject *obj, jsval* rval);
+static JSBool checkError(JSContext *cx);
+static JSBool PMToString(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval);
+static JSBool PVToString(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval);
+static SV*    PVGetRef(JSContext *cx, JSObject *obj);
+static JSBool PVGetProperty(JSContext *cx, JSObject *obj, jsval name, jsval *rval);
+static JSBool PVSetProperty(JSContext *cx, JSObject *obj, jsval name, jsval *rval);
+static JSBool PVGetElement(JSContext *cx, JSObject *obj, jsint index, jsval *rval);
+static JSBool PVSetElement(JSContext *cx, JSObject *obj, jsint index, jsval v);
+static JSBool PVGetKey(JSContext *cx, JSObject *obj, char* name, jsval *rval);
+static JSBool PVSetKey(JSContext *cx, JSObject *obj, char* name, jsval v);
+static JSBool PVConvert(JSContext *cx, JSObject *obj, JSType type, jsval *v);
+static void PVFinalize(JSContext *cx, JSObject *obj);
+/* Exported functions */
+JS_EXPORT_API(JSObject*)	JS_InitPerlClass(JSContext *cx, JSObject *obj);
+JS_EXPORT_API(JSBool)		JSVALToSV(JSContext *cx, JSObject *obj, jsval v, SV** sv);
+JS_EXPORT_API(JSBool)		SVToJSVAL(JSContext *cx, JSObject *obj, SV *ref, jsval *rval);
+
+/*
+    The following is required by the Perl dynamic loading mechanism to
+    link with modules that use C properly. See perlembed man page for details.
+    This allows things like sockets to be called via PerlConnect.
+*/
+#ifdef __cplusplus
+#  define EXTERN_C extern "C"
+#else
+#  define EXTERN_C extern
+#endif
+
+EXTERN_C void boot_DynaLoader _((CV* cv));
+EXTERN_C void
+xs_init()
+{
+    newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__);
+}
+
+/* These properties are not processed by the getter for PerlValue */
+static char* predefined_methods[] = {"toString", "valueOf", "type", "length"};
+
+/* Represents a perl interpreter */
+JSClass perlClass = {
+    "Perl", JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub,  JS_PropertyStub, PMGetProperty, /*PMSetProperty*/JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,  PerlFinalize
+};
+
+static JSFunctionSpec perlMethods[] = {
+    {"toString",  (JSNative)PerlToString, 0},
+    {"eval",  (JSNative)perl_eval, 0},
+    {"call",  (JSNative)perl_call, 0},
+    {"use",   (JSNative)perl_use,  0},
+    { NULL, NULL,0 }
+};
+
+
+/* Represents a Perl module */
+JSClass perlModuleClass = {
+    "PerlModule", JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub,  JS_PropertyStub, PMGetProperty, JS_PropertyStub,
+    JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
+};
+
+JSFunctionSpec perlModuleMethods[] = {
+    {"toString",  (JSNative)PMToString, 0},
+    { NULL, NULL,0 }
+};
+
+
+/* Represents a value returned from Perl */
+JSClass perlValueClass = {
+    "PerlValue", JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub,  JS_PropertyStub, PVGetProperty, PVSetProperty,
+    JS_EnumerateStub, JS_ResolveStub, PVConvert, PVFinalize
+};
+
+JSFunctionSpec perlValueMethods[] = {
+    {"toString",  (JSNative)PVToString, 0},
+    { NULL, NULL,             0}
+};
+
+/*
+    Initializes Perl class. Should be called by applications that
+    want to enable PerlConnect. This will probably preload the Perl
+    DLL even though Perl might not actually be used. We may postpone
+    this and load the DLL at runtime after the constructor is called.
+*/
+static JSObject*
+js_InitPerlClass(JSContext *cx, JSObject *obj)
+{
+    jsval v;
+    JSObject *module;
+    JSString *mainString = JS_NewStringCopyZ(cx, "main");
+    if (!mainString)
+        return NULL;
+    v = STRING_TO_JSVAL(mainString);
+    module = JS_NewObject(cx, &perlModuleClass, NULL, obj);
+    if (!module)
+        return NULL;
+
+    if (!JS_DefineFunctions(cx, module, perlModuleMethods))
+        return NULL;
+
+    JS_SetProperty(cx, module, "path", &v);
+
+    return JS_InitClass(cx, obj, module, &perlClass, PerlConstruct, 0,
+        NULL, NULL, NULL, NULL);
+}
+
+/* Public wrapper for the function above */
+JSObject*
+JS_InitPerlClass(JSContext *cx, JSObject *obj)
+{
+    return js_InitPerlClass(cx, obj);
+}
+
+/*
+    Perl constructor. Allocates a new interpreter and defines methods on it.
+    The constructor is sort of bogus in that it doesn't create a new namespace
+    and all the variables defined in one instance of the Perl object will be
+    visible in others. In the future, I think it may be a good idea to use
+    Safe.pm to provide independent contexts for different Perl objects and
+    prohibit certain operations (like exit(), alarm(), die(), etc.). Or we
+    may simple disallow calling the constructor more than once.
+*/
+static JSBool
+PerlConstruct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *v)
+{
+    PerlInterpreter *perl;
+    JSObject *perlObject;
+    JSBool ok;
+    char *embedding[] = {"", "-e", "0"};
+    char *t = "use PerlConnect qw(perl_eval perl_resolve perl_call $js $ver);";
+
+    /* create a new interpreter */
+    perl = perl_alloc();
+
+    if(perl==NULL){
+        JS_ReportError(cx, "Can't allocate a new interpreter");
+        return JS_FALSE;
+    }
+
+    perl_construct(perl);
+    if(perl_parse(perl, xs_init, 3, embedding, NULL)){
+        JS_ReportError(cx, "Parsing failed");
+        return JS_FALSE;
+    }
+    if(perl_run(perl)){
+        JS_ReportError(cx, "Run failed");
+        return JS_FALSE;
+    }
+    ok = use(cx, obj, argc, argv, t);
+
+    /* make it into an object */
+    perlObject = JS_NewObject(cx, &perlClass, NULL, NULL);
+    if(!perlObject)
+        return JS_FALSE;
+    if(!JS_DefineFunctions(cx, perlObject, perlMethods))
+        return JS_FALSE;
+    JS_SetPrivate(cx, perlObject, perl);
+    *v = OBJECT_TO_JSVAL(perlObject);
+    return ok;
+}
+
+/* Destructor. Deallocates the interpreter */
+static void
+PerlFinalize(JSContext *cx, JSObject *obj)
+{
+    PerlInterpreter *perl = JS_GetPrivate(cx, obj);
+    if (perl) {
+        perl_destruct(perl);
+        perl_free(perl);
+    }
+    /*    return JS_TRUE; */
+}
+
+/*
+    Returns a string representation of the Perl interpreter.
+    Can add printing of the Perl version, @ISA, etc., like the
+    output produced by perl -V. Can also make certain variables
+    available off the Perl object, like Perl.version, etc.
+*/
+static JSBool
+PerlToString(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
+    JSString *imported;
+    SV* sv = perl_get_sv("JS::ver", FALSE);
+    if (!sv) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+    imported = JS_NewStringCopyZ(cx, SvPV(sv, PL_na));
+    if (!imported)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(imported);
+    return JS_TRUE;
+}
+
+/*
+    Evaluates the first parameter in Perl and put the eval's
+    return value into *rval. The return value is of type PerlValue.
+    This procedure uses JS::perl_eval. Example of use of perl.eval():
+        p = new Perl();
+        str = p.eval("'-' x 80");   // str contains 80 dashes
+*/
+static JSBool
+perl_eval(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval)
+{
+    char *statement;
+    char *args[] = {NULL, NULL};    /* two elements */
+
+    if(argc!=1){
+        JS_ReportError(cx, "Perl.eval expects one parameter");
+        return JS_FALSE;
+    }
+    statement = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+
+    args[0] = statement;
+    perl_call_argv("JS::perl_eval", G_SCALAR|G_KEEPERR|G_EVAL, args);
+    return processReturn(cx, obj, rval);
+}
+
+/*
+    Call the perl procedure specified as the first argument and
+    pass all the other arguments as parameters. The return value
+    is returned in *rval. Example of use of perl.call():
+        p = new Perl('Time::gmtime');
+        time = p.call("Time::gmtime::gmtime");   // time is now the following array:
+                                                 // [40,42,1,22,6,98,3,202,0]
+    NB: The full function name has to be supplied, i.e. Time::gmtime::gmtime
+    instead of gmtime unless gmtime is exported into the current package.
+
+    This method is also used when one uses the full package name syntax like
+    this:
+        p = new Perl("Sys::Hostname", "JS")
+        result = p.JS.c(1, 2, 4)
+        p.hostname()
+
+    This gets called from PMGetProperty, which creates a
+    function whose native method is perl_call. Also see
+    JS::perl_call.
+*/
+static JSBool
+perl_call(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval)
+{
+    JSBool ok;
+    int count, i;
+    char* fun_name;
+    SV *sv;
+    dSP;
+
+    /* Differetiate between direct and method-like call */
+    if((JS_TypeOfValue(cx, argv[-2]) == JSTYPE_FUNCTION) &&
+            strcmp("call", JS_GetFunctionName(JS_ValueToFunction(cx, argv[-2])))){
+        fun_name = (char*)JS_GetFunctionName(JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[-2])));
+        i=0;
+    }else{
+        fun_name = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+        i=1;
+    }
+
+    PUSHMARK(sp);
+    XPUSHs(sv_2mortal(newSVpv(fun_name,0)));
+
+    for(;i<argc;i++){
+        JSVALToSV(cx, obj, argv[i], &sv);
+        XPUSHs(sv);
+    }
+    PUTBACK;
+
+    count = perl_call_sv(newSVpv("JS::perl_call", 0), G_KEEPERR|G_SCALAR|G_EVAL|G_DISCARD);
+    if(count!=0){
+        JS_ReportError(cx, "Implementation error: count=%d, must be 0!\n", count);
+        return JS_FALSE;
+    }
+    ok = processReturn(cx, obj, rval);
+
+    return ok;
+}
+
+/*
+    Loads Perl libraries specified as arguments.
+*/
+static JSBool
+perl_use(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval)
+{
+    return use(cx, obj, argc, argv, NULL);
+}
+
+/*
+    Utility function used by perl_use and Perl's constructor.
+    Executes use lib1; use lib2, etc. in the current interpreter.
+*/
+static JSBool
+use(JSContext *cx, JSObject *obj, int argc, jsval *argv, const char* t){
+    char *evalStr = JS_malloc(cx, t?strlen(t)+1:1);
+    int i;
+
+    if (!evalStr)
+        return JS_FALSE;
+
+    strcpy(evalStr, t?t:"");
+
+    for(i=0;i<argc;i++){
+        char *arg = JS_GetStringBytes(JS_ValueToString(cx, argv[i])), *tmp, old[256];
+
+        /* call use() on every parameter */
+        strcpy(old, evalStr);
+	JS_free(cx, evalStr);
+        tmp = JS_malloc(cx, strlen(old)+strlen(arg)+6);
+        if (!tmp)
+            return JS_FALSE;
+        sprintf(tmp, "%suse %s;", old, arg);
+        evalStr = tmp;
+    }
+
+    perl_eval_sv(newSVpv(evalStr, 0), G_KEEPERR);
+
+    checkError(cx);
+    JS_free(cx, evalStr);
+    return JS_TRUE;
+}
+
+/*
+    Looks at $@ to see if there was an error. Used by
+    perl_eval, perl_call, etc.
+*/
+static JSBool
+checkError(JSContext *cx)
+{
+    if(SvTRUE(GvSV(PL_errgv))){ 
+        JS_ReportError(cx, "perl eval failed: %s",
+            SvPV(GvSV(PL_errgv), PL_na));
+        /* clear error status. there should be a way to do this faster */
+        perl_eval_sv(newSVpv("undef $@;", 0), G_KEEPERR);
+        return JS_FALSE;
+    }
+    return JS_TRUE;
+}
+
+/*
+    Take the value of $JS::js and convert in to a jsval. It's stotred
+    in *rval. perl_eval and perl_call use $JS::js to store return results.
+*/
+static JSBool
+processReturn(JSContext *cx, JSObject *obj, jsval* rval)
+{
+    SV  *js;
+
+    js = perl_get_sv("JS::js", FALSE);
+
+    if(!js || !SvOK(js)){
+        *rval = JSVAL_VOID;
+        /* XXX isn't this wrong? */
+        return JS_FALSE;
+    }
+    if(!SvROK(js)){
+        JS_ReportError(cx, "$js (%s) must be of reference type", SvPV(js,PL_na));
+        return JS_FALSE;
+    }
+
+    checkError(cx);
+
+    return SVToJSVAL(cx, obj, js, rval);
+}
+
+/*
+    Implements namespace-like syntax that maps Perl packages to
+    JS objects. One can say
+        p = new Perl('Foo::Bar')
+    and then call
+        a = p.Foo.Bar.f()
+    or access variables exported from those packages like this:
+        a = p.Foo.Bar["$var"]
+    this syntax will also work:
+        a = p.Foo.Bar.$var
+    but if you want to access non-scalar values, you must use the subscript syntax:
+        p.Foo.Bar["@arr"]
+    and
+        p.Foo.Bar["%hash"]
+*/
+static JSBool
+PMGetProperty(JSContext *cx, JSObject *obj, jsval name, jsval *rval)
+{
+    char *last = JS_GetStringBytes(JS_ValueToString(cx, name)), *path, package[256];
+    char *args[] = {NULL, NULL};
+    char *predefined_methods[] = {"toString", "eval", "call", "use", "path"};
+    int count;
+    SV  *js;
+    jsval v;
+    int i;
+
+    for(i=0;i<sizeof(predefined_methods)/sizeof(char*);i++){
+        if(!strcmp(predefined_methods[i], last)){
+            return JS_TRUE;
+        }
+    }
+
+    JS_GetProperty(cx, obj, "path", &v);
+    path = JS_GetStringBytes(JS_ValueToString(cx, v));
+    sprintf(package, "%s::%s", path, last);
+    args[0] = package;
+
+    count = perl_call_argv("JS::perl_resolve", G_KEEPERR|G_SCALAR|G_EVAL|G_DISCARD, args);
+    if(count!=0){
+        JS_ReportError(cx, "Implementation error: count=%d, must be 0!\n", count);
+        return JS_FALSE;
+    }
+
+    checkError(cx);
+
+    js = perl_get_sv("JS::js", FALSE);
+
+    if(js && SvOK(js)){
+        if(SvROK(js)){
+            SVToJSVAL(cx, obj, js, rval);
+        }else{
+            /* defined function */
+            if(SvIV(js) == 1){
+                JSFunction *f = JS_NewFunction(cx, (JSNative)perl_call, 0, 0, NULL, package);
+                if (!f) {
+                    return JS_FALSE;
+                }
+                *rval = OBJECT_TO_JSVAL(JS_GetFunctionObject(f));
+            }else
+            if(SvIV(js) == 2){
+                JSObject *module;
+                JSString *packageString;
+                module = JS_NewObject(cx, &perlModuleClass, NULL, obj);
+                packageString = JS_NewStringCopyZ(cx,package);
+                if (!module || !packageString) {
+                    return JS_FALSE;
+                }
+                v = (js && SvTRUE(js))?STRING_TO_JSVAL(packageString):JSVAL_VOID;
+                JS_SetProperty(cx, module, "path", &v);
+                *rval = OBJECT_TO_JSVAL(module);
+            }else{
+                JS_ReportError(cx, "Symbol %s is not defined", package);
+                *rval = JSVAL_VOID;
+            }
+        }
+        return JS_TRUE;
+    }else{
+        JS_ReportError(cx, "failure");
+        return JS_FALSE;
+    }
+}
+
+/*
+    Gets called when a Perl value gets assigned to like this:
+        p.Foo.Bar["$var"] = 100
+*/
+static JSBool
+PMSetProperty(JSContext *cx, JSObject *obj, jsval name, jsval *rval)
+{
+    /* TODO: just call SVToJSVAL() and make the assignment. */
+    return JS_TRUE;
+}
+
+/*
+    toString() for PerlModule. Prints the path the module represents.
+    Note that the path doesn't necessarily have to be valid. We don't
+    have a way to check that until we call a function from that package.
+    TODO: In 5.005 exists Foo::{Bar::} checks is Foo::{Bar::} exists.
+    We can use this to validate package names.
+*/
+static JSBool
+PMToString(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
+    char str[256];
+    JSString *s, *newString;
+    jsval v;
+
+    JS_GetProperty(cx, obj,  "path", &v);
+    s = JSVAL_TO_STRING(v);
+    sprintf(str, "[PerlModule %s]", JS_GetStringBytes(s));
+    newString = JS_NewStringCopyZ(cx, str);
+    if (!newString)
+        return JS_FALSE;
+    *rval = STRING_TO_JSVAL(newString);
+    return JS_TRUE;
+}
+
+/*
+    Helped method. Retrieves the Perl reference stored
+    in PerlValue object as private data.
+*/
+
+#include <stdio.h>
+
+static SV*
+PVGetRef(JSContext *cx, JSObject *obj)
+{
+    SV* ref;
+
+    ref = (SV*)JS_GetInstancePrivate(cx, obj, &perlValueClass, NULL);
+
+    if(!ref || !SvOK(ref) || !SvROK(ref)){
+        JS_ReportError(cx, "Can't extract ref");
+        return NULL;
+    }
+    return ref;
+}
+
+static JSBool
+PVCallStub (JSContext *cx, JSObject *obj, uintN argc, 
+            jsval *argv, jsval *rval) {
+    JSFunction *fun;
+    int i, cnt;
+    I32 ax;
+    SV *sv, *perl_object;
+    GV *gv;
+    HV *stash;
+    char *name;
+
+    dSP;
+
+    fun = JS_ValueToFunction(cx, argv[-2]);
+    perl_object = PVGetRef(cx, obj);
+
+    fun = JS_ValueToFunction(cx, argv[-2]);
+    name = (char*) JS_GetFunctionName(fun);
+
+    stash = SvSTASH(SvRV(perl_object));
+    gv = gv_fetchmeth(stash, name, strlen(name), 0);
+    /* cnt = perl_call_pv(method_name, 0); */
+    /* start of perl call stuff */
+    if (! gv) {
+        char msg[256];
+        sprintf(msg, "Method ``%s'' not defined", name);
+        JS_ReportError(cx, msg);
+        return JS_FALSE;
+    }
+
+    ENTER;
+    SAVETMPS;
+    PUSHMARK(SP);
+    //SvREFCNT_inc(perl_object);
+    XPUSHs(perl_object); /* self for perl object method */
+    for (i = 0; i < argc; i++) {
+        //sv = sv_newmortal();
+        JSVALToSV(cx, obj, argv[i], &sv);
+        //sv_2mortal(sv);
+        XPUSHs(sv);
+    }
+    PUTBACK;
+
+    cnt = perl_call_sv((SV*)GvCV(gv), G_ARRAY | G_KEEPERR | G_EVAL);
+
+    //SvREFCNT_dec(perl_object);
+
+    SPAGAIN;
+    /* adjust stack for use of ST macro (see perlcall) */
+    SP -= cnt;
+    ax = (SP - PL_stack_base) + 1;
+
+    /* read value(s) */
+    if (cnt == 1) {
+        SVToJSVAL(cx, obj, ST(0), rval);
+    } else {
+        JSObject *jsarr;
+        jsval val;
+        int i;
+        jsarr = JS_NewArrayObject(cx, 0, NULL);
+        for (i = 0; i < cnt; i++) {
+            SVToJSVAL(cx, JS_GetGlobalObject(cx), ST(i), &val);
+            JS_DefineElement(cx, jsarr, i, val, NULL, NULL, 0);
+        }
+        *rval = OBJECT_TO_JSVAL(jsarr);
+    }
+    PUTBACK;
+
+    FREETMPS;
+    LEAVE;
+
+    //return(JS_TRUE);
+    return checkError(cx);
+}
+
+/*
+    Retrieve property from PerlValue object by its name. Tries
+    to look at the PerlValue object both as a hash and array.
+    If the index is numerical, then it looks at the array part
+    first. *rval contains the result.
+*/
+/* __PH__
+    ...but. PVGetproperty now firstly looks for method in given 
+    object package. If such method if found, then is returned 
+    universal method stub. Sideeffect of this behavior is, that
+    method are looked first before properties of the same name.
+
+    Second problem is security. In this way any perl method could 
+    be called. We pay security leak for this. May be we could 
+    support some Perl exporting process (via some package global 
+    array).
+*/
+static JSBool
+PVGetProperty(JSContext *cx, JSObject *obj, jsval name, jsval *rval)
+{
+    char* str;
+
+    /* __PH__ array properties should be served first */
+    if(JSVAL_IS_INT(name)){
+        int32 ip;
+
+        JS_ValueToInt32(cx, name, &ip);
+        PVGetElement(cx, obj, ip, rval);
+        if(*rval!=JSVAL_VOID){
+            return JS_TRUE;
+        }
+    }
+
+    str = JS_GetStringBytes(JS_ValueToString(cx, name));
+
+    /* __PH__ may, be */
+    if(!strcmp(str, "length")){
+        SV* sv = SvRV(PVGetRef(cx, obj));
+
+        if(SvTYPE(sv)==SVt_PVAV){
+            *rval = INT_TO_JSVAL(av_len((AV*)sv)+1);
+            return JS_TRUE;
+        }else
+        if(SvTYPE(sv)==SVt_PVHV){
+            *rval = INT_TO_JSVAL(av_len((AV*)sv)+1);
+            return JS_TRUE;
+        }else{
+            *rval = INT_TO_JSVAL(0);
+            return JS_TRUE;
+        }
+    }else{
+        int i;
+        /* __PH__ predefined methods NUST win */
+        for(i=0; i < sizeof(predefined_methods)/sizeof(char*); i++){
+            if(!strcmp(predefined_methods[i], str)){
+                return JS_TRUE;
+            }
+        }
+
+        /* __PH__ properties in hash should be served at last (possibly) */
+        PVGetKey(cx, obj, str, rval);
+        if (*rval!=JSVAL_VOID) {
+            return JS_TRUE;
+        } else {
+#if 0
+            char* str = JS_GetStringBytes(JS_ValueToString(cx, name));
+            JS_ReportError(cx, "Perl: can't get property '%s'", str);
+            return JS_FALSE;
+#else
+            /* when Volodya does another job, we may experiment :-) */
+            char* str = JS_GetStringBytes(JS_ValueToString(cx, name));
+            /* great, but who will dispose it? (GC of JS??) */
+            JSFunction *fun = JS_NewFunction(cx, PVCallStub, 0, 0, NULL, str);
+            *rval = OBJECT_TO_JSVAL(JS_GetFunctionObject(fun));
+            return(JS_TRUE);
+#endif
+        }
+    }
+    return JS_TRUE;
+}
+
+/*
+    Set property of PerlValue object. Like GetProperty is looks at
+    both array and hash components.
+*/
+static JSBool
+PVSetProperty(JSContext *cx, JSObject *obj, jsval name, jsval *rval)
+{
+    char* str = JS_GetStringBytes(JS_ValueToString(cx, name));
+
+    if(JSVAL_IS_INT(name)){
+        int32 ip;
+
+        JS_ValueToInt32(cx, name, &ip);
+        if(PVSetElement(cx, obj, ip, *rval)) return JS_TRUE;
+    }
+    return PVSetKey(cx, obj, str, *rval);
+}
+
+/*
+    Retrieve numerical property of a PerlValue object.
+    If the object doesn't contain an array, or the
+    property doesn't exist, NULL is returned.
+*/
+static JSBool
+PVGetElement(JSContext *cx, JSObject *obj, jsint index, jsval *rval)
+{
+    SV *ref, **sv;
+    AV *list;
+
+    *rval = JSVAL_VOID;
+
+    ref = PVGetRef(cx, obj);
+
+    if(SvTYPE(SvRV(ref)) != SVt_PVAV){
+        return JS_FALSE;
+    }
+
+    list = (AV*)SvRV(ref);
+
+    if(!list){
+        return JS_FALSE;
+    }
+    sv = av_fetch(list, (I32)index, 0);
+    if(!sv){
+        return JS_FALSE;
+    }
+    //return SVToJSVAL(cx, obj, newRV_inc(*sv), rval);
+    return SVToJSVAL(cx, obj, *sv, rval);
+}
+
+/*
+    Set a numeric property of a PerlValue object.
+    If the object doesn't contain an array or the
+    index doesn't exist, JS_FALSE is returned.
+*/
+static JSBool
+PVSetElement(JSContext *cx, JSObject *obj, jsint index, jsval v)
+{
+    SV *ref, **sv, *s;
+    AV *list;
+
+    ref = PVGetRef(cx, obj);
+
+    if(SvTYPE(SvRV(ref)) != SVt_PVAV){
+        return JS_FALSE;
+    }
+
+    list = (AV*)SvRV(ref);
+
+    if(!list) return JS_FALSE;
+    JSVALToSV(cx, obj, v, &s);
+    sv = av_store(list, (I32)index, s);
+    if(!sv) return JS_FALSE;
+    return JS_TRUE;
+}
+
+/*
+    Retrieve property. If the object doesn't contain an hash, or the
+    property doesn't exist, NULL is returned.
+*/
+static JSBool
+PVGetKey(JSContext *cx, JSObject *obj, char* name, jsval *rval)
+{
+    SV *ref, **sv;
+    HV *hash;
+
+    *rval = JSVAL_VOID;
+    ref = PVGetRef(cx, obj);
+
+    if(SvTYPE(SvRV(ref)) != SVt_PVHV){
+        return JS_FALSE;
+    }
+
+    hash = (HV*)SvRV(ref);
+
+    if(!hash){
+        return JS_FALSE;
+    }
+    sv = hv_fetch(hash, name, strlen(name), 0);
+    if(!sv){
+        return JS_FALSE;
+    }
+    return SVToJSVAL(cx, obj, newRV_inc(*sv), rval);
+}
+
+/*
+    Get property of a PerlValue object.
+    If the object doesn't contain a hash or the
+    property doesn't exist, JS_FALSE is returned.
+*/
+static JSBool
+PVSetKey(JSContext *cx, JSObject *obj, char* name, jsval v)
+{
+    SV *ref, **sv, *s;
+    HV *hash;
+
+    ref = PVGetRef(cx, obj);
+
+    if(SvTYPE(SvRV(ref)) != SVt_PVHV){
+        return JS_FALSE;
+    }
+
+    hash = (HV*)SvRV(ref);
+
+    if(!hash) return JS_FALSE;
+    JSVALToSV(cx, obj, v, &s);
+    sv = hv_store(hash, name, strlen(name), s, 0);
+    if(!sv) return JS_FALSE;
+    else return JS_TRUE;
+}
+
+/*
+    toString() method for PerlValue. For arrays uses array's methods.
+    If this fails, the type of the value gets returned. TODO: It's actually
+    better to use a Perl module like Data::Dumpvar.pm to print complex
+    data structures recursively.
+*/
+static JSBool
+PVToString(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval)
+{
+    SV* ref     = PVGetRef(cx, obj);
+    SV* sv      = SvRV(ref);
+    svtype type = SvTYPE(sv);
+    /*jsval args[]= {STRING_TO_JSVAL(JS_NewStringCopyZ(cx, "JS::Object::toString")),
+                            OBJECT_TO_JSVAL(obj)};*/
+    jsval v;
+    /*return perl_call(cx, obj, 2, args, rval);*/
+
+    if (type==SVt_PVAV) {
+        JSObject   *arrayObject = JS_NewArrayObject(cx,0,NULL);
+        JSFunction *fun;
+
+        JS_GetProperty(cx, arrayObject, "toString", &v);
+        fun = JS_ValueToFunction(cx, v);
+        return JS_CallFunction(cx, obj, fun, 0, NULL, rval);
+    } 
+    {
+        char out[256];
+        JSString *newString;
+        JS_GetProperty(cx, obj, "type", &v);
+        if(!JSVAL_IS_VOID(v))
+            sprintf(out, "[%s]", JS_GetStringBytes(JSVAL_TO_STRING(v)));
+        else
+            strcpy(out, "[PerlValue]");
+        newString = JS_NewStringCopyZ(cx, out);
+        if (!newString)
+            return JS_FALSE;
+        *rval = STRING_TO_JSVAL(newString);
+    }
+    return JS_TRUE;
+}
+
+static JSBool
+PVConvert (JSContext *cx, JSObject *obj, JSType type, jsval *rval)
+{
+    *rval = OBJECT_TO_JSVAL(obj);
+    return JS_TRUE;
+}
+
+/*
+    Takes care of GC in Perl: we need to decrement Perl's
+    reference count when PV goes out of scope.
+*/
+
+/* #include <stdio.h> */
+
+static void
+PVFinalize (JSContext *cx, JSObject *obj)
+{
+    /* SV* sv = SvRV(PVGetRef(cx, obj)); */
+    SV *sv;
+
+    if ( obj ) {
+        sv = PVGetRef(cx, obj);
+        
+        /* SV *sv = PVGetRef(cx, obj);
+           if ( SvROK(sv) ) sv = SvRV( sv ); _PH_ test*/
+        
+        /* TODO: GC */
+        if(sv && SvREFCNT(sv) > 0){
+            /*fprintf(stderr, "Finalization: %d references left", SvREFCNT(sv));*/
+            SvREFCNT_dec(sv);
+            /*fprintf(stderr, "Finalization: %d references left", SvREFCNT(sv));*/
+        }
+    }
+    /*    return JS_TRUE; */
+}
+
+/*
+    Convert a jsval to a SV* (scalar value pointer).
+    Used for parameter passing. This function is also
+    used by the Perl part of PerlConnect.
+*/
+
+JSBool
+JSVALToSV(JSContext *cx, JSObject *obj, jsval v, SV** sv)
+{
+    //*sv = &sv_undef; //__PH__??
+    if(JSVAL_IS_PRIMITIVE(v)){
+        if(JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)){
+            *sv = &PL_sv_undef;
+            //printf("===> JSVALToSV: VOID\n");
+        }else
+        if(JSVAL_IS_INT(v)){
+            *sv = sv_newmortal();
+            sv_setiv(*sv, JSVAL_TO_INT(v));
+            //*sv = newSViv(JSVAL_TO_INT(v));
+            //printf("===> JSVALToSV: INT\n");
+        }else
+        if(JSVAL_IS_DOUBLE(v)){
+            *sv = sv_newmortal();
+            sv_setnv(*sv, *JSVAL_TO_DOUBLE(v));
+            //*sv = newSVnv(*JSVAL_TO_DOUBLE(v));
+            //printf("===> JSVALToSV: DOUBLE\n");
+        }else
+        if(JSVAL_IS_STRING(v)){
+            *sv = sv_newmortal();
+            sv_setpv(*sv, JS_GetStringBytes(JSVAL_TO_STRING(v)));
+            //*sv = newSViv(0);
+            //sv_setpv(*sv, JS_GetStringBytes(JSVAL_TO_STRING(v)));
+            //printf("===> JSVALToSV: CHAR\n");
+        }else{
+            warn("Unknown primitive type");
+        }
+    }else{
+        if(JSVAL_IS_OBJECT(v)){
+            JSObject *object = JSVAL_TO_OBJECT(v);
+            if(JS_InstanceOf(cx, object, &perlValueClass, NULL)){
+                *sv = PVGetRef(cx, object);
+            }else{
+                if(JS_IsArrayObject(cx, object)){
+                    *sv = sv_newmortal();
+                    sv_setref_pv(*sv, "JS::Object", (void*)object);
+                    sv_magic(SvRV(*sv), sv_2mortal(newSViv((IV)cx)), 
+                             '~', NULL, 0);
+                    /* printf("===> JSVALToSV: ARRAY\n); */
+                }else{
+                    *sv = sv_newmortal();
+                    sv_setref_pv(*sv, "JS::Object", (void*)object);
+                    sv_magic(SvRV(*sv), sv_2mortal(newSViv((IV)cx)), 
+                             '~', NULL, 0);
+                    //printf("===> JSVALToSV: JS OBJECT\n");
+                }
+            }
+        }else{
+            warn("Type conversion is not supported");
+            *sv = &PL_sv_undef;  //__PH__??
+            return JS_FALSE;
+        }
+    }
+    return JS_TRUE;
+}
+
+/*
+    Converts a reference Perl value to a jsval. If ref points
+    to an immediate value, the value itself is returned in rval.
+    O.w. a PerlValue object is returned. This function is also
+    used by the Perl part of PerlConnect.
+*/
+
+#define SV_BIND_TO_OBJECT(sv) (sv_isobject(sv) || (SvROK(sv) && (\
+               SvTYPE(SvRV(sv)) == SVt_RV   ||\
+               SvTYPE(SvRV(sv)) == SVt_PVAV ||\
+               SvTYPE(SvRV(sv)) == SVt_PVHV ||\
+               SvTYPE(SvRV(sv)) == SVt_PVCV\
+            )))
+
+JSBool
+SVToJSVAL(JSContext *cx, JSObject *obj, SV *ref, jsval *rval) {
+    SV *sv;
+    char* name=NULL;
+    JSBool ok = JS_TRUE;
+
+    /* we'll use the dereferrenced value (excpet for object) */
+    if( SvROK(ref) ) {
+        sv = SvRV(ref);
+    }else{
+        sv = ref;
+    }
+
+    /* printf("+++> In SVToJSVAL value %s, type=%d\n", SvPV(sv, PL_na), SvTYPE(sv)); */
+
+    if ( ! SvOK( ref ) ){
+        *rval = JSVAL_VOID;
+        /* printf("---> SVToJSVAL returning VOID\n"); */
+    } else
+    if ( SV_BIND_TO_OBJECT(ref) ) {
+        JSObject *perlValue, *prototype = NULL;
+        JSString *nameString;
+
+        /*svtype type = SvTYPE(sv);
+          switch(type){
+          case SVt_RV:   name = "Perl Reference"; break;
+          case SVt_PVAV: name = "Perl Array"; break;
+          case SVt_PVHV: name = "Perl Hash"; break;
+          case SVt_PVCV: name = "Perl Code Reference"; break;
+          case SVt_PVMG: name = "Perl Magic"; break;
+          default:
+          warn("Unsupported type in SVToJSVAL: %d", type);
+          *rval = JSVAL_VOID;
+          return JS_FALSE;
+          }*/
+        
+        /* printf("---> SVToJSVAL returning object\n"); */
+        name = "Perl Value";
+        /* __PH__ */
+        SvREFCNT_inc(ref);
+
+        if (SvTYPE(sv) == SVt_PVAV) {
+            prototype = JS_NewArrayObject(cx, 0, NULL);
+            if (!prototype)
+                return JS_FALSE;
+        }
+
+        perlValue = JS_DefineObject(cx, obj, "PerlValue",
+                                    &perlValueClass, prototype, 
+                                    JSPROP_ENUMERATE);
+        if (!perlValue)
+            return JS_FALSE;
+        JS_SetPrivate(cx, perlValue, ref);
+        if (!JS_DefineFunctions(cx, perlValue, perlValueMethods))
+            return JS_FALSE;
+        if (name) {
+            nameString = JS_NewStringCopyZ(cx, name);
+            if (!nameString)
+                return JS_FALSE;
+        }
+        if (!JS_DefineProperty(cx, perlValue, "type",
+                               name?STRING_TO_JSVAL(nameString):JSVAL_VOID,
+                               NULL, NULL, JSPROP_PERMANENT|JSPROP_READONLY))
+            return JS_FALSE;
+        *rval = OBJECT_TO_JSVAL(perlValue); 
+    } else
+    if(SvIOK(sv)){
+        *rval = INT_TO_JSVAL(SvIV(sv));
+        /* printf("---> SVToJSVAL returning INTEGER\n"); */
+    } else
+    if(SvNOK(sv)){
+        ok = JS_NewDoubleValue(cx, SvNV(sv), rval);
+        /* printf("---> SVToJSVAL returning DOUBLE\n"); */
+    } else
+    if(SvPOK(sv)){
+        *rval = STRING_TO_JSVAL((JS_NewStringCopyZ(cx, SvPV(sv, PL_na))));
+        /* printf("---> SVToJSVAL returning CHAR\n\n"); */
+    } else {
+        *rval = JSVAL_VOID; /* shouldn't happen */
+        /* printf("---> SVToJSVAL returning VOID (panic)\n"); */
+    }
+    return ok;
+}

Added: freeswitch/trunk/libs/js/src/perlconnect/jsperl.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/perlconnect/jsperl.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,52 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the 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 ***** */
+
+/* This is the public header, which means that this is the only thing one    */
+/* needs to include to enable the Perl object. See README.html for more      */
+/* documentation                                                             */
+
+#include <jsapi.h>
+
+/*
+    This is the only function that must be called by an
+    application that wants to use PerlConnect.
+*/
+JS_EXTERN_API(JSObject*)
+JS_InitPerlClass(JSContext *cx, JSObject *obj);
+

Added: freeswitch/trunk/libs/js/src/perlconnect/jsperlpvt.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/perlconnect/jsperlpvt.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the 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 "EXTERN.h"
+#include "perl.h"
+#include "jsperl.h"
+/* Copyright © 1998 Netscape Communications Corporation, All Rights Reserved.*/
+/* This is the private header, which means that it shouldn't be included     */
+/* unless you need to use some of the jsval<->SV* conversion functions       */
+/* provided by PerlConnect needs to include to enable the Perl object. See   */
+/* README.html for more documentation                                        */
+
+/*
+    This and the following function are used to convert
+    between Perl's "SV*" and JS's "jsval" types.
+*/
+JS_EXTERN_API(SV*)
+JSVALToSV(JSContext *cx, JSObject *obj, jsval v, SV** sv);
+
+JS_EXTERN_API(JSBool)
+SVToJSVAL(JSContext *cx, JSObject *obj, SV *ref, jsval *rval);

Added: freeswitch/trunk/libs/js/src/perlconnect/typemap
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/perlconnect/typemap	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,121 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Communicator client code, released
+# March 31, 1998.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the 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 *****
+
+#
+# Typemap for PerlConnect
+#
+
+TYPEMAP
+# These types have direct equivalents implemented as Perl packages
+JSRuntime *      RUNTIME
+JSContext *      CONTEXT
+JSScript  *      SCRIPT
+jsval            jsval
+# This is an auxilary type. Object serves as a wrapper for it
+JSObject *       OBJECT
+
+
+OUTPUT
+jsval
+    {
+	SV *foo = sv_newmortal();
+        JSVALToSV(cx, JS_GetGlobalObject(cx), $var, &foo);
+	sv_setsv($arg, foo);
+    }
+
+OBJECT
+    sv_setref_pv($arg, "JS::Object", (void*)$var);
+
+#CONTEXT
+#    sv_setref_pv($arg, "JS::Context", (void*)$var);
+
+SCRIPT
+    sv_setref_pv($arg, "JS::Script", (void*)$var);
+
+RUNTIME
+    sv_setref_pv($arg, "JS::Runtime", (void*)$var);
+
+#JS_OBJECT
+#    sv_setref_pv($arg, "JSObject", (void*)$var);
+
+INPUT
+jsval
+    {
+        /* JSContext *cx = getContext(); */
+        SVToJSVAL(cx, JS_GetGlobalObject(cx), newRV($arg), &$var);
+    }
+
+OBJECT
+    if(sv_isa($arg, \"JS::Object\"))
+        $var = ($type)SvIV((SV*)SvRV($arg));
+    else{
+        warn(\"${Package}::$func_name() -- $var is not a blessed JS::Object reference\");
+        XSRETURN_UNDEF;
+    }
+
+#CONTEXT
+#    if(sv_isa($arg, \"JS::Context\"))
+#        $var = ($type)SvIV((SV*)SvRV($arg));
+#    else{
+#        warn(\"${Package}::$func_name() -- $var is not a blessed JS::Context reference\");
+#        XSRETURN_UNDEF;
+#    }
+
+CONTEXT
+    if(sv_isa($arg, \"JS::Context\"))
+        $var = ($type)SvIV(*hv_fetch((HV*)SvRV($arg), \"_handle\", 7, 0));
+    else{
+        warn(\"${Package}::$func_name() -- $var is not a blessed JS::Context reference\");
+        XSRETURN_UNDEF;
+    }
+
+SCRIPT
+    if(sv_isa($arg, \"JS::Script\"))
+        $var = ($type)SvIV((SV*)SvRV($arg));
+    else{
+        warn(\"${Package}::$func_name() -- $var is not a blessed JS::Script reference\");
+        XSRETURN_UNDEF;
+    }
+
+RUNTIME
+    if(sv_isa($arg, \"JS::Runtime\"))
+        $var = ($type)SvIV((SV*)SvRV($arg));
+    else{
+        warn(\"${Package}::$func_name() -- $var is not a blessed JS::Runtime reference\");
+        XSRETURN_UNDEF;
+    }

Added: freeswitch/trunk/libs/js/src/prmjtime.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/prmjtime.c	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,440 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * PR time code.
+ */
+#include "jsstddef.h"
+#ifdef SOLARIS
+#define _REENTRANT 1
+#endif
+#include <string.h>
+#include <time.h>
+#include "jstypes.h"
+#include "jsutil.h"
+
+#include "jsprf.h"
+#include "prmjtime.h"
+
+#define PRMJ_DO_MILLISECONDS 1
+
+#ifdef XP_OS2
+#include <sys/timeb.h>
+#endif
+#ifdef XP_WIN
+#include <windef.h>
+#include <winbase.h>
+#endif
+
+#if defined(XP_UNIX) || defined(XP_BEOS)
+
+#ifdef _SVID_GETTOD   /* Defined only on Solaris, see Solaris <sys/types.h> */
+extern int gettimeofday(struct timeval *tv);
+#endif
+
+#include <sys/time.h>
+
+#endif /* XP_UNIX */
+
+#define IS_LEAP(year) \
+   (year != 0 && ((((year & 0x3) == 0) &&  \
+		   ((year - ((year/100) * 100)) != 0)) || \
+		  (year - ((year/400) * 400)) == 0))
+
+#define PRMJ_HOUR_SECONDS  3600L
+#define PRMJ_DAY_SECONDS  (24L * PRMJ_HOUR_SECONDS)
+#define PRMJ_YEAR_SECONDS (PRMJ_DAY_SECONDS * 365L)
+#define PRMJ_MAX_UNIX_TIMET 2145859200L /*time_t value equiv. to 12/31/2037 */
+/* function prototypes */
+static void PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm);
+/*
+ * get the difference in seconds between this time zone and UTC (GMT)
+ */
+JSInt32
+PRMJ_LocalGMTDifference()
+{
+#if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS)
+    struct tm ltime;
+
+    /* get the difference between this time zone and GMT */
+    memset((char *)&ltime,0,sizeof(ltime));
+    ltime.tm_mday = 2;
+    ltime.tm_year = 70;
+#ifdef SUNOS4
+    ltime.tm_zone = 0;
+    ltime.tm_gmtoff = 0;
+    return timelocal(&ltime) - (24 * 3600);
+#else
+    return mktime(&ltime) - (24L * 3600L);
+#endif
+#endif
+}
+
+/* Constants for GMT offset from 1970 */
+#define G1970GMTMICROHI        0x00dcdcad /* micro secs to 1970 hi */
+#define G1970GMTMICROLOW       0x8b3fa000 /* micro secs to 1970 low */
+
+#define G2037GMTMICROHI        0x00e45fab /* micro secs to 2037 high */
+#define G2037GMTMICROLOW       0x7a238000 /* micro secs to 2037 low */
+
+/* Convert from base time to extended time */
+static JSInt64
+PRMJ_ToExtendedTime(JSInt32 base_time)
+{
+    JSInt64 exttime;
+    JSInt64 g1970GMTMicroSeconds;
+    JSInt64 low;
+    JSInt32 diff;
+    JSInt64  tmp;
+    JSInt64  tmp1;
+
+    diff = PRMJ_LocalGMTDifference();
+    JSLL_UI2L(tmp, PRMJ_USEC_PER_SEC);
+    JSLL_I2L(tmp1,diff);
+    JSLL_MUL(tmp,tmp,tmp1);
+
+    JSLL_UI2L(g1970GMTMicroSeconds,G1970GMTMICROHI);
+    JSLL_UI2L(low,G1970GMTMICROLOW);
+#ifndef JS_HAVE_LONG_LONG
+    JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
+    JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
+#else
+    JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,32);
+#endif
+    JSLL_ADD(g1970GMTMicroSeconds,g1970GMTMicroSeconds,low);
+
+    JSLL_I2L(exttime,base_time);
+    JSLL_ADD(exttime,exttime,g1970GMTMicroSeconds);
+    JSLL_SUB(exttime,exttime,tmp);
+    return exttime;
+}
+
+JSInt64
+PRMJ_Now(void)
+{
+#ifdef XP_OS2
+    JSInt64 s, us, ms2us, s2us;
+    struct timeb b;
+#endif
+#ifdef XP_WIN
+    JSInt64 s, us,
+    win2un = JSLL_INIT(0x19DB1DE, 0xD53E8000),
+    ten = JSLL_INIT(0, 10);
+    FILETIME time, midnight;
+#endif
+#if defined(XP_UNIX) || defined(XP_BEOS)
+    struct timeval tv;
+    JSInt64 s, us, s2us;
+#endif /* XP_UNIX */
+
+#ifdef XP_OS2
+    ftime(&b);
+    JSLL_UI2L(ms2us, PRMJ_USEC_PER_MSEC);
+    JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
+    JSLL_UI2L(s, b.time);
+    JSLL_UI2L(us, b.millitm);
+    JSLL_MUL(us, us, ms2us);
+    JSLL_MUL(s, s, s2us);
+    JSLL_ADD(s, s, us);
+    return s;
+#endif
+#ifdef XP_WIN
+    /* The windows epoch is around 1600. The unix epoch is around 1970.
+       win2un is the difference (in windows time units which are 10 times
+       more precise than the JS time unit) */
+    GetSystemTimeAsFileTime(&time);
+    /* Win9x gets confused at midnight
+       http://support.microsoft.com/default.aspx?scid=KB;en-us;q224423
+       So if the low part (precision <8mins) is 0 then we get the time
+       again. */
+    if (!time.dwLowDateTime) {
+        GetSystemTimeAsFileTime(&midnight);
+        time.dwHighDateTime = midnight.dwHighDateTime;
+    }
+    JSLL_UI2L(s, time.dwHighDateTime);
+    JSLL_UI2L(us, time.dwLowDateTime);
+    JSLL_SHL(s, s, 32);
+    JSLL_ADD(s, s, us);
+    JSLL_SUB(s, s, win2un);
+    JSLL_DIV(s, s, ten);
+    return s;
+#endif
+
+#if defined(XP_UNIX) || defined(XP_BEOS)
+#ifdef _SVID_GETTOD   /* Defined only on Solaris, see Solaris <sys/types.h> */
+    gettimeofday(&tv);
+#else
+    gettimeofday(&tv, 0);
+#endif /* _SVID_GETTOD */
+    JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC);
+    JSLL_UI2L(s, tv.tv_sec);
+    JSLL_UI2L(us, tv.tv_usec);
+    JSLL_MUL(s, s, s2us);
+    JSLL_ADD(s, s, us);
+    return s;
+#endif /* XP_UNIX */
+}
+
+/* Get the DST timezone offset for the time passed in */
+JSInt64
+PRMJ_DSTOffset(JSInt64 local_time)
+{
+    JSInt64 us2s;
+    time_t local;
+    JSInt32 diff;
+    JSInt64  maxtimet;
+    struct tm tm;
+    PRMJTime prtm;
+#ifndef HAVE_LOCALTIME_R
+    struct tm *ptm;
+#endif
+
+
+    JSLL_UI2L(us2s, PRMJ_USEC_PER_SEC);
+    JSLL_DIV(local_time, local_time, us2s);
+
+    /* get the maximum of time_t value */
+    JSLL_UI2L(maxtimet,PRMJ_MAX_UNIX_TIMET);
+
+    if(JSLL_CMP(local_time,>,maxtimet)){
+        JSLL_UI2L(local_time,PRMJ_MAX_UNIX_TIMET);
+    } else if(!JSLL_GE_ZERO(local_time)){
+        /*go ahead a day to make localtime work (does not work with 0) */
+        JSLL_UI2L(local_time,PRMJ_DAY_SECONDS);
+    }
+    JSLL_L2UI(local,local_time);
+    PRMJ_basetime(local_time,&prtm);
+#ifndef HAVE_LOCALTIME_R
+    ptm = localtime(&local);
+    if(!ptm){
+        return JSLL_ZERO;
+    }
+    tm = *ptm;
+#else
+    localtime_r(&local,&tm); /* get dst information */
+#endif
+
+    diff = ((tm.tm_hour - prtm.tm_hour) * PRMJ_HOUR_SECONDS) +
+	((tm.tm_min - prtm.tm_min) * 60);
+
+    if(diff < 0){
+	diff += PRMJ_DAY_SECONDS;
+    }
+
+    JSLL_UI2L(local_time,diff);
+
+    JSLL_MUL(local_time,local_time,us2s);
+
+    return(local_time);
+}
+
+/* Format a time value into a buffer. Same semantics as strftime() */
+size_t
+PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *prtm)
+{
+#if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS)
+    struct tm a;
+
+    /* Zero out the tm struct.  Linux, SunOS 4 struct tm has extra members int
+     * tm_gmtoff, char *tm_zone; when tm_zone is garbage, strftime gets
+     * confused and dumps core.  NSPR20 prtime.c attempts to fill these in by
+     * calling mktime on the partially filled struct, but this doesn't seem to
+     * work as well; the result string has "can't get timezone" for ECMA-valid
+     * years.  Might still make sense to use this, but find the range of years
+     * for which valid tz information exists, and map (per ECMA hint) from the
+     * given year into that range.
+
+     * N.B. This hasn't been tested with anything that actually _uses_
+     * tm_gmtoff; zero might be the wrong thing to set it to if you really need
+     * to format a time.  This fix is for jsdate.c, which only uses
+     * JS_FormatTime to get a string representing the time zone.  */
+    memset(&a, 0, sizeof(struct tm));
+
+    a.tm_sec = prtm->tm_sec;
+    a.tm_min = prtm->tm_min;
+    a.tm_hour = prtm->tm_hour;
+    a.tm_mday = prtm->tm_mday;
+    a.tm_mon = prtm->tm_mon;
+    a.tm_wday = prtm->tm_wday;
+    a.tm_year = prtm->tm_year - 1900;
+    a.tm_yday = prtm->tm_yday;
+    a.tm_isdst = prtm->tm_isdst;
+
+    /* Even with the above, SunOS 4 seems to detonate if tm_zone and tm_gmtoff
+     * are null.  This doesn't quite work, though - the timezone is off by
+     * tzoff + dst.  (And mktime seems to return -1 for the exact dst
+     * changeover time.)
+
+     */
+
+#if defined(SUNOS4)
+    if (mktime(&a) == -1) {
+        /* Seems to fail whenever the requested date is outside of the 32-bit
+         * UNIX epoch.  We could proceed at this point (setting a.tm_zone to
+         * "") but then strftime returns a string with a 2-digit field of
+         * garbage for the year.  So we return 0 and hope jsdate.c
+         * will fall back on toString.
+         */
+        return 0;
+    }
+#endif
+
+    return strftime(buf, buflen, fmt, &a);
+#endif
+}
+
+/* table for number of days in a month */
+static int mtab[] = {
+    /* jan, feb,mar,apr,may,jun */
+    31,28,31,30,31,30,
+    /* july,aug,sep,oct,nov,dec */
+    31,31,30,31,30,31
+};
+
+/*
+ * basic time calculation functionality for localtime and gmtime
+ * setups up prtm argument with correct values based upon input number
+ * of seconds.
+ */
+static void
+PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm)
+{
+    /* convert tsecs back to year,month,day,hour,secs */
+    JSInt32 year    = 0;
+    JSInt32 month   = 0;
+    JSInt32 yday    = 0;
+    JSInt32 mday    = 0;
+    JSInt32 wday    = 6; /* start on a Sunday */
+    JSInt32 days    = 0;
+    JSInt32 seconds = 0;
+    JSInt32 minutes = 0;
+    JSInt32 hours   = 0;
+    JSInt32 isleap  = 0;
+    JSInt64 result;
+    JSInt64	result1;
+    JSInt64	result2;
+    JSInt64 base;
+
+    JSLL_UI2L(result,0);
+    JSLL_UI2L(result1,0);
+    JSLL_UI2L(result2,0);
+
+    /* get the base time via UTC */
+    base = PRMJ_ToExtendedTime(0);
+    JSLL_UI2L(result,  PRMJ_USEC_PER_SEC);
+    JSLL_DIV(base,base,result);
+    JSLL_ADD(tsecs,tsecs,base);
+
+    JSLL_UI2L(result, PRMJ_YEAR_SECONDS);
+    JSLL_UI2L(result1,PRMJ_DAY_SECONDS);
+    JSLL_ADD(result2,result,result1);
+
+    /* get the year */
+    while ((isleap == 0) ? !JSLL_CMP(tsecs,<,result) : !JSLL_CMP(tsecs,<,result2)) {
+        /* subtract a year from tsecs */
+        JSLL_SUB(tsecs,tsecs,result);
+        days += 365;
+        /* is it a leap year ? */
+        if(IS_LEAP(year)){
+            JSLL_SUB(tsecs,tsecs,result1);
+            days++;
+        }
+        year++;
+        isleap = IS_LEAP(year);
+    }
+
+    JSLL_UI2L(result1,PRMJ_DAY_SECONDS);
+
+    JSLL_DIV(result,tsecs,result1);
+    JSLL_L2I(mday,result);
+
+    /* let's find the month */
+    while(((month == 1 && isleap) ?
+            (mday >= mtab[month] + 1) :
+            (mday >= mtab[month]))){
+	 yday += mtab[month];
+	 days += mtab[month];
+
+	 mday -= mtab[month];
+
+         /* it's a Feb, check if this is a leap year */
+	 if(month == 1 && isleap != 0){
+	     yday++;
+	     days++;
+	     mday--;
+	 }
+	 month++;
+    }
+
+    /* now adjust tsecs */
+    JSLL_MUL(result,result,result1);
+    JSLL_SUB(tsecs,tsecs,result);
+
+    mday++; /* day of month always start with 1 */
+    days += mday;
+    wday = (days + wday) % 7;
+
+    yday += mday;
+
+    /* get the hours */
+    JSLL_UI2L(result1,PRMJ_HOUR_SECONDS);
+    JSLL_DIV(result,tsecs,result1);
+    JSLL_L2I(hours,result);
+    JSLL_MUL(result,result,result1);
+    JSLL_SUB(tsecs,tsecs,result);
+
+    /* get minutes */
+    JSLL_UI2L(result1,60);
+    JSLL_DIV(result,tsecs,result1);
+    JSLL_L2I(minutes,result);
+    JSLL_MUL(result,result,result1);
+    JSLL_SUB(tsecs,tsecs,result);
+
+    JSLL_L2I(seconds,tsecs);
+
+    prtm->tm_usec  = 0L;
+    prtm->tm_sec   = (JSInt8)seconds;
+    prtm->tm_min   = (JSInt8)minutes;
+    prtm->tm_hour  = (JSInt8)hours;
+    prtm->tm_mday  = (JSInt8)mday;
+    prtm->tm_mon   = (JSInt8)month;
+    prtm->tm_wday  = (JSInt8)wday;
+    prtm->tm_year  = (JSInt16)year;
+    prtm->tm_yday  = (JSInt16)yday;
+}

Added: freeswitch/trunk/libs/js/src/prmjtime.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/libs/js/src/prmjtime.h	Mon Dec 18 10:53:47 2006
@@ -0,0 +1,103 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef prmjtime_h___
+#define prmjtime_h___
+/*
+ * PR date stuff for mocha and java. Placed here temporarily not to break
+ * Navigator and localize changes to mocha.
+ */
+#include <time.h>
+#include "jslong.h"
+#ifdef MOZILLA_CLIENT
+#include "jscompat.h"
+#endif
+
+#ifdef OSSP
+/* avoid namespace pollution */
+#define PRMJ_Now                js_PRMJ_Now
+#define PRMJ_LocalGMTDifference js_PRMJ_LocalGMTDifference
+#define PRMJ_FormatTime         js_PRMJ_FormatTime
+#define PRMJ_DSTOffset          js_PRMJ_DSTOffset
+#endif
+
+JS_BEGIN_EXTERN_C
+
+typedef struct PRMJTime       PRMJTime;
+
+/*
+ * Broken down form of 64 bit time value.
+ */
+struct PRMJTime {
+    JSInt32 tm_usec;            /* microseconds of second (0-999999) */
+    JSInt8 tm_sec;              /* seconds of minute (0-59) */
+    JSInt8 tm_min;              /* minutes of hour (0-59) */
+    JSInt8 tm_hour;             /* hour of day (0-23) */
+    JSInt8 tm_mday;             /* day of month (1-31) */
+    JSInt8 tm_mon;              /* month of year (0-11) */
+    JSInt8 tm_wday;             /* 0=sunday, 1=monday, ... */
+    JSInt16 tm_year;            /* absolute year, AD */
+    JSInt16 tm_yday;            /* day of year (0 to 365) */
+    JSInt8 tm_isdst;            /* non-zero if DST in effect */
+};
+
+/* Some handy constants */
+#define PRMJ_USEC_PER_SEC       1000000L
+#define PRMJ_USEC_PER_MSEC      1000L
+
+/* Return the current local time in micro-seconds */
+extern JSInt64
+PRMJ_Now(void);
+
+/* get the difference between this time zone and  gmt timezone in seconds */
+extern JSInt32
+PRMJ_LocalGMTDifference(void);
+
+/* Format a time value into a buffer. Same semantics as strftime() */
+extern size_t
+PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *tm);
+
+/* Get the DST offset for the local time passed in */
+extern JSInt64
+PRMJ_DSTOffset(JSInt64 local_time);
+
+JS_END_EXTERN_C
+
+#endif /* prmjtime_h___ */
+



More information about the Freeswitch-svn mailing list